CTF

2024 Layer7 CTF write-ups

xdfyrj 2025. 1. 12. 08:00

소감

재밌었다@! 리버싱을 2문제 밖에 못 풀었지만(그래서 등수가...) chess를 풀어 상품을 받았다는 게 기분이 좋다.

리버싱 남은 2문제도 후딱 풀어보겠다.

드림핵에 포팅되면 좋을듯~

mic check

Layer7 디스코드 > rules

flag : Layer7{Did_you_check_your_ Affiliation??}

Overlap

다운 받으면 txt 파일을 준다.

HxD로 열어보면 PNG 파일 시그니처가 보인다. PNG 파일 트레일러를 검색해보면 그 아래 PNG 파일 시그니처가 또 보인다.

이로서 PNG 파일 두개를 붙여놓은 파일이라는 것을 알 수 있다.

대충 GPT 이용해서 파일 나누는 프로그램 짜주면 된다.

with open("Overlap.txt", 'rb') as file:
    binary_data = file.read()

png_signature = b'\x89PNG\r\n\x1a\n'
iend_chunk = b'IEND\xaeB`\x82'

def extract_pngs(binary_data):
    start = 0
    png_count = 0
    while True:
        sig_index = binary_data.find(png_signature, start)
        if sig_index == -1:
            break
        end_index = binary_data.find(iend_chunk, sig_index)
        if end_index == -1:
            break
        png_data = binary_data[sig_index:end_index + len(iend_chunk)]
        with open(f'extracted_{png_count}.png', 'wb') as f:
            f.write(png_data)
        png_count += 1
        start = sig_index + 1
    return png_count

num_png = extract_pngs(binary_data)
print(f"총 {num_png}개의 PNG 파일이 추출되었습니다.")

flag : Layer7{gReAT_0VErla_sOlv}

잘 기억은 안 나지만 }가 없어도 넣으면 맞았던 것 같다.

모든것의 해결책 햄스터

알맞는 툴 찾고 사용하는 과정을 배우는 데 구글링보다 GPT한테 물어보는게 더 효과적일 것 같아서 GPT를 적극 이용했다.

https://chatgpt.com/share/67826967-2814-8013-ad06-235b6c5d648b

  1. binwalk로 정보를 봤다.
➜  Layer7 binwalk hamster.jpg

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
28            0x1C            TIFF image data, big-endian, offset of first image directory: 8
24093         0x5E1D          Copyright string: "Copyright (c) 1998 Hewlett-Packard Company"
10825302      0xA52E56        End of Zip archive, footer length: 22

Zip 파일이 있었다.

또 GPT한테 물어보니 zip파일 서명을 이용해서 시작 바이트 오프셋을 볼 수 있다고 한다.

grep -a -b -o "PK" hamster.jpg

그 추출한 정보를 바탕으로 dd 명령어로 Zip 아카이브를 추출하였다.

dd if=hamster.jpg of=hidden.zip bs=1 skip=46345

이거 하는데 2시간 정도 걸렸다ㅠㅠ

어떻게 빨리 푸는지 궁금하다.

hidden.zip이 추출 되고 압축해제 후 폴더 안을 보면 .mp3 파일이 보인다.

고민 해보다가 스테가노그래피인가? 하는 생각이 들어서 Audacity로 확인했다.

Spectogram / Spectogram Settings > Lenear, grayscale / 확대 => flag 

flag : Layer7{la2er_musics}

Chess

간단한 체스 프로그램이다.

nc로 접속하며 프로그램을 분석하면 분석이 아주 쉽다.

ida에서 shift + f12를 하여 문자열 검색을 해보니 플래그 포맷이 보여서 플래그 출력해주는 함수를 찾았다.

파라미터로 보드 정보를 넘겨줘서 그것을 갖고 특정 조건을 만족하는 보드 가지면 플래그를 주는 것 같았다.

GPT를 이용해서 정확한 조건을 알아주면 다음과 같은 사실을 알 수 있다.

  • 백일 경우
    1. 비숍, 룩, 퀸 중 상관없이 아무거나 3개의 기물의 행과 열을 저장한다.
      (※ 8행이 1행으로 저장된다.)
    2. 기물 1, 2, 3의 행을 v1, v2, v3 / 기물 1, 2, 3의 열을 v4, v5, v6라고 할 경우
      v1^2 + v4^2 + v2^2 + v5^2 + v3^2 + v6^2 == 100이면 성공이다.
  • 흑일 경우
    1. 생각 안했다. 백만 생각했다.

실제 체스처럼 a1이 행이 1, 열이 1인 줄 알아서 삽질 1시간 했다..

나중에 동적분석으로 flag check 함수의 인자가 메모리상으로 어떻게 생겼는지 확인, 그리고 실제 행과 열을 저장하는 변수들의 값을 본 후 깨달았다..

제일 만들기 쉬운 열, 행의 제곱합이 무엇일지 생각해보았다.

결국 a3, b4, c4에 있으면 (1, 6), (2, 5), (3, 5)로 다음과 같은 수식을 만들어 플래그를 얻을 수 있는데 이게 가장 쉬울 것 같아서 이것으로 했다.


(1^2+6^2)+(2^2+5^2)+(3^2+5^2)=1+36+4+25+9+25=100


이제 체스하면서 flag를 얻는 럭키비키한 상황을 즐기면 된다.

Q, R, B 중 아무거나 (1, 6), (2, 5), (3, 5)에 박아보자.

➜  ~ nc 172.104.94.19 11001
백색(White)으로 시작하시겠습니까? (y/n): y
y
White으로 시작합니다!

  a b c d e f g h
 +-----------------+
8|r n b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|. . . . . . . . |
3|. . . . . . . . |
2|P P P P P P P P |
1|R N B Q K B N R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: a2 a4
a2 a4

  a b c d e f g h
 +-----------------+
8|r n b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . . . . . . . |
3|. . . . . . . . |
2|. P P P P P P P |
1|R N B Q K B N R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 b8 a6 이동했습니다.

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|n . . . . . . . |
5|. . . . . . . . |
4|P . . . . . . . |
3|. . . . . . . . |
2|. P P P P P P P |
1|R N B Q K B N R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: e2 e4
e2 e4

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|n . . . . . . . |
5|. . . . . . . . |
4|P . . . P . . . |
3|. . . . . . . . |
2|. P P P . P P P |
1|R N B Q K B N R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 a6 c5 이동했습니다.

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . n . . . . . |
4|P . . . P . . . |
3|. . . . . . . . |
2|. P P P . P P P |
1|R N B Q K B N R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: d2 d4
d2 d4

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . n . . . . . |
4|P . . P P . . . |
3|. . . . . . . . |
2|. P P . . P P P |
1|R N B Q K B N R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 c5 e4 이동했습니다.

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . . P n . . . |
3|. . . . . . . . |
2|. P P . . P P P |
1|R N B Q K B N R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: g1 h3
g1 h3

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . . P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B Q K B . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 a8 b8 이동했습니다.

  a b c d e f g h
 +-----------------+
8|. r b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . . P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B Q K B . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: f1 c4
f1 c4

  a b c d e f g h
 +-----------------+
8|. r b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B Q K . . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 b8 a8 이동했습니다.

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B Q K . . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: e1 g1
e1 g1
잘못된 이동입니다. 규칙에 맞는 이동을 시도하세요.

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B Q K . . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: e1 f1
e1 f1

  a b c d e f g h
 +-----------------+
8|r . b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B Q . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 a8 b8 이동했습니다.

  a b c d e f g h
 +-----------------+
8|. r b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B Q . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: d1 e1
d1 e1

  a b c d e f g h
 +-----------------+
8|. r b q k b n r |
7|p p p p p p p p |
6|. . . . . . . . |
5|. . . . . . . . |
4|P . B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B . Q K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 g8 f6 이동했습니다.

  a b c d e f g h
 +-----------------+
8|. r b q k b . r |
7|p p p p p p p p |
6|. . . . . n . . |
5|. . . . . . . . |
4|P . B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B . Q K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: e1 b4
e1 b4

  a b c d e f g h
 +-----------------+
8|. r b q k b . r |
7|p p p p p p p p |
6|. . . . . n . . |
5|. . . . . . . . |
4|P Q B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B . . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 e7 e6 이동했습니다.

  a b c d e f g h
 +-----------------+
8|. r b q k b . r |
7|p p p p . p p p |
6|. . . . p n . . |
5|. . . . . . . . |
4|P Q B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N B . . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: c1 d2
c1 d2

  a b c d e f g h
 +-----------------+
8|. r b q k b . r |
7|p p p p . p p p |
6|. . . . p n . . |
5|. . . . . . . . |
4|P Q B P n . . . |
3|. . . . . . . N |
2|. P P B . P P P |
1|R N . . . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 f8 b4 이동했습니다.

  a b c d e f g h
 +-----------------+
8|. r b q k . . r |
7|p p p p . p p p |
6|. . . . p n . . |
5|. . . . . . . . |
4|P b B P n . . . |
3|. . . . . . . N |
2|. P P B . P P P |
1|R N . . . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: d2 b4
d2 b4

  a b c d e f g h
 +-----------------+
8|. r b q k . . r |
7|p p p p . p p p |
6|. . . . p n . . |
5|. . . . . . . . |
4|P B B P n . . . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N . . . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
컴퓨터의 차례입니다...
컴퓨터가 f6 g4 이동했습니다.

  a b c d e f g h
 +-----------------+
8|. r b q k . . r |
7|p p p p . p p p |
6|. . . . p . . . |
5|. . . . . . . . |
4|P B B P n . n . |
3|. . . . . . . N |
2|. P P . . P P P |
1|R N . . . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력: a1 a3
a1 a3

  a b c d e f g h
 +-----------------+
8|. r b q k . . r |
7|p p p p . p p p |
6|. . . . p . . . |
5|. . . . . . . . |
4|P B B P n . n . |
3|R . . . . . . N |
2|. P P . . P P P |
1|. N . . . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
축하합니다! 조건을 만족했습니다.
백색 말 조건 충족: 100 == 100
Layer7{this_is_a_real_flag_maybe_not_submit_it!!!}
컴퓨터의 차례입니다...
컴퓨터가 b8 a8 이동했습니다.

  a b c d e f g h
 +-----------------+
8|r . b q k . . r |
7|p p p p . p p p |
6|. . . . p . . . |
5|. . . . . . . . |
4|P B B P n . n . |
3|R . . . . . . N |
2|. P P . . P P P |
1|. N . . . K . R |
 +-----------------+

점수판:
White:  (0점)
Black:  (0점)
축하합니다! 조건을 만족했습니다.
백색 말 조건 충족: 100 == 100
Layer7{this_is_a_real_flag_maybe_not_submit_it!!!}
White의 차례입니다.
이동을 입력하세요 (예: e2 e4), 종료하려면 exit 입력:
➜  ~                                                 

flag : Layer7{this_is_a_real_flag_maybe_not_submit_it!!!}

reverse the reverse

UPX 패킹 되어서 언팩하고 md5 해쉬 VirusTotal에 검색해보니 뭐가 나온다.

공격자의 패킷을 알기 위해선 실행해봐야 할 것 같았다.

windows 10 VM이 없어서 다운 받다가 ticket으로 실행해도 문제 없냐고 물어보니 없다고 하셔서 실행했다.

네트워크 연결 기록 보고 악성 IP 찾는 것을 구글링 해보니 netstat이라는 게 있었다.

악성 프로그램 실행 후 netstat -na를 사용하여 확인해보니 수상해보이는 것이 있었다.

TCP    192.168.0.105:53124    71.92.213.182:10203    SYN_SENT 

비표준 포트에다가 SYN_SENT로 연결 시도 중이여서 제출 하였다. 근데 맞았다.

flag : Layer7{71.92.213.182:10203}

profile editor

웹을 못해서 GPT한테 물어봐서 풀었다.

  1. 프로필 생성 : asdf
  2. 프로필 업데이트 : asdf
  3. { "__proto__": { "isAdmin": true } }
  1. 관리자 권한 확인 : asdf
  2. 실행 결과
  3. { "success": true, "message": "관리자 권한이 확인되었습니다.", "flag": "Layer7{Pr0t0typ3_P0llut10n_1s_D4ng3r0us}" }

flag : Layer7{Pr0t0typ3_P0llut10n_1s_D4ng3r0us}

layer blog

@app.route("/image/<filename>")
def serve_image(filename):
    return send_from_directory("static", filename)

여기 보면 /image/<filename>으로 static 폴더에 접근 할 수 있음을 알 수 있다.

그렇다면 문제 설명에서 볼 수 있듯이 /image/flag/static/flag를 불러올 수 있다.

# ex.md

![FLAG](/image/flag.png)

flag : Layer7{516AE6629E4A3AF07464C5EE8}