오랜 기간 계속해서 OWASP 10의 가장 심각한 리스크로 선정된 인젝션 리스크의 대표적인 공격.
- SQL 인젝션은 웹 서버 영역의 데이터베이스로 전송되는 SQL 쿼리문을 사용자가 임의로 조작할 수 있는 경우에 발생
- 이 취약점을 이용해 데이터베이스에 저장되어 있는 다른 사용자의 개인정보 등 허가되지 않은 정보에 접근하거나
데이터를 변조할 수 있음.
Low 레벨
- userid를 입력받는 Form이 보임. 이 Form으로 웹 서버 내부 DB에서 회원정보를 조회하는형식인것 같음.
- 최우선적으로 SQL Injection을 할 수 있는지 테스를 해야함
- ' 와 " 를 사용해 웹서버 내부에서 쿼리문을 어떤 방식으로 처리하는지 알 수 있음.
- 이상한 오류가뜨면 SQL Injection에 취약한것으로 판단할 수 있음.
본격적으로 SQL Injection을 수행하여 WHERE 절 우회할 수 있음.
- ' or 1=1 # 으로 모든 레코드 출력가능
- 내부적인 동작 방식을 고려해보면, 주석(#)없이 ' or '1'=1 로도 우회를 할 수 있음.
DVWA 내에서 Form에서 입력받은 문자열을 어떤 방식으로 처리해주는지 보자.
아래 문장은 Form에서 입력한 문자열을 DVWA 내부에서 처리하는 코드이다.
맨앞, 맨뒤의 큰따옴표 " 와 ; 는 서버로 넘어갈때 없어지고 처리된다.
" SELECT first_name, last_name FROM users WHERE user_id = '$id'; ";
결과적으로 아래의 쿼리문이 서버로 넘어가는 것이다. $id는 Form에서 입력한 문자열이 들어가게된다.
SELECT first_name, last_name FROM users WHERE user_id = '$id';
따라서, WHERE절을 우회하기 위해 사전에 입력한 Injection문이 내부적으로 아래와 같이 처리되는 것이다.
- #은 주석이며 # 뒤에나오는 구문은 언어의 능력이 상실하게되어 아무런 뜻이 없게 된다.
SELECT first_name, last_name FROM users WHERE user_id = ' ' or 1=1 #';
- 즉, 작은 따옴표가 안정적이게 닫혀 조작된 쿼리문이 완성되게 된다.
SELECT first_name, last_name FROM users WHERE user_id = ' ' or 1=1 #
- # 주석을 사용하지 않았을때 또한 작은따옴표가 안정적이게 처리되는것을 확인할 수 있다.
SELECT first_name, last_name FROM users WHERE user_id = ' ' or '1'='1';
나아가서, UNION과 ORDER BY문으로 SQL Injection을 심화학습할 수 있다.
UNION을 사용하면 데이터베이스의 정보를 빼올 수 있고, 본래 쿼리에서 몇개의 컬럼을 출력해주는지 알수 있다.
ORDER BY를 사용하면 본래 쿼리에서의 몇개의 컬럼을 출력해주는지 알 수 있다.
- UNION문은 합집합의 역할을 한다. 이게 무슨뜻이냐? 서로다른 레코드들을 합쳐서 출력해준다는 의미이다.
하지만, UNION을 사용하기 위해서는 원래의 SQL 쿼리문이 조회하는 SELECT 문의 칼럼 개수와 UNION절 뒤의
SELECT 문에서 요청하는 칼럼의 개수가 같아야 한다. 그렇기 때문에, 원래의 쿼리문에서 몇개의 컬럼을 리턴해주는지
알아내야 한다.
- 이렇게 컬럼의 개수를 알아내는 역할을 ORDER BY가 수행한다. 본래 ORDER BY는 특정 컬럼의 이름을 기준으로 정렬
해주는 역할을 하지만, 컬럼의 인덱스를 기준으로도 정렬을 해줄수가 있다.
그리고 설명을못했지만, 컬럼의 개수를 알아내는 역할은 ORDER BY뿐만아니라, UNION도 가능하다.
우선 UNION 으로 컬럼 개수를 알아내보자. union절 뒤에 select 1 # 을 입력해보면, 컬럼의 개수가 다르다고 나온다.
select 1이 무슨 잡소리냐라고 생각할 수 있다. mysql에서만 그런지는 모르겠지만, select하고 숫자를 적어주면 해당 숫자를 고대로 출력 (사진 (좌)) 해주는 특징을 갖고 있다. 그리고 union과 결합해 응용해보면 아래사진(우)처럼 나온다. 무슨 느낌인지 알겠는가?
앞서 설명했지만, UNION절 앞의 SELECT문과 뒤의 SELECT문이 출력해주는 컬럼개수가 같아야 UNION쿼리문이 성공할 수 있다. 아래 사진에서 볼 수 있듯, UNION절 뒤의 SELECT문의 숫자를 한개씩 늘려주면, 본래 쿼리문에서 리턴해주는 컬럼 수를 알 수 있다.
따라서 DVWA에서도 똑같이 union절 뒤 select문의 숫자를 한개씩올리다 보면, 해당 쿼리에서 리턴해주는 컬럼 수를 알 수 있다.
두번째로 ORDER BY 문으로 해당 쿼리의 컬럼 개수를 알아내보자.
- ORDER BY는 UNION과 약간 차이점이 있다.
- UNION은 앞뒤의 SELECT문에서 출력해주는 컬럼의 수가 같아야 컬럼의 개수를 알 수 있었지만
ORDER BY는 특정 컬럼의 인덱스(INDEX)를 기준으로 정렬해주는 특성과 전체 컬럼의 개수를 넘어서는 INDEX를 기준
으로는 정렬을 하지 못한다는 특성을 이용하여 쿼리에서 출력해주는 컬럼수를 알 수 있다.
아래의 사진을 보자. INDEX가 1과 2인 컬럼을 기준으로 정렬하는 쿼리문을 입력했지만, 아무일도 일어나지않았다. 오류가 일어나지않았기 때문에 입력한 ORDER문은 정상적으로 수행된다고 볼 수 있다.
하지만 INDEX가 3인 컬럼을 기준으로 정렬하면 어떻게 될까? 아래 사진처럼 IDX가 3인 컬럼을 기준으로 정렬할 수 없다 오류가 출력된다. 따라서, 해당 쿼리에는 2개의 컬럼이 존재한다고 알 수 있다.
아래 사진을 봄으로써, order by 문을 이해할수 있길 바란다.
이렇게 기본적인 WHERE절 우회와, UNION과 ORDER BY 문으로 해당 쿼리에서의 컬럼개수를 알아내는 과정을 공부했다. UNION으로 전체 컬럼의 개수를 찾을때는 정확한 값을 입력할때까지 일일이 숫자의 개수를 늘려가며 다 대입해봐야
했지만, ORDER BY 로는 입력한 값보다 컬럼의 개수가 많은지 작은지 알 수 있기 때문에, 컬럼의 개수를 찾을 때는 ORDER BY 문을 사용하는지 더 괜찮다는 결론이 나왔다.
아직 학생이고 항상 까먹기때문에 틀린부분이 있을수도 있지만, 자세하게 적어본다....
컬럼개수를 알아내었으니 다음 포스팅은 이걸 토대로 DB정보를 빼내는 과정을 적어봐야겠다.
'WebHacking > DVWA' 카테고리의 다른 글
[DVWA] Command Injection (0) | 2022.01.12 |
---|---|
[DVWA] SQL Injection (3) (0) | 2022.01.12 |
[DVWA] SQL Injection (Blind) (0) | 2022.01.12 |
[DVWA] SQL Injection (2) (0) | 2022.01.12 |
[DVWA] Brute-Force (0) | 2022.01.10 |