Search code examples
assemblyx86nasmshellcodeobjdump

How to get an objdump without NUL bytes?


I have this code in assembly:

global _start
section .rodata
  hello: db "Hello World!", 10

section .text

_start:
    mov eax,4           
    mov ebx,1          
    mov ecx,hello       
    mov edx,13     
    int 80h             

    ; Terminate program
    mov eax,1          
    xor ebx,ebx           
    int 80h

If I take objdump of the following code, I get:

enter image description here

If I get NUL characters in the objdump I will not be able to achieve the task I'm working on. How can I get objdump without any NUL(0x00) bytes?


Solution

  • In order to eliminate NUL(0x00) bytes in OBJDUMP you need to write shellcode that assembles into instructions that don't include NUL bytes. The methods you use are also dependent on the target. Are you writing a 32-bit exploit or a 64-bit exploit? Your current question appears to be a 32-bit exploit, so I will make that assumption.

    The more complex situation in 32-bit code is getting the address of a string (that will be stack based when run as an exploit without NUL bytes). You can use the JMP/CALL/POP method to achieve that. Alternatively You can also build the Hello World! string on the stack directly. I will propose a version using JMP/CALL/POP as described in the article:

    hello1.asm:

    global _start    
    section .text
    
    _start:
        jmp call
    pop:
        pop ecx                     ; ECX = address of hello
        xor eax, eax                ; EAX = 0
        mov al, 4                   ; EAX = 4 (int 0x80 sys_write)
        xor ebx, ebx
        inc ebx                     ; EBX = 1 (1 = Standard output)
        xor edx, edx
        mov dl, hellolen            ; EDX = length of hello string
        int 0x80
    
        ; Terminate program
        xor eax, eax
        inc eax                     ; EAX = 1 (int 0x80 sys_exit)
        xor ebx, ebx                ; EBX = return value of 0
        int 0x80
    call:
        call pop
        hello: db "Hello World!", 10
    hellolen equ $-hello
    

    You can assemble and link this code to a 32-bit executable called hello1 using:

    nasm -f elf32 hello1.asm -o hello1.o
    ld -melf_i386 hello1.o -o hello1
    

    The result of objdump -D hello1 is:

    hello1:    file format elf32-i386  
    
    Disassembly of section .text:
    
    08048060 <_start>:
     8048060:       eb 15                   jmp    8048077 <call>
    
    08048062 <pop>:
     8048062:       59                      pop    %ecx
     8048063:       31 c0                   xor    %eax,%eax
     8048065:       b0 04                   mov    $0x4,%al
     8048067:       31 db                   xor    %ebx,%ebx
     8048069:       43                      inc    %ebx
     804806a:       31 d2                   xor    %edx,%edx
     804806c:       b2 0d                   mov    $0xd,%dl
     804806e:       cd 80                   int    $0x80
     8048070:       31 c0                   xor    %eax,%eax
     8048072:       40                      inc    %eax
     8048073:       31 db                   xor    %ebx,%ebx
     8048075:       cd 80                   int    $0x80
    
    08048077 <call>:
     8048077:       e8 e6 ff ff ff          call   8048062 <pop>
    
    0804807c <hello>:
     804807c:       48                      dec    %eax
     804807d:       65 6c                   gs insb (%dx),%es:(%edi)
     804807f:       6c                      insb   (%dx),%es:(%edi)
     8048080:       6f                      outsl  %ds:(%esi),(%dx)
     8048081:       20 57 6f                and    %dl,0x6f(%edi)
     8048084:       72 6c                   jb     80480f2 <hello+0x76>
     8048086:       64 21 0a                and    %ecx,%fs:(%edx)
    

    You should note that there are no NUL bytes with this code. If you run ./hello1 as a standalone program it should output:

    Hello World!

    You can now convert this to a shellcode string with:

    objcopy -Obinary hello1 shellcode.bin
    hexdump -v -e '"\\""x" 1/1 "%02x" ""' shellcode.bin
    

    The OBJCOPY command converts the executable to raw binary and the second outputs a string that can be used for the purposes of an exploit. The output should be:

    \xeb\x15\x59\x31\xc0\xb0\x04\x31\xdb\x43\x31\xd2\xb2\x0d\xcd\x80\x31\xc0\x40\x31\xdb\xcd\x80\xe8\xe6\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\x0a

    If you are looking for the equivalent code for 64-bit exploits you can find such an example in this Stackoverflow answer.