-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsledge.cpp
More file actions
105 lines (104 loc) · 3.29 KB
/
Copy pathsledge.cpp
File metadata and controls
105 lines (104 loc) · 3.29 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <stdlib.h>
#include <cstdio>
#include <string>
#include <fstream>
#include <cstdint>
#include <sys/ptrace.h>
#include <random>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <chrono>
#include <thread>
int main(int argc, char* argv[]) {
if(argc != 4) {
printf("sledgehammer - corrupts the heap of a selected process for fun and for profit\n\n");
printf("WARNING: don't hit an important process with this. or if you do, do it in a VM.\ncorrupting heap is inherently unsafe, and could result in severe data loss.\ni'm not responsible for whatever damage you cause with this.\n\n");
printf("usage: %s [victim pid] [bytes per cycle] [delay (ms) between cycles]\n", argv[0]);
return 1;
}
if(geteuid()) {
printf("error: you have to run this program as root!\n");
return 1;
}
pid_t victim_pid = strtol(argv[1], NULL, 10);
if(victim_pid == 0) {
printf("error: invalid PID\n");
return 1;
}
long bytes_per_cycle = strtol(argv[2], NULL, 10);
if(bytes_per_cycle == 0) {
printf("error: invalid bytes per cycle\n");
return 1;
}
long delay = strtol(argv[3], NULL, 10);
if(delay == 0) {
printf("error: invalid delay\n");
return 1;
}
printf("finding the heap for process ID %d...\n", victim_pid);
std::string map_file = "/proc/" + std::string(argv[1]) + "/maps";
printf("gonna open %s\n", map_file.c_str());
std::ifstream mapFile(map_file.c_str());
std::string line;
std::string s_heapStart;
std::string s_heapEnd;
bool found = false;
while(std::getline(mapFile, line)) {
if(line.find("[heap]") != std::string::npos) {
printf("found heap line: %s\n", line.c_str());
int dashLoc = line.find_first_of("-");
int spaceLoc = line.find_first_of(" ");
s_heapStart = line.substr(0, dashLoc);
s_heapEnd = line.substr(dashLoc+1, spaceLoc-dashLoc);
found = true;
}
}
if(!found) {
printf("error: couldn't find a heap section\n");
return 1;
}
printf("the process' heap spans from %s to %s\n", s_heapStart.c_str(), s_heapEnd.c_str());
uintptr_t heapStart = strtoull(s_heapStart.c_str(), nullptr, 16);
uintptr_t heapEnd = strtoull(s_heapEnd.c_str(), nullptr, 16);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<uintptr_t> distrib(heapStart, heapEnd - sizeof(long));
printf("latching onto the process now!\n");
if(ptrace(PTRACE_SEIZE, victim_pid, NULL, NULL) == -1) {
perror("ptrace seize");
return 1;
}
/*if(waitpid(victim_pid, NULL, 0) == -1) {
perror("waitpid");
return 1;
}*/
printf("now attached to the process\n");
std::string mem_file = "/proc/" + std::string(argv[1]) + "/mem";
int mem_fd = open(mem_file.c_str(), O_RDWR);
if(mem_fd == -1) {
perror("open");
return 1;
}
while(1) {
for(int i = 0; i < bytes_per_cycle; i++) {
uintptr_t target_byte = distrib(gen);
target_byte &= ~(sizeof(long)-1);
long orig_value;
if(pread(mem_fd, &orig_value, sizeof(orig_value), target_byte) == -1) {
perror("pread");
return 1;
}
if(orig_value == 0) {
continue;
}
orig_value += 10;
if(pwrite(mem_fd, &orig_value, sizeof(orig_value), target_byte) == -1) {
perror("pwrite");
return 1;
}
printf("fucking up value at location %lu (orig_value %lu)\n", target_byte, orig_value);
}
std::this_thread::sleep_for(std::chrono::milliseconds(delay));
}
}