yon11b

[SK 쉴더스 루키즈] [CI/CD GOAT] Mad Hatter 문제 Write up 본문

보안/SK 쉴더스 루키즈

[SK 쉴더스 루키즈] [CI/CD GOAT] Mad Hatter 문제 Write up

yon11b 2026. 4. 30. 23:58
반응형


문제

풀이

1. 사전 지식 점검

CICD GOAT의 환경은 이런 구조로 되어있다.

 

이번 문제에서는 Gitea-Jenkins만 이해하면 된다.

 

Gitea

코드 관리해주는 곳.

Github이랑 비슷한 느낌

Jenkins

Gitea 코드 변경되면 자동으로 빌드·테스트·배포까지 해주는 서버

코드 변경 ->  Jenkins가 빌드 -> 그 로그기록을 Jenkins UI에서 볼 수 있음

 

docker ps 뒷부분만 자른 것

jenkins는 localhost:8080에서, gitea는 localhost:3000에서 돌아간다.

 

2. 진짜 풀이

방향 잡기

문제를 보면 Wonderland/mad-hatter에 있는 flag3을 찾으라고 한다.

이번에는 레포에 Jenkinsfile이 없다..!

 

전혀 모르겠다. 힌트를 보자

repo 이름을 검색해라고 한다.

여기서 검색할 수 있다.

누가봐도 mad hatter랑 관련이 있어보이는 mad hatter pipeline 레포를 찾았다!

아싸! 여기에 Jenkins 파일이 들어있었다.

이 파일을 수정한 후 White Rabbit 문제처럼 PR을 날리면 될 것 같다.

 

Jenkinsfile 수정하기

수정하려고 봤더니 main브랜치에서 Jenkinsfile 수정이 안 되는 것은 물론이고 새 브랜치 생성도 안 된다!

그래서 기존 Jenkinsfile 코드를 확인해봤다.

 

 

흐름 이해하기...............

1. 이미 전에 Jenkins Credential Store에서 flag3, username, password가 구성되었다.

[Jenkins Credential Store]
        │
        └── ID: flag3
              ├── username: testuser
              └── password: FLAG{abc123}

 

 

2. 그리고 여기에서 username, password를 각각 USERNAME, FLAG로 환경변수 지정해 주었다.

withCredentials([
  usernamePassword(
    credentialsId: 'flag3',
    usernameVariable: 'USERNAME',
    passwordVariable: 'FLAG'
  )
])

 

 

환경변수 지정되면 이렇게 됨

  USERNAME = testuser
  FLAG     = FLAG{abc123}

 

 

3. Makefile에서는 이제 이렇게 접근할 수 있다.

$USERNAME → testuser
$FLAG     → FLAG{abc123}

 

-> 그럼 makefile에서 echo FLAG을 하면 되겠다!!

 

Makefile 수정하기

다시 mad-hatter 레포지토리로 돌아가서

 

1. 새 브랜치(hack)를 생성한 후, 

2. Makefile을 다음과 같이 수정해주었다.

all:
	echo $$FLAG | base64
	echo $$FLAG | rev
	echo $$USERNAME

 

3. 새로 만든 브랜치를 pr 날리고

4. Jenkins UI에서 로그를 확인해보자.

flag가 잘 출력이 된 것을 확인할 수 있다.

 

전체 흐름 정리

Gitea: mad hatter pipline 레포에서 브랜치 생성
→ Makefile 수정
→ PR 생성 또는 push
→ Jenkins 빌드 트리거
→ Jenkins가 flag3 credential을 환경변수로 주입
→ make 실행
→ Makefile에서 FLAG 출력
→ Jenkins 로그에서 결과 확인
→ base64 디코딩 또는 rev 복원
→ CTFd에 제출

728x90