이 문서에 포함된 어떠한 내용도 불법적이거나 비윤리적인 목적으로 보안 도구나 방법론을 사용하도록 가르치거나 장려하지 않습니다. 항상 책임감 있는 태도로 행동하세요. 여기에 설명된 도구나 기법을 사용하기 전에 개인 테스트 환경 또는 허가를 받았는지 확인하세요. |
[ 환경 ]
DVWA | v1.9 |
Burp Suite | Community Edition v2024.11.2 |
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
$user = $_GET[ 'username' ];
$user = stripslashes( $user );
$user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass = $_GET[ 'password' ];
$pass = stripslashes( $pass );
$pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass = md5( $pass );
$query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
if( $result && mysqli_num_rows( $result ) == 1 ) {
$row = mysqli_fetch_assoc( $result );
$avatar = $row["avatar"];
echo "<p>Welcome to the password protected area {$user}</p>";
echo "<img src=\"{$avatar}\" />";
}
else {
sleep( rand( 0, 3 ) );
echo "<pre><br />Username and/or password incorrect.</pre>";
generateSessionToken();
앞서 소스코드를 살펴보았을때, '사이트 간 요청 위조 방지(CSRF, Cross-Site Request Forgery) 토큰'이 사용되었다는 것을 확인하였다. 이 보호 기능이 Brute Force 공격을 막을 수 있다는 오해가 오래전부터 있었으나, 이는 사실이 아니다. High level에서도 로그인 실패 시 무작위로 0~3초의 지연을 시키는 것을 확인하였다. 이는 타이밍 예측(timing prediction)에 혼란을 주기 위한 것이다.
이전 Level에서와 동일하게 로그인 페이지에서 Username과 Password를 입력한 다음 로그인 버튼을 클릭 후 Burp Suite로 Request를 Intercept 하여 확인해 보면 GET으로 username Parameter와 password Parameter에 앞서 로그인 페이지에서 입력한 test가 들어가며, 다른 점은 user_token Parameter가 추가된것을 확인할 수 있다.
로그인 페이지의 소스코드를 살펴보면 로그인 시 user_token이라는 추가 값이 제출되고 있음을 알 수 있다.
user_token은 양식과 함께 제출되는 숨겨진 필드로, 이 필드를 삭제한 다음 양식을 제출하고 어떤 일이 발생하는지 확인해 보자.
user_token Prameter를 제거한 다음 전송한 결과 [그림 4]와 같은 오류 메시지를 확인할 수 있다. 이는 반듯이 user_token 값이 있어야 한다는 것을 알 수 있다.
로그인 페이지의 소스코드를 다시 살펴보면 user_token 값이 변경된 것을 확인할 수 있으며, 페이지를 새로 고침 할 때마다 값도 변경되는 것을 확인할 수 있다. 이를 CSRF토큰이라고 하며, 서버가 수신하는 요청이 악의적인 제3자가 아닌 올바른 출처에서 온 것임을 증명하는 데 사용된다. 따라서, 모든 로그인 요청에 대해 유효한 사용자 토큰을 제공해야 하지만 여기에 문제가 있다. 유효한 토큰의 값은 페이지를 로드할 때마다 변경된다는 점이다.
admin에 대한 패스워드를 확인하기 위해 로그인 페이지에서 UserName에 admin을 입력하고, Password에 test를 입력 다음 로그인 버튼을 클릭한다. 전송되는 Request를 Burp Suite로 Intercept 후 이전 Level에서와 동일하게 마우스 오른쪽 클릭 > Send to Intruder를 클릭하여, Intercept 한 Request의 내용을 Intruder로 보낸다.
Intruder의 Positions탭에서 공격 유형은 정의된 각 위치에 대해 서로 다른 페이로드 세트를 통해 반복하는 Pitchfork를 선택 후 Payload가 삽입될 위치를 선택 후 Add$를 이용하여 Payload 삽입 위치를 설정한다. Payload가 삽입될 위치는 password Parameter와 user_token Parameter이다.
다음으로 password Parameter에 삽입할 Payload Set 1번을 설정한다. 여기서 Patload typem은 Simple list로 지정하고 이전 Level에서와 같은 방식으로 Payload 정보를 입력한다.
user_token Parameter에 삽입할 Payload Set 2번은 Recursive grep으로 설정한다. Recursive Grep은 기본적으로 "Match and Replace" 또는 "Grep - Match" 기능을 활용하여 요청 또는 응답에서 특정 패턴을 재귀적으로 검색하고 처리하는 과정이다. 이를 통해 자동화된 테스트와 패턴 검색을 효율적으로 수행할 수 있다.
여러 요청 스레드에서 Recursive grep Payload를 사용하면, 여러 요청 스레드를 사용할 수 없기 때문에 사용자 지정 Resource pool 을 설정한다. 사용자 지정 Resource pool은 Intruder > Resource pool > Create new resource pool에서 설정 가능하며, 최대 동시 요청 한도 (Maximum concurrent request)를 1로 설정한다.
user_token 은 숨겨져 있었기 때문에 웹 페이지에서 추출하여야 하며, Burp는 로그인할 때마다 해당 위치에서 값을 추출하여 무차별 대입 공격을 수행해야 하기 때문에, Intruder > Settings > Grep - Extract를 설정한다. Grep - Extract는 요청 및 응답의 특정 부분에서 데이터를 추출하여 Intruder의 페이로드에 동적으로 활용할 수 있도록 설정하는 기능으로 주로 CSRF 토큰, 세션 ID, 또는 기타 동적 값을 다음 요청에서 재사용하거나 테스트 자동화를 위해 사용된다. Grep - Extract에서 Extract the following items from responses를 선택하고, Add를 클릭한다.
Add를 클릭하면 세부 설정할 수 있는 창이 나타나며 여기서 user_token을 캡처해야 하기 때문에 Refetch response를 클릭하여, Response 내용을 확인한다. 이후 Response에서 확인해야 할 값은 user_token 값으로 Start after expression값을 user_token의 value=' 를 입력하고, user_token 값의 최대 길이 32를 End at fixed length에 입력한다.
공격을 수행할 때 Burp가 리디렉션을 처리하는 방법을 제어하며, 공격의 목적을 달성하기 위해 리디렉션을 따라야 하는 경우가 종종 있다. 예를 들어 비밀번호 추측 공격에서는 리디렉션을 따라야만 각 시도의 결과가 표시될 수 있으며, 퍼징 공격의 경우 초기 리디렉션 응답 후 반환되는 오류 메시지에만 관련 피드백이 표시될 수 있다. 이를 위해 Reditections 기능을 이용하여, 리다이렉션 처리 방식을 제어한다. 여기서는 Follow Redirections 옵션을 Always로 설정한다.
Follow Redirections 옵션은 4가지가 존재하며, 각각 다음과 같이 동작한다.
옵션 | 동작 | 사용 사례 |
Never | 리다이렉션을 절대 따르지 않음 | 수동으로 리다이렉션을 분석하거나 자동 요청을 원치 않을 때 |
On-site only | 동일한 사이트(호스트/도메인)로의 리다이렉션만 따름 | 내부 네트워크 또는 특정 도메인 내에서 테스트할 때 |
In-scope only | Burp 스코프 내 URL로의 리다이렉션만 따름 | 특정 테스트 범위를 초과하지 않도록 요청을 제한할 때 |
Always | 모든 리다이렉션을 따름(스코프 외 URL 포함) | 리다이렉션 체인을 완전히 추적하거나 테스트가 모든 대상에 대해 전면적으로 이루어져야 할 때 |
Process cookies in redirections 은 리디렉션 대상을 따라갈 때 리디렉션 응답에 설정된 모든 쿠키를 다시 제출할 때 사용한다. 예를 들어 로그인 결과를 나타내는 페이지로 항상 리디렉션을 반환하는 무차별 로그인 챌린지를 시도하고 각 로그인 시도에 대한 응답으로 새 세션이 생성되는 경우 이 기능이 필요할 수 있다.
다음으로 확인을 조금 더 편하게 하기 위해 Grep - Match를 설정 한다. Grep - Match 기능은 HTTP 요청 및 응답에서 특정 텍스트나 패턴을 검색하여 매칭 결과를 출력하는 도구로 반복적인 요청/응답 분석을 간소화하고, 특정 키워드나 패턴을 효과적으로 추적하는 데 강력한 도구이다. Grep - Match에서 Responses matching these expressions를 선택하고 앞서 소스코드에서 확인한 로그인 성공 시 출력되는 메시지 일부인 Welcome 지정 한다. Responses matching these expressions는 응답의 특정 텍스트나 정규 표현식(Regex)을 기반으로 결과를 필터링하는 기능을 제공한다.
모든 설정이 완료 후 Start attack를 클릭하면 설정한 Payload Set에 Brute Force 공격을 진행한다. 공격이 완료되면 Grep - Match에서 설정한 Welcome 탭으로 정렬하면, 1로 표시된 내용을 확인할 수 있다. 1로 표시된 내용이 admin의 Password인것이다.
DVWA : Command Injection - Low level (0) | 2024.12.29 |
---|---|
DVWA : Brute Force - Impossible level (0) | 2024.12.29 |
DVWA : Brute Force - Medium level (0) | 2024.12.28 |
DVWA : Brute Force - Low level (0) | 2024.12.28 |
DVWA (Damn Vulnerable Web Application) 초기 세팅 하기 (1) | 2024.12.28 |