Soal ini nilainya 150 dalam kategori Crypto, soalnya seperti ini:
Kita diberikan source code dalam Python. Intinya adalan: program ini menerima signature dan message, dan akan membalas dengan flag jika signature dan message sudah benar. Kita juga diberi contoh signature dan message yang sudah pernah dikirimkan ke server ini. Server ini tidak akan menerima jika message/signature adalah duplikat dari yang di file sigs.txt.
Bagian terpenting adalah baris-baris berikut:
sig = json.loads(sig)
Kemudian berikut ini pengecekan yang dilakukan:
if "r" not in sig or "s" not in sig or "m" not in sig:
self.request.close()
return
r = sig["r"]
s = sig["s"]
m = sig["m"]
if not elgamal_verify(r, s, m):
self.request.close()
elif is_duplicate(sig):
self.request.close()
elif m != "There is no need to be upset":
self.request.close()
else:
self.request.sendall(FLAG)
self.request.close()
Dan caranya mengecek duplikat adalah dengan:
def is_duplicate(s):
return s in DUPLICATES
Perhatikan bahwa karena formatnya JSON kita bisa menambahkan field lain, dan dengan menambahkan field lain maka apa yang kita kirimkan tidak akan dianggap duplikat. Untuk mencegah orang melakukan brute force, maka server meminta "proof of work" yang meminta kita mencari string 20 karakter (X) dengan prefix 12 karakter yang diberikan, sedemikian sehingga sha1(X) berakhiran dengan 3 heksadesimal ff. Saya memakai cara sederhana brute force dengan menambahkan angka (kadang ini tidak berhasil, jadi perlu diulangi, kadang berhasil dalam sedetik, karena hanya butuh masuk sekali, maka tidak saya optimasi). Berikut ini solusinya.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import hashlib | |
import base64 | |
import sys | |
import socket | |
import struct | |
s = socket.create_connection(("52.0.217.48", 60231)) | |
proof = s.recv(12) | |
print "proof ", proof | |
tosend=None | |
for i in xrange (0,99999999): | |
test = proof + ("%08d" % i) | |
ha = hashlib.sha1() | |
ha.update(test) | |
if ha.digest().endswith('\xFF\xFF\xFF'): | |
print "found ", test | |
tosend = test | |
break | |
if not tosend: | |
print "try again" | |
exit(0) | |
enc = '{"s": 21054468908426331574045415757705596312490608697034679252162205415258689488938792588831531807614306762187107454355496991706280940746682086684651382392894440056488208110510117519357395297916485175485376815711109501315034875521798843436925869757482592549470778789601115554255653914305843242151026272506459011629018207321332425287985213417534380034990214393005755147720206544994968697500781616394595450665975848378431384407629728617806162081729861628808736537317534949224293348236319554315763862173514513324698536191701038439870012572806910098312290000388970881226934180445872436810927891008412644093329663435621581021347, "r": 14556450625812013575484254421723445809678777888922992010061032704679042904146923866457426159198384764425155312389074479869246038712459861363560250202380689697680368931395645962819850774655376322711776181621394119949333235937168169126299818515407603115358673337217251397556879636425925559398418798688723285385352425490135869490681971673314086977191132841003292451662521230410289882511683145128157815153694864096645608834771938938231775760394427067003660948668863059181615823395710566418746839898936118863944244851022473133036526007136492008659921439714025852802299228292891053541064974277813868083959677233126603099132, "m": "There is no need to be upset", "z": 1}' | |
s.send(tosend + enc) | |
print s.recv(8192) | |
print "done" |
Ketika dijalankan:
No comments:
Post a Comment