crash分析 報文解密造成的系統crash

2021-10-09 08:37:18 字數 3892 閱讀 2454

現網環境出現了crash,原因是"general protection fault: 0000 [#1] ",也就是說訪問了異常位址導致。

檢視異常呼叫棧。

//...省略部分

#6 [ffff88041fd43830] general_protection at ffffffff8168ef68

[exception rip: put_page+10]

rip: ffffffff8118edaa rsp: ffff88041fd438e8 rflags: 00010202

rax: 0000000000000040 rbx: 0000000000000002 rcx: 0000000000000010

rdx: ffffea000a758960 rsi: ffff88041fd5a0a8 rdi: 2f302009302f3020

rbp: ffff88041fd438f0 r8: ffffea000a758960 r9: ffff88041fb78980

r10: 00000000000000cc r11: 000000000000004e r12: ffff8800775db4c0

r13: ffff88020cf2c900 r14: ffff8800775db46a r15: ffff8800775db44e

orig_rax: ffffffffffffffff cs: 0010 ss: 0018

#7 [ffff88041fd438f8] skb_release_data at ffffffff8155ea0f

#8 [ffff88041fd43920] skb_release_all at ffffffff8155eae4

#9 [ffff88041fd43938] consume_skb at ffffffff8155efdc

#10 [ffff88041fd43958] __dev_kfree_skb_any at ffffffff8156ee5d

#11 [ffff88041fd43980] tm_wanrx at ffffffffa03374d8 [testmod]

//...省略部分

crash> dis -r put_page+10

0xffffffff8118edb0 : data32 data32 data32 xchg %ax,%ax [ftrace nop]

0xffffffff8118edb5 : push %rbp

0xffffffff8118edb6 : mov %rsp,%rbp

0xffffffff8118edb9 : push %rbx

0xffffffff8118edba : testq $0xc000,(%rdi) //訪問page

在skb_release_data處理中將skb指標儲存在暫存器$13中,且put_page並未對其改動,所以我們可以指導skb指標位址為 r13: ffff88020cf2c900。

crash> sk_buff ffff88020cf2c900

struct sk_buff \364\f\220\036

進而得到 skb_shared_info的內容 skb->head + skb->end = 0xffff8800775db400 + c0 = 0xffff8800775db4c0。

crash> skb_shared_info 0xffff8800775db4c0

struct skb_shared_info ,

syststamp =

}, ip6_frag_id = 0,

dataref =

, destructor_arg = 0x945424f52502009,

frags =

, page_offset = 140,

size = 1350

}, ,

page_offset = 807405872,

size = 808398895

},//...

}

可以看到是在釋放frags[1]的page時出現異常的。

skb->data_len = 0表示沒有分片,所以skb_shared_info的nr_frags = 102 是異常值。

由於 skb_shared_info是緊跟在資料buffer的end之後,懷疑是修改資料buffer時異常將buffer之後的內容也修改了。

檢視業務**邏輯,我們在 tm_wanrx 處理中會對payload進行解密操作,使用的是aes對稱解密,blocksize是16位元組。

但是payload的長度是76位元組,由於業務處理邏輯不嚴謹,導致會解密16 * 5 = 80位元組,也就是tail之後多操作了4個位元組。

//錯誤邏輯會導致將skb->tail之後的位元組也當作密文解密了

for(i =

0; i < skb->len; i +

=crypto_cipher_blocksize

(tfm)

)

skb->tail=190 , skb->end = 192,也就是說會把end之後2個位元組寫壞。剛好是 nr_frags和tx_flags,然後在釋放skb時,因為nr_frags不為0,依次釋放page時,導致異常。

crash> rd 0xffff8800775db472 16		//檢視payload內容

ffff8800775db472: 3403a58d819d566b 050a63aafa6fb6e1 kv..

...4..o..c..

ffff8800775db482: bdcf9439980168d5 8d64ed8067bebebd .h..9..

....g..d.

ffff8800775db492: 27cecee77191c13f e7d5fb356007b55c ?..q...'\..`5...

ffff8800775db4a2: 7d31b864d0a64319 7858d97b1e900cf4 .c..d.1}

....

{.xx

ffff8800775db4b2: fad7522b284cd211 de66b565321f9356 ..l(+r..v..2e.f. //66是nr_frags de是tx_flags

ffff8800775db4c2: 0000000000000000 0000000000000000 ..

....

....

....

..ffff8800775db4d2: 0000000000000000 0000000000000000 ..

....

....

....

..crash> rd 0xffff8800775db4c0 -8 //skb_shared_info開始

ffff8800775db4c0: 66 //nr_frags

crash> rd 0xffff8800775db4c1 -8

ffff8800775db4c1: de //tx_flags .

觸發問題的場景找到了,但是有個小問題。正常情況下對端加密後payload應該是16位元組的整數倍,然後這邊正常解密。什麼情況導致payload長度錯誤呢?

檢視系統log發現,在crash前有個配置變更,將報文傳輸方式由不加密修改為加密。配置是發向連線的兩端裝置,但是存在時間差,在這時收到了對端發來的不加密報文,被當作加密報文處理了,從而導致了該問題的發生。

使用密碼解密TACACS 的報文

本測試是在裝置登入的時候,抓取的tacacs資訊。裝置的ip為10.8.8.150,tacacs server的ip為10.1.1.200,如下是登陸裝置的過程。username adminuser password 這裡輸入了錯誤的密碼ccisco 123 authentication faile...

分析 crash 報告的方法

從這裡只能初步判斷是因為訪問了空的記憶體。但是具體的就不知道了。因為下面的程序呼叫都是堆疊資訊,在網上找了很久終於找到了解決的辦法。分析crash報告 2 下面我們需要 找到 symbolicatecrash developer platforms iphoneos.platform develop...

分析 crash 報告的方法

從這裡只能初步判斷是因為訪問了空的記憶體。但是具體的就不知道了。因為下面的程序呼叫都是堆疊資訊,在網上找了很久終於找到了解決的辦法。分析crash報告 2 下面我們需要 找到 symbolicatecrash developer platforms iphoneos.platform develop...