ctrl+shift+c 打开禁用f12的网页的devtools
零宽隐写和base64隐写
零宽隐写
当给一个txt文件,或者题目有0/零之类的词就要开始考虑零宽隐写了,零宽隐写主要考虑的是使用的字符,在cyber里面,通过escape unicode characters可以查看unicode编码
- 可用的在线工具
 https://www.mzy0.com/ctftools/zerowidth1/
 http://330k.github.io/misc_tools/unicode_steganography.html
 https://offdev.net/demos/zwsp-steg-js
 https://yuanfux.github.io/zero-width-web/
 http://www.atoolbox.net/Tool.php?Id=829
通过观察编码即可确定需要勾选的项
base64隐写
import base64
def get_base64_diff_value(s1, s2):
    base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    res = 0
    for i in range(len(s1)):
        if s1[i] != s2[i]:
            return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))
    return res
def solve_stego():
    with open('.\字频统计.txt', 'rb') as f:
        file_lines = f.readlines()
    bin_str=''
    for line in file_lines:
        steg_line = line.decode().replace('\r\n', '')#看具体情况,可能是\r\n也可能是\n
        norm_line = base64.b64encode((base64.b64decode(line))).decode()
        diff = get_base64_diff_value(steg_line, norm_line)
        pads_num = steg_line.count('=')
        if diff:
            bin_str += bin(diff)[2:].zfill(pads_num * 2)
        else:
            bin_str += '0' * pads_num * 2
    print (bin_str)
    res_str = ''
    for i in range(0, len(bin_str), 8):
        res_str += chr(int(bin_str[i:i+8], 2))
    print (res_str)
if __name__=='__main__':
    solve_stego()
常见文件头
| 文件类型 | 文件头 | 文件尾 | 
|---|---|---|
| JPEG (jpg) | FFD8FFE1 | FF D9 | 
| PNG (png) | 89504E47 (PNG) | AE 42 60 82 | 
| GIF (gif) | 47494638 | 01 01 00 3B | 
| TIFF (tif) | 49492A00 | |
| Windows Bitmap (bmp) | 424D | |
| CAD (dwg) | 41433130 | |
| Adobe Photoshop (psd) | 38425053 | |
| Rich Text Format (rtf) | 7B5C727466 | |
| XML (xml) | 3C3F786D6C | |
| HTML (html) | 68746D6C3E | |
| Email [thorough only] (eml) | 44656C69766572792D646174653A | |
| Outlook Express (dbx) | CFAD12FEC5FD746F | |
| Outlook (pst) | 2142444E | |
| MS Word/Excel (xls.or.doc) | D0CF11E0 | |
| MS Access (mdb) | 5374616E64617264204A | |
| WordPerfect (wpd) | FF575043 | |
| Postscript (eps.or.ps) | 252150532D41646F6265 | |
| Adobe Acrobat (pdf) | 255044462D312E | |
| Quicken (qdf) | AC9EBD8F | |
| Windows Password (pwl) | E3828596 | |
| ZIP Archive (zip) | 504B0304 | 504B | 
| RAR Archive (rar) | 52617221 | |
| Wave (wav) | 57415645 | |
| AVI (avi) | 41564920 | |
| Real Audio (ram) | 2E7261FD | |
| Real Media (rm) | 2E524D46 | |
| MPEG (mpg) | 000001BA | |
| MPEG (mpg) | 000001B3 | |
| Quicktime (mov) | 6D6F6F76 | |
| Windows Media (asf) | 3026B2758E66CF11 | |
| MIDI (mid) | 4D546864 | |
| MP3 | FFFB | |
| zlib | 78 01 or 78 9C or 78 DA | |
| Adobe After Effects(aep) | 52494658(RIFX) | 
mp3 文件隐写
MP3Stego提取
.\Decode.exe -X -P 1111 hidden.WAV
-X是提取隐藏文件
-P是密码
111为文件隐藏时的密码
 hidden.WAV是要提取的文件
图片隐写
 binwalk检查
 binwalk -e分离
或者foremost 分离
像素提取
在正常图片中,每固定像素点间距插入像素,使用python脚本提取
from PIL import Image
original_image = Image.open('arcaea.png')
new_width = original_image.width // 12  #每12个像素点改变一个像素
new_height = original_image.height // 12
new_image = Image.new("RGB",(new_width,new_height))
for x in range(new_width):
    for y in range(new_height):
        pixel = original_image.getpixel((x *12,y*12))
        new_image.putpixel((x,y),pixel)
new_image.save("flag.png")
zsteg一把梭
zsteg可以检测PNG和BMP图片里的隐写数据
zsteg flag.png
zsteg -a flag.png #一把梭
高度改写

内存取证
使用volatility 对raw等格式进行分析
volatility -f <文件名> --profile=<配置文件> <插件> [插件参数]
eg: .\volatility_2.6_win64_standalone.exe -f E:\Desktop\放题\计算机取证\1.dmp --profile=Win7SP1x64 pslist
- <插件>中可以使用 - imageinfo:显示目标镜像的摘要信息,这常常是第一步,获取内存的操作系统类型及版本,之后可以在 –profile 中带上对应的操作系统,后续操作都要带上这一参数- pslist:该插件列举出系统进程,但它不能检测到隐藏或者解链的进程,psscan可以- pstree:以树的形式查看进程列表,和pslist一样,也无法检测隐藏或解链的进程- psscan:可以找到先前已终止(不活动)的进程以及被rootkit隐藏或解链的进程- cmdscan:可用于查看终端记录- notepad:查看当前展示的 notepad 文本(–profile=winxp啥的低版本可以,win7的不行,可以尝试使用editbox)- filescan:扫描所有的文件列表
 linux配合 grep 命令进行相关字符定向扫描,如:grep flag、grep -E ‘png|jpg|gif|zip|rar|7z|pdf|txt|doc’- dumpfiles:导出某一文件(指定虚拟地址)
 需要指定偏移量 -Q 和输出目录 -D- memdump:提取出指定进程,常用foremost 来分离里面的文件
 需要指定进程-p [pid] 和输出目录 -D- editbox:显示有关编辑控件(曾经编辑过的内容)的信息- screenshot:保存基于GDI窗口的伪截屏- clipboard:查看剪贴板信息- iehistory:检索IE浏览器历史记录- systeminfo:显示关于计算机及其操作系统的详细配置信息(插件)- hashdump:查看当前操作系统中的 password hash,例如 Windows 的 SAM 文件内容(mimikatz插件可以获取系统明文密码)- mftparser:恢复被删除的文件- svcscan:扫描 Windows 的服务- connscan:查看网络连接- envars:查看环境变量- dlllist: 列出某一进程加载的所有dll文件- hivelist: 列出所有的注册表项及其虚拟地址和物理地址- timeliner: 将所有操作系统事件以时间线的方式展开
- 出题点: 
 对ie浏览记录进行分析
 对画图软件mspaint.exe进行提取- volatility -f 1.raw --profile=WinXPSP2x86 memdump -p 468 -D .
ntfs 数据流隐写
使用 labs.exe 进行检测
指令:
lads.exe /S #检测当前目录
lads.exe <文件夹> /S #检测这个目录和子目录
eg: lads.exe test /S
notepad 查看文件
编码猜测
使用010editor 更改字符集

pdf bmp txt htm 文件隐写
使用wbstego4.3open隐写,一般肉眼无法判断,只能靠试
使用wbstego4.3open解码和加密
misc密码加密
仿射密码 affine
仿射密码需要两个密码,并且其中一个为1,3,5,7,9,11,15,17,19,21,23,25中的一个,另一个0~25。且flag格式正确但是字母被替换,一般仿射密码的两个密码不会直接给出,可能以方程式等方式给出
在线解密
键盘密码
用手机键盘或者电脑键盘进行加密
手机键盘密码
每个数字键上有 3-4 个字母,用两位数字来表示字母,例如:ru 用手机键盘表示就是:7382,那么这里就可以知道了,手机键盘加密方式不可能用 1 开头,第二位数字不可能超过4

电脑键盘密码
电脑键盘棋盘加密,利用了电脑的棋盘方阵

zlib文件解压
三种文件头
| 文件头 | 压缩方式 | 
|---|---|
| 78 01 | No Compression/low | 
| 78 9C | Default Compression | 
| 78 DA | Best Compression | 
解压python脚本
import zlib
import binascii
id='789cad50cb92a2500cfd2016c2151516bd08efdb80c54304d979012ff2101015e4eb1b6aa6bb66379b4ea59293e4544e2a3e078a24b900b383520e153bf6fc280a219d6b9587252ee184c432ce9c8c5ec0b997e92db7754489b05d8161b43eabdb9d7cf7c41e71c4e1d77e5767bdc534aede6cd8aa98f809278f6ec4fdc138a20dc3d50775f7d21291561b1c5c2fbb0bb7ba1bb835ba6a77eb4c8730c8dede3ceb39e4815093d5c04916b87805ffbb535e867f0cff20a920c8ab640af4bb01d20cb59742f9e8cc0eaa40a17ee4e2fd008737c86764a0872d056aaf49f42f7f5e7d5cb0312ce209680f378bbc86209eda577e1db9ace9143c83cd5cec0cd45ce65a71db20a9b5220e3ff313eaa9a973af64edd2a43ecebd0d8bf57d4ef481125d9b52b9dc2a6e43b11ab7440f282ec6218bf64d1c8e3d9e80c1d785573d631f464b965a7205818462998663e550d6c432d07fb5c3faf826acd7a675359d43f1e9459f6fb2c6db1fcef997b20f82e54bc329da4f2912dfb10c3bf3fb17001f5f8a8cc192'
result = binascii.unhexlify(id)
print(result)
result = zlib.decompress(result)
print(result)
即可解压
常见编码
UUencode 编码
特征:所有字符看起来像乱码,但都是可打印字符;如果有多行,那么除了最后一行,都以“M”开头
Xxencode 编码
Xxencode是一种类似于uuencode的二进制到文本的编码,它只使用字母数字字符以及加号和减号。发明它是为了以一种可以在字符集转换的方式传输文件,特别是在ASCII和IBM大型机上使用的EBCDIC编码之间。
很像base64,但又不是base64使用base64会乱码
社工题
经纬度转换
PNG CRC 检验

贴代码算就完了
import binascii
import struct
# \x49\x48\x44\x52\x00\x00\x01\x00\x00\x00\x00\x00\x08\x02\x00\x00\x00
crc32key = 0x121B804D
for i in range(0, 65535):
    for j in range(0, 65535):
        width = struct.pack('>i', j)
        height = struct.pack('>i', i)
        data = b'\x49\x48\x44\x52' + width + height + b'\x08\x02\x00\x00\x00'
        crc32result = binascii.crc32(data) & 0xffffffff
        if crc32result == crc32key:
            print(''.join(map(lambda c: "%02X" % c, width)))
            print(''.join(map(lambda c: "%02X" % c, height)))
希尔密码
jpg 隐写
steghide 隐写
steghide embed -cf test.jpg -ef secret.txt -p 123456 #加密
steghide extract -sf test.jpg -p 123456 #解密
F5隐写
java Extract 1.jpg -p 123456 #解密
tupper(塔珀自指公式)
一般这种题都会给提示有可能是英文提示或者中文提示,要不然就是顶级脑洞题
import numpy as np
import matplotlib.pyplot as plt
def Tupper_self_referential_formula(k): 
    aa = np.zeros((17,106))
    def f(x, y):
        y += k
        a1 = 2**-(-17*x - y%17)
        a2 = (y // 17) // a1
        return 1 if a2 % 2 > 0.5 else 0
    for y in range(17):
        for x in range(106):
            aa[y, x] = f(x, y)
    return aa[:,::-1]
k = 14278193432728026049298574575557534321062349352543562656766469704092874688354679371212444382298821342093450398907096976002458807598535735172126657504131171684907173086659505143920300085808809647256790384378553780282894239751898620041143383317064727136903634770936398518547900512548419486364915399253941245911205262493591158497708219126453587456637302888701303382210748629800081821684283187368543601559778431735006794761542413006621219207322808449232050578852431361678745355776921132352419931907838205001184
aa = Tupper_self_referential_formula(k)
plt.figure(figsize=(15,10))
plt.imshow(aa,origin='lower')
plt.show()
敲击码(topcode)
敲击码之间没有空格,被坑过一次-_-
带密码的jpg隐写
| 工具 | 指令 | 
|---|---|
| outguess | outguess -k “HAPPY_NEW_YEAR” -r 00000000.jpg hidden.txt | 
| JSteg | 
Linux的/proc/self/
/proc 目录
Linux 提供访问/proc文件系统,以便在运行时访问内核内部数据结构、改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。
fd
fd是一个目录,里面包含着当前进程打开的每一个文件的描述符(file descriptor)差不多就是路径啦,这些文件描述符是指向实际文件的一个符号连接,即每个通过这个进程打开的文件都会显示在这里。所以我们可以通过fd目录的文件获取进程,从而打开每个文件的路径以及文件内容
ls -al /proc/1083/fd
这个fd比较重要,因为在Linux系统中,如果一个程序用 open() 打开了一个文件,但是最终没有关闭它,即使从外部(如:os.remove(SECRET_FILE))删除这个文件之后,在/proc这个进程的 pid目录下的fd文件描述符 目录下 还是会有这个文件的文件描述符,通过这个文件描述符我们即可以得到被删除的文件的内容
self
/proc/self 表示当前进程目录,等效于/proc/$pid/,通过/proc/self可以不用获取PID从而获取自己的系统信息
fd中自带三个IO
0 - stdin(/dev/null)
1 - stdout(/dev/null)
2 - stderr(/dev/null)
所以打开的文件是从3开始算起,在moe的readme中为
0 - stdin(/dev/null)
1 - stdout(/dev/null)
2 - stderr(/dev/null)
3 - flag (therealflag)
所以要读取删除的文件则为/proc/self/fd/3
光栅图隐写
图片类似于这种

使用曾哥的脚本
python3 Raster-Terminator.py -x demo.png
隔离区⽂件恢复
使用 可以恢复⼤多数杀毒软件隔离区的⽂件
powershell 转义
使用```符号转义或者双写
zip 已知部分明文攻击
参考:https://www.freebuf.com/articles/network/255145.html
普通明文攻击必备条件
完整的明文文件
明文文件需要被相同的压缩算法标准压缩(也可理解为被相同压缩工具压缩)
明文对应文件的加密算法需要是 ZipCrypto Store
ZIP的加密算法大致分为两种ZipCrypto和AES-256,各自又分Deflate和Store。
ZipCrypto Deflate
ZipCrypto Store
AES-256 Deflate
AES-256 Store
ZipCrypto算是传统的zip加密方式。只有使用ZipCrypto Deflate /Store才可以使用 ZIP已知明文攻击进行破解。
传统的ZIP已知明文攻击利用,windows下可以使用AZPR,linux下可以使用pkcrack。
这里是部分明文攻击
部分明文攻击条件
至少已知明文的12个字节及偏移,其中至少8字节需要连续。
明文对应的文件加密方式为ZipCrypto Store
使用png
准备明文
echo 89504E470D0A1A0A0000000D49484452 | xxd -r -ps > png_header
攻击
time bkcrack -C png4.zip -c 2.png -p png_header -o 0 >1.log&
tail -f 1.log
解出
bkcrack -C png4.zip -c flag.txt -k e0be8d5d 70bb3140 7e983fff -d flag.txt
#准备已知明文
echo -n "lag{16e3" > plain1.txt   //连续的8明文
echo -n "74f6" | xxd             //额外明文的十六进制格式,37346636
#攻击
bkcrack -C flag_360.zip -c flag.txt -p plain1.txt -o 1 -x 29 37346636
#由于时间较长,为防止终端终端导致破解中断,可以加点小技巧
bkcrack -C flag_360.zip -c flag.txt -p plain1.txt -o 1 -x 29 37346636 > 1.log& //后台运行,结果存入1.log
//加上time参数方便计算爆破时间
time bkcrack -C flag_360.zip -c flag.txt -p plain1.txt -o 1 -x 29 37346636 > 1.log&
//查看爆破进度
tail -f 1.log
使用tar
https://docs.fileformat.com/zh/compression/tar/
根据tar的格式我们可以发现,其前面100字节除了文件名都是用0来填充,那么我们就可以利用明文爆破,额外的数据就是0
bkcrack -C misc-public-ahead.zip -c flag.tar -x 20 00000000000000000000000000
┌──(kali㉿kali)-[~/Desktop/pm]
└─$ bkcrack -C misc-public-ahead.zip -c flag.tar -x 20 00000000000000000000000000     
bkcrack 1.5.0 - 2023-10-15
[08:52:26] Z reduction using 5 bytes of known plaintext
100.0 % (5 / 5)
[08:52:26] Attack on 1113877 Z values at index 27
Keys: 945815e7 4e7a2163 e46b8f88
4.5 % (50321 / 1113877) 
[08:53:11] Keys
945815e7 4e7a2163 e46b8f88
我们直接解出明文即可
┌──(kali㉿kali)-[~/Desktop/pm]
└─$ bkcrack -C misc-public-ahead.zip -c flag.tar -k 945815e7 4e7a2163 e46b8f88 -d flag.tar
bkcrack 1.5.0 - 2023-10-15
[08:53:54] Writing deciphered data flag.tar (maybe compressed)
Wrote deciphered data.
vigenere
维吉尼亚密码
解密
https://www.guballa.de/vigenere-solver
这类题就是将字符用key挨个替换了
替换脚本
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    freopen("flag.txt","r",stdin);
    freopen("flag_encode.txt","w",stdout);
    char key[] = /*SADLY SAYING! Key is eaten by Monster!*/;
    int len = strlen(key);
    char ch;
    int index = 0;
    while((ch = getchar()) != EOF){
        if(ch>='a'&&ch<='z'){
            putchar((ch-'a'+key[index%len]-'a')%26+'a');
            ++index;
        }else if(ch>='A'&&ch<='Z'){
            putchar((ch-'A'+key[index%len]-'a')%26+'A');
            ++index;
        }else{
            putchar(ch);
        }
    }
    return 0;
}
我们只用上面的解密网站解密即可
Emoji aes 加密
https://www.nssctf.cn/problem/1161
看到emoji和key就可以往这上面靠了
python 随机数预测
在2024江西省信息安全技术大赛遇到了,今天又在xyctf里面遇到了,记录一下
预测的前提是有至少624个32比特的随机数
这里使用的是randcrack这个库
交互题
from pwn import *
from randcrack import RandCrack
context(arch = 'amd64',os = 'linux',log_level='debug')
rc =RandCrack()
p = remote("39.106.69.240",22559)
for i in range(624):
    p.sendafter(b": >>>",b"1\n")
    p.sendafter(b": >>>",b"1\n")
    rc.submit(int(p.recvline().replace(b"\n",b"").split(b" ")[3]))
rand1 = rc.predict_getrandbits(11000)
rand2 = rc.predict_getrandbits(10000)
p.sendafter(b": >>>",b"2\n")
p.sendafter(b": >>>",f"{rand1 // rand2}\n".encode('utf-8'))
p.interactive()
再丢一个示例代码,这个跟清晰
import random #导入random库(Python内置了)
from randcrack import RandCrack #下载randcrack库后导入类
#你可以掷随机数种子来确保预测的有效性, 不过random预测的时候默认以当前时间作为随机数种子
rc = RandCrack()#实例化randcrack类
for i in range(624):#循环624次
    rc.submit(random.getrandbits(32))#每次循环提交一个32位random生成的随机数
print(random.getrandbits(64))#利用random库获取一个64位的随机数(你可以修改为任意位数)
print(rc.predict_getrandbits(64))#利用randcrack获取的随机数
brainfuck编码
最小的,具有图灵完备性的语言
| 字符 | 含义 | 
|---|---|
| > | 指针加一 | 
| < | 指针减一 | 
| + | 指针指向的字节的值加一 | 
| - | 指针指向的字节的值减一 | 
| . | 输出指针指向的单元内容(ASCII码) | 
| , | 输入内容到指针指向的单元(ASCII码) | 
| [ | 如果指针指向的单元值为零,向后跳转到对应的 ]指令的下一指令处 | 
| ] | 如果指针指向的单元值不为零,向前跳转到对应的 [指令的下一指令处 | 
有时候会考察对这个编程的理解而不仅仅是编码
snow 隐写
解密
```
 
         
                   
                   
                   
                  

 
                          