{"id":1086,"date":"2013-08-31T17:20:06","date_gmt":"2013-08-31T16:20:06","guid":{"rendered":"http:\/\/www.phillips321.co.uk\/?p=1086"},"modified":"2013-08-31T17:20:06","modified_gmt":"2013-08-31T16:20:06","slug":"multi-threading-python-a-quick-example","status":"publish","type":"post","link":"https:\/\/www.phillips321.co.uk\/2013\/08\/31\/multi-threading-python-a-quick-example\/","title":{"rendered":"Multi-threading python &#8211; a quick example"},"content":{"rendered":"<p>So in order to teach myself how to create multi-threaded python apps I decided to have a go this morning at writing a simple MD5 bruteforcer (using a wordlist).<\/p>\n<p>The way this works is that you create worker threads and each worker thread pulls an item from the queue and processes it; when finished it pulls another item from the queue and so on.<\/p>\n<div class=\"codecolorer-container python vibrant\" style=\"overflow:auto;white-space:nowrap;width:100%;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/>39<br \/><\/div><\/td><td><div class=\"python codecolorer\"><span class=\"co1\">#!\/usr\/bin\/env python<\/span><br \/>\n<span class=\"co1\"># md5brute.py<\/span><br \/>\n<br \/>\n<span class=\"kw1\">import<\/span> <span class=\"kw3\">sys<\/span><span class=\"sy0\">,<\/span><span class=\"kw3\">Queue<\/span><span class=\"sy0\">,<\/span><span class=\"kw3\">threading<\/span><span class=\"sy0\">,<\/span>hashlib<span class=\"sy0\">,<\/span><span class=\"kw3\">os<\/span><br \/>\n<br \/>\nNumOfThreads<span class=\"sy0\">=<\/span><span class=\"nu0\">100<\/span> &nbsp;<span class=\"co1\"># Number of threads<\/span><br \/>\nqueue <span class=\"sy0\">=<\/span> <span class=\"kw3\">Queue<\/span>.<span class=\"kw3\">Queue<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n<span class=\"co1\"># get hash and wordlist input<\/span><br \/>\n<span class=\"kw1\">try<\/span>:<br \/>\n&nbsp; &nbsp; TargetHash<span class=\"sy0\">=<\/span><span class=\"kw3\">sys<\/span>.<span class=\"me1\">argv<\/span><span class=\"br0\">&#91;<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#93;<\/span>.<span class=\"me1\">lower<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; WordList<span class=\"sy0\">=<\/span><span class=\"kw2\">open<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw3\">sys<\/span>.<span class=\"me1\">argv<\/span><span class=\"br0\">&#91;<\/span><span class=\"nu0\">2<\/span><span class=\"br0\">&#93;<\/span><span class=\"sy0\">,<\/span><span class=\"st0\">'r'<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">except<\/span>:<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">print<\/span> <span class=\"st0\">&quot;Usage: %s hash wordlist&quot;<\/span> % <span class=\"kw3\">sys<\/span>.<span class=\"me1\">argv<\/span><span class=\"br0\">&#91;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#93;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw3\">sys<\/span>.<span class=\"me1\">exit<\/span><span class=\"br0\">&#40;<\/span><span class=\"nu0\">1<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">class<\/span> checkHash<span class=\"br0\">&#40;<\/span><span class=\"kw3\">threading<\/span>.<span class=\"me1\">Thread<\/span><span class=\"br0\">&#41;<\/span>:<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">def<\/span> <span class=\"kw4\">__init__<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw2\">self<\/span><span class=\"sy0\">,<\/span>queue<span class=\"br0\">&#41;<\/span>:<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">threading<\/span>.<span class=\"me1\">Thread<\/span>.<span class=\"kw4\">__init__<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw2\">self<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw2\">self<\/span>.<span class=\"me1\">queue<\/span><span class=\"sy0\">=<\/span>queue<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">def<\/span> run<span class=\"br0\">&#40;<\/span><span class=\"kw2\">self<\/span><span class=\"br0\">&#41;<\/span>:<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">while<\/span> <span class=\"kw2\">True<\/span>:<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw2\">self<\/span>.<span class=\"me1\">clear<\/span><span class=\"sy0\">=<\/span><span class=\"kw2\">self<\/span>.<span class=\"me1\">queue<\/span>.<span class=\"me1\">get<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">if<\/span> hashlib.<span class=\"kw3\">md5<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw2\">self<\/span>.<span class=\"me1\">clear<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">hexdigest<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">==<\/span> TargetHash:<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">print<\/span> <span class=\"st0\">&quot;Hash found!!! %s = %s&quot;<\/span> % <span class=\"br0\">&#40;<\/span><span class=\"kw2\">self<\/span>.<span class=\"me1\">clear<\/span><span class=\"sy0\">,<\/span>TargetHash<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">os<\/span>._exit<span class=\"br0\">&#40;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw2\">self<\/span>.<span class=\"me1\">queue<\/span>.<span class=\"me1\">task_done<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n<span class=\"co1\">#spawn a pool of threads<\/span><br \/>\n<span class=\"kw1\">for<\/span> i <span class=\"kw1\">in<\/span> <span class=\"kw2\">range<\/span><span class=\"br0\">&#40;<\/span>NumOfThreads<span class=\"br0\">&#41;<\/span>:<br \/>\n&nbsp; &nbsp; t<span class=\"sy0\">=<\/span>checkHash<span class=\"br0\">&#40;<\/span>queue<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; t.<span class=\"me1\">setDaemon<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw2\">True<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; t.<span class=\"me1\">start<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\n<span class=\"co1\">#populate queue with wordlist<\/span><br \/>\n<span class=\"kw1\">for<\/span> word <span class=\"kw1\">in<\/span> WordList.<span class=\"me1\">readlines<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>:<br \/>\n&nbsp; &nbsp; queue.<span class=\"me1\">put<\/span><span class=\"br0\">&#40;<\/span>word.<span class=\"me1\">strip<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<br \/>\nqueue.<span class=\"me1\">join<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>We will try to crack the MD5 hash b0b129991a71c1ba6e8b6a280c5fbed2 using the rockyou wordlist.<\/p>\n<div class=\"codecolorer-container text vibrant\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/><\/div><\/td><td><div class=\"text codecolorer\">Matthews-MacBook-Pro:Desktop phillips321$ .\/md5brute.py<br \/>\nUsage: .\/md5brute.py hash wordlist<br \/>\nMatthews-MacBook-Pro:Desktop phillips321$ .\/md5brute.py b0b129991a71c1ba6e8b6a280c5fbed2 rockyou.txt<br \/>\nHash found!!! a6_123 = b0b129991a71c1ba6e8b6a280c5fbed2<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Voila! It worked.<\/p>\n<p>What&#8217;s important to note here is that although python is running multiple threads it is only running on 1 core so it&#8217;s not making full use of the CPU.<br \/>\n<a href=\"https:\/\/www.phillips321.co.uk\/wp-content\/uploads\/2013\/08\/Screen-Shot-2013-08-31-at-17.09.17.png\"><img loading=\"lazy\" src=\"https:\/\/www.phillips321.co.uk\/wp-content\/uploads\/2013\/08\/Screen-Shot-2013-08-31-at-17.09.17.png\" alt=\"Screen Shot 2013-08-31 at 17.09.17\" width=\"604\" height=\"88\" class=\"aligncenter size-full wp-image-1090\" srcset=\"https:\/\/www.phillips321.co.uk\/wp-content\/uploads\/2013\/08\/Screen-Shot-2013-08-31-at-17.09.17.png 604w, https:\/\/www.phillips321.co.uk\/wp-content\/uploads\/2013\/08\/Screen-Shot-2013-08-31-at-17.09.17-300x43.png 300w\" sizes=\"(max-width: 604px) 100vw, 604px\" \/><\/a><br \/>\n<a href=\"https:\/\/www.phillips321.co.uk\/wp-content\/uploads\/2013\/08\/Screen-Shot-2013-08-31-at-17.09.36.png\"><img loading=\"lazy\" src=\"https:\/\/www.phillips321.co.uk\/wp-content\/uploads\/2013\/08\/Screen-Shot-2013-08-31-at-17.09.36.png\" alt=\"Screen Shot 2013-08-31 at 17.09.36\" width=\"252\" height=\"208\" class=\"aligncenter size-full wp-image-1091\" \/><\/a><br \/>\nIn order to fully utilise the multiple cores on the CPU I would need to use the multiprocessing module in python&#8230; but i&#8217;ll save that for another day.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So in order to teach myself how to create multi-threaded python apps I decided to have a go this morning at writing a simple MD5 bruteforcer (using a wordlist). The way this works is that you create worker threads and each worker thread pulls an item from the queue and processes it; when finished it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1091,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[188,205,398,111,396,397],"_links":{"self":[{"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/posts\/1086"}],"collection":[{"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/comments?post=1086"}],"version-history":[{"count":6,"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/posts\/1086\/revisions"}],"predecessor-version":[{"id":1095,"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/posts\/1086\/revisions\/1095"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/media\/1091"}],"wp:attachment":[{"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/media?parent=1086"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/categories?post=1086"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.phillips321.co.uk\/wp-json\/wp\/v2\/tags?post=1086"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}