lol
This commit is contained in:
parent
2671c3d6af
commit
a979444bc9
19
_config.yml
19
_config.yml
@ -4,8 +4,8 @@
|
||||
|
||||
# Site
|
||||
title: 混元霹雳手
|
||||
subtitle:
|
||||
description: Sauce is forever
|
||||
subtitle: Battle⚔️ 2 the world🌎
|
||||
description: Juice is temporary but Sauce is forever
|
||||
keywords:
|
||||
author: Cool-Y
|
||||
language: zh-Hans
|
||||
@ -34,6 +34,21 @@ code_dir: downloads/code
|
||||
i18n_dir: :lang
|
||||
skip_render:
|
||||
|
||||
# RSS
|
||||
# https://github.com/hexojs/hexo-generator-feed
|
||||
feed:
|
||||
type: atom
|
||||
path: atom.xml
|
||||
limit: 20
|
||||
hub:
|
||||
content:
|
||||
content_limit: 140
|
||||
content_limit_delim: ' '
|
||||
order_by: -date
|
||||
icon: icon.png
|
||||
autodiscovery: true
|
||||
template:
|
||||
|
||||
# Writing
|
||||
new_post_name: :title.md # File name of new posts
|
||||
default_layout: post
|
||||
|
141
package-lock.json
generated
141
package-lock.json
generated
@ -2051,6 +2051,147 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"hexo-generator-feed": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hexo-generator-feed/-/hexo-generator-feed-3.0.0.tgz",
|
||||
"integrity": "sha512-Jo35VSRSNeMitS2JmjCq3OHAXXYU4+JIODujHtubdG/NRj2++b3Tgyz9pwTmROx6Yxr2php/hC8og5AGZHh8UQ==",
|
||||
"requires": {
|
||||
"hexo-util": "^2.1.0",
|
||||
"nunjucks": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"camel-case": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
|
||||
"integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
|
||||
"requires": {
|
||||
"pascal-case": "^3.1.2",
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"requires": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.1.tgz",
|
||||
"integrity": "sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^4.0.0",
|
||||
"entities": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domhandler": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.1.0.tgz",
|
||||
"integrity": "sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
|
||||
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz",
|
||||
"integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.5.2.tgz",
|
||||
"integrity": "sha512-MHTthCb1zj8f1GVfRpeZUbohQf/HdBos0oX5gZcQFepOZPLLRyj6Wn7XS7EMnY7CVpwv8863u2vyE83Hfu28HQ==",
|
||||
"requires": {
|
||||
"dom-serializer": "^1.0.1",
|
||||
"domelementtype": "^2.2.0",
|
||||
"domhandler": "^4.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"domhandler": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.1.0.tgz",
|
||||
"integrity": "sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
|
||||
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
|
||||
},
|
||||
"hexo-util": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/hexo-util/-/hexo-util-2.4.0.tgz",
|
||||
"integrity": "sha512-IPQvAyn0cznYMU2gskMiZ6LZEvN7wHNusrJoYxrir4f7S7POpZeDTBswiko9R1qqd+/hu07wUYZdm4ceTTCEaA==",
|
||||
"requires": {
|
||||
"bluebird": "^3.5.2",
|
||||
"camel-case": "^4.0.0",
|
||||
"cross-spawn": "^7.0.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"highlight.js": "^10.0.0",
|
||||
"htmlparser2": "^4.0.0",
|
||||
"prismjs": "^1.17.1",
|
||||
"strip-indent": "^3.0.0",
|
||||
"striptags": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "10.7.2",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz",
|
||||
"integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg=="
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz",
|
||||
"integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==",
|
||||
"requires": {
|
||||
"domelementtype": "^2.0.1",
|
||||
"domhandler": "^3.0.0",
|
||||
"domutils": "^2.0.0",
|
||||
"entities": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"strip-indent": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
|
||||
"integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
|
||||
"requires": {
|
||||
"min-indent": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"striptags": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/striptags/-/striptags-3.1.1.tgz",
|
||||
"integrity": "sha1-yMPn/db7S7OjKjt1LltePjgJPr0="
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"hexo-generator-index": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "http://registry.npm.taobao.org/hexo-generator-index/download/hexo-generator-index-0.2.1.tgz",
|
||||
|
@ -12,6 +12,7 @@
|
||||
"hexo-generator-archive": "^0.1.5",
|
||||
"hexo-generator-baidu-sitemap": "^0.1.6",
|
||||
"hexo-generator-category": "^0.1.3",
|
||||
"hexo-generator-feed": "^3.0.0",
|
||||
"hexo-generator-index": "^0.2.1",
|
||||
"hexo-generator-json-content": "^4.2.3",
|
||||
"hexo-generator-search": "^2.4.0",
|
||||
|
@ -40,7 +40,7 @@ s.close()
|
||||
|
||||
#### 漏洞复现
|
||||
使用firmadyne进行固件模拟,运行UPnP服务
|
||||
<img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1614665628/cve/carbon.png" width="50%" height="50%">
|
||||
<img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1614665628/cve/carbon.png">
|
||||
|
||||
攻击者可以是连接到路由器局域网内并且能够向UPnP端口发送请求的任何人。可以通过编写简单的python脚本将精心制作的数据包发送到特定的upnp端口,该脚本随后将作为精心制作的请求的一部分执行提供的命令。共享的POC将打开端口8089上的telnet服务。
|
||||
<img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1614665899/cve/carbon_1.png" width="50%" height="50%">
|
||||
<img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1614665899/cve/carbon_1.png">
|
||||
|
@ -56,7 +56,7 @@ https://www.anquanke.com/post/id/217606
|
||||
首先下载有问题的固件 R8300 Firmware Version 1.0.2.130 http://www.downloads.netgear.com/files/GDC/R8300/R8300-V1.0.2.130_1.0.99.zip
|
||||
使用binwalk对固件中的特征字符串进行识别,可以看到R8300采用了squashfs文件系统格式
|
||||
|
||||
```
|
||||
```shell
|
||||
$ binwalk R8300-V1.0.2.130_1.0.99.chk
|
||||
|
||||
DECIMAL HEXADECIMAL DESCRIPTION
|
||||
@ -69,7 +69,7 @@ DECIMAL HEXADECIMAL DESCRIPTION
|
||||
|
||||
使用 `binwalk -Me` 提取出 Squashfs 文件系统,可以看到R8300为ARM v5架构.
|
||||
|
||||
```
|
||||
```shell
|
||||
$ file usr/sbin/upnpd
|
||||
usr/sbin/upnpd: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), stripped
|
||||
```
|
||||
@ -84,7 +84,7 @@ usr/sbin/upnpd: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamic
|
||||
|
||||
* NVRAM库劫持失败,firmadyne实现了sem_get()、sem_lock()、sem_unlock()等函数https://github.com/firmadyne/libnvram
|
||||
|
||||
```
|
||||
```shell
|
||||
$ ./fat.py 'Path to R8300 firmware file'
|
||||
|
||||
__ _
|
||||
@ -374,7 +374,7 @@ sem_lock: Unable to get semaphore!
|
||||
使用Qemu模拟固件需要下载对应的arm虚拟机镜像,内核和initrd。
|
||||
https://people.debian.org/~aurel32/qemu/armhf/
|
||||
|
||||
```
|
||||
```shell
|
||||
[debian_wheezy_armhf_desktop.qcow2](https://people.debian.org/~aurel32/qemu/armhf/debian_wheezy_armhf_desktop.qcow2) 2013-12-17 02:43 1.7G [debian_wheezy_armhf_standard.qcow2](https://people.debian.org/~aurel32/qemu/armhf/debian_wheezy_armhf_standard.qcow2) 2013-12-17 00:04 229M
|
||||
[initrd.img-3.2.0-4-vexpress](https://people.debian.org/~aurel32/qemu/armhf/initrd.img-3.2.0-4-vexpress) 2013-12-17 01:57 2.2M
|
||||
[vmlinuz-3.2.0-4-vexpress](https://people.debian.org/~aurel32/qemu/armhf/vmlinuz-3.2.0-4-vexpress) 2013-09-20 18:33 1.9M
|
||||
@ -389,8 +389,8 @@ https://people.debian.org/~aurel32/qemu/armhf/
|
||||
|
||||
对于R8300固件,在 Host 机上创建一个 tap 接口并分配 IP,启动虚拟机:
|
||||
|
||||
```
|
||||
`sudo tunctl -t tap0 -u `whoami`
|
||||
```shell
|
||||
sudo tunctl -t tap0 -u `whoami`
|
||||
sudo ifconfig tap0 192.168.2.1/24
|
||||
qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.img-3.2.0-4-vexpress -drive if=sd,file=debian_wheezy_armhf_standard.qcow2 -append "root=/dev/mmcblk0p2" -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic`
|
||||
```
|
||||
@ -398,16 +398,16 @@ qemu-system-arm -M vexpress-a9 -kernel vmlinuz-3.2.0-4-vexpress -initrd initrd.i
|
||||
与标准命令区别在于` -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic`
|
||||
启动之后输入用户名和密码,都是 root,为虚拟机分配 IP:
|
||||
|
||||
```
|
||||
`root@debian-armhf:~# ifconfig eth0 ``192.168``.``2.2``/``24`
|
||||
```shell
|
||||
root@debian-armhf:~# ifconfig eth0 192.168.2.2/24
|
||||
```
|
||||
|
||||
这样 Host 和虚拟机就网络互通了,然后挂载 proc、dev,最后 chroot 即可。
|
||||
|
||||
```
|
||||
`root@debian-armhf:~# mount -t proc /proc ./squashfs-root/proc
|
||||
root@debian-armhf:~# mount -t proc /proc ./squashfs-root/proc
|
||||
root@debian-armhf:~# mount -o bind /dev ./squashfs-root/dev
|
||||
root@debian-armhf:~# chroot ./squashfs-root/ sh`
|
||||
root@debian-armhf:~# chroot ./squashfs-root/ sh
|
||||
```
|
||||
|
||||
|
||||
@ -429,26 +429,26 @@ $ arm-linux-gcc -Wall -fPIC -shared nvram.c -o nvram.so
|
||||
nvram库的实现者还同时 hook 了 `system`、`fopen`、`open` 等函数,因此还会用到 `dlsym`,`/lib/libdl.so.0 `导出了该符号。
|
||||
|
||||
```
|
||||
`$ grep ``-``r ``"dlsym"`` ``.`
|
||||
`Binary`` file ``./``lib``/``libcrypto``.``so``.``1.0``.``0`` matches`
|
||||
`Binary`` file ``./``lib``/``libdl``.``so``.``0`` matches`
|
||||
`Binary`` file ``./``lib``/``libhcrypto``-``samba4``.``so``.``5`` matches`
|
||||
`Binary`` file ``./``lib``/``libkrb5``-``samba4``.``so``.``26`` matches`
|
||||
`Binary`` file ``./``lib``/``libldb``.``so``.``1`` matches`
|
||||
`Binary`` file ``./``lib``/``libsamba``-``modules``-``samba4``.``so matches`
|
||||
`Binary`` file ``./``lib``/``libsqlite3``.``so``.``0`` matches`
|
||||
`grep``:`` ``./``lib``/``modules``/``2.6``.``36.4brcmarm``+:`` ``No`` such file ``or`` directory`
|
||||
$ grep -r "dlsym" .
|
||||
Binary file ./lib/libcrypto.so.1.0.0 matches
|
||||
Binary file ./lib/libdl.so.0 matches
|
||||
Binary file ./lib/libhcrypto-samba4.so.5 matches
|
||||
Binary file ./lib/libkrb5-samba4.so.26 matches
|
||||
Binary file ./lib/libldb.so.1 matches
|
||||
Binary file ./lib/libsamba-modules-samba4.so matches
|
||||
Binary file ./lib/libsqlite3.so.0 matches
|
||||
grep: ./lib/modules/2.6.36.4brcmarm+: No such file or directory
|
||||
|
||||
$ `readelf ``-``a `**`./``lib``/``libdl``.``so``.`**`**0**`` ``|`` grep dlsym`
|
||||
` ``26``:`` ``000010f0`` ``296`` FUNC GLOBAL DEFAULT ``7`` dlsym`
|
||||
$ readelf -a *./lib/libdl.so.**0* | grep dlsym
|
||||
26: 000010f0 296 FUNC GLOBAL DEFAULT 7 dlsym
|
||||
```
|
||||
|
||||
* 配置tmp/nvram.ini信息
|
||||
|
||||
接下来要做的就是根据上面的日志补全配置信息,也可以参考https://github.com/zcutlip/nvram-faker/blob/master/nvram.ini。至于为什么这么设置,可以查看对应的汇编代码逻辑(配置的有问题的话很容易触发段错误)。
|
||||
|
||||
```
|
||||
`upnpd_debug_level=9
|
||||
```shell
|
||||
upnpd_debug_level=9
|
||||
lan_ipaddr=192.168.2.2
|
||||
hwver=R8500
|
||||
friendly_name=R8300
|
||||
@ -461,13 +461,13 @@ upnp_duration=3600
|
||||
upnp_DHCPServerConfigurable=1
|
||||
wps_is_upnp=0
|
||||
upnp_sa_uuid=00000000000000000000
|
||||
lan_hwaddr=AA:BB:CC:DD:EE:FF`
|
||||
lan_hwaddr=AA:BB:CC:DD:EE:FF
|
||||
```
|
||||
|
||||
* 运行过程
|
||||
|
||||
```
|
||||
**# ./usr/sbin/upnpd**
|
||||
```shell
|
||||
# ./usr/sbin/upnpd
|
||||
# /dev/nvram: No such file or directory
|
||||
/dev/nvram: No such file or directory
|
||||
/dev/nvram: No such file or directory
|
||||
@ -480,13 +480,13 @@ lan_hwaddr=AA:BB:CC:DD:EE:FF`
|
||||
/dev/nvram: No such file or directory
|
||||
/dev/nvram: No such file or directory
|
||||
|
||||
**# LD_PRELOAD="./nvram.so" ./usr/sbin/upnpd**
|
||||
# LD_PRELOAD="./nvram.so" ./usr/sbin/upnpd
|
||||
# ./usr/sbin/upnpd: can't resolve symbol 'dlsym'
|
||||
|
||||
**# LD_PRELOAD="./nvram.so ./lib/libdl.so.0" ./usr/sbin/upnpd**
|
||||
# LD_PRELOAD="./nvram.so ./lib/libdl.so.0" ./usr/sbin/upnpd
|
||||
# [0x00026460] fopen('/var/run/upnpd.pid', 'wb+') = 0x00b19008
|
||||
[0x0002648c] custom_nvram initialised
|
||||
[0x76eb7cb8] **fopen****('/tmp/nvram.ini', 'r') = 0x00b19008**
|
||||
[0x76eb7cb8] *fopen**('/tmp/nvram.ini', 'r') = 0x00b19008*
|
||||
[nvram 0] upnpd_debug_level = 9
|
||||
[nvram 1] lan_ipaddr = 192.168.2.2
|
||||
[nvram 2] hwver = R8500
|
||||
@ -523,21 +523,21 @@ acosNvramConfig_get('upnpd_debug_level') = '9'
|
||||
在 `sub_25E04()` 中调用 `strcpy()` 将以上数据拷贝到大小为 `0x634 - 0x58 = 0x5dc` 的 buffer。如果超过缓冲区大小,数据就会覆盖栈底部分甚至返回地址。
|
||||
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083972/netgear/image_30.png)
|
||||
|
||||
```
|
||||
` ``+-----------------+`
|
||||
` ``|`` retaddr ``|`
|
||||
` ``+-----------------+`
|
||||
` ``|`` saved ebp ``|`
|
||||
` ebp``--->+-----------------+`
|
||||
` ``|`` ``|`
|
||||
` ``|`` ``|
|
||||
```shell
|
||||
+-----------------+
|
||||
| retaddr |
|
||||
+-----------------+
|
||||
| saved ebp |
|
||||
ebp--->+-----------------+
|
||||
| |
|
||||
s,ebp-0x58-->+-----------------+`
|
||||
` ``|`` ``|`
|
||||
` ``|`` buffer ``|`
|
||||
` ``|`` ``|`
|
||||
` ``|`` ``|`
|
||||
` v40``,``ebp``-``0x634``-->+-----------------+`
|
||||
| |
|
||||
| |
|
||||
s,ebp-0x58-->+-----------------+
|
||||
| |
|
||||
| buffer |
|
||||
| |
|
||||
| |
|
||||
v40,ebp-0x634-->+-----------------+
|
||||
```
|
||||
|
||||
|
||||
@ -562,17 +562,17 @@ Listening on port 12345
|
||||
`gdb-multiarch -x dbgscript`
|
||||
dbgscript 内容
|
||||
|
||||
```
|
||||
`set`` architecture arm`
|
||||
`gef``-``remote ``-``q ``192.168``.2``.1``:``12345`
|
||||
`file usr``/``sbin``/``upnpd`
|
||||
`set`` remote ``exec``-``file ``/``usr``/``sbin``/upnpd`
|
||||
```shell
|
||||
set architecture arm
|
||||
gef-remote -q 192.168.2.1:12345
|
||||
file usr/sbin/upnpd
|
||||
set remote exec-file /usr/sbin/upnpd
|
||||
```
|
||||
|
||||
直接构造溢出字符,程序不会正常返回,因为栈上存在一个v40的指针v51,需要覆盖为有效地址才能正确返回。
|
||||
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083781/netgear/image_23.png)
|
||||
|
||||
```
|
||||
```python
|
||||
#!/usr/bin/python3
|
||||
|
||||
import socket
|
||||
@ -593,7 +593,7 @@ s.close()
|
||||
|
||||
|
||||
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083780/netgear/image_24.png)
|
||||
```
|
||||
```python
|
||||
#!/usr/bin/python3
|
||||
|
||||
import socket
|
||||
@ -626,7 +626,7 @@ s.close()
|
||||
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083780/netgear/image_25.png)
|
||||
在堆栈恢复前下一个断点,观察控制流转移情况,将PC指针控制为重启指令。通过 hook 的日志可以看到,ROP 利用链按照预期工作(由于模拟环境的问题,reboot 命令运行段错误了...)
|
||||
|
||||
```
|
||||
```shell
|
||||
gef➤ b *0x00025F40
|
||||
Breakpoint 1 at 0x25f40
|
||||
|
||||
@ -669,7 +669,7 @@ rmmod: dhd.ko: No such file or directory
|
||||
路由器已启用ASLR缓解功能,我们可以使用ROP攻击绕过该功能。但是,我们通过使用对NULL字节敏感的**strcpy**来执行复制调用,这反过来又会阻止我们使用ROP攻击。因此,要利用包含NULL字节的地址,我们将需要使用堆栈重用攻击。即想办法提前将 ROP payload 注入目标内存。(`stack reuse`)
|
||||
注意到recvfrom函数在接收 socket 数据时 buffer 未初始化,利用内存未初始化问题,我们可以向sub_1D020的堆栈中布置gadgets。构造如下 PoC,每个 payload 前添加 `\x00` 防止程序崩溃(strcpy遇到\x00截断,不会拷贝后面部分)。
|
||||
|
||||
```
|
||||
```python
|
||||
#!/usr/bin/python3
|
||||
|
||||
import socket
|
||||
@ -684,7 +684,7 @@ s.close()
|
||||
|
||||
在strcpy下断点调试,并检查栈区内存
|
||||
|
||||
```
|
||||
```shell
|
||||
gef➤ info b
|
||||
Num Type Disp Enb Address What
|
||||
1 breakpoint keep y 0x76dd6e48 <recvfrom+4>
|
||||
@ -711,7 +711,7 @@ gef➤ x/s 0x7eb6cc75+1588
|
||||
|
||||
此时程序上下文为
|
||||
|
||||
```
|
||||
```shell
|
||||
gef➤ context
|
||||
[ Legend: Modified register | Code | Heap | Stack | String ]
|
||||
───────────────────────────────────────────────────────────────────────────────────────────── registers ────
|
||||
@ -774,7 +774,7 @@ $cpsr: [NEGATIVE zero carry overflow interrupt fast thumb]
|
||||
|真实利用: |IP:192.168.2.2 Port:upnp/1900 |
|
||||
||![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083779/netgear/image_27.png) |
|
||||
|
||||
```
|
||||
```python
|
||||
import socket
|
||||
import time
|
||||
import sys
|
||||
|
@ -29,7 +29,7 @@ https://github.com/therealsaumil/armx/issues/4
|
||||
|
||||
该函数的逻辑如下,a1为要查询的key,a2为待比较的对应value,调用nvram_get获得nvram中a1的value,然后和a2比较,相同的话返回1。
|
||||
|
||||
```
|
||||
```c
|
||||
const char *__fastcall acosNvramConfig_match(int a1, const char *a2)
|
||||
{
|
||||
const char *v2; // r4
|
||||
@ -48,7 +48,7 @@ const char *__fastcall acosNvramConfig_match(int a1, const char *a2)
|
||||
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610094619/nvram/image_24.png)
|
||||
我做出了一个假设:所有a2都是能够使程序正常运行的nvram值,现在想要获取它。编写IDA脚本如下:
|
||||
|
||||
```
|
||||
```c
|
||||
def GetAddr(func_name):
|
||||
func_list = Functions()
|
||||
for func in func_list:
|
||||
@ -88,7 +88,7 @@ for x in XrefsTo(func_addr,flags=0):
|
||||
|
||||
粘贴部分结果,有大量的重复,还有许多键值不存在,假设不成立。
|
||||
|
||||
```
|
||||
```shell
|
||||
('acosNvramConfig_match', '0xa3d4L')
|
||||
XrefsTo nvram-match func addr: 0xc940L
|
||||
nvram key: qos_bw_set_sel
|
||||
@ -116,7 +116,7 @@ nvram value: U12H127T00_NETGEAR
|
||||
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610094620/nvram/image_23.png)
|
||||
利用IDApython获取该区域存放的键值,注意:该区域并不存放字符串,而是存放“存放字符串地址处”的地址,所以也要通过Doword来获取实际地址
|
||||
|
||||
```
|
||||
```python
|
||||
import idautils
|
||||
for seg in idautils.Segments():
|
||||
if SegName(seg) == '.data':
|
||||
@ -135,7 +135,7 @@ for seg in idautils.Segments():
|
||||
|
||||
这里我们只关注有upnp特征的键值对
|
||||
|
||||
```
|
||||
```shell
|
||||
.data [77868 94004](tel:7786894004)
|
||||
upnp_enable=1
|
||||
upnp_turn_on=1
|
||||
@ -148,7 +148,7 @@ upnp_DHCPServerConfigurable=1
|
||||
|
||||
另外再补充几个与网络有关的配置
|
||||
|
||||
```
|
||||
```shell
|
||||
friendly_name=Netgear
|
||||
lan_hwaddr=AA:BB:CC:DD:EE:FF
|
||||
lan_ipaddr=192.168.2.2
|
||||
|
@ -38,7 +38,7 @@ KVM的用户空间组件包含在主线QEMU(快速仿真器)中,该QEMU特
|
||||
|
||||
由于我们定位的漏洞已经修复,因此我们需要签出QEMU存储库的源,并切换到这些漏洞的修复之前的提交。 然后,我们仅为目标x86_64配置QEMU并启用调试,在我们的测试环境中,我们使用Gcc的4.9.2版构建QEMU:
|
||||
|
||||
```
|
||||
```shell
|
||||
$ git clone git://git.qemu-project.org/qemu.git
|
||||
$
|
||||
$ git checkout bd80b59
|
||||
@ -51,21 +51,21 @@ KVM的用户空间组件包含在主线QEMU(快速仿真器)中,该QEMU特
|
||||
|
||||
使用qemu-img来生成一个qcow2系统文件
|
||||
|
||||
```
|
||||
**`$`**` ./qemu-img create -f qcow2 ubuntu.qcow2 20G`
|
||||
```shell
|
||||
$ ./qemu-img create -f qcow2 ubuntu.qcow2 20G`
|
||||
$ sudo chmod 666 /dev/kvm
|
||||
```
|
||||
|
||||
之后首先通过qemu-system-x86_64完成对qcow2系统文件中系统的安装,需要用-cdrom对iso镜像文件进行加载
|
||||
|
||||
```
|
||||
```shell
|
||||
$ ./x86_64-softmmu/qemu-system-x86_64 -enable-kvm -m 2048 -hda ./ubuntu.qcow2 -cdrom\
|
||||
'/home/han/VMescape/ubuntu-16.04-server-amd64.iso'
|
||||
```
|
||||
|
||||
安装完成后就获得了一个有系统的qcow2文件,我们分配2GB的内存并创建两个网络接口卡:RTL8139和PCNET,同时创建tap接口连接虚拟机和主机:
|
||||
|
||||
```
|
||||
```shell
|
||||
✗ sudo tunctl -t tap0 -u `whoami`
|
||||
✗ sudo ifconfig tap0 192.168.2.1/24
|
||||
$ ./x86_64-softmmu/qemu-system-x86_64 -enable-kvm -m 2048 -display vnc=:89 \
|
||||
@ -79,7 +79,7 @@ format=qcow2,if=ide,cache=writeback,\
|
||||
使用vncviewer连接qemu
|
||||
|
||||
```
|
||||
`apt-get install xvnc4viewer`
|
||||
apt-get install xvnc4viewer
|
||||
vncviewer 127.0.0.1:5989
|
||||
```
|
||||
|
||||
@ -90,21 +90,21 @@ vncviewer 127.0.0.1:5989
|
||||
下图说明了来宾的内存和主机的内存如何共存。
|
||||
|
||||
|
||||
```
|
||||
```shell
|
||||
Guest' processes
|
||||
+--------------------+
|
||||
Virtual addr space | |
|
||||
+--------------------+
|
||||
| |
|
||||
**\__ Page Table \__
|
||||
\ \**
|
||||
\__ Page Table \__
|
||||
\ \
|
||||
| | Guest kernel
|
||||
+----+--------------------+----------------+
|
||||
Guest's phy. memory | | | |
|
||||
+----+--------------------+----------------+
|
||||
| |
|
||||
**\__ \__
|
||||
\ \**
|
||||
\__ \__
|
||||
\ \
|
||||
| QEMU process |
|
||||
+----+------------------------------------------+
|
||||
Virtual addr space | | |
|
||||
@ -120,7 +120,7 @@ Physical memory | | ||
|
||||
|
||||
此外,QEMU为BIOS和ROM保留了一个内存区域。 这些映射在QEMU映射文件中可用:
|
||||
|
||||
```
|
||||
```shell
|
||||
✗ cat /proc/36220/maps
|
||||
555aae05c000-555aae931000 r-xp 00000000 08:01 2239549 /usr/bin/qemu-system-x86_64
|
||||
555aaeb30000-555aaecfc000 r--p 008d4000 08:01 2239549 /usr/bin/qemu-system-x86_64
|
||||
@ -156,8 +156,8 @@ ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
|
||||
|
||||
在x64系统上,虚拟地址由页偏移量(位0-11)和页码组成。 在linux系统上,具有CAP_SYS_ADMIN特权的用户空间进程能够使用页面映射文件(pagemap )找出虚拟地址和物理地址的映射。 页面映射文件为每个虚拟页面存储一个64位值,其中`physical_address = PFN * page_size + offset`
|
||||
|
||||
```
|
||||
**- Bits 0-54 : physical frame number if present.**
|
||||
```shell
|
||||
- Bits 0-54 : physical frame number if present.
|
||||
- Bit 55 : page table entry is soft-dirty.
|
||||
- Bit 56 : page exclusively mapped.
|
||||
- Bits 57-60 : zero
|
||||
@ -181,13 +181,13 @@ ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
|
||||
1. 根据物理内存的 PFN (**physical frame number**)以及页内偏移,就可以计算出对应的物理地址;
|
||||
|
||||
```
|
||||
`physical_address = PFN * page_size + offset
|
||||
physcial_addr ``=`` ``(``page_frame_number ``<<`` PAGE_SHIFT``)`` ``+`` distance_from_page_boundary_of_buffer`
|
||||
physical_address = PFN * page_size + offset
|
||||
physcial_addr =(page_frame_number << PAGE_SHIFT) + distance_from_page_boundary_of_buffer
|
||||
```
|
||||
|
||||
我们依靠Nelson Elhage的[代码](https://github.com/nelhage/virtunoid/blob/master/virtunoid.c)。 下面的程序分配一个缓冲区,并用字符串“Where am I?”填充它。 并打印其物理地址:
|
||||
|
||||
```
|
||||
```c
|
||||
---[ mmu.c ]---
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -256,7 +256,7 @@ int main()
|
||||
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618050992/VMescape/image_29.png)
|
||||
在主机将gdb附加到QEMU进程,我们可以看到缓冲区位于为guest虚拟机分配的物理地址空间内。 更准确地说,输出的guest物理地址地址实际上是与**guest物理内存基址**的偏移量。
|
||||
|
||||
```
|
||||
```shell
|
||||
✗ sudo gdb qemu-system-x86_64 38140
|
||||
(gdb) info proc mappings
|
||||
process 38140
|
||||
@ -269,7 +269,7 @@ Mapped address spaces:
|
||||
0x556857d67000 0x5568581ca000 0x463000 0x0
|
||||
0x556859c27000 0x55685b038000 0x1411000 0x0 [heap]
|
||||
... ... ... ...
|
||||
**0x7f72afe00000** **** **0x7f732fe00000** **** **0x80000000** 0x0 [2GB RAM]
|
||||
0x7f72afe00000 0x7f732fe00000 0x80000000 0x0 [2GB RAM]
|
||||
... ... ... ...
|
||||
(gdb) x/s 0x7f72afe00000+0x73b17b20
|
||||
0x7f7323917b20: "Where am I?"
|
||||
@ -288,7 +288,7 @@ REALTEK网卡支持两种 接收/发送 操作模式:C模式和C +模式。
|
||||
|
||||
该漏洞存在于hw/net/rtl8139.c的 rtl8139_cplus_transmit_one 函数中:
|
||||
|
||||
```
|
||||
```c
|
||||
/* ip packet header */
|
||||
ip_header *ip = NULL;
|
||||
int hlen = 0;
|
||||
@ -317,7 +317,7 @@ if (proto == ETH_P_IP)
|
||||
} else {
|
||||
hlen = IP_HEADER_LENGTH(ip);
|
||||
ip_protocol = ip->ip_p;
|
||||
**ip_data_len** **= be16_to_cpu(ip->ip_len) - hlen;**
|
||||
ip_data_len** **= be16_to_cpu(ip->ip_len) - hlen;
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -326,8 +326,8 @@ IP头包含两个字段hlen和ip-> ip_len,分别表示IP头的长度(考虑
|
||||
|
||||
更精确地讲,ip_data_len稍后用于计算TCP数据的长度,如果该数据超过MTU的大小,则将其逐块复制到一个malloc缓冲区中:
|
||||
|
||||
```
|
||||
int **tcp_data_len** **= ip_data_len - tcp_hlen;**
|
||||
```c
|
||||
int tcp_data_len** **= ip_data_len - tcp_hlen;
|
||||
int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
|
||||
|
||||
int is_last_frame = 0;
|
||||
@ -363,7 +363,7 @@ for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len;
|
||||
|
||||
下图显示了RTL8139寄存器。 我们将不详述所有这些内容,而是仅详述与我们的利用相关的那些内容:
|
||||
|
||||
```
|
||||
```shell
|
||||
+---------------------------+----------------------------+
|
||||
0x00 | MAC0 | MAR0 |
|
||||
+---------------------------+----------------------------+
|
||||
@ -395,7 +395,7 @@ for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len;
|
||||
|
||||
Rx/Tx描述符 由以下结构定义,其中buf_lo和buf_hi分别是Tx/Rx缓冲区的低32位和高32位物理存储地址。 这些地址指向保存要发送/接收的数据包的缓冲区,并且必须在页面大小边界上对齐。 变量dw0对缓冲区的大小以及其他标志(例如所有权标志)进行编码,以表示缓冲区是由网卡还是由驱动程序拥有。
|
||||
|
||||
```
|
||||
```c
|
||||
struct rtl8139_desc {
|
||||
uint32_t dw0;
|
||||
uint32_t dw1;
|
||||
@ -406,7 +406,7 @@ struct rtl8139_desc {
|
||||
|
||||
网卡通过in*() out*()原语(来自sys/io.h)进行配置。 为此,我们需要具有CAP_SYS_RAWIO特权。 以下代码段配置了网卡并设置了一个Tx描述符。
|
||||
|
||||
```
|
||||
```c
|
||||
#define RTL8139_PORT 0xc000
|
||||
#define RTL8139_BUFFER_SIZE 1500
|
||||
|
||||
@ -442,14 +442,14 @@ outl(0x0, RTL8139_PORT + TxAddr0 + 0x4);
|
||||
phrack随附的源代码中提供了完整的利用(cve-2015-5165.c)。( uuencode用于将二进制文件编码为纯ASCII文本,以便可以通过电子邮件发送它们。)
|
||||
cve-2015-5165.c依赖qemu.h头文件中的函数偏移地址,因此首先需要通过[build-exploit.sh](https://github.com/jiayy/android_vuln_poc-exp/blob/master/EXP-2015-7504/build-exploit.sh)来进行计算。
|
||||
|
||||
```
|
||||
```shell
|
||||
./build-exploit.sh '/home/han/VMescape/qemu/bin/debug/native/x86_64-softmmu/qemu-system-x86_64'
|
||||
```
|
||||
|
||||
该漏洞利用程序在网卡上配置所需的寄存器,并设置Tx和Rx缓冲区描述符。 然后,它伪造了格式错误的IP数据包,该IP数据包的目的地址和源地址为网卡的MAC地址。 这使我们能够通过访问已配置的Rx缓冲区来读取泄漏的数据。
|
||||
通过对qemu运行程序下断点,可用看到漏洞触发的过程,由于ip_len小于伪造的hlen,导致最后tcp_data_len比实际的 tcp 数据大, 多余的内存区会被拷贝到包里发送出去(网卡需要配置为loopback 口)
|
||||
|
||||
```
|
||||
```shell
|
||||
(gdb) b rtl8139.c:2173
|
||||
Breakpoint 1 at 0x55a5ef757b03: file /home/han/VMescape/qemu/hw/net/rtl8139.c, line 2173.
|
||||
(gdb) c
|
||||
@ -493,7 +493,7 @@ at /home/han/VMescape/qemu/hw/net/rtl8139.c:2231
|
||||
|
||||
虚拟机内部的用户进程通过读取收包队列的数据包就可以知道被泄露的那块 qemu 内存区的内容。在分析泄漏的数据时,我们观察到存在多个函数指针。经过调试,发现这些函数指针都是struct ObjectProperty这个 qemu 内部结构体的数据。struct ObjectProperty 包含 11 个指针, 这里边有 4 个函数指针 **get/set/resolve/release**
|
||||
|
||||
```
|
||||
```c
|
||||
typedef struct ObjectProperty
|
||||
{
|
||||
gchar *name;
|
||||
@ -511,7 +511,7 @@ typedef struct ObjectProperty
|
||||
|
||||
QEMU遵循对象模型来管理设备,内存区域等。启动时,QEMU创建多个对象并为其分配属性。 例如,以下的函数将“may-overlap”属性添加给一个内存区域对象。 此属性具有getter方法,可以检索此boolean属性的值:
|
||||
|
||||
```
|
||||
```c
|
||||
object_property_add_bool(OBJECT(mr), "may-overlap",
|
||||
memory_region_get_may_overlap,
|
||||
NULL, /* memory_region_set_may_overlap */
|
||||
@ -545,18 +545,18 @@ RTL8139网卡设备仿真器在堆上保留了64 KB的空间以重组数据包
|
||||
|
||||
这样获取到的是 .plt.got 段,在我的环境里, mprotect 等系统函数符号没有在 .plt.got 这个段,而是在 .plt 这个段。因此替换如下:
|
||||
|
||||
```
|
||||
```shell
|
||||
#plt=$(readelf -S $binary | grep plt | tail -n 1 | awk '{print $2}')
|
||||
plt=.plt
|
||||
```
|
||||
|
||||
1. Phrack 文章提供的 Exploit 代码中搜索的地址是PHY_MEM + 0x78,但实际上并不固定为0x78,更通用的做法是统计泄露的数据中出现的 `uint64_t` 类型的数据 `0x00007FXXYYZZZZZZ` ,其中 `7FXXYY` 出现次数最多的数据,就是 QEMU 虚拟机物理内存的结束地址;修改之后成功获得物理地址
|
||||
|
||||
<img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1618050992/VMescape/image_31.png" width="50%" height="50%">
|
||||
<img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1618050992/VMescape/image_31.png">
|
||||
|
||||
通过 gdb 调试验证结果正确性:
|
||||
|
||||
<img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1618050992/VMescape/image_32.png" width="50%" height="50%">
|
||||
<img src="https://res.cloudinary.com/dozyfkbg3/image/upload/v1618050992/VMescape/image_32.png" >
|
||||
|
||||
## ref
|
||||
http://jiayy.me/2019/04/15/CVE-2015-5165-7504/
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: 关于我
|
||||
title: About Cool❄️, aka 混元霹雳手
|
||||
date: 2019-03-17 18:55:11
|
||||
type: "about"
|
||||
comments: false
|
||||
@ -16,7 +16,7 @@ comments: false
|
||||
- 💬 Ask me about ...
|
||||
|
||||
------
|
||||
## 论文
|
||||
## 🙊Papers
|
||||
### **智能家居攻击与防御方法综述**
|
||||
**信息安全学报** , Han Yan, Guojun Peng, Luo Yuan, Side Liu
|
||||
|
||||
@ -27,11 +27,11 @@ comments: false
|
||||
**ICSE'21**, Song, Wenna, Jiang Ming, Lin Jiang, Han Yan, Yi Xiang, Yuan Chen, Jianming Fu, and Guojun Peng.
|
||||
|
||||
-------
|
||||
## 学术服务
|
||||
## 🙈Academic service
|
||||
**Journal Sub Reviewer:** 信息安全学报,Cyber Security
|
||||
|
||||
-------
|
||||
## Vulnerabilities Disclosure
|
||||
## 🐒Vulnerabilities Disclosure
|
||||
- PSV-2018-0020(duplicate)
|
||||
- PSV-2019-0164
|
||||
- CVE-2019-15843
|
||||
|
@ -15,8 +15,8 @@ comments: true
|
||||
### Qingdao & Yantai
|
||||
| | |
|
||||
| ------ | ----------- |
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075784/life/4d315332aae693e6ddd7f46fb44e5eb.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075783/life/0b39705d40d1b3afa5983fad0656659.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075783/life/8d8a7ee74e6ee20f4b5e5d64b50bba1.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075783/life/d68aef840e0b27734e55514324c3aad.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075784/life/4d315332aae693e6ddd7f46fb44e5eb.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075783/life/8d8a7ee74e6ee20f4b5e5d64b50bba1.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075783/life/0b39705d40d1b3afa5983fad0656659.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075783/life/d68aef840e0b27734e55514324c3aad.jpg)|
|
||||
|
||||
### Hangzhou
|
||||
| | |
|
||||
@ -27,8 +27,8 @@ comments: true
|
||||
### Nanjing
|
||||
| | |
|
||||
| ------ | ----------- |
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076604/life/d4f61566a74c89128e8945c5fff6576.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076607/life/482f05f94499ab26f0402386d02acb7.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076607/life/482f05f94499ab26f0402386d02acb7.jpg)|![]()|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076607/life/482f05f94499ab26f0402386d02acb7.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076607/life/482f05f94499ab26f0402386d02acb7.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076604/life/d4f61566a74c89128e8945c5fff6576.jpg)|![]()|
|
||||
|
||||
### Shanghai
|
||||
| | |
|
||||
@ -39,21 +39,21 @@ comments: true
|
||||
### Quanzhou & Xiamen
|
||||
| | |
|
||||
| ------ | ----------- |
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077136/life/3d6b16a8e1c0d5151081c3403e3ccd5.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077126/life/8c0a20d89fac9efba2a5d9178825f28.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077118/life/59f3440e97133fa3aa0e85de0a90e90.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077111/life/c9bdcb566db1455ff73fc43c3b739f6.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077118/life/59f3440e97133fa3aa0e85de0a90e90.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077126/life/8c0a20d89fac9efba2a5d9178825f28.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077136/life/3d6b16a8e1c0d5151081c3403e3ccd5.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077111/life/c9bdcb566db1455ff73fc43c3b739f6.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077105/life/87a585bbc588baa4167a1805e92d928.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077099/life/d025c15c0b5e787bf8b3cb3cf834f53.jpg)|
|
||||
|
||||
### Haikou
|
||||
| | |
|
||||
| ------ | ----------- |
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077399/life/93b6111863fa916917fc8f13ad03512.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077392/life/2edd325305b8a9cfba0eae36eb99855.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077394/life/7065c06f743c629881d0b981d9ca1de.jpg)|![]()|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077399/life/93b6111863fa916917fc8f13ad03512.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077394/life/7065c06f743c629881d0b981d9ca1de.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077392/life/2edd325305b8a9cfba0eae36eb99855.jpg)|![]()|
|
||||
|
||||
### Qinghai
|
||||
| | |
|
||||
| ------ | ----------- |
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077771/life/d2f538547401446600ad278f659f278.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077774/life/21de36a564974001f43a126ac665a29.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077779/life/38c46862480582a77bb301c4aa374ab.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077784/life/6adf21f23d7eb1718e3e66ce59bbc90.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077771/life/d2f538547401446600ad278f659f278.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077784/life/6adf21f23d7eb1718e3e66ce59bbc90.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077779/life/38c46862480582a77bb301c4aa374ab.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077774/life/21de36a564974001f43a126ac665a29.jpg)|
|
||||
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618077790/life/5ecab6c5ef8d00d0bf98c6ee7a493bf.jpg)|![]()|
|
||||
|
||||
### Xian
|
@ -101,7 +101,7 @@ menu:
|
||||
#sitemap: /sitemap.xml || sitemap
|
||||
#commonweal: /404/ || heartbeat
|
||||
bookmarks: /bookmarks/ || map
|
||||
HACK之外: /hack之外/ || heartbeat
|
||||
album: /album/ || heartbeat
|
||||
|
||||
# Enable/Disable menu icons.
|
||||
menu_icons:
|
||||
@ -145,6 +145,7 @@ social:
|
||||
#YouTube: https://youtube.com/yourname || youtube
|
||||
Instagram: https://www.instagram.com/yan__han/ || instagram
|
||||
#Skype: skype:yourname?call|chat || skype
|
||||
RSS: /atom.xml || fas fa-rss
|
||||
|
||||
social_icons:
|
||||
enable: true
|
||||
@ -205,7 +206,7 @@ sidebar:
|
||||
scrollpercent: true
|
||||
|
||||
# Enable sidebar on narrow view (only for Muse | Mist).
|
||||
onmobile: false
|
||||
onmobile: true
|
||||
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
@ -266,7 +267,7 @@ post_copyright:
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
# Reduce padding / margin indents on devices with narrow width.
|
||||
mobile_layout_economy: false
|
||||
mobile_layout_economy: true
|
||||
|
||||
# Android Chrome header panel color ($black-deep).
|
||||
android_chrome_color: "#222"
|
||||
|
@ -17,6 +17,7 @@ menu:
|
||||
sitemap: 站点地图
|
||||
commonweal: 公益404
|
||||
bookmarks: 书签
|
||||
album: 相簿
|
||||
|
||||
sidebar:
|
||||
overview: 站点概览
|
||||
|
@ -228,11 +228,11 @@ $brand-color = white
|
||||
$brand-hover-color = white
|
||||
$brand-bg = $black-deep
|
||||
|
||||
$logo-font-size = 20px
|
||||
$logo-font-size = 25px
|
||||
$logo-font-size = unit(hexo-config('font.logo.size'), px) if hexo-config('font.logo.size') is a 'unit'
|
||||
|
||||
$site-subtitle-color = $grey-dark
|
||||
$subtitle-font-size = 13px
|
||||
$subtitle-font-size = 25px
|
||||
$subtitle-color = $grey-dark
|
||||
|
||||
// Menu
|
||||
|
Loading…
Reference in New Issue
Block a user