osrg/gobgp

Gobgp does not check the length of the received `Capability Length` of the `Software Version Capability`

GoldBinocle opened this issue · 4 comments

Summary

Gobgp does not check the length of the received Capability Length of the Software Version Capability. The Capability Length SHOULD be no greater than 64, as per draft-abraitis-bgp-version-capability-12.

Reproduce

Config

The config of the under-test node is as follows, and its IP is 10.0.255.6

[global.config]
  as = 65001
  router-id = "192.168.10.6"


[[neighbors]]
  [neighbors.config]
    neighbor-address = "10.0.255.5"
    peer-as = 64512

The config of the test node is as follows, and its IP is 10.0.255.5

[global.config]
  as = 64512
  router-id = "192.168.10.5"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "10.0.255.6"
    peer-as = 65001

Attack

On the test node, send a BGP Open packet with Software Version Capability whose length is greater than 64:

echo "ffffffffffffffffffffffffffffffff00620104fc00005ac0a80a054502434b414000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" | xxd -p -r | nc 10.0.255.6 179

Then, the under-test node will accept the Open packet without checking whether the length exceeds the maximum, and the full logs are as follows:

{"level":"info","msg":"gobgpd started","time":"2023-10-31T02:35:32Z"}
{"Topic":"Config","level":"info","msg":"Finished reading the config file","time":"2023-10-31T02:35:32Z"}
{"Key":"10.0.255.5","Topic":"config","level":"info","msg":"Add Peer","time":"2023-10-31T02:35:32Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"info","msg":"Add a peer configuration","time":"2023-10-31T02:35:32Z"}
{"Duration":0,"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"IdleHoldTimer expired","time":"2023-10-31T02:35:32Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"state changed","new":"BGP_FSM_ACTIVE","old":"BGP_FSM_IDLE","reason":{"Type":7,"BGPNotification":null,"Data":null},"time":"2023-10-31T02:35:32Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"Accepted a new passive connection","time":"2023-10-31T02:35:33Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"stop connect loop","time":"2023-10-31T02:35:33Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"state changed","new":"BGP_FSM_OPENSENT","old":"BGP_FSM_ACTIVE","reason":{"Type":11,"BGPNotification":null,"Data":null},"time":"2023-10-31T02:35:33Z"}
{"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"state changed","new":"BGP_FSM_OPENCONFIRM","old":"BGP_FSM_OPENSENT","reason":{"Type":12,"BGPNotification":null,"Data":null},"time":"2023-10-31T02:35:33Z"}

Analysis

The parse result of the PoC packet is

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Marker (first 8 bytes)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // Marker (second 8 bytes)
0x00, 0x62, // Length: 98
0x01, // Type: OPEN


0x04,       // version: 4
0xfc, 0x00, // my as: 64512
0x00, 0x5a, // hold time: 90 seconds
0xc0, 0xa8, 0x0a, 0x05, // BGP identifier: 192.168.10.5
0x45, // optional parameters length: 69
0x02, // parameter type: capability
0x43, // parameter length: 67

0x4b,       // capability type: Software Version (75)
0x41,       // capability length: 65   <-------- the length value is larger than 64
0x40,      // version length: 64   
0x00 * 64  // version

The corresponding parse function is:

gobgp/pkg/packet/bgp/bgp.go

Lines 1073 to 1083 in 1b975be

func (c *CapSoftwareVersion) DecodeFromBytes(data []byte) error {
c.DefaultParameterCapability.DecodeFromBytes(data)
data = data[2:]
if len(data) < 2 {
return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilitySoftwareVersion bytes allowed")
}
softwareVersionLen := uint8(data[0])
c.SoftwareVersionLen = softwareVersionLen
c.SoftwareVersion = string(data[1:c.SoftwareVersionLen])
return nil
}

In line 1079, SoftwareVersionLen represents the version length field and is read from the packet without sanitization, we should check whether it exceeds the maximum, i.e., 64. This bug is similar to CVE-2023-41361.

fujita commented

Thanks for the report. Can you send a pull request?

fujita commented

Let me know if you prefer me to fix this.

@fujita I would prefer you to fix it because I'm not familiar with gobgp right now and I don't know which error type should be returned for this violation. I can fix another one.

fujita commented

fixed, thanks.