STUDY.md
  • 웹 해킹(Web Hacking). 쿠키 & 세션
    2024년 07월 01일 20시 48분 01초에 업로드 된 글입니다.
    작성자: 방세연

     

     

     

     🍪쿠키 

    웹 서버에서 클라이언트를 기억하기 위한 단위.

    클라이언트는 서버에 요청을 보낼 때마다 쿠키를 포함하고, 서버는 해당 쿠키를 통해 클라이언트를 식별함.

    (Key, Value로 이루어짐)

     

    HTTP 프로토콜에서는 Connectionless, Stateless의 특징을 가지고 있는데,

    쿠키는 이 특성을 가진 HTTP의 상태를 유지하게 해줌 (기억)

     

    Connectionless 하나의 요청에 하나의 응답 후 연결 종료
    ( 연속적 X. 매번 끊어져 다시 새로운 연결)
    Stateless 통신이 끝난 후 상태 정보를 저장하지 않는 것.

     

    서버에서 쿠키를 설정하는 방법

    HTTP 응답 중 헤더에 쿠키 설정 헤더(Set-Cookie)를 추가한다.

    from flask import Flask, make_response
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        response = make_response('쿠키가 설정되었습니다!')
        response.set_cookie('cookieName', 'cookieValue', max_age=900)
        return response
    
    if __name__ == '__main__':
        app.run(debug=True)

     

     

    클라이언트에서 쿠키를 설정하는 방법

    1. 개발자 도구- 콘솔에서 document.cookie를 치면 쿠키 정보가 나온다.

     

    2. 로그인 창-검색-네트워크에서 응답 헤더를 확인해 set-cookie를 확인한다.

     

     

    3. 개발자 도구-애플리케이션 창에서 Session id를 확인할 수 있다.

     

     

    세션 아이디를 삭제하면 로그인이 풀린다.

    세션 아이디 값을 추가해서 입력하면 다시 로그인이 된다.

     

    Session Hijacking
    세션에 해당하는 이용자의 인증 상태를 훔치는 것

     

     

    Modern Storage APIs

    쿠키가 필요없는 요청을 보낼 때 리소스가 낭비되는 단점을 보완하기 위해 나온 방식

     

    💡웹 해킹
    만약 악의적인 클라이언트가 쿠키 정보를 위조해 서버에 요청을 보낸다면,
    타 이용자로 사칭해 정보를 탈취할 수 있는 문제가 발생할 수도 있다.

     

     

    Session / Session ID

    KEY : 유추할 수 없는 랜덤한 문자열

    브라우저는 키를 쿠키에 저장하고 ->

    이후에 HTTP 요청을 보낼 때 키를 사용한다.->

    서버는 키에 해당하는 데이터를 가져와 인증 상태를 확인할 수 있다.->

     

     

    Cookie 데이터 자체를 이용자가 저장 (admin, guset)
    Session 서버에 저장 (KEY: nhmuifinwkernejrwbwkja)

     

     

    웹 서비스 분석

    GET 입력 페이지를 제공
    POST 이용자의 입력 값을 변숫값과 비교함

     

    => username 변수가 요청에 포함된 쿠키에 의해 결정되면(클라이언트 요청),

    공격자는 클라이언트 요청을 조작할 수 있기 때문에 문제가 발생한다.

     

     


    Same Origin Policy (SOP)

    만약 악의적인 페이지에 접속했을 때.

    => 사용자는 쿠키 정보를 HTTP 요청에 포함시킨다.

    => 악의적인 웹 클라이언트 권한이 HTTP 응답 정보를 획득한다.

     

    SOP는 가져온 데이터를 악의적인 페이지에서 읽을 수 없도록 보안을 강화하는 것.

     

    프로토콜 (Protocol) https:// , http://
    포트 (Port) 1234
    호스트 (Host) spacefriend.tistory.com
       

     

     

     

     

     

    #1. Same Origin

    sameNewWindow = window.open('https://dreamhack.io/lecture');
    
    Window {window: Window, self: Window, document: document, name: '', location: Location, …}
    console.log(sameNewWindow.location.href);
    
    5fd04f2.js:2 https://dreamhack.io/lecture

     

     

    #2. Cross Origin

    crossNewWindow = window.open('https://spacefriend.tistory.com');
    
    Window {window: Window, self: Window, document: document, name: '', location: Location, …}
    console.log(crossNewWindow.location.href);
    
    VM617:1 Uncaught DOMException: Failed to read a named property 'href' from 'Location': Blocked a frame with origin "https://dreamhack.io" from accessing a cross-origin frame.
        at <anonymous>:1:37

     

    데이터를 쓰는 것은 응답하여 새로운 창을 띄어주었지만, crossNewWindow 데이터를 읽을 때는 오류가 나타난다.

     

     

    CORS (교차 출처 리소스 공유)

    1. SOP에 <img>, <style>, <script> 등의 태그가 영향을 받지 않는다. 
    2. 같은 페이지지만 오리진이 다를 경우 SOP에 차단되지 않아야 한다.
    => 자원을 공유하기 위해 CORS를 사용한다.

    서버에서 응답할 때
    Acess-Control-Allow-Origin: https://spacefriend.tistory.com
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Aceess-Control-Allow-Credentials: true
    Aceess-Control-Allow-Headers: Content-Type​

    발신측은 CORS 헤더를 설정하고 수신측에 요청(질의)한다.

    수신측에서 헤더를 구분해 정해진 규칙에 맞게 데이터를 수집하고 응답한다.
    => 그 후 브라우저가 수신측, 발신측이 일치하는지 확인하고 HTTP 요청을 보낸다.

     

    JSON with Padding (JSONP)
    마찬가지로 SOP의 영향을 받지 않는다. 
    <script> </script>​

     

    태그로 Cross Origin 데이터를 불러온다.
    callback 함수를 이용해 Cross Origin 데이터를 자바스크립트 코드로 인식하지 않고 응답하게 한다.

     


     

     

     

     🏆  Cookie 

     

    @app.route('/')
    def index():
        username = request.cookies.get('username', None)
        if username:
            return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not admin"}')
        return render_template('index.html')


    #1. 웹 서비스 코드를 분석해 guest로 로그인 한다.
    (코드를 살펴보면 입력해줘야 하는 username이 클라이언트 요청에 의해 결정된다.
    이때, 요청은 쿠키가 포함되어있는데 이를 변조할 수 있다.)



    #2. 취약점을 이용해 guest 값을 admin으로 고친다.

     

     

     

     

     

     🏆  Description 

    @app.route('/admin')
    def admin():
        # developer's note: review below commented code and uncomment it (TODO)
    
        #session_id = request.cookies.get('sessionid', None)
        #username = session_storage[session_id]
        #if username != 'admin':
        #    return render_template('index.html')
    
        return session_storage


    #1. 웹 서비스 코드를 분석해 인덱스를 입력해준다. (/admin)
    코드를 보면 세션을 admin으로 인증하지 않고 인덱스 /admin을 입력해 페이지를 연결해도
    32자리 Hex값이 노출된다는 것을 알 수 있다. (admin if문이 주석처리가 되었기 때문이다)


    #2. 개발자 도구-쿠키에서 세션id값을 넣어주면 FLAG가 노출된다.


     

     

     

    💡스터디 참고 출처 : Dream Web Hacking

    https://dreamhack.io/lecture/roadmaps/1

     

    Web Hacking

    웹 해킹을 공부하기 위한 로드맵입니다.

    dreamhack.io

     

    댓글