feat: initial impl of NSA
This commit is contained in:
parent
9ec5b14306
commit
8103309419
14 changed files with 140 additions and 100 deletions
60
.github/workflows/mdbook.yml
vendored
60
.github/workflows/mdbook.yml
vendored
|
@ -1,60 +0,0 @@
|
|||
# Sample workflow for building and deploying a mdBook site to GitHub Pages
|
||||
#
|
||||
# To get started with mdBook see: https://rust-lang.github.io/mdBook/index.html
|
||||
#
|
||||
name: Deploy mdBook site to Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Build job
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MDBOOK_VERSION: 0.4.36
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install mdBook
|
||||
run: |
|
||||
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf -y | sh
|
||||
rustup update
|
||||
cargo install --version ${MDBOOK_VERSION} mdbook
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v4
|
||||
- name: Build with mdBook
|
||||
run: mdbook build
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: ./book
|
||||
|
||||
# Deployment job
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
docs/book
|
||||
target
|
||||
openat
|
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -3,5 +3,14 @@
|
|||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "okrust"
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "nosey_syscall_auditor"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
[package]
|
||||
name = "okrust"
|
||||
name = "nosey_syscall_auditor"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
name = "nsa"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.153"
|
||||
|
|
8
Makefile
Normal file
8
Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
all: test_openat
|
||||
|
||||
test_openat: test_openat.c
|
||||
$(CC) $(CFLAGS) -o openat test_openat.c
|
||||
|
||||
clean veryclean:
|
||||
$(RM) Hello
|
17
README.md
17
README.md
|
@ -1,10 +1,13 @@
|
|||
<img src="docs/src/okRust.png" width="200" height="200" alt="okRust logo">
|
||||
<img src="nsa.png" width="200" height="200" alt="Nosey Syscall Auditor">
|
||||
|
||||
# okRust
|
||||
# Nosey Syscall Auditor
|
||||
|
||||
okrust is the template for new rust projects within oknotok.computer.
|
||||
NSA, a tortured backronym for Nosey Syscall Auditor, is a simple tool to audit system calls made by a process.
|
||||
|
||||
It has some opinionated defaults, like using:
|
||||
- mdBook for documentation
|
||||
- release please for releases
|
||||
- github actions for CI/CD
|
||||
I'm sorry. I couldn't resist.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
LD_PRELOAD=./nsa.so make all
|
||||
```
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
[book]
|
||||
authors = ["sevki"]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "docs/src"
|
|
@ -1,3 +0,0 @@
|
|||
# Summary
|
||||
|
||||
- [Intro](intro.md)
|
|
@ -1,10 +0,0 @@
|
|||
# okRust
|
||||
|
||||
<img src="okRust.png" width="200" height="200" align="right" alt="okRust logo">
|
||||
|
||||
okrust is the template for new rust projects within oknotok.computer.
|
||||
|
||||
It has some opinionated defaults, like using:
|
||||
- mdBook for documentation
|
||||
- release please for releases
|
||||
- github actions for CI/CD
|
Binary file not shown.
Before Width: | Height: | Size: 273 KiB |
BIN
nsa.png
Normal file
BIN
nsa.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 724 KiB |
3
rust-toolchain
Normal file
3
rust-toolchain
Normal file
|
@ -0,0 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "1.76"
|
||||
components = [ "rustfmt", "rust-src", "cargo", "clippy" ]
|
101
src/lib.rs
101
src/lib.rs
|
@ -1,14 +1,91 @@
|
|||
pub fn add(left: usize, right: usize) -> usize {
|
||||
left + right
|
||||
//! ![NSA](https://raw.githubusercontent.com/sevki/nsa/master/nsa.png)
|
||||
//!
|
||||
//! # NSA: Nosey Syscall Abstractions
|
||||
//!
|
||||
//! NSA is a library that allows you to intercept and log system calls.
|
||||
//! It uses the `dlsym` function to get the address of the original function and then calls it. This is a simple way to intercept and log system calls.
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! ```shell
|
||||
//! cargo build --release
|
||||
//! LD_PRELOAD=./target/release/nsa.so make
|
||||
//! ```
|
||||
|
||||
// set docs rs logo and favicon
|
||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/sevki/nsa/master/nsa.png")]
|
||||
#![doc(html_favicon_url = "https://raw.githubusercontent.com/sevki/nsa/master/nsa.png")]
|
||||
|
||||
use libc::c_char;
|
||||
use std::ffi::CStr;
|
||||
|
||||
macro_rules! wrap_syscall {
|
||||
($func_name:ident, $($arg_name:ident: $arg_type:ty),*) => {
|
||||
/// # Safety
|
||||
///
|
||||
/// These functinos are inherently unsafe as they are calling system calls.
|
||||
///
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn $func_name($($arg_name: $arg_type),*) -> i32 {
|
||||
let orig_func: unsafe extern "C" fn($($arg_type),*) -> i32 =
|
||||
unsafe { std::mem::transmute(libc::dlsym(libc::RTLD_NEXT, concat!(stringify!($func_name), "\0").as_ptr() as *const i8)) };
|
||||
|
||||
println!("Intercepted {}", stringify!($func_name));
|
||||
println!("Arguments: ");
|
||||
$(
|
||||
println!(" {} {}: {}", stringify!($func_name), stringify!($arg_name), {
|
||||
// check argtype is *const c_char
|
||||
if stringify!($arg_type) == "*const c_char" {
|
||||
if let Some(s) = unsafe { ($arg_name as *const c_char).as_ref() } {
|
||||
let string = unsafe { CStr::from_ptr(s).to_string_lossy() };
|
||||
format!("{:?}", string)
|
||||
} else {
|
||||
format!("{:?}", $arg_name)
|
||||
}
|
||||
} else {
|
||||
format!("{:?}", $arg_name)
|
||||
}
|
||||
});
|
||||
)*
|
||||
|
||||
let result = orig_func($($arg_name),*);
|
||||
println!("Original {} returned {}", stringify!($func_name), result);
|
||||
|
||||
result
|
||||
}
|
||||
};
|
||||
|
||||
($func_name:ident) => {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn $func_name() -> i32 {
|
||||
let orig_func: unsafe extern "C" fn() -> i32 =
|
||||
unsafe { std::mem::transmute(libc::dlsym(libc::RTLD_NEXT, concat!(stringify!($func_name), "\0").as_ptr() as *const i8)) };
|
||||
|
||||
println!("Intercepted {}", stringify!($func_name));
|
||||
|
||||
let result = orig_func();
|
||||
println!("Original {} returned {}", stringify!($func_name), result);
|
||||
|
||||
result
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
||||
// open
|
||||
wrap_syscall!(open, path: *const c_char, flags: i32, mode: i32);
|
||||
// openat
|
||||
wrap_syscall!(openat, dirfd: i32, path: *const c_char, flags: i32, mode: i32);
|
||||
// execve
|
||||
wrap_syscall!(execve, path: *const c_char, argv: *const *const c_char, envp: *const *const c_char);
|
||||
// access
|
||||
wrap_syscall!(access, pathname: *const c_char, mode: i32);
|
||||
// uname
|
||||
wrap_syscall!(uname, buf: *mut libc::utsname);
|
||||
// getuid
|
||||
wrap_syscall!(getuid);
|
||||
// getpid
|
||||
wrap_syscall!(getpid);
|
||||
// getppid
|
||||
wrap_syscall!(getppid);
|
||||
// fork
|
||||
wrap_syscall!(fork);
|
||||
|
|
13
test_openat.c
Normal file
13
test_openat.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
int fd = openat(AT_FDCWD, "Cargo.toml", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
perror("openat");
|
||||
return 1;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue