Xi4or0uji's blog

hacklu 2018 Baby PHP

字数统计: 699阅读时长: 2 min
2018/10/27 Share

这个比赛只有两道web题,一题代码审计,另一题神仙题??贼少人做……….
这篇博客先只讲一题,另一题用另一篇博客讲

题目

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

require_once('flag.php');
error_reporting(0);


if(!isset($_GET['msg'])){
highlight_file(__FILE__);
die();
}

@$msg = $_GET['msg'];
if(@file_get_contents($msg)!=="Hello Challenge!"){
die('Wow so rude!!!!1');
}

echo "Hello Hacker! Have a look around.\n";

@$k1=$_GET['key1'];
@$k2=$_GET['key2'];

$cc = 1337;$bb = 42;

if(intval($k1) !== $cc || $k1 === $cc){
die("lol no\n");
}

if(strlen($k2) == $bb){
if(preg_match('/^\d+$/', $k2) && !is_numeric($k2)){
if($k2 == $cc){
@$cc = $_GET['cc'];
}
}
}

list($k1,$k2) = [$k2, $k1];

if(substr($cc, $bb) === sha1($cc)){
foreach ($_GET as $lel => $hack){
$$lel = $hack;
}
}

$‮b = "2";$a="‮b";//;1=b

if($$a !== $k1){
die("lel no\n");
}

// plz die now
assert_options(ASSERT_BAIL, 1);
assert("$bb == $cc");

echo "Good Job ;)";
// TODO
// echo $flag;

这题把所有绕过都绕了就解出来了,考了很多个点,下面一个个解释

绕过file_get_contents


可以看到get方法获得一个msg,然后去读名字为msg的文件,如果内容是Hello Challenge!那就能进入下一步,否则就退出程序
这里可以用php://input去进行绕过,用我们写入的值作为内容,然后就能绕过了

key1


源码要求获得的key1转成int型要能等于1337,又要key1与1337不能相等,这里用字符串就能绕过了
key1=’1337’

key2


key2的长度必须是42,而且key2满足以$结尾,同时不是数字
这里可以用一个长度为42的以美元符号结尾的字符串去绕过,key2=’000000000000000000000000000000000001337$’,这样构造一个符合规则的key2方便我们后面可以利用cc

substr和sha1


可以看到,这里的条件如果可以满足的话,我们就可以进行变量覆盖,也会多了可控的值
这里想要两边都是true是不可能的了,只能让他两边同时为false
substr:这个函数只能处理字符串,如果给他一个数组的话,那就会返回null
sha1:很巧的是,这个函数也是处理数组的时候出错会返回一个null
两边同时为null,恰好可以满足条件,进去下一步

$a !== $k1


这里第一行的代码倒了过来,应该是 $b = “2”; $a = “b”; // ;1 = b
这是一个小的trick,https://rawsec.ml/en/2-less-known-tricks-spoofing-extensions/#rtlo-trick
所以a的值其实是2,因此我们上一步进行变量覆盖的时候可以将k1赋值为2

assert_options


这个考到了assert这些函数,看下官方解释,http://php.net/manual/en/function.assert-options.php
这里利用assert(“$bb == $cc”);
我们可以用 // 注释掉后面的 == $aa”,然后再插入函数,读出flag,也就是assert(“show_source(‘flag.php’); // == $cc”)
至此,完成了整个代码的绕过了,最终payload
?msg=php://input&key1=1337&k1=2&key2=000000000000000000000000000000000001337%ef%bc%84&cc[]=&bb=show_source(‘flag.php’);//
Hello Challenge!

CATALOG
  1. 1. 题目
  2. 2. 绕过file_get_contents
  3. 3. key1
  4. 4. key2
  5. 5. substr和sha1
  6. 6. $a !== $k1
  7. 7. assert_options