Skip to content

Instantly share code, notes, and snippets.

@speeddragon
Last active November 24, 2018 11:23
Show Gist options
  • Save speeddragon/69a6fc9ea204b6b9be817ffc166f8c66 to your computer and use it in GitHub Desktop.
Save speeddragon/69a6fc9ea204b6b9be817ffc166f8c66 to your computer and use it in GitHub Desktop.
bSidesLisbon CTF
from ecdsa import SigningKey
from ecdsa import VerifyingKey
import ecdsa
from ecdsa.numbertheory import inverse_mod
import hashlib
import binascii
import base64
import httplib
sessid = "6621a96c7db568374f2885d6d135f395010e75a94ec2233a433ff8e2"
curve_order = ecdsa.curves.NIST192p.order
# Other curves: PRIME192v1, secp224r1, prime256v1, SECP384r1, and secp521r1 , SECP256k1
def string_to_number(tstr):
return int(binascii.hexlify(tstr), 16)
def sha1(content):
sha1_hash = hashlib.sha1()
sha1_hash.update(content)
return sha1_hash.digest()
def recover_key(c1, sig1, c2, sig2):
n = curve_order
# cut up the strings before we convert to number!
s1 = string_to_number(sig1[-24:])
s2 = string_to_number(sig2[-24:])
r = string_to_number(sig1[-48:-24])
print "r: " + str(r)
print "R values match: " + str(string_to_number(sig2[-48:-24]) == r)
z1 = string_to_number(sha1(c1))
z2 = string_to_number(sha1(c2))
# solve
sdelta_inv = inverse_mod(((s1-s2)%n),n)
k = ( ((z1-z2)%n) * sdelta_inv) % n
inverse_r = inverse_mod(r,n)
da = (((((s1*k) %n) -z1) %n) * inverse_r) % n
print "n: " + str(n)
print "da: " + str(da)
recovered_private_key = SigningKey.from_secret_exponent(da, curve=ecdsa.curves.NIST192p)
return recovered_private_key.to_pem()
def make_request(signature):
struct = "{\"auth\": {\"sessid\": \"" + sessid + "\", \"user\": \"anonymous\"}, \"sign\": {\"ECDSA\": \"" + signature + "\"}}"
print "Struct:"
print struct
struct_b64 = base64.b64encode(struct)
headers = {"Content-type": "application/x-www-form-urlencoded", "Cookie": "auth=" + struct_b64 + "; sessid=" + sessid}
params = urllib.urlencode({'username': 'admin', 'password': 'admin', 'submit': ''})
c = httplib.HTTPSConnection("quals.bsideslisbon.org")
c.request("POST", "/4D4DA3EE778A4170D336DED21FCB1DAA/", params, headers)
response = c.getresponse()
print "Server Response:"
print response.status, response.reason
print response.read()
if __name__ == "__main__":
sessid1 = '6621a96c7db568374f2885d6d135f395010e75a94ec2233a433ff8e2'
user1 = 'anonymous'
challenge1 = "{\"sessid\": \"" + sessid1 + "\", \"user\": \"" + user1 + "\"}"
sig1 = '''
yknlPaDhkiufqzU5figrZ4cZ1nI87rH/zcCHDV2rLJ6nhdjE9vzblfpkzrhqzVjY
'''.strip()
sessid2 = '9027072a68c41cf9fcaa92672091f7184b13b577924408ed25d971a5'
user2 = 'anonymous'
challenge2 = "{\"sessid\": \"" + sessid2 + "\", \"user\": \"" + user2 + "\"}"
sig2 = '''
yknlPaDhkiufqzU5figrZ4cZ1nI87rH/h9DI/NbP5Mk+XGpYdJHWvJCXToXsMhP6
'''.strip()
key = recover_key(challenge1,base64.b64decode(sig1),challenge2,base64.b64decode(sig2))
print key
#create the signature
sk = SigningKey.from_pem(key)
challenge = "{\"sessid\": \"" + sessid1 + "\", \"user\": \"" + user1 + "\"}"
vk = sk.get_verifying_key()
signature = sk.sign(challenge)
try:
# because who trusts python
vk.verify(signature, challenge)
print "good signature"
except BadSignatureError:
print "BAD SIGNATURE"
encoded_signature = base64.b64encode(signature)
print(encoded_signature)
make_request(encoded_signature)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment