┌──(kali💀kali)-[~]
└─$ sudo nmap -sC -sV -O 10.10.10.185
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 06:d4:89:bf:51:f7:fc:0c:f9:08:5e:97:63:64:8d:ca (RSA)
| 256 11:a6:92:98:ce:35:40:c7:29:09:4f:6c:2d:74:aa:66 (ECDSA)
|_ 256 71:05:99:1f:a8:1b:14:d6:03:85:53:f8:78:8e:cb:88 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Magic Portfolio
|_http-server-header: Apache/2.4.29 (Ubuntu)
Aggressive OS guesses: Linux 4.15 - 5.8 (96%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.5 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (95%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%)
No exact OS matches for host (test conditions non-ideal).
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 42.89 seconds
┌──(kali💀kali)-[~]
└─$ sudo nmap -sU -O 10.10.10.185
68/udp open|filtered dhcpc
631/udp open|filtered ipp
5353/udp open|filtered zeroconf
17468/udp open|filtered unknown
45247/udp open|filtered unknown
Too many fingerprints match this host to give specific OS details
Network Distance: 2 hops
OS detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 1041.34 seconds
The OpenSSH version that is running on port 22 is not associated with any critical vulnerabilities, so it’s unlikely that we gain initial access through this port, unless we find credentials.
┌──(kali💀kali)-[~]
└─$ nikto -h http://10.10.10.185/
+ Server: Apache/2.4.29 (Ubuntu)
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.29 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.
+ /images: IP address found in the 'location' header. The IP is "127.0.1.1". See: https://portswigger.net/kb/issues/00600300_private-ip-addresses-disclosed
+ /images: The web server may reveal its internal or real IP in the Location header via a request to with HTTP/1.0. The value is "127.0.1.1". See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2000-0649
+ /: Web Server returns a valid response with junk HTTP methods which may cause false positives.
+ /: DEBUG HTTP verb may show server debugging information. See: https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-enable-debugging-for-aspnet-applications?view=vs-2017
+ /login.php: Cookie PHPSESSID created without the httponly flag. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
+ /icons/README: Apache default file found. See: https://www.vntweb.co.uk/apache-restricting-access-to-iconsreadme/
+ /login.php: Admin login page/section found.
+ 8046 requests: 0 error(s) and 10 item(s) reported on remote host
+ End Time: 2024-01-11 20:24:45 (GMT-5) (3090 seconds)
OPTION 1:
/upload.php
Right off the bat, I see something that could potentially be very concerning. The upload.php & logout.php pages are internal pages (require authentication) that lead to a 302 redirect when a user attempts to access them. However, the interesting part is the response size. The upload.php response size is much larger than what a normal 302 redirect response would be. So if I had to guess, the PHP script is not properly terminated after user redirection, which could give us unrestricted access to any internal page in the application.
10.10.10.185/upload.php
10.10.10.185/logout.php
We can confirm this using Burp proxy. Visit the upload.php script and intercept the traffic in Burp. As can be seen in the below image, before the request is redirected to the login page, we are served with the upload page.
Now all we have to do is change the HTTP Status Code from “302 Found” to “200 OK” and we get access to the upload page. To have Burp automatically do that for you, visit the Proxy > Options tab. In the Match and Replace section, set the following options. Proxy > Options tab. In the Match and Replace section, set the following options.
Clicking Login leads to /login.php, with a simple login form:
I tried a few basic logins like admin/admin and magic/magic without luck. I tried a basic SQLi login bypass of username ' or 1=1-- -, and it logged me in.
This works because the site must be doing something like:
SELECT * from users where username = '$username' and password = '$password';
So my input makes that:
SELECT * from users where username = '' or 1=1-- -and password = 'admin';
That must satisfy the site’s logic, as it allows me in.
To check the filters on upload, I like to find the POST request where the legitimate image file was uploaded in Burp and send it to repeater. After making sure it successfully submits, I’ll start changing things to see where it break. There are three checks that a site typically employs with this kind of upload:
file extension block/allow lists;
mimetype or Magic bytes for the file must match that of the allowed type(s);
Content-Type header on the image must be image.
Some testing shows that there are at least two filters applied on upload: filename must end with .jpg, .jpeg, or .png and mimetype passes for images.
The second filter can be bypassed by putting PHP code into the middle of a valid image.
I’ll create a copy of my image and name it avatar-mod.png. Then I’ll open it with vim and add a simple PHP webshell to the middle of the file:
Upload PHP Webshell:
On successful login, the browser is redirected to /upload.php:
Looking at the home directories, there’s one user, theseus, and as www-data I can see user.txt but not read it:
Enumerating as www-data didn’t turn out anything obvious, so I went into the web configurations to see what I could find. The site is hosted out of /var/www/Magic:
www-data@ubuntu:/var/www/Magic$ ls
assets db.php5 images index.php login.php logout.php upload.php
db.php5 does have creds for the database:
Database Dump:
Unfortunately, mysql, the binary I would typically use to connect to the local port and interrogate the DB, isn’t on the box. This is a case where having a full PTY shell on the box paid off, because when I typed mys[tab][tab][tab], it gave a list of things that were on the box:
It would have been not that hard to upload Chisel and create a tunnel from my host to the MySQL port (3306) listening on localhost on Magic, but mysqldump jumped out as an alternative. Once I figured out the syntax, it worked like a charm:
Enumeration:
Now we need to escalate our privileges to root. I downloaded the LinEnum script and ran it. It looks like the SUID bit is set for the sysinfo program, which means that the program runs with the privileges of the owner of the file. We can see that it runs the fdisk & lshw programs without specifying the full path. Therefore, we could abuse that to our advantage and have it instead run a malicious fdisk program that we control.
Any enumeration script will highlight SUID binaries, or I can find files owned by root with SUID set using find:
/bin/sysinfo is new to me, so I’ll check it out. It’s also interesting that only members of the users group can execute it, and theseus is the only member of that group:
Running sysinfo with ltrace prints out the calls made outside the binary. There’s a ton of output, but looking through it, there’s a line that jumps out at me:
theseus@magic:/dev/shm# ltrace sysinfo
popen is another way to open a process on Linux. The binary is making a call to fdisk, which is fine, except that it is doing so without specifying the full path. This leave the binary vulnerable to path hijacking.
OPTION1:
I’ll create a reverse shell script in /dev/shm:
This way when we run the sysinfo program, it’ll look for the fdisk program in the tmp directory and execute our reverse shell. Setup a netcat listener to receive the reverse shell: