前言
近期一些比赛和做过的题的wp,稍微写几道总结下
wps
第五届上海市大学生网路安全大赛
web decade
考点是无参数文件读取
1 |
|
1 | '/[a-z]+\((?R)?\)/' |
这段正则限制了payload只能是以小写字母开头的无参数函数或者嵌套的单一参数函数的组合。
这道题bytectf的时候考过,但是少了对if time local 还有readfile的绕过。来分析下当时的一个payload
1 | if(chdir(next(scandir(pos(localeconv())))))readgzfile(end(scandir(pos(localeconv())))); |
题目明确说了flag在code文件夹在同一层,而文件排序是按照ascii码低到高排,所以相当于是要跳到上一层然后读取最后一个文件的内容。
- localeconv()函数返回本地数字和货币信息,第一个数据是
.
可以通过这个加上pos和current函数来获取当前文件夹的指针 pos(localeconv()) 获取当前目录。 - readfile函数用来读取当前文件的内容
- chdir函数用来切换文件夹,并返回布尔值。这里scandir列出目录的第二个是
..
(ls -a)。可以和chdir配和切换到上一层目录。chdir(next(scandir(pos(localeconv())))) - if() 可以用来连接两串表达式
这题的几个可替换的点主要如下
- 读文件函数,这里查手册可以发现readgzfile 可以用来替代readfile
- 获取. 加密后的字符串,搞出小数点,获取数字46,等等办法获取。
- 逻辑连接,这里没有过滤php的关键词and和or,可以用来连接两串表达式。
主要讲下第二点,我选择了加密这条路子
参考手册
1 | crypt ( string $str [, string $salt ] ) : string |
这个函数默认的算法是CRYPT_STD_DES,当不设置salt时,会从./0-9A-Za-z挑选任意两个字母放在最后作为salt,我们需要做的就是,凑到出现.的情况,并且将这个点提取出来。
这里我们需要两个函数帮忙
- strrev逆序
- ord 获取字符串第一个字母的ascii
最终构造payload如下:
1 | chr(ord(strrev(crypt(serialize(array()))))) 获取. |
这里还可以通过时间函数来获取46这个数字,但是这里time都被过滤了就不行了。另外几个加密函数还没尝试,以后可以去试试。
最终payload如下
1 | echo(chdir(next(scandir(chr(ord(strrev(crypt(serialize(array())))))))))and(readgzfile(end(scandir(chr(ord(strrev(crypt(serialize(array()))))))))); |
web ssrf (安恒月赛原题)
1 |
|
- strpos 会对字符串urldecode,二次编码urlcode可以过。
- 文件读取协议读/etc/hosts获取内网ip 172.18.0.3
- fuzz c段和端口 .2上有文件包含,且内网开了25 stmp服务,这里考虑用工具Gopherus打一波。写命令,读文件都可以。
- 最后读flag
需要注意的是由于内网包含的那个参数是get参数,所以我们需要对生成的payload再次urlencode
web 简单地sql注入
很明显是个注入
fuzz发现过滤了
, ,select union组合中间加东西可以绕过,or,if,--+注释符,-等等
这里其实我已经发现union注入是可以的,但是,,,,偏偏去盲注了。
- 由于过滤了or所以这里不能从information.schema里拖表名列名,表名可以从mysql.innodb_table_stats的table_name列获取,列名不知道,,,
- substr截取字符串,from 可以从最后来去字符串,case when 来替代if。
- guoup_concat是没问题的,但是,爆不了,被过滤了,所以只能用limt offset的形式去取数据。
- 自己写的脚本无法区分大小写,binary好像没有用不知道为啥。
最后拖出来数据库名
cctttfff ,version 5.6.46,表名 fl111aa44a99g,没了。这里感觉又盲注无列名又无法区分大小写,就没往下做了。赛后才知道,如果那个时候改union注入就,,,,
最终payload
1 | http://47.105.183.208:29898/article.php?id=1%27UNION%0ASELECT%20*%20from%20((select%201)a%20join%20(select%20*%20from%20fl111aa44a99g)b)%20limit%201%20offset%201%23 |
需要关注的就是这个无列名注入应该只有在列只有一个时才能这么用。
pwnhub 公开赛 web
1.首先f12查看源码
发现提示
1 |
|
尝试包含run.py,获取源码
1 |
|
- 审计源码发现思路如下,伪造flask的session key以Ne*用户登录,Numpy反序列化命令执行漏洞分析(CVE-2019-6446),进行命令盲注读取flag.txt
- 首先爆破获取flask的secret key,这里用了flask_session_cookie_manager3.py解密,如果使用的secret key能解密成功就得到了secret key
1 |
|
获得key ‘KEY_SECRET_PWN_HUB’, 可通过用户 Neo( 这里可以看index.html的源码猜测)
- 利用poc生成test.npy文件(这里需要注意numpy的版本钥匙1.16.0),上传至。/matrix/即可在vps上获得回显
1 |
|
unctf 审计(类似seacms)
##parse_again -> parse_if -> @eval
思路ssti(seacms)
1 |
|
已知
每一串传入payload不大于20个字母
: eval 等为敏感字符
共3到2个分割点可以过2到3个敏感字符
#构造第一次
1 |
|
1 |
|
1 | //被处理的关键词 |
//经验证 正则没理解好,提取{if{内容}}
&content=
1=phpinfo();
1 |
|
1 | <?php |
那么我们的思路来了,创建一个.doc改后缀为zip,把我们的shell搞进去,再上传的时候改回来,最后用phar协议读shell