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

heap-use-after-free in decompileJUMP (decompile.c) #131

Closed
traceprobe opened this issue Mar 25, 2018 · 3 comments
Closed

heap-use-after-free in decompileJUMP (decompile.c) #131

traceprobe opened this issue Mar 25, 2018 · 3 comments

Comments

@traceprobe
Copy link

traceprobe commented Mar 25, 2018

In latest version of libming (0.4.8), there is a heap-use-after-free in decompileJUMP function of decompile.c file, which could be triggered by the POC below.

The "FREE" operation corresponds to a "realloc" in parseSWF_DOACTION (parser.c:2435):
2424 SWF_Parserstruct *
2425 parseSWF_DOACTION (FILE * f, int length)
2426 {
2433 while ( fileOffset < end ) {
2434 parseSWF_ACTIONRECORD (f, &(parserrec->numActions), parserrec->Actions );
2435 parserrec->Actions = (SWF_ACTION *) realloc (parserrec->Actions,

2441 }

2446 }

The freed memory is used in decompileJUMP function (decompile.c:1857):
1810 static int
1811 decompileJUMP(int n, SWF_ACTION *actions, int maxn)
1812 {
...
1857 if (sactif->Actions[sactif->numActions-1].SWF_ACTIONRECORD.ActionCode==SWFACTION_JUMP
...
1922 }

To reproduce the issue, compile libming with ASAN and run: ./swftophp $POC

The complete stack trace is:
==193066==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000000040 at pc 0x00000054335b bp 0x7ffee1b86480 sp 0x7ffee1b86478
READ of size 1 at 0x607000000040 thread T0
#0 0x54335a in decompileJUMP /u/test/test/product/libming/master/src/util/decompile.c:1857:64
#1 0x54335a in decompileAction /u/test/test/product/libming/master/src/util/decompile.c:3250
#2 0x562a22 in decompileActions /u/test/test/product/libming/master/src/util/decompile.c:3419:6
#3 0x562a22 in decompile5Action /u/test/test/product/libming/master/src/util/decompile.c:3441
#4 0x522350 in outputSWF_DOACTION /u/test/test/product/libming/master/src/util/outputscript.c:1552:29
#5 0x520727 in outputBlock /u/test/test/product/libming/master/src/util/outputscript.c:2083:4
#6 0x5275be in readMovie /u/test/test/product/libming/master/src/util/main.c:286:4
#7 0x5275be in main /u/test/test/product/libming/master/src/util/main.c:359
#8 0x7f62cf484c04 in __libc_start_main (/lib64/libc.so.6+0x21c04)
#9 0x41b49b in _start (/home/test/test/product/libming/master/exe_asan/bin/swftophp+0x41b49b)
libming_0-4-8_swftophp_heap-use-after-free_decompileJUMP.swf.zip

@hlef
Copy link
Contributor

hlef commented May 14, 2018

Same issue as f42fdb4, same fix. I recommend patching other source code places which might be affected by the same bug.

diff --git a/util/decompile.c b/util/decompile.c
index e9341356..3e5ba8e7 100644
--- a/util/decompile.c
+++ b/util/decompile.c
@@ -1929,7 +1929,7 @@ decompileJUMP(int n, SWF_ACTION *actions, int maxn)
                        {
                                sactif = (struct SWF_ACTIONIF *)&(actions[n+i+j]);
                                /* chk whether last jump does lead us back to start of loop */
-                               if (sactif->Actions[sactif->numActions-1].SWF_ACTIONRECORD.ActionCode==SWFACTION_JUMP
+                               if (OpCode(sactif->Actions, sactif->numActions-1, maxn) == SWFACTION_JUMP
                                    && sactif->Actions[sactif->numActions-1].SWF_ACTIONJUMP.BranchOffset+
                                    sactif->Actions[sactif->numActions-1].SWF_ACTIONJUMP.Offset==
                                    actions[n].SWF_ACTIONRECORD.Offset )
@@ -2334,7 +2334,7 @@ decompileIF(int n, SWF_ACTION *actions, int maxn)
         * that points to a JUMP above the IF statement.
         */
        if(n && isLogicalOp(n-1, actions, maxn) &&
-          (sact->Actions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) &&
+          (OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) &&
           ( (sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.Offset +
              sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset) < actions[n].SWF_ACTIONRECORD.Offset) &&
              isLogicalOp(sact->numActions-2, sact->Actions, maxn) ) 
@@ -2424,7 +2424,7 @@ decompileIF(int n, SWF_ACTION *actions, int maxn)
         */
        
        if( isLogicalOp(n-1, actions, maxn) &&
-           ( (sact->Actions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) &&
+           ( (OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) &&
               sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset < 0) ) 
        {
                if(0)       dumpRegs();
@@ -2460,7 +2460,7 @@ decompileIF(int n, SWF_ACTION *actions, int maxn)
        }
        { // WTF ???
 #define SOME_IF_DEBUG 0        /* coders only */
-               int has_else_or_break= ((sact->Actions[sact->numActions-1].SWF_ACTIONRECORD.ActionCode == SWFACTION_JUMP) &&
+               int has_else_or_break=((OpCode(sact->Actions, sact->numActions-1, maxn) == SWFACTION_JUMP) &&
                        (sact->Actions[sact->numActions-1].SWF_ACTIONJUMP.BranchOffset > 0 )) ? 1:0;
                int has_lognot=(OpCode(actions, n-1, maxn) == SWFACTION_LOGICALNOT) ? 1:0;
                int else_action_cnt=0,is_logor=0,is_logand=0,sbi,sbe;

@strk
Copy link
Member

strk commented May 20, 2018

Will you send the above patch as a PR ?

@hlef
Copy link
Contributor

hlef commented May 21, 2018

Yes, I intend to submit a PR including the last batch of bug fixes I worked on.

hlef added a commit to hlef/libming that referenced this issue May 26, 2018
Same issue as f42fdb4 (functions accessing actions array without
checking the validity of n, the user entered index), same fix.

In this patch we also fix other source code places which might be
affected by the same bug.

Fixes libming#131 (CVE-2018-9009).
@strk strk closed this as completed in 1d698a4 Jul 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants