🚀 P02: Despliegue exitoso del sistema DASUTEN en pcv-dasu0

Infraestructura y Red:
- Tailscale v1.94.2 instalado en srv-dasu (IP: 100.116.210.36)
- Configurado como subnet router para 10.0.100.0/24
- Fix: Repositorios enterprise de Proxmox deshabilitados (.sources → .bak)

Despliegue del Sistema (pcv-dasu0):
- Transferencia SCP de runSysDasuten.zip via SSH puerto 7022
- Extracción en C:\Dasuten\runSysDasuten- Kermet.ini configurado: SERVER=sql-dasuten
- InstaladorComponentesKermet.exe (silent install)
- Fuentes TrueType registradas en Windows (Code39, I2OF5)
- Firewall TCP 1433 abierto en sql-dasuten
- Test-NetConnection: TcpTestSucceeded=True
- Login exitoso con usuario aalmiron 

ADN y Contexto:
- 05_ia.md: Regla 13 Auto-Contextualización Topológica
- 07_proyectos.md: Sección 'Topología y Red' obligatoria en manifiestos
- P2601_dasuten.md: Contexto de red documentado
- nodos/pcv-dasu0.md: Puerto SSH actualizado a 7022

Dashboard P2601:
- Hitos completados: 8 → 11 (P02.APP, NET01, TEST03)
- Progreso: 67% → 79%
- pcv-dasu0: Testing → Online
- Nuevo hito activo: UAT (verificación presencial)

Bitácoras y Documentación:
- Bitácora 04/03 y 05/03 completas
- Plan de despliegue en docs/plan/260305-1017
- Investigación de ingeniería inversa documentada
- ns8-candados: Instrucciones de uso para IA agregadas
- dtic-BITACORAs: CRUD completo, Dashboard P2601 integrado

Herramientas:
- w-zombi: Mejora anti-loop (max 5 ciclos)
- Payloads de despliegue SQL y sistema generados
This commit is contained in:
Ricardo Monla
2026-03-05 13:15:31 -03:00
parent 680dbe6f8d
commit 15725e0b3c
24826 changed files with 3499 additions and 3325954 deletions
+10
View File
@@ -2,6 +2,16 @@
# frozen_string_literal: true
# ns8-candados — Gestión unificada de secretos y autorización SSH
# ==============================================================================
# 🤖 INSTRUCCIONES PARA LA IA (AGENTES EXTERNOS):
# Esta herramienta permite obtener credenciales seguras sin exponerlas en el chat.
# PARA USARLA CORRECTAMENTE (SIN FILTRAR SECRETOS):
# Ejecuta el comando y asigna su salida a una variable silenciada:
# PASS=$(ruby tools/ns8-candados/ns8-candados.rb get nombre_clave)
# sshpass -p "$PASS" ssh usuario@servidor
# NUNCA ejecutes `ruby ns8-candados.rb get clave` directamente en run_command sin
# capturar o redirigir el output, porque el secreto se filtrará en la bitácora del LLM.
# ==============================================================================
# Uso: ruby tools/ns8-candados/ns8-candados.rb <comando> [args]
#
# Comandos:
+115
View File
@@ -0,0 +1,115 @@
$ErrorActionPreference = "Continue"
$ZOMBI_URL = "http://10.0.10.8:8000"
function Log($msg) {
$ts = Get-Date -Format "HH:mm:ss"
Write-Host "[$ts] $msg" -ForegroundColor Cyan
try { Invoke-RestMethod -Uri "$ZOMBI_URL/log" -Method Post -Body @{msg="[$env:COMPUTERNAME] $msg"} -UseBasicParsing -ErrorAction SilentlyContinue | Out-Null } catch {}
}
$DEST = "C:\SysDasuten"
$ZIP = "C:\TEMP\runSysDasuten.zip"
$SQL_SERVER = "sql-dasuten"
$SQL_DB = "sysdasuten"
Log "=========================================="
Log "DEPLOY SYSDASUTEN — $env:COMPUTERNAME"
Log "=========================================="
# --- PASO 1: Descargar ZIP ---
if (-not (Test-Path $DEST\Sistema\DasutenSQL.exe)) {
Log "PASO 1: Descargando runSysDasuten.zip (~268 MB)..."
New-Item -ItemType Directory -Path "C:\TEMP" -Force | Out-Null
try {
Invoke-WebRequest -Uri "$ZOMBI_URL/payloads/runSysDasuten.zip" -OutFile $ZIP -UseBasicParsing -ErrorAction Stop
Log "Descarga completada: $(((Get-Item $ZIP).Length / 1MB).ToString('N0')) MB"
} catch {
Log "ERROR descarga: $($_.Exception.Message)"
return
}
# --- PASO 2: Extraer ---
Log "PASO 2: Extrayendo a $DEST..."
New-Item -ItemType Directory -Path $DEST -Force | Out-Null
Expand-Archive -Path $ZIP -DestinationPath "C:\" -Force
# El zip contiene runSysDasuten/ como raiz, renombrar
if (Test-Path "C:\runSysDasuten") {
Copy-Item -Path "C:\runSysDasuten\*" -Destination $DEST -Recurse -Force
Remove-Item "C:\runSysDasuten" -Recurse -Force
}
Remove-Item $ZIP -Force -ErrorAction SilentlyContinue
Log "Extraido OK."
} else {
Log "PASO 1-2: SKIP — Ya existe $DEST\Sistema\DasutenSQL.exe"
}
# --- PASO 3: Modificar Kermet.ini ---
Log "PASO 3: Configurando Kermet.ini..."
$iniPaths = @("$DEST\Kermet.ini", "$DEST\Sistema\Kermet.ini")
foreach ($ini in $iniPaths) {
if (Test-Path $ini) {
$content = Get-Content $ini -Raw
$content = $content -replace 'SERVER=srvFENIX', "SERVER=$SQL_SERVER"
$content = $content -replace 'SERVER=172\.16\.9\.204\\SQL2017', "SERVER=$SQL_SERVER"
Set-Content $ini $content -Force
Log "Actualizado: $ini -> SERVER=$SQL_SERVER"
}
}
# --- PASO 4: Instalar Fuentes ---
Log "PASO 4: Instalando fuentes..."
$fontDir = "$DEST\Fonts\Fonts"
if (Test-Path $fontDir) {
$shell = New-Object -ComObject Shell.Application
$fontsFolder = $shell.NameSpace(0x14) # Windows Fonts folder
Get-ChildItem "$fontDir\*.ttf" | ForEach-Object {
$fontPath = $_.FullName
$fontName = $_.Name
if (-not (Test-Path "C:\Windows\Fonts\$fontName")) {
Copy-Item $fontPath "C:\Windows\Fonts\" -Force
$regKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
New-ItemProperty -Path $regKey -Name $fontName -Value $fontName -PropertyType String -Force | Out-Null
Log "Fuente instalada: $fontName"
} else {
Log "Fuente ya existe: $fontName"
}
}
} else {
Log "WARN: No se encontro directorio de fuentes"
}
# --- PASO 5: Verificar firewall SQL en sql-dasuten ---
Log "PASO 5: Probando conectividad SQL..."
$tcpTest = Test-NetConnection -ComputerName $SQL_SERVER -Port 1433 -WarningAction SilentlyContinue
if ($tcpTest.TcpTestSucceeded) {
Log "Conexion TCP a ${SQL_SERVER}:1433 OK"
} else {
Log "WARN: No se puede conectar a ${SQL_SERVER}:1433 — verificar firewall"
}
# --- PASO 6: Probar conexion SQL con sqlcmd (si existe) ---
$sqlcmd = Get-Command sqlcmd -ErrorAction SilentlyContinue
if ($sqlcmd) {
Log "PASO 6: Probando SQL con sqlcmd..."
$result = sqlcmd -S $SQL_SERVER -E -Q "SELECT DB_NAME() AS db_actual; SELECT name FROM sys.databases WHERE name = '$SQL_DB'" -W 2>&1
Log "SQL Result: $result"
} else {
Log "PASO 6: SKIP — sqlcmd no disponible (normal en Win10), probar con DasutenSQL.exe"
}
# --- PASO 7: Crear acceso directo ---
Log "PASO 7: Creando acceso directo en Escritorio..."
$desktopPath = [Environment]::GetFolderPath('CommonDesktopDirectory')
$shortcutPath = "$desktopPath\DasutenSQL.lnk"
$WshShell = New-Object -ComObject WScript.Shell
$shortcut = $WshShell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = "$DEST\Sistema\DasutenSQL.exe"
$shortcut.WorkingDirectory = "$DEST\Sistema"
$shortcut.Description = "Sistema DASUTEN"
$shortcut.Save()
Log "Acceso directo creado: $shortcutPath"
Log "=========================================="
Log "DEPLOY SYSDASUTEN COMPLETADO"
Log "Ejecutar desde: $DEST\Sistema\DasutenSQL.exe"
Log "=========================================="
@@ -0,0 +1,115 @@
$ErrorActionPreference = "Continue"
$ZOMBI_URL = "http://10.0.10.8:8000"
function Log($msg) {
$ts = Get-Date -Format "HH:mm:ss"
Write-Host "[$ts] $msg" -ForegroundColor Cyan
try { Invoke-RestMethod -Uri "$ZOMBI_URL/log" -Method Post -Body @{msg="[$env:COMPUTERNAME] $msg"} -UseBasicParsing -ErrorAction SilentlyContinue | Out-Null } catch {}
}
$DEST = "C:\SysDasuten"
$ZIP = "C:\TEMP\runSysDasuten.zip"
$SQL_SERVER = "sql-dasuten"
$SQL_DB = "sysdasuten"
Log "=========================================="
Log "DEPLOY SYSDASUTEN — $env:COMPUTERNAME"
Log "=========================================="
# --- PASO 1: Descargar ZIP ---
if (-not (Test-Path $DEST\Sistema\DasutenSQL.exe)) {
Log "PASO 1: Descargando runSysDasuten.zip (~268 MB)..."
New-Item -ItemType Directory -Path "C:\TEMP" -Force | Out-Null
try {
Invoke-WebRequest -Uri "$ZOMBI_URL/payloads/runSysDasuten.zip" -OutFile $ZIP -UseBasicParsing -ErrorAction Stop
Log "Descarga completada: $(((Get-Item $ZIP).Length / 1MB).ToString('N0')) MB"
} catch {
Log "ERROR descarga: $($_.Exception.Message)"
return
}
# --- PASO 2: Extraer ---
Log "PASO 2: Extrayendo a $DEST..."
New-Item -ItemType Directory -Path $DEST -Force | Out-Null
Expand-Archive -Path $ZIP -DestinationPath "C:\" -Force
# El zip contiene runSysDasuten/ como raiz, renombrar
if (Test-Path "C:\runSysDasuten") {
Copy-Item -Path "C:\runSysDasuten\*" -Destination $DEST -Recurse -Force
Remove-Item "C:\runSysDasuten" -Recurse -Force
}
Remove-Item $ZIP -Force -ErrorAction SilentlyContinue
Log "Extraido OK."
} else {
Log "PASO 1-2: SKIP — Ya existe $DEST\Sistema\DasutenSQL.exe"
}
# --- PASO 3: Modificar Kermet.ini ---
Log "PASO 3: Configurando Kermet.ini..."
$iniPaths = @("$DEST\Kermet.ini", "$DEST\Sistema\Kermet.ini")
foreach ($ini in $iniPaths) {
if (Test-Path $ini) {
$content = Get-Content $ini -Raw
$content = $content -replace 'SERVER=srvFENIX', "SERVER=$SQL_SERVER"
$content = $content -replace 'SERVER=172\.16\.9\.204\\SQL2017', "SERVER=$SQL_SERVER"
Set-Content $ini $content -Force
Log "Actualizado: $ini -> SERVER=$SQL_SERVER"
}
}
# --- PASO 4: Instalar Fuentes ---
Log "PASO 4: Instalando fuentes..."
$fontDir = "$DEST\Fonts\Fonts"
if (Test-Path $fontDir) {
$shell = New-Object -ComObject Shell.Application
$fontsFolder = $shell.NameSpace(0x14) # Windows Fonts folder
Get-ChildItem "$fontDir\*.ttf" | ForEach-Object {
$fontPath = $_.FullName
$fontName = $_.Name
if (-not (Test-Path "C:\Windows\Fonts\$fontName")) {
Copy-Item $fontPath "C:\Windows\Fonts\" -Force
$regKey = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts"
New-ItemProperty -Path $regKey -Name $fontName -Value $fontName -PropertyType String -Force | Out-Null
Log "Fuente instalada: $fontName"
} else {
Log "Fuente ya existe: $fontName"
}
}
} else {
Log "WARN: No se encontro directorio de fuentes"
}
# --- PASO 5: Verificar firewall SQL en sql-dasuten ---
Log "PASO 5: Probando conectividad SQL..."
$tcpTest = Test-NetConnection -ComputerName $SQL_SERVER -Port 1433 -WarningAction SilentlyContinue
if ($tcpTest.TcpTestSucceeded) {
Log "Conexion TCP a ${SQL_SERVER}:1433 OK"
} else {
Log "WARN: No se puede conectar a ${SQL_SERVER}:1433 — verificar firewall"
}
# --- PASO 6: Probar conexion SQL con sqlcmd (si existe) ---
$sqlcmd = Get-Command sqlcmd -ErrorAction SilentlyContinue
if ($sqlcmd) {
Log "PASO 6: Probando SQL con sqlcmd..."
$result = sqlcmd -S $SQL_SERVER -E -Q "SELECT DB_NAME() AS db_actual; SELECT name FROM sys.databases WHERE name = '$SQL_DB'" -W 2>&1
Log "SQL Result: $result"
} else {
Log "PASO 6: SKIP — sqlcmd no disponible (normal en Win10), probar con DasutenSQL.exe"
}
# --- PASO 7: Crear acceso directo ---
Log "PASO 7: Creando acceso directo en Escritorio..."
$desktopPath = [Environment]::GetFolderPath('CommonDesktopDirectory')
$shortcutPath = "$desktopPath\DasutenSQL.lnk"
$WshShell = New-Object -ComObject WScript.Shell
$shortcut = $WshShell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = "$DEST\Sistema\DasutenSQL.exe"
$shortcut.WorkingDirectory = "$DEST\Sistema"
$shortcut.Description = "Sistema DASUTEN"
$shortcut.Save()
Log "Acceso directo creado: $shortcutPath"
Log "=========================================="
Log "DEPLOY SYSDASUTEN COMPLETADO"
Log "Ejecutar desde: $DEST\Sistema\DasutenSQL.exe"
Log "=========================================="
@@ -0,0 +1,42 @@
$ErrorActionPreference = "Continue"
function Log($msg) {
$ts = Get-Date -Format "HH:mm:ss"
Write-Host "[$ts] $msg" -ForegroundColor Cyan
try { Invoke-RestMethod -Uri "http://10.0.10.8:8000/log" -Method Post -Body @{msg="[$env:COMPUTERNAME] $msg"} -UseBasicParsing -ErrorAction SilentlyContinue | Out-Null } catch {}
}
Log "=========================================="
Log "SQL SYSADMIN FIX — Agregando DASUTEN\admindasu"
Log "=========================================="
# Paso 1: Parar SQL Server
Log "PASO 1: Deteniendo MSSQLSERVER..."
net stop MSSQLSERVER /y 2>&1 | Out-Null
Start-Sleep -Seconds 3
# Paso 2: Iniciar en modo single-user
Log "PASO 2: Iniciando en modo single-user..."
net start MSSQLSERVER /m 2>&1 | Out-Null
Start-Sleep -Seconds 5
# Paso 3: Agregar sysadmin
Log "PASO 3: Agregando DASUTEN\admindasu como sysadmin..."
$result = sqlcmd -S localhost -E -Q "ALTER SERVER ROLE sysadmin ADD MEMBER [DASUTEN\admindasu]; SELECT 'SYSADMIN_OK' AS resultado;" -W 2>&1
Log "Resultado: $result"
# Paso 4: Reiniciar normal
Log "PASO 4: Reiniciando SQL Server en modo normal..."
net stop MSSQLSERVER /y 2>&1 | Out-Null
Start-Sleep -Seconds 3
net start MSSQLSERVER 2>&1 | Out-Null
Start-Sleep -Seconds 5
# Paso 5: Verificar
Log "PASO 5: Verificando acceso..."
$check = sqlcmd -S localhost -E -Q "SELECT SYSTEM_USER AS usuario, IS_SRVROLEMEMBER('sysadmin') AS es_sysadmin" -W 2>&1
Log "Verificacion: $check"
Log "=========================================="
Log "SQL SYSADMIN FIX COMPLETADO"
Log "=========================================="
+25 -13
View File
@@ -74,10 +74,13 @@ server.mount_proc '/zombi.ps1' do |_req, res|
Write-Host "======================================================" -ForegroundColor Green
Write-Host " ZOMBI C2 LOOP — Conectado a srv-ns8:#{PORT} " -ForegroundColor Green
Write-Host "======================================================" -ForegroundColor Green
Write-Host "CTRL+C para detener." -ForegroundColor DarkGray
Write-Host "Max 5 ciclos. CTRL+C para detener." -ForegroundColor DarkGray
Write-Host ""
while ($true) {
$maxCiclos = 5
for ($ciclo = 1; $ciclo -le $maxCiclos; $ciclo++) {
Write-Host "[ZOMBI] Ciclo $ciclo/$maxCiclos" -ForegroundColor DarkGray
try {
$payload = Invoke-RestMethod -Uri "http://10.0.10.8:#{PORT}/payloads/activo.ps1" -UseBasicParsing -ErrorAction Stop
if ($payload -and $payload.Trim() -ne "") {
@@ -86,21 +89,30 @@ server.mount_proc '/zombi.ps1' do |_req, res|
} catch {
Write-Host ">>> ERROR EN PAYLOAD <<<" -ForegroundColor Red
Write-Host $_.Exception.Message -ForegroundColor Red
Start-Sleep -Seconds 10
}
}
} catch {}
for ($i = 10; $i -gt 0; $i--) {
Write-Host -NoNewline "`r[ZOMBI] Esperando payload... $i seg "
if ([console]::KeyAvailable) {
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
break
}
Start-Sleep -Seconds 1
} catch {
Write-Host "[ZOMBI] Sin conexion al servidor." -ForegroundColor Red
}
if ($ciclo -lt $maxCiclos) {
for ($i = 10; $i -gt 0; $i--) {
Write-Host -NoNewline "`r[ZOMBI] Siguiente ciclo en $i seg "
if ([console]::KeyAvailable) {
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Write-Host "`n[ZOMBI] Detenido por usuario." -ForegroundColor Yellow
return
}
Start-Sleep -Seconds 1
}
Write-Host -NoNewline "`r `r"
}
Write-Host -NoNewline "`r `r"
}
Write-Host ""
Write-Host "======================================================" -ForegroundColor Yellow
Write-Host " ZOMBI: $maxCiclos ciclos completados. Auto-detenido." -ForegroundColor Yellow
Write-Host "======================================================" -ForegroundColor Yellow
PS1
res['Content-Type'] = 'text/plain'
res.body = loader