Thứ Sáu, 2 tháng 9, 2016

[write-up][ADCTF2014] crypto day 8 ROTATE

file http://adctf2014.katsudon.org/dat/bvvpSQFmYqKQLhEp/rotate.zip
extract thì có 2 file. 1 file là encypt hình và một file là flag.jpg.enc

import sys
import math
import struct

p = lambda x: struct.pack('f', x)
u = lambda x: struct.unpack('b', x)[0]

if len(sys.argv) != 3:
    sys.exit(1)

filename = sys.argv[1]
key = math.radians(int(sys.argv[2]))

bs = open(filename, 'rb').read()
enc = open(filename + '.enc', 'wb')

for i in range(0, len(bs), 2):
    x, y = u(bs[i]), u(bs[i+1])
    enc.write(p(x * math.cos(key) - y * math.sin(key)) + p(x * math.sin(key) + y * math.cos(key)))



Program này hoạt động như sau :
 - Ta truyền vào 2 argv ban đầu là tên file cần encrypt, thứ 2 là key. Key ở đây là một số. Do có đoạn 
"key = math.radians(int(sys.argv[2]))"
nên key chỉ nằm ở khoảng 0 - 360 . Sau đó sẽ đọc từng char xong file hình là encrypt theo công thức.
Sau khi hiểu cách hoạt động của program, mình bắt đầu vào viết code. Vì là code decrypt nên sẽ tiếp cận theo cách bottom-up.
Sau khi thử encrypt một file bình thường thì mình thấy sau khi encrypt thì từ 1 char ban đầu sẽ tăng lên 4 char, thì thế mình sẽ tách một đoạn 8 kí tự ra làm 2 phần. Sau đó giải pt tìm x và y. Rồi tiếp tục pack char đó lại về thành bs[i] và bs[i+1]. Sau khi decrypt, ta cần phải kiểm tra xem phải file hình không. Ban đầu mình kiểm tra header là ffd8ffe000 tuy nhiên k có file nào hợp lệ. Vì vậy đã giảm xuống ffd8ff. Tuy vậy nhưng vẫn decrypt được file như bình thường. 
Đây là code decrypt :
import sys
import math
import struct

z = lambda x: struct.unpack('f', x)[0]
t = lambda x: struct.pack('b', int(round(x)))


def cp(x): #check if x can pack with func t()
    if int(round(x))>127:
        return 0 
    elif int(round(x))<-128:
        return 0
    else:
        return 1


def decode(filee,key):
    de=''
    key=math.radians(int(key))
    sx=math.sin(key)
    cx=math.cos(key)
    for i in range(0,len(filee),8):
        a=z(filee[i:i+4]) 
        b=z(filee[i+4:i+8])
        y=((b*cx-a*sx)) 
        x=(a+y*sx)/cx
        if cp(x)==0 or cp(y)==0 :
            return 0
        xx=t(x)
        yy=t(y)
        de+=xx+yy
    if de.encode('hex')[:6]=='ffd8ff':
        return de
    else:
        return 0
def solve(filename):
    filee=open(filename,'rb').read()
    dc=open(filename + '.jpg','wb')
    for i in range(360): 
        if i!=0 and i!=90 and i!=270:
            if decode(filee,i)!=0 :
                print i
                dc.write(decode(filee,i))
solve(sys.argv[1])

Không có nhận xét nào:

Đăng nhận xét