<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>neck392</title>
    <link>https://neck392.tistory.com/</link>
    <description>https://github.com/neck392
https://huggingface.co/neck392</description>
    <language>ko</language>
    <pubDate>Thu, 25 Jun 2026 14:22:38 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>neck392</managingEditor>
    <image>
      <title>neck392</title>
      <url>https://tistory1.daumcdn.net/tistory/6873507/attach/93dcf888ef774cb7a48ef46c104610dc</url>
      <link>https://neck392.tistory.com</link>
    </image>
    <item>
      <title>[CNN] VGG 구조를 참고한 경량 CNN 설계</title>
      <link>https://neck392.tistory.com/120</link>
      <description>&lt;div style=&quot;font-family: 'Noto Sans KR', 'Apple SD Gothic Neo', sans-serif; line-height: 1.8; color: #222;&quot;&gt;

  &lt;h2 style=&quot;border-left: 6px solid #4f81bd; padding-left: 12px;&quot;&gt;
    VGG 구조를 참고한 경량 CNN 설계
  &lt;/h2&gt;

  &lt;p&gt;
    이번 글에서는 Food-101 음식 이미지 분류 프로젝트에서 사용한
    &lt;strong&gt;VGG 구조를 참고한 경량 CNN&lt;/strong&gt;을 정리한다.
    VGG-16은 Simonyan과 Zisserman이 제안한 CNN 구조로, 작은 3×3 convolution filter를 반복적으로 쌓아
    깊은 네트워크를 구성하는 방식이 이미지 분류에서 효과적임을 보였다 [2].
    본 프로젝트에서는 해당 설계 아이디어를 참고하여, 프로젝트 환경에 맞게 더 작은 CNN 구조로 재구성하였다.
  &lt;/p&gt;

  &lt;hr /&gt;

  &lt;h3&gt;1. VGG-16이란?&lt;/h3&gt;

  &lt;p&gt;
    VGG는 Simonyan과 Zisserman이 제안한 CNN 구조이다 [2].
    핵심 아이디어는 큰 convolution filter를 사용하는 대신,
    &lt;strong&gt;작은 3×3 convolution filter를 여러 층에 반복적으로 쌓는 것&lt;/strong&gt;이다.
    이를 통해 이미지의 지역적인 특징을 단계적으로 학습할 수 있다.
  &lt;/p&gt;

  &lt;p&gt;
    흔히 VGG-16이라고 부르지만, 여기서 16은 convolution layer만 16개라는 뜻이 아니다.
    VGG-16은 일반적으로 &lt;strong&gt;13개의 convolution layer와 3개의 fully connected layer&lt;/strong&gt;를 포함하여
    총 16개의 학습 가능한 weight layer를 갖는 구조를 의미한다.
    MaxPooling layer는 중간중간 사용되지만, 학습되는 가중치가 없기 때문에 16개 layer 수에 포함하지 않는다.
  &lt;/p&gt;

  &lt;div style=&quot;background: #f7f7f7; border-left: 5px solid #999; padding: 14px; margin: 18px 0;&quot;&gt;
    &lt;strong&gt;정리&lt;/strong&gt;&lt;br /&gt;
    VGG-16 = 13개 Conv layer + 3개 Fully Connected layer&lt;br /&gt;
    핵심 아이디어 = 작은 3×3 Conv를 반복적으로 쌓아 깊이를 늘리는 구조
  &lt;/div&gt;

  &lt;hr /&gt;

  &lt;h3&gt;2. 왜 VGG-16을 그대로 사용하지 않았는가?&lt;/h3&gt;

  &lt;p&gt;
    Food-101은 101개 음식 클래스를 가진 대규모 이미지 데이터셋이다.
    그러나 이번 프로젝트의 목적은 사전학습된 복잡한 모델을 사용하는 것이 아니라,
    직접 설계한 CNN을 통해 이미지 데이터 분류 과정을 이해하는 것이었다.
    따라서 VGG-16 전체 구조를 그대로 사용하지 않고,
    VGG의 핵심 아이디어만 가져와 경량 CNN으로 설계하였다.
  &lt;/p&gt;

  &lt;p&gt;
    즉, 본 프로젝트의 모델은 다음과 같이 이해할 수 있다.
  &lt;/p&gt;

  &lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 16px 0;&quot;&gt;
    &lt;thead&gt;
      &lt;tr style=&quot;background: #f0f3f7;&quot;&gt;
        &lt;th style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;구분&lt;/th&gt;
        &lt;th style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;설명&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;VGG-16&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;
          13개 Conv layer와 3개 FC layer를 갖는 깊은 CNN 구조
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;본 프로젝트 모델&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;
          VGG의 3×3 Conv 반복 아이디어를 참고한 경량 CNN
        &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;차이점&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;
          VGG-16 전체 구조를 사용하지 않고 Conv block 수와 파라미터 수를 줄임
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;hr /&gt;

  &lt;h3&gt;3. Baseline CNN 구조&lt;/h3&gt;

  &lt;p&gt;
    먼저 기준 모델로 단순한 Baseline CNN을 구성하였다.
    Baseline CNN은 각 단계에서 Conv2D를 한 번 적용한 뒤 MaxPooling을 수행하는 구조이다.
  &lt;/p&gt;

  &lt;pre style=&quot;background: #272822; color: #f8f8f2; padding: 16px; overflow-x: auto;&quot;&gt;&lt;code&gt;Input
→ Rescaling
→ Conv2D + MaxPooling
→ Conv2D + MaxPooling
→ Conv2D + MaxPooling
→ Conv2D
→ GlobalAveragePooling2D
→ Dense
→ Softmax&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;
    이 구조는 비교적 단순하기 때문에 기준 모델로 사용하기 좋다.
    하지만 Food-101처럼 클래스 수가 많고 음식 간 시각적 유사성이 큰 데이터셋에서는
    더 풍부한 특징 추출이 필요할 수 있다.
  &lt;/p&gt;

  &lt;hr /&gt;

  &lt;h3&gt;4. VGG 구조를 참고한 경량 CNN&lt;/h3&gt;

  &lt;p&gt;
    VGG 구조를 참고한 경량 CNN에서는 pooling을 하기 전에 Conv2D를 두 번 적용하였다.
    즉, 이미지 크기를 줄이기 전에 같은 해상도에서 특징을 한 번 더 추출하도록 구조를 바꾸었다.
    &lt;strong&gt;3×3 Conv를 반복한 뒤 pooling을 수행하는 설계 방향&lt;/strong&gt;을 참고하여 프로젝트 환경에 맞는 CNN을 설계하였다.
  &lt;/p&gt;

  &lt;pre style=&quot;background: #272822; color: #f8f8f2; padding: 16px; overflow-x: auto;&quot;&gt;&lt;code&gt;Input
→ Rescaling
→ Conv2D → BatchNorm → ReLU
→ Conv2D → BatchNorm → ReLU
→ MaxPooling

→ Conv2D → BatchNorm → ReLU
→ Conv2D → BatchNorm → ReLU
→ MaxPooling

→ Conv2D → BatchNorm → ReLU
→ Conv2D → BatchNorm → ReLU
→ MaxPooling

→ Conv2D → BatchNorm → ReLU
→ GlobalAveragePooling2D
→ Dense
→ Softmax&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;
    이 구조를 짧게 표현하면 다음과 같다.
  &lt;/p&gt;

  &lt;div style=&quot;background: #fff8e6; border: 1px solid #e0c57a; padding: 14px; margin: 18px 0;&quot;&gt;
    &lt;strong&gt;최종 구조의 핵심&lt;/strong&gt;&lt;br /&gt;
    (Conv2D + BatchNorm + ReLU) × 2 → MaxPooling
  &lt;/div&gt;

  &lt;p&gt;
    여기서 중요한 점은 &lt;strong&gt;Conv2D → Conv2D → BatchNorm&lt;/strong&gt; 순서가 아니라는 것이다.
    실제 구조는 각 Conv2D 뒤에 Batch Normalization과 ReLU를 적용하는 형태이다.
    즉, &lt;strong&gt;Conv2D → BatchNorm → ReLU&lt;/strong&gt; 단위를 반복한 뒤 MaxPooling을 수행한다.
  &lt;/p&gt;

  &lt;hr /&gt;

  &lt;h3&gt;5. Batch Normalization을 함께 사용한 이유&lt;/h3&gt;

  &lt;p&gt;
    convolution layer 수를 늘리면 모델이 더 많은 특징을 학습할 수 있지만,
    동시에 학습이 불안정해질 수도 있다.
    실제 실험에서도 Batch Normalization을 적용하지 않은 경량 CNN은 거의 무작위 예측에 가까운 성능을 보였다.
  &lt;/p&gt;

  &lt;p&gt;
    Batch Normalization은 Conv2D 이후 생성된 feature map의 값 분포를 mini-batch 단위로 정리하는 층이다 [3].
    이를 통해 학습 과정에서 중간 출력값이 지나치게 흔들리는 문제를 완화하고,
    깊어진 CNN 구조가 더 안정적으로 학습되도록 돕는다.
  &lt;/p&gt;

  &lt;p&gt;
    Batch Normalization에는 학습되는 값이 있다.
    대표적으로 &lt;strong&gt;gamma&lt;/strong&gt;와 &lt;strong&gt;beta&lt;/strong&gt;가 학습 가능한 파라미터이며,
    정규화된 값을 다시 조정하는 역할을 한다.
  &lt;/p&gt;

  &lt;hr /&gt;

  &lt;h3&gt;6. GlobalAveragePooling2D의 역할&lt;/h3&gt;

  &lt;p&gt;
    마지막 convolution layer의 출력은 예를 들어 16×16×128 형태의 feature map이다.
    이는 16×16 크기의 feature map이 128장 있다는 의미이다.
  &lt;/p&gt;

  &lt;p&gt;
    GlobalAveragePooling2D는 각 feature map의 모든 위치값을 평균내어 하나의 값으로 요약한다.
    따라서 16×16×128 형태의 출력을 128개의 값으로 줄일 수 있다.
    Global Average Pooling은 Network in Network 논문에서 feature map을 요약하는 방식으로 제안되었다 [4].
  &lt;/p&gt;

  &lt;pre style=&quot;background: #272822; color: #f8f8f2; padding: 16px; overflow-x: auto;&quot;&gt;&lt;code&gt;16 × 16 × 128
→ 각 feature map의 평균 계산
→ 128&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;
    이 방식은 Flatten을 사용해 모든 위치값을 그대로 펼치는 방식보다 Dense layer로 전달되는 입력 크기를 줄일 수 있다.
    따라서 모델을 더 간결하게 구성하는 데 도움이 된다.
  &lt;/p&gt;

  &lt;hr /&gt;

  &lt;h3&gt;7. Keras 구현 코드&lt;/h3&gt;

  &lt;p&gt;
    아래는 실제 프로젝트에서 사용한 VGG 구조 참고 경량 CNN의 핵심 구현이다.
  &lt;/p&gt;

  &lt;pre style=&quot;background: #272822; color: #f8f8f2; padding: 16px; overflow-x: auto;&quot;&gt;&lt;code&gt;from tensorflow import keras
from tensorflow.keras import layers

IMG_SIZE = 128
NUM_CLASSES = 101

def conv_unit_bn(x, filters, idx):
    x = layers.Conv2D(
        filters,
        kernel_size=3,
        padding=&quot;same&quot;,
        use_bias=False,
        name=f&quot;conv_{idx}&quot;
    )(x)

    x = layers.BatchNormalization(name=f&quot;bn_{idx}&quot;)(x)
    x = layers.ReLU(name=f&quot;relu_{idx}&quot;)(x)

    return x

def build_model():
    inputs = keras.Input(shape=(IMG_SIZE, IMG_SIZE, 3), name=&quot;input_image&quot;)

    x = layers.Rescaling(1./255, name=&quot;rescaling&quot;)(inputs)

    # Block 1
    x = conv_unit_bn(x, 32, idx=1)
    x = conv_unit_bn(x, 32, idx=2)
    x = layers.MaxPooling2D(pool_size=2, name=&quot;pool_1&quot;)(x)

    # Block 2
    x = conv_unit_bn(x, 64, idx=3)
    x = conv_unit_bn(x, 64, idx=4)
    x = layers.MaxPooling2D(pool_size=2, name=&quot;pool_2&quot;)(x)

    # Block 3
    x = conv_unit_bn(x, 128, idx=5)
    x = conv_unit_bn(x, 128, idx=6)
    x = layers.MaxPooling2D(pool_size=2, name=&quot;pool_3&quot;)(x)

    # Final Conv
    x = conv_unit_bn(x, 128, idx=7)

    x = layers.GlobalAveragePooling2D(name=&quot;global_average_pooling&quot;)(x)
    x = layers.Dense(128, activation=&quot;relu&quot;, name=&quot;dense_1&quot;)(x)

    outputs = layers.Dense(
        NUM_CLASSES,
        activation=&quot;softmax&quot;,
        name=&quot;class_output&quot;
    )(x)

    model = keras.Model(inputs=inputs, outputs=outputs)
    return model&lt;/code&gt;&lt;/pre&gt;

  &lt;hr /&gt;

  &lt;h3&gt;8. Label Smoothing 적용&lt;/h3&gt;

  &lt;p&gt;
    최종 모델에서는 Label Smoothing도 함께 적용하였다.
    일반적인 one-hot encoding은 정답 클래스만 1이고 나머지 클래스는 0으로 둔다.
    반면 Label Smoothing은 정답 클래스의 값을 조금 낮추고,
    나머지 클래스에도 작은 확률을 나누어 주는 방식이다 [5].
  &lt;/p&gt;

  &lt;pre style=&quot;background: #272822; color: #f8f8f2; padding: 16px; overflow-x: auto;&quot;&gt;&lt;code&gt;일반 one-hot encoding
정답 클래스: 1.0
오답 클래스: 0.0

Label Smoothing
정답 클래스: 0.9
오답 클래스: 작은 확률 분배&lt;/code&gt;&lt;/pre&gt;

  &lt;p&gt;
    Food-101은 101개 음식 클래스를 갖고 있으며,
    서로 시각적으로 유사한 음식도 많다.
    따라서 모델이 특정 정답 클래스에 지나치게 확신하는 것을 줄이기 위해 Label Smoothing을 적용하였다.
  &lt;/p&gt;

  &lt;pre style=&quot;background: #272822; color: #f8f8f2; padding: 16px; overflow-x: auto;&quot;&gt;&lt;code&gt;loss_fn = keras.losses.CategoricalCrossentropy(
    label_smoothing=0.1
)&lt;/code&gt;&lt;/pre&gt;

  &lt;hr /&gt;

  &lt;h3&gt;9. 실험 결과&lt;/h3&gt;

  &lt;p&gt;
    실험 결과, 단순 Baseline CNN보다 VGG 구조를 참고한 경량 CNN에
    Batch Normalization과 Label Smoothing을 적용한 모델이 가장 좋은 validation 성능을 보였다.
    특히 Batch Normalization을 적용하지 않은 경량 CNN은 거의 무작위 예측에 가까운 성능을 보였지만,
    Batch Normalization을 추가한 뒤 성능이 크게 향상되었다.
  &lt;/p&gt;

  &lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 16px 0;&quot;&gt;
    &lt;thead&gt;
      &lt;tr style=&quot;background: #f0f3f7;&quot;&gt;
        &lt;th style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;모델&lt;/th&gt;
        &lt;th style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;Val Accuracy&lt;/th&gt;
        &lt;th style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;Val Top-5 Accuracy&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;Baseline CNN&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.3399&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.6230&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;경량 CNN&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.0099&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.0495&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;경량 CNN + BatchNorm&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.4646&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.7491&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr style=&quot;background: #fff8e6;&quot;&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;&lt;strong&gt;경량 CNN + BatchNorm + Label Smoothing&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;&lt;strong&gt;0.4952&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;&lt;strong&gt;0.7684&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;p&gt;
    최종 test set 평가에서는 다음과 같은 성능을 확인하였다.
  &lt;/p&gt;

  &lt;table style=&quot;border-collapse: collapse; width: 100%; margin: 16px 0;&quot;&gt;
    &lt;thead&gt;
      &lt;tr style=&quot;background: #f0f3f7;&quot;&gt;
        &lt;th style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;지표&lt;/th&gt;
        &lt;th style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;값&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;Test Accuracy&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.5354&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;Test Top-5 Accuracy&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.8128&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;Macro F1-score&lt;/td&gt;
        &lt;td style=&quot;border: 1px solid #ccc; padding: 10px;&quot;&gt;0.5384&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;hr /&gt;

  &lt;h3&gt;10. 정리&lt;/h3&gt;

  &lt;p&gt;
    이번 실험에서 가장 중요한 점은 모델을 단순히 깊게 만드는 것만으로는 충분하지 않았다는 점이다.
    실제로 Batch Normalization을 적용하지 않은 경량 CNN은 거의 무작위 예측에 가까운 성능을 보였다.
    반면 VGG의 3×3 Conv 반복 구조를 참고하되, 각 Conv 뒤에 Batch Normalization과 ReLU를 추가한 모델은 성능이 크게 개선되었다.
    여기에 Label Smoothing을 적용하자 validation accuracy와 validation top-5 accuracy가 모두 가장 높게 나타났다.
  &lt;/p&gt;

  &lt;div style=&quot;background: #eaf4ff; border-left: 5px solid #4f81bd; padding: 14px; margin: 18px 0;&quot;&gt;
    &lt;strong&gt;최종 결론&lt;/strong&gt;&lt;br /&gt;
    VGG 구조의 핵심 아이디어인 3×3 Conv 반복 구조를 적용하여 경량 CNN을 설계하고,&lt;br /&gt;
    Batch Normalization으로 학습을 안정화하며,&lt;br /&gt;
    Label Smoothing으로 과도한 확신을 줄였을 때 Food-101 분류 성능이 가장 좋았다.
  &lt;/div&gt;

  &lt;hr /&gt;

  &lt;h3&gt;Reference&lt;/h3&gt;

  &lt;ol&gt;
    &lt;li&gt;
      L. Bossard, M. Guillaumin, and L. Van Gool,
      &lt;em&gt;Food-101 – Mining Discriminative Components with Random Forests&lt;/em&gt;,
      Computer Vision – ECCV 2014 Workshops, 2014.
    &lt;/li&gt;
    &lt;li&gt;
      K. Simonyan and A. Zisserman,
      &lt;em&gt;Very Deep Convolutional Networks for Large-Scale Image Recognition&lt;/em&gt;,
      International Conference on Learning Representations, 2015.
    &lt;/li&gt;
    &lt;li&gt;
      S. Ioffe and C. Szegedy,
      &lt;em&gt;Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift&lt;/em&gt;,
      International Conference on Machine Learning, 2015.
    &lt;/li&gt;
    &lt;li&gt;
      M. Lin, Q. Chen, and S. Yan,
      &lt;em&gt;Network in Network&lt;/em&gt;,
      International Conference on Learning Representations, 2014.
    &lt;/li&gt;
    &lt;li&gt;
      C. Szegedy, V. Vanhoucke, S. Ioffe, J. Shlens, and Z. Wojna,
      &lt;em&gt;Rethinking the Inception Architecture for Computer Vision&lt;/em&gt;,
      IEEE Conference on Computer Vision and Pattern Recognition, 2016.
    &lt;/li&gt;
  &lt;/ol&gt;

&lt;/div&gt;</description>
      <category>AI_Machine_Learning</category>
      <category>AI</category>
      <category>CNN</category>
      <category>dl</category>
      <category>ML</category>
      <category>NN</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/120</guid>
      <comments>https://neck392.tistory.com/120#entry120comment</comments>
      <pubDate>Mon, 8 Jun 2026 05:16:39 +0900</pubDate>
    </item>
    <item>
      <title>AEPC(Adaptive Excess-Preserving Clipping) 제안</title>
      <link>https://neck392.tistory.com/119</link>
      <description>&lt;h2&gt;AEPC(Adaptive Excess-Preserving Clipping): 극단값을 단순 절단하지 않고 초과 정보를 보존하는 전처리 전략&lt;/h2&gt;

&lt;p&gt;정형 데이터 기반 회귀 모델을 학습하다 보면 자주 마주치는 문제가 있다. 바로 &lt;b&gt;극단값(outlier)&lt;/b&gt;이다. 일부 feature는 대부분의 값이 특정 구간에 몰려 있지만, 소수의 값이 매우 크거나 매우 작게 나타난다. 이러한 극단값은 모델 학습 과정에서 손실을 크게 만들거나, 특정 변수의 영향력을 과도하게 키워 모델이 전체적인 데이터 경향을 안정적으로 학습하는 것을 방해할 수 있다.&lt;/p&gt;

&lt;p&gt;일반적으로 이러한 문제를 완화하기 위해 &lt;b&gt;clipping&lt;/b&gt;을 적용한다. 가장 흔한 방식은 특정 분위수를 기준으로 값을 제한하는 &lt;b&gt;Quantile Clipping&lt;/b&gt;이다. 하지만 Quantile Clipping은 기준을 벗어난 값을 모두 동일한 상한 또는 하한으로 고정하기 때문에, 극단값이 가지고 있던 상대적 크기 정보가 사라질 수 있다.&lt;/p&gt;

&lt;p&gt;이 문제를 완화하기 위해 본 프로젝트에서는 &lt;b&gt;AEPC(Adaptive Excess-Preserving Clipping)&lt;/b&gt;라는 전처리 전략을 설계하였다.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;AEPC는 극단값을 완전히 잘라내지 않고, 기준값을 벗어난 초과 정보의 일부를 보존하는 전처리 방식이다.&lt;/p&gt;&lt;/blockquote&gt;

&lt;hr&gt;

&lt;h3&gt;1. 실험 데이터 개요&lt;/h3&gt;

&lt;p&gt;실험에는 와인 품질 예측 데이터를 사용하였다. 데이터는 총 &lt;b&gt;4,898개 샘플과 12개 컬럼&lt;/b&gt;으로 구성되어 있으며, 11개의 입력 feature와 &lt;code&gt;quality&lt;/code&gt; 종속변수를 가진다. 실제 관측된 &lt;code&gt;quality&lt;/code&gt; 값은 3부터 9까지 존재하였다.&lt;/p&gt;

&lt;p&gt;입력 feature는 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;fixed acidity&lt;/li&gt;
  &lt;li&gt;volatile acidity&lt;/li&gt;
  &lt;li&gt;citric acid&lt;/li&gt;
  &lt;li&gt;residual sugar&lt;/li&gt;
  &lt;li&gt;chlorides&lt;/li&gt;
  &lt;li&gt;free sulfur dioxide&lt;/li&gt;
  &lt;li&gt;total sulfur dioxide&lt;/li&gt;
  &lt;li&gt;density&lt;/li&gt;
  &lt;li&gt;pH&lt;/li&gt;
  &lt;li&gt;sulphates&lt;/li&gt;
  &lt;li&gt;alcohol&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;전체 데이터는 train/validation/test를 60/20/20 비율로 분할하였다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;train set: 2,938개&lt;/li&gt;
  &lt;li&gt;validation set: 980개&lt;/li&gt;
  &lt;li&gt;test set: 980개&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;이 중 &lt;code&gt;residual sugar&lt;/code&gt;, &lt;code&gt;chlorides&lt;/code&gt;, &lt;code&gt;total sulfur dioxide&lt;/code&gt;, &lt;code&gt;density&lt;/code&gt; 등은 일부 값이 분포의 꼬리 부분에 크게 치우쳐 있어 극단값 완화가 필요한 변수로 확인되었다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;2. 기존 Quantile Clipping 방식&lt;/h3&gt;

&lt;p&gt;Quantile Clipping은 train set 기준으로 하위 분위수와 상위 분위수를 계산한 뒤, 해당 범위를 벗어난 값을 각각 하한값과 상한값으로 고정하는 방식이다.&lt;/p&gt;

&lt;p&gt;예를 들어 하위 1% 분위수를 \(q_{0.01}\), 상위 99% 분위수를 \(q_{0.99}\)라고 하면 Quantile Clipping은 다음과 같이 정의할 수 있다.&lt;/p&gt;

\[
x' =
\begin{cases}
q_{0.01}, &amp; x \lt q_{0.01} \\
x, &amp; q_{0.01} \le x \le q_{0.99} \\
q_{0.99}, &amp; x \gt q_{0.99}
\end{cases}
\]

&lt;p&gt;즉, 아래쪽 극단값은 하위 1% 분위수로 끌어올리고, 위쪽 극단값은 상위 99% 분위수로 낮춘다.&lt;/p&gt;

&lt;p&gt;실제 데이터에서 Quantile Clipping 기준은 다음과 같이 계산되었다.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;q01 lower&lt;/th&gt;&lt;th&gt;q99 upper&lt;/th&gt;&lt;th&gt;min before&lt;/th&gt;&lt;th&gt;max before&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;fixed acidity&lt;/td&gt;&lt;td&gt;5.0000&lt;/td&gt;&lt;td&gt;9.2000&lt;/td&gt;&lt;td&gt;3.8000&lt;/td&gt;&lt;td&gt;14.2000&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;residual sugar&lt;/td&gt;&lt;td&gt;0.9000&lt;/td&gt;&lt;td&gt;18.8630&lt;/td&gt;&lt;td&gt;0.7000&lt;/td&gt;&lt;td&gt;65.8000&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;chlorides&lt;/td&gt;&lt;td&gt;0.0200&lt;/td&gt;&lt;td&gt;0.1570&lt;/td&gt;&lt;td&gt;0.0120&lt;/td&gt;&lt;td&gt;0.3460&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;total sulfur dioxide&lt;/td&gt;&lt;td&gt;50.0000&lt;/td&gt;&lt;td&gt;243.0000&lt;/td&gt;&lt;td&gt;9.0000&lt;/td&gt;&lt;td&gt;366.5000&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;density&lt;/td&gt;&lt;td&gt;0.9889&lt;/td&gt;&lt;td&gt;1.00038&lt;/td&gt;&lt;td&gt;0.98711&lt;/td&gt;&lt;td&gt;1.03898&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;예를 들어 &lt;code&gt;residual sugar&lt;/code&gt;의 경우 train set 기준 상위 99% 분위수는 18.863이고, 원본 최댓값은 65.8이었다. 따라서 Quantile Clipping을 적용하면 다음과 같이 변환된다.&lt;/p&gt;
\[65.8 \rightarrow 18.863\]

&lt;p&gt;또한 &lt;code&gt;total sulfur dioxide&lt;/code&gt;의 경우 원본 최댓값 366.5는 상위 99% 분위수인 243.0으로 제한된다.&lt;/p&gt;
\[366.5 \rightarrow 243.0\]

&lt;p&gt;하단 극단값도 동일하게 처리된다. &lt;code&gt;fixed acidity&lt;/code&gt;의 경우 하위 1% 분위수가 5.0이고, 원본 최솟값이 3.8이므로 다음과 같이 변환된다.&lt;/p&gt;
\[3.8 \rightarrow 5.0\]

&lt;p&gt;이 방식은 극단값의 영향을 줄이는 데 효과적이다. 그러나 상한을 초과한 값들은 모두 같은 값으로 바뀌고, 하한보다 작은 값들도 모두 같은 값으로 바뀐다. 즉, 극단값 구간 안에서 원래 값들이 가지고 있던 상대적 차이가 사라진다.&lt;/p&gt;

&lt;p&gt;예를 들어 &lt;code&gt;residual sugar&lt;/code&gt;의 상위 극단값들은 원래 서로 다른 크기를 갖지만, Quantile Clipping 이후에는 모두 18.863으로 고정된다.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Original&lt;/th&gt;&lt;th&gt;Quantile Clipping&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;65.80&lt;/td&gt;&lt;td&gt;18.863&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;26.05&lt;/td&gt;&lt;td&gt;18.863&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;23.50&lt;/td&gt;&lt;td&gt;18.863&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;20.70&lt;/td&gt;&lt;td&gt;18.863&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;즉, Quantile Clipping은 안정적이지만, 극단값의 &lt;b&gt;상대적 순서와 크기 정보&lt;/b&gt;를 제거한다는 한계가 있다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;3. 기존 클리핑 방식을 개선하기 위한 AEPC 제안&lt;/h3&gt;

&lt;p&gt;AEPC는 이러한 한계를 완화하기 위해 설계한 방식이다. AEPC는 극단값을 기준값으로 완전히 고정하지 않고, 기준값을 벗어난 부분의 일부만 보존한다.&lt;/p&gt;

&lt;p&gt;이를 위해 하단 cap과 상단 cap을 각각 정의한다.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;lower cap: \(c_L\)&lt;/li&gt;&lt;li&gt;upper cap: \(c_U\)&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;그리고 하단 극단값과 상단 극단값에 대해 각각 보존 비율을 둔다.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;lower alpha: \(\alpha_L\)&lt;/li&gt;&lt;li&gt;upper alpha: \(\alpha_U\)&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;양방향 AEPC는 다음과 같이 정의할 수 있다.&lt;/p&gt;
\[
x' =
\begin{cases}
c_L + \alpha_L(x - c_L), &amp; x \lt c_L \\
x, &amp; c_L \le x \le c_U \\
c_U + \alpha_U(x - c_U), &amp; x \gt c_U
\end{cases}
\]

&lt;p&gt;이 수식에서 \(x\)는 원본 값, \(x'\)는 AEPC 적용 후 값이다.&lt;/p&gt;
&lt;p&gt;하단 극단값에서는 \(x - c_L\)이 음수이다. 따라서 \(x\)가 하단 cap보다 작으면, 원래 값과 cap 사이의 차이를 \(\alpha_L\) 비율만큼만 보존한다.&lt;/p&gt;
&lt;p&gt;상단 극단값에서는 \(x - c_U\)가 양수이다. 따라서 \(x\)가 상단 cap보다 크면, cap을 초과한 부분을 \(\alpha_U\) 비율만큼만 보존한다.&lt;/p&gt;

&lt;p&gt;여기서 \(\alpha\)는 hard clipping과 원본 유지 사이의 절충 정도를 의미한다.&lt;/p&gt;
\[\alpha = 0 \Rightarrow \text{hard clipping}\]
\[\alpha = 1 \Rightarrow \text{original value}\]

&lt;p&gt;즉, \(\alpha\)가 0에 가까울수록 기존 clipping처럼 강하게 값을 제한하고, \(\alpha\)가 1에 가까울수록 원본 값을 더 많이 유지한다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;4. AEPC cap 계산 방식&lt;/h3&gt;

&lt;p&gt;AEPC에서는 cap을 단순히 1%와 99% 분위수로 고정하지 않는다. 각 feature의 분포를 기준으로 하단 cap과 상단 cap을 따로 계산한다.&lt;/p&gt;
&lt;p&gt;먼저 다음 통계량을 계산한다.&lt;/p&gt;
\[Q_1,\ Q_3,\ IQR\]
&lt;p&gt;여기서 IQR은 다음과 같다.&lt;/p&gt;
\[IQR = Q_3 - Q_1\]
&lt;p&gt;상단 cap 후보는 다음과 같이 계산한다.&lt;/p&gt;
\[c_{U,raw} = Q_3 + 3.0 \times IQR\]
&lt;p&gt;하단 cap 후보는 다음과 같이 계산한다.&lt;/p&gt;
\[c_{L,raw} = Q_1 - 3.0 \times IQR\]

&lt;p&gt;일반적인 IQR 기반 이상치 기준에서는 \(1.5 \times IQR\)을 많이 사용하지만, AEPC에서는 \(3.0 \times IQR\)을 사용하였다. 그 이유는 너무 많은 값을 극단값으로 간주하지 않고, 실제 꼬리 영역에 해당하는 값만 완화하기 위해서이다.&lt;/p&gt;

&lt;p&gt;다만 raw cap이 너무 낮거나 높게 설정되는 것을 방지하기 위해 분위수 범위로 한 번 더 제한한다.&lt;/p&gt;
&lt;p&gt;상단 cap은 다음과 같이 제한한다.&lt;/p&gt;
\[c_U = \min(\max(c_{U,raw}, Q_{97.5}), Q_{99.5})\]
&lt;p&gt;즉, 상단 cap은 다음 범위 안에서 결정된다.&lt;/p&gt;
\[Q_{97.5} \le c_U \le Q_{99.5}\]
&lt;p&gt;하단 cap은 다음과 같이 제한한다.&lt;/p&gt;
\[c_L = \min(\max(c_{L,raw}, Q_{0.5}), Q_{2.5})\]
&lt;p&gt;즉, 하단 cap은 다음 범위 안에서 결정된다.&lt;/p&gt;
\[Q_{0.5} \le c_L \le Q_{2.5}\]

&lt;p&gt;이렇게 하면 AEPC는 대부분의 일반적인 값은 그대로 유지하고, 하단과 상단의 꼬리 영역에 해당하는 값만 완화한다.&lt;/p&gt;

&lt;p&gt;실제 데이터에서 Bidirectional AEPC 기준은 다음과 같이 계산되었다.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;lower cap&lt;/th&gt;&lt;th&gt;upper cap&lt;/th&gt;&lt;th&gt;min before&lt;/th&gt;&lt;th&gt;max before&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;fixed acidity&lt;/td&gt;&lt;td&gt;4.8000&lt;/td&gt;&lt;td&gt;9.6000&lt;/td&gt;&lt;td&gt;3.8000&lt;/td&gt;&lt;td&gt;14.2000&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;residual sugar&lt;/td&gt;&lt;td&gt;0.8000&lt;/td&gt;&lt;td&gt;19.84725&lt;/td&gt;&lt;td&gt;0.7000&lt;/td&gt;&lt;td&gt;65.8000&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;chlorides&lt;/td&gt;&lt;td&gt;0.018685&lt;/td&gt;&lt;td&gt;0.100725&lt;/td&gt;&lt;td&gt;0.0120&lt;/td&gt;&lt;td&gt;0.3460&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;total sulfur dioxide&lt;/td&gt;&lt;td&gt;32.3700&lt;/td&gt;&lt;td&gt;249.9725&lt;/td&gt;&lt;td&gt;9.0000&lt;/td&gt;&lt;td&gt;366.5000&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;density&lt;/td&gt;&lt;td&gt;0.988614&lt;/td&gt;&lt;td&gt;1.000631&lt;/td&gt;&lt;td&gt;0.98711&lt;/td&gt;&lt;td&gt;1.03898&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;이 기준을 보면 AEPC는 Quantile Clipping처럼 값을 분위수 경계에 바로 고정하지 않고, 각 feature의 분포와 tail 특성을 반영하여 완화 기준을 정한다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;5. alpha 계산 방식&lt;/h3&gt;

&lt;p&gt;AEPC에서 가장 중요한 값은 \(\alpha\)이다. \(\alpha\)는 cap을 벗어난 값을 얼마나 보존할지 결정한다.&lt;/p&gt;
&lt;p&gt;본 프로젝트에서는 \(\alpha\)를 고정값으로 두지 않고, feature별 tail 특성을 반영하여 계산하였다.&lt;/p&gt;
&lt;p&gt;이를 위해 세 가지 점수를 사용하였다.&lt;/p&gt;
\[S_{tail},\ S_{target},\ S_{cont}\]

&lt;p&gt;각 점수의 의미는 다음과 같다.&lt;/p&gt;
&lt;table&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;\(S_{tail}\)&lt;/td&gt;&lt;td&gt;cap을 벗어난 값이 얼마나 반복적으로 등장하는가&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;\(S_{target}\)&lt;/td&gt;&lt;td&gt;cap 밖의 값들이 target과 얼마나 관련되어 있는가&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;\(S_{cont}\)&lt;/td&gt;&lt;td&gt;tail이 한두 개만 튀는 형태인지, 연속적으로 존재하는지&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;최종 보존 점수는 다음과 같이 계산하였다.&lt;/p&gt;
\[S_{preserve} = 0.3S_{tail} + 0.5S_{target} + 0.2S_{cont}\]

&lt;p&gt;그리고 이를 \(\alpha\)로 변환한다.&lt;/p&gt;
\[\alpha = \alpha_{min} + (\alpha_{max} - \alpha_{min})S_{preserve}\]

&lt;p&gt;실험에서는 다음 범위를 사용하였다.&lt;/p&gt;
\[\alpha_{min} = 0.1\]
\[\alpha_{max} = 0.9\]

&lt;p&gt;따라서 \(S_{preserve}\)가 클수록 \(\alpha\)가 커지고, cap을 벗어난 정보를 더 많이 보존한다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;6. 각 스코어의 정의&lt;/h3&gt;

&lt;h4&gt;6.1 Tail Ratio Score&lt;/h4&gt;

&lt;p&gt;먼저 cap을 벗어난 샘플 집합을 정의한다. 상단 tail은 다음과 같다.&lt;/p&gt;
\[T_U = \{x_i \mid x_i \gt c_U\}\]
&lt;p&gt;하단 tail은 다음과 같다.&lt;/p&gt;
\[T_L = \{x_i \mid x_i \lt c_L\}\]
&lt;p&gt;전체 샘플 수를 \(n\)이라고 하면 tail ratio는 다음과 같다.&lt;/p&gt;
\[r_{tail} = \frac{|T|}{n}\]
&lt;p&gt;이를 기준 tail 비율 \(r_{ref}\)와 비교해 점수화한다.&lt;/p&gt;
\[S_{tail} = \min\left(\frac{r_{tail}}{r_{ref}}, 1\right)\]
&lt;p&gt;본 프로젝트에서는 \(r_{ref}=0.05\)를 기준으로 두었다. 즉, cap 밖의 값이 전체의 5%에 가까울수록 tail ratio score가 커진다.&lt;/p&gt;
&lt;p&gt;이 점수는 cap 밖의 값이 단순히 우연히 등장한 이상치인지, 아니면 어느 정도 반복적으로 나타나는 분포의 일부인지를 판단하기 위한 값이다.&lt;/p&gt;

&lt;h4&gt;6.2 Target Signal Score&lt;/h4&gt;

&lt;p&gt;극단값을 보존할지 판단할 때 가장 중요한 기준은 target과의 관련성이다.&lt;/p&gt;
&lt;p&gt;따라서 AEPC에서는 tail 구간의 target 평균과 일반 구간의 target 평균 차이를 계산한다. tail 구간의 target 값을 \(y_{tail}\), 나머지 구간의 target 값을 \(y_{body}\)라고 하면 다음과 같이 정의할 수 있다.&lt;/p&gt;
\[
S_{target} =
\min\left(
\frac{|\mu(y_{tail}) - \mu(y_{body})|}{\sigma(y)},
1
\right)
\]

&lt;p&gt;이 수식은 다음 질문에 답한다.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;cap 밖의 값들이 실제 quality와 관련된 차이를 가지고 있는가?&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;만약 tail 구간의 quality 평균이 body 구간의 quality 평균과 많이 다르다면, 해당 극단값은 단순 노이즈가 아니라 예측에 의미 있는 신호일 수 있다.&lt;/p&gt;

&lt;h4&gt;6.3 Tail Continuity Score&lt;/h4&gt;

&lt;p&gt;마지막으로 tail이 한두 개만 튀는 형태인지, 아니면 꼬리 구간이 어느 정도 연속적으로 존재하는지를 확인한다.&lt;/p&gt;
&lt;p&gt;상단 tail에서는 excess를 다음과 같이 정의한다.&lt;/p&gt;
\[e_i = x_i - c_U,\quad x_i \gt c_U\]
&lt;p&gt;하단 tail에서는 excess를 다음과 같이 정의한다.&lt;/p&gt;
\[e_i = c_L - x_i,\quad x_i \lt c_L\]
&lt;p&gt;즉, cap에서 얼마나 벗어났는지를 양수로 계산한다.&lt;/p&gt;
&lt;p&gt;Tail continuity score는 다음과 같이 계산한다.&lt;/p&gt;
\[S_{cont} = \frac{\operatorname{median}(e)}{\max(e) + \epsilon}\]
&lt;p&gt;여기서 \(\epsilon\)은 0으로 나누는 것을 방지하기 위한 작은 값이다.&lt;/p&gt;
&lt;p&gt;이 값은 tail이 일부 값만 비정상적으로 튀는 형태인지, 아니면 꼬리 구간이 비교적 연속적으로 존재하는지를 판단하기 위한 보조 지표이다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;7. 알파값을 정하기 위한 스코어 계수(가중치)&lt;/h3&gt;

&lt;p&gt;AEPC의 보존 점수는 다음과 같이 계산된다.&lt;/p&gt;
\[S_{preserve} = 0.3S_{tail} + 0.5S_{target} + 0.2S_{cont}\]

&lt;p&gt;이 계수는 모델이 자동으로 학습한 값이 아니라, AEPC의 설계 목적을 반영한 &lt;b&gt;경험적 가중치&lt;/b&gt;이다.&lt;/p&gt;

&lt;p&gt;가장 큰 가중치는 \(S_{target}\)에 부여하였다.&lt;/p&gt;
\[0.5S_{target}\]
&lt;p&gt;AEPC의 목적은 극단값을 무조건 보존하는 것이 아니다. 예측에 의미 있을 가능성이 있는 극단값을 더 많이 보존하는 것이다. 따라서 tail 구간이 target과 얼마나 관련되어 있는지가 가장 중요한 기준이라고 판단하였다.&lt;/p&gt;

&lt;p&gt;두 번째로 큰 가중치는 \(S_{tail}\)에 부여하였다.&lt;/p&gt;
\[0.3S_{tail}\]
&lt;p&gt;cap 밖의 값이 한두 개만 존재한다면 단순 이상치일 가능성이 크다. 반면 cap 밖의 값이 반복적으로 나타난다면 해당 feature가 원래 가지고 있는 분포 특성일 수 있다. 따라서 tail ratio는 target signal보다는 낮지만 중요한 보조 기준으로 보았다.&lt;/p&gt;

&lt;p&gt;마지막으로 \(S_{cont}\)에는 가장 낮은 가중치를 부여하였다.&lt;/p&gt;
\[0.2S_{cont}\]
&lt;p&gt;tail continuity는 tail이 연속적인지 확인하는 지표이지만, target과 직접적으로 연결되는 기준은 아니다. 따라서 보조적인 안정성 판단 기준으로 두었다.&lt;/p&gt;

&lt;p&gt;정리하면 AEPC의 가중치 구조는 다음 우선순위를 반영한다.&lt;/p&gt;
\[S_{target} \gt S_{tail} \gt S_{cont}\]
&lt;p&gt;즉, 다음과 같다.&lt;/p&gt;
\[0.5 \gt 0.3 \gt 0.2\]

&lt;hr&gt;

&lt;h3&gt;8. 실제 데이터 적용 예시 1: residual sugar&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;residual sugar&lt;/code&gt;는 상단 극단값이 매우 크게 나타난 feature이다.&lt;/p&gt;
&lt;p&gt;train set에서 &lt;code&gt;residual sugar&lt;/code&gt;의 Quantile Clipping 상한은 18.863이고, 원본 최댓값은 65.8이었다. 반면 AEPC의 상단 cap은 19.84725, 상단 alpha는 0.223661로 계산되었다.&lt;/p&gt;
&lt;p&gt;Quantile Clipping을 적용하면 다음과 같다.&lt;/p&gt;
\[65.8 \rightarrow 18.863\]
&lt;p&gt;AEPC를 적용하면 다음과 같이 계산된다.&lt;/p&gt;
\[x' = c_U + \alpha_U(x - c_U)\]
\[x' = 19.84725 + 0.223661(65.8 - 19.84725)\]
\[x' = 19.84725 + 0.223661 \times 45.95275\]
\[x' \approx 30.125\]
&lt;p&gt;즉, Quantile Clipping은 65.8을 18.863으로 강하게 절단하지만, AEPC는 30.125로 완화한다.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Original&lt;/th&gt;&lt;th&gt;Quantile Clipping&lt;/th&gt;&lt;th&gt;AEPC&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;65.80&lt;/td&gt;&lt;td&gt;18.863&lt;/td&gt;&lt;td&gt;30.125&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;26.05&lt;/td&gt;&lt;td&gt;18.863&lt;/td&gt;&lt;td&gt;21.235&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;23.50&lt;/td&gt;&lt;td&gt;18.863&lt;/td&gt;&lt;td&gt;20.664&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;20.70&lt;/td&gt;&lt;td&gt;18.863&lt;/td&gt;&lt;td&gt;20.038&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이 결과를 보면 AEPC는 극단값을 그대로 두지는 않지만, 원래 값이 더 컸다는 상대적 정보는 유지한다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;9. 실제 데이터 적용 예시 2: total sulfur dioxide&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;total sulfur dioxide&lt;/code&gt;도 AEPC의 특성이 잘 드러나는 feature이다.&lt;/p&gt;
&lt;p&gt;train set에서 &lt;code&gt;total sulfur dioxide&lt;/code&gt;의 Quantile Clipping 상한은 243.0이고, 원본 최댓값은 366.5였다. 반면 AEPC의 상단 cap은 249.9725, 상단 alpha는 0.531410으로 계산되었다.&lt;/p&gt;
&lt;p&gt;Quantile Clipping을 적용하면 다음과 같다.&lt;/p&gt;
\[366.5 \rightarrow 243.0\]
&lt;p&gt;AEPC를 적용하면 다음과 같다.&lt;/p&gt;
\[x' = c_U + \alpha_U(x - c_U)\]
\[x' = 249.9725 + 0.531410(366.5 - 249.9725)\]
\[x' = 249.9725 + 0.531410 \times 116.5275\]
\[x' \approx 311.896\]
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Original&lt;/th&gt;&lt;th&gt;Quantile Clipping&lt;/th&gt;&lt;th&gt;AEPC&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;366.5&lt;/td&gt;&lt;td&gt;243.0&lt;/td&gt;&lt;td&gt;311.896&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;344.0&lt;/td&gt;&lt;td&gt;243.0&lt;/td&gt;&lt;td&gt;299.940&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;307.5&lt;/td&gt;&lt;td&gt;243.0&lt;/td&gt;&lt;td&gt;280.543&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;272.0&lt;/td&gt;&lt;td&gt;243.0&lt;/td&gt;&lt;td&gt;261.678&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Quantile Clipping은 상한을 초과한 값을 모두 243.0으로 고정한다. 반면 AEPC는 초과분의 약 53%를 보존하여 원래 값들의 상대적 크기 차이를 유지한다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;10. 실제 데이터 적용 예시 3: 하단 극단값&lt;/h3&gt;
&lt;p&gt;AEPC는 상단 극단값뿐 아니라 하단 극단값도 같은 원리로 처리할 수 있다.&lt;/p&gt;
&lt;p&gt;예를 들어 &lt;code&gt;fixed acidity&lt;/code&gt;의 경우 Quantile Clipping 하한은 5.0이고 원본 최솟값은 3.8이었다. Bidirectional AEPC에서는 하단 cap이 4.8로 계산되었다.&lt;/p&gt;
&lt;p&gt;Quantile Clipping은 다음과 같이 처리한다.&lt;/p&gt;
\[3.8 \rightarrow 5.0\]
&lt;p&gt;반면 AEPC는 하단 cap을 기준으로 다음 수식을 적용한다.&lt;/p&gt;
\[x' = c_L + \alpha_L(x - c_L)\]
&lt;p&gt;여기서 \(x - c_L\)는 음수이다. 따라서 원본 값이 cap보다 낮았다는 정보를 일부 보존하면서, 값을 cap 방향으로 완화한다.&lt;/p&gt;
&lt;p&gt;예를 들어 설명을 위해 \(c_L = 4.8\), \(\alpha_L = 0.4\)라고 두면 다음과 같이 계산된다.&lt;/p&gt;
\[x' = 4.8 + 0.4(3.8 - 4.8)\]
\[x' = 4.8 + 0.4(-1.0)\]
\[x' = 4.8 - 0.4\]
\[x' = 4.4\]
&lt;p&gt;즉, Quantile Clipping은 3.8을 5.0으로 완전히 끌어올리지만, AEPC는 4.4처럼 원래 값이 낮았다는 정보를 일부 보존한 상태로 완화할 수 있다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;11. 상관관계 변화 확인&lt;/h3&gt;
&lt;p&gt;AEPC 적용 후 feature와 &lt;code&gt;quality&lt;/code&gt; 간의 관계가 어떻게 변했는지 확인하기 위해 Pearson 및 Spearman 상관계수를 비교하였다.&lt;/p&gt;
&lt;p&gt;여기서 중요한 점은 &lt;b&gt;상관관계의 방향이 아니라 강도&lt;/b&gt;를 비교해야 한다는 것이다. 예를 들어 어떤 feature가 &lt;code&gt;quality&lt;/code&gt;와 음의 상관관계를 갖는다면, 상관계수가 -0.22에서 -0.25로 변했을 때 숫자 자체는 작아졌지만, 절댓값은 커졌으므로 관계의 강도는 증가했다고 볼 수 있다.&lt;/p&gt;
&lt;p&gt;따라서 본 분석에서는 다음 값을 함께 확인하였다.&lt;/p&gt;
\[|\text{corr}(x, quality)|\]

&lt;h4&gt;11.1 Pearson 상관계수&lt;/h4&gt;
&lt;p&gt;Pearson 상관계수는 값의 선형적 크기 관계에 민감하다. 따라서 극단값의 크기를 어떻게 조정했는지에 영향을 받을 수 있다.&lt;/p&gt;
&lt;p&gt;실험 결과 &lt;code&gt;chlorides&lt;/code&gt;에서 가장 뚜렷한 변화가 나타났다.&lt;/p&gt;
&lt;p&gt;Raw feature 기준:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;Original corr&lt;/th&gt;&lt;th&gt;Quantile corr&lt;/th&gt;&lt;th&gt;AEPC corr&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;chlorides&lt;/td&gt;&lt;td&gt;-0.216275&lt;/td&gt;&lt;td&gt;-0.233189&lt;/td&gt;&lt;td&gt;-0.249089&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;log1p 적용 후:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;Original corr&lt;/th&gt;&lt;th&gt;Quantile corr&lt;/th&gt;&lt;th&gt;AEPC corr&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;chlorides&lt;/td&gt;&lt;td&gt;-0.222471&lt;/td&gt;&lt;td&gt;-0.237445&lt;/td&gt;&lt;td&gt;-0.252598&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;즉, &lt;code&gt;chlorides&lt;/code&gt;는 AEPC 적용 후 Pearson 상관계수의 절댓값이 가장 크게 증가하였다. log1p 적용 후 기준으로 보면 원본의 절댓값은 0.222471, Quantile Clipping은 0.237445, AEPC는 0.252598이었다.&lt;/p&gt;
\[|corr_{original}| = 0.222471\]
\[|corr_{qclip}| = 0.237445\]
\[|corr_{AEPC}| = 0.252598\]
&lt;p&gt;이 결과는 AEPC가 &lt;code&gt;chlorides&lt;/code&gt;에서 극단값의 크기 효과를 조정하면서 &lt;code&gt;quality&lt;/code&gt;와의 선형 관계를 더 뚜렷하게 만들었을 가능성을 보여준다.&lt;/p&gt;
&lt;p&gt;다만 이러한 효과가 모든 feature에서 동일하게 나타난 것은 아니다. 예를 들어 &lt;code&gt;total sulfur dioxide&lt;/code&gt;는 AEPC 적용 후 Pearson 상관계수 절댓값이 원본보다 소폭 감소하였다.&lt;/p&gt;
&lt;p&gt;Raw Pearson 기준으로 보면 다음과 같다.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;Original corr&lt;/th&gt;&lt;th&gt;Quantile corr&lt;/th&gt;&lt;th&gt;AEPC corr&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;total sulfur dioxide&lt;/td&gt;&lt;td&gt;-0.168759&lt;/td&gt;&lt;td&gt;-0.170613&lt;/td&gt;&lt;td&gt;-0.167668&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;따라서 AEPC는 모든 변수의 상관관계를 일괄적으로 증가시키는 방식이 아니라, feature의 tail 특성에 따라 관계 변화가 다르게 나타나는 전처리 방식으로 보는 것이 적절하다.&lt;/p&gt;

&lt;h4&gt;11.2 Spearman 상관계수&lt;/h4&gt;
&lt;p&gt;Spearman 상관계수는 값의 크기보다 순위 기반 관계를 반영한다.&lt;/p&gt;
&lt;p&gt;실험 결과 Spearman 상관계수는 AEPC 적용 전후에 거의 변하지 않았다.&lt;/p&gt;
&lt;p&gt;예를 들어 &lt;code&gt;chlorides&lt;/code&gt;의 Spearman 상관계수는 다음과 같았다.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;Original Spearman&lt;/th&gt;&lt;th&gt;Quantile Spearman&lt;/th&gt;&lt;th&gt;AEPC Spearman&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;chlorides&lt;/td&gt;&lt;td&gt;-0.323436&lt;/td&gt;&lt;td&gt;-0.323453&lt;/td&gt;&lt;td&gt;-0.323436&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;density&lt;/code&gt;도 거의 동일하였다.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;Original Spearman&lt;/th&gt;&lt;th&gt;Quantile Spearman&lt;/th&gt;&lt;th&gt;AEPC Spearman&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;density&lt;/td&gt;&lt;td&gt;-0.342469&lt;/td&gt;&lt;td&gt;-0.342448&lt;/td&gt;&lt;td&gt;-0.342469&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이는 AEPC가 데이터의 순위 구조를 크게 바꾸기보다는, cap 밖의 값의 크기만 완화하는 방식으로 작동했음을 보여준다.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;순위 구조는 거의 유지한다.&lt;/li&gt;
  &lt;li&gt;극단값의 크기 효과는 완화한다.&lt;/li&gt;
  &lt;li&gt;일부 feature에서는 target과의 Pearson 관계가 더 뚜렷해질 수 있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h3&gt;12. Quantile Clipping과 AEPC의 수식적 차이&lt;/h3&gt;
&lt;p&gt;두 방식의 차이는 수식으로 보면 더 명확하다.&lt;/p&gt;
&lt;p&gt;Quantile Clipping에서는 상한을 넘는 두 값 \(x_1, x_2\)가 있을 때 다음과 같이 가정할 수 있다.&lt;/p&gt;
\[x_1 \gt x_2 \gt q_{0.99}\]
&lt;p&gt;변환 후에는 다음과 같이 된다.&lt;/p&gt;
\[x_1' = x_2' = q_{0.99}\]
&lt;p&gt;즉, 상한을 넘은 값들의 순서 정보가 사라진다.&lt;/p&gt;
&lt;p&gt;반면 AEPC에서는 다음과 같이 가정할 수 있다.&lt;/p&gt;
\[x_1 \gt x_2 \gt c_U\]
&lt;p&gt;이때 AEPC 적용 후 값은 다음과 같다.&lt;/p&gt;
\[x_1' = c_U + \alpha_U(x_1 - c_U)\]
\[x_2' = c_U + \alpha_U(x_2 - c_U)\]
&lt;p&gt;그리고 \(\alpha_U \gt 0\)이면 다음 관계가 유지된다.&lt;/p&gt;
\[x_1' \gt x_2'\]
&lt;p&gt;하단 극단값도 마찬가지다. \(x_1 \lt x_2 \lt c_L\)이고 \(\alpha_L \gt 0\)이면 AEPC 적용 후에도 다음 관계가 유지된다.&lt;/p&gt;
\[x_1' \lt x_2'\]
&lt;p&gt;즉, AEPC는 상단과 하단 극단값 모두에서 &lt;b&gt;값의 상대적 순서&lt;/b&gt;를 보존한다.&lt;/p&gt;

&lt;hr&gt;

&lt;h3&gt;13. 한계와 향후 개선 방향&lt;/h3&gt;
&lt;p&gt;AEPC는 극단값을 완전히 제거하지 않고 일부 정보를 보존한다는 장점이 있다. 하지만 모든 상황에서 Quantile Clipping보다 항상 우수하다고 볼 수는 없다.&lt;/p&gt;
&lt;p&gt;극단값이 실제로 노이즈라면 AEPC가 불필요한 정보를 남길 수 있다. 반대로 극단값이 target과 관련된 의미 있는 신호라면 AEPC가 Quantile Clipping보다 유리할 수 있다.&lt;/p&gt;
&lt;p&gt;또한 이번 실험에 사용한 와인 품질 데이터는 종속변수인 &lt;code&gt;quality&lt;/code&gt;가 5, 6, 7 구간에 크게 집중되어 있다. 실제로 대부분의 샘플이 중간 품질 등급에 몰려 있기 때문에, 입력 feature의 극단값을 일부 보존하더라도 target 측면에서 충분히 뚜렷한 차이를 만들기 어려울 수 있다. 즉, AEPC가 극단값의 상대적 정보를 보존하더라도, 종속변수 자체가 중간 등급에 편중되어 있다면 그 효과가 제한적으로 나타날 가능성이 있다.&lt;/p&gt;
&lt;p&gt;따라서 본 실험 결과만으로 AEPC의 일반적인 유효성을 단정하기는 어렵다. AEPC가 실제로 다양한 정형 회귀 문제에서 유효한 전처리 전략인지 확인하기 위해서는, target 분포가 더 다양하거나 극단 구간의 target 차이가 뚜렷한 데이터셋을 포함하여 추가적인 실험과 검증이 필요하다.&lt;/p&gt;
&lt;p&gt;또한 본 프로젝트에서 사용한 \((0.3, 0.5, 0.2)\) 가중치는 모델 학습으로 최적화된 값이 아니라, AEPC 설계 의도를 반영한 경험적 가중치이다. 특히 target 관련성을 가장 중요하게 보고 0.5의 가중치를 부여하였으며, tail의 반복성과 연속성에는 각각 0.3과 0.2를 부여하였다. 그러나 이 가중치 조합이 최적이라는 의미는 아니다. 데이터셋의 분포, target과의 관계, 극단값의 형태에 따라 적절한 가중치가 달라질 수 있으므로, 계수 조합에 대한 추가적인 실험과 민감도 분석이 필요하다.&lt;/p&gt;
&lt;p&gt;향후에는 다음과 같은 추가 검증이 필요하다.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;가중치 조합에 대한 ablation study&lt;/li&gt;
  &lt;li&gt;alpha_min, alpha_max 변화에 따른 민감도 분석&lt;/li&gt;
  &lt;li&gt;하단 AEPC와 상단 AEPC의 개별 효과 비교&lt;/li&gt;
  &lt;li&gt;여러 random seed 기반 반복 실험&lt;/li&gt;
  &lt;li&gt;target 분포가 서로 다른 다양한 정형 회귀 데이터셋에 대한 일반화 검증&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h3&gt;결론&lt;/h3&gt;
&lt;p&gt;AEPC는 극단값을 단순히 제거하는 것이 아니라, 극단값의 영향을 줄이면서도 cap을 벗어난 정보의 일부를 보존하기 위한 전처리 전략이다.&lt;/p&gt;
&lt;p&gt;핵심 수식은 다음과 같다.&lt;/p&gt;
\[
x' =
\begin{cases}
c_L + \alpha_L(x - c_L), &amp; x \lt c_L \\
x, &amp; c_L \le x \le c_U \\
c_U + \alpha_U(x - c_U), &amp; x \gt c_U
\end{cases}
\]
&lt;p&gt;이 방식은 hard clipping과 원본 유지 사이의 절충점을 만든다.&lt;/p&gt;
\[\alpha = 0 \Rightarrow \text{hard clipping}\]
\[\alpha = 1 \Rightarrow \text{original value}\]
&lt;p&gt;Quantile Clipping은 극단값을 안정적으로 제한하지만, 기준 밖의 값을 모두 같은 값으로 고정한다. 반면 AEPC는 기준 밖의 값을 완화하면서도 원래 값의 상대적 순서와 일부 크기 정보를 유지한다.&lt;/p&gt;
&lt;p&gt;결국 AEPC는 &lt;b&gt;극단값 제거&lt;/b&gt;가 아니라 &lt;b&gt;극단값 완화와 정보 보존 사이의 균형&lt;/b&gt;을 목표로 한 전처리 방식이다.&lt;/p&gt;</description>
      <category>AI_Machine_Learning</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/119</guid>
      <comments>https://neck392.tistory.com/119#entry119comment</comments>
      <pubDate>Mon, 18 May 2026 09:08:54 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크] IPv4 주소의 구분과 할당 가능 주소 계산 예제</title>
      <link>https://neck392.tistory.com/117</link>
      <description>&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot; data-start=&quot;129&quot; data-end=&quot;175&quot;&gt;침해사고 분석 문제들을 풀어보면 공격자 IP를 식별하는 과정을 필요로 한다. IP 주소 공간에 대해 깊이 있는 내용을 탐구해 본다.&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kKVlK/btsN4ozbmow/oV1PaSIf3r7CdN4cVToBRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kKVlK/btsN4ozbmow/oV1PaSIf3r7CdN4cVToBRk/img.png&quot; data-alt=&quot;&amp;amp;lt;IP 주소 클래스 (Classful Addressing)&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kKVlK/btsN4ozbmow/oV1PaSIf3r7CdN4cVToBRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkKVlK%2FbtsN4ozbmow%2FoV1PaSIf3r7CdN4cVToBRk%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;685&quot; height=&quot;360&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;IP 주소 클래스 (Classful Addressing)&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-end=&quot;98&quot; data-start=&quot;75&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. IP 주소: 129.3.4.5&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;175&quot; data-start=&quot;100&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;118&quot; data-start=&quot;100&quot;&gt;첫 번째 바이트: &lt;b&gt;129&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;175&quot; data-start=&quot;119&quot;&gt;이진수: 10000001이므로 맨 앞 두 비트가 10&lt;/li&gt;
&lt;li data-end=&quot;175&quot; data-start=&quot;119&quot;&gt;혹은, 첫 바이트가 128 to 191에 속함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;b&gt;클래스 B&lt;/b&gt;에 해당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스 B의 구조에서 Prefix는 16비트이며 Suffix도 16비트(32-16)이다.&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;background-color: #f3c000;&quot;&gt;&lt;b&gt;Net ID는 129.3&lt;/b&gt;&lt;/span&gt;이 되며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;Host ID는 4.5&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;호스트 부분을 모두 0으로 설정한 129.3.0.0가 네트워크 주소이며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트 부분을 모두 1로 설정한 IP: 129.3.255.255가 브로드캐스트 주소가 된다.&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;Suffix가 16비트이므로 2^16 = 65,536 이지만&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;2^16 - 2 = 65,534(개)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;정리&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP&amp;nbsp;주소&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;129.3.4.5/16 &lt;br /&gt;이진&amp;nbsp;표현&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;10000001.00000011.00000100.00000101 &lt;br /&gt;&lt;br /&gt;[ Net ID ]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: 앞 16비트 &amp;rarr; 129.3 &lt;br /&gt;[&amp;nbsp;Host&amp;nbsp;ID&amp;nbsp;]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;뒤&amp;nbsp;16비트&amp;nbsp;&amp;rarr;&amp;nbsp;4.5 &lt;br /&gt;&lt;br /&gt;Network&amp;nbsp;addr&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;129.3.0.0/16 &lt;br /&gt;Broadcast&amp;nbsp;addr&amp;nbsp;:&amp;nbsp;129.3.255.255/16 &lt;br /&gt;Host&amp;nbsp;범위&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;129.3.0.1&amp;nbsp;~&amp;nbsp;129.3.255.254 &lt;br /&gt;할당 가능한 호스트 수 : 2^16 - 2 = 65,534 개&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. IP 주소: 167.199.170.82/27&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 8비트가 82이다. 이진수로 표현하면 01010010가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;27+5=32이므로 마지막 5비트가 Suffix이다.&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;00000&lt;/b&gt; &lt;br /&gt;&amp;rarr;&amp;nbsp;10100111.11000111.10101010.010&lt;b&gt;00000&lt;/b&gt; &lt;br /&gt;&amp;rarr;&amp;nbsp;167&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.199&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.170&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.64&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;네트워크 주소&lt;/b&gt;: 167.199.170.64/27&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;11111&lt;/b&gt; &lt;br /&gt;&amp;rarr;&amp;nbsp;10100111.11000111.10101010.010&lt;b&gt;11111&lt;/b&gt; &lt;br /&gt;&amp;rarr;&amp;nbsp;167&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.199&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.170&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.95&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;브로드캐스트 주소&lt;/b&gt;: 167.199.170.95&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;네트워크 주소 : 167.199.170.64/27&amp;nbsp;&amp;nbsp;&amp;larr; Host bits = 00000&lt;/li&gt;
&lt;li&gt;브로드캐스트 주소 : 167.199.170.95&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;larr; Host bits = 11111&lt;/li&gt;
&lt;li&gt;할당 가능한 주소 : 167.199.170.65 ~ 167.199.170.94&lt;/li&gt;
&lt;li&gt;호스트 개수 : 2^5 - 2 = 30 개&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] B. A. Forouzan, Data Communications and Networking, 5th ed., New York: McGraw-Hill Education, 2013.&lt;/p&gt;</description>
      <category>보안, IT/네트워크, IT</category>
      <category>broadcast address</category>
      <category>host id</category>
      <category>net id</category>
      <category>network address</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/117</guid>
      <comments>https://neck392.tistory.com/117#entry117comment</comments>
      <pubDate>Wed, 21 May 2025 00:02:28 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크] IPv4 Address Space</title>
      <link>https://neck392.tistory.com/116</link>
      <description>&lt;blockquote data-end=&quot;175&quot; data-start=&quot;129&quot; data-ke-style=&quot;style2&quot;&gt;침해사고 분석 문제들을 풀어보면 공격자 IP를 식별하는 과정을 필요로 한다. IP 주소 공간에 대해 깊이 있는 내용을 탐구해 본다.&lt;/blockquote&gt;
&lt;p data-end=&quot;175&quot; data-start=&quot;129&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;175&quot; data-start=&quot;129&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;IPv4에서 주소 공간이란 &lt;b&gt;사용 가능한 모든 IP 주소의 범위&lt;/b&gt;&lt;/span&gt;를 의미한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;467&quot; data-start=&quot;413&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;440&quot; data-start=&quot;413&quot;&gt;IPv4는 &lt;b&gt;32비트&lt;/b&gt; 주소를 사용 (MAC 주소는 48비트)&lt;/li&gt;
&lt;li data-end=&quot;467&quot; data-start=&quot;441&quot;&gt;주소 공간은 2^32개가 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1747746671608&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2^32 = 4,294,967,296&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;546&quot; data-start=&quot;501&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;546&quot; data-start=&quot;501&quot;&gt;즉, 이론적으로 &lt;b&gt;약 43억 개&lt;/b&gt;의 고유한 IP 주소를 만들 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;569&quot; data-start=&quot;553&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;641&quot; data-start=&quot;571&quot; data-ke-size=&quot;size16&quot;&gt;이론상 43억 개의 주소가 존재하지만, &lt;b&gt;모든 주소가 실제 사용 가능한 것은 아니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 불가능한 주소&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;918&quot; data-start=&quot;643&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;918&quot; data-start=&quot;679&quot;&gt;
&lt;tr data-end=&quot;715&quot; data-start=&quot;679&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;695&quot; data-start=&quot;679&quot;&gt;127.0.0.0/8&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;715&quot; data-start=&quot;695&quot;&gt;루프백(Loopback) 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;756&quot; data-start=&quot;716&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;728&quot; data-start=&quot;716&quot;&gt;0.0.0.0&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;756&quot; data-start=&quot;728&quot;&gt;미지정 주소 (Default route 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;813&quot; data-start=&quot;757&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;792&quot; data-start=&quot;757&quot;&gt;192.168.0.0/16, 10.0.0.0/8 등&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;813&quot; data-start=&quot;792&quot;&gt;사설(Private) IP 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;866&quot; data-start=&quot;814&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;846&quot; data-start=&quot;814&quot;&gt;224.0.0.0 ~ 239.255.255.255&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;866&quot; data-start=&quot;846&quot;&gt;멀티캐스트(Multicast)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;918&quot; data-start=&quot;867&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;899&quot; data-start=&quot;867&quot;&gt;240.0.0.0 ~ 255.255.255.255&lt;/td&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;918&quot; data-start=&quot;899&quot;&gt;미래 예약(Reserved)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-end=&quot;960&quot; data-start=&quot;920&quot; data-ke-size=&quot;size16&quot;&gt;이로 인해 &lt;b&gt;사용 가능한 IPv4 주소는 이론치보다 훨씬 적다. &lt;/b&gt;그러나 IPv6는 &lt;b&gt;128비트&lt;/b&gt; 주소를 사용한다.&lt;/p&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1747746897728&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2^128 &amp;asymp; 3.4 &amp;times; 10^38&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1131&quot; data-start=&quot;1066&quot; data-ke-size=&quot;size16&quot;&gt;사실상 &lt;b&gt;무제한에 가까운 IP 주소 제공&lt;/b&gt;이 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;457&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byO3sw/btsN4050vMY/ZCRqSceLGWMqeZ7sVfMJh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byO3sw/btsN4050vMY/ZCRqSceLGWMqeZ7sVfMJh0/img.png&quot; data-alt=&quot;&amp;amp;lt;IPv6의 표현 방식&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byO3sw/btsN4050vMY/ZCRqSceLGWMqeZ7sVfMJh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyO3sw%2FbtsN4050vMY%2FZCRqSceLGWMqeZ7sVfMJh0%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;265&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;457&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;IPv6의 표현 방식&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; IP 주소의 구조 &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;922&quot; data-origin-height=&quot;589&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGPwLS/btsN45MDsMB/scTRcglwjRJPGiTiEwaKe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGPwLS/btsN45MDsMB/scTRcglwjRJPGiTiEwaKe0/img.png&quot; data-alt=&quot;&amp;amp;lt;Ip의 구조&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGPwLS/btsN45MDsMB/scTRcglwjRJPGiTiEwaKe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGPwLS%2FbtsN45MDsMB%2FscTRcglwjRJPGiTiEwaKe0%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;609&quot; height=&quot;389&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;589&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;Ip의 구조&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;101&quot; data-start=&quot;0&quot; data-ke-size=&quot;size16&quot;&gt;하나의 IP 주소는 &lt;b&gt;네트워크를 식별하는 부분&lt;/b&gt;과 &lt;b&gt;개별 장치를 식별하는 부분&lt;/b&gt;으로 나누어 진다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;218&quot; data-start=&quot;157&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;181&quot; data-start=&quot;157&quot;&gt;&lt;b&gt;총 32비트로 구성된 주소&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;218&quot; data-start=&quot;182&quot;&gt;예: 192.168.1.10 8비트 &amp;times; 4 = 32비트&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;264&quot; data-start=&quot;225&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Prefix (n bits): 네트워크 부분&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;366&quot; data-start=&quot;265&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;300&quot; data-start=&quot;265&quot;&gt;앞쪽의 &lt;b&gt;n비트&lt;/b&gt;는 &quot;어느 네트워크인가?&quot;를 나타낸다.&lt;/li&gt;
&lt;li data-end=&quot;335&quot; data-start=&quot;301&quot;&gt;예를 들어 /24이면 앞 24비트가 prefix이다. (즉, 끝의 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;/n의 값은 프리픽스의 길이를 의미&lt;/b&gt;&lt;/span&gt;)&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;868&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blXbnd/btsN5m8rqEN/XRxbvxKGLchEvSg0c1ey90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blXbnd/btsN5m8rqEN/XRxbvxKGLchEvSg0c1ey90/img.png&quot; data-alt=&quot;&amp;amp;lt;프리픽스의 길이와 예시&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blXbnd/btsN5m8rqEN/XRxbvxKGLchEvSg0c1ey90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblXbnd%2FbtsN5m8rqEN%2FXRxbvxKGLchEvSg0c1ey90%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;415&quot; height=&quot;229&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;프리픽스의 길이와 예시&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;366&quot; data-start=&quot;265&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;366&quot; data-start=&quot;336&quot;&gt;이 값이 같으면 같은 네트워크에 있는 장치들이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;420&quot; data-start=&quot;368&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;192.168.1.0/24에서 Prefix(=net id)는 192.168.1이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-end=&quot;476&quot; data-start=&quot;427&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;476&quot; data-start=&quot;427&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Suffix ((32 - n) bits): 호스트(장치) 부분&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;562&quot; data-start=&quot;477&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;526&quot; data-start=&quot;477&quot;&gt;뒤쪽의 &lt;b&gt;(32 - n)비트&lt;/b&gt;는 &quot;네트워크 내에서 어떤 장치인가?&quot;를 나타낸다.&lt;/li&gt;
&lt;li data-end=&quot;562&quot; data-start=&quot;527&quot;&gt;즉, 동일한 네트워크 내에서 각 장치를 구별하는 용도이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;602&quot; data-start=&quot;564&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;192.168.1.10에서 10이 Suffix(=host id)이다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; IPv4 주소 클래스(Classful Addressing) &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;1065&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beF4bH/btsN47jsptx/DOTvOfP6Ub8GQjnK5Fh66K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beF4bH/btsN47jsptx/DOTvOfP6Ub8GQjnK5Fh66K/img.png&quot; data-alt=&quot;&amp;amp;lt;IPv4 주소 클래스(Classful Addressing)&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beF4bH/btsN47jsptx/DOTvOfP6Ub8GQjnK5Fh66K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeF4bH%2FbtsN47jsptx%2FDOTvOfP6Ub8GQjnK5Fh66K%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;655&quot; height=&quot;344&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;IPv4 주소 클래스(Classful Addressing)&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IPv4 주소는 과거에 주소 크기(네트워크 규모)에 따라 5개의 클래스(A~E)로 나누었다. 이 방식을 &lt;b&gt;클래스풀(classful) 주소 지정 방식&lt;/b&gt;이라고 한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 126px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;클래스&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;맨 앞 비트&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;Prefix 길이&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;Suffix 길이&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;첫 바이트 범위&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;용도&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;A&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;0xxx xxxx&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;8비트&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;24비트&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;0 ~ 127&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;b&gt;B&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;10xx xxxx&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;16비트&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;16비트&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;128 ~ 191&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;b&gt;C&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;110x xxxx&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;24비트&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;8비트&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;192 ~ 223&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;b&gt;D&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;1110 xxxx&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;해당 없음&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;해당 없음&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;224 ~ 239&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;b&gt;E&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;1111 xxxx&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;해당 없음&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;해당 없음&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;240 ~ 255&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;실험적 / 예약됨 (사용 안 함)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 바이트의 비트 형태에 따라 클래스가 결정된다고도 표현할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Behrouz A. Forouzan, Data Communications and Networking, 5th Edition, McGraw-Hill Education, 2013. ISBN: 9780073376226.&lt;/p&gt;</description>
      <category>보안, IT/네트워크, IT</category>
      <category>class</category>
      <category>ip address</category>
      <category>IPv4</category>
      <category>prefix</category>
      <category>suffix</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/116</guid>
      <comments>https://neck392.tistory.com/116#entry116comment</comments>
      <pubDate>Tue, 20 May 2025 23:02:35 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크 해킹] OSI 7 계층과 패킷 분석 개요</title>
      <link>https://neck392.tistory.com/105</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;size18&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;MTIM, ARP 스푸핑, 디도스 등등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&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;/ul&gt;
&lt;p data-ke-size=&quot;size18&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;LAN : 논리적, 물리적 영역 안에서 연결된 네트워크&lt;/li&gt;
&lt;li&gt;WAN : 넓은 지리적 영역에 걸쳐있는 컴퓨터 및 자원을 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도시, 국가, 대륙 간 ISP(end system에게 다양한 네트워크 접속을 제공)에 의해 관리된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하위 계층 ISP는 국가, 국제 상위 계층 ISP를 통해 연결된다.&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;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전 세계적으로 컴퓨터 장치(end system)를 연결하는 컴퓨터 네트워크 (네트워크의 네트워크)&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;패킷&amp;nbsp;&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;end system에서 수신하여 end system으로 보내지는 데이터&lt;/li&gt;
&lt;li&gt;보내고자하는 데이터를 segment 단위로 나누고, 각 segment에 헤더를 연결하여 전송&lt;/li&gt;
&lt;li&gt;캡슐화된 시스템에 의거하여 목적지에서 다시 조립&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;경로(=path or route)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패킷이 수신되어 end system에 도달하는 동안 거쳐온 모든(일련의) 통신 링크&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;OSI 7 계층&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;osi 서비스모델.jpg&quot; data-origin-width=&quot;1478&quot; data-origin-height=&quot;563&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhyTHN/btsM1RohARY/C6inq32bCfkQfr5Y3eoMHK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhyTHN/btsM1RohARY/C6inq32bCfkQfr5Y3eoMHK/img.jpg&quot; data-alt=&quot;&amp;amp;lt;OSI 서비스 모델&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhyTHN/btsM1RohARY/C6inq32bCfkQfr5Y3eoMHK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhyTHN%2FbtsM1RohARY%2FC6inq32bCfkQfr5Y3eoMHK%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;1478&quot; height=&quot;563&quot; data-filename=&quot;osi 서비스모델.jpg&quot; data-origin-width=&quot;1478&quot; data-origin-height=&quot;563&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;OSI 서비스 모델&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;프로토콜 스택을 거치면서 기존 정보에 헤더를 붙여서 캡슐화&lt;/span&gt; 한다. 여기서 프로토콜은 장치 간에 통신할 때 지켜야 하는 규약이며 메시지의 형식, 순서, 메시지 전송, 수신시 수행하는 작업을 정의한다. 라우터는 3계층 패킷 교환기(네트워크 계층 주소 사용),&amp;nbsp; 스위치(패킷 스위치이지만 mac 주소 사용)는 2계층 패킷 교환기이다.&lt;/p&gt;
&lt;p 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;size18&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;계층 구조는 크고 복잡한 시스템의 정의된 특정 부분을 논의할 수 있게 해준다. -&amp;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;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;/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;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;/li&gt;
&lt;li&gt;전체 프레임을 한 네트워크 요소에서 이웃 네트워크 요소로 이동&lt;/li&gt;
&lt;li&gt;서비스가 해당 링크 계층에서 사용하는 프로트콜에 의해 결정된다.&lt;/li&gt;
&lt;li&gt;다음 상위 계층인 네트워크 계층은 &quot;데이터그램&quot;을 링크 계층으로 보낸다 즉, &quot;링크 계층 서비스에 의존&quot;한다. 라고 표현할 수 있다.&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;/h3&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;네트워크 계층을 가진 모든 인터넷 요소는 ip 프로토콜을 수행한다.&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;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;/li&gt;
&lt;li&gt;클라이언트와 서버 간에 애플리케이션 계층 메시지를 전송하는 서비스 제공&lt;/li&gt;
&lt;li&gt;&lt;b&gt;TCP&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;연결 지향형 서비스를 제공&lt;/li&gt;
&lt;li&gt;흐름 제어를 포함(송신자와 수신자와의 속도 일치)&lt;/li&gt;
&lt;li&gt;혼잡 제어 기능 제공(출발지의 전송률을 줄임)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UDP&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;비연결형 서비스 제공&lt;/li&gt;
&lt;li&gt;신뢰성, 흐름 제어, 혼잡 제어등을 제공하지 않는다.&lt;/li&gt;
&lt;li&gt;따라서 영화같은 데이터 량이 방대한 서비스에서 깨짐 현상이 일어난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&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;/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;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;/li&gt;
&lt;li&gt;즉, 응용 계층에서 요구하는 대부분의 암호화와 복호화를 수행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&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;/li&gt;
&lt;li&gt;네트워크 애플리케이션과 애플리케이션 계층 프로토콜&lt;/li&gt;
&lt;li&gt;end system에 있는 애리케이션 간에 메시지를 교환하는데 사용&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;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;TCP/IP 와 OSI&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두 모델에서 2개의 계층인 세션 계층과 표현 계층이 TCP/IP 프로토콜 그룹에는 없다. 그 이유는 크게 2가지로 유추해 볼 수 있다.&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;background-color: #f3c000;&quot;&gt;TCP/IP는 하나 이상의 전송층 프로토콜을 가지고 있다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;세션층의 일부 기능은 몇몇 전송층 프로토콜에서 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;응용 계층이 단순히 소프트웨어의 한 부분만은 아니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;만약 세션 그리고 표현 계층에서 사용하는 기능 중 몇 개가 특정 응용 계층에서 필요로 한다면, 소프트웨어의 한 부분으로 개발할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;OSI 모델이 TCP/IP 모델을 모두 대체하지 못한 이유&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;OSI 모델은 TCP/IP 모델 이후에 나타났으나 TCP/IP 모델을 완벽히 대체하지는 못하였다.&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;background-color: #f3c000;&quot;&gt;OSI 모델은 TCP/IP 모델이 나오고 많은 시간이 흐른 뒤에 등장하였다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;TCP/IP 모델이 이미 완전히 자리잡고, 많은 돈과 시간이 TCP/IP 그룹에 투자되고 난 이후에 완성되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;OSI 모델의 일부 계층은 완전히 정의되지 않았다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;표현 계층과 세션 계층에 의해 제공된 서비스들이 문서에는 기술되어 있으나 두 계층에 대한 실제 프로토콜은 완전히 정의되거나 기술되지 않았다. 당연히 이에 따라 대응하는 소프트웨어가 완전히 개발되지 않았다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;OSI가 완전히 구현되었을 때 TCP/IP 프로토콜에서 OSI 모델로 완전히 전환하기 위한 충분히 높은 수준의 성능을 보여주지 못하였다.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;네트워크 패킷 분석&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WireShark를 사용하여 실제 패킷을 간략하게 분석해본다. 와이어샤크는 호스트 장치에서 발생하는 네트워크 패킷을 캡쳐하고 분석할 수 있는 도구이다. 디지털 포렌식적 관점에서 트래픽이 오갈 때 공격자 행위를 유추 및 분석(명확한 타임라인 확보 등)하는 것에 가치가 있는 도구이다. 이번에는 와이어샤크로 간단한 분석을 진행해 본다.&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;background-color: #f3c000;&quot;&gt;많은 패킷이 오가는 것을 식별&lt;/span&gt;할 수 있으며 &lt;b&gt;만약 엣지 브라우저를 사용하고 있으면 크롬 기반이기에 QUIC 프로토콜이 많은 것을 확인&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;b&gt;React를 사용하여 간단한 페이지를 제작하여 로컬호스트로 접속하는 과정&lt;/b&gt;을 와이어샤크로 캡쳐해 본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MnENH/btsM3nM2Lle/u0rQ2n0ryuWsrV0LzCFKK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MnENH/btsM3nM2Lle/u0rQ2n0ryuWsrV0LzCFKK0/img.png&quot; data-alt=&quot;&amp;amp;lt;로컬호스트 열기(npm start)&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MnENH/btsM3nM2Lle/u0rQ2n0ryuWsrV0LzCFKK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMnENH%2FbtsM3nM2Lle%2Fu0rQ2n0ryuWsrV0LzCFKK0%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;562&quot; height=&quot;258&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;로컬호스트 열기(npm start)&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react로 간단한 페이지를 제작한 후에 npm start 명령어를 입력하여 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;로컬호스트로 접속가능한 웹 페이지를 간단하고 빠르게 실행&lt;/span&gt;할 수 있다. (3000포트 사용 설정)&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;1897&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKFufo/btsM2KaUzDg/Dyif75xFBA4H2kGkINPSQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKFufo/btsM2KaUzDg/Dyif75xFBA4H2kGkINPSQ0/img.png&quot; data-alt=&quot;&amp;amp;lt;구현한 웹페이지&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKFufo/btsM2KaUzDg/Dyif75xFBA4H2kGkINPSQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKFufo%2FbtsM2KaUzDg%2FDyif75xFBA4H2kGkINPSQ0%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;635&quot; height=&quot;178&quot; data-origin-width=&quot;1897&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;구현한 웹페이지&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹페이지에 접속하기전 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;와이어샤크 캡처를 시작한 후에 http 패킷 분석을 진행&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;1587&quot; data-origin-height=&quot;587&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgAPUN/btsM0siyGO7/6HYV1B3Eu5sgiP7Z6qU6k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgAPUN/btsM0siyGO7/6HYV1B3Eu5sgiP7Z6qU6k0/img.png&quot; data-alt=&quot;&amp;amp;lt;http 필터 적용&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgAPUN/btsM0siyGO7/6HYV1B3Eu5sgiP7Z6qU6k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgAPUN%2FbtsM0siyGO7%2F6HYV1B3Eu5sgiP7Z6qU6k0%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;1587&quot; height=&quot;587&quot; data-origin-width=&quot;1587&quot; data-origin-height=&quot;587&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;http 필터 적용&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;http 필터를 적용하고 보면 여러 해당 패킷들을 확인할 수 있다. 로컬 호스트로 된 페이지에 접속하였으므로 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;Source와 Destination의 IP가 동일&lt;/span&gt;하다. 빨간색 박스의 HTTP 처음 통신 과정 응답에서 보통 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;HTTP/1.1 200 OK로 시작하지만 304 Not Modified인 이유는 브라우저 캐시 때문&lt;/span&gt;이다. 이는 react를 로컬호스트로 실행하면 생기는 정상적인 동작이며 이전에 브라우저에서 한번 받아본 적이 있으면 &lt;b&gt;파일 변경 여부에 대한 조건부 요청을 보내고 파일이 변경되지 않았으면 304 Not Modified로 응답&lt;/b&gt;하며 브라우저는 캐시에 저장된 파일을 그대로 사용한다. 리소스를 수정한 뒤에 새로 저장하여 빌드하면 파일의 해시와 타임스탬프가 변경되기에 브라우저가 새 파일을 인식하고 200 OK를 보내게 된다.&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;747&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cX3wvd/btsM3kW7g2T/P2QcXDQIPRx33DysBjK7Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cX3wvd/btsM3kW7g2T/P2QcXDQIPRx33DysBjK7Z0/img.png&quot; data-alt=&quot;&amp;amp;lt;개요&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cX3wvd/btsM3kW7g2T/P2QcXDQIPRx33DysBjK7Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcX3wvd%2FbtsM3kW7g2T%2FP2QcXDQIPRx33DysBjK7Z0%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;747&quot; height=&quot;117&quot; data-origin-width=&quot;747&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;개요&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 개요에서 Frame은 데이터링크에서 사용하는 단위이며 &lt;b&gt;데이터 링크 계층에서 네트워크 요소로 전달하기 위한 모든 데이터를 담고있기에 Frame을 오버레이(클릭)하면 모든 데이터가 select&lt;/b&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;595&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxxBUi/btsM2LnjOHg/FaTRTeHOadKuYMgwoz6C91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxxBUi/btsM2LnjOHg/FaTRTeHOadKuYMgwoz6C91/img.png&quot; data-alt=&quot;&amp;amp;lt;IPV4 상세&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxxBUi/btsM2LnjOHg/FaTRTeHOadKuYMgwoz6C91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxxBUi%2FbtsM2LnjOHg%2FFaTRTeHOadKuYMgwoz6C91%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;595&quot; height=&quot;312&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;IPV4 상세&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상단에 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;0100 4개의 비트를 사용하여 Version&lt;/span&gt;을 나타낸다. &lt;span style=&quot;background-color: #f3c000;&quot;&gt;Protocol에서 TCP를 사용함(세그먼트가 어떤 프로토콜을 사용하는 지)을 나타내고&lt;/span&gt; 있으며 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;Time to Live(TTL)에서는 네트워크에서 데이터가 헛돌게 하지 않기 위하여 라우팅 되는 과정에서 제한&lt;/span&gt;을 걸어둔다. &lt;span style=&quot;background-color: #f3c000;&quot;&gt;Header Checksum에서는 데이터그램의 비트 손실 여부를 판단&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;813&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cquJgc/btsM0LB9CZy/PSkogyES0Mu3SkkwZ3mFfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cquJgc/btsM0LB9CZy/PSkogyES0Mu3SkkwZ3mFfk/img.png&quot; data-alt=&quot;&amp;amp;lt;TCP 상세&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cquJgc/btsM0LB9CZy/PSkogyES0Mu3SkkwZ3mFfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcquJgc%2FbtsM0LB9CZy%2FPSkogyES0Mu3SkkwZ3mFfk%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;813&quot; height=&quot;492&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;TCP 상세&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;상단에 Source Port(59185)와 Destination Port(3000)을 확인&lt;/span&gt;할 수 있다. S&lt;span style=&quot;background-color: #f3c000;&quot;&gt;equence Number와 Acknowledgment Number를 통하여 TCP로 요청과 응답을 받으며 신뢰적인 연결&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;852&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WBegs/btsM1d6b4sS/JYL7ZlA0Nq7TmTXzF27da0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WBegs/btsM1d6b4sS/JYL7ZlA0Nq7TmTXzF27da0/img.png&quot; data-alt=&quot;&amp;amp;lt;http request 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WBegs/btsM1d6b4sS/JYL7ZlA0Nq7TmTXzF27da0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWBegs%2FbtsM1d6b4sS%2FJYL7ZlA0Nq7TmTXzF27da0%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;852&quot; height=&quot;422&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;http request 확인&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상기의 http request를 확인해보면 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;http 버전(1.1) method인 GET 방식을 확인&lt;/span&gt;(URL로 접속하였기 때문)할 수 있으며 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;Host 즉 서버에 대한 정보(주소)도 확인&lt;/span&gt;할 수 있다. 밑으로 많은 Header들을 볼 수 있는데 여기서 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;User-Agent는 본인이 현재 접속한 장치의 환경&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;878&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs6Eoo/btsM0wZveEs/aS0dtQ0bMmiRnKgCVLF0QK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs6Eoo/btsM0wZveEs/aS0dtQ0bMmiRnKgCVLF0QK/img.png&quot; data-alt=&quot;&amp;amp;lt;http response 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs6Eoo/btsM0wZveEs/aS0dtQ0bMmiRnKgCVLF0QK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs6Eoo%2FbtsM0wZveEs%2FaS0dtQ0bMmiRnKgCVLF0QK%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;878&quot; height=&quot;427&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;http response 확인&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청에 대한 응답 패킷을 확인해보면 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;Date로 날짜도 확인&lt;/span&gt;할 수 있다. 이후 빨간색 동그라미의 \r\n &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;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;663&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Snv75/btsM2bT6CeU/Nbl7pDfRNZ9V8vVuYyXcZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Snv75/btsM2bT6CeU/Nbl7pDfRNZ9V8vVuYyXcZ0/img.png&quot; data-alt=&quot;&amp;amp;lt;follow -&amp;amp;gt; TCP Stream 클릭&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Snv75/btsM2bT6CeU/Nbl7pDfRNZ9V8vVuYyXcZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSnv75%2FbtsM2bT6CeU%2FNbl7pDfRNZ9V8vVuYyXcZ0%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;379&quot; height=&quot;293&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;follow -&amp;gt; TCP Stream 클릭&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;617&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be8pNE/btsM1jSFsVg/k6fcyBjwz5bojwhY2KwIr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be8pNE/btsM1jSFsVg/k6fcyBjwz5bojwhY2KwIr1/img.png&quot; data-alt=&quot;&amp;amp;lt;요청과 응답 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be8pNE/btsM1jSFsVg/k6fcyBjwz5bojwhY2KwIr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe8pNE%2FbtsM1jSFsVg%2Fk6fcyBjwz5bojwhY2KwIr1%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;355&quot; height=&quot;350&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;617&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;요청과 응답 확인&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와이어샤크에서 &lt;b&gt;패킷을 우클릭하고 follow -&amp;gt; tcp stream&lt;/b&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;444&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B8fW1/btsM1dd5HbZ/dvjgkHMy77YLhHkD5ZYHf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B8fW1/btsM1dd5HbZ/dvjgkHMy77YLhHkD5ZYHf0/img.png&quot; data-alt=&quot;&amp;amp;lt;Statistics -&amp;amp;gt; Flow Graph 클릭&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B8fW1/btsM1dd5HbZ/dvjgkHMy77YLhHkD5ZYHf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB8fW1%2FbtsM1dd5HbZ%2FdvjgkHMy77YLhHkD5ZYHf0%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;268&quot; height=&quot;314&quot; data-origin-width=&quot;444&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;Statistics -&amp;gt; Flow Graph 클릭&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1891&quot; data-origin-height=&quot;771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YtgnY/btsM2dxDEvU/GMgKykgxR4OqlR6pYixxb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YtgnY/btsM2dxDEvU/GMgKykgxR4OqlR6pYixxb0/img.png&quot; data-alt=&quot;&amp;amp;lt;Graph 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YtgnY/btsM2dxDEvU/GMgKykgxR4OqlR6pYixxb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYtgnY%2FbtsM2dxDEvU%2FGMgKykgxR4OqlR6pYixxb0%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;571&quot; height=&quot;233&quot; data-origin-width=&quot;1891&quot; data-origin-height=&quot;771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;Graph 확인&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 &lt;b&gt;Statistics -&amp;gt; Flow Graph&lt;/b&gt;를 클릭하면 TCP의 3-way handshake 과정을 포함하여 직관적으로 확인할 수 있다. 앞서 TCP 상세에서의 SYN과 ACK가 오고가는 과정을 한눈에 알기 쉽다. 좌측 하단의 Limit to display filter를 클릭하면 와이어샤크에서 적용한 필터를 Flow Graph에서도 적용할 수 있으며 &quot;ip.addr == (주소)&quot;필터를 사용하여 더욱 편하게 확인할 수 있다. 위의 TCP 연결에서는 로컬호스트를 사용하였기에 소스 주소와 목적지 주소가 동일하여 예외적으로 일반적인 경우보다 직관성이 떨어진다.&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;size18&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;Behrouz A. Forouzan, Data Communications and Networking 5th ed, McGraw-Hill Education, 2012.&lt;/span&gt;&lt;/p&gt;</description>
      <category>보안, IT/네트워크, IT</category>
      <category>network</category>
      <category>OSI 7 Layer</category>
      <category>Packet</category>
      <category>wireshark</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/105</guid>
      <comments>https://neck392.tistory.com/105#entry105comment</comments>
      <pubDate>Sun, 30 Mar 2025 10:29:50 +0900</pubDate>
    </item>
    <item>
      <title>[메모리] 단일 프로그래밍 연속 메모리 할당</title>
      <link>https://neck392.tistory.com/101</link>
      <description>&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;메모리할당개요.jpg&quot; data-origin-width=&quot;1496&quot; data-origin-height=&quot;704&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LBPTY/btsLCIlfQg4/2uv2V4lXogcCpHejNCUEZK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LBPTY/btsLCIlfQg4/2uv2V4lXogcCpHejNCUEZK/img.jpg&quot; data-alt=&quot;&amp;amp;lt;메모리할당 - 연속 메모리 - 단일 프로그래밍&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LBPTY/btsLCIlfQg4/2uv2V4lXogcCpHejNCUEZK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLBPTY%2FbtsLCIlfQg4%2F2uv2V4lXogcCpHejNCUEZK%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;1496&quot; height=&quot;704&quot; data-filename=&quot;메모리할당개요.jpg&quot; data-origin-width=&quot;1496&quot; data-origin-height=&quot;704&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;메모리할당 - 연속 메모리 - 단일 프로그래밍&amp;gt;&lt;/figcaption&gt;
&lt;/figure&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_KakaoTalk_20241231_232349030_01.jpg&quot; data-origin-width=&quot;1237&quot; data-origin-height=&quot;1143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uPl1x/btsLBuuV8d3/PQGckipornutY7r92Wv7l0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uPl1x/btsLBuuV8d3/PQGckipornutY7r92Wv7l0/img.png&quot; data-alt=&quot;&amp;amp;lt;전형적인 단일 프로그래밍 연속 메모리 할당 시스템&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uPl1x/btsLBuuV8d3/PQGckipornutY7r92Wv7l0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuPl1x%2FbtsLBuuV8d3%2FPQGckipornutY7r92Wv7l0%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;579&quot; height=&quot;535&quot; data-filename=&quot;edited_KakaoTalk_20241231_232349030_01.jpg&quot; data-origin-width=&quot;1237&quot; data-origin-height=&quot;1143&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;전형적인 단일 프로그래밍 연속 메모리 할당 시스템&amp;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;b&gt;초기 컴퓨터 시스템에서 단일 사용자(하나의 프로그램)만이 실행될 수 있었고 자원도 해당 프로그램 혼자만 사용&lt;/b&gt;하였다. 그리고 &lt;b&gt;프로그램은 메모리보다 클 수 없었으며 프로그래머가 직접 배치 과정을 수행하여 항상 같은 메모리 위치에 적재&lt;/b&gt;하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 시스템 설계자들은 &lt;b&gt;기본 기능을 구현한 입출력 코딩을 입출력 제어 시스템(Input/Output Control System, IOCS)에 통합&lt;/b&gt;하여 각 프로그램을 위하여 새로 작성할 필요없이 &lt;b&gt;IOCS 루틴을 호출해 원하는 작업을 수행&lt;/b&gt;하였다. IOCS는 코딩 과정을 매우 간단하고 빠르게 진행하게 해주었으며 입출력 제어 시스템 구현은 현태 운영체제 개념의 시작이라 할 수 있다.&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;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;메모리를 제어하는 모든 권한이 사용자에게 있기 때문에 사용자가 주소를 잘못 지정하면 운영체제가 손상되는 문제가 생긴다. 따라서 아래 그림과 같이 경계(한계) 레지스터를 사용하여 사용자 프로그램이 메모리 주소를 참조할 때마다 경계 레지스터를 검사한 후 실행하여 메모리를 보호&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-filename=&quot;edited_KakaoTalk_20241231_232349030.jpg&quot; data-origin-width=&quot;1496&quot; data-origin-height=&quot;777&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzpT8e/btsLCp0yLx8/8DTWQzzJCWnaxeW5ak9Y60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzpT8e/btsLCp0yLx8/8DTWQzzJCWnaxeW5ak9Y60/img.png&quot; data-alt=&quot;&amp;amp;lt;경계 레지스터를 활용한 메모리 보호 기법 적용&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzpT8e/btsLCp0yLx8/8DTWQzzJCWnaxeW5ak9Y60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzpT8e%2FbtsLCp0yLx8%2F8DTWQzzJCWnaxeW5ak9Y60%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;647&quot; height=&quot;336&quot; data-filename=&quot;edited_KakaoTalk_20241231_232349030.jpg&quot; data-origin-width=&quot;1496&quot; data-origin-height=&quot;777&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;경계 레지스터를 활용한 메모리 보호 기법 적용&amp;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;b&gt;프로그램의 크기가 제한되었다. 소프트웨어 설계자들은 이러한 메모리의 한계를 극복하기 위하여 중첩(Overlay)을 생성&lt;/b&gt;하여 메인 메모리보다 큰 프로그램을 실행할 수 있게 해주었다. 프로그래머는 프로그램을 논리적인 구역으로 나누고 &lt;b&gt;프로그램이 특정 구역에 필요한 메모리를 요구하지 않을 때, 시스템은 해당 구역의 일부나 전체를 필요한 구역의 메모리와 교체&lt;/b&gt;할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중첩과 관련된 자세한 내용은 블로그 앞의 글에서 짚고 넘어갔으므로 생략한다.&lt;/p&gt;</description>
      <category>Computer_science/Memory</category>
      <category>iocs</category>
      <category>Overlay</category>
      <category>register</category>
      <category>경계 레지스터</category>
      <category>단일 프로그래밍</category>
      <category>연속 메모리</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/101</guid>
      <comments>https://neck392.tistory.com/101#entry101comment</comments>
      <pubDate>Thu, 26 Dec 2024 00:21:03 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] BMP Recovery Write-up</title>
      <link>https://neck392.tistory.com/100</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. BMP Recovery&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;658&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nERFu/btsLxLQb69K/oKCUakM2gyk0f2lzeaHI11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nERFu/btsLxLQb69K/oKCUakM2gyk0f2lzeaHI11/img.png&quot; data-alt=&quot;&amp;amp;lt;문제 설명&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nERFu/btsLxLQb69K/oKCUakM2gyk0f2lzeaHI11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnERFu%2FbtsLxLQb69K%2FoKCUakM2gyk0f2lzeaHI11%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;658&quot; height=&quot;225&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;문제 설명&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;168&quot; data-origin-height=&quot;105&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIa0xT/btsLws49Ets/2tFdKFFxLkBdHkctMhWLj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIa0xT/btsLws49Ets/2tFdKFFxLkBdHkctMhWLj0/img.png&quot; data-alt=&quot;&amp;amp;lt;문제 파일&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIa0xT/btsLws49Ets/2tFdKFFxLkBdHkctMhWLj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIa0xT%2FbtsLws49Ets%2F2tFdKFFxLkBdHkctMhWLj0%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;168&quot; height=&quot;105&quot; data-origin-width=&quot;168&quot; data-origin-height=&quot;105&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;문제 파일&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G4t30/btsLxNApE3C/rJausKscR3S1nBWj4AWSSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G4t30/btsLxNApE3C/rJausKscR3S1nBWj4AWSSK/img.png&quot; data-alt=&quot;&amp;amp;lt;또 백만년만에 쓰는 롸업이다&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G4t30/btsLxNApE3C/rJausKscR3S1nBWj4AWSSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG4t30%2FbtsLxNApE3C%2FrJausKscR3S1nBWj4AWSSK%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;240&quot; height=&quot;80&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;또 백만년만에 쓰는 롸업이다&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Explanation&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디지털 포렌식을 공부하며 처음하였던 것이 각 파일 구조를 기반으로 바이너리 데이터를 분석하는 것이었기에 이 문제를 보고 자신있게 시작했던 기억이 난다. 아무튼 우선 &lt;b&gt;chal.py를 열어서 코드를 분석&lt;/b&gt;한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2APsN/btsLwdtNJqN/VGFeh2FIZX2SlZk31ghFK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2APsN/btsLwdtNJqN/VGFeh2FIZX2SlZk31ghFK0/img.png&quot; data-alt=&quot;&amp;amp;lt;chal.py&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2APsN/btsLwdtNJqN/VGFeh2FIZX2SlZk31ghFK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2APsN%2FbtsLwdtNJqN%2FVGFeh2FIZX2SlZk31ghFK0%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;472&quot; height=&quot;237&quot; data-origin-width=&quot;472&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;chal.py&amp;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;flag.bmp 파일을 열어서 data에 해당 파일의 바이너리 데이터를 저장하고&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) data[:0x1C] = b'\x00' * 0x1C&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;첫 번째 바이트부터 0x1C까지&lt;/li&gt;
&lt;li&gt;즉, 0~28바이트까지 '00'으로 저장(1C이므로 길이는 28바이트)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;2) data[0x22:0x36] = b'\x00' * 0x14&lt;/b&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;0x22번째 바이트 부터 0x36번째 바이트까지 0x14길이의 데이터를 '00'으로 저장&lt;/li&gt;
&lt;li&gt;34번째 바이트부터 54번째 바이트까지 20바이트를 '00'으로 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에 다시 수정한 파일을 flag.bmp.broken으로 저장한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl6Tco/btsLxGamyqI/dF5gWL5GvdhKnlL6tJWPYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl6Tco/btsLxGamyqI/dF5gWL5GvdhKnlL6tJWPYk/img.png&quot; data-alt=&quot;&amp;amp;lt;flag.bmp.broken 파일 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl6Tco/btsLxGamyqI/dF5gWL5GvdhKnlL6tJWPYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl6Tco%2FbtsLxGamyqI%2FdF5gWL5GvdhKnlL6tJWPYk%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;778&quot; height=&quot;217&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;flag.bmp.broken 파일 확인&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;16진수 한 개의 값은 2개의 문자로 이루어져 있으며 문자 1개의 크기는 4bit이므로 16진수 한 개의 값은 4bit+4bit=1byte가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 flag.bmp.broken 파일을 확인해보면 위와 같이 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;빨간 박스 안의 28바이트가 00으로 수정되었으며 파란 박스 안의 20바이트가 00으로 수정&lt;/span&gt;되었음을 알 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;우선 BitMapFile Header에 정의된 구조체에 의거하여 14바이트의 File Header 데이터를 수정해본다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&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;837&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byTbXy/btsLyT7O4CY/u9lzolx3P4Jge7F9m7PN91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byTbXy/btsLyT7O4CY/u9lzolx3P4Jge7F9m7PN91/img.png&quot; data-alt=&quot;&amp;amp;lt;File Header 수정&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byTbXy/btsLyT7O4CY/u9lzolx3P4Jge7F9m7PN91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyTbXy%2FbtsLyT7O4CY%2Fu9lzolx3P4Jge7F9m7PN91%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;837&quot; height=&quot;180&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;File Header 수정&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;우선 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;처음 2바이트는 .bmp 파일의 파일 시그니처인 '42 4D'를 입력&lt;/b&gt;&lt;/span&gt;한다[1].&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coKvcW/btsLyDD2W08/OvxcJ3xP7PVEq7rT2sqzU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coKvcW/btsLyDD2W08/OvxcJ3xP7PVEq7rT2sqzU0/img.png&quot; data-alt=&quot;&amp;amp;lt;속성에서 파일 크기 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coKvcW/btsLyDD2W08/OvxcJ3xP7PVEq7rT2sqzU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoKvcW%2FbtsLyDD2W08%2FOvxcJ3xP7PVEq7rT2sqzU0%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;460&quot; height=&quot;286&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;속성에서 파일 크기 확인&amp;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;b&gt;다음 4바이트는 파일의 크기를 입력&lt;/b&gt;한다. 파일 속성에서 파일 크기 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;14,309,622 바이트를 확인할 수 있으며 16진수로 변환하면 &quot;00 DA 58 F6&quot;이 되지만 컴퓨터는 데이터를 Little Endian 방식으로 처리하기 때문에 이에 맞게 &quot;F6 58 DA 00&quot;를 입력&lt;/b&gt;&lt;/span&gt;해준다[2].&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;다음 2바이트 + 2바이트 총 4바이트는 는 예약된 영역이므로 항상 0이다. 따라서 &quot;00&quot;을 입력&lt;/b&gt;&lt;/span&gt;한다[3][4].&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;그 다음 4바이트는 픽셀 데이터의 시작 위치(오프셋)로 헤더 영역들의 length 합을 입력하며 file header의 14바이트와 info header의 40바이트를 더하여 54바이트, 16진수로 &quot;36&quot;을 입력&lt;/b&gt;&lt;/span&gt;한다[5].&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;파일명도 flag.bmp로 저장하고 작업을 편리하게 하기 위하여 나머지는 010 editer를 사용하여 분석 및 수정&lt;/b&gt;한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xsJFO/btsLyXh5Evy/kxfwDyoIjMMKe2McKRlQq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xsJFO/btsLyXh5Evy/kxfwDyoIjMMKe2McKRlQq1/img.png&quot; data-alt=&quot;&amp;amp;lt;010 editor 사용&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xsJFO/btsLyXh5Evy/kxfwDyoIjMMKe2McKRlQq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxsJFO%2FbtsLyXh5Evy%2FkxfwDyoIjMMKe2McKRlQq1%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;579&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;010 editor 사용&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;file header는 hxd editor로 수정하였기에&lt;b&gt; info(info header)를 살펴본다.&lt;/b&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;841&quot; data-origin-height=&quot;293&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CF6b2/btsLvTvmWHc/il0XJLndWHslNyU9Camibk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CF6b2/btsLvTvmWHc/il0XJLndWHslNyU9Camibk/img.png&quot; data-alt=&quot;&amp;amp;lt;가로(Width)와 세로(Height)를 제외한 나머지 값 입력&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CF6b2/btsLvTvmWHc/il0XJLndWHslNyU9Camibk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCF6b2%2FbtsLvTvmWHc%2Fil0XJLndWHslNyU9Camibk%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;841&quot; height=&quot;293&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;293&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;가로(Width)와 세로(Height)를 제외한 나머지 값 입력&amp;gt;&lt;/figcaption&gt;
&lt;/figure&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;info header의 크기는 40바이트이므로 biSize에 40을 입력&lt;/b&gt;&lt;/span&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;biPlanes의 지원되는 값은 1로 고정되므로 1을 입력&lt;/b&gt;&lt;/span&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;biSizeImage는 이미지 데이터의 크기이다. 전체 데이터의 크기가 14309622이므로 header 크기인 54바이트를 제외하면 14309568바이트가 된다.&lt;/b&gt;&lt;/span&gt; 밑의 나머지 데이터는 일반적으로 0이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl1PyR/btsLyuNZIo7/Gz7haiWPKK0NBf2sd4jkz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl1PyR/btsLyuNZIo7/Gz7haiWPKK0NBf2sd4jkz1/img.png&quot; data-alt=&quot;&amp;amp;lt;입력한 데이터&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl1PyR/btsLyuNZIo7/Gz7haiWPKK0NBf2sd4jkz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl1PyR%2FbtsLyuNZIo7%2FGz7haiWPKK0NBf2sd4jkz1%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;752&quot; height=&quot;125&quot; data-origin-width=&quot;752&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;입력한 데이터&amp;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;b&gt;Width와 Height값을 구하기 위하여 경우의 수&lt;/b&gt;를 생각해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PNG 파일은 CRC 값을 이용하여 width와 height 값을 구할 수 있지만 BMP 파일에서는 불가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;이미지 데이터의 크기가 14309568바이트(14309622 - 54)이며 픽셀에 할당된 바이트 수가 24bit(biBitCount)이므로 3바이트이다. 따라서 픽셀 데이터의 크기는 14309568 / 3을 수행하면 4,769,856바이트&lt;/b&gt;&lt;/span&gt;가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 Width * Height = 4,769,856이 되는 경우의 수를 코드를 짜서 살펴본다.&lt;/p&gt;
&lt;pre id=&quot;code_1735069977518&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def findDimensions(totalPixels):
    dimensions = set()
    for width in range(1, int(totalPixels**0.5) + 1):
        if totalPixels % width == 0:
            height = totalPixels // width
            dimensions.add((width, height))
            dimensions.add((height, width))
    return sorted(dimensions)

totalPixels = 4769856
dimensions = findDimensions(totalPixels)

for width, height in dimensions:
    print(f&quot;Width: {width}, Height: {height}&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;320&quot; data-origin-height=&quot;797&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2mVAE/btsLv8Tu2w1/InRiOKUkB0c0VRKZfAYuLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2mVAE/btsLv8Tu2w1/InRiOKUkB0c0VRKZfAYuLK/img.png&quot; data-alt=&quot;&amp;amp;lt;모든 경우의 수 출력&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2mVAE/btsLv8Tu2w1/InRiOKUkB0c0VRKZfAYuLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2mVAE%2FbtsLv8Tu2w1%2FInRiOKUkB0c0VRKZfAYuLK%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;227&quot; height=&quot;565&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;797&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;모든 경우의 수 출력&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Width * Height =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;4,769,856이 되는 모든 경우의 수를 출력해보니 경우의 수가 많으므로 직접 바이너리 데이터를 수정해가며 찾는 것 보다는 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;각 경우의 수에 해당하는 Width와 Height 값들을 수정 및 각각의 bmp 파일로 저장하여 명확히 복구된 이미지 파일을 찾아본다.&lt;/b&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_1735071299954&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def findDimensions(totalPixels):
    dimensions = set()
    for width in range(1, int(totalPixels**0.5) + 1):
        if totalPixels % width == 0:
            height = totalPixels // width
            dimensions.add((width, height))
            dimensions.add((height, width))
    return sorted(dimensions)

def convertLittleEndianBytes(value, length):
    return value.to_bytes(length, 'little')

def saveBmpFiles(originalBmpPath, totalPixels):
    dimensions = findDimensions(totalPixels)

    with open(originalBmpPath, 'rb') as bmpFile:
        originalData = bmpFile.read()

    for width, height in dimensions:
        modifiedData = bytearray(originalData)

        widthBytes = convertLittleEndianBytes(width, 4)
        heightBytes = convertLittleEndianBytes(height, 4)

        modifiedData[18:22] = widthBytes
        modifiedData[22:26] = heightBytes

        newFileName = f&quot;flag_{width}x{height}.bmp&quot;
        with open(newFileName, 'wb') as newBmpFile:
            newBmpFile.write(modifiedData)

originalBmpPath = 'flag.bmp'
totalPixels = 4769856
saveBmpFiles(originalBmpPath, totalPixels)&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;1686&quot; data-origin-height=&quot;680&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KKTzi/btsLv5P7crR/4x1OBhKCuGsutpu0fi7cpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KKTzi/btsLv5P7crR/4x1OBhKCuGsutpu0fi7cpK/img.png&quot; data-alt=&quot;&amp;amp;lt;코드 동작 결과&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KKTzi/btsLv5P7crR/4x1OBhKCuGsutpu0fi7cpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKKTzi%2FbtsLv5P7crR%2F4x1OBhKCuGsutpu0fi7cpK%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;1686&quot; height=&quot;680&quot; data-origin-width=&quot;1686&quot; data-origin-height=&quot;680&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;코드 동작 결과&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 코드를 동작하였을 때 정상적으로 Width와 Height 길이에 대한 경우의 수에 따른 bmp 파일들이 생성되며 여기서 &lt;b&gt;이미지가 명확히 보이는 파일을 찾아보면&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1410&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctjAEI/btsLyWDtIBt/jtSy4AEkohA5D3fqizqwzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctjAEI/btsLyWDtIBt/jtSy4AEkohA5D3fqizqwzk/img.png&quot; data-alt=&quot;&amp;amp;lt;flag 획득&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctjAEI/btsLyWDtIBt/jtSy4AEkohA5D3fqizqwzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctjAEI%2FbtsLyWDtIBt%2FjtSy4AEkohA5D3fqizqwzk%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;1410&quot; height=&quot;438&quot; data-origin-width=&quot;1410&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;flag 획득&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 flag를 찾을 수 있다.&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. Reference&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@jaeyoonheo/bmp-reader&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@jaeyoonheo/bmp-reader&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.naver.com/lunchtime82/100055581202&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/lunchtime82/100055581202&lt;/a&gt;&lt;/p&gt;</description>
      <category>Digital_forensic/CTF</category>
      <category>Bitmap</category>
      <category>bmp</category>
      <category>bmp header</category>
      <category>bmp recovery</category>
      <category>bmp signature</category>
      <category>bmp structure</category>
      <category>ctf</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/100</guid>
      <comments>https://neck392.tistory.com/100#entry100comment</comments>
      <pubDate>Wed, 25 Dec 2024 02:30:49 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] sleepingshark Write-up</title>
      <link>https://neck392.tistory.com/99</link>
      <description>&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. sleepingshark&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2022 Fall GoN Open Qual&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QHYlp/btsLup7FN71/M4jOCj39DpdKZAIXYEtoeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QHYlp/btsLup7FN71/M4jOCj39DpdKZAIXYEtoeK/img.png&quot; data-alt=&quot;&amp;amp;lt;문제 설명&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QHYlp/btsLup7FN71/M4jOCj39DpdKZAIXYEtoeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQHYlp%2FbtsLup7FN71%2FM4jOCj39DpdKZAIXYEtoeK%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;452&quot; height=&quot;232&quot; data-origin-width=&quot;452&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;문제 설명&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;117&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lIMzC/btsLtGI1JDA/rAPLKVWEhUDSAfG8MMiZG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lIMzC/btsLtGI1JDA/rAPLKVWEhUDSAfG8MMiZG0/img.png&quot; data-alt=&quot;&amp;amp;lt;문제 파일&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lIMzC/btsLtGI1JDA/rAPLKVWEhUDSAfG8MMiZG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlIMzC%2FbtsLtGI1JDA%2FrAPLKVWEhUDSAfG8MMiZG0%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;117&quot; height=&quot;71&quot; data-origin-width=&quot;117&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;문제 파일&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Explanation&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dump.pcap 파일을 Wireshark로 열어보면 아래&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;와 같이 나타난다.&lt;span&gt;&amp;nbsp;&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;1858&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WYjvy/btsLvmP03wk/oo0KsMRQlwWnAV0IPiut3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WYjvy/btsLvmP03wk/oo0KsMRQlwWnAV0IPiut3K/img.png&quot; data-alt=&quot;&amp;amp;lt;문제 파일 열기&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WYjvy/btsLvmP03wk/oo0KsMRQlwWnAV0IPiut3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWYjvy%2FbtsLvmP03wk%2Foo0KsMRQlwWnAV0IPiut3K%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;626&quot; height=&quot;198&quot; data-origin-width=&quot;1858&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;문제 파일 열기&amp;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;HTTP 통신이 많기에 &lt;b&gt;server로의 요청 내역들&lt;/b&gt;만 모아본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s4Gxl/btsLuYIvYeL/IUdkIa8M2WkYqsJpA2sZM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s4Gxl/btsLuYIvYeL/IUdkIa8M2WkYqsJpA2sZM0/img.png&quot; data-alt=&quot;&amp;amp;lt;http 통신 확인 경로&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s4Gxl/btsLuYIvYeL/IUdkIa8M2WkYqsJpA2sZM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs4Gxl%2FbtsLuYIvYeL%2FIUdkIa8M2WkYqsJpA2sZM0%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;358&quot; height=&quot;384&quot; data-origin-width=&quot;642&quot; data-origin-height=&quot;689&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;http 통신 확인 경로&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위와 같이 &lt;b&gt;Statistics &amp;gt; HTTP &amp;gt; Requests&lt;/b&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;1885&quot; data-origin-height=&quot;516&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RJXBi/btsLvwE0nrY/QLsnQeLNUum3JjnqZHN6e1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RJXBi/btsLvwE0nrY/QLsnQeLNUum3JjnqZHN6e1/img.png&quot; data-alt=&quot;&amp;amp;lt;http 통신 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RJXBi/btsLvwE0nrY/QLsnQeLNUum3JjnqZHN6e1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRJXBi%2FbtsLvwE0nrY%2FQLsnQeLNUum3JjnqZHN6e1%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;688&quot; height=&quot;188&quot; data-origin-width=&quot;1885&quot; data-origin-height=&quot;516&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;http 통신 확인&amp;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 style=&quot;background-color: #f3c000;&quot;&gt;URL의 Query string을 보았을 때 SELECT와 FROM 등 SQL 문법으로 보이는 문자열들을 확인할 수 있으며 SQL Injection 공격을 시도 중인 것으로 유추&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;1872&quot; data-origin-height=&quot;136&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OjjA0/btsLvwkGAdQ/QmAZoOd8svNTxu8ftQMMg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OjjA0/btsLvwkGAdQ/QmAZoOd8svNTxu8ftQMMg1/img.png&quot; data-alt=&quot;&amp;amp;lt;Info 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OjjA0/btsLvwkGAdQ/QmAZoOd8svNTxu8ftQMMg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOjjA0%2FbtsLvwkGAdQ%2FQmAZoOd8svNTxu8ftQMMg1%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;1872&quot; height=&quot;136&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;136&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;Info 확인&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 명확히 판단하기 위하여 &lt;b&gt;http 패킷을 분석&lt;/b&gt; 해본다. 위 사진과 같이 http로 필터링을 한 후에 무작위의 19번 패킷의 Info를 URL Decode한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crtb6D/btsLtKLn9Ug/mzKkcbBEec4cI0bCEHObO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crtb6D/btsLtKLn9Ug/mzKkcbBEec4cI0bCEHObO1/img.png&quot; data-alt=&quot;&amp;amp;lt;URL decode 결과&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crtb6D/btsLtKLn9Ug/mzKkcbBEec4cI0bCEHObO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcrtb6D%2FbtsLtKLn9Ug%2FmzKkcbBEec4cI0bCEHObO1%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;611&quot; height=&quot;312&quot; data-origin-width=&quot;1187&quot; data-origin-height=&quot;606&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;URL decode 결과&amp;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;pre id=&quot;code_1734976201792&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT IF(ASCII(SUBSTRING((SELECT flag FROM s3cr3t LIMIT 1),34,1))=45, SLEEP(3), 0)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 Query String을 확인할 수 있다. 쿼리문을 분석해보면 다음과 같다.&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;SELECT flag FROM s3cr3t LIMIT 1&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;s3cr3t라는 테이블에서 flag라는 컬럼의 1번째 행의 데이터&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SUBSTRING((SELECT flag FROM s3cr3t LIMIT 1), 34, 1)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;flag 컬럼 데이터에서 34인덱스의 문자를 추출(0부터 시작)하여 반환&lt;/li&gt;
&lt;li&gt;34는 start position 즉 추출을 시작할 문자의 위치를 의미&lt;/li&gt;
&lt;li&gt;1은 length 추출할 문자의 길이를 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;IF(ASCII(...) = 45, SLEEP(3), 0)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;추출한 문자의 ASCII 값이 45인지 확인(45는 -(하이픈)을 의미)&lt;/li&gt;
&lt;li&gt;조건이 참(TRUE)이면 3초 동안 지연 후 응답(SLEEP(3)).&lt;/li&gt;
&lt;li&gt;조건이 거짓(FALSE)이면 지연 시간 없이 즉시 응답을 반환(0).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리문을 분석해보았을 때 처음 유추하였던 것과 같이 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;SQL Injection 공격이 맞으며 그 중에서도 정확히는 Time-Based Bllind SQL Injection 공격을 시도하고 있음&lt;/b&gt;&lt;/span&gt;을 알 수 있다. 3초 동안 지연 후 응답된다는 것은 웹 페이지가 3초 동안 로딩되며 3초 이후에 정상적으로 웹 페이지가 로딩 후 동작되는 것을 의미한다. 이를 통하여 조건의 논리를 알 수 있다.&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;932&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt7c2k/btsLuoOsap4/hhrk82X7qu5a39gjRsRb8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt7c2k/btsLuoOsap4/hhrk82X7qu5a39gjRsRb8k/img.png&quot; data-alt=&quot;&amp;amp;lt;쿼리문들 중 성공 여부 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt7c2k/btsLuoOsap4/hhrk82X7qu5a39gjRsRb8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt7c2k%2FbtsLuoOsap4%2Fhhrk82X7qu5a39gjRsRb8k%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;932&quot; height=&quot;230&quot; data-origin-width=&quot;932&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;쿼리문들 중 성공 여부 확인&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;http 패킷 중에서 3초 뒤에 응답이 온 패킷을 필터링하였을 때 위와 같이 &lt;b&gt;조건이 true인 패킷들이 존재&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;b&gt;위와 같은 형태의 쿼리문이 포함된 http 패킷들을 요청하였을 때 3초 뒤에 응답이 온 패킷들 즉, 요청 값이 True인 패킷들만 모아서 Query String을 분석하면 flag를 획득&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;Python의 pyshark 라이브러리를 사용하여 코드를 짜본다.&lt;/p&gt;
&lt;pre id=&quot;code_1734977771427&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import pyshark
import urllib.parse
import re

def extractLongDelayTimeRequests(pcapFile, setTime):
    cap = pyshark.FileCapture(pcapFile, display_filter='http')

    requestTimes = {}
    flag_parts = []

    for packet in cap:
        if 'HTTP' in packet:
            try:
                if hasattr(packet.http, 'request_full_uri'):
                    streamIndex = packet.tcp.stream
                    requestTime = float(packet.sniff_timestamp)
                    requestTimes[streamIndex] = (packet, requestTime)

                elif hasattr(packet.http, 'response_code'):
                    streamIndex = packet.tcp.stream
                    responseTime = float(packet.sniff_timestamp)

                    if streamIndex in requestTimes:
                        requestPacket, requestTime = requestTimes[streamIndex]
                        delayTime = responseTime - requestTime

                        if delayTime &amp;gt; setTime:
                            fullUri = requestPacket.http.request_full_uri
                            decodedUri = urllib.parse.unquote(fullUri)
                            print(f&quot;Request Info (Encoded URI): {fullUri}&quot;)
                            print(f&quot;Request Info (Decoded URI): {decodedUri}&quot;)
                            print(f&quot;Delay Time: {delayTime} seconds&quot;)
                            print(&quot;&quot;)

                            match = re.search(r'SUBSTRING.*?,(\d+),1\)\)=(\d+)', decodedUri)
                            if match:
                                position = int(match.group(1))
                                ascii_value = int(match.group(2))
                                if len(flag_parts) &amp;lt; position:
                                    flag_parts.extend([None] * (position - len(flag_parts)))
                                flag_parts[position - 1] = chr(ascii_value)

            except AttributeError:
                continue

    cap.close()

    flag = ''.join([char for char in flag_parts if char])
    print(f&quot;Extracted Flag: {flag}&quot;)

pcapFile = 'dump.pcap'
setTime = 3
extractLongDelayTimeRequests(pcapFile, setTime)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 위와 같이 Delay Time, 지연 시간이 3초 이상인 패킷들을 식별하여 해당 패킷의 Info와 Decode한 값들을 출력되게 하였다. 조건이 참인 모든 패킷들이 출력된다. 이후 Decode한 Query String에서 문자의 위치에 해당하는 아스키 코드 값을 조합하여 flag를 출력한다(출력되는 패킷들은 모두 조건이 True인 패킷들).&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;1813&quot; data-origin-height=&quot;687&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FgE8Y/btsLurRWFFn/hSHq0FEWGfiG1mk3VM5ba0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FgE8Y/btsLurRWFFn/hSHq0FEWGfiG1mk3VM5ba0/img.png&quot; data-alt=&quot;&amp;amp;lt;코드 동작 결과&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FgE8Y/btsLurRWFFn/hSHq0FEWGfiG1mk3VM5ba0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFgE8Y%2FbtsLurRWFFn%2FhSHq0FEWGfiG1mk3VM5ba0%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;1813&quot; height=&quot;687&quot; data-origin-width=&quot;1813&quot; data-origin-height=&quot;687&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;코드 동작 결과&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 동작시키면 위와 같이 flag를 획득할 수 있다.&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. Reference&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://taesam.tistory.com/25&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://taesam.tistory.com/25&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.naver.com/stop2y/221033895075&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/stop2y/221033895075&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.urldecoder.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.urldecoder.org/&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;&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;</description>
      <category>Digital_forensic/CTF</category>
      <category>blind sql injection</category>
      <category>ctf</category>
      <category>Injection</category>
      <category>SQL Injection</category>
      <category>time-based sql injection</category>
      <category>wireshark</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/99</guid>
      <comments>https://neck392.tistory.com/99#entry99comment</comments>
      <pubDate>Tue, 24 Dec 2024 03:29:08 +0900</pubDate>
    </item>
    <item>
      <title>[Dreamhack] lolololologfile Write-up</title>
      <link>https://neck392.tistory.com/98</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. lolololologfile&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2022 Christmas CTF&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bko6Id/btsLqa2YonU/MH6HhdHBsEdh7YjsdXvtJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bko6Id/btsLqa2YonU/MH6HhdHBsEdh7YjsdXvtJ0/img.png&quot; data-alt=&quot;&amp;amp;lt;문제 설명&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bko6Id/btsLqa2YonU/MH6HhdHBsEdh7YjsdXvtJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbko6Id%2FbtsLqa2YonU%2FMH6HhdHBsEdh7YjsdXvtJ0%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;433&quot; height=&quot;290&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;문제 설명&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;117&quot; data-origin-height=&quot;37&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEBim1/btsLn5B6Xt3/YN8PBuHuV72zzKlESjb1zK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEBim1/btsLn5B6Xt3/YN8PBuHuV72zzKlESjb1zK/img.png&quot; data-alt=&quot;&amp;amp;lt;문제 파일&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEBim1/btsLn5B6Xt3/YN8PBuHuV72zzKlESjb1zK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEBim1%2FbtsLn5B6Xt3%2FYN8PBuHuV72zzKlESjb1zK%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;117&quot; height=&quot;37&quot; data-origin-width=&quot;117&quot; data-origin-height=&quot;37&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;문제 파일&amp;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;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;75&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccHRhZ/btsLpGVEi41/sJorfBnFFYzncoROfITB80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccHRhZ/btsLpGVEi41/sJorfBnFFYzncoROfITB80/img.png&quot; data-alt=&quot;&amp;amp;lt;이백만년만에 쓰는 롸업&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccHRhZ/btsLpGVEi41/sJorfBnFFYzncoROfITB80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccHRhZ%2FbtsLpGVEi41%2FsJorfBnFFYzncoROfITB80%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;170&quot; height=&quot;75&quot; data-origin-width=&quot;170&quot; data-origin-height=&quot;75&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;이백만년만에 쓰는 롸업&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Explanation&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문제 설명을 확인해보면 flag가 담긴 PDF 파일을 삭제하였다고 한다. FTK Imager로 분석해보았을 때 휴지통 아티팩트에도 남겨진 데이터가 없는 것으로 보아 &lt;b&gt;휴지통에서도 완전히 삭제된 파일이라 유추&lt;/b&gt;할 수 있다. 따라서 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;비할당된 영역(unallocated space)을 통하여 PDF 파일 복구&lt;/span&gt;를 시도한다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;완전히 &lt;b&gt;삭제된 파일은 경우에 따라 복구할 수 있다.&lt;/b&gt; NTFS 뿐만이 아니라 FAT 등의 파일 시스템은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;실제 클러스터에 저장된 내용을 삭제하는 것이 아니라 파일에 할당된 클러스터를 사용 가능한 상태로 바꾸어 클러스터들이 다른 파일에 할당될 수 있게 한다.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;따라서, 이미 덮어 써진 파일은 복구가 불가능하지만 그렇지 않은 삭제된 파일들은 복구할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;삭제되어 데이터와 클러스터와의 연결이 끊어진 데이터들은 비할당 영역에 존재한다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; 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;을 뜻한다. 주로 포맷 이전의 데이터, 디렉토리 엔트리 정보 즉 메타데이터가 사라진 데이터들이 남아있다. FAT 영역에서 0x00의 값을 갖는 클러스터가 비할당 클러스터인데, 이 부분을 분석하면 데이터 카빙이 가능하다.&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;문제 파일을 FTK Imager로 열어본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cH09Za/btsLodz7hTi/GlFygzaUFjwBWMeW7rs1b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cH09Za/btsLodz7hTi/GlFygzaUFjwBWMeW7rs1b0/img.png&quot; data-alt=&quot;&amp;amp;lt;비할당된 영역 확인&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cH09Za/btsLodz7hTi/GlFygzaUFjwBWMeW7rs1b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcH09Za%2FbtsLodz7hTi%2FGlFygzaUFjwBWMeW7rs1b0%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;813&quot; height=&quot;365&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;비할당된 영역 확인&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;비할당 영역에 위와 같이 남겨진 데이터들이 존재함을 식별할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; 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;591&quot; data-origin-height=&quot;571&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/No3wZ/btsLpQjn0hJ/7CyqerR8ukGolcChnyLMnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/No3wZ/btsLpQjn0hJ/7CyqerR8ukGolcChnyLMnK/img.png&quot; data-alt=&quot;&amp;amp;lt;PDF 파일 시그니처 식별&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/No3wZ/btsLpQjn0hJ/7CyqerR8ukGolcChnyLMnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNo3wZ%2FbtsLpQjn0hJ%2F7CyqerR8ukGolcChnyLMnK%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;591&quot; height=&quot;571&quot; data-origin-width=&quot;591&quot; data-origin-height=&quot;571&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;PDF 파일 시그니처 식별&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;02067 파일의 바이너리 데이터를 확인해보면&lt;b&gt; PDF 파일의 헤더 시그니처를 식별&lt;/b&gt;할 수 있다. PDF 파일 구조를 기반으로 PDF 파일의 푸터 시그니처도 찾아본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMT15n/btsLpNfTpa7/KgYDPJo9bjwYobtHh4Dnv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMT15n/btsLpNfTpa7/KgYDPJo9bjwYobtHh4Dnv0/img.png&quot; data-alt=&quot;&amp;amp;lt;PDF 파일의 푸터 시그니처 식별&amp;amp;gt;.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMT15n/btsLpNfTpa7/KgYDPJo9bjwYobtHh4Dnv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMT15n%2FbtsLpNfTpa7%2FKgYDPJo9bjwYobtHh4Dnv0%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;587&quot; height=&quot;450&quot; data-origin-width=&quot;587&quot; data-origin-height=&quot;450&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;PDF 파일의 푸터 시그니처 식별&amp;gt;.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;CTRL+F&quot;를 통하여 PDF 파일의 푸터 시그니처인 &quot;25 25 45 4F 46&quot;을 찾아본 결과 05082 파일에서 발견할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, &quot;02067&quot; 파일과 &quot;03405&quot;, &quot;04466&quot;, &quot;05082&quot; 파일들을 Export하여 하나의 파일로 합치는 과정을 수행한다.&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;803&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/paGfN/btsLoDZtn5d/KvL7sswqKPJzULKKKXQmh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/paGfN/btsLoDZtn5d/KvL7sswqKPJzULKKKXQmh1/img.png&quot; data-alt=&quot;&amp;amp;lt;하나로 합친 무제1 파일&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/paGfN/btsLoDZtn5d/KvL7sswqKPJzULKKKXQmh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpaGfN%2FbtsLoDZtn5d%2FKvL7sswqKPJzULKKKXQmh1%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;803&quot; height=&quot;198&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;하나로 합친 무제1 파일&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 파일들의 바이터리 데이터를 순차적으로 연결하여 &quot;무제1&quot;로 저장한뒤에 .pdf 파일로 확장자를 추가한다.&lt;/p&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;1107&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/by8arp/btsLpFoUIBO/KbrV8D5R9kVVSPUz1PZEB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/by8arp/btsLpFoUIBO/KbrV8D5R9kVVSPUz1PZEB1/img.png&quot; data-alt=&quot;&amp;amp;lt;flag 획득&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/by8arp/btsLpFoUIBO/KbrV8D5R9kVVSPUz1PZEB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fby8arp%2FbtsLpFoUIBO%2FKbrV8D5R9kVVSPUz1PZEB1%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;619&quot; height=&quot;537&quot; data-origin-width=&quot;1107&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;flag 획득&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 flag를 획득할 수 있다.&lt;/p&gt;</description>
      <category>Digital_forensic/CTF</category>
      <category>2022 christmas ctf</category>
      <category>carving</category>
      <category>ctf</category>
      <category>log</category>
      <category>logfile</category>
      <category>recyclebin</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/98</guid>
      <comments>https://neck392.tistory.com/98#entry98comment</comments>
      <pubDate>Thu, 19 Dec 2024 16:57:13 +0900</pubDate>
    </item>
    <item>
      <title>[메모리] 메모리 할당(적재) 개요</title>
      <link>https://neck392.tistory.com/96</link>
      <description>&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;1473&quot; data-origin-height=&quot;704&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRQIjD/btsLaFRa605/EjMD1dKliD6k4LGcQITRg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRQIjD/btsLaFRa605/EjMD1dKliD6k4LGcQITRg0/img.png&quot; data-alt=&quot;&amp;amp;lt;메모리 할당 방법&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRQIjD/btsLaFRa605/EjMD1dKliD6k4LGcQITRg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRQIjD%2FbtsLaFRa605%2FEjMD1dKliD6k4LGcQITRg0%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;316&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1473&quot; data-origin-height=&quot;704&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;메모리 할당 방법&amp;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;b&gt;운영체제가 프로그램 전체를 수용할 수 있는 연속적인 메인 메모리 공간을 확보&lt;/b&gt;해야 했다. &lt;b&gt;프로그램이 여유 메모리보다 큰 경우 이를 실행할 수 없었다.&lt;/b&gt;&amp;nbsp; 이와 같이 &lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;b&gt;연속적인 메인 메모리 공간에 프로그램을 할당하는 방식을 연속 메모리 할당(Contiguous Memory Allocation)&lt;/b&gt;&lt;/span&gt;이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연속 메모리 할당에서 발생하는 문제점을 해결하기 위해 불연속 메모리 할당(Noncontiguous Memory Allocation)을 통해 메모리를 더 효율적으로 사용할 수 있다. 제한된 압축으로 메모리 할당을 변화시켜 외부 단편화 문제를 해결하면 연속적인 공간을 만들 수는 있지만, 실행 시간이 낭비된다.&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;background-color: #f3c000;&quot;&gt;&lt;b&gt;불연속 메모리 할당은 프로그램을 블록 또는 세그먼트(Segment)로 나누고, 하나의 프로그램에 대하여 연속적으로 붙어 있지 않은 슬롯(Slot)들에 이 정보를 배치&lt;/b&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;&lt;b&gt;연속 메모리 할당&lt;/b&gt;&lt;/h4&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;&lt;b&gt;불연속 메모리 할당&lt;/b&gt;&lt;/h4&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;Harvey M. Deitel, Paul J. Deitel, and David R. Choffnes, Operating Systems, 3rd ed., Pearson, 2003.&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;Hyun-Hoe Koo, Operating System: Principles and Structure Illustrated, 1st ed., Hanbit Academy, 2016. (7th printing, 2022).&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer_science/Memory</category>
      <author>neck392</author>
      <guid isPermaLink="true">https://neck392.tistory.com/96</guid>
      <comments>https://neck392.tistory.com/96#entry96comment</comments>
      <pubDate>Mon, 9 Dec 2024 04:23:35 +0900</pubDate>
    </item>
  </channel>
</rss>