picoCTF “HEEEEEEERE’S Johnny!”

I’ve kinda been all over the place with CTF stuff lately, there is just so much to learn and at any given time I could go in 5 different directions. There have been a few that I’ve started on and they end up being to difficult for me right now, so I’ve made a draft version of that solution with what I’ve learned along the way. One of them is how shellcode works which has been eye opening – I knew it from a high level, but getting into the weeds is awesome. So for that one, I’ve documented what I’ve read, watched and learned in addition to the level, but I’m not ready to solve it so I’ve moved on for a little while and the concepts have solidified.

The levels on picoctf aren’t really numbered or anything, so this one is by the tag line. The problem reads like this:

Okay, so we found some important looking files on a linux computer. Maybe they can be used to get a password to the process. Connect with nc 2018shell.picoctf.com 35225. Files can be found here: passwd shadow.

When you run nc to that port, you get a login similar to ssh.

Here’s the contents of the passwd file:

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

And here’s the shadow file:

root:$6$HRMJoyGA$26FIgg6CU0bGUOfqFB0Qo9AE2LRZxG8N3H.3BK8t49wGlYbkFbxVFtGOZqVIq3qQ6k0oetDbn2aVzdhuVQ6US.:17770:0:99999:7:::

I can’t remember when, but if I recall correctly, at one point passwords were hashed in /etc/passwd and were in the second column (where the ‘x’) is now. With the ‘x’ there, it points to the /etc/shadow file. There is a breakdown of the /etc/passwd file structure here.

So we have a username and an encrypted password. Wut do? I guess we can run it through a cracking program. The hint said something about ‘rockyou’ and that was a dead give away. See here.

I’ve messed around with cracking before, but not a lot and the first thing I thought of was hashcat. That didn’t seem to work well. I might have got it to work, but then I remembered “John the Ripper” and looked for that.

Using john was pretty easy.

hellokitty is the password for user root

With this information we can nc to where we connected previously, enter the information and get the flag.

Bingo

OTW Narnia0 -> Narnia1

From what I’m understanding is it run’s the echo command and then runs cat with the previous command as STDIN since no arguments are given. Then that’s piped into the narnia0 executable. Pretty cool!

New set up

I’ve thought about a way to boot my main OS off a thumb drive or something like that so I’d be able to boot if off any PC or laptop (64 bit). It would make it so I could use any resource that I had at the time and pick off where I left off. After doing some digging, I got a solution.

I bought a 1TB M.2 SSD with an enclosure off Amazon. I was easily able to install Linux on it and thought about partitioning it so it’d have Windows and Linux and a NTFS partition for VM’s and storage. I was really paranoid about installing over my main disks MBR, so I took it out while I was testing this just in case something went awry.

It turns out that, after a lot of tinkering, I wasn’t able to boot Windows or multiple partitions. So that was a bust. I wasn’t able to even install Windows onto the USB, so I tried installing it with the SSD installed. After I got it installed, I realized I wasn’t able to remove the internal SSD unless I disassembled more than I wanted to do so that was out.

It turns out that Windows 10 Enterprise has the ability to install on USB’s so I gave that a shot and it worked exactly as I’d expect it to. I then downloaded a few ISO’s and installed various VM’s that I use – like I still am using Linux Mint as a daily driver, but this time it’s installed in a VM. Oh, and as a side note, I’m able to play GTA V on it (inside Windows) so that makes for an awesome bonus 🙂

Kids

Oh man I’ve had quite the adventure over the last week + a few days. Without getting into too much detail, my wife and I were the guardians of 3 kids: 16 y/o girl, 11 y/o boy and 18 month boy. And man, was it eye opening and exhausting to do.

I realized a lot about myself and how I relate to others. I’m excited to have more kids too and need to learn to balance my time better. I’m glad that I was able to be a good influence for them for the short time they were with us (they were family, so I’ll see them again).

I haven’t been able to get any personal projects done and it took the whole weekend to catch back up to where I wanted to be with cleaning, etc. One thing I did get done was booted a copy of Windows from a USB M2 drive. Basically, I can take it anywhere I want and boot off of it and the nicer thing is that I loaded up VMware with a handful of VM’s that I would normally run.

I originally wanted to run Linux Mint natively, but after some consideration and troubleshooting, I felt that it would accomplish the same thing by running Windows 10 and then virtualizing the OS’s I wanted to use. For fun, I downloaded GTA5 again and got to relax and play that.

I haven’t gotten everything exactly how I want it, but I like to so far. One OS I wasn’t able to get working was Sigint, it’s like kali, but more focused on signal intelligence. It seems pretty sweet and I’d like to get some hardware so I can play with it more down the road.

GDB + progress

I found out some information that had stumped me for a while. I thought that I had found a solution for narnia0, but it turns out that gdb can’t be used for priv esc, as least as far as root is concerned. I am getting a shell, but it’s as the same user I am. I think that since I’m running the program inside of gdb, it’s keeping the same user and spawning a shell that way. Oh well. I feel like I’ve learned a lot about gdb and now wish that I’d learned more assembly.

I’ve been playing with running the program and throwing random input values at it. I realized it changed which is what I’m needing to change.

Making progress. I got it to take the 0xdeadbeef value, but it’s not doing what I would expect again.

Narnia0

Since I passed the last level in leviathan, I thought I’d take a crack at Narnia. I spent some time on it and I’ll post the screenshots, but I wasn’t able to solve it yet.

The code is included and basically if a pre-set value equals something else, then (from what I can gather), you’ll get a new shell. I loaded it up into gdb, set the layout asm and layout regs option

What I did for this one is locate the part of code that compares something to 0xdeadbeef. The line after that jumps to another part if they are not equal. It gave me a shell, but I was still narnia0

For this one I set the instruction pointer to a part of the code to begin executing. That got me a shell too. I might want to print out or copy the code and go through it more thoroughly because I must be missing something. BUT if I can get the debugger to jump to a specific part of code, I can bypass the comparison and spawn the shell. But the shell is being spawned, so it might be in the setreuid part.

After some trial and error, I was able to set what I think to 0xdeadbeef (used set *(char*)0x8048565=0xde (then incremented the last 2 digits to 0xad, etc). I thought I had these backwards, but I was looking at 62-65 and setting 65 to ef so I thought it was backwards. Anyway, got a shell here, but it wasn’t elevated either.

In doing some digging here here and here I learned how to look at memory values, how to set a memory value. The way that I’m doing it is probably not that efficient and after some troubleshooting it’s backwards (but then again it’s pushed onto the stack so it comes off in a LIFO order).

I know a lot of people probably just look for the answer which is fine, but what I feel you miss is the exploration and journey of learning along the way. I’ll admit, I have looked up some hints, and I’ve learned two things:

  • I was on the right track which is reassuring
  • Most other write ups are pretty straight to the point and don’t offer an in depth walk through. There have been a couple that I’ve stumbled across, but for the most part it’s two screenshots or a line or two of code and that’s it. Either they are super good at this and don’t need the validation or are copying the end result from other solutions they’ve looked up.

All in all, this has been fun, learningful and challenging so far. And based on the notes on the website it’s difficulty is 2/10… yikes.

OTW Leviathan 6 -> 7

This one was pretty easy. Figure out the 4 digit combo on the program. No biggie, right?

So I started off with an initial version of a script, but this was the one that I settled on.

for x in {0000..9999}; do /home/leviathan6/leviathan6 $x >> output.txt; sleep .01s; done

I had a couple versions, one to display the output as it scrolled along with the combo it was on, but that got a little too mind numbing to look at. So why not put the output to a text file and look at it when it’s done?

The text file was basically like after line after line of the word “Wrong”, so all I thought I’d have to do was to grep -v “Wrong” and get the password. But that was an incorrect assumption. Since this was an escalation exercise, it would give me an escalated shell once I got the right combination.

What I noticed was that the script would take forever to run. Way longer than I thought it would. And the file wasn’t getting any bigger. Weird.

So what I thought to do was to connect with another terminal and look at the output (previously I was using CTRL^Z and thought that doing that might be messing with the script somehow). I never found any word besides “Wrong” which isn’t what I expected, so I checked the lines in the file. The number of lines stopped going up, so that was interesting. Since each word was on a new line I had a rough idea of which one it sopped on. So I tried that and ended up getting the combination that way.

It turned out that the script would get the right combo and get dropped into a shell, so it was waiting to get back out to keep brute forcing thus waiting indefinitely. Overall a pretty easy level I’d say.

*** UPDATE ***

Since I was logged in as leviathan7 I thought I’d initially check out the level.

Oops

OTV Leviathan 5 -> 6 + BONUS

I keep over thinking things.

But this time it paid off 🙂

This level was pretty much like the old ones. Let’s dive into it.

ltrace ./leviathan5 | less
objdump -xD ./levianthan5

This is where I spent a good amount of time. That and gdb. The upside is I’ve learned a lot of stuff in gdb (gdb -tui, info registers, ni, start, x/s find, etc), but the downside is it didn’t directly help me solve the level. It did help me discover some cool stuff though.

So I searched for the main function with objdump. It looks like goes through the following functions (but I didn’t trace it out, I’m just reading it).

  • main
  • fopen
  • exit
  • fgetc
  • feof
  • puchar
  • fclose
  • getuid
  • setuid
  • unlink

All of those are what I expected. I guess? Except unlink. That’s interesting.

From what I could gather, the file looks for /tmp/file.log, if the file isn’t there it exits. From the ltrace, I could surmise that it tried to open the file as read only. So let’s see what we can do with it.

Bingo

So the leviathan5 program looks for the /tmp/file.log file, if it exists, then it will display it. But if it’s a symlink to another file, then it will display the contents of file it points to – according to its permissions. So there we have it.

The bonus part is something I found out that I was pretty excited to discover. After I solved the level I googled answers to this level to see if anyone had done it before, and as far as I can tell, no one has.

I noticed that there was an unlink function at the end of the program, and noticed that after leviathan5 was run the /tmp/file.log wasn’t there. I wonder if that happens with everyone.

So I logged in with two terminals. One to get up to the point of getting the contents of the file and the other to run the program to actually get the contents of the file. It worked as I expected. Huh. I wonder. So I wrote a quick script and this happened.

oh man someone is getting messed with
while true; do  cat
/tmp/file.log; /home/leviathan5/leviathan5 | grep -v "Cannot
find"; sleep 1s; echo "Do it non stop and do it again";
done

This was a simple script that wait for 1 second, then run the leviathan5 program over and over and over again. I could tell someone was trying to get the file, but I was stopping it. After a bit of tweaking, I settled on something I liked. Here’s a screenshot of how it played out.

Oh man some people are probably annoyed with me

And here’s the code

links=1
files=1
time=0
while true;
do
if [ -L /tmp/file.log ];
then echo "link exists… killing…" && unlink /tmp/file.log && echo "Links killed: $links" && let "links++";
elif [ -f /tmp/file.log ];
then echo "file exists… here it is" && cat /tmp/file.log && rm -f /tmp/file.log && echo "Files killed: $files" && let "files++";
fi
sleep 1s;
let "time++";
if [ "$time" -gt 200 ];
then echo "200 seconds have passed, just letting you know";
time=0;
fi
done;

All in all, this was a fun and challenging level. Just like the previous ones, I seem to look deeper than what I need to do but the upsides are that I learn new things and feel the focus of frustration and I stumbled across a way I could mess with other players.

OTW Leviathan 4 -> 5

This one was easy.


I guess it wants to be converted to text?

Hmmmm maybe not

Or maybe using su isn’t permitted for our user? Lets try.

Yep. leviathan4 cannot use su to become leviathan5. The password was good.

OTW Leviathan 3 -> 4

This one built off of previous ones and seemed a lot easier, although there were some things that threw me for a loop. I could do one screenshot here, but I’ll break it down into chunks.

Initially looking at the program reveals it similar to ones before it.

This is interesting. It’s doing a string compare before asking for input. Weird, but whatever. Then it asks for the password and compares it to ‘snlprintf’. Let’s try that.

Oh cool, that was easy. Wait. I’m still level 3. Hmmm, let’s run it again, without ltrace.

Ok that was too easy.

For some reason, I keep thinking that I’ll need to disassemble the program and learn how to program in assembly in order to deconstruct an algorithm or something. I didn’t show the first little bit I did, where I objdumped the program and looked for things that way. Maybe in a future ctf I’ll have to do that, but not so far.