From cf6e9c14ee456cf0699a9e5ac2769ecd0441901a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=8F=84=EB=A1=9C=EB=A1=B1?= Date: Fri, 24 Oct 2025 11:46:18 +0900 Subject: [PATCH] asdf --- src/content/blog/01-whpre-writeup/temp.txt | 215 --------------------- 1 file changed, 215 deletions(-) delete mode 100644 src/content/blog/01-whpre-writeup/temp.txt diff --git a/src/content/blog/01-whpre-writeup/temp.txt b/src/content/blog/01-whpre-writeup/temp.txt deleted file mode 100644 index 8c052d9..0000000 --- a/src/content/blog/01-whpre-writeup/temp.txt +++ /dev/null @@ -1,215 +0,0 @@ -1 Introduction -본문서는 2025 WHITEHAT 예선에 참가한팀헤일메리의문항별WriteUp이며, AI sommelier, Leakage -Investigation만을 다룬다(나머진 귀찮음) -2 AI sommelier -2.1 Overview -서버는 llama3.2가생성한텍스트 10개와gemma3가생성한텍스트 10개(총20개)를 무작위로제공한다. -참가자는 각텍스트의생성모델을판별하여 정답을제출하면 플래그를 획득한다. -핵심가정은다음과같다. 언어모델은 자기가 생성했을 법한 텍스트에 대해 상대적으로 더높은 로그우도 -(log-likelihood)를 부여한다. 따라서후보모델을실제로구동한뒤입력텍스트에 대한logprobs를 관측하면 -모델기원분류(model attribution)가가능하다. -2.2 Methodology -입력x = (t1, . . . , tn)에 대해모델M 의로그우도합은 -log pM (x) = -n -i=1 -로정의된다. 길이편향을줄이기위해평균로그우도 -mean -_logprob(x) = 1 -n -n -i=1 -를 사용하고, 근소차이의안정화를 위해바이트 단위교차엔트로피 -−log pM (x) -bpb(x) = -log pM (ti |t all_strings.txt -검색 결과, 다음문장이발견되었다. -From now on, let’s hide our messages inside images. -이문장을통해공격자가이후스테가노그래피(steganography) 기법을사용할것임을유추할수있었다. -4 -3) TCP 스트림 재구성. 해당 문장을포함하는 패킷을기준으로양단 IP/포트를 식별하고, 동일한TCP -세션내의모든페이로드를 시간순서대로병합하여 전체 대화를 복원하였다. -from scapy.all import * -pkts = rdpcap(’prob.pcap’) -needle = b"From now on, let’s hide our messages inside images." -for i, p in enumerate(pkts): -if p.haslayer(Raw) and needle in bytes(p[Raw].load): -src, dst = p[IP].src, p[IP].dst -sport, dport = p[TCP].sport, p[TCP].dport -stream = [] -for q in pkts: -if q.haslayer(IP) and q.haslayer(TCP): -cond1 = (q[IP].src, q[IP].dst, q[TCP].sport, q[TCP].dport) == (src, dst, sport, -dport) -cond2 = (q[IP].src, q[IP].dst, q[TCP].sport, q[TCP].dport) == (dst, src, dport, -sport) -if cond1 or cond2: stream.append(q) -data = b’’.join(bytes(q[Raw].load) for q in sorted(stream, key=lambda x: x.time) if q. -haslayer(Raw)) -print(data.decode(’utf-8’, errors=’ignore’)[:2000]) -break -복원된대화에는 다음과같은내용이포함되어 있었다. -[198.51.100.23] From now on, let’s hide our messages inside images. -[192.168.110.128] Inside images? How would anyone know to look for them? -[198.51.100.23] I’ll put a four-digit length at the front. Just read up to that. -[192.168.110.128] Got it. How can I notice that an image has a message? -[198.51.100.23] I’ll invert the red channel so you can notice. -이를 통해, 메시지는 이미지파일내부에 숨겨지며, Red 채널반전과4자리 길이 프리픽스가삽입된것으로 -확인되었다. -4) 이미지 파일 카빙. 두IP 간스트림 중PNG 파일서명을포함하는 데이터 블록을추출하였다. -from scapy.all import * -from collections import defaultdict -pkts = rdpcap(’prob.pcap’) -ip1, ip2 = "198.51.100.23", "192.168.110.128" -streams = defaultdict(list) -for i, p in enumerate(pkts): -if p.haslayer(IP) and p.haslayer(TCP): -if {p[IP].src, p[IP].dst} == {ip1, ip2}: -sid = f"{p[IP].src}:{p[TCP].sport}-{p[IP].dst}:{p[TCP].dport}" -5 -streams[sid].append(p) -for sid, arr in streams.items(): -payload = b’’.join(bytes(p[Raw].load) for p in sorted(arr, key=lambda x: x[TCP].seq) if p. -haslayer(Raw)) -if b’\x89PNG’ in payload: -start = payload.find(b’\x89PNG’) -blob = payload[start:] -endmk = b’IEND\xae\x42\x60\x82’ -end = blob.find(endmk) -if end != -1: -blob = blob[:end+len(endmk)] -name = f"extracted_{sid.replace(’:’,’_’).replace(’-’,’_’)}.png" -with open(name, ’wb’) as f: -f.write(blob) -print("Saved:", name, len(blob)) -총8개의PNG 이미지파일이추출되었으며, 모두동일한Red 채널반전패턴을보였다. -5) 스테가노그래피분석. Red 채널반전이존재하는 이미지를 분석한결과평문 메시지가존재함을확인 -하였다. (https://stylesuxx.github.io/steganography/ 활용) -발견된메시지에서찾은필요한정보는 다음과같다: -The product name is "HelioKey." The release date for this product is "2025-12-25". -3.3 Results -분석을통해다음정보를 복원하였다. -• ProductName: HelioKey -• ReleaseDate: 2025-12-25 -최종플래그는 다음과같다. -whitehat2025{HelioKey_2025-12-25} -3.4 Discussion -본문제는 네트워크 포렌식과스테가노그래피분석이결합된전형적인정보유출사건분석유형이다. 단 -순한HTTPS 트래픽에 가려져있었지만, 평문 문자열(‘hide our messages inside images‘)이결정적단서가 -되었으며, 이후Red 채널반전이라는 명시적시그널을통해은닉 데이터의존재를 확인할수있었다