먼저 low때와 같이 Message에 script 코드를 입력해보았다.
아래처럼 <script>가 필터링이 되어서 나오는 것을 보고 또 str_replace로 <script>를 공백처리하나 의심했다.
그래서 str_replace를 우회해보았다.
이 역시 필터링 되었다.
그래서 혹시나 하는 마음에 Name 부분에 코드를 입력해보았는데
아래처럼 성공적으로 Stored XSS가 성공한 것을 볼 수 있었다.
이유를 알기 위해 아래 서버 코드를 분석해보았다.
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = str_replace( '<script>', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$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>' );
//mysql_close();
}
?>
message변수에 있는 htmlspecialchars <- 이건 XSS를 방어하기 위한 함수인데 str_replace와 달리 여러번 필터링 해주고 모든 태그들을 필터링 해준다.
그래서 message에서 필터링이 되었던 것이다.
하지만 name부분을 보면 str_replace로 되어 있기 때문에 기존의 방법으로 우회할 수 있었다.
사용자의 입장에서 저 게시물을 클릭하게 되면 사용자의 쿠키를 이용해 코드가 실행된다.