吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 944|回复: 7
收起左侧

[其他原创] 应用GO语言协程,高效解决ctf中MD5以及sha256爆破问题

[复制链接]
Twilightl 发表于 2023-7-28 16:04

应用GO语言协程,高效解决ctf中MD5以及sha256爆破问题

例题BUUCTF:rot

题目

  • 破解下面的密文:
  • 83 89 78 84 45 86 96 45 115 121 110 116 136 132 132 132 108 128 117 118 134 110 123 111 110 127 108 112 124 122 108 118 128 108 131 114 127 134 108 116 124 124 113 108 76 76 76 76 138 23 90 81 66 71 64 69 114 65 112 64 66 63 69 61 70 114 62 66 61 62 69 67 70 63 61 110 110 112 64 68 62 70 61 112 111 112
  • flag格式flag{}

要点

  • 参考rot原理,将所有的数字 -13 后,再转ascii码
    • FLAG IS flag{www_shiyanbar_com_is_verygood????}
    • MD5:38e4c352809e150186920aac37190cbc
  • 爆破后四位
    • 使用go语言爆破

答案

  • flag{www_shiyanbar_com_is_verygood@8Mu}

代码

  • 源代码
package main
import (
    "crypto/md5"
    "fmt"
    "math"
    "strings"
    "time"
)
func MD5(str string) string {
    data := []byte(str) //切片
    has := md5.Sum(data)
    md5str := fmt.Sprintf("%x", has) //将[]byte转成16进制
    return md5str
}
var ans = make(chan string)
var count, sum int = 0, 0
var flag int = 0
func f(s string, com string, cnt int) {
    cnt--
    for i := 33; i <= 126; i++ {
        temp_s := strings.Replace(s, "?", fmt.Sprintf("%c", i), 1)
        if cnt == 0 {
            count++
            str := MD5(temp_s)
            if str == com {
                flag = 1
                ans <- temp_s
                return
            }
        } else {
            go f(temp_s, com, cnt)
        }
    }
}
func main() {
    s := "flag{www_shiyanbar_com_is_very_good_????}"//待爆破字符串
    com := "38e4c352809e150186920aac37190cbc"//目标MD5
    num := int(0)
    for i := 0; i < len(s); i++ {
        if s[i] == '?' {
            num++
        }
    }//计算未知位置数量
    sum = int(math.Pow((126 - 33 + 1), float64(num)))
    go f(s, com, 4)//创建协程
    var sec int = 0
    for flag != 1 {//flag!=1表示爆破完成
        sec++
        fmt.Println(count, "/", sum, ":", flag)
        time.Sleep(1 * time.Second)
    }
    fmt.Println(count, "/", sum, ":", <-ans)
    fmt.Print("Time:", sec)
}
  • 运行结果如下:
Starting: D:\lenovo\VSCode\Go\bin\dlv.exe dap --listen=127.0.0.1:8737 from D:\lenovo\VSCode\CTF\buuctf_crypto\5.8\rot
DAP server listening at: 127.0.0.1:8737
Type 'dlv help' for list of commands.
0 / 78074896 : 0
9089074 / 78074896 : 0
18553168 / 78074896 : 0
25049890 / 78074896 : 0
32998255 / 78074896 : 0
40769957 / 78074896 : 0
48668620 / 78074896 : flag{www_shiyanbar_com_is_very_good_@8Mu}
Time:6
Process 25280 has exited with status 0
Detaching
  • 代码中包含一个不太严谨的计时器以及爆破进度条,仅供参考。

    延伸

  • 类似的对于sha256爆破也可以使用几乎相同的代码
  • 仅需修改计算模块:
    import (
    "crypto/sha256"//添加
    "encoding/hex"//添加
    "fmt"
    "math"
    "strings"
    "time"
    )
    func sha(str string) string {
    h := sha256.New()
    h.Write([]byte(str))
    a := h.Sum(nil)
    hashCode2 := hex.EncodeToString(a[:]) //将数组转换成切片,转换成16进制,返回字符串
    return hashCode2
    }
  • f函数中将计算过程调用的函数从MD5换为sha
    • 替换为str := sha(temp_s)
  • 例如计算:
    • s := "????" + "teilcm0NyiScbzKQ"
    • com := "71cee1525a232a1b6e828d85fa14d089d323b6af6a64d5454a12192382258aab"
  • 结果为:
    Starting: D:\lenovo\VSCode\Go\bin\dlv.exe dap --listen=127.0.0.1:9012 from D:\lenovo\VSCode\CTF\ciscn\1
    DAP server listening at: 127.0.0.1:9012
    Type 'dlv help' for list of commands.
    0 / 78074896 : 0
    5764073 / 78074896 : 0
    20661477 / 78074896 : 0
    29663447 / 78074896 : 0
    38204353 / 78074896 : 0
    45519550 / 78074896 : 0
    52308375 / 78074896 : 0
    59639937 / 78074896 : QVNtteilcm0NyiScbzKQ
    Time:7 115

免费评分

参与人数 3威望 +1 吾爱币 +11 热心值 +3 收起 理由
苏紫方璇 + 1 + 10 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
hrh123 + 1 用心讨论,共获提升!
liufeisvip + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

高维可破 发表于 2023-7-28 18:01
不明白对于这种计算瓶颈的任务,楼主使用协程的目的和意义是什么
 楼主| Twilightl 发表于 2023-7-28 21:42
高维可破 发表于 2023-7-28 18:01
不明白对于这种计算瓶颈的任务,楼主使用协程的目的和意义是什么

本来写的是python多线程,不太会写Python的多线程,不太稳定。
用go的协程变相实现多线程,加快枚举爆破速度。
高维可破 发表于 2023-7-28 21:56
本帖最后由 高维可破 于 2023-7-28 21:57 编辑
Twilightl 发表于 2023-7-28 21:42
本来写的是python多线程,不太会写Python的多线程,不太稳定。
用go的协程变相实现多线程,加快枚举爆破 ...

协程提高的是并发量
对计算瓶颈场景下起不了多大作用
起作用的应该是提高并行计算量

另外go的协程会自动启动多线程? 还是只在一个线程上模拟?
 楼主| Twilightl 发表于 2023-7-28 23:34
高维可破 发表于 2023-7-28 21:56
协程提高的是并发量
对计算瓶颈场景下起不了多大作用
起作用的应该是提高并行计算量

计算过程中对于爆破过程做了优化,对比单线程时直接递归暴力,多线程下可以并行。
比如有两位未知,每一位有10种情况,开始程序就会创建10个协程,直接完成第一位的枚举,然后同时开始下一位的枚举,肯定加快了爆破效率
 楼主| Twilightl 发表于 2023-7-28 23:35
高维可破 发表于 2023-7-28 21:56
协程提高的是并发量
对计算瓶颈场景下起不了多大作用
起作用的应该是提高并行计算量

GO的协程我记得是在一个线程上模拟的,但感觉实际用起来应该是自动多线程了,你可以再查查手册看看。
高维可破 发表于 2023-7-29 06:54
本帖最后由 高维可破 于 2023-7-29 06:57 编辑
Twilightl 发表于 2023-7-28 23:34
计算过程中对于爆破过程做了优化,对比单线程时直接递归暴力,多线程下可以并行。
比如有两位未知,每一 ...

这个是否高效取决于是否在多核上并行运算。
如果只是单线程模拟 这种情况下的协程实际上就是单线程暴力枚举 ,
没有差别 甚至还多出了维护协程的开销

这个也就是我之前提问的原因所在
 楼主| Twilightl 发表于 2023-7-29 12:06
高维可破 发表于 2023-7-29 06:54
这个是否高效取决于是否在多核上并行运算。
如果只是单线程模拟 这种情况下的协程实际上就是单线程暴力 ...

我查到一下两段:
       协程可以理解为轻量级线程,一个线程可以拥有多个协程,与线程相比,协程不受操作系统调度,协程调度器按照调度策略把协程调度到线程中执行,协程调度器由应用程序的runtime包提供,用户使用go关键字即可创建协程,这也就是GO在语言层面直接支持协程的含义。
      由于协程运行在用户态,能够大大减少上下文切换带来的开销,并且协程调度器把可运行的协程逐个调度到线程中执行,同时及时把阻塞的协程调度出线程,从而有效的避免了线程的频繁切换,达到了使用少量的线程实现高并发的效果,但是对于一个线程来说每一时刻只能运行一个协程。

我理解的是运行过程中,可以并行的协程会被放到多个线程中执行。所以协程也是并行运算的。

实际使用中,运算用时比单纯递归爆破快很多。
然后运行时简单的观察win11任务管理器,cpu负载会升到80%以上,线程数会多几百个。
直接递归的话占用小很多,用时也很长。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-2 15:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表