4
由于使用编程语言和数据库的不同,漏洞的利用以及所造成的危害也不同。
Sql注入原理
Test.asp文件代码片段:
sqlStr = “select * from n_user where username=‘”&username&”’ and password=‘“&password&”’
rs = conn.execute(sqlStr)
正常的查询:test.asp?username=test&password=123
sqlStr = “select * from n_user where username=‘test’ and password=‘123’“
使password=123 ‘ or ‘1’=‘1:
Sql语句到数据库后:
sqlStr = “select * from n_user where username=‘test’ and password=‘123’ or ‘1’=‘1’“
Or ‘1’=‘1’始终成立。
5
可以通过修改city来构造不同的语句来达到我们查询数据库的效果,现在对于sql注入已经全自动化了,最初出现的工具有原54NB论坛小竹写的NBSI,是最经典的工具了,后来出来了无数的全自动注入工具,在这里就不再赘述了。
Sql二次注入
Update,Insert插入注入语句,通过内部传参进行注入。
Insert users (username)values(’1 and 1=1’)
Select * from users where username =values
6
二次注射原理图
SQL注射
数据库
其他函数[如Include]
构造变量
UPDATA INSERT
提取变量
SELECT
7
Asp表现
存在数字型和字符型注入。
(A) 数字型 字段=51
Select * from 表名 where 字段=51
构造参数:ID=49 And [查询条件]
生成语句:Select * from 表名 where 字段=49 And [查询条件]
(B)字符型的另一种形式
搜索语句:Select * from 表名 where 字段like ’%关键字%’
构造参数:keyword=’ and [查询条件] and ‘%25’=’
生成语句:Select * from 表名 where字段like ’%’ and [查询条件] and ‘%’=’%’
8
Asp注入的预防
对于用户端输入的任意字符,包括GET提交,POST提交,Cookie提交,SERVER提交的都需要做严格过滤。
对于数字型参数判断是否为数字:可用函数isNumeric来判断,返回值为true和false。
对于字符型参数过滤单引号,将其替换为l两个单引号,使其无法闭合当前sql语句的单引号。
例外:base64编码
Sql通用防注入,全局过滤GET、POST
9
Asp防注入过滤demo
Function SafeCheck(strString)
If isNumeric(strString) then
strString=strString
Else
strString=replace(strString,"'","''")
End if
SafeCheck=strString
End function
10
Php中的表现
Php的魔术引号(magic_quotes_gpc ) 。
php.ini-dist 默认是开启此功能。如果安装php时使用此文件,将不会产生字符型注入,主要是数字型注入。
数字型注入:
select * from guess where id=“.$id.”
select * from guess where id=$id
11
魔术引号(Magic Quote)是一个自动将进入 PHP 脚本的数据进行转义的过程。 ,当打开时,所有的 ‘(单引号),“(双引号),\(反斜线)和 NULL 字符都会被自动加上一个反斜线进行转义。
GPC不起作用的情况
二次编码
编码解码引起
Urlencode()/Urldecode
Rawurlencode()/Rawurldecode
Base64_encode()/Base64_decode
mysql处理GBK编码字符%bf%27导致单引号被绕过的问题。
其他数据库,如ms sql。对于转义符反斜杠作为字符处理的。
select * from test where title ='aaa\' or '1'='1‘
12
Php注入的预防(一)
确认GPC开启,若没开启则用addslashes 函数过滤之
function myaddslashes($strString){
if (is_numeric($strString)){
$strString = $strString;
}else{
$strString = addslashes($strString);
}
return $strString;
}
注意mysql的版本以及默认字符集,Mysql>4.1
字符集连接字符串:
mysql_query("SET character_set_connection=$dbcharset,
character_set_results=$dbcharset, character_set_client=binary;");
13
Php注入的预防(二)
Php5以上版本Mysqli扩展预防,参数化查询
$city = "Amersfoort";
/* create a prepared statement */
$stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")
$stmt->bind_param("s", $city);
$stmt->execute();
$stmt->bind_result($district);
$stmt->fetch();
printf("%s is in district %s\n", $city, $district);
$stmt->close();
}
PHP加入的PDO(PHP Data Object)也有预处理。
14
Jsp 表现
由于java语言是强类型语言,所有变量定义前必须声明其类型,因而仅存在字符型的注入。
字符型注入实例:
String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
stmt = conn.prepareStatement(sql);
构造参数varpasswd值为:' or '1' = '1
Sql语句经过解析后将是:
select * from tb_name = '随意' and passwd = '' or '1' = '1';
15
由于j2ee项目有很多持久层框架,在这里仅仅用jdbc来讲解。
Jsp预防
采用jdbc的prepareStatement查询数据库,并且sql语句中不出现参数,如:
sqlStr = “select id from info where city=? and open=? order by id desc”;
stmt = conn.prepareStatement(sqlStr);
stmt.setString(1,city);
stmt.setString(2,var1);
‘ Check the file extension
if right(tFile,4) <> “.bmp” then exit sub
tFile=tFile &".bmp"
Set FSO = Server.CreateObject("Scripting.FileSystemObject")
Set FSOFile=
FSO.CreateTextFile(FSO.BuildPath(Path, tFile))
21
04年,dvbbs出现的上传漏洞。
04年动力文章系统3.6最先暴出来,之后的oblog。
Asp上传漏洞表现(二)
const UpFileType="rar|zip|exe|mpg|rm|wav|mid"
dim EnableUpload
FoundErr=false '默认FoundErr变量为假EnableUpload=false '默认EnableUpload变量为假,即不能上...
for each formName in upload.file
set ofile=upload.file(formName) ‘生成一个文件对象
arrUpFileType=split(UpFileType,“|”) ’允许上传后缀 名
for i=0 to ubound(arrUpFileType)
if fileEXT=trim(arrUpFileType(i)) then
EnableUpload=true ’变量改变了!
exit for
end if
next
if fileEXT="asp" or fileEXT="asa" or fileEXT="aspx" then
EnableUpload=false
end if
if EnableUpload=false then
msg=“这种文件类型不允许上传!\n\n只允许上传这几种文件类型:” & UpFileType
FoundErr=true ‘hoho,FoundErr变量改变了!
end if
22
Asp上传漏洞表现(二)
...
if FoundErr<>true then
randomize
ranNum =int(900*rnd)+100 '生成一个随机数 filename=SavePath& year(now)&month(now)&day(now)&hour(now)&minute(now)&second (now)&ranNum&"."&fileExt '没有改变上传文件的后缀,爽阿
...
ofile.SaveToFile Server.mappath(FileName) '保存文件