Leviathan: Lv 1->2
#overthewire #wargames #leviathan #linux #ctf
There is no information given regarding these levels. Upon ssh
ing 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
- check
sudo
privileges:sudo -l
- use
sudo
to go into a command to check if current user can execute any commands without password entry - if so, run that with
sudo
, for example:sudo /usr/bin/man man
to run theman
command onman
withsudo
- then drop into a bash shell with
!/bin/bash