CTF misc圖片類總結(入門級)


misc文件頭尾
文件隱寫和圖片隱寫步驟
misc思路
MISC文件隱寫總結(圖片,音頻,視頻,壓縮包等文件)
misc圖片類總結(新賽題)

一、改高寬

打開圖片發現下面好像少了什么。
在這里插入圖片描述
WinHex打開可以看到PNG的文件頭
在這里插入圖片描述
解析:
(固定)八個字節89 50 4E 47 0D 0A 1A 0A為png的文件頭
(固定)四個字節00 00 00 0D(即為十進制的13)代表數據塊的長度為13
(固定)四個字節49 48 44 52(即為ASCII碼的IHDR)是文件頭數據塊的標示(IDCH)
(可變)13位數據塊(IHDR)
前四個字節代表該圖片的寬
后四個字節代表該圖片的高
后五個字節依次為:
Bit depth、ColorType、Compression method、Filter method、Interlace method
(可變)剩余四字節為該png的CRC檢驗碼,由從IDCH到IHDR的十七位字節進行crc計算得到。
文件尾:AE 42 60 82

圖片尺寸為787x500(高x寬)
00 00 00 0D 說明IHDR頭塊長為13
49 48 44 52 IHDR標識
00 00 03 13 圖像的寬,787像素
00 00 01 F4 圖像的高,500像素
發現高寬錯誤
這里需要注意的是,文件寬度不能任意修改,需要根據 IHDR 塊的 CRC 值爆破得到寬度,否則圖片顯示錯誤不能得到 flag

import os
import binascii
import struct

crcbp = open("D:\\桌面文件\\bingbing.png", "rb").read()    #打開圖片
for i in range(2000):
    for j in range(2000):
        data = crcbp[12:16] + \
            struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
        crc32 = binascii.crc32(data) & 0xffffffff
        if(crc32 == 0xda5a4a50):    #圖片當前CRC
            print(i, j)
            print('hex:', hex(i), hex(j))

在這里插入圖片描述
把高寬都改成787保存得flag
在這里插入圖片描述

二、lsb(最低有效位)隱寫+base64編碼圖片

lsb隱寫簡介

攻防世界Misc高手進階區 3-11

下載png文件,binwalk,發現zlib文件。
binwalk詳解
在這里插入圖片描述
在這里插入圖片描述
LSB隱寫,save bin,改后綴解壓,彈出已損壞,用winrar自帶的修復
在這里插入圖片描述
在這里插入圖片描述
結尾的=號判斷是base64編碼,開頭iVBORw0K說明是base64編碼的圖片。
用captfencoder加上頭,轉為圖片:FLAG{LSB_i5_SO_EASY}
在這里插入圖片描述

CRC32碰撞腳本

Misc中的有一類題目是要求我們知道加密后的rar文件中的內容。但是rar文件密碼我們不知道,直接爆破密碼也不是很現實。
但是當文件的大小比較小,或者字符數量較少時,就可以根據crc校驗碼來爆破出rar內部文件的內容。

在這里插入圖片描述
可以看到最后一列是對應文件的CRC校驗碼。並且每個文件只有4字節,所以可以看作每個CRC校驗碼都對應了唯一的文件。Python2爆破如下:

import binascii
import string
 
dic=string.printable #打印出字符表
crc1=0x7DE0AB32
crc2=0xB1441D53
crc3=0x49BD11F5
crc4=0xB42F1DFA
crc5=0x8163F43E
crc6=0x1FC8FEE5
 
for i in dic:
    for j in dic:
        for n in dic:
            for m in dic:
                s=i+j+n+m
                if(crc1==(binascii.crc32(s) & 0xffffffff)):
                    text1=s
                if (crc2 == (binascii.crc32(s) & 0xffffffff)):
                    text2=s
                if (crc3 == (binascii.crc32(s) & 0xffffffff)):
                    text3=s
                if (crc4 == (binascii.crc32(s) & 0xffffffff)):
                    text4=s
                if (crc5 == (binascii.crc32(s) & 0xffffffff)):
                    text5=s
                if (crc6 == (binascii.crc32(s) & 0xffffffff)):
                    text6=s
print text1+text2+text3+text4+text5+text6

CRC爆破的另一個腳本

三、盲水印+明文攻擊

攻防世界Misc的warmup,2017ciscn(全國大學生信息安全競賽)
下載打開,兩個一樣的open_forun.png, 明文攻擊,將open_forum.png壓縮成zip,然后使用ARCHPR的明文攻擊
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
注:兩個open_forum.png的crc32的值一樣,以及兩個文件被壓縮之后的大小,滿足明文攻擊要求。
在這里插入圖片描述
在這里插入圖片描述
解壓出來是這樣:
在這里插入圖片描述
兩個圖,試試盲水印:

python bwmforpy3.py decode fuli.png fuli2.png flag.png --oldseed

注:如果要讓python3兼容python2的random算法請加 --oldseed參數。結果就是flag.png。

在這里插入圖片描述

在這里插入圖片描述
盲水印詳解

傅里葉盲水印

VNCTF021 冰冰好像藏着秘密
傅里葉盲水印原理:
圖片經過傅里葉變換后,水印圖片直接按像素覆蓋到頻率域,因為頻譜是中心對稱的,所以加水印也要對稱的加,具體就是圖片分上下兩部分,左上加了什么,右下也要加同樣的內容。之后傅里葉反變換回去。解水印的時候變換到傅里葉變換提取就可以了。

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img = cv.imread('D:\\CTF\\FFT.png', 0) #直接讀為灰度圖像,不過此題已經是灰度圖片了
f = np.fft.fft2(img)            #做頻率變換
fshift = np.fft.fftshift(f)     #轉移像素做幅度譜
s1 = np.log(np.abs(fshift))#取絕對值:將復數變化成實數取對數的目的為了將數據變化到0-255
plt.subplot(121)
plt.imshow(img, 'gray')
plt.title('original')
plt.subplot(122)
plt.imshow(s1,'gray')
plt.title('center')
plt.show()

CTF盲水印詳解

四、IDAT塊隱寫

提數據+zlib解壓+625二維碼

圖像數據塊 IDAT(image data chunk):它存儲實際的數據,在數據流中可包含多個連續順序的圖像數據塊。IDAT 塊只有當上一個塊充滿時,才會繼續一個新的塊。

pngcheck.exe -v sctf.png

在這里插入圖片描述

前面的塊都是65524,到了0x150008變為45027,再到0x15aff7的138。
很明顯最后一個 IDAT 塊是有問題的,因為他本來應該並入到倒數第二個未滿的塊里。
0x150008中的45027位數據是正常的圖片信息。0x15aff7的138位數據是人為錄入的,且所在的數據塊也是人為創建的。
IDAT中的數據采用 LZ77 算法的派生算法進行壓縮,所以可以用 zlib 解壓縮。
可以用010 editor直接提取出數據,然后扔進zlib解壓腳本里解壓獲得原始數據。

查看異常數據塊的情況,使用010editor/winhex打開,導出異常數據塊:
在這里插入圖片描述
查找78 9C文件頭標志,zlib。
在這里插入圖片描述
將異常的IDAT數據塊斬頭去尾之后使用腳本解壓,在python2代碼如下:

import zlib
import binascii
IDAT = "789C5D91011280400802BF04FFFF5C75294B5537738A21A27D1E49CFD17DB3937A92E7E603880A6D485100901FB0410153350DE83112EA2D51C54CE2E585B15A2FC78E8872F51C6FC1881882F93D372DEF78E665B0C36C529622A0A45588138833A170A2071DDCD18219DB8C0D465D8B6989719645ED9C11C36AE3ABDAEFCFC0ACF023E77C17C7897667".decode('hex')
result = binascii.hexlify(zlib.decompress(IDAT))
print (result.decode('hex'))
print (len(result.decode('hex')))

得到壓縮后的文件:
在這里插入圖片描述
發現是625,是一個二維碼的矩陣,使用python2代碼做成二維碼:

from PIL import Image
MAX = 25
pic = Image.new("RGB",(MAX,MAX))
str ="1111111000100001101111111100000101110010110100000110111010100000000010111011011101001000000001011101101110101110110100101110110000010101011011010000011111111010101010101111111000000001011101110000000011010011000001010011101101111010101001000011100000000000101000000001001001101000100111001111011100111100001110111110001100101000110011100001010100011010001111010110000010100010110000011011101100100001110011100100001011111110100000000110101001000111101111111011100001101011011100000100001100110001111010111010001101001111100001011101011000111010011100101110100100111011011000110000010110001101000110001111111011010110111011011"
i=0
for y in range(0,MAX):
    for x in range(0,MAX):
        if(str[i] == '1'):
            pic.putpixel([x,y],(0,0,0))
        else:pic.putpixel([x,y],(255,255,255))
        i = i+1
pic.show()
pic.save("flag.png")

運行得到二維碼

png末尾藏zip

PNG (png),文件頭:89504E47 文件尾:49454E44AE426082
在這里插入圖片描述
從0304后全部保存,在前面和后面加上504B,后保存為zip
在這里插入圖片描述
用stegpy得到zip密碼:
在這里插入圖片描述

五、分離與拼接

convert分離gif+montage拼接

攻防世界MISC進階:glance-50,mma-ctf-2nd-2016

下載拿到一個gif圖片,很窄(寬2px)。
(1)用kali的convert命令先把gif分解開:

convert glance.gif flag.png

補充:
水平鏡像反轉圖片

convert -flop reverse.jpg reversed.jpg

垂直鏡像反轉圖片

convert -flip reverse.jpg reversed.jpg

convert命令使用

總共分離出來200個圖片。用工具:montage合成,命令:

montage flag*.png -tile x1 -geometry +0+0 flag.png

-tile是拼接時每行和每列的圖片數,這里用x1,就是只一行
-geometry是首選每個圖和邊框尺寸,我們邊框為0,圖照原始尺寸即可
flag:TWCTF{Bliss by Charles O’Rear}

(2)也可以直接用網站。GIF動態圖片是由多張靜態圖片組合而成,按照一定的順序和時間進行播放。該網站將GIF圖片反向分解成一張張靜態圖。GIF圖片有多少幀,就有多少張靜態圖片。
GIF分解網站

(3)也可以寫腳本

import os 
from PIL import Image

im = Image.new('RGB', (2*201,600))#new(mode,size) size is long and width
PATH = 'E:/ctf/glance.gif'

FILE_NAME = [i for i in os.listdir(PATH)]

width = 0
for i in FILE_NAME:
    im.paste(Image.open(PATH+i),(width,0,width+2,600))#box is 左,上,右,下
    width += 2
im.show()    

六、像素點合成

1、PPM格式+多種文件轉換網站

攻防世界 Misc Miscellaneous-200 defkthon-ctf
miscellaneous
adj. 混雜的; 各種各樣的;

(1)提供的flag.txt文件每行包含由三個逗號分隔的值組成的元組。這看起來像一個給定RGB值的圖像。
在這里插入圖片描述
總共有61366行:
在這里插入圖片描述
注:Linux wc命令用於計算字數。
-l或–lines 顯示行數。
-w或–words 只顯示字數。
-c或–bytes或–chars 只顯示Bytes數。
flag.txt文件的行數為61366、單詞數61366、字節數730988

圖像的尺寸是這個數字(61366)的等分,所以可能是:1,2,61,122,503,1006,30683,61366。
最可能的圖像大小是 122×503px 或 503×112px 。

注:px是分辨率的單位,是英語單詞pixel的縮寫,意為像素(組成屏幕圖像的最小獨立元素)。

將文本文件轉換為圖像的最可以將其轉換為PPM格式,其標題如下:

P3
122 503
255

注:PPM(Portable PixMap,便攜式像素映射)。這些圖片格式都相對比較容易處理,跟平台無關,所以稱之為portable,簡單理解,就是比較直接的圖片格式,比如PPM,其實就是把每一個點的RGB分別保存起來。所以,PPM格式的文件是沒有壓縮的,相對比較大,但是由於圖片格式簡單,一般作為圖片處理的中間文件(不會丟失文件信息),或者作為簡單的圖片格式保存。
PPM文件
PPM文件格式詳解

然后是flag.txt的內容,逗號用空格替換。(快捷鍵ctrl+h 實現替換的功能)
在這里插入圖片描述
TXT到PPM轉換器
這個網站可以轉換許多東西!
結果是flag.ppm。用極速看圖軟件打開(kali中可以直接打開):
在這里插入圖片描述

轉換為PNG,並翻轉+旋轉它,使它更容易閱讀,結果如下圖所示:

convert -flip -rotate 90 flag.ppm flag.png

在這里插入圖片描述

(2)分析文本發現是道畫圖題,直接編寫 python 程序

from ast import literal_eval as make_tuple
from PIL import Image
f = open('flag.txt', 'r')
corl = [make_tuple(line) for line in f.readlines()]
f.close()
img0 = Image.new('RGB', (270, 270), '#ffffff')
k=0
for i in range(246):
   for j in range(246):
      img0.putpixel ([i , j], corl[k])
      k=k+1
img0.save("result.png")

flag{ youc@n’tseeme }

七、流量類

1、wireshark提取數據流//tcpxtract

攻防世界misc進階Cephalopod
用wireshark搜索flag字符串,可以看到
在這里插入圖片描述
PNG頭的16進制為89504E47,然后搜索該16進制,找到一條TCP報文,然后追蹤TCP流。
可以看到這是一個圖片數據流。尾為:文件尾:AE 42 60 82。保留原始數據。

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
然后復制進去winhex只保留png頭尾數據,然后修改文件后綴名為png,就可以得到flag圖片
在這里插入圖片描述

tcpxtract

也可以直接

tcpxtract -f 1.pcap

得到一張png圖片 得到flag :HITB{95700d8aefdc1648b90a92f3a8460a2c}
Tcpxtract是用來從網卡抓包並將其還原成文件的一個開源軟件,它的基本原理是在抓取的數據包中匹配文件的特征頭和特征尾。

strings

strings webshell.pcapng | grep {

strings命令在對象文件或二進制文件中查找可打印的字符串。字符串是4個或更多可打印字符的任意序列,以換行符或空字符結束。 strings命令對識別隨機對象文件很有用。 grep 命令用於查找文件里符合條件的字符串

strings xxx.png
有時可以出flag

2、協議分級+導出HTTP對象

攻防世界-互相傷害!!!
wireshark打開,協議分級,基本都是TCP流量,又以超文本傳輸協議為主,導出HTTP對象。

八、二維碼類

1、bmp轉二維碼

攻防世界 Misc高手low
下來一個bmp文件,用stegsolve分析無果,但是通過觀察發現是RGB的通道有問題,利用的是圖片中最低位的奇偶性。
實驗吧原題直接用畫圖另存為png格式,用StegSolve打開后,調到RGB紅色位置。這里有所變化
轉QR Code,即二維碼(Quick Response Code)

# lsb隱寫
import PIL.Image as Image
img = Image.open('low.bmp')
img_tmp = img.copy()
pix = img_tmp.load()
width,height = img_tmp.size
for w in range(width):
   for h in range(height):
      if pix[w,h]&1 == 0:
         pix[w,h] = 0
      else:
         pix[w,h] = 255
img_tmp.show()

在這里插入圖片描述
用QR research解碼得:
在這里插入圖片描述

2、16進制轉pyc

攻防世界 MISC 適合作為桌面(世安杯)

使用stegsolve發現在綠色的低位通道中有二維碼
在這里插入圖片描述
使用二維碼掃描器掃描,並將16進制數字結果在winhex中打開
在這里插入圖片描述
在這里插入圖片描述
注:如果錯選中間這個(ANSI-ASCII),則再ASCII碼轉二進制(快捷鍵Ctrl+R)
在這里插入圖片描述
03F3開頭,pyc文件。保存為.pyc然后反編譯,在腳本后加上flag(),運行之后即可得到flag。

pyc在線轉換

或者,使用“uncompyle6 文件路徑\文件名.pyc > 文件路徑\文件名.py”命令

D:\Python385\Lib\site-packages\uncompyle6\bin

pyc隱寫Stegosaurus

在這里插入圖片描述
Stegosaurus 是一款隱寫工具,它允許我們在 Python 字節碼文件( pyc 或 pyo )中嵌入任意 Payload 。由於編碼密度較低,因此我們嵌入 Payload 的過程既不會改變源代碼的運行行為,也不會改變源文件的文件大小。 Payload 代碼會被分散嵌入到字節碼之中,所以類似 strings 這樣的代碼工具無法查找到實際的 Payload 。 Python 的 dis 模塊會返回源文件的字節碼,然后我們就可以使用 Stegosaurus 來嵌入 Payload 了。
pyc文件存在無效空間,修改后大小不變,不影響運行,可以隱藏信息。
stegosaurus.py可以隱藏和解密pyc文件中隱藏的信息。
只能利用pyc文件中的無效空間(Python3.6后參數會占1字節,如果沒有參數用0x00填充,運行時被忽
略,修改不影響),編碼密度較低,嵌入 Payload 后不會改變源代碼的正常運行和大小,不容易被發現。
同時 Payload 會被分散嵌入到字節碼之中,類似 strings 這樣的代碼工具無法查找到實際的 Payload 。
通過github下載后(https://github.com/AngelKitty/stegosaurus)運行 python stegosaurus.py -h
在這里插入圖片描述

可以發現有很多參數,-p 要隱藏的文本,-r 顯示最大隱藏字節,-x可以解密。
stegosaurus解密
使用 python stegosaurus.py py_py_py.pyc -x 得到如下結果 Extracted payload: Flag{HiD3_Pal0ad_1n_Python} 。

Stegosaurus詳解

3、二進制作二維碼

攻防世界 Misc很普通的數獨
下載發現是一堆數獨圖片,把有數字的記為1,沒有數字的記為0,結果保存在txt文本中。也可以調節文件位置后用畫圖拼接,並將有數字的格塗黑。

# -*- coding:utf-8 -*-
from PIL import Image
x = 45
y = 45

im = Image.new("RGB", (x, y))  # 創建圖片
file = open('1.txt', 'r')  # 打開rbg值文件
for i in range(0, x):
    line = file.readline()  # 獲取一行
    for j in range(0, y):
        if line[j] == '0':
            im.putpixel((i, j), (255, 255, 255))  # rgb轉化為像素
        else:
            im.putpixel((i, j), (0, 0, 0))  # rgb轉化為像素
im.show()

掃描得到一串字符串,base64多次解碼得到flag:flag{y0ud1any1s1}

4、4個值轉二維碼

2019西湖論劍網絡安全技能大賽(大學生組)–奇怪的TTL字段
發現ttl.txt中的ttl只有4個值63,127,191,255,寫出他們的二進制表示后發現只有最高兩位不同(高兩位比特的數在數據傳輸中不容易受影響),拿下來,每4個TTL值湊出一個字節的二進制數來
63=00111111
127=01111111
191=10111111
255=11111111
於是考慮做如下轉換,發現寫出來的16進制數開頭是ffd8,應該是jpg,於是寫入文件中:

fp = open('ttl.txt','r')
a = fp.readlines()
p = []
for i in a:
    p.append(int(i[4:]))
s = ''
for i in p:
    if i == 63:
        a = '00'
    elif i == 127:
        a = '01'
    elif i == 191:
        a = '10'
    elif i == 255:
        a = '11'
    s += a
# print(s)

import binascii
flag = ''
for i in range(0,len(s),8):
    flag += chr(int(s[i:i+8],2))
flag = binascii.unhexlify(flag)
wp = open('res.jpg','wb')
wp.write(flag)
wp.close()

寫完之后發現只有二維碼的一部分,應該是不止一張圖,用foremost直接分開就好了,之后用PPT拼在一塊,掃描之后得到如下信息:
key:AutomaticKey cipher:fftu{2028mb39927wn1f96o6e12z03j58002p}
是AutoKey加密,用在線網站解密得flag
autokey解密
自動密鑰密碼(Autokey Cipher)也是多表替換密碼,與維吉尼亞密碼密碼類似,但使用不同的方法生成密鑰。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM