前言

继续ctf的旅程
攻防世界Crypto高手进阶区的6分题
本篇是xor_game的writeup

发现攻防世界的题目分数是动态的
就仅以做题时的分数为准了

解题过程

题目描述


得到一段py和一个密文
分别如下

from Crypto.Util.strxor import strxor
import base64
import randomdef enc(data, key):key = (key * (len(data) / len(key) + 1))[:len(data)]return strxor(data, key)poem = open('poem.txt', 'r').read()
flag = "hctf{xxxxxxxxxxx}"with open('cipher.txt', 'w') as f:f.write(base64.b64encode(enc(poem, flag[5:-1])))f.close()
ciMbOQxffx0GHQtSBB0QSQIORihXVQAUOUkHNgQLVAQcAVMAAAMCASFEGQYcVS8BNh8BGAoHFlMAABwCTSVQC2UdMQx5FkkGEQQAAVMAAQtHRCNLF0NSORscMkkaHABSExIYBQseUmBCFgtSKwEWfwELFRcGbzwEDABHVS8DDAcXfwUcMQwCDUUBCgYYSQEBATNKGwQeOkkbPhsYERYGDB0TYzwCUSVCDE8dKh0BNg4GAAkLSVMWHBpHQCxQF08AOhkWPh1OAA0XRQQRBQJKQyVKFghSMA95Gh8LGhEHBB8YEE4UViFaEQEVfwAdfx0GEUUWAAARGxpHTiFQERx4FkkROgUHERMXRTpUCANtYy9RFk8TLEkHNwxOFhcbAhsASR0STC1GCk8UMwYEOhsdfiEdRR0bHU4QSDRLHR0XO0kGMQ0LEgATERYQSQgORDJaWAsXMgYdfxsbGAB4LRYVGxpHUyFXHU8TMQ1TPRsLFREaDB0TSRoIASJGGR1SKwEWfwUBFQFSChVUHQYCASNWFQ0XLRocMgxkNgoAABd+PRkIKwkDEAoTLQ1TKwELVAgHFhoXRU4BUy9OWBsaOkkeMAYAVAQcAVMXCBwEQDNQci4HJwAfNggcDUUXHQcGDAMCASFGCxsaOh0aPAAdGUUQBBoASRoIASNCCBsHLQxTMgAdABx4IxoYBQcJRmBXEApSNgcHOgcdEUUeDBURRU4FVDQDGQMBMEkVNgUCHQsVRQccDE4XVDJGcjsaOhsWfwgcEUUTCQQVEB1HTCVOFx0bOhpTKwEcGxAVDRwBHU4TSSUDHQ4AKwF5FkkMEQkbAAURSSdHQC0pPAYXO0kSLEkaHABSFAYdDBpHQyVCDRsLfwYVfwgbABAfC1MYDA8RRDMpKwcXMQ5TNhpOGgoGRRAcCAEUDWBQFQAZOkkUOhoaARcXbzYCDABHVilPDE8TMxocfxsLAAQbCxYQSQwITyUDCB0dKg0fJkk/HQsVRTURBwlHTDVQGwMXVSYQPBwCAG8mDQERDGQuAShGGR1SMwYFOkVOPUUQAB8dDBgCASlNWAMdKQx5EwYYEUUbFlMVSR4ITiwDFwlSLB0BKg4JGAwcAlMWBRsCDCdRHQocfwgfOAgLfiQBRRcRGgELQDRGWAIbPBsccgsbBhYGRRwSSRkOTyQpOgMXOg0aMQ5OAA0ACgYTAU4KWGBVHQYcLGMqOggcB0UBERIAAAEJRCQDEQFSKwEWfwsLGAwXA3kyBhsVKwkDGgoeNgwFOkkaHAQGRRIYBU4EQC4DEAoTLWM2KQwAVAQcERoXAB4GVSUDHAYBPBsWKwxCVCxSCBYASRoPRGBMDAcXLUkHNwwHBkUdEh1+OgEKRGBAGQFSMQYHfw4cFRYCRQccDE4KTi1GFht4EwwVK0kaG0UGDRZULA8UVWBXF08VMEkkOhoaWEUGDRZUDQsGRWBODRwGfwccK0kcEREHFx1UHQFHTy9UEAoAOmMgOgxCVCxSEhYVG049QC4DPgMdKAwBLEkBGkUfHFMcDA8DDWBKFk8UKgUffwsCGwofRRIYBgAAATRLHU8FPhBTPgUCVBEaAFMDCBdtZzJGCRoXMR0fJkkDHRYBABdUGgEKRGwDGhoGfwgfLAZOEAAXFR8NSQMIVyVHWA0Lfx4aMQ1CVAMACgAARU4UTy9UWAAAfxsSNgdkMgwEAHkkGw8NTyEDKA4APgQaKwhCVBYdCh1UCB1HUi9MFk8TLGMfNg8LVAcXRRERCBsTSCZWFE8eNgIWfxobGQgXF1MSBQEQRDJQWA4cO0kXOggaHEUeDBgRSQ8SVTVOFk8eOggFOhpkNQkBClMXCBwCASFBFxoGfx4bPh1OHAQB

有点类似这题
https://findneo.github.io/180527suctf/#Cycle

挪用下脚本

# coding:utf8# by https://findneo.github.io/
def getCipher(file='cipher.txt'):
'''从文件中读取十六进制串,返回十六进制数组
'''c=''.join(map(lambda x:x.strip(),open('cipher.txt').readlines())).decode('base_64')cc= [ord(i) for i in c]# print cc,len(cc)return cc# c = open(file).read()# codeintlist = []# codeintlist.extend(#     (map(lambda i: int(c[i:i + 2], 16), range(0, len(c), 2))))# return codeintlistdef getKeyPool(cipher, stepSet, plainSet, keySet):
''' 传入的密文串、明文字符集、密钥字符集、密钥长度范围均作为数字列表处理.形如[0x11,0x22,0x33]返回一个字典,以可能的密钥长度为键,以对应的每一字节的密钥字符集构成的列表为值,密钥字符集为数字列表。形如{1:[[0x11]],3:[[0x11,0x33,0x46],[0x22,0x58],[0x33]]}
'''keyPool = dict()for step in stepSet:maybe = [None] * stepfor pos in xrange(step):maybe[pos] = []for k in keySet:flag = 1for c in cipher[pos::step]:if c ^ k not in plainSet:flag = 0if flag:maybe[pos].append(k)for posPool in maybe:if len(posPool) == 0:maybe = []breakif len(maybe) != 0:keyPool[step] = maybe
return keyPooldef calCorrelation(cpool):
'''传入字典,形如{'e':2,'p':3}返回可能性,0~1,值越大可能性越大(correlation between the decrypted column letter frequencies andthe relative letter frequencies for normal English text)
'''frequencies = {"e": 0.12702, "t": 0.09056, "a": 0.08167, "o": 0.07507, "i": 0.06966,"n": 0.06749, "s": 0.06327, "h": 0.06094, "r": 0.05987, "d": 0.04253,"l": 0.04025, "c": 0.02782, "u": 0.02758, "m": 0.02406, "w": 0.02360,"f": 0.02228, "g": 0.02015, "y": 0.01974, "p": 0.01929, "b": 0.01492,"v": 0.00978, "k": 0.00772, "j": 0.00153, "x": 0.00150, "q": 0.00095,"z": 0.00074}relative = 0.0total = 0fpool = 'etaoinshrdlcumwfgypbvkjxqz'total = sum(cpool.values())  # 总和应包括字母和其他可见字符for i in cpool.keys():if i in fpool:relative += frequencies[i] * cpool[i] / totalreturn relativedef analyseFrequency(cfreq):key = []for posFreq in cfreq:mostRelative = 0for keyChr in posFreq.keys():r = calCorrelation(posFreq[keyChr])if r > mostRelative:mostRelative = rkeychar = keyChrkey.append(keychar)return keydef getFrequency(cipher, keyPoolList):
''' 传入的密文作为数字列表处理传入密钥的字符集应为列表,依次包含各字节字符集。形如[[0x11,0x12],[0x22]]返回字频列表,依次为各字节字符集中每一字符作为密钥组成部分时对应的明文字频形如[{0x11:{'a':2,'b':3},0x12:{'e':6}},{0x22:{'g':1}}]
'''freqList = []keyLen = len(keyPoolList)for i in xrange(keyLen):posFreq = dict()for k in keyPoolList[i]:posFreq[k] = dict()for c in cipher[i::keyLen]:p = chr(k ^ c)posFreq[k][p] = posFreq[k][p] + 1 if p in posFreq[k] else 1freqList.append(posFreq)return freqListdef vigenereDecrypt(cipher, key):plain = ''cur = 0ll = len(key)for c in cipher:plain += chr(c ^ key[cur])cur = (cur + 1) % llreturn plaindef main():ps = []ks = []ss = []ps.extend(xrange(0xff))ks.extend(xrange(0x20,0x80))ss.extend(xrange(1, 50))cipher = getCipher()keyPool = getKeyPool(cipher=cipher, stepSet=ss, plainSet=ps, keySet=ks)for i in keyPool:freq = getFrequency(cipher, keyPool[i])key = analyseFrequency(freq)print ''.join(map(chr,key))if __name__ == '__main__':main()

得到

得到flag:hctf{xor_is_interesting!@#}

结语

xortools也可以用

攻防世界 Crypto高手进阶区 6分题 xor_game相关推荐

  1. 攻防世界 Crypto高手进阶区 3分题 wtc_rsa_bbq

    前言 继续ctf的旅程 攻防世界Crypto高手进阶区的3分题 本篇是wtc_rsa_bbq的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 解题过程 得到一个无后缀文件 扔 ...

  2. 攻防世界 Crypto高手进阶区 3分题 你猜猜

    前言 继续ctf的旅程 攻防世界Crypto高手进阶区的3分题 本篇是你猜猜的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 解题过程 得到一串16进制 504B03040A ...

  3. 攻防世界 Crypto高手进阶区 5分题 简单流量分析

    前言 继续ctf的旅程 攻防世界Crypto高手进阶区的5分题 本篇是简单流量分析的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 解题过程 题目描述 binwalk无果 查 ...

  4. 攻防世界 Crypto高手进阶区 2分题 cr3-what-is-this-encryption

    前言 继续ctf的旅程 攻防世界Crypto高手进阶区的2分题 本篇是cr3-what-is-this-encryption的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 ...

  5. 攻防世界 Crypto高手进阶区 3分题 shanghai

    前言 继续ctf的旅程 攻防世界Crypto高手进阶区的3分题 本篇是shanghai的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 解题过程 得到一个文本 提示说是维吉利 ...

  6. 攻防世界 Crypto高手进阶区 4分题 safer-than-rot13

    前言 继续ctf的旅程 攻防世界Crypto高手进阶区的4分题 本篇是safer-than-rot13的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数为准了 解题过程 得到一串字符 ...

  7. 攻防世界 Reverse高手进阶区 2分题 reverse-for-the-holy-grail-350

    前言 继续ctf的旅程 攻防世界Reverse高手进阶区的2分题 本篇是reverse-for-the-holy-grail-350的writeup 发现攻防世界的题目分数是动态的 就仅以做题时的分数 ...

  8. 攻防世界 web高手进阶区 9分题 favorite_number

    前言 继续ctf的旅程 开始攻防世界web高手进阶区的9分题 本文是favorite_number的writeup 解题过程 进入界面 简单的代码审计 首先是个判断,既要数组强等于,又要首元素不等 然 ...

  9. 攻防世界 web高手进阶区 10分题 weiphp

    前言 继续ctf的旅程 开始攻防世界web高手进阶区的10分题 本文是weiphp的writeup 解题过程 进入界面 点击 进入一个登陆界面 没有注册 那肯定得找源码了 惯例源码+御剑 发现git泄 ...

最新文章

  1. Web应用开发技术-CSS
  2. 利用反射自动封装成实体对象
  3. 【C++基础学习】const限定修饰符详解
  4. 【AutoML白皮书】:感知、认知、决策算法布局提升企业决策水平.pdf(附下载链接)...
  5. Web Application Projects的一个问题
  6. 基于编辑方法的文本生成(上)
  7. MFC异形窗口-多边形窗口-根据图片自定义窗口形状-CRgn
  8. android 70 使用ListView把数据显示至屏幕
  9. eclipse关联KEmulator模拟器开发J2ME游戏
  10. smartadmin官网_smartadmin api_smartadmin 下载
  11. 经典歌曲多版本欣赏:刘欢《情怨》:华夏元素鲜明的“中国风格“
  12. AV终结者新变种(随机7位字母病毒)的分析
  13. Java导出超大Excel文件,防止内存溢出
  14. App地推活动怎么做才能事半功倍
  15. [MATLAB App Designer] 多窗口 App 中的交互(含数据传递)
  16. 笔记本桌面窗口管理器占用内存过高怎么办?
  17. 嵌入式接口之TIM定时器与NVIC的STM32模板库函数的一些解释
  18. USB-PD快充和QC快充的区别
  19. 2021高博会扩大举办,助力高尔夫运动新发展
  20. SLB 负载均衡实践

热门文章

  1. 河北工业机器人夹爪生产厂家_GIMATIC,GIMATIC电动夹爪,GIMATIC气动夹爪-工业控制领域一站式服务商-华联欧...
  2. 一、Glade-3安装配置
  3. mojing手柄遥杆控制
  4. 《进击的巨人》展现了日本羸弱的二次元文化
  5. 用matlab朴素贝叶斯,Matlab朴素贝叶斯
  6. 计算机安装两个键盘会怎样,一台电脑可以同时装两个键盘吗?而且互不干扰 – 手机爱问...
  7. 浅谈 Quartz2D 在开发中的用处 - 图形的状态
  8. 北京大学研究员董艳:数据功能开放管道——助力政府数据资源共享交换和融合应用...
  9. 一篇生物学博士的自白,写的很不错,博士生的真实写照
  10. c++ 实现深度学习网络结构【附源码】