<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>big_tree.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 18 May 2023 07:55:27 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>big_tree.log</title>
            <url>https://velog.velcdn.com/images/jh_0517/profile/c232af5e-6072-4876-ad09-736375149723/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. big_tree.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jh_0517" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Dream Hack write-up(4)]]></title>
            <link>https://velog.io/@jh_0517/Dream-Hack-write-up4</link>
            <guid>https://velog.io/@jh_0517/Dream-Hack-write-up4</guid>
            <pubDate>Thu, 18 May 2023 07:55:27 GMT</pubDate>
            <description><![CDATA[<h4 id="rev-basic-5">rev-basic-5</h4>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p><strong>문제</strong>
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.</p>
</blockquote>
<p>chall5.exe의 main 함수를 찾아 decompile 한 결과
<img src="https://velog.velcdn.com/images/jh_0517/post/e2e3ce5a-275b-4923-bda8-45ab960e30eb/image.png" alt="">함수 sub_140001000()
<img src="https://velog.velcdn.com/images/jh_0517/post/d612dbec-bfc5-4203-aed0-714830aad8b2/image.png" alt="">
함수 sub_140001000()의 코드를 python으로 작성해보면 아래와 같다는 것을 할 수 있다. </p>
<pre><code>for i in range(23):
    if (input[i+1] + input[i] != byte_140003000[i]):
        return False       </code></pre><p>byte_140003000에는 아래와 같은 값이 저장되어있다. 
AD D8 CB CB 9D 97 CB C4 92 A1 D2 D7 D2 D6 A8 A5 DC C7 AD A3 A1 98 4C 00 00 00 00 00 00 00 00 00
<img src="https://velog.velcdn.com/images/jh_0517/post/5f25586d-394e-4e9d-8708-3af5b7e4dbd1/image.png" alt=""></p>
<p>flag를 뒤에서 부터 한 글자씩 구한뒤, byte_140003000에 저장된 값과 빼면 flag를 얻을 수 있다. </p>
<pre><code>value = [&#39;AD&#39;, &#39;D8&#39;, &#39;CB&#39;, &#39;CB&#39;, &#39;9D&#39;, &#39;97&#39;, &#39;CB&#39;, &#39;C4&#39;, &#39;92&#39;, &#39;A1&#39;, &#39;D2&#39;, &#39;D7&#39;, &#39;D2&#39;,
         &#39;D6&#39;, &#39;A8&#39;, &#39;A5&#39;, &#39;DC&#39;, &#39;C7&#39;, &#39;AD&#39;, &#39;A3&#39;, &#39;A1&#39;, &#39;98&#39;, &#39;4C&#39;]
result = []
prev_value = 0

for i in range(len(value)-1, -1, -1):
    flag_value = int(value[i], 16) - prev_value
    result.append(chr(flag_value))
    prev_value = flag_value

flag = &#39;&#39;
for i in range(len(result)-1, -1, -1):
    flag += result[i]

print(flag)</code></pre><p>따라서 flag는 DH{All_l1fe_3nds_w1th_NULL}이다. </p>
<h4 id="rev-basic-6">rev-basic-6</h4>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p><strong>문제</strong>
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.</p>
</blockquote>
<p>chall6.exe의 main 함수를 decomfile 한 결과 
<img src="https://velog.velcdn.com/images/jh_0517/post/138ae8f6-3f53-4634-a8da-1e23d98b5832/image.png" alt="">함수 sub_140001000()
<img src="https://velog.velcdn.com/images/jh_0517/post/b7f479f5-ac50-4a77-8aca-3cce49de9f07/image.png" alt="">
함수 sub_140001000()의 코드를 python으로 작성해보면 아래와 같다는 것을 할 수 있다. </p>
<pre><code>for i in range(18):
    if (byte_140003020[input[i]]!= byte_140003000[i]):
        return False       </code></pre><p><img src="https://velog.velcdn.com/images/jh_0517/post/eafaaf03-d636-4c44-a9f8-da7cfe8ac6b7/image.png" alt=""></p>
<p>음.. ㅎㅎ  난 byte_140003020의 모든 숫자를 다 코드로 옮길 생각이 없다... flag는 눈으로 찾았다. 숫자 12개만 찾으면 되니 이쪽이 더 빠르다. 
예를 들어서, byte_140001000의 첫번째 숫자는 0이고, 0은 byte_140003020에서 83번째에 위치한 숫자이다. 따라서 첫번째 글자는 char(82)인 R이다. 이 짓을 12번 하면 flag를 얻을 수 있다. </p>
<p>따라서 flag는 DH{Replac3_the_w0rld}</p>
<h4 id="rev-basic-8">rev-basic-8</h4>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p>문제
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.</p>
</blockquote>
<p>chall8.exe의 main 함수를 찾아 decompile 한 결과
<img src="https://velog.velcdn.com/images/jh_0517/post/baeda12c-461d-4b03-9fe7-efce1fedd4b1/image.png" alt="">함수 sub_140001000
<img src="https://velog.velcdn.com/images/jh_0517/post/b85b9e1e-952a-40ad-90cf-3420a91ccaa5/image.png" alt="">
함수 sub_140001000()의 코드를 보면, 입력한 값과 -5를 곱한 후 unsigned__int8로 형변환 한 후에 byte_140003000의 값과 비교한다. </p>
<p>즉, 2^8(0-255)의 값과 -5를 곱한 후, 뒤의 8bit만 얻은 후에 byte_140003000의 값과 일치하는 것을 brute forece 방식으로 찾아야한다. </p>
<p>따라서 flag는 DH{Did_y0u_brute_force?}</p>
<p>rev-basic 8로 rev basic 문제의 write-up을 모두 작성하였다. 다음주에는 다른 리버싱 level-1 문제를 가져와야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dream Hack write-up(3)]]></title>
            <link>https://velog.io/@jh_0517/Dream-Hack-write-up3</link>
            <guid>https://velog.io/@jh_0517/Dream-Hack-write-up3</guid>
            <pubDate>Thu, 04 May 2023 06:34:17 GMT</pubDate>
            <description><![CDATA[<p>사실 4주차 과제를 할 생각이 없었다. 그런데 갑자기 마감이 오늘까지라는 이야기를 들어서... 그냥 하기로 했다. <del>벌금을 좀 아껴보자</del> 오늘도 리버싱 문제를 3개 풀어보려고 한다. 지금 시간은 13시 41분. 마감은 6시 30분까지다. 화이팅 나새끼</p>
<h4 id="rev-basic-2">rev-basic-2</h4>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p>문제
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.</p>
</blockquote>
<p>지난 포스팅의 1번 문제와 동일하게 IDA를 이용하여 디컴파일을 진행한다. 
<a href="https://velog.io/@jh_0517/Dream-Hack-write-up2">https://velog.io/@jh_0517/Dream-Hack-write-up2</a>
디컴파일을 진행하면 아래와 같은 메인 함수를 얻을 수 있다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/0bda76d4-c82b-4b51-8f76-a49ab46dbfd0/image.png" alt="">sub_140001000으로 이동하면 조건에 대해 알 수 있다. <img src="https://velog.velcdn.com/images/jh_0517/post/1c22cfe7-3c58-402f-9cf4-b8a384115883/image.png" alt="">ac에 저장된 값과 입력한 값을 비교하고 값이 일치하면 Correct가 출력됨을 알 수 있다. aC로 이동해서 저장된 값을 알아보자. 이동하면 140003000의 주소가 기록되어있다. 4byte에 저장된 값을 나열하면 &#39;Comp4re_the_arr4y&#39;임을 알 수 있다.</p>
<p>flag = DH{Comp4re_the_arr4y}</p>
<h4 id="rev-basic-3">rev-basic-3</h4>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p>문제
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.</p>
</blockquote>
<p>디컴파일을 진행하면 아래와 같은 메인 함수를 얻을 수 있다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/9afb9a98-e55c-4bfd-8e9a-a1a2a2768ea0/image.png" alt="">
line 8의 if는 (unsigned int)sub_140001000(v4)이 true 값을 가지면 Correct를 출력한다. 해당 함수를 따라가면 이와 같은 함수를 확인할 수 있다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/778d3c98-0202-4701-b37b-8baa21ee6841/image.png" alt=""></p>
<p>자세히 읽어보면 140003000의 주소에 저장된 1-24번째 값을 읽으며, 입력받은 값을 연산한 후 비교하는 간단한 코드이다. 
일단 140003000에 저장된 값을 찾아보자. 
<img src="https://velog.velcdn.com/images/jh_0517/post/b16c76fd-85cf-471d-8674-4dbef0f9bcdf/image.png" alt=""></p>
<p>[49, 60, 69, 74, 36, 37, 42, 66, 80, 78, 69, 69, 7B, 99, 6D, 88, 68, 94, 9F, 8D, 4D, A5, 9D, 45]의 값을 가지고 있다. </p>
<p>해당 값에 i^(입력값[i]) + (2<em>i)의 역연산을 진행하면 원하는 값을 알 수 있다. 즉, (저장된 값[i]-(2</em>i)) ^ i연산을 진행하여 flag를 찾으면 된다. </p>
<p>[ 코드 ]</p>
<pre><code>value = [&#39;49&#39;,&#39;60&#39;,&#39;67&#39;,&#39;74&#39;,&#39;63&#39;,&#39;67&#39;,&#39;42&#39;,&#39;66&#39;,&#39;80&#39;,&#39;78&#39;,&#39;69&#39;,&#39;69&#39;,&#39;7B&#39;,&#39;99&#39;,&#39;6D&#39;,&#39;88&#39;,&#39;68&#39;,&#39;94&#39;,&#39;9F&#39;,&#39;8D&#39;,&#39;4D&#39;,&#39;A5&#39;,&#39;9D&#39;,&#39;45&#39;]
flag = &#39;&#39;

for i in range(23):
    flag += chr((int(value[i], 16) - (2*i)) ^ i)

print(flag)</code></pre><p>flag : DH{I_am_X0_xo_Xor_eXcit1ng}</p>
<h4 id="rev-basic-4">rev-basic-4</h4>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p>문제
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 알아내세요.
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/jh_0517/post/700928dc-02b5-4afb-aa8e-9ffe4c2de04f/image.png" alt=""><del>똑같은 사진이 3개째...</del>
앞의 문제와 똑같이 sub_140001000함수를 확인해보자.
<img src="https://velog.velcdn.com/images/jh_0517/post/82e2d6ec-5bd4-4739-9570-0402a470b964/image.png" alt="">다... 똑같고 그 식이 죅금 복잡해졌다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/88a62907-8cf9-4713-9d18-5d2925dc631f/image.png" alt=""> 저장된 값은<del>옮겨쓰기 귀찮다</del> [&#39;24&#39;, &#39;27&#39;, &#39;13&#39;, &#39;C6&#39;, &#39;C6&#39;, &#39;13&#39;, &#39;16&#39;, &#39;E6&#39;, &#39;47&#39;, &#39;F5&#39;, &#39;26&#39;, &#39;96&#39;, &#39;47&#39;, &#39;F5&#39;, &#39;46&#39;, &#39;27&#39;, &#39;13&#39;, &#39;26&#39;, &#39;26&#39;, &#39;C6&#39;, &#39;56&#39;, &#39;C3&#39;, &#39;C3&#39;, &#39;F5&#39;, &#39;E3&#39;, &#39;E3&#39;] 이다. </p>
<p>16X 입력값[i] | 입력값[i]&gt;&gt;4를 역 연산하면 flag를 찾을 수 있다. 
입력값[i]를 0x24라고 할 때, 16X입력값[i]의 값은 02 40가 된다. 입력값[i]&gt;&gt;4는 0x02가 된다. 02 40 | 02의 값은 0x42가 된다. 따라서 저장된 값의 첫번째 수와 두번째 수를 바꾼 다음 출력하면 flag를 얻을 수 있다. </p>
<pre><code>value = [&#39;24&#39;, &#39;27&#39;, &#39;13&#39;, &#39;C6&#39;, &#39;C6&#39;, &#39;13&#39;, &#39;16&#39;, &#39;E6&#39;, &#39;47&#39;, &#39;F5&#39;, &#39;26&#39;, &#39;96&#39;, &#39;47&#39;, &#39;F5&#39;, &#39;46&#39;, &#39;27&#39;, &#39;13&#39;, &#39;26&#39;, &#39;26&#39;, &#39;C6&#39;, &#39;56&#39;, &#39;F5&#39;, &#39;C3&#39;, &#39;C3&#39;, &#39;F5&#39;, &#39;E3&#39;, &#39;E3&#39;]
flag = &#39;&#39;

for i in range(len(value)):
    flag += chr(int(value[i][1]+value[i][0], 16))

print(flag)</code></pre><p>flag : 글씨로 쓰면 언더스코어가 안보인다... <img src="https://velog.velcdn.com/images/jh_0517/post/7d8e9355-ff0f-46ea-8fe2-62d96a519872/image.png" alt=""></p>
<p>문제가 다... 너무 똑같다. 약간 양심이 찔리지만 1시간 30분만에 과제 다 해서 행복하다. 리버싱은 가성비가 좋구나 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dream Hack write-up(2)]]></title>
            <link>https://velog.io/@jh_0517/Dream-Hack-write-up2</link>
            <guid>https://velog.io/@jh_0517/Dream-Hack-write-up2</guid>
            <pubDate>Thu, 06 Apr 2023 06:59:12 GMT</pubDate>
            <description><![CDATA[<p> 벌써 한 주가 지나서 새로운 숙제를 제출해야 할 때가 다가오고 있다. 저번에 제출 2시간 전부터 했더니 너무... 급하게 문제를 풀어야했어서 이번에는 이틀 전부터 해보려고 한다! </p>
<p> 저번에는 Crypto를 주로 풀었는데, 이번에는 새롭게 Reversing에 도전해보자. 먼저 Dream Hack에서 제공하는 리버싱 로드맵으로 공부하고 basic 문제 3개를 풀어 보는 것이 오늘의 계획이다!1!!</p>
<blockquote>
<p>Dream hack : 리버싱 로드맵
<a href="https://dreamhack.io/lecture/roadmaps/4">https://dreamhack.io/lecture/roadmaps/4</a></p>
</blockquote>
<p>역공학/리버스 엔지니어링/리버싱은 모두 같은 말입니다. 드림핵의 로드맵에 따르면 <strong>&quot;완성된 제품을 해체하고 분석하여 구조와 기능, 디자인을 파악&quot;</strong>하는 것이라고 한다. 자세한 설명들은 위의 로드맵 링크를 통해 알아보시길!</p>
<p><img src="https://velog.velcdn.com/images/jh_0517/post/551565de-33fd-404b-b381-75792508a2a8/image.png" alt=""></p>
<p>리버싱은.. 참 아는게 많아야하는 CTF 문제인것 같다. 고급언어 알아야하고, 컴파일 과정 및 방법 당연히 알아야하고, 어셈블리어도 읽고 해석할 줄 알아야하고 문제에 맞는 툴도 사용할 줄 알아야한다... 거기에 파일구조와 프로그램 구조까지 알아야한다. 그러니 전공 수업에서 컴퓨터 구조를 배운 후에 리버싱 문제를 푸는 것이 더 수월할 것이다. <del>안푸는게 제일 정신 건강에 좋다 암호에 이어.. 이런것만 건드리는 나도 제정신은 아닌듯...</del></p>
<p>아무튼... 서론이 길었다. 문제를 풀어보자</p>
<h3 id="rev_basic_0">rev_basic_0</h3>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p><strong>문제</strong>
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.</p>
</blockquote>
<p>문제파일을 다운로드 한 후, 실행하면 input 값을 요구하고 input 값에 따라 Wrong/correct가 출력된다. </p>
<blockquote>
<p>PS C:\Users\user\Downloads\rev-basic-0&gt; .\chall0.exe
Input : AAAA
Wrong</p>
</blockquote>
<p>물론 brute force 방식으로 정답을 알아내는 것도 가능하겠지만, 일단은 리버싱 문제이니 정적분석을 시도해보자. </p>
<p>IDA를 사용하면 파일을 분석하는 데 도움을 받을 수 있다. 
아래는 IDA로 문제 파일을 열었을 때 볼 수 있는 화면이다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/79f494a6-562b-4b25-9792-573fc2fabc2e/image.png" alt="">
우리는 현재 프로그램에서 wrong/correct라는 단어를 출력하는 것을 알고 있기 때문에, string 검색을 통해 해당 부분으로 이동해본다. Shift-F12 단축키를 사용하면 stirng view로 이동할 수 있다. 
키워드 검색을 통해 wrong을 찾았다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/a5c34290-2b69-4cda-9c78-894026c90f85/image.png" alt="">
해당 주소로 이동했을 때 볼 수 있는 코드
<img src="https://velog.velcdn.com/images/jh_0517/post/fd4b4b45-170d-4652-9168-0e869403d78e/image.png" alt=""></p>
<p>wrong을 선택한 후, x를 눌러서 해당 함수의 main을 찾고 다시 f5를 눌러서 디컴파일을 하면! 이런 결과를 얻을 수 있다. <del>그냥 한 번에 디컴파일까지 해줬으면 좋겠다</del>
<img src="https://velog.velcdn.com/images/jh_0517/post/f7020311-8eba-436e-ae43-b5704e12ea33/image.png" alt=""></p>
<p>코드를 보면, sub_140001190에서 &quot;Input : &quot;을 출력하고, sub_1400011F0에서 그 값을 입력받는 것을 알 수 있다. 그 아래 if에서 v4에 저장된 값을 sub_140001000에 전달해주고 그 값의 반환에 따라 Correct와 Wrong을 출력하는 것으로 보아, sub_140001000에서 입력한 값을 flag와 비교하고있다는 것을 알 수 있다. </p>
<p>sub_140001000 함수를 확인하면 Compar3_the_str1ng의 값을 입력받은 값과 비교하여 그 결과를 반환하고 있는 것을 확인할 수 있습니다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/8c2af16f-c6ea-4a4c-aa33-9376523882f2/image.png" alt=""></p>
<p>따라서! flag는 DH{Compar3_the_str1ng}입니다.</p>
<h3 id="rev_basic_1">rev_basic_1</h3>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p><strong>문제</strong>
Reversing Basic Challenge #1
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 알아내세요.
획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요.
예시) 입력 값이 Apple_Banana일 경우 flag는 DH{Apple_Banana}</p>
</blockquote>
<p>rev_basic_0와 같은 과정을 거쳐서 main 함수를 compiling하면 아래와 같은 결과를 얻을 수 있다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/a1cf4821-92fc-4bdd-b49e-792399dc09db/image.png" alt=""></p>
<p>마찬가지로 sub_140001000 함수를 확인하면 flag를 얻을 수 있다. </p>
<blockquote>
<p>_BOOL8 __fastcall sub_140001000(_BYTE *a1)
{
  if ( *a1 != 67 )
    return 0i64;
  if ( a1[1] != 111 )
    return 0i64;
  if ( a1[2] != 109 )
    return 0i64;
  if ( a1[3] != 112 )
    return 0i64;
  if ( a1[4] != 97 )
    return 0i64;
  if ( a1[5] != 114 )
    return 0i64;
  if ( a1[6] != 51 )
    return 0i64;
  if ( a1[7] != 95 )
    return 0i64;
  if ( a1[8] != 116 )
    return 0i64;
  if ( a1[9] != 104 )
    return 0i64;
  if ( a1[10] != 101 )
    return 0i64;
  if ( a1[11] != 95 )
    return 0i64;
  if ( a1[12] != 99 )
    return 0i64;
  if ( a1[13] != 104 )
    return 0i64;
  if ( a1[14] != 52 )
    return 0i64;
  if ( a1[15] != 114 )
    return 0i64;
  if ( a1[16] != 97 )
    return 0i64;
  if ( a1[17] != 99 )
    return 0i64;
  if ( a1[18] != 116 )
    return 0i64;
  if ( a1[19] != 51 )
    return 0i64;
  if ( a1[20] == 114 )
    return a1[21] == 0;
  return 0i64;
}</p>
</blockquote>
<p>숫자를 아스키 코드로 바꾸면 flag를 얻을 수 있다. </p>
<blockquote>
<p><em>BOOL8 __fastcall sub_140001000(_BYTE *a1)
{
  if ( *a1 != &#39;C&#39; )
    return 0i64;
  if ( a1[1] != &#39;o&#39; )
    return 0i64;
  if ( a1[2] != &#39;m&#39; )
    return 0i64;
  if ( a1[3] != &#39;p&#39; )
    return 0i64;
  if ( a1[4] != &#39;a&#39; )
    return 0i64;
  if ( a1[5] != &#39;r&#39; )
    return 0i64;
  if ( a1[6] != &#39;3&#39; )
    return 0i64;
  if ( a1[7] != &#39;</em>&#39; )
    return 0i64;
  if ( a1[8] != &#39;t&#39; )
    return 0i64;
  if ( a1[9] != &#39;h&#39; )
    return 0i64;
  if ( a1[10] != &#39;e&#39; )
    return 0i64;
  if ( a1[11] != &#39;_&#39; )
    return 0i64;
  if ( a1[12] != &#39;c&#39; )
    return 0i64;
  if ( a1[13] != &#39;h&#39; )
    return 0i64;
  if ( a1[14] != &#39;4&#39; )
    return 0i64;
  if ( a1[15] != &#39;r&#39; )
    return 0i64;
  if ( a1[16] != &#39;a&#39; )
    return 0i64;
  if ( a1[17] != &#39;c&#39; )
    return 0i64;
  if ( a1[18] != &#39;t&#39; )
    return 0i64;
  if ( a1[19] != &#39;3&#39; )
    return 0i64;
  if ( a1[20] == &#39;r&#39; )
    return a1[21] == 0;
  return 0i64;
}</p>
</blockquote>
<p>flag는 DH{Compar3_the_ch4ract3r}</p>
<h3 id="patch">patch</h3>
<p>🍇LEVEL 1 : Reversing</p>
<blockquote>
<p><strong>문제</strong>
flag를 그리는 루틴을 분석하고 가려진 flag를 보이게 해주세요.
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
GDI+ - Win32 apps | Microsoft Docs
Graphics Functions - Win32 apps | Microsoft Docs
File — x64dbg documentation</p>
</blockquote>
<p>문제에서 주어지는 파일을 다운로드 받은 후 실행하면 아래처럼 flag가 가려진 프로그램이 실행된다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/1a5dcceb-8b4f-41be-a3fb-8f763cc9fab5/image.png" alt=""></p>
<p>프로그램을 자체적으로 patch해서 flag를 가리는 부분을 제거해야한다. 
GUI 프로그램의 경우 WinMain 함수를 찾아야한다. IDA의 import 탭에서 보편적으로 윈도우 창을 만들 때 사용하는 CreateWindowExW 함수를 이용하여 WinMain 함수를 찾고, WinMain 함수를 이용하여 decompiling을 진행한다.
<img src="https://velog.velcdn.com/images/jh_0517/post/e8c67e8a-a391-44c6-8c7c-eafd6cf100c4/image.png" alt="">
<img src="https://velog.velcdn.com/images/jh_0517/post/f62255a6-4318-4afa-9b38-ef5de15c6a2f/image.png" alt=""></p>
<p>14번째 줄에서 lpfnWndProc가 메시지 처리 콜벡 함수를 등록한다. 윈도우를 생성하고 메시지를 처리할 때 여기에 등록한 함수를 사용하여 처리한다. 
여기에서 사용하고 있는 sub_1400032F0 함수를 들여다보면, BeginPaint와 EndPaint를 지정하고 있고, 중간에 sub_14002C40을 호출하고 있다. 즉, sub_14002C40 함수에서 Flag를 비롯한 무언가를 그리고 있다고 짐작할 수 있다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/fce3f6b9-0851-4deb-b925-e52ec4ba0d18/image.png" alt=""></p>
<p>sub_14002C40 함수를 보면 반복적으로 sub_140002B80 함수를 호출하는데, 해당 함수는 펜을 생성하고, 라인 1개를 그리고 펜을 제거하는 기능을한다. 따라서 이 함수가 FLAG를 그리는 함수라고  생각할 수 있다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/b612e6c3-3111-4c73-99ec-4b92600551c5/image.png" alt="">
<img src="https://velog.velcdn.com/images/jh_0517/post/270f1892-0ddb-4ae8-bbab-db0eb594586a/image.png" alt=""></p>
<p>이와 다르게 sub_1400017A0 함수를 살펴보면 반복적으로 펜을 생성하고 line을 그리고 있다. 따라서 함수가 Flag를 그리는 함수라고 생각할 수 있다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/00445c5d-9e23-4234-8307-8bd5234a0eec/image.png" alt="">
따라서 flag를 지우는 sub_140002B80 함수가 동작하지 않도록 IDA View-A 페이지에서 sub_140002B80함수를 찾은 후, Edit&gt;Patch Program &gt; Assemble을 이용하여 프로그램을 패치한다. Assemble에서 함수가 동작하지 않도록 ret를 삽입한다. </p>
<p>Edit&gt;Patch Progrm&gt;Apply Patchs to input file을 실행하면 flag가 가려지지 않은 프로그램이 만들어진다. 
프로그램을 다시 실행하면 flag를 얻을 수 있다.
<img src="https://velog.velcdn.com/images/jh_0517/post/1a55842b-6658-4e84-9702-090efd0d6c73/image.png" alt=""></p>
<p>flag는 DH{UPATCHED}</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dream Hack write-up(1)]]></title>
            <link>https://velog.io/@jh_0517/Dream-Hack-write-up1</link>
            <guid>https://velog.io/@jh_0517/Dream-Hack-write-up1</guid>
            <pubDate>Thu, 30 Mar 2023 09:18:30 GMT</pubDate>
            <description><![CDATA[<h3 id="icm2022">ICM2022</h3>
<p><strong>🍇LEVEL 1</strong> : <strong>Crypto</strong></p>
<blockquote>
<p><strong>문제 정보</strong>
Integral Cipher Master 2022 알고리즘을 사용하여 flag를 암호화 한것같은데…
복호화 할때 중요한 키와 복호화 코드를 실수로 지워버렸어요
암호화 된 flag를 다시 복호화 해주세요!</p>
</blockquote>
<blockquote>
<p><strong>readme</strong>
n = 3
key 1 = #cencored#
key 2 = 95
q = -200640142664324295933714
p = #cencored# (p is number)</p>
</blockquote>
<hr>
<p>if you get the p(decrypted q)
plz enter the p in the DH{here}</p>
<pre><code># 문제 코드 
def enc(p, n, key1, key2):
    q = (Fraction(p, n+1)*key1**(n+1)) - (Fraction(p, n+1)*key2**(n+1))
    print(&quot;[OK] plain is encrypted : &quot;, q)
    return q


def dec(q):
    a = 0


def key_make():
    n, key1, key2 = 0, 1, 0
    while key2 &lt; key1:
        n = random.randrange(1, 10)
        key1 = random.randrange(1, 100)
        key2 = random.randrange(1, 100)
    return n, key1, key2</code></pre><p>enc 함수에 따르면 p값은 아래와 같다. 
$$
p = \frac{q\times(n+1)}{key1^{(n+1)}-key2^{(n+1)}}
$$</p>
<p>위 수식을 코드로 구현하염 아래와 같다. </p>
<pre><code>p = Fraction(q*(n+1), key2**(n+1) - key1**(n+1))
</code></pre><p>처음 입력하는 p값이 정수일 것이라는 점에 착안하여 아래와 같이 코드를 작성하면 정답을 얻을 수 있다. </p>
<pre><code>from fractions import Fraction
n = 3
key2 = 95
q = -200640142664324295933714

for key1 in range(1, 95, 1) :
    p = Fraction(q*(n+1), key2**(n+1) - key1**(n+1))
    if p.numerator%p.denominator == 0:
        print(p)</code></pre><p>flag : DH{10112210997116104}</p>
<h3 id="robot-onlt">Robot Onlt</h3>
<p><strong>🍇LEVEL 1</strong> : <strong>Crypto, MISC</strong></p>
<blockquote>
<p><strong>문제정보</strong>
로봇만 이용할 수 있는 도박장이에요.
로봇임을 인증하고 경기에서 이겨 플래그를 구매하세요!</p>
</blockquote>
<p>접속하면 이런 메뉴가 뜬다. </p>
<blockquote>
<p>you&#39;re are now verified as a robot :]</p>
</blockquote>
<ol>
<li>go to gamble</li>
<li>verify you&#39;re a robot</li>
<li>buy flag</li>
<li>leave</li>
</ol>
<p>먼저 2. verify you&#39;re a robot을 선택해서 verify를 한 후, gamble을 통해 돈을 벌고, 마지막으로 3.buy flag로 flag를 얻으면 된다. </p>
<blockquote>
<p>=======================================</p>
</blockquote>
<ol>
<li>go to gamble</li>
<li>verify you&#39;re a robot</li>
<li>buy flag</li>
<li>leave<blockquote>
<p>2
please type this same: &quot;4438571604814975098817099123686656342147150658235533979780&quot;
4438571604814975098817099123686656342147150658235533979780
you&#39;re are now verified as a robot :]</p>
</blockquote>
</li>
</ol>
<p>시스템에서 원하는 숫자를 빠르게 입력하면 robot으로 verify 될 수 있다. 
물론 코드를 사용하는 방법도 있지만, 귀찮기 때문에 피지컬을 발휘해보자. 
생각보다 여유롭게 기다려주기 때문에 윈도우의 더블클릭을 이용하면 프로그램에서 원하는 만큼 빠르게 숫자를 입력할 수 있다. 
pwn에서 send하는데 자꾸 byte 형식으로 안 보낸다고 오류가 떠서 이런 방법을 사용하는 것은 <strong>절대로 아니니까</strong> 오해하지 않길 바란다. ^^ </p>
<p>아무튼 로봇으로 <strong>&gt;인정&lt;</strong> 받고나면 gamble 메뉴를 사용할 수 있다. 접속해보면 우리는 500원의 돈을 가지고 있는 것을 확인 할 수 있다. 
근데 flag를 구입하려면 10000000000원이 필요하다. 
그러니까, 연속해서 20번 이상 게임에서 승리하면 된다. 
1<del>5중에서 맞는 숫자를 입력하면 되니까 (1/5)^20 이상의 확률을 뚫고 돈을 벌면 된다. ~</del>되겠냐고~~ 그런 능력이 있다면 CTF 풀지 말고 강원랜드에 가면 된다. 많은 돈을 벌고 즐겁게 살아가면 된다. </p>
<p>gamble 함수를 보면 이를 회피할 방법이 있다. </p>
<pre><code>def gamble():
    global money
    global verified

    if verified is False:
        print(&#39;you\&#39;re are not verified as a robot ;[&#39;)
        return

    print(&#39;greetings, robot :]&#39;)

    bet = int(input(&#39;how much money do you want to bet (your money: ${0})? &#39;.format(money)))
    if money &lt; bet:
        print(&#39;you don\&#39;t have enough money (your money: ${0}).&#39;.format(money))
        return

    randn = get_randn()
    answer = randn % 5 + 1

    print(&#39;[1] [2] [3] [4] [5]&#39;)
    user_answer = int(input(&#39;pick one of the box &gt; &#39;))

    print(&#39;answer is [{0}]!&#39;.format(answer))

    if user_answer == answer:
        print(&#39;you earned ${0}.&#39;.format(bet))
        money += bet
    else:
        print(&#39;you lost ${0}.&#39;.format(bet))
        money -= bet

    if money &lt;= 0:
        print(&#39;you busted ;]&#39;)
        sys.exit()</code></pre><p>gamble에서 지면 그 만큼의 돈을 빼는 연산을 한다. 이를 이용해서 돈을 음수만큼 걸면 한 번에 많은 돈을 벌 수 있다. 프로그램에서는 내 돈보다 돈을 많이 거는 것만 금지하고 있고, 더 적은 돈을 버는 것은 괜찮기 때문에 적당히 -9999999999999999999999999만큼 돈을 걸면 4/5의 확률로 9999999999999999999999999의 돈을 벌 수 있다. 이렇게 우회하여 돈을 벌면 3번 메뉴를 선택하여 flag를 얻을 수 있다. </p>
<blockquote>
<p>=======================================</p>
</blockquote>
<ol>
<li>go to gamble</li>
<li>verify you&#39;re a robot</li>
<li>buy flag</li>
<li>leave<blockquote>
<p>3
price of the flag is $10,000,000,000.
b&#39;flag is DH{0086b1776b2b2dac7aebb790ec005ecf2bcce345c52225f03bb177b47a357a40}&#39;</p>
</blockquote>
</li>
</ol>
<p>flag : DH{0086b1776b2b2dac7aebb790ec005ecf2bcce345c52225f03bb177b47a357a40}</p>
<h3 id="chinese-what">chinese what?</h3>
<p><strong>🍇LEVEL 1</strong> : <strong>Crypto</strong></p>
<blockquote>
<p><strong>문제정보</strong>
CRT는 rsa에 많이 응용되는 정리입니다.
간단한 문제를 풀어보며 CRT란 무엇인지 알아보세요.
<del>문제 설명이 참 자세하기도 하다</del></p>
</blockquote>
<pre><code>cipher = [0x54, 0x58, 0x6b, 0x64, 0x58, 0x75, 0x4f, 0x7b, 0x21, 0x5c, 0x7c,
          0x75, 0x42, 0x4f, 0x21, 0x63, 0x4f, 0x74, 0x42, 0x75, 0x51, 0x7d, 0x6d]

for i in range(256):
    answer = &quot;&quot;
    for j in range(23):
        answer += str(hex(cipher[j]^i))[2:]
    print(answer)</code></pre><p>이렇게 코드를 돌리면 결과가 256개 나온다. 아 0을 제외하면 255개인다. 많이 줄어드네 ^^</p>
<blockquote>
<p>54586b6458754f7b215c7c75424f21634f744275517d6d
55596a6559744e7a205d7d74434e20624e754374507c6c
565a69665a774d79235e7e77404d23614d764077537f6f
575b68675b764c78225f7f76414c22604c774176527e6e
505c6f605c714b7f25587871464b25674b704671557969
515d6e615d704a7e24597970474a24664a714770547868
525e6d625e73497d275a7a734449276549724473577b6b
535f6c635f72487c265b7b724548266448734572567a6a
5c50636c507d47732954747d4a47296b477c4a7d597565
5d51626d517c46722855757c4b46286a467d4b7c587464
5e52616e527f45712b56767f48452b69457e487f5b7767
5f53606f537e44702a57777e49442a68447f497e5a7666
58546768547943772d5070794e432d6f43784e795d7161
59556669557842762c5171784f422c6e42794f785c7060
5a56656a567b41752f52727b4c412f6d417a4c7b5f7363
5b57646b577a40742e53737a4d402e6c407b4d7a5e7262
44487b7448655f6b314c6c65525f31735f645265416d7d
45497a7549645e6a304d6d64535e30725e655364406c7c
464a79764a675d69334e6e67505d33715d665067436f7f
474b78774b665c68324f6f66515c32705c675166426e7e
404c7f704c615b6f35486861565b35775b605661456979
414d7e714d605a6e34496960575a34765a615760446878
424e7d724e63596d374a6a635459377559625463476b7b
434f7c734f62586c364b6b625558367458635562466a7a
4c40737c406d57633944646d5a57397b576c5a6d496575
4d41727d416c56623845656c5b56387a566d5b6c486474
4e42717e426f55613b46666f58553b79556e586f4b6777
4f43707f436e54603a47676e59543a78546f596e4a6676
48447778446953673d4060695e533d7f53685e694d6171
49457679456852663c4161685f523c7e52695f684c6070
4a46757a466b51653f42626b5c513f7d516a5c6b4f6373
4b47747b476a50643e43636a5d503e7c506b5d6a4e6272
74784b4478556f5b17c5c55626f1436f546255715d4d
75794a4579546e5a07d5d54636e0426e556354705c4c
767a49467a576d5937e5e57606d3416d566057735f4f
777b48477b566c5827f5f56616c2406c576156725e4e
707c4f407c516b5f5785851666b5476b506651755949
717d4e417d506a5e4795950676a4466a516750745848
727e4d427e53695d77a5a53646974569526453775b4b
737f4c437f52685c67b5b52656864468536552765a4a
7c70434c705d6753974545d6a6794b675c6a5d795545
7d71424d715c6652875555c6b6684a665d6b5c785444
7e72414e725f6551b76565f6865b49655e685f7b5747
7f73404f735e6450a77575e6964a48645f695e7a5646
7874474874596357d7050596e63d4f63586e597d5141
7975464975586256c7151586f62c4e62596f587c5040
7a76454a765b6155f72525b6c61f4d615a6c5b7f5343
7b77444b775a6054e73535a6d60e4c605b6d5a7e5242
64685b5468457f4b116c4c45727f11537f447245614d5d
65695a5569447e4a106d4d44737e10527e457344604c5c
666a59566a477d49136e4e47707d13517d467047634f5f
676b58576b467c48126f4f46717c12507c477146624e5e
606c5f506c417b4f15684841767b15577b407641654959
616d5e516d407a4e14694940777a14567a417740644858
626e5d526e43794d176a4a437479175579427443674b5b
636f5c536f42784c166b4b427578165478437542664a5a
6c60535c604d77431964444d7a77195b774c7a4d694555
6d61525d614c76421865454c7b76185a764d7b4c684454
6e62515e624f75411b66464f78751b59754e784f6b4757
6f63505f634e74401a67474e79741a58744f794e6a4656
68645758644973471d6040497e731d5f73487e496d4151
69655659654872461c6141487f721c5e72497f486c4050
6a66555a664b71451f62424b7c711f5d714a7c4b6f4353
6b67545b674a70441e63434a7d701e5c704b7d4a6e4252
14182b241835f3b611c3c352f6123f34235113d2d
15192a251934e3a601d3d343e6022e35334103c2c
161a29261a37d39631e3e370d6321d36037133f2f
171b28271b36c38621f3f361c6220c37136123e2e
101c2f201c31b3f651838316b6527b30631153929
111d2e211d30a3e641939307a6426a31730143828
121e2d221e3393d671a3a33496725932433173b2b
131f2c231f3283c661b3b32586624833532163a2a
1c10232c103d7336914343da7692b73ca3d193525
1d11222d113c6326815353cb6682a63db3c183424
1e12212e123f5316b16363f856b2953e83f1b3727
1f13202f133e4306a17373e946a2843f93e1a3626
1814272814393376d103039e36d2f338e391d3121
1915262915382366c113138f26c2e239f381c3020
1a16252a163b1356f12323bc16f2d13ac3b1f3323
1b17242b173a0346e13333ad06e2c03bd3a1e3222
483b348251f2b71c2c25121f71331f24122512d3d
593a359241e2a70d2d24131e70321e25132402c3c
6a3936a271d2973e2e27101d73311d26102732f3f
7b3837b261c2872f2f26111c72301c27112622e3e
0c3f30c211b2f7582821161b75371b20162152939
1d3e31d201a2e7492920171a74361a21172042838
2e3d32e23192d77a2a23141977351922142372b3b
3f3c33f22182c76b2b22151876341823152262a3a
c0333c02d1723794242d1a17793b172c1a2d92535
d1323d12c1622785252c1b16783a162d1b2c82434
e2313e22f15217b6262f18157b39152e182fb2737
f3303f32e14207a7272e19147a38142f192ea2636
84373842913277d020291e137d3f13281e29d2131
95363952812267c121281f127c3e12291f28c2030
a6353a62b11257f2222b1c117f3d112a1c2bf2333
b7343b72a10247e3232a1d107e3c102b1d2ae2232
3438b438152f1b413c1c15222f4132f142215311dd
3539a539142e1a403d1d14232e4022e152314301cc
363a963a172d19433e1e17202d4312d162017331ff
373b873b162c18423f1f16212c4202c172116321ee
303cf03c112b1f45381811262b4572b10261135199
313de13d102a1e44391910272a4462a11271034188
323ed23e13291d473a1a13242947529122413371bb
333fc33f12281c463b1b12252846428132512361aa
3c303c301d27134934141d2a2749b271c2a1d39155
3d312d311c26124835151c2b2648a261d2b1c38144
3e321e321f25114b36161f28254b9251e281f3b177
3f330f331e24104a37171e29244a8241f291e3a166
383478341923174d3010192e234df23182e193d111
393569351822164c3111182f224ce22192f183c100
3a365a361b21154f32121b2c214fd211a2c1b3f133
3b374b371a20144e33131a2d204ec201b2d1a3e122
24281b142853fb512cc5323f51133f432521d1d
25291a152943ea502dd4333e50123e533420c1c
262a19162a73d9532ee7303d53113d630723f1f
272b18172b63c8522ff6313c52103c731622e1e
202c1f102c13bf552881363b55173b036125919
212d1e112d03ae542990373a54163a137024818
222e1d122e339d572aa33439571539234327b1b
232f1c132f238c562bb23538561438335226a1a
2c20131c20d37359244d3a37591b37c3ad29515
2d21121d21c36258255c3b36581a36d3bc28414
2e22111e22f3515b266f38355b1935e38f2b717
2f23101f23e3405a277e39345a1834f39e2a616
282417182493375d20093e335d1f3383e92d111
292516192583265c21183f325c1e3293f82c010
2a26151a26b3155f222b3c315f1d31a3cb2f313
2b27141b27a3045e233a3d305e1c30b3da2e212
d4d8ebe4d8f5cffba1dcfcf5c2cfa1e3cff4c2f5d1fded
d5d9eae5d9f4cefaa0ddfdf4c3cea0e2cef5c3f4d0fcec
d6dae9e6daf7cdf9a3defef7c0cda3e1cdf6c0f7d3ffef
d7dbe8e7dbf6ccf8a2dffff6c1cca2e0ccf7c1f6d2feee
d0dcefe0dcf1cbffa5d8f8f1c6cba5e7cbf0c6f1d5f9e9
d1ddeee1ddf0cafea4d9f9f0c7caa4e6caf1c7f0d4f8e8
d2deede2def3c9fda7dafaf3c4c9a7e5c9f2c4f3d7fbeb
d3dfece3dff2c8fca6dbfbf2c5c8a6e4c8f3c5f2d6faea
dcd0e3ecd0fdc7f3a9d4f4fdcac7a9ebc7fccafdd9f5e5
ddd1e2edd1fcc6f2a8d5f5fccbc6a8eac6fdcbfcd8f4e4
ded2e1eed2ffc5f1abd6f6ffc8c5abe9c5fec8ffdbf7e7
dfd3e0efd3fec4f0aad7f7fec9c4aae8c4ffc9fedaf6e6
d8d4e7e8d4f9c3f7add0f0f9cec3adefc3f8cef9ddf1e1
d9d5e6e9d5f8c2f6acd1f1f8cfc2aceec2f9cff8dcf0e0
dad6e5ead6fbc1f5afd2f2fbccc1afedc1faccfbdff3e3
dbd7e4ebd7fac0f4aed3f3facdc0aeecc0fbcdfadef2e2
c4c8fbf4c8e5dfebb1ccece5d2dfb1f3dfe4d2e5c1edfd
c5c9faf5c9e4deeab0cdede4d3deb0f2dee5d3e4c0ecfc
c6caf9f6cae7dde9b3ceeee7d0ddb3f1dde6d0e7c3efff
c7cbf8f7cbe6dce8b2cfefe6d1dcb2f0dce7d1e6c2eefe
c0ccfff0cce1dbefb5c8e8e1d6dbb5f7dbe0d6e1c5e9f9
c1cdfef1cde0daeeb4c9e9e0d7dab4f6dae1d7e0c4e8f8
c2cefdf2cee3d9edb7caeae3d4d9b7f5d9e2d4e3c7ebfb
c3cffcf3cfe2d8ecb6cbebe2d5d8b6f4d8e3d5e2c6eafa
ccc0f3fcc0edd7e3b9c4e4eddad7b9fbd7ecdaedc9e5f5
cdc1f2fdc1ecd6e2b8c5e5ecdbd6b8fad6eddbecc8e4f4
cec2f1fec2efd5e1bbc6e6efd8d5bbf9d5eed8efcbe7f7
cfc3f0ffc3eed4e0bac7e7eed9d4baf8d4efd9eecae6f6
c8c4f7f8c4e9d3e7bdc0e0e9ded3bdffd3e8dee9cde1f1
c9c5f6f9c5e8d2e6bcc1e1e8dfd2bcfed2e9dfe8cce0f0
cac6f5fac6ebd1e5bfc2e2ebdcd1bffdd1eadcebcfe3f3
cbc7f4fbc7ead0e4bec3e3eaddd0befcd0ebddeacee2f2
f4f8cbc4f8d5efdb81fcdcd5e2ef81c3efd4e2d5f1ddcd
f5f9cac5f9d4eeda80fdddd4e3ee80c2eed5e3d4f0dccc
f6fac9c6fad7edd983feded7e0ed83c1edd6e0d7f3dfcf
f7fbc8c7fbd6ecd882ffdfd6e1ec82c0ecd7e1d6f2dece
f0fccfc0fcd1ebdf85f8d8d1e6eb85c7ebd0e6d1f5d9c9
f1fdcec1fdd0eade84f9d9d0e7ea84c6ead1e7d0f4d8c8
f2fecdc2fed3e9dd87fadad3e4e987c5e9d2e4d3f7dbcb
f3ffccc3ffd2e8dc86fbdbd2e5e886c4e8d3e5d2f6daca
fcf0c3ccf0dde7d389f4d4ddeae789cbe7dceaddf9d5c5
fdf1c2cdf1dce6d288f5d5dcebe688cae6ddebdcf8d4c4
fef2c1cef2dfe5d18bf6d6dfe8e58bc9e5dee8dffbd7c7
fff3c0cff3dee4d08af7d7dee9e48ac8e4dfe9defad6c6
f8f4c7c8f4d9e3d78df0d0d9eee38dcfe3d8eed9fdd1c1
f9f5c6c9f5d8e2d68cf1d1d8efe28ccee2d9efd8fcd0c0
faf6c5caf6dbe1d58ff2d2dbece18fcde1daecdbffd3c3
fbf7c4cbf7dae0d48ef3d3daede08ecce0dbeddafed2c2
e4e8dbd4e8c5ffcb91ecccc5f2ff91d3ffc4f2c5e1cddd
e5e9dad5e9c4feca90edcdc4f3fe90d2fec5f3c4e0ccdc
e6ead9d6eac7fdc993eecec7f0fd93d1fdc6f0c7e3cfdf
e7ebd8d7ebc6fcc892efcfc6f1fc92d0fcc7f1c6e2cede
e0ecdfd0ecc1fbcf95e8c8c1f6fb95d7fbc0f6c1e5c9d9
e1edded1edc0face94e9c9c0f7fa94d6fac1f7c0e4c8d8
e2eeddd2eec3f9cd97eacac3f4f997d5f9c2f4c3e7cbdb
e3efdcd3efc2f8cc96ebcbc2f5f896d4f8c3f5c2e6cada
ece0d3dce0cdf7c399e4c4cdfaf799dbf7ccfacde9c5d5
ede1d2dde1ccf6c298e5c5ccfbf698daf6cdfbcce8c4d4
eee2d1dee2cff5c19be6c6cff8f59bd9f5cef8cfebc7d7
efe3d0dfe3cef4c09ae7c7cef9f49ad8f4cff9ceeac6d6
e8e4d7d8e4c9f3c79de0c0c9fef39ddff3c8fec9edc1d1
e9e5d6d9e5c8f2c69ce1c1c8fff29cdef2c9ffc8ecc0d0
eae6d5dae6cbf1c59fe2c2cbfcf19fddf1cafccbefc3d3
ebe7d4dbe7caf0c49ee3c3cafdf09edcf0cbfdcaeec2d2
9498aba498b58fbbe19cbcb5828fe1a38fb482b591bdad
9599aaa599b48ebae09dbdb4838ee0a28eb583b490bcac
969aa9a69ab78db9e39ebeb7808de3a18db680b793bfaf
979ba8a79bb68cb8e29fbfb6818ce2a08cb781b692beae
909cafa09cb18bbfe598b8b1868be5a78bb086b195b9a9
919daea19db08abee499b9b0878ae4a68ab187b094b8a8
929eada29eb389bde79abab38489e7a589b284b397bbab
939faca39fb288bce69bbbb28588e6a488b385b296baaa
9c90a3ac90bd87b3e994b4bd8a87e9ab87bc8abd99b5a5
9d91a2ad91bc86b2e895b5bc8b86e8aa86bd8bbc98b4a4
9e92a1ae92bf85b1eb96b6bf8885eba985be88bf9bb7a7
9f93a0af93be84b0ea97b7be8984eaa884bf89be9ab6a6
9894a7a894b983b7ed90b0b98e83edaf83b88eb99db1a1
9995a6a995b882b6ec91b1b88f82ecae82b98fb89cb0a0
9a96a5aa96bb81b5ef92b2bb8c81efad81ba8cbb9fb3a3
9b97a4ab97ba80b4ee93b3ba8d80eeac80bb8dba9eb2a2
8488bbb488a59fabf18caca5929ff1b39fa492a581adbd
8589bab589a49eaaf08dada4939ef0b29ea593a480acbc
868ab9b68aa79da9f38eaea7909df3b19da690a783afbf
878bb8b78ba69ca8f28fafa6919cf2b09ca791a682aebe
808cbfb08ca19baff588a8a1969bf5b79ba096a185a9b9
818dbeb18da09aaef489a9a0979af4b69aa197a084a8b8
828ebdb28ea399adf78aaaa39499f7b599a294a387abbb
838fbcb38fa298acf68baba29598f6b498a395a286aaba
8c80b3bc80ad97a3f984a4ad9a97f9bb97ac9aad89a5b5
8d81b2bd81ac96a2f885a5ac9b96f8ba96ad9bac88a4b4
8e82b1be82af95a1fb86a6af9895fbb995ae98af8ba7b7
8f83b0bf83ae94a0fa87a7ae9994fab894af99ae8aa6b6
8884b7b884a993a7fd80a0a99e93fdbf93a89ea98da1b1
8985b6b985a892a6fc81a1a89f92fcbe92a99fa88ca0b0
8a86b5ba86ab91a5ff82a2ab9c91ffbd91aa9cab8fa3b3
8b87b4bb87aa90a4fe83a3aa9d90febc90ab9daa8ea2b2
b4b88b84b895af9bc1bc9c95a2afc183af94a295b19d8d
b5b98a85b994ae9ac0bd9d94a3aec082ae95a394b09c8c
b6ba8986ba97ad99c3be9e97a0adc381ad96a097b39f8f
b7bb8887bb96ac98c2bf9f96a1acc280ac97a196b29e8e
b0bc8f80bc91ab9fc5b89891a6abc587ab90a691b59989
b1bd8e81bd90aa9ec4b99990a7aac486aa91a790b49888
b2be8d82be93a99dc7ba9a93a4a9c785a992a493b79b8b
b3bf8c83bf92a89cc6bb9b92a5a8c684a893a592b69a8a
bcb0838cb09da793c9b4949daaa7c98ba79caa9db99585
bdb1828db19ca692c8b5959caba6c88aa69dab9cb89484
beb2818eb29fa591cbb6969fa8a5cb89a59ea89fbb9787
bfb3808fb39ea490cab7979ea9a4ca88a49fa99eba9686
b8b48788b499a397cdb09099aea3cd8fa398ae99bd9181
b9b58689b598a296ccb19198afa2cc8ea299af98bc9080
bab6858ab69ba195cfb2929baca1cf8da19aac9bbf9383
bbb7848bb79aa094ceb3939aada0ce8ca09bad9abe9282
a4a89b94a885bf8bd1ac8c85b2bfd193bf84b285a18d9d
a5a99a95a984be8ad0ad8d84b3bed092be85b384a08c9c
a6aa9996aa87bd89d3ae8e87b0bdd391bd86b087a38f9f
a7ab9897ab86bc88d2af8f86b1bcd290bc87b186a28e9e
a0ac9f90ac81bb8fd5a88881b6bbd597bb80b681a58999
a1ad9e91ad80ba8ed4a98980b7bad496ba81b780a48898
a2ae9d92ae83b98dd7aa8a83b4b9d795b982b483a78b9b
a3af9c93af82b88cd6ab8b82b5b8d694b883b582a68a9a
aca0939ca08db783d9a4848dbab7d99bb78cba8da98595
ada1929da18cb682d8a5858cbbb6d89ab68dbb8ca88494
aea2919ea28fb581dba6868fb8b5db99b58eb88fab8797
afa3909fa38eb480daa7878eb9b4da98b48fb98eaa8696
a8a49798a489b387dda08089beb3dd9fb388be89ad8191
a9a59699a588b286dca18188bfb2dc9eb289bf88ac8090
aaa6959aa68bb185dfa2828bbcb1df9db18abc8baf8393
aba7949ba78ab084dea3838abdb0de9cb08bbd8aae8292</p>
</blockquote>
<p>이것들을 온라인 hex to ascii로 convert하면 flag를 찾을 수 있다. </p>
<p><img src="https://velog.velcdn.com/images/jh_0517/post/850a2adb-b0bc-418c-a8cc-84a5d83fd1af/image.png" alt=""></p>
<p>flag : DH{tHe_k1LleR_1s_dReAm}</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Fuzzer]]></title>
            <link>https://velog.io/@jh_0517/Fuzzer</link>
            <guid>https://velog.io/@jh_0517/Fuzzer</guid>
            <pubDate>Thu, 23 Mar 2023 07:17:39 GMT</pubDate>
            <description><![CDATA[<h3 id="fuzzzer-">Fuzzzer ?</h3>
<p><strong>퍼저(Fuzzer)</strong>는 소프트웨어 프로그램에 랜덤한 값을 입력하는 프로그램이다. 퍼저를 이용해서 <strong>퍼즈 테스팅(Fuzz testing)</strong> 또는 <strong>퍼징(fuzzing)</strong>은 이러한 퍼저를 사용하여 소프트웨어 프로그램의 문제를 테스트하는 기법이다. 주로 소프트웨어나 컴퓨터 시스템들의 보안 문제를 테스트하기 위해 사용된다. 퍼즈 테스팅은 HTTP api를 포함한 모든 프로그램에 적용 할 수 있다. </p>
<h3 id="fuzzer-기법">Fuzzer 기법</h3>
<p>Fuzzer에서 입력하는 값은 input의 형식과 관계 없이 완벽하게 무작위 값을 대입할 수도 있고, input의 형식과 맞는 무작위의 값을 대입 할 수도 있다. 또 Fuzzer가 무작위로 생성하는 값을 기준으로도 기법을 나눌 수 있다. </p>
<h4 id="dumb-fuzzer">Dumb Fuzzer</h4>
<p>소프트웨어 프로그램의 input에서 요구하는 입력값 형식과 상관없이 완전하게 랜덤한 값을 입력하는 Fuzzer이다. Dumb Fuzzer에서 사용할 수 있는 기법으로 Mutation Fuzzer가 있다.</p>
<p><strong>pros and cons</strong></p>
<table>
<thead>
<tr>
<th align="left">pros</th>
<th align="center">cons</th>
</tr>
</thead>
<tbody><tr>
<td align="left">Fuzzer를 만들기 위한 일의 양이 적다.</td>
<td align="center">완전히 무작위한 입력값으로모든 소프트웨어를 다루기 어렵다.<br>(Code coverage가 높다)</td>
</tr>
<tr>
<td align="left">Fuzzer의 기능과 설정이 직관적이다.</td>
<td align="center">프로그램 자체보다 프로그램 parser를 테스트 하게 된다.</td>
</tr>
</tbody></table>
<h4 id="smart-fuzzer">Smart Fuzzer</h4>
<p>소프트웨어 프로그램 input의 형식에 맞는 입력값을 생성하여 입력하는 Fuzzer이다. Generation-Based Fuzzer는 Smart Fuzzer에서 사용할 수 있는 기법 중 하나이다.</p>
<p><strong>pros and cons</strong></p>
<table>
<thead>
<tr>
<th align="left">pros</th>
<th align="center">cons</th>
</tr>
</thead>
<tbody><tr>
<td align="left">Dumb Fuzzer보다 더 적합한 값을 입력할 수 있다.<br>(높은 Code coverage)</td>
<td align="center">Fuzzer를 만드는 데 더 많은 노력이 필요하다.</td>
</tr>
<tr>
<td align="left">더 많은 bug를 잡아낼 수 있다.</td>
<td align="center"></td>
</tr>
</tbody></table>
<h4 id="mutation-based-fuzzer">Mutation-Based Fuzzer</h4>
<p>무작위로 생성된 대부분의 입력값은 프로그램의 입력값 filtering으로 거부될 수 있다. Mutation-Based Fuzzer는 이를 개선하기 위해 valid한 input을 약간 변형하는 방식으로 랜덤한 input을 생성한다.</p>
<h4 id="generation-based-fuzzer">Generation-Based Fuzzer</h4>
<p>제공된 valid한 input의 구조를 분석하여 이전의 데이터와 완전히 다른 새로운 input을 생성하는 기법이다. </p>
<h3 id="bug를-발생시킬-수-있다고-여겨지는-데이터들">Bug를 발생시킬 수 있다고 여겨지는 데이터들</h3>
<table>
<thead>
<tr>
<th align="left">Value</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody><tr>
<td align="left">Empty strings</td>
<td align="left">Sometimes, empty string by-pass missing value checks and trigger bugs</td>
</tr>
<tr>
<td align="left">Long strings</td>
<td align="left">Bugs as a result of truncation come to the surface as a result of passing long strings to programs</td>
</tr>
<tr>
<td align="left">Strings with variant length</td>
<td align="left">Short, medium, and long strings can trigger bugs as well</td>
</tr>
<tr>
<td align="left">0</td>
<td align="left">Similar to empty strings, value 0 can sometimes pass the missing value checks and trigger bugs</td>
</tr>
<tr>
<td align="left">Negative numbers</td>
<td align="left">Triggers bugs related to assuming positive numbers but lacking validation for that</td>
</tr>
<tr>
<td align="left">Decimals</td>
<td align="left">Triggers bugs related to assuming integers but lacking validation for that</td>
</tr>
<tr>
<td align="left">Special characters</td>
<td align="left">Bring up bugs related to embedding values in URL or saving in database</td>
</tr>
<tr>
<td align="left">Max / Min numbers</td>
<td align="left">Does the code cope well with a maximum allowed number? what about the minimum?</td>
</tr>
</tbody></table>
<p><br/><br/>
출처
<a href="https://ko.wikipedia.org/wiki/%ED%8D%BC%EC%A7%95">https://ko.wikipedia.org/wiki/%ED%8D%BC%EC%A7%95</a>
<a href="https://rninche01.tistory.com/entry/Fuzzing-%EA%B3%B5%EB%B6%80">https://rninche01.tistory.com/entry/Fuzzing-%EA%B3%B5%EB%B6%80</a>
<a href="https://testfully.io/blog/fuzz-testing/">https://testfully.io/blog/fuzz-testing/</a>
<a href="https://www.fuzzingbook.org/html/MutationFuzzer.html4">https://www.fuzzingbook.org/html/MutationFuzzer.html4</a>
<a href="https://cpuu.postype.com/post/589162">https://cpuu.postype.com/post/589162</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CTF write-up : OSINT]]></title>
            <link>https://velog.io/@jh_0517/CTF-write-up-OSINT</link>
            <guid>https://velog.io/@jh_0517/CTF-write-up-OSINT</guid>
            <pubDate>Fri, 17 Mar 2023 08:21:12 GMT</pubDate>
            <description><![CDATA[<p>학과 동아리의 일환으로 Hackday라는 CTF 대회에 참여하게 되었다. 
대회 기간에 작성하여 대회가 마무리된 이후(2023-03-19)에 공개 포스트롤 돌리려고 한다. </p>
<p>동아리 시간에는 OSINT가 아니고 MISC를 풀었는데, 이미 나보다 먼저 해당 문제를 해결한 동아리원이 있어서... 다른 문제를 풀어보았다. 
동아리원들 모두 문제 1개(혹은 dreamhack 문제 3개)의 write-up를 써야하는데, 고학번 체면상 <del>민첩한 하루 되세요</del>먼저 write-up을 올려버릴 수는 없기 때문이었다.. </p>
<h4 id="osint--open-source-intelligence">OSINT = Open Source INTelligence</h4>
<p>이 유형의 문제는 이미 공개된 정보(Open Source)를 이용해서 flag를 찾아야한다. 쉽게 말하자면 알아서 잘 검색해서 찾아봐라<del>뭐 그런거다. 보통은 google의 이미지 검색이나 사진(혹은 영상) 속의 키워드 등을 이용하여 검색해보는 게 일반적인 풀이이다. 
하지만 ~</del>이 미친 프랑스 새끼들~~ HackDay에서는 좀.. 난해한 사진들을 주어서 저런 예쁜 방법으로 flag를 찾을 수 없었다. </p>
<p>HackDay의 OSINT 문제는 총 3개인데 Vrooooom, A long time ago in a galaxy far, far away, A starry night sky이다. 
나는 이중에서 Vrooooom을 풀었는데, 왜냐면 사진/영상을 보면 안다. </p>
<img src="https://velog.velcdn.com/images/jh_0517/post/5b7ad4f1-b24f-44d4-883e-c5161cb166cc/image.jpg" height="200px" width="500px">
⬆️이게 Vroooom

<img src="https://velog.velcdn.com/images/jh_0517/post/3d7fcbb6-b587-4f14-a755-6662dd3d69af/image.jpg" height="100px" width="600px">
⬆️그리고 이게 A starry night sky

<p>그리고 A long time ago~는 아래 링크의 영상이다. 
<a href="https://www.youtube.com/watch?v=2q7esbZ0l0Y&amp;t=1s">https://www.youtube.com/watch?v=2q7esbZ0l0Y&amp;t=1s</a></p>
<p>자 딱 봐도 저 별 사진은 <del>인간이 할 게 아니다</del> 많이 어려워 보인다. 
그리고 영상은 생각하고 싶지 않다. ^^ </p>
<p>그래서 Vroooom을 하게 되었다 얼마나 좋아 회사 로고도 있고 자동차라는 것도 알 수 있고... 차에 대해서는 ㅊ도 모르지만 검색하면 뭐라고 나오겠지라는 마음으로 시작했다.</p>
<p>문제에서는 해당 사진이 찍혔던 event의 명칭을 찾으라고 했다.</p>
<blockquote>
<p>&lt; 문제 원문 &gt;
🇬🇧 The MIA (Intergalactic Automobile Museum) has just received a donation of several photo books from an old (probably very old) car collector. Among the documents was a photo of a car, but the curator was unable to determine its origin... He then decides to call on you, will you be able to give the name of the event where this photo was taken?
The flag is to be constructed in the form: HACKDAY{...} with &quot;...&quot; your answer respecting the case and without space</p>
</blockquote>
<p>어디서 나온 사진인지를 알아야하니까 가장 기본적인 google 이미지 검색을 돌려보았다. 그럼... 이딴식으로 나온다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/f94fa005-413d-431c-98d7-060d78dbc384/image.png" alt="">
이것도 내가 1시간 이상 서치해서 약간 걸러진.. 검색 결과다
<del>이 결과가 도움이 되었습니까? 아니요 아니요 아니요 아니요</del></p>
<p>그래서 어떻게 했냐면, 저 차에 적혀있는 여러 회사명을 같이 검색했다. 
그러면(아주 오랜 검색을 통해) Mission H24라는 곳의 스포츠카라는 것을 알 수 있다. 차가 2종류 나온다. 우리가 원하는 차는 두 번째 차다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/e2703113-32ff-473e-b1ac-c9c0b5438843/image.png" alt="">
그리고 Mission H24에서 행사 나갈 때 마다, 스폰서 로고가 조금씩 달라진다. 그래서 무작정 두번째 차가 출연(?)했던 행사명을 적으면, 틀린다. 당연하지 그렇게 flag 입력횟수를 5번 날려먹었다.</p>
<p>일단 우리에게 주어진 사진에 대한 정보가 더 필요할 것 같아서, Mission H24의 홈페이지(<a href="https://www.missionh24.fr/en/)%EC%99%80">https://www.missionh24.fr/en/)와</a> SNS 계정(facebook : <a href="https://es-la.facebook.com/missionh24">https://es-la.facebook.com/missionh24</a> / twitter : @MissionH24)을 뒤지기로 했다.</p>
<p>홈페이지에서는 별로 건진게 없다. 왜냐면, 일단 프랑스 웹 사이트에 접속해서 정보를 얻기 위해서는 엄청난 인내심이 필요하다. 프랑스 웹사이트라서 그런가 요청 처리 속도가 프랑스인 일 처리 속도 같다. 그리고 포스팅은 중요한 행사 정보만 해놔서 정보를 얻는데 제약이 있었다. <del>그래 솔직히 클릭 한 번 할 때마다 5분 기다리는게 환멸나서 안봤다.</del></p>
<p>facebook 계정을 뒤지다가 이 사진을 찾았다. 
<img src="https://velog.velcdn.com/images/jh_0517/post/f22bd8ae-0dee-4370-bc98-6aa7afcc7bbd/image.jpg" height="200px" width="500px"></p>
<p>천막 안에 차 있는거랑 날씨, 그리고 뒤에 있는 맥주 브랜드의 파라솔까지 똑같다. 하지만 이 사진으로도 행사 이름은 찾을 수 없다. 왜냐면 계정에는 정말 이 사진이랑 facebook에 사진을 올린 날짜만 적혀있었다. <del>망할 프랑스새끼들</del></p>
<p>그래도 2022/10/11이라는 날짜를 찾았으니, 이를 바탕으로 트위터 검색을 해보았다. 트위터에서는 트윗을 올린 계정/날짜/키워드 등등을 지정해서 검색할 수 있다. 트위터는 정보 검색할 때 꽤 유용하다. 트위터의 장점은 많은 정보를 접할 수 있다는 거고 단점은 알고 싶지 않았던 것까지 강제로 알려준다는 점이다. 예를 들어... 음 잊어버리자 
<img src="https://velog.velcdn.com/images/jh_0517/post/eb428d04-4381-4217-909d-ba27355d345f/image.png" height="200px" width="300px"></p>
<p>아무튼 트위터에 아래와 같이 검색하면, @MissionH24 계정에서 작성한 트윗 중 2022년 9월 30일 부터 2022년 10월 31일 사이에 작성한 것만 모아서 볼 수 있다. </p>
<blockquote>
<p>@MissionH24 since:2022-09-30 until:2022-10-31 </p>
</blockquote>
<p>보다보면 아래와 같은 트윗을 찾을 수 있다. 이 트윗 전에 레이싱 경기 트윗이 몇개 있긴 한데 그건 아니다. 왜냐면 내가 이미 넣어봤다. 아까 날린 5개 중에...
<img src="https://velog.velcdn.com/images/jh_0517/post/0b255648-9ded-42a2-9814-2ff63173cca5/image.png" height="200px" width="300px"></p>
<p>&quot;During the #GPExplorer, @xSqueeZie received a postcard from~&quot;이라고 써있으니 해당 행사의 이름은 GPExplorer이다. </p>
<h4 id="따라서-flag는-hackdaygpexplorer">따라서 flag는 HACKDAY{GPExplorer}!!!!</h4>
<p>정답 맞는거 확인하고 기뻐서 flag 찾고 생협 가서 과자 사먹었다. </p>
<p>모두 즐거운 ctf 되시길! ㅎㅎ</p>
<p>끝!</p>
]]></description>
        </item>
    </channel>
</rss>