2

I'm trying to learn some stack overflow techniques and use shellcode in them. I was able to successfully use some basic shellcodes. Then I started working on using exeve in assembly and invoke ls -l with that, again successful. Now I am trying to use relative addressing and get rid of null values in my code. Because of that I tried a simple self-modifying code. I know code segment is read-only so I tried calling mprotect to make it writable. My code still doesn't work and I get segmentation fault at movb %al, 0x7(%esi). I really appreciate it if someone could give me some insight into the thing that is wrong in my code.

.text
.globl _start

_start:
  jmp StartPoint

  execvecall:
  popl %esi    # the address of string

  #calling mprotect to make the memory writable
  movl $0x7d, %eax
  movl %esi, %ebx
  movl $0x20, %ecx
  movl $7, %edx
  int $0x80

  xorl %eax, %eax

  movb %al, 0x7(%esi)  #putting zero for at the end of /bin/ls
  movb %al, 0xa(%esi)  #putting another zero at the end of -l

  #this part forms an array ending with for the second parameter of execve
  movl %esi, 0xb(%esi)
  movl %esi, %ebx
  addl $8, %ebx
  movl %ebx, 0xf(%esi)
  movl %eax, 0x13(%esi)

  movl %esi, %ebx
  leal 0xb(%esi), %ecx
  leal 0x13(%esi), %edx

  movb $11, %al
  int $0x80

StartPoint:
  call execvecall
SomeVarHere:
  .ascii "/bin/ls0-l0111122223333"
AKJ88
  • 713
  • 2
  • 10
  • 20
  • I suggest checking the return value. – cadaniluk Sep 22 '15 at 15:41
  • I've checked and it isn't -1. – AKJ88 Sep 22 '15 at 15:51
  • 1
    I executed your code and gdb tells me its returning `-22` (a.k.a `EINVAL` on my machine). – cadaniluk Sep 22 '15 at 16:13
  • Use `strace` to see what your code does, if you aren't running it under gdb. It saves a lot of debug-prints in C code that you write to try out some system calls, too. – Peter Cordes Sep 22 '15 at 16:36
  • Some systems may disallow having write and execute permissions at the same time, e.g: PaX https://en.wikipedia.org/wiki/PaX#Restricted_mprotect.28.29 , OpenBSD W^X https://en.wikipedia.org/wiki/W%5EX , ... See also http://www.akkadia.org/drepper/selinux-mem.html for Ulrich Drepper's recommended way of doing this under SELinux. – ninjalj Sep 22 '15 at 23:16
  • Thanks for your comments. They were really helpful. – AKJ88 Sep 23 '15 at 06:47

1 Answers1

5

man mprotect says:

The implementation may require that addr be a multiple of the page size as returned by sysconf().

This is apparently the case on your machine. Assuming you have 4 KiB pages (as on x86, no PSE), you can round the address down by executing

and $0xfffff000, %ebx

after

movl %esi, %ebx

when preparing to call mprotect.

Note that calling mprotect changes the protection for the whole page.

cadaniluk
  • 15,027
  • 2
  • 39
  • 67
  • Thanks man, I thought it would be the problem but I don't remember why I didn't at least try it!!! :-( – AKJ88 Sep 22 '15 at 16:30