[UIUCTF] 2017 REV400 Scratches
States:
nc challenge.uiuc.tf 11347
every day I do
100 push ups
100 sit ups
100 squats
100 crackmes
ALL YOUR SOLUTIONS SHOULD BE ASCII
https://www.youtube.com/watch?v=ElGLWB5ffGk
Hello everyone !
This one was a bit tricky, since the gloal was to break 100 crackmes.
At connection, the TCP service send you a huge base64
string, which is an ELF encoded binary then asking you for a flag .. Like this:
[BASE64]
What is the flag ?
<< flag
>> [Good Boy|Bad Boy]
[BASE64]
What is the flag ?
[ETC ETC ]
First analyse the binary ..
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax@3
__int64 v4; // rcx@7
int i; // [sp+28h] [bp-58h]@1
char buf[32]; // [sp+30h] [bp-50h]@1
char s[8]; // [sp+50h] [bp-30h]@1
__int64 v8; // [sp+68h] [bp-18h]@1
v8 = *MK_FP(__FS__, 40LL);
read(0, buf, 0x11uLL);
strcpy(s, "vkakmltocmkwwrvzd");
for ( i = 0; i < strlen(s); ++i )
{
if ( s[i] != buf[i] )
{
puts("sounds fake but ok");
result = 1;
goto LABEL_7;
}
}
puts("you got it!");
result = 0;
LABEL_7:
v4 = *MK_FP(__FS__, 40LL) ^ v8;
return result;
}
Here is the Pseudo code, pretty easy, but the flag is a random generated string, which is in the .text section :
/ (fcn) main 228
| main ();
| ; var int local_78h @ rbp-0x78
| ; var int local_70h @ rbp-0x70
| ; var int local_64h @ rbp-0x64
| ; var int local_59h @ rbp-0x59
| ; var int local_58h @ rbp-0x58
| ; var int local_54h @ rbp-0x54
| ; var int local_50h @ rbp-0x50
| ; var int local_30h @ rbp-0x30
| ; var int local_28h @ rbp-0x28
| ; var int local_20h @ rbp-0x20
| ; var int local_18h @ rbp-0x18
| ; DATA XREF from 0x0040054d (entry0)
| 0x00400626 55 push rbp
| 0x00400627 4889e5 mov rbp, rsp
| 0x0040062a 53 push rbx
| 0x0040062b 4883ec78 sub rsp, 0x78 ; 'x'
| 0x0040062f 897d9c mov dword [rbp - local_64h], edi
| 0x00400632 48897590 mov qword [rbp - local_70h], rsi
| 0x00400636 48895588 mov qword [rbp - local_78h], rdx
| 0x0040063a 64488b042528. mov rax, qword fs:[0x28] ; [0x28:8]=0x1a88 ; '('
| 0x00400643 488945e8 mov qword [rbp - local_18h], rax
| 0x00400647 31c0 xor eax, eax
| 0x00400649 488d45b0 lea rax, qword [rbp - local_50h]
| 0x0040064d ba11000000 mov edx, 0x11 ; rdx ; size_t nbyte
| 0x00400652 4889c6 mov rsi, rax ; void *buf
| 0x00400655 bf00000000 mov edi, 0 ; int fildes
| 0x0040065a b800000000 mov eax, 0
| 0x0040065f e89cfeffff call sym.imp.read ; ssize_t read(int fildes, void *buf, size_t nbyte)
| 0x00400664 48b8766b616b. movabs rax, 0x6f746c6d6b616b76 ; Flag 1 0x6f746c6d6b616b76·at adress 0x400666
| 0x0040066e 488945d0 mov qword [rbp - local_30h], rax
| 0x00400672 48b8636d6b77. movabs rax, 0x7a767277776b6d63 ; Flag 2 0x7a767277776b6d63 at adress 0x400674
| 0x0040067c 488945d8 mov qword [rbp - local_28h], rax
| 0x00400680 66c745e06400 mov word [rbp - local_20h], 0x64 ; 'd' Flag 3 0x64 at adress 0x00400680
| 0x00400686 c745a8000000. mov dword [rbp - local_58h], 0
| ,=< 0x0040068d eb3a jmp 0x4006c9
Btw, I inserted asm comment for you to see the flag fragments. Now We should we have to write an automated script, that will do some I/O stuff and ELF Reading (Python pwntools is doing everything for us) Here is the script :
#!/usr/bin/env python2
from pwn import *
from time import sleep
from sys import exit
s = remote('challenge.uiuc.tf', 11347)
for i in range(100):
content = s.recvuntil("What's the flag?")
content = content.split('What')[0].replace('\n', '').decode('base64')
f = open('/tmp/%d' % (i), 'w+')
f.write(content)
f.close()
context.log_level = 'error'
elf = ELF('/tmp/%d' % (i))
context.log_level = 'info'
flag = elf.read(0x400666, 8)
flag += elf.read(0x400674, 8)
flag += elf.read(0x400684, 1)
s.sendline(flag)
data = s.recvline()
data += s.recvline()
log.success(data.strip() + " FOR BINARY %d flag %s" % (i, flag))
if "wrong" in data:
print content
exit(0)
log.success(s.recvall())
s.close()
Fun challenge !