Link
Notice
Recent Posts
Recent Comments
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

hiariz 님의 블로그

[hacktheon CTF] Barcode 본문

CTF, Wargame

[hacktheon CTF] Barcode

hiariz 2025. 9. 11. 17:49

파일을 다운 받으면 다음과 같은 파일들이 존재합니다.

 

각각 파일을 확인해봅시다.

 

파일을 살펴보면 barcode 파일은 16진수를 입력받고 이를 바코드로 변환해주는 파일인 것 같습니다.

 

그리고 우리는 flag.barcode라는 값에 저장된 모양처럼 나오는 16진수 값을 찾아야합니다.

 

 

barcode 파일에 16진수 값을 차례대로 입력을 해보면 16진수 값을 2진수로 변환하여 화면에 출력하는 것을 볼 수 있습니다.

 

따라서 위의 결과에 따라서 F라는 문자열은 다음 16진수 값을 넣으면 볼 수 있습니다.

 

출력할 수 있는 하나의 토큰 값은 8바이트로 구성이 되어 있습니다.

 

그 다음 값부터는 첫 번째 토큰 값의 마지막 값과 두 번째 토큰 값의 첫 번째 값을 연산하여 값이 반대되어 출력이 되는 것을 볼 수 있습니다.

 

이를 고려하여 두 번째 토큰값부터는 다음과 같은 과정을 거처야합니다.

 

출력바이트 = (~이전토큰바이트) XOR 현재토큰바이트

 

위를 고려하여 flag.barcode를 역으로 연산하여 16진수 값을 추출하는 코드는 다음과 같습니다.

import sys, argparse

def rows_from_source(fh):
    rows = []
    for ln in fh:
        ln = ln.rstrip("\n")       
        rows.append(ln)
        if len(rows) == 32:
            break

    if len(rows) != 32:
        sys.exit(f"32 lines 필요, 현재 {len(rows)}줄.")
    if any(len(r) > 8 for r in rows):
        sys.exit("가로 8칸을 초과한 줄이 있습니다.")
    return [r.ljust(8) for r in rows]

def row_to_byte(row: str) -> int:
    val = 0
    for i, ch in enumerate(row):
        if ch == '*':
            val |= 1 << i          
    return val

def block_in(prev_in, out_rows):
    desired = [row_to_byte(r) for r in out_rows]  
    cur = [0] * 8
    for row in range(8):             
        idx = 7 - row                 
        cur[idx] = desired[row] ^ (~prev_in[idx] & 0xFF)
    return cur

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("-f", "--file", help="barcode ASCII file")
    args = ap.parse_args()

    with (open(args.file) if args.file else sys.stdin) as fh:
        rows = rows_from_source(fh)

    block0_in = list(reversed([row_to_byte(r) for r in blocks[0]]))
    inputs = block0_in.copy()

    prev = block0_in
    for blk in blocks[1:]:
        cur = block_in(prev, blk)
        inputs.extend(cur)
        prev = cur

    token = "0x" + "".join(f"{b:02x}" for b in inputs)
    print(token)

if __name__ == "__main__":
    main()

 

위의 코드를 실행하면 FLAG를 그리는 16진수 값이 나오고 이를 barcode에 넣으면 플래그 모양을 얻을 수 있습니다.

 

FLAG{0x000202027e027e00ff83ffff83ff83ff003e424202424000fffdffcfffff83ff}

'CTF, Wargame' 카테고리의 다른 글

[2025 ACS] web_funable  (0) 2025.11.19
[2025 ACDC] Audio Challenge  (0) 2025.11.15
[hacktheon CTF] I love revsersing  (0) 2025.09.11
[hacktheon CTF] Shadow Of the System  (0) 2025.09.11
[hacktheon CTF] TAR  (0) 2025.09.11