使用腾讯混元LLM辅助红队代码能力建设

对于我,一个有一点 golang 基础底子但不多的人,有时候想写点代码但是苦于脑中没有构思和对应库的详细使用经验,因此在开发过程中需要耗费大量的时间精力去百度查看文档。

机缘巧合下发现腾讯的混元大模型有代码生成和解释的能力,便尝试着使用该大模型来提高自己的代码能力,创造出一些适合自己的基础建设。

混元大模型地址:https://hunyuan.tencent.com

指纹识别

近期刚好需要开始铺设一条自动化发现和利用的基础架构,正好借着这个大模型来辅助开发。

我向混元进行提问:

用golang帮我编写一个Web指纹识别器,要求读取urls.txt中的URL地址并批量进行指纹识别,识别前会先发送HEAD请求进行存活探测,然后将识别到的内容输出

返回了一个代码片段,并给这段代码做出了解释:

package main
import (
    "bufio"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "strings"
)
func main() {
    file, err: = os.Open("urls.txt")
    if err != nil {
        fmt.Println("Error opening file:", err)
        return
    }
    defer file.Close()
    scanner: = bufio.NewScanner(file)
    for scanner.Scan() {
        url: = scanner.Text()
        if isAlive(url) {
            fingerprint: = getFingerprint(url)
            fmt.Printf("URL: %snFingerprint: %snn", url,
                fingerprint)
        } else {
            fmt.Printf("URL: %s is not alivenn", url)
        }
    }
    if err: = scanner.Err();
    err != nil {
        fmt.Println("Error reading file:", err)
    }
}
func isAlive(url string) bool {
    client: = & http.Client {}
    req,
    _: = http.NewRequest("HEAD", url, nil)
    resp,
    err: = client.Do(req)
    if err != nil {
        return false
    }
    defer resp.Body.Close()
    return resp.StatusCode == http.StatusOK
}
func getFingerprint(url string) string {
    client: = & http.Client {}
    req,
    _: = http.NewRequest("GET", url, nil)
    resp,
    err: = client.Do(req)
    if err != nil {
        return ""
    }
    defer resp.Body.Close()
    body,
    err: = ioutil.ReadAll(resp.Body)
    if err != nil {
        return ""
    }
    return strings.Join(strings.Fields(string(body)), " ")
}

使用腾讯混元LLM辅助红队代码能力建设

我仔细看了一下生成的这个代码,可以说是把我的需求实现的非常准确!

但由于我没有告诉它如何识别指纹,因此这个 getFingerprint 函数的返回还不够细化,接着继续问:

我还需要一个finger.json的规则库,里面有必须存在的Path字段设置了该匹配什么URI路径,必须设置 的匹配类型字段Type可以选择MD5、HTTP状态码、响应Body中的正则字符串、网站标题的Title、 Cookie名称、某个响应的Header头,且还需要一个operator字段设置”or”或者”and”值,用于判断匹配 类型是满足其中一个还是都需要满足,请生成这样的json文件内容。

返回了一个 JSON 内容

{
  "rules": [
    {
      "name""Rule 1",
      "path""/example1",
      "operator""and",
      "matches": [
        {
          "type""md5",
          "value""abcd1234"
        },
        {
          "type""status_code",
          "value": 200
        },
        {
          "type""regex",
          "value""example regex"
        },
        {
          "type""title",
          "value""Example Title"
        },
        {
          "type""cookie",
          "name""cookie_name",
          "operator""exists"
        },
        {
          "type""header",
          "name""X-Custom-Header",
          "value""custom_value"
        }
      ]
    }
  ]
}

同时给出修饰:

使用腾讯混元LLM辅助红队代码能力建设

生成了 JSON 文件,自然就需要让大模型为我们修改之前的代码

根据这个JSON,我需要解析该finger.json文件,同时修改getFingerprint函数的内容,批量请求Json 中Path字段指定的地址并根据对应的type类型进行匹配

返回的结果也很有意思

package utils
import (
    "bytes"
    "crypto/md5"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "regexp"
    "strings"
    "sync"
    "github.com/PuerkitoBio/goquery"
)

type Fingerprint struct {
    Name string `json:"name"`
    Path string `json:"path"`
    Operator string `json:"operator"`
    Matches[] Match `json:"matches"`
}

type Match struct {
    Type string `json:"type"`
    Value string `json:"value,omitempty"`
    Name string `json:"name,omitempty"`
}

func main() {
    jsonFile, err: = os.Open("finger.json")
    if err != nil {
        fmt.Println(err)
        return
    }

    defer jsonFile.Close()

    byteValue, _: = ioutil.ReadAll(jsonFile)
    var fingerprints[] Fingerprint
    json.Unmarshal(byteValue, & fingerprints)

    var wg sync.WaitGroup
    for _, fingerprint: = range fingerprints {
        wg.Add(1)
        go func(fingerprint Fingerprint) {
            defer wg.Done()
            result: = getFingerprint(fingerprint)
            fmt.Printf("Result for %s: %vn", fingerprint.Name, result)
        }(fingerprint)
    }

    wg.Wait()
}

func getFingerprint(fingerprint Fingerprint) bool {
        client: = & http.Client {
            CheckRedirect: func(req * http.Request, via[] * http.Request) error {
                return http.ErrUseLastResponse
            },
        }

            targetURL: = "http://example.com" + fingerprint.Path
        req,
        err: = http.NewRequest("GET", targetURL, nil)
        if err != nil {
            return false
        }

        req.Header.Set("User-Agent""Mozilla/5.0 (Windows NT 10.0; Win64; x64)
            AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 58.0.3029.110 Safari / 537.3 "


            resp, err: = client.Do(req) if err != nil {
                return false
            }

            defer resp.Body.Close()

            body, err: = ioutil.ReadAll(resp.Body) if err != nil {
                return false
            }

            doc, err: = goquery.NewDocumentFromReader(bytes.NewReader(body)) if err != nil {
                return false
            }

            var results[] bool
            for _, match: = range fingerprint.Matches {
                result: = false
                switch match.Type {
                    case "md5":
                        result = checkMD5(body, match.Value)
                    case "status_code":
                        result = checkStatusCode(resp, match.Value)
                    case "regex":
                        result = checkRegex(string(body), match.Value)
                    case "title":
                        result = checkTitle(doc, match.Value)
                    case "cookie":
                        result = checkCookie(resp, match.Name, match.Operator)
                    case "header":
                        result = checkHeader(resp, match.Name, match.Value, match.Operator)
                }
                results = append(results, result)
            }

            if fingerprint.Operator == "and" {
                for _, result: = range results {
                    if !result {
                        return false
                    }
                }
                return true
            } else if fingerprint.Operator == "or" {
                for _, result: = range results {
                    if result {
                        return true
                    }
                }
                return false
            }

            return false
        }

        func checkMD5(body[] byte, expectedMD5 string) bool {
            return fmt.Sprintf("%x", md5.Sum(body)) == expectedMD5
        }

        func checkStatusCode(resp * http.Response, expectedStatusCode string) bool {
            return fmt.Sprint(resp.StatusCode) == expectedStatusCode
        }

        func checkRegex(body string, regex string) bool {
            matched, err: = regexp.MatchString(regex, body)
            if err != nil {
                return false
            }
            其实大致上功能逻辑都没问题, 但还是存在有少部分地方需要修改, 如结构体Matchs中没有
            Operator, 大模型给误识别到。
            还有一处是resp.Cookie, 但是这个 * http.Response是没有Cookie字段, 因为这里其实就是
            return matched
        }

        func checkTitle(doc * goquery.Document, expectedTitle string) bool {
            title: = doc.Find("title").Text()
            return title == expectedTitle
        }

        func checkCookie(resp * http.Response, cookieName string, operator string) bool {
            cookie, err: = resp.Cookie(cookieName)
            if err != nil {
                return false
            }

            switch operator {
                case "exists":
                    return true
                case "not_exists":
                    return false
                default:
                    return false
            }
        }

        func checkHeader(resp * http.Response, headerName string, expectedValue string,
            operator string) bool {
            headerValue: = resp.Header.Get(headerName)

            switch operator {
                case "equals":
                    return headerValue == expectedValue
                case "not_equals":
                    return headerValue != expectedValue
                case "contains":
                    return strings.Contains(headerValue, expectedValue)
                case "not_contains":
                    return !strings.Contains(headerValue, expectedValue)
                default:
                    return false
            }
        }

其实大致上功能逻辑都没问题,但还是存在有少部分地方需要修改,如结构体 Matchs 中没有 Operator,大模型给误识别到。

还有一处是 resp.Cookie,但是这个 *http.Response 是没有 Cookie 字段,因为这里其实就是 Header 头中的 Set-Cookie 字段。

使用腾讯混元LLM辅助红队代码能力建设

于是我让混元大模型继续帮我修改问题:

func checkCookie(resp * http.Response, cookieName string, operator string) bool {
    setCookieHeader: = resp.Header.Get("Set-Cookie")
    if setCookieHeader == "" {
        return false
    }

    switch operator {
        case "exists":
            return strings.Contains(setCookieHeader, cookieName)
        case "not_exists":
            return !strings.Contains(setCookieHeader, cookieName)
        default:
            return false
    }
}

之后稍微检查一下逻辑并与之前的代码跑通就可以开始进行测试

有缺漏的地方也可以直接交给大模型继续修复

使用腾讯混元LLM辅助红队代码能力建设

// 创建 Rules 结构体实例
      var rules Rules
// 使用 Unmarshal 函数将 JSON 数据反序列化为 Rules 结构体实例
err: = json.Unmarshal([] byte(jsonData), & rules)
if err != nil {
    fmt.Println("反序列化失败:", err)
    return
}

运行测试

编写完成之后,就可以开始跑程序进行测试,由于 url 是需要批量的,因此肯定会用到协程的方式

完成任务。但是这个根据服务器或者机器的性能区别,要设置一个信号量在短时间内设置并发数量。

我用goroutine执行任务的时候,给它设置一个信号量,只允许最大并发数量10个线程来处理任务,请给 出代码

返回 demo 如下:

package main
import (
    "fmt"
    "sync"
)
// 定义一个信号量类型
type Semaphore struct {
    ch chan struct {}
}
// 创建一个新的信号量实例,并设置最大并发数量
func NewSemaphore(maxConcurrency int) * Semaphore {
        return &Semaphore {
            ch: make(chan struct {}, maxConcurrency)
        }
    }
    // 获取信号量
func(s * Semaphore) Acquire() {
        s.ch < -struct {} {}
    }
    // 释放信号量
func(s * Semaphore) Release() { < -s.ch
    }
    // 任务函数
func task(i int, wg * sync.WaitGroup, sem * Semaphore) {
    defer wg.Done()
    sem.Acquire() // 获取信号量
    fmt.Printf("Task %d startedn", i)
        // 模拟任务执行时间
    time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
    fmt.Printf("Task %d finishedn", i)
    sem.Release() // 释放信号量
}
func main() {
    maxConcurrency: = 10
    numTasks: = 20
        // 创建一个新的信号量实例
    sem: = NewSemaphore(maxConcurrency)
    var wg sync.WaitGroup
    wg.Add(numTasks)
    // 使用goroutine执行任务
    for i: = 0;i < numTasks;i++{
        go task(i, & wg, sem)
    }
    // 等待所有任务完成
    wg.Wait()
}

其实这里返回的代码虽然可以,但 golang 官方其实有类似的库 "golang.org/x/sync/semaphore"

关键代码如下所示:

var sem = semaphore.NewWeighted(10)
wg.Add(1)
go func(url string) {
    defer wg.Done()
    sem.Acquire(context.Background(), 1)
    defer sem.Release(1)
    fingerprint, isHave: = utils.GetFingerprint(url)
    if isHave {
        log.Printf("[+] URL: %s FingerPrint: %s", url, fingerprint)
    } else {
        log.Printf("[-] URL: %s not found fingerprint.", url)
    }
}(url)

使用腾讯混元LLM辅助红队代码能力建设

这里也能通过规则正确识别出来

扩展功能

有了这个,每次还需要写 json 感觉很麻烦,就接着问大模型让它帮我生成一个批量添加的

{ “rules”: [ { “name”: “Tencent OpenSource”, “path”: “/”, “condition”: “and”,”matches”: [ { “type”: “status_code”, “value”: “200” }, { “type”: “title”, “value”: “腾讯开源 | Tencent Open Source” } ] } } 


根据上面的Json内容编写一个命令行生成工具,循环挨个询问每个字段需要填入的内容,最后输出完整 的JSON

给我生成了一个命令行的输出工具

package main
import (
    "encoding/json"
    "fmt"
)
type Rule struct {
    Name string `json:"name"`
    Path string `json:"path"`
    Condition string `json:"condition"`
    Matches[] Match `json:"matches"`
}
type Match struct {
    Type string `json:"type"`
    Value string `json:"value"`
}
func main() {
    var rules[] Rule
    for {
        var rule Rule
        fmt.Print("Enter rule name (or 'done' to finish): ")
        var name string
        fmt.Scanln( & name)
        if name == "done" {
            break
        }
        rule.Name = name
        fmt.Print("Enter path: ")
        fmt.Scanln( & rule.Path)
        fmt.Print("Enter condition (and/or): ")
        fmt.Scanln( & rule.Condition)
        for {
            var match Match
            fmt.Print("Enter match type (or 'done' to finish): ")
            var matchType string
            fmt.Scanln( & matchType)
            if matchType == "done" {
                break
            }
            match.Type = matchType
            fmt.Print("Enter match value: ")
            fmt.Scanln( & match.Value)
            rule.Matches = append(rule.Matches, match)
        }
        rules = append(rules, rule)
    }
    jsonData, err: = json.MarshalIndent(rules, """ ")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Generated JSON:")
    fmt.Println(string(jsonData))
}

我测试了一下,除了生成的 json 格式没有外面的 rule 标签之外,还是挺正确的

使用腾讯混元LLM辅助红队代码能力建设

总结

总体来说,我感觉借助大模型和自己的一些能看懂代码的基础上进行开发,完全是可以满足日常的需求,包括自己想实现什么样的功能都可以直接从大模型上进行询问、设计。

从个人的角度来说,很多时候开发只是需要满足某个功能点,可以让它先给出一个需求的大致实现,再慢慢询问优化,同时结合自己的一些主观想法做引导,最后再完善修改就能在提高开发效率的基础上达到准确的需求实现。


使用腾讯混元LLM辅助红队代码能力建设

关注公众号后台回复 0001 领取域渗透思维导图,0002 领取VMware 17永久激活码,0003 获取SGK地址,0004 获取在线ChatGPT地址,0005 获取 Windows10渗透集成环境0006 获取 CobaltStrike 4.9.1破解版


加我微信好友,邀请你进交流群


使用腾讯混元LLM辅助红队代码能力建设




往期推荐



对某金融App的加解密hook+rpc+绕过SSLPinning抓包

疑似境外黑客组织对CSDN、吾爱破解、bilibili等网站发起DDoS攻击

Fofa新产品 – 绕CDN溯源真实IP!

Cobalt Strike 4.8 正式发布上线!

团队在线Windows进程识别正式内测

突发!微信疑似存在RCE

APT29利用CVE-2023-38831攻击大使馆

某次以目的为导向的内网渗透-取开发源码

微信PC客户端存在@全体逻辑错误

对某app的加密定位与hook

《永结无间》客户端RCE漏洞

NSA组织”二次约会”间谍软件功能复现及加解密分析

发现新恶意团伙”紫狐”!针对finalshell的供应链事件

记一次渗透中因为JS拿下整个云

APK逆向分析入门-以某车载音乐APP为例

备用号,欢迎关注


使用腾讯混元LLM辅助红队代码能力建设

​​​​​

原文始发于微信公众号(刨洞安全团队):使用腾讯混元LLM辅助红队代码能力建设

版权声明:admin 发表于 2023年11月30日 下午11:41。
转载请注明:使用腾讯混元LLM辅助红队代码能力建设 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...