pwnable.kr —— flag
送分題
下載文件,查看一下,是ELF文件並且有UPX殼。這個殼只是個壓縮殼,不是難事,脫殼。之後用IDA打開看一下,加載完之後主函數就是整個邏輯,malloc()一個空間,然後使用strcpy複製。數據的來源也很清晰,來自CS段的flag變量。直接進入到cs:flag的位置複製出來目標字符串提交即可。
pwnable.kr —— passcode
題目主要的邏輯函數是main()、welcome()和login()。後面兩個函數是在main()中連續調用的,這導致它們擁有相同的棧底。具體可以連接之後看源代碼,或者下載到本地調試。welcome()是一個字符輸入,由變量name接收。login()主要是scanf(“%d”, passcode1);和scanf(“%d”, passcode2);兩個輸入,之後進行比較:if(passcode1==338150 && passcode2==13371337),最後執行system()讀取flag。
沒有加&,沒有辦法把338150和13371337直接輸入進去,直接輸入符合條件的數字會失敗,readelf -r ./passcode
。
沒法直接覆蓋寫passcode2。
scanf("%d", passcode1);
中passcode1沒有加取地址符號&,如果scanf沒加&的話,程序會默認從棧中讀取4個字節的數據當做scanf函數中取回的地址,並在操作之後寫到這個地址中。
在scanf之後下一個要執行的函數是fflush函數,並且兩者都在GOT表中,這就可以使用GOT覆寫技術。
scanf("%d", passcode1);
fflush(stdin);
首先,GOT表段是可寫的
。基於同一個函數的連續調用有相同棧底
的條件,計算passcode1和name的距離:0x60。
用一個GOT表中的函數地址來充當scanf取的地址,然後把system(“/bin/cat flag”)這條指令的地址
通過scanf寫到這個函數中,當這個函數被調用時,跳到system(“/bin/cat flag”)。這裏就用fflush()作爲scanf()寫入的地址,當程序調用fflush()的時候就會執行system()。
scanf(“%d”,&fflush())接受的參數格式是十進制%d,所以在傳遞參數時把system("/bin/cat flag")的地址
轉換成十進制134514147
寫進去。
python -c "print 'A'*96+'\x00\xa0\x04\x08'+'134514147\n'" | ./passcode
enter you name : Welcome AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!
Sorry mom.. I got confused about scanf usage :(
enter passcode1 : Now I can safely trust you that you have credential :)