开发者

Can anyone help me understand this asm code (It's short)

I'm trying to learn shellcode for a project in comp science

but I’m having a bit of a problem writing it I’m reading a book called The Shellcoder's Handbook and it gives me a code that wont work properly This is the code:

    section     .text
    global _start
_start:
    jmp short      GotoCall
shellcode:
     pop            rsi
     xor            rax, rax
     mov  byte      [rsi + 7], al
     lea            rbx, [rsi]
     mov            [rsi + 8], rbx
     mov            [rsi + 14], rax
     mov  byte      al, 0x0b
     mov            rbx, rsi
     lea            rcx, [rsi + 8]
     lea            rdx, [rsi + 14]
     int            0x80
GotoCall:
     Call            shellcode
     db             '/bin/shJAAAAAAKKKKKK'

simply put this is supposed to spawn a shell... but it wont work and when i use gdb to debug it i get a weird code and a segmentation fault error at

mov  byte      [rsi + 7], al

this is the gdb output: gdb ./sclivro

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400085 in _start ()
(gdb) disas _sta开发者_Go百科rt
Dump of assembler code for function _start:
0x0000000000400080 <_start+0>:  jmp    0x4000a2 <_start+34>
0x0000000000400082 <_start+2>:  pop    %rsi
0x0000000000400083 <_start+3>:  xor    %rax,%rax
0x0000000000400085 <_start+5>:  mov    %al,0x7(%rsi)
0x0000000000400088 <_start+8>:  lea    (%rsi),%rbx
0x000000000040008b <_start+11>: mov    %rbx,0x8(%rsi)
0x000000000040008f <_start+15>: mov    %rax,0xe(%rsi)
0x0000000000400093 <_start+19>: mov    $0xb,%al
0x0000000000400095 <_start+21>: mov    %rsi,%rbx
0x0000000000400098 <_start+24>: lea    0x8(%rsi),%rcx
0x000000000040009c <_start+28>: lea    0xe(%rsi),%rdx
0x00000000004000a0 <_start+32>: int    $0x80
0x00000000004000a2 <_start+34>: callq  0x400082 <_start+2>
0x00000000004000a7 <_start+39>: (bad)  
0x00000000004000a8 <_start+40>: (bad)  
0x00000000004000a9 <_start+41>: imul   $0x414a6873,0x2f(%rsi),%ebp
0x00000000004000b0 <_start+48>: rex.B
0x00000000004000b1 <_start+49>: rex.B
0x00000000004000b2 <_start+50>: rex.B
0x00000000004000b3 <_start+51>: rex.B
0x00000000004000b4 <_start+52>: rex.B
0x00000000004000b5 <_start+53>: rex.WXB
0x00000000004000b6 <_start+54>: rex.WXB
0x00000000004000b7 <_start+55>: rex.WXB
0x00000000004000b8 <_start+56>: rex.WXB
0x00000000004000b9 <_start+57>: rex.WXB
0x00000000004000ba <_start+58>: rex.WXB add    %bpl,(%r14)
End of assembler dump.

I compile the code using yasm and ld

yasm -f elf64 sclivro.asm

ld -o sclivro sclivro.o

My OS is Debian 6.0 x64

I have a Intel Celeron processor

I wanted to know why am I getting a seg fault error and explain to me.

Thanks for your time.

Also the book tells me to follow these steps:

  1. Fill EAX with nulls by xoring EAX with itself.

  2. Terminate our /bin/sh string by copying AL over the last byte of the string. Remember that AL is null because we nulled out EAX in the previ- ous instruction. You must also calculate the offset from the beginning of the string to the J placeholder.

  3. Get the address of the beginning of the string, which is stored in ESI, and copy that value into EBX.

  4. Copy the value stored in EBX, now the address of the beginning of the string, over the AAAA placeholders. This is the argument pointer to the binary to be executed, which is required by execve. Again, you need to calculate the offset.

  5. Copy the nulls still stored in EAX over the KKKK placeholders, using the correct offset.

  6. EAX no longer needs to be filled with nulls, so copy the value of our execve syscall (0x0b) into AL.

  7. Load EBX with the address of our string.

  8. Load the address of the value stored in the AAAA placeholder, which is a pointer to our string, into ECX.

  9. Load up EDX with the address of the value in KKKK, a pointer to null.

  10. Execute int 0x80.


The shellcode you've posted is for Linux running on a 32bit x86 processor - as can be seen from the use of "int 0x80" as system call instruction.

You've compiled it in 64bit mode, though, and attempted to run that. Which fails at the first memory access, because you're not using the real address of the "/bin/sh" string (which is in RSI) but only the explicitly truncated lower 32bit of it (since your code explicitly stated ESI). The latter is invalid, in 64bit mode, where your stack is somewhere at the upper end 0xffff....(64bit addr) of the address space.


The pop rsi instruction is getting the address of the string.

You are overwriting a write protected area when you try to put the nul byte after /bin/sh. I'm not sure why this code is supposed to be special: IT just looks like an obfuscated call to execve().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜