djcsdy / swfmill

Generate or decompile Adobe Flash SWF files using an XML dialect. Inspect and modify the XML by hand, or by using a built in XSLT processor.
http://www.swfmill.org/
GNU General Public License v2.0
131 stars 28 forks source link

bug4: heap oob read (info leak) of swfmill swf2xml #49

Open ghost opened 6 years ago

ghost commented 6 years ago

poc: https://drive.google.com/open?id=1NT-eAqw-yxV8IlwKG-Y2FoaOxIe43kjK asan: https://drive.google.com/open?id=14LD3HjGsdQZOyw2FLocu6TzTyRP55yBS

bool MetadataInfo::parse( Reader *r, int end, Context *ctx ) {
file_offset = r->getPosition();
if( ctx->debugTrace ) {
fprintf( stderr, "PARSE %s @%i-%i :%i\n",
"MetadataInfo",
r->getPosition(),
r->getBits(),
end );
}

nameIndex = r->getU30();
if( ctx->debugTrace ) {
fprintf( stderr, "PARSE %s: %" PRIi32 "\n",
"nameIndex",
nameIndex );
}
valuesCount = r->getU30();
if( ctx->debugTrace ) {
fprintf( stderr, "PARSE %s: %" PRIi32 "\n",
"valuesCount",
valuesCount );
}

{
if( ctx->debugTrace ) {
fprintf( stderr, "PARSE list<%s> %s: %i items, @%i-%i :%i\n",
"U30",
"keys",
valuesCount,
r->getPosition(),
r->getBits(),
end );
}
U30 *item;
for( int i=0; i<valuesCount; i++ ) {
item = U30::get(r,end,ctx);
keys.append( item );
}
}

Due to that the val valuesCount is set based on the value from file (r->getU30()), this value can be faked! In the loop below, for( int i=0; i<valuesCount; i++ ), it will execute U30::get(r,end,ctx) many times without checking.

bool U30::parse( Reader *r, int end, Context *ctx ) {
file_offset = r->getPosition();
if( ctx->debugTrace ) {
fprintf( stderr, "PARSE %s @%i-%i :%i\n",
"U30",
r->getPosition(),
r->getBits(),
end );
}

value = r->getU30();
if( ctx->debugTrace ) {
fprintf( stderr, "PARSE %s: %" PRIi32 "\n",
"value",
value );
}

return r->getError() == Reader::ok;
}

the val end is useless! So Heap Out-of-bound Read will happen, which may cause memory leaking!