mouse07410 / asn1c

The ASN.1 Compiler
http://lionet.info/asn1c/
BSD 2-Clause "Simplified" License
101 stars 73 forks source link

Buffer overflow in ASN.1 deserializer #134

Closed acetcom closed 1 year ago

acetcom commented 1 year ago

Dear Community People,

A malformed ASN.1 S1AP packet may be used to overwrite a pointer to a struct with data beyond the end of an array (buffer overflow). This can lead to a Denial of Service attack by an attacker repeatedly sending these packets. Additionally, the struct contains function pointers that are subsequently called; certain installations may be vulnerable to remote code execution as a result.

Crashing Input Examples (Base64 encoded):

a) ACZAYwAACgB6QA8gBNIipkUAv0jzKBcLt1sAekACAAAAekACAAAAekAE9QI9TQB6UAIAAAB6QAMAAVoAekALIAAAj8X4nkVWSmZ6C0AMIAHMAKzE5zgAg72TAHpAAwABgwB6QAIAAA==

b) ACVAWgAACgB5QAsgAAAfZBElvWBQIQB5QAIAAAB5QAYABGgOmQkAeUACAAAAeUACAAAAeUAPIAQkjCirADXNVuo9rz91AHlAAgAAAHlAA/8B9gB5QAIA6gB5QAIAAA==

Steps to reproduce:

  1. aper_decode() with the above decoded base64 payload
  2. Observe segmentation fault

Cause:

When the APC_EXTENSIBLE flag is set, the CHOICE_decode_aper function in constr_CHOICE_aper.c pulls a single bit value from the packet to set as its value. In certain conditions, this bit may be set (equal to 1) such that value = 1, and the value of elm is subsequently set based on using that value as an index:

lib/asn1c/common/constr_CHOICE_aper.c:72

elm = &td->elements[value];

However, the asn_MBR_S1AP_Inter_SystemInformationTransferType_1 array (which td->elements may be set to) has only one element. In this case, a value index of 1 will overflow the buffer, leading to type confusion on subsequent function calls and value references from that elm struct.

This vulnerability may be leveraged to crash the program via malformed inputs sent from a malicious base station (such as a compromised home eNB femtocell). Additionally, the type confusion caused by the buffer overflow may be leveraged by an attacker to facilitate further attacks such as remote code execution, given ideal conditions.

Please let me know if you have any questions.

Thanks in advance. Sukchan

mouse07410 commented 1 year ago

Thank you for letting us know.

Would you have any suggestions how to fix this issue?

acetcom commented 1 year ago

@mouse07410

I am unable to resolve this issue.

Sorry for not help this! Sukchan

lucasgonze commented 1 year ago

Let's brainstorm ways to make progress on this.

There are two strategies.

  1. Set the array size of asn_MBR_S1AP_Inter_SystemInformationTransferType_1 dynamically to accommodate value > 1.
  2. Check whether value > 1 and throw an error. This

@mouse07410, I recognize that you have limited time, but your help would make a big difference. Feel free to email me (lucas@gonze.com).

velichkov commented 1 year ago

Hi @acetcom,

Do you have a unit test that reproduce this crash? If not can you implement one and share it in your open5gs repository or send the pach file to my email.

Regards, Vasil

acetcom commented 1 year ago

@velichkov

I've added the unit test to the open5gs repository (branch mouse07410_issues134).

To reproduce this crash, see the following sequence:

$ git clone https://github.com/open5gs/open5gs
$ cd open5gs
$ git checkout mouse07410-issues134  
$ meson build --prefix=`pwd`/install
$ ninja -C build
$ ./build/
$ ./build/tests/unit/unit
crash-test          : -[1]    45910 segmentation fault (core dumped)  ./build/tests/unit/unit

Here is the GDB.

$ gdb ./build/tests/unit/unit 
(gdb) bt
No stack.
(gdb) r
Starting program: /home/acetcom/Documents/git/open5gs/build/tests/unit/unit 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
crash-test          : -
Program received signal SIGSEGV, Segmentation fault.
aper_open_type_get_simple (ctx=0x7fffffffb958, td=0x7ffff7d6c220, constraints=0x0, sptr=0x7fffffffaf90, pd=0x7fffffffb090) at ../lib/asn1c/common/aper_opentype.c:58
58      rv = td->op->aper_decoder(ctx, td, constraints, sptr, &spd);
(gdb) bt
#0  aper_open_type_get_simple (ctx=0x7fffffffb958, td=0x7ffff7d6c220, 
    constraints=0x0, sptr=0x7fffffffaf90, pd=0x7fffffffb090)
    at ../lib/asn1c/common/aper_opentype.c:58
#1  0x00007ffff7f9535c in aper_open_type_get (ctx=0x7fffffffb958, 
    td=0x7ffff7d6c220, constraints=0x0, sptr=0x7fffffffaf90, pd=0x7fffffffb090)
    at ../lib/asn1c/common/aper_opentype.c:130
#2  0x00007ffff7f9a7de in CHOICE_decode_aper (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7de3960 <asn_DEF_S1AP_Inter_SystemInformationTransferType>, 
    constraints=0x0, sptr=0x7fffffffb180, pd=0x7fffffffb090)
    at ../lib/asn1c/common/constr_CHOICE_aper.c:86
#3  0x00007ffff7f95091 in aper_open_type_get_simple (ctx=0x7fffffffb958, 
    td=0x7ffff7de3960 <asn_DEF_S1AP_Inter_SystemInformationTransferType>, 
    constraints=0x0, sptr=0x7fffffffb180, pd=0x7fffffffb5d0)
    at ../lib/asn1c/common/aper_opentype.c:58
#4  0x00007ffff7f9535c in aper_open_type_get (ctx=0x7fffffffb958, 
    td=0x7ffff7de3960 <asn_DEF_S1AP_Inter_SystemInformationTransferType>, 
    constraints=0x0, sptr=0x7fffffffb180, pd=0x7fffffffb5d0)
    at ../lib/asn1c/common/aper_opentype.c:130
#5  0x00007ffff7f99dde in OPEN_TYPE_aper_get (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7e312c0 <asn_DEF_S1AP_MMEDirectInformationTransferIEs>, 
    sptr=0x5555555aab60, 
    elm=0x7ffff7e31260 <asn_MBR_S1AP_MMEDirectInformationTransferIEs_385+160>, 
    pd=0x7fffffffb5d0) at ../lib/asn1c/common/OPEN_TYPE_aper.c:56
#6  0x00007ffff7f9ba77 in SEQUENCE_decode_aper (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7e312c0 <asn_DEF_S1AP_MMEDirectInformationTransferIEs>, 
    constraints=0x0, sptr=0x7fffffffb3b0, pd=0x7fffffffb5d0)
    at ../lib/asn1c/common/constr_SEQUENCE_aper.c:138
#7  0x00007ffff7f9d18b in SET_OF_decode_aper (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7e10820 <asn_DEF_S1AP_ProtocolIE_Container_8143P69>, 
    constraints=0x0, sptr=0x7fffffffb4a0, pd=0x7fffffffb5d0)
    at ../lib/asn1c/common/constr_SET_OF_aper.c:159
#8  0x00007ffff7f9bad2 in SEQUENCE_decode_aper (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7de3a60 <asn_DEF_S1AP_MMEDirectInformationTransfer>, 
    constraints=0x0, sptr=0x7fffffffb6c0, pd=0x7fffffffb5d0)
    at ../lib/asn1c/common/constr_SEQUENCE_aper.c:140
#9  0x00007ffff7f95091 in aper_open_type_get_simple (ctx=0x7fffffffb958, 
    td=0x7ffff7de3a60 <asn_DEF_S1AP_MMEDirectInformationTransfer>, 
    constraints=0x0, sptr=0x7fffffffb6c0, pd=0x7fffffffb970)
    at ../lib/asn1c/common/aper_opentype.c:58
#10 0x00007ffff7f9535c in aper_open_type_get (ctx=0x7fffffffb958, 
    td=0x7ffff7de3a60 <asn_DEF_S1AP_MMEDirectInformationTransfer>, 
    constraints=0x0, sptr=0x7fffffffb6c0, pd=0x7fffffffb970)
    at ../lib/asn1c/common/aper_opentype.c:130
#11 0x00007ffff7f99dde in OPEN_TYPE_aper_get (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7dda9e0 <asn_DEF_S1AP_InitiatingMessage>, sptr=0x5555555a9db0, 
    elm=0x7ffff7dda980 <asn_MBR_S1AP_InitiatingMessage_1+160>, 
    pd=0x7fffffffb970) at ../lib/asn1c/common/OPEN_TYPE_aper.c:56
#12 0x00007ffff7f9ba77 in SEQUENCE_decode_aper (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7dda9e0 <asn_DEF_S1AP_InitiatingMessage>, constraints=0x0,
   sptr=0x7fffffffba88, pd=0x7fffffffb970)
    at ../lib/asn1c/common/constr_SEQUENCE_aper.c:138
#13 0x00007ffff7f9a7a6 in CHOICE_decode_aper (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7dd91c0 <asn_DEF_S1AP_S1AP_PDU>, constraints=0x0, 
    sptr=0x7fffffffb9f0, pd=0x7fffffffb970)
    at ../lib/asn1c/common/constr_CHOICE_aper.c:83
#14 0x00007ffff7f93cb6 in aper_decode (opt_codec_ctx=0x7fffffffb958, 
    td=0x7ffff7dd91c0 <asn_DEF_S1AP_S1AP_PDU>, sptr=0x7fffffffb9f0, 
    buffer=0x5555555a1d40, size=103, skip_bits=0, unused_bits=0)
    at ../lib/asn1c/common/aper_decoder.c:78
#15 0x00007ffff7f4a2f2 in ogs_asn_decode (
    td=0x7ffff7dd91c0 <asn_DEF_S1AP_S1AP_PDU>, struct_ptr=0x7fffffffba80, 
    struct_size=40, pkbuf=0x5555555a1ce0) at ../lib/asn1c/util/message.c:65
#16 0x00007ffff7fb5e5d in ogs_s1ap_decode (message=0x7fffffffba80, 
    pkbuf=0x5555555a1ce0) at ../lib/s1ap/message.c:50
#17 0x0000555555566333 in test7_func (tc=0x7fffffffdb00, data=0x0)
    at ../tests/unit/crash-test.c:625
#18 0x00007ffff7f71833 in abts_run_test (ts=0x555555588320, 
    f=0x55555556620a <test7_func>, value=0x0) at ../lib/core/abts.c:190
#19 0x0000555555566555 in test_crash (suite=0x555555588320)
    at ../tests/unit/crash-test.c:669
#20 0x0000555555558346 in main (argc=1, argv=0x7fffffffdd78)
    at ../tests/unit/abts-main.c:117

You can see how the unit test program is implemented at the following link: https://github.com/open5gs/open5gs/commit/373b6610958c2761aa9b741cde8fd903e7264f79

Please let me know if you have any other questions.

Thanks a lot! Sukchan

mouse07410 commented 1 year ago

Let's brainstorm ways to make progress on this.

There are two strategies.

  1. Set the array size of asn_MBR_S1AP_Inter_SystemInformationTransferType_1 dynamically to accommodate value > 1.

This seems more attractive - assuming the size is obvious at the point where asn_MBR_S1AP_Inter_SystemInformationTransferType_1 is being set.

  1. Check whether value > 1 and throw an error.

If we cannot conveniently and easily figure the correct size, then indeed this (2) would be the path.

@mouse07410, I recognize that you have limited time, but your help would make a big difference. Feel free to email me (lucas@gonze.com).

Let's see if we can find a way here, without resorting to emails.

velichkov commented 1 year ago

Hi @acetcom, @mouse07410, @lucasgonze,

I just opened mouse07410#140 that fixes the segmentation fault in the two unit tests in the open5gs project.

mouse07410 commented 1 year ago

@velichkov thank you!!

acetcom commented 1 year ago

@velichkov and @mouse07410

I confirmed that the fix passed all open5gs tests.

Thanks a lot! Sukchan

lucasgonze commented 1 year ago

I'm impressed by the health of this community. It's a departure from comparable projects.

mouse07410 commented 1 year ago

@acetcom would you consider making PRs to this repo?

acetcom commented 1 year ago

@mouse07410

This issue has already been merged on #140 .

Please let me know if I have misunderstood.

Thanks a lot! Sukchan