i take one breath / mint at a time

Leviathan: Lv 1->2

#overthewire #wargames #leviathan #linux #ctf

There is no information given regarding these levels. Upon sshing into Lv1, I found a program called check that according to the file command is:

check: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), > dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux
2.6.32, BuildID[sha1]=c735f6f3a3a94adcad8407cc0fda40496fd765dd, not > stripped

Running ./check gives us a prompt for password: so I tried the only password I currently have (from entering this level) and nothing.

Decided to track down this /lib/ld-linux.so.2 directory mentioned. Tracing all the symbolic links gets us to this file: /lib32/ld-2.24.so. Running the file goes us:

You have invoked ld.so', the helper program for shared library >executables. This program usually lives in the file/lib/ld.so', and >special directives in executable files using ELF shared libraries tell the >system's program loader to load the helper program from this file. This >helper program loads the shared libraries needed by the program >executable, prepares the program to run, and runs it. You may invoke >this helper program directly from the command line to load and run an >ELF executable file; this is like executing that file itself, but always uses >this helper program from the file you specified, instead of the helper >program file specified in the executable file you run. This is mostly of >use for maintainers to test new versions of this helper program; >chances are you did not intend to run this program.

So researching how to analyze Linux binaries gives us a list of commands to explore:

ldd –> print shared object dependencies. Used to run against dynamically linked binary to show its dependent libraries and their paths. Running this on check binary shows:

linux-gate.so.1 (0xf7fd7000)
libc.so.6 => /lib32/libc.so.6 (0xf7e12000)
/lib/ld-linux.so.2 (0xf7fd9000)

Which is info we had already ascertained from following the breadcrumbs. But at least next time, I won't need to follow the breadcrumbs.

ltrace –> displays all the functions that are being called at run time from the library. (Function names, arguments being passed into that function, and what is returned.)

hexdump –> display file contents in ASCII, decimal, hexadecimal, or octal

strings –> print the strings of printable characters in files

readelf –> display information about ELF files

objdump –> reads the binary or executable file and dumps the assembly language instructions on the screen.

strace –> traces system calls aka calls that interface with kernel

nm –> list symbols from objects > if using a binary that was not stripped, you can identify variables, functions, and other valuable info embedded in the binary during compilation

gdb –> GNU debugger: load a program, set breakpoints, analyze memory and CPU register, etc.

But what is relevant here?

Let's try ltrace check. Immediately we get prompted for the password along with information about the function calls behind that prompt:

__libc_start_main(0x804853b, 1, 0xffffd744, 0x8048610 <unfinished ...>
printf("password: ") = 10
getchar(1, 0, 0x65766f6c, 0x646f6700password:

This means that the functions __libc_start_main, printf, and getchar were called in order to run the program up to the password prompt. Entering a password of rioGegei8m gives the following output:

getchar(1, 0, 0x65766f6c, 0x646f6700password: rioGegei8m
) = 114
getchar(1, 0, 0x65766f6c, 0x646f6700) = 105
getchar(1, 0, 0x65766f6c, 0x646f6700) = 111
strcmp("rio", "sex") = -1
puts("Wrong password, Good Bye ..."Wrong password, Good Bye ...
) = 29
+++ exited (status 0) +++

It looks like we used the getchar function for stndin then we called strcmp for matching rio to sex. I'm assuming that only the first three characters of my password attempt was matched because the password is only three characters longs. I will pretend not to judge that the password for here is `sex. Really?

Entering the password into the ./check binary brings us to a shell. Immediately, let's check whoami and echo $0 which tells us that we are levianthan2 and our shell is /bin/sh.

Let's check the leviathan2 home directory. There is a file called printfile that is a setuid regular file with no read permission. Checking permissions show that:

-r-sr-x--- 1 leviathan3 leviathan2 7436 Aug 26 2019 printfile

This file belongs to leviathan3 user and the group leviathan2. The s in the permissions for leviathan3 user means that the setuid bit is set, and the execute bit is set. According to research: “A file with SUID always executes as the user who owns the file, regardless of the user passing the command. But when I try to execute the file, I still get /bin/sh: 31: ./printfile: Permission denied.

Tried to change permissions for

$ chmod u-s printfile
chmod: changing permissions of 'printfile': Operation not permitted

Thinking more about the permissions and checking my own with id:

uid=12002(leviathan2) gid=12001(leviathan1) groups=12001(leviathan1)

Turns out that even though I have managed to set my uid to leviathan2 from running the check binary, I am still in the leviathan group. Let's learn more about the s permissions:

“The setuid bit simply indicates that when running the executable, it will set its permissions to that of the user who created it (owner), instead of setting it to the user who launched it.”

A very, long deep dive time later...

Yeah, I just realized I didn't check the regular ol' etc/leviathan_pass/leviathanLVL file.. and there it was. The password.


Random Notes on New Knowledge

openssl to generate password + salt!

$ openssl passwd -1 "hello world"
$1$Y3FAzTxG$/I/sykzmytIduJwbL4mjo1
$ openssl passwd -1 -salt "my salt" "hello world"
$1$my salt$lY65QUBqL1JO3LEh3ENqe.

The shell escape feature/exploit