Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stack buffer overflow of parsing swf #138

Open
binjo opened this issue Nov 9, 2017 · 4 comments
Open

Stack buffer overflow of parsing swf #138

binjo opened this issue Nov 9, 2017 · 4 comments
Labels

Comments

@binjo
Copy link

binjo commented Nov 9, 2017

Hi,

When I play with r2 and the swf plugin, it crashes with a buffer overflow.

(lldb) run
Process 54371 launched: '/usr/local/bin/r2' (x86_64)
2017-11-09 08:40:51.921302+0800 r2[54371:19870295] detected buffer overflow
Process 54371 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff98965d42 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff98965d42 <+10>: jae    0x7fff98965d4c            ; <+20>
    0x7fff98965d44 <+12>: movq   %rax, %rdi
    0x7fff98965d47 <+15>: jmp    0x7fff9895ecaf            ; cerror_nocancel
    0x7fff98965d4c <+20>: retq
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x00007fff98965d42 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff98a53457 libsystem_pthread.dylib`pthread_kill + 90
    frame #2: 0x00007fff988cb420 libsystem_c.dylib`abort + 129
    frame #3: 0x00007fff988cb592 libsystem_c.dylib`abort_report_np + 181
    frame #4: 0x00007fff988f1f28 libsystem_c.dylib`__chk_fail + 48
    frame #5: 0x00007fff988f1ef8 libsystem_c.dylib`__chk_fail_overflow + 16
    frame #6: 0x00007fff988f1f8e libsystem_c.dylib`__memset_chk + 37
    frame #7: 0x0000000101a2de09 bin_swf.dylib`r_bin_swf_get_header + 169
    frame #8: 0x0000000101a2d9b7 bin_swf.dylib`entries + 119
    frame #9: 0x0000000100357d90 libr_bin.dylib`r_bin_object_set_items(binfile=0x0000000101c09ca0, o=0x0000000101b373a0) at bin.c:770
    frame #10: 0x000000010035aa35 libr_bin.dylib`r_bin_object_new(binfile=0x0000000101c09ca0, plugin=0x0000000101d00740, baseaddr=18446744073709551615, loadaddr=0, offset=0, sz=856) at bin.c:1377
    frame #11: 0x0000000100359ebc libr_bin.dylib`r_bin_file_new_from_bytes(bin=0x0000000101b09220, file="testfk.swf", bytes="CWS\x1b, sz=856, file_sz=856, rawstr=0, baseaddr=18446744073709551615, loadaddr=0, fd=3, pluginname=0x0000000000000000, xtrname=0x0000000000000000, offset=0, steal_ptr=true) at bin.c:1567
    frame #12: 0x00000001003598c4 libr_bin.dylib`r_bin_load_io_at_offset_as_sz(bin=0x0000000101b09220, fd=3, baseaddr=18446744073709551615, loadaddr=0, xtr_idx=0, offset=0, name=0x0000000000000000, sz=856) at bin.c:1118
    frame #13: 0x0000000100358ad6 libr_bin.dylib`r_bin_load_io_at_offset_as(bin=0x0000000101b09220, fd=3, baseaddr=18446744073709551615, loadaddr=0, xtr_idx=0, offset=0, name=0x0000000000000000) at bin.c:1132
    frame #14: 0x0000000100358970 libr_bin.dylib`r_bin_load_io(bin=0x0000000101b09220, fd=3, baseaddr=18446744073709551615, loadaddr=0, xtr_idx=0) at bin.c:1021
    frame #15: 0x0000000100196584 libr_core.dylib`r_core_file_do_load_for_io_plugin(r=0x00000001000084e0, baseaddr=18446744073709551615, loadaddr=0) at file.c:406
    frame #16: 0x000000010019507f libr_core.dylib`r_core_bin_load(r=0x00000001000084e0, filenameuri="testfk.swf", baddr=18446744073709551615) at file.c:563
    frame #17: 0x0000000100003962 r2`main(argc=2, argv=0x00007fff5fbff548, envp=0x00007fff5fbff560) at radare2.c:1009
    frame #18: 0x00007fff98837235 libdyld.dylib`start + 1
    frame #19: 0x00007fff98837235 libdyld.dylib`start + 1

Checking the code, turns out a simple stack buffer overflow.

// https://github.com/radare/radare2-extras/blob/master/libr/bin/format/swf/swf_specs.h
#define SWF_HDR_MIN_SIZE 12

// https://github.com/radare/radare2-extras/blob/master/libr/bin/format/swf/swf.h
typedef struct __attribute__((__packed__)) {
  ut8 signature[3];
  ut8 version;
  ut32 file_size;
  ut8 rect_size;
  ut16 frame_rate;
  ut16 frame_count;
} swf_hdr;

// https://github.com/radare/radare2-extras/blob/master/libr/bin/p/bin_swf.c
static RList* entries(RBinFile *arch) {
  RList *ret = NULL;
  RBinAddr *ptr = NULL;

  if (!(ret = r_list_new()))
    return NULL;
  if (!(ptr = R_NEW0 (RBinAddr)))
    return ret;

  swf_hdr header;        // stack variable
  header = r_bin_swf_get_header(arch);
  // ...
}

// https://github.com/radare/radare2-extras/blob/master/libr/bin/format/swf/swf.c
swf_hdr r_bin_swf_get_header(RBinFile *arch) {
  swf_hdr header;     // stack variable
  ut8 nBits;

  /* First, get the rect size */
  r_buf_read_at (arch->buf, 8, (ut8*)&nBits, 1);
  nBits = (nBits & 0xf8) >> 3;
  ut32 rect_size_bits = nBits*4 + 5;
  ut32 rect_size_bytes = rect_size_bits / 8;
  if (rect_size_bits % 8) rect_size_bytes++;

  /* Read the whole header */
  memset(&header, 0, SWF_HDR_MIN_SIZE + rect_size_bytes);   // stack overflow
  r_buf_read_at(arch->buf, 0, (ut8*)&header, 8);
  // ...
}

the header is a variable on the stack, the memset call with size of SWF_HDR_MIN_SIZE + rect_size_bytes will easily exceeds the bound, leads to buffer overflow.

The parser needs to decompress the flash file first when it's compressed flash(CWS/ZWS) and proceed the parse logic IMHO.

Cheers.

@Maijin
Copy link
Contributor

Maijin commented Nov 9, 2017

Can you send a Pull Request fixing this.

@radare
Copy link
Collaborator

radare commented Nov 13, 2017

what about providing a binary to reproduce the issue?

@binjo
Copy link
Author

binjo commented Nov 14, 2017

Hi @radare,
try this one, it is a CWS compressed flash file.
http://www.diyed.co.uk/diy-ed-information-book-sample/files/flash/expressInstall.swf
you may use my trivial script to decompress, https://github.com/binjo/utils/blob/master/cws2fws.py

md5sum expressInstall.swf fws-expressInstall.swf
7b65fbfaec8b2955090389af60646e8b  expressInstall.swf
7089405dc1945dd72bcfb14630900f46  fws-expressInstall.swf

it should crash on any flash file :<

@radare
Copy link
Collaborator

radare commented Nov 16, 2017

@xarkes please have a look at this

@XVilka XVilka added the swf label Jul 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants