首页 > 其他分享 >在一个简单的pwn题目中探究执行系统调用前堆栈的对齐问题

在一个简单的pwn题目中探究执行系统调用前堆栈的对齐问题

时间:2023-11-02 19:56:19浏览次数:33  
标签:0000000140001584 text rbp 堆栈 地址 0000000140001540 pwn 对齐 rsp

题目介绍:在输入AAAAAAAAAAAAAAAAAAAAAAAAA后,程序会打开一个shell,这是为什么?字符串中的A能否更换为@
1.程序接收输入AAAAAAAAAAAAAAAAAAAAAAAAA 获得shell的原理:

.text:0000000140001584                 public vuln
.text:0000000140001584 vuln            proc near               ; CODE XREF: main+D↑p
.text:0000000140001584                                         ; DATA XREF: .pdata:000000014000F078↓o ...
.text:0000000140001584
.text:0000000140001584 DstBuf          = byte ptr -10h
.text:0000000140001584
.text:0000000140001584                 push    rbp
.text:0000000140001585                 mov     rbp, rsp
.text:0000000140001588                 sub     rsp, 30h
.text:000000014000158C                 lea     rax, [rbp+DstBuf]
.text:0000000140001590                 mov     r8d, 19h        ; MaxCharCount
.text:0000000140001596                 mov     rdx, rax        ; DstBuf
.text:0000000140001599                 mov     ecx, 0          ; FileHandle
.text:000000014000159E                 call    read
.text:00000001400015A3                 nop
.text:00000001400015A4                 add     rsp, 30h
.text:00000001400015A8                 pop     rbp
.text:00000001400015A9                 retn
.text:00000001400015A9 vuln            endp

可以看到写入的目标地址为rbp-10h处,read读入的字节数为19h,可以猜到read的输入覆盖了目标地址的16字节后,又覆盖了rbp的8字节,最后覆盖了地址的最低地址字节,由于此处地址是小端序,覆盖了地址的最低位,不难猜到,返回地址被修改到了原返回地址的附近的代码中,且根据输入AAAAAAAAAAAAAAAAAAAAAAAAA 和调用此函数的main函数代码对应的地址,可以推出地址被修改为0x0000000140001541附近的代码。

.text:0000000140001540                 public backd00r
.text:0000000140001540 backd00r        proc near               ; DATA XREF: .pdata:000000014000F06C↓o
.text:0000000140001540                 push    rbp
.text:0000000140001541                 mov     rbp, rsp
.text:0000000140001544                 sub     rsp, 20h
.text:0000000140001548                 lea     rcx, Buffer     ; "getshell"
.text:000000014000154F                 call    puts
.text:0000000140001554                 lea     rcx, Command    ; "C:\\Windows\\system32\\cmd.exe"
.text:000000014000155B                 call    system
.text:0000000140001560                 nop
.text:0000000140001561                 add     rsp, 20h
.text:0000000140001565                 pop     rbp
.text:0000000140001566                 retn
.text:0000000140001566 backd00r        endp

可以看到,该地址确实在一个名为backd00r的函数中,该函数执行系统调用获取了shell。

2.程序接收的输入中A能否更换为@

A对应ascii码为41,而@对应ascii码为40,更换后,ret指令将跳到0x0000000140001540处,多压栈了一次rbp,感觉上是可行的,因为即使堆栈不平衡应该也不会影响当前函数的调用,事实上前面的puts函数也确实能正常执行输出getshell字符串。但system却不能正常执行,使用xdbg动态调试,可以看到是在地址为0x7FFA3A437F64的语句:movaps xmmword ptr ss:[rsp+40],xmm6 处报访存异常。但不从push rbp开始时却没有这个问题。从这条语句开始分析,这条语句的意思是将xmm6浮点数寄存器保存的16字节内容存入栈中的地址,这时就不难想到是否是因为没有对齐的原因,查看此时栈中的地址,最低的16进制数不为0,确实没有对齐。

image-20230930132547743

为了验证猜想,使用IDA将back00r函数修改如下,连续压入两个rbp,此时应该能对齐,此时用@代替A,确实能执行成功。

.text:0000000140001540
.text:0000000140001540                 public backd00r
.text:0000000140001540 backd00r:                               ; DATA XREF: .pdata:000000014000F06C↓o
.text:0000000140001540                 push    rbp
.text:0000000140001541                 push    rbp
.text:0000000140001542                 nop
.text:0000000140001543                 nop
.text:0000000140001544                 sub     rsp, 20h
.text:0000000140001548                 lea     rcx, Buffer     ; "getshell"
.text:000000014000154F                 call    puts
.text:0000000140001554                 lea     rcx, Command    ; "C:\\Windows\\system32\\cmd.exe"
.text:000000014000155B                 call    system
.text:0000000140001560                 nop
.text:0000000140001561                 add     rsp, 20h
.text:0000000140001565                 pop     rsi
.text:0000000140001566                 retn

因此,使用@在此处不能代替A,虽然在执行系统调用时不会因为堆栈未平衡报错,但会在内核中一个mov语句拷贝16字节数据时因为地址未对齐而产生访存异常。

标签:0000000140001584,text,rbp,堆栈,地址,0000000140001540,pwn,对齐,rsp
From: https://www.cnblogs.com/jiasun/p/17806157.html

相关文章

  • cmake打印堆栈
    设置参数add_compile_options(-g)add_compile_options(-O0)add_compile_options(-no-pie)set(CMAKE_C_FLAGS"${CMAKE_C_FLAGS}-O0-g0")set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}-O0-g0")set(CMAKE_CXX_FLAGS"${CMAKE_CXX_FLAGS}-std=c++11......
  • 2023 SHCTF-校外赛道 PWN WP
    WEEK1nc连接靶机直接梭hardnc同样是nc直接连,但是出题人利用linux命令的特性,将部分flag放在了特殊文件中利用ls-a查看所有文件,查看.gift,可以得到前半段然后再lsgift2以及cat相关的内容得不到任何数据。。。因此考虑到会不会是进入目录下找,再更换到gift2目录中,查看flag2,......
  • 【pwn】[SWPUCTF 2021 新生赛]nc签到 --shell过滤字符
    附件下载打开:importosart='''  (( "####@@!!$$  ))    `#####@@!$$` ))  (( '####@!!$:  (( ,####@!!$: ))    .###@!!$:    `##@@!$:    `#@!!$ !@#  `#@!$:   @#$  #$  `#@!$:   !@!......
  • 在Windows下,可以使用以下步骤来捕获程序崩溃的堆栈信息
    在Windows下,Qt程序崩溃时,可以通过以下步骤捕获堆栈信息:定义一个全局的异常处理函数,在该函数中获取并保存堆栈信息。可以使用WindowsAPI函数SetUnhandledExceptionFilter来注册这个函数。LONGWINAPIUnhandledExceptionFilter(struct_EXCEPTION_POINTERS*ExceptionInfo){//在这......
  • Dasctf&CBctf-pwn部分题目复现
    打了一下Dasctf&CBCTF的pwn题目,感觉有些思路,但是就是做不出来,赛后发WP才恍然大悟,还是太菜了喵(---------------------------------------------------------------------------------------------------------------------------------------------------------------------------......
  • 【pwn】[MoeCTF 2022]babyfmt --格式化字符串漏洞,got表劫持
    拿到程序,先checksec一下发现是PartialRELRO,got表可修改当RELRO保护为NORELRO的时候,init.array、fini.array、got.plt均可读可写;为PARTIALRELRO的时候,ini.array、fini.array可读不可写,got.plt可读可写;为FULLRELRO时,init.array、fini.array、got.plt均可读不可写。然后看主......
  • 【pwn】[SDCTF 2022]Horoscope--栈溢出,atoi函数绕过
    checksec检查一下,发现只开了nx,然后ida打开直接看主函数发现fgets函数往s里面读入320个字节的数据,此处可造成溢出,再看看test和debug函数voiddebug(){ temp=1;} inttest(){ intresult;//eax result=temp; if(temp==1)  returnsystem("/bin/sh");......
  • Qt之堆栈布局(QStackedLayout)
    一、QStackedLayout概述QStackedLayout是Qt中的一个布局管理器,用于管理多个子窗口或页面的堆叠显示。它允许你在一个固定区域内显示多个子窗口,但每次只显示其中一个子窗口,其他子窗口被堆叠在后面。与QStackedWidget类似,但QStackedLayout是一个布局管理器,可以与其他布局管......
  • pandas算术 算术运算与数据对齐
    #range()打出来的相当于是数列,arange()打出来的相当于是数组obj_one=pd.Series(range(10,13),index=range(3))print(obj_one)obj_two=pd.Series(range(10,15),index=range(5))print(obj_two)#两数相加,没有对应值的话结果就会是NaNobj_one+obj_two#使用add(),可以确定填......
  • 堆栈模拟队列
    堆栈模拟队列题目大意PTA上的一道题,详题见文末。设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。输入:32A1A2A3A4A5DA6DA7DA8DDDDT输出:ERROR:Full1ERROR:Full23478ERROR:Empty思路最开始设想的是将长度小的栈作为存储栈,长度大......