[normaltic 취업반 5기] 2023-12-02 6주차 과제 : 3번 과제

2023. 12. 2. 22:36normaltic 취업반 5기/과제

3번 과제

 

  • 과제 목표 : 실습용 웹 어플리케이션의 SQL Injection 1, 2 풀기

 

3번 과제 실습 : SQL Injection 1번 문제

 

실습용 웹 어플리케이션

 

  실습용 웹 어플리케이션의 기능으로 사용자 아이디를 입력하게 되면 사용자의 정보가 조회되는 것으로 보인다. 조회되는 데이터의 수에는 딱히 제한이 없는 것 같이 보인다. 조회에 사용되는 쿼리문이 어떤 형태로 구성되어 있는지 확인해 보기 위해 테스트로 데이터를 입력해 보자.

 

사용된 쿼리문 구성

 

  입력창에 'admin' 문자열을 입력했더니 아이디가 'Adminer'인 사용자의 정보가 조회되었다. 입력된 데이터와 정확히 일치하지 않아도 입력한 문자열이 포함된 사용자 정보가 조회되는 것으로 보아 게시글 조회에 사용되는 쿼리문처럼 like문을 사용하는 것으로 보인다. 

 

  그렇다면 해당 문제의 목표인 플레그를 찾기 위해서 UNION SQL Injection을 사용하여 DB 데이터를 추출해 보자.

 

1) UNION SQL Injection

 

  UNION SQL Injection은 다음과 같은 과정으로 진행된다.

 

  1. SQL Injection 작동 여부
  2. COLUMN 개수 찾기
  3. 출력되는 COLUMN 위치 찾기
  4. DB 이름 찾기
  5. TABLE 이름 찾기
  6. COLUMN 이름 찾기
  7. DATA 추출

 

[1] SQL Injection 작동 여부

 

 

  SQL Injection의 작동 여부를 확인하기 위해 항등원을 삽입하여 작동하는지 확인한 결과 정상적으로 작동되는 것이 확인되었다.

 

[2] COLUMN 개수 찾기

 

 

  'ORDER BY 5'를 삽입하였더니 조회가 되지 않는 것으로 보아 쓰이는 컬럼은 네 개인 것으로 확인이 되었다.

 

[3] 출력되는 COLUMN 위치 찾기

 

 

  쿼리문 삽입 결과 모든 컬럼에서 데이터가 출력되는 것이 확인이 되었다.

 

[4] DB 이름 찾기

 

 

  현재 DB 이름을 조회한 결과 'sqli_1'라는 이름으로 확인이 되었다.

 

[5] TABLE 이름 찾기

 

 

  admin%' UNION SELECT 1,table_name,3,4 from information_schema.tables where table_schema = 'sqli_1' #라는 쿼리문을 삽입하여 'sqli_1' DB에 존재하는 테이블을 조회한 결과 'flag_table, user_info'의 테이블들을 확인했고 플레그를 찾기 위해 'flag_table' 테이블의 컬럼명을 확인하자.

 

[6] COLUMN 이름 찾기

 

 

  admin%' UNION SELECT 1,column_name,3,4 from information_schema.columns where table_name = 'flag_table' #라는 쿼리문을 삽입하여 ' flag_table ' 테이블에 존재하는 'flag'라는 컬럼명을 확인하였다.

 

[7] DATA 추출

 

 

  admin%' UNION SELECT 1,flag,3,4 from flag_table #라는 쿼리문을 삽입하여 SQL Injection 1번 문제의 플레그를 발견하였다.

 

3번 과제 실습 : SQL Injection 2번 문제

 

실습용 웹 어플리케이션

 

  실습용 웹 어플리케이션의 기능으로 사용자 아이디를 입력하게 되면 사용자의 정보가 조회되는 것으로 보인다. 조회에 사용되는 쿼리문이 어떤 형태로 구성되어 있는지 확인해 보기 위해 테스트로 데이터를 입력해 보자.

 

입력창에 'normaltic'을 입력했을 때
입력창에 의미없는 문자열을 입력했을 때

 

  입력창에 벡그라운드에 적혀있는 'normaltic'이라는 아이디를 입력했더니 ID 컬럼에 입력한 내용이 출력되고 Info 컬럼에 관련 정보가 출력되는 것을 확인할 수 있다. 그러나 의미없는 문자열을 입력했더니 마찬가지로 ID 컬럼에 입력한 내용이 출력되고 Info 컬럼에는 아무런 내용이 출력되지 않았다. 

 

  이는 'ID, Level, Rank Point' 컬럼들은 쿼리문의 결과와 상관없이 출력이 되고 Info 컬럼은 입력한 아이디와 일치하는 데이터가 존재한 경우만 출력하는 것으로 추측해 볼 수 있다.

 

입력창에 'mal'을 입력했을 때
사용된 쿼리문 구성

 

  이번에는 쿼리문이 어떤 형태로 구성되어 있는지 확인하기 위해 DB에 존재하는 데이터인 'normaltic'에 포함된 'mal'문자열을 입력했더니 Info 컬럼에 출력된 결과가 없는 것으로 보아 해당 쿼리문은 'LIKE' 문법을 쓰지 않은 즉, ID = '입력 아이디'를 조건으로 DB에 저장되어 있는 데이터와 비교하는 것으로 추측해 볼 수 있다.

 

 그렇다면 해당 문제의 목표인 플레그를 찾기 위해서 UNION SQL Injection을 사용하여 DB 데이터를 추출해 보자.

 

1) UNION SQL Injection

 

  UNION SQL Injection은 다음과 같은 과정으로 진행된다.

 

  1. SQL Injection 작동 여부
  2. COLUMN 개수 찾기
  3. 출력되는 COLUMN 위치 찾기
  4. DB 이름 찾기
  5. TABLE 이름 찾기
  6. COLUMN 이름 찾기
  7. DATA 추출

 

[1] SQL Injection 작동 여부

 

 

  SQL Injection의 작동 여부를 확인하기 위해 항등원을 삽입하여 작동하는지 확인한 결과 정상적으로 작동되는 것이 확인되었다.

 

[2] COLUMN 개수 찾기

 

 

  'ORDER BY 7'을 삽입하였더니 조회가 되지 않는 것으로 보아 쓰이는 컬럼은 여섯 개인 것으로 확인이 되었다.

 

[3] 출력되는 COLUMN 위치 찾기

 

 

  쿼리문 삽입 결과 출력되는 데이터 중 숫자를 출력하는 데이터도 조회 됐어야 하는데 아이디가 'normaltic'인 정보만 조회된 것으로 보아 출력되는 데이터는 최대 한 개라고 볼 수 있다.

 

 

  그래서 DB에 저장되어 있는 데이터를 조회하지 않도록 하여 쿼리문을 삽입하였더니 Info 컬럼에 '6'이라는 숫자가 출력됨으로써 여섯 번째 순서로 입력된 것을 확인할 수 있었다.

 

[4] DB 이름 찾기

 

 

  현재 DB 이름을 조회한 결과 'sqli_5'라는 이름으로 확인이 되었다. 또한 최대 출력되는 결과가 한 개로 제한되어 있기 때문에 'ORDER BY' 구문을 사용하여 각 컬럼을 기준으로 쿼리문을 삽입하였으나 다른 DB는 없는 것으로 확인이 되었다.

 

[5] TABLE 이름 찾기

 

 

  ' UNION SELECT 1,2,3,4,5,table_name from information_schema.tables where table_schema = 'sqli_5' #라는 쿼리문을 삽입하여 'sqli_5' DB에 존재하는 테이블을 조회한 결과 'flag_honey, secret, game_user'의 테이블들을 확인하였다. 비밀 데이터가 어느 테이블에 존재하는지 모르므로  'flag_honey, secret, game_user' 순서대로 확인을 해보도록 하자.

 

[6] COLUMN 이름 찾기

 

[6-1] flag_honey 테이블

 

 

  ' UNION SELECT 1,2,3,4,5,column_name from information_schema.columns where table_name = 'flag_honey' #는 쿼리문을 삽입하여 'flag'라는 컬럼명을 확인하였다. 또한 'ORDER BY' 구문을 사용하여 다른 컬럼명도 있는지 확인하였으나 없었다.

 

[6-2] secret 테이블

 

  

  ' UNION SELECT 1,2,3,4,5,column_name from information_schema.columns where table_name = 'secret' #는 쿼리문을 삽입하여 'flag'라는 컬럼명을 확인하였다. 또한 'ORDER BY' 구문을 사용하여 다른 컬럼명도 있는지 확인하였으나 없었다.

 

[6-3] game_user 테이블

 

 

' UNION SELECT 1,2,3,4,5,column_name from information_schema.columns where table_name = 'game_user' #는 쿼리문을 삽입하여 'idx'라는 컬럼명을 확인하였다. 또한 'ORDER BY' 구문을 사용하여 다른 컬럼명도 있는지 확인했더니 'rank_point, level, pass, id'라는 컬럼들을 추가로 찾아냈다.

 

[7] DATA 추출

 

[7-1] flag_honey 테이블

 

 

  ' UNION SELECT 1,2,3,4,5,flag from flag_honey #라는 쿼리문을 삽입하였으나 플레그는 출력되지 않았다. 다른 데이터도 있는지 'ORDER BY' 구문을 사용하였으나 존재하지 않았다.

 

[7-2] secret 테이블

 

 

 ' UNION SELECT 1,2,3,4,5,flag from secret #라는 쿼리문을 삽입하였으나 플레그는 출력되지 않았다. 다른 데이터도 있는지 'ORDER BY' 구문을 사용하였더니 플레그를 발견할 수 있었다.