当前位置: 首页 > 面试题库 >

Linux Shellcode“你好,世界!”

翟曦
2023-03-14
问题内容

我有以下工作的NASM代码:

global _start

section .text

_start:
    mov eax, 0x4
    mov ebx, 0x1
    mov ecx, message
    mov edx, 0xF
    int 0x80

    mov eax, 0x1
    mov ebx, 0x0
    int 0x80

section .data
    message: db "Hello, World!", 0dh, 0ah

在屏幕上显示“ Hello,World!\ n”。我还具有以下C包装器,其中包含先前的NASM对象代码:

char code[] =
"\xb8\x04\x00\x00\x00"
"\xbb\x01\x00\x00\x00"
"\xb9\x00\x00\x00\x00"
"\xba\x0f\x00\x00\x00"
"\xcd\x80\xb8\x01\x00"
"\x00\x00\xbb\x00\x00"
"\x00\x00\xcd\x80";

int main(void)
{
    (*(void(*)())code)();
}

但是,当我运行代码时,似乎未执行汇编代码,但程序退出正常。有任何想法吗?

谢谢


问题答案:

注入此shellcode时,您不知道位置message

mov ecx, message

在注入的过程中,它可以是任何东西,但不会如此,"Hello world!\r\n"因为仅转储文本部分时它位于数据部分。您可以看到您的shellcode没有"Hello world!\r\n"

"\xb8\x04\x00\x00\x00"
"\xbb\x01\x00\x00\x00"
"\xb9\x00\x00\x00\x00"
"\xba\x0f\x00\x00\x00"
"\xcd\x80\xb8\x01\x00"
"\x00\x00\xbb\x00\x00"
"\x00\x00\xcd\x80";

这是Shellcode开发中的常见问题,解决方法是这样的:

global _start

section .text

_start:
    jmp MESSAGE      ; 1) lets jump to MESSAGE

GOBACK:
    mov eax, 0x4
    mov ebx, 0x1
    pop ecx          ; 3) we are poping into `ecx`, now we have the
                     ; address of "Hello, World!\r\n" 
    mov edx, 0xF
    int 0x80

    mov eax, 0x1
    mov ebx, 0x0
    int 0x80

MESSAGE:
    call GOBACK       ; 2) we are going back, since we used `call`, that means
                      ; the return address, which is in this case the address 
                      ; of "Hello, World!\r\n", is pushed into the stack.
    db "Hello, World!", 0dh, 0ah

section .data

现在转储文本部分:

$ nasm -f elf shellcode.asm
$ ld shellcode.o -o shellcode
$ ./shellcode 
Hello, World!
$ objdump -d shellcode

shellcode:     file format elf32-i386


Disassembly of section .text:

08048060 <_start>:
 8048060:   e9 1e 00 00 00   jmp    8048083 <MESSAGE>

08048065 <GOBACK>:
 8048065:   b8 04 00 00 00   mov    $0x4,%eax
 804806a:   bb 01 00 00 00   mov    $0x1,%ebx
 804806f:   59               pop    %ecx
 8048070:   ba 0f 00 00 00   mov    $0xf,%edx
 8048075:   cd 80            int    $0x80
 8048077:   b8 01 00 00 00   mov    $0x1,%eax
 804807c:   bb 00 00 00 00   mov    $0x0,%ebx
 8048081:   cd 80            int    $0x80

08048083 <MESSAGE>:
 8048083:   e8 dd ff ff ff   call   8048065 <GOBACK>
 8048088:   48               dec    %eax                    <-+
 8048089:   65               gs                               |
 804808a:   6c               insb   (%dx),%es:(%edi)          |
 804808b:   6c               insb   (%dx),%es:(%edi)          |
 804808c:   6f               outsl  %ds:(%esi),(%dx)          |
 804808d:   2c 20            sub    $0x20,%al                 |
 804808f:   57               push   %edi                      |
 8048090:   6f               outsl  %ds:(%esi),(%dx)          |
 8048091:   72 6c            jb     80480ff <MESSAGE+0x7c>    |
 8048093:   64               fs                               |
 8048094:   21               .byte 0x21                       |
 8048095:   0d               .byte 0xd                        |
 8048096:   0a               .byte 0xa                      <-+

$

我标记的行是我们的"Hello, World!\r\n"字符串:

$ printf "\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0d\x0a"
Hello, World!

$

因此,我们的C包装器将是:

char code[] =

    "\xe9\x1e\x00\x00\x00"  //          jmp    8048083 <MESSAGE>
    "\xb8\x04\x00\x00\x00"  //          mov    $0x4,%eax
    "\xbb\x01\x00\x00\x00"  //          mov    $0x1,%ebx
    "\x59"                  //          pop    %ecx
    "\xba\x0f\x00\x00\x00"  //          mov    $0xf,%edx
    "\xcd\x80"              //          int    $0x80
    "\xb8\x01\x00\x00\x00"  //          mov    $0x1,%eax
    "\xbb\x00\x00\x00\x00"  //          mov    $0x0,%ebx
    "\xcd\x80"              //          int    $0x80
    "\xe8\xdd\xff\xff\xff"  //          call   8048065 <GOBACK>
    "Hello wolrd!\r\n";     // OR       "\x48\x65\x6c\x6c\x6f\x2c\x20\x57"
                            //          "\x6f\x72\x6c\x64\x21\x0d\x0a"


int main(int argc, char **argv)
{
    (*(void(*)())code)();

    return 0;
}

让我们测试一下:

$ gcc test.c -o test
$ ./test 
Hello wolrd!
$

有用。



 类似资料:
  • 本文向大家介绍TypeScript 你好,世界,包括了TypeScript 你好,世界的使用技巧和注意事项,需要的朋友参考一下 示例 这里我们有一个类 Greeter,它有一个构造函数和一个 greet 方法。我们可以使用 new 关键字构造一个类的实例,然后传入一个字符串,我们希望 greet 方法输出到控制台。Greeter 类的实例存储在 Greeter 变量中,然后我们调用 greet 方

  • 本文向大家介绍qml 你好,世界,包括了qml 你好,世界的使用技巧和注意事项,需要的朋友参考一下 示例 一个简单的应用程序在窗口中心显示文本“ Hello World”。            

  • 本文向大家介绍xaml 你好,世界,包括了xaml 你好,世界的使用技巧和注意事项,需要的朋友参考一下 示例 这是WPF中XAML页面的简单示例。它由XAML中最常见的元素a Grid,aTextBlock和aButton组成。 语法 描述 <Window> 根容器,用于承载可视化数据并使用户能够与之交互的内容。WPF窗口是XAML(.xaml)文件(其中元素为根)和CodeBehind(.cs)

  • 本文向大家介绍processing 你好,世界,包括了processing 你好,世界的使用技巧和注意事项,需要的朋友参考一下 示例 编写处理代码的最简单方法是简单地调用一系列函数。在处理编辑器中按运行按钮,处理将运行您的代码。这是一个例子: 此代码创建一个200x200窗口,绘制一个蓝色背景,将填充颜色更改为绿色,然后在屏幕中间绘制一个圆圈。 但是,大多数处理草图将使用预定义的setup()和d

  • 本文向大家介绍F# 你好,世界!,包括了F# 你好,世界!的使用技巧和注意事项,需要的朋友参考一下 示例 这是一个简单的控制台项目的代码,该项目显示“ Hello,World!”。到STDOUT,然后退出代码为0 逐行细分示例: [<EntryPoint>] -.net属性,用于标记程序(源)的“用于设置入口点的方法”。 let main argv-这定义了main一个由单个参数调用的函数argv

  • 本文向大家介绍sapui5 你好,世界!,包括了sapui5 你好,世界!的使用技巧和注意事项,需要的朋友参考一下 示例 我们首先为应用创建HTML页面。在那里,我们定义了元标记,用于加载SAPUI5库的脚本标记以及用于应用程序内容的占位符。 根据您的安装调整资源所在的路径(<>:<>)。对于OpenUI5,您可以使用src =“ https://openui5.hana.ondemand.com

  • 本文向大家介绍polymer 你好,世界,包括了polymer 你好,世界的使用技巧和注意事项,需要的朋友参考一下 示例 本示例创建一个名为的Polymer元素x-foo,其元素绑定到名为“ message”的字符串属性。元素的HTML导入到主文档中,从而允许使用中的<x-foo>标记<body>。 x-foo.html index.html 参见CodePen中的演示

  • 本文向大家介绍MATLAB你好,世界,包括了MATLAB你好,世界的使用技巧和注意事项,需要的朋友参考一下 示例 在MATLAB编辑器中打开一个新的空白文档(在最新版本的MATLAB中,通过选择工具栏的“主页”选项卡,然后单击“新建脚本”来执行此操作)。创建新脚本的默认键盘快捷键是Ctrl-n。 或者,键入edit myscriptname.m将打开文件myscriptname.m进行编辑,或者如