banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Forum Index Thảo luận hệ điều hành *nix [Hỏi] Shellcode không thực hiện được  XML
  [Programming]   [Hỏi] Shellcode không thực hiện được 30/07/2008 04:33:27 (+0700) | #1 | 144061
[Avatar]
Tal
Member

[Minus]    0    [Plus]
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
[Profile] [PM]
Em có đoạn mã với mục đích là: 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
[Up] [Print Copy]
  [Question]   Re: [Hỏi] Shellcode không thực hiện được 30/07/2008 05:40:20 (+0700) | #2 | 144075
mrro
Administrator

Joined: 27/12/2001 05:07:00
Messages: 745
Offline
[Profile] [PM]
Hi Tal,

Bồ xem thêm cái này http://nasm.sourceforge.net/doc/nasmdoc5.html, mục 5.1.

--m

http://tinsang.net

TetCon 2013 http://tetcon.org

Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html
[Up] [Print Copy]
  [Question]   Re: [Hỏi] Shellcode không thực hiện được 30/07/2008 06:16:31 (+0700) | #3 | 144079
TQN
Elite Member

[Minus]    0    [Plus]
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
[Profile] [PM] [WWW] [Yahoo!]
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.
Để ý 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.
[Up] [Print Copy]
  [Question]   Re: [Hỏi] Shellcode không thực hiện được 30/07/2008 06:32:07 (+0700) | #4 | 144082
mrro
Administrator

Joined: 27/12/2001 05:07:00
Messages: 745
Offline
[Profile] [PM]
TQN: vấn đề ở đây nó đơn giản hơn nhiều anh. nasm mặc định xuất ra code để chạy trên các processor 16-bit:


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

http://tinsang.net

TetCon 2013 http://tetcon.org

Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html
[Up] [Print Copy]
  [Question]   Re: [Hỏi] Shellcode không thực hiện được 30/07/2008 10:35:55 (+0700) | #5 | 144118
[Avatar]
Tal
Member

[Minus]    0    [Plus]
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
[Profile] [PM]
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 smilie

Đâ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
[Up] [Print Copy]
  [Question]   Re: [Hỏi] Shellcode không thực hiện được 30/07/2008 10:38:43 (+0700) | #6 | 144119
[Avatar]
Tal
Member

[Minus]    0    [Plus]
Joined: 15/09/2007 16:50:17
Messages: 67
Offline
[Profile] [PM]

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?
[Up] [Print Copy]
  [Question]   Re: [Hỏi] Shellcode không thực hiện được 30/07/2008 11:17:57 (+0700) | #7 | 144126
TQN
Elite Member

[Minus]    0    [Plus]
Joined: 29/06/2006 22:28:01
Messages: 888
Location: Biết làm chi ?
Offline
[Profile] [PM] [WWW] [Yahoo!]
Trường hợp của cậu thì OK vì nó là void function, không push parameters vào stack.
[Up] [Print Copy]
  [Question]   Re: [Hỏi] Shellcode không thực hiện được 30/07/2008 11:29:08 (+0700) | #8 | 144128
mrro
Administrator

Joined: 27/12/2001 05:07:00
Messages: 745
Offline
[Profile] [PM]

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

http://tinsang.net

TetCon 2013 http://tetcon.org

Làm an toàn thông tin thì học gì?/hvaonline/posts/list/42133.html
[Up] [Print Copy]
[digg] [delicious] [google] [yahoo] [technorati] [reddit] [stumbleupon]
Go to: 
 Users currently in here 
1 Anonymous

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|