题目来源:csaw-ctf-2016-quals
0x01 考点关键词
路径穿越、cookie欺骗、代码审计
0x02 分析
flag1
题目环境是一个论坛,有注册、登录、发文章、评论的功能。
在展示文章的页面 post.wtf 下发现路径穿越漏洞,可以获得网站源码:
找一下flag字眼:
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/std.css" >
</head>
$ if contains 'user' ${!URL_PARAMS[@]} && file_exists "users/${URL_PARAMS['user']}"
$ then
$ local username=$(head -n 1 users/${URL_PARAMS['user']});
$ echo "<h3>${username}'s posts:</h3>";
$ echo "<ol>";
$ get_users_posts "${username}" | while read -r post; do
$ post_slug=$(awk -F/ '{print $2 "#" $3}' <<< "${post}");
$ echo "<li><a href=\"/post.wtf?post=${post_slug}\">$(nth_line 2 "${post}" | htmlentities)</a></li>";
$ done
$ echo "</ol>";
$ if is_logged_in && [[ "${COOKIES['USERNAME']}" = 'admin' ]] && [[ ${username} = 'admin' ]]
$ then
$ get_flag1
$ fi
$ fi
</html>
以 admin身份登录即可获得 flag1
审计发现有 users 这个目录,继续穿越
发现自己注册的账号以及 admin 都被显示了出来,对比之前的 cookie,发现这个就是TOKEN
的值。
admin 的TOKEN
也知道了,可以进行 cookie 欺骗。
抓包修改
这样我们就得到了 flag1,前一部分还是挺简单的,后面的 flag2 就很头大了,可以说是涉及到知识盲区,看 wp 跟着做才做出来。
flag2
因为 wtf 不是常规的网页文件,故寻找解析 wtf 文件的代码:
格式化后:
max_page_include_depth=64
page_include_depth=0
function include_page {
# include_page pathname
local pathname=$1
local cmd=
[[ ${pathname(-4)} = '.wtf' ]];
local can_execute=$;
page_include_depth=$(($page_include_depth+1))
if [[ $page_include_depth -lt $max_page_include_depth ]]
then
local line;
while read -r line; do
# check if we're in a script line or not ($ at the beginning implies script line)
# also, our extension needs to be .wtf
[[ $ = ${line01} && ${can_execute} = 0 ]];
is_script=$;
# execute the line.
if [[ $is_script = 0 ]]
then
cmd+=$'n'${line#$};
else
if [[ -n $cmd ]]
then
eval $cmd log Error during execution of ${cmd};
cmd=
fi
echo $line
fi
done ${pathname}
else
echo pMax include depth exceeded!p
fi
}
能够解析并执行 wtf 文件,如果还能够上传 wtf 文件并执行的话,就可以达到控制服务器的目的。
继续审计代码,发现如下代码 reply 函数给了这个机会:
function reply {
local post_id=$1;
local username=$2;
local text=$3;
local hashed=$(hash_username "${username}");
curr_id=$(for d in posts/${post_id}/*; do basename $d; done | sort -n | tail -n 1);
next_reply_id=$(awk '{print $1+1}' <<< "${curr_id}");
next_file=(posts/${post_id}/${next_reply_id});
echo "${username}" > "${next_file}";
echo "RE: $(nth_line 2 < "posts/${post_id}/1")" >> "${next_file}";
echo "${text}" >> "${next_file}";
# add post this is in reply to to posts cache
echo "${post_id}/${next_reply_id}" >> "users_lookup/${hashed}/posts";
}
这是评论功能的后台代码,这部分也是存在路径穿越的。
这行代码把用户名写在了评论文件的内容中:
echo "${username}" > "${next_file}";
如果用户名是一段可执行代码,而且写入的文件是 wtf 格式的,那么这个文件就能够执行我们想要的代码。
先普通地评论一下,知晓评论发送的数据包的结构:
在普通评论的基础上,进行路径穿越,上传后门sh.wtf
,访问后门,发现成功写入:
%09
是水平制表符,必须添加,不然后台会把我们的后门当做目录去解析。
为了写入恶意代码,我们得让用户名里携带代码,故注册这样一个用户:
得到 flag 路径,继续注册访问此文件:
将 flag 拼接即可。
0x03 PS
代码审计能力还是要加强啊,还有一些小细节如“%09
是水平制表符,必须添加,不然后台会把我们的后门当做目录去解析”,这道题后面很多东西都是知识盲区,不愧是国际级赛事的真题,多见识见识。
参考 wp:传送门