代码审计

零基础实战审计SQL注射漏洞

字号+ 作者:万年死宅 来源:i春秋社区 2016-11-25 09:08 我要评论( )

从今天开始,深入学习web安全系列文章一改之前的排版,希望改头换面~新排版,新气象,希望大家能一如既往的支持小宅~ 今天,小宅给大家带来的内容相信是很多朋......

作者:万年死宅
首发:i春秋社区
注明:转载请务必注明i春秋社区(bbs.ichunqiu.com)

前言
从今天开始,深入学习web安全系列文章一改之前的排版,希望改头换面~新排版,新气象,希望大家能一如既往的支持小宅~
今天,小宅给大家带来的内容相信是很多朋友都很想学习的“代码审计”的姿势,希望能对大家有所启发~

目录
root@1~# mysql_connect()函数
root@2~# mysql_select_db()函数
root@3~# mysql_query()函数
root@4~# mysql_fetch_array()函数
root@5~# WeChall-Training: MySQL I

正文
  • root@1~# mysql_connect()函数

既然标题都说了零基础,那我自然也不能太“标题党”了,所以为了真的实现“零基础”,我们就得先补点基础知识,好了废话不多说,进入正题——mysql_connect()函数。
这个函数的“宅名片”如下(嘿嘿,以后你们会常看到“宅名片”的):
语言:PHP名称:mysql_connect()
功能:连接mysql服务
参数表:(HOST,USER,PASS)

就如这张“宅名片”上所写,这个mysql_connect()函数是一个PHP的函数,用于连接MySQL服务,我们来实际的使用一下。
首先,我们先启动MySQL服务和Apache2服务:





接着我们到Apache的根目录,新建一个MysqlDemo.php文件:





然后,我们使用vim编辑这个文件,书写如下代码:



然后去访问"http://localhost/MysqlDemo.php",效果如下:



接着,我们就来使用一下mysql_connect()函数:



我们来看下效果:



可以看到,这是一个人Resource。OK,接着,我们继续下一个主题。

  • root@2~# mysql_select_db()函数


接着,我们来学习第二个与数据库相关的函数,叫做:mysql_select_db(),相信大家从字面上就能理解这个函数的功能了,但是,我们还是来看下这个函数的“宅名片”吧,嘿嘿:
语言:PHP
名称:mysql_select_db()
功能:选择一个一个数据库
参数表:(DB_NAME,MYSQL_RESOURCE)

可以了,有了这个“宅名片”相信对于这个函数一定很明了了,我们还是来看下用法:



我们来访问看下:



可以看到成功了,为啥呢?因为我写了or die所以如果那个函数出现错误的话就会输出die()的参数。OK,由于MySQL是个多数据库的数据库软件,所以才会有这样一个函数。好滴,下一个内容~~

  • root@3~# mysql_query()函数


接着就是mysql_query函数了,我们来看“宅名片”:
语言:PHP
名称:mysql_query()
功能:执行一条SQL语句
参数表:(SQL)

OK,一目了然也,嘿嘿,我们就来试试看:



O了,来看看结果,我猜是个Resource,嘿嘿:



bingo!就是个Resource,嘿嘿,那么我们的查询结果哪儿去了呢?恩?哪儿呢?切,这都不知道,大表姐都鄙视你~~
这就和下个函数扯上关系了,接着上。

  • root@4~# mysql_fetch_array()函数


OK啦,我们来看mysql_fetch_array()函数“宅名片”:
语言:PHP
名称:mysql_fetch_array()
功能:把查询结果的Resource变成Array
参数表:(QUERY_RESOURCE)

其实啊,自从有了“宅名片”之后,妈妈在也不用担心我有没见过的函数啦~~^_^嘿嘿。我们还是来用一下:



我们来看效果,如下:



就是这个Feel~~倍儿爽~~Feel、Feel倍儿爽~~嘿嘿。(容我腼腆的摸摸头,然后憨厚的嘿嘿一下)
OK了,终于阔以进入正题了,Feel、Feel倍儿爽~~

  • root@5~# WeChall-Training: MySQL I


我们今天选来实战的是WeChall上的Training:MySQL I,这道题的地址:
小宅的传送门
这道题,其实是“万能密码”,但是如果是只知道or 1=1--的就不用去解了,你解不出的,这个题虽然不难,但是要求对“SQL注射”很了解,其实这个题是属于MySQL注射,但是呢,它的目的却不是GET数据,而是auth_bypass(认证绕过)。
我们先来看下题的主页面:



我们先看下highlighted version,其实是高亮的版本的源代码,如下:



有点长,截图截不完,大家自己看吧,小宅的传送门,嘿嘿。
我们开始分析代码逻辑,首先,我们来看登录框:




我们看到这个Form表单是以POST方式提交的数据,参数有username和password。于是我们在前文中寻找接收POST参数的地方就好,于是找到第11行到第13行的代码,如下:



我们可以看到,如果获取了两个参数就去调用auth1_onLogin()函数,我们定位到auth1_onLogin()函数的定义处,直接搜索“function auth1_onLogin(”就可以找到,是36行到58行,如下图:



OK,我们来观察,这个函数的处理过程,首先是$db=auth1_db();于是找到auth1_db()函数,19行到27行,如下:



最后返回了一个对象赋值给了$db,接着将POST参数password进行md5加密,并赋值给$password。
接着生成了查询语句,如下:



然后未经任何过滤直接代入了$db->queryFirst()函数,也就是查询了,所以说明这里的SQL语句:
SELECT * FROM users WHERE username='$username' AND password='$password'
的$username和$password位是我们可以控制的,接着,我们注意一个问题,也就是这个程序的认证机制。
首先是查询返回false时:



注意,if里的代码:“$result = $db->queryFirst($query)”,这里是一定会执行的,因为要if,必须看条件成立否,就像是if(1+1>3),这个if,我们就可以知道,要得知1+1>3这个表达式的返回值,就必须先运算1+1,懂了吧,嘿嘿。
OK,所以这里的SQL查询结果会被赋值给$result。因为要知道if的表达式的返回值就必须“运算”出结果。
接着,如果返回的结果不是false就会继续向下执行:




只要查询返回的不是false就会输出welcome和转义过的username,为啥转义呢?因为要防止XSS,嘿嘿。
OK,接着我们可以看到注释,上面那个只是成功登录,而下面才是这道题要求绕过的认证,也就是说要让程序执行到最后一个if里去。
所以,我们的解决方案就是构造username和password的值拼接进如下SQL语句中:
SELECT * FROM users WHERE username='$username' AND password='$password'
使得在我们不知道正确的username和password的情况下也能够使其返回真。
于是做如下构造:
SELECT * FROM users WHERE username='admin' and 1=1#' AND password='xxx'
这样就解开了这道题,我们来看:





OK,本paper到此结束,嘿嘿,希望大家一如既往的支持深入学习Web安全系列文章!!!
最后说一句:

本文来自: 蜗蜗侠's Blog-关注网络安全 http://blog.icxun.cn/hack/Code/246.html

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • (四)DVWA之SQL注射漏洞源码审计

    (四)DVWA之SQL注射漏洞源码审计

    2016-12-16 11:18

  • PHP代码审计SQL注入篇

    PHP代码审计SQL注入篇

    2016-11-25 10:56

  • 对代码审计sql漏洞的看法

    对代码审计sql漏洞的看法

    2016-11-25 09:52

网友点评
暂时未开启评论功能~