CTF学习之密码学练习

admin 2023年3月17日12:38:03评论76 views字数 12839阅读42分47秒阅读模式

1Mysterious

题目提示需要逆向分析,首先用PEiD看看是否加壳

CTF学习之密码学练习


未加壳,32位程序,用IDA进行分析,打开后用快捷键shift+F12string window),发现了个很特别的字符串
well done(一般过关后会有类似字符串)

CTF学习之密码学练习

点击进入此字符串在内存中的位置

CTF学习之密码学练习

点击sub_401090,查看调用这个字符串的函数,跳转到汇编图形界面,按f5反编译查看伪C代码。

CTF学习之密码学练习

分析这个关键函数:

int __stdcall sub_401090(HWND hWnd, int a2, int a3, int a4)

hwnd是句柄,a2是消息,a3,a4是其他消息。

memset(String, 0, sizeof(String));Value = 0;


memset:将string中当前位置后面的sizeof(String)个字节用0替换并返回string

GetDlgItemTextA(hWnd, 1002, String, 260); # 获取输入strlen(String);if ( strlen(String) > 6 ) # 输入字符串不能大于6ExitProcess(0); # 退出程序
atoi(String)=122

所以sting的值为122xxx,接下来把354转化成ascii码看看,
S3=xS5=zS4=y

v4 = atoi(String); # atoi函数:将字符串转换成整型Value = v4 + 1;v4 == 122 && String[3] == 120 && String[5] == 122 && String[4] == 121

flag赋值给text,然后是置零操作

strcpy(Text, "flag");memset(&Text[5], 0, 0xFCu);v8 = 0;v9 = 0;_itoa(Value, Source, 10);

itoa函数的功能是将int转化为char,第一个参数是要转化的值,第二个参数是转化后值的储存地址,第三个数是要转化的值的进制,这里为10进制。

strcat(Text, "{");strcat(Text, Source);strcat(Text, "_");strcat(Text, "Buff3r_0v3rf|0w");strcat(Text, "}");

第一条代码使Text="flag{",接着第二条指令使Text="flag{123",到最后Text="flag{123_Buff3r_0v3rf|0w}"
MessageBoxA(0, Text, "well done", 0);
messagebox,标题为well done,内容为Text

2、变异凯撒

题目提示变异凯撒,说明有新的规律,先试试前面几个字母和flag对比一下
:::info
f102 —— a97 5
l108 —— f102 6
a97 —— Z90 7
g103 —— _95 8
:::
发现每次的偏移量比前一次多一,写个脚本


flag = "afZ_r9VYfScOeO_UL^RWUc"i = 1k = 5m = 0while i<=len(flag):  for j in flag:    new = chr(ord(j)+k)    k += 1    i += 1    print(new,end="")

3Quoted-printable

直接搜一下题目,在线解码

CTF学习之密码学练习


3.1 Quoted-printable

可打印字符引用编码
https://blog.csdn.net/qq_22146195/article/details/107500750

CTF学习之密码学练习

quoted-printable 就是说用一些可打印常用字符,表示一个字节(8位)中所有非打印字符方法
任何一个8位的字节值可编码为3个字符:一个等号”=”后跟随两个十六进制数字(0–9A–F)表示该字节的数值 例如,ASCII码换页符(十进制值为12)可以表示为”=0C”, 等号”=”(十进制值为61)必须表示为”=3D”. 除了可打印ASCII字符与换行符以外,所有字符必须表示为这种格式
所有可打印ASCII字符(十进制值的范围为33126)可用ASCII字符编码来直接表示, 但是等号”=”(十进制值为61)不可以这样直接表示
ASCII的水平制表符(tab)与空格符, 十进制为932, 如果不出现在行尾则可以用其ASCII字符编码直接表示。如果这两个字符出现在行尾,必须QP编码表示为”=09″ (tab)”=20″ (space).
如果数据中包含有意义的行结束标志,必须转换为ASCII回车(CR)换行(LF)序列,既不能用原来的ASCII字符也不能用QP编码的”=”转义字符序列。相反,如果字节值1310有其它的不是行结束的含义,它们必须QP编码为=0D=0A.
quoted-printable编码的数据的每行长度不能超过76个字符. 为满足此要求又不改变被编码文本,在QP编码结果的每行末尾加上软换行,即在每行末尾加上一个”=”, 但并不会出现在解码得到的文本中

4、丢失的MD5

直接用python2运行给出的代码

CTF学习之密码学练习

import hashlib for i in range(32,127):  for j in range(32,127):    for k in range(32,127):                    m=hashlib.md5() # 使用hash对象的update方法添加消息      m.update('TASC'+chr(i)+'O3RJMV'+chr(j)+'WDJKX'+chr(k)+'ZM')        des=m.hexdigest()      if 'e9032' in des and 'da' in des and '911513' in des:            print des  

4.1 hashlib模块

1)此模块支持多种摘要算法
2
hashlib.md5()
通过构造函数获得一个hash对象
3
hash.update()
更新hash对象。连续的调用该方法相当于连续的追加更新。例如
m.update(a); m.update(b)相当于m.update(a+b)由于消息摘要是只针对当前状态产生的,所以每一次update后,再次计算hexdigest()的值都会不一样。
4
hash.digest()
返回bytes格式的消息摘要
5
hash.hexdigest()
digest方法类似,不过返回的是两倍长度的字符串对象,所有的字符都是十六进制的数字。
6
hash.copy()
返回一个hash对象的拷贝

5、大帝的密码武器

tips1:

公元前一百年,在罗马出生了一位对世界影响巨大的人物,他生前是罗马三巨头之一。他率先使用了一种简单的加密函,因此这种加密方法以他的名字命名。

以下密文被解开后可以获得一个有意义的单词:FRPHEVGL
你可以用这个相同的加密向量加密附件中的密文,作为答案进行提交。


tips2
密文:ComeChina



猜测是移位密码,用一下大佬脚本,偏移量为13时刻得到flag,若超出z需要减26使其回到A-z范围内

str1 = 'FRPHEVGL'str2 = str1.lower() # 转换为小写方便识别num = 1 # 偏移量for i in range(26):  print("{:<2d}".format(num), end=' ')  # 输出偏移量,左对齐宽度为2      for temp in str2:  # 先加密str1    if ord(temp) + num > ord('z'):  # 如果超出'z',需要重新映射会a~z这26个字母上      print(chr(ord(temp) + num - 26), end='')    else:      print(chr(ord(temp) + num), end='')num += 1print('')  # 换行str = 'ComeChina'for temp in str:  # 再加密str  if ord(temp) + 13 > ord('z'):    print(chr(ord(temp) + 13 - 26), end='')else:    print(chr(ord(temp) + 13), end='')print('')

CTF学习之密码学练习

6rsarsa


tips1
p= 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q= 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c= 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034



题目给出了p q e以及明文

from gmpy2 import invertp = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407e = 65537c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034n = p * qy = (p - 1) * (q - 1) # 欧拉数d = invert(e, y) # 逆元dflag = pow(c, d, n)print(flag)

7、信息化时代步伐


tips
也许中国可以早早进入信息化时代,但是被清政府拒绝了。附件中是数十年后一位伟人说的话的密文。请翻译出明文(答案为一串中文!)


info
606046152623600817831216121621196386



提示有清政府和明文为中文,想到可能是
中文电码

CTF学习之密码学练习


7.1 中文电码

中文电码表采用了四位数字作代号,从00019999按四位数顺序排列,用四位数字表示最多一万个汉字、字母和符号。汉字先按部首,后按笔划排列。字母和符号放到电码表的最尾。后来由于一万个汉字不足以应付户籍管理的要求,又有第二字面汉字的出现。在香港,两个字面都采用同一编码,由输入员人手选择字面;在台湾,第二字面的汉字会在开首补上“1”字,变成5个数字的编码。

8、传统知识+古典密码


tips小明某一天收到一封密信,信中写了几个不同的年份辛卯,癸巳,丙戌,辛未,庚辰,癸酉,己卯,癸巳。信的背面还写有“+甲子”,请解出这段密文。key值:CTF{XXX}


第一个提示就是本题flag

8.1 Hint1

年份就是六十甲子嘛,根据下表推出每个对应的值,背面还有“+甲子即为+1或者+60(一个甲子对应60年)
+1的话对照ASCII码有问题,那就+60刚好合适分别为:
88(X) 90(Z) 83(S) 68(D) 77(M) 70(F) 76(L) 90(Z)
XZSDMFLZ

CTF学习之密码学练习

题目提示古典密码:尝试栅栏和凯撒
先用栅栏解密:

CTF学习之密码学练习

将这两个栅栏解密得到的字符串分别凯撒爆破
发现此时shungyu能读懂可能是flag

CTF学习之密码学练习


8.2 Hint2

https://www.cnblogs.com/darkcyan/p/15686724.html
https://blog.csdn.net/qq_52193383/article/details/119984884
https://blog.csdn.net/weixin_45897326/article/details/104069305

tips5555555595555A65556AA696AA6666666955这是某压力传感器无线数据包解调后但未解码的报文(hex)已知其ID为0xFED31F,请继续将报文完整解码,提交hex。提示1:曼联


提示曼联猜测曼彻斯特编码,每位16进制数转成四位二进制数(位数不够高位补零),再进行转换。本次采用第二种编码即:

tips0x5=0101 编码为110x6=0110 编码为100x9=1001 编码为010xA=1010 编码为00


5555555595555A65556AA696AA6666666955转为二进制再编码后得到
11111111 11111111 01111111 11001011 11111000 00100110 00001010 10101010 10011111
转为十六进制
0xffff7fcbf8260aaa9f
但是不包括题目
0xFED31F,于是需要根据八位倒序传输协议将二进制每八位reverse
8位翻转:镜像翻转 比如
01010101反转后10101010),
翻转后得到

11111111 11111111 11111110 11010011 00011111 01100100 01010000 01010101 11111001
转为十六进制
0xfffffed31f645055f9包含0xFED31F
康康大佬脚本:


cipher='5555555595555A65556AA696AA6666666955'def iee(cipher):  tmp=''  for i in range(len(cipher)):    a=bin(eval('0x'+cipher[i]))[2:].zfill(4)    tmp=tmp+a[1]+a[3]    print(tmp)  plain=[hex(int(tmp[i:i+8][::-1],2))[2:] for i in range(0,len(tmp),8)]  print(''.join(plain).upper())
iee(cipher)

8.3 曼彻斯特编码

曼彻斯特编码也叫做相位编码,是一个同步时钟编码技术,被物理层使用来编码一个同步位流的时钟和数据。它在以太网媒介系统中的应用属于数据通信中的两种位同步方法里的自同步法(另一种是外同步法),即接收方利用包含有同步信号的特殊编码从信号自身提取同步信号来锁定自己的时钟脉冲频率,达到同步目的。用电平跳变来表示10的编码方法,其变化规则很简单,即每个码元均用两个不同相位的电平信号表示,也就是一个周期的方波,但0码和1码的相位正好相反。
解密:
第一种指定对于0位,信号电平将为低高电平(假设对数据进行幅度物理编码)-在位周期的前半段为低电平,在后半段为高电平。对于1位,信号电平将为高-低。即01 => 0 , 10 => 1
第二种指出逻辑0由高-低信号序列表示,逻辑1由低-高信号序列表示。也就是说10代表001代表1,这正好也反映了每个码元均用两个不同相位的电平信号表示。

9RSA1

p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852


由题目给出的信息,发现是dpdq泄露

import gmpy2I = gmpy2.invert(q,p) #求逆元mp = pow(c,dp,p)mq = pow(c,dq,q) #求幂取模运算m = (((mp-mq)*I)%p)*q+mq #求明文公式print(hex(m)) #转为十六进制

十六进制转字符

DpDq泄露

https://blog.csdn.net/m0_51507437/article/details/122440936https://blog.csdn.net/weixin_45369385/article/details/109208109
dp ≡ d % (p - 1)dq ≡ d % (q - 1)


已知dpdqpqc

CTF学习之密码学练习


10old-fashion

tipsOs drnuzearyuwn, y jtkjzoztzoes douwlr oj y ilzwex eq lsdexosa kn pwodw tsozj eq ufyoszlbz yrl rlufydlx pozw douwlrzlbz, ydderxosa ze y rlatfyr jnjzli; mjy gfbmw vla xy wbfnsy symmyew (mjy vrwm qrvvrf), hlbew rd symmyew, mebhsymw rd symmyew, vbomgeyw rd mjy lxrzy, lfk wr dremj. Mjy eyqybzye kyqbhjyew mjy myom xa hyedrevbfn lf bfzyewy wgxwmbmgmbrf. Wr mjy dsln bw f1_2jyf-k3_jg1-vb-vl_l

直接爆破(词频统计)

CTF学习之密码学练习

11RSA3

::: tipsc1=22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361n=22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801e1=11187289c2=18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397e2=9647291


编写脚本:

from Crypto.Util.number import long_to_bytesfrom gmpy2 import gcdext
def rsa(c1,c2,e1,e2,n): g,s1,s2 = gcdext(e1,e2) m = (pow(c1,s1,n)*pow(c2,s2,n))%n print(long_to_bytes(m)) # 正整数转化为byte类型字符串 if '__name__'=='__name__': c1 = 22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361 n = 22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801 e1 = 11187289 c2 = 18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397 e2 = 9647291 rsa(c1,c2,e1,e2,n)

11.1 共摸n攻击

https://blog.csdn.net/m0_51507437/article/details/122978218


攻击条件:c1,e1,c2,e2,n => m
已知n,同一份密文me1e2两个公钥分别加密得到c1c2两份密文

CTF学习之密码学练习


脚本:

from gmpy2 import *from Crypto.Util.number import *# c1,e1,c2,e2,n => m
def rsa(c1,c2,e1,e2,n):#扩展欧几里得算法,第一个返回结果是最大公因数,后面两个分别对应e1,e2的系数 g,s1,s2=gcdext(e1,e2) m=(pow(c1,s1,n)*pow(c2,s2,n))%n print(long_to_bytes(m)) if __name__ == "__main__":rsa(c1,c2,e1,e2,n)

变式:若e1e2不互素呢?

from gmpy2 import *from Crypto.Util.number import *e1 =e2 =n =c1 =c2 =a, s1, s2 = gcdext(e1, e2)m = (pow(c1, s1, n)*pow(c2, s2, n)) % nwhile True:  if iroot(m, a)[1]:    m = iroot(m, a)[0]    print(long_to_bytes(m))    break     m += n


原文始发于微信公众号(川云安全团队):CTF学习之密码学练习

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年3月17日12:38:03
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CTF学习之密码学练习https://cn-sec.com/archives/1611385.html

发表评论

匿名网友 填写信息