Format String Vulnerability lab实验

//csdn博客目前暂时不再更新了,有兴趣请访问我的技术博客-晓的博客:zhangxiaolong.org 

     今天做格式化字符串漏洞实验。是一个比较有难度的实验,这也是下一个shellcode实验的基础。

     首先呢,要了解一下我们将会用到的知识(以我的预习情况来给大家做知识讲解): 

(1)给出以下程序:

   main()

  {

      int num=0x41414141;

      printf("Before: num = %#x \n", num);

     printf("%.20d%hn\n", num, &num);

     printf("After: num = %#x \n", num);

  }

查看这段代码的执行结果,解释%.20d和%hn的含义。

经过运行输出为:

Before:num=0x41414141

00000000001094795585

After : num= 0x4141001a

解释:

%.20d:%m.n格式中m为输出宽度,n为精度控制。d表示以十进制形式输出带符号整数,所以解释是为输出精度为20的整形量。

%hn: h表示按短整型量输出,%n 并不告诉printf()显示什么内容,而是将已输出的字符个数放入到变元指向的变量中。在printf()调用返回后,这个变量将包含一个遇到%n是字符输出的数目。

(2)解释linux用root执行下面这条命令sysctl -w kernel.randomize_va_space=0的含义和用途。

解答:

Sysctl:sysctl is an interface that allows you to make changes to a running Linux kernel. With /etc/sysctl.conf you can configure various Linux networking and system settings such as:

1. Limit network-transmitted configuration for IPv4

2. Limit network-transmitted configuration for IPv6

3. Turn on execshield protection

4. Prevent against the common 'syn flood attack'

5. Turn on source IP address verification

6. Prevents a cracker from using a spoofing attack against the IP address of the server.

7. Logs several types of suspicious packets, such as spoofed packets, source-routed packets, and redirects.

sysctl -w kernel.randomize_va_space=0  表示关掉aslr功能,ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对栈、共享库映射等线性区布局的随机化,防止攻击者定位攻击代码位置,达到阻止溢出攻击的目的。

     经过这两个小问题的学习之后,我们要了解Format String Vulnerability的实验的要求(这实验任务书是英文的,我就偷个懒,就不翻译了,不过应该很容易看懂的):

      In the following program, you will be asked to provide an input, which will be saved in a buffer calleduser input. The program then prints out the buffer using printf. The program is a Set-UID program(the owner
is root), i.e., it runs with the root privilege. Unfortunately, there is a format-string vulnerabilityin the way how the printf is called on the user inputs. We want to exploit this vulnerability and see howmuch damage we can achieve.

     The program has two secret values stored in its memory, and you are interested in these secret values.However, the secret values are unknown to you, nor can you find them from reading the binary code (forthe
sake of simplicity, we hardcode the secrets using constants 0x44 and 0x55). Although you do not knowthe secret values, in practice, it is not so difficult to find out the memory address (the range or the exactvalue) of them (they are in consecutive addresses),
because for many operating systems, the addresses areexactly the same anytime you run the program. In this lab, we just assume that you have already known theexact addresses. To achieve this, the program “intentionally” prints out the addresses for you.

With suchknowledge, your goal is to achieve the followings (not necessarily at the same time)Crash the program .

_ Print out the secret[0] value.

_ Modify the secret[0] value.

_ Modify the secret[0] value to a pre-determined value.

Note that the binary code of the program (Set-UID) is only readable/executable by you, and there isno way you can modify the code. Namely, you need to achieve the above objectives without modifying thevulnerable
code. However, you do have a copy of the source code, which can help you design your attacks.

     总体来说,需要做以下任务:

          1.  指出cret[0]中的值;

          2.  修改cret[0]中的值;

          3.  更改secret[0]的值为设计好的数值。

实验过程步骤:

(1)在linux中要关掉内存随机化分配的功能,指令如下:

       sysctl -w kernel.randomize_va_space=0                 

(2) 编写root程序vulp.c,vulp.c程序为(这个程序就是我们用printf格式化字符串攻击的程序):

/* vul_prog.c */
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[])
{
  char user_input[100];
  int *secret;
  int int_input;
  int a, b, c, d; /* other variables, not used here.*/
  /* The secret value is stored on the heap */
  secret = (int *) malloc(2*sizeof(int));
  /* getting the secret */
  secret[0] = SECRET1; secret[1] = SECRET2;
  printf("The variable secret's address is 0x%8x (on stack)\n", &secret);
  printf("The variable secret's value is 0x%8x (on heap)\n", secret);
  printf("secret[0]'s address is 0x%8x (on heap)\n", &secret[0]);
  printf("secret[1]'s address is 0x%8x (on heap)\n", &secret[1]);

  printf("Please enter a decimal integer\n");
  scanf("%d", &int_input);  /* getting an input from user */
  printf("Please enter a string\n");
  scanf("%s", user_input); /* getting a string from user */

  /* Vulnerable place */
  printf(user_input);
  printf("\n");

  /* Verify whether your attack is successful */
  printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
  printf("The new secrets:      0x%x -- 0x%x\n", secret[0], secret[1]);
  return 0;
}

      编译vulp.c程序,设置为suid权限,并以用户权限执行这段程序。输入一个用于定位的数值,例如输入25,在机器中十六进制为00000019,在输入一个字符串%08x. %08x. %08x. %08x. %08x. %08x. %08x. %08x. %08x. %08x. %08x. %08x.用以输出堆栈中此时的数值,可以看到我们自己的数值0x19的位置。如下图所示。

(3)更改secret[0]中值。首先要确定这个数值的地址。可以在上图看到地址为0x804b008,换算为十进制数为134524936,故在要求输入数值时输入134524936,此数值换为十六进制为我们要写入的地址,即secret[0]。更改这个地址的内容。如图所示:

 

(4)更改secret[0]中的值为指定的数值,进行漏洞攻击。前面如(3)所示,要在secret[0]中写入0x1234替换原来的0x44,0x1234换算为十进制数为4660,计算位置数值为8×9=72,即4660=72+4588,所以要填补4588个0,才能保证secret[0]中为0x1234.如下两图所示。

 

时间: 2024-10-12 09:27:14

Format String Vulnerability lab实验的相关文章

String.format详解

转载自:(http://www.cnblogs.com/fsjohnhuang/p/4094777.html) Java魔法堂:String.format详解   目录     一.前言    二.重载方法     三.占位符     四.对字符.字符串进行格式化     五.对整数进行格式化     六.对浮点数进行格式化     七.对日期时间进行格式化     八.其他转换符    九.总结     参考   一.前言    String.format 作为文本处理工具,为我们提供强大而丰

tring format报错-在myEclipse9.0中运行String.format报错

问题描述 在myEclipse9.0中运行String.format报错 错误信息:The method format(String, Object[]) in the type String is not applicable for the arguments (String, String) 源代码: public void test1(){ String str=null; str=String.format("Hi, %s", "林计钦"); // 格式化

Java魔法堂:String.format详解-

  目录     一.前言     二.重载方法     三.占位符     四.对字符.字符串进行格式化     五.对整数进行格式化     六.对浮点数进行格式化     七.对日期时间进行格式化     八.其他转换符     九.总结     参考   一.前言    String.format 作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,为了不止步于简单调用 String.format("Hello %s", "John"); ,下面将笔记

String.Format in Java and C#

原文:String.Format in Java and C# JDK1.5中,String类新增了一个很有用的静态方法String.format(): format(Locale l, String format, Object... args) 使用指定的语言环境.格式字符串和参数返回一个格式化字符串. format(String format, Object... args) 使用指定的格式字符串和参数返回一个格式化字符串. 举几个这个方法实用的例子(注释是输出结果): CODE: lon

C#中string.format的格式和用法

原文:C#中string.format的格式和用法 String.Format 方法的几种定义: String.Format (String, Object) 将指定的 String 中的格式项替换为指定的 Object 实例的值的文本等效项. String.Format (String, Object[]) 将指定 String 中的格式项替换为指定数组中相应 Object 实例的值的文本等效项. String.Format (IFormatProvider, String, Object[]

JAVA字符串格式化-String.format()的使用_java

本篇介绍JAVA字符串格式化-String.format()的使用,具体如下: 常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重载形式. format(String format, Object... args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字符串. format(Locale locale, String for

javascript下利用arguments实现string.format函数_javascript技巧

下面摘抄一下源码,深入分析一下他的设计实现思路: 复制代码 代码如下: function format(string) { var args = arguments; var pattern = new RegExp("%([1-" + arguments.length + "])", "g"); return String(string).replace(pattern, function(match, index) { return args

javascript下string.format函数补充_javascript技巧

又重新阅读了一遍Andrew的原文,在原文下面的评论中,赫然发现也有人早提出参数个数的问题,同样懒惰的楼猪直接拷贝原文评论答复了一下,同时还发现说漏了很重要的一个注意点Array.prototype.slice.下面统一补充说明一下: 1.string.format的参数个数 在Andrew的原文中,已经有人指出: eric d. Hi, thanks for that brilliant article. Made a lot of things a lot clearer! Note: ne

string.Format字符串格式化说明

先举几个简单的应用案例: 1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 (英文操作系统结果:$0.20) 默认格式化小数点后面保留两位小数,如果需要保留一位或者更多,可以指定位数 string.Format("{0:C1}",23.15) 结果为:¥23.2 (截取会自动四舍五入) 格式化多个Object实例 string.Format("市场价: