ctf中关于文件压缩的2个web题

公粽号:黒掌

一个专注于分享渗透测试、黑客圈热点、黑客工具技术区博主!

1sql注入总结

[CSCCTF 2019 Final]ZlipperyStillAlive

题目下载链接

https://github.com/sturmisch/cscctf-problem/tree/master/2019/final/web/zlippery-still-alive

这个题网上没有找到具体细节的wp,而且关于go的web题比较少,这里记录一下,看看题目

img

看看源码,发现有2个路由,get请求的根目录,和post请求的upload

img

先来看看get请求/的代码吧,发现调用了getServerTime这个函数,看看这个函数,发现执行了一个叫time.sh的脚本,所以如果我们可以覆写这个文件,那就可以达到命令执行,所以可以确定目标

img

看看upload这个路由,发现允许上传rar和png和jpg文件,重点放在rar,如果后缀名为rar就会调用extract这个函数把rar文件解压

img

img

google查询了一下相关代码,发现有个zip的slip漏洞

img

具体搜索这个漏洞,发现go也受影响,并且rar等多种压缩文件受影响,网上有现成的zip压缩的构造脚本,但是没有rar的,下一个目标就是要搞清楚rar的一些格式,但是rar的文件压缩是不开源的,但是我们可以从go代码的一些验证里面进行突破

img

linux和window都不可以以/为文件名,所以先在文件里面写上读取flag的代码,然后压缩为rar文件

img

用winhex打开把2改成/

img

上传文件后发现了报错bad header crc

img

参考源码发现调用了这个rardecode这个库

img

所以继续跟踪这个库,然后搜索这个报错的字符串发现了位置

img

在看看哪里调用了这个错误

img

这里判断了crc的值,如果不等于,就报错,所以我们的目标就是绕过这个,但是具体不知道他是计算的哪里的crc值,所以我们一会写脚本爆破

img

我们在创建一个…1…1time.sh的文件,并且压缩为rar文件,对2个文件进行对比

img

发现就只有这个4个字节不同,但是我们不知道他是计算的哪些字符串的crc32的值,所以写脚本爆破

img

这里的16进制直接重winhex里面复制就行

img

import binascii
from zlib import crc32
s='526172211A0701003392B5E50A01050600050101808000C1CCD15B2902030B900004900020E57A05988000000D2E2E312E2E3174696D652E73680A0302A5263B1FFA2BD601746163202F6574632F7370617274616E1D77565103050400'
for x in range(len(binascii.a2b_hex(s))):
    for y in range(x+1,len(binascii.a2b_hex(s))):
        if '5b' in hex(crc32(binascii.a2b_hex(s)[x:y])) and 'c1' in hex(crc32(binascii.a2b_hex(s)[x:y])):
            print(x,y,hex(crc32(binascii.a2b_hex(s)[x:y])))

爆破出来发现是第27位到第69位

img

所以取出第27到第69,然后修改内容计算crc32的值,修改成计算出来的值

img

然后上传

img

回地开始界面刷新就会执行那个覆写的time.sh的脚本

img

tctf2021的1linephp

题目的代码很简单,可惜这个phpinfo是个静态的phpinfo.html,不然可以尝试一下临时缓存文件的利用,所以只有通过session的文件上传包含了。题目是有zip拓展的(通过phpinfo.html可以发现),结合之前的文件包含的学习总结,可以知道后缀名限制时可以用zip://t.zip#t.phpphar://a.phar/a.php,但是phar的文件包含的条件比较苛刻,第一个就是文件必须有后缀名,但是我们通过session构造上传的文件是没有后缀名的,所以就得想办法利用zip了

<?php
($_=@$_GET['yxxx'].'.php') && @substr(file($_)[0],0,6) === '@<?php' ? include($_) : highlight_file(__FILE__) && include('phpinfo.html');

借用维基百科上面zip文件为单文件时的结构图,可以明显的看到前26字节基本上是一些基础信息,一般是用于校验用的

img

先看看php的文档上面正常打开zip文件的操作,先是选择了ZipArchive::CHECKCONS的模式进行了检查,检查通过后就用stream_get_contents读取了文件内容,最后进行了crc的校验

img

来看看底层ZipArchive的open方法,接受2个参数,第二个flags就是打开时启用的模式

img

那么ZipArchive::CHECKCONS其实就是ZIP_CHECKCONSZIP_CHECKCONS是什么就可以看看libzip里面的声明了

img

img

然后看看官网的libzip的说明,也就是说如果是ZIP_CHECKCONS的模式打开才会进行魔数这些东西的检查,结合之前维基百科的zip单文件压缩结构图,真正对读取文件起作用的就是第26个字节后关于文件的描述

img

然后我们看看php底层通过数据流打开时的代码,可以发现php通过zip的数据流打开时是没有进行验证的,就直接调用了zip_open函数,但是打开的方式是ZIP_CREATE,这个模式是不会检测文件的,然后通过zip_fopen打开要读取的zip文件

php_stream_zip_opener

img

然后看看libzip的源码的zip_open怎么写的吧,zip_open_from_source函数就是针对我们传入的模式进行创建数据流

img

直接看看函数调用链到关键地方吧

img

img

这里是对魔数进行了检测匹配的,但是匹配的是504b0506,而没有匹配的文件头

img

但是如果是ZIP_CHECKCONS模式就会进入_zip_checkcons,这个函数就是zip的格式检查函数,所以可以通过ZIP_CREATE的模式打开的就不会进入_zip_checkcons

img

可以看看他检查的主要内容

img

img

所以我们目标就很明确了,只要读取文件的关键位置偏移不变,那么就可以成功读取文件,所以只需要删除构造的zip的单文件的前16字节,在配合zip协议进行包含就行

img

img

然后通过bp进行条件竞争,包含session的临时文件后写入一句话,得到flag

img

img

img

img

来源: https://www.anquanke.com/post/id/246722

活码3D(缩小)

今天的分享就到这里,喜欢的小伙伴记得点赞收藏转发,我有一个公粽号【黒掌】, 里面分享了更多黑客秘籍,欢迎来耍!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值