Задание представляет из себя исполняемый ELF, написанный на Go. В нем пользователю предлагают ввести seed для рандома и флаг. Затем выводят набор из 20 слов в качестве подсказки.
Открываем бинарь в любимом виде и понимаем, что:
- Флаг зашифрован AES-CFB с ключем и IV, сгенерированными на основе введенного seed.
- Слова выбираются из массива из 115 слов с индексом rand.Randn(115).
- Если ввести seed из шаблона (1337000900080091), то он выводит зашифрованный AES флаг и набор слов, для исходного seed.
То есть нам необходимо восстановить сид, с которым все это дело было зашифровано.
Восстанавливаем набор получаемых чисел (индексов слов) и смотрим в исходниках golang, что seed в самом начале берётся по модулю 2**31 - 1, значит нам достаточно сбрутить достаточно мало значений.
Программа, подбирающая seed. В ней мы перебираем seed до тех пор, пока первые 20 rand.Intn(115)
не будут равны исходным.
package main
import (
"fmt"
"math/rand"
)
func main() {
nums := []int{15,53,109,65,58,1,88,110,13,49,30,79,55,114,29,102,91,84,20,33}
fmt.Println(nums)
arr := []byte("000000000000000000000000000000000000000000000000")
for i := 1; i < (1 << 31); i++ {
if (i % 1000000 == 0) {
fmt.Println(i)
}
rand.Seed(int64(i))
rand.Read(arr)
flag := true
for num := range nums {
if rand.Intn(115) != num {
flag = false
break
}
}
if flag == true {
fmt.Println("Success")
fmt.Println(i)
break
}
}
}
Брутим сид, расшифровываем флаг.