Skip to content

Commit

Permalink
Merge pull request #17 from praetorian-inc/detect-ipmi
Browse files Browse the repository at this point in the history
Add IPMI Detection Plugin
  • Loading branch information
UNC1739 committed Apr 25, 2023
2 parents 312cf79 + f3d12c9 commit 4b720d4
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 0 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
)

require (
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/kr/text v0.2.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
)
Expand All @@ -37,6 +38,7 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opencontainers/runc v1.1.3 // indirect
github.com/ory/dockertest v3.3.5+incompatible
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VM
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
Expand Down Expand Up @@ -77,6 +79,8 @@ github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b
github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY=
github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
142 changes: 142 additions & 0 deletions pkg/plugins/services/ipmi/ipmi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright 2022 Praetorian Security, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ipmi

import (
"io"
"net"
"time"

"github.com/praetorian-inc/fingerprintx/pkg/plugins"
)

// http://72.47.221.139/sites/default/files/standards/documents/DSP0114.pdf

var ipmiInitialPacket = [23]byte{

//
// Remote Management Control Protocol, Class: IPMI
// Version: 0x06
// Reserved: 0x00
// Sequence: 0xFF
// Type: 0x07
//

0x06, 0x00, 0xFF, 0x07,

//
// IPMI v1.5 Session Wrapper, Session ID 0x00
// Authentication Type: NONE (0x00)
// Session ID: 0x00 0x00 0x00 0x00
// Session Sequence number: 0x00 0x00 0x00 0x00
// Message Length: 9
//

0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x09,

//
// Intelligent Platform Management Bus
// Bus Command Data: 20 18 C8 81 00 38 8E 04 B5
//

0x20, 0x18, 0xC8, 0x81, 0x00, 0x38, 0x8E, 0x04, 0xB5,
}

var ipmiExpectedResponse = [13]byte{

/*
* Remote Management Control Protocol, Class: IPMI
* Version: 0x06
* Reserved: 0x00
* Sequence: 0xFF
* Type: 0x07
*/

0x06, 0x00, 0xFF, 0x07,

//
// IPMI v1.5 Session Wrapper, Session ID 0x00
// Authentication Type: NONE (0x00)
// Session ID: 0x00 0x00 0x00 0x00
// Session Sequence number: 0x00 0x00 0x00 0x00
//

0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
}

type IPMIPlugin struct{}

const IPMI = "ipmi"

func isIPMI(conn net.Conn, timeout time.Duration) (bool, error) {
_, err := conn.Write(ipmiInitialPacket[:])
if err != nil {
return false, err
}

response := make([]byte, len(ipmiExpectedResponse))

err = conn.SetReadDeadline(time.Now().Add(timeout))
if err != nil {
return false, err
}

_, err = io.ReadFull(conn, response)
if err != nil {
return false, err
}

for i, b := range ipmiExpectedResponse {
if response[i] != b {
return false, nil
}
}

return true, nil
}

func init() {
plugins.RegisterPlugin(&IPMIPlugin{})
}

func (p *IPMIPlugin) PortPriority(port uint16) bool {
return port == 623
}

func (p *IPMIPlugin) Run(conn net.Conn, timeout time.Duration, target plugins.Target) (*plugins.Service, error) {
if isIPMI, err := isIPMI(conn, timeout); !isIPMI || err != nil {
return nil, nil
}
payload := plugins.ServiceIPMI{}

return plugins.CreateServiceFrom(target, payload, false, "", plugins.UDP), nil
}

func (p *IPMIPlugin) Name() string {
return IPMI
}

func (p *IPMIPlugin) Type() plugins.Protocol {
return plugins.UDP
}

func (p *IPMIPlugin) Priority() int {
return 80
}
53 changes: 53 additions & 0 deletions pkg/plugins/services/ipmi/ipmi_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2022 Praetorian Security, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ipmi

import (
"testing"

"github.com/ory/dockertest/v3"
"github.com/praetorian-inc/fingerprintx/pkg/plugins"
"github.com/praetorian-inc/fingerprintx/pkg/test"
)

func TestIPMI(t *testing.T) {
testcases := []test.Testcase{
{
Description: "ipmi",
Port: 623,
Protocol: plugins.UDP,
Expected: func(res *plugins.Service) bool {
return res != nil
},
RunConfig: dockertest.RunOptions{
Repository: "vaporio/ipmi-simulator",
ExposedPorts: []string{"623/udp"},
},
},
}

p := &IPMIPlugin{}

for _, tc := range testcases {
tc := tc
t.Run(tc.Description, func(t *testing.T) {
t.Parallel()
err := test.RunTest(t, tc, p)
if err != nil {
t.Errorf(err.Error())
}
})
}
}
5 changes: 5 additions & 0 deletions pkg/plugins/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const (
ProtoHTTP2 = "http2"
ProtoIMAP = "imap"
ProtoIMAPS = "imaps"
ProtoIPMI = "ipmi"
ProtoIPSEC = "ipsec"
ProtoKafka = "kafka"
ProtoLDAP = "ldap"
Expand Down Expand Up @@ -488,6 +489,10 @@ type ServiceEcho struct{}

func (e ServiceEcho) Type() string { return ProtoEcho }

type ServiceIPMI struct{}

func (e ServiceIPMI) Type() string { return ProtoIPMI }

type ServiceRsync struct{}

func (e ServiceRsync) Type() string { return ProtoRsync }
1 change: 1 addition & 0 deletions pkg/scan/plugin_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
_ "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/ftp"
_ "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/http"
_ "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/imap"
_ "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/ipmi"
_ "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/ipsec"
_ "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/kafka/kafkaNew"
_ "github.com/praetorian-inc/fingerprintx/pkg/plugins/services/kafka/kafkaOld"
Expand Down

0 comments on commit 4b720d4

Please sign in to comment.