There's a flag shop selling stuff, can you buy a flag? Source. Connect with nc 2019shell1.picoctf.com 3967.
請連上 nc 2019shell1.picoctf.com 3967. 在這裡你能找到一間賣旗子的商店,看看有沒有辦法買到旗子吧。商店原始碼。
Two's compliment can do some weird things when numbers get really big!
p.s. 這裡應為官方誤植,2的補數應為 complement。故意的?
本題做為基本技巧中唯一很有”漏洞”風格的題目,在難度上對新手而言也是有難度的。如果按照 HINT 所給的提示查詢教學中的 5.Two’sComplementRepresentation,也許你已經知道如何解了。本題漏洞在於數字在計算時有可能出現溢位的情況,進而導致非預期的計算結果。
先進入 shell 主機後連上題目位址
nc 2019shell1.picoctf.com 3967
Welcome to the flag exchange
We sell flags
1. Check Account Balance
2. Buy Flags
3. Exit
Enter a menu selection
是一個文字的互動小遊戲! 點選各個選項後,很快的發現擁有的金額是不夠買旗子的,而且有一個莫名的物品選項,想也知道這大概就是能夠獲得大量的金額的地方了。所以我們先暫且放著遊戲,轉頭去看看題目中的Source 有何漏洞問題。
點擊 Source 連結並打開下載的 store.c。順著看過程式流程,可以得知金額變動的地方只有購買knockoff Flags 的區段,也相當於漏洞有可能出現的地方。
if(number_flags > 0){
int total_cost = 0;
total_cost = 900*number_flags;
printf("\nThe final cost is: %d\n", total_cost);
if(total_cost <= account_balance){
account_balance = account_balance - total_cost;
printf("\nYour current balance after transaction: %d\n\n", account_balance);
}
else{
printf("Not enough funds to complete purchase\n");
}
}
再縮小範圍的話,就是在輸入買多少的範圍上。由於這裡不能輸入負數,加上題目的提示需要誘發程式出現奇怪的行為,因此我們試著輸入一個夠大的數字。
果不奇然,測得幾個數字後得到一個範圍內的數字會導致金額反額增加的 bug 如下
Currently for sale
1. Definitely not the flag Flag
2. 1337 Flag
1
These knockoff Flags cost 900 each, enter desired quantity
99999999999
The final cost is: -1039688580
Your current balance after transaction: 1039689680
至此有足夠的金錢就能買旗子了。
對於電腦使用 2 的補數來表示數字為何有可能發生錯誤的原理可以參考2 的補數 two’s complement。從數字範圍計算的結果來看,此處 的 int 應是 32bit。
picoCTF{m0n3y_bag5_cd0ead78}
注意每個人不同