[OverTheWire] Natas – Level 11
http://natas11.natas.labs.overthewire.org/
Cookies are protected with XOR encryption
Xem source:
[php] $defaultdata = array( "showpassword"=>“no”, “bgcolor”=>”#ffffff”);
function xor_encrypt($in) {
$key = ‘
$text = $in;
$outText = ”;
// Iterate through each character
for($i=0;$i
if($data["showpassword"] == "yes") {
print "The password for natas12 is
“;
}
?>[/php]
Ok, chúng ta cần có $data[“showpassword”] == “yes”.
Trước đó, $data được lấy giá trị thông qua hàm loadData():
[php]function loadData($def) {
global $_COOKIE;
$mydata = $def;
if(array_key_exists(“data”, $_COOKIE)) {
$tempdata = json_decode(xor_encrypt(base64_decode($_COOKIE[“data”])), true);
if(is_array($tempdata) && array_key_exists(“showpassword”, $tempdata) && array_key_exists(“bgcolor”, $tempdata)) {
if (preg_match(‘/^#(?:[a-fd]{6})$/i’, $tempdata[‘bgcolor’])) {
$mydata[‘showpassword’] = $tempdata[‘showpassword’];
$mydata[‘bgcolor’] = $tempdata[‘bgcolor’];
}
}
}
return $mydata;
}[/php]
Hiểu tổng quát, $data được lấy từ biến data của cookie (không có thì lấy từ biến mặc định), với các thao tác xử lý lần lượt là:
base64_decode → xor_encrypt → json_decode
Quá trình này dễ thấy là đối xứng với các thao tác trong hàm saveData():
json_encode → xor_encrypt → base64_encode
Do json_encode, json_decode, base64_encode, base64_decode là các hàm có sẵn của PHP, nên cái ta cần bây giờ là hiểu được hàm xor_encrypt.
Nhưng… khoan đã, nãy giờ chúng ta cứ lan man về vấn đề mã hóa cookie, vậy nó có ý nghĩa gì đối với task này?
Hãy nhớ lại rằng, chúng ta phải có $data[“showpassword”] == “yes”, nhưng biến showpassword được mặc định là “no” (trong khai báo $defaultdata), còn cái mà chúng ta có thể thay đổi chỉ là mỗi bgcolor. Vậy thì chỉ còn cách đọc hiểu cơ chế xử lý cookie của task, và chỉnh sửa nó thủ công mà thôi.
Trở về với hàm xor_encrypt:
[php]function xor_encrypt($in) {
$key = ‘
$text = $in;
$outText = ”;
// Iterate through each character
for($i=0;$i
Chúng ta có input, dựa trên $data = $defaultdata. Chúng ta cũng có output, dựa trên giá trị cookie. Tóm tắt lại một chút:
[php]$defaultdata = array( “showpassword”=>”no”, “bgcolor”=>”#ffffff”);[/php]
[php]cookie[‘data’] = ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw%3D[/php]
[php]saveData() = setcookie(“data”, base64_encode(xor_encrypt(json_encode($d))));[/php]
Thực thi câu lệnh PHP sau để tìm được input của hàm xor_encrypt:
[php]echo json_encode(array( “showpassword”=>”no”, “bgcolor”=>”#ffffff”));[/php]
{"showpassword":"no","bgcolor":"#ffffff"}
Tương tự như vậy, thực thi câu lệnh PHP sau để xác định output của hàm xor_encrypt:
[php]echo base64_decode(‘ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=’);[/php]
Như vậy, ta đã có input và ouput. Kết hợp với tính chất kinh điển của phép toán XOR (mà mình đã từng nhắc đến trong một writeup trước đây), chúng ta coi như có đủ dữ kiện cần thiết. Đoạn code dưới đây sẽ cho ta biết các byte lần lượt được dùng để XOR input thành output là gì:
[php]import base64
plain = ‘{“showpassword”:”no”,”bgcolor”:”#ffffff”}’
xored = base64.b64decode(‘ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw=’)
for i in range(len(xored)):
print hex(ord(xored[i]) ^ ord(plain[i]))[/php]
0x71 0x77 0x38 0x4a 0x71 0x77 0x38 0x4a 0x71 0x77 0x38 0x4a 0x71 0x77 0x38 0x4a 0x71 0x77 ...
Dễ thấy $key = ‘x71x77x38x4a’. Giờ thì ta đã có thể thay đổi giá trị cookie theo ý muốn được rồi
Đoạn code sau sẽ sinh cho ta một cookie với biến data[“showpassword”] = “yes”:
[php]import base64
def xor(plain):
xor_key = ‘x71x77x38x4a’
encoded = ”
for i in range(len(plain)):
encoded += chr(ord(xor_key[i % len(xor_key)]) ^ ord(plain[i]))
return encoded
print base64.b64encode(xor(‘{“showpassword”:”yes”,”bgcolor”:”#ffffff”}’))[/php]
ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK
Thay thế cookie bằng kết quả vừa thu được:
The password for natas12 is EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
→ flag = EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3.
Recent comments