• [ ASIS CTF 2020 ] Latte

    2020. 7. 6.

    by. ugonfor

    라떼는 말이야~ 에서의 라떼는 아닌거 같고 Latte 문제를 풀어봤어요.

    사실 왜 이게 Latte 인지는 모르겠네요.

     

    이거 문제에서 의도한 대로 푼거같지는 않고 좀 엉뚱하게 푼거같은데 정식 롸업이 뭔지 모르겠습니다.

     

    latte-distfiles.zip
    0.01MB

    문제파일 보면 latte가 문제파일이고(암호화 프로게스) flag.latte가 아웃풋이거든요.

    근데 이런 문제 풀다보면, 진짜 그 모든 바이너리를 보고 싶은 게 싫어서 저는 보통 문자열 몇개마다 암호화가 이뤄지는 지부터 확인을 합니다.

    근데 만약에 '확산'이 잘 되어 있는 암호화라면 뭐 바이너리 전체를 분석을 해야겠죠. 근데 이 문제같은 경우에는 확산이 잘 되어있지는 않고, 각 문자에 대해서 1차 암호화를 하고 나서, 그 1차 암호화가 된 텍스트에 대해서 다시 일부 암호화를 하는 방식이었습니다.

     

    그래서 저는 각 문자에 대해서 암호화가 되면 어떤 값이 나오는 지 확인해보고 바로 복호화가 되는 건 바로 복호화 하고, 안된 부분은 브루트포싱을 통해서 복호화를 했습니다.

     

    ASIS_Left_B윮_F_뛢_ag_U�

    이거 포맷이 잘 안맞아서 제대로 안써지는 데 하여튼 위같은 형태로 flag.latte가 주어졌습니다.

     

    #!/usr/bin/python
    import subprocess
    
    for i in range(0x21,0x7f):
        f = open("input","wb")
        f.write(chr(i))
    
        subprocess.call(["./latte", "input", "0000000000000000", "output"])
    
        o = open("output","rb")
        t = o.readline()
        print chr(i-1),t

    이 코드를 돌리면 

     

    ! _Exc䴉q_
    " _D��e_Quo�_
    # _H�h_
    $ _Do�s_Sign_
    % _P��K_
    & _A���_
    ' _S�e_Quo�_
    ( _Left_P��
               �_
    ) _Right_P��
                �_
    * _A�P�k_
    + _Pl�_
    , _Com�_
    - _M��_
    . _F�l_S�p_
    / _SӒ_
    0 _z�o_
    1 _�e_
    2 _two__two_
    3 _�(e__�(e__�(e_
    4 _f�r__f�r__f�r__f�r_
    5 _five__five__five__five__five_
    6 _�x__�x__�x__�x__�x__�x_
    7 _�v�__�v�__�v�__�v�__�v�__�v�__�v�_
    8 _eight__eight__eight__eight__eight__eight__eight__eight_
    9 _��__��__��__��__��__��__��__��__��_
    : _Col�_
    ; _Se��l�_
    < _L�s _
    = _Equal_Sign_
    > _G�!�_T�n_
    ? _Qu�ˍ_M�k_
    @ _At_Sign_
    A A
    B B
    C C
    D D
    E E
    F F
    G G
    H H
    I I
    J J
    K K
    L L
    M M
    N N
    O O
    P P
    Q Q
    R R
    S S
    T T
    U U
    V V
    W W
    X X
    Y Y
    Z Z
    [ _Left_B��F_
    \ _BacksӒ_
    ] _Right_B��F_
    ^ _C��_
    _ _U�s�_
    ` _G�ve_Ac�K_
    a a
    b b
    c c
    d d
    e e
    f f
    g g
    h h
    i i
    j j
    k k
    l l
    m m
    n n
    o o
    p p
    q q
    r r
    s s
    t t
    u u
    v v
    w w
    x x
    y y
    z z
    { _Left_B��_
    | _V�3�l_B�_
    } _Right_B��_

    이렇게 아웃풋이 나오는 데 왼쪽의 텍스트가 오른쪽으로 바뀝니다. 그래서 이런 형태가 나와있는 것은 대부분 바꿔주었습니다.

     

    그리고 오른쪽의 텍스트에 해당하지 않는 부분은 두글자 이상이 결합한거라고 생각해서,

    두 글자, 3글자, 4글자씩 돌려서 그 값들을 확인해 봤는 데,

     

    아래가 두글자

    #!/usr/bin/python
    import subprocess
    
    print
    
    for i in range(0x61,0x7b):
    #	if 0x5b <= i and i <= 0x60 :
    #		continue
    	for j in range(0x61,0x7b):
    #		if 0x5b <= j and j <= 0x60 :
    #			continue
    		f = open("input","wb")
    		f.write(chr(i)+chr(j))
    
    		subprocess.call(["./latte", "input", "0000000000000000", "output"])
    
    		o = open("output","rb")
    		t = o.readline()
    		
    		#if ord(t[0]) == 0x9c:
    		print hex(ord(t[0])), t
    		print chr(i)+chr(j)

     

    아래가 3글자

    #!/usr/bin/python
    import subprocess
    
    print
    
    for i in range(0x41,0x7b):
    	if 0x5b <= i and i <= 0x60 :
    		continue
    	for j in range(0x41,0x7b):
    		if 0x5b <= j and j <= 0x60 :
    			continue
    		for k in range(0x41,0x7b):
    			if 0x5b <= k and k <= 0x60 :
    				continue
    			f = open("input","wb")
    			f.write(chr(i)+chr(j)+chr(k))
    
    			subprocess.call(["./latte", "input", "0000000000000000", "output"])
    
    			o = open("output","rb")
    			t = o.readline()
    			
    			check = chr(i) == t[0:1]
    
    			if check:
    				continue
    			if t[1] == "Z":
    				continue
    			if t[1] == "z":
    				continue
    
    
    			print "  "+ hex(ord(t[0])) + " "+ t
    			print chr(i)+chr(j)+chr(k)+ " : " ,

     

    아래가 4글자

    #!/usr/bin/python
    import subprocess
    for h in range(0x61,0x7b):
    	for i in range(0x61,0x7b):
    		for j in range(0x61,0x7b):
    			for k in range(0x61,0x7b):
    				text = chr(h)+ chr(i)+chr(j)+chr(k)
    				f = open("input","wb")
    				f.write(text)
    
    				subprocess.check_output(["./latte", "input", "0000000000000000", "output"])
    				o = open("output","rb")
    				t = o.readline()
    				
    				if ord(t[0]) == 0xdb or ord(t[0]) == 0xd6 or ord(t[0]) == 0xda:
    					print text, t, hex(ord(t[0])),hex(ord(t[1]))

     

    출력되는 부분은 제가 필요한 부분만 출력하게 해서, 다 출력되진 않습니다. 

    하여튼 이런 식으로 브루트 포싱을 해서 flag랑 비교해서 답을 구했습니다.... 

    좋은 풀이는 아닌거 같네요.

    ASIS{F1ag_C0mpress_Decompre3s_Fun_With_Th3_{f1agz}_this_tim3_smile!!}

     

    댓글