应用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
- 爆破后四位
答案
- 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
- 例如计算:
- 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
|