読者です 読者をやめる 読者になる 読者になる

CTF各位1

CTF

10guess (crypto 10)

running at ctf.katsudon.org:5555

package main

import (
	"bufio"
	cr "crypto/rand"
	"crypto/rsa"
	"fmt"
	"log"
	"math/big"
	"math/rand"
	"net"
	"strconv"
)

var seed int64 = ?????

func handleConnection(conn net.Conn) {
	log.Printf("connect: %s", conn.RemoteAddr())
	defer func() {
		log.Printf("close: %s", conn.RemoteAddr())
		conn.Close()
	}()

	priv, err := rsa.GenerateKey(cr.Reader, 2048)
	if err != nil {
		return
	}
	e := big.NewInt(int64(priv.E))

	conn.Write([]byte(fmt.Sprintf("N=%s\n", priv.N.String())))
	conn.Write([]byte(fmt.Sprintf("E=%d\n", priv.E)))

	stage := 1
	reader := bufio.NewReader(conn)
	for {
		conn.Write([]byte(fmt.Sprintf("### %d/10\n", stage)))

		expected := int(rand.Intn(0x10000))

		// encrypt
		c := new(big.Int).Exp(big.NewInt(int64(expected)), e, priv.N)
		conn.Write([]byte("C=" + c.String() + "\nM="))

		ln, err := reader.ReadBytes('\n')
		if err != nil {
			return
		}
		n, err := strconv.Atoi(string(ln[:len(ln)-1]))
		if err != nil {
			return
		}
		if n != expected {
			stage = 0
			continue
		}

		stage++

		if stage > 10 {
			log.Printf("flag: %s", conn.RemoteAddr())
			conn.Write([]byte(fmt.Sprintf("congratz! the flag is: %x\n", seed)))
			return
		} else {
			continue
		}
	}
}

func main() {
	rand.Seed(seed)

	ln, err := net.Listen("tcp", ":5555")
	if err != nil {
		log.Fatal(err)
	}

	for {
		conn, err := ln.Accept()
		if err != nil {
			continue
		}
		go handleConnection(conn)
	}
}