Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:0-3.11"

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"python.linting.pylintEnabled": true,
"python.linting.enabled": true
}
220 changes: 140 additions & 80 deletions Btcbf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
import threading
from concurrent.futures import ThreadPoolExecutor
from multiprocessing import cpu_count
from multiprocessing import Manager, Process

if os.path.exists(os.getcwd()+"/cache.txt") == False:
open("cache.txt", "w+")


class Btcbf():

def __init__(self):
self.start_t = 0
self.cores = 0
self.prev_n = 0
self.cur_n = 0
self.start_n = 0
self.end_n = 0
self.seq = False
Expand All @@ -22,80 +24,114 @@ def __init__(self):
load_data = open("address.txt", "r").readlines()
load_data = [x.rstrip() for x in load_data]
# Remove invalid wallet addresses
load_data = [x for x in load_data if x.find('wallet') == -1 and len(x) > 0]
load_data = dict(zip(load_data, load_data))
load_data = [x for x in load_data if x.find(
'wallet') == -1 and len(x) > 0]
load_data = dict(zip(load_data, load_data))
self.load_data = load_data


self.process_list = []
self.manager = Manager()

# Declare threadsafe variables that are sharable across the processes
self.cur_n = self.manager.Value('i', 0)
self.start_t = self.manager.Value('i', 0)

# Whether we use `Process` or `ThreadPoolExecutor` to run the task
self.use_process = False

def speed(self):
while True:
if self.cur_n != 0:
if self.cur_n.value != 0:
cur_t = time()
n = self.cur_n
n = self.cur_n.value
if self.prev_n == 0:
self.prev_n = n
elapsed_t=cur_t-self.start_t
print("current n: "+str(n)+", current rate: "+str(abs(n-self.prev_n)//2)+"/s"+f", elapsed time: [{str(elapsed_t//3600)[:-2]}:{str(elapsed_t//60%60)[:-2]}:{int(elapsed_t%60)}], total: {n-self.start_r} ", end="\r")
elapsed_t = cur_t-self.start_t.value
print("current n: "+str(n)+", current rate: "+str(abs(n-self.prev_n)//2)+"/s" +
f", elapsed time: [{str(elapsed_t//3600)[:-2]}:{str(elapsed_t//60%60)[:-2]}:{int(elapsed_t%60)}], total: {n-self.start_r} ", end="\r")
self.prev_n = n
if self.seq:
open("cache.txt","w").write(f"{self.cur_n}-{self.start_r}-{self.end_n}")
open("cache.txt", "w").write(
f"{self.cur_n.value}-{self.start_r}-{self.end_n}")
sleep(2)

def random_brute(self, n):
self.cur_n=n

def random_brute(self):
key = Key()
if key.address in self.load_data.keys():
print("Wow matching address found!!")
print("Public Adress: "+key.address)
print("Private Key: "+key.to_wif())
f = open("foundkey.txt", "a") # the found privatekey and address saved to "foundkey.txt"
f.write(key.address+"\n")
f.write(key.to_wif()+"\n")
f.close()
sleep(510)
exit()

print("Wow matching address found!!")
print("Public Adress: "+key.address)
print("Private Key: "+key.to_wif())
# the found privatekey and address saved to "foundkey.txt"
f = open("foundkey.txt", "a")
f.write(key.address+"\n")
f.write(key.to_wif()+"\n")
f.close()
sleep(510)
exit()

def random_brute_process(self, cur_n, core_number):
print(f'Starting core {core_number} ... \n')

count = 0
r = range(100000000000000000)
for _ in r:
self.random_brute()

count = count + 1

# Wait until we executed 10000 times, then we will update the variable since updating a threadsafe variable is a big cost
# Doing this, we can improve the performance significantly
if count == 10000:
cur_n.value = cur_n.value + count
count = 0

print("Stopping\n")

def sequential_brute(self, n):
self.cur_n=n
self.cur_n.value = n
key = Key().from_int(n)
if key.address in self.load_data.keys():
print("Wow matching address found!!")
print("Public Adress: "+key.address)
print("Private Key: "+key.to_wif())
f = open("foundkey.txt", "a") # the found privatekey and address saved to "foundkey.txt"
# the found privatekey and address saved to "foundkey.txt"
f = open("foundkey.txt", "a")
f.write(key.address+"\n")
f.write(key.to_wif()+"\n")
f.close()
sleep(500)
exit()



def random_online_brute(self, n):
self.cur_n = n
self.cur_n.value = n
key = Key()
the_page = requests.get("https://blockchain.info/q/getreceivedbyaddress/"+key.address+"/").text
if int(the_page)>0:
the_page = requests.get(
"https://blockchain.info/q/getreceivedbyaddress/"+key.address+"/").text
if int(the_page) > 0:
print(the_page)
print("Wow active address found!!")
print(key.address)
print(key.to_wif())
f = open("foundkey.txt", "a") # the found privatekey and address saved to "foundkey.txt"
# the found privatekey and address saved to "foundkey.txt"
f = open("foundkey.txt", "a")
f.write(key.address+"\n")
f.write(key.to_wif()+"\n")
f.close()
sleep(500)
exit()



def num_of_cores(self):
available_cores = cpu_count()
cores = input(f"\nNumber of available cores: {available_cores}\n \n How many cores to be used? (leave empty to use all available cores) \n \n Type something>")
cores = input(
f"\nNumber of available cores: {available_cores}\n \n How many cores to be used? (leave empty to use all available cores) \n \n Type something>")

if cores == "":
self.cores = int(available_cores)
elif cores.isdigit():
cores = int(cores)
if 0 < cores <= available_cores:
self.cores = cores
elif cores<=0 :
elif cores <= 0:
print(f"Hey you can't use {cores} number of cpu cores!!")
input("Press Enter to exit")
raise ValueError("negative number!")
Expand All @@ -112,22 +148,25 @@ def num_of_cores(self):
print("Wrong input!")
input("Press Enter to exit")
exit()


print('\n')

def generate_random_address(self):
key = Key()
print("\n Public Address: "+key.address)
print(" Private Key: "+key.to_wif())

def generate_address_fromKey(self):
if self.privateKey != "":
key = Key(self.privateKey)
print("\n Public Address: "+key.address)
print("\n Your wallet is ready!")
else:
print("no entry")

def get_user_input(self):
user_input = input("\n What do you want to do? \n \n [1]: generate random key pair \n [2]: generate public address from private key \n [3]: brute force bitcoin offline mode \n [4]: brute force bitcoin online mode \n [0]: exit \n \n Type something>")
user_input = input(
"\n What do you want to do? \n \n [1]: generate random key pair \n [2]: generate public address from private key \n [3]: brute force bitcoin offline mode \n [4]: brute force bitcoin online mode \n [0]: exit \n \n Type something>")
if user_input == "1":
self.generate_random_address()
print("\n Your wallet is ready!")
Expand All @@ -142,48 +181,52 @@ def get_user_input(self):
input("Press Enter to exit")
exit()
elif user_input == "3":
method_input = input(" \n Enter the desired number: \n \n [1]: random attack \n [2]: sequential attack \n [0]: exit \n \n Type something>")
if method_input=="1":
target = self.random_brute
elif method_input=="2":
method_input = input(
" \n Enter the desired number: \n \n [1]: random attack \n [2]: sequential attack \n [0]: exit \n \n Type something>")
if method_input == "1":
target = self.random_brute_process
self.use_process = True
elif method_input == "2":
if open("cache.txt", "r").read() != "":
r0=open("cache.txt").read().split("-")
r0 = open("cache.txt").read().split("-")
print(f"resume range {r0[0]}-{r0[2]}")
with ThreadPoolExecutor(max_workers=self.num_of_cores()) as pool:
print("\nResuming ...\n")
self.start_t = time()
self.start_t.value = time()
self.start_r = int(r0[1])
self.start_n = int(r0[0])
self.end_n = int(r0[2])
self.seq=True
for i in range(self.start_n,self.end_n):
self.seq = True
for i in range(self.start_n, self.end_n):
pool.submit(self.sequential_brute, i)
print("Stopping\n")
exit()
else:
range0 = input("\n Enter range in decimals(example:1-100)>")
range0 = input(
"\n Enter range in decimals(example:1-100)>")
r0 = range0.split("-")
r0.insert(1,r0[0])
r0.insert(1, r0[0])
open("cache.txt", "w").write("-".join(r0))
with ThreadPoolExecutor(max_workers=self.num_of_cores()) as pool:
print("\n Starting ...")
self.start_t = time()
self.start_t.value = time()
self.start_r = int(r0[1])
self.start_n = int(r0[0])
self.end_n = int(r0[2])
self.seq=True
for i in range(self.start_n,self.end_n):
self.seq = True
for i in range(self.start_n, self.end_n):
pool.submit(self.sequential_brute, i)
print("Stopping\n")
exit()
else:
print("exitting...")
exit()
elif user_input == "4":
method_input = input(" \n Enter the desired number: \n \n [1]: random attack \n [2]: sequential attack \n [0]: exit \n \n Type something>")
if method_input=="1":
method_input = input(
" \n Enter the desired number: \n \n [1]: random attack \n [2]: sequential attack \n [0]: exit \n \n Type something>")
if method_input == "1":
target = self.random_online_brute
elif method_input=="2":
elif method_input == "2":
print("sequential online attack will be available soon!")
input("Press Enter to exit")
exit()
Expand All @@ -200,34 +243,51 @@ def get_user_input(self):
print("Your wallet is ready!")
input("Press Enter to exit")
exit()
with ThreadPoolExecutor(max_workers=self.num_of_cores()) as pool:
r = range(100000000000000000)
print("\n Starting ...")
self.start_t = time()

if self.use_process:
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the fact that I don't have enough time to convert all tasks to using the Process. I converted the random_brute. That's why I need this flag

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be better if the value is declared in the if __name__ == "__main__": and then passed to the class.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want use_process to be used for this particular option. The rest should be used the old approach. Then, slowly we can migrate to the new approach.

If we move use_process to the outside of the class, how can we switch and meet this expectation?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean to share the values between speed() and the rest.
The problem is that we need to measure the speed and display it. Thus, the current number should be shared to the speed() function.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that the metrics are shared across the threads. It means that t1 = threading.Thread(target=obj.speed) is able to display it correctly.

In details, these lines of code help to to share metrics between speed()

self.cur_n = self.manager.Value('i', 0)
self.start_t = self.manager.Value('i', 0)

Could you specify which information is not shown so that I can look deeper?

self.start_t.value = time()
self.start_n = 0
for i in r:
pool.submit(target, i)
print("Stopping\n")
exit()

self.num_of_cores()
for core_number in range(0, self.cores):
process = Process(target=target, args=(
self.cur_n, core_number))
self.process_list.append(process)

for process in self.process_list:
process.start()

if __name__ =="__main__":
obj = Btcbf()
try:
t0 = threading.Thread(target=obj.get_user_input)
t1 = threading.Thread(target=obj.speed)
t1.daemon = True
t0.daemon = True
t0.start()
t1.start()
sleep(4000000) # stay in the `try..except`
sleep(4000000) # stay in the `try..except`
except KeyboardInterrupt:
print("\n\nCtrl+C pressed. \nexitting...")
for process in self.process_list:
process.join()

print("Stopping\n")
exit()
else:
print(f"\n\nError: {Exception.args}\n")
exit()


with ThreadPoolExecutor(max_workers=self.num_of_cores()) as pool:
r = range(100000000000000000)
print("\n Starting ...")
self.start_t.value = time()
self.start_n = 0
for i in r:
pool.submit(target, i)
print("Stopping\n")
exit()


if __name__ == "__main__":
obj = Btcbf()
try:
t0 = threading.Thread(target=obj.get_user_input)
t1 = threading.Thread(target=obj.speed)
t1.daemon = True
t0.daemon = True
t0.start()
t1.start()
sleep(4000000) # stay in the `try..except`
sleep(4000000) # stay in the `try..except`
except KeyboardInterrupt:
print("\n\nCtrl+C pressed. \nexitting...")
exit()
else:
print(f"\n\nError: {Exception.args}\n")
exit()