<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>baguette.room</title>
    <link>https://threethreefivefive.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 29 Sep 2026 02:55:40 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>bage2room</managingEditor>
    <image>
      <title>baguette.room</title>
      <url>https://tistory1.daumcdn.net/tistory/6583892/attach/57e6c805448741ff82751a13b057c4f3</url>
      <link>https://threethreefivefive.tistory.com</link>
    </image>
    <item>
      <title>Breaking Bad (26 인코 ctf)</title>
      <link>https://threethreefivefive.tistory.com/71</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1401&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bizG9i/dJMb99STlTY/CxlQRnEdDFdTKncMKPF7X1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bizG9i/dJMb99STlTY/CxlQRnEdDFdTKncMKPF7X1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bizG9i/dJMb99STlTY/CxlQRnEdDFdTKncMKPF7X1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbizG9i%2FdJMb99STlTY%2FCxlQRnEdDFdTKncMKPF7X1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;361&quot; data-origin-width=&quot;1401&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영어 문장들이 적혀있는 텍스트 파일( gale_notebook.txt ), 문제 설명에 적힌 프로그램 파일이 주어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램 파일을 IDA 로 열어준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1161&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egqzrm/dJMcagYNgg4/lcDK7jorG7qlWimNDVVkQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egqzrm/dJMcagYNgg4/lcDK7jorG7qlWimNDVVkQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egqzrm/dJMcagYNgg4/lcDK7jorG7qlWimNDVVkQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fegqzrm%2FdJMcagYNgg4%2FlcDK7jorG7qlWimNDVVkQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;682&quot; height=&quot;1161&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;1161&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 main() 함수가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 설명에서는 프로그램이 무언가를 검증하고&lt;br /&gt;그 검증을 통과하는 정확한 입력값을 찾아야 한다고 했다. 그리고 텍스트 파일에 있는 시가 열쇠가 된다고 했다.&lt;/p&gt;
&lt;pre id=&quot;code_1771560837764&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;init_buffer(argc, argv, envp);
  if ( g_key_len &amp;gt; 0 )
  {
    printf(&quot;input: &quot;);
    if ( fgets(s, 256, _bss_start) )
    {
      s[strcspn(s, &quot;\r\n&quot;)] = 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;g_key&amp;nbsp;:&amp;nbsp;텍스트&amp;nbsp;파일에서&amp;nbsp;나온&amp;nbsp;암호화에&amp;nbsp;쓸&amp;nbsp;키 &lt;br /&gt;input&amp;nbsp;으로&amp;nbsp;사용자의&amp;nbsp;입력을&amp;nbsp;기다리고&amp;nbsp;strcspn()&amp;nbsp;으로&amp;nbsp;엔터키값&amp;nbsp;제거&lt;/p&gt;
&lt;pre id=&quot;code_1771561232746&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if ( (unsigned int)strlen(s) == 54 )
      {
        if ( (unsigned int)check_input((__int64)s) )
          puts(&quot;You're Goddamn Right&quot;);
        else
          puts(&quot;Wrong answer. Better call Saul!&quot;);
        return 0;
      }
      else
      {
        puts(&quot;Wrong length. Better call Saul!&quot;);
        return 1;
      }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력값이&amp;nbsp;정확히&amp;nbsp;54글자인지&amp;nbsp;확인 &lt;br /&gt;아닐경우&amp;nbsp;탈락 &lt;br /&gt;그리고&amp;nbsp;check_input()&amp;nbsp;함수를&amp;nbsp;거쳐서&amp;nbsp;입력값이&amp;nbsp;플래그와&amp;nbsp;일치하는지&amp;nbsp;확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;check_input() 함수를 보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;957&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bogmJ3/dJMcafFA5sz/lEgp9zqHpUKfKb2Z5Z9sv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bogmJ3/dJMcafFA5sz/lEgp9zqHpUKfKb2Z5Z9sv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bogmJ3/dJMcafFA5sz/lEgp9zqHpUKfKb2Z5Z9sv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbogmJ3%2FdJMcafFA5sz%2FlEgp9zqHpUKfKb2Z5Z9sv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;957&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;957&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771561388801&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for ( i = 0; i &amp;lt;= 53; ++i )
  {
    if ( (unsigned __int8)enc_byte(*(_BYTE *)(i + a1), i) != target_0[i] )
      return 0;
  }
  return 1;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0번&amp;nbsp;인덱스~53번&amp;nbsp;인덱스까지&amp;nbsp;검사 &lt;br /&gt;&lt;br /&gt;a1(사용자가 키보드로 입력한 글자에서 '현재 처리중인 한 글자'를 의미) 에서 i번째 글자 한개 가져옴 &lt;br /&gt;enc_byte()&amp;nbsp;를&amp;nbsp;거침 &lt;br /&gt;enc_byte()&amp;nbsp;를&amp;nbsp;거친&amp;nbsp;결과가&amp;nbsp;target_0[i]&amp;nbsp;와&amp;nbsp;일치하는지&amp;nbsp;확인 &lt;br /&gt;일치하면&amp;nbsp;return&amp;nbsp;1&amp;nbsp;(참) &lt;br /&gt;일치하지&amp;nbsp;않으면&amp;nbsp;return&amp;nbsp;0&amp;nbsp;(거짓)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;enc_byte() 함수를 보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;954&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blb4fG/dJMcaaxwMHg/vErqj3Qvn27x185wP2Fgu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blb4fG/dJMcaaxwMHg/vErqj3Qvn27x185wP2Fgu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blb4fG/dJMcaaxwMHg/vErqj3Qvn27x185wP2Fgu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fblb4fG%2FdJMcaaxwMHg%2FvErqj3Qvn27x185wP2Fgu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;423&quot; data-origin-width=&quot;989&quot; data-origin-height=&quot;954&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771561595050&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  return (unsigned __int8)swap4((unsigned __int8)(a2 + g_key[a2 % g_key_len]) ^ a1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1771561825419&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a2 + g_key[a2 % g_key_len]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;a2 = 현재 인덱스 번호를 알려주는 변&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;텍스트 파일에서 생성된 키 배열(g_key) 중 하나를 가져와 더함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(이때 인덱스가 키의 길이를 넘지 않도록 % 연산자를 사용함)&lt;/p&gt;
&lt;pre id=&quot;code_1771561993020&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(위에서 합친 값) ^ a1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 조합한 것과 사용자가 입력한 실제 글자(a1)를 XOR(^) 연산&lt;/p&gt;
&lt;pre id=&quot;code_1771562186590&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;swap4((위에서 합친 값) ^ a1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;swap4() 함수를 보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2eWSS/dJMb996sbfe/TK2KuPkYKzPL1zRIDteBzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2eWSS/dJMb996sbfe/TK2KuPkYKzPL1zRIDteBzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2eWSS/dJMb996sbfe/TK2KuPkYKzPL1zRIDteBzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2eWSS%2FdJMb996sbfe%2FTK2KuPkYKzPL1zRIDteBzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;339&quot; height=&quot;505&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;164&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771562349575&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  return (a1 &amp;gt;&amp;gt; 4) | (16 * (unsigned int)a1);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;a1 &amp;gt;&amp;gt; 4 : 비트를 오른쪽으로 4칸 민다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;16 * a1 : 곱하기 16은 비트를 왼쪽으로 4칸 미는 것과 같음!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;| : OR(|) 연산을 통해 두 값을 하나로 합친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 앞 4비트와 뒤 4비트를 swap 하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;target_0 값&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dn74NS/dJMb99ST9QK/K5db8qLqljOllri3Acvrb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dn74NS/dJMb99ST9QK/K5db8qLqljOllri3Acvrb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dn74NS/dJMb99ST9QK/K5db8qLqljOllri3Acvrb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdn74NS%2FdJMb99ST9QK%2FK5db8qLqljOllri3Acvrb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1272&quot; height=&quot;266&quot; data-origin-width=&quot;1272&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 입력한 글자를 enc_byte() 로 암호화했을 때, 이 target_0에 적힌 숫자들과 똑같이 나와야 통과된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 target_0 에 54바이트만큼 숫자가 있는 것이고 암호화된 결과물이라는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 해야할 것은 이 target_0 배열을 가지고 복호화를 해서 원본=플래그를 알아내는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호화 :&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 텍스트 파일을 읽어 숫자 배열인 g_key를 만든다.&lt;br /&gt;2. 위치 더하기: 입력한 글자의 인덱스(i)와 그에 해당하는 키 값(g_key[i])을 더한다.&lt;br /&gt;3. XOR : 위에서 만든 값과 사용자가 입력한 글자를 XOR(^) 연산.&amp;nbsp;&lt;br /&gt;4. 비트 위치 바꾸기 (swap4)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 복호화는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. target_0 배열에 들어있는 16진수 값 54개를 그대로 가져온다.&lt;br /&gt;2. 비트 위치 되돌리기 (swap4) : target_0의 값들에 다시 한번 swap4를 실행해서 원래대로 돌아오게 한다.&lt;br /&gt;3. XOR 되돌리기: 암호화 때 썼던 똑같은 키 값(index + key)을 가져와서 다시 XOR 해줘서 원래대로 돌아오게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 계산된 숫자(ASCII 코드)를 문자로 변환하여 합친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(내가 입력한 글자(내가 알아내야 하는 플래그)) ^ (g_key 관련 숫자) = target_0 인 것인데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;g_key 가 뭘까??&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 g_key 가 영어문자열인줄 알았지만 그러기엔 너무 길고,, 어떤 규칙이 있을까 찾아보다가&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lORaF/dJMcaiWAlyQ/t33edi9O2JK6lXVxNkvXvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lORaF/dJMcaiWAlyQ/t33edi9O2JK6lXVxNkvXvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lORaF/dJMcaiWAlyQ/t33edi9O2JK6lXVxNkvXvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlORaF%2FdJMcaiWAlyQ%2Ft33edi9O2JK6lXVxNkvXvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;263&quot; height=&quot;498&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기 왼쪽 함수명에 extract_spaces 로 되어있는 것을 발견했다. 즉 공백을 기준으로 키 배열을 만드는 것이 맞지 않을까 생각했다. 또 공백의 개수가 54 바이트와 비슷했다,,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1245&quot; data-origin-height=&quot;985&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mffdE/dJMcabpGJhW/xFhSw9JUyaJ0NojeuPWJOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mffdE/dJMcabpGJhW/xFhSw9JUyaJ0NojeuPWJOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mffdE/dJMcabpGJhW/xFhSw9JUyaJ0NojeuPWJOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmffdE%2FdJMcabpGJhW%2FxFhSw9JUyaJ0NojeuPWJOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1245&quot; height=&quot;985&quot; data-origin-width=&quot;1245&quot; data-origin-height=&quot;985&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;if ( v8 == 32 &amp;amp;&amp;amp; (int)v7 &amp;lt; a3 ) : 32 = 공백(Space)의 ASCII 코드&lt;br /&gt;*(_DWORD *)(a2 + 4LL * v4) = v6;&amp;nbsp; : 찾은 공백의 위치(v6)를 배열에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 복호화 과정을 파이썬 코드로 만들면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1771565461067&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import os

# 1. swap4() 함수
def swap(byte_val):
    return ((byte_val &amp;gt;&amp;gt; 4) | (byte_val &amp;lt;&amp;lt; 4)) &amp;amp; 0xFF
    # 문제 main 코드의 swap4() 함수랑 같음
    # 비트를 왼쪽으로 밀 때 8비트 범위를 넘을 수 있으므로 0xFF(=8비트)를 곱해서 크기고정

# 2. target_0 값
target_hex = (
    &quot;d4c47474d4a59644348ff684976605271466e6e6e6f6778351&quot;
    &quot;f13100babc4475c3c36345f4745536336293d202334c1c328365a09083&quot;
)
target_bytes = bytes.fromhex(target_hex)

# 3. 텍스트 파일 읽기, 줄바꿈 처리
file_path = &quot;gale_notebook.txt&quot;

with open(file_path, &quot;rb&quot;) as f:
    raw_data = f.read()

# 줄바꿈을 CRLF(\r\n)로 통일하여 인덱스 계산(엔터 글자수를 통일해주지 않으면 글자가 밀림)
normalized = raw_data.replace(b&quot;\r\n&quot;, b&quot;\n&quot;).replace(b&quot;\n&quot;, b&quot;\r\n&quot;)

# 4. 공백(= 0x20) 위치 찾기, 키 생성
space_pos = [] # 위치 번호를 담을 빈 바구니
for i, b in enumerate(normalized): # 번호(i)와 글자(b)를 하나씩 확인
    if b == 0x20: # 만약 글자가 공백이라면
        space_pos.append(i) # 그 번호(i)를 넣는다
# enumerate() : 리스트에서 값을 하나씩 꺼낼 때 몇번째인지의 순서(i)와 그 위치값(pos)을 동시에 가져오는 함수 
g_key = [] # 결과를 담을 빈 바구니
for i, pos in enumerate(space_pos): # 순서(i)와 위치(pos)를 하나씩 꺼내서
    temp = pos ^ (7 * i) # XOR 계산을 하고
    key_value = temp &amp;amp; 0xFF # 1바이트 크기로 자른다.
    g_key.append(key_value) 

# 5. 복호화
flag = &quot;&quot;
for i in range(len(target_bytes)):
    # swap =&amp;gt; XOR(key + index)
    val = swap(target_bytes[i])
    key_val = g_key[i % len(g_key)]
    plain_char = val ^ ((key_val + i) &amp;amp; 0xFF)
    flag += chr(plain_char)

print(&quot;flag:&quot;, flag)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 위 코드에서&lt;/p&gt;
&lt;pre id=&quot;code_1771568416444&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;temp = pos ^ (7 * i)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 순서 * 7을 해주지 않으면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것에 관해서는 extract_spaces() 함수 바로 다음에 실행되는 init_buffer() 안에서 찾을 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;950&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djnl8r/dJMcaf6EXXZ/tHbXT2nkqE8Bl3PvEGynq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djnl8r/dJMcaf6EXXZ/tHbXT2nkqE8Bl3PvEGynq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djnl8r/dJMcaf6EXXZ/tHbXT2nkqE8Bl3PvEGynq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdjnl8r%2FdJMcaf6EXXZ%2FtHbXT2nkqE8Bl3PvEGynq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1250&quot; height=&quot;950&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;950&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1771568577500&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;g_key[i] = v3[4 * i] ^ (7 * i);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v3[4 * i] = extract_spaces 함수가 텍스트파일에서 찾은 공백의 인덱스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;^ (7 * i) : 순서 * 7, XOR연산&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;g_key[i] : 암호 키&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ntIRj/dJMcadnrgFC/YKCWK6xXtaIa5cXjpO3nbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ntIRj/dJMcadnrgFC/YKCWK6xXtaIa5cXjpO3nbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ntIRj/dJMcadnrgFC/YKCWK6xXtaIa5cXjpO3nbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FntIRj%2FdJMcadnrgFC%2FYKCWK6xXtaIa5cXjpO3nbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1010&quot; height=&quot;86&quot; data-origin-width=&quot;1010&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 플래그는 INCOGNITO{your_answer_is_99.1_percent_pure_perfection} 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;(문제를 맞춘 학회원에게 이 플래그가 맞는지 확인받음.)&lt;/span&gt;&lt;/p&gt;</description>
      <category>워게임,CTF</category>
      <author>bage2room</author>
      <guid isPermaLink="true">https://threethreefivefive.tistory.com/71</guid>
      <comments>https://threethreefivefive.tistory.com/71#entry71comment</comments>
      <pubDate>Thu, 19 Feb 2026 17:29:08 +0900</pubDate>
    </item>
  </channel>
</rss>