暑假第二周

发布时间 2023-07-11 23:22:35作者: Tree_24

Rev_Dizzy

xuenixiang.com上的一道题
F5 反编译失败提示
img
这里可以展开查看汇编代码
img
一种方法是直接手撸汇编代码,因为汇编代码中只有add,sub,xor三种操作,
可以尝试手撸汇编,或者交给Chat_GPT
搜索一番后学到还有一种解决方法
可以通过修改IDA配置文件\cfg\hexrays.cfg
将里面的MAX_FUNCSIZE改大一点例如1024
可以看到注释里面也说明了若函数大于64K的话会无法反汇编,所以我们将它改大
img
反汇编后逻辑很简单就是5000多行的加减异或操作后与密文比较
img
只需要将加替换成减,减替换成加然后倒着跑一遍密文就行
将加密的5000多行复制下来保存为data.txt
注意跑的时候要& 0xff防止溢出
用exec函数执行字符串代码

exp

with open('data.txt', 'rb') as fp:
    data = fp.read()
flag = [0x27,0x3C,0xE3,0xFC,0x2E,0x41,0x07,0x5E,0x62,0xCF,
        0xE8,0xF2,0x92,0x80,0xE2,0x36,0xB4,0xB2,0x67,0x77,
        0x0F,0xF6,0x0D,0xB6,0xED,0x1C,0x65,0x8A,0x07,0x53,
        0xA6,0x66]
fp1 = open("ans.txt", "w")
data = data.split(b'\n')
for i in data[::-1]:
    tmp = i[2:].decode()
    if '+' in tmp:
        tmp = tmp.replace('+', '-')
        code = tmp + '\n' + tmp[:tmp.find('-')] + "&= 0xff"
    elif '-' in tmp:
        tmp = tmp.replace('-', '+')
        code = tmp + '\n' + tmp[:tmp.find('+')] + "&= 0xff"
    else: code = tmp + '\n' + tmp[:tmp.find('^')] + "&= 0xff"
    fp1.write(tmp+'\n')
    exec(code)
fp1.close()
fp.close()
for i in flag:
  print(chr(i),end='')

flag

flag{Try_R3vers1ng_W1th_ScR!pt!}

[CatCTF]The cat did it

点进来很复杂一个函数图像,猫猫可爱捏
flag是CatCTF{MD5(我离开猫猫的概率)}
img
我的定义域是[-200,200]拖动一下我
可以发现无论怎么拖都有一部分是在猫猫体内的
所以猜测概率为0%,算一下md5
img

flag

CatCTF{9f1ef07877f9d85a82bd500f408b4814}

[BUUCTF]rsa

RSA介绍

RSA 加密算法是一种非对称加密算法。在公开密钥加密和电子商业中 RSA 被广泛使用。RSA 是 1977 年由罗纳德 · 李维斯特(Ron Rivest)、阿迪 · 萨莫尔(Adi Shamir)和伦纳德 · 阿德曼(Leonard Adleman)一起提出的。RSA 就是他们三人姓氏开头字母拼在一起组成的。
RSA 算法的可靠性由极大整数因数分解的难度决定。换言之,对一极大整数做因数分解愈困难,RSA 算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用 RSA 加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。如今,只有短的 RSA 密钥才可能被强力方式解破。到 2017 年为止,还没有任何可靠的攻击 RSA 算法的方式。

原理

公钥与私钥的生成

  • 随机选择两个不同的大质数 \(p\)\(q\) 计算\(N = p \times q\)
  • 由欧拉函数\(\varphi(N)=\varphi(p)\varphi(q)=(p-1)(q-1)\)
  • 选择一个小于\(\varphi(N)\)的整数\(e\),使得\(e\)\(\varphi(N)\)互质
  • \(e\)关于\(\varphi(N)\)的乘法逆元\(d\),即求满足\(ed=1(\text{mod}\enspace \varphi(N))\)
  • \(p\)\(q\)的记录销毁
  • \((N,e)\)即为公钥,\((N,d)\)即为私钥

加密

首先需要将消息 以一个双方约定好的格式转化为一个小于\(N\),且与\(N\)互质的整数\(m\)。如果消息太长,可以将消息分为几段,这也就是我们所说的块加密,后对于每一部分利用如下公式加密:

\[m^{e}\equiv c(\text{mod}\enspace N) \]

解密

用d可以解密

\[c^{d}\equiv m(\text{mod}\enspace N) \]

解题过程

公钥解析

法一

在线公钥解析
img
在线分解质因数
img

法二

from Crypto.Util.number import *
from Crypto.PublicKey import RSA
import gmpy2
import rsa
from factordb.factordb import FactorDB

with open('pub.key','r') as f:
    key = RSA.import_key(f.read())
e = key.e
n = key.n
print('e = %d\nn = %d'%(e,n))
a = FactorDB(n)
a.connect()
fac = a.get_factor_list()
#或者factors = list(primefac.primefac(n))但是对大整数来说这个方法很慢
p,q = fac[0],fac[1]
print('p = %d\nn = %d'%(p,q))

解密

phi_n = (p-1)*(q-1)
d = gmpy2.invert(e, phi_n)
key = rsa.PrivateKey(p*q, e, d, p, q)

with open("flag.enc", 'rb') as file: 
    file = file.read()
    print(rsa.decrypt(file, key))  
#e = 65537
#n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
#p = 285960468890451637935629440372639283459
#q = 304008741604601924494328155975272418463
#b'flag{decrypt_256}\n'

完整exp

from Crypto.Util.number import *
from Crypto.PublicKey import RSA
import gmpy2
import rsa
from factordb.factordb import FactorDB

with open('pub.key','r') as f:
    key = RSA.import_key(f.read())
e = key.e
n = key.n
print('e = %d\nn = %d'%(e,n))
a = FactorDB(n)
a.connect()
fac = a.get_factor_list()
p,q = fac[0],fac[1]
print('p = %d\nn = %d'%(p,q))
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e, phi_n)
key = rsa.PrivateKey(p*q, e, d, p, q)

with open("flag.enc", 'rb') as file: 
    file = file.read()
    print(rsa.decrypt(file, key))  
#e = 65537
#n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
#p = 285960468890451637935629440372639283459
#q = 304008741604601924494328155975272418463
#b'flag{decrypt_256}\n'

flag

flag{decrypt_256}