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评价)
暂无