文号
t48824
阅读
2947
回复
1
收藏
2
枚举应用程序中有缓冲区溢出危险的函数
2012/08/01
IP:北京
枚举应用程序中有缓冲区溢出危险的函数,这些函数大多位于老版本的C运行库中,使用Python编写。注意该脚本使用了pydbg库,该库可以从一款名为“白眉”的工具中得到,我会在附件中附上。同时附上微软公布的危险函数列表。如果软件中使用了这些函数,还愁找不到攻击目标吗,哈哈哈。
注意:pydbg只能用于python 2.4版,切记!!!

下面是源代码:


#!/usr/bin/env python


from pydbg import *
from pydbg.defines import *


import utils


# The max number of times of executing single step after restore snapshot
MAX_INSTRUCTIONS = 10


# Functions are considered to be dangerous
dangerous_functions = {
    # Dangerous string copy functions
    "strcpy" : "msvcrt.dll",
    "wcscpy" : "msvcrt.dll",
    "_mbscpy" : "msvcrt.dll",
    "_mbccpy" : "msvcrt.dll",
    "lstrcpyA" : "kernel32.dll",
    "lstrcpyW" : "kernel32.dll",
    # Dangerous string concatenation functions
    "strcat" : "msvcrt.dll",
    "wcscat" : "msvcrt.dll",
    "_mbscat" : "msvcrt.dll",
    "lstrcatA" : "kernel32.dll",
    "lstrcatW" : "kernel32.dll",
    # Dangerous sprintf functions
    "sprintf" : "msvcrt.dll",
    "swprintf" : "msvcrt.dll",
    "wsprintfA" : "user32.dll",
    "wsprintfW" : "user32.dll",
    "wnsprintfA" : "shlwapi.dll",
    "wnsprintfW" : "shlwapi.dll",
    # Dangerous "n" sprint functions
    "_snprintf" : "msvcrt.dll",
    "_snwprintf" : "msvcrt.dll",
    # Dangerous variable argument sprintf functions
    "wvsprintfA" : "user32.dll",
    "wvsprintfW" : "user32.dll",
    "vsprintf" : "msvcrt.dll",
    "vswprintf" : "msvcrt.dll",
    # Dangerous variable argument "n" sprintf functions
    "_vsnprintf" : "msvcrt.dll",
    "_vsnwprintf" : "msvcrt.dll",
    "wvnsprintfA" : "shlwapi.dll",
    "wvnsprintfW" : "shlwapi.dll",
    # Dangerous "n" string copy functions
    "strncpy" : "msvcrt.dll",
    "wcsncpy" : "msvcrt.dll",
    "_mbsncpy" : "msvcrt.dll",
    "_mbsnbcpy" : "msvcrt.dll",
    "lstrcpynA" : "kernel32.dll",
    "lstrcpynW" : "kernel32.dll",
    # Dangerous "n" string concatenation functions
    "strncat" : "msvcrt.dll",
    "wcsncat" : "msvcrt.dll",
    "_mbsnbcat" : "msvcrt.dll",
    # Other dangerous functions will be added
}


dangerous_functions_resolved = {}


crash_encountered = False


instruction_count = 0


def DangeroursFuncHandler(dbg):
    # If dangerous function is invoked,
    # display some of parameters of function on stack.
    esp_offset = 0
    print "[*] Hit %s" % dangerous_functions_resolved[dbg.context.Eip]
    print "=" * 88
    while esp_offset <= 20:
        parameter = dbg.smart_dereference(dbg.context.Esp + esp_offset)
        print "[ESP + 0x%02x] => %s" % (esp_offset, parameter)
        esp_offset += 4
    print "=" * 88
    dbg.suspend_all_threads()
    dbg.process_snapshot()
    dbg.resume_all_threads()
    return DBG_CONTINUE


def AccessViolationHandler(dbg):
    # If access violation occurs,
    # restore process to last point of calling of dangerous function.
    
    # When exception occurs, the debugger will receives the exception
    # before debuggee get it. For debuggee can receive this exception,
    # we have to pass the first chance exception.
    if dbg.dbg.u.Exception.dwFirstChance:
        return DBG_EXCEPTION_NOT_HANDLED
    crash = utils.crash_binning.crash_binning()
    crash.record_crash(dbg)
    print crash.crash_synopsis()
    if crash_encountered == False:
        dbg.suspend_all_threads()
        dbg.process_restore()
        crash_encountered = True
        # Set each of thread to status of single step
        for threadId in dbg.enumerate_threads():
            print "[*] Setting single step for thread: 0x%08x" % threadId
            hThread = dbg.open_thread(threadId)
            dbg.single_step(True, hThread)
            dbg.close_handle(hThread)
        # Now, resume all threads of debugee,
        # this cause the control of debugee was handled by
        # SingleStepHandler routine right now.
        dbg.resume_all_threads()
        return DBG_CONTINUE
    else:
        dbg.terminate_process()
    return DBG_EXCEPTION_NOT_HANDLED


def SingleStepHandler(dbg):
    global instruction_count
    global crash_encountered
    if crash_encountered:
        if instruction_count == MAX_INSTRUCTIONS:
            dbg.single_step(False)
            return DBG_CONTINUE
        else:
            # Disassembly next instruction
            instruction = dbg.disasm(dbg.context.Eip)
            print "#%d\t0x%08x : %s" % (instruction_count, dbg.context.Eip, instruction)
            instruction_count += 1
            dbg.single_step(True)
    return DBG_CONTINUE


dbg = pydbg()
pid = int(raw_input("Enter the PID you wish to monitor: "))
dbg.attach(pid)


# Search for dangerous functions,
# and set bp for them,
# and append them to dict which used to store resolved functions.
for func in dangerous_functions.keys():
    funcAddr = dbg.func_resolve(dangerous_functions[func], func)
    print "[*] Resolved breakpoint: %s -> 0x%08x" % (func, funcAddr)
    dbg.bp_set(funcAddr, handler=DangeroursFuncHandler)
    dangerous_functions_resolved[funcAddr] = func


dbg.set_callback(EXCEPTION_ACCESS_VIOLATION, AccessViolationHandler)
dbg.set_callback(EXCEPTION_SINGLE_STEP, SingleStepHandler)
dbg.run()


危险函数的列表可以自己扩展的呦。

attachment icon PaiMei-1.1-REV122.zip 1.74MB ZIP 22次下载

attachment icon Dangerous CRT Functions.rar 79.99KB RAR 23次下载
14年5个月前IP:未同步
431226
1楼
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑收租↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

基本上就是字符串处理函数嘛。。。
请使用[code][/code]标记[s:275]
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的