2011-03-17: 细节已通知厂商并且等待厂商处理中 2011-03-22: 厂商已经主动忽略漏洞,细节向公众公开
最近在分析皮皮播放器的时候,发现皮皮播放器的负责通讯的进程中的jfCacheMgr.exe中存在一处溢出。
...... memset(DstBuf, 0, 0x800u); // 我们可以看到DstBuf这里是0x800的大小 v5 = fread(DstBuf, 1u, 0x800u, v3); //将文件内容读入DstBuf中。最大为0x800 fclose(v4); if ( ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::Find(&v261, ".jia", 0) == -1 )//如果在打开的文件名中找不到.jia字符串,则执行如下代码 { 。。。。。。 return 0; } // 主要判断文件名中是否含有.jia if ( (signed int)v5 < 10 || v5 >= 0x800 ) // v5如果读到的内容小于10或者大于0x800,退出 {LABEL_298: v242 = (const CHAR *)ATL::CSimpleStringT<char_1>::operator char_const__(&v261); DeleteFileA(v242); goto LABEL_299; } if ( !strncmp(DstBuf, "/sysoptions", 0xBu) ) // 如果数据中有/sysoptions选项 { Time = time64(0); v7 = sub_4082D0(&Time, (int)&v302, "%A, %B %d, %Y"); LOBYTE(v344) = 8; v8 = ATL::CSimpleStringT<char_1>::operator char_const__(v7); std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>( &v324, v8); LOBYTE(v344) = 10; ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::_CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v302); v287 = &v252; std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>( &v252, &v324); sub_49D070(&v325, v252); LOBYTE(v344) = 11; if ( strncmp(&Str1, "/p", 2u) ) { *((_DWORD *)v283 + 43) = 0; v258 = &Str1; } else { ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::operator_(&v278, v341); v9 = (const char *)ATL::CSimpleStringT<char_1>::operator char_const__(&v278); *((_DWORD *)v283 + 43) = atoi(v9); v258 = (char *)&v341 + 2; } ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::operator_(&v278, v258); v258 = (const char *)std::basic_string<char_std::char_traits<char>_std::allocator<char>>::c_str(&v325); if ( !ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::Compare(&v278) && dword_4CA0D8 ) { v258 = (const char *)32773; *((_DWORD *)dword_4CA0D8 + 96) = 1; sub_40E5B0(v258); } v10 = (const CHAR *)ATL::CSimpleStringT<char_1>::operator char_const__(&v261); DeleteFileA(v10); LOBYTE(v344) = 10; std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_basic_string<char_std::char_traits<char>_std::allocator<char>>(&v325); LOBYTE(v344) = 6; std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_basic_string<char_std::char_traits<char>_std::allocator<char>>(&v324); goto LABEL_299; } if ( !strncmp(DstBuf, "/hotkeyopt", 0xAu) ) // 如果数据中有/hotkeyopt选项 { sub_409FA0(&v316); v11 = sub_4082D0((__time64_t *)&v316, (int)&v304, "%A, %B %d, %Y"); LOBYTE(v344) = 12; v12 = ATL::CSimpleStringT<char_1>::operator char_const__(v11); std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>( &v327, v12); LOBYTE(v344) = 14; ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::_CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v304); v287 = &v252; std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>( &v252, &v327); sub_49D070(&v326, v252); LOBYTE(v344) = 15; if ( (unsigned __int8)std::operator__<char_std::char_traits<char>_std::allocator<char>>(&v326, &v339) && dword_4CA0D8 ) { v258 = (const char *)32777; *((_DWORD *)dword_4CA0D8 + 96) = 1; sub_40E5B0(v258); } v13 = (const CHAR *)ATL::CSimpleStringT<char_1>::operator char_const__(&v261); DeleteFileA(v13); LOBYTE(v344) = 14; std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_basic_string<char_std::char_traits<char>_std::allocator<char>>(&v326); LOBYTE(v344) = 6; std::basic_string<char_std::char_traits<char>_std::allocator<char>>::_basic_string<char_std::char_traits<char>_std::allocator<char>>(&v327); goto LABEL_299; } if ( strncmp(DstBuf, "/uninstall", 0xAu) ) // 如果数据中没有/unistall选项 { v258 = (const char *)ATL::CSimpleStringT<char_1>::GetLength(&unk_4CA174); v14 = (const char *)ATL::CSimpleStringT<char_1>::operator char_const__(&unk_4CA174); if ( strnicmp(DstBuf, v14, (size_t)v258) ) // 如果没有这个字符串 { v258 = (const char *)ATL::CSimpleStringT<char_1>::GetLength(&unk_4CA178); v15 = (const char *)ATL::CSimpleStringT<char_1>::operator char_const__(&unk_4CA178); if ( strnicmp(DstBuf, v15, (size_t)v258) ) goto LABEL_298; } if ( dword_4C9E50 != 4 ) { CStringList::AddTail(&v313, &v261); goto LABEL_299; } v16 = (const CHAR *)ATL::CSimpleStringT<char_1>::operator char_const__(&v261); DeleteFileA(v16); // 删除v261,这个文件 v17 = 0; sub_4102F0(*((_DWORD *)v283 + 8), 1, 0); // init the player v18 = 0; v292 = 0; v287 = (int *)3; v293 = 0; ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v264); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v263); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v282); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v286); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v281); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v284); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v285); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v269); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v270); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v276); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v266); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v265); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v271); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v274); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v272); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v279); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v275); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v277); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v280); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v268); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>(&v267); LOBYTE(v344) = 36; ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::operator_(&v268, "1"); ATL::CStringT<char_StrTraitMFC_DLL<char_ATL::ChTraitsCRT<char>>>::operator_(&v267, "1"); ((void (__thiscall *)(char *))std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>)(&v321); LOBYTE(v344) = 37; v298 = 0; v19 = strstr(DstBuf, "|info="); // 看DstBuf中是否有这个字符串,如果有则返回其指针 if ( v19 ) { ((void (__thiscall *)(char *))std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>)(&v322); LOBYTE(v344) = 38; ((void (__thiscall *)(char *))std::basic_string<char_std::char_traits<char>_std::allocator<char>>::basic_string<char_std::char_traits<char>_std::allocator<char>>)(&v323); memset(Source, 0, 0x104u); // source的大小为0x104 LOBYTE(v344) = 39; v20 = strchr(v19 + 6, 124); // 在DstBuf中从"|info="后开始找'|'这个符号,如果找到 hWnd = v20; if ( v20 ) { //如果找到|这个符号,就把'|'到"|info="中间的内容拷贝到Source这个缓冲区中,前面我们知道这个缓冲区的大小为0x104,而DstBuf最大可以为0x800,所以我们可以构造超长的文件内容,从而产生溢出。譬如我们构造ppfilm://aaaaa|info=aaaaa(大于0x104个a)|bbb,则可产生溢出。 memcpy(Source, v19 + 6, v20 - v19 - 6); // std::basic_string<char_std::char_traits<char>_std::allocator<char>>::operator_(&v322, Source); memset(Source, 0, 0x104u); strncpy(Source, hWnd, 0x103u); } else { std::basic_string<char_std::char_traits<char>_std::allocator<char>>::operator_(&v322, v19 + 6); }
这个是拿IDA看出来的,它读取的是pipi\config\candel12953414392524453.jias这个文件,由于暂时还不知道如何让jfCcheMgr.exe读这个文件,所以暂时还没找到利用的方法。所以无法证明
对从文件读取的内容长度进行限制,或者对其拷贝的内容的长度进行判断。
危害等级:无影响厂商忽略
忽略时间:2011-03-22 21:00
漏洞Rank:10 (WooYun评价)
暂无
可以通过Hook来使读取重定向的方式来让皮皮读取恶意构建的但是这个方法实在没影响力。