kjh00n의 기록저장소

XSS 보안 및 우회 본문

어플리케이션 보안 운영

XSS 보안 및 우회

kjh00n 2025. 1. 7. 11:21

Server Side Validation

 

우회방법 및 필터링

① str_replace (필터링)

str_replace("검색할 문자열","변경 후 문자열","원본데이터");

→ 원본데이터의 특정 글자를 다른 문자로 변환시켜주는 함수

 

str_replace("a","b","$b_cont");

→ b_cont라는 내용물 안에서 a를 b로 변경하겠다

$b_cont=str_replace("<script>","","$b_cont");
글 등록중
<script>가 지워진 모습

DB와 F12에서의 내용 모두 <script>가 지워진 형태로 저장되어 있다.

 

② 대문자 사용 (우회)

→ 태그는 대소문자 상관없이 사용 가능

str_replace 함수는 대소문자를 구분하기 때문에 우회가 된 것

<script>에서 s를 대문자 S로 변경해도 우회가 되어서 실행이 된다
실행되었음


-대소문자 우회 방지 (필터링)

ireplace는 대소문자를 구분하지 않는다.

$b_cont=str_ireplace("<script>","","$b_cont");

소문자만 사용 / 대문자만 사용 / 섞어서 사용
셋 다 필터링되었다

③ 반복 입력 (우회)

<scr<script>ipt>alert("hello");</script>

필터링 후 저장되면

<script>alert("hello");</script>

으로 저장되어서 태그가 자동으로 완성되어 실행이 된다.

반복 입력이 되도록 사용
hello가 3번 출력된다

DB에 들어가면 <script>가 지워진 상태로 <script>가 자동완성 된 상태로 저장된다


③-① 필터링 코드를 반복문으로 입력 (필터링)

str_replace, str_ireplace는 한번 검색 후 한번 삭제만 가능하다.

삭제되고 나서 이후에는 신경X

 

while문 사용 ①

    while(strrpos($b_cont,"<script>",0)) {
        $b_cont=str_ireplace("<script>","","$b_cont");
    } # 글 내용에 <script> 태그가 있으면 삭제

게시글 내용에서 <script> 문자열의 위치를 찾아 그 위치가 0이 아니면 반복적으로 필터링을 수행하는 코드

→ <script> 태크의 위치가 0이면 필터링을 수행하지 않는다.

→ <script>가 0인 경우는 = <script>가 없는 경우, <script> 태그가 가장 앞에 위치한 경우

[게시글 내용에 hello<scr<script>ipt>alert("hello");</script> 이렇게 되어있으면 필터링이 되지만

<scr<script>ipt>alert("hello");</script>라고 맨 앞에 <script>가 존재하게 되면 필터링이 되지 않음]

필터링이 적용된 모습

while문 사용 ②

    while(preg_match("/<script>/i",$b_cont)) {
        $b_cont=str_ireplace("<script>","","$b_cont");
    } # 글 내용에 <script> 태그가 있으면 삭제
$b_cont에서 / /사이에 있는 문자열을 찾겠다. i는 대소문자를 구분하지 않겠다라는 의미이다.

preg_match는 정규표현식이라는 문자식을 이용하여 특정 문자열을 검색하는 함수

 

정규표현식이란?

→ 문자열 안에서 특정 데이터를 검색, 가공, 지정하기 위해 사용하는 식(문법)

→ [^(a-zA-Z0-9)] (Ex)

필터링된 모습

④ <script>에 띄어쓰기 사용해서 우회하기 (우회)

<script >alert("hello");</script>

→ <script>맨 앞에 띄어쓰기를 사용하면 우회가 안되고 맨 뒤에 띄어쓰기를 사용하면 우회가 된다.

→ 태그는 태그 안에 문자와 '>' 문자 사이에 공백이 존재해도 실행되는데 문제가 없다.

→ 태그 안에 문자와 '<' 문자 사이에 공백은 허용하지 않는다.

우회가 된 모습

④-① 공백을 포함하여 검색과 필터링을 같이 수행 (필터링)

    while(preg_match("/<script *>/i",$b_cont)) {
        $b_cont=preg_replace("/<script *>/i","","$b_cont");
    } # 글 내용에 <script> 태그가 있으면 삭제

<script *>

→ *의 앞에 문자인 공백이 있던 없던 여러개 있어도 상관없이 검색하겠다는 의미

preg_replace

→ 정규표현식으로 필터링

필터링된 모습
지금까지 사용한 우회방법을 모두 사용했음
모든 우회방법을 사용했음에도 필터링됐다(그래도 허점은 있다)

⑤ 속성 사용 / 줄바꿈 (우회)

● <script type="text/javascript">alert("hello");</script>

 

● <script

>alert("hello");</script>

띄어쓰기와 줄바꿈을 사용해서 우회
hello가 2번 출력된다

-① 필터링

    while(preg_match("/<script.*?>/is",$b_cont)) {
        $b_cont=preg_replace("/<script.*?>/is","","$b_cont");
    } # 글 내용에 <script> 태그가 있으면 삭제

.*? = 모든 데이터를 매칭(데이터가 없어도 매칭)

/is = i는 대소문자 구분 없이, s는 줄바꿈문자도 매칭

줄바꿈을 사용
모든 우회하는 방식을 필터링

⑥ 모든 데이터를 삭제

    while(preg_match("/<script.*?>.*?<\/script.*?>/is",$b_cont)) {
        $b_cont=preg_replace("/<script.*?>.*?<\/script.*?>/is","","$b_cont");
    } # 글 내용에 <script> 태그가 있으면 삭제

데이터를 싹 다 지우고 싶다

내용에 모든 데이터가 삭제되어서 저장된다

⑦ htmlspecialchars (필터링)

htmlspecialchars(원본데이터);

→ html 인코딩해주는 함수

→ html에서 사용하는 메타 문자들을 전부 일반 문자로 변환

→ 태그로 입력한 공격 코드가 태그로 인식 안되고 일반 문자로 인식된다.

→ 다른 태그들도 못 쓰게 되서 잘 사용하지 않음

    $b_cont=htmlspecialchars($b_cont);

스크립트 태그가 그냥 문자열로 인식이 되버림
DB에는 저렇게 저장된다.

⑧ strip_tags (필터링)

strip_tags(원본데이터,태그);

→ 지정한 태그를 제외한 나머지 태그들을 삭제하는 함수

→ 관리자가 허용하는 태그만 사용하고 나머지 태그들은 사용 불가능

    $b_cont=strip_tags($b_cont,"<a><img><h1>"); // 허용 태그만 허용하도록 처리

여러가지 태그를 사용
허용된 <a>태그와 <h1>태그만 정상작동


세션 ID가 발급되는 것을 막기

23번 게시물 접근하면 Session ID가 출력됨
특정 게시물을 접속하면 해커쪽에서 클라이언트의 Session ID 탈취가 가능

systemctl restart httpd

리눅스를 껐다가 다시 켜기

그러면 더이상 Session ID를 가져오지 않는다
하지만 설정 이후에 클라이언트가 특정 게시물에 접근을 해도 Session ID 탈취가 불가능하다

자바스크립트가 더 이상 접근하지 못하도록 막는것이다


세션 ID 없애고 재발급

setcookie("설정할 쿠키 이름","설정할 값(랜덤)","시간(세션아이디 유효시간)","경로","WEB page 주소","옵션");

PHPSESSID라는 쿠키를 지울 것이다

        setcookie("PHPSESSID","",time()-3600,"/");

session id가 출력되게 설정했음

logout.php

<?php

    session_start();
    // session_regenerate_id(); # 기존 세션ID는 두고 값만 바꾼 것
    if ($_SESSION["user_id"]){
        session_destroy();
        setcookie("PHPSESSID","",time()-3600,"/"); # 기존 세션ID 자체를 삭제
        echo "<script>
        alert('로그아웃 되었습니다.');
        location.replace('../index.php');
        </script>";
    } else {
        echo "<script>
        alert('로그인 후 이용해 주세요.');
        history.back();
        </script>";
    }
    
?>

로그아웃을 하면 기존에 사용하던 세션ID를 지우고 세션ID를 새로 발급되게 설정


Client Side Validation

XSS 보안 - Client 보안

 

'어플리케이션 보안 운영' 카테고리의 다른 글

SQL Injection  (1) 2025.01.08
CSRF  (0) 2025.01.07
XSS  (0) 2025.01.06
WEB Session Attack  (0) 2025.01.06
WEB 인증 공격  (0) 2025.01.03