웹 CTF에서 화면만 보고 버튼을 누르다 보면 정작 단서는 CSS에 숨어 있는 경우가 있다. “Cascading the Seven Seas”를 보자마자 CSS(Cascading Style Sheets)를 의심했고, Chrome DevTools의 Sources 전체 검색으로 범위를 줄였다. 이 글은 현재 문제의 플래그나 정답을 공개하지 않고, 다른 웹 문제에도 그대로 쓸 수 있는 조사 순서만 정리한다.
첫 화면의 DOM만 펼쳐보다가 단서가 없으면 “소스에 아무것도 없다”고 착각하기 쉽다. 실제로는 인라인 <style>, 동적으로 추가된 스타일시트, @import로 연결된 파일, 가상 요소의 content 등 여러 층에 문자열이 나뉘어 있을 수 있다.
Chrome DevTools에서 Ctrl+Shift+F(macOS는 Cmd+Option+F)를 누르면 현재 페이지가 불러온 리소스 전체를 검색한다. 파일 트리를 한 개씩 여는 것보다 빠르다. 처음에는 플래그 접두사 하나만 찾기보다 아래처럼 구조를 드러내는 키워드를 번갈아 본다.
@import
content:
::before
::after
--flag
part
hidden
display: none
문자열이 여러 조각이면 검색 결과의 파일 경로와 줄 번호를 먼저 기록한다. 발견 순서대로 붙이는 게 정답 순서라는 보장은 없기 때문이다.
Sources는 로드된 파일 내용과 인라인 스크립트·스타일을 읽기 좋다. Network는 어떤 요청이 실제로 나갔는지, 리다이렉트가 있었는지, CSS가 캐시에서 왔는지 확인하는 데 낫다. 스타일 파일이 목록에 없다고 느껴지면 Network에서 CSS 필터를 걸고 새로고침한다. 응답 본문과 Initiator를 함께 보면 어느 문서가 그 파일을 불렀는지 알 수 있다.
::before와 ::after는 HTML에 텍스트 노드가 없어도 화면에 내용을 그릴 수 있다. Elements에서 선택한 요소의 Styles 또는 Computed를 보면 가상 요소 규칙이 따로 나타난다. JavaScript의 element.textContent만 출력해서는 이 문자열을 놓칠 수 있다.
.ocean::after {
content: var(--fragment);
opacity: 0;
position: absolute;
left: -9999px;
}
content는 일반적으로 가상 요소와 함께 쓰인다. 화면에서 투명하거나 뷰포트 밖으로 밀려 있어도 CSS 원문에는 값이 남는다. CSS 변수(--fragment)를 거쳐 값이 들어간다면 변수 정의 위치까지 따라가야 한다.
스타일시트 안의 @import가 다른 도메인이나 다음 단계 파일을 부르면 “cascading”이라는 제목 자체가 파일 연결 구조를 암시할 수 있다. 이때 무작정 URL을 추측하지 않고, Network의 요청 순서와 Initiator를 따라간다. 같은 파일이 중복 로드되거나 캐시 때문에 보이지 않으면 Disable cache를 켠 상태로 새로고침하는 것도 도움이 된다.
content·@import 검색::before, ::after, CSS 변수, 숨김 속성 확인이 문제에서 가장 크게 남은 건 특정 문자열이 아니라 검색 습관이었다. 파일 하나씩 눈으로 훑기보다 브라우저가 이미 로드한 범위를 먼저 검색하면, CSS와 DOM의 경계를 이용한 문제를 훨씬 빠르게 구조화할 수 있다.
입력에 따라 응답이 달라지는 웹 문제를 분석한 과정은 Boolean Blind SQLi로 한 글자씩 데이터 뽑아내기에 따로 정리했다.
| Boolean Blind SQLi로 한 글자씩 데이터 뽑아내기 — WHS 워게임 5단계 (0) | 2026.07.26 |
|---|---|
| AIxCC 우승 시스템 ATLANTIS·Crete 로컬 설치 후기 (1) | 2026.07.26 |
| 드림핵 시스템 해킹 입문 — 무료 자료만으로 시작하는 루트 (0) | 2026.07.24 |
| AFL++로 네트워크 포렌식 파서 퍼징해서 GHSA 10건 제보·게재까지 (0) | 2026.07.23 |
| ipTIME N2V 공유기 CVE-2025-55423 분석 — UPnP Relay에 박힌 Command Injection (0) | 2026.07.23 |