김승현

[part 6]누구나 쉽게 따라 하며 배우는 웹 해킹 첫걸음 - 공격기술2 : 다른 사용자를 공격하는 XSS(Cross Site Scripting) 본문

book_summary/web

[part 6]누구나 쉽게 따라 하며 배우는 웹 해킹 첫걸음 - 공격기술2 : 다른 사용자를 공격하는 XSS(Cross Site Scripting)

kshind 2023. 5. 2. 15:04

xss란? cross site scripting의 줄임말로 공격자가 상대방의 브라우저에 스크립트가 실행되도록 해 사용자의 세션을 가로채거나, 웹사이트를 변조하거나, 악의적 콘텐츠를 삽입하거나, 피싱 공격을 진행하는 것

 

Cross site scripting인데 xss인 이유 - 웹 프론트엔드에서 디자인을 담당하는 언어가 이미 css라는 이름을 가지고 있기 때문

 

데이터베이스를 대상으로 한 공격인 sqli와 다르게 사용자들을 대상으로 하는 공격임

 

xss의 종류 

xss에는 크게 Reflected XSS, Stored XSS, DOM Based XSS가 있다.

 

Reflected XSS

반사라는 뜻을 가진 reflected를 사용하는 것처럼 xss공격 구문이 포함된 URI로 사용자가 접근을 해야지만 발생하는 xss

피싱 메일을 사용하는 등 악의적인 URI를 접속하도록 유도하여 사용함

 

Stored XSS

공격자가 웹서비스에 xss 공격 구문이 들어간 무엇인가를 게시하고, 이를 사용자가 읽게 되면 발생하는 xss

 

DOM Based XSS

js로 URI의 정보를 가져와서 포론트엔드 소스코드를 수정하는 게 있다면 해당 xss가 발생할 수 있음.

(서버를 고치는 reflected, stored와 다르게 서버를 거치지 않고 발생함)

 

xss 방어 방법

HTML Entity인코딩

공격 구문에 사용될 수 있는 특수문자들을 일반문자들로 바꾸는 방법 

               <변경 예시>

문자 HTML Entity
공백 &nbsp;
< &lt;
> &gt;
' &apos;
" &quot;
& &amp;

특수문자를 일반문자처러 사용하려는 목적으로 만들어진 HTML Entity를 이용해서 모두 일반문자로 만들어서

공격구문을 사용할 수 없게 만듦

php에서 htmlentities함수를 사용해서 이용 가능

 

xss문제풀이

level1

적절한 이스케이프 없이 xss가 발생하는 그런 사이트를 보여줌 직접 입력하거나 URL을 수정해서 공격해보라고 한다.

ALERT()를 이용해서 경고창을 띄움으로써 다음 단계로 넘어가라고 한다.

<!doctype html>
<html>
  <head>
    <!-- Internal game scripts/styles, mostly boring stuff -->
    <script src="/static/game-frame.js"></script>
    <link rel="stylesheet" href="/static/game-frame-styles.css" />
  </head>

  <body id="level1">
    <img src="/static/logos/level1.png">
      <div>

<form action="" method="GET">
  <input id="query" name="query" value="Enter query here..."
    onfocus="this.value=''">
  <input id="button" type="submit" value="Search">
</form>

    </div>
  </body>
</html>

form 태그를 보면 GET메소드로 query라는 파라미터로 전달하는 걸 확인할 수 있음

 

<target code>

page_header = """
<!doctype html>
<html>
  <head>
    <!-- Internal game scripts/styles, mostly boring stuff -->
    <script src="/static/game-frame.js"></script>
    <link rel="stylesheet" href="/static/game-frame-styles.css" />
  </head>
 
  <body id="level1">
    <img src="/static/logos/level1.png">
      <div>
"""
 
page_footer = """
    </div>
  </body>
</html>
"""
 
main_page_markup = """
<form action="" method="GET">
  <input id="query" name="query" value="Enter query here..."
    onfocus="this.value=''">
  <input id="button" type="submit" value="Search">
</form>
"""
 
class MainPage(webapp.RequestHandler):
 
  def render_string(self, s):
    self.response.out.write(s)
 
  def get(self):
    # Disable the reflected XSS filter for demonstration purposes
    self.response.headers.add_header("X-XSS-Protection", "0")
 
    if not self.request.get('query'):
      # Show main search page
      self.render_string(page_header + main_page_markup + page_footer)
    else:
      query = self.request.get('query', '[empty]')
       
      # Our search engine broke, we found no results :-(
      message = "Sorry, no results were found for <b>" + query + "</b>."
      message += " <a href='?'>Try again</a>."
 
      # Display the results page
      self.render_string(page_header + message + page_footer)
     
    return
 
application = webapp.WSGIApplication([ ('.*', MainPage), ], debug=False)

 

<level2>

 데이터를 서버 측 및 클라이언트 측 데이터베이스에 보관하고 나중에 사용자에게 표시하기 때문에 처리할 땐 신중하게 해야 한다. 

 

1번 방법

<script>alert(1)</script>

2번 방법

<a href="javascript:alert('xss')">xss</a>

 

level3

url에 입력해서 xss 공격을 시도하는 문제이다.

 

image2를 누르면 사진이 변하고 frame#2로 변함

html을 보면 img src해서 cloud2.png임을 볼 수 있음. 다음으로 3을 눌러보자.

 

image3를 누르면 image3으로 변하고 frame#3으로 변하는 걸 볼 수 있음

이번엔 cloud3.jpg임을 알 수 있다. frame#{값}에의 값이 cloud{값} 형식으로 되는 것 같아서 url을 고쳐보겠다.