CISCN2021东北赛区-Maple_root-WriteUp
参赛队员:
总结
最终成绩:3627
最终排名:13
一血数量:3
本次比赛前期一切顺利,后期感觉被py爆了,结果名次就拉了下来,整体题目全部都偏向MISC,打的很迷惑,但是算不上难(RE除外),希望下次国赛能进决赛看看...
MISC
MISC_签到
打开以后压缩包内有一个二维码文件,利用压缩包内的二维码扫描器扫描后即可得到flag
Sudoku
根据题目判断是一个数独解密,下载以后在压缩包内有一个flag压缩包和一个数独游戏的excel表格,打开以后是一个数独游戏,直接放入z3解密工具解出答案以后按照从左上到右下的对角线顺序依次输入以后解开flag压缩包得到最终结果
Vigenère
下载文件后使用binwalk解出一个b.txt文件,根据题目标题判断是维吉尼亚密码,但是没有找到key,用脚本爆破
import itertools
import string
import sys
import textwrap
"""
Run this script in a shell with the ciphertext to decode on STDIN
"""
####################################################################################################
# Vienere encryption and decryption functions
####################################################################################################
def vigenere(plaintext, key, a_is_zero=True):
key = key.lower()
if not all(k in string.ascii_lowercase for k in key):
raise ValueError("Invalid key {!r}; the key can only consist of English letters".format(key))
key_iter = itertools.cycle(map(ord, key))
return "".join(
chr(ord('a') + (
(next(key_iter) - ord('a') + ord(letter) - ord('a')) # Calculate shifted value
+ (0 if a_is_zero else 2) # Account for non-zero indexing
) % 26) if letter in string.ascii_lowercase # Ignore non-alphabetic chars
else letter
for letter in plaintext.lower()
)
def vigenere_decrypt(ciphertext, key, a_is_zero=True):
# Decryption is encryption with the inverse key
key_ind = [ord(k) - ord('a') for k in key.lower()]
inverse = "".join(chr(ord('a') +
((26 if a_is_zero else 22) -
(ord(k) - ord('a'))
) % 26) for k in key)
return vigenere(ciphertext, inverse, a_is_zero)
def test_vigenere(text, key, a_is_zero=True):
ciphertext = vigenere(text, key, a_is_zero)
plaintext = vigenere_decrypt(ciphertext, key, a_is_zero)
assert plaintext == text, "{!r} -> {!r} -> {!r} (a {}= 0)".format(
text, ciphertext, plaintext, "" if a_is_zero else "!")
# Test that the Vigenere encrypt and decrypt work (or are at least inverses)
for text in ["rewind", "text with spaces", "pun.ctuation", "numb3rs"]:
for key in ["iepw", "aceaq", "safe", "pwa"]:
test_vigenere(text, key, True)
test_vigenere(text, key, False)
# Now that we're sure that all the vigenere stuff is working...
####################################################################################################
# Cipher solver
####################################################################################################
# From http://code.activestate.com/recipes/142813-deciphering-caesar-code/
ENGLISH_FREQ = (0.0749, 0.0129, 0.0354, 0.0362, 0.1400, 0.0218, 0.0174, 0.0422, 0.0665, 0.0027, 0.0047,
0.0357, 0.0339, 0.0674, 0.0737, 0.0243, 0.0026, 0.0614, 0.0695, 0.0985, 0.0300, 0.0116,
0.0169, 0.0028, 0.0164, 0.0004)
def compare_freq(text):
"""
Compare the letter distribution of the given text with normal English. Lower is closer.
Performs a simple sum of absolute difference for each letter
"""
if not text:
return None
text = [t for t in text.lower() if t in string.ascii_lowercase]
freq = [0] * 26
total = float(len(text))
for l in text:
freq[ord(l) - ord('a')] += 1
return sum(abs(f / total - E) for f, E in zip(freq, ENGLISH_FREQ))
def solve_vigenere(text, key_min_size=None, key_max_size=None, a_is_zero=True):
"""
Solve a Vigenere cipher by finding keys such that the plaintext resembles English
Returns:
the first and second best from the set of best keys for each length
This is not a brute force solver; instead, it takes advantage of a weakness in the cipher to
solve in O(n * K^2) where n is the length of the text to decrypt and K is the length of the
longest key to try.
The idea is that for any key length, the key is used repeatedly, so if the key is of length k
and we take every k'th letter, those letters should have approximately the same distribution as
the English language on a whole. Furthermore, since each letter in the key is independent, we
can perform the analysis for each letter in the key by taking every k'th letter at different
starting offsets. Then, since the letters in the key are independent, we can construct the best
key for a given length by simply joining the best candidates for each position.
"""
best_keys = []
key_min_size = key_min_size or 1
key_max_size = key_max_size or 20
text_letters = [c for c in text.lower() if c in string.ascii_lowercase]
for key_length in range(key_min_size, key_max_size):
# Try all possible key lengths
key = [None] * key_length
for key_index in range(key_length):
letters = "".join(itertools.islice(text_letters, key_index, None, key_length))
shifts = []
for key_char in string.ascii_lowercase:
shifts.append(
(compare_freq(vigenere_decrypt(letters, key_char, a_is_zero)), key_char)
)
key[key_index] = min(shifts, key=lambda x: x[0])[1]
best_keys.append("".join(key))
best_keys.sort(key=lambda key: compare_freq(vigenere_decrypt(text, key, a_is_zero)))
return best_keys[:2]
CIPHERTEXT = sys.stdin.read().strip()
print "Solving Vigenere cipher:"
print "*" * 80
print textwrap.fill(CIPHERTEXT, 80)
print "*" * 80
for key in reversed(solve_vigenere(CIPHERTEXT)):
print ""
print "Found key: {!r}".format(key)
print "Solution:"
print "=" * 80
print textwrap.fill(vigenere_decrypt(CIPHERTEXT, key))
print "=" * 80
得出了keyfaisnigslk并得到了明文,最后MD5哈希后提交即为flag
flagpng
png宽爆破,使用crc32fix工具修复后flag直接写脸上了。
easy_rsa
密码学的模板题...不知道怎么说,直接有现成的解密脚本
import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
import binascii
def hack_RSA(e,n):
'''
Finds d knowing (e,n)
applying the Wiener continued fraction attack
'''
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k,d) in convergents:
#check if d is actually the key
if k!=0 and (e*d-1)%k == 0:
phi = (e*d-1)//k
s = n - phi + 1
# check if the equation x^2 - s*x + n = 0
# has integer roots
discr = s*s - 4*n
if(discr>=0):
t = Arithmetic.is_perfect_square(discr)
if t!=-1 and (s+t)%2==0:
print("Hacked!")
return d
# TEST functions
def test_hack_RSA():
print("Testing Wiener Attack")
while(times>0):
e,n,d = RSAvulnerableKeyGenerator.generateKeys(1024)
print("(e,n) is (", e, ", ", n, ")")
print("d = ", d)
hacked_d = hack_RSA(e, n)
if d == hacked_d:
print("Hack WORKED!")
else:
print("Hack FAILED")
print("d = ", d, ", hacked_d = ", hacked_d)
print("-------------------------")
times -= 1
if __name__ == "__main__":
#test_is_perfect_square()
#print("-------------------------")
# test_hack_RSA()
e = 932333292871340311536583425772799788581476608800501618257200913635688712797956595013312457091949241781390707236218326324287260096872275100972804737277188856396706341586791458364387568557914836880210799183882901779150174060503451992261799576875742788774243390310560719634789720219992974946820314802939572580353
n = 1083178419603719448638799632475202672644727971741749926078568673467491721729891939162664192885208434541370193744078154888072589708037117486860213089624795029582525501783298026959443870222339003799747202112246474259375161019073230508249672271697738321500894559008261698558072028050806042318719109646040290668273
c = 629671321698958970045785762020010033814849277886377341930329645318473402676175912514800812974363555981287129835454344489639514895119374277833430799149513068930055615330516662428479865724507981237582779353644800423513485357718723908554543915240117995464419165823214748496569735844685568687856495834900999682293
d=hack_RSA(e, n)
print('d=',d)
m=pow(c, d,n)
print('m=',m)
b = hex(m) #转换成相同的字符串即'0x665554'
b = b[2:] #截取掉'0x'
c = binascii.a2b_hex(b) #转换成ASCii编码的字符串
print(c)
huahua
下载以后发现压缩包受损,在010editor中把压缩包头改为504b0304解压后得到一张png图片,也是缺少png头,加上89504e47后工具中又提示crc报错,那就再把高改一下即可得到flag
WEB
简单的注入
发一个登录请求,burp存下来
用sqlmap跑出时间盲注,跑出库名表名,
然后在lostandfound.user表里select * from user where username='admin';

出密码Admin@12999 ...,登录拿到flag。

Flagin
先用burp抓个包,怀疑是xee
waf拦截后去掉<?xml可过
最终payload:
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "php://read=convert.base64-encode/resource=/flag.txt" >]>
<user><username>&xxe;</username><password>admin</password></user>
Be_Careful
上来careful的index.php是个链接
点进去是?file=a.php来着? 里面是there is nothing
然后改成php伪协议base64读index.php源码
看到过滤列表和结尾注释的real_flag.php
这里过滤了存flag的文件 但没过滤real_flag.php
再读real_flag.php的源码 构造?a获得flag

Crypto
Sign_me_up
下载打开文件以后发现是一大段的BASE64加密后的内容,疑似多次套娃,多次解密以后即得到密文内容Welcome to ciscn. flag{4b7fb332177a5df1b4aa6ba53e29d8fd}
Super_Man
依然是010editor打开图片,文件头88改为89后图片变为超人图片,接着在文件尾找到salted,放入cyperchef解两层即可得到flag
凯撒大帝的Unicode
根据unicode提示,将unicode转化为数字后尝试偏移(25000-24000)(忽略负数)到ascii区域进行解码
偏移到24591时得到字符串'k_\\Here&comes$the]un1c0de[f1Ag1s{3c3b832287a5578b3511fcd7486f4ef9}&%O##%&P!#TQR%"&$'
脚本:
f = open("caesar", "r", encoding="utf-8").read()
f = f.split("\n")[1]
f = [int(c.encode("unicode-escape").decode("utf-8").replace("\\u", ""), 16) for c in f]
offset = 25000
while True:
# 尝试过用unicode还原回去 没找到
# print(''.join([hex(b-offset).replace("0x", "\\u0" if len(hex(b-offset).replace("-", "")) == 5 else "\\u").encode().decode("unicode-escape") for b in f]))
try:
print(f"offset:{offset} result: " + ''.join([chr(b-offset) for b in f]))
except:
continue
finally:
offset -= 1
print("-------")
可读出flag
cipertext
古典密码题...打开之后一段ook密码和一段BrainFuck以及一段jsfuck密码解密以后连起来就是flag
RE
RE_签到
本题拿入后在IDA7.5中多次查看无果,只能分析出是一个调用了官方库的哈希加密工具,后来在Linux环境下分别使用了strings+greg和cat查看,发现在cat后文件的最后有一段形如flag{xxx}的内容,即为最后答案,但是这里有一点很不解的就是为何使用strings无法正常找到flag段,这一点有待研究。
CISCN2021东北赛区-Maple_root-WriteUp的更多相关文章
- 刷题记录:[CISCN2019 东北赛区 Day2 Web3]Point System
目录 刷题记录:[CISCN2019 东北赛区 Day2 Web3]Point System 知识点 1.padding-oracle attack 2.cbc字节翻转攻击 3.FFMpeg文件读取漏 ...
- BUUCTF-[CISCN2019 华东北赛区]Web2
BUUCTF-[CISCN2019 华东北赛区]Web2 看题 一个论坛,内容不错:) 可以投稿,点击投稿发现要注册,那就先注册登录.随便账号密码就行. 常规操作,扫一下站点,发现有admin.php ...
- BUU XSS COURSE 1 & [CISCN2019 华东北赛区]Web2
BUU XSS COURSE 1 & [CISCN2019 华东北赛区]Web2 XSS的题目没怎么做过,比赛基本上也没有(=_=),总结下今天做的两题 都是看赵总视频现学现做的,这里附上学习 ...
- 2018工业信息安全技能大赛华东赛区初赛 第2题 writeup
2018工业信息安全技能大赛华东赛区初赛 第2题 解题思路 本题主要考察点是对常见工控协议的理解(modbus/tcp和s7comm),题目目标是寻找出报文中某条异常报文流量.很让人疑惑的是,题目中并 ...
- 【转】2014区域赛小结(牡丹江&&鞍山)by kuangbin
Posted on 2014年10月20日 by kuangbin 最后的两场区域赛结束了! ICPC生涯的最后两场区域赛,选择了前两个赛区——牡丹江和鞍山,主要是时间比较靠前,而且我向来对东北赛区有 ...
- 2015年ACM长春区域赛比赛感悟
距离长春区域赛结束已经4天了,是时候整理一下这次比赛的点点滴滴了. 也是在比赛前一周才得到通知要我参加长春区域赛,当时也是既兴奋又感到有很大的压力,毕竟我的第一场比赛就是区域赛水平,还是很有挑战性的. ...
- 学习方法分享:为何一年半就能拿到大厂 offer
毕竟是聊聊曾经,放一张大学课堂上灵光一现,手写的一个我曾经一直使用的网名 前言 原文地址:Nealyang/personalBlog 讲真,的确是运气,才有机会进大厂.也没想到,那篇一年半工作经验试水 ...
- 工控安全入门(二)—— S7comm协议
在上一次的文章中我们介绍了施耐德公司的协议modbus,这次我们把目标转向私有协议,来看看另一家巨头西门子的S7comm.首先要说明,这篇文章中的内容有笔者自己的探索,有大佬们的成果,但由于S7com ...
- O准备如何苟进复赛圈?华为软挑开挂指南(附赛题预测)
事先声明,这不是华为软挑的软广,我也不是海军. 这篇文章纯粹是心血来潮,原因是去年上传到github的参赛代码,前几天又有两个人star和fork了. 记得star热潮还是去年4月复赛刚结束的那几天, ...
- Xss Game挑战
前言 最新学习了下xss的更深入的东西,学习了一波浏览器解析机制和XSS向量编码的知识. 这里就些xss的练习题巩固知识 学习的话结合如下两篇文章看,从例子和基础原理层面都有: http://boba ...
随机推荐
- std::unique_ptr release的使用
在c++中,动态内存管理是通过new/delete 运算符来进行的.由于确保在正确的时间释放内存是很困难的,为了避免内存泄漏,更加容易,安全地使用动态内存,C++11标准库提供了两种智能指针类型来管理 ...
- Debug --> 攻击方式
1.CSRF攻击概述: CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一. CSRF攻击原 ...
- vue表格拖拽使用Sortable插件库
1 <template > 2 <el-table 3 row-key="name" 4 :data="tableData" 5 stripe ...
- Linux磁盘相关工具 -- iostat
iostat主要用于监控系统设备的IO负载情况,根据这个可以看出当前系统的写入量和读取量,CPU负载和磁盘负载. iostat主要用于输出磁盘IO和CPU统计信息. 1. iostat用法: iost ...
- Spring系列之资源-11
目录 `Resource` 内置`Resource`实现 `UrlResource` `ClassPathResource` `FileSystemResource` `ServletContextR ...
- 量化交易-可视化展示(grafana)
先上图 简单的实现了一下,效果还好,可玩性强 大概部署mysql+grafana step 1: 服务器:阿里云,ucloud啥的随意,配置也不需要什么,我的是阿里云1核1GB,足以 我用的ubunt ...
- Zookeeper分布式服务
Zookeeper(CP) 以集群的方式[leader和follower]为分布式应用提供协调服务.负责存储和管理大家都关系的数据,接受观察者注册.消息分发等服务 特点: 只要有半数以上的节点存活就能 ...
- 如何确保获取的输入为整数-C语言基础
这一篇探讨的是如何确保你输入的数据是一个整数.虽然标题用的是这个,但我其实真正想要探讨的内容是 "在程序调试的过程中,需要注意把输入缓存区中的上一次输入的残留信息清理干净,以免影响下一次的输 ...
- mysql主从复制常见问题(useing version:8)
Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ...
- 磊磊零基础打卡算法:day18 c++模拟哈希表来模拟散列表
5.21 哈希表 Hash表又称为散列表,一般由Hash函数(散列函数)与链表结构共同实现,与离散化思想类似. 一般要求:防止冲突,便于查询 模拟hash表: 拉链法:两个核心操作insert(),f ...