<![CDATA[Latest posts for the topic "[Hỏi] Shellcode không thực hiện được"]]> /hvaonline/posts/list/24.html JForum - http://www.jforum.net [Hỏi] Shellcode không thực hiện được sau khi chạy sẽ cho ra byte code của 1 chương trình viết bằng assembly để có thể đưa vào C. Chương trình như sau: Code:
#include <stdio.h>
#include <stdlib.h>

#define MAX_BUFFER 150

/*A function pointer for executing shellcode*/
void (*shell_code_execute)(void);

/*A buffer for input shellcode*/
char buffer[MAX_BUFFER];

int main(int argc, char **argv)
{
  FILE *f;
  unsigned int col,byte;
  int *ret;
  char *ptrbuff;
  
  /*The number of argument must be 1 or 2*/
  if(argc > 3 || argc ==1)
    {
      printf("Usage: bct filename [exec]\n");
      return 1;
    }

  /*Open a file for reading*/
  if((f=fopen(argv[1],"r"))==NULL)
    {
      printf("Error! File not found!\n");
      return -1;
    }

  printf("----------\n");
  printf("Printing your code\n");
  printf("----------\n");

  printf("buffer[]=\n");
  col = 0;

  /*Repeat reading each byte from opened file until reaching end of file
   With each byte, print and put it in buffer*/

  ptrbuff = (char*)&buffer; //pointer to buffer
  while((byte=fgetc(f))!=EOF)
    {
      if(col==0) printf("\""); 
      printf("\\x%.2x",(unsigned char)byte);
      *(ptrbuff++)=(unsigned char)byte;
      col++;
      if(col==10) //print a new line after printing 10 bytes
	{
	  col=0;
	  printf("\"\n");
	}
    }
  printf("\";\n");
  fclose(f);

  /*Execute the code has been read. We get address of buffer and call
   the shellcode in buffer by using function pointer shell_code_execute*/
  if(argc==3 && strcmp(argv[2],"exec")==0)
    {
      
      printf("------------\n");
      printf("Executing your code!\n");
      printf("------------\n");

      shell_code_execute = (void(*)(void))buffer;
      (*shell_code_execute)();
    }

  return 0;
}
Bây giờ em có 1 đoạn mã assembly như sau (đặt tên là hello.asm) Code:
jmp short string
code:
  pop ecx       
  mov ebx, 1    
  mov edx, 14   
  mov eax, 4    
  int 80h
  mov ebx, 0    
  mov eax, 1
  int 80h
string:
  call code
  db "Hello, World!", 00h
Đầu tiên em dịch đoạn mã assembly trên Code:
nasm hello.asm -o hello
Khi chạy chương trình với 1 đối đầu vào là tên chương trình nó cho ra kết quả đúng như sau: Code:
Tal@vxer:~/Documents/Research$ ./bct hello
----------
Printing your code
----------
buffer[]=
"\xeb\x24\x66\x59\x66\xbb\x01\x00\x00\x00"
"\x66\xba\x0e\x00\x00\x00\x66\xb8\x04\x00"
"\x00\x00\xcd\x80\x66\xbb\x00\x00\x00\x00"
"\x66\xb8\x01\x00\x00\x00\xcd\x80\xe8\xd9"
"\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f"
"\x72\x6c\x64\x21\x0a";
Nhưng nếu chạy với 2 đối số (thêm đối số exec) thì chương trình bị lỗi segmentation fault Em đã dùng gdb để debug thì thấy byte code đã được chép vào buffer và địa chỉ của con trò hàm đúng = địa chỉ của buffer. Tuy vậy đoạn code trong buffer không được thực hiện Máy của em chạy ubuntu 8.04, dịch = gcc 4.2.3 và lênh biên dịch là: Code:
gcc -o bct bct.c
]]>
/hvaonline/posts/list/23910.html#144061 /hvaonline/posts/list/23910.html#144061 GMT
Re: [Hỏi] Shellcode không thực hiện được /hvaonline/posts/list/23910.html#144075 /hvaonline/posts/list/23910.html#144075 GMT Re: [Hỏi] Shellcode không thực hiện được /hvaonline/posts/list/23910.html#144079 /hvaonline/posts/list/23910.html#144079 GMT Re: [Hỏi] Shellcode không thực hiện được The BITS directive specifies whether NASM should generate code designed to run on a processor operating in 16-bit mode, 32-bit mode or 64-bit mode. The syntax is BITS XX, where XX is 16, 32 or 64. In most cases, you should not need to use BITS explicitly. The aout, coff, elf, macho, win32 and win64 object formats, which are designed for use in 32-bit or 64-bit operating systems, all cause NASM to select 32-bit or 64-bit mode, respectively, by default. The obj object format allows you to specify each segment you define as either USE16 or USE32, and NASM will set its operating mode accordingly, so the use of the BITS directive is once again unnecessary. The most likely reason for using the BITS directive is to write 32-bit or 64-bit code in a flat binary file; this is because the bin output format defaults to 16-bit mode in anticipation of it being used most frequently to write DOS .COM programs, DOS .SYS device drivers and boot loader software.   Thành ra chỉ cần sửa cái file .asm trên lại, thêm vào cái directive "BITS 32" là xong. Tal: bồ mà dùng gdb debug thêm chút nữa, chẳng hạn đặt breakpoint ngay trong cái đoạn shellcode của bồ, thì bồ sẽ thấy nguyên nhân tại sao liền àh :-p. --m ]]> /hvaonline/posts/list/23910.html#144082 /hvaonline/posts/list/23910.html#144082 GMT Re: [Hỏi] Shellcode không thực hiện được The BITS directive specifies whether NASM should generate code designed to run on a processor operating in 16-bit mode, 32-bit mode or 64-bit mode. The syntax is BITS XX, where XX is 16, 32 or 64. In most cases, you should not need to use BITS explicitly. The aout, coff, elf, macho, win32 and win64 object formats, which are designed for use in 32-bit or 64-bit operating systems, all cause NASM to select 32-bit or 64-bit mode, respectively, by default. The obj object format allows you to specify each segment you define as either USE16 or USE32, and NASM will set its operating mode accordingly, so the use of the BITS directive is once again unnecessary. The most likely reason for using the BITS directive is to write 32-bit or 64-bit code in a flat binary file; this is because the bin output format defaults to 16-bit mode in anticipation of it being used most frequently to write DOS .COM programs, DOS .SYS device drivers and boot loader software.   Đúng rồi! Cái này là do mặc định của nasm sẽ dịch ra bytecode 16 bits, nếu mà không có chọn lựa gì thêm :D Đây là chương trình asm sau khi sửa lại: Code:
USE32                 ;directive này nói cho ta biết ta dịch ra mã 32 bits
  jmp short string
code:
  pop ecx
  mov ebx, 1    		
  mov edx, 14   
  mov eax, 4    
  int 80h
  mov ebx, 0    
  mov eax, 1
  int 80h
string:
  call code
  db "Hello, World!", 00h
Tal: bồ mà dùng gdb debug thêm chút nữa, chẳng hạn đặt breakpoint ngay trong cái đoạn shellcode của bồ, thì bồ sẽ thấy nguyên nhân tại sao liền àh :-p.  
Đặt breakpoint trong shellcode kiểu gì vậy anh? Em không làm thế mà em đặt break point trước lệnh gọi shellcode và disassembly cái hàm đó ra. Kết quả mã asm nếu không có directive USE32 Code:
Breakpoint 1, main (argc=3, argv=0xbffff9f4) at bct.c:69
69	      shell_code_execute = (void(*)(void))buffer;
(gdb) n
70	      (*shell_code_execute)();
(gdb) disas shell_code_execute 
Dump of assembler code for function buffer:
0x08049920 <buffer+0>:	jmp    0x8049946 <buffer+38>
0x08049922 <buffer+2>:	pop    %cx
0x08049924 <buffer+4>:	mov    $0x1,%bx
0x08049928 <buffer+8>:	add    %al,(%eax)
0x0804992a <buffer+10>:	mov    $0xe,%dx
0x0804992e <buffer+14>:	add    %al,(%eax)
0x08049930 <buffer+16>:	mov    $0x4,%ax
0x08049934 <buffer+20>:	add    %al,(%eax)
0x08049936 <buffer+22>:	int    $0x80
0x08049938 <buffer+24>:	mov    $0x0,%bx
0x0804993c <buffer+28>:	add    %al,(%eax)
0x0804993e <buffer+30>:	mov    $0x1,%ax
0x08049942 <buffer+34>:	add    %al,(%eax)
0x08049944 <buffer+36>:	int    $0x80
0x08049946 <buffer+38>:	call   0x6d4d9924
0x0804994b <buffer+43>:	insb   (%dx),%es:(%edi)
0x0804994c <buffer+44>:	insb   (%dx),%es:(%edi)
0x0804994d <buffer+45>:	outsl  %ds:(%esi),(%dx)
0x0804994e <buffer+46>:	sub    $0x20,%al
0x08049950 <buffer+48>:	push   %edi
0x08049951 <buffer+49>:	outsl  %ds:(%esi),(%dx)
0x08049952 <buffer+50>:	jb     0x80499c0
Đặt lại như anh mrro nói là ok. --m]]>
/hvaonline/posts/list/23910.html#144118 /hvaonline/posts/list/23910.html#144118 GMT
Re: [Hỏi] Shellcode không thực hiện được

TQN wrote:
File object còn có 1 mớ thứ linh tinh nữa trước đoạn shell code của cậu. Dùng 1 decompiler và 1 hex editor, extract từ file object của cậu ra chính xác đoạn code cần execute, lưu thành 1 .bin chẵng hạn rồi test lại. 
Nếu dịch bằng nasm mà không chỉ rõ file format bằng option -f thì mặc định là nó sẽ tạo ra file bin (opcode của các lệnh asm)

TQN wrote:
Để ý calling convention của function pointer shell_code_execute, trong trường hợp này là _cdecl phải không, debug xem stack có cân bằng không. 
Em không hiểu đoạn này lắm, anh có thể giải thích kỹ hoặc lấy ví dụ cụ thể được không?]]>
/hvaonline/posts/list/23910.html#144119 /hvaonline/posts/list/23910.html#144119 GMT
Re: [Hỏi] Shellcode không thực hiện được /hvaonline/posts/list/23910.html#144126 /hvaonline/posts/list/23910.html#144126 GMT Re: [Hỏi] Shellcode không thực hiện được

Tal wrote:
Đặt breakpoint trong shellcode kiểu gì vậy anh? Em không làm thế mà em đặt break point trước lệnh gọi shellcode và disassembly cái hàm đó ra. Kết quả mã asm nếu không có directive USE32  
Ý tôi là sau khi bồ đã biết địa chỉ của đoạn shellcode rồi, thì bồ đặt breakpoint trong đó, để xem nó chạy đến lệnh nào của shellcode thì bị segfault. Ví dụ như ở trên, bồ disas ra shellcode bắt đầu từ 0x08049920, thì bồ có thể đặt breakpoint từ đây trở đi. Tuy vậy đoạn code này khá đơn giản, nên nhìn vào là thấy ngay nguyên nhân bị segfault, đó là do cái lệnh: Code:
0x08049946 <buffer+38>:	call   0x6d4d9924
Nguyên nhân thì Tal đã giải thích rồi đó. --m ]]>
/hvaonline/posts/list/23910.html#144128 /hvaonline/posts/list/23910.html#144128 GMT