<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>bbang_ssn.log</title>
        <link>https://velog.io/</link>
        <description>bbang_ssn</description>
        <lastBuildDate>Fri, 31 May 2024 10:24:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>bbang_ssn.log</title>
            <url>https://velog.velcdn.com/images/halla_bbong/profile/85896d39-40b8-4065-b3ba-7d2a36625208/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. bbang_ssn.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/halla_bbong" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[백준BOJ] 16998번 - It’s a Mod, Mod, Mod, Mod World ]]></title>
            <link>https://velog.io/@halla_bbong/%EB%B0%B1%EC%A4%80BOJ-16998%EB%B2%88-Its-a-Mod-Mod-Mod-Mod-World</link>
            <guid>https://velog.io/@halla_bbong/%EB%B0%B1%EC%A4%80BOJ-16998%EB%B2%88-Its-a-Mod-Mod-Mod-Mod-World</guid>
            <pubDate>Fri, 31 May 2024 10:24:17 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p>주어진 세 개의 정수 p, q, r에 대해서<br>$$\displaystyle\sum_{i=1}^{n}{((p \cdot i) \text{ mod } q)}$$
를 계산시오!  </p>
<p>(<strong>*주의*</strong> 전체 합에는 모듈로 연산을 하지 않습니다!)  </p>
<h2 id="입력">입력</h2>
<p>W: 케이스의 수. 
($1\le W \le 10^5$)</p>
<p>각 케이스별로 p, q, n이 차례로 입력된다.
($1\le p,\ q,\ n\le 10^6$)  </p>
<hr>
<h2 id="풀이과정">풀이과정!</h2>
<p>채택된 아이디어는 ⭐로 표시했습니다!!  
주요한 흐름만 보고 싶다면 ⭐만 보면 됩니다!
.</p>
<h3 id="생각-1-수학박치기">생각 1. 수학박치기!</h3>
<p>주의사항이 왜 붙었나 생각해보면,<br>정답이 전체 합에 나머지 연산을 하는 것이었다면 
문제는 아래와 같이 단순화 될 수 있기 때문입니다.  </p>
<blockquote>
<p>$$\displaystyle (\sum_{i=1}^{n}p \cdot i)\text{ mod q} = (p \cdot {n\cdot(n-1)\over{2}})\text{ mod q}$$  </p>
</blockquote>
<p>슬프지만 다른 방법을 모색해야 할 거 같습니다...(유유,😢)<br>.
.</p>
<h3 id="생각-2-반복문박치기">생각 2. 반복문박치기!</h3>
<p>보이는 대로의 구현을 해보겠습니다!!  </p>
<pre><code class="language-cpp">result = 0;

for(int i=1; i&lt;=n; i++)
    result += p*i%q;</code></pre>
<p>무지막지한 n 값에 의하여 시간 초과가 발생할 것으로 보입니다... (유유,,😢)    </p>
<p>이제부터는 더이상 무얼 할 구석이 없으므로<br>여기서 뭘 더 어떻게 최적화를 할 수 있을까 고민해봤습니다,,,<br>.
.</p>
<h3 id="생각-3-무언가-더-수학스러운-것">생각 3. 무언가 더 수학스러운 것,</h3>
<p>반복되는 모듈러들의 합을 단숨에 계산할 수 있는 어떤 수학적 성질이 있을까?</p>
<h6 id="예를-들면-막-나머지값이-반복된다거나-하는">(예를 들면 막 나머지값이 반복된다거나 하는,,,)</h6>
<p>슬프게도 p, q, n 사이에 어떤 관계도 제시되지 않아 어려워보입니다... (유유,,,😢)  </p>
<h6 id="만약-p와-q가-서로소였다면-기약잉여계-성질을-사용할-여지가-있습니다-궁금하다면-페르마-소정리의-증명을-찾아보세요">(만약 p와 q가 서로소였다면 기약잉여계 성질을 사용할 여지가 있습니다. 궁금하다면 페르마 소정리의 증명을 찾아보세요!!)</h6>
<p>.</p>
<h3 id="생각-4-floor와-약간의-트릭🪄⭐">생각 4. floor와 약간의 트릭!🪄⭐</h3>
<p>$pi \text{ mod q }$자체를 단순화할 순 없을까?  </p>
<p>적절한 정수 n에 대해서 $pi = qn + r$로 표현할 수 있습니다.  </p>
<blockquote>
<p>해당 정수 n은  $\lfloor {pi\over q}\rfloor$로 표현이 가능하다. (조건이 중요합니다 꼭 기억하십쇼!!)
$\displaystyle pi = q\lfloor {pi\over q}\rfloor + r$<br>$\displaystyle r = pi- q\lfloor {pi\over q}\rfloor = (pi \text{ mod q})$   </p>
</blockquote>
<p>이를 이용해 본래 식을 표현하면  </p>
<blockquote>
</blockquote>
<p>$\displaystyle\sum_{i=1}^{n}{((p \cdot i) \text{ mod } q)}\ =\ \sum_{i=1}^{n}{(pi- q\lfloor {pi\over q}\rfloor)} \ =\  p\cdot {n(n+1)\over2} - q\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$</p>
<p>까지 정리가 가능합니다!    </p>
<p>여기서부터는 목표가 조금 더 구체적으로 변해,<br><strong>$\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$를 어떻게 잘 구할 수만 있다면 문제의 정답에 근접하게 될 것입니다!!!</strong></p>
<p>.</p>
<h3 id="생각-5-floor와-더-많은-트릭🪄⭐">생각 5. floor와 더 많은 트릭!🪄⭐</h3>
<p><strong>$\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$를 어떻게 다룰 수 있을까. - 첫번째 시도</strong>   </p>
<p>$pi\over q$는 다음과 같이 변형될 여지가 있습니다.</p>
<blockquote>
</blockquote>
<p>$\displaystyle{p\over q} = \lfloor{p\over q}\rfloor + r\ (0 \le r &lt; 1)$  </p>
<p>코드에 쓰기 좋은 형태로 변신시켜보자면,  </p>
<blockquote>
<p>$\displaystyle{p\over q} = \lfloor{p\over q}\rfloor + {p\mod q \over q}$</p>
</blockquote>
<pre><code class="language-cpp">p/q + p%q/q </code></pre>
<p>여기서 floor 연산의 성질 하나를 더 생각해보자면,
어떤 정수 n과 실수 a에 대해서 다음이 성립합니다!!!! </p>
<blockquote>
<p>$\lfloor n + a\rfloor = n + \lfloor a\rfloor$</p>
</blockquote>
<p>적용하자면,</p>
<blockquote>
<p>$\displaystyle\lfloor {pi\over q}\rfloor = \lfloor \lfloor {p\over q}\rfloor{} i \ +\ {p \mod q \over q}i\rfloor = \lfloor {p\over q}\rfloor i + \lfloor {p \mod q\over q} i\rfloor$</p>
</blockquote>
<h5 id="pover-q를-lfloorpover-qrfloor--p-mod-q-over-q-로-변신시켰습니다">($p\over q$를 $\lfloor{p\over q}\rfloor + {p \mod q \over q}$ 로 변신시켰습니다)</h5>
<p>이 아이디어 매우 ⭐중요⭐합니다!
이를 적용하면 여기까지도 정리 가능합니다.  </p>
<blockquote>
<p>$\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor = \sum_{i=1}^{n}(\lfloor {p\over q}\rfloor i + \lfloor {p \mod q\over q} i\rfloor) = \lfloor{p\over q}\rfloor\cdot {n(n+1)\over 2} + \sum_{i=1}^{n}\lfloor {p \mod q\over q}i\rfloor$</p>
</blockquote>
<p>이 부분을 코드로 적어보겠습니다. (코드로 작성하고 무언가 힌트를 얻었기 때문입니다)!</p>
<pre><code class="language-cpp">result = p/q * n * (n+1) / 2;

for(int i=1; i&lt;=n; i++)
    result += p%q*i/q;</code></pre>
<p>제일 처음 <a href="#%EC%83%9D%EA%B0%81-2-%EB%B0%98%EB%B3%B5%EB%AC%B8%EB%B0%95%EC%B9%98%EA%B8%B0">반복문박치기</a> 코드를 가져와 비교해보자면, </p>
<pre><code class="language-cpp">result = 0;

for(int i=1; i&lt;=n; i++)
    result += p*i%q;</code></pre>
<p>반복문 부분을 보자면, 
p에 p%q를 대입한 것과 맥이 상통합니다!
f(p, q, n) = (생략...) + f(p%q, q, n) ⭐  </p>
<h3 id="생각-6-그래프를-그리면-보이는-것⭐">생각 6. 그래프를 그리면 보이는 것⭐</h3>
<p><strong>$\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$를 어떻게 다룰 수 있을까. - 두번째 시도</strong></p>
<p>그러나 여전히 $\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$는 계산이 오래 걸리므로 시그마의 범위를 어떻게든 하지 않으면 안됩니다.  </p>
<p>$f(x) = {p\over q}x$ 그래프를 그려보겠습니다.  </p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/58a949c4-707a-431c-8201-89f4b988f7d3/image.png" alt=""></p>
<p>이때, 
$$\lfloor {pi\over q}\rfloor$$는, $f(i) = {p\over q}i$ 아래의 양수 격자점들의 갯수로,  </p>
<p>$\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$는 그래프를 포함한 그 아래의 모든 양수 격자점들의 갯수를 의미합니다.  </p>
<p>이를 조금 비틀어서 생각해보면, 해당 식을 이렇게 바꿔볼만도 합니다.<br><strong>$\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$ = (사각형 내 모든 격자점 - 포함되지 않는 격자점의 수)</strong><br>이는 바꿔말하면, 해당 그래프를 
<img src="https://velog.velcdn.com/images/halla_bbong/post/5a25c5f9-bc78-4a41-9a8f-a192eb153ddb/image.png" alt=""></p>
<p>이렇게 뒤집고 사각형 내부의 격자 중, 그래프 아래의 격자를 빼는 것으로 생각할 수 있습니다.<br>이때의 그래프 포함 그래프 아래의 격자의 수는<br>$\displaystyle\sum_{i=1}^{\lfloor {p \over q}n\rfloor}\lfloor {qi\over p}\rfloor$ 입니다.<br>그 중 정확히 그래프 위에 있는 격자점들은 제외해야합니다.<br>그러한 점의 개수는 n까지의 숫자 중 q의 배수인 것의 개수이므로, $\displaystyle\lfloor {n \over q}\rfloor$입니다.<br>따라서 다음과 같은 식을 얻을 수 있습니다.  </p>
<p><strong>$\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor = \lfloor{pn \over q}\rfloor n -(\sum_{i=1}^{\lfloor {p \over q}n\rfloor}\lfloor {qi\over p}\rfloor - \lfloor {n \over q}\rfloor)$</strong>  </p>
<p>이는 <strong>p&lt;q</strong> 인 상황에선 반복 횟수를 줄일 수 있습니다.
f(p, q, n) = (생략...) - f(q, p, p*n/q) ⭐</p>
<hr>
<h3 id="한-번-정리하고-코드를-볼까요">한 번 정리하고 코드를 볼까요?</h3>
<p>$$\displaystyle\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$$ 연산을 가진 함수를 $sum(p,\ q,\ n)$라고 정의해봅시다.<br>그러면 다음이 성립합니다!  
$$\displaystyle sum(p, q, n) = \lfloor{p\over q}\rfloor\cdot {n(n+1)\over 2}\ +\ sum(p\mod q,\ q,\ n)$$ ⭐ (p &gt; q)
$$\displaystyle sum(p, q, n) =  \lfloor{pn \over q}\rfloor n + \lfloor {n \over q}\rfloor \ -\ sum(q,\ p,\ \lfloor{pn\over q}\rfloor)$$ ⭐ (p&lt;q)</p>
<h6 id="첫번쩨에-조건이-붙은-것은-pq가-아닐-때에는-무의미한-재귀가-되기-때문입니다">(첫번쩨에 조건이 붙은 것은, p&gt;q가 아닐 때에는 무의미한 재귀가 되기 때문입니다.)</h6>
<p>오... 이 흐름은 함수가 계속 함수를 아주 재귀적으로 구현할 수 있겠습니다.</p>
<pre><code class="language-cpp">sum(p, q, n){
    ...

    if(p &gt; q)                                        
        return sum(p%q, q, n) + (p/q)*(n*(n+1)/2);
    else if(p &lt; q)
        return n * (p*n/q) + n/q - sum(q, p, p*n/q); 
}</code></pre>
<p>재귀를 하려면 더 엄밀할 필요가 있어 보입니다. </p>
<blockquote>
</blockquote>
<p>sum(p, q, n) 에서</p>
<ol>
<li>p=q인 경우를 생각해봅시다.<br>p==q일 때는 고민할 것도 없이 0입니다. p mod  q는 0이기 때문입니다.<blockquote>
</blockquote>
</li>
<li>p = 0이면 결과값은 0입니다.  <blockquote>
</blockquote>
</li>
<li>q = 1이면 결과값은 $\displaystyle p{n(n+1)\over2}$입니다.<blockquote>
</blockquote>
</li>
<li>n=0이어도 결과값은 0입니다.</li>
</ol>
<p>작은 아이디어를 하나 추가해봅니다. p와 q는 함수 내에서 서로를 나누는 데에만 사용이 됩니다.<br>따라서 각각의 수에 최대공약수를 제해버려도 결과는 같습니다.<br>함수를 사용할 때 p와 q를 공배수를 제하고 사용한다 가정한다면<br>조건을 조금 더 깔끔하게 쓸 수 있겠습니다.  </p>
<p>즉 다음과 같이 코드가 완성됩니다.</p>
<pre><code class="language-cpp">sum(p, q, n){
    if(p == 0 || n == 0)
        return 0;
    if(q == 1)
        return p*n*(n+1)/2

    if(p &gt;= q)                                        
        return sum(p%q, q, n) + (p/q)*(n*(n+1)/2);

    return n * (p*n/q) + n/q - sum(q, p, p*n/q); 
}</code></pre>
<p>문제에서 요구하는 정답이
$\displaystyle\sum_{i=1}^{n}{((p \cdot i) \text{ mod } q)}\ =\  p\cdot {n(n+1)\over2} - q\sum_{i=1}^{n}\lfloor {pi\over q}\rfloor$
였던 것을 생각해보면
정답은<code>p*n*(n+1)/2 - q*sum(p,q,n)</code>로 계산됩니다.</p>
<h2 id="정답-코드">정답 코드</h2>
<pre><code class="language-cpp">#include&lt;iostream&gt;
#include&lt;algorithm&gt;

using namespace std;

typedef unsigned long long ull;

ull gcd(ull a, ull b){
    if(a &lt; b) swap(a, b);

    if(b == 0)
        return a;

    return gcd(b, a%b);
}

ull sum(ull p, ull q, ull n){
    if(p == 0 || n == 0)
        return 0;
    if(q == 1)
        return p*n*(n+1)/2;

    if(p &gt;= q)
        return sum(p%q, q, n) + (p/q)*(n*(n+1)/2);

    return n * (p*n/q) + n/q - sum(q, p, p*n/q);
}

int main(void){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int w;
    cin&gt;&gt;w;

    while(w--){
        ull p, q, n;
        cin&gt;&gt;p&gt;&gt;q&gt;&gt;n;

        ull g = gcd(p, q);
        ull s = sum(p/g, q/g, n);

        ull result = p*n*(n+1)/2 - q*s;
        cout&lt;&lt;result&lt;&lt;&#39;\n&#39;;
    }
    return 0;
}</code></pre>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[XSS game]]></title>
            <link>https://velog.io/@halla_bbong/XSS-game</link>
            <guid>https://velog.io/@halla_bbong/XSS-game</guid>
            <pubDate>Sun, 19 May 2024 04:06:02 GMT</pubDate>
            <description><![CDATA[<h2 id="목표">목표</h2>
<p>모든 문제의 목표는 자바스크립트 코드인 alert()를 삽입, 실행시키는 것이다.  </p>
<h2 id="level-1">level 1</h2>
<h3 id="분석">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/3eb5a0ab-4467-4364-abb9-2bbe89fc0de6/image.png" alt="">  </p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/3d603ae9-7815-4c11-918f-82d9734a8840/image.png" alt=""></p>
<p>입력한 값을 띄운다.</p>
<h3 id="풀이">풀이</h3>
<p>아무런 필터링이 없으므로</p>
<pre><code class="language-html">&lt;script&gt;alert()&lt;/script&gt;</code></pre>
<p>를 입력하면 된다.</p>
<hr>
<h2 id="level-2">level 2</h2>
<h3 id="분석-1">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/68b1b004-fa7d-4dcb-9bf9-2bc26bddd7bc/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/29d1a184-cd00-4323-bdbe-1aea899c1d38/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/f3795415-6b3c-46ab-9ede-8fbc64177d27/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/374bf984-89bd-416c-8f78-bb3173966917/image.png" alt=""></p>
<p>소스코드를 들여보면</p>
<pre><code class="language-html">&lt;td valign=&quot;top&quot; class=&quot;message-container&quot;&gt; 
 &lt;!--(중략,,,)--&gt;
  &lt;blockquote&gt;
    &lt;test&gt;&lt;/test&gt;
  &lt;/blockquote&gt;
&lt;/td&gt;</code></pre>
<p>제대로 입력된 걸 알 수 있다.  </p>
<h3 id="풀이-1">풀이</h3>
<p><code>&lt;script&gt;&lt;/script&gt;</code>만 필터링되므로 스크립트를 실행할 수 있는</p>
<pre><code class="language-html">&lt;img src=&quot;#&quot; onerror=&quot;javascript:alert()&quot;&gt;</code></pre>
<p>를 입력하면 스크립트가 실행된다.  </p>
<hr>
<h2 id="level-3">level 3</h2>
<h3 id="분석-2">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/8fb450c8-1023-45de-9395-5a6667c7c76a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/23a05948-4ab0-4974-8715-a254fd16fbf9/image.png" alt=""></p>
<p>선택된 이미지에 따라 URL에서 <strong>fragment(#)</strong> 뒤의 숫자가 바뀌는 것을 볼 수 있다.  </p>
<p>프레그먼트에 임의의 값을 넣으니 다음과 같이 되었고,  </p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/ae3caa8b-537e-409e-8376-e892e8b794aa/image.png" alt=""></p>
<p>그때의 코드는 담음과 같았다   </p>
<pre><code class="language-html">&lt;div id=&quot;tabContent&quot;&gt;
  Image NaN
  &lt;br&gt;
  &lt;img src=&quot;/static/level3/cloudtest.jpg&quot;&gt;
&lt;/div&gt;</code></pre>
<p>cloud+fragment숫자+.jpg로 img를 불러오는 것 같다.  </p>
<h3 id="풀이-2">풀이</h3>
<p>위의 가정 하에 img에 onerror를 삽입하면,    </p>
<p><code>&#39; onerror= &quot;javascript:alert()&quot;&gt;</code>  </p>
<p>실행이 된다!  </p>
<h5 id="사실-만-쓰니-안돼서-시행착오가-있었다만-javascript에선-와-가-구분된다는-점을-고려해-잘-작성하면-된다">(사실 &quot;만 쓰니 안돼서 시행착오가 있었다만, javascript에선 &#39;와 &quot;가 구분된다는 점을 고려해 잘 작성하면 된다!)</h5>
<hr>
<h2 id="level-4">level 4</h2>
<h3 id="분석-3">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/dcd2223c-89cf-4fd5-8ae8-d786d1c1921c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/d238d34c-c966-408d-8664-956c3e134737/image.png" alt=""></p>
<p>이때 로딩 화면의 소스코드는  </p>
<pre><code class="language-html">&lt;body id=&quot;level4&quot;&gt;
  &lt;!--(중략)--&gt;
  &lt;img src=&quot;/static/loading.gif&quot; onload=&quot;startTimer(&#39;3&#39;);&quot;&gt;
  &lt;br&gt;
  &lt;div id=&quot;message&quot;&gt;Your timer will execute in 20seconds.&lt;/div&gt;
&lt;/body&gt;</code></pre>
<p>사진이 로딩될 대 어떤 javascript 함수를 실행함을 볼 수 있다. 그런데 인자로 받는 값의 형태가 특이하기에, test를 입력해보았다.<br><img src="https://velog.velcdn.com/images/halla_bbong/post/203ce0dd-9d27-4723-bbbc-1eb0bd9518f5/image.png" alt=""></p>
<p>이때 소스코드는 다음과 같았다.</p>
<pre><code class="language-html">&lt;body id=&quot;level4&quot;&gt;
  &lt;!--(중략)--&gt;
  &lt;img src=&quot;/static/loading.gif&quot; onload=&quot;startTimer(&#39;test&#39;);&quot;&gt;
  &lt;br&gt;
  &lt;div id=&quot;message&quot;&gt;Your timer will execute in testseconds.&lt;/div&gt;
&lt;/body&gt;</code></pre>
<p><code>startTimer(&quot;</code> + 입력 + <code>&#39;)</code>의 형태인 것으로 보인다.  </p>
<h3 id="풀이-3">풀이</h3>
<p>적당한 입력을 넣어 startTimer(에서 벗어나 다른 함수를 또한 입력시킬 수 없을까??<br>있다.</p>
<p><code>3&#39;);alert();(&#39;</code>  </p>
<hr>
<h2 id="level-5">level 5</h2>
<h3 id="분석-4">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/38ee006f-ec79-4393-83ee-232b52d1d04e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/74888a71-5ffe-41f1-86ed-8baeccef55bb/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/5541a499-899e-489f-9fb1-b488552cf386/image.png" alt=""></p>
<p>그리고 다시 처음으로 돌아온다.  </p>
<p>소스코드를 읽어보는 중에 이메일을 입력하는 부분에 걸린<br><code>Next&gt;&gt;</code> 가 다음과 같이 구현되어있었다.  </p>
<pre><code class="language-html">&lt;body&gt;
  &lt;!--(중략~~~)--&gt;
  &lt;a herf=&quot;confirm&quot;&gt;Next &gt;&gt;&lt;/a&gt;
&lt;/body&gt;</code></pre>
<p>next에 다른 값을 넣어 signup 페이지를 요청해보니,  </p>
<p>이때의 코드는,  </p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/a765f93f-b2b9-4079-8c0f-486da681586e/image.png" alt=""></p>
<pre><code class="language-html">&lt;body&gt;
  &lt;!--(중략~~~)--&gt;
  &lt;a herf=&quot;test&quot;&gt;Next &gt;&gt;&lt;/a&gt;
&lt;/body&gt;</code></pre>
<p><code>herf</code> 속성의 값이 바뀐 것을 볼 수 있다.  </p>
<h3 id="풀이-4">풀이</h3>
<p><code>~~/signup?next=javascript:alert()</code><br>다음과 같이 쿼리를 조정해 재접속하면,<br><code>Next&gt;&gt;</code>에 걸린 herf가 <code>javascript:alert()</code>가 되어 클릭하면 alert()가 실행된다.  </p>
<h2 id="level-6">level 6</h2>
<h5 id="해당-문제는-검색의-힘을-빌렸음을-미리-말씀드립니다😔">(해당 문제는 검색의 힘을 빌렸음을 미리 말씀드립니다.😔)</h5>
<h3 id="분석-5">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/87085dae-2102-40fe-9593-e423f5e0ca74/image.png" alt=""></p>
<p>소스코드를 보니 html에 스크립트 일부를 노출시켰다<br><img src="https://velog.velcdn.com/images/halla_bbong/post/569649e6-941c-4f42-af91-ab5f207465e4/image.png" alt=""></p>
<h6 id="중략">(중략)</h6>
<p><strong>fragement(#)</strong> 로 입력받은 값을 script로 테그로 감싸 html에 추가한다.<br>시험해보자면<br><img src="https://velog.velcdn.com/images/halla_bbong/post/7329d26c-8fef-4cd4-a488-ebfd45cdbd1d/image.png" alt=""></p>
<h6 id="페이지에-표시된-저-test는-필터링된다">(페이지에 표시된 저 test는 필터링된다)</h6>
<p>소스코드상에서 보면 헤더에 스크립트가 다음과 같이   </p>
<pre><code class="language-html">&lt;head&gt;
  &lt;!--(중략)--&gt;
  &lt;script src=&quot;/static/gadget.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;test&quot;&gt;&lt;/script&gt;
&lt;/head&gt;</code></pre>
<p>한 번 더 test2로 해보면</p>
<pre><code class="language-html">&lt;head&gt;
  &lt;!--(중략)--&gt;
  &lt;script src=&quot;/static/gadget.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;test&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;test2&quot;&gt;&lt;/script&gt;
&lt;/head&gt;</code></pre>
<p>이렇게 스크립트 테그가 불어나는 것을 볼 수 있다.  </p>
<h3 id="풀이-5">풀이</h3>
<p>1.
외부에서 <code>alert()</code>를 실행시키는 js를 가져오기  </p>
<ol start="2">
<li>src 속성에서 javascript를 실행시키는 방법이 있는 줄은 몰랐는디,,
<code>data:text/javascript,alert()</code>
로 입력하면 src 상에서 스크립트가 실행된다!!  </li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[XSS challenges by yamagata21]]></title>
            <link>https://velog.io/@halla_bbong/XSS-challenges-by-yamagata21</link>
            <guid>https://velog.io/@halla_bbong/XSS-challenges-by-yamagata21</guid>
            <pubDate>Thu, 09 May 2024 09:01:46 GMT</pubDate>
            <description><![CDATA[<p>####
모든 스테이지의 목적은<br>javascript 코드인 alert(document.domain)를 실행시키는 것입니다.  </p>
<h1 id="stage-1">stage #1</h1>
<h3 id="분석">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/135dd3e2-004b-4c27-85fd-a10c9438c179/image.png" alt=""></p>
<p>t입력 후 <strong>Search</strong> 버튼을 누르면<br><img src="https://velog.velcdn.com/images/halla_bbong/post/8f261e25-9f9a-4ee3-8b45-c741cb606ef0/image.png" alt=""></p>
<p>입력한 값을 아래에 띄우는 것을 관찰할 수 있습니다.  </p>
<h3 id="풀이">풀이</h3>
<p>어디까지 필터링이 되는지 모르겠으므로 (그리고 스테이지 1이므로)<br>적당히</p>
<pre><code class="language-html">&lt;script&gt;alert(document.domain)&lt;/script&gt;</code></pre>
<p>을 입력해보았습니다.</p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/e411dfa1-ad68-4b0d-bb4f-82ebef6bed5c/image.png" alt="">
통과입니다!</p>
<hr>
<h1 id="stage-2">stage #2</h1>
<h3 id="분석-1">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/c03e66d2-cfdd-46ab-adce-b62854643235/image.png" alt=""></p>
<p>test를 입력하고 <strong>Search</strong> 버튼을 눌러보겠습니다.
<img src="https://velog.velcdn.com/images/halla_bbong/post/0ce8cb26-602a-427e-8766-a507d8c71054/image.png" alt=""></p>
<p>입력한 값이 입력 박스에 그대로 남아있는 것을 볼 수 있습니다.
html코드를 보면</p>
<pre><code class="language-html">&lt;input type=&quot;text&quot; name=&quot;p1&quot; size=&quot;50&quot; value=&quot;test&quot;&gt;</code></pre>
<p>하고 입력한 값이 그대로 남아있는 것을 볼 수 있습니다.  </p>
<h3 id="풀이-1">풀이</h3>
<p>필터링이 없다고 생각해보면,<br><code>&quot; onclick= &quot;javascript:alert(document.domain)</code>
을 입력했을 때</p>
<pre><code class="language-html">&lt;input type=&quot;text&quot; name=&quot;p1&quot; size=&quot;50&quot; value=&quot;&quot; onclik=&quot;javascript:alert(document.domain)&quot;&gt;</code></pre>
<p>이 되어 입력 박스를 클릭하면 코드가 실행됩니다!
<img src="https://velog.velcdn.com/images/halla_bbong/post/30b8d9b6-332d-4add-9bbd-ed50ebe7c514/image.png" alt=""></p>
<hr>
<h1 id="stage-3">stage #3</h1>
<h3 id="분석-2">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/81928d66-ad32-4462-94ab-5709e1f95bde/image.png" alt=""></p>
<p>입력 박스에 값을 집어넣으면,
<img src="https://velog.velcdn.com/images/halla_bbong/post/70b13fe1-2197-4441-98ff-21612b185436/image.png" alt=""></p>
<p>위와 같이 검색어와 선택한 나라가 표시되는 것을 알 수 있다.</p>
<p>테그를 입력해보면,
<img src="https://velog.velcdn.com/images/halla_bbong/post/e5414360-4d8b-4002-86c3-104c66f30f30/image.png" alt=""></p>
<p>이처럼 필터링이 되는 것을 관찰할 수 있다.</p>
<h3 id="풀이-2">풀이</h3>
<p>post 요청을 보면,
<img src="https://velog.velcdn.com/images/halla_bbong/post/28d20995-bfa3-43e0-b71c-9b78fb57803f/image.png" alt="">
p1으로는 입력 박스에 넣은 값이,<br>p2값으론 나라 이름이 들어가는 것을 볼 수 있다.  </p>
<p>임의의 값으로 p2를 수정할 시에 다음과 같이
<img src="https://velog.velcdn.com/images/halla_bbong/post/4bfcd80f-aa6a-40fb-a68a-68b8f5f941d5/image.png" alt=""></p>
<p>표시되는 것을 관찰할 수 있다.
p2에 적절한 스크립트를 입력해주면
<img src="https://velog.velcdn.com/images/halla_bbong/post/2f389af8-ed4d-4c76-be56-a2b63bb950b5/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/7eac24cf-48f0-4832-9333-78408a4c6530/image.png" alt="">
이상입니다!</p>
<hr>
<h1 id="stage-4">stage #4</h1>
<h3 id="분석-3">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/fd2424bc-8e3f-4c00-bc20-ae15d322c83e/image.png" alt=""></p>
<p>스테이지 3과 닮은 페이지입니다.  </p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/7b115c7b-0552-4ff3-afd1-b9ecca8d5f62/image.png" alt=""></p>
<p>임의로 country 값을 바꿔도 표시가 되군요.
<img src="https://velog.velcdn.com/images/halla_bbong/post/45da991d-c173-4c82-8067-52b73caf2df1/image.png" alt=""></p>
<p>그러나 이전과 같은 방법은 필터링때문에 어려울 것 같습니다.
<img src="https://velog.velcdn.com/images/halla_bbong/post/7ab0b290-a019-41fc-929d-012787c457ab/image.png" alt=""></p>
<p>f12로 코드를 보니 p1 p2에 이어 p3가 있는 것을 볼 수 있습니다!
<img src="https://velog.velcdn.com/images/halla_bbong/post/a51b1b87-d6d5-4352-95f4-2dbb8f808255/image.png" alt=""></p>
<p>post 요청을 확인해보면 p3값도 같이 넘어가는 것을 확인할 수 있습니다.</p>
<p>p3로 어떤 것이 가능할지 찔러보겠습니다.
p3의 값을 test로 변경한 후 <strong>Search</strong> 버튼을 누르면,</p>
<pre><code class="language-html">&lt;input type=&quot;hidden&quot; name=&quot;p3&quot; value=&quot;test&quot;&gt;</code></pre>
<p>화면상에는 보이지 않지만 코드상에는 해당 입력 박스(그러나 숨겨진!)의 value에 들어감을 확인할 수 있습니다.  </p>
<h3 id="풀이-3">풀이</h3>
<p>p3의 값에
<code>&quot;&gt;&lt;script&gt;alert(document.domain)&lt;/script&gt;</code>
을 넣어보겠습니다.</p>
<p>그러면 코드가 이와 같이
<img src="https://velog.velcdn.com/images/halla_bbong/post/49b6e499-71dd-4eb6-89c3-12a87de84ed8/image.png" alt=""></p>
<p>조작되어!
<img src="https://velog.velcdn.com/images/halla_bbong/post/04f7acbf-2ba3-4ff0-978f-ec96410bd415/image.png" alt=""></p>
<p>정답임을 확인할 수 있습니다.</p>
<hr>
<h1 id="stage-5">stage #5</h1>
<h3 id="분석-4">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/62f7be75-16b9-419f-b675-6de7a7915481/image.png" alt=""></p>
<p>이쯤되면 따분한 화면입니다.
test를 입력하고 검색하니
<img src="https://velog.velcdn.com/images/halla_bbong/post/2fce614c-deb9-43d0-bf5b-9b81c3b8a3e4/image.png" alt=""></p>
<p>이와처럼 입력값이 그대로 남아있는 모습을 볼 수 있습니다.</p>
<h3 id="풀이-4">풀이</h3>
<p>여기다가 </p>
<p><code>&quot; onclick=&quot;javascript:alert(document.domain)</code></p>
<p>를 입력하려고 했는데  </p>
<p><code>&quot; onclick= &quot;java</code>
중간에 잘리기에 보니까</p>
<pre><code class="language-html">&lt;input type=&quot;text&quot; name=&quot;p1&quot; maxlength=&quot;15&quot; size=&quot;30&quot; value=&quot;test&quot;&gt;</code></pre>
<p>maxlength가 15로 제한되어있었습니다.<br>maxlength를 지우고 다시 입력한 이후,</p>
<p>입력 박스를 클릭해주면 코드가 실행됩니다!
<img src="https://velog.velcdn.com/images/halla_bbong/post/4ed2f540-d473-40df-aed9-293d753dfce6/image.png" alt=""></p>
<hr>
<h1 id="stage-6">stage #6</h1>
<h3 id="분석-5">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/d66a84fb-5998-4085-a08a-138fe4439241/image.png" alt=""></p>
<p>이전 문제와 닮아있습니다.</p>
<h3 id="풀이-5">풀이</h3>
<p><code>&quot; onclick= &quot;javascript:alert(document.domain)</code></p>
<p>이전에 쓴 코드를 한번 더 써보겠습니다.
<img src="https://velog.velcdn.com/images/halla_bbong/post/9857aca0-6dc0-4b93-a1ee-c1c9b5b60ee5/image.png" alt=""></p>
<p>어 됐다.
아무래도 이전 문제에 요구했던 정답은 브라켓을 닫고, 스크립트 테그를 여는 것이었나보다.</p>
<hr>
<h1 id="stage-7">stage #7</h1>
<h3 id="분석-6">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/ea7bb947-3dbe-40c5-9b62-75fffcced4da/image.png" alt="">  </p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/7fd5e583-c4cb-4bbe-8df4-24bd12c259b5/image.png" alt=""></p>
<p>이번엔 test말고 바로 코드를 입력해보겠습니다.</p>
<p><code>&quot; onclick= &quot;javascript:alert(document.domain)</code></p>
<p>뭔가 됐는데 다릅니다. html 코드를 보면,</p>
<pre><code class="language-html">&lt;input type=&quot;text&quot; name=&quot;p1&quot; size=&quot;50&quot; value=&quot;&amp;quot;&quot; onclick=&quot;&amp;quot;javascript:alert(document.domain)&quot;&gt;</code></pre>
<p>몇몇 특수문자들이 바뀐 것을 볼 수 있습니다.
그런데 뭔가 특이합니다.<br>왜</p>
<pre><code class="language-html">&lt;input type=&quot;text&quot; name=&quot;p1&quot; size=&quot;50&quot; value=&quot;&amp;quot; onclick=&amp;quot;javascript:alert(document.domain)&quot;&gt;</code></pre>
<p>가 아니라, 저렇게 된거지?
하면서 여러 테스트를 해보니,
test test
입력시, </p>
<pre><code class="language-html">&lt;input type=&quot;text&quot; name=&quot;p1&quot; size=&quot;50&quot; value=&quot;test&quot; test=&quot;&quot;&gt;</code></pre>
<p>이렇게 됩니다. 이상해... 참 이상해.</p>
<h3 id="풀이-6">풀이</h3>
<p><code>test onclick=javascript:alert(document.domain)</code></p>
<p>이렇게 입력하니 알아서 뒷부분을 속성으로 해석해 따옴표를 붙여,</p>
<pre><code class="language-html">&lt;input type=&quot;text&quot; name=&quot;p1&quot; size=&quot;50&quot; value=&quot;test&quot; onclick=&quot;javascript:alert(document.domain)&quot;&gt;</code></pre>
<p>가 되어 원하는 코드를 실행할 수 있습니다.
<img src="https://velog.velcdn.com/images/halla_bbong/post/23c44521-06c6-461d-a4f3-cbfc124e5083/image.png" alt="">  </p>
<hr>
<h1 id="stage-8">stage #8</h1>
<h3 id="분석-7">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/a2dd0408-5d01-4452-8bf2-c9a71dfc8a49/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/cd4dcba5-4f23-4f56-be61-f97462da48f1/image.png" alt=""></p>
<p>해당 링크의 코드는,</p>
<pre><code class="language-html">&lt;a href=&quot;test&quot;&gt;test&lt;/a&gt;</code></pre>
<p>입니다.</p>
<h3 id="풀이-7">풀이</h3>
<p>지금껏 써온 
<code>javascript:alert(document.domain)</code>
을 사용하면 href에 바로 저 값이 들어가므로??</p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/b2b87133-7321-422f-8e38-6e2bb60787c3/image.png" alt=""></p>
<p>링크를 클릭할 시 정답이 됩니다!</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Basic RCE L04]]></title>
            <link>https://velog.io/@halla_bbong/Basic-RCE-L04</link>
            <guid>https://velog.io/@halla_bbong/Basic-RCE-L04</guid>
            <pubDate>Tue, 16 Apr 2024 13:45:36 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p>이 프로그램은 디버거 프로그램을 탐지하는 기능을 갖고 있다.<br>디버거를 탐지하는 함수의 이름은 무엇인가?</p>
<h3 id="실행">실행</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/2db1d7b8-a479-4153-9fa1-3792c2c42ff3/image.png" alt=""></p>
<p>디버거로 실행시
<img src="https://velog.velcdn.com/images/halla_bbong/post/0e6645af-7980-4398-b8a0-87016553611a/image.png" alt=""></p>
<h3 id="분석">분석</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/60fea3a6-8e98-47cd-9d21-65a8a56af905/image.png" alt="">
메인에서 _main_0를 호출하는 것을 볼 수 있다.
<img src="https://velog.velcdn.com/images/halla_bbong/post/6f8a90aa-555e-4a02-8ec3-61cc3f0eecb3/image.png" alt="">
일단 이름으로 보았을 때 </p>
<h3 id="문제에서-요구하는-정답은-isdebuggerpresent-이다">문제에서 요구하는 정답은 IsDebuggerPresent 이다!</h3>
<hr>
<h3 id="조금-더-분석해보자면">조금 더 분석해보자면...</h3>
<p>분기 이후로 printf가 둘 존재하는 것을 보면 <strong>IsDebuggerPresent</strong> 실행 후 <strong><em>일련의 과정</em></strong> 으로 디버깅 여부를 판단하고 eax에 0 혹은 다른 값을 저장하는 것으로 보인다.<br>정적 분석으로는 <strong>IsDebuggerPresent</strong> 의 동작을 알기 어려우니
브레이크 포인트를 걸고 디버거로 분석해보자.</p>
<h6 id="step-into">step into</h6>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/4f927656-220d-4442-8c03-645edd09ca98/image.png" alt=""></p>
<h6 id="step-into-1">step into</h6>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/a0c6b49e-7c00-4a03-a569-add43a241169/image.png" alt=""></p>
<p>에, 이게 끝이다.
보아하니 <strong>[fs:0x30]+2</strong> 의 값을 eax에 저장하는 것을 볼 수 있다.
구체적으로 어떤 값이지?!
<img src="https://velog.velcdn.com/images/halla_bbong/post/a74be712-fbe4-4883-a2d3-fcfefd593134/image.png" alt=""></p>
<p><strong>IsDebuggerPresent</strong> 의 호출이 끝나고 eax에는 1이 저장되어있다.<br><img src="https://velog.velcdn.com/images/halla_bbong/post/9f18922f-d49e-4fa8-876e-8b4bd4185fbd/image.png" alt=""></p>
<p>이대로 계속 진행되면 jz를 스무스하게 지나가게 되므로
<img src="https://velog.velcdn.com/images/halla_bbong/post/3f08c4f1-4074-4f9e-af69-04f4483af1b8/image.png" alt=""></p>
<p>요로코롬 출력이 된다.</p>
<p>그렇다면 디버거 실행 중 eax값을 0으로 수정해주면 정상인 척 실행시킬 수 있을 것 같다!</p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/5057ba26-7be4-45e1-84c9-70378bc77d4e/image.png" alt=""></p>
<p>요로코롬,</p>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/e93a9724-27e4-4f62-b999-24540353b792/image.png" alt=""></p>
<p>우회가 된다!</p>
<h3 id="번외">번외</h3>
<p>자 그러면 <strong>fs:0x30</strong> 과 <strong>[fs:0x30] + 2</strong> 에는 무엇이 있을까?
조사해본 결과를 정리해보겠다!
.
.
여러 세그먼트 레지스터 중, 역할이 고정적인 것들도 있는 반면
운영체제에 따라 역할이 유동적인 것도 있다.
fs가 그렇다.</p>
<p>문제로 제시된 프로그램은 32bit 윈도우이며,
32bit 윈도우에서는 fs가 무엇으로 사용되냐면,,,</p>
<blockquote>
<p>32비트 윈도우의 FS 레지스터는 유저 모드 기준으로 
<strong>TIB(Thread Information Block)</strong> 이라고 불리는 구조체를 가리킨다. 
(<strong>TEB(Thread Environment Block)</strong>라고도 불린다!)</p>
</blockquote>
<p>이 구조체는 <strong>현재 실행 중인 스레드</strong> 에 대한 정보를 저장하고 있다. 
<strong>API 함수를 호출하지 않고도 정보를 얻기 위해</strong> 사용된다. </p>
<blockquote>
</blockquote>
<p>대략적인 구조는 이렇다<a href="https://ko.wikipedia.org/wiki/Win32_%EC%8A%A4%EB%A0%88%EB%93%9C_%EC%A0%95%EB%B3%B4_%EB%B8%94%EB%A1%9D">(참고)</a></p>
<blockquote>
<p><strong>FS:[0x00] : 현재 SEH 프레임
FS:[0x18] : TEB
FS:[0x20] : PID
FS:[0x24] : TID
FS:[0x30] : PEB
FS:[0x34] : Last Error Value</strong></p>
</blockquote>
<p>우리가 궁금했던 <strong>fs:0x30</strong>은 <strong>PEB(Process Environment Block)</strong> 의 주소였다!</p>
<blockquote>
</blockquote>
<p><strong>0x002 BYTE BeingDebugged;
0x008 void* ImageBaseAddress;
0x00C _PEB_LDR_DATA* Ldr;
0x018 void* ProcessHeap
0x064 DWORD NumberOfProcessors;
0x068 DWORD NtGlobalFlag;</strong></p>
<p><strong>[fs:0x30]+2</strong> 는 BeingDebugged 값으로,
프로세스가 디버깅 당하는 중일 때는 1,
아닐 때는 0을 저장하는 부분이다.</p>
<h3 id="참고자료">참고자료</h3>
<p><a href="https://sanseolab.tistory.com/47">https://sanseolab.tistory.com/47</a>
<a href="https://reverseengineering.stackexchange.com/questions/16336/where-es-gs-fs-are-pointing-to">https://reverseengineering.stackexchange.com/questions/16336/where-es-gs-fs-are-pointing-to</a>
<a href="https://ko.wikipedia.org/wiki/Win32_%EC%8A%A4%EB%A0%88%EB%93%9C_%EC%A0%95%EB%B3%B4_%EB%B8%94%EB%A1%9D">https://ko.wikipedia.org/wiki/Win32_%EC%8A%A4%EB%A0%88%EB%93%9C_%EC%A0%95%EB%B3%B4_%EB%B8%94%EB%A1%9D</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Basic RCE L03]]></title>
            <link>https://velog.io/@halla_bbong/Basic-RCE-L-03</link>
            <guid>https://velog.io/@halla_bbong/Basic-RCE-L-03</guid>
            <pubDate>Sun, 14 Apr 2024 07:54:47 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">문제</h3>
<p>비주얼베이직에서 스트링 비교함수 이름은?  </p>
<h3 id="실행">실행</h3>
<p><img src="https://velog.velcdn.com/images/halla_bbong/post/7ec38cf8-ff30-424f-9c68-9f51ded72506/image.png" alt="">
<img src="https://velog.velcdn.com/images/halla_bbong/post/a0d2dcc5-a942-4a7c-8dca-6a5e5b18d3e8/image.png" alt=""></p>
<p>특징적인 문자열을 발견했다!</p>
<h3 id="문제-해결-시나리오">문제 해결 시나리오</h3>
<p>정적 분석 툴에서 <em>Error! Das Passwort...</em> 를 찾 아 역참조를 하면 어떤 분기를 볼 수 있을테고<br>그 전에는 분명 입력된 값과의 문자열 비교가 있을 것이다.  </p>
<p>IDA로 확인을 해보려고 했는데,<br>함수 이름중에 대놓고 <strong>__vbaStrCmp</strong> 인 것이 있다...!  
<img src="https://velog.velcdn.com/images/halla_bbong/post/55bb22d4-c8d6-483e-905c-c52ef2444cab/image.png" alt="">
엄,, 음...<br>그러나 성실하게 찾아보자면,<br><img src="https://velog.velcdn.com/images/halla_bbong/post/111d2dcc-879d-49c8-be3a-81f1cbb13864/image.png" alt="">
<img src="https://velog.velcdn.com/images/halla_bbong/post/db8eab94-5ea9-4bb1-8967-a3c1e4090172/image.png" alt="">
뭐 엄 그리 되었수다,<br><img src="https://velog.velcdn.com/images/halla_bbong/post/90892023-7bbd-48e6-b37d-12a54c41876a/image.png" alt="">
조금 위로 올라가니 이런 부분이 있었다.  </p>
<h3 id="문제에서-요구하던-정답은-vbastrcmp-이다">문제에서 요구하던 정답은 vbaStrCmp 이다!</h3>
<hr>
<h3 id="번외">번외</h3>
<p>해당 분기를 기점으로 비밀번호가 틀릴 시 나오는 문구가 나오는 걸 보면
이 프로그램의 비밀번호는 2G83G35Hs2일지도 모르겠다.
<img src="https://velog.velcdn.com/images/halla_bbong/post/9222c548-502a-4bac-b308-93dcc7f76b8f/image.png" alt="">
엄,,, 그니까,,<br><img src="https://velog.velcdn.com/images/halla_bbong/post/bf457e5a-11b2-47c8-9dda-09948ded9ae1/image.png" alt=""></p>
<p>! 그렇다.  </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DES]]></title>
            <link>https://velog.io/@halla_bbong/DES</link>
            <guid>https://velog.io/@halla_bbong/DES</guid>
            <pubDate>Sun, 24 Mar 2024 12:46:50 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>분류 : 대칭키, 블록, 곱, 페이스텔</p>
</li>
<li><p>입력 : 평문 (Plaintext), 비밀키 : 64bit(52bit + 8bit parity)</p>
</li>
<li><p>출력 : 암호문 (Ciphertext)</p>
</li>
<li><p>구조 
초기 순열 (Initial Permutation, IP)
페이스텔 구조 (Feistel) * 16라운드 &lt;= 각 라운드에 48bit key &lt;= key 생성 함수 &lt;= 56비트 비밀키
최종 순열 (Final Permutation, FP)</p>
</li>
<li><p>특징</p>
</li>
</ul>
<hr>
<h2 id="암호화">암호화</h2>
<h3 id="1-구성">1. 구성</h3>
<pre><code class="language-python">IP = [...]                                             # IP : 64index -&gt; 64index, 일대일 전치, 전치할 인덱스 값 저장
FP = [...]                                             # FP(IP[in]) = in, 일대일 전치, 전치할 인덱스 값 저장

#Feistel
#EPT = [...]                                           # Expansion P-Box table
#SBOX = [[],[],[],..]                                  # S-box
#SPT = [...]                                           # Strait P-box table
#def roundf(block : 32bit, key : 48bit) -&gt; 32bit: ...  # 라운드 함수
#def key_scheduler(key:64bit) -&gt; 48bit array: ...      # 라운드별로 사용할 키를 생성!
def Feistel(block : 64bit, key : 64bit) -&gt; 64bit: ...  # Feistel (후술)

plain = ...                                            # 평문 : 64bit로 나눠 떨어지도록 패딩!
key = ...                                              # key : 64bit 중 parity bit 8개 제외 56비트 사용!(후술)


v1 = [IP[c] for c in plain]                            # 초기 순열 적용

v2 = [Feistel(v1[b:b+64]) for b in range(0, size, 64)] # 각 블록별로 Feistel 적용

v3 = [FP[c] for c in v2]                               # 최종 순열 적용

cipher = v3                                            # 암호화 완료!</code></pre>
<h3 id="2-feistel-구성">2. Feistel 구성</h3>
<p>Feistel 구성이라 함은, 다음과 같이</p>
<p>$L_0 := input[:half]\
R_0 := input[half:]\
L_{n+1} := R_n\
R_{n+1} := L_n \oplus roundf(R_n, K_n)$</p>
<p>반 쪼개서 (라운드 함수를 첨가해) 좌우로 섞는 구성이다.</p>
<p>여느 대칭키 암호가 그렇듯, 역연산이 가능하다.</p>
<pre><code class="language-python">#EPT = [...]                                           # Expansion P-Box table
#SBOX = [[],[],[],..]                                  # S-box
#SPT = [...]                                           # Strait P-box table
def roundf(block : 32bit, key : 48bit) -&gt; 32bit: ...   # 라운드 함수
def key_scheduler(key : 64bit) -&gt; 48bit array: ...     # 라운드별로 사용할 키를 생성!

#자 설명 드갑니다~~
def Feistel(block : 64bit, key : 64bit) -&gt; 64bit:

    #1. 블록을 좌측 반쪽과 우측 반쪽으로 나눈다
    left_half = block[:half]
    right_half = block[half:]

    #2. 라운드별로 사용할 키를 생성합니다!
    key_schedule = key_scheduler(key)

    #3. 16라운드 돌립니다!
    for i in range(16):
        tmp = left_half
        left_half = right_half
        right_half = tmp ^ roundf(right_half, key_scheduler[i])

    #4. 이후 좌측 반쪽과 우측 반쪽을 연접해 반환합니다
    return lefthalf + righthalf</code></pre>
<h3 id="2-1-라운드-함수-구성">2-1. 라운드 함수 구성</h3>
<ul>
<li>입력 : 블록의 반절 : 32bit, 라운드 키 : 48bit</li>
<li>출력 : 블록의 반절 : 32bit</li>
<li>구조
확장 순열 (Expansion P-Box, EPB)
XOR 라운드 키
치환 테이블 (S-Box)
고정 순열 (Straight P-Box, SPB)</li>
</ul>
<h4 id="라운드-함수">라운드 함수</h4>
<pre><code class="language-python">EPB = [...]                                            # EPB : 32bit 입력을 48bit로 확장/전치할 때 사용됨.
SBOX = [[[],[]...],...]                                # S-box : 48bit -&gt; 32bit 치환
SPB = [...]                                            # SPB : 32bit -&gt; 32bit 전치

def roundf(block : 32bit, key : 48bit) -&gt; 32bit:

    #1. 입력된 값을 48비트로 확장!
    expansioned = [block[i] for i in EPT]

    #2. 확장된 값과 라운드 키값을 xor연산!
       expansioned = expansioned ^ key

    #3. SBOX로 48bit -&gt; 32bit로 치환한다
    extraction = [0 for i in range(32)]                # 32bit
    for i in range(8):
        extraction[4*i:4*i+4] = SBOX[i][..][..]        # 후술, 

    #4. SPB로 전치!
    result = [SPB[i] for i in extraction]

    return result</code></pre>
<h4 id="확장-순열-및-고정-순열">확장 순열 및 고정 순열</h4>
<pre><code class="language-python">EPB = [32, 1, 2, 3, 4, 5,
       4, 5, 6, 7, 8, 9,
       8, 9, 10, 11, 12, 13,
       12, 13, 14, 15, 16, 17,
       16, 17, 18, 19, 20, 21,
       20, 21, 22, 23, 24, 25,
       24, 25, 26, 27, 28, 29,
       28, 29, 30, 31, 32, 1]

SPB = [16, 7, 20, 21, 29, 12, 28, 17,
       1, 15, 23, 26, 5, 18, 31, 10,
       2, 8, 24, 14, 32, 27, 3, 9,
       19, 13, 30, 6, 22, 11, 4, 25]</code></pre>
<p>확장된 순열의 i번 인덱스엔 입력의 EPB[i]번 인덱스 값이 위치함.
SPB도 같은 원리이며, SPB는 확장 없이 전치만 함.</p>
<h6 id="챠카챠카-섞음">(챠카챠카 섞음)</h6>
<h4 id="sbox">SBOX</h4>
<p>이짝이 약간 문제인데, 아무렴 어떤가.</p>
<pre><code class="language-python">SBOX = [
    # S1
    [
        [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
        [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
        [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
        [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]
    ],
     ...
    # S8
    [
        [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
        [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
        [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
        [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11],
    ]
]</code></pre>
<p>SBOX의 각 원소들은 <strong>4비트</strong>로 표현될 수 있는 값의 무작위다.</p>
<p>SBOX[i]에 들어있는 2차원 리스트를 보자.
4*16 행렬이다. </p>
<p>어떤 6bit에 대해</p>
<p>MSB와 LSB로 행을 정하고
나머지 네 비트로 열을 정하면</p>
<p>무작위 4비트 값을 뱉어낸다!
이런 방식으로 6bit -&gt; 4bit로 바꾸는 2차원 리스트가 들어있는데,</p>
<p>그런 2차원 리스트가 8개가 있다.
그러니까, SBOX는 6*8bit 를 4*8bit로 변환하는데 사용된다!
<strong>SBOX : 48bit -&gt; 32bit</strong></p>
<h3 id="2-2-키-생성-함수-구성">2-2. 키 생성 함수 구성</h3>
<ul>
<li><p>입력 : raw key : 64bit</p>
</li>
<li><p>출력 : 48bit key가 16개담긴 array</p>
</li>
<li><p>구조
패리티 비트 제거 (Parity Bit Drop)
순환쉬프트 (Rotate Left, ROL)
압축 순열 (Comporession P-Box)</p>
<h4 id="키-생성-함수">키 생성 함수</h4>
<pre><code class="language-python"></code></pre>
</li>
</ul>
<p>def key_scheduler(key : 64bit) -&gt; 48bit array:</p>
<pre><code>result = []

#1.key에서 parity bit를 지워 56bit로 만든다
del_parity = [delete parity bit from key]

#2.키를 반으로 쪼갠다!
left_half = del_parity[:half]
right_half = del_parity[half:]

#3.라운드 횟수만큼 쉬프트
for i in range(16):
    if i in [1, 2, 6, 16]:
        left_half &lt;&lt;&lt; 2
        right_half &lt;&lt;&lt; 2
    else:
        left_half &lt;&lt;&lt; 1
        right_half &lt;&lt;&lt; 1

    #4. 합치고 압축 순열 적용
    tmp = left_half + right_half

    result.append([tmp[CPB[i]] for i in range(48)])

return result</code></pre><pre><code>#### 패리티 비트 제거
64bit = 8byte 중 각 바이트의 패리티 비트를 제거해
64 - 8 = 56bit를 반환

#### 쉬프트
56bit를 반으로 나눠
각자 왼쪽으로 1비트씩 순환 쉬프트를 취한다
이 때, 1, 2, 9, 16 라운드에선 2비트씩 순환한다.
$L_0 := key[:half]\\
R_0 := key[:half]\\
L_{n} := \begin{cases}
            L_{n-1}&lt;&lt;&lt;2&amp;if&amp;n\in\{1,2,9,16\}\\
            L_{n-1}&lt;&lt;&lt;1&amp;else\end{cases}\\
R_{n} := \begin{cases}
            R_{n-1}&lt;&lt;&lt;2&amp;if&amp;n\in\{1,2,9,16\}\\
            R_{n-1}&lt;&lt;&lt;1&amp;else\end{cases}
$
#### 압축 순열
56bit 입력을 48bit로 압축시키는 과정이다.
```python
CPB = [14, 17, 11, 24, 1, 5, 3, 28,
        15, 6, 21, 10, 23, 19, 12, 4,
        26, 8, 16, 7, 27, 20, 13, 2,
        41, 52, 31, 37, 47, 55, 30, 40,
        51, 45, 33, 48, 44, 49, 39, 56,
        34, 53, 46, 42, 50, 36, 29, 32]</code></pre><p>압축된 순열의 i번 인덱스엔 입력의 CPB[i]번 인덱스 값이 위치하게 한다. (P-Box들은 원리가 다 같다!)</p>
<hr>
<h2 id="복호화">복호화</h2>
<p>뭐... 전부 역원이 존재하는 연산이었으므로 
<strong>복호화는 암호화의 역순입니,,,다,,</strong>
(언젠가 시간이 남으면 한 번 해보고 올리겠습니다!)</p>
<hr>
<h2 id="취약점">취약점</h2>
<h3 id="브루트-포스">브루트 포스!</h3>
<ul>
<li>대상 : DES</li>
<li>목적 : key 획득 및 복호화</li>
<li>요구사항 : 암호문 c, (평문 p)</li>
</ul>
<p>56bit key는 오늘날에는 너무나도 짧아 브루트 포스로도 충분히 알아낼 수 있다고 합니다... 
놀라운걸?</p>
<h3 id="중간-일치-공격">중간 일치 공격</h3>
<ul>
<li>대상 : 2-DES(이중 DES)</li>
<li>목적 : key 획득</li>
<li>요구사항 : 평문 p, 암호문 c, 암호화 E, 복호화 D</li>
</ul>
<p>2-DES는 DES보다 키의 길이가 배로 길다.(DES를 두 번 하기 때문이지!)
그러나 DES는 중간 일치 공격에 약점이 있다.</p>
<p>$E_{k_2}(E_{k_1}(p)) = c$
위는 우리의 나약한 2-DES다...</p>
<p>$D_{k_2}(E_{k_2}(E_{k_1}(p))) = D_{k_2}(c)\
E_{k_1}(p) = D_{k_2}(c)$
암호화와 복호화 방식을 알고있고, 평문 p와 암호문 c를 알고 있으므로
위를 성립시키는 k_1과 k_2를 찾는다!</p>
<p>대충 이렇게 표현하는 모양이다
$
sol := {(k_1, k_2)|E_{k_1}(p) = D_{k_2}(c)\space for\space k_1, k_2 \isin K}
$</p>
<p>이 짓 하고도 우연하게 일치하는 (k,k)가 둘 이상 있을 수 있다.
그럴땐 평문 p&#39;와 암호문 c&#39;를 하나 더 갖고와서 찾아내야한다...</p>
<hr>
]]></description>
        </item>
    </channel>
</rss>