閱讀169 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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.如下兩圖所示。

 

最後更新:2017-04-02 06:52:01

  上一篇:go cctype <ctype.h> <cctype>
  下一篇:go 《Java 本地接口規範》- JNI 函數(二)