The Necromancer: 1 is a challenge posted on VulnHub created by Xerubus. This is a write-up of my experience solving this awesome CTF challenge.
With my Attack Machine (Kali Linux) and Victim Machine (Necromancer) set up and running, I decided to get down to solving this challenge.
Read more about my set up and environment here
I decided to start my journey with the classic netdiscover
. My Kali Linux VM has an IP of 192.168.56.102
according to ifconfig
. With this knowledge and the fact that I set up host-only networking for my VMs, I decided to run the following command: netdiscover -r 192.168.56.0/24
.
Now we can see that the IP of the victim machine is 192.168.56.101
. Great!
The next step involves finding a way to communicate with the Victim Machine. I decided to use the trusty nmap
with an aim to find any open ports on the machine.
Let’s start with the common ports: nmap -F 192.168.56.101
Hmm, that’s strange. No open ports. What if some obscure port is open? The only way is to scan every port from 1-65535: nmap -p- 192.168.56.101
Gee, still nothing. I decided to explore other avenues. There just had to be either some channel of communication or existing communication between the machines.
With this is mind, I decided to fire up Wireshark and capture network traffic on eth0
.
The packet capture on Wireshark showed us traffic from the Victim Machine (192.168.56.101
) to our Attack Machine (192.168.56.102
) to destination port 4444
.
Okay, there’s some communication going on. But what exactly? I needed a way to listen for the traffic to Kali Linux on port 4444
. I decided to go with netcat: nc -lvp 4444
Boom! We got something… This looks like Base 64 encoding to me. I tried to decode it using the terminal itself with the handy base64 -d
command: echo <message> | base64 -d
Yes! The Necromancer has a message for us! If we read it carefully, we can pick up 2 important points:
e6078b9b1aac915d11b9fd59791030bf
Chant the string of flag1 - u666
Easy, the string of flag1
must refer to the flag and u666
must refer to port 666
via UDP (User Datagram Protocol). I decided to continue using netcat: echo e6078b9b1aac915d11b9fd59791030bf | nc -u 192.168.56.101 666
Oh boy, that never worked. Try in a different tongue? What do you mean, Necromancer?
This string wasn’t Base 64 encoding. It looked like a hash to me. With the help of my trusty Hash Analyzer, it was clear that the flag was an MD5 or MD4 hash. Okay, we need to decrypt the hash. No big deal.
Well, I was not really going to decrypt it. Instead, I went over to my trusted MD5 online website in hopes of finding the matching hash in their database.
Yay! The un-hashed string is opensesame
.
I proceeded to send this to the Necromancer using netcat: echo opensesame | nc -u 192.168.56.101 666
Awesome. We got the second flag. Flag 2 is c39cd4df8f2e35d20d92c2e44de5f7c6
.
But wait, there’s another clue hidden in the message - Squinting your eyes from the light coming from the object, you can see the formation looks like the number 80.
Almost instantly I thought of HTTP (port 80
). Did the message mean that port 80 is now open for traffic? The last line in the message increased my confidence: 666 is closed.
I decided to verify my hunch using nmap
. But this time I chose to be specific with port 80
: nmap -p 80 192.168.56.101
Yes, port 80
was open for business. Time to hit the browser!
First things first, I checked the source code (CTRL + U
). It did not reveal anything exciting except: <img src="/pics/pileoffeathers.jpg">
Hmm, an image file. I decided to download this image and dissect. Who knows what treasures could be hidden…
I decided to start with the file
command: file pileoffeathers.jpg
Nothing exciting here. I decided to try again with the binwalk
tool: binwalk pileoffeathers.jpg
Oh my! I can see the words Zip archive data
. Some more details follow:
121
125
feathers.txt
Obviously, I proceeded with unzipping this pseudo image.
Let’s have a look at feathers.txt
Once again, Base 64: ZmxhZzN7OWFkM2Y2MmRiN2I5MWMyOGI2ODEzNzAwMDM5NDYzOWZ9IC0gQ3Jvc3MgdGhlIGNoYXNtIGF0IC9hbWFnaWNicmlkZ2VhcHBlYXJzYXR0aGVjaGFzbQ==
Decoding this Base 64 string gave me: flag3{9ad3f62db7b91c28b68137000394639f} - Cross the chasm at /amagicbridgeappearsatthechasm
Woo! We got the third flag. Flag 3 is 9ad3f62db7b91c28b68137000394639f
and a hint on how to proceed. Cross the chasm at /amagicbridgeappearsatthechasm
must refer to a URL. Back to the browser with http://192.168.56.101/amagicbridgeappearsatthechasm
You know the drill. Look at source code, download the image, binwalk
it and beat the Necromancer. Only, there was absolutely nothing! Did the Necromancer get the best of me?
In an attempt to beat the Necromancer, I decided to run the trust dirb
(a web content scanner). You know… in case a hidden URL is revealed or something.
There appears to be nothing apart from index.html
. I did not bother trying with another wordlist. Back to the message…
There must be a magical item that could protect you from the necromancer's spell.
Hmm, I never really knew much about Necromancers or magical items that could defeat them. Google to the rescue!
With lots of reading, trial and error, and plain guessing… I came up with the word talisman
.
What’s a talisman? According to Google, an object, typically an inscribed ring or stone, that is thought to have magic powers and to bring good luck.
Okay, we have the magical item that could protect us from the necromancer’s spell. How do I use it?
Practically speaking, there is no form or inputs on the HTML web page.
Hence, I decided to manipulate the URL: http://192.168.56.101/amagicbridgeappearsatthechasm/talisman
Well look what we have here! A binary file!
After setting the right permissions (chmod +x talisman
), I ran it…
Okay. So, the program demanded user input. Do you want to wear the talisman?
I typed yes
and the program exited with the message: Nothing happens. I tried other strings and words but nothing worked. Time to reverse engineer this program…
In my past experiences with binary exploitation, I have used gdb
. I decided to fire up gdb
with the talisman
program: gdb ./talisman
Now, I wanted to have a look at the main()
function which is the entry point of any program. Inside gdb
, I typed: disassemble main
A quick read through the Assembly code reveals a function call to the function wearTalisman()
. Typically, I have seen programs which have some if-conditional
as follows:
However, in the above Assembly code, I could not see any CMP
(compare) or JMP
(jump) Assembly instructions. I concluded that there is no checking user input.
What next? I decided to review the functions within the program. This can be done within gdb
using: info functions
Interesting. The function chantToBreakSpell()
looks like it might be the solution. Now, if main()
is making a call to wearTalisman()
… how about we break at main()
and simply call chantToBreakSpell()
instead?
I decided to set a breakpoint on main()
as follows: break main
Then, I ran the program with the command: run
Okay, it hit the breakpoint. The program is at main()
. I tried making a call to chantToBreakSpell()
as follows: jump chantToBreakSpell
Wow! We got the fourth flag. Flag 4 is ea50536158db50247e110a6c89fcf3d3
. There’s more… a hint to proceed… Chant these words at u31337
.
I decided to work with my trusty netcat once again: echo ea50536158db50247e110a6c89fcf3d3 | nc -u 192.168.56.101 31337
MD5? Again? Back to my trusted MD5 online website in hopes of finding the matching hash in their database.
Found it - blackmagic
Another flag! We got the fifth flag. Flag 5 is 0766c36577af58e15545f099a3b15e60
. We also got a clue on how to proceed:
Above them, a word etched in blood on the wall.
/thenecromancerwillabsorbyoursoul
Based on what we saw earlier, I guess that this belongs in a URL as follows: http://192.168.56.101/thenecromancerwillabsorbyoursoul
Wait… there’s more if you scroll down…
We got the sixth flag! Flag 6 is b1c3ed8f1db4258e4dcb0ce565f6dc03
.
Reading through the message reveals 2 important points:
It's the necromancer!
there is a reference link in the word necromancer
to
http://192.168.56.101/thenecromancerwillabsorbyoursoul/necromancer
which will download a binary file.Looking closer at the skill, you can see u161 engraved into the forehead.
there is a hint that some traffic is passing through UDP port 161
.I decided to start with the necromancer
binary file. I changed the permission to executable using chmod +x necromancer
and ran it using: ./necromancer
Uh oh! Not a binary? What?
Bzip2 compression! Not a problem. Easy enough to decompress it with: bzip2 -d necromancer
Okay, we now have necromancer.out
. Let’s see what is inside…
Maybe the Necromancer can read that. I couldn’t!
I decided to investigate the file further using the file
command: file necromancer.out
A POSIX tar archive, huh? Naturally, I unzipped it to find a .cap
file.
I decided to open necromancer.cap
with my trusty friend, Wireshark using: wireshark necromancer.cap
Looking at the packet capture, I understood that it was Wi-Fi traffic. With a .cap
file and the knowledge that Wi-Fi traffic exists within it, I decided to go with my trusty tool - aircrack-ng
with hopes of breaking the password.
Since we are cracking passwords, we need a proper wordlist. I decided to go with the infamous rockyou.txt
. My only concern with rockyou.txt
is that it is huge and the brute-force could take ages.
I proceeded with aircrack-ng
as follows: aircrack-ng -w /usr/share/wordlists/rockyou.txt necromancer.cap
Well Necromancer, death2all
… really?
I got the password but was unsure what exactly to do with it. All this while, we have ignored the second clue -Looking closer at the skill, you can see u161 engraved into the forehead.
Something about u161
bothered me. I tried communicating the password to that port as follows: echo death2all | nc -u 192.168.56.101 161
… but got nothing!
It was then I decided to run nmap
again… just for the heck of it as follows: nmap -p 161 192.168.56.101
That’s when it hit me. I was dealing with SNMP
.
I am going to admit. I did not know much about SNMP
and its relevance to CTFs so I spent some time reading snmp-check
and snmpwalk
which are tools provided in Kali Linux. I decided to give snmp-check
a try with different community strings…
Oho, death2all
was the community string after all!
The message tells us us that the door is locked and it must be unlocked. There is a unique word - death2allrw
. Is that another community string?
Jackpot!
That’s a lot of information. I felt like a kid inside a candy shop…
Not for long though. The message still haunted me - The door is Locked. If you choose to defeat me, the door must be Unlocked.
How can I unlock the door, Necromancer? Time to Google!
With lots of Googling and reading (this, this, and this), I learnt about SNMP
and MIB
. Basically, there is a way to change information displayed in the MIB
using the snmpset
command. However, this requires something called ObjectID
or OID
of the field we wish to change.
In the above screenshot, I figured that we needed to change the Location
field from Locked
to Unlocked
. But I could not spot its OID
. Hence, I decided to go with snmpwalk
instead as follows: snmpwalk -c death2allrw 192.168.56.101
This gave me an error: snmpwalk: No securityName specified
With some Googling, I found this and tried with a different version: snmpwalk -v 2c -c death2allrw 192.168.56.101
Got it! The OID
for the Location
field is iso.3.6.1.2.1.1.6.0
. Time to use snmpset
as follows: snmpset -v 2c -c death2allrw 192.168.56.101 .1.3.6.1.2.1.1.6.0 s Unlocked
Awesome! That command took tons of Googling and trial-and-error.
Now that we unlocked the door, I decided to check the SNMP
information again using snmp-check
:
Finally, the seventh flag! Flag 7 is 9e5494108d10bbd5f9e7ae52239546c4
and a clue - t22
which obviously refers to TCP port 22
. Hello SSH, my old friend!
With all the excitement, the first thing I tried was to log in to SSH as root
with the flag as the password…
Obviously, this never worked.
I decided that I needed to figure out a username for my SSH adventure. After some more trial and error, I decided the brute-force was the way to go. Hello rockyou.txt
!
I went with my trusty hydra
to brute-force the username as follows: hydra -L /usr/share/wordlists/rockyou.txt -p 9e5494108d10bbd5f9e7ae52239546c4 192.168.56.101 ssh
While waiting for the brute-force to finish, it hit me that the flag is an MD5 string. So I went back to my trusted MD5 online website in hopes of finding the matching hash in their database and I did….
9e5494108d10bbd5f9e7ae52239546c4 = demonslayer
Here goes hydra
: hydra -L /usr/share/wordlists/rockyou.txt -p demonslayer 192.168.56.101 ssh
Without much luck on the username… I decided that I was probably doing it wrong. Maybe demonslayer
is the username?
I decided to fire up hydra
again with rockyou.txt
as my wordlist as follows: hydra -l demonslayer -P /usr/share/wordlists/rockyou.txt 192.168.56.101 ssh
Got it! 12345678
… really demonslayer
? Time to SSH!
I have to say… it was a proud moment for me!
So… whoami
? Well, I am demonslayer
with a mission to escalate my privileges and get root
.
First things first… I decided to run an ls -l
in my current directory:
The ls -l
revealed flag8.txt
and a peek at its contents revealed something interesting - Defend yourself! Counter attack the Necromancer's spells at u777!
I decided to go with netcat as follows: nc -u localhost 777
I messed up! Turns out the Necromancer is super serious because I couldn’t even connect to SNMP anymore. Time to go backwards…
After a painful trip backwards and running way too many old commands, I decided to give the Q and A session another try. This time, I kept Google really handy!
Got it! A close call there but boy was that hard!
We can see the tenth flag. Flag 10 is 8dc6486d2c63cafcdc6efbba2be98ee4
.
Back to trying privilege escalation… My Linux senses were tingling. One of the most common things I try is checking my sudo
privileges as a user. This is done as follows: sudo -l
Wow! Are you seeing what I am seeing? (ALL) NOPASSWD: /bin/cat /root/flag11.txt
This means that we can run /bin/cat /root/flag11.txt
as root
… and that’s what I did next: sudo cat /root/flag11.txt
Finally! We got the eleventh and final flag. Flag 11 is 42c35828545b926e79a36493938ab1b1
For what it was worth… flag 11 decrypts to hackergod
.
That was amazing. Seriously, I had a blast and learnt a plethora of things by solving this challenge. I also learnt a little bit about the Necromancer. He’s a scary guy.
I have to admit that certain parts (like the SNMP
) were challenging for me because of my lack of experience with snmpwalk
, snmp-check
, and snmpset
but it was a great learning experience.
I respect Xerubus for helping me keep my sanity with the brute-force parts. The wordlist rockyou.txt
is pretty long and agonizing to wait until completion. Passwords like 12345678
take seconds to find!