ret2xx

随着NX保护的开启,以往直接向栈或者堆上直接注入代码的方式难以发挥效果,攻击者们也提出来相应的方法来绕过保护,目前主要的是ROP(ReturnOrientedProgramming);其主要思想是在栈缓冲区溢出的基础上,利用程序中已有的小片段(gadgets)来改变某些寄存器或者变量的值,从而控制程序的执行流程,所谓gadgets就是以ret结尾的指令序列,通过这些指令序列,我们可以修改某些地址的内容,方便控制程序的执行流程,
之所以称之为ROP,是因为核心在于利用了指令集中的ret指令,改变了指令流的执行顺序。ROP攻击一般得满足如下条件:
1:程序存在溢出,并且可以控制返回地址。
2:可以找到满足条件的gadgets以及相应gadgets的地址。
如果gadgets,每次的地址都是不固定的,那我们就就需要想办法动态获取对应地址了。

ret2text即控制程序本身已有的代码(.text),其实,这种攻击方法是一种笼统的描述,我们控制执行程序已有的代码的时候也可以控制程序执行好几段不相邻的程序已有的代码(也就是gadgets),这就是我们所要说的ROP。

int __cdecl main(int argc,const char **argv,const char **envp)
{
vulnerable_function();
system(echo "Hello World")
return 0;
}

vulnerable_function:

ssize_t vulnerable_function()
{
char buf;//[esp+0h][ebp-88h]
system("echo input:");
return read(0,&buf,0x100u);
}

Read函数存在栈溢出,且存在/bin/sh字符串
思路:覆盖返回地址为system_plt,并根据32位的参数传递规则设置参数/bin/sh。
如何构造payload:
先去padding,覆盖返回地址为system_return,调用c的函数的返回值为地址,这里调用4个C,调用参数;如果程序需要重复触发漏洞的话,可以将函数调用的返回地址改为main函数,这样执行完后,就会连续的触发漏洞。

如何设置rdi指向binsh?
我们可以寻找到gadges,poprdi;return,这样就能将rdi指向/bin/sh,
如果找到pop rdi;ret?
可以使用ropper帮助寻找gadget;

ret2shellcode,即控制程序执行shellcode代码,shellcode指的是用于完成某个功能的汇编代码,常见的功能主要是获取目标系统的shell,已办理来说,shellcode需要我们自己填充,这其实是另外一种典型的利用方法,几次是我们需要自己去填充一些可执行代码。

ssize_vulnerable_function()
{
char buf;// [esp_0h][ebp-88h]
printf("What is this:%p?\n",&buf);
return read(0,&buf,0x100u);
}

程序栈可执行,泄露buf地址,read函数存在栈溢出,
思路:在buf地址处写入shellcode,覆盖ret地址为buf。

ret2syscall,即控制程序执行系统调用,获取shell。

int overflow()
{
char v1; //[esp+Ch] [ebp-Ch]
return gets(&v1);
}

get()函数存在栈溢出,且没有长度限制,直到读到0x0A。但是程序中没有backdoor,system函数,/bin/sh字符串。
思路:由于是静态贬义程序会存在init 0x80,可以使用终端调用系统函数
1:read(0,bss+0x100,8)读入/bin/sh
2:execve(bss+0x100,0,0)getshell

为了实现上面的调用需要寻找5个gadget
1:int 0x80;ret来触发终端的系统调用。
2:pop eax;ret来设置eax寄存器
3:pop ebx;ret
4:pop ecx;ret
5: pop edx;ret

对于静态生成的程序可以使用ropper和ROPgadget来直接生成ropchain
ropper --file innidy_rop --chain execveropper --file inndy_rop --chain execve ROPgadget --binary inndy_rop --ropchain

ret2libc即控制函数的执行libc中的函数,通常是返回至某个函数的plt处或者函数的具体位置(即函数对应的got表项的内容)。一般情况下,我们会选择执行system(“/bin/sh”),故而此时我们需要知道system函数的地址。

思路:构造rop调用write(1,xx_got,4),泄露libc基址并再次调用Main函数,(例:前面执行完read函数,后面的read_got能得到read函数的真实地址)。·
根据libc地址得到system和/bin/sh字符串地址
再次利用漏洞构造rop调用system(‘/bin/sh’)

ret2csu:
在64位程序中,函数的前6个参数是通过寄存器传递的,但是大多数时间,我们很难找到每一个寄存器对应的gadgets。这时候,我们可以利用x64下的___libc_csu_init中的gadgets。这个函数是用来对Libc进行初始化操作的,而一般的程序都会调用libc函数,所以这个函数一定会存在。

假设我们现在要利用csu调用write(1,write_got,8)来达到泄露libc,该如何布置rop链?
第一步:为了使用call来调用write需要r12+rbx*8=write_got。
2:设置参数:edi=r13d=1; rsi=r14=write_got; rdx=r15=8,这样就能输出write_got的地址值,
3: 为了使jnz不跳转,继续向=下执行(为了可以继续构造rop链),需要rbx+1=rbp
rbx=0
rbp=1
r12=write_got
步骤2:第二次执行gadget1会执行add rsp,38h。
当我们需要构造rop覆盖分会地址时需要先填充0x38的padding

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值