0

0

PHP+MYSQL网站SQL Injection攻防

php中文网

php中文网

发布时间:2016-06-21 08:56:34

|

1724人浏览过

|

来源于php中文网

原创

程序员们写代码的时候讲究tdd(测试驱动开发):在实现一个功能前,会先写一个测试用例,然后再编写代码使之运行通过。其实当黑客sql injection时,同样是一个tdd的过程:他们会先尝试着让程序报错,然后一点一点的修正参数内容,当程序再次运行成功之时,注入也就随之成功了。

进攻:

假设你的程序里有类似下面内容的脚本:

$sql = "select id, title, content from articles where id = {$_get['id']}";

正常访问时其url如下:

/articles.php?id=123

当黑客想判断是否存在sql injection漏洞时,最常用的方式就是在整形id后面加个单引号:

/articles.php?id=123'

由于我们没有过滤$_get['id']参数,所以必然会报错,可能会是类似下面的信息:

supplied argument is not a valid mysql result resource in ...

这些信息就足以说明脚本存在漏洞了,我们可以再耍点手段:

/articles.php?id=0 union select 1,2,3

之所以select 1,2,3是因为union要求两边的字段数一致,前面是id,title,content三个字段,后面1,2,3也是三个,所以不会报语法错误,还有设置id=0是一条不存在的记录,那么查询的结果就是1,2,3,反映到网页上,原本显示id的地方会显示1,显示title的地方会显示2,显示content的地方会显示3。

至于如何继续利用,还要看magic_quotes_gpc的设置:

当magic_quotes_gpc为off时

/articles.php?id=0 union select 1,2,load_file('/etc/passwd')

如此一来,/etc/passwd文件的内容就会显示在原本显示content的地方。

当magic_quotes_gpc为on时

此时如果直接使用load_file('/etc/passwd')就无效了,因为单引号被转义了,但是还有办法:

/articles.php?id=0 union select 1,2,load_file(char(47,101,116,99,47,112,97,115,115,119,100))

其中的数字就是/etc/passwd字符串的ascii:字符串每个字符循环输出ord(...)

除此以为,还可以使用字符串的十六进制:字符串每个字符循环输出dechex(ord(...))

/articles.php?id=0 union select 1,2,load_file(0x2f6574632f706173737764)

这里仅仅说了数字型参数的几种攻击手段,属于冰山一角,字符串型参数等攻击手段看后面的文档链接。

防守:

网络上有一些类似sql injection firewall的软件可供使用,比如说greensql,如果网站已经开始遭受sql injection攻击,那么使用这样的快捷工具往往会救你一命,不过这样的软件在架构上属于一个proxy的角色,多半会影响网站并发性能,所以在选择与否这个问题上最好视客观条件来慎重决定。很多时候专业的软件并不是必须的,还有很多轻量级解决方案,下面演示一下如何使用awk来检测可能的漏洞。

创建detect_sql_injection.awk脚本,内容如下(如果要拷贝一下内容的话记得不要包括行号):

01 #!/bin/gawk -f
02
03 /$_(getpostcookierequest)\s*\[/ {
04     ignorecase = 1
05     if (match(

程序员们写代码的时候讲究tdd(测试驱动开发):在实现一个功能前,会先写一个测试用例,然后再编写代码使之运行通过。其实当黑客sql injection时,同样是一个tdd的过程:他们会先尝试着让程序报错,然后一点一点的修正参数内容,当程序再次运行成功之时,注入也就随之成功了。

进攻:

假设你的程序里有类似下面内容的脚本:

$sql = "select id, title, content from articles where id = {$_get['id']}";

正常访问时其url如下:

/articles.php?id=123

当黑客想判断是否存在sql injection漏洞时,最常用的方式就是在整形id后面加个单引号:

/articles.php?id=123'

由于我们没有过滤$_get['id']参数,所以必然会报错,可能会是类似下面的信息:

supplied argument is not a valid mysql result resource in ...

这些信息就足以说明脚本存在漏洞了,我们可以再耍点手段:

/articles.php?id=0 union select 1,2,3

之所以select 1,2,3是因为union要求两边的字段数一致,前面是id,title,content三个字段,后面1,2,3也是三个,所以不会报语法错误,还有设置id=0是一条不存在的记录,那么查询的结果就是1,2,3,反映到网页上,原本显示id的地方会显示1,显示title的地方会显示2,显示content的地方会显示3。

至于如何继续利用,还要看magic_quotes_gpc的设置:

当magic_quotes_gpc为off时

/articles.php?id=0 union select 1,2,load_file('/etc/passwd')

如此一来,/etc/passwd文件的内容就会显示在原本显示content的地方。

当magic_quotes_gpc为on时

此时如果直接使用load_file('/etc/passwd')就无效了,因为单引号被转义了,但是还有办法:

/articles.php?id=0 union select 1,2,load_file(char(47,101,116,99,47,112,97,115,115,119,100))

其中的数字就是/etc/passwd字符串的ascii:字符串每个字符循环输出ord(...)

除此以为,还可以使用字符串的十六进制:字符串每个字符循环输出dechex(ord(...))

/articles.php?id=0 union select 1,2,load_file(0x2f6574632f706173737764)

这里仅仅说了数字型参数的几种攻击手段,属于冰山一角,字符串型参数等攻击手段看后面的文档链接。

防守:

网络上有一些类似sql injection firewall的软件可供使用,比如说greensql,如果网站已经开始遭受sql injection攻击,那么使用这样的快捷工具往往会救你一命,不过这样的软件在架构上属于一个proxy的角色,多半会影响网站并发性能,所以在选择与否这个问题上最好视客观条件来慎重决定。很多时候专业的软件并不是必须的,还有很多轻量级解决方案,下面演示一下如何使用awk来检测可能的漏洞。

创建detect_sql_injection.awk脚本,内容如下(如果要拷贝一下内容的话记得不要包括行号):

01 #!/bin/gawk -f
02
03 /\$_(getpostcookierequest)\s*\[/ {
04     ignorecase = 1
05     if (match($0, /\$.*(sqlquery)/)) {
06         ignorecase = 0
07         output()
08         next
09     }
10 }
11
12 function output()
13 {
14     $1 = $1
15     print "crud: " $0 "\nfile: " filename "\nline: " fnr "\n"
16 }


此脚本可匹配出类似如下的问题代码,想要扩展匹配模式也容易,只要照猫画虎写if match语句即可。

1:$sql = "select * from users where username = '{$_post['username']}'";
2:$res = mysql_query("select * from users where username = '{$_post['username']}'");


使用前别忘了先chmod +x detect_sql_injection.awk,有两种调用方法:

1:./detect_sql_injection.awk /path/to/php/script/file
2:find /path/to/php/script/directory -name "*.php" xargs ./detect_sql_injection.awk


会把有问题的代码信息显示出来,样子如下:

crud: $sql = "select * from users where username = '{$_post['username']}'";
file: /path/to/file.php
line: 123


现实环境中有很多应用这个脚本的方法,比如说通过cron定期扫描程序源文件,或者在svn提交时通过钩子方法自动匹配。

使用专业工具也好,检测脚本亦罢,都是被动的防守,问题的根本始终取决于在程序员头脑里是否有必要的安全意识,下面是一些必须要牢记的准则:

1:数字型参数使用类似intval,floatval这样的方法强制过滤。
2:字符串型参数使用类似mysql_real_escape_string这样的方法强制过滤,而不是简单的addslashes。
3:最好抛弃mysql_query这样的拼接sql查询方式,尽可能使用pdo的prepare绑定方式。
4:使用rewrite技术隐藏真实脚本及参数的信息,通过rewrite正则也能过滤可疑的参数。
5:关闭错误提示,不给攻击者提供敏感信息:display_errors=off。
6:以日志的方式记录错误信息:log_errors=on和error_log=filename,定期排查,web日志最好也查。
7:不要用具有file权限的账号(比如root)连接mysql,这样就屏蔽了load_file等危险函数。
8:......

网站安全其实并不复杂,总结出来就是一句话:过滤输入,转义输出。其中,我们上面一直讨论的sql injection问题就属于过滤输入问题,至于转义输出问题,其代表是cross-site scripting,但它不属于本文的范畴,就不多说了。

文档:

addslashes() versus mysql_real_escape_string()
sql injection with mysql
advanced sql injection with mysql
mysql注入中导出字段内容的研究——通过注入导出webshell

, /$.*(sqlquery)/)) {
06         ignorecase = 0
07         output()
08         next
09     }
10 }
11
12 function output()
13 {
14     =
15     print "crud: "

程序员们写代码的时候讲究tdd(测试驱动开发):在实现一个功能前,会先写一个测试用例,然后再编写代码使之运行通过。其实当黑客sql injection时,同样是一个tdd的过程:他们会先尝试着让程序报错,然后一点一点的修正参数内容,当程序再次运行成功之时,注入也就随之成功了。

进攻:

假设你的程序里有类似下面内容的脚本:

$sql = "select id, title, content from articles where id = {$_get['id']}";

正常访问时其url如下:

/articles.php?id=123

当黑客想判断是否存在sql injection漏洞时,最常用的方式就是在整形id后面加个单引号:

/articles.php?id=123'

由于我们没有过滤$_get['id']参数,所以必然会报错,可能会是类似下面的信息:

supplied argument is not a valid mysql result resource in ...

这些信息就足以说明脚本存在漏洞了,我们可以再耍点手段:

/articles.php?id=0 union select 1,2,3

之所以select 1,2,3是因为union要求两边的字段数一致,前面是id,title,content三个字段,后面1,2,3也是三个,所以不会报语法错误,还有设置id=0是一条不存在的记录,那么查询的结果就是1,2,3,反映到网页上,原本显示id的地方会显示1,显示title的地方会显示2,显示content的地方会显示3。

至于如何继续利用,还要看magic_quotes_gpc的设置:

当magic_quotes_gpc为off时

/articles.php?id=0 union select 1,2,load_file('/etc/passwd')

如此一来,/etc/passwd文件的内容就会显示在原本显示content的地方。

当magic_quotes_gpc为on时

此时如果直接使用load_file('/etc/passwd')就无效了,因为单引号被转义了,但是还有办法:

/articles.php?id=0 union select 1,2,load_file(char(47,101,116,99,47,112,97,115,115,119,100))

其中的数字就是/etc/passwd字符串的ascii:字符串每个字符循环输出ord(...)

除此以为,还可以使用字符串的十六进制:字符串每个字符循环输出dechex(ord(...))

/articles.php?id=0 union select 1,2,load_file(0x2f6574632f706173737764)

这里仅仅说了数字型参数的几种攻击手段,属于冰山一角,字符串型参数等攻击手段看后面的文档链接。

防守:

网络上有一些类似sql injection firewall的软件可供使用,比如说greensql,如果网站已经开始遭受sql injection攻击,那么使用这样的快捷工具往往会救你一命,不过这样的软件在架构上属于一个proxy的角色,多半会影响网站并发性能,所以在选择与否这个问题上最好视客观条件来慎重决定。很多时候专业的软件并不是必须的,还有很多轻量级解决方案,下面演示一下如何使用awk来检测可能的漏洞。

创建detect_sql_injection.awk脚本,内容如下(如果要拷贝一下内容的话记得不要包括行号):

01 #!/bin/gawk -f
02
03 /\$_(getpostcookierequest)\s*\[/ {
04     ignorecase = 1
05     if (match($0, /\$.*(sqlquery)/)) {
06         ignorecase = 0
07         output()
08         next
09     }
10 }
11
12 function output()
13 {
14     $1 = $1
15     print "crud: " $0 "\nfile: " filename "\nline: " fnr "\n"
16 }


此脚本可匹配出类似如下的问题代码,想要扩展匹配模式也容易,只要照猫画虎写if match语句即可。

1:$sql = "select * from users where username = '{$_post['username']}'";
2:$res = mysql_query("select * from users where username = '{$_post['username']}'");


使用前别忘了先chmod +x detect_sql_injection.awk,有两种调用方法:

1:./detect_sql_injection.awk /path/to/php/script/file
2:find /path/to/php/script/directory -name "*.php" xargs ./detect_sql_injection.awk


会把有问题的代码信息显示出来,样子如下:

crud: $sql = "select * from users where username = '{$_post['username']}'";
file: /path/to/file.php
line: 123


现实环境中有很多应用这个脚本的方法,比如说通过cron定期扫描程序源文件,或者在svn提交时通过钩子方法自动匹配。

使用专业工具也好,检测脚本亦罢,都是被动的防守,问题的根本始终取决于在程序员头脑里是否有必要的安全意识,下面是一些必须要牢记的准则:

1:数字型参数使用类似intval,floatval这样的方法强制过滤。
2:字符串型参数使用类似mysql_real_escape_string这样的方法强制过滤,而不是简单的addslashes。
3:最好抛弃mysql_query这样的拼接sql查询方式,尽可能使用pdo的prepare绑定方式。
4:使用rewrite技术隐藏真实脚本及参数的信息,通过rewrite正则也能过滤可疑的参数。
5:关闭错误提示,不给攻击者提供敏感信息:display_errors=off。
6:以日志的方式记录错误信息:log_errors=on和error_log=filename,定期排查,web日志最好也查。
7:不要用具有file权限的账号(比如root)连接mysql,这样就屏蔽了load_file等危险函数。
8:......

网站安全其实并不复杂,总结出来就是一句话:过滤输入,转义输出。其中,我们上面一直讨论的sql injection问题就属于过滤输入问题,至于转义输出问题,其代表是cross-site scripting,但它不属于本文的范畴,就不多说了。

文档:

addslashes() versus mysql_real_escape_string()
sql injection with mysql
advanced sql injection with mysql
mysql注入中导出字段内容的研究——通过注入导出webshell

"\nfile: " filename "\nline: " fnr "\n"
16 }


此脚本可匹配出类似如下的问题代码,想要扩展匹配模式也容易,只要照猫画虎写if match语句即可。

1:$sql = "select * from users where username = '{$_post['username']}'";
2:$res = mysql_query("select * from users where username = '{$_post['username']}'");


使用前别忘了先chmod +x detect_sql_injection.awk,有两种调用方法:

1:./detect_sql_injection.awk /path/to/php/script/file
2:find /path/to/php/script/directory -name "*.php" xargs ./detect_sql_injection.awk


会把有问题的代码信息显示出来,样子如下:

crud: $sql = "select * from users where username = '{$_post['username']}'";
file: /path/to/file.php
line: 123


现实环境中有很多应用这个脚本的方法,比如说通过cron定期扫描程序源文件,或者在svn提交时通过钩子方法自动匹配。

使用专业工具也好,检测脚本亦罢,都是被动的防守,问题的根本始终取决于在程序员头脑里是否有必要的安全意识,下面是一些必须要牢记的准则:

1:数字型参数使用类似intval,floatval这样的方法强制过滤。
2:字符串型参数使用类似mysql_real_escape_string这样的方法强制过滤,而不是简单的addslashes。
3:最好抛弃mysql_query这样的拼接sql查询方式,尽可能使用pdo的prepare绑定方式。
4:使用rewrite技术隐藏真实脚本及参数的信息,通过rewrite正则也能过滤可疑的参数。
5:关闭错误提示,不给攻击者提供敏感信息:display_errors=off。
6:以日志的方式记录错误信息:log_errors=on和error_log=filename,定期排查,web日志最好也查。
7:不要用具有file权限的账号(比如root)连接mysql,这样就屏蔽了load_file等危险函数。
8:......

网站安全其实并不复杂,总结出来就是一句话:过滤输入,转义输出。其中,我们上面一直讨论的sql injection问题就属于过滤输入问题,至于转义输出问题,其代表是cross-site scripting,但它不属于本文的范畴,就不多说了。

文档:

addslashes() versus mysql_real_escape_string()
sql injection with mysql
advanced sql injection with mysql
mysql注入中导出字段内容的研究——通过注入导出webshell

DouPHP轻量级外贸商城系统
DouPHP轻量级外贸商城系统

DouPHP模块化企业网站管理系统是一款轻量级企业网站管理系统,基于PHP+MYSQL架构的,包含“手机版”、“公众号管理模块”、“小程序”,可以使用它快速搭建一个企业网站。 DouPHP功能特色: (模块全部免费,一键安装) 功能性模块:防伪查询模块、投票模块、自定义表单模块、工单模块等、会员模块、订单模块、视频模块、下载模块、图片模块等; 企业官网模块:业务范围

下载



PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

61

2026.02.06

java多线程方法汇总
java多线程方法汇总

本专题整合了java多线程面试题、实现函数、执行并发相关内容,阅读专题下面的文章了解更多详细内容。

28

2026.02.06

1688阿里巴巴货源平台入口与批发采购指南
1688阿里巴巴货源平台入口与批发采购指南

本专题整理了1688阿里巴巴批发进货平台的最新入口地址与在线采购指南,帮助用户快速找到官方网站入口,了解如何进行批发采购、货源选择以及厂家直销等功能,提升采购效率与平台使用体验。

446

2026.02.06

快手网页版入口与电脑端使用指南 快手官方短视频观看入口
快手网页版入口与电脑端使用指南 快手官方短视频观看入口

本专题汇总了快手网页版的最新入口地址和电脑版使用方法,详细提供快手官网直接访问链接、网页端操作教程,以及如何无需下载安装直接观看短视频的方式,帮助用户轻松浏览和观看快手短视频内容。

258

2026.02.06

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

18

2026.02.06

Python 微服务架构与 FastAPI 框架
Python 微服务架构与 FastAPI 框架

本专题系统讲解 Python 微服务架构设计与 FastAPI 框架应用,涵盖 FastAPI 的快速开发、路由与依赖注入、数据模型验证、API 文档自动生成、OAuth2 与 JWT 身份验证、异步支持、部署与扩展等。通过实际案例,帮助学习者掌握 使用 FastAPI 构建高效、可扩展的微服务应用,提高服务响应速度与系统可维护性。

9

2026.02.06

JavaScript 异步编程与事件驱动架构
JavaScript 异步编程与事件驱动架构

本专题深入讲解 JavaScript 异步编程与事件驱动架构,涵盖 Promise、async/await、事件循环机制、回调函数、任务队列与微任务队列、以及如何设计高效的异步应用架构。通过多个实际示例,帮助开发者掌握 如何处理复杂异步操作,并利用事件驱动设计模式构建高效、响应式应用。

12

2026.02.06

java连接字符串方法汇总
java连接字符串方法汇总

本专题整合了java连接字符串教程合集,阅读专题下面的文章了解更多详细操作。

67

2026.02.05

java中fail含义
java中fail含义

本专题整合了java中fail的含义、作用相关内容,阅读专题下面的文章了解更多详细内容。

30

2026.02.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 16.2万人学习

Pandas 教程
Pandas 教程

共15课时 | 1万人学习

C# 教程
C# 教程

共94课时 | 8.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号