Forensics/DFC

[2025 DFC] 2025 디지털포렌식 챌린지 - 203 - Ooops, your files have ben encrypted!

pental 2026. 4. 20. 20:58
Step-by-step methodology:

 문제를 풀기에 앞서 대회측에서 제공한 파일의 해시값과 다운로드 받은 해시값이 일치하는지 확인한다.

그림 1 대회에서 주어진 파일 정보

그림 2 HashTab을 이용한 해시 확인

파일의 해시값과 다운로드 받은 파일의 해시값이 A530D2ABDEBF60EE0D81B7DC6ED92C7A으로 동일함을 확인하였다.

반디집 프로그램을 통해 PD12M_dataset.zip.enc 파일을 열어보면 다음과 같은 오류를 확인 할 수 있다.

그림 3 반디집을 통해 PD12M_dataset.zip.enc 파일 열기

오류에서 확인되는 내용은 이 파일은 손상된 파일입니다.” 이며, 확인 버튼을 클릭하면 일부 파일이 식별된다.

그림 4 그림 3에서 확인 버튼 클릭 후 보여지는 화면

추출할 수 있는 데이터는 다음과 같다.

FileName
012.jpg
013.jpg
014.jpg
015.jpg
016.jpg
017.jpg
018.jpg
019.jpg
020.jpg

1 반디집을 통해 PD12M_dataset.zip.enc 에서 추출된 파일

그림 5 그림 4에서 확인된 파일 추출 모습

하지만 추출된 020.jpg 파일에서 확인 할 수 있듯, 제대로 추출되지 않음을 육안으로 확인 할 수 있다. 따라서 손상된 zip 아카이브를 복구 하기 위해 zip도구를 사용한다.

zip도구의 강력모드인 -FF 인자를 통해 복구된 결과를 temp.zip으로 출력하는 명령은 다음과 같다.

zip -FF PD12M_dataset.zip.enc --out temp.zip

그림 6 zip 명령어를 사용한 강제 복구 과정 및 결과

실행 결과는 위 사진과 같으며 temp.zip에서 확인되며 추출할 수 있는 데이터는 다음과 같다.

그림 7 temp.zip 에서 발견된 46개의 데이터

46개의 데이터를 확인할 수 있으며, 그중 085번의 파일은 docx파일로 확인되었다. 해당 docx파일에서는 100 – A Key Too Familiar 이라는 문제를 추가적으로 확인 할 수 있다.

203번의 문제를 풀기 위해서는 100번 문제를 필수적으로 풀어야 하기에, 해당 문제 풀이를 먼저 진행한다. 100번 문제에서 확인 할 수 있는 내용은 다음과 같다. 

Instructions


Description
당신은 컴퓨터에 존재하는 랜섬웨어 프로그램을 역공학 하였습니다. 결과, 암호화에 사용된 키는 찾아낼 없었지만, 랜섬웨어에 취약점이 있음을 확인하였습니다. 암호화된 파일들을 분석하여 FLAG 찾아내시기 바랍니다.

Hint.

-       랜섬웨어는 스트림 암호를 사용하였습니다.

-       FLAG 바탕화면에 존재하는 FILE_H 저장되어 있습니다.

-       FILE_A ~ FILE_H ASCII 문자열로만 구성되어 있습니다.

-       FLAG FILE_A ~ FILE_H 만으로도 획득 가능합니다.

Target Hash (MD5)
Disk image (.img) D330AF1D7D67349334F96B902652945D
Download url: https://www.dropbox.com/scl/fi/9u0jepu2z80mkvgdlg4ub/diskdump.img?rlkey=6x8mfdw557vkd29nmf3deqmpv&st=i9kf1zjy&dl=0

Credits

1)   FLAG 획득함 (100 points)

다운로드 URL을 통해 받은 diskdump.img 파일과 문제에서 주어진 MD5의 해시값이 동일한지 확인한다.

그림 8 HashTab을 이용한 diskdump.img 파일 해시 정보

다운로드 받은 파일이 주어진 해시값 D330AF1D7D67349334F96B902652945D과 동일함을 확인하였다. 해당 img 파일을 FTK Imager에 탑재해 분석을 진행한다.

그림 9 FTK Imager을 사용하여 diskdump.img 인식 모습

FTK Imager을 통해서 [NTFS]/[root]/Users/DFC/Desktop 폴더에서 FILE_A ~ H.txt 파일 총 8개를 확인 할 수 있다. 또한 [NTFS]/[root]/Users/DFC/Downloads 폴더에서 각 프로그램 설치파일 또한 enc 확장자를 가진체 암호화 된 모습을 확인 할 수 있다.

그림 10 Downloads 폴더에서 확인된 암호화된 파일들 

분석을 위해서 Everything-1.4.1.1005.x64-Setup.exe, python-3.13.3-amd64.exe, node-v22.16.0-x64.msi 파일을 공식 홈페이지를 통해서 다운로드 했다. 아래는 각 다운로드 버전 및 링크이다.

FileName Version URL
Everything 1.4.1.1005.x64 https://www.voidtools.com/ko-kr/support/everything/previous_versions/
python 3.13.3-amd64 https://www.python.org/downloads/release/python-3133/
node v22.16.0 https://nodejs.org/en/blog/release/v22.16.0/

2 분석을 위해 사용된 설치 파일 정보

이 케이스에서는 랜섬웨어가 스트림 암호를 사용했다는 것이 주어졌고, 동일한 키스트림을 여러 파일에 재 사용했다고 전재하고 시작한다. 따라서 각 암호화된 파일과 원본에 대해서 XOR 연산결과를 비교하여 키스트림 추출을 진행한다.

encrypted_file = "python-3.13.3-amd64.exe.enc"
original_file = "python-3.13.3-amd64.exe"
keystream_output = "python-keystream"
with open(encrypted_file, "rb") as enc_fp, open(original_file, "rb") as orig_fp:
    enc_data = enc_fp.read()
    orig_data = orig_fp.read()
if len(enc_data) != len(orig_data):
    print(f"[!] Warning: File sizes are off ({len(enc_data)} vs {len(orig_data)}), will chop to the shorter one.")
length = min(len(enc_data), len(orig_data))
keystream = []
for i in range(length):
    keystream.append(enc_data[i] ^ orig_data[i])
xor_result = bytes(keystream)
with open(keystream_output, "wb") as out_fp:
    out_fp.write(xor_result)
 
print(f"[+] XOR complete. Output written to '{keystream_output}' ({len(xor_result)} bytes).")
 

3 XOR 연산을 통한 키스트림 추출 코드

위 코드를 수행한 결과 python-keystream 파일이 생성되었으며 아래는 해당 파일의 해시 값 및 정보이다.

그림 11 추출된 keystream의 해시값 정보

FileName python-keystream
FileSize 28,640,016 바이트
MD5 232D6D772CBFFA2A512BCB0C90062165
SHA-1 A17A73FAE191A54651C9DABEB4F1A89EB21CAB55

4 keystream의 정보

추출된 키스트림을 바탕으로 바탕화면에 존재하는 FILE_A ~ H.txt 파일 복호화를 진행한다. 다음은 복호화에 사용한 코드이다.

import pathlib
keystream_path = "python-keystream"
encrypted_files = [
    "FILE_A.txt.enc",
    "FILE_B.txt.enc",
    "FILE_C.txt.enc",
    "FILE_D.txt.enc",
    "FILE_E.txt.enc",
    "FILE_F.txt.enc",
    "FILE_G.txt.enc",
    "FILE_H.txt.enc"
]
output_path = "TEMP.txt"
try:
    ks_bytes = pathlib.Path(keystream_path).read_bytes()
except Exception as e:
    print(f"Error: Couldn't read keystream file – {e}")
    exit(1)
with open(output_path, "wb") as out_file:
    for enc_filename in encrypted_files:
        try:
            encrypted_data = pathlib.Path(enc_filename).read_bytes()
        except FileNotFoundError:
            print(f"(!) Skipping missing file: {enc_filename}")
            continue
        except Exception as e:
            print(f"(!) Error reading {enc_filename}: {e}")
            continue
        usable_len = min(len(encrypted_data), len(ks_bytes))
        decrypted = []
        for i in range(usable_len):
            decrypted.append(encrypted_data[i] ^ ks_bytes[i])
 
        out_file.write(bytes(decrypted))
print(f"Decryption done. Combined output written to '{output_path}'")
 
 

5 FILE_A ~ H.txt 파일 복호화를 위해 사용된 코드

해당 코드를 실행한 결과 temp.txt 파일이 생성되었으며 아래는 텍스트 파일에서 발견된 내용이다.

그림 12 temp.txt 에서 확인 된 평문 메시지

Cryptographic algorithms must be used in strict compliance with the recommended requirements.In particular, take care with stream cipher to avoid vulnerabilities such as the many-time pad attack.OTP security dies once pads repeat; treat every pad as a singleuse consumable block of data.
Reusing keystreams can lead to plaintext leaks. Update the key or change the mode before reusing.XORing two reused ciphertexts yields P1^P2; The guessed ciphertext can lead to a recovery.Reused pads turn pairs of ciphertexts into clues. With just one good ciphertext, you can decrypt the rest.By the way, one of the encrypted compressed files that should be on this computer is missing. Where is it?Flag: T29vcHMsIGZsYWch

6 temp.txt 파일의 평문

FlagT29vcHMsIGZsYWch 으로 적혀있으며 base64를 통해 인코딩 된 것을 확인하였다. base64decode.org 를 통해 온라인 base64 디코딩을 진행한다.

그림 13 base64decode.org를 이용한 복호화

: Ooops, flag!

 

다시 203번 문제로 돌아와 zip파일 암호화에 사용됬을걸로 추정되는 스트림분석을 진행하였다.

그림 14 keystream 분석 과정 좌 node, python

그림 15 27BA74 이후 두 키스트림의 차이

오프셋 27BA74부분까지 node 키스트림과 python 키스트림이 동일한 것을 확인하였다. 하지만 python에서는 27BA74 이후 부분이 00으로 되어 있고, node 부분에는 데이터가 있는 것을 확인하였다. 이 분석을 통해서 키스트림과 널바이트의 상관 관계 분석을 진행하였으며, 그 결과 python-keystream에서는 0x27BA74부분의 2배인 0x4F74E8 부분에 동일하게 키스트림이 있는 것을 확인하였다.

그림 16 오프셋 27BA74에서 확인된 동일한 키스트림

위에서 확인했던 46개의 데이터에서 숫자 연속성이 깨지는 부분을 확인하였으며, 001.jpg ~ 011.jpg, 021.jpg ~ 028.jpg, 038.jpg ~ 046.jpg, 057.jpg ~ 062.jpg, 071.jpg ~ 081.jpg, 092.jpg ~ 100.jpg 가 누락된 것을 확인 할 수 있다. 따라서 주어진 enc 파일에 020.jpg 뒷 부분을 확인한다.

그림 17 020.jpg 를 검색한 모습

020.jpg 다음으로 발견되는 jpg 문자열은 029.jpg이다. 따라서 020.jpg 내용부터 029.jpg가 발견된 부분을 따로 저장해 분석을 진행했다. (0x1DF40F ~ 0x2DE60D)

복호화에 사용한 키스트림의 길이와 시작 위치를 찾기 위해 키스트림 파일(key)을 이용한 XOR 브루트포스 복호화 실험을 수행하였다. 우선 key 파일의 앞부분을 이용해 암호화된 ZIP 파일 전체를 XOR으로 복호화해 보았고, 복호화가 정상적으로 진행되는 시작 지점이 0x1DF40F에서 1079바이트 떨어진 위치임을 확인하였다. 이를 통해 총 키 길이가 0x1DF40F + 1079 = 1,964,102바이트로 추정되었다.

키스트림이 순환 특성을 가지므로 실제 암호화의 시작점이 위에서 구한 길이보다 얼마만큼 더 떨어져 있을 수 있음을 고려해야 했다. 특히 시작 위치가 4096바이트 단위로 어긋날 가능성이 있어, 스크립트를 일반화하고 브루트포스 방식으로 여러 후보 길이를 시도하도록 확장하였다. 키 길이를 늘려가며 각 경우에 대해 복호화 파일을 생성하였다. 그 결과 생성된 ZIP들 가운데 1개 파일이 정상적으로 압축해제 되었고 100장의 이미지 파일을 복구할 수 있었다. 사용한 코드는 다음과 같다.

def _xor_bytes(data, key):
    if not key:
        raise ValueError("키가 비어있습니다: 'python-keystream' 파일을 확인하세요")
    out = bytearray(len(data))
    klen = len(key)
    for idx in range(len(data)):
        out[idx] = data[idx] ^ key[idx % klen]
    return bytes(out)
 
with open('python-keystream', 'rb') as kf:
    keystream = kf.read()
with open('PD12M_dataset.zip.enc', 'rb') as ef:
    encrypted = ef.read()
 
for i in range(0, 100) :
    part_len = 982051 + 2048 * i
    prefix = keystream[:part_len]
    pad_unit = b'\x00'
    zeros = pad_unit * part_len
    predict_key = prefix + zeros
 
    decrypted = _xor_bytes(encrypted, predict_key)
    out_name = f'decrypted_{i}.zip'
    with open(out_name, 'wb') as out_f:
        out_f.write(decrypted)
 

7 복구에 사용된 코드

그림 18 코드 실행 후 100개의 파일이 모두 복구된 모습

그림 19 추출된 100개의 파일

복구 된 파일은 총 100개 이며 각 파일 이름 및 해시값은 다음과 같다.

FileName SHA256
000.jpg e55d9e636ce8197ecad3c52b1073de098e28cd9a02c035a1f5ada5c186c3e086
001.jpg 54272c394e867833f17099d1fd2462c9562ff33397eda9795a9a2280808b2915
002.jpg 432e775467541125a8923bad3646a51688ccc7af08562ff5670faba1490ab71f
003.jpg bad50ba579e971f73942f90a9c014bc52fef02c56155fdc600c6f262a7cd75c4
004.jpg 7602d9134fb58ac8433081e3161de088ba54da857056c31c04b20a9a924629bf
005.jpg f4136cefc4c29775390075e25eece8fd2a62dccd466969d9f0dcc02d5e11e8df
006.jpg 8488fcfe4dc24d5ffe0d1dcb42dc8662b04978cf55c540c98991177f164fcd64
007.jpg 420da57b90142851499968f85dc99616b103febbb60ace31cab72b64d9076700
008.jpg e2a648f9729b029f3f53329409aca962d98f7763d8110f93d8ffdd882a402233
009.jpg 41891d418c99586c508cf3947426761933f200e37c68ef4776816b8fe0c6e2b4
010.jpg 73b060e408f0bf8c2133d6b5bb4fefb191ccfcd108f28e90b98331797c743016
011.jpg 93e76032b7a0f0db464b5e004859f09576485e5370fdab102b7305d63638354a
012.jpg 65c682f04647569debbc5f321d43a18c10617ea180e7db6cf45e23c0f1090e7a
013.jpg 75116d1266299dd256eb9e00dffeae90054c725c9b7b4718d9903f9537675711
014.jpg a1e51ea589d0d69757065365b845fe550a1848c962dccd4f8b81d1f0ddef1155
015.jpg 25121a3273ee88f0df1337d35aad7f3b7f10b84edfa1814b298eed43f88bd11a
016.jpg 12ed595337cef2251e9fc6ac12d592264847ffbc9e07e788988b8bf54ee5db38
017.jpg 9517cfe1e757e16eff5e3259ef8ee83fd98a40af9b954e807894382bac3fc9c0
018.jpg d378aa5496e30b4f2f498966e5f7c608c3b86bd1c0f1d748ea1c487db8dac335
019.jpg 677ec871700acd0e0ce6b0e1f3068109438f88ce3d0cd39b895ae53c000c9042
020.jpg 283f9dba470570467c661b18dbba9cf1007d7342334e8187437ff9ea7fe2429a
021.jpg 54b63d61782c384e4bed74b7b0e984f4d7ac6e954f649f8542450cd074060366
022.jpg 32f8e76a8973c98b1400634c84917c5d6ef1468dfbbd44f271823e3cca708f42
023.jpg bc2396495058e8b02717a58be4fad9d1c14ddcf4319e611093d30b5736851083
024.jpg a123d84525160846f58bb2551e6a01091c871f10e835f9bb65299734bbbcabec
025.jpg 70a0678489b8dc88b63803110ec8d1b8b34888607da479b5d7b102bb6725a759
026.jpg 5ef67a9a3b0f7c1f404f82f17365fe1991f44a94d85f84eeee651c252bae4575
027.jpg e553fbb2d611ec2fc617c5b5e4f4e08e5b8094b55ac594191b6e1e4c4eea4d13
028.jpg 7cd5ca48fca223a182bc10e0730247e85e4694e21f19444382c23f6df90912c3
029.jpg 119bf2d66f4226b8309dfc1e3763de5061bea8bec3379f76a17a12380db0fc7e
030.jpg 3e2863569378a3c1ad574352e5c040ace6146956f1fd70f7b03c52f292bce673
031.jpg 8db8a962144e815483844703ac04e5668b994289a631f4a47ac436b9d2bc5a20
032.jpg 1a29041185e7ceaa3684f91edcfead59a17b9b392e0aa21c97a340e4e01abb8e
033.jpg 54402ef3e746e4fafe11b8e62851f37901e3186277f75227d346d8007f2f9fe6
034.jpg 952a3b521a166c9a0298ecd6b4b6c984e64dd230cc2780d3b7eb0e74207e9956
035.jpg e4fa96b54edd334969c1befabc50642caf4ea317f34b4c6137353b58a20c3a7f
036.jpg 95a1dc9c7b613f7692d12cb9af04b9148fdafe122cea4b4bce72cf582c96e43c
037.jpg 8a121ea8fe8a812f70e25d39eac401e4e76d6dd7097a3be33b23b8d1de47008e
038.jpg 51e688aa7eba6be0fec1986f23b3a621ac8186c2d26bbe9955e58063713d5599
039.jpg f63c4e097b374e37256e5343a5d6c7258fd0403ce3e7e635baa6f949c4be37cc
040.jpg f8fe607f1299b595fc6284fa9f806b1214ff4fab6eae45f07a162d884dbdf378
041.jpg ad29d72b517e64d96553ade02aa3d9a315f539c84bed72c904a70398754a2f67
042.jpg 1941f33daa2ed8ed046d449bf1e30bfa7b0b89bc55f4561d667c2147997df53d
043.jpg 4f2e8ccafa0b37ee96729e4510f32d9f945dc5fdf46059f90d96cdb233883fe5
044.jpg cfade6a2cf26ea6b398605510d1365d17968439d70f4eede484e4a74a0dfd083
045.jpg 743e154ee31a780647770869fe1e81985430a403bf3d876932a34d309524970d
046.jpg 5d2d7a738f6f7f2434e412ae13ff698e7e630f128db597ec7af219616d3a41ff
047.jpg 4ae608c262f4a3690f76b6a4c43ce670b2a156be00dce90d1430fbadc21b1d68
048.jpg 575ef9765c2545e85391e608fdf9cd0f514f92bad34e6f8eb52ad4a6e3877750
049.jpg f5bc9f8cc2ed62e53dcb29c3cd8085c4015d2fbd59551dafd6ff0ef35b9efe9b
050.jpg f8a57d0643609ff2b7dd29a1a6b1a04a866540422d5d2113c717968147da157e
051.jpg 9c47048b9f4cb927639a50b5ccec067f77b44eef7097cf827d6dd537066a4bd7
052.jpg e38209e2ad3df0b5c36b8cbf408d7063cca58c8e256686452535829d38aedf28
053.jpg ddaea6d062b8d2b5cf2c5a8971d6a5e90670c7b3181478b348f17feab8c0ac50
054.jpg b2a813f44fda174f4dc553b9dea1f0349f526e3cde54ce0b09f7c30ad61349ef
055.jpg 43a721782cf0aa8153dd1208d96df75913b7cc1c4fa36e7c26160d7b1a3892bb
056.jpg 4096de8557452cd4340a39f490d83d73db063379a1faa0c3aca56c676c3c358e
057.jpg 6b2173ac8b74273df65bc6198ed78fe0ffa974a512ffe2a2ca219ccedc0fccd1
058.jpg c0ec02162ead5297f463abcdc21d10f391f3e3f53f0520253407cd6f37fb0008
059.jpg f4881a1ddd87ae81366f9b67548fc62f9f27617d2c1b7599c7ec2cf164cf8976
060.jpg 69a1f40718d35c4c5cd3394b6063e2c9f0160d3610210d4ee9d222f3fa12f393
061.jpg 63919b22fdff3796c193bf7c22e8ef5f230088a62b3053fee5b865ebe0331a6d
062.jpg 6f408488ab51d95d4b88ee3c3f950e4d30e096b7a8ee30b04e46e5719eafbaee
063.jpg f223e40609779931c233d3e520281083427d8dd21c767a837f283f9b354d9b2b
064.jpg 34c60e55adc557b77bda9a6bad312de6aa6d0cb5d9fd0ddecf83be2eaa82edf8
065.jpg 6f70487ffb30962d737d3580ffcdeb0e980c93af9e015fa79d7f799f593967fb
066.jpg 5e3fdc8a1c6348d990bcc164d0513d504d20d29374e3f2cff28b68eb18b02c57
067.jpg e16e05553c6f69260b463a16077a6601071bbde3ec9bdceae72f1066d25c871f
068.jpg 9dc9d7d8476883476e517cfbcb9a3b56fc793d464403cb222f72696ab4034791
069.jpg dd5cae541faaaa5e51e649699838278e2374f4b496169756236a3c67b3b2d1e2
070.jpg ad7ffba7bae55a0772b4fdf74f960c687170a9c381c3781d7a332ab72340a873
071.jpg b879856dc38bf5a0de6955ffc872811254f81783f47bf78449f771c598ce4066
072.jpg 17ba314bf7b7d5537edd42f1c5d93c2a25f3ba7af65487aa1bfbf9ca1b030ca0
073.jpg f0f3e4f2f2bc57a49d4d761ac603d4a079fac7702396dcb0ee3cb1c7fd1d893d
074.jpg ec915beb9e12f32d467298388ba678d933ba539cf92e104aaa2b281a5b3fe083
075.jpg b1069fee3cdc995f2f93447501af29cdc8bbb8c8ee690f66757f6ab3415c89d6
076.jpg 6e3baf882e5d310cdb59d95de5fd71baf6345b68c99d4eb2a205fea5f4759407
077.jpg f5eecbd13cd597ee214ab788ccf9574f6d4ecb7d0da845678b0cf4605f8abebe
078.jpg 2341b398277d2211453e6a8a4df61a6480a1643c5bee639bee3dbcedfca754cf
079.jpg 7188c9059aabedcbd01770ba34184fd7ed3d7f02c5d6cadb29fd441b7c932602
080.jpg 49ad230c6c11ac9124768566f6b3cb57350a2648609251ddaebe5a5793eee2af
081.jpg 9fb35e59bed3ada2069b707047a30c77d2fc4b5c5ccc0fc6aa15846564dcc8fa
082.jpg 2383505b28b2b5e01d2457d646e50aa06843880607c54c957c2e5fe6d28b158f
083.jpg e0c55fbca33757cdde58c28a073e2ec6d8d18fb89f522c9a0e344b3c1939149d
084.jpg 7c705703060c68b8af61dadcadaf497ef90541681711af66d2e41c6976516f8c
085 - A Key Too Familiar(ko,en).docx 70bf4cf76692accca06779b384d2281b3d96a9386ac593d75b3d7da55fac9a22
086.jpg 15d43227afc5cdbba30e36cd68c521d8132859d09a1e4c6963e61fe4f07a7f8b
087.jpg 26c866c5e9bdeaf211d52dbca62113bd167f5ef6f3226e0604639e8a35d1e6c3
088.jpg 1a3ffe670cbe0603b53e2be18349578807495b0c4e92abea2f7c0f06e8df5b4c
089.jpg 76caa577d7f8a72bc16121f94ae9d8639353e354f52d5ade6de5114117cb1f38
090.jpg c9dcd8d000bab94e0e4694d1fae8d52c09e91a55778dd6f28ae3f0b04ebf3c44
091.jpg ad8e0b8ee16970db43d683d82f5463eab8ae3dad260f8f51a924c71291821ac8
092.jpg cf2e5b962894e317a139d8fcc66fcbcceec0c8e8d62c9627cb402f28e86f35c6
093.jpg 66e787c1d66cab51602ed86b3efe9b445105b1f624627f5203a46c8aff9b12b8
094.jpg 04b4b5b135e1da4848697bb7baef7cd8332a3b3d3e0ed716fa24ac7721a23046
095.jpg e66a9a404bb8980e4bd498b8533bb6cdce4bf9a260e9692f07e5aad4414843ea
096.jpg 2d228defbfafa7ba082be19dd25a51196d5136acde510fcc997b4523e96a6afe
097.jpg 0d1a2f1354b0a13ef2f6c66b2b7465f749d18aa24b64d8870788e60a078b30ab
098.jpg 848e1b11a6030a4d61672b9ad3fbba1309abd978e42f66f17016274e3c173f76
099.jpg 9bdc53c96af007c5887c33dbf8dfa5aee4e81a928ae3a9e8b4514cc02169ab0b