代码审计–SQL注入

幸运草
幸运草
幸运草
896
文章
3
评论
2020年3月30日18:54:39 评论 328

 SQL注入漏洞,产生的直接原因就是服务器过于信任用户输入,将用户输入直接拼入SQL查询语句,返回了大量用户的敏感信息。

        后来,结合一些正则表达式、黑名单、白名单等手段的过滤,一些低端的SQL注入手段被识别和终止。但天下没有不透风的墙,一味的写规则总会有纰漏。就这样,SQL注入的攻与防永远在持续。

今天在这里,要分享的是我在代码审计学习中关于sql注入漏洞的研究,因为在代码审计领域还处于入门阶段,故此文可归为扫盲类,大神可以过过过。

01

PHP代码审计

php涉及的SQL注入漏洞类型
(1)整型注入

(2)编码绕过GPC

GPC,即magic_quotes_gpc。在开启情况下,如果输入的数据有单引号(’)、双引号(”)、反斜线()与 NUL(NULL 字符)等字符都会被加上反斜线进行转义处理,和addslashes函数功能相同。代码修改为如下:

$query="select * from book where id = '$id'";

$result=mysql_query($query);

由于GPC会对单引号’进行转义为’,导致不能注入sql语句。但是仍然有一些地方没有魔术引号的保护,如$_SERVER变量、$_FILES变量、getenv()得到的变量、$HTTP_RAW_POST_DATA与PHP输入、输出流等,同时一些变量的编码与解码使用不当也可以造成绕过GPC的保护,如base64_decode、urldecode、rawurldecode以及反序列化函数unserialize等。

(3)宽字节注入

宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而导致的注入漏洞。具体原理如下:

    • 正常情况下当GPC开启或使用addslashes函数过滤GET或POST提交的参数时,黑客使用的单引号 ‘ 就会被转义为: ’;
    • 如果存在宽字节注入,我们输入%df%27时首先经过上面提到的单引号转义变成了%df%5c%27(%5c是反斜杠),之后在数据库查询前由于使用了GBK多字节编码,即在汉字编码范围内两个字节会被编码为一个汉字。然后MySQL服务器会对查询语句进行GBK编码即%df%5c转换成了汉字“運”(注:GBK的汉字编码范围见附录),而单引号逃逸了出来,从而造成了注入漏洞。

这里将id变量从UTF-8转为gbk,因为反斜杠的GBK编码为5c,“錦”这个字的gbk编码是e55c,刚好出现5C,会对GPC转义单引号的反斜杠进行转义,从而单引号不会被转义,造成注入

除了上述这些示例,还可以关注二次攻击造成的注入、魔术引号针对数组类型只处理值而忽略key的情况。

具体实例

1.WillNews(Mobile新闻系统)

关注一处输入处理:

$id=sqlReplace(Trim($_GET['id']));

$sqlStr="select * from wiinews_news where news_id=$id";

$result = mysql_query($sqlStr) or die ("查询失败,请检查 SQL 语句。编码号:1010");

$row = mysql_fetch_array($result);

跟进sqlReplace函数:

function sqlReplace($str)

{

$strResult = $str;

if(!get_magic_quotes_gpc())

//如果 gpc 没有开的话

{

$strResult = addslashes($strResult);

//编码

}

return HTMLEncode($strResult);

//gpc 开的话,返回 HTMLEncode()

}

判断了gpc是否开启,如果magic_quotes_gpc=On,PHP解析器就会自动为post、get、cookie过来的数据增加转义字符“”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符(认为是php的字符)引起的污染。如果gpc没开,就会php内置函数addslashes进行处理,如果开启了,使用函数HTMLEncode处理,跟进一下函数:

function HTMLEncode($str){

if (!empty($str)){

$str=str_replace("&","&",$str);

$str=str_replace(">",">",$str);

$str=str_replace("<","<",$str);

$str=str_replace(CHR(32)," ",$str);

$str=str_replace(CHR(9)," ",$str);

$str=str_replace(CHR(9)," ",$str);

$str=str_replace(CHR(34),""",$str);

$str=str_replace(CHR(39),"'",$str);

$str=str_replace(CHR(13),"",$str);

$str=str_replace(CHR(10),"",$str);

}

return $str;

}

此时,可以发现代码中拦截了CHR(9)tab空格、CHR(10)换行、CHR(13)回车、CHR(32)空格、CHR(34)双引号、CHR(39)单引号,未拦截select、from、and等函数。则可利用宽字节、十六进制等绕过限制。单引号的宽字节:%bf%27 %df%27 %aa%27,如下列payload:

select column_name  from information_schema.tables where table_name="users"

改换成:select column_name  from information_schema.tables where table_name=0x7573657273

2.tpshop注入

首先查看index.php:

if (extension_loaded('zlib')){

ob_end_clean();

ob_start('ob_gzhandler');

} //

检测PHP环境

if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !');

//检测是否已安装TPshop系统

if(file_exists("./Install/") && !file_exists("./Install/install.lock")){

if($_SERVER['PHP_SELF'] != '/index.php'){

header("Content-type: text/html; charset=utf-8");

exit("请在域名根目录下安装,如:<br/>

www.xxx.com/index.php 正确 <br/>

www.xxx.com/www/index.php 错误,域名后面不能圈套目录, 但项目没有根目录存放限制,可以放在任意目录,apache虚拟主机配置一下即可");

}

header('Location:/Install/index.php');

exit();

}

error_reporting(E_ALL ^ E_NOTICE);//显示除去 E_NOTICE 之外的所有错误信息

// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false

define('APP_DEBUG',false);

// 定义应用目录

define('APP_PATH','./Application/');

// 定义插件目录

define('PLUGIN_PATH','plugins/')

这里跟进应用目录,关注其中一个文件File:Application/Home/Controller/ApiController.class.php

class ApiController extends Controller {

/*

* 获取地区

*/

public function getRegion(){

$parent_id = I('get.parent_id');

$selected = I('get.selected',0);

$data = M('region')->where("parent_id=$parent_id")->select();

$html = '';

if($data){

foreach($data as $h){

if($h['id'] == $selected){

$html .= "<option value='{$h['id']}' selected>{$h['name']}</option>";

}

$html .= "<option value='{$h['id']}'>{$h['name']}</option>”;

}

}

echo $html;

}

通过`I('get.parent_id')` 处理输入,这是 thinkphp 的一个写法,通过 GET接收 parent_id 这个变量。I方法是ThinkPHP众多单字母函数中的新成员,其命名来自于英文Input(输入),主要用于更加方便和安全的获取系统输入变量。echo I('get.id'); // 相当于 $_GET['id']。

获取的 parent_id 之后直接带入了数据库查询。

$data = M('region')->where("parent_id=$parent_id")->select();

Python sqlmap.py -u "http://demo2.tp-shop.cn/index.php?m=Home&c=Api&a=get Region&parent_id=2" -p parent_id -v 3

3.iSiteCMS 几处注射漏洞

File:/isite/components/messages/messages.fe.php

if($form->status == TFORM_STATUS_GETED_VALID){

//这个是站内短信的写信息表单的处理

$arr = $form->getValues();//直接获取表单中信息

$tos = explode(',',trim($arr['to']));//只是分割, 不是过滤

$noExistsMenber = array();

$toMenbers = array();

foreach ($tos as $menber){

$i =$this->DBE->getOne("select `id` from #__user where `name`='$menber'");//直接拼接到sql查询语句中

if(is_null($i) or empty($i)){

$noExistsMenber[] = $menber;

//id 只要有返回就可以继续

}else{

$m['name'] = $menber;

$m['id'] = $i;

$toMenbers[] = $m;

}

}

if(!empty($noExistsMenber)){

addGlobalNotice("以下用户不存在:".implode(',',$noExistsMenber));

}else{

$msg['tos'] = $arr['to'];

$msg['subject'] = $arr['subject'];

$msg['content'] = $arr['content'];

$mMessage->sendMessage($toMenbers,$msg);

$this->flash('成功','发送成功',bu(1,'messages','inbox'));

}

4.laravel SQL注入

先放5.6.5版本中Validation/Rules/unique.php中ignore方法定义

代码审计–SQL注入

通过阅读代码可知,用户可控制的id字符串,未经过滤赋给了$this->ignore,接着在下面代码中找到引用:

代码审计–SQL注入

5.8.4版本:

代码审计–SQL注入

public function __toString() {

……

$this->ignore ? '"'.$this->ignore.'"' : 'NULL',

……

}

测试代码:

代码审计–SQL注入

则可进行注入。

02

JAVA代码审计

        一般直接搜索 select、 update、 delete、 insert 关键词就会有收获。

如果 sql 语句中有出现+ append、 $() # 等字眼,如果没有配置 SQL 过滤文件,则判断存在 SQL 注入漏洞。

类似于PHP代码审计,不断跟入。

03

防范方法

整型参数
运用 intval 函数将数据转换成整数

int intval(mixed var, int base),var 是要转换成整形的变量,base,可选,是基础数,默认是 10。

浮点型参数

运用 floatval 或 doubleval 函数分别转换单精度和双精度浮点型参数

int floatval(mixed var),var 是要转换的变量

int doubleval(mixed var),var 是要转换的变量

字符型参数

运用 addslashes 函数来将单引号“’”转换成“’”,双引号“"”转换成“"”,反斜杠“”转换成“\”,NULL字符加上反斜杠“”

string addslashes (string str),str 是要检查的字符串

如果是字符型,先判断 magic_quotes_gpc 能无法 为 On,当不为 On 的时候运用 addslashes 转义特殊字符

if(get_magic_quotes_gpc()){

$var = $_GET["var"];

}else{

$var = addslashes($_GET["var"]);

}

 

本文来源于:代码审计--SQL注入-变化吧
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

转载请注明:{{title}}-变化吧
  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 赞助本站
  • 支付宝扫一扫
  • weinxin
幸运草
学会与网络威胁共存 安全防范

学会与网络威胁共存

网络威胁就像感冒或者其他什么感染性病毒,谁也无法避免。但这是生活的一部分,它们就在那里,伺机给你来上一下,让你的生活变得有那么点点艰难。 同时,你又不能以牺牲业务发展的方式全情投入到防范潜在风险上。你...
2020年7种最大的网络安全威胁 安全防范

2020年7种最大的网络安全威胁

计算机盲打的技巧与方法【听看打练习】盲打不是几天就能练出来的。 首先你要把键盘上字母和数字的位置背下来。 再有严格遵照正规指法练习(就是哪个指头负责哪片键盘区)。 每个字都要按照上面的要求打出来,一个...
Web | 渗透神器nmap:端口扫描工具 漏洞扫描

Web | 渗透神器nmap:端口扫描工具

Watcher - 被动Web应用程序漏洞扫描程序Watcher是基于HTTP的Web应用程序的运行时被动分析工具。被动意味着它不会损害生产系统,在云计算,共享托管和专用托管环境中使用它是完全安全的。...