Skip to content

Commit 7b936b0

Browse files
author
Brent Cook
committed
Land rapid7#8184, convert IPMI protocol and modules to bindata
2 parents 7384212 + 6f70efc commit 7b936b0

File tree

10 files changed

+247
-141
lines changed

10 files changed

+247
-141
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
The ipmi_cipher_zero module is used to find IPMI 2.0-compatible systems that are vulnerable to an authentication bypass vulnerability through the use of IPMI cipher zero, which means no cipher is used at all.
2+
3+
## Vulnerable Devices
4+
5+
This is an error in the IPMI 2.0 specification itself, so any device BMC fully implementing IPMI 2.0 will possibly have the vulnerable non-cipher enabled.
6+
7+
## Verification Steps
8+
9+
Set RHOSTS to the target device or range and run:
10+
11+
```
12+
msf > use auxiliary/scanner/ipmi/ipmi_cipher_zero
13+
msf auxiliary(ipmi_cipher_zero) > set RHOSTS 192.168.1.2
14+
RHOSTS => 192.168.1.2
15+
msf auxiliary(ipmi_cipher_zero) > run
16+
17+
[*] Sending IPMI requests to 192.168.1.2->192.168.1.2 (1 hosts)
18+
[*] 192.168.1.2:623 - IPMI - NOT VULNERABLE: Rejected cipher zero with error code 17
19+
20+
```
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
The ipmi_dumphashes module identifies IPMI 2.0-compatible systems and attempts to retrieve the HMAC-SHA1 password hashes of default usernames. The hashes can be stored in a file using the OUTPUT_FILE option and then cracked using hmac_sha1_crack.rb in the tools subdirectory as well hashcat (cpu) 0.46 or newer using type 7300.
2+
3+
## Vulnerable Devices
4+
5+
Any IPMI 2.0 device implementing the RAKP protocol according to the IPMI specification is vulnerable. This is a design flaw rather than a vendor-specific vulnerability.
6+
7+
## Verification Steps
8+
9+
Set RHOSTS to the target device or range and run:
10+
11+
```
12+
msf > use auxiliary/scanner/ipmi/ipmi_dumphashes
13+
msf auxiliary(ipmi_dumphashes) > set RHOSTS 192.168.1.2
14+
RHOSTS => 192.168.1.2
15+
msf auxiliary(ipmi_dumphashes) > run
16+
17+
[*] 192.168.1.2:623 - IPMI - Sending IPMI probes
18+
[*] 192.168.1.2:623 - IPMI - Trying username 'ADMIN'...
19+
[-] 192.168.1.2:623 - IPMI - Returned error code 13 for username ADMIN: Unauthorized name
20+
[*] 192.168.1.2:623 - IPMI - Trying username 'admin'...
21+
[-] 192.168.1.2:623 - IPMI - Returned error code 13 for username admin: Unauthorized name
22+
[*] 192.168.1.2:623 - IPMI - Trying username 'root'...
23+
[+] 192.168.1.2:623 - IPMI - Hash found: root:redacted
24+
[*] 192.168.1.2:623 - IPMI - Trying username 'Administrator'...
25+
[-] 192.168.1.2:623 - IPMI - Returned error code 13 for username Administrator: Unauthorized name
26+
[*] 192.168.1.2:623 - IPMI - Trying username 'USERID'...
27+
[-] 192.168.1.2:623 - IPMI - Returned error code 13 for username USERID: Unauthorized name
28+
[*] 192.168.1.2:623 - IPMI - Trying username 'guest'...
29+
[-] 192.168.1.2:623 - IPMI - Returned error code 13 for username guest: Unauthorized name
30+
[*] 192.168.1.2:623 - IPMI - Trying username ''...
31+
[+] 192.168.1.2:623 - IPMI - Hash found: redacted
32+
[*] Scanned 1 of 1 hosts (100% complete)
33+
[*] Auxiliary module execution completed
34+
```
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The ipmi_version module is used to identify the version of the IPMI specification implemented by devices on a network.
2+
3+
## Target Devices
4+
5+
Any exposed device that implements the IPMI specification should work with this module. This is a recon module rather than an exploitation module.
6+
7+
## Verification Steps
8+
9+
Set RHOSTS to the target device or range and run:
10+
11+
```
12+
msf > use auxiliary/scanner/ipmi/ipmi_version
13+
msf auxiliary(ipmi_version) > set RHOSTS 192.168.1.2
14+
RHOSTS => 192.168.1.2
15+
msf auxiliary(ipmi_version) > run
16+
17+
[*] Sending IPMI requests to 192.168.1.2->192.168.1.2 (1 hosts)
18+
[*] 192.168.1.2:623 - IPMI - Probe sent
19+
[+] 192.168.1.2:623 - IPMI - IPMI-2.0 OEMID:180010 UserAuth(auth_msg, auth_user, non_null_user) PassAuth(password, md5, md2) Level(1.5, 2.0)
20+
21+
```

lib/rex/proto/ipmi.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
module Rex
66
module Proto
77
module IPMI
8-
require 'bit-struct'
98
require 'rex/proto/ipmi/channel_auth_reply'
109
require 'rex/proto/ipmi/open_session_reply'
1110
require 'rex/proto/ipmi/rakp2'

lib/rex/proto/ipmi/channel_auth_reply.rb

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,57 @@
11
# -*- coding: binary -*-
22

3+
require 'bindata'
4+
35
module Rex
46
module Proto
57
module IPMI
68

7-
class Channel_Auth_Reply < BitStruct
8-
unsigned :rmcp_version, 8, "RMCP Version"
9-
unsigned :rmcp_padding, 8, "RMCP Padding"
10-
unsigned :rmcp_sequence, 8, "RMCP Sequence"
11-
unsigned :rmcp_mtype, 1, "RMCP Message Type"
12-
unsigned :rmcp_class, 7, "RMCP Message Class"
13-
14-
unsigned :session_auth_type, 8, "Session Auth Type"
15-
unsigned :session_sequence, 32, "Session Sequence Number"
16-
unsigned :session_id, 32, "Session ID"
17-
unsigned :message_length, 8, "Message Length"
18-
19-
unsigned :ipmi_tgt_address, 8, "IPMI Target Address"
20-
unsigned :ipmi_tgt_lun, 8, "IPMI Target LUN"
21-
unsigned :ipmi_header_checksum, 8, "IPMI Header Checksum"
22-
unsigned :ipmi_src_address, 8, "IPMI Source Address"
23-
unsigned :ipmi_src_lun, 8, "IPMI Source LUN"
24-
unsigned :ipmi_command, 8, "IPMI Command"
25-
unsigned :ipmi_completion_code, 8, "IPMI Completion Code"
26-
27-
unsigned :ipmi_channel, 8, "IPMI Channel"
28-
29-
unsigned :ipmi_compat_20, 1, "IPMI Version Compatibility: IPMI 2.0+"
30-
unsigned :ipmi_compat_reserved1, 1, "IPMI Version Compatibility: Reserved 1"
31-
unsigned :ipmi_compat_oem_auth, 1, "IPMI Version Compatibility: OEM Authentication"
32-
unsigned :ipmi_compat_password, 1, "IPMI Version Compatibility: Straight Password"
33-
unsigned :ipmi_compat_reserved2, 1, "IPMI Version Compatibility: Reserved 2"
34-
unsigned :ipmi_compat_md5, 1, "IPMI Version Compatibility: MD5"
35-
unsigned :ipmi_compat_md2, 1, "IPMI Version Compatibility: MD2"
36-
unsigned :ipmi_compat_none, 1, "IPMI Version Compatibility: None"
37-
38-
unsigned :ipmi_user_reserved1, 2, "IPMI User Compatibility: Reserved 1"
39-
unsigned :ipmi_user_kg, 1, "IPMI User Compatibility: KG Set to Default"
40-
unsigned :ipmi_user_disable_message_auth, 1, "IPMI User Compatibility: Disable Per-Message Authentication"
41-
unsigned :ipmi_user_disable_user_auth, 1, "IPMI User Compatibility: Disable User-Level Authentication"
42-
unsigned :ipmi_user_non_null, 1, "IPMI User Compatibility: Non-Null Usernames Enabled"
43-
unsigned :ipmi_user_null, 1, "IPMI User Compatibility: Null Usernames Enabled"
44-
unsigned :ipmi_user_anonymous, 1, "IPMI User Compatibility: Anonymous Login Enabled"
45-
46-
unsigned :ipmi_conn_reserved1, 6, "IPMI Connection Compatibility: Reserved 1"
47-
unsigned :ipmi_conn_20, 1, "IPMI Connection Compatibility: 2.0"
48-
unsigned :ipmi_conn_15, 1, "IPMI Connection Compatibility: 1.5"
49-
50-
unsigned :ipmi_oem_id, 24, "IPMI OEM ID", :endian => 'little'
51-
52-
rest :ipm_oem_data, "IPMI OEM Data + Checksum Byte"
53-
9+
class Channel_Auth_Reply < BinData::Record
10+
endian :little
11+
uint8 :rmcp_version ,label: "RMCP Version"
12+
uint8 :rmcp_padding ,label: "RMCP Padding"
13+
uint8 :rmcp_sequence ,label: "RMCP Sequence"
14+
bit1 :rmcp_mtype ,label: "RMCP Message Type"
15+
bit7 :rmcp_class ,label: "RMCP Message Class"
16+
17+
uint8 :session_auth_type ,label: "Session Auth Type"
18+
uint32 :session_sequence ,label: "Session Sequence Number"
19+
uint32 :session_id ,label: "Session ID"
20+
uint8 :message_length ,label: "Message Length"
21+
22+
uint8 :ipmi_tgt_address ,label: "IPMI Target Address"
23+
uint8 :ipmi_tgt_lun ,label: "IPMI Target LUN"
24+
uint8 :ipmi_header_checksum ,label: "IPMI Header Checksum"
25+
uint8 :ipmi_src_address ,label: "IPMI Source Address"
26+
uint8 :ipmi_src_luna ,label: "IPMI Source LUN"
27+
uint8 :ipmi_command ,label: "IPMI Command"
28+
uint8 :ipmi_completion_code ,label: "IPMI Completion Code"
29+
30+
uint8 :ipmi_channel ,label: "IPMI Channel"
31+
32+
bit1 :ipmi_compat_20 ,label: "IPMI Version Compatibility: IPMI 2.0+"
33+
bit1 :ipmi_compat_reserved1 ,label: "IPMI Version Compatibility: Reserved 1"
34+
bit1 :ipmi_compat_oem_auth ,label: "IPMI Version Compatibility: OEM Authentication"
35+
bit1 :ipmi_compat_password ,label: "IPMI Version Compatibility: Straight Password"
36+
bit1 :ipmi_compat_reserved2 ,label: "IPMI Version Compatibility: Reserved 2"
37+
bit1 :ipmi_compat_md5 ,label: "IPMI Version Compatibility: MD5"
38+
bit1 :ipmi_compat_md2 ,label: "IPMI Version Compatibility: MD2"
39+
bit1 :ipmi_compat_none ,label: "IPMI Version Compatibility: None"
40+
41+
bit2 :ipmi_user_reserved1 ,label: "IPMI User Compatibility: Reserved 1"
42+
bit1 :ipmi_user_kg ,label: "IPMI User Compatibility: KG Set to Default"
43+
bit1 :ipmi_user_disable_message_auth ,label: "IPMI User Compatibility: Disable Per-Message Authentication"
44+
bit1 :ipmi_user_disable_user_auth ,label: "IPMI User Compatibility: Disable User-Level Authentication"
45+
bit1 :ipmi_user_non_null ,label: "IPMI User Compatibility: Non-Null Usernames Enabled"
46+
bit1 :ipmi_user_null ,label: "IPMI User Compatibility: Null Usernames Enabled"
47+
bit1 :ipmi_user_anonymous ,label: "IPMI User Compatibility: Anonymous Login Enabled"
48+
49+
bit6 :ipmi_conn_reserved1 ,label: "IPMI Connection Compatibility: Reserved 1"
50+
bit1 :ipmi_conn_20 ,label: "IPMI Connection Compatibility: 2.0"
51+
bit1 :ipmi_conn_15 ,label: "IPMI Connection Compatibility: 1.5"
52+
bit24 :ipmi_oem_id ,label: "IPMI OEM ID"
53+
54+
rest :ipm_oem_data ,label: "IPMI OEM Data + Checksum Byte"
5455

5556
def to_banner
5657
info = self

lib/rex/proto/ipmi/open_session_reply.rb

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,39 @@
11
# -*- coding: binary -*-
22

3-
module Rex
4-
module Proto
5-
module IPMI
6-
7-
class Open_Session_Reply < BitStruct
8-
unsigned :rmcp_version, 8, "RMCP Version"
9-
unsigned :rmcp_padding, 8, "RMCP Padding"
10-
unsigned :rmcp_sequence, 8, "RMCP Sequence"
11-
unsigned :rmcp_mtype, 1, "RMCP Message Type"
12-
unsigned :rmcp_class, 7, "RMCP Message Class"
13-
14-
unsigned :session_auth_type, 8, "Authentication Type"
15-
16-
unsigned :session_payload_encrypted, 1, "Session Payload Encrypted"
17-
unsigned :session_payload_authenticated, 1, "Session Payload Authenticated"
18-
unsigned :session_payload_type, 6, "Session Payload Type", :endian => 'little'
19-
20-
unsigned :session_id, 32, "Session ID"
21-
unsigned :session_sequence, 32, "Session Sequence Number"
22-
unsigned :message_length, 16, "Message Length", :endian => "little"
23-
24-
unsigned :ignored1, 8, "Ignored"
25-
unsigned :error_code, 8, "RMCP Error Code"
26-
unsigned :ignored2, 16, "Ignored"
27-
char :console_session_id, 32, "Console Session ID"
28-
char :bmc_session_id, 32, "BMC Session ID"
3+
require 'bindata'
294

30-
rest :stuff, "The Rest of the Stuff"
31-
end
32-
33-
end
34-
end
5+
module Rex
6+
module Proto
7+
module IPMI
8+
class Open_Session_Reply < BinData::Record
9+
endian :little
10+
uint8 :rmcp_version ,label: "RMCP Version"
11+
uint8 :rmcp_padding ,label: "RMCP Padding"
12+
uint8 :rmcp_sequence ,label: "RMCP Sequence"
13+
bit1 :rmcp_mtype ,label: "RMCP Message Type"
14+
bit7 :rmcp_class ,label: "RMCP Message Class"
15+
16+
uint8 :session_auth_type ,label: "Authentication Type"
17+
18+
bit1 :session_payload_encrypted ,label: "Session Payload Encr"
19+
bit1 :session_payload_authenticated ,label: "Session Payload Auth"
20+
bit6 :session_payload_type ,label: "Session Payload Type"
21+
22+
uint32 :session_id ,label: "Session ID"
23+
uint32 :session_sequence ,label: "Session Sequence Number"
24+
uint16 :message_length ,label: "Message Length"
25+
26+
uint8 :ignored1 ,label: "Ignored"
27+
uint8 :error_code ,label: "RMCP Error Code"
28+
uint16 :ignored2 ,label: "Ignored"
29+
rest :data ,label: "Session Info"
30+
end
31+
32+
class Session_Data < BinData::Record
33+
endian :little
34+
string :console_session_id, length: 4 ,label: "Console Session ID"
35+
string :bmc_session_id, length: 4 ,label: "BMC Session ID"
36+
end
37+
end
38+
end
3539
end
36-

lib/rex/proto/ipmi/rakp2.rb

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
11
# -*- coding: binary -*-
22

3-
module Rex
4-
module Proto
5-
module IPMI
6-
7-
class RAKP2 < BitStruct
8-
unsigned :rmcp_version, 8, "RMCP Version"
9-
unsigned :rmcp_padding, 8, "RMCP Padding"
10-
unsigned :rmcp_sequence, 8, "RMCP Sequence"
11-
unsigned :rmcp_mtype, 1, "RMCP Message Type"
12-
unsigned :rmcp_class, 7, "RMCP Message Class"
3+
require 'bindata'
134

14-
unsigned :session_auth_type, 8, "Authentication Type"
5+
module Rex
6+
module Proto
7+
module IPMI
8+
class RAKP2 < BinData::Record
9+
endian :little
10+
uint8 :rmcp_version ,label: "RMCP Version"
11+
uint8 :rmcp_padding ,label: "RMCP Padding"
12+
uint8 :rmcp_sequence ,label: "RMCP Sequence"
13+
bit1 :rmcp_mtype ,label: "RMCP Message Type"
14+
bit7 :rmcp_class ,label: "RMCP Message Class"
1515

16-
unsigned :session_payload_encrypted, 1, "Session Payload Encrypted"
17-
unsigned :session_payload_authenticated, 1, "Session Payload Authenticated"
18-
unsigned :session_payload_type, 6, "Session Payload Type", :endian => 'little'
16+
uint8 :session_auth_type ,label: "Authentication Type"
1917

20-
unsigned :session_id, 32, "Session ID"
21-
unsigned :session_sequence, 32, "Session Sequence Number"
22-
unsigned :message_length, 16, "Message Length", :endian => "little"
18+
bit1 :session_payload_encrypted ,label: "Session Payload Encrypted"
19+
bit1 :session_payload_authenticated ,label: "Session Payload Authenticated"
20+
bit6 :session_payload_type ,label: "Session Payload Type"
2321

24-
unsigned :ignored1, 8, "Ignored"
25-
unsigned :error_code, 8, "RMCP Error Code"
26-
unsigned :ignored2, 16, "Ignored"
27-
char :console_session_id, 32, "Console Session ID"
28-
char :bmc_random_id, 128, "BMC Random ID"
29-
char :bmc_guid, 128, "RAKP2 Hash 2 (nulls)"
30-
char :hmac_sha1, 160, "HMAC_SHA1 Output"
31-
rest :stuff, "The rest of the stuff"
32-
end
22+
uint32 :session_id ,label: "Session ID"
23+
uint32 :session_sequence ,label: "Session Sequence Number"
24+
uint16 :message_length ,label: "Message Length"
25+
uint8 :ignored1 ,label: "Ignored"
26+
uint8 :error_code ,label: "RMCP Error Code"
27+
uint16 :ignored2 ,label: "Ignored"
28+
rest :data ,label: "RAKP2 Data"
29+
end
3330

34-
end
35-
end
31+
class RAKP2_Data < BinData::Record
32+
endian :little
33+
string :console_session_id, length: 4 ,label: "Console Session ID"
34+
string :bmc_random_id, length: 16 ,label: "BMC Random ID"
35+
string :bmc_guid, length: 16 ,label: "RAKP2 Hash 2 (nulls)"
36+
string :hmac_sha1, length: 20 ,label: "HMAC_SHA1 Output"
37+
end
38+
end
39+
end
3640
end

modules/auxiliary/scanner/ipmi/ipmi_cipher_zero.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def initialize
1616
super(
1717
'Name' => 'IPMI 2.0 Cipher Zero Authentication Bypass Scanner',
1818
'Description' => %q|
19-
This module identifies IPMI 2.0 compatible systems that are vulnerable
19+
This module identifies IPMI 2.0-compatible systems that are vulnerable
2020
to an authentication bypass vulnerability through the use of cipher
2121
zero.
2222
|,
@@ -54,9 +54,8 @@ def scan_host(ip)
5454
end
5555

5656
def scanner_process(data, shost, sport)
57-
info = Rex::Proto::IPMI::Open_Session_Reply.new(data) rescue nil
58-
return if not info
59-
return if not info.session_payload_type == Rex::Proto::IPMI::PAYLOAD_RMCPPLUSOPEN_REP
57+
info = Rex::Proto::IPMI::Open_Session_Reply.new.read(data)# rescue nil
58+
return unless info && info.session_payload_type == Rex::Proto::IPMI::PAYLOAD_RMCPPLUSOPEN_REP
6059

6160
# Ignore duplicate replies
6261
return if @res[shost]

0 commit comments

Comments
 (0)