Skip to content

Instantly share code, notes, and snippets.

@vladvis
Created May 4, 2018 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vladvis/6463547d2432505e54a8be89ce5095c8 to your computer and use it in GitHub Desktop.
Save vladvis/6463547d2432505e54a8be89ce5095c8 to your computer and use it in GitHub Desktop.

Write-up: k3y

Задание представляет из себя исполняемый 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
		}
	}
}

Брутим сид, расшифровываем флаг.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment