프로젝트

팀 프로젝트_Pyramid Walkthrough

ljm 2025. 9. 30. 17:46

Pyramid CTF Walkthrough

 

Box의 ip는 192.168.16.19 라는 것을 알아냈다.

 

 

ssh 와 http 서비스가 동작 중인것을 확인

http 접속

 

 

아무런 값을 대입해보았는데, 기록에 없는 이름이라고 뜬다.

 


 

SQL Injection 취약점은 없는지 작은 따옴표를 입력해보았다.

 

'를 입력한 결과 Mysql 에러 메세지가 출력 화면에 표시되는 모습

 

 

이로써 알 수 있는 정보 두가지

 

1. 사용자가 입력한 값이 웹 애플리케이션의 필터링 없이 데이터베이스 쿼리에 직접 사용되고 있다. (SQL 인젝션 취약점 존재)

2. URL에 index.php?name=? 형태로 파라미터가 노출되는 것은 GET 방식을 사용하여 사용자 입력을 서버로 전송하고 있다.

3. 해당 php는 총 3개의 칼럼을 표시할 수 있다.

 

(필드명은 차이가 있겠지만 실행되는 쿼리는 대충  SELECT Name, Dynasty, Regnal Period FROM TABLE WHERE NAME='$input_value'  쯤으로 예상된다.)

 


 

먼저 가장 기본적인 SQLi를 입력해보았다.

' OR '1'='1

 

"사용자 이름이 'a'와 같거나 (아니어도 상관없음), 조건 **'1'='1' (참)**이므로, 모든 조건을 무시하고 모든 행을 반환하라."

 

그 결과 DB의 내용들이 일부 출력되는것을 확인

 

 

이로써, OR 등의 SQL 언어가 php에서 필터링 되지않는 것을 확인했다.

 

 


 

이제 본격적으로 테이블 이름을 추출하는 SQLi를 실행해보자.

 

테이블명을 추출하는 SQLi

' UNION SELECT 1, group_concat(table_name), 3 FROM information_schema.tables WHERE table_schema=database() --

 

2번째 항목에 table_name 표시

 

 

1. 전제 조건 및 쿼리 시작 (' UNION SELECT)

 

작은따옴표(')

: 사용자가 입력하는 필드가 원래 SQL 쿼리에서 열려 있던 따옴표(')를 닫아주어, 공격자가 삽입한 코드가 구문 오류 없이 실행되도록 만든다.

 

UNION SELECT 

: 앞서 실행된 취약한 원본 SELECT 쿼리의 결과와, 공격자가 뒤에 붙인 새로운 SELECT 쿼리의 결과를 하나로 합치도록 지시하는 핵심 연산자이다.

 

 

2. 칼럼 일치 및 데이터 추출 (1, group_concat(table_name), 3)

 

1, __, 3

: UNION 구문은 앞선 쿼리와 컬럼의 개수와 타입이 일치해야 하는데, 앞에서 칼럼 수가 3개인것을 확인

 

group_concat(table_name)

: table_name 필드에서 조회된 모든 테이블 이름을 쉼표(,)로 구분된 하나의 긴 문자열로 합쳐서 반환하는 함수

 

 

3. 정보원 및 조건 (FROM information_schema.tables WHERE...)

 

FROM information_schema.tables

: 데이터베이스의 스키마 정보(테이블, 칼럼 정의 등)를 담고 있는 특별한 시스템 데이터베이스

 

WHERE table_schema=database()

: 현재 사용 중인 데이터베이스의 이름을 반환

 

 

4. 나머지 쿼리 무시하고 종료 ( -- )

 

MySQL을 포함한 SQL에서 -- (뒤에 공백 필수)는 그 뒤에 오는 모든 내용을 주석(Comment) 처리하여 코드로 실행되지 않도록 무시하는 명령어

 

 

 웹페이지는 원래 데이터를 출력하는 대신, 두 번째 SELECT 문이 반환하는 값인 "1, 현재 모든 데이터베이스 이름, 3" 을 사용자에게 보여주게 된다.

 


 

다음은 얻은 테이블명을 바탕으로 칼럼명을 추출하는 SQLi를 실행한다.

 

칼럼명을 추출하는 SQLi

' UNION SELECT 1, group_concat(column_name), 3 FROM information_schema.columns WHERE table_name='pharaohs' --

 

2번째 항목에 모든 칼럼명 표시

 

 

1. 쿼리 결합 및 구조 맞추기 (' UNION SELECT 1, ..., 3)

 

칼럼개수 3개로 일치 시킨 후 UNION SELECT

 

 

2. 칼럼 이름 추출의 핵심 (group_concat(column_name))

 

MySQL에서 사용되는 함수로, 조회된 모든 column_name 값들을 쉼표로 구분된 하나의 긴 문자열로 합쳐서 반환한다. 이 결과가 웹 페이지에 노출되어 공격자가 숨겨진 칼럼명을 알 수 있게 된다.

 


 

secret_info 에 담긴 최종 힌트를 얻는 SQLi

' UNION SELECT 1, 2, secret_info FROM pharaohs WHERE id = 6 --

 

 

긴 문자열이 표시될 수도 있기때문에 secret_info 값을 세 번째 칼럼 위치에 표시

 

"where id=?" 부분을 제거하고 전체를 조회한 후 웹 페이지를 Inspect 해도 된다.


 

획득한 힌트는 어디에서 쓰이는 단서일까?

 

 

아까 웹 페이지의 view-source에서 발견한 또 다른 힌트이다.

웹 페이지 소스에 담긴 주석 힌트 : 엄청 긴 문자열

 

 

해당 코드는 ROT13으로 인코딩 된 것을 확인했다.

 

ROT13.com 에서 디코딩

 

 

The Pharaoh's cipher exists not for the gatekeeper's key, but for the logic of the Nile's unfolding map. Follow the flow to the next chamber.
→ "파라오의 암호는 문지기의 열쇠를 위한 것이 아니라, 펼쳐지는 나일강 지도의 논리를 위해 존재한다. 흐름을 따라 다음 방으로 나아가라."

 

이 문구는 SSH 접속 정보가 아님을 간접적으로 나타내며, 다음 웹 디렉토리를 이동해야 함을 비유적으로 알 수 있다.

 

최종힌트

 

최종 힌트를 보면 '/' 표시가 있는데, 이것을 보고 디렉토리 경로라는 것을 유추해볼 수 있다.

 

얻은 정보들을 바탕으로 "http://pyramidIP/the_architect_of_the_Great_Pyramid" 로 이동하면 다음 단계로 넘어간다.