Day14 我們說到的驗證程式,透過 strings 搜尋就可以找到。於是我們想要提升逆向的成本,何不將驗證方式改掉?改成駭客想不到的方式?
原本的程式太薄弱了,雖然叫驗證程式但密碼隨隨便就可以被找到(如下圖),根本驗證不了什麼。
原本的程式(如下圖),若輸入等於 AAAA-Z10N-42-OK 即可通關。但使用 strings 或是一些簡單的方法就可以取得字串,因此我們思考,能否讓這串字串稍微不容易被發現?
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
if(argc==2) {
printf("Checking License: %s\n", argv[1]);
if(strcmp(argv[1], "AAAA-Z10N-42-OK")==0) {
printf("Access Granted!\n");
} else {
printf("WRONG!\n");
}
} else {
printf("Usage: <key>\n");
}
return 0;
}
現在改成(如下圖),將驗證方式改成輸入內容變成 ASCII 的數值,最後相加,若符合特定數值(這裡是916),才能通關。
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
if(argc==2) {
printf("Checking License: %s\n", argv[1]);
int sum = 0;
for (int i = 0; i < strlen(argv[1]); i++) {
sum += (int)argv[1][i];
}
printf("%d\n", sum);
if (sum == 916) {
printf("Access Granted!\n");
} else {
printf("WRONG!\n");
}
} else {
printf("Usage: <key>\n");
}
return 0;
}
希望可以稍微抵禦駭客的入侵...
現在我們來破解自己補強的程式XD
設置斷點在 cmp
b *0x400642
不用理會 cmp,直接繞過(控 EIP 者控天下XD)
set $rip=0x40064b
直接跳到 Access Granted 那段程式
成功破解:
順便練習 Radare 2 動態分析。
跟 GDB 一模一樣的流程。換湯不換藥。
s main
V
可以得到下圖:
接著使用 ood 開啟 Debug mode
dc 表執行(等同 GDB 的 r)
發現是 Wrong,我們可以設斷點在 cmp(如上圖)
透過 db 可以設置斷點(等同 GDB 的 b)
db 0x00400642(cmp 的位置)
接著 ood 執行,發現撞到斷點
透過 dr 可以獲得所有暫存器的資訊(如下圖)(等同 GDB 的 info registers)
誠如我們上述所說的控 EIP 者控天下,直接將 EIP 換成我們想跳到的記憶體位置(0x0040064b)。
透過 dr 可以改變暫存器的記憶體位址(等同 GDB 的 set $rip=0x0040064b [注意! GDB 要加$ 字號,Radare2 不用])
dr rip=0x0040064b
接著繼續執行dc
發現闖關成功!
今天逆向並繞過了補強的程式,發現問題點在 Debugger 太強了。有沒有什麼方法可以不被 Debugger 逆向?