XSS Bypass scenario

DATE : 2024/1/11 ~ 12

scenario#1 : script word filtering

$script = $_GET['script'];
    
if ($script == 'script') { 
    echo "you are hacker";
} else {
    echo $script;
}

만약 script 단어를 필터링하고 있는 상황이라면

INPUT > script를 입력했을 때

you are hacker 문구가 나오게 될 것이다. 하지만 여기엔 큰 함정이 숨어있다..!

위에서 본 코드처럼 black list 기반의 필터링은 우회 가능성이 존재하기 때문에 그리 좋은 방법은 못 된다.

만약 사용자가 대소문자를 섞어 script 단어를 만들게 되면

성공적으로 우회를 할 수 있기 때문이다. 😏

(대문자로만 작성해도 가능)

$script = $_GET['script'];

if(preg_match('/script/',$script)) { 
    echo "you are hacker";
} else {
    echo $script;
}

코드를 조금 수정해 preg_match를 사용한다고 해도 i option을 설정하지 않는 이상

대문자로 우회가 가능하다.

scenario#2 : replace script word

$script = $_GET['script'];
    
$script = str_replace('script','',$script,);

echo $script;

이번엔 script 단어 차단이 아닌 replace다.

사용자가 script 라는 단어를 입력하게 되면

공백으로 바꿔 버려 아무런 결과도 나오지 않게 된다.

하지만 이런 경우도 대문자를 사용하면 우회할 수 있으며

대문자를 막아둔다 하더라도 script 단어를 겹쳐 쓰면

안에 작성된 script가 제거되면서 밖에서 script를 감싸고 있던 단어들이 새로운 script를 만들어 낸다.

scenario#3 : length limitation

$script = $_GET['script'];
    
$script = substr($script,0,35);

echo $script;

만약 사용자가 입력할 수 있는 길이가 제한되는 상황이라면 어떻게 스크립트를 삽입할 수 있을까?

cookie를 팝업 창에 띄우라는 짧은 내용조차

길이 제한으로 인해 스크립트가 중간에 잘리는 걸 볼 수 있다.

이럴 땐, 실행하고자 하는 스크립트를 다른 파일로 작성해둔 뒤에

cookie.php
<?php
    echo "<script>alert(document.cookie);</script>";
?>

src 속성을 활용해 외부의 다른 파일을 불러오게 만들면

길이가 제한된다 하더라도 스크립트가 잘리지 않는 선에서 다른 파일을 불러와

성공적으로 스크립트를 실행할 수 있게 된다.

다른 제한이 적용되는 상황에서도 활용할 수 있는 방법이기 때문에

외부에 있는, 혹은 다른 경로의 파일(or 사이트)을 가져옴으로써 우회 하는 방법이 존재한다는 걸 기억하자.

scenario#4 : replace script word 2

$script = $_GET['script'];
    
$result = preg_replace("/script/","xcript",$script);

echo $result;

이번에 살펴볼 시나리오는 script 단어를 xcript로 바꿔 버리는 경우,

즉 script tag가 완전 다른 단어로 치환되는 경우를 다루고 있다.

만약 사용자가 script라는 단어를 사용하게 된다면

preg_replace() 함수가 이를 발견하고 xcript로 바꿔 버리기 때문에

응답 Packet 속에서 <xcript> 라는 태그를 볼 수 있을 것이다.

이런 경우에는 다른 태그를 사용할 수 있다면

이와 같이 <img> tag를 넣어 의도적으로 에러를 발생 시킨 뒤, onerror event handler

실행 시키고자 하는 스크립트를 작성하며 된다.

scenario#5 : block angle bracket

$script = $_GET['script'];
    
if (preg_match("/>|</",$script)) {
    echo "you are hacker!!";
}
else {
echo "<script>
    document.write('입력된 코드 : '+'$script');
</script>";
}

마지막으로 살펴볼 시나리오는 서버에서 JS로 HTML element를 다루는 상황에서

angle bracket이 차단되는 경우이다.

사용자가 < > 기호를 입력하게 되면 if문에 걸리기 때문에

문구가 나오는 외에 스크립트 실행은 불가능하다.

하지만 이번 시나리오에서는 말 그대로 < > 기호만 차단하고 있지, 따옴표까지 차단 되는 상황은 아니다.

또한, 서버에서 이미 <script> tag를 작성해둔 상태에서 사용자의 입력 값을 tag 안으로 가져가기 때문에

우리는 document.write() 함수에서 빠져나와 스크립트가 실행될 수 있는 형태로 값을 삽입하면 된다.

이와 같이 사용자가 태그 없이 스크립트만 적어 넣어도

서버에 작성되어 있는 <script> tag가 있기 때문에

결과적으로 alert()를 실행할 수 있는 코드가 만들어지게 되는 것!

이처럼 <script> tag가 이미 사용되고 있고, 사용자의 입력 값이 그 안으로 들어가는 구조라면

태그를 사용할 필요 없이 XSS 공격이 가능하다.

이보다 더 다양한 공격 시나리오가 존재하지만 쉽게 마주칠 수 있는 시나리오 위주로 살펴보았다.

Stored, Reflected, DOM Based XSS는 각 공격 방식 별로 대표적인 공격 시나리오가 더 존재하는 데

그 부분은 Port swigger 사이트를 활용하면 좋을 듯하다!

Last updated