chore: display for Vec<u8>, project structure
This commit is contained in:
parent
29c9a403f4
commit
45d3f8d734
3 changed files with 32 additions and 5 deletions
|
@ -1,6 +1,6 @@
|
||||||
use nix::{unistd::Pid, Result, libc::{PROT_READ, MAP_PRIVATE, MAP_ANON, PROT_WRITE}, sys::{ptrace, wait::waitpid}};
|
use nix::{unistd::Pid, Result, libc::{PROT_READ, MAP_PRIVATE, MAP_ANON, PROT_EXEC}, sys::{ptrace, wait::waitpid}};
|
||||||
|
|
||||||
use crate::{syscalls::RemoteMMap, senders::write_buffer, injector::RemoteOperation};
|
use crate::{syscalls::RemoteMMap, senders::{write_buffer, read_buffer, ByteVec}, injector::RemoteOperation};
|
||||||
|
|
||||||
pub struct RemoteShellcode<'a> {
|
pub struct RemoteShellcode<'a> {
|
||||||
code: &'a [u8],
|
code: &'a [u8],
|
||||||
|
@ -16,16 +16,21 @@ impl RemoteOperation for RemoteShellcode<'_> {
|
||||||
fn inject(&mut self, pid: Pid, syscall: usize) -> Result<u64> {
|
fn inject(&mut self, pid: Pid, syscall: usize) -> Result<u64> {
|
||||||
let original_regs = ptrace::getregs(pid)?;
|
let original_regs = ptrace::getregs(pid)?;
|
||||||
let ptr = RemoteMMap::args(
|
let ptr = RemoteMMap::args(
|
||||||
0, self.code.len(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0
|
0, self.code.len() + 1, PROT_READ | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0
|
||||||
).inject(pid, syscall)?;
|
).inject(pid, syscall)?;
|
||||||
|
println!("Obtained area @ 0x{:X}", ptr);
|
||||||
let mut shellcode = self.code.to_vec();
|
let mut shellcode = self.code.to_vec();
|
||||||
shellcode.push(0xCC); // is this the debugger trap?
|
shellcode.push(0xCC); // is this the debugger trap?
|
||||||
write_buffer(pid, ptr as usize, shellcode.as_slice())?;
|
write_buffer(pid, ptr as usize, shellcode.as_slice())?;
|
||||||
|
let shellcode = read_buffer(pid, ptr as usize, self.code.len() + 1)?;
|
||||||
|
println!("Copied shellcode {}", ByteVec::from(shellcode));
|
||||||
let mut regs = original_regs.clone();
|
let mut regs = original_regs.clone();
|
||||||
regs.rip = ptr;
|
regs.rip = ptr;
|
||||||
ptrace::setregs(pid, regs)?;
|
ptrace::setregs(pid, regs)?;
|
||||||
ptrace::cont(pid, None)?;
|
ptrace::cont(pid, None)?;
|
||||||
waitpid(pid, None)?;
|
waitpid(pid, None)?;
|
||||||
|
let after_regs = ptrace::getregs(pid)?;
|
||||||
|
println!("Executed shellcode (RIP: 0x{:X}", after_regs.rip);
|
||||||
ptrace::setregs(pid, original_regs)?;
|
ptrace::setregs(pid, original_regs)?;
|
||||||
Ok(ptr)
|
Ok(ptr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ mod syscalls;
|
||||||
mod executors;
|
mod executors;
|
||||||
mod senders;
|
mod senders;
|
||||||
mod injector;
|
mod injector;
|
||||||
|
mod explorers;
|
||||||
|
|
||||||
use injector::{RemoteOperation, step_to_syscall};
|
use injector::{RemoteOperation, step_to_syscall};
|
||||||
use nix::{Result, {sys::{ptrace, wait::waitpid}, unistd::Pid}};
|
use nix::{Result, {sys::{ptrace, wait::waitpid}, unistd::Pid}};
|
||||||
|
@ -18,12 +19,14 @@ struct NeedleArgs {
|
||||||
pid: i32,
|
pid: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SHELLCODE : [u8; 2] = [0x90, 0x90];
|
||||||
|
|
||||||
pub fn nasty_stuff(pid: Pid) -> Result<()> {
|
pub fn nasty_stuff(pid: Pid) -> Result<()> {
|
||||||
let syscall_addr = step_to_syscall(pid)?;
|
let syscall_addr = step_to_syscall(pid)?;
|
||||||
let mut msg = RemoteString::new("injected!\n\0".into());
|
let mut msg = RemoteString::new("injected!\n\0".into());
|
||||||
msg.inject(pid, syscall_addr)?;
|
msg.inject(pid, syscall_addr)?;
|
||||||
RemoteWrite::args(1, msg).inject(pid, syscall_addr)?;
|
RemoteWrite::args(1, msg).inject(pid, syscall_addr)?;
|
||||||
RemoteShellcode::new(&[0u8]).inject(pid, syscall_addr)?;
|
RemoteShellcode::new(&SHELLCODE).inject(pid, syscall_addr)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::ffi::c_void;
|
use std::{ffi::c_void, fmt::Display};
|
||||||
|
|
||||||
use nix::{Result, unistd::Pid, sys::ptrace, libc::{PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON}};
|
use nix::{Result, unistd::Pid, sys::ptrace, libc::{PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON}};
|
||||||
|
|
||||||
|
@ -6,6 +6,25 @@ use crate::{injector::RemoteOperation, syscalls::RemoteMMap};
|
||||||
|
|
||||||
const WORD_SIZE : usize = 32;
|
const WORD_SIZE : usize = 32;
|
||||||
|
|
||||||
|
pub struct ByteVec(pub Vec<u8>);
|
||||||
|
|
||||||
|
impl From<Vec<u8>> for ByteVec {
|
||||||
|
fn from(value: Vec<u8>) -> Self {
|
||||||
|
ByteVec(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ByteVec {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "[ ")?;
|
||||||
|
for el in self.0.iter() {
|
||||||
|
write!(f, "0x{:x} ", el)?;
|
||||||
|
}
|
||||||
|
write!(f, "]")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn read_buffer(pid: Pid, addr: usize, size: usize) -> Result<Vec<u8>> {
|
pub fn read_buffer(pid: Pid, addr: usize, size: usize) -> Result<Vec<u8>> {
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
|
|
Loading…
Reference in a new issue