一次对路边饮用水RFID供应机的跑路玩法
"如何成為一個(gè)合格的硬件白帽子? 答案: 一個(gè)有聰明大腦的你 要有歸納類比和善于用GOOGLE的能力(百度?放棄吧) 善于翻閱和查詢相關(guān)開發(fā)文檔和強(qiáng)大的跑路能力。"
WARNING!!! 本文具有相當(dāng)?shù)墓粜砸约皬?fù)現(xiàn)性,僅供技術(shù)參考與教學(xué)用途研究,切勿用于非法用途,參考此文進(jìn)行犯罪的相關(guān)人員與本人無關(guān)。
?
——免責(zé)聲明。參考刑法修正案:構(gòu)成非法提供控制計(jì)算機(jī)信息系統(tǒng)的程序、工具罪,兩罪量刑都是三年以下有期徒刑或者拘役,并處或者單處罰金,情節(jié)嚴(yán)重的,處三年以上七年以下有期徒刑,并處罰金。非法獲取計(jì)算機(jī)信息系統(tǒng)數(shù)據(jù)罪
這次我們要用到的工具:ProxMark3? ?? ???鎮(zhèn)樓寶圖在此:
?
??
No.2開始搞事。
為了打發(fā)漫長而炎熱的假期,回到了祖父家避暑,結(jié)果發(fā)現(xiàn)原本破敗荒蕪的家屬大院內(nèi)多了一臺(tái)純凈水供應(yīng)設(shè)備,而祖父也剛好辦了一張卡,華山這幾天溫度熱的要死,我竟然神奇的把黑色連到從北京坑到了華山美其名曰避暑然而,連續(xù)五天溫度過了42度,無形裝逼最為致命。現(xiàn)在家里面無聊到爆,于是總是再找點(diǎn)事情做,048??049玩爛了。于是拿出了隨身攜帶的戰(zhàn)術(shù)包中的Proxmark3??hackrf? ?等工具??玩爛了RTL8187? ?HACKRF出問題?于是在一個(gè)炎熱的午后去打水,發(fā)現(xiàn)了那張水卡。踏破鐵鞋無覓處得來全不費(fèi)工夫,不要慫,就是干。征得物業(yè)同意之后開始測(cè)試這個(gè)水機(jī)的認(rèn)證系統(tǒng)。
過程·?首先拿出手電筒對(duì)著M1卡片照射看其中線圈結(jié)構(gòu)。結(jié)果發(fā)現(xiàn)是正方形線圈,按照經(jīng)驗(yàn)是13.56MHZ的高頻卡,于是話不多說直接上工具,是經(jīng)proxmark3的檢測(cè),結(jié)果印證了是Mifare Classic 1k的卡
上手過程按照國際慣例先掃了掃默認(rèn)密碼區(qū),結(jié)果發(fā)現(xiàn)密碼區(qū)防護(hù)做的相當(dāng)?shù)暮?#xff0c;每個(gè)M1卡都有一個(gè)唯一的序列號(hào),我們稱為“UID”,是32位的,也就是4個(gè)字節(jié)。
注:其中每個(gè)data?數(shù)據(jù)區(qū)為一個(gè)“塊”。這樣我們可以計(jì)算一下:16b* 4(塊)*16(扇區(qū))=1024B 就是1K。
第0扇區(qū)的塊0(即絕對(duì)地址0塊),它用于存放廠商代碼,已經(jīng)固化鎖死,不可更改。原來在實(shí)驗(yàn)室見過一個(gè)廠商代碼沒有鎖死的M1??被我玩了好久。。。。。
在全扇區(qū)加密時(shí),通常用前三個(gè)“塊”(0,1,2號(hào)塊)存放數(shù)據(jù),用最后一個(gè)”塊“(3號(hào)塊)存放密碼。
其中密碼分為A密碼和B密碼:前6個(gè)字節(jié)存放A密碼,中間4字節(jié)為控制字段,后6字節(jié)存放B密碼。
·?M1卡是典型的高頻卡,工作頻率為13.56MHz,一般調(diào)頻(FM)收音機(jī)接收的廣播頻率在87MHz到108MHz之間。而我們常說的路由器工作在2.4GHZ中。這個(gè)時(shí)候注意一個(gè)小科普,很多人分不清5G路由和5GLTE。導(dǎo)致很多人認(rèn)為5G路由就是5G通訊技術(shù)的路由,這里進(jìn)行一個(gè)更正 .一般路由是工作在2.4GHZ?頻段下面的通訊信號(hào),而所謂的5G路由是工作頻率在5.8GHZ下的路由器。而5GLTE指的是第五代通訊技術(shù),而逆向工程最好的方法就是了解他的基礎(chǔ)結(jié)構(gòu),我們來看一下M1卡的工作通訊機(jī)制
言歸正傳,來看看M1卡的通訊通信速率:106KBPS,也就是說可以在10毫秒的時(shí)間內(nèi)完成讀寫內(nèi)容。
工作半徑:100mm。大約在100mm以內(nèi)的距離,可以使用讀卡器對(duì)m1卡進(jìn)行操作(一般寫距離小于讀距離)。
在使用proxmark3對(duì)M1卡進(jìn)行破解時(shí)?,我先用了默認(rèn)密碼掃描,結(jié)果發(fā)現(xiàn)卡的安全是很好的,沒有默認(rèn)密碼
于是使用了有卡嗅探,網(wǎng)上很多人都在用proxmark3去暴力破解或者RPNG漏洞利用,對(duì)于proxmark3來說真的是大材小用。Proxmark3可以通過抓取卡與讀卡器之間的通訊來解開相應(yīng)的密碼
準(zhǔn)備1個(gè)充電寶?和1跟 雙頭usb供電線數(shù)據(jù)線淘寶一大把
和原來一樣正常連接電腦。打開窗口(下圖)
一切正常之后??你輸入??hf 14a snoop這時(shí)主板會(huì)亮一個(gè)燈
再撥了主機(jī)上的USB口
到電梯那里去刷卡.(把?PM3天線?放??卡片??和?卡機(jī)?之間)
讓天線?夾到卡與讀卡器之間
不同角度的刷卡??多刷幾次
刷到主板上的燈全滅了
拿?回來直接連接上電腦
打開軟件
再輸入?hf list 14a?
查看監(jiān)聽數(shù)據(jù)
如果監(jiān)聽到完整數(shù)據(jù)后
通過軟件直接算出來就可以了
這就是完整的數(shù)據(jù)
這是激卡 04 00
9320 是要卡返回卡號(hào)
93 70 是選擇卡號(hào)
這三個(gè)就是 密碼了?(當(dāng)然是加密的)?通過軟件可以算出密碼
破解中間我們可以看下M1卡的通訊工作流程圖以更加好的了解工作原理:
破解M1卡的破解算法已經(jīng)爛大街了,我們可以利用M1卡已知的PRNG 漏洞來爆破出其他幾個(gè)扇區(qū)的密碼最后讀出數(shù)據(jù)。保存數(shù)據(jù)后后我又過去進(jìn)行了一次消費(fèi),用來進(jìn)行數(shù)據(jù)對(duì)比(卡中金額有變動(dòng)
·?的話數(shù)據(jù)也有變動(dòng)。)對(duì)比數(shù)據(jù):然后發(fā)現(xiàn)數(shù)據(jù)存儲(chǔ)在14塊、15塊。16塊有數(shù)據(jù)但是沒有變動(dòng),初步猜測(cè)是用戶識(shí)別信息。其他區(qū)塊都是空的。也是夠了。
上手逆向在上手逆向之前我們要認(rèn)識(shí)一下CRC冗余校驗(yàn)和奇偶校驗(yàn)以及異或校驗(yàn),累加校驗(yàn)等
舉個(gè)例子:循環(huán)冗余碼CRC(Cyclic Redundancy Code)又稱多項(xiàng)式碼.
任何一個(gè)由二進(jìn)制數(shù)位串組成的代碼,都可以惟一地與一個(gè)只含有0和1兩個(gè)系數(shù)的多項(xiàng)式建立一一對(duì)應(yīng)的關(guān)系.例如,代碼1010111對(duì)應(yīng)的多項(xiàng)式為X6+X4+X2+X+1,多項(xiàng)式X5+X3+X2+X+1對(duì)應(yīng)的代碼為10111.
CRC碼在發(fā)送端編碼和接收端檢驗(yàn)時(shí),都可以利用事先約定的生成多項(xiàng)式G(X)來得到.設(shè)G(X)中最高位X的次方為Xr,信息位為K(X);則CRC碼=Xr乘以K(X)再除以G(X).
比如:信息位K(X)=X6+X4+X3+1既1011001,生成多項(xiàng)式G(X)=11001既X4+X3+1(可得Xr=X4)
則CRC碼=X4* (X6+X4+X3+1)/(X4+X3+1)=X10+X8+X7+X4/(X4+X3+1)=10110010000/11001
得到的余數(shù)就是CRC碼
注:以上除法用的是模2除法,是一種不考慮減法借位的運(yùn)算.既0-0=0,0-1=1,1-0=1,1-1=0
每個(gè)塊的前八組HEX和后八組HEX中,數(shù)據(jù)基本相同 ,而變動(dòng)數(shù)據(jù)是紅框部位,后面的因?yàn)橄嗤雎圆挥?jì)。然后經(jīng)過詳細(xì)的觀察和運(yùn)算發(fā)現(xiàn):
當(dāng)方框中劃出的數(shù)據(jù)用FF做異或運(yùn)算后,得出的數(shù)值剛好與箭頭所指數(shù)據(jù)相同
A4異或FF??等于5B
答案很明顯了??使用的是異或校驗(yàn)運(yùn)算。我刷掉了1.5元而校驗(yàn)值是箭頭指向的數(shù)據(jù)減去金額,而M1卡數(shù)據(jù)寫入機(jī)制是倒序的。也就是說金額數(shù)據(jù)是14 A4/14 08?我們用校驗(yàn)位減去相應(yīng)金額再轉(zhuǎn)化為十六進(jìn)制即我們想要的數(shù)據(jù):
e31400001cebff ffe314000014eb14eb
爆破原理深源揭秘不法分子爆破M1卡的方式。
使用技術(shù)手段完成M1卡破解的方式有4種:
1.暴力破解
即便是暴力破解,也需要先得到確切的明文和對(duì)應(yīng)的碼流。這大約要進(jìn)行1536次認(rèn)證過程,用時(shí)在一秒鐘之內(nèi)。不過還要進(jìn)行離線暴力破解,估計(jì)在36分鐘可完成。但是需要專用的硬件設(shè)備。
2.以讀卡器的挑戰(zhàn)值做變量
這里說的讀卡器實(shí)際上指的是用來模擬讀卡器的攻擊工具,下個(gè)攻擊亦如此。這種攻擊又可稱選擇密文攻擊,想法用工具控制被攻擊的卡每次在認(rèn)證時(shí)產(chǎn)生同一挑戰(zhàn)值,而讀卡端則回應(yīng)不同值。這種攻擊需要大約28500次的認(rèn)證過程,用時(shí)約15分鐘,然后計(jì)算密鑰,用時(shí)約一分鐘。
3.卡的挑戰(zhàn)值做變量
第三種攻擊與攻擊2類似,但需要使自己的工具的挑戰(zhàn)值為常數(shù),而令卡的挑戰(zhàn)值數(shù)不斷變化。需要預(yù)制一個(gè)384 GB的狀態(tài)表。要進(jìn)行4096次認(rèn)證。大約用時(shí)2分鐘。
4.嵌套認(rèn)證攻擊
第四種攻擊假設(shè)攻擊者已知了至少一個(gè)扇區(qū)的密鑰,他可以根據(jù)漏洞得到其它密鑰的32位,然后對(duì)其它16位進(jìn)行窮舉攻擊。只需3次認(rèn)證(時(shí)間可以忽略不計(jì))。離線攻擊計(jì)算時(shí)間約為一秒。
M1卡的存儲(chǔ)器組織?M1卡存儲(chǔ)詳細(xì)解說。1024 x 8 bit EEPROM存儲(chǔ)器分為16區(qū),每區(qū)4塊,每塊16字節(jié)。
在擦處后的狀態(tài)下,EEPROM的單元讀為邏輯“0”,寫后的狀態(tài)下讀為“1”。
| 扇區(qū) | 塊 | ? | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | ? | 說明 |
| 15 | 3 | ? | KEY A | 控制位 | KEY B | ? | 扇區(qū)15尾塊 | |||||||||||||
| 2 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 1 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 0 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 14 | 3 | ? | KEY A | 控制位 | KEY B | ? | 扇區(qū)14尾塊 | |||||||||||||
| 2 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 1 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 0 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| ::: | ::: | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |
| 1 | 3 | ? | KEY A | 控制位 | KEY B | ? | 扇區(qū)1尾塊 | |||||||||||||
| 2 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 1 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 0 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 0 | 3 | ? | KEY A | 控制位 | KEY B | ? | 扇區(qū)0尾塊 | |||||||||||||
| 2 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 1 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 數(shù)據(jù) | |
| 0 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | 制造商占用塊 | |
3.6.1 廠商代碼塊
這是第1區(qū)的第1塊(塊0)。它含有集成電路制造商數(shù)據(jù)。出于安全和系統(tǒng)需求,此塊是制造商在生產(chǎn)過程中編程后寫保護(hù)的。
3.6.2 數(shù)據(jù)塊
各區(qū)均有3個(gè)16字節(jié)的塊用于存儲(chǔ)數(shù)據(jù)(區(qū)0只有兩個(gè)數(shù)據(jù)塊以及一個(gè)只讀的廠商代碼塊)。
數(shù)據(jù)塊可以通過讀寫控制位設(shè)置為:
· 讀寫塊,例如用于非接觸門禁管理
· 數(shù)值塊,例如用于電子錢包,另有可直接控制存儲(chǔ)值的命令,如增值、減值。
在任何存儲(chǔ)器操作之前必須執(zhí)行認(rèn)證命令。
3.6.2.1數(shù)值塊
數(shù)值塊具有電子錢包功能(有效命令:read, write, increment,decrement, restore, transfer)。
數(shù)值塊有固定的數(shù)據(jù)格式,以便于錯(cuò)誤檢測(cè)、糾錯(cuò)和備份管理。
數(shù)值塊只能通過以數(shù)值塊格式的寫操作生成:
· 數(shù)值:有符號(hào)4字節(jié)數(shù)值。數(shù)值的最低字節(jié)存儲(chǔ)在最低地址字節(jié)。負(fù)值以標(biāo)準(zhǔn)的2的補(bǔ)碼形式存儲(chǔ)。出于數(shù)據(jù)完整性和安全原因,數(shù)值存儲(chǔ)三次,兩次不取反,一次取反。
·?地址(Adr):1字節(jié)地址,當(dāng)進(jìn)行備份管理時(shí),可用于保存塊的地址。地址保存四次。兩次取反,兩次不取反。在increment、decrement、restore和transfer 操作中,地址保持不變。它只能通過write命令更改。
| 說明 | 數(shù)值 | 數(shù)值 | 數(shù)值 | Adr | Adr | Adr | Adr | |||||||||
3.6.3 尾塊(塊3)
各區(qū)均有一個(gè)尾塊,存有:
· 密鑰A和B(可選),讀時(shí)返回邏輯“0”。
· 該區(qū)四個(gè)塊的讀寫條件,存儲(chǔ)在字節(jié)6至9 。讀寫控制位也指定了數(shù)據(jù)塊的類型(讀寫塊或數(shù)值塊)。
如果不需要密鑰B,塊3的最后6字節(jié)可以用作數(shù)據(jù)字節(jié)。
尾塊的字節(jié)9可用于用戶數(shù)據(jù)。因?yàn)榇俗止?jié)享有與字節(jié)6、7、8相同的讀寫權(quán)限。
| 說明 | 密鑰A | 讀寫條件 | 密鑰B(可選) | |||||||||||||
?
3.7?存儲(chǔ)器讀寫
必須如前所述,先選定卡并通過認(rèn)證,才能執(zhí)行存儲(chǔ)器操作。
| 操作 | 說明 | 使用塊型 |
| 讀 | 讀存儲(chǔ)器塊 | 讀寫、數(shù)值和尾塊 |
| 寫 | 寫存儲(chǔ)器塊 | 讀寫、數(shù)值和尾塊 |
| 增值 | 增加塊的內(nèi)容,并將結(jié)果存入內(nèi)部寄存器 | 數(shù)值 |
| 減值 | 減少塊的內(nèi)容,并將結(jié)果存入內(nèi)部寄存器 | 數(shù)值 |
| 轉(zhuǎn)存 | 將內(nèi)部寄存器內(nèi)容寫入塊中 | 數(shù)值 |
| 恢復(fù) | 將塊中內(nèi)容寫入內(nèi)部寄存器 | 數(shù)值 |
對(duì)指定塊可以執(zhí)行的存儲(chǔ)器操作取決于所用的密鑰和存儲(chǔ)在相應(yīng)尾塊中的讀寫條件。
3.7.1 讀寫條件
每個(gè)數(shù)據(jù)塊和尾塊的讀寫條件均由3個(gè)bit定義,并以非取反和取反形式保存在各個(gè)區(qū)的尾塊中。
讀寫控制位管理著使用密鑰A和B讀寫存儲(chǔ)器的權(quán)限。如果知道相關(guān)的密鑰,并且當(dāng)前讀寫條件允許,讀寫條件是可以更改的。
| C13 C23 C33 | read, write | ? | 3 | 尾塊 |
| C12 C22 C32 | read, write, increment, decrement, transfer, restore | ? | 2 | 數(shù)據(jù)塊 |
| C11 C21 C31 | read, write, increment, decrement, transfer, restore | ? | 1 | 數(shù)據(jù)塊 |
| C10 C20 C30 | read, write, increment, decrement, transfer, restore | ? | 0 | 數(shù)據(jù)塊 |
注意:在每一次存儲(chǔ)器讀寫時(shí),內(nèi)部邏輯會(huì)驗(yàn)證存儲(chǔ)條件的格式。如果發(fā)現(xiàn)個(gè)是錯(cuò)誤,這個(gè)區(qū)將被永久性鎖死。
注意:在下列說明中,讀寫控制位是僅以非取反形式表述的。
MF1的內(nèi)部邏輯保證了命令只有在通過認(rèn)證后才被執(zhí)行。
3.7.2 尾塊的讀寫條件
對(duì)密鑰和控制位的讀寫取決于尾塊(塊3)的訪問控制位,分為“禁止”、“KEY A”、“KEY B”和“KEY A|B”( KEY A或KEY B)。
| KEY A | 訪問控制位 | KEY B | |||||||
| C1 | C2 | C3 | 讀 | 寫 | 讀 | 寫 | 讀 | 寫 | ? |
| 0 | 0 | 0 | 禁止 | Key A | Key A | Key B | Key A | Key A | Key B可讀 |
| 0 | 1 | 0 | 禁止 | 禁止 | Key A | 禁止 | Key A | 禁止 | Key B可讀 |
| 1 | 0 | 0 | 禁止 | Key B | Key A|B | 禁止 | 禁止 | Key B | ? |
| 1 | 1 | 0 | 禁止 | 禁止 | Key A|B | 禁止 | 禁止 | 禁止 | ? |
| 0 | 0 | 1 | 禁止 | Key A | Key A | Key A | Key A | Key A | Key B可讀傳輸配置狀態(tài) |
| 0 | 1 | 1 | 禁止 | Key B | Key A|B | Key B | 禁止 | Key B | ? |
| 1 | 0 | 1 | 禁止 | 禁止 | Key A|B | Key B | 禁止 | 禁止 | ? |
| 1 | 1 | 1 | 禁止 | 禁止 | Key A|B | 禁止 | 禁止 | 禁止 | ? |
注:灰色行為key B可讀并可用于存儲(chǔ)數(shù)據(jù)的訪問控制條件。
尾塊和key A被預(yù)定義為傳輸配置狀態(tài)。因?yàn)樵趥鬏斉渲脿顟B(tài)下key B可讀,新卡必須用key A認(rèn)證。
因?yàn)樵L問控制位本身也可以禁止訪問,所以個(gè)人化時(shí)應(yīng)當(dāng)特別小心。
3.7.3 數(shù)據(jù)塊的訪問控制條件
對(duì)數(shù)據(jù)塊(塊0至2)的讀寫訪問取決于其訪問控制位,分為“禁止”、“KEY A”、“KEY B”和“kEY A|B”( KEY A或KEY B)。相關(guān)訪問控制位的設(shè)置確定了其用途以及相應(yīng)的可用命令。
· 讀寫塊:允許讀、寫操作。
· 數(shù)值塊:運(yùn)行另外的數(shù)值操作——加值、減值、轉(zhuǎn)存和恢復(fù)。在用于非充值卡的一種情況(‘001’)下,只能夠讀和減值。在另一種情況(‘110‘)下,可以用key B充值。
· 制造廠商塊:只讀,不受訪位控制位設(shè)置的影響!
· 密鑰管理:在傳輸配置狀態(tài)下,必須用key A 認(rèn)證。
| C1 | C2 | C3 | 讀 | 寫 | 加值 | 減值轉(zhuǎn)存恢復(fù) | ? |
| 0 | 0 | 0 | key A|B1 | key A|B1 | key A|B1 | key A|B1 | 傳輸配置狀態(tài) |
| 0 | 1 | 0 | key A|B1 | key B1 | 禁止 | 禁止 | 讀寫塊 |
| 1 | 0 | 0 | key A|B1 | key B1 | 禁止 | 禁止 | 讀寫塊 |
| 1 | 1 | 0 | key A|B1 | key B1 | key B1 | key A|B1 | 數(shù)值塊 |
| 0 | 0 | 1 | key A|B1 | 禁止 | 禁止 | key A|B1 | 數(shù)值塊 |
| 0 | 1 | 1 | key B1 | key B1 | 禁止 | 禁止 | 讀寫塊 |
| 1 | 0 | 1 | key B1 | 禁止 | 禁止 | 禁止 | 讀寫塊 |
| 1 | 1 | 1 | 禁止 | 禁止 | 禁止 | 禁止 | 讀寫塊 |
1? ?如果相應(yīng)扇區(qū)尾塊Key B可讀,則不得用作認(rèn)證(前表中所有灰色行)。
?
后果:如果讀寫器試圖用灰色行的訪問控制條件以Key B認(rèn)證任何扇區(qū)的任何塊,卡將在認(rèn)證后拒絕所有后續(xù)存儲(chǔ)器訪問。
Ps:突發(fā)奇想可以用M1卡當(dāng)數(shù)據(jù)存儲(chǔ)解密玩。
總結(jié)
以上是生活随笔為你收集整理的一次对路边饮用水RFID供应机的跑路玩法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 日常喝的矿泉水中矿物质含量是越高越好吗?
- 下一篇: Django学习(第四天:ORMMode