4

Watching this article:

http://www.exploit-db.com/exploits/13474/

I can see this:

/*
 *  NetBSD
 *  execve() of /bin/sh by humble of Rhino9
 */

char shellcode[] =
  "\xeb\x23"
  "\x5e"
  "\x8d\x1e"
  "\x89\x5e\x0b"
  "\x31\xd2"
  "\x89\x56\x07"
  "\x89\x56\x0f"
  "\x89\x56\x14"
  "\x88\x56\x19"
  "\x31\xc0"
  "\xb0\x3b"
  "\x8d\x4e\x0b"
  "\x89\xca"
  "\x52"
  "\x51"
  "\x53"
  "\x50"
  "\xeb\x18"
  "\xe8\xd8\xff\xff\xff"
  "/bin/sh"
  "\x01\x01\x01\x01"
  "\x02\x02\x02\x02"
  "\x03\x03\x03\x03"
  "\x9a\x04\x04\x04\x04\x07\x04";

# milw0rm.com [2004-09-26]

What are the:

char shellcode[] =
  "\xeb\x23"
  "\x5e"
  "\x8d\x1e"
  "\x89\x5e\x0b"
  "\x31\xd2"
  "\x89\x56\x07"

How could I use them? What programming language are there in? Assembly? Perl? How can I run them?

5 Answers 5

16

The content of that array, is low level machine code that will execute the shell /bin/sh, if executed on the correct architecture. An attacker may be able to feed it as data to a program which will execute it as code because of a bug.

It's commonly used to exploit buffer overflows.

One of the core principle of software programming is the concept of sub routines. So a programmer can call a function which has it's own set of variables and does some work. After it is completed, the program continues execution right after the call.

This concept, however, does not exist at the hardware layer. The processor just executes the next command, unless it is a jump to somewhere else.

So in order to be able to return from a call, some preparation has to be done at the time the call is made: The return address is saved on a stack, together with parameters for the function. All local variables that are created by the function are stored on the stack as well. At the end of the function, the local variables are deleted from the stack and the saved return address is used as the target of a jump.

In theory this works fine. In practice a bug in the program may allow an attacker to store some data to a local variable that is longer then the capacity of that variable. Since the local variables are stored before the return address in memory, the attacker may overwrite the return address, to point into his own data. The processor will happily execute it, assuming it is valid machine code.

If you are interested in the background have a look at Smashing The Stack For Fun And Profit. It's old and there are some counter measurements in place today, but it gives a very good introduction.

7
  • I just don't understand a big thing: If I'm a programmer and I give a variable a type ex.: integer, then how can anybody give bigger values to the variable what the "integer" type could accept?? Commented Sep 19, 2011 at 17:07
  • 3
    At this level, there are no data types, just instructions and memory addresses. If your code didn't handle things cleanly (overwrote some other memory address that you didn't want as a designer), then you might change the structure of the program unpredictably -- this sometimes results in an exploit. You need to look deeper at the concept of a buffer overflow. en.wikipedia.org/wiki/Buffer_overflow. Usually this relates to string types.
    – Jeff Ferland
    Commented Sep 19, 2011 at 17:12
  • 2
    @LanceBaynes, Jeff is correct, at this level there are no datatypes, just flat memory. So if there was no previous length check, data can be copied beyond the end of an array. Strings are handled as character arrays in plain old C. Commented Sep 19, 2011 at 17:23
  • @Jeff, actually, I think Lance is correct. It is impossible to buffer overflow an int itself. Only array-like types can be overflowed. However, it is possible to use a crafted number as part of an inconsistent input attack. Such an attack can lead to read, writes, or both beyond the intended range. CVE-2008-5316 is such a vulnerability in the LCMS color engine. Commented Sep 20, 2011 at 1:16
  • 1
    @MatthewFlaschen (int) i=99999999999999999 won't buffer overflow, but that doesn't mean I can't really mess things up with a memcpy to *i.
    – Jeff Ferland
    Commented Sep 20, 2011 at 13:03
11

What you're looking at is called shellcode. It is meant to be interpreted as the hexadecimal values shown and is specific to a given processor architecture and will only work with known memory addresses, so also specific to a certain OS or program. This is below assembly language -- you are looking at the actual machine code itself.

For example, 0xEB is an x86 jump instruction, and some number of the immediately following bytes are the target address. Reverse engineering malware/viruses might be a good starting point for learning how to interpret that code.

9

If you are interested and know a little assembly this is what the shellcode looks:

(gdb) x/s shellcode+61
0x804a07d <shellcode+61>:    "\232\004\004\004\004\a\004"
(gdb) x/31i shellcode
   0x804a040 <shellcode>:   jmp    0x804a065 <shellcode+37>
   0x804a042 <shellcode+2>: pop    esi
   0x804a043 <shellcode+3>: lea    ebx,[esi]
   0x804a045 <shellcode+5>: mov    DWORD PTR [esi+0xb],ebx
   0x804a048 <shellcode+8>: xor    edx,edx
   0x804a04a <shellcode+10>:    mov    DWORD PTR [esi+0x7],edx
   0x804a04d <shellcode+13>:    mov    DWORD PTR [esi+0xf],edx
   0x804a050 <shellcode+16>:    mov    DWORD PTR [esi+0x14],edx
   0x804a053 <shellcode+19>:    mov    BYTE PTR [esi+0x19],dl
   0x804a056 <shellcode+22>:    xor    eax,eax
   0x804a058 <shellcode+24>:    mov    al,0x3b
   0x804a05a <shellcode+26>:    lea    ecx,[esi+0xb]
   0x804a05d <shellcode+29>:    mov    edx,ecx
   0x804a05f <shellcode+31>:    push   edx
   0x804a060 <shellcode+32>:    push   ecx
   0x804a061 <shellcode+33>:    push   ebx
   0x804a062 <shellcode+34>:    push   eax
   0x804a063 <shellcode+35>:    jmp    0x804a07d <shellcode+61>
   0x804a065 <shellcode+37>:    call   0x804a042 <shellcode+2>
   0x804a06a <shellcode+42>:    das    
   0x804a06b <shellcode+43>:    bound  ebp,QWORD PTR [ecx+0x6e]
   0x804a06e <shellcode+46>:    das    
   0x804a06f <shellcode+47>:    jae    0x804a0d9
   0x804a071 <shellcode+49>:    add    DWORD PTR [ecx],eax
   0x804a073 <shellcode+51>:    add    DWORD PTR [ecx],eax
   0x804a075 <shellcode+53>:    add    al,BYTE PTR [edx]
   0x804a077 <shellcode+55>:    add    al,BYTE PTR [edx]
   0x804a079 <shellcode+57>:    add    eax,DWORD PTR [ebx]
   0x804a07b <shellcode+59>:    add    eax,DWORD PTR [ebx]
   0x804a07d <shellcode+61>:    call   0x407:0x4040404
   0x804a084 <shellcode+68>:    add    BYTE PTR [eax],al
(gdb) x/s shellcode+42
0x804a06a <shellcode+42>:    "/bin/sh\001\001\001\001\002\002\002\002\003\003\003\003\232\004\004\004\004\a\004"

The string "/bin/sh" is on shellcode+42 and is the string which is going to be execute on system and bring you a shell (here the meaning of shell-code). By the way dissasembly of instructions from shellcode+42 till 7 bytes more seems "strange code", this is because dissasembler managed the string as if it were code instead of data.

2

It's part of exploit development.

A hacker first discovers a problem. For example, he might notice that while logging onto email, if he types in a username 1000 bytes long, the server crashes.

So what the hacker does is figure out how to manipulate the overflowing bytes to cause program execution to "jump" somewhere in the buffer.

The hacker then writes code to open up a command-prompt (aka "shell"), and interact with that command prompt over the network. This is called "shellcode". It's the shellcode that that you see above.

The hacker the combines this all into an "exploit" program that can be used to hack into a system by simply specifying an IP address of the victim.

The hacker than scans a network looking for vulnerable systems. When he finds one, he then runs his exploit against it, breaks in with a shell prompt. This is realistically shown in the 2nd Matrix movie.

Once the hacker has the command prompt, he can send arbitrary commands to the system. He might create his own user account. He might download the password file. He might dump credit card numbers from the database.

That shellcode you see above is specified in C, because that's what most exploits are written in. But it's easily translated to other popular languages that have similar syntax in C.

The shellcode specifically is designed for NetBSD running on x86. NetBSD is an operating system system closely related to Mac OS X and more distantly related to Linux. It used to be popular for small computers, but has largely disappeared these days. So this is pretty useless.

-2

This is a C char declaration. There is no reason to suggest that if you write your own C program that you could not include these headers in your code and then make use of them.

2
  • 1
    -1: If there were an execution pointer to the start of that code block (in direct bytes, not an ASCII representation), it would execute. In a properly linked environment, it would spawn a shell.
    – Jeff Ferland
    Commented Sep 19, 2011 at 18:14
  • There is "can" and then there is "should." The question asked would be how to make use of these headers. As C declarations you can simply include the headers in a C program. "Should" the user do this without knowing what is contained? In my book, No. But then that is not what was asked. Commented Oct 3, 2011 at 13:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .