第三个注入实例(机器码的注入)

本文详细介绍了一种使用自定义机器码进行进程注入的技术实现过程。通过具体代码实例展示了如何利用汇编语言生成的机器码,结合Windows API函数如VirtualAllocEx和CreateRemoteThread等,将指定的代码注入到目标进程中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注入的机器码是用汇编编译器生成的,与C语言相比,更灵活自由。以前用过一阵MASM,而这本书上是用OD地汇编功能,倒是第一次见过。。。汗,又发现一个没掌握的OD功能。

先上传四张图,前三张是注入代码的三种不同形式的呈现:

第一张是反汇编指令形式的图

第二张是经CTRL+A分析过后的反汇编指令,1033,1044处不是指令,是两个字符窜

第三张是数据形式

这一张表是修改后用来直接注入的数据

下图直观一点。

 

下面贴实现代码

 

#include "stdafx.h"
#include "windows.h"

typedef struct _THREAD_PARAM
{
    FARPROC pFunc[2];               // LoadLibraryA(), GetProcAddress()
} THREAD_PARAM, *PTHREAD_PARAM;

BYTE g_InjectionCode[] =
{
    0x55, 0x8B, 0xEC, 0x8B, 0x75, 0x08, 0x68, 0x6C, 0x6C, 0x00,
    0x00, 0x68, 0x33, 0x32, 0x2E, 0x64, 0x68, 0x75, 0x73, 0x65,
    0x72, 0x54, 0xFF, 0x16, 0x68, 0x6F, 0x78, 0x41, 0x00, 0x68,
    0x61, 0x67, 0x65, 0x42, 0x68, 0x4D, 0x65, 0x73, 0x73, 0x54,
    0x50, 0xFF, 0x56, 0x04, 0x6A, 0x00, 0xE8, 0x0C, 0x00, 0x00,
    0x00, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x43, 0x6F,
    0x72, 0x65, 0x00, 0xE8, 0x14, 0x00, 0x00, 0x00, 0x77, 0x77,
    0x77, 0x2E, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x63,
    0x6F, 0x72, 0x65, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x6A, 0x00,
    0xFF, 0xD0, 0x33, 0xC0, 0x8B, 0xE5, 0x5D, 0xC3
};

//提权的

BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
{
    TOKEN_PRIVILEGES tp;
    HANDLE hToken;
    LUID luid;

    if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
        &hToken))
    {
        printf("OpenProcessToken error: %u\n", GetLastError());
        return FALSE;
    }

    if (!LookupPrivilegeValue(NULL,           // lookup privilege on local system
        lpszPrivilege,  // privilege to lookup
        &luid))        // receives LUID of privilege
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError());
        return FALSE;
    }

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;

    // Enable the privilege or disable all privileges.
    if (!AdjustTokenPrivileges(hToken,
        FALSE,
        &tp,
        sizeof(TOKEN_PRIVILEGES),
        (PTOKEN_PRIVILEGES)NULL,
        (PDWORD)NULL))
    {
        printf("AdjustTokenPrivileges error: %u\n", GetLastError());
        return FALSE;
    }

    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    {
        printf("The token does not have the specified privilege. \n");
        return FALSE;
    }

    return TRUE;
}

//注入实现,与上一篇注入代码略有不同,实则上这样反而不够灵活了。。。重用性大大降低,但安全性确实能提高。
BOOL InjectCode(DWORD dwPID)
{
    HMODULE         hMod = NULL;
    THREAD_PARAM    param = { 0, };
    HANDLE          hProcess = NULL;
    HANDLE          hThread = NULL;
    LPVOID          pRemoteBuf[2] = { 0, };

    hMod = GetModuleHandleA("kernel32.dll");

    // set THREAD_PARAM
    param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
    param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");

    // Open Process
    if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS,               // dwDesiredAccess
        FALSE,                            // bInheritHandle
        dwPID)))                         // dwProcessId
    {
        printf("OpenProcess() fail : err_code = %d\n", GetLastError());
        return FALSE;
    }

    // Allocation for THREAD_PARAM
    if (!(pRemoteBuf[0] = VirtualAllocEx(hProcess,                  // hProcess
        NULL,                      // lpAddress
        sizeof(THREAD_PARAM),      // dwSize
        MEM_COMMIT,                // flAllocationType
        PAGE_READWRITE)))         // flProtect
    {
        printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
        return FALSE;
    }

    if (!WriteProcessMemory(hProcess,                               // hProcess
        pRemoteBuf[0],                          // lpBaseAddress
        (LPVOID)&param,                         // lpBuffer
        sizeof(THREAD_PARAM),                   // nSize
        NULL))                                 // [out] lpNumberOfBytesWritten
    {
        printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
        return FALSE;
    }

    // Allocation for ThreadProc()
    if (!(pRemoteBuf[1] = VirtualAllocEx(hProcess,                  // hProcess
        NULL,                      // lpAddress
        sizeof(g_InjectionCode),   // dwSize
        MEM_COMMIT,                // flAllocationType
        PAGE_EXECUTE_READWRITE))) // flProtect
    {
        printf("VirtualAllocEx() fail : err_code = %d\n", GetLastError());
        return FALSE;
    }

    if (!WriteProcessMemory(hProcess,                               // hProcess
        pRemoteBuf[1],                          // lpBaseAddress
        (LPVOID)&g_InjectionCode,               // lpBuffer
        sizeof(g_InjectionCode),                // nSize
        NULL))                                 // [out] lpNumberOfBytesWritten
    {
        printf("WriteProcessMemory() fail : err_code = %d\n", GetLastError());
        return FALSE;
    }

    if (!(hThread = CreateRemoteThread(hProcess,                    // hProcess
        NULL,                        // lpThreadAttributes
        0,                           // dwStackSize
        (LPTHREAD_START_ROUTINE)pRemoteBuf[1],
        pRemoteBuf[0],               // lpParameter
        0,                           // dwCreationFlags
        NULL)))                     // lpThreadId
    {
        printf("CreateRemoteThread() fail : err_code = %d\n", GetLastError());
        return FALSE;
    }

    WaitForSingleObject(hThread, INFINITE);

    CloseHandle(hThread);
    CloseHandle(hProcess);

    return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD dwPID = 0;

    if (argc != 2)
    {
        printf("\n USAGE  : %s <pid>\n", argv[0]);
        return 1;
    }

    // change privilege
    if (!SetPrivilege(SE_DEBUG_NAME, TRUE))
        return 1;

    // code injection
    dwPID = (DWORD)_wtol(argv[1]);
    InjectCode(dwPID);
    return 0;
}

 

从上面的代码并不能看出那些像是花指令的代码如何正确运行的,必须跟踪调试一步一步观察才能彻底了解。所以个人觉得,学习编程特别是逆向,特别花时间,不能理所当然地以为自己掌握了而忽略了实践的过程。事实上,就算你实践了,大部分情况下你也不大可能一次掌握其中所有的技巧,只有通过多次调试,修改代码,举一反三的加深印象,才能掌握更多地知识。

转载于:https://www.cnblogs.com/DJ0322/p/4511642.html

### SQL注入原理概述 SQL注入是一种安全漏洞,允许攻击者通过应用程序向数据库发送恶意的SQL语句。这种技术利用了Web应用未能正确过滤用户输入的情况。当这些未经过滤的数据被用于构建动态SQL查询时,就可能执行任意的SQL命令[^1]。 在具体实现上,如果一个网站存在SQL注入风险,则可以通过修改URL参数、POST数据或Cookie等方式来尝试构造特殊的字符串,使服务器端程序将其作为部分SQL指令处理并最终提交给后台的关系型数据库管理系统(RDBMS),从而达到控制RDBMS的目的[^2]。 对于如何防范此类攻击,在开发过程中应该遵循最小权限原则设置账户;采用预编译语句代替直接拼接字符串形成SQL表达式的方法;并对所有的外部输入做严格的验证与清理工作,比如去除掉不必要的特殊字符等措施可以有效减少遭受SQL注入的风险[^3]。 ### SeedLab 实验环境部署指南 为了更好地理解SQL注入的工作机制以及学习相应的防护手段,建议按照如下步骤完成SeedLab实验平台上的SQL注入练习: #### 准备阶段 - 安装必要的软件包和服务,包括但不限于Apache HTTP Server, PHP 和 MySQL/MariaDB 数据库服务。 - 下载 sqli-labs 项目源码至本地机器,并解压到 Web根目录下以便能够正常访问各个测试页面[^4]。 ```bash git clone https://github.com/Audi-1/sqli-labs.git /var/www/html/ ``` #### 构建数据库结构 启动MySQL客户端工具连接到已安装的服务实例中创建一个新的名为 `users` 的数据库对象及其内部表格用来存储模拟用户的认证凭证信息(用户名/密码)。这一步骤通常涉及编写一系列DDL(Data Definition Language) 命令以定义模式(schema)。 ```sql CREATE DATABASE users; USE users; CREATE TABLE credentials ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50), password TEXT NOT NULL ); INSERT INTO credentials (username,password) VALUES ('Alice','secret'); ``` #### 执行基本注入案例 现在可以在浏览器里打开对应于第一个任务(Task 1)的教学材料链接,它会引导参与者逐步探索不同类型的SELECT语句下的潜在弱点位置。例如,在登录界面处尝试输入类似 `' OR '1'='1 --` 这样的值作为EID字段的内容将会绕过身份验证逻辑而成功登陆系统。 ```python eid = "5002'#" # 用户提供的恶意输入 password = "xyz" query = f"SELECT * FROM credentials WHERE eid='{eid}' AND passwd='{password}';" print(query) ``` 上述代码片段展示了怎样将不受信任的数据嵌入到了SQL查询之中,进而破坏原始意图之外的行为表现形式。请注意实际环境中绝不可如此操作!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值