상세 컨텐츠

본문 제목

DVWA : CSRF - Medium level

Vulnerability Assessment/Web Application

by DarkSoul.Story 2025. 1. 1. 15:45

본문

반응형
이 문서에 포함된 어떠한 내용도 불법적이거나 비윤리적인 목적으로 보안 도구나 방법론을 사용하도록 가르치거나 장려하지 않습니다. 항상 책임감 있는 태도로 행동하세요. 여기에 설명된 도구나 기법을 사용하기 전에 개인 테스트 환경 또는 허가를 받았는지 확인하세요.

 

[ 환경 ]

DVWA v1.9
Burp Suite Community Edition v2024.11.2

 

1.  Source code analysis

[그림 1] Medium level Source code

요청 출처 검증

if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
  • $_SERVER'HTTP_REFERER' ] : 요청이 발생한 페이지의 URL을 나타낸다.
  • $_SERVER'SERVER_NAME' ] : 현재 서버의 호스트 이름을 반환한다.
  • stripos(  ) HTTP_REFERER에 현재 서버 이름( SERVER_NAME )이 포함되어 있는지 확인한다. 결과가 false가 아니면 같은 서버에서 요청된 것으로 간주하고, 외부에서 발생한 요청은 신뢰하지 않으므로 차단한다.

사용자 입력값 가져오기

$pass_new  = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];

 

  • password_new: 사용자가 입력한 새 비밀번호
  • password_conf: 새 비밀번호 확인 입력값

비밀번호 일치 여부 확인

if( $pass_new == $pass_conf ) {
  • 새 비밀번호($pass_new)와 확인 입력값($pass_conf)이 동일한지 확인하고, 비밀번호가 일치하면 데이터베이스에 저장하는 작업을 진행한다.
  • 일치하지 않으면 아래의 else 블록으로 넘어가 오류 메시지를 출력한다.

새 비밀번호 처리

$pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass_new = md5( $pass_new );

 

  • mysqli_real_escape_string( ) 함수를 이용하여 SQL 인젝션(SQL Injection)을 방지하기 위해 데이터베이스 쿼리에 안전하도록 입력값을 이스케이프 처리한다. ( $GLOBALS["___mysqli_ston"]는 MySQL 연결 객체)
  • 입력된 새 비밀번호를 md5 해시 알고리즘으로 암호화하고,암호화된 비밀번호를 데이터베이스에 저장한다.
  • md5는 더 이상 안전하지 않은 해시 알고리즘으로, rainbow table 공격 및 GPU 기반 크래킹 공격에 취약하다.

데이터베이스 업데이트

$current_user = dvwaCurrentUser();
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . $current_user . "';";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
  • dvwaCurrentUser( ) 함수는 현재 로그인된 사용자 이름을 반환한다.
  • UPDATE 쿼리를 생성하여 현재 사용자의 비밀번호를 새 비밀번호($pass_new)로 업데이트한다.
  • mysqli_query( )를 통해 쿼리를 실행하고, 실행 중 오류가 발생하면 die( ) 로 오류 메시지를 출력하고 실행을 중단한다.

신뢰하지 않은 요청 차단

else {
     echo "<pre>That request didn't look correct.</pre>";
}
  • 요청 출처가 신뢰할 수 없는 경우, "That request didn't look correct." 메시지를 출력한다. 이는 HTTP_REFERER 검사를 통과하지 못한 요청에 대한 대응이다.

데이터베이스 연결 종료

((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
  • MySQL 연결을 종료한다. mysqli_close()로 연결을 닫으며, 종료가 실패하면 false를 반환한다.

 

2. Practical exercises

소스코드를 살펴보면 요청이 신뢰할 수 있는 출처(이전 페이지)라고 가정하고,  HTTP Referer헤더를 사용하여 동일한 서버에서 온 요청인지 확인한다. HTTP Referer는 HTTP 요청 헤더의 한 종류로, 요청이 발생한 출처(이전 페이지)의 URL을 서버에 전달한다. 이 정보는 사용자가 특정 웹페이지나 리소스에 어떻게 도달했는지를 나타내며, 서버나 애플리케이션에서 이를 활용하여 다양한 기능을 구현할 수 있다. Low level에서 사용한 방법을 사용하면, [그림 2]와 같이 더 이상 작동하지 않는것을 확인할 수 있다.

[그림 2] Low level 방식으로 CERF 공격 시 차단

 

 Request를 Burp Suite로 Intercept 하여 정상적인 요청과 Low level에서 사용 요청을 한번 비교해보자. [그림 3]은 정상적인 비밀번호 변경 요청할 때 Request를 Burp Suite로 Intercept한 내용이다. 자세히 살펴보면, HTTP Referer헤더가 존재하는것을 확인할 수 있다.

[그림 3] 정상적인 비밀번호 변경 요청

 

[그림 4]는 Low level에서 사용한 방법으로 비밀번호 변경 요청한 내용으로, 여기서는 HTTP Referer헤더가 존재하지 않는 것을 확인할 수 있다. 이러한 차이로 인해 HTTP Referer를 이용하여 동일한 서버에서 온 요청 아니라 판단하여 CSRF 공격을 차단을 하는것이다.

[그림 4] Low level에서 사용한 방법으로 비밀번호 변경 요청

 

그러나 HTTP Referer헤더는 공격자가 쉽게 조작할 수 있다. 이를 통해 공격자는 악성 웹사이트를 만들거나 이 스크립트로 요청하는 URL을 조작하여 사용자의 브라우저를 속여 사용자 모르게 비밀번호 변경과 같은 원치 않는 작업을 대신 수행하도록 할 수 있다.

 

여기서는 Reflected XSS를 이용하여, 비밀번호를 변경하고자 한다. 아래와 같은 XSS 스크립트로 악성 비밀번호 변경 요청을 트리거할 수 있다.

<Script> var xmlHttp = new XMLHttpRequest(); var url = "http://192.168.107.144/DVWA/vulnerabilities/csrf/?password_new=test111&password_conf=test111&Change=Change"; xmlHttp.open("GET", url, false); xmlHttp.send(null); </Script>

[그림 5] Reflected  XSS를 이용하여 CSRF 공격

 

 

[그림 5] Request를 Burp Suite로 Intercept하면, [그림 6]과 같다. 

[그림 6] Reflected  XSS

1차 GET 요청에 의해 HTTP_REFERER 소스를 가져오면 모든 자바스크립트 코드가 수락되고, 리디렉션되면서 2차 GET 요청에 의해 비밀번호가 변경된다. HTTP_REFERER를 이용하여 요청이 발생한 페이지의 URL과 현재 서버의 호스트 이름만으로 출처가 동일한지 여부만 확인하면 Reflected  XSS 공격을 사용하여 리디렉션될 수 있으므로 요청이 유효한지 확신할 수 없다.

[그림 7] 리디렉션 요청에 의해 변경된 비밀번호

 

반응형

관련글 더보기