-2
0x7fffffffeef8: xor    %rsi,%rsi
0x7fffffffeefb: xor    %rax,%rax   <- now rax is 0
0x7fffffffeefe: movabs $0xff978cd091969dd1,%rbx   <- rbx='/bin/dash'
0x7fffffffef08: neg    %rbx
0x7fffffffef0b: push   %rbx
0x7fffffffef0c: push   %rsp
0x7fffffffef0d: pop    %rdi   <- rdi is string
0x7fffffffef0e: mov    $0x3b,%al
0x7fffffffef10: syscall 

(gdb) stepi
0x00007fffffffef08 in ?? ()
(gdb) stepi
0x00007fffffffef0b in ?? ()
(gdb) stepi
0x00007fffffffef0c in ?? ()
(gdb) stepi
0x00007fffffffef0d in ?? ()
(gdb) stepi
0x00007fffffffef0e in ?? ()
(gdb) stepi
0x00007fffffffef10 in ?? ()
(gdb) stepi
0x00007fffffffef12 in ?? ()

In 0x7fffffffef10, syscall instruction exists. But when I use stepi command in GDB, I never execute /bin/dash. I think this assembly should execute /bin/dash. Did I misunderstand?

I uploaded full assembly code. I changed xor %eax, %eax to xor %rax, %rax

I added xor %rdx, %rdx in assembly code. But I can't get expected results.

process 1993 is executing new program: /bin/dash
[Inferior 1 (process 1993) exited normally]
(gdb) 

Result is like this but what I wanted is $ instead of (gdb)

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

int main(void)
{
    char str[256];

    printf("Type sentence.\n");
    gets(str);
    printf("%s\n", str);
}

Above is program which shell code was inserted.

I use Linux 16.04, x64 architecture

Damotorie
  • 586
  • 7
  • 25
  • 2
    It's very likely that the `syscall` is executed indeed but its arguments are somehow wrong. You didn't provide a [mcve] so we can't tell. – Margaret Bloom Oct 07 '16 at 09:54
  • But in other program, those assembly code executed properly. Arguments are also same. `syscall` only use `rax`, `rsi`, `rdi`, `rdx` isn't it? – Damotorie Oct 07 '16 at 10:07
  • 3
    You don't show any argument values in your code, except `al=0x3b` and `rdi` = `rsp`. That's not even enough to figure out which syscall function is called. If you are lucky enough to have almost zero in `rax` ahead of this, it will execute `execve`. It takes 3 parameters I think (I'm never sure which docs to check for syscall, as there are several similar C entry points in the linux source). Looks like you misunderstood how assembly works, and what it means to provide value in `rsi`/etc.. – Ped7g Oct 07 '16 at 10:45
  • I updated question. – Damotorie Oct 07 '16 at 11:09
  • `SIGSEGV` is preventing you from executing code in stack segment. CS will have been mapped with a limit well below canonical upper limit. – Shift_Left Oct 07 '16 at 12:18
  • I can't understand your comment... can you explain more please? – Damotorie Oct 07 '16 at 12:31
  • 1
    I suspect your problem is related to the parameters in _RDX_ (envp). You may wish to read the [execve](http://man7.org/linux/man-pages/man2/execve.2.html) documentation. I'm guessing that when you ran this code as a program you lucked out that _RDX_ happened to be 0 (NULL) and that an error wasn't generated (If there was an error a return value indicating as such will be in _RAX_ after the system call). You could run your program through `strace` to see the system calls, parameters and return values. You'd likely discover why it failed. – Michael Petch Oct 07 '16 at 15:24
  • 1
    `xor %eax, %eax` and `xor %rax, %rax` will do the same thing. `xor %eax, %eax` is a byte shorter and since the destination is a 32-bit register it will be zero extended through the upper half of the 64-bit register in 64-bit modes. – Michael Petch Oct 07 '16 at 15:27
  • 1
    $0xff978cd091969dd1 decoded is `hs/nib/` which when reversed will be `/bin/sh` not `/bin/dash`. It may be on your system `dash` is the default shell so it will be the one that is run, but of course that will differ if someone uses a different default shell. – Michael Petch Oct 07 '16 at 15:39
  • 1
    So what happens if you add `xor %edx, %edx` to your code? – Michael Petch Oct 07 '16 at 17:17
  • Run your code under `strace` to see what it passed as args to the system call. – Peter Cordes Oct 07 '16 at 22:00
  • @PeterCordes : seems to me that was part of a comment 6 hours ago too. _You could run your program through `strace` to see the system calls, parameters and return values. You'd likely discover why it failed._ . The OP just hasn't been seen for at least 8 hours. – Michael Petch Oct 07 '16 at 22:02
  • @MichaelPetch: ah yes, I didn't read all the comments. I would have thought this OP would get the hint that strace was a key tool after my answer on http://stackoverflow.com/questions/39848264/ubuntu-16-04-assembly-code-for-shell. – Peter Cordes Oct 07 '16 at 22:09
  • I updated my question – Damotorie Oct 08 '16 at 04:30
  • 1
    Are you aware that `$0xff978cd091969dd1` is `/bin/sh` and not `/bin/dash`? – Michael Petch Oct 08 '16 at 04:49
  • 2
    What does running `strace` on your program say. There should be a line for the `execve` . As well after the `syscall`, what is the return value in _RAX_? You can turn on a text mode windows gdb by issuing these commands: `layout asm` followed by `layout reg` . – Michael Petch Oct 08 '16 at 04:50
  • @MichaelPetch: I just tested `gdb /bin/sh`: `r -c /bin/sh`, and you do indeed get DASH's `$` prompt from inside gdb's `layout reg` TUI mode. (I have that in my `~/.gdbinit`). So probably the OP is passing an argv that makes it exit right away, and is still wasting our time by not posting output from the other key debugging tool for this. – Peter Cordes Oct 08 '16 at 05:11
  • 1
    Yes, see my previous comment about shell defaults. I said `$0xff978cd091969dd1` is `/bin/sh` . Whether that shell is directed to dash, bash, zsh or whatever is dependent on the user or system configuration. That part isn't in dispute. One other possibility is that whatever program is being injected has redirected stdin and possibly the shell is not entering interactive mode and simply returns. Without seeing the program being injected I can't tell. – Michael Petch Oct 08 '16 at 05:16
  • 1
    So looking at your program (last update), I assume you are calling it by redirecting standard input from a file? If that is the case the shell is likely simply exiting since there is no interactive input with the user/ – Michael Petch Oct 08 '16 at 05:44
  • Yes I used file redirecting for input. People saids when I want to use hex code as input in gdb, I have to use file redirection. So I used file redirection – Damotorie Oct 08 '16 at 05:47
  • 1
    That is the execve for the program itself. There will be another one for the execve syscall. – Michael Petch Oct 08 '16 at 05:49
  • `execve("/bin/sh", NULL, NULL) = 0`. Maybe this one? – Damotorie Oct 08 '16 at 05:50
  • 1
    Yes, that is your `syscall`. That says things look okay (first parameter was `/bin/sh` second and third parameter were passed as NULL) and `syscall` returned 0 (= 0). So you successfully ran `/bin/sh`. And the likely reason you don't get a prompt is related to my comments about standard input coming from somewhere other than the console. What you can do now is pass something to the shell as a parameter to the syscall and see if it works. – Michael Petch Oct 08 '16 at 05:59
  • 2
    Most people who launch `/bin/sh` in shell code don't do so to launch an interactive terminal with the user. They use it to run commands that do interesting things without user input. Since your user input is coming from a file, the shell won't become interactive and won't provide a prompt. – Michael Petch Oct 08 '16 at 06:02
  • Umm.. then you mean that I can't get prompt if I use file redirection as input? – Damotorie Oct 08 '16 at 06:42
  • 1
    That is correct – Michael Petch Oct 08 '16 at 07:04
  • @MichaelPetch Wow Your genius. Thank you so much – Damotorie Oct 08 '16 at 08:43

1 Answers1

-1

Memory protection is a quite an involved subject, but the premise is to isolate code from data and one process from another. There is really no logical reason to get an error @ 7fffffffef08 as neg %rbx is a perfectly legitimate instruction. Even trying to execute code at that address is possible, but in this case, that area of memory has mapped as stack. Therefore, the executable bit for that region has not been set and that is why you get 0x7fffffffef08 in ?? ().

But in other program, those assembly code executed properly.

leads me to believe you've done something to read code into that area, logically thinking it would work, but it won't.

Shift_Left
  • 1,208
  • 8
  • 17
  • 1
    `0x00007fffffffef08 in ?? ()` doesn't mean there is an error. The `??` suggests symbols have likely been stripped from the code (GCC's `-s` option will do it for example). The `??` simply suggests the function that is being debugged doesn't have a known label. Each one of those `stepi` actually executed instructions. If the OP were to use GDB's `layout asm` followed by `layout reg` commands he'd actually see the assembler instructions being executed and register contents. – Michael Petch Oct 07 '16 at 17:44
  • As it is this users code is actually executing without any faults. It isn't doing what he expects because he hasn't initialized _RDX_ (the 3rd parameter which is `envp` with the execve syscall) and the syscall likely returned an error code in _RAX_ with the failure reason (bad address, invalid argument etc) – Michael Petch Oct 07 '16 at 17:46
  • 1
    If he was executing code on a non-exectuable stack he'd be getting a `SIGSEGV` fault on the very first instruction executed on the stack. – Michael Petch Oct 07 '16 at 18:04