WEB安全

人人都可学会的MySQL高级注射技巧

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

过了Today的 No.7paper,我们就不在讲SQL注射的问题了,我们将慢慢过渡到前端,那么,这节课呢。有两个主题,一是WeChall的第二道MySQL题(这 道题,当时我也琢磨......

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

前言
过了Today的 No.7paper,我们就不在讲SQL注射的问题了,我们将慢慢过渡到前端,那么,这节课呢。有两个主题,一是WeChall的第二道MySQL题(这 道题,当时我也琢磨了一会才做出来。。。),第二个呢,就是MySQL注射的高级技巧。(一万个舍不得~~)。好了废话不多说,我们进入正题。

目录
root@1~# Training: MySQL II的简单分析
root@2~# MySQL高级注射技巧load_file()来读文件
root@3~# MySQL高级注射技巧into otfile来getshell

正文
  • root@1~# Training: MySQL II的简单分析

OK,昨天的Training:MySQL I给大家的启发很大吧。总之,对我启发很大,因为,我就是从这道题开始才真正的算是开始了解MySQL注射的(之前就是背注射语句,然后套。。。)
好了,我们不废话,直接来看这道题:
小宅的传送门
OK,大家可以先尝试解一下,然后在回来继续看这份教程,首先,我们还是先来看高亮的代码:
小宅的传送门
我们定位到HTML的Form表单(68~83行):



我们注意表单的method为POST,要传送的参数是username和password,于是定位到接收参数的地方(10~13行):



我们看到接收了POST参数username和password就调用了auth2_onLogin()函数,我们跟踪到该函数的定义处(36~66行):



我们来看函数的流程,可以发现于昨天的No.6paper极其相似,但是,有一处不同,就是认证不同了,我们来观察一下。首先是用于我们可控的SQL语句不同了(42行):



本次的SQL语句成了这样,接着,我们来看44~47行,这是和上道题一样的判断,只是SQL语句变了,但是还是一个道理:
[PHP] 纯文本查看 复制代码
?
1
if (false === ($result = $db->queryFirst($query)))

可以看到,还是调用$db->queryFirst()来执行SQL语句,并将查询结果赋值给$result,然后以这个整体(也就是这次查询的返回值)与false进行比较。当为false时自然就是说查询语句失败,例如,传入“xxx”,SQL语句则是:
[SQL] 纯文本查看 复制代码
?
1
SELECT * FROM users WHERE username='xxx';

若查询失败,则证明不存在xxx这条记录,若查询成功则证明存在xxx这条记录。这次的查询语句还有不同的是select的是*,所以,我们来看下users表的表结构(2~8行):





可以看到这个users表里有三个字段,分别是:“userid,username,password”。因为我们select的是*所以$result里就同时存在这三个与username同行的userid和password。
接着,我们来看重头戏,新的认证检测步骤(50~56行):





我们来看这个新增的步骤:
[PHP] 纯文本查看 复制代码
?
1
if ($result['password'] !== $password)

这个if语句的条件是查询结果里的与我们赋值的username同行的password是否与我们传入的password相同,如果不相同则执行if里的内容。
看起来简直天衣无缝,这样的验证从逻辑上来讲几乎没有问题了,所以,我们的突破口,绝不会在PHP代码上。
于是,我们就发现这次的SQL语句也是存在注射漏洞的,因为我们来看这个代码片段:





从图中可以看到,从SQL语句的生成到查询之间并未进行任何过滤,所以存在SQL注射。所以问题就出在我们可控的SQL语句上,我就提示到这里,大家先自己动动脑筋,想想怎么绕过认证。
我们得清楚,首先,我们不知道正确的username和password,而且不是以SQL的返回值来认证的,那怎么办?
这个,其实解决方案,我在No.5paper里讲过,就不知道大家有没印象了。
好了,大家想完之后呢,就来看正确的解题思路吧。
首先,既然我们不知道正确的用户名和密码,那我们就构造啊,什么意思呢?
大家记不记得UNION的神奇功效,假设我们如下SQL语句:
[SQL] 纯文本查看 复制代码
?
1
SELECT A FROM B WHERE C='$aaa'

假设在B表里有C等于111,但是我们不知道,那么如果我们构造如下$aaa的值会发生什么?
[SQL] 纯文本查看 复制代码
?
1
xxx' UNION SELECT 1#

这样一拼接就成了:
[SQL] 纯文本查看 复制代码
?
1
SELECT A FROM B WHERE C='xxx' UNION SELECT 1#'

所以A就成了1,对吧,嘿嘿,其实就是这么简单,只是由于我们对SQL的理解还不够深,才导致我们一时半会没想出解法。
于是我们在还去看题里的SQL语句:

[SQL] 纯文本查看 复制代码
?
1
SELECT * FROM users WHERE username='$username';

所以我们构造:
[SQL] 纯文本查看 复制代码
?
1
xxx' UNION SELECT 1,'test','123456'#

就拼接成了:
[SQL] 纯文本查看 复制代码
?
1
SELECT * FROM users WHERE username='xxx' UNION SELECT 1,'test','123456'#';

由于xxx这个username本就不存在,所以查询结果自然的变成了UNION的,于是userid变为1,username变为test,而password变为123456。
所以,我们username填"xxx' UNION SELECT 1,'test','123456'#",password填123456就OK了吗?我们试试就知道了,如下图:



我们点Login听天由命吧,哈哈:



密码错误!知道为什么吗?恩?嘿嘿,大家细想一个细节,在PHP程序中处理我们传入password的细节(在40行,哈哈):



知道问题出在哪里了吗?哈哈,对的,我们UNION的password一定要是输入的password的MD5值,当然,也可以是我们输入的password是UNION的password的MD5值。
我们来试试看(123456的MD5值是:e10adc3949ba59abbe56e057f20f883e)。把username填成:"xxx' UNION SELECT 1,'test','e10adc3949ba59abbe56e057f20f883e'#",把password填成123456,我们来看:



结果是:



成功!Bypass了新的认证方式!但是,这道题并没解出来,我们来看原题的题意:



要以admin的身份登录,而不是test,所以,我们得稍稍的改一下payload:
[SQL] 纯文本查看 复制代码
?
1
xxx' UNION SELECT 1,'admin','e10adc3949ba59abbe56e057f20f883e'#

我们再来看:



来,和我一起欢呼!yeah!(O了,别**了,我们还有事呢。)

  • root@2~# MySQL高级注射技巧load_file()来读文件


接下来,我们进入下一个主题,MySQL高级注射技巧,这里我只提及几个很常见的技巧。现在我们来说第一个load_file()函数。
我们来简单的学习一下这个load_file()函数,首先我们得先启动mysql和apache服务:



OK了,我们登录MySQL:



接着,我们进入早已准备好的sqliDemo数据库(这个其实无所谓,大家自己随便新建一个数据库也阔以,嘿嘿):



然后,我们来来学习一下使用这个load_file()函数(语句在下图中):



就这么简单,然后用 No.5paper里提到的公式去构造适合的Payload即可利用,但是啊,前几天就有同学问我我就这样在mysql里演示,没有将怎么注射啊。。。当 时我的内心是崩溃的,因为我就是想让大家具有这种自己构造Payload的能力啊,而不是说到头来你还是只能背人家给的payload。
但是,我还是演示一下吧,以免看不懂的人说假。(我心累,而且还很无奈。)
我在本地搭建了一下,构造了这样一个注射点"http://localhost/test.php?id=1",参数是id(GET)没任何过滤。
我们用FireFox来的HackBar演示吧,我们先到如下页面:



接着点击HackBar上的Load URL,如图:





我们接着构造如下Payload,即可load那个file了:





接着点击Execute,如下图:





成功了吧,就这么简单,甚至可以不用绝对路径,大家自己尝试嘛,嘿嘿。


  • root@3~# MySQL高级注射技巧into otfile来getshell


接着是第二个MySQL高级注射技巧into outfile写文件,来GetWebshell,嘿嘿,以后妈妈再也不用担心我GetWebshell的方法少了,嘿嘿。
我们还是先演示MySQL Console的语句,首先,我决定写一个<?php echo "iChunqiu";?>到Web跟目录/var/www/html的my.php文件里:



可以看到失败了,报错了,这是目录权限问题,执行如下命令:



接着,重来:



成功了,我们在Web上访问看看:



OK,接着我们演示在SQL注射点如何写,其实也很简单,如图:



接着,我们来访问试试写进去没:




O了,就这样吧,这篇paper就陪大家到这里了,希望大家好梦~~

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

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

相关文章
  • 移位溢注:告别依靠人品的偏移注入

    移位溢注:告别依靠人品的偏移注入

    2017-03-09 14:12

  • ZABBIX SQL注入

    ZABBIX SQL注入

    2016-12-24 14:47

  • 浅谈sql注入中的Post注入

    浅谈sql注入中的Post注入

    2016-11-25 10:17

  • mysql注入点的另类利用

    mysql注入点的另类利用

    2016-11-25 09:54

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