lsb_oracle,Sharif CTF 7-LSB Oracle

类型:Crypto

考察知识点:LSB-Oracle,RSA

题目给了我们加密的flag和 一个binary程序。该程序会告诉我们RSA的公钥,当我们输入密文时,binary会输出解密后明文的最低比特位(LSB)。这题是https://www.jianshu.com/p/a8d5fadd32f4的变种。

在前一题中,用的是rabin加密,而这题是RSA加密,我们同样可以用二分查找的方式去逼近最后的明文。只不过为了让binary输出明文乘2的LSB,我们必须对密文乘pow(2,e,n)。根据RSA加密原理,我们知道:

ct = pt^e mod n

ct' = ct * 2^e mod n = pt^e mod n * 2^e mod n = (2 * pt)^e mod n

ct'^d = ((2 * pt)^e mod n)^d mod n = (2 * pt)^ed mod n = 2 * pt mod n

只需要简单改变上一题的脚本,就能解出这题:

from subprocess import Popen, PIPE

from Crypto.Util.number import long_to_bytes

def oracle(ciphertext):

print("sent ciphertext " + str(ciphertext))

p = Popen(['lsb_oracle.vmp.exe', '/decrypt'], stdout=PIPE, stdin=PIPE, stderr=PIPE)

result = p.communicate(str(ciphertext) + "\n-1")

lsb = int(result[0][97])

print(lsb, result)

return lsb

def brute_flag(encrypted_flag, n, e, oracle_fun):

flag_count = n_count = 1

flag_lower_bound = 0

flag_upper_bound = n

ciphertext = encrypted_flag

mult = 1

while flag_upper_bound > flag_lower_bound + 1:

ciphertext = (ciphertext * pow(2, e, n)) % n

flag_count *= 2

n_count = n_count * 2 - 1

print("upper = %d" % flag_upper_bound)

print("upper flag = %s" % long_to_bytes(flag_upper_bound))

print("lower = %d" % flag_lower_bound)

print("lower flag = %s" % long_to_bytes(flag_lower_bound))

print("bit = %d" % mult)

mult += 1

if oracle_fun(ciphertext) == 0:

flag_upper_bound = n * n_count / flag_count

else:

flag_lower_bound = n * n_count / flag_count

n_count += 1

return flag_upper_bound

def main():

n = 120357855677795403326899325832599223460081551820351966764960386843755808156627131345464795713923271678835256422889567749230248389850643801263972231981347496433824450373318688699355320061986161918732508402417281836789242987168090513784426195519707785324458125521673657185406738054328228404365636320530340758959

ct = 2201077887205099886799419505257984908140690335465327695978150425602737431754769971309809434546937184700758848191008699273369652758836177602723960420562062515168299835193154932988833308912059796574355781073624762083196012981428684386588839182461902362533633141657081892129830969230482783192049720588548332813

print(long_to_bytes(brute_flag(ct, n, 65537, oracle)))

main()

注意由于flag在明文的最后,因此这里需要求出完整的明文。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值