###### tags: `Computer Security`
# Steganography
[TOC]
這次網路攻防實習的一個關於圖片隱寫術的Lab作業還蠻有趣的,所以決定來記錄一下。
## 1. A PNG Tale
(hint: PNG filter)
Teaser CONFidence CTF 2015 的題目,給了一張Png圖片。

PNG圖片在壓縮前會經過filter,把PNG的資料解壓縮後看起來會像這樣子~[2]~
以3x2的png為例的話
```python=
with open ('3x2b.png','rb') as f:
result = f.seek (0x6a)
data = f.read()
d = zlib.decompress(data)
print ([x for x in d])
>>>
[1, 224, 215, 200, 227, 241, 48, 2, 36, 225, 1, 253, 255, 195, 245, 182, 244, 232, 245, 57]
```
下面的list輸出的東西的對應關係
```
filter RGB RGB RGB
1 (224,215,200) (227,241,48) (2,36,225)
1 (253,255,195) (245,182,244, (232,245,57)
```
其中filter的值就是使用的filter method,對應如下~[1]~:
```
Type Name
0 None
1 Sub
2 Up
3 Average
4 Paeth
```
不過這邊的重點其實是要說這個filter method的值是可以藏東西的。
用Hex viewer打開圖片找IDAT的起始點(0x29)

圖片的維度是800x800,所以應該會有800x800*3(RGB)+800(一行一個filter bit)個bit,把這些bit都撈出來整理一下,就可以得到flag。
```python=
d = zlib.decompress(data)
dd = [x for x in d]
bits = ''
for i in range(0, len(dd), 800 *3 +1):
bit = dd[i : i + 800 * 3 + 1]
bits += str(bit[0])
endianess_filterbits = [bits[i:i+8][::-1] for i in range(0, len(bits), 8)]
flag = ''
for x in endianess_filterbits:
if x=='00000000':
break
flag += unhexlify('%x' % int('0b'+str(x), 2)).decode('ascii')
print(flag)
```
:::success
:triangular_flag_on_post: DrgnS{WhenYouGazeIntoThePNGThePNGAlsoGazezIntoYou}
:::
#### Reference:
1. https://www.w3.org/TR/PNG-Filters.html
2. https://stackoverflow.com/questions/49017937/png-decompressed-idat-chunk-how-to-read
3. https://github.com/ctfs/write-ups-2015/tree/master/confidence-ctf-teaser-2015/stegano/a-png-tale-200
---
## 2. doge_stege
plaidCTF 2014的題目,圖片就是那個doge。

用StegSolve在Random color map下可以看到原本看不見的Flag。


:::success
:triangular_flag_on_post: pctf{keep_doge_alive_2014}
:::
---
## 3. Stegano
(hint: LSB, bruteforce)
Volga CTF 2014的一題,給了一張風景圖。

pixel的R/G/B值可以是00000000(0)-11111111(255),人眼無法輕易察覺最小的bit(LSB)的變動,因此可以利用LSB的值來藏資料。
把圖片中每個pixel的LSB抓出來:
```python=
img = Image.open('bonas.png')
pixels = img.getdata()
lsbs = ''
for i in pixels:
lsbs += bin(i)[-1]
```
接著把它8個bit8個bit讀取,會發現它是一個RAR檔:
```python=
for i in range(5):
bits = lsbs[8*i: 8*(i+1)]
print(chr(int(bits, base=2)))
>>> R
>>> A
>>> R
>>> !
>>>
```
所有LSB串起來輸出成rar檔
```python=
outfile=open("steg.rar","ab")
for i in range(0,len(lsbs),8):
outfile.write(bytes([int(lsbs[i: i+8], base = 2)]))
```
結果解壓發現有密碼,用john the ripper去破解,得到密碼為`brute`
```
$ rar2john steg.rar > rar.hashes
! file name: Techniques for Data Hiding.pdf
! file name: flag.txt
! steg.rar: Not recognising any more headers
$ john -incrementall:ASCII rar.hashes
brute (steg.rar)
```
成功解壓縮後,發現裡面有flag.txt,打開得到flag。

:::success
:triangular_flag_on_post: {LSB_is_ubiquitous}
:::
#### Reference:
1. https://whitesnake1004.tistory.com/352
2. https://dfir.science/2014/07/how-to-cracking-zip-and-rar-protected.html