picoCTF Recovering From the Snap

This one was fun. I hadn’t ever played around with recovering deleted files.

There used to be a bunch of animals here, what did Dr. Xernon do to them?

This level starts off with the file animals.dd.

A few things I checked on. It looks like this is a disk image. I mounted the image and there are 4 files, but nothing that would indicate a flag or anything.

initial cut at the file

I knew that .dd files were used in disk images, and a quick search lead me to some software called ‘testdisk’

Huh ok, let’s try ‘P’
This looks promising
arrowed down, then will press ‘c’

From here you select the directory you want to save the recovered file to.

This is the flag file

Pretty cool.

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!

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.

OTW Leviathan 2 -> 3

Let me explain what’s going on here.

You have the files listed above, each with a line of text. One is “0ne” and two is “tw0” (with zeros). The file named “one two” contains the words “one two” which is the same name as the two files. echo you cat “one two” you get the contents of the file “one two”, but when you run the program and pass “one two” into it, it cats each of the files individually. It’ll even do the same thing with three files. So I looks like it actually does pass what you type in as a string, passes that to cat. How can this be exploited?

What this does is exploits the programs execution of cat with elevated permissions, but it looks like it only checks for the permissions the first time. Let’s check.

Huh, looks like I was wrong. From this, I’m guessing then, that it checks to see if the file “three two one” is owned by leviathan2 (which it is), then passes “three two one” as an argument and cats it. Pretty cool.