iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0

昨天水過了,今天大概或許會認真一點。事實證明沒有,我很抱歉。


今天會接續著 Day6 大雜燴之紅燒雜燴 - Pwn:Basic(4)的那題講解一下是怎麼做的。

附上題目的程式碼:

#include <stdio.h>
#include <stdlib.h>

void game() {
    long val = 0xdeadbeef;
    char buf[4] = "abcd";

    printf("Input: ");
    scanf("%4s",&buf);

    printf("buf: %s\n",buf);
    printf("val: 0x%08x\n",val);

    if(val == 0xdeadbe00) {
        printf("GOOD!!\n");
    } else {
        printf("BAD!!\n");
    }
}

int main() {
    game();
    return 0;
}

https://ithelp.ithome.com.tw/upload/images/20230927/20163074WKNYb4j3EK.png
我們使用 s 進入 game
https://ithelp.ithome.com.tw/upload/images/20230927/20163074HXqJjIzm6h.png
可以看到在 game+18 以及 game+25 的位置,分別在 ebp-0xc 以及 ebp-0x10 的位置設置了兩個變數。
對應到高階語言就會是:

long val = 0xdeadbeef;
char buf[4] = "abcd";

大家可能會疑惑為什麼我是設 abcd(0x61626364),但實際上卻是將 dcba(0x64636261)放入到 ebp-0x10 呢?

這是因為在不同架構下位元組的儲存順序不同,以本次實驗為例,我們使用的是 Little-Endian,意思是它會把最高位的位元組放在最高的記憶體位址上,下面會有具體的例子。

              low address
===========================================
ebp-0x10   (0xffffd0e8)    |_____0x61_____|
           (0xffffd0e9)    |_____0x62_____|
           (0xffffd0ea)    |_____0x63_____|
           (0xffffd0eb)    |_____0x64_____|
ebp-0xc    (0xffffd0ec)    |_____0xef_____|
           (0xffffd0ed)    |_____0xbe_____|
           (0xffffd0ee)    |_____0xad_____|
           (0xffffd0ef)    |_____0xde_____|
 :                         |      :       |
ebp        (0xffffd0f8)    |______________|
===========================================
              high address

還記得之前說過一個函數的 stack frame 會由 ebp 當底,所以記憶體內容會長上面這樣,可以看到 dcba(0x64636261)最高位元 d(0x64)放在記憶體位置最高位,這就是 Little-Endian。

將 abcd 以 dcba 順序存到記憶體的結果就是我們很直觀的看到我們 abcd 是由低到高這樣排下去。

從 gdb 觀察記憶體,也同樣會長這樣
https://ithelp.ithome.com.tw/upload/images/20230927/20163074JxLrdeoVTp.png

補充:要看到記憶體存甚麼,可以在 gdb 下 x 指令,具體怎麼用可以用 help x 查看。

我們繼續往下看

printf("Input: ");
scanf("%4s",&buf);

https://ithelp.ithome.com.tw/upload/images/20230927/20163074aTtCUbuNjH.png
由於我們是設 %4s,因此最多會讀取 4 個 bytes 進來,而因為是字串(s)因此會在尾端補上 '\0' (null 字元)。

那會造成什麼問題呢?還記得我們是怎麼宣告的嗎?

char buf[4] = "abcd";

我們當初只設了 4 個 bytes 的大小,而我們若輸入 aaaa 會在尾端被多加一個 byte,超出我們原先設置的 buffer 大小,會往下覆蓋下去,因此就會變這樣:

              low address
===========================================
ebp-0x10   (0xffffd0e8)    |_____0x61_____|
           (0xffffd0e9)    |_____0x61_____|
           (0xffffd0ea)    |_____0x61_____|
           (0xffffd0eb)    |_____0x61_____|
ebp-0xc    (0xffffd0ec)    |_____0x00_____| <=
           (0xffffd0ed)    |_____0xbe_____|
           (0xffffd0ee)    |_____0xad_____|
           (0xffffd0ef)    |_____0xde_____|
 :                         |      :       |
ebp        (0xffffd0f8)    |______________|
===========================================
              high address

https://ithelp.ithome.com.tw/upload/images/20230927/20163074xMvv5fgIFZ.png
因此我們就能成功印出 GOOD!
https://ithelp.ithome.com.tw/upload/images/20230927/20163074rpWA97kMAO.png


清蒸雜燴

反正就是清蒸的雜燴,應該不需要圖了吧。


上一篇
Day11 大雜燴之想不到了 - 資安管:名詞介紹
下一篇
Day13 大雜燴之不想想了 - 資安管:名詞介紹
系列文
雜七雜八大雜燴,資安技術大亂鬥30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言