syurhia 님의 블로그

PortSwigger SQL injection UNION attack, retrieving multiple values in a single column 본문

보안관련/PortSwigger

PortSwigger SQL injection UNION attack, retrieving multiple values in a single column

syurhia 2026. 4. 24. 19:22

이번에는 쿼리에서 반환되는 것 중 문자열을 반환하는 게 한 개의 열밖에 없을 때 어떻게 대처하는지에 대한 방법이다.

이럴때는 여러 개의 문자열(예를 들면 id랑 password열)을 하나의 문자열로 붙여서 출력시키면 된다고 한다.

 

방법은 || 을 쓰면 문자열을 붙일 수 있다고 한다.

단, id랑 pass를 그냥 붙여버리면 알아보기 어려우니 || ':' ||와 같이 구분하는 문자열도 추가해줘서 알아보기 쉽게 해주자.

 

이번 문제도 users테이블에 username과 password열이 존재한다. 

그림1. 카테고리에 취약점이 존재하는 웹사이트

그림1과 같은 사이트에서 카테고리에 SQL injection 취약점이 존재한다고 한다.

 

일단 쿼리에서 몇 개의 열이 반환되는지 확인해보자.

category = Gifts' UNION SELECT NULL, NULL --를 입력했다.

그림2. 쿼리의 반환 열 개수

그림2와 같이 총 2개의 열이 반환된다는 게 확인이 되었다.

 

그러면 이제 어느 열이 문자열을 반환하는지 확인해야 되는데, 첫 번째 열에 문자열 'a'를 넣으니 에러가 떴다.

그래서 두 번째 열에 넣어봤더니 이번에는 반환이 됐다. 다만, 첫 번째 열은 뭔지 몰라서 숫자를 넣어봤더니 반환이 되더라.

category = Corporate+gifts' UNION SELECT 1, 'a' --와 같이 입력했다.

그림3. 두 번째 열에 문자열 입력

그 결과가 그림3과 같다.

보면 숫자 1은 어디에 출력되는진 모르겠지만 a는 출력이 되어있다.

1은 아무래도 쿼리에서 반환은 하지만 웹사이트에 출력은 안 하는 게 아닐까 싶다. 추측이다

 

그림4. 관리자 계정 출력

이제, 문자열이 어디서 출력되는지 알았으니 2번째 열에다가 username과 password를 합쳐서 출력해보자.

category = Corporate+gifts' UNION SELECT NULL, username || '~' || password FROM users --를 입력한다.

이거는 두 번째 열에 username~password로 출력해달라는것과 같다.

조건문인 WHERE이 없으니 users의 모든 계정이 출력될 것이다. 

 

결과를 보면 그림4와 같이 administrator, carlos, wiener라는 계정 3개가 출력된다.

우리가 필요한 건 administrator이니까 아이디랑 비밀번호를 복사해서 로그인을 하면...

 

그림5. 로그인 완료

그림5와 같이 로그인에 성공한다.

 

 

테이블에 대해 알고 있고, 쿼리에서 문자열을 반환하는 열이 있다면 출력이 가능하다는 얘기다.

 

보면 볼수록 별 방법이 다 있다. 맨 처음에 막는 방법으로 '와 같은 특수문자를 필터링하면 되지않을까라고 얘기했는데, 그런 방법으로 하면 진짜 다 털릴 것 같다는 생각이 든다. 

 

그러니, 출력과 입력에 관한 처리는 항상 조심할 것.