看雪论坛
发新帖
1

[原创]CVE-2010-2883分析笔记

holing 2017-9-10 23:11 777
本来不想写的。。怕技术太差丢人。。。不过还是写下吧,丢了人被人指出来才能提高技术,哈哈

char __cdecl vunerableFunc(int initial_critical_class, int a2, int a3, int a4)
{
int critical_class; // edi@1
bool v5; // zf@1
int v6; // eax@4
size_t v7; // eax@13
int v8; // eax@13
int v9; // eax@15
int v10; // eax@16
int v12; // eax@33
char v13; // [sp+Ch] [bp-58h]@40
int v14; // [sp+2Ch] [bp-38h]@13
int v15; // [sp+34h] [bp-30h]@1
int v16; // [sp+38h] [bp-2Ch]@23
int v17; // [sp+3Ch] [bp-28h]@1
int sing; // [sp+40h] [bp-24h]@4
int v19; // [sp+44h] [bp-20h]@12
int v20; // [sp+48h] [bp-1Ch]@2
int v21; // [sp+4Ch] [bp-18h]@2
char v22; // [sp+53h] [bp-11h]@3
int v23; // [sp+60h] [bp-4h]@1
char v24; // [sp+64h] [bp+0h]@7

critical_class = initial_critical_class;
v17 = initial_critical_class;
v15 = a4;
sub_8041626();
v5 = *(_DWORD *)(initial_critical_class + 8) == 3;
v23 = 0;
if ( !v5 )
{
v20 = 0;
v21 = 0;
v5 = *(_DWORD *)(initial_critical_class + 12) == 1;
LOBYTE(v23) = 1;
if ( v5 )
{
v22 = 0;
sub_802178F(&v20, initial_critical_class, "name");
if ( v20 )
goto LABEL_52;
procSing((int)&sing, initial_critical_class, "SING");
v6 = sing;
LOBYTE(v23) = 2;
if ( sing )
{
if ( !(*(_DWORD *)sing & 0xFFFF) || (*(_DWORD *)sing & 0xFFFF) == 256 )
{
v24 = 0;
strcat(&v24, (const char *)(sing + 16));// overflow here!!!
sub_8001243((int *)a2, (int)&v24);
v6 = sing;
}
v22 = 1;
}
LOBYTE(v23) = 1;
if ( v6 )
sub_80417B9(v6);
if ( !v22 )
{
LABEL_52:
v5 = *(_BYTE *)(initial_critical_class + 188) == 0;
v19 = 0;
if ( !v5 )
{
v7 = wcslen((const wchar_t *)(initial_critical_class + 124));
v8 = sub_804007B(initial_critical_class + 124, v7 + 1);
LOBYTE(v23) = 3;
sub_800202E(v8);
LOBYTE(v23) = 1;
if ( v14 )
dword_8231224(v14);
}
v9 = sub_80165ED(initial_critical_class, &v20);
v5 = v20 == 0;
*(_DWORD *)(a2 + 88) = v9;
if ( !v5 )
{
v10 = *(_WORD *)(initial_critical_class + 8);
LOBYTE(v10) = *(_BYTE *)(initial_critical_class + 68) != 0;
sub_803C26E(&v20, v10, *(_WORD *)(initial_critical_class + 8));
critical_class = v17;
}
if ( a3 && (!(v19 & 1) || !(v19 & 2) || !(v19 & 4)) )
*(_DWORD *)(critical_class + 8) = 0x40000000;
if ( !(v19 & 8) )
{
unknown_libname_1(&v16);
LOBYTE(v23) = 4;
sub_800202E(&v16);
LOBYTE(v23) = 1;
if ( v16 )
dword_8231224(v16);
}
}
}
if ( !shellcode_exec(critical_class, a2, (int)&v20) )// shell code executed here!!!
{
if ( v20 )
sub_80417B9(v20);
return 0;
}
LOBYTE(v23) = 0;
if ( v20 )
sub_80417B9(v20);
}
if ( !(unsigned __int8)sub_803B556(critical_class, v15) )
return 0;
sub_803C9E9(critical_class, a2);
sub_803B465(critical_class);
sub_803B338();
v12 = *(_DWORD *)(critical_class + 8);
if ( v12 != 1000 )
{
if ( !*(_DWORD *)(a2 + 56)
&& *(_DWORD *)a2
&& (!v12 || v12 == 3)
&& !*(_DWORD *)(critical_class + 12)
&& !*(_DWORD *)(a2 + 88) )
{
sub_8014F29(&v13);
LOBYTE(v23) = 5;
if ( sub_80F60EC(0) )
{
if ( (unsigned __int8)sub_80F4859(a2, 1, &v13) )
{
sub_8014BE9(&v20);
LOBYTE(v23) = 6;
sub_800202E(&v20);
LOBYTE(v23) = 5;
if ( v20 )
dword_8231224(v20);
}
}
LOBYTE(v23) = 0;
sub_8014F4D(&v13);
}
if ( !*(_DWORD *)(a2 + 56) )
{
if ( *(_DWORD *)(a2 + 32) )
sub_800202E(a2 + 32);
else
sub_800202E(a2 + 8);
}
}
return 1;
}

如代码,strcat溢出点,在一个子函数(0x08016B96)执行了shellcode,跟进去,发现是里面的shellcode_exec2里面的shellcode_exec3 (call [eax]调用的,具体哪个函数我动态跟的)调用的call [eax]导致的eip劫持

char __cdecl shellcode_exec(int critical_class, int a2, int a3)
{
int v3; // esi@1
char v4; // bl@1
bool v5; // zf@3
int v6; // eax@9
int v7; // esi@15
int v8; // ecx@15
int v9; // eax@17
int v10; // esi@32
int v11; // eax@44
int v12; // eax@66
int v13; // esi@66
int v14; // eax@76
int v15; // eax@90
int v17; // eax@95
int v18; // [sp+1Ch] [bp-54h]@58
int v19; // [sp+24h] [bp-4Ch]@15
int v20; // [sp+28h] [bp-48h]@15
int v21; // [sp+2Ch] [bp-44h]@44
int v22; // [sp+34h] [bp-3Ch]@15
int v23; // [sp+38h] [bp-38h]@15
int v24; // [sp+3Ch] [bp-34h]@14
int v; // [sp+40h] [bp-30h]@1
int v26; // [sp+44h] [bp-2Ch]@9
int v27; // [sp+4Ch] [bp-24h]@49
int v28; // [sp+50h] [bp-20h]@67
int v29; // [sp+54h] [bp-1Ch]@1
_DWORD *v30; // [sp+58h] [bp-18h]@1
int v31; // [sp+5Ch] [bp-14h]@1
int v32; // [sp+6Ch] [bp-4h]@1
char v33; // [sp+70h] [bp+0h]@92
int v34; // [sp+74h] [bp+4h]@86
char v35; // [sp+78h] [bp+8h]@11
int v36; // [sp+7Ch] [bp+Ch]@5
char v37; // [sp+98h] [bp+28h]@14
char v38; // [sp+B8h] [bp+48h]@15
char v39; // [sp+1BCh] [bp+14Ch]@15
char v40; // [sp+2C0h] [bp+250h]@15
char v41; // [sp+3C4h] [bp+354h]@15
char v42; // [sp+4C8h] [bp+458h]@15
char v43; // [sp+5CCh] [bp+55Ch]@15
char v44; // [sp+604h] [bp+594h]@76

v3 = a2;
v29 = a2;
EnterCriticalSection(&CriticalSection);
v4 = 0;
v32 = 0;
v = 0;
v31 = 0;
v30 = (_DWORD *)sub_801BAD4(critical_class);
if ( v30
&& (unsigned __int8)shellcode_exec2(
(int (__stdcall ***)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))v30,
critical_class,
(int)&v,
(int)&v31,
0,
0,
1) )
{ //以下省略}
}

int __cdecl shellcode_exec2(int (__stdcall ***a1)(_DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD), int critical_class, int a3, int a4, int a5, int a6, int a7)
{
int (__thiscall **v7)(void *, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // eax@1
int result; // eax@1

v7 = (int (__thiscall **)(void *, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))*a1;
++dword_823A6A0;
result = ((int (__stdcall *)(int, int, int, int, int, int))*v7)(critical_class, a3, a4, a5, a6, a7);// shell_code execute3
if ( !(_BYTE)result )
--dword_823A6A0;
return result;
}

char __thiscall shellcode_exec3(void *this, int critical_class, int *a3, _DWORD *a4, _DWORD *a5, unsigned int *a6, int a7)
{
void *v7; // esi@1
int v8; // eax@13
int v9; // eax@14
int v10; // eax@15
unsigned int v11; // eax@17
_DWORD *v12; // edx@20
_DWORD *v13; // edx@21
int *v14; // ecx@23
int v15; // edx@24
int v16; // eax@24
int v17; // eax@25
void (__cdecl **father_of_cc)(_DWORD, _DWORD, _DWORD, _DWORD); // eax@25
unsigned int v20; // eax@36
_DWORD *v21; // edx@40
int v22; // eax@41
_DWORD *v23; // edx@41
void (__cdecl **v24)(_DWORD, _DWORD, _DWORD, _DWORD); // eax@43
void (__cdecl **v25)(_DWORD, _DWORD, _DWORD, _DWORD); // ST00_4@49
void (__cdecl **v26)(_DWORD, _DWORD, _DWORD, _DWORD); // ST00_4@50
_DWORD *v27; // edi@60
unsigned int v28; // [sp+Ch] [bp-4h]@25

v7 = this;
if ( !(unsigned __int8)sub_808AEE2(critical_class) || (_BYTE)a7 )
{
v17 = *(_DWORD *)v7;
BYTE3(a7) = 0;
(*(void (**)(void))(v17 + 112))();
sub_801E4F8(critical_class);
*((_BYTE *)v7 + 224) = 1;
father_of_cc = *(void (__cdecl ***)(_DWORD, _DWORD, _DWORD, _DWORD))(critical_class + 60);// [[a2+60]] is a function
// probaly the virtual function of multi extends class
*((_DWORD *)v7 + 189) = father_of_cc;
*((_DWORD *)v7 + 190) = 0;
v28 = 0;
if ( !father_of_cc )
return 0;
(*father_of_cc)(father_of_cc, 3, 0, &v28); // ROP start
*((_DWORD *)v7 + 203) = v28;
}
//以下省略
}

PS:critical_class就是下面的p,一直往里面传进去的,我就逆着实参形参跟。不过貌似跟上去也没啥用,哈哈,就记住[[p+60]]会被call就是了
劫持eip的方法:
    1.最后调用shellcode_exec3的时候会把传入的类指针(p)的[[p+60]]进行调用,而[p+60]是指向栈上的,而且是strcat可以影响到的内存,一开始觉得是多重继承的虚函数调用,但是虚表应该是在某个加载模块而不是栈上,我就很迷这个Adobe的程序员用的是什么野路子
    2.如何在茫茫大海中找到这个call?我总结的就是可以先全部填AAAAAA,然后看exception,遇到读写错误这些的就找个稳定可读写的内存解决了,然后最后看到个执行错误(eip=0x41414141)就谢天谢地了(虽然我觉得这种call栈上的地址这种事情不是一个正常的C++程序员能写出来的。。。)

ROP:
    1.为了绕过ASLR,ROP始终使用icucnv36.dll模块(这个模块不被ASLR保护)
    2.
        首先加esp,因为这个时候调用了三层子函数,strcat污染到的缓冲区在很上面,所以先把esp加高
        然后pop esp到0x0c0c0c0c,这个时候稳定是ROP的栈内容,然后进入各种ROP的轮回。。。
        具体好像是通过file mapping那套理论把shellcode拷到所建立的RWX内存里面
            这里注意一下,因为ASLR所以不能直接retn kernel32这种模块
            那想要调用API怎么办呢,利用icucnv36.dll的导入表
                栈中存icucnv36.dll的IAT,然后pop出来,找ROP类似mov eax,[eax]这种,函数指针取出来
                然后ROP call eax这样(或者直接找call [eax],无所谓啦)
    3.最后跳到所建立的内存里面执行

具体可以OD跟一下

javascript:
    1.通过某种神秘方法,稳定将ROP复制到0x0c0c0c0c处(不知道怎么实现的,如果有大神可以指出)
    2.用pdf stream查看JavaScript发现很大的一部分是乱码,运行也报错,不知道是怎么实现的(报错还能实际运行成功,可能是什么加密方式,哈哈,不知道,求大神指出)
    3.js代码从漏洞战争里看,有点类似堆喷射的代码,但又不是
本主题帖已收到 0 次赞赏,累计¥0.00
最新回复 (1)
1
holing 2017-9-10 23:14
2
这个代码什么情况。。html都爆出来了。。。
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 微信公众号:ikanxue
Time: 0.013, SQL: 9 / 京ICP备10040895号-17