Skip to content

Commit 9cc908b

Browse files
authored
Merge pull request #3 from USArmyResearchLab/master
Update fork
2 parents 7328fe8 + 5bf4831 commit 9cc908b

17 files changed

Lines changed: 372 additions & 7 deletions

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ Key features:
4747
* `decode -d <decoder> <pcap>`
4848
* Run the selected decoder on a pcap file
4949

50+
## Development
51+
* [Using Dshell With PyCharm](doc/UsingDshellWithPyCharm.md)
52+
5053
## Partners
5154

5255
Below are repositories from partners Dshell has worked together with.

decoders/http/httpdump.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import hashlib
44
import urllib
55
import re
6+
import colorout
67

78
from httpdecoder import HTTPDecoder
89

@@ -25,7 +26,7 @@ def __init__(self):
2526
'urlfilter': {'type': 'string', 'default': None, 'help': 'Filter to URLs matching this regex'},
2627
},
2728
)
28-
self.output = 'colorout'
29+
self.out = colorout.ColorOutput()
2930
# Disable auto-gunzip as we want to indicate content that was
3031
# compressed in the output
3132
self.gunzip = False

decoders/http/peht.py

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
#
2+
# Author: MM - https://github.com/1modm
3+
#
4+
# Most of the Penetration/Exploit/Hijacking Tools use the HTTP methods to try to inject
5+
# or execute code into the attacked server, also this tools usually have a well known
6+
# "hardcoded" User-Agent, URI or request content.
7+
#
8+
# So if the original scanner is not modified can be detected. This is a PoC in order to generate
9+
# simple rules to detect and identified some of the most commons Penetration/Exploit/Hijacking Tools.
10+
#
11+
# Some of the most commons tools source and information:
12+
#
13+
# Nmap
14+
# User-Agent header by default it is "Mozilla/5.0 (compatible; Nmap Scripting Engine; https://nmap.org/book/nse.html)".
15+
# https://nmap.org/nsedoc/lib/http.html
16+
#
17+
# OpenVAS
18+
# http://www.openvas.org/src-doc/openvas-libraries/nasl__http_8c_source.html
19+
# User-Agent header by default: #define OPENVAS_USER_AGENT "Mozilla/5.0 [en] (X11, U; OpenVAS)"
20+
#
21+
# MASSCAN
22+
# https://github.com/robertdavidgraham/masscan
23+
#
24+
# Morpheus
25+
# https://github.com/r00t-3xp10it/morpheus
26+
# https://latesthackingnews.com/2016/12/19/morpheus-automated-ettercap-tcpip-hijacking-tool/
27+
#
28+
# DataCha0s Web Scanner
29+
# http://eromang.zataz.com/2011/05/23/suc026-datacha0s-web-scannerrobot/
30+
# https://blogs.harvard.edu/zeroday/2006/06/12/data-cha0s-connect-back-backdoor/
31+
#
32+
# HNAP (Home Network Administration Protocol)
33+
# https://nmap.org/nsedoc/scripts/hnap-info.html
34+
#
35+
# ZmEu Scanner
36+
# https://en.wikipedia.org/wiki/ZmEu_(vulnerability_scanner)
37+
# http://linux.m2osw.com/zmeu-attack
38+
# https://code.google.com/archive/p/caffsec-malware-analysis/wikis/ZmEu.wiki
39+
# https://ensourced.wordpress.com/2011/02/25/zmeu-attacks-some-basic-forensic/
40+
# http://philriesch.com/computersecurity_zmeu.html
41+
#
42+
# Jorgee Scanner
43+
# http://www.skepticism.us/2015/05/new-malware-user-agent-value-jorgee/
44+
# https://www.checkpoint.com/defense/advisories/public/2016/cpai-2016-0214.html
45+
# https://blog.paranoidpenguin.net/2017/04/jorgee-goes-on-a-rampage/
46+
47+
import re
48+
import util
49+
import dshell
50+
import datetime
51+
import colorout
52+
from httpdecoder import HTTPDecoder
53+
54+
class DshellDecoder(HTTPDecoder):
55+
56+
def __init__(self):
57+
HTTPDecoder.__init__(self,
58+
name='peht',
59+
description='Penetration/Exploit/Hijacking Tool detector',
60+
longdescription="""
61+
The Penetration/Exploit/Hijacking Tool detector will identify the tool used to scan or exploit a server using the
62+
User agent, URI or HTTP content.
63+
64+
General usage:
65+
decode -d peht <pcap>
66+
67+
Detailed usage:
68+
decode -d peht --peht_showcontent <pcap>
69+
70+
Output:
71+
72+
Request Timestamp (UTC): 2017-07-16 02:41:47.238549
73+
Penetration/Exploit/Hijacking Tool: Open Vulnerability Assessment System
74+
User-Agent: Mozilla/5.0 [en] (X11, U; OpenVAS 8.0.9)
75+
Request Method: GET
76+
URI: /scripts/session/login.php
77+
Source IP: 1.2.3.4 - Source port: 666 - MAC: 50:b4:02:39:24:56
78+
Host requested: example.com
79+
80+
Response Timestamp (UTC): 2017-07-16 02:41:48.238549
81+
Response Reason: Not Found
82+
Response Status: 404
83+
Destination IP: 192.168.1.1 - Destination port: 80 - MAC: a4:42:ab:56:b6:23
84+
85+
86+
Detailed Output:
87+
88+
Request Timestamp (UTC): 2017-07-16 02:41:47.238549
89+
Penetration/Exploit/Hijacking Tool: Arbitrary Remote Code Execution/injection
90+
User-Agent: Wget(linux)
91+
Request Method: POST
92+
URI: /command.php
93+
Source IP: 1.2.3.4 - Source port: 666 - MAC: 50:b4:02:39:24:56
94+
Host requested: example.com
95+
96+
cmd=%63%64%20%2F%76%61%72%2F%74%6D%70%20%26%26%20%65%63%68%6F%20%2D%6E%65%20%5C%5C%78%33%6B%65%72%20%3E%20%6B%65%72%2E%74%78%74%20%26%26%20%63%61%74%20%6B%65%72%2E%74%78%74
97+
98+
Response Timestamp (UTC): 2017-07-16 02:41:48.238549
99+
Response Reason: Found
100+
Response Status: 302
101+
Destination IP: 192.168.1.1 - Destination port: 80 - MAC: a4:42:ab:56:b6:23
102+
103+
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
104+
<html><head>
105+
<title>302 Found</title>
106+
</head><body>
107+
<h1>Found</h1>
108+
<p>The document has moved <a href="https://example.com/command.php">here</a>.</p>
109+
</body></html>
110+
111+
""",
112+
filter='tcp and (port 80 or port 81 or port 8080 or port 8000)',
113+
filterfn=lambda ((sip, sp), (dip, dp)): sp in (
114+
80, 81, 8000, 8080) or dp in (80, 81, 8000, 8080),
115+
author='mm',
116+
optiondict={
117+
'showcontent': {'action': 'store_true', 'default': False, 'help': 'Display the request and response body content.'}
118+
}
119+
)
120+
121+
self.out = colorout.ColorOutput()
122+
self.direction = None
123+
self.request_ioc = None
124+
self.request_method = None
125+
self.request_user_agent = None
126+
self.request_host = None
127+
self.request_rangestr = None
128+
self.request_body = None
129+
self.request_referer = None
130+
self.response_content_type = None
131+
self.response_body = None
132+
self.response_contentencoding = None
133+
self.response_status = None
134+
self.response_contentlength = None
135+
self.response_reason = None
136+
137+
def preModule(self):
138+
if 'setColorMode' in dir(self.out):
139+
self.out.setColorMode()
140+
141+
def check_payload(self, payloadheader, payloaduri, requestbody):
142+
143+
ET_identified = None
144+
145+
r = re.compile(r'\bbash\b | \bcmd\b | \bsh\b | \bwget\b', flags=re.I | re.X)
146+
if r.findall(requestbody):
147+
ET_identified = 'Arbitrary Remote Code Execution/injection'
148+
149+
if payloadheader.has_key('content-type'):
150+
struts_ioc = ['cmd', 'ProcessBuilder', 'struts']
151+
#Will return empty if all words from struts_ioc are in payloadheader['content-type']
152+
struts_check = list(filter(lambda x: x not in payloadheader['content-type'], struts_ioc))
153+
if not struts_check:
154+
ET_identified = 'Apache Struts Content-Type arbitrary command execution'
155+
156+
if payloadheader.has_key('user-agent'):
157+
if 'Jorgee' in payloadheader['user-agent']:
158+
ET_identified = 'Jorgee Scanner'
159+
elif 'Nmap' in payloadheader['user-agent']:
160+
ET_identified = 'Nmap'
161+
elif 'masscan' in payloadheader['user-agent']:
162+
ET_identified = 'Mass IP port scanner'
163+
elif ('ZmEu' in payloadheader['user-agent'] and 'w00tw00t' in payloaduri):
164+
ET_identified = 'ZmEu Vulnerability Scanner'
165+
elif 'immoral' in payloadheader['user-agent']:
166+
ET_identified = 'immoral'
167+
elif 'chroot' in payloadheader['user-agent']:
168+
ET_identified = 'chroot'
169+
elif 'DataCha0s' in payloadheader['user-agent']:
170+
ET_identified = 'DataCha0s Web Scanner'
171+
elif 'OpenVAS' in payloadheader['user-agent']:
172+
ET_identified = 'Open Vulnerability Assessment System'
173+
elif ('bash' or 'sh' or 'cmd' or 'wget') in (payloadheader['user-agent']):
174+
ET_identified = 'Arbitrary Remote Code Execution/injection'
175+
176+
if 'muieblackcat' in payloaduri:
177+
ET_identified = 'Muieblackcat Web Scanner/Robot'
178+
if '/HNAP1/' in payloaduri:
179+
ET_identified = 'Home Network Administration Protocol'
180+
181+
return ET_identified
182+
183+
184+
185+
def HTTPHandler(self, conn, request, response, requesttime, responsetime):
186+
187+
if not request:
188+
return
189+
190+
# Obtain the response content
191+
try:
192+
if 'gzip' in util.getHeader(response, 'content-encoding'):
193+
self.response_body = self.decompressGzipContent(response.body)
194+
if self.response_body == None:
195+
self.response_body = '(gunzip failed)\n' + response.body
196+
else:
197+
self.response_body = '(gzip encoded)\n' + self.response_body
198+
else:
199+
self.response_body = response.body
200+
except AttributeError as e:
201+
self.response_body = None
202+
203+
# Obtain the request content
204+
try:
205+
if 'gzip' in util.getHeader(request, 'content-encoding'):
206+
self.request_body = self.decompressGzipContent(request.body)
207+
if self.request_body == None:
208+
self.request_body = '(gunzip failed)\n' + request.body
209+
else:
210+
self.request_body = '(gzip encoded)\n' + self.request_body
211+
else:
212+
self.request_body = request.body
213+
except AttributeError as e:
214+
self.request_body = None
215+
216+
# Identify the Exploit/Hijacking Tool
217+
self.request_ioc = self.check_payload(request.headers, request.uri, self.request_body)
218+
219+
if self.request_ioc:
220+
221+
# REQUEST
222+
if request.method in ('GET', 'POST', 'HEAD'):
223+
self.direction = "sc"
224+
self.request_method = request.method
225+
self.request_user_agent = request.headers.get('user-agent')
226+
self.request_host = util.getHeader(request, 'host')
227+
self.request_rangestr = util.getHeader(request,'range')
228+
self.request_body = request.body
229+
self.request_referer = util.getHeader(request, 'referer')
230+
231+
if request.headers.has_key('user-agent'):
232+
self.request_user_agent = request.headers['user-agent']
233+
234+
self.out.write("\nRequest Timestamp (UTC): {0} \nPenetration/Exploit/Hijacking Tool: {1}\nUser-Agent: {2}\nRequest Method: {3}\nURI: {4}\nSource IP: {5} - Source port: {6} - MAC: {7}\nHost requested: {8}\nReferer: {9}\n".format(datetime.datetime.utcfromtimestamp(
235+
requesttime), self.request_ioc, self.request_user_agent, self.request_method, request.uri, conn.sip, conn.sport, conn.smac, self.request_host, self.request_referer), formatTag="H2", direction=self.direction)
236+
237+
# Show request body content
238+
if self.showcontent:
239+
self.out.write("\n{0}\n".format(self.request_body), formatTag="H2", direction=self.direction)
240+
241+
if not response:
242+
self.direction = "cs"
243+
self.out.write('\nNo response\n', formatTag="H2", direction=self.direction)
244+
245+
# RESPONSE
246+
else:
247+
self.direction = "cs"
248+
self.response_content_type = util.getHeader(response, 'content-type')
249+
self.response_contentencoding = util.getHeader(response, 'content-encoding')
250+
self.response_status = response.status
251+
self.response_reason = response.reason
252+
253+
self.out.write("\nResponse Timestamp (UTC): {0} \nResponse Reason: {1}\nResponse Status: {2}\nDestination IP: {3} - Destination port: {4} - MAC: {5}\n".format(datetime.datetime.utcfromtimestamp(
254+
responsetime), self.response_reason, self.response_status, conn.dip, conn.dport, conn.dmac), formatTag="H2", direction=self.direction)
255+
256+
# Show response body content
257+
if self.showcontent:
258+
self.out.write("\n{0}\n".format(self.response_body), formatTag="H2", direction=self.direction)
259+
260+
if __name__ == '__main__':
261+
dObj = DshellDecoder()
262+
print dObj
263+
else:
264+
dObj = DshellDecoder()

decoders/misc/xor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ def makeKey(self, key):
5050
def connectionInitHandler(self, conn):
5151
# need to set up a custom connection tracker to handle
5252
self.xorconn[conn.addr] = dshell.Connection(self, conn.addr, conn.ts)
53-
# self.xorconn[conn.addr]=conn
53+
self.xorconn[conn.addr].nextoffset = conn.nextoffset
54+
self.xorconn[conn.addr].proto = conn.proto
55+
self.xorconn[conn.addr].info(proto=conn.proto)
5456

5557
#
5658
# Each blob will be xor'ed and the "newblob" data will be added to the connection

decoders/smb/psexec.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __init__(self):
5252
)
5353
self.legacy = True
5454
# self.out=colorout.ColorOutput(title='psexec')
55-
self.output = 'colorout'
55+
self.out = colorout.ColorOutput()
5656

5757
def sessIndexFromPID(self, conn, pid):
5858
return ':'.join((str(conn.starttime), conn.sip, str(conn.sport), conn.dip, str(conn.dport), pid))

0 commit comments

Comments
 (0)