이 문서에 포함된 어떠한 내용도 불법적이거나 비윤리적인 목적으로 보안 도구나 방법론을 사용하도록 가르치거나 장려하지 않습니다. 항상 책임감 있는 태도로 행동하세요. 여기에 설명된 도구나 기법을 사용하기 전에 개인 테스트 환경 또는 허가를 받았는지 확인하세요. |
[ 환경 ]
DVWA | v1.9 |
Burp Suite | Community Edition v2024.11.2 |
이 코드는 세션에 저장된 id 값을 사용하여 데이터베이스에서 사용자 정보를 조회하고 출력하는 PHP 스크립트이다.
if( isset( $_SESSION [ 'id' ] ) ) {
$id = $_SESSION[ 'id' ];
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysql_query( $query ) or die( '<pre>Something went wrong.</pre>' );
$num = mysql_numrows( $result );
$i = 0;
while( $i < $num ) {
$first = mysql_result( $result, $i, "first_name" );
$last = mysql_result( $result, $i, "last_name" );
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
$i++;
}
SQL 인젝션 취약점
SELECT first_name, last_name FROM users WHERE user_id = '1 OR 1=1' LIMIT 1;
구식 데이터베이스 함수 사용
세션 값 신뢰 문제
에러 메시지 노출
High level에서는 "아이디를 변경하려면 여기를 클릭하세요" 라는 텍스트가 링크와 함께 표시되어 있다.
해당 링크를 클릭하면 최종 사용자가 입력을 제출할 수 있는 텍스트 상자가 있는 팝업 창이 열린다.
[그림 4]와 같이 텍스트 상자에 1을 입력하면, 제출 후 이전과 같이 메인 페이지에 데이터베이스에서 가져온 사용자에 대한 정보를 제공하는것을 확인할 수 있다.
숫자를 계속 입력하면, 최대 5명의 사용자에 대한 정보를 검색할 수있다. 항상 연속된 숫자로 구현되는 것은 아니므로 반드시 5명의 사용자가 있다는 것을 의미하지 않는다. 여기서는 최소 5명의 사용자 정보가 있다고 가정하겠다.
Burp Suite를 이용해서 최종 사용자가 입력을 제출할 수 있는 텍스트 상자에서 전송되는 Request를 살펴보면, id 파라미터에 입력한 값을 넣고 전송하는것을 확인할 수 있다.
데이터는 사용자 대한 정보를 제공하기 때문에 사용자 자격증명, 일반적으로 애플리케이션을 사용하는 사용자인 경우 암호를 얻으려고 할것이다. 공격자는 더 많은 정보를 얻을려고 할것이다.
소스 코드에서 확인하였듯이, Medium level에서처럼 제한이나 필터링이 수행되지 않고 주석 기호로 쉽게 우회할 수 있는 LIMIT 절만 설정되어 있는 것을 발견확인하였다. 우선 응답에 반환되는 열 수를 확인하기 위해 오류가 발생하지 않을 때 까지 다양한 수의 Payload를 제출 한다. [그림 7]은 응답에 2개의 열이 반환되었음을 알려준다.
1' UNION SELECT NULL, NULL# |
이제 열 데이터 유형을 확인해 보겠다. 우리는 사용자 이름/(해시된) 비밀번호 데이터를 검색하고 있는데, 이는 문자열 형식으로 저장되어 있을 가능성이 높다. 원하는 데이터를 검색할 때 활용할 수 있도록 문자열 데이터를 반환하는 열이 하나 이상 있어야 한다. 사용자 이름과 비밀번호의 정보를 해당 열에 연결할 수 있으므로 열 하나만 있으면 충분하다.
이를 위해 페이로드를 제출하고 첫 번째, 두 번째 또는 두 Payload 모두에 문자열 값을 배치하여 오류가 없는 경우를 확인한다. 다행히도 [그림 8]과 같이 두 열 모두 문자열 데이터를 보유하고 있다.
1' UNION SELECT 'a', 'a'# |
이제 2개의 문자열 열을 반환하는 쿼리를 구성할 수 있다는 것을 알게 되었다. 데이터베이스에 대한 정보를 더 많이 수집하고 테이블 목록부터 시작해 보겠다.
1' UNION SELECT schema_name, NULL FROM information_schema.schemata # |
성공적으로 테이블 이름을 확인하였고, 이제 User 테이블의 구조를 확인해 보자.
1' UNION SELECT column_name, NULL FROM information_schema.columns WHERE table_name= 'users' # |
마지막으로 information_schema.columns 테이블에서 추출한 users 테이블의 열 이름 목록을 확인 한 후 사용자 이름과 비밀번호를 확인해 보자.
1' UNION SELECT user, password FROM users # |
DVWA : SQL Injection - Impossible level (0) | 2025.01.14 |
---|---|
DVWA : SQL Injection - Medium level (0) | 2025.01.06 |
DVWA : SQL Injection - Low level (0) | 2025.01.05 |
DVWA : File Upload - Impossible level (0) | 2025.01.05 |
DVWA : File Upload - High level (0) | 2025.01.05 |