HACK THE BOO πŸŽƒ: Challenge Writeups

 

Challenge Links:

 
 

Web Challenges

Evaluation Deck 🎴

Home page where the card game was being displayed. Once a card is flipped, the health bar amount is either gained or subtracted, depending on the card that is flipped [random].

When a card is flipped, I could intercept the POST request being used in order to determine three different values and their variables: current_health, attack_power, & operator. Playing around with the different variables, I noticed that the operator value could be manipulated:
Moving the attack further, I was given the python code used to generate these values and variables. Quite a ways down the code given below, the variables are defined:
from flask import Blueprint, render_template, request
from application.util import response

web = Blueprint('web', __name__)
api = Blueprint('api', __name__)

@web.route('/')
def index():
return render_template('index.html')

@api.route('/get_health', methods=['POST'])
def count():
if not request.is_json:
return response('Invalid JSON!'), 400

data = request.get_json()

current_health = data.get('current_health')
attack_power = data.get('attack_power')
operator = data.get('operator')

if not current_health or not attack_power or not operator:
return response('All fields are required!'), 400

result = {}
try:
code = compile(f'result = {int(current_health)} {operator} {int(attack_power)}', '<string>', 'exec')
exec(code, result)
return response(result.get('result'))
except:
return response('Something Went Wrong!'), 500
Something interesting is the result variable & the operator variable. The operator variable is left wide open for manipulation without any definition to it. In addition to this, I can leverage the result variable in order to [hopefully] read files on the server. Messing with some options, I was able to manipulate the operator variable to receive a null message value:
Now, how do I get out of this sandbox? Viewing hacktricks methods and digging deeper into how Werkzeug works, there is a way to open and then read the contents of a file, shown here. Here is the attempt to grab the flag:
FLAG = HTB{c0d3_1nj3ct10ns_4r3_Gr3at!!}

Web Challenges

Spookifier πŸ‘»

Upon opening the website to the main page, there is an input field where you can type in string and it will re-write the string in different fonts.

Capturing the input field that re-writes the string to different fonts, we are presented with the following burp suite request and response:
Viewing different Python Web Testing methods here, I was presented with the SSTI method, or Server Side Template Injection. Here is the methodology to follow when testing for SSTI:
Going through the steps, one-by-one, here are the results:
This is indicative that the template being used is Mako. With this knowledge, I used the ${-input command here-} method in combination with escaping the python sandbox to retrieve the flag:
FLAG = HTB{t3mpl4t3_1nj3ct10n_1s_$p00ky!}

Web Challenges

Juggling Facts 🀹

Right away, I am presented with a simple website with three different options: Spooky Facts, Not So Spooky Facts, & Secret Facts. Without admin access, or local access, I am unable to view the Secret Facts.

Attempting to click the Secret Facts button, we are presented with the Secrets can only be accessed by admin message. Let's go ahead and capture the action of clicking on the Secret Facts button with Burp Suite:
One major thing that caught my eye is that the application is using a content type of JSON. This is very interesting and now makes sense as to why the title of this challenge is Juggling facts. The reason why I say that is explained here, and can be shown in the PHP code given in the challenge, displayed below:
<?php

class IndexController extends Controller
{
public function __construct()
{
parent::__construct();
}

public function index($router)
{
$router->view('index');
}

public function getfacts($router)
{
$jsondata = json_decode(file_get_contents('php://input'), true);

if ( empty($jsondata) || !array_key_exists('type', $jsondata))
{
return $router->jsonify(['message' => 'Insufficient parameters!']);
}

if ($jsondata['type'] === 'secrets' && $_SERVER['REMOTE_ADDR'] !== '127.0.0.1')
{
return $router->jsonify(['message' => 'Currently this type can be only accessed through localhost!']);
}

switch ($jsondata['type'])
{
case 'secrets':
return $router->jsonify([
'facts' => $this->facts->get_facts('secrets')
]);

case 'spooky':
return $router->jsonify([
'facts' => $this->facts->get_facts('spooky')
]);

case 'not_spooky':
return $router->jsonify([
'facts' => $this->facts->get_facts('not_spooky')
]);

default:
return $router->jsonify([
'message' => 'Invalid type!'
]);
}
}
}
Further towards the middle-top portion of the PHP code above, there is the json_decode() function, which is sometimes a good indicator that the code may be susceptible to type juggling. For example, and shown above in the POST request being captured in Burp Suite, the type is looking for a string called secrets. If I change the string [secrets] to, let's say the boolean true, it will most likely accept that data type. And it does, which is shown below!
FLAG = HTB{sw1tch_stat3m3nts_4r3_vuln3r4bl3!!!}

Pwn Challenges

Pumpkin Stand πŸŽƒ

For this Pwn Challenge, I was presented with a program where you could buy either a Shovel for 1337 pumpcoins OR a Laser for 9999 pumpcoins. I was given exactly 1337 pumpcoins and buying a shovel dropped my pumpcoins amount to exactly 0. After playing around with different integers, I was able to manipulate the pumpcoin value that I possess to a negative value of -20710 when I entered in a large number of just 1's. This made me realize that the program may be vulnerable to an integer overflow, therefore I could somehow get that Laser without having the correct amount. Here's the process I followed below:
β”Œβ”€β”€(rootπŸ’€kali)-[~/Downloads]
└─# nc 139.59.167.169 32160

                                          ##&
                                        (#&&
                                       ##&&
                                 ,*.  #%%&  .*,
                      .&@@@@#@@@&@@@@@@@@@@@@&@@&@#@@@@@@(
                    /@@@@&@&@@@@@@@@@&&&&&&&@@@@@@@@@@@&@@@@,
                   @@@@@@@@@@@@@&@&&&&&&&&&&&&&@&@@@@@@&@@@@@@
                 #&@@@@@@@@@@@@@@&&&&&&&&&&&&&&&#@@@@@@@@@@@@@@,
                .@@@@@#@@@@@@@@#&&&&&&&&&&&&&&&&&#@@@@@@@@@@@@@&
                &@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@
                @@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&&@@@@@@@@@&@@@@@
                @@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@
                @@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@@
                .@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@
                 (@@@@@@@@@@@@@@&&&&&&&&&&&&&&&&&@@@@@@@@@@@@@@.
                   @@@@@@@@@@@@@@&&&&&&&&&&&&&&&@@@@@@@@@@@@@@
                    ,@@@@@@@@@@@@@&&&&&&&&&&&&&@@@@@@@@@@@@@
                       @@@@@@@@@@@@@&&&&&&&&&@@@@@@@@@@@@/

Current pumpcoins: [1337]

Items: 

1. Shovel  (1337 p.c.)
2. Laser   (9999 p.c.)

>> 111111111111111111111111111111111

How many do you want?

>> 1

Current pumpcoins: [-20710]


[-] Not enough pumpcoins for this!


Current pumpcoins: [-20710]

Items: 

1. Shovel  (1337 p.c.)
2. Laser   (9999 p.c.)

>> 1111111111111111111111111111111

How many do you want?

>> 1

Congratulations, here is the code to get your laser:

HTB{1nt3g3R_0v3rfl0w_101_0r_0v3R_9000!}
FLAG: HTB{1nt3g3R_0v3rfl0w_101_0r_0v3R_9000!}

Reversing Challenges

Cult Meeting 🀝

After downloading the file given to us for this challenge, there a shell script that could be executed, called meeting. After running the strings command on this file, I could see something secretive:
β”Œβ”€β”€(rootπŸ’€kali)-[~/Downloads/rev_cult_meeting]
└─# strings meeting
/lib64/ld-linux-x86-64.so.2
mgUa
puts
stdin
fgets
stdout
system
fwrite
strchr
__cxa_finalize
setvbuf
strcmp
__libc_start_main
libc.so.6
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u/UH
[]A\A]A^A_
[3mYou knock on the door and a panel slides back
[3m A hooded figure looks out at you
"What is the password for this week's meeting?" 
sup3r_s3cr3t_p455w0rd_f0r_u!
[3mThe panel slides closed and the lock clicks
|      | "Welcome inside..." 
/bin/sh
   \/
 \| "That's not our password - call the guards!"
;*3$"
GCC: (Debian 10.2.1-6) 10.2.1 20210110
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.0
__do_global_dtors_aux_fini_array_entry
frame_dummy
__frame_dummy_init_array_entry
main.c
__FRAME_END__
__init_array_end
_DYNAMIC
__init_array_start
__GNU_EH_FRAME_HDR
_GLOBAL_OFFSET_TABLE_
__libc_csu_fini
_ITM_deregisterTMCloneTable
stdout@GLIBC_2.2.5
puts@GLIBC_2.2.5
stdin@GLIBC_2.2.5
_edata
system@GLIBC_2.2.5
strchr@GLIBC_2.2.5
__libc_start_main@GLIBC_2.2.5
fgets@GLIBC_2.2.5
__data_start
strcmp@GLIBC_2.2.5
__gmon_start__
__dso_handle
_IO_stdin_used
__libc_csu_init
__bss_start
main
setvbuf@GLIBC_2.2.5
fwrite@GLIBC_2.2.5
__TMC_END__
_ITM_registerTMCloneTable
__cxa_finalize@GLIBC_2.2.5
.symtab
.strtab
.shstrtab
.interp
.note.gnu.build-id
.note.ABI-tag
.gnu.hash
.dynsym
.dynstr
.gnu.version
.gnu.version_r
.rela.dyn
.rela.plt
.init
.plt.got
.text
.fini
.rodata
.eh_frame_hdr
.eh_frame
.init_array
.fini_array
.dynamic
.got.plt
.data
.bss
.comment
Towards the top of the strings output, I noticed the string sup3r_s3cr3t_p455w0rd_f0r_u!. Doing a little more digging, it looks like when I answer the question, What is the password for this week's meeting?, correctly, I am given a /bin/sh shell on wherever the file is run on. Let's connect to the docker that this challenge is using and enter that correct password when asked:
β”Œβ”€β”€(rootπŸ’€kali)-[~/Downloads/rev_cult_meeting]
└─# nc 139.59.167.169 31234
You knock on the door and a panel slides back
|/πŸ‘οΈ πŸ‘οΈ \| A hooded figure looks out at you
"What is the password for this week's meeting?" sup3r_s3cr3t_p455w0rd_f0r_u!
sup3r_s3cr3t_p455w0rd_f0r_u!
The panel slides closed and the lock clicks
|      | "Welcome inside..." 
/bin/sh: 0: can't access tty; job control turned off
$ cat flag.txt
cat flag.txt
HTB{1nf1ltr4t1ng_4_cul7_0f_str1ng5}
After receiving the shell on the docker container hosting the challenge, I went ahead and ran the cat command on the flag.txt file to retrieve the flag.
FLAG = HTB{1nf1ltr4t1ng_4_cul7_0f_str1ng5}

Previous
Previous

SMB Relay to Reverse Shells: Initial Attack Vector Evading AV

Next
Next

Buffer Overflow: Exploring Exploit Development