Hacking/Web

SQL injection에서 IN 함수의 사용

Wermut 2025. 2. 27. 01:20

 

in 함수란?

 

SELECT * FROM [테이블명] WHERE [칼럼명] IN ([조건1], [조건2], [조건3]);

 

위 형태로 사용가능한 함수이며 or 과 비슷한 연산을 한다.

 

SELECT * FROM users
WHERE username = 'user1' OR username = 'user2' OR username = 'user3';

 

위 OR을 사용한 SQL 쿼리와 

 

SELECT * FROM users
WHERE username IN ('user1', 'user2', 'user3');

 

해당 쿼리는 같은 결과를 도출해낸다. IN 함수 내부엔 단순 값도 들어갈 수 있지만 서브 쿼리 또한 입력 가능하다.

 

한 CTF 문제를 풀던 중 이 in 함수에 대해 예상하지 못한 동작이 발생해 이 글을 포스트한다.

 

테이블 구조

 

문제의 데이터베이스 테이블은 위와 같이 형성되어있고,

 

테이블 내용

 

태이블에 작성된 내용은 다음과 같았다. 문제는 각종 필터링을 거쳐 최종적으로 superadmin 계정으로 SQL 인젝션 공격을 통해 로그인 하는 문제였고, 각종 필터링을 우회해 논리 우회를 시도하던 도중 

 

SELECT * FROM users WHERE username = ''in(1)

 

해당 쿼리가 참으로 동작한다는 것을 알 수 있었는데

 

 

도커에서 이를 실행해 보면 쿼리가 참으로 동작하여 테이블 내부의 내용들이 모두 불러와지는걸 알 수 있었다.

 

SELECT * FROM users WHERE username=''in(id like 2);

 

심지어 위 형식으로 조회하게 되면 

 

 

id가 2인 자료만 조회된다. 이러한 SQL 문법을 전부 무시하고 진행되는 쿼리가 납득이 가진 않는다.

 

첫 번째 쿼리에서 당연히 in을 '' 바로 뒤에 두는 쿼리는 문법에 어긋나는데 in 함수 안에 칼럼 조건을 넣는 위 쿼리조차 SQL 문법을 무시하는 쿼리이다. 

 

 

in을 사용한 조건문도 username = '' 이 따옴표 안의 문자에 따라 결정되는듯 보인다.

 

 

in 안의 조건을 두지 않으면 syntax 오류가 발생하고 0으로 둘경우엔 참으로 처리되지 않는듯하다. 이 모든 과정이 SQL 문법에 어긋나며 엄격하게 db의 문법이 작동했다면, syntax 오류가 발생하는것이 정상적이다.

 

다만 특정 오픈소스 기반의 DBMS는 SQL 문법을 벗어난 쿼리를 허용하는 경우가 있는데 위 예시 쿼리의 내용 중 username = '' 을 평가한 후 그 결과를 in(1)과 결합해 True로 평가했을 가능성이 존재하며

 

in 함수 내부의 조건을 삽입한 구문도 이와 동일하게 작용해 id = 1인 True 레코드를 반환할 가능성이 존재하다는 답변을 받았다.

 

즉 DBMS가 쿼리 자체를 유연하게 받아들이면서 해당 쿼리가 참으로 동작하는것으로 보이며 SQL의 문법을 엄격하게 검증하지 않는 이상 다른 DBMS에서도 이런 오류가 발생할 가능성은 충분히 존재한다고 추측된다.