# Week1
# A Dark Room
查看网页源码就能拿到 flag
# 喵喵喵 ´・ﻌ・`
没有什么过滤,直接执行系统命令
# md5 绕过欸
经典 md5 绕过,不管是强比较还是弱比较,利用数组绕过即可
# HTTP 是什么呀
对基础 http 信息头和请求头的考察,按要求更改即可,其中 get 的内容中由于含有特殊字符,仅对特殊字符 url 编码即可
# upload
普通文件上传问题,在 png 文件中写入一句话木马,然后抓包修改后缀
显示传入成功后利用 uploads 这个目录去利用 1.php
# Aura 酱的礼物
这题涉及到了伪协议与 SSRF 漏洞的处理还有一些骚操作
首先 pan 的传入可以使用 data 伪协议来直接构造 Arua 这个内容;
challenge 即需要开头为 http://jamineaura.github.io
这个字符,又需要能利用 file_get_contents
函数读出含有 ' 已经收到 KengWang 的礼物啦 ' 这个字符串的内容。但是发现上述网址是无法利用的,也就无法通过日志包含等操作写入内容,骚操作就是利用当前题目网址,直接读取题目内容。这就转变成典型 ssrf 问题,通过 @
就能让函数读取到指定网址;
最后的 gift 传入,通过 php://filter
伪协议就行了,读取 base64 编码后的 flag.php
解码就得到 flag
# Week2
# RCEisamazingwithspace
题目利用 \s
过滤了空白字符,所以无法利用 tab 键等来代替空格,这里可以通过 ${IFS}
来绕过:
成功拿到 flag
# 一起吃豆豆
检查网页源码,发现源码泄漏,在游戏结束的段落发现一段 base64 编码的字符串
直接解码即可拿到 flag
# 你听不到我的声音
shell_exec
不会直接输出执行结果,可以通过 >
(流重定向符号)可以将内容写入指定文件,在 url 处查看文件内容
# ez_ser
反序列化永远的痛,想不明白,去复现官方 wp:
首先,入口一般为 __wakeup
、 __destruct
、 __construct
这里发现在 Crypto 中的 wakeup 方法和 getflag 方法都是无效的,需要利用 Misc 类中的 getflag 来实现 flag 获取;
发现可以通过 pwn 类来执行,但需要绕过对于 dusk 内容的判断,输入内容可以依靠 get 魔术方法,但触发需要利用不存在变量,题目中的不存在变量即为 nononono 存在于 re 类中,而 re 中存在的 tostring 魔术方法将在把对象当作字符串来使用时会自动调用,所以目标就切换成获得一个字符串;
字符串的获得方法就存在于 web 类中,把 chou 赋值即可
# 所以你说你懂 MD5?
前两处比较很好绕过,第一个直接利用数组绕过apple[]=1&banana[]=2
第二个利用转化后的 0e 开头 md5 值使 php 将其认为科学计数法来绕过字符串的弱比较(0e 开头字符串转化为 0)appple=240610708&bananana=s878926199a
第三处是字符 md5 值的强比较,需要找到本身值不同但转化为 md5 值后相同的内容(fastcoll 或者 hashclash)apppple=TEXTCOLLBYfGiJUETHQ4hAcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak&banananana=TEXTCOLLBYfGiJUETHQ4hEcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak
第四处需要利用哈希长度拓展攻击,利用脚本生成
https://github.com/luoingly/attack-scripts/blob/main/logic/md5-extension-attack.py
关于长度,是这么来的:
在这一部分生成 random 的过程中, random_bytes(16)
会随机产生 16 字节数据, bin2hex
函数将二进制字节转换成十六进制,由于一个字节是 8 位,所以 16 个字节共有 16X8 位,一个十六进制数有 4 位,所以一轮 bin2hex(random_bytes(16))
能产生 32 个十六进制字符,进行 3 轮就是 96 个
拿到 name 和 md5 的值name=%80%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%03%00%00%00%00%00%00admin&md5=cdae0001abf73a64129e2651ea28708a
# 数学大师
靠手算肯定不行,这一看就得写脚本,需要注意的是存在 session,要将 cookie 加上来进行循环求解
脚本如下:
import requests | |
import re | |
s=requests.session() | |
url="http://gz.imxbt.cn:20805" | |
response=s.get(url) | |
for i in range (50): | |
preg=re.search(r'\d+[×÷\-\+\*\/]\d+', response.text) | |
expression=preg.group(0).replace('×', '*').replace('÷', '//') | |
answer=eval(expression) | |
result={"answer": answer} | |
response=s.post(url,data=result) | |
print(response.text) |
拿到 flag
# Week3
# 滤个不停
第一重判定很好解决,直接将 incompetent 的内容定为 HelloWorld 就行;之后题目利用 foreach 循环来判断字符是否存在,需要包含's','e','v' 等内容,不能含有 'php://' 等伪协议;最后还需要 $Datch 所包含的文件名正确。这里涉及文件包含知识点,在不能利用伪协议的情况下,考虑到利用文件日志包含的方法来写入木马:
在 User-Agent 处写入一句话木马,通过 get 执行,获得所有文件名,抓取 flag
# 玩原神玩的
审计代码发现,第一部分通过 len 的长度等于 tip 的内容若等于 "我要玩原神" 时就能进入到 dumpFlag 函数中;
dumpFlag 函数中 post 传入的 m 数组的长度被限制在了 2,分别赋值给 b; 其中b 的内容为 "love100%" 拼接上 $a 的 md5 值;
最后一部分所做的操作就是将 flag 的每一个内容转换成对应 ascii 码之后与当前位置进行异或处理,最后转化成对应 md5 值传入 flag 数组并以 json 的形式输出
一个个绕过,首先对于 len 的验证,由于 flag 的长度是 45(固定已知),随便填入 len 数组的内容使之长度为 45,再让 tip 为 "我要玩原神",最后通过加密方式,逆向解密
# ez_php_jail
审计发现 get 的参数名为 Jail_by.Happy
,在 PHP 版本小于 8 时,点号会被转化成下划线,需要利用 [
来绕过,因为了解到,参数名中如果含有 [
, [
就会被转换成 _
,而 [
后面跟的 .
号则会保持不变
关于判断 php 版本,这题将信息藏在了网页元素中
base64 解码:
访问即可了解到版本信息:
发现版本是小于 8 的,需要用到上述绕过
在后面的 Like_Jail
函数中,对可能的利用方式进行了过滤,但过滤了字母 a 和 s 之后发现很多查看目录或者访问文件的操作都失效了,翻了老半天以前的笔记才记起来还有 glob 函数可以看文件(glob 伪协议由于路径含有 a 所以也失效了),glob 函数利用的话也是通过没有被过滤的 highlight_file
函数来实现,因为要查找的 flag 文件也含有过滤字母 a,所以直接用通配符绕过:
由于 glob 返回的是一个列表,整个列表在网页上没有回显,不知道是因为什么限制,所以我直接取了第一项内容,成功拿到 flag
4. 复读机
复读机?SSTI!
测试一下都 fuzz 了什么关键词