[Writeup] Chủ đề Crypto - Vòng Chung kết WhiteHat Grand Prix 2014

BkavCR

VIP Members
27/09/2013
105
203 bài viết
[Writeup] Chủ đề Crypto - Vòng Chung kết WhiteHat Grand Prix 2014
Topic này được tạo để các bạn viết, trao đổi thảo luận về Writeup Chủ đề Crypto - Vòng Chung kết WhiteHat Grand Prix 2014.

Đề thi:

Crypto 300

nc grandprix.whitehat.vn 6003

Source

Gợi ý: Challenge-Handshake

Crypto 400

http://grandprix.whitehat.vn:6001/

Gợi ý 1: html-source
Gợi ý 2: AES - Javascript
Gợi ý 3: HPP


Hoặc mời bạn đăng nhập vào trang http://grandprix.whitehat.vn/ bằng tài khoản và mật khẩu WhiteHat Forum để lấy đề thi.
 
Chỉnh sửa lần cuối bởi người điều hành:
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Re: [Writeup] Chủ đề Crypto - Vòng Chung kết WhiteHat Grand Prix 2014

Crypto 400

1. Phân tích kỹ thuật:
Có thể thấy, với mỗi chuỗi nhập vào sẽ trả về 1 giá trị token

1.jpg


Xem qua source code, có 1 comment

Mã:

Truy cập đến đường dẫn này để láy source code backup:


Giải nén thu được 3 file: index.php, controller.php, encryption.php
Xem qua source code, có thể xác định được dòng dữ liệu đi như sau

3.jpg


Download file encryption.js:

Ngoài ra có một số nhận định:
  • Index.php mặc định gán cookie cho người dùng là Iam=encrypt(“man”), nếu cookie là Iam=encrypt(“superman”) thì in ra flag, trong đó encrypt() là hàm mã hóa.
  • encryption.php không thể truy cập trực tiếp do bị chặn IP khác IP local, và nếu msg truyền vào có chứa từ “man” thì sẽ bị chuyển thành “zzz” trước khi mã hóa, nên việc thử mã hóa “superman” trực tiếp vào đây là bất khả thi.

encryption.js là core của việc sinh token, xem code cẩn thận chúng ta biết đây là cài đặt mã hóa AES bằng javascript. Tuy nhiên key mã hóa thì đã được ẩn đi

Google đoạn code để lấy thêm thông tin, các bạn sẽ thấy là đoạn cài đặt AES này có lỗi bảo mật với hàm SubBytes
Đoạn mã hóa aes như sau
Mã:
function aes_encrypt(msg) {
    var w = new Array(44); 
    var state = new Array(16); 
    var round;

    msg = get_value("Message", msg, true);

    w = key_expand(key);
    state = transpose(msg);
    state = AddRoundKey(state, w, 0);

    for (round = 1; round < 10; round++) {
        state = SubBytes(state, S_enc);
        state = ShiftRows(state);
        state = MixColumns(state);
        state = AddRoundKey(state, w, round * 4 * 4);
    }

    SubBytes(state, S_enc);
    ShiftRows(state);
    AddRoundKey(state, w, 10 * 4 * 4);

    AES_output = transpose(state);
    return format_AES_output("hex");
}

state là mảng có 16 phần từ và là kết quả của các hàm lấy dữ liệu đầu(transpose) vào và xáo trộn với khóa con(AddRoundKey). State sau đấy được truyền vào hàm subbytes()
Mã:
function SubBytes(state, Sbox) {
    var i;

    for (i = 0; i < 16; i++)
        state[i] = Sbox[state[i]];

    return state;
}

Chú ý là sbox là mảng có 256 phần tử, vậy nếu state lớn hơn 256 thì sẽ có lỗi, điều này xảy ra khi msg truyền vào chứa ký tự unicode(mã > 256)
Dựa vào lỗi này, chúng ta có thể thu được key mã hóa bằng cách sử dụng hàm trên:
• Mã hóa một chuỗi unicode 16 byte, chẳng hạn như ưưưưưưưưưưưưưưưư
• Giải mã
• XOR mỗi ký tự của kết quả giải mã với 0x52 để thu được khóa

2. Tiến hành khai thác
2.1. Mã hóa chuỗi unicode

Với mỗi giá trị username nhập vào, msg gửi đi là kết quả của hàm md5 đã được substring 16 byte ở controller.php

Mã:
$msg = substr(md5($return['username']), 0, 16);

Đi qua hàm này thì unicode sẽ bị chuyển về ký tự đọc được nên việc gửi unicode trực tiếp qua textbox sẽ không có tác dụng.
May mắn là ngoài việc gửi username thì index.php còn gửi kèm giá trị timestamp, và biến này thì không bị lọc đầu vào. Chúng ta có thể lợi dụng lỗi HTTP Parameter Pollution ở controller.php để fake giá trị của msg mà ecryption.php nhận được.
Request POST gửi đi

Mã:
POST /crypto/controller.php HTTP/1.1
username=ping&action=encrypt&timestamp=141379820170%26msg%3d%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0%C6%B0

Thu được token: c091d348acd3467bafc04f004169bb23
Đây chính là giá trị mã hóa của chuỗi ưưưưưưưưưưưưưưưư

2.2 Giải mã kết quả
Ở controller.php, thấy ngay action có thể nhận một trong 2 giá trị encrypt/decrypt tương ứng với hàm sinh mã và giải mã.
Giải mã bằng Request
Mã:
POST /crypto/controller.php HTTP/1.1
username=c091d348acd3467bafc04f004169bb23&action=decrypt&timestamp=141379820170

Thu được token = c22e45bc7f37dad688226edf2b1f40e2
Mã:
2.3 Lấy key
Đoạn code sau thực hiện việc xor từng byte của kết quả giải mã với 0x52 để thu được key
Mã:
__author__ = 'Ping'
cipher = "c2 2e 45 bc 7f 37 da d6 88 22 6e df 2b 1f 40 e2".split(' ')
key = []
for c in cipher:
    key.append(hex(int(c, 16) ^ int('52', 16))[2:])

key = ''.join(key)
print key
#907c17ee2d658884da703c8d794d12b0

2.4. Mã hóa để lấy cookie đúng
Để có thể đọc được flag thì cần mã hóa chuỗi “superman” và lưu vào cookie Iam
Sử dụng khóa tìm được ở trên thay vào file encryption.js
Sau đó thực thi, ở đây tôi sử dụng nodejs
Mã:
node encryption.js enc c3VwZXJtYW4=
chuỗi base64 trên là kết quả của encode "superman"
2.jpg


Kết quả thu được: 63b8c3be22502c32b05269b2cb7e6075
Thay cookie Iam bằng giá trị trên để lấy Flag :)1.jpg

1.png
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Re: [Writeup] Chủ đề Crypto - Vòng Chung kết WhiteHat Grand Prix 2014

Cry300

​Hàm giải mã (viết ngược lại hàm mã hoá, thử tất cả 256 khả năng có thể):

Mã:
def decrypt(ciphertext):    for iv in xrange(0,256):
        p = ""
        iiv = iv
        for i in range(0,len(ciphertext)):
            tmp = ord(ciphertext[i])
            tmp = ror(tmp,((800-i)%8))
            tmp = invSbox[tmp]
            tmp ^= iiv
            p += chr(tmp) # + p
            iiv = ord(ciphertext[i]) ^ tmp
        if all(c in string.printable for c in p):
            print p

Sau khi thử một số input từ server thì mình kết luận là server sẽ gửi về dạng "username:password". Sau khi có hint từ BTC mình mới biết cái protocol HS này :|...

PHP:
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Re: [Writeup] Chủ đề Crypto - Vòng Chung kết WhiteHat Grand Prix 2014

Bài Crypto 400 gợi ý 3 lần mà chưa Team nào giải được. Thực sự khó.
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Re: [Writeup] Chủ đề Crypto - Vòng Chung kết WhiteHat Grand Prix 2014

vhnvn;17171 đã viết:
Sau khi có hint từ BTC mình mới biết cái protocol HS này :|...
Chú ý thông tin trả về từ phía server sau khi nhập tên vào thì bạn sẽ thấy đoạn này:
"Now start handshake-challenge" :)
 
Mời các bạn tham gia Group WhiteHat để thảo luận và cập nhật tin tức an ninh mạng hàng ngày.
Lưu ý từ WhiteHat: Kiến thức an ninh mạng để phòng chống, không làm điều xấu. Luật pháp liên quan
Comment
Bên trên