syurhia 님의 블로그

PortSwigger SQL injection attack, listing the database contents on non-Oracle databases 본문

보안관련/PortSwigger

PortSwigger SQL injection attack, listing the database contents on non-Oracle databases

syurhia 2026. 4. 27. 18:39

이번 내용은 데이터베이스에서 어떠한 테이블을 쓰고 있고 어떠한 column이 있는지 알아내야 될 때 사용하는 기법이다.

즉, 아무것도 모르는 상황에서 쓰는 기법이다. (다만, 이번 편에서는 non-oracle database일 때 기법이다.)

이 상황에서 administrator의 비밀번호를 알아내는 게 목표이다.

 

평소에 답을 안보고 푸는 걸 선호하는 탓에, 개념을 학습하고도 문제를 푸는데 시간이 좀 걸렸다.

데이터베이스에서 Table은 BASE TABLE과 VIEW로 나뉜다.

Base Table은 그냥 값을 저장하는 테이블로 생각하면 되겠다. 흔히 우리가 아는 데이터베이스의 테이블이 이거다. 값을 저장하고 수정하고 등등 하는 것.

View는 가상의 테이블이다. 실제로 값을 저장하는 게 아니라 SQL쿼리문만 저장한다. 참조를 하는 순간, 저장된 SQL쿼리문들을 실행시켜서 실제 base table에서 데이터를 가져오는 역할이다. 이게 왜 필요한가 했는데, 중요한 데이터가 담긴 테이블을 숨겨주고 필요한 데이터만 쏙 뽑아서 다른 테이블마냥 보여줄 수 있다는 보안적인 장점이 있다고 한다.

 

이 문제의 데이터베이스에서 View와 base table을 보는 방법은 아래의 쿼리를 URL에 붙여주면 된다. 중요한 건 'category=' 이 부분 다음부터 붙여줘야 한다.

Gifts%27+UNION+SELECT+table_name,table_type+FROM+information_schema.tables+--+

table_type에서 View와 base table을 출력해준다.

 

 

그리고, 테이블에는 table_schema라는 것이 있는데, 간단히 얘기하면 테이블들의 폴더명이다. SELECT table_name, table_schema FROM infromation_schema.tables로 확인할 수 있다. 아무것도 정의하지 않았을 때, 사용자가 만드는 테이블들은 public에 저장된다.(단, PostgreSQL의 경우가 그렇다. 다른 데이터베이스의 경우는 다를 수 있다.)

테이블들의 폴더명은 table_schema로 살펴볼 수 있다.

Gifts%27+UNION+SELECT+table_name,table_schema+FROM+information_schema.tables+--+

 

좀 삽질을 많이 해서, 이번 문제의 경우에는 테이블들의 폴더명과 View, Base table등의 정보들을 다양한 테이블에서 본 것 같다. 그래도 이런 삽질의 내용은 되도록 안 담을테니 아래의 내용은 깔끔하게 볼 수 있을 것이다.

 

그럼 이제 문제를 풀어보겠다. Congratulations라고 나와있지만 신경쓰지 말자. 이미 풀어버려서 처음부터 이미지를 새로 찍은거니까..

 

그림 1. 취약점이 있는 사이트

그림 1의 사이트가 있다. 카테고리쪽에 SQL인젝션 취약점이 존재한다고 한다.

 

이번엔 UNION을 이용해서 풀 것인데, 그러기 위해서는 반환하는 column이 몇 개인지 확인하고 data type을 확인해보자. 

그림 2. UNION을 쓰기 위한 확인

 

그림 2는 category=Gifts에서 아래의 코드를 삽입한 결과이다.

Gifts'+UNION+SELECT+'aaa','bbb'+--+

이미지에는 담기지 않았지만 아래에 aaa와 bbb가 출력되어 있다. 이것으로 보아, 2개의 열을 반환하고 문자열과 호환 가능한 것을 알 수 있다.

 

그럼 이제 이 데이터베이스의 테이블을 참조해보자. 보통 information_schema.tables라는 테이블에 테이블들의 이름(table_name)과 테이블들의 타입(table_type)이 저장되어 있다. 

 

그림 3. 테이블 출력하기

 

우리가 확인할 테이블은 Base table일 것이고, 테이블의 타입의 경우에는 public일 것이니 아래와 같이 쿼리를 작성해주자.

Gifts%27+UNION+SELECT+table_name,table_type+FROM+information_schema.tables+WHERE+table_type=%27BASE%20TABLE%27+AND+table_schema='public'--+

이 쿼리를 사용할 경우 그림3과 같은 결과가 나온다. products와 users_woumfa테이블에 정보가 담겨있다는 것이다.

products는 제품에 관련된 정보가 담겨있으니,  users_woumfa가 정답이 있는 테이블이 되겠다.

 

그림 4. users_woumfa살펴보기

 

그러니, users_woumfa에서 무슨 열이 있나를 한 번 살펴보자. 모든 테이블에서 특정 테이블의 열의 정보를 살펴보려면 information_schema.columns를 쓰고, 테이블을 WHERE로 지정해야 한다. users_woumfa를 지정해서 column_name과 data_type을 살펴보기 위해 쿼리를 짠 게 아래의 쿼리이다. 

Gifts'+UNION+SELECT+column_name,data_type+FROM+information_schema.columns+WHERE+table_name='users_woumfa'+--+

이 쿼리를 실행시키면 그림 4와 같이 값들이 출력된다.

 

우리에게 필요한건 username_lsppby와 password_jzjtuh열이다. 아마 id와 password일 것이다. 이것을 출력해보자.

 

그림 5. 아이디와 비밀번호

아래의 쿼리를 실행시켜보자.

Gifts'+UNION+SELECT+username_lsppby, password_jzjtuh+FROM+users_woumfa+--+

그러면 그림5와 같이 결과가 나오는데 administrator과 비밀번호가 떴다. 저걸로 로그인을 하면 된다.