misc常用工具

算法实现

编程之法:面试和算法心得

稀疏文件读取(sample:Test_your_nc,BJDctf-2020):off_t lseek(int fd, off_t offset, int whence);当whence=SEEK_DATA(3)是跳过hole寻找下一个数据,SEEK_HOLE(4)是跳过数据寻找下一个hole。

辅助命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
xxd -r -ps result.hex > 1.gif #以postscript的连续将十六进制输出内容转换回原文件的二进制内容
xxd -b train.ini #以二进制格式输出
0000000: 01011011 01110100 01110010 01100001 01101001 01101110  [train

dd if=longmao.png of=out.png ibs=256953 skip=1 obs=1M #跳过读入缓冲区开头的ibs*skip块
dd if=1.txt of=11.txt bs=2 skip=2 count=2 seek=2 conv=ascii#输入跳过ibs*skip,从输出文件开头跳过obs*seek,输出ibs*count:1234567890 -> 5678,conv=ascii(from EBCDIC to ASCII),conv=ebcdic(from ASCII to EBCDIC)

vim -r .index.php.swp #还原vim缓存文件

tar -cvfS /var/tmp/flag.tar flag #-S或—sparse 倘若一个文件内含大量的连续0字节,则将此文件存成稀疏文件。

>trid test.bin #识别文件类型,http://mark0.net/soft-trid-e.html

ciphey -t "ZMJTPM33TL4TRMYRZD3JXAGOZVMJRLWEZMFGFAEIZV2GVMOMZZ3JTZ3RUR2U2==="

#Vigenere根据已知结果猜密钥
D:\ctf\tools\misc\CTF_Script\Vigenere-Tools>D:\ctf\software\Python38\python.exe main.py

#带密码文件转john(Kali)
python /usr/share/john/office2john.py
/usr/sbin/keepass2john

隐写分析

双图

1
2
3
>python2 D:\ctf\tools\misc\blindwatermark\bwm.py decode 1.png 2.png flag.png #盲水印
$compare 1.png 2.jpg diff.png
Stegsolve->Analyse->Image Combiner(可与jpg格式combine)

单图

隐形水印工具(须在虚拟机运行)

png

1
2
3
4
5
6
$zsteg 6.png --all #分析LSB:https://github.com/zed-0xff/zsteg,gem install zsteg
>stegpy -p flag.png #png,bmp,gif,webp,wav。颜色通道最低两位的隐写,如red/green/blue plane 0/1
>python2 D:\ctf\tools\misc\cloacked-pixel\lsb.py extract stego.png out 123456 #LSB加密隐写,https://github.com/livz/cloacked-pixel
>D:\ctf\tools\misc\pngcheck-2.3.0-win32\pngcheck.exe -v sctf.png
D:\ctf\tools\misc\StegoTool>rRMS.exe #https://sourceforge.net/projects/stegtool/,载体图像是24位的BMP格式图像,Images->Stegoanalyis,Symmetics Key输入密码
python D:\ctf\tools\misc\Depix\depix.py -p mosaic.png -s D:\ctf\tools\misc\Depix\images\searchimages\debruinseq_notepad_Windows10_closeAndSpaced.png #去除马赛克,从像素化截屏中还原密码:https://github.com/beurtschipper/Depix

色彩类图片:npiet图片编程语言

风儿西PNG图片宽高一把梭工具

jpg

1
2
3
4
5
6
7
8
>D:\ctf\tools\misc\stegdetect\stegdetect.exe -s 10 like.jpg #http://ftp.mirrorservice.org/sites/ftp.wiretapped.net/pub/security/steganography/stegdetect/
>D:\ctf\tools\misc\OurSecret.exe #http://www.securekit.net/OurSecret.exe
D:\ctf\tools\misc\F5-steganography>java Extract lopez.jpg [-p password]
>D:\ctf\tools\misc\jphs05-jpg\jpseek.exe input.jpg out.txt #jphide
$steghide extract -sf 02.jpg #先steghide info查看
$outguess -r /root/Desktop/angrybird.jpg -t 11.txt -k password #outguess
D:\ctf\tools\misc\JPEGsnoop_v1_8_0>JPEGsnoop.exe #http://www.impulseadventure.com/photo/jpeg-snoop.html
https://github.com/libjpeg-turbo/libjpeg-turbo,配合python的https://pypi.org/project/PyTurboJPEG库 #Colorful Strips, bluehat-2022, YCbCr转RGB

qrcode

qrazybox,数出需要复原qrcode的尺寸,新建项目后,在Editor Mode中选择对应的尺寸,然后,对照着把黑色块点出来,再在Decode Mode解码。

微微二维码,批量解二维码。(sample:九宫格,网鼎杯-2020朱雀组)

bctester,导出二维码中二进制。

mp3

1
>D:\ctf\tools\misc\MP3Stego_1_1_18\MP3Stego\Decode.exe -X -P password 1.mp3
  • audacity:点击向下箭头,选频谱图,频谱图设置(调整最低最高频率)
  • silenteye
  • MPEG_FRAME->MPEG_HEADER有一位private_bit是保留位可以用于隐写(sample:private,xiangshan-2022)

wav

deepsound

steghide extract -sf miao.wav

gif

1
>magick identify -format "%T" 14.gif #同Linux下的identify命令,%T	image time delay,https://www.imagemagick.org/script/identify.php

avi

docx

  • ctrl+A全选->右键Font->Effects去掉勾选Hidden
  • File->Options->Display->勾选Hidden text
  • 使用7zip解压docx,在word/document.xml中查找

flash(swf)

1
>D:\ctf\tools\stego\ffdec_11.2.0\ffdec.exe #工具->文本查找,JPEXS:https://www.free-decompiler.com/flash/

web

  • snow隐写
  • 空字符加密:sample:babyweb,安恒202005月赛,decoded = zwsp_steg.decode(encoded)
  • 零宽度字符的Unicode隐写 https://www.mzy0.com/ctftools/zerowidth1/ https://330k.github.io/misc_tools/unicode_steganography.html https://yuanfux.github.io/zero-width-web/
  • 韩文等各种编码:CyberChef,Text Encoding Brute Force,选Decode模式。sample:sqlmapHell,wangdingcup-2022白虎

rar

  • 修改RarBlockTypeFILE_OR_DIR(116):sample:Unpleasant_music,wdb3rd-2018

pyc

1
python3 D:\ctf\tools\misc\stegosaurus\stegosaurus.py -x .\leaf.pyc #https://github.com/AngelKitty/stegosaurus

拼图

1
2
$ montage *.png -tile 4x4 -geometry +0+0 flag.png
$ gaps --image=flag.png --size=65 --save --generations=20 #65是小图的像素

fillter(sample:pintu,春秋杯2022)

流量分析

Wireshark

filter写法的field字段不明确时,右键选中字段->作为过滤器应用->选中。

未知流量(安恒杯201810月赛)

统计->协议分级,发现Secure Socket Layer(ssl)协议

数据按Length排序,选择长度较长的,右键Leftover Capture Data->显示分组字节,发现类似:

1
CLIENT_RANDOM d4488ecfef5686ff40cdf9953ca41de340a91c1ad4a8e2eff393ef9c31aaeaad 4783b191795b6262bf59d49e7bb853271fdbb6bc9fc5b80f05ed5897cf8737f6380aae009e8c206daa693c7e01015b96
1
2
3
4
5
6
7
8
9
10
RSA <EPMS> <PMS>
RSA Session-ID:<SSLID> Master-Key:<MS>
CLIENT_RANDOM <CRAND> <MS>
PMS_CLIENT_RANDOM <CRAND> <PMS>
其中如下field都是十六进制表示:
<EPMS>=First 8 bytes of the Encrypted PMS
<PMS>=The Pre-Master-Secret(PMS) used to derive the MS
<SSLID>=The SSL Session ID
<MS>=The Master-Secret(MS)
<CRAND>=The Client's random number from the ClientHello message

Master-Secret log格式,save as->ssl.log

协议过滤处填ssl,过滤出ssl包,右键->协议首选项->Open Secure Sockets Layer Preferences,Secure Socket Layer页面,(Pre)-Master-Secret log filename选中ssl.log

非常简单的流量分析(安恒杯201902月赛)

统计->协议分级,发现Encapsulating Security Payload(ESP)协议

过滤http流量分析到有robots.txt,发现abc.html(也可以直接文件->导出对象->HTTP得到abc.html),得到:

1
2
3
md5 0x99a98e067af6b09e64f3740767096c96
DES 0xb19b21e80c685bcb052988c11b987802d2f2808b2c2d8a0d    (129->143)
DES 0x684a0857b767672d52e161aa70f6bdd07c0264876559cb8b    (143->129)

协议过滤处填esp,过滤出ESP包,右键->协议首选项,选中Attempt to detect/decode encrypted ESP payloads,然后打开ESP SAs:

复制对应ESP SPI填好,Encryption处如果选DES-CBC不行,可以尝试TripleDES-CBC,Encryption Key填对应DES值,Authentication选HMAC-MD5-96,Authentication Key填对应md5值。

再过滤协议http,即可看到url带ascii码,解码即可。

DNS流量,stealer(DASCTF-202108)

D:\ctf\tools\web\Wireshark\tshark.exe -r misc_dump.pcapng -T fields -e dns.qry.name -Y "ip.src==172.27.221.13"> hex

键盘/鼠标流量,difficult_programming_language(HCTF-2018)
1
D:\ctf\tools\web\Wireshark\tshark.exe -r usb1.pcap -T fields -e usb.capdata > usbdata.txt #将usb.capdata提取出txt文件

键盘格式:02:00:07:00:00:00:00:00,数据长度为8个字节, 第一个字节为0x00或0x20表示原始击键;为0x01表示按下Ctrl,0x02时表示按下Shift。击键信息集中在第三个字节,表示每次key stroke产生一个keyboard event usb packet。根据键值对应表,查询对应字符。

鼠标格式:02:ff:01:00,数据长度为4个字节 ,第一个字节代表按键,当取0x00时,代表没有按键;为0x01时,代表按左键;为0x02时,代表当前按键为右键。第二个字节可以看成是一个signed byte类型,其最高位为符号位,当这个值为正时,代表鼠标水平右移多少像素,为负时,代表水平左移多少像素。第三个字节与第二字节类似,代表垂直上下移动的偏移。

MySQL流量:编辑->首选项->Protocol->MySQL,show SQL Query string in INFO
Not_Only_Wireshark(Redhat-2018)
1
D:\ctf\tools\packet\Wireshark\tshark.exe -e http.request.uri -T fields -r "Not Only Wireshark.pcapng" | grep -P 'name=[A-F0-9]{3}' | awk -F '=' '{printf $2}'
ospf流量(wangdingcup-2022)
1
2
3
4
ettercap -Tqr ospf_md5_dump.pcapng
cat raw-hashes.txt | cut -d ":" -f 2 >> net-md5-hashes.txt
john net-md5-hashes.txt --wordlist=brute.txt
rm /root/.john/john.pot
SYN半连接
1
tcp.flags.syn==1 and tcp.flags.ack==1
分析哥斯拉、冰歇流量

jsp哥斯拉:AES ECB,gunzip

编码分析

emoji

sample:奇怪的组织,虎符杯2020

利用CyberChef{"message":"🚄🏂🐙🐙💥⏰💥😓🐙💾","key":"😀"}进行base64编码,拼接网址头部并进行url编码(+改%2B,否则默认会改成%20),得到:https://codemoji.org/share.html?data=eyJtZXNzYWdlIjoi8J%2BahPCfj4Lwn5CZ8J%2BQmfCfkqXij7Dwn5Kl8J%2BYk/CfkJnwn5K%2BIiwia2V5Ijoi8J%2BYgCJ9,访问即可解。

Malbolge

采用ascii中所有(0x7e - 0x20 + 1 = 94)个非空字符进行编程,输入的字符和所在位置相加的值减33模94

1
2
v = (ord(array[i]) - 33 + i) % 94
if v in target:

只允许是:[6, 7, 29, 35, 48, 65, 66, 84]中的一个,对应xlat表中的字符:ji*p</vo

1
2
3
char xlat1[] =
  "+b(29e*j1VMEKLyC})8&m#~W>qxdRp0wkrUo[D7,XTcA\"lI"
  ".v%{gJh4G\-=O@5`_3i<?Z';FNQuY]szf$!BS/|t:Pn6^Ha";

采用malbolge-interpreter可进行解码或运行程序:

1
2
3
4
D:\ctf\tools\stego\malbolge-interpreter>cat tests\helloworld.mal | python3 a.py xlat1
jpp<ppppp<pppp<<pp<ppp<pppp<ppppp<pp<ioooj/ojji</oiivoooi<ojvpoj/pvojj<j/o*jov/<ojjj*o/jj/oo/oooooopp<pppp<pppp<pp<v
D:\ctf\tools\stego\malbolge-interpreter>python3 a.py execute tests\helloworld.mal
Hello, world.

键盘密码

Qwerty, Dvorak, Colemak, Workman and Russian keyboard(sample:Qweauty and the Beast,ez-ctf2022)

遍历破解

freq_game(HCTF-2018)

解法一:Fast Fourier Transformation(FFT,快速傅立叶变换)

1
2
3
4
5
6
7
8
9
  freq_val=np.fft.fft(y)
  freq_val=map(abs,freq_val)
  freq_val_sorted=[i for i in freq_val]
  freq_val_sorted.sort(reverse=1)
  response=[]
  for j in range(4):
   response.append(
     min(freq_val.index(freq_val_sorted[j*2]),freq_val.index(freq_val_sorted[j*2+1])))
  print response

解法二:遍历预生成查询表

从m种不同元素里,每次可重复取出n个元素组合,用的是隔板法

设第i个元素取了xi次,则原问题相当于x1+x2+…+xm=n的非负整数解的个数,即y1+y2+…+ym=n+m(yi=xi+1)的正整数解的个数。用隔板法,将n+m个1分为n组,每组至少一个,相当于在所有1的n+m-1个空里插n-1个板子,因此总的情况数是

\(C_{n+m-1}^{n-1} =\frac{(n+m-1)!}{n!*(m-1)!}\) 因此从0x00-0xff共256种元素每次可重复取4个元素组合,共有情况:math.factorial(256+4-1) / (math.factorial(4) * math.factorial(256-1))=183181376种。直接生成4个字节的原始表需要耗费大量时间和空间。

  • 可以先生成256种元素每次可重复取2个字节和的原始表,由于计算方式相同,另两个字节和的值也可在此表查到,再通过反查表的方式(对于浮点数处理需要注意下一节提到的精度问题)确认剩下两个字节。
1
2
3
4
5
6
7
8
for i in itertools.combinations_with_replacement([i for i in range(0x100)], 2):
    sum = get_number(x, i[0]) + get_number(x, i[1])
    sum_map[i] = y0 + y1 #正向表
    revert_map[round(y0+y1, 14)] = i #反查表
for i in sum_map:
    dis = round(y - sum_map[i], 14)
    if revert_map.has_key(dis):
      return i, revert_map[dis]
  • 可以生成256中元素每次可重复取2个字节和的原始表,由于另两个和的值也可在此表查到,因此通过寻找和为定值的两个数算法可以确定哪两个和值之和为目标值。因为此处是计算之后的和值和目标值直接对比,不存在精度损失,无需考虑精度问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
for i in itertools.combinations_with_replacement([i for i in range(0x100)], 2):
    sum_array.append((sum, i))
sum_array.sort(key=lambda i: i[0]) #排序
def get_freq2(sum):  #get sum algorithm
  start = 0
  end = len(sum_array) - 1
  while start < end:
    result = sum_array[start][0] + sum_array[end][0]
    if result > sum:
      end -= 1
    elif result < sum:
      start += 1
    else:
      return sum_array[start][1], sum_array[end][1]

浮点数float处理

内部处理时默认保留15位小数,但直接print只会打印10位小数

1
2
3
>>> y = 18.300257482375283
>>> json.dumps(y) #'18.300257482375283'
>>> print y #18.3002574824

进行相等比较时,只能考虑14位精度

1
2
3
4
if abs(sum_map[j] - v) < 1e-14: #不能直接if sum_map[j] == v
revert_map[round(y0+y1, 14)] = i #或者将精度通过round设置到14位小数再对比
dis = round(y - v, 14)
if revert_map.has_key(dis):