Skip to content

Commit 3c318f1

Browse files
Merge pull request #34 from Hackplayers/dev
Dev to master v2.4
2 parents e501272 + 837b99e commit 3c318f1

File tree

5 files changed

+65
-19
lines changed

5 files changed

+65
-19
lines changed

.editorconfig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#EditorConfig: http://editorconfig.org
2+
3+
root = true
4+
5+
[*]
6+
charset = utf-8
7+
end_of_line = lf
8+
insert_final_newline = true
9+
10+
[*.{rb,md}]
11+
indent_style = space
12+
indent_size = 4
13+
trim_trailing_whitespace = true
14+
15+
[Gemfile]
16+
indent_style = space
17+
indent_size = 4
18+
19+
[Dockerfile]
20+
indent_style = space
21+
indent_size = 4

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
### 2.4
2+
- File permission access error now handled in exception to avoid losing connection
3+
- Improvements on bundler installation method
4+
- Added spn (Service Principal Names) option param for kerberos auth to set some different than default HTTP
5+
- Fixed prompt colors (ANSI)
6+
17
### 2.3
28
- Fixed Invoke-Binary arguments
39
- Service function improved, now show privileges over the services
@@ -29,7 +35,7 @@
2935
### 1.8
3036
- Added pass-the-hash feature
3137
- Added bundler installation method
32-
38+
3339
### 1.7
3440
- Added x64 compatibility to use Donut payloads
3541

Gemfile.lock

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,3 @@ DEPENDENCIES
4040
stringio
4141
winrm
4242
winrm-fs
43-
44-
BUNDLED WITH
45-
2.0.2

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ if you have credentials and permissions to use it. So we can say that it could b
1515
phase. The purpose of this program is to provide nice and easy-to-use features for hacking. It can be used with legitimate
1616
purposes by system administrators as well but the most of its features are focused on hacking/pentesting stuff.
1717

18+
It is based mainly in the WinRM Ruby library which changed its way to work since its version 2.0. Now instead of using WinRM
19+
protocol, it is using PSRP (Powershell Remoting Protocol) for initializing runspace pools as well as creating and processing pipelines.
20+
1821
## Features
1922
- Compatible to Linux and Windows client systems
2023
- Load in memory Powershell scripts
@@ -36,18 +39,19 @@ purposes by system administrators as well but the most of its features are focus
3639

3740
## Help
3841
```
39-
Usage: evil-winrm -i IP -u USER [-s SCRIPTS_PATH] [-e EXES_PATH] [-P PORT] [-p PASS] [-H HASH] [-U URL] [-S] [-c PUBLIC_KEY_PATH ] [-k PRIVATE_KEY_PATH ] [-r REALM]
42+
Usage: evil-winrm -i IP -u USER [-s SCRIPTS_PATH] [-e EXES_PATH] [-P PORT] [-p PASS] [-H HASH] [-U URL] [-S] [-c PUBLIC_KEY_PATH ] [-k PRIVATE_KEY_PATH ] [-r REALM] [--spn SPN_PREFIX]
4043
-S, --ssl Enable ssl
4144
-c, --pub-key PUBLIC_KEY_PATH Local path to public key certificate
4245
-k, --priv-key PRIVATE_KEY_PATH Local path to private key certificate
4346
-r, --realm DOMAIN Kerberos auth, it has to be set also in /etc/krb5.conf file using this format -> CONTOSO.COM = { kdc = fooserver.contoso.com }
4447
-s, --scripts PS_SCRIPTS_PATH Powershell scripts local path
48+
--spn SPN_PREFIX SPN prefix for Kerberos auth (default HTTP)
4549
-e, --executables EXES_PATH C# executables local path
46-
-i, --ip IP Remote host IP or hostname (required)
47-
-U, --url URL Remote url endpoint (default wsman)
50+
-i, --ip IP Remote host IP or hostname. FQDN for Kerberos auth (required)
51+
-U, --url URL Remote url endpoint (default /wsman)
4852
-u, --user USER Username (required if not using kerberos)
4953
-p, --password PASS Password
50-
-H, --hash NTHash NTHash
54+
-H, --hash HASH NTHash
5155
-P, --port PORT Remote host port (default 5985)
5256
-V, --version Show version
5357
-n, --no-colors Disable colors
@@ -73,9 +77,10 @@ For some Linux like Debian based (Kali, Parrot, etc.) it is called `krb5-user`.
7377
- Step 3. Ready. Just launch it! `~$ cd evil-winrm && ruby evil-winrm.rb -i 192.168.1.100 -u Administrator -p 'MySuperSecr3tPass123!' -s '/home/foo/ps1_scripts/' -e '/home/foo/exe_files/'`
7478

7579
### Method 3. Using bundler (dependencies will not be installed on your system, just to use evil-winrm)
76-
- Step 1. Install bundler: `gem install bundler:2.0.2`
77-
- Step 2. Install dependencies with bundler: `cd evil-winrm && bundle install --path vendor/bundle`
78-
- Step 3. Launch it with bundler: `bundle exec evil-winrm.rb -i 192.168.1.100 -u Administrator -p 'MySuperSecr3tPass123!' -s '/home/foo/ps1_scripts/' -e '/home/foo/exe_files/'`
80+
- Step 1. Install bundler: `gem install bundler`
81+
- Step 2. Clone the repo: `git clone https://github.com/Hackplayers/evil-winrm.git`
82+
- Step 3. Install dependencies with bundler: `cd evil-winrm && bundle install --path vendor/bundle`
83+
- Step 4. Launch it with bundler: `bundle exec evil-winrm.rb -i 192.168.1.100 -u Administrator -p 'MySuperSecr3tPass123!' -s '/home/foo/ps1_scripts/' -e '/home/foo/exe_files/'`
7984

8085
### Method 4. Using Docker
8186
- Step 1. Launch docker container based on already built image: `docker run --rm -ti --name evil-winrm -v /home/foo/ps1_scripts:/ps1_scripts -v /home/foo/exe_files:/exe_files -v /home/foo/data:/data oscarakaelvis/evil-winrm -i 192.168.1.100 -u Administrator -p 'MySuperSecr3tPass123!' -s '/ps1_scripts/' -e '/exe_files/'`
@@ -221,7 +226,7 @@ Use it at your own servers and/or with the server owner's permission.
221226
[@_Laox]: https://twitter.com/_Laox
222227

223228
<!-- Badges URLs -->
224-
[Version-shield]: https://img.shields.io/badge/version-2.3-blue.svg?style=flat-square&colorA=273133&colorB=0093ee "Latest version"
229+
[Version-shield]: https://img.shields.io/badge/version-2.4-blue.svg?style=flat-square&colorA=273133&colorB=0093ee "Latest version"
225230
[Ruby2.3-shield]: https://img.shields.io/badge/ruby-2.3%2B-blue.svg?style=flat-square&colorA=273133&colorB=ff0000 "Ruby 2.3 or later"
226231
[License-shield]: https://img.shields.io/badge/license-LGPL%20v3%2B-blue.svg?style=flat-square&colorA=273133&colorB=bd0000 "LGPL v3+"
227232
[Docker-shield]: https://img.shields.io/docker/cloud/automated/oscarakaelvis/evil-winrm.svg?style=flat-square&colorA=273133&colorB=a9a9a9 "Docker rules!"

evil-winrm.rb

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# Constants
1818

1919
# Version
20-
VERSION = '2.3'
20+
VERSION = '2.4'
2121

2222
# Msg types
2323
TYPE_INFO = 0
@@ -46,6 +46,7 @@
4646
$user = ""
4747
$password = ""
4848
$url = "wsman"
49+
$default_service = "HTTP"
4950

5051
# Redefine download method from winrm-fs
5152
module WinRM
@@ -85,9 +86,9 @@ class EvilWinRM
8586

8687
# Arguments
8788
def arguments()
88-
options = { port:$port, url:$url }
89+
options = { port:$port, url:$url, service:$service }
8990
optparse = OptionParser.new do |opts|
90-
opts.banner = "Usage: evil-winrm -i IP -u USER [-s SCRIPTS_PATH] [-e EXES_PATH] [-P PORT] [-p PASS] [-H HASH] [-U URL] [-S] [-c PUBLIC_KEY_PATH ] [-k PRIVATE_KEY_PATH ] [-r REALM]"
91+
opts.banner = "Usage: evil-winrm -i IP -u USER [-s SCRIPTS_PATH] [-e EXES_PATH] [-P PORT] [-p PASS] [-H HASH] [-U URL] [-S] [-c PUBLIC_KEY_PATH ] [-k PRIVATE_KEY_PATH ] [-r REALM] [--spn SPN_PREFIX]"
9192
opts.on("-S", "--ssl", "Enable ssl") do |val|
9293
$ssl = true
9394
options[:port] = "5986"
@@ -96,10 +97,11 @@ def arguments()
9697
opts.on("-k", "--priv-key PRIVATE_KEY_PATH", "Local path to private key certificate") { |val| options[:priv_key] = val }
9798
opts.on("-r", "--realm DOMAIN", "Kerberos auth, it has to be set also in /etc/krb5.conf file using this format -> CONTOSO.COM = { kdc = fooserver.contoso.com }") { |val| options[:realm] = val.upcase }
9899
opts.on("-s", "--scripts PS_SCRIPTS_PATH", "Powershell scripts local path") { |val| options[:scripts] = val }
100+
opts.on("--spn SPN_PREFIX", "SPN prefix for Kerberos auth (default HTTP)") { |val| options[:service] = val }
99101
opts.on("-e", "--executables EXES_PATH", "C# executables local path") { |val| options[:executables] = val }
100102
opts.on("-i", "--ip IP", "Remote host IP or hostname. FQDN for Kerberos auth (required)") { |val| options[:ip] = val }
101103
opts.on("-U", "--url URL", "Remote url endpoint (default /wsman)") { |val| options[:url] = val }
102-
opts.on("-u", "--user USER", "Username (required)") { |val| options[:user] = val }
104+
opts.on("-u", "--user USER", "Username (required if not using kerberos)") { |val| options[:user] = val }
103105
opts.on("-p", "--password PASS", "Password") { |val| options[:password] = val }
104106
opts.on("-H", "--hash HASH", "NTHash") do |val|
105107
if !options[:password].nil? and !val.nil?
@@ -163,6 +165,12 @@ def arguments()
163165
$pub_key = options[:pub_key]
164166
$priv_key = options[:priv_key]
165167
$realm = options[:realm]
168+
$service = options[:service]
169+
if !$realm.nil? then
170+
if $service.nil? then
171+
$service = $default_service
172+
end
173+
end
166174
end
167175

168176
# Print script header
@@ -200,7 +208,8 @@ def connection_initialization()
200208
user: "",
201209
password: "",
202210
transport: :kerberos,
203-
realm: $realm
211+
realm: $realm,
212+
service: $service
204213
)
205214
else
206215
$conn = WinRM::Connection.new(
@@ -225,7 +234,7 @@ def docker_detection()
225234
def colorize(text, color = "default")
226235
colors = {"default" => "38", "blue" => "34", "red" => "31", "yellow" => "1;33", "magenta" => "35"}
227236
color_code = colors[color]
228-
return "\033[0;#{color_code}m#{text}\033[0m"
237+
return "\001\033[0;#{color_code}m\002#{text}\001\033[0m\002"
229238
end
230239

231240
# Messsage printing
@@ -393,6 +402,10 @@ def main
393402
self.print_message("Password is not needed for Kerberos auth. Ticket will be used", TYPE_WARNING)
394403
end
395404

405+
if $realm.nil? and !$service.nil? then
406+
self.print_message("Useless spn provided, only used for Kerberos auth", TYPE_WARNING)
407+
end
408+
396409
if !$scripts_path.nil? then
397410
self.check_directories($scripts_path, "scripts")
398411
functions = self.read_scripts($scripts_path)
@@ -412,7 +425,7 @@ def main
412425
when Readline.line_buffer =~ /help.*/i
413426
puts("#{$LIST.join("\t")}")
414427
when Readline.line_buffer =~ /\[.*/i
415-
$LISTASSEM.grep( /^#{Regexp.escape(str)}/i ) unless str.nil?
428+
$LISTASSEM.grep( /^#{Regexp.escape(str)}/i ) unless str.nil?
416429
when Readline.line_buffer =~ /Invoke-Binary.*/i
417430
executables.grep( /^#{Regexp.escape(str)}/i ) unless str.nil?
418431
when Readline.line_buffer =~ /donutfile.*/i
@@ -590,6 +603,10 @@ def main
590603
STDERR.print(stderr)
591604
end
592605
end
606+
rescue Errno::EACCES => ex
607+
puts()
608+
self.print_message("An error of type #{ex.class} happened, message is #{ex.message}", TYPE_ERROR)
609+
retry
593610
rescue Interrupt
594611
puts("\n\n")
595612
self.print_message("Press \"y\" to exit, press any other key to continue", TYPE_WARNING)

0 commit comments

Comments
 (0)