漏洞挖掘与防范(基础篇)

这几天学习代码审计,学的是漏洞与挖掘(基础篇),这相对于其他的漏洞挖掘确实简单点,这几种漏洞是常见的SQL注入漏洞、XSS漏洞、CSRF漏洞,讲的是这三种漏洞的从代码部分的挖掘技巧,我感觉很有用,就写下来,希望能帮助大家学习。

1. SQL注入漏洞

SQL注入漏洞是我们知道的最多的漏洞,原理是由于开发者在编写操作数据库代码时,直接将外部可控的参数拼接到SQL语句中,没有经过任何过滤就直接放入数据库引擎执行。
SQL注入是直接对数据库进行攻击的,通常利用SQL注入攻击方式有下面几种:一是在权限比较大的情况下,通过SQL注入可以直接写入webshell,或者执行系统命令等;二是在权限较小的情况下,可以通过注入来获得管理员的密码等信息,或者修改数据库内容进行一些钓鱼或者其他间接利用。

挖掘经验
SQL注入经常出现在登录页面、获取HTTP头、订单处理等地方。登录页面的注入大多是发生在HTTP头里面的client-ip和x-forward-for,一般用来记录登陆的IP地址;另外在订单系统里面,由于订单涉及购物车等多个交互,所以经常会发生二次注入。

SQL注入实例
普通的注入有int型和string型,在string型注入中需要使用单或者双引号闭合。
测试代码如下:
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 



 

 

 

Welcome    Dhakkan 

 

<?php
//including the Mysql connect parameters.
include(“../sql-connections/sql-connect.php”);
error_reporting(0);
// take the variables
if(isset($_GET[‘id’]))
{
$id=$_GET[‘id’];
//logging the connection parameters to a file for analysis.
$fp=fopen(‘result.txt’,’a’);
fwrite($fp,’ID:’.$id.”\n”);
fclose($fp);

// connectivity

$sql=”SELECT * FROM users WHERE id=’$id’ LIMIT 0,1”;
echo $sql.”
“;
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
  echo "<font size='5' color= '#99FF00'>";
  echo 'Your Login name:'. $row['username'];
  echo "<br>";
  echo 'Your Password:' .$row['password'];
  echo "</font>";
  }
else 
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";  
}

}
else { echo “Please input the ID as parameter with numeric value”;}

?>



 





在浏览器输入http://localhost/sqli/Less-1/?id=1

页面没有变化

 

再在浏览器输入http://localhost/sqli/Less-1/?id=1'

发现报了sql语句的语法错误,那么应该存在sql注入

这是从页面的反应来看是否存在注入,测试代码中GET id参数存在SQL注入漏洞。从上面的代码中可以发现,数据库操作存在一些关键字,比如select from、mysql_connect、mysql_query、mysql_fetch_row等,数据库的查询方式还有update、insert、delete,我们做白盒审计时,只需要查找这些关键字,即可定向挖掘SQL注入漏洞。

编码注入
程序在进行一些操作之前,经常会进行一些编码处理,而做编码处理的函数也是存在问题的,通过输入转码函数不兼容的特殊字符,可以导致输出的字符变成有害数据。
(1)宽字节注入
在使用PHP连接MySQL时,当设置”set character_set_client=gbk”时会导致一个编码转换的问题,当存在宽字节注入漏洞时,注入参数李带入%df%27,即可把程序中过滤的(%5c)吃掉。
测试代码如下:
<?php
$conn=mysql_connect(‘localhost’,’root’,’123456’);
mysql_select_db(“test”,$conn);
mysql_query(“SET NAMES ‘gbk’”,$conn);
$uid=addslashes($_GET[‘id’]);
$result=mysql_query($sql,$conn);
print_r(‘当前SQL语句: ‘.$sql.’
结果: ‘);
print_r(mysql_fetch_row($result));
mysql_close()
?>
当提交/1.php?id=%df union select 1,2,3,4%23时

由上面代码代码可知,对宽字节注入的挖掘方法也比较简单,只要搜索如下几个关键字即可:
SET NAMES character_set_client=gbk mysql_set_charset(‘gbk’)

宽字节注入漏洞防范方法:

  1. 在执行查询之前先执行SET NAMES ‘gbk’,character_set_client=binary设置character_set_client为binary;
  2. 使用mysql_set_charset(‘gbk’)设置编码,然后使用mysql_real_escape_string()函数被参数过滤;
  3. 使用pdo方式,在PHP5.3.6及以下版本需要设置setAttribute(PDO::ATTR_EMULATE_PREPARES,false);禁用prepared statements的仿真效果。

(2)二次uldecode注入
只要字符被进行转换就有可能产生漏洞,原理是我们提交参数到WebShell时,WebShell会自动解码一次,假设目标程序开启了GPC,我们提交.php?id=1%2527,因为我们提交的参数里面没有引号,所以第一次解码结果是id=1%27,%25解码结果是%。
测试代码如下:
<?php
$a=addslashes($_GET[‘p’]);
$b=urldecode($a);
echo ‘$a=’.$a;
echo ‘
‘;
echo ‘$b=’.$b;
?>
测试效果如图:

由上面代码可知,挖掘二次urldecode注入漏洞,主要搜索urldecode和rawurldecode函数。

漏洞防范:
(1)数据有效性校验:增加字符复杂度自动验证功能和限制表单数据输入和查询字符串输入的长度;
(2)封装数据信息:对客户端提交的数据进行封装,不要将数据直接存入cookie中,方法就是在编程的代码中,插入session、if、try、else,这样可以有效地防止攻击者获取cookie中的重要信息;
(3)去除代码中的敏感信息:将在代码中存在的用户名、口令信息等敏感字段删除,替换成输入框;
(4)替换或删除单引号:使用双引号替换掉所有用户输入的单引号可以使大部分SQL注入漏洞攻击失败;
(5)指定错误返回页面:在Web Service中指定一个不包含任何信息的错误提示页面。
(6)限制SQL字符串连接的配置文件:使用SQL变量,因为变量不是可以执行的脚本,即在Web页面中将连接数据库的SQL字符串替换成指定的Value,然后将Web.config文件进行加密,拒绝访问;
(7)设置Web目录的访问权限。将虚拟站点的文件目录禁止游客用户(如:Guest用户等)访问,将User用户权限修改成只读权限,切勿将管理权限的用户添加到访问列表。
(8)最小服务原则:Web服务器应以最小权限进行配置,只提供Web服务,这样可以有效地阻止系统的危险命令,如ftp、cmd、vbscript等;
(9)鉴别信息加密存储:将保存在数据库users表中的用户名、口令信息以密文形式保存,也可以对users表进行加密处理,这样可以大大增加对鉴别信息访问的安全级别;
(10)用户权限分离:应尽可能的禁止或删除数据库中sa权限用户的访问,对不同的数据库划分不同的用户权限,这样不同的用户只能对授权给自己的数据库执行查询、插入、更新、删除操作,就可以防止不同用户对非授权的数据库进行访问。

2. XSS漏洞

XSS漏洞学名为跨站脚本攻击,这种漏洞有两种情况:一种是通过外部输入然后直接在浏览器端触发,即反射型XSS;还有一种是先把利用代码保存到数据库或文件中,当Web程序读取利用代码并输出在页面上时触发漏洞,即存储型XSS。

挖掘经验:
挖掘XSS漏洞的关键在于寻找没有被过滤的参数,且这些参数传入到输出函数,常用的输出函数列表如下:print、print_r、echo、printf、sprintf、die、var_dump、var_export,所以我们只要找寻带有变量的的这些函数即可。
XSS漏洞经常出现在文章发表、评论回复、留言以及资料设置的地方,特别是在发文章的时候,因为这里大多都是富文本,有各种图片引用、文字格式设置等。

反射型XSS
对于反射型XSS,白盒审计中只需要寻找带有参数的输出函数,然后根据输出函数对输出内容回溯输入参数,观察有没有经过过滤。
举例一个反射型XSS漏洞的大致形成方式,代码如下:
if($_GET[“openid”])
{
if(!is_vaild_openid($_GET[“openid”],$_GET[“timestamp],$_GET[“oauth_signature”]))
{
showerr(‘API账号有误!’);
echo “###invalid openid\n”;
echo “sig:”.$_GET[“ouath_signature”].”\n”;
exit;
}
}
代码中echo “sig:”.$_GET[“ouath_signature”].”\n”;直接将$_GET[“ouath_signature”]的值输出到浏览器中,则可以直接用GET方式注入代码。

存储型XSS
存储型XSS原理图如下:

存储型XSS不用考虑绕过浏览器的过滤,尤其在社交网络中的存储型XSS蠕虫能造成大面积的传播。要挖掘存储型XSS也是要寻找未过滤的输入点和未过滤的输出函数。

骑士cms存储型XSS案例分析
安装骑士cms
在浏览器输入http://localhost/74cms/1/upload/install

点击下面的我同意,填写参数配置

安装成功

前台有一个申请友情链接,根据经验这个友情申请链接的地方应该是一个payload输入的地方,先看
/admin/admin_link.php的代码:
$act = !empty($_GET[‘act’]) ? trim($_GET[‘act’]) : ‘list’;
$smarty->assign(‘pageheader’,”友情链接”);
if($act == ‘list’)
{
get_token();
check_permissions($_SESSION[‘admin_purview’],”link_show”);
require_once(QISHI_ROOT_PATH.’include/page.class.php’);
$oederbysql=” order BY l.show_order DESC”;
这是判断访问admin_link.php这个文件有没有act参数,没有就给$act变量赋值为list,即进入到输出友情链接列表的代码:
$offset=($currenpage-1)$perpage;
$link = get_links($offset, $perpage,$joinsql.$wheresql.$oederbysql);
$smarty->assign(‘link’,$link);
$smarty->assign(‘page’,$page->show(3));
$smarty->assign(‘upfiles_dir’,$upfiles_dir);
$smarty->assign(‘get_link_category’,get_link_category());
$smarty->assign(‘navlabel’,”list”);
$smarty->display(‘link/admin_link.htm’);
get_links()函数代码如下:
function get_links($offset,$perpage,$get_sql=’’)
{
global $db;
$row_arr=array();
$limit=”LIMIT”.$offset.’,’.$perpage;
$result=$db->query(“SELECT 1.
,c.categoryname FROM”.table(‘link’).” AS 1 “.$get_sql.$limit);
while($row=$db->fetch_array($result))
{
row_arr[]=$row;
}
return $row_arr;
}
很清楚看到,这是一个从数据库读取友情链接列表的功能,后面的代码则是将读取的内容以link/admin_link.htm为模板显示出来。跟进模板页看看,有一段关键代码片段:
[logo]
这里的利用点是可以是实体编码,从而绕过骑士cms的安全检查。在前台申请友情链接页面http://127.0.0.1/74cms/1/upload/link/add_link.php的logo字段输入
1 onerror=alert(1)
构造代码:
[logo]
结果如图所示:

当管理员在后台查看链接是触发漏洞执行代码,结果如下图:

漏洞防范:

  1. 特殊字符HTML实体转码:过滤掉相关的特殊字符;
  2. 标签事件属性黑白名单:加标签事件白名单,实现规则可以直接用正则表达式来匹配,如果匹配到的事件不在白名单列表,就直接拦截掉。

3. CSRF漏洞

CSRF漏洞全称为跨站请求伪造。说白一点就是可以劫持其他用户去进行一些请求。

挖掘经验:
CSRF主要是用于越权操作,所有漏洞自然在有权限控制的地方,像管理后台、会员中心、论坛帖子以及交易管理等。从白盒角度来说,只要读代码的时候看看几个核心文件里面有没有验证token和referer相关的代码,这里的核心文件指的是被大量文件引用的基础文件,如果在核心文件没有,再去看看功能点的代码有没有验证。

DISCUZ CSRF备份脱裤分析
漏洞文件在source/admincp/admincp_db.php,代码如下:
if(!$backupdir) {
$backupdir = random(6);
@mkdir(‘./data/backup_’.$backupdir, 0777);
DB::query(“REPLACE INTO “.DB::table(‘common_setting’).” (skey, svalue) values (‘backupdir’, ‘$backupdir’)”);
}
$backupdir = ‘backup_’.$backupdir;
if(!is_dir(‘./data/‘.$backupdir)) {
mkdir(‘./data/‘.$backupdir, 0777);
DB::query(‘SET SQL_QUOTE_SHOW_CREATE=0’, ‘SILENT’);

if(!$_G['gp_filename'] || preg_match("/(\.)(exe|jsp|asp|aspx|cgi|fcgi|pl)(\.|$)/i", $_G['gp_filename'])) {
    cpmsg('database_export_filename_invalid', '', 'error');
}
$backupfilename = './data/'.$backupdir.'/'.str_replace(array('/', '\\', '.', "'"), '', $_G['gp_filename']);

if($_G['gp_usezip']) {
    require_once './source/class/class_zip.php';
}

if($_G['gp_method'] == 'multivol') {

    $sqldump = '';
    $tableid = intval($_G['gp_tableid']);
    $startfrom = intval($_G['gp_startfrom']);

    if(!$tableid && $volume == 1) {
        foreach($tables as $table) {
            $sqldump .= sqldumptablestruct($table);
        }
    }

    $complete = TRUE;
    for(; $complete && $tableid < count($tables) && strlen($sqldump) + 500 < $_G['gp_sizelimit'] * 1000; $tableid++) {
        $sqldump .= sqldumptable($tables[$tableid], $startfrom, strlen($sqldump));
        if($complete) {
            $startfrom = 0;
        }
    }

在这个漏洞中,由于表名和文件都是直接提交的,目录名由一个固定的backup加上一个六位数字组成,备份成功后可以直接爆破,最终利用可以直接在论坛发帖加入下面的代码即可:
img src=”http://127.0.0.1/Discuz/uploadadmin.php?action=db&operation=export&setup=1&scrolltop=&anchor=&type=custom&customtables%5B%5D={表名&method=multivol&sizelimit=2048&extendins=0&sqlcompat=&usehex=1&usezip=0&filename={文件名}&exportsubmit=%CC%E1%BD%BB22"

漏洞防范:

  1. 增加token/referer验证避免img标签请求的水坑攻击;
  2. 增加验证码。

猜你喜欢

转载自blog.csdn.net/qq_36197704/article/details/81623772