-
-
Save skmedix/6cdce9d6d3b464c1bd719b72d1f6bce4 to your computer and use it in GitHub Desktop.
The reporting address shown above for Skyhigh (virus_research_gateway@avertlabs.com) seems non-functional.
(For weeks it reported "disk full"; now it bounces with new detail provided.).
Also non-functional: GatewayAnti-Malware-SupportEscalations@SkyhighSecurity.com
Is anyone aware of an alternative address or channel for false-positive reports for this vendor?
The reporting address shown above for Skyhigh (virus_research_gateway@avertlabs.com) seems non-functional. (For weeks it reported "disk full"; now it bounces with new detail provided.). Also non-functional: GatewayAnti-Malware-SupportEscalations@SkyhighSecurity.com
Is anyone aware of an alternative address or channel for false-positive reports for this vendor?
@mblumberg Try gatewayantimalwarefpsubmission@skyhighsecurity.com, looks like it's working
High regards,
Does anyone have report email/methods for Check Point? Thanks.
Have you guys gotten a reply from ADMINUSLabs? Bastards don't have contact/report form and just email address for reports and nothing, not even auto-reply enabled.
@rrecinos sorry to hear that , i am also waiting for them to ack / respond back to the email. Wondering if you have found any other way to report False Positive on ADMINUSLabs ? can you share if you know
The reporting address shown above for Skyhigh (virus_research_gateway@avertlabs.com) seems non-functional. (For weeks it reported "disk full"; now it bounces with new detail provided.). Also non-functional: GatewayAnti-Malware-SupportEscalations@SkyhighSecurity.com
Is anyone aware of an alternative address or channel for false-positive reports for this vendor?@mblumberg Try gatewayantimalwarefpsubmission@skyhighsecurity.com, looks like it's working
@skmedix , or anyone else --
To this day I've yet to get a reply from Skyhigh on a persistent false-positive; have tried all three emails above (two from the list, and one suggested in this discussion).
Does anyone have current/active contact info for SkyHigh, or other relevant advice?
@GRMatt Unfortunately, I wasn't able to contact SkyHigh either; their inbox is rejecting everything. It looks like they're sharing a ticketing system with Trellix now though, so I would try contacting Trellix via email instead.
@rrecinos @ksingh-scogo
Have either of you managed to get into contact with ADMINUSLabs?
I have tried their form, and all contact emails and have received no correspondence.
I'm also trying to get into contact with SCUMWARE but every one of their forms are completely broken and there's no contact email.
ADMINUSLabs Team Dead!!! I tried to reach their support team via email, but haven't received any response from them. Is anyone able to contact them? I think we should report to virustotal team to exclude that security vendors.
Thank you for this. Still not able to reach Adimus either..
Same here - ADMINUSLabs is not responding.
What I tried:
- Wrote to ADMINUSLabs false/positive email
- Wrote to all other ADMINUSLabs email addresses
- Wrote to ADMINUSLabs on LinkedIn
- I asked VirusTotal for help - got none
- I asked SSLTrust for help - they added my service to a blacklist, which even looked more suspicious. Changed that back.
I don't understand how someone would include such a suspicious service in their offering (@VirusTotal @ssltrust)?
Btw. click on the "Submit CV" on the Contact page (https://www.adminuslabs.net/contact) and you'll see - what a professional company that is ;-)
I haven't tried to call them yet...
cyberfoxbd
Same here, tried several times, hey detect a false positive, contacted on their 3 email adresses but still no answer 3 weeks after.
Adminus is a shame honnestly
Hi,
I have tried each and every single email for WEEKS now and they do not respond - not even a courtesy reply. I have my business on pause, because they decided it was ok to conveniently flag my website as malicious even when this flag is a False Positive.
I reached VirusTotal for help, because this company ADMINUSlabs is affecting companies everywhere with their false positives and so far I have not gotten any response.
Other forums, say exactly the same about ADMINUSlabs, so I'm just curious of this is a real company or a business just created to damage companies online.
If someone gets a response or a solution to this, please post it here.
If not, I may need to start my business and websites from scratch due to this absurd company.
Incredible, over a month for me ... if a company can flag you they should be able to answer too.
Yup, having the same issue as many of you have with ADMINUSLabs. Almost a year now with no reply and going strong! lol and that's how I found this thread, out of sheer desperation.
Adding my voice to the chorus. We have sent multiple messages and contact form submissions to ADMINUSLabs with no response whatsoever. We've also sent messages to VirusTotal and received the same lack of response.
CyRadar: https://cyradar.com/reportfp/
Hi friends, I submitted some reports to AdminUsLabs. I haven't received a response, but they removed one of my domains and it stopped appearing on VirusTotal.
However, Avast / AVG / Avira / Norton are still reporting me =/
I looked into this after they started reporting it to me. And so far, nothing.
The problem is that my SaaS has subdomains per tenant, and this is impacting all of our tenants.
Example:
- https://tenant-name-01.tenants.my.domain
- https://tenant-name-02.tenants.my.domain
- https://tenant-name-03.tenants.my.domain
Does anyone know a quick way to solve this?
# JERI.PY
import math, uuid
import numpy as np
import faiss
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.cuda.amp import autocast, GradScaler
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
def rand_quaternion(batch=1, device=device, dtype=torch.float32):
"""Retorna quaternions normalizados (batch,4) no device e dtype especificados."""
u1 = torch.rand(batch, device=device, dtype=dtype)
u2 = torch.rand(batch, device=device, dtype=dtype)
u3 = torch.rand(batch, device=device, dtype=dtype)
q = torch.stack([
torch.sqrt(1 - u1) * torch.sin(2 * math.pi * u2),
torch.sqrt(1 - u1) * torch.cos(2 * math.pi * u2),
torch.sqrt(u1) * torch.sin(2 * math.pi * u3),
torch.sqrt(u1) * torch.cos(2 * math.pi * u3),
], dim=-1)
return F.normalize(q, dim=-1)
def quat_slerp(q1, q2, t):
"""
SLERP robusto entre quaternions.
- q1, q2: tensors (...,4), assumidos normalizados
- t: tensor (...) escalar ou com mesma shape de prefixo
Corrige sinal quando dot < 0 para caminho mais curto e faz fallback linear quando sin(theta) ~ 0.
"""
# assegura shapes compatíveis
orig_shape = q1.shape
dot = (q1 * q2).sum(-1, keepdim=True)
# flip para menor arco quando necessário
q2 = torch.where(dot < 0, -q2, q2)
dot = (q1 * q2).sum(-1, keepdim=True).clamp(-1 + 1e-6, 1 - 1e-6)
theta = torch.acos(dot)
sinth = torch.sin(theta)
t_shaped = t.unsqueeze(-1) if t.dim() == dot.dim() - 1 else t
small = sinth.abs() < 1e-4
s1 = torch.where(small, 1.0 - t_shaped, torch.sin((1.0 - t_shaped) * theta) / (sinth + 1e-12))
s2 = torch.where(small, t_shaped, torch.sin(t_shaped * theta) / (sinth + 1e-12))
out = s1 * q1 + s2 * q2
return F.normalize(out, dim=-1)
class NodeTable(nn.Module):
"""
Tabela de nós guardando CPs, centros, quat deltas e metadados.
Buffers: active_mask, eligibility, responsibility, layer_id (ints).
"""
def __init__(self, N_nodes, k_control, d_in):
super().__init__()
self.N_nodes = int(N_nodes)
self.k = int(k_control)
self.d = int(d_in)
# parâmetros treináveis
self.C = nn.Parameter(torch.randn(self.N_nodes, self.k, self.d, dtype=torch.float32) * 0.05)
self.centers = nn.Parameter(torch.randn(self.N_nodes, self.d, dtype=torch.float32) * 0.05)
self.delta_q = nn.Parameter(torch.zeros(self.N_nodes, 4, dtype=torch.float32))
self.scale = nn.Parameter(torch.ones(self.N_nodes, 1, dtype=torch.float32))
self.bias = nn.Parameter(torch.zeros(self.N_nodes, 1, dtype=torch.float32))
# metadados persistentes como buffers (no CPU/GPU conforme .to())
self.register_buffer('active_mask', torch.ones(self.N_nodes, dtype=torch.bool))
self.register_buffer('eligibility', torch.zeros(self.N_nodes, dtype=torch.float32))
self.register_buffer('responsibility', torch.zeros(self.N_nodes, dtype=torch.float32))
# identificador de layer por nó (int32)
self.register_buffer('layer_id', torch.zeros(self.N_nodes, dtype=torch.int32))
def eval_bspline_placeholder(C_nodes, x_local):
"""
Avalia ativação placeholder:
C_nodes: [M, k, d] (k centroids por nó) -> reduz para centro médio
x_local: [B, d] (pontos locais)
Retorna: [B, M] ativações
"""
cp_centers = C_nodes.mean(dim=1) # [M,d]
dists = torch.cdist(x_local, cp_centers) # [B, M]
act = torch.exp(- (dists ** 2) / (2 * (0.5 ** 2)))
return act
class SparseRouter:
"""
Gerencia índice FAISS (GPU) para consulta de K vizinhos por centro.
"""
def __init__(self, node_table: NodeTable, faiss_gpu_id=0):
self.nodes = node_table
self.faiss_index = None
self.faiss_res = None
self.gpu_id = int(faiss_gpu_id)
def build_index(self):
"""Constroi/atualiza índice FAISS com os centros atuais (copia para FAISS)."""
centers = self.nodes.centers.detach().cpu().numpy().astype('float32')
d = centers.shape[1]
# Recursos GPU padrão
self.faiss_res = faiss.StandardGpuResources()
idx = faiss.IndexFlatL2(d)
# mover índice para GPU escolhida
self.faiss_index = faiss.index_cpu_to_gpu(self.faiss_res, self.gpu_id, idx)
self.faiss_index.add(centers)
def query(self, x_batch, K=32):
"""
Consulta K vizinhos para x_batch: x_batch tensor [B,d] (pode estar em GPU).
Retorna indices tensor [B,K] no mesmo device do 'device' global.
"""
xb = x_batch.detach().cpu().numpy().astype('float32')
D, I = self.faiss_index.search(xb, K)
return torch.from_numpy(I).long().to(device) # [B,K]
class MetaController(nn.Module):
"""
Controlador de fase/frequência por layer.
Mantém buffers registrados para mover com .to(device) e parâmetros numpy para EMAs leves.
"""
def __init__(self, n_layers, token_budget=64, token_period=100):
super().__init__()
self.n_layers = int(n_layers)
# registramos fases e frequências como buffers (para mover com device)
self.register_buffer('phases', torch.zeros(self.n_layers, dtype=torch.float32))
self.register_buffer('freqs', torch.ones(self.n_layers, dtype=torch.float32) * 8.0)
# EMAs mantidas em numpy (pequenas, persistência fora do grafo)
self.A = np.zeros(self.n_layers, dtype='float32') # alinhamento de fase(placeholder)
self.D = np.zeros(self.n_layers, dtype='float32') # demanda
self.N = np.zeros(self.n_layers, dtype='float32') # novidade/erro
# tokens
self.global_tokens = int(token_budget)
self.token_budget = int(token_budget)
self.token_period = int(token_period)
self.step_count = 0
# pesos fixos de spawn [A,D,N]
self.w = np.array([1.0, 1.0, 1.0], dtype='float32')
def step_phase(self, dt=1/256.0):
"""Avança fase por dt (em segundos). Fases mantêm-se em [0,1)."""
self.phases = (self.phases + self.freqs * float(dt)) % 1.0
def aggregate_layer_stats(self, layer_id_array, node_responsibility_cpu, node_errors_cpu):
"""
Agrega estatísticas por layer a partir de arrays numpy por nó.
layer_id_array: numpy int array shape (N_nodes,)
node_responsibility_cpu, node_errors_cpu: numpy arrays shape (N_nodes,)
"""
for l in range(self.n_layers):
idxs = np.where(layer_id_array == l)[0]
if len(idxs) == 0:
continue
self.D[l] = 0.9 * self.D[l] + 0.1 * node_responsibility_cpu[idxs].sum()
self.N[l] = 0.9 * self.N[l] + 0.1 * node_errors_cpu[idxs].mean()
def compute_spawn_tokens(self):
"""
Computa alocação inteira de tokens por layer com base nas EMAs A,D,N.
Retorna array int de tamanho n_layers.
"""
spawn_rates = np.zeros(self.n_layers, dtype='float32')
for l in range(self.n_layers):
A_l, D_l, N_l = float(self.A[l]), float(self.D[l]), float(self.N[l])
score = self.w[0] * A_l + self.w[1] * D_l + self.w[2] * N_l
rate = 1.0 / (1.0 + math.exp(-score))
spawn_rates[l] = rate
if self.global_tokens <= 0:
return np.zeros(self.n_layers, dtype=int)
raw = spawn_rates / (spawn_rates.sum() + 1e-6)
alloc = np.floor(raw * self.global_tokens).astype(int)
if alloc.sum() == 0 and self.global_tokens > 0:
top = spawn_rates.argsort()[::-1][:min(self.global_tokens, self.n_layers)]
for t in top:
alloc[t] += 1
self.global_tokens -= alloc.sum()
return alloc
def refill_if_needed(self):
"""Refil de tokens periódico."""
self.step_count += 1
if self.step_count % self.token_period == 0:
self.global_tokens = self.token_budget
class AgentStore:
def __init__(self):
self.store = {}
def save(self, agent_dict):
self.store[agent_dict['id']] = agent_dict
class SplineNet(nn.Module):
"""
Rede que agrega K vizinhos usando features locais e um embedding pequeno de nó,
evitando construir a matriz B x N completa.
- node_table: NodeTable
- meta: MetaController
- topk: número de vizinhos retornados pelo router
- out_dim: dimensão de saída
"""
def __init__(self, node_table: NodeTable, meta: MetaController, topk=32, out_dim=10, node_emb_dim=16):
super().__init__()
self.nodes = node_table
self.meta = meta
self.topk = int(topk)
self.out_dim = int(out_dim)
self.node_emb_dim = int(node_emb_dim)
# um embedding pequeno por nó (para leitura eficiente)
self.node_emb = nn.Parameter(torch.randn(self.nodes.N_nodes, self.node_emb_dim) * 0.01)
# pequena MLP de leitura que consome pooling local e produz saída
self.readout = nn.Sequential(
nn.Linear(self.node_emb_dim, 64),
nn.ReLU(),
nn.Linear(64, self.out_dim)
)
# peso para combinar matching de fase por layer (learnable)
self.phase_match_w = nn.Parameter(torch.ones(meta.n_layers, dtype=torch.float32))
def forward(self, x, neighbor_idx):
"""
- x: [B,d]
- neighbor_idx: [B,K] indices inteiros de nós
Retorna:
out [B, out_dim],
node_out_local [B,K] (ativação/score por vizinho),
idx_flat [B*K] índice plano dos vizinhos (para acumulação de responsabilidade)
"""
B, K = neighbor_idx.shape
# gather parâmetros dos nós vizinhos
C = self.nodes.C # [N, k, d]
# seleciona por índice plano
idx_flat = neighbor_idx.view(-1) # [B*K]
# gathered C e centers para os vizinhos
gathered_C = C.index_select(0, idx_flat).view(B, K, C.shape[1], C.shape[2]) # [B,K,k,d]
centers = self.nodes.centers.index_select(0, idx_flat).view(B, K, -1) # [B,K,d]
x_local = x.unsqueeze(1) - centers # [B,K,d]
# avalia ativação placeholder por vizinho
C_flat = gathered_C.view(B * K, gathered_C.shape[2], gathered_C.shape[3]) # [B*K, k, d]
xflat = x_local.view(B * K, x_local.shape[-1]) # [B*K, d]
acts_flat = eval_bspline_placeholder(C_flat, xflat) # [B*K, M?] -> nosso placeholder retorna [B*K, M_nodes_flat]
# para placeholder, reduzimos por média (sendo coerente com a implementação previa)
if acts_flat.ndim > 1:
acts = acts_flat.mean(dim=1)
else:
acts = acts_flat
acts = acts.view(B, K) # [B,K]
scale = self.nodes.scale.squeeze(-1).index_select(0, idx_flat).view(B, K)
bias = self.nodes.bias.squeeze(-1).index_select(0, idx_flat).view(B, K)
node_out = acts * scale + bias # [B,K] -> "responsibility" local por vizinho
# agora obtemos embeddings dos nós vizinhos e agregamos por soma ponderada
node_embs = self.node_emb.index_select(0, idx_flat).view(B, K, self.node_emb_dim) # [B,K,emb_dim]
weights = F.softmax(node_out, dim=1).unsqueeze(-1) # normaliza por K para estabilidade
pooled = (weights * node_embs).sum(dim=1) # [B, emb_dim]
# possibilidade de ajustar por fase (meta): multiplicador escalar por layer médio
# computa layer ids dos vizinhos (puxa do buffer layer_id)
layer_ids = self.nodes.layer_id.index_select(0, idx_flat).view(B, K) # [B,K]
# média ponderada das phase_match_w por vizinho (convertendo para float tensor)
phase_w_per_idx = self.phase_match_w[layer_ids] # [B,K]
phase_factor = (weights.squeeze(-1) * phase_w_per_idx).sum(dim=1, keepdim=True) # [B,1]
pooled = pooled * (1.0 + phase_factor) # escala leve
out = self.readout(pooled) # [B, out_dim]
return out, node_out, idx_flat
# # Lógica de arbitragem e spawn(igual mas com correções de device/dtype)
def arbitration_and_spawn(node_table: NodeTable, meta: MetaController, agent_store: AgentStore,
resp_accum_cpu, err_accum_cpu, max_spawn_per_layer=8):
"""
resp_accum_cpu, err_accum_cpu: numpy arrays (N_nodes,) em CPU dtype float32
Retorna lista de agentes spawnados (arquivados em agent_store).
"""
layer_map = node_table.layer_id.detach().cpu().numpy()
meta.aggregate_layer_stats(layer_map, resp_accum_cpu, err_accum_cpu)
alloc = meta.compute_spawn_tokens()
spawned = []
for l, tokens in enumerate(alloc):
if tokens <= 0:
continue
idxs = np.where(layer_map == l)[0]
if len(idxs) == 0:
continue
scores = resp_accum_cpu[idxs] * 0.6 + err_accum_cpu[idxs] * 0.4
order = np.argsort(scores)[::-1]
chosen = idxs[order[:min(len(order), tokens, max_spawn_per_layer)]]
for p in chosen:
# prepara quaternions: pega parent, gera perturbação no mesmo device e dtype
q_parent = node_table.delta_q[p].detach().to(device) # tensor [4] no device
q_pert = rand_quaternion(1, device=device) # [1,4]
q_child = quat_slerp(q_parent.unsqueeze(0), q_pert, torch.tensor(0.2, device=device))
agent = {
"id": str(uuid.uuid4()),
"parent": int(p),
"layer": int(l),
"phase": float(meta.phases[l].item()),
"freq": float(meta.freqs[l].item()),
"rot_q": q_child.squeeze(0).detach().cpu().numpy().tolist(),
"priority": float(scores[order[0]] if order.size > 0 else 0.5)
}
agent_store.save(agent)
spawned.append(agent)
# Em produção: escrever parâmetros do novo nó em um slot prealocado na GPU, ativar mask e inicializar eligibility
meta.refill_if_needed()
return spawned
def train_loop(model: SplineNet, router: SparseRouter, agent_store: AgentStore, optimizer, scaler, data_loader, meta: MetaController, K=32):
model.train()
N = model.nodes.N_nodes
resp_accum = np.zeros(N, dtype='float32')
err_accum = np.zeros(N, dtype='float32')
for step, (x_batch, y_batch) in enumerate(data_loader):
x = x_batch.to(device); y = y_batch.to(device)
neighbor_idx = router.query(x, K=K) # [B,K]
optimizer.zero_grad()
with autocast():
y_pred, node_out, idx_flat = model(x, neighbor_idx)
loss = F.mse_loss(y_pred, y)
# regularizador leve sobre CPs
loss = loss + 1e-4 * (model.nodes.C.float().pow(2).sum())
scaler.scale(loss).backward()
scaler.step(optimizer); scaler.update()
# acumulação de responsabilidades por nó (CPU)
B = node_out.shape[0]
flat_idx = idx_flat.detach().cpu().numpy() # length B*K
flat_vals = node_out.view(-1).detach().cpu().numpy()
np.add.at(resp_accum, flat_idx, np.abs(flat_vals))
# erro por amostra
batch_error = (y_pred - y).detach().cpu().numpy() # [B, out_dim]
sample_err = np.linalg.norm(batch_error, axis=1) # [B]
node_weights = np.abs(node_out.detach().cpu().numpy()) # [B,K]
norm = node_weights.sum(axis=1, keepdims=True) + 1e-9
contrib = (node_weights / norm) * sample_err[:, None] # [B,K]
for b in range(B):
idxs = neighbor_idx[b].cpu().numpy()
err_accum[idxs] += contrib[b]
# periódica: arbitragem spawn / prune
if step % 32 == 0 and step > 0:
spawned = arbitration_and_spawn(model.nodes, meta, agent_store, resp_accum, err_accum)
# decaimento dos acumuladores
resp_accum *= 0.1
err_accum *= 0.1
return
# # Exemplo de montagem/execução
if __name__ == "__main__":
N = 8192; k = 8; d = 32; n_layers = 8
node_table = NodeTable(N, k, d).to(device)
# atribui nós às layers uniformemente
layer_ids = torch.arange(N, dtype=torch.int32) // (N // n_layers)
node_table.layer_id.copy_(layer_ids.to(node_table.layer_id.device))
router = SparseRouter(node_table, faiss_gpu_id=0); router.build_index()
meta = MetaController(n_layers=n_layers, token_budget=64, token_period=200).to(device)
agent_store = AgentStore()
model = SplineNet(node_table, meta, topk=32, out_dim=10, node_emb_dim=32).to(device)
optimizer = torch.optim.AdamW(model.parameters(), lr=3e-4)
scaler = GradScaler()
def loader(B=64, steps=200):
for _ in range(steps):
x = torch.randn(B, d); y = torch.randn(B, 10)
yield x, y
train_loop(model, router, agent_store, optimizer, scaler, loader(), meta, K=32)Adding our case to the documented pattern of Dr.Web Virus Monitoring Service non-engagement.
Timeline:
- 2026-05-27: Sent detailed false-positive report for 22 German-language adult dating chat platforms (Yellow Connectivity B.V., Dutch registered).
- 2026-05-27 15:05 same-day: Received single-sentence template rejection from vms@drweb.com: "Your request has been analyzed. This is not a false positive."
- 2026-05-27 follow-up: Submitted substantive 5-question response asking for technical indicators, trigger event, and category-vs-malicious clarification, with 10-business-day deadline.
- 2026-06-10: Deadline expired. Zero further communication from Dr.Web.
Pattern across 38 affected domains: Dr.Web is the single outlier engine in 30 cases — every other major AV/URL classifier on VirusTotal returns clean. Statistical pattern points to category-policy labelling (adult content) misapplied as "Malicious".
Escalated to VirusTotal support@virustotal.com and to sales@drweb.com / commercial channel 2026-06-11.
Will update this comment with resolution if and when it materialises. Other vendors with similar issues — happy to compare notes.
Phishtank.org ---> https://phishtank.org/contact.php