Restructure repository: organize tools by purpose, create what search tool
- Move single-file tools to tools/ organized by category (security, forensics, data, etc.) - Move multi-file projects to projects/ (go-tools, puzzlebox, timesketch, rust-tools) - Move system scripts to scripts/ (proxy, display, setup, windows) - Organize config files in config/ (shell, visidata, applications) - Move experimental tools to archive/experimental - Create 'what' fuzzy search tool with progressive enhancement (ollama->fzf->grep) - Add initial metadata database for intelligent tool discovery - Preserve git history using 'git mv' commands
This commit is contained in:
BIN
codegrab/.DS_Store
vendored
Normal file
BIN
codegrab/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -1,440 +0,0 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This script will discover and download all available programs from https://ericzimmerman.github.io and download them to $Dest
|
||||
.DESCRIPTION
|
||||
A file will also be created in $Dest that tracks the SHA-1 of each file, so rerunning the script will only download new versions. To redownload, remove lines from or delete the CSV file created under $Dest and rerun.
|
||||
.PARAMETER Dest
|
||||
The path you want to save the programs to.
|
||||
.EXAMPLE
|
||||
C:\PS> Get-ZimmermanTools.ps1 -Dest c:\tools
|
||||
Downloads/extracts and saves details about programs to c:\tools directory.
|
||||
.NOTES
|
||||
Author: Eric Zimmerman
|
||||
Date: January 22, 2019
|
||||
#>
|
||||
|
||||
[CmdletBinding(DefaultParameterSetName="NoProxy")]
|
||||
Param
|
||||
(
|
||||
[Parameter()]
|
||||
[string]$Dest= (Resolve-Path "."), #Where to save programs to
|
||||
|
||||
#Specifies a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName="ProxyAlone")]
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName="ProxyWithCreds")]
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName="ProxyDefaultCreds")]
|
||||
[string]$Proxy,
|
||||
|
||||
#Specifies a user account that has permission to use the proxy server that is specified by the Proxy parameter.
|
||||
#Type a user name, such as "User01" or "Domain01\User01", or enter a PSCredential object, such as one generated by the Get-Credential cmdlet.
|
||||
#This parameter is valid only when the Proxy parameter is also used in the command. You cannot use the ProxyCredential and ProxyUseDefaultCredentials parameters in the same command.
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName="ProxyWithCreds")]
|
||||
[pscredential]$ProxyCredential,
|
||||
|
||||
#Indicates that the cmdlet uses the credentials of the current user to access the proxy server that is specified by the Proxy parameter.
|
||||
#This parameter is valid only when the Proxy parameter is also used in the command. You cannot use the ProxyCredential and ProxyUseDefaultCredentials parameters in the same command.
|
||||
[Parameter(Mandatory=$true,
|
||||
ParameterSetName="ProxyDefaultCreds")]
|
||||
[switch]$ProxyUseDefaultCredentials
|
||||
|
||||
)
|
||||
|
||||
|
||||
function Write-Color {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Write-Color is a wrapper around Write-Host.
|
||||
It provides:
|
||||
- Easy manipulation of colors,
|
||||
- Logging output to file (log)
|
||||
- Nice formatting options out of the box.
|
||||
.DESCRIPTION
|
||||
Author: przemyslaw.klys at evotec.pl
|
||||
Project website: https://evotec.xyz/hub/scripts/Write-Color-ps1/
|
||||
Project support: https://github.com/EvotecIT/PSWriteColor
|
||||
Original idea: Josh (https://stackoverflow.com/users/81769/josh)
|
||||
.EXAMPLE
|
||||
Write-Color -Text "Red ", "Green ", "Yellow " -Color Red,Green,Yellow
|
||||
.EXAMPLE
|
||||
Write-Color -Text "This is text in Green ",
|
||||
"followed by red ",
|
||||
"and then we have Magenta... ",
|
||||
"isn't it fun? ",
|
||||
"Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan
|
||||
.EXAMPLE
|
||||
Write-Color -Text "This is text in Green ",
|
||||
"followed by red ",
|
||||
"and then we have Magenta... ",
|
||||
"isn't it fun? ",
|
||||
"Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan -StartTab 3 -LinesBefore 1 -LinesAfter 1
|
||||
.EXAMPLE
|
||||
Write-Color "1. ", "Option 1" -Color Yellow, Green
|
||||
Write-Color "2. ", "Option 2" -Color Yellow, Green
|
||||
Write-Color "3. ", "Option 3" -Color Yellow, Green
|
||||
Write-Color "4. ", "Option 4" -Color Yellow, Green
|
||||
Write-Color "9. ", "Press 9 to exit" -Color Yellow, Gray -LinesBefore 1
|
||||
.EXAMPLE
|
||||
Write-Color -LinesBefore 2 -Text "This little ","message is ", "written to log ", "file as well." `
|
||||
-Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt" -TimeFormat "yyyy-MM-dd HH:mm:ss"
|
||||
Write-Color -Text "This can get ","handy if ", "want to display things, and log actions to file ", "at the same time." `
|
||||
-Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt"
|
||||
.EXAMPLE
|
||||
# Added in 0.5
|
||||
Write-Color -T "My text", " is ", "all colorful" -C Yellow, Red, Green -B Green, Green, Yellow
|
||||
wc -t "my text" -c yellow -b green
|
||||
wc -text "my text" -c red
|
||||
.NOTES
|
||||
CHANGELOG
|
||||
Version 0.5 (25th April 2018)
|
||||
-----------
|
||||
- Added backgroundcolor
|
||||
- Added aliases T/B/C to shorter code
|
||||
- Added alias to function (can be used with "WC")
|
||||
- Fixes to module publishing
|
||||
Version 0.4.0-0.4.9 (25th April 2018)
|
||||
-------------------
|
||||
- Published as module
|
||||
- Fixed small issues
|
||||
Version 0.31 (20th April 2018)
|
||||
------------
|
||||
- Added Try/Catch for Write-Output (might need some additional work)
|
||||
- Small change to parameters
|
||||
Version 0.3 (9th April 2018)
|
||||
-----------
|
||||
- Added -ShowTime
|
||||
- Added -NoNewLine
|
||||
- Added function description
|
||||
- Changed some formatting
|
||||
Version 0.2
|
||||
-----------
|
||||
- Added logging to file
|
||||
Version 0.1
|
||||
-----------
|
||||
- First draft
|
||||
Additional Notes:
|
||||
- TimeFormat https://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
|
||||
#>
|
||||
[alias('Write-Colour')]
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[alias ('T')] [String[]]$Text,
|
||||
[alias ('C', 'ForegroundColor', 'FGC')] [ConsoleColor[]]$Color = [ConsoleColor]::White,
|
||||
[alias ('B', 'BGC')] [ConsoleColor[]]$BackGroundColor = $null,
|
||||
[alias ('Indent')][int] $StartTab = 0,
|
||||
[int] $LinesBefore = 0,
|
||||
[int] $LinesAfter = 0,
|
||||
[int] $StartSpaces = 0,
|
||||
[alias ('L')] [string] $LogFile = '',
|
||||
[Alias('DateFormat', 'TimeFormat')][string] $DateTimeFormat = 'yyyy-MM-dd HH:mm:ss',
|
||||
[alias ('LogTimeStamp')][bool] $LogTime = $true,
|
||||
[ValidateSet('unknown', 'string', 'unicode', 'bigendianunicode', 'utf8', 'utf7', 'utf32', 'ascii', 'default', 'oem')][string]$Encoding = 'Unicode',
|
||||
[switch] $ShowTime,
|
||||
[switch] $NoNewLine
|
||||
)
|
||||
$DefaultColor = $Color[0]
|
||||
if ($null -ne $BackGroundColor -and $BackGroundColor.Count -ne $Color.Count) { Write-Error "Colors, BackGroundColors parameters count doesn't match. Terminated." ; return }
|
||||
#if ($Text.Count -eq 0) { return }
|
||||
if ($LinesBefore -ne 0) { for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host -Object "`n" -NoNewline } } # Add empty line before
|
||||
if ($StartTab -ne 0) { for ($i = 0; $i -lt $StartTab; $i++) { Write-Host -Object "`t" -NoNewLine } } # Add TABS before text
|
||||
if ($StartSpaces -ne 0) { for ($i = 0; $i -lt $StartSpaces; $i++) { Write-Host -Object ' ' -NoNewLine } } # Add SPACES before text
|
||||
if ($ShowTime) { Write-Host -Object "[$([datetime]::Now.ToString($DateTimeFormat))]" -NoNewline} # Add Time before output
|
||||
if ($Text.Count -ne 0) {
|
||||
if ($Color.Count -ge $Text.Count) {
|
||||
# the real deal coloring
|
||||
if ($null -eq $BackGroundColor) {
|
||||
for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
|
||||
} else {
|
||||
for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackGroundColor[$i] -NoNewLine }
|
||||
}
|
||||
} else {
|
||||
if ($null -eq $BackGroundColor) {
|
||||
for ($i = 0; $i -lt $Color.Length ; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -NoNewLine }
|
||||
for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $DefaultColor -NoNewLine }
|
||||
} else {
|
||||
for ($i = 0; $i -lt $Color.Length ; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackGroundColor[$i] -NoNewLine }
|
||||
for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $BackGroundColor[0] -NoNewLine }
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($NoNewLine -eq $true) { Write-Host -NoNewline } else { Write-Host } # Support for no new line
|
||||
if ($LinesAfter -ne 0) { for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host -Object "`n" -NoNewline } } # Add empty line after
|
||||
if ($Text.Count -ne 0 -and $LogFile -ne "") {
|
||||
# Save to file
|
||||
$TextToFile = ""
|
||||
for ($i = 0; $i -lt $Text.Length; $i++) {
|
||||
$TextToFile += $Text[$i]
|
||||
}
|
||||
try {
|
||||
if ($LogTime) {
|
||||
Write-Output -InputObject "[$([datetime]::Now.ToString($DateTimeFormat))]$TextToFile" | Out-File -FilePath $LogFile -Encoding $Encoding -Append
|
||||
} else {
|
||||
Write-Output -InputObject "$TextToFile" | Out-File -FilePath $LogFile -Encoding $Encoding -Append
|
||||
}
|
||||
} catch {
|
||||
$_.Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Setup proxy information for Invoke-WebRequest
|
||||
[hashtable]$IWRProxyConfig = @{}
|
||||
|
||||
if ($Proxy){
|
||||
$IWRProxyConfig.Add("Proxy",$Proxy)
|
||||
}
|
||||
if ($ProxyCredential){
|
||||
$IWRProxyConfig.Add("ProxyCredential",$ProxyCredential)
|
||||
}
|
||||
if ($ProxyUseDefaultCredentials){
|
||||
$IWRProxyConfig.Add("ProxyUseDefaultCredentials",$true)
|
||||
}
|
||||
|
||||
|
||||
Write-Color -LinesBefore 1 "This script will discover and download all available programs" -BackgroundColor Blue
|
||||
Write-Color "from https://ericzimmerman.github.io and download them to $Dest" -BackgroundColor Blue -LinesAfter 1
|
||||
Write-Color "A file will also be created in $Dest that tracks the SHA-1 of each file,"
|
||||
Write-Color "so rerunning the script will only download new versions."
|
||||
Write-Color -LinesBefore 1 -Text "To redownload, remove lines from or delete the CSV file created under $Dest and rerun. Enjoy!" -LinesAfter 1
|
||||
|
||||
$TestColor = (Get-Host).ui.rawui.ForegroundColor
|
||||
if ($TestColor -eq -1)
|
||||
{
|
||||
$defaultColor = [ConsoleColor]::Gray
|
||||
} else {
|
||||
$defaultColor = $TestColor
|
||||
}
|
||||
|
||||
$newInstall = $false
|
||||
|
||||
if(!(Test-Path -Path $Dest ))
|
||||
{
|
||||
Write-Color -Text "* ", "$Dest does not exist. Creating..." -Color Green,$defaultColor
|
||||
New-Item -ItemType directory -Path $Dest > $null
|
||||
|
||||
$newInstall = $true
|
||||
}
|
||||
|
||||
$URL = "https://raw.githubusercontent.com/EricZimmerman/ericzimmerman.github.io/master/index.md"
|
||||
|
||||
$WebKeyCollection = @()
|
||||
|
||||
$localDetailsFile = Join-Path $Dest -ChildPath "!!!RemoteFileDetails.csv"
|
||||
|
||||
if (Test-Path -Path $localDetailsFile)
|
||||
{
|
||||
Write-Color -Text "* ", "Loading local details from '$Dest'..." -Color Green,$defaultColor
|
||||
$LocalKeyCollection = Import-Csv -Path $localDetailsFile
|
||||
}
|
||||
|
||||
$toDownload = @()
|
||||
|
||||
#Get zips
|
||||
$progressPreference = 'silentlyContinue'
|
||||
$PageContent = (Invoke-WebRequest @IWRProxyConfig -Uri $URL -UseBasicParsing).Content
|
||||
$progressPreference = 'Continue'
|
||||
|
||||
$regex = [regex] '(?i)\b(https)://[-A-Z0-9+&@#/%?=~_|$!:,.;]*[A-Z0-9+&@#/%=~_|$].(zip|txt)'
|
||||
$matchdetails = $regex.Match($PageContent)
|
||||
|
||||
Write-Color -Text "* ", "Getting available programs..." -Color Green,$defaultColor
|
||||
$progressPreference = 'silentlyContinue'
|
||||
while ($matchdetails.Success) {
|
||||
$headers = (Invoke-WebRequest @IWRProxyConfig -Uri $matchdetails.Value -UseBasicParsing -Method Head).Headers
|
||||
|
||||
$getUrl = $matchdetails.Value
|
||||
$sha = $headers["x-bz-content-sha1"]
|
||||
$name = $headers["x-bz-file-name"]
|
||||
$size = $headers["Content-Length"]
|
||||
|
||||
$details = @{
|
||||
Name = [string]$name
|
||||
SHA1 = [string]$sha
|
||||
URL = [string]$getUrl
|
||||
Size = [string]$size
|
||||
}
|
||||
|
||||
$webKeyCollection += New-Object PSObject -Property $details
|
||||
|
||||
$matchdetails = $matchdetails.NextMatch()
|
||||
}
|
||||
$progressPreference = 'Continue'
|
||||
|
||||
Foreach ($webKey in $webKeyCollection)
|
||||
{
|
||||
if ($newInstall)
|
||||
{
|
||||
$toDownload+= $webKey
|
||||
continue
|
||||
}
|
||||
|
||||
$localFile = $LocalKeyCollection | Where-Object {$_.Name -eq $webKey.Name}
|
||||
|
||||
if ($null -eq $localFile -or $localFile.SHA1 -ne $webKey.SHA1)
|
||||
{
|
||||
#Needs to be downloaded since SHA is different or it doesnt exist
|
||||
$toDownload+= $webKey
|
||||
}
|
||||
}
|
||||
|
||||
if ($toDownload.Count -eq 0)
|
||||
{
|
||||
Write-Color -LinesBefore 1 -Text "* ", "All files current. Exiting." -Color Green,Blue -LinesAfter 1
|
||||
return
|
||||
}
|
||||
|
||||
$downloadedOK = @()
|
||||
|
||||
$destFile = ""
|
||||
$name = ""
|
||||
|
||||
$i=0
|
||||
$dlCount= $toDownload.Count
|
||||
Write-Color -Text "* ", "Files to download: $dlCount" -Color Green,$defaultColor
|
||||
foreach($td in $toDownload)
|
||||
{
|
||||
$p = [math]::round( ($i/$toDownload.Count) *100, 2 )
|
||||
|
||||
#Write-Host ($td | Format-Table | Out-String)
|
||||
|
||||
try
|
||||
{
|
||||
$dUrl = $td.URL
|
||||
$size = $td.Size
|
||||
$name = $td.Name
|
||||
|
||||
Write-Progress -Activity "Updating programs...." -Status "$p% Complete" -PercentComplete $p -CurrentOperation "Downloading $name"
|
||||
$destFile = [IO.Path]::Combine($Dest, $name)
|
||||
|
||||
$progressPreference = 'silentlyContinue'
|
||||
Invoke-WebRequest @IWRProxyConfig -Uri $dUrl -OutFile $destFile -ErrorAction:Stop -UseBasicParsing
|
||||
|
||||
Write-Color -Text "* ", "Downloaded $name (Size: $size)" -Color Green,Blue
|
||||
|
||||
if ( $name.endswith("zip") )
|
||||
{
|
||||
Expand-Archive -Path $destFile -DestinationPath $Dest -Force
|
||||
}
|
||||
|
||||
$downloadedOK += $td
|
||||
}
|
||||
catch
|
||||
{
|
||||
$ErrorMessage = $_.Exception.Message
|
||||
Write-Color -Text "* ", "Error downloading $name ($ErrorMessage). Wait for the run to finish and try again by repeating the command" -Color Green,Red
|
||||
}
|
||||
finally
|
||||
{
|
||||
$progressPreference = 'Continue'
|
||||
if ( $name.endswith("zip") )
|
||||
{
|
||||
remove-item -Path $destFile
|
||||
}
|
||||
|
||||
}
|
||||
$i+=1
|
||||
}
|
||||
|
||||
#Write-Host ($webKeyCollection | Format-Table | Out-String)
|
||||
|
||||
#Downloaded ok contains new stuff, but we need to account for existing stuff too
|
||||
foreach($webItems in $webKeyCollection)
|
||||
{
|
||||
#Check what we have locally to see if it also contains what is in the web collection
|
||||
$localFile = $LocalKeyCollection | Where-Object {$_.SHA1 -eq $webItems.SHA1}
|
||||
|
||||
#if its not null, we have a local file match against what is on the website, so its ok
|
||||
|
||||
if ($null -ne $localFile)
|
||||
{
|
||||
#consider it downloaded since SHAs match
|
||||
$downloadedOK+=$webItems
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Write-Color -LinesBefore 1 -Text "* ", "Saving downloaded version information to $localDetailsFile" -Color Green,$defaultColor -LinesAfter 1
|
||||
|
||||
$downloadedOK | export-csv -Path $localDetailsFile
|
||||
|
||||
|
||||
# SIG # Begin signature block
|
||||
# MIIOCQYJKoZIhvcNAQcCoIIN+jCCDfYCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
|
||||
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
|
||||
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU3h3hKI/PCw9Fhvn2sUIunz8M
|
||||
# gFmgggtAMIIFQzCCBCugAwIBAgIRAOhGMy2+0dm4G+A32Y4gvJwwDQYJKoZIhvcN
|
||||
# AQELBQAwfDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3Rl
|
||||
# cjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQw
|
||||
# IgYDVQQDExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcgQ0EwHhcNMTkxMjI1MDAw
|
||||
# MDAwWhcNMjMwMzI0MjM1OTU5WjCBkjELMAkGA1UEBhMCVVMxDjAMBgNVBBEMBTQ2
|
||||
# MDQwMQswCQYDVQQIDAJJTjEQMA4GA1UEBwwHRmlzaGVyczEcMBoGA1UECQwTMTU2
|
||||
# NzIgUHJvdmluY2lhbCBMbjEaMBgGA1UECgwRRXJpYyBSLiBaaW1tZXJtYW4xGjAY
|
||||
# BgNVBAMMEUVyaWMgUi4gWmltbWVybWFuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
# MIIBCgKCAQEAtU2gix6QVzDg+YBDDNyZj1kPFwPDhTbojEup24x3swWNCI14P4dM
|
||||
# Cs6SKDUPmKhe8k5aLpv9eacsgyndyYkrcSGFCwUwbTnetrn8lzOFu53Vz4sjFIMl
|
||||
# mKVSPfKE7GBoBcJ8jT3LKoB7YzZF6khoQY84fOJPNOj7snfExN64J6KVQlDsgOjL
|
||||
# wY720m8bN/Rn+Vp+FBXHyUIjHhhvb+o29xFmemxzfTWXhDM2oIX4kRuF/Zmfo9l8
|
||||
# n3J+iOBL/IiIVTi68adYxq3s0ASxgrQ4HO3veGgzNZ9KSB1ltXyNVGstInIs+UZP
|
||||
# lKynweRQJO5cc7zK64sSotjgwlcaQdBAHQIDAQABo4IBpzCCAaMwHwYDVR0jBBgw
|
||||
# FoAUDuE6qFM6MdWKvsG7rWcaA4WtNA4wHQYDVR0OBBYEFGsRm7mtwiWCh8MSEbEX
|
||||
# TwjtcryvMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoG
|
||||
# CCsGAQUFBwMDMBEGCWCGSAGG+EIBAQQEAwIEEDBABgNVHSAEOTA3MDUGDCsGAQQB
|
||||
# sjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzBD
|
||||
# BgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29S
|
||||
# U0FDb2RlU2lnbmluZ0NBLmNybDBzBggrBgEFBQcBAQRnMGUwPgYIKwYBBQUHMAKG
|
||||
# Mmh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1JTQUNvZGVTaWduaW5nQ0Eu
|
||||
# Y3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAfBgNVHREE
|
||||
# GDAWgRRlcmljQG1pa2VzdGFtbWVyLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAhX//
|
||||
# xLBhfLf4X2OPavhp/AlmnpkQU8yIZv8DjVQKJ0j8YhxClIAgyuSb/6+q+njOsxMn
|
||||
# ZDoCAPlzG0P74e1nYTiw3beG6ePr3uDc9PjUBxDiHgxlI69mlXYdjiAircV5Z8iU
|
||||
# TcmqJ9LpnTcrvtmQAvN1ldoSW4hmHIJuV0XLOhvAlURuPM1/C9lh0K65nH3wYIoU
|
||||
# /0pELlDfIdUxL2vOLnElxCv0z07Hf9yw+3grWHJb54Vms6o/xYxZgqCu02DH0q1f
|
||||
# KrNBwtDkLKKObBF54wA7LdaDGbl3CJXQVRmgokcDI/izmZJxHAHebdbj4zVFyCND
|
||||
# sMRySmbR+m58q/jv3DCCBfUwggPdoAMCAQICEB2iSDBvmyYY0ILgln0z02owDQYJ
|
||||
# KoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5
|
||||
# MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO
|
||||
# ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0
|
||||
# aG9yaXR5MB4XDTE4MTEwMjAwMDAwMFoXDTMwMTIzMTIzNTk1OVowfDELMAkGA1UE
|
||||
# BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2Fs
|
||||
# Zm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdv
|
||||
# IFJTQSBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
# AoIBAQCGIo0yhXoYn0nwli9jCB4t3HyfFM/jJrYlZilAhlRGdDFixRDtsocnppnL
|
||||
# lTDAVvWkdcapDlBipVGREGrgS2Ku/fD4GKyn/+4uMyD6DBmJqGx7rQDDYaHcaWVt
|
||||
# H24nlteXUYam9CflfGqLlR5bYNV+1xaSnAAvaPeX7Wpyvjg7Y96Pv25MQV0SIAhZ
|
||||
# 6DnNj9LWzwa0VwW2TqE+V2sfmLzEYtYbC43HZhtKn52BxHJAteJf7wtF/6POF6Yt
|
||||
# VbC3sLxUap28jVZTxvC6eVBJLPcDuf4vZTXyIuosB69G2flGHNyMfHEo8/6nxhTd
|
||||
# VZFuihEN3wYklX0Pp6F8OtqGNWHTAgMBAAGjggFkMIIBYDAfBgNVHSMEGDAWgBRT
|
||||
# eb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUDuE6qFM6MdWKvsG7rWcaA4Wt
|
||||
# NA4wDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYw
|
||||
# FAYIKwYBBQUHAwMGCCsGAQUFBwMIMBEGA1UdIAQKMAgwBgYEVR0gADBQBgNVHR8E
|
||||
# STBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVNFUlRydXN0UlNB
|
||||
# Q2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYIKwYBBQUHAQEEajBoMD8GCCsG
|
||||
# AQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vVVNFUlRydXN0UlNBQWRk
|
||||
# VHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5j
|
||||
# b20wDQYJKoZIhvcNAQEMBQADggIBAE1jUO1HNEphpNveaiqMm/EAAB4dYns61zLC
|
||||
# 9rPgY7P7YQCImhttEAcET7646ol4IusPRuzzRl5ARokS9At3WpwqQTr81vTr5/cV
|
||||
# lTPDoYMot94v5JT3hTODLUpASL+awk9KsY8k9LOBN9O3ZLCmI2pZaFJCX/8E6+F0
|
||||
# ZXkI9amT3mtxQJmWunjxucjiwwgWsatjWsgVgG10Xkp1fqW4w2y1z99KeYdcx0BN
|
||||
# YzX2MNPPtQoOCwR/oEuuu6Ol0IQAkz5TXTSlADVpbL6fICUQDRn7UJBhvjmPeo5N
|
||||
# 9p8OHv4HURJmgyYZSJXOSsnBf/M6BZv5b9+If8AjntIeQ3pFMcGcTanwWbJZGehq
|
||||
# jSkEAnd8S0vNcL46slVaeD68u28DECV3FTSK+TbMQ5Lkuk/xYpMoJVcp+1EZx6El
|
||||
# QGqEV8aynbG8HArafGd+fS7pKEwYfsR7MUFxmksp7As9V1DSyt39ngVR5UR43QHe
|
||||
# sXWYDVQk/fBO4+L4g71yuss9Ou7wXheSaG3IYfmm8SoKC6W59J7umDIFhZ7r+YMp
|
||||
# 08Ysfb06dy6LN0KgaoLtO0qqlBCk4Q34F8W2WnkzGJLjtXX4oemOCiUe5B7xn1qH
|
||||
# I/+fpFGe+zmAEc3btcSnqIBv5VPU4OOiwtJbGvoyJi1qV3AcPKRYLqPzW0sH3DJZ
|
||||
# 84enGm1YMYICMzCCAi8CAQEwgZEwfDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
|
||||
# ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2Vj
|
||||
# dGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcg
|
||||
# Q0ECEQDoRjMtvtHZuBvgN9mOILycMAkGBSsOAwIaBQCgeDAYBgorBgEEAYI3AgEM
|
||||
# MQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQB
|
||||
# gjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqGSIb3DQEJBDEWBBSub3DNneg8U2SV
|
||||
# 3eSlV1WAf1WW3jANBgkqhkiG9w0BAQEFAASCAQBfJ7rjKfvcpG38nVyhlWsnJY5h
|
||||
# udJfTzZ4Cd5CSNnf84dPyLFqMCjk6PhCzFteJ6JimvoOiCu0N0DRYjIGaL6+iKWK
|
||||
# P5IBFWyNSmH3PN3ENjmOj0xTnKdodJ8Uos9GmYT7JXtodYpO2fxTKyq5yAwY1dY4
|
||||
# jmrDdQgseRoR99UTzVO7BZHsBbDj6mT3Jo1NVCD5fgz1CtMi++fFYlayOUPwDBr0
|
||||
# DnV0yg0wR6CPMH37Qx2Y6jRpD5Yk9BrypT50rY9ORayOL0qav4srjVVN8MwMHjcq
|
||||
# PMarEg4Hyq+Q91i4+z0xp+PwWNuwwbdrrJaQwa6FXgbC3GJgCHqTNnVbZPh2
|
||||
# SIG # End signature block
|
||||
@@ -1,113 +0,0 @@
|
||||
#!/bin/bash
|
||||
###################Wipe (optional)
|
||||
DEVICE=${1}
|
||||
wipedelay=20
|
||||
|
||||
# Required packages
|
||||
REQUIRED_PACKAGES=("hdparm" "dialog" "dc3dd" "util-linux")
|
||||
|
||||
# Check for missing packages
|
||||
check_missing_packages()
|
||||
{
|
||||
for package in "${REQUIRED_PACKAGES[@]}"; do
|
||||
if ! dpkg -s "${package}" >/dev/null 2>&1; then
|
||||
echo "Wipe script requires the following packages:"
|
||||
for p in "${REQUIRED_PACKAGES[@]}"; do
|
||||
echo " ${p}"
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Get device from the user if not specified or invalid
|
||||
get_device()
|
||||
{
|
||||
if [ -z "$DEVICE" ] || [ ! -b "$DEVICE" ]; then
|
||||
# Create a list of available devices
|
||||
W=()
|
||||
while read -r line; do
|
||||
dev=$(echo $line | cut -f1 -d" ")
|
||||
rest=$(echo $line | cut -f2- -d" " | tr -s " ")
|
||||
W+=("/dev/${dev}" "${rest}")
|
||||
done < <(lsblk -l -oname,size,model,type | grep -e disk)
|
||||
|
||||
# Display device selection menu
|
||||
DEVICE=$(dialog --backtitle "CERTBw - SecureErase" --title "Available Devices" --menu "Which disk should be wiped?" 24 80 17 "${W[@]}" 3>&2 2>&1 1>&3)
|
||||
fi
|
||||
}
|
||||
|
||||
# cleanup function to unset the ATA Password if execution gets interrupted
|
||||
cleanup()
|
||||
{
|
||||
echo
|
||||
echo "==WIPE : Removing ATA password due to user interruption..."
|
||||
hdparm --user-master u --security-disable certbw "${DEVICE}"
|
||||
echo "==WIPE : ATA password removed."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Display warning and countdown
|
||||
display_warning()
|
||||
{
|
||||
dialog --backtitle "CERTBw - SecureErase" --defaultno --cancel-label "Cancel" --colors --title "\Z1!WARNING!\Zn" --pause "\n\Z1The device ${DEVICE} will be completely erased!\Zn\n\nThe SecureErase process must not be interrupted, as this will lock the device, and it will need to be manually unlocked afterward.\n\n\nThe process will automatically continue after the countdown expires.\n\nTo cancel the DiskWipe, you can:\n \Z4Select \"Cancel\"\n Press \"ESC\"\n Press \"CTRL + C\"\n Turn off the computer\Zn" 24 80 ${wipedelay}
|
||||
if [ "$?" -gt 0 ]; then
|
||||
echo "==WIPE : Wipe was canceled by the user."
|
||||
sleep 1
|
||||
read -p "Press [ENTER] key for Shell..."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Securely erase the device
|
||||
secure_erase()
|
||||
{
|
||||
if hdparm -I "${DEVICE}" | grep supported | grep -q erase; then
|
||||
echo "==WIPE : Secure Erase is supported by ${DEVICE}"
|
||||
if ! (hdparm -I "${DEVICE}" | grep not | grep -q frozen); then
|
||||
echo "==WIPE : The device ${DEVICE} is frozen"
|
||||
echo "==WIPE : The notebook will now be put to sleep for 10 seconds."
|
||||
echo "==WIPE : Do not turn off the notebook."
|
||||
sleep 5
|
||||
rtcwake -s 10 -m mem
|
||||
echo "==WIPE : The notebook has woken up. Checking the status of ${DEVICE}."
|
||||
fi
|
||||
if hdparm -I "${DEVICE}" | grep not | grep -q frozen; then
|
||||
echo "==WIPE : The device ${DEVICE} is 'not frozen'"
|
||||
echo
|
||||
echo "==WIPE : A temporary ATA password (certbw) must be set for SecureErase."
|
||||
echo "==WIPE : If the SecureErase process is interrupted, the disk will be unusable until manually unlocked."
|
||||
echo "==WIPE : Do not turn off the notebook."
|
||||
sleep 5
|
||||
# Set a trap to catch SIGINT and call the cleanup function
|
||||
trap 'cleanup' SIGINT
|
||||
# Set ATA password
|
||||
hdparm --user-master u --security-set-pass certbw "${DEVICE}"
|
||||
# Issue Secure Erase command
|
||||
hdparm --user-master u --security-erase certbw "${DEVICE}"
|
||||
# Remove the trap after the Secure Erase is completed
|
||||
trap - SIGINT
|
||||
else
|
||||
# Normal wipe because unfreeze didn't work
|
||||
echo "==WIPE : The device could not be unfrozen."
|
||||
echo "==WIPE : The device ${DEVICE} will be overwritten."
|
||||
/usr/bin/dc3dd wipe="${DEVICE}"
|
||||
fi
|
||||
else
|
||||
# Normal wipe because Secure Erase is not supported
|
||||
echo "==WIPE : Secure Erase is NOT supported."
|
||||
echo "==WIPE : The device ${DEVICE} will be overwritten."
|
||||
/usr/bin/dc3dd wipe="${DEVICE}"
|
||||
fi
|
||||
}
|
||||
|
||||
check_missing_packages
|
||||
get_device
|
||||
if [ ! -b "${DEVICE}" ]; then
|
||||
echo "==WIPE : Kein gültiges BLOCK-Device ausgewählt."
|
||||
sleep 1
|
||||
read -p "Press [ENTER] key for Shell..."
|
||||
exit 1
|
||||
fi
|
||||
display_warning
|
||||
secure_erase
|
||||
@@ -1,37 +0,0 @@
|
||||
import sqlite3
|
||||
import sys
|
||||
import re
|
||||
dbfile=sys.argv[1]
|
||||
# dbfile="/home/skyhawk/Documents/test.db"
|
||||
|
||||
try:
|
||||
db=sqlite3.connect(dbfile)
|
||||
cur = db.cursor()
|
||||
cur.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;")
|
||||
tables=cur.fetchall()
|
||||
# for row in db.execute("pragma table_info('sqlite_master')").fetchall():
|
||||
# print(row)
|
||||
nice_tables={}
|
||||
for table in tables:
|
||||
# print(table)
|
||||
nice_rows=[]
|
||||
for row in db.execute("pragma table_info(" + str(table[0]) +")").fetchall():
|
||||
# print(row[1])
|
||||
if re.match('hash|pass',row[1], re.IGNORECASE):
|
||||
nice_rows.append(row[1])
|
||||
if len(nice_rows) > 0:
|
||||
nice_tables[table[0]]=nice_rows
|
||||
|
||||
|
||||
|
||||
except Exception as e:
|
||||
# print("Error opening DB %s" % dbfile)
|
||||
# sys.std.write(e)
|
||||
exit(1)
|
||||
|
||||
print("[+] %s is Valid DB " % dbfile)
|
||||
if len(nice_tables)>0:
|
||||
for tab in nice_tables:
|
||||
print(nice_tables[tab])
|
||||
|
||||
db.close()
|
||||
@@ -1,98 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import logging
|
||||
import owncloud
|
||||
import gnupg
|
||||
import os
|
||||
import requests
|
||||
import re
|
||||
from icecream import ic
|
||||
|
||||
|
||||
def isurl(text):
|
||||
pattern = 'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
|
||||
matcher = re.compile(pattern)
|
||||
return matcher.match(text)
|
||||
|
||||
def upload(file,url):
|
||||
try:
|
||||
oc = owncloud.Client.from_public_link(args.url)
|
||||
ic(oc)
|
||||
response = oc.drop_file(fn)
|
||||
ic(response)
|
||||
return response
|
||||
except owncloud.owncloud.HTTPResponseError as e:
|
||||
logging.error(f'Error while uploading file {fn} <{e}>')
|
||||
|
||||
def upload_rq(file,url):
|
||||
CLOUDURL=""
|
||||
FOLDERTOKEN=""
|
||||
|
||||
# FILENAME="$1"
|
||||
|
||||
# CLOUDURL=''
|
||||
# # if we have index.php in the URL, process accordingly
|
||||
# if [[ $2 == *"index.php"* ]]; then
|
||||
# CLOUDURL="${2%/index.php/s/*}"
|
||||
# else
|
||||
# CLOUDURL="${2%/s/*}"
|
||||
# fi
|
||||
|
||||
# FOLDERTOKEN="${2##*/s/}"
|
||||
# -T "$FILENAME" -u "$FOLDERTOKEN":"$PASSWORD" -H "$HEADER" "$CLOUDURL/$PUBSUFFIX/$BFILENAME"
|
||||
# if [ ! -f "$FILENAME" ]; then
|
||||
# initError "Invalid input file: $FILENAME"
|
||||
# fi
|
||||
|
||||
# if [ -z "$CLOUDURL" ]; then
|
||||
# initError "Empty URL! Nowhere to send..."
|
||||
# fi
|
||||
|
||||
# if [ -z "$FOLDERTOKEN" ]; then
|
||||
# initError "Empty Folder Token! Nowhere to send..."
|
||||
# fi
|
||||
|
||||
|
||||
PUBSUFFIX="public.php/webdav"
|
||||
HEADER='X-Requested-With: XMLHttpRequest'
|
||||
INSECURE=''
|
||||
|
||||
headers = {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
}
|
||||
|
||||
|
||||
response = requests.put('https://nextcloud.exampyocclientple.com/public.php/webdav/testfile.txt', headers=headers, verify=args.insecure, auth=('AtAxVrKorgC5YJf', ''))
|
||||
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-k","--insecure",action="store_false")
|
||||
parser.add_argument("-x","--encryption",action="store",default=None,const='*',nargs="?",type=str)
|
||||
parser.add_argument("url")
|
||||
parser.add_argument("file",nargs="+")
|
||||
args=parser.parse_args()
|
||||
|
||||
if args.encryption is not None:
|
||||
ic(args.encryption)
|
||||
|
||||
if not isurl(args.url):
|
||||
logging.warning(f"URL '{args.url}' is not valid")
|
||||
|
||||
ic(args)
|
||||
for fn in args.file:
|
||||
ic(os.path.isdir(fn))
|
||||
ic(os.path.isfile(fn))
|
||||
if os.path.isdir(fn):
|
||||
logging.warning("Foldersupport not implemented yet")
|
||||
continue
|
||||
if upload(fn,args.url):
|
||||
logging.info(f"{fn} successfully uploaded")
|
||||
else:
|
||||
logging.warning(f"Error uploading {fn}")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
############################################################
|
||||
# MIGRATED TO REPOSITORY
|
||||
# https://github.com/tavinus/cloudsend.sh
|
||||
#
|
||||
# This gist will NOT be updated anymore
|
||||
############################################################
|
||||
|
||||
|
||||
############################################################
|
||||
#
|
||||
# cloudsend.sh
|
||||
#
|
||||
# Uses curl to send files to a shared
|
||||
# Nextcloud/Owncloud folder
|
||||
#
|
||||
# Usage: ./cloudsend.sh <file> <folderLink>
|
||||
# Help: ./cloudsend.sh -h
|
||||
#
|
||||
# Gustavo Arnosti Neves
|
||||
# https://github.com/tavinus
|
||||
#
|
||||
# Contributors:
|
||||
# @MG2R @gessel
|
||||
#
|
||||
# Get this script to current folder with:
|
||||
# curl -O 'https://raw.githubusercontent.com/tavinus/cloudsend.sh/master/cloudsend.sh' && chmod +x cloudsend.sh
|
||||
#
|
||||
############################################################
|
||||
|
||||
|
||||
CS_VERSION="0.1.6"
|
||||
|
||||
|
||||
|
||||
# https://cloud.mydomain.net/s/fLDzToZF4MLvG28
|
||||
# curl -k -T myFile.ext -u "fLDzToZF4MLvG28:" -H 'X-Requested-With: XMLHttpRequest' https://cloud.mydomain.net/public.php/webdav/myFile.ext
|
||||
|
||||
log() {
|
||||
[ "$VERBOSE" == " -s" ] || printf "%s\n" "$1"
|
||||
}
|
||||
|
||||
printVersion() {
|
||||
printf "%s\n" "CloudSender v$CS_VERSION"
|
||||
}
|
||||
|
||||
initError() {
|
||||
printVersion >&2
|
||||
printf "%s\n" "Init Error! $1" >&2
|
||||
printf "%s\n" "Try: $0 --help" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
usage() {
|
||||
printVersion
|
||||
printf "\n%s%s\n" "Parameters:" "
|
||||
-h | --help Print this help and exits
|
||||
-q | --quiet Be quiet
|
||||
-x | --encrypt Encrypt Upload with Password
|
||||
-V | --version Prints version and exits
|
||||
-k | --insecure Uses curl with -k option (https insecure)
|
||||
-p | --password Uses env var \$CLOUDSEND_PASSWORD as share password
|
||||
You can 'export CLOUDSEND_PASSWORD' at your system, or set it at the call.
|
||||
Please remeber to also call -p to use the password set."
|
||||
printf "\n%s\n%s\n%s\n" "Use:" " $0 <filepath> <folderLink>" " CLOUDSEND_PASSWORD='MySecretPass' $0 -p <filepath> <folderLink>"
|
||||
printf "\n%s\n%s\n%s\n" "Example:" " $0 './myfile.txt' 'https://cloud.mydomain.net/s/fLDzToZF4MLvG28'" " CLOUDSEND_PASSWORD='MySecretPass' $0 -p './myfile.txt' 'https://cloud.mydomain.net/s/fLDzToZF4MLvG28'"
|
||||
}
|
||||
|
||||
##########################
|
||||
# Process parameters
|
||||
|
||||
|
||||
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "-V" ] || [ "$1" = "--version" ]; then
|
||||
printVersion
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "-q" ] || [ "$1" = "--quiet" ]; then
|
||||
VERBOSE=" -s"
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$1" = "-k" ] || [ "$1" = "--insecure" ]; then
|
||||
INSECURE=' -k'
|
||||
log " > Insecure mode ON"
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ] || [ "$1" = "--password" ]; then
|
||||
PASSWORD=${CLOUDSEND_PASSWORD}
|
||||
log " > Using password from env"
|
||||
shift
|
||||
fi
|
||||
|
||||
|
||||
##########################
|
||||
# Validate input
|
||||
|
||||
FILENAME="$1"
|
||||
|
||||
CLOUDURL=''
|
||||
# if we have index.php in the URL, process accordingly
|
||||
if [[ $2 == *"index.php"* ]]; then
|
||||
CLOUDURL="${2%/index.php/s/*}"
|
||||
else
|
||||
CLOUDURL="${2%/s/*}"
|
||||
fi
|
||||
|
||||
FOLDERTOKEN="${2##*/s/}"
|
||||
|
||||
if [ ! -f "$FILENAME" ]; then
|
||||
initError "Invalid input file: $FILENAME"
|
||||
fi
|
||||
|
||||
if [ -z "$CLOUDURL" ]; then
|
||||
initError "Empty URL! Nowhere to send..."
|
||||
fi
|
||||
|
||||
if [ -z "$FOLDERTOKEN" ]; then
|
||||
initError "Empty Folder Token! Nowhere to send..."
|
||||
fi
|
||||
|
||||
|
||||
##########################
|
||||
# Check for curl
|
||||
|
||||
CURLBIN='/usr/bin/curl'
|
||||
if [ ! -x "$CURLBIN" ]; then
|
||||
CURLBIN="$(which curl 2>/dev/null)"
|
||||
if [ ! -x "$CURLBIN" ]; then
|
||||
initError "No curl found on system!"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
##########################
|
||||
# Extract base filename
|
||||
|
||||
BFILENAME=$(/usr/bin/basename $FILENAME)
|
||||
|
||||
|
||||
##########################
|
||||
# Send file
|
||||
|
||||
#echo "$CURLBIN"$INSECURE$VERBOSE -T "$FILENAME" -u "$FOLDERTOKEN":"$PASSWORD" -H "$HEADER" "$CLOUDURL/$PUBSUFFIX/$BFILENAME"
|
||||
"$CURLBIN"$INSECURE$VERBOSE -T "$FILENAME" -u "$FOLDERTOKEN":"$PASSWORD" -H "$HEADER" "$CLOUDURL/$PUBSUFFIX/$BFILENAME"
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if a file argument is provided
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <file-to-convert>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign the file argument to a variable
|
||||
FILE_TO_CONVERT=$1
|
||||
FILE_NAME=$(basename "$FILE_TO_CONVERT")
|
||||
|
||||
# Define the Gotenberg Docker image
|
||||
GOTENBERG_IMAGE="gotenberg/gotenberg:8"
|
||||
|
||||
# Start the Gotenberg Docker container in the background
|
||||
docker run --rm -d -p 3000:3000 --name gotenberg $GOTENBERG_IMAGE
|
||||
|
||||
# Function to stop the Docker container
|
||||
function stop_container {
|
||||
docker stop gotenberg
|
||||
}
|
||||
|
||||
# Register the stop_container function to be called on script exit
|
||||
trap stop_container EXIT
|
||||
|
||||
# Wait for a moment to ensure that the container is up and running
|
||||
sleep 3
|
||||
|
||||
# Determine the correct API endpoint based on the file extension
|
||||
EXTENSION="${FILE_TO_CONVERT##*.}"
|
||||
API_ENDPOINT="/forms/libreoffice/convert"
|
||||
|
||||
# Special handling for HTML files to use Chromium conversion
|
||||
if [ "$EXTENSION" == "html" ]; then
|
||||
API_ENDPOINT="/forms/chromium/convert/html"
|
||||
# Ensure the HTML file is named index.html
|
||||
if [ "$FILE_NAME" != "index.html" ]; then
|
||||
echo "Renaming $FILE_NAME to index.html for conversion"
|
||||
cp "$FILE_TO_CONVERT" "/tmp/index.html"
|
||||
FILE_TO_CONVERT="/tmp/index.html"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Convert the file to PDF using the Gotenberg API
|
||||
curl --request POST \
|
||||
--url http://localhost:3000$API_ENDPOINT \
|
||||
--header 'Content-Type: multipart/form-data' \
|
||||
--form files=@"$FILE_TO_CONVERT" \
|
||||
-o converted.pdf
|
||||
|
||||
# Check if the conversion was successful
|
||||
if [ ! -f converted.pdf ]; then
|
||||
echo "Failed to convert the file to PDF."
|
||||
exit 3
|
||||
fi
|
||||
|
||||
# Display the PDF with Evince
|
||||
evince converted.pdf &
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
#check if comma or semicolon
|
||||
if [[ $( grep -c ',' $1 ) -gt $( grep -c ';' $1 ) ]]
|
||||
then
|
||||
delim=','
|
||||
else
|
||||
delim=';'
|
||||
fi
|
||||
|
||||
#get headings and display them
|
||||
head -n1 $1 | tr "$delim" "\n" | nl
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import sys
|
||||
from nltk.corpus import stopwords
|
||||
from nltk.tokenize import word_tokenize
|
||||
|
||||
|
||||
with open(sys.argv[0],'r') as f:
|
||||
text=" ".join(f.readlines())
|
||||
stop_words = set(stopwords.words('english'))
|
||||
word_tokens = word_tokenize(text)
|
||||
for word in [w for w in word_tokens if len(w)>3 and not w in stop_words]:
|
||||
word=word.strip(' \n,.=!_\'')
|
||||
word.replace(".","_")
|
||||
print(word)
|
||||
@@ -1,2 +0,0 @@
|
||||
def getjss(text):
|
||||
return "String.fromCharCode({})".format(",".join(["{}".format(ord(x)) for x in text]))
|
||||
@@ -1,22 +0,0 @@
|
||||
import requests
|
||||
import sys
|
||||
from pprint import pprint
|
||||
|
||||
def getjss(text):
|
||||
return "String.fromCharCode({})".format(",".join(["{}".format(ord(x)) for x in text]))
|
||||
|
||||
|
||||
def test(teststring):
|
||||
return '''test' + ''' + getjss('},'+teststring+',{"guess":"') + ''' + 'test'''
|
||||
|
||||
|
||||
burp0_url = "http://cxvhbgkymde5cg.code.unibw-muenchen.de:80/a81b583202982d472bde5e9f4a89becd/guess"
|
||||
burp0_headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0", "Accept": "application/json, text/plain, */*", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate", "Referer": "http://cxvhbgkymde5cg.code.unibw-muenchen.de/a81b583202982d472bde5e9f4a89becd/", "Content-Type": "application/json;charset=utf-8", "Authorization": "Basic dX==", "Connection": "close"}
|
||||
|
||||
s=test(sys.argv[1])
|
||||
burp0_json={"guess": s }
|
||||
print(s)
|
||||
r=requests.post(burp0_url, headers=burp0_headers, json=burp0_json)
|
||||
pprint(r.text)
|
||||
for head in r.headers:
|
||||
print("{}\t{}".format(head,r.headers[head]))
|
||||
@@ -1,112 +0,0 @@
|
||||
import psutil
|
||||
import os
|
||||
import pwd
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
|
||||
mypid=os.getpid()
|
||||
|
||||
#Check if run as root
|
||||
white_list_pname = [ "systemd", "kthreadd", "apport-gtk"]
|
||||
white_list_pid =[]
|
||||
|
||||
if (os.geteuid()) != 0:
|
||||
print("[-] Not Root")
|
||||
else:
|
||||
#whitelist this python script and all parents
|
||||
cursor=psutil.Process()
|
||||
ende=0
|
||||
while cursor != None:
|
||||
white_list_pid.append(cursor.pid)
|
||||
cursor=cursor.parent()
|
||||
print(white_list_pid)
|
||||
|
||||
mydict = defaultdict(list)
|
||||
ps_dict = defaultdict(list)
|
||||
|
||||
def on_terminate(proc):
|
||||
print("[+] Terminating Child: %s" % (str(proc)))
|
||||
|
||||
def killpid(pid):
|
||||
parent = psutil.Process(pid)
|
||||
|
||||
print(len(parent.children()))
|
||||
children=parent.children(recursive=True)
|
||||
for child in children:
|
||||
try:
|
||||
child.terminate()
|
||||
except Exception as e :
|
||||
print("[-] FAILED - Terminating Child: %s" % (str(child)))
|
||||
print("[-] ERROR: %s" % str(e))
|
||||
|
||||
|
||||
gone, still_alive = psutil.wait_procs(children, timeout=3, callback=on_terminate)
|
||||
|
||||
for child in still_alive:
|
||||
try:
|
||||
child.kill()
|
||||
except Exception as e :
|
||||
print("[-] FAILED - Terminating Child: %s" % (str(child)))
|
||||
print("[-] ERROR: %s" % str(e))
|
||||
else:
|
||||
print("[+] Terminating Child: %s" % (str(child)))
|
||||
try:
|
||||
parent.terminate()
|
||||
parent.wait(timeout=3)
|
||||
parent.kill()
|
||||
except Exception as e:
|
||||
print("[-] FAILED - Killing Process: %s" % (str(parent)))
|
||||
print("[-] ERROR: %s" % str(e))
|
||||
else:
|
||||
print("[+] Process Killes: %s" % (str(parent)))
|
||||
|
||||
|
||||
|
||||
def printproc(p: psutil.Process):
|
||||
return "{0}({1})".format(p.name(),p.pid())
|
||||
|
||||
|
||||
def printchild(p: psutil.Process):
|
||||
output=printproc(p) + "-"
|
||||
for c in p.children():
|
||||
output+=printproc(c)
|
||||
|
||||
|
||||
#Fill ps_dict with processes
|
||||
for proc in psutil.process_iter():
|
||||
try:
|
||||
pinfo = proc.as_dict(attrs=['pid','uids','ppid','name','create_time','terminal','username'])
|
||||
except psutil.NoSuchProcess:
|
||||
pass
|
||||
else:
|
||||
pid=str(pinfo['pid'])
|
||||
ps_dict[pid]=pinfo
|
||||
|
||||
|
||||
#Walk ps_dict and fill in missing information
|
||||
for key in ps_dict:
|
||||
p=ps_dict[key]
|
||||
ppid=str(p['ppid'])
|
||||
if ppid in ps_dict:
|
||||
pp=ps_dict[ppid]
|
||||
p['ppname'] = pp['name']
|
||||
p['ppusername'] = pp['username']
|
||||
p['ppuids'] = pp['uids']
|
||||
p['ppcreate_time'] = pp['create_time']
|
||||
|
||||
|
||||
#Kill all escalators
|
||||
to_kill=[]
|
||||
|
||||
for key in ps_dict:
|
||||
p=ps_dict[key]
|
||||
if 'ppusername' in p and 'real=0' in str(p['uids']) and p['username'] not in p['ppusername']:
|
||||
if p['name'] not in white_list_pname:
|
||||
print("[+] Escalted Process found: %s (%s)" % (str(p['name']),str(p['pid'])))
|
||||
printchild(psutil.Process(p['pid']))
|
||||
|
||||
|
||||
|
||||
for pid in to_kill:
|
||||
if pid not in white_list_pid:
|
||||
killpid(pid)
|
||||
@@ -1,17 +0,0 @@
|
||||
import math
|
||||
x=1
|
||||
notfound=1
|
||||
while notfound:
|
||||
silber=math.pow(x,2)
|
||||
ungerade=math.floor(silber/16.)%2
|
||||
rest=silber%16
|
||||
# print str(silber) + " " + str(ungerade)
|
||||
if ungerade == 1 and rest>1 and rest<9:
|
||||
print "rest passt"
|
||||
print x
|
||||
print silber
|
||||
print rest
|
||||
print 16-rest
|
||||
notfound=0
|
||||
x+=1
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
curl 'https://score.code.unibw-muenchen.de/quali/flag' -H 'Authorization: Basic Y3RmMjAxOXF1YWxpOmN0ZjIwMTl0aDM1dGhlbGVtM250' -H 'Sec-Fetch-Site: same-origin' -H 'Origin: https://score.code.unibw-muenchen.de' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-DE,en;q=0.9,de-DE;q=0.8,de;q=0.7,en-US;q=0.6' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36' -H 'Sec-Fetch-Mode: cors' -H 'Content-Type: application/json;charset=UTF-8' -H 'Accept: application/json, text/plain, */*' -H 'Referer: https://score.code.unibw-muenchen.de/quali/' -H 'Cookie: connect.sid=s%3AYfJKqsKR9tYJTPFRUfgTGr3-r306-LL2.yo4tGwhIG%2FaqwiHCmEJgj%2Blr1m7wTd1OKN0BHGLEHt4; io=uqljJkFKOYy_3X_QAAlQ' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary '{"flag":"$1"}' --compressed
|
||||
sleep 6
|
||||
@@ -1,125 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import pprint
|
||||
import math
|
||||
import itertools
|
||||
try:
|
||||
import tqdm
|
||||
has_tqdm=True
|
||||
except ImportError:
|
||||
print("Install tqdm for Progressbar! (pip3 install tqdm)")
|
||||
has_tqdm=False
|
||||
|
||||
|
||||
secret="OUHRSTHFSOENOFETURFELIRFTSNEMOEEMELNTARETOKCAETBFIHFTTTNMEELEEOHYBAERORCRSEDNCEUUTHITOYRSTEDSBEIEOTNLRMOEFPOHHAYLAGXYISNIARAUABGBURILFERPEEHTECDINNDITHFFIEHTKESYTDHEREOALGNABSMWEHVEFSOAMETAOCRFTAHEOFSINAMEOTRNGRINTHFFIEHTIEGMELNTSTEOMCOHEOWTEWREAIDANHTRARARTEHEETVFIYREAHVSAONDPROSTRAEUOYCTTTHWISANMUHETENTIISEDHETSUSENTEITNG OOLEEB L"
|
||||
col_key="EJALMVWUSTRPOBY" # (16)missing 1 char
|
||||
row_key="GHPTYPAMTAPQRNDHD" # (21) missing 4 chars one of which is 'D'
|
||||
col_alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
row_alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
|
||||
def cell_length(text_length,key_length):
|
||||
return math.ceil(text_length/key_length)
|
||||
|
||||
def padded_length(text_length,key_length):
|
||||
return cell_length(text_length,key_length)*key_length
|
||||
|
||||
def revert_key(enc_key):
|
||||
return [x[0] for x in sorted(enumerate(enc_key), key=lambda x: x[1])]
|
||||
|
||||
def mosh(text,enc_key):
|
||||
tmp=sorted(zip(text,enc_key), key=lambda x: x[1])
|
||||
return [x[0] for x in tmp]
|
||||
|
||||
def cols(text,key_length):
|
||||
# col_length=cell_length(len(text),key_length)
|
||||
columns=[ "" for i in range(0,key_length) ]
|
||||
cursor=0
|
||||
for c in text:
|
||||
columns[cursor%key_length]+=c
|
||||
cursor += 1
|
||||
return columns
|
||||
|
||||
def rows(text,key_length):
|
||||
# row_length=math.ceil(len(text)/key_length)
|
||||
rows=[text[i:i+key_length] for i in range(0,len(text),key_length)]
|
||||
return rows
|
||||
|
||||
def cols_to_str(a):
|
||||
max_length=max([len(i) for i in a] )
|
||||
result=""
|
||||
for i in range(0,max_length):
|
||||
for x in a:
|
||||
try:
|
||||
result+=x[i]
|
||||
except:
|
||||
pass
|
||||
return result
|
||||
|
||||
def rows_to_str(a):
|
||||
return "".join(a)
|
||||
|
||||
def pcols(a):
|
||||
print("COLUMS:")
|
||||
text=cols_to_str(a)
|
||||
split_text=rows(text,len(a))
|
||||
for x in split_text:
|
||||
print(x)
|
||||
|
||||
def prows(a,header=None):
|
||||
print("ROWS:")
|
||||
counter=0
|
||||
for x in a:
|
||||
if header:
|
||||
heading="{}".format(header[counter]).ljust(5)
|
||||
else:
|
||||
heading="{}".format(counter).ljust(5)
|
||||
counter+=1
|
||||
print("%s : %s"%(heading,x))
|
||||
|
||||
def encode(text,key):
|
||||
text=text.ljust(padded_length(len(text),len(key)),'_')
|
||||
columnized_text=cols(text,len(key))
|
||||
shuffled_colums=mosh(columnized_text,key)
|
||||
return rows_to_str(shuffled_colums)
|
||||
|
||||
def decode(text,key):
|
||||
row_data=rows(text,cell_length(len(text), len(key)))
|
||||
reorderd=mosh(row_data,revert_key(key))
|
||||
return cols_to_str(reorderd)
|
||||
|
||||
def get_col_keys():
|
||||
for x in col_alpha:
|
||||
yield col_key+x
|
||||
|
||||
def get_row_keys():
|
||||
for x in row_alpha:
|
||||
for y in row_alpha:
|
||||
for z in row_alpha:
|
||||
# for d in row_alpha:
|
||||
# yield(row_key+d+x+y+z)
|
||||
yield(row_key+"D"+x+y+z)
|
||||
yield(row_key+x+"D"+y+z)
|
||||
yield(row_key+x+y+"D"+z)
|
||||
yield(row_key+x+y+z+"D")
|
||||
|
||||
def normalize_keys(key_generator):
|
||||
k = [revert_key(revert_key(x)) for x in key_generator]
|
||||
k.sort()
|
||||
return list(k for k,_ in itertools.groupby(k))
|
||||
|
||||
def decryptor():
|
||||
rowkeys=normalize_keys(get_row_keys())
|
||||
colkeys=normalize_keys(get_col_keys())
|
||||
if has_tqdm:
|
||||
pbar=tqdm.tqdm(total=(len(rowkeys)*len(colkeys)))
|
||||
|
||||
with open("normalized2.txt",'w') as f:
|
||||
for col_key in colkeys:
|
||||
for row_key in rowkeys:
|
||||
text=encode(encode(secret,col_key),row_key)
|
||||
f.write("{};{};{}\n".format(row_key,col_key,text))
|
||||
if has_tqdm:
|
||||
pbar.update(1)
|
||||
if has_tqdm:
|
||||
pbar.close()
|
||||
|
||||
decryptor()
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Create dirs
|
||||
mkdir -p timesketch/{data/postgresql,data/elasticsearch,logs,etc,etc/timesketch,etc/timesketch/sigma/rules,upload}
|
||||
|
||||
echo -n "* Setting default config parameters.."
|
||||
POSTGRES_USER="timesketch"
|
||||
POSTGRES_PASSWORD="$(< /dev/urandom tr -dc A-Za-z0-9 | head -c 32 ; echo)"
|
||||
POSTGRES_ADDRESS="postgres"
|
||||
POSTGRES_PORT=5432
|
||||
SECRET_KEY="$(< /dev/urandom tr -dc A-Za-z0-9 | head -c 32 ; echo)"
|
||||
ELASTIC_ADDRESS="elasticsearch"
|
||||
ELASTIC_PORT=9200
|
||||
REDIS_ADDRESS="redis"
|
||||
REDIS_PORT=6379
|
||||
GITHUB_BASE_URL="https://raw.githubusercontent.com/google/timesketch/master"
|
||||
ELASTIC_MEM_USE_GB=$(cat /proc/meminfo | grep MemTotal | awk '{printf "%.0f", ($2 / 1000000 / 2)}')
|
||||
echo "OK"
|
||||
echo "* Setting Elasticsearch memory allocation to ${ELASTIC_MEM_USE_GB}GB"
|
||||
|
||||
# Docker compose and configuration
|
||||
echo -n "* Fetching configuration files.."
|
||||
curl $GITHUB_BASE_URL/docker/release/docker-compose.yml > timesketch/docker-compose.yml
|
||||
curl $GITHUB_BASE_URL/docker/release/config.env > timesketch/config.env
|
||||
|
||||
# Fetch default Timesketch config files
|
||||
curl $GITHUB_BASE_URL/data/timesketch.conf > timesketch/etc/timesketch/timesketch.conf
|
||||
curl $GITHUB_BASE_URL/data/tags.yaml > timesketch/etc/timesketch/tags.yaml
|
||||
curl $GITHUB_BASE_URL/data/plaso.mappings > timesketch/etc/timesketch/plaso.mappings
|
||||
curl $GITHUB_BASE_URL/data/generic.mappings > timesketch/etc/timesketch/generic.mappings
|
||||
curl $GITHUB_BASE_URL/data/features.yaml > timesketch/etc/timesketch/features.yaml
|
||||
curl $GITHUB_BASE_URL/data/sigma_config.yaml > timesketch/etc/timesketch/sigma_config.yaml
|
||||
curl $GITHUB_BASE_URL/data/sigma/rules/lnx_susp_zenmap.yml > timesketch/etc/timesketch/sigma/rules/lnx_susp_zenmap.yml
|
||||
curl $GITHUB_BASE_URL/contrib/nginx.conf > timesketch/etc/nginx.conf
|
||||
echo "OK"
|
||||
|
||||
# Create a minimal Timesketch config
|
||||
echo -n "* Edit configuration files.."
|
||||
sed -i 's#SECRET_KEY = \x27\x3CKEY_GOES_HERE\x3E\x27#SECRET_KEY = \x27'$SECRET_KEY'\x27#' timesketch/etc/timesketch/timesketch.conf
|
||||
|
||||
# Set up the Elastic connection
|
||||
sed -i 's#^ELASTIC_HOST = \x27127.0.0.1\x27#ELASTIC_HOST = \x27'$ELASTIC_ADDRESS'\x27#' timesketch/etc/timesketch/timesketch.conf
|
||||
sed -i 's#^ELASTIC_PORT = 9200#ELASTIC_PORT = '$ELASTIC_PORT'#' timesketch/etc/timesketch/timesketch.conf
|
||||
|
||||
# Set up the Redis connection
|
||||
sed -i 's#^UPLOAD_ENABLED = False#UPLOAD_ENABLED = True#' timesketch/etc/timesketch/timesketch.conf
|
||||
sed -i 's#^UPLOAD_FOLDER = \x27/tmp\x27#UPLOAD_FOLDER = \x27/usr/share/timesketch/upload\x27#' timesketch/etc/timesketch/timesketch.conf
|
||||
|
||||
sed -i 's#^CELERY_BROKER_URL =.*#CELERY_BROKER_URL = \x27redis://'$REDIS_ADDRESS':'$REDIS_PORT'\x27#' timesketch/etc/timesketch/timesketch.conf
|
||||
sed -i 's#^CELERY_RESULT_BACKEND =.*#CELERY_RESULT_BACKEND = \x27redis://'$REDIS_ADDRESS':'$REDIS_PORT'\x27#' timesketch/etc/timesketch/timesketch.conf
|
||||
|
||||
# Set up the Postgres connection
|
||||
sed -i 's#postgresql://<USERNAME>:<PASSWORD>@localhost#postgresql://'$POSTGRES_USER':'$POSTGRES_PASSWORD'@'$POSTGRES_ADDRESS':'$POSTGRES_PORT'#' timesketch/etc/timesketch/timesketch.conf
|
||||
|
||||
sed -i 's#^POSTGRES_PASSWORD=#POSTGRES_PASSWORD='$POSTGRES_PASSWORD'#' timesketch/config.env
|
||||
sed -i 's#^ELASTIC_MEM_USE_GB=#ELASTIC_MEM_USE_GB='$ELASTIC_MEM_USE_GB'#' timesketch/config.env
|
||||
|
||||
ln -s ./config.env ./timesketch/.env
|
||||
echo "OK"
|
||||
echo "* Installation done."
|
||||
|
||||
echo
|
||||
echo "Start the system:"
|
||||
echo "1. cd timesketch"
|
||||
echo "2. docker-compose up -d"
|
||||
echo "3. docker-compose exec timesketch-web tsctl add_user --username <USERNAME>"
|
||||
echo
|
||||
echo "WARNING: The server is running without encryption."
|
||||
echo "Follow the instructions to enable SSL to secure the communications:"
|
||||
echo "https://github.com/google/timesketch/blob/master/docs/Installation.md"
|
||||
echo
|
||||
echo
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
file="${1}"
|
||||
stag="${2}"
|
||||
max=0
|
||||
open=0
|
||||
grep -Po "</?${stag}" "${file}" | while read tag; do
|
||||
if [[ "$tag" == "<${stag}" ]] ; then
|
||||
(( open++ ))
|
||||
else
|
||||
(( open--))
|
||||
fi
|
||||
|
||||
echo "$open - $max"
|
||||
|
||||
if [[ $open -gt $max ]] ; then
|
||||
max=$open
|
||||
fi
|
||||
done
|
||||
@@ -1,23 +0,0 @@
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
image=sys.argv[1]
|
||||
inode=sys.argv[2]
|
||||
|
||||
|
||||
output = subprocess.check_output(f"fls -F {image} {inode}", shell=True)
|
||||
|
||||
output=output.decode()
|
||||
result = {}
|
||||
for row in output.split('\n'):
|
||||
if ':' in row:
|
||||
key, value = row.split(':')
|
||||
idx = key.split(" ")[-1]
|
||||
fsid = idx.split("-")[0]
|
||||
result[fsid] = value.strip()
|
||||
|
||||
for fsid in result:
|
||||
print(f"Writing Inode {fsid} -> {result[fsid]} ")
|
||||
outfile=open(result[fsid],'w')
|
||||
subprocess.run(["icat", image, fsid],stdout=outfile)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
if ! which zathura 1>/dev/null 2>&1 ; then
|
||||
echo "zathura pdf viewer not found"
|
||||
echo "sudo apt install zathura"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! which docker 1>/dev/null 2>&1 ; then
|
||||
echo "docker not found"
|
||||
echo "sudo apt install docker.io"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -f "${1}" ]] ; then
|
||||
cat "${1}" | docker run -i --rm tabledevil/flatpdf | zathura -
|
||||
fi
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import sys
|
||||
import re
|
||||
|
||||
ignore_case=True
|
||||
|
||||
pattern=str(sys.argv[1])
|
||||
if ignore_case:
|
||||
pattern=pattern.lower()
|
||||
filename=str(sys.argv[2])
|
||||
shortpattern=""
|
||||
print("Pattern is '%s'" % pattern)
|
||||
chars={}
|
||||
|
||||
for char in pattern:
|
||||
if not char in chars:
|
||||
newchar={}
|
||||
newchar['char']=char
|
||||
newchar['count']=pattern.count(char)
|
||||
newchar['idx']=[m.start() for m in re.finditer(re.escape(char),pattern)]
|
||||
print(char)
|
||||
#print("Char '%s' occurs %d times in pattern %s" % (c,newchar['count'],newchar['idx']))
|
||||
chars[char]=newchar
|
||||
shortpattern=shortpattern + char
|
||||
try:
|
||||
f=file(filename,'r')
|
||||
except:
|
||||
print("[-] Can't open File %s" % filename)
|
||||
exit(1)
|
||||
|
||||
print(shortpattern)
|
||||
longest_match_yet=0
|
||||
def get_char():
|
||||
return f.read(1).lower() if ignore_case else f.read(1)
|
||||
|
||||
while longest_match_yet<len(pattern):
|
||||
# read_a_char=f.read(1)
|
||||
read_a_char=get_char()
|
||||
if read_a_char in shortpattern and read_a_char in chars:
|
||||
#candidate
|
||||
for index in chars[read_a_char]['idx']:
|
||||
#lets see if its long enough
|
||||
possible_length=len(pattern) - index
|
||||
if possible_length>longest_match_yet:
|
||||
sub_pattern=pattern[(index+1):]
|
||||
match_so_far=read_a_char
|
||||
offset=f.tell()
|
||||
# print("Possible new Match starting with %s found at %d" % (read_a_char,offset))
|
||||
# print("trying to find rest of pattern '%s'" % sub_pattern)
|
||||
x=1
|
||||
for char_to_compare in sub_pattern:
|
||||
# next_char=f.read(1)
|
||||
next_char=get_char()
|
||||
if not read_a_char:
|
||||
print("No more Chars to consume in File")
|
||||
break
|
||||
# print("comparing %s <> %s (%d)" % (next_char,char_to_compare,x))
|
||||
if next_char != char_to_compare:
|
||||
break
|
||||
match_so_far=match_so_far+next_char
|
||||
x=x+1
|
||||
# print("matching endet with %d matching chars (%d)" % (x,longest_match_yet))
|
||||
if x > longest_match_yet:
|
||||
#new longest Match
|
||||
print("found new longest match %s at %d" % (match_so_far,offset))
|
||||
longest_match_yet=x
|
||||
f.seek(offset)
|
||||
|
||||
if not read_a_char:
|
||||
print("No more Chars to consume in File")
|
||||
break
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Stolen from Hippie2000 and modified by Jackfritt ;)
|
||||
# Stolen from Jackfritt and modified by Chaosmaster :-P
|
||||
ipddr="fritz.box"
|
||||
unset dumpfile
|
||||
unset passwd
|
||||
if [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ ! $1 ]; then
|
||||
echo "Usage: $0 <PASSWORD> [<DUMPFILE>] [<IP>]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ $1 ] && passwd=$1
|
||||
[ $2 ] && dumpfile="-w $2"
|
||||
[ $3 ] && ipaddr=$3
|
||||
|
||||
# Challenge abholen
|
||||
ChallengeXML=`wget -O - "http://$ipddr/cgi-bin/webcm?getpage=../html/login_sid.xml" 2>/dev/null| grep Challenge`
|
||||
Challenge=`echo $ChallengeXML | awk '{match($0,/>[^<>]+</); print substr($0,RSTART+1,RLENGTH-2)}'`
|
||||
|
||||
# login aufbauen und hashen
|
||||
CPSTR="$Challenge-$passwd"
|
||||
MD5=`echo -n $CPSTR | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}'`
|
||||
RESPONSE="$Challenge-$MD5"
|
||||
POSTDATA="login:command/response=$RESPONSE&getpage=../html/de/menus/menu2.html"
|
||||
|
||||
# login senden und SID herausfischen
|
||||
SID=`wget -O - --post-data="$POSTDATA" "http://$ipddr/cgi-bin/webcm" 2>/dev/null| grep "name=\"sid\"" | head -1 | awk '{match($0,/value="[^"]+"/); print substr($0,RSTART+7,RLENGTH-8)}'`
|
||||
|
||||
# Internet Capture
|
||||
wget -O - "http://$ipddr/cgi-bin/capture_notimeout?ifaceorminor=3-17 \
|
||||
&snaplen=1600&capture=Start&sid=$SID" 2>/dev/null | \
|
||||
wireshark -k $dumpfile -i -
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/bin/sh
|
||||
IP="fritz.box"
|
||||
echo -n Password:
|
||||
read -s Passwd
|
||||
|
||||
# Challenge abholen
|
||||
Challenge=`wget -O - "http://$IP/login_sid.lua" 2>/dev/null | sed 's/.*<Challenge>\(.*\)<\/Challenge>.*/\1/'`
|
||||
|
||||
# login aufbauen und hashen
|
||||
CPSTR="$Challenge-$Passwd"
|
||||
MD5=`echo -n $CPSTR | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}'`
|
||||
RESPONSE="$Challenge-$MD5"
|
||||
POSTDATA="?username=&response=$RESPONSE"
|
||||
|
||||
# login senden und SID herausfischen
|
||||
SID=`wget -O - --post-data="$POSTDATA" "http://$IP/login_sid.lua" 2>/dev/null | sed 's/.*<SID>\(.*\)<\/SID>.*/\1/'`
|
||||
|
||||
# Internet Capture
|
||||
#Schnittstelle 1(Internet)=3-17
|
||||
#wget -O - "http://$IP/cgi-bin/capture_notimeout?ifaceorminor=3-17 \
|
||||
#alle Schnittstellen =3-0
|
||||
#wget -O - "http://$IP/cgi-bin/capture_notimeout?ifaceorminor=3-0 \
|
||||
#&snaplen=1600&capture=Start&sid=$SID" 2>/dev/null | \
|
||||
#tshark -i - -S -l -N nmtC
|
||||
#wget -O - "http://$IP/cgi-bin/capture_notimeout?ifaceorminor=3-0 \
|
||||
#Externe Schnittstelle
|
||||
#wget -O - "http://$IP/cgi-bin/capture_notimeout?ifaceorminor=3-17 \
|
||||
#Lokal LAN
|
||||
#wget -O - "http://$IP/cgi-bin/capture_notimeout?ifaceorminor=1-eth0&snaplen=1600&capture=Start&sid=$SID" 2>/dev/null | tshark -i - -S -l -N nmtC
|
||||
wget -O - "http://$IP/cgi-bin/capture_notimeout?ifaceorminor=1-eth0&snaplen=1600&capture=Start&sid=$SID" 2>/dev/null | tcpdump -r - -w /tmp/trace -W 48 -G 1800 -C 100 -K -n
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
pattern='\b(([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])\b'
|
||||
#count ips in log
|
||||
count=$(cat $1 | grep -Po $pattern | sort -u | wc -l)
|
||||
#create ip_map for translation of IPs
|
||||
paste <(cat $1 | grep -Po $pattern | sort -u) <(paste <(shuf <(for i in {0..255};do echo $i; done)) <(shuf <(for i in {0..255};do echo $i; done)) <(shuf <(for i in {0..255};do echo $i; done)) <(shuf <(for i in {0..255};do echo $i; done)) | tr "\t" "." | head -n $count) > ${1}.ip_map
|
||||
|
||||
#awk script to replace IPs
|
||||
awk_script='
|
||||
NR == FNR {
|
||||
rep[$1] = $2
|
||||
next
|
||||
}
|
||||
|
||||
{
|
||||
for (key in rep)
|
||||
gsub(key, rep[key])
|
||||
print
|
||||
}
|
||||
'
|
||||
#OUTPUT
|
||||
cat $1 | awk "$awk_script" ${1}.ip_map -
|
||||
|
||||
echo "Lookup-Table is stored in ${1}.ip_map" >&2
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import zipfile
|
||||
import sys
|
||||
import hashlib
|
||||
|
||||
zip_file_name = sys.argv[1]
|
||||
|
||||
with zipfile.ZipFile(zip_file_name, 'r') as zf:
|
||||
print(f"======== Filelisting for {zip_file_name} ========")
|
||||
for file_info in zf.filelist:
|
||||
date_time = file_info.date_time
|
||||
with zf.open(file_info) as zip_file:
|
||||
content = zip_file.read()
|
||||
md5 = hashlib.md5(content).hexdigest()
|
||||
print(f"{file_info.filename} ({file_info.file_size}) {md5} {date_time[0]}/{date_time[1]:02}/{date_time[2]:02} {date_time[3]:02}:{date_time[4]:02}:{date_time[5]:02}")
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/python3
|
||||
a="ksabvdkbvksajbvkjsabvkjsabvkjabsvkjsabvbvghahfksajfkjhcxvsLHREFIsdfsdfsdfasdfasdfasfd"
|
||||
b="kucasdhkausughaksdflsad iajfdaslfdlgajldsag asldivclsadgnaksndglkasdjasdvc"
|
||||
def longest_common_substring(s1, s2):
|
||||
m = [[0] * (1 + len(s2)) for i in range(1 + len(s1))]
|
||||
longest, x_longest = 0, 0
|
||||
for x in range(1, 1 + len(s1)):
|
||||
for y in range(1, 1 + len(s2)):
|
||||
if s1[x - 1] == s2[y - 1]:
|
||||
m[x][y] = m[x - 1][y - 1] + 1
|
||||
if m[x][y] > longest:
|
||||
longest = m[x][y]
|
||||
x_longest = x
|
||||
else:
|
||||
m[x][y] = 0
|
||||
return s1[x_longest - longest: x_longest]
|
||||
|
||||
print(longest_common_substring(a, b))
|
||||
1
codegrab/imphash.go
Normal file
1
codegrab/imphash.go
Normal file
@@ -0,0 +1 @@
|
||||
package main
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import pefile
|
||||
import sys
|
||||
pe=pefile.PE(sys.argv[1])
|
||||
print(pe.get_imphash())
|
||||
@@ -1,12 +0,0 @@
|
||||
BEGIN{
|
||||
if (max=="") max=3
|
||||
cmd="for i in {0..255} | shuf "
|
||||
while ( ( cmd | getline result ) > 0 ) {
|
||||
print result
|
||||
}
|
||||
}
|
||||
{
|
||||
print
|
||||
for (i=4; i >max ; i-=1)
|
||||
print $i
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import simplejson
|
||||
import json
|
||||
|
||||
def put(data, filename):
|
||||
try:
|
||||
jsondata = simplejson.dumps(data, indent=4, skipkeys=True, sort_keys=True)
|
||||
fd = open(filename, 'w')
|
||||
fd.write(jsondata)
|
||||
fd.close()
|
||||
except Exception as e:
|
||||
print('ERROR writing', filename)
|
||||
print( e)
|
||||
pass
|
||||
|
||||
def get(filename):
|
||||
returndata = {}
|
||||
try:
|
||||
fd = open(filename, 'r')
|
||||
text = fd.read()
|
||||
fd.close()
|
||||
returndata = json.read(text)
|
||||
# Hm. this returns unicode keys...
|
||||
#returndata = simplejson.loads(text)
|
||||
except:
|
||||
print('COULD NOT LOAD:', filename)
|
||||
return returndata
|
||||
|
||||
|
||||
# print(mail.filename)
|
||||
# print(mail.status)
|
||||
|
||||
# import gzip
|
||||
# import json
|
||||
#
|
||||
# # writing
|
||||
# with gzip.GzipFile(jsonfilename, 'w') as outfile:
|
||||
# for obj in objects:
|
||||
# outfile.write(json.dumps(obj) + '\n')
|
||||
#
|
||||
# # reading
|
||||
# with gzip.GzipFile(jsonfilename, 'r') as isfile:
|
||||
# for line in infile:
|
||||
# obj = json.loads(line)
|
||||
# # process obj
|
||||
# picklefile=open("mails.dump",'wb')
|
||||
# for mail in list_of_mail:
|
||||
# pickle.dump(mail, picklefile )
|
||||
#
|
||||
# picklefile.close()
|
||||
|
||||
171
codegrab/kv.py
171
codegrab/kv.py
@@ -1,171 +0,0 @@
|
||||
import sys
|
||||
from pyparsing import *
|
||||
from icecream import ic
|
||||
|
||||
sys.setrecursionlimit(3000)
|
||||
ParserElement.enablePackrat()
|
||||
ppc = pyparsing_common
|
||||
integer = ppc.integer
|
||||
variable = Word(alphas, exact=1)
|
||||
operand = integer | variable
|
||||
|
||||
undop = Literal("*")
|
||||
oderop = Literal("+")
|
||||
notop = Literal("!")
|
||||
|
||||
expr = infixNotation(
|
||||
operand,
|
||||
[
|
||||
(notop, 1, opAssoc.RIGHT),
|
||||
(undop, 2, opAssoc.LEFT),
|
||||
(oderop, 2, opAssoc.LEFT),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class operation():
|
||||
|
||||
def _unpack(self,data):
|
||||
if isinstance(data,str):
|
||||
if len(data) == 1:
|
||||
return data
|
||||
else:
|
||||
raise ValueError
|
||||
else:
|
||||
return operation(data)
|
||||
|
||||
def __init__(self,data) -> None:
|
||||
if isinstance(data,str):
|
||||
data=expr.parseString(data.lower().strip()).asList()
|
||||
|
||||
self.operands = []
|
||||
self.operator = ""
|
||||
if isinstance(data,list):
|
||||
if len(data) == 1:
|
||||
data = data[0]
|
||||
|
||||
if isinstance(data,list):
|
||||
if len(data) == 2:
|
||||
self.operator = data[0]
|
||||
self.operands.append(self._unpack(data[1]))
|
||||
|
||||
if len(data) >2:
|
||||
self.operator = data[1]
|
||||
for x in data:
|
||||
if x == self.operator:
|
||||
continue
|
||||
else:
|
||||
self.operands.append(self._unpack(x))
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
|
||||
def __tt(vars):
|
||||
if len(vars) == 1:
|
||||
yield {vars[0] : False}
|
||||
yield {vars[0] : True}
|
||||
else:
|
||||
for rv in operation.__tt(vars[1:]):
|
||||
yield {vars[0] : False, **rv }
|
||||
yield {vars[0] : True, **rv }
|
||||
|
||||
|
||||
|
||||
def print_tt(self):
|
||||
myvars = self.get_vars()
|
||||
print(" " + " ".join(myvars)+ " Y")
|
||||
print("--" * len(myvars) + "-----")
|
||||
tt=operation.__tt(myvars)
|
||||
for line in tt:
|
||||
r=[f"{'1' if line[x] else '0'}" for x in line]
|
||||
result="1" if self.solve(line) else "0"
|
||||
print(" " + " ".join(r) + " " + result)
|
||||
|
||||
|
||||
|
||||
def __repr__(self) -> str:
|
||||
if self.operator == "!":
|
||||
return f"NICHT {self.operands[0]}"
|
||||
else:
|
||||
if self.operator == "*":
|
||||
return "(" + " UND ".join([str(x) for x in self.operands]) + ")"
|
||||
|
||||
if self.operator == "+":
|
||||
return "(" + " ODER ".join([str(x) for x in self.operands]) + ")"
|
||||
|
||||
def solve(self,values):
|
||||
for vary in self.get_vars():
|
||||
if not vary in values:
|
||||
raise KeyError
|
||||
if self.operator == '!':
|
||||
if isinstance(self.operands[0],operation):
|
||||
return not self.operands[0].solve(values)
|
||||
else:
|
||||
return not values[self.operands[0]]
|
||||
|
||||
if self.operator == '*':
|
||||
result = True
|
||||
for operand in self.operands:
|
||||
if isinstance(operand,operation):
|
||||
result = result and operand.solve(values)
|
||||
else:
|
||||
result = result and values[operand]
|
||||
return result
|
||||
|
||||
if self.operator == '+':
|
||||
result = False
|
||||
for operand in self.operands:
|
||||
if isinstance(operand,operation):
|
||||
result = result or operand.solve(values)
|
||||
else:
|
||||
result = result or values[operand]
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def get_vars(self):
|
||||
vars = []
|
||||
for x in self.operands:
|
||||
if isinstance(x,operation):
|
||||
vars += x.get_vars()
|
||||
else:
|
||||
vars.append(x)
|
||||
return list(dict.fromkeys(vars))
|
||||
|
||||
|
||||
@property
|
||||
def hasop(self):
|
||||
return len(self.operator)>0
|
||||
|
||||
|
||||
|
||||
|
||||
test = [
|
||||
"(a*b+(a*(!c+b))*c)",
|
||||
"a*b+(a*(!c+b)*c)",
|
||||
"a *b+ ( a * ( ! c + (b) ) *c)",
|
||||
"a*b+c+d",
|
||||
"a*b+c",
|
||||
"!a*!(a+b*!c)",
|
||||
]
|
||||
|
||||
testval={'a':True,'b':False,'c':True, 'd':False}
|
||||
|
||||
def tt(vars):
|
||||
if len(vars) == 1:
|
||||
yield {vars[0] : False}
|
||||
yield {vars[0] : True}
|
||||
else:
|
||||
for rv in tt(vars[1:]):
|
||||
yield {vars[0] : False, **rv }
|
||||
yield {vars[0] : True, **rv }
|
||||
|
||||
|
||||
|
||||
|
||||
for t in test:
|
||||
ic(t)
|
||||
c=operation(t)
|
||||
c.print_tt()
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import re
|
||||
import json
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-p", "--preserve", action='store_true', help="preserve original logline in dict")
|
||||
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
|
||||
parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
|
||||
args = parser.parse_args()
|
||||
|
||||
data = args.infile.readlines()
|
||||
|
||||
kv_pat = re.compile('(?P<key>[^= ]+)=(?P<value>"[^"]+"|\S+)')
|
||||
|
||||
log=[]
|
||||
for line in data:
|
||||
line_dict={}
|
||||
line = line.strip()
|
||||
matches=kv_pat.findall(line)
|
||||
for match in matches:
|
||||
line_dict[match[0]] = match[1].strip('"')
|
||||
if args.preserve:
|
||||
line_dict['original_logline'] = line
|
||||
log.append(line_dict)
|
||||
|
||||
json.dump(log,args.outfile)
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
index=0
|
||||
cat $@ | hxselect .qtext -s "@TKE@" | tr -d "\n" | tr -s " " | sed -e 's/@TKE@/\n/g' | while read block; do
|
||||
(( index++ ))
|
||||
echo "Frage $index"
|
||||
echo "=================="
|
||||
frage=$(echo $block | hxnormalize -e | sed -ne '/div class=qtext/,/div class=answer/p' | html2text)
|
||||
echo $frage
|
||||
echo "Antworten:"
|
||||
answ=$(echo $block | hxnormalize -e | hxselect .answers )
|
||||
echo $answ
|
||||
echo "Erklärung:"
|
||||
expl=$(echo $block | hxnormalize -e | hxselect .explanation )
|
||||
echo $expl
|
||||
echo "=================="
|
||||
echo "=================="
|
||||
|
||||
done
|
||||
@@ -1,65 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import curses
|
||||
from operator import itemgetter
|
||||
import time
|
||||
|
||||
# Number of top items to be displayed
|
||||
N = 10
|
||||
|
||||
|
||||
def gen_output(item_dict, N=10):
|
||||
"""
|
||||
Generate a formatted output string for the top N items in item_dict.
|
||||
|
||||
:param item_dict: A dictionary containing items and their counts
|
||||
:param N: The number of top items to be displayed
|
||||
:return: A generator yielding formatted strings for each of the top N items
|
||||
"""
|
||||
top_items = dict(sorted(item_dict.items(), key=itemgetter(1), reverse=True)[:N])
|
||||
count_length = len(str(max(top_items.values())))
|
||||
|
||||
for i, key in enumerate(top_items):
|
||||
yield i, f'{i + 1:3} : [{top_items[key]:{count_length}}] {key}'
|
||||
|
||||
|
||||
def main(screen):
|
||||
"""
|
||||
Main function to read input lines, maintain a count of each unique line, and
|
||||
periodically display the top N lines with the highest counts using curses.
|
||||
|
||||
:param screen: A curses window object
|
||||
"""
|
||||
if not sys.stdin.isatty(): # Check if the input comes from a pipe
|
||||
# Initialize an empty dictionary to store unique input lines and their counts
|
||||
toplist = {}
|
||||
|
||||
# Set the next screen update time
|
||||
t_update = time.time() + 1
|
||||
|
||||
for line in sys.stdin:
|
||||
line = line.strip()
|
||||
|
||||
# Increment the count for each unique input line
|
||||
if line in toplist:
|
||||
toplist[line] += 1
|
||||
else:
|
||||
toplist[line] = 1
|
||||
|
||||
# Periodically update the screen with the top N lines
|
||||
if time.time() > t_update:
|
||||
for idx, line in gen_output(toplist):
|
||||
screen.addstr(idx, 0, line)
|
||||
screen.refresh()
|
||||
t_update = time.time() + 1
|
||||
|
||||
# Clean up the curses environment and print the final top N lines
|
||||
curses.endwin()
|
||||
for idx, line in gen_output(toplist):
|
||||
print(line)
|
||||
else:
|
||||
print("Usage: cat input_file.txt | ./top_lines.py")
|
||||
print("Or: ./top_lines.py < input_file.txt")
|
||||
|
||||
# Initialize the curses library, run the main function, and restore the terminal state
|
||||
curses.wrapper(main)
|
||||
@@ -1,11 +0,0 @@
|
||||
NR == FNR {
|
||||
rep[$1] = $2
|
||||
next
|
||||
}
|
||||
|
||||
{
|
||||
for (key in rep)
|
||||
gsub(key, rep[key])
|
||||
print
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
PUT _template/template_1
|
||||
{
|
||||
"index_patterns" : ["leak*"],
|
||||
"settings" : {
|
||||
"number_of_shards" : 2,
|
||||
"number_of_replicas" : 0,
|
||||
"refresh_interval": "60s"
|
||||
},
|
||||
|
||||
"mappings": {
|
||||
"credential": {
|
||||
"properties": {
|
||||
"containsDigits": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"containsLowerCase": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"containsSpecial": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"containsUpperCase": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"domain": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 512,
|
||||
"norms" : false
|
||||
},
|
||||
"file": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 1024,
|
||||
"norms" : false
|
||||
},
|
||||
"length": {
|
||||
"type": "short"
|
||||
},
|
||||
"password": {
|
||||
"type": "keyword",
|
||||
"norms" : false,
|
||||
"ignore_above": 512
|
||||
},
|
||||
"passwordMask": {
|
||||
"type": "keyword",
|
||||
"norms" : false,
|
||||
"ignore_above": 512
|
||||
},
|
||||
"user": {
|
||||
"type": "keyword",
|
||||
"norms" : false,
|
||||
"ignore_above": 512
|
||||
},
|
||||
"username": {
|
||||
"type": "keyword",
|
||||
"norms" : false,
|
||||
"ignore_above": 512
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
x = np.linspace(0, 6*np.pi, 100)
|
||||
y = np.sin(x)
|
||||
|
||||
# You probably won't need this if you're embedding things in a tkinter plot...
|
||||
plt.ion()
|
||||
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(111)
|
||||
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma
|
||||
|
||||
for phase in np.linspace(0, 10*np.pi, 500):
|
||||
line1.set_ydata(np.sin(x + phase))
|
||||
fig.canvas.draw()
|
||||
fig.canvas.flush_events()
|
||||
@@ -1,11 +0,0 @@
|
||||
Function Get-Screen
|
||||
{
|
||||
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
|
||||
$size = [Windows.Forms.SystemInformation]::VirtualScreen
|
||||
$bitmap = new-object Drawing.Bitmap $size.width, $size.height
|
||||
$graphics = [Drawing.Graphics]::FromImage($bitmap)
|
||||
$graphics.CopyFromScreen($size.location,[Drawing.Point]::Empty, $size.size)
|
||||
$graphics.Dispose()
|
||||
$bitmap.Save($args[0])
|
||||
$bitmap.Dispose()
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import random
|
||||
|
||||
from random import shuffle
|
||||
from collections import Counter
|
||||
|
||||
|
||||
def main():
|
||||
employees = []
|
||||
for i in range(0, 19):
|
||||
employees.append(1)
|
||||
for i in range(0, 23):
|
||||
employees.append(0)
|
||||
|
||||
count = 0
|
||||
for i in range(1, 1000001):
|
||||
temp = employees[:]
|
||||
shuffle(temp)
|
||||
if Counter(temp[0:11])[1] == 4:
|
||||
count += 1
|
||||
|
||||
print(count / 1000000.)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
sys.exit(0)
|
||||
@@ -1,272 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import os
|
||||
import re
|
||||
import mmh3
|
||||
import string
|
||||
import sys
|
||||
from os import walk
|
||||
from chardet.universaldetector import UniversalDetector
|
||||
from elasticsearch import Elasticsearch
|
||||
from elasticsearch.helpers import bulk
|
||||
from multiprocessing import Pool,Lock
|
||||
import multiprocessing
|
||||
import hashlib
|
||||
import json
|
||||
import argparse
|
||||
|
||||
|
||||
lock = Lock()
|
||||
|
||||
|
||||
def log_to_file(text):
|
||||
global log_filename
|
||||
with lock: # thread blocks at this line until it can obtain lock
|
||||
with open(log_filename, 'a+') as file_log:
|
||||
file_log.write("{}\n".format(text))
|
||||
|
||||
def log_to_console(text):
|
||||
ps=multiprocessing.current_process()
|
||||
with lock: # thread blocks at this line until it can obtain lock
|
||||
print("[{}]:{}".format(ps.pid,text))
|
||||
|
||||
|
||||
def get_mask(s):
|
||||
mask = ""
|
||||
for c in s:
|
||||
if c.isdigit():
|
||||
mask += "?d"
|
||||
elif c.islower():
|
||||
mask += "?l"
|
||||
elif c.isupper():
|
||||
mask += "?u"
|
||||
else:
|
||||
mask += "?s"
|
||||
return mask
|
||||
|
||||
|
||||
def check_special(s):
|
||||
for c in s:
|
||||
if c in string.punctuation or c.isspace():
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def check_upper(s):
|
||||
return any(i.isupper() for i in s)
|
||||
|
||||
|
||||
def check_lower(s):
|
||||
return any(i.islower() for i in s)
|
||||
|
||||
|
||||
def check_digit(s):
|
||||
return any(i.isdigit() for i in s)
|
||||
|
||||
|
||||
# list all files in dir
|
||||
def get_file_enconding(file):
|
||||
detector = UniversalDetector()
|
||||
with open(file, 'rb') as daf:
|
||||
i = 1000
|
||||
for line in daf.readlines():
|
||||
i -= 1
|
||||
detector.feed(line)
|
||||
if detector.done or i == 0:
|
||||
break
|
||||
detector.close()
|
||||
|
||||
r = detector.result
|
||||
return r["encoding"]
|
||||
|
||||
|
||||
patter = re.compile("([^@]+)@([^@]+\.[^@]+)(\s|:|;)(.*)")
|
||||
|
||||
|
||||
def extract_email(line):
|
||||
global patter
|
||||
match = patter.search(line)
|
||||
if match:
|
||||
res = (match.group(1), match.group(2), match.group(4))
|
||||
return (res)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def strip_badbytes(b, encoding):
|
||||
return (b.decode(encoding, errors='ignore')).strip()
|
||||
|
||||
|
||||
def get_files(dir):
|
||||
files_in_log={}
|
||||
global threshold
|
||||
try:
|
||||
with open(log_filename,'r') as file_log:
|
||||
for line in file_log.readlines():
|
||||
try:
|
||||
filedata=line.split(";")
|
||||
files_in_log[filedata[0]]=float(filedata[1])
|
||||
except:
|
||||
log_to_console("Can't parse Line")
|
||||
pass
|
||||
except:
|
||||
log_to_console("Can't open Logfile")
|
||||
pass
|
||||
|
||||
for (dirpath, dirnames, filenames) in walk(dir):
|
||||
for file in filenames:
|
||||
full_filename=os.path.join(dirpath, file)
|
||||
if full_filename in files_in_log and files_in_log[full_filename] > threshold:
|
||||
log_to_console('[~] Skipping file [Already Parsed]: %s' % full_filename)
|
||||
continue
|
||||
yield full_filename
|
||||
|
||||
|
||||
def get_lines(file,encoding=None):
|
||||
if not encoding:
|
||||
encoding = get_file_enconding(file)
|
||||
with open(file, 'rb') as f:
|
||||
return [strip_badbytes(line, encoding) for line in f]
|
||||
# for line in f:
|
||||
# yield (strip_badbytes(line, encoding))
|
||||
|
||||
|
||||
def get_parsable_lines(file,encoding):
|
||||
global log_filename
|
||||
success = 0 # initialized with 1 to preven div/0
|
||||
failure = 0
|
||||
for line in get_lines(file,encoding):
|
||||
doc = extract_email(line)
|
||||
if doc:
|
||||
success += 1
|
||||
yield doc
|
||||
else:
|
||||
failure += 1
|
||||
success_rate = (success / (success + failure))
|
||||
log_to_console('[+] Done parsing file: {} ({})'.format(file,success_rate))
|
||||
log_to_file("{};{}".format(file, success_rate))
|
||||
|
||||
|
||||
def get_hash(text):
|
||||
hash_object = hashlib.md5(text.encode())
|
||||
return hash_object.hexdigest()
|
||||
# return hex(mmh3.hash(text, 12, signed=False)).split("x")[1]
|
||||
|
||||
|
||||
def get_user_pw_hash(text):
|
||||
return get_hash(text)
|
||||
# return hex(mmh3.hash128(text, 12,signed=False) % 1000000000000000).split("x")[1]
|
||||
|
||||
|
||||
def create_doc(file,encoding):
|
||||
for cred in get_parsable_lines(file,encoding):
|
||||
doc = {
|
||||
"user" : cred[0],
|
||||
"domain" : cred[1],
|
||||
"password" : cred[2][:129],
|
||||
"file" : file,
|
||||
"length" : len(cred[2]),
|
||||
"passwordMask" : get_mask(cred[2]),
|
||||
"containsDigits" : check_digit(cred[2]),
|
||||
"containsLowerCase" : check_lower(cred[2]),
|
||||
"containsUpperCase" : check_upper(cred[2]),
|
||||
"containsSpecial" : check_special(cred[2])
|
||||
}
|
||||
username_split=cred[0].split(";")
|
||||
if len(username_split)==2:
|
||||
if len(username_split[0]) > 0 and len(username_split[1]) > 0:
|
||||
doc["username"]=username_split[0]
|
||||
doc["user"]=username_split[1]
|
||||
id_hash=get_user_pw_hash("{}{}{}".format(doc["user"],doc["domain"],doc["password"]))
|
||||
id_domain=id_hash[:1]
|
||||
yield id_domain, id_hash, doc
|
||||
|
||||
|
||||
def process_file(input_file,encoding):
|
||||
global index, doc_type_name
|
||||
for id_domain, id_hash, doc in create_doc(input_file,encoding):
|
||||
yield {
|
||||
"_index": "{}_{}".format(index,id_domain),
|
||||
"_type": doc_type_name,
|
||||
"_id": id_hash,
|
||||
"_source": doc
|
||||
}
|
||||
|
||||
|
||||
def index_file(input_file):
|
||||
encoding=get_file_enconding(input_file)
|
||||
if encoding:
|
||||
es = Elasticsearch(["172.16.1.141"],http_compress=True)
|
||||
# count = es.count(index=index, doc_type=doc_type_name, body={ "query": {"match_all" : { }}})
|
||||
# pre=count["count"]
|
||||
log_to_console('[*] Indexing file: {}'.format(input_file))
|
||||
try:
|
||||
success, _ = bulk(es, process_file(input_file,encoding), chunk_size=10000, initial_backoff=60, max_retries=3, request_timeout=60, raise_on_error=False, raise_on_exception=True)
|
||||
log_to_console('[!] Indexing done: {} [{} lines committed]'.format(input_file,success))
|
||||
except Exception as e:
|
||||
log_to_console('[!] Indexing failed for: {}\n[!] REASON:{}'.format(input_file,str((e.errors[0]))))
|
||||
# count = es.count(index=index, doc_type=doc_type_name, body={ "query": {"match_all" : { }}})
|
||||
# post=count["count"]
|
||||
# log_to_console('[{}:=] Added {} Documents with {}'.format(ps.pid,post-pre,input_file))
|
||||
else:
|
||||
log_to_console('[~] Skipping file [Unknown Encoding]: {}'.format(input_file))
|
||||
|
||||
|
||||
def bench_file(input_file):
|
||||
ps=multiprocessing.current_process()
|
||||
encoding=get_file_enconding(input_file)
|
||||
devnull=open(os.devnull,'w')
|
||||
if encoding:
|
||||
es = Elasticsearch()
|
||||
# count = es.count(index=index, doc_type=doc_type_name, body={ "query": {"match_all" : { }}})
|
||||
# pre=count["count"]
|
||||
log_to_console('[{}:*] Benching file: {}'.format(ps.pid,input_file))
|
||||
docs=0
|
||||
try:
|
||||
# success, _ = bulk(es, process_file(input_file,encoding), chunk_size=1000, request_timeout=60, raise_on_error=False, raise_on_exception=False)
|
||||
for doc in process_file(input_file,encoding):
|
||||
docs+=1
|
||||
devnull.write(json.dumps(doc))
|
||||
|
||||
|
||||
log_to_console('[{}:*] Benching Done: {} [processed {} docs]'.format(ps.pid,input_file,docs))
|
||||
|
||||
|
||||
|
||||
|
||||
except Exception as e:
|
||||
log_to_console('[{}:!] Benching failed for: {}\n[{}:!] REASON: {}'.format(ps.pid,input_file,e.message))
|
||||
# count = es.count(index=index, doc_type=doc_type_name, body={ "query": {"match_all" : { }}})
|
||||
# post=count["count"]
|
||||
# log_to_console('[{}:=] Added {} Documents with {}'.format(ps.pid,post-pre,input_file))
|
||||
else:
|
||||
log_to_console('[{}:~] Skipping file [Unknown Encoding]: {}'.format(ps.pid,input_file))
|
||||
|
||||
|
||||
|
||||
index=""
|
||||
doc_type_name = "credential"
|
||||
log_filename = "processed_files"
|
||||
threshold = -1 #threshold for reparsing an already parsed file
|
||||
|
||||
|
||||
def main():
|
||||
global index
|
||||
parser = argparse.ArgumentParser(description="Put Leakdata into local Elasticsearch")
|
||||
parser.add_argument("-p",help="how many workers (default:4)",default=4,type=int,nargs='?')
|
||||
parser.add_argument("-i",help="index suffix",default="leak_data")
|
||||
parser.add_argument("-b",help="dont write to es just benchmark",action='store_true')
|
||||
parser.add_argument('folder')
|
||||
args = parser.parse_args()
|
||||
index=args.i
|
||||
workers=args.p
|
||||
dir=args.folder
|
||||
p=Pool(workers)
|
||||
if args.b:
|
||||
p.map(bench_file,get_files(dir))
|
||||
else:
|
||||
p.map(index_file,get_files(dir))
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,25 +0,0 @@
|
||||
[[[1, 1, 1, 1, 22],
|
||||
[6, 6, 6, 6, 22],
|
||||
[2, 6, 9, 22, 22],
|
||||
[9, 9, 9, 9, 22],
|
||||
[10, 15, 15, 15, 15]],
|
||||
[[2, 11, 1, 19, 20],
|
||||
[2, 11, 13, 19, 21],
|
||||
[2, 11, 11, 19, 23],
|
||||
[2, 11, 17, 19, 24],
|
||||
[10, 14, 18, 15, 25]],
|
||||
[[3, 3, 3, 3, 20],
|
||||
[4, 13, 13, 19, 21],
|
||||
[8, 8, 8, 8, 23],
|
||||
[10, 14, 17, 17, 24],
|
||||
[10, 14, 18, 18, 25]],
|
||||
[[4, 12, 3, 20, 20],
|
||||
[4, 12, 13, 21, 21],
|
||||
[4, 12, 8, 23, 23],
|
||||
[4, 12, 17, 24, 24],
|
||||
[10, 14, 18, 25, 25]],
|
||||
[[5, 5, 5, 5, 20],
|
||||
[7, 5, 13, 16, 21],
|
||||
[7, 12, 16, 16, 23],
|
||||
[7, 7, 17, 16, 24],
|
||||
[7, 14, 18, 16, 25]]]
|
||||
@@ -1,129 +0,0 @@
|
||||
import pprint
|
||||
import operator
|
||||
import numpy as np
|
||||
import math
|
||||
from copy import copy, deepcopy
|
||||
|
||||
piece=[[0,0,0],[0,1,0],[0,2,0],[0,3,0],[1,2,0]]
|
||||
sizeofcube=5
|
||||
|
||||
def init_cube(size=sizeofcube):
|
||||
return [[[0 for x in range(0,size)] for y in range(0,size)] for z in range(0,size)]
|
||||
|
||||
def move_start_position(piece,index):
|
||||
return [np.subtract(x, piece[index]) for x in piece]
|
||||
|
||||
def draw_cube(cube):
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import matplotlib.pyplot as plt
|
||||
fig = plt.figure()
|
||||
ax = fig.gca(projection='3d')
|
||||
ax.set_aspect('equal')
|
||||
ax.set_xlabel('x', fontsize=10)
|
||||
ax.set_ylabel('y', fontsize=10)
|
||||
ax.set_zlabel('z', fontsize=10)
|
||||
|
||||
ma=np.array(cube)
|
||||
ax.voxels(ma, edgecolor="k")
|
||||
plt.show()
|
||||
|
||||
def put_piece_in_cube(piece,cube,position,index):
|
||||
cursors = [np.add(position,p) for p in piece]
|
||||
in_cube = [ max(c) < len(cube) and min(c) >= 0 for c in cursors]
|
||||
if all(in_cube):
|
||||
for cursor in cursors:
|
||||
try:
|
||||
if cube[cursor[0]][cursor[1]][cursor[2]]!=0:
|
||||
return False
|
||||
except:
|
||||
return False
|
||||
for cursor in cursors:
|
||||
cube[cursor[0]][cursor[1]][cursor[2]]=index
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def rotate_vector(vector,axis,angle):
|
||||
x,y,z=vector
|
||||
angle=math.radians(angle)
|
||||
if axis == "z":
|
||||
return (int(round((x*math.cos(angle)) - (y*math.sin(angle)))),int(round((x*math.sin(angle)) + (y*math.cos(angle)))),z)
|
||||
if axis == "y":
|
||||
return (int(round(x*math.cos(angle) + z*math.sin(angle))),y,int(round(-x*math.sin(angle) + z*math.cos(angle))))
|
||||
if axis == "x":
|
||||
return (x,int(round(y*math.cos(angle) - z*math.sin(angle))),int(round(y*math.sin(angle) + z*math.cos(angle))))
|
||||
|
||||
def rotate_piece(piece,axis,angle):
|
||||
return [rotate_vector(x, axis, angle) for x in piece]
|
||||
|
||||
def shift_piece(piece,anchor_index):
|
||||
anchor=piece[anchor_index]
|
||||
return [np.subtract(p,anchor) for p in piece]
|
||||
|
||||
def generate_rotations(piece):
|
||||
all_rotations=set()
|
||||
for i in range(0,4):
|
||||
for j in range(0,4):
|
||||
for k in range(0,4):
|
||||
for p in range(0,5):
|
||||
rotated_piece=rotate_piece(rotate_piece(rotate_piece(shift_piece(piece,p),"x",k*90),"y",j*90),"z",i*90)
|
||||
all_rotations.add(tuple(rotated_piece))
|
||||
return frozenset(all_rotations)
|
||||
|
||||
def find_empty_spot(cube):
|
||||
for z in range(0,sizeofcube):
|
||||
for y in range(0,sizeofcube):
|
||||
for x in range(0,sizeofcube):
|
||||
if cube[x][y][z]==0:
|
||||
return (x,y,z)
|
||||
return None
|
||||
|
||||
def solve(cube,index):
|
||||
#make copy of cube
|
||||
global maxindex
|
||||
if index > maxindex:
|
||||
print(index)
|
||||
maxindex=index
|
||||
|
||||
backup=deepcopy(cube)
|
||||
# draw_cube(backup)
|
||||
#make copy of available pieces
|
||||
global all_rotations
|
||||
pieces=set(all_rotations.copy())
|
||||
|
||||
# print("{}:find empty spot#########################".format(index))
|
||||
empty_pos=find_empty_spot(backup)
|
||||
|
||||
if empty_pos==None:
|
||||
pprint.pprint(cube)
|
||||
draw_cube(cube)
|
||||
return True
|
||||
else:
|
||||
(x,y,z)=empty_pos
|
||||
# print("{}:empty_spot at ({},{},{})".format(index,x,y,z))
|
||||
#found empty space > trying to fill it
|
||||
while len(pieces)>0:
|
||||
#use copy of cube without my parts
|
||||
local_cube=deepcopy(backup)
|
||||
piece=pieces.pop()
|
||||
if put_piece_in_cube(piece, local_cube, (x,y,z), index):
|
||||
# print("{}:found fitting piece {} ({} left)".format(index,piece,len(pieces)))
|
||||
if solve(local_cube, index+1):
|
||||
return True
|
||||
else:
|
||||
# print("{}:removing ({},{},{}):{}".format(index,x,y,z,len(pieces)))
|
||||
pass
|
||||
#nothing fits return fail
|
||||
return False
|
||||
|
||||
|
||||
maxindex=0
|
||||
|
||||
|
||||
def main():
|
||||
global all_rotations
|
||||
all_rotations=generate_rotations(piece)
|
||||
solve(init_cube(),1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,85 +0,0 @@
|
||||
import numpy as np
|
||||
import math
|
||||
from operator import add
|
||||
import matplotlib.pyplot as plt
|
||||
import pprint
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
|
||||
# g_cube=np.zeros((10,10,10))
|
||||
n=6
|
||||
g_cube=[[[0 for k in range(0,n)] for j in range(0,n)] for i in range(0,n)]
|
||||
|
||||
form=[[0,0,0],[1,0,0],[2,0,0],[3,0,0],[2,1,0]]
|
||||
|
||||
|
||||
|
||||
def set_origin(form,index):
|
||||
newform=list()
|
||||
for x in form:
|
||||
newform.append(np.subtract(x,form[index]))
|
||||
return newform
|
||||
|
||||
def vector_rotate(vector,angle,axis):
|
||||
if axis=='x':
|
||||
result=[vector[0],( ( vector[1]*math.cos(angle) ) - ( vector[2]*math.sin(angle) ) ),( ( vector[1]*math.sin(angle) ) + ( vector[2]*math.cos(angle) ) )]
|
||||
if axis=='y':
|
||||
result=[( ( vector[0]*math.cos(angle) ) + ( vector[2]*math.sin(angle) ) ),vector[1],( ( -vector[0]*math.sin(angle) ) + ( vector[2]*math.cos(angle) ) )]
|
||||
if axis=='z':
|
||||
result=[( ( vector[0]*math.cos(angle) ) - ( vector[1]*math.sin(angle) ) ),( ( vector[0]*math.sin(angle) ) + ( vector[1]*math.cos(angle) ) )]
|
||||
|
||||
|
||||
def form_in_cube(form):
|
||||
for cursor in form:
|
||||
for element in cursor:
|
||||
if element<=0 or element>=n:
|
||||
return False
|
||||
return True
|
||||
|
||||
def put_in(form,cube,offset,piece=1):
|
||||
form_positions=[(x+offset[0],y+offset[1],z+offset[2]) for (x,y,z) in form]
|
||||
# form_positions=list([map(add,p,offset) for p in form])
|
||||
|
||||
if form_in_cube(form_positions):
|
||||
for cursor in form_positions:
|
||||
cube[cursor[0]][cursor[1]][cursor[2]]=piece
|
||||
print("set ({},{},{}) to {}".format(cursor[0],cursor[1],cursor[2],piece))
|
||||
else:
|
||||
print("out")
|
||||
|
||||
def draw_field(g_cube):
|
||||
# g_cube=np.zeros((6,6,6))
|
||||
# g_cube=cube
|
||||
# prepare some coordinates
|
||||
# x, y, z = np.indices((6, 6, 6))
|
||||
x, y, z = np.indices((len(g_cube),len(g_cube[0]), len(g_cube[0][0])))
|
||||
farben=["red","blue","green","cyan","magenta","yellow"]
|
||||
|
||||
list_of_cubes =list()
|
||||
for x_pos in range(0,len(g_cube)):
|
||||
for y_pos in range(0,len(g_cube[x_pos])):
|
||||
for z_pos in range(0,len(g_cube[x_pos][y_pos])):
|
||||
color=(g_cube[x_pos][y_pos][z_pos])
|
||||
if color>0:
|
||||
print("Voxel by ({},{},{}) : {}".format(x_pos,y_pos,z_pos,type(g_cube[x_pos][y_pos][z_pos])))
|
||||
farbe=farben[int((color+1)%len(farben))]
|
||||
list_of_cubes.append({"cube":(x < x_pos) & (x >= (x_pos-1) ) & (y < y_pos) & (y >= (y_pos-1) ) & (z < z_pos) & (z >= (z_pos-1) ),"farbe":farbe})
|
||||
|
||||
|
||||
voxels=list_of_cubes[0]["cube"]
|
||||
colors = np.empty(voxels.shape, dtype=object)
|
||||
|
||||
for x in list_of_cubes:
|
||||
voxels=voxels | x["cube"]
|
||||
colors[x["cube"]]=x["farbe"]
|
||||
|
||||
fig = plt.figure()
|
||||
ax = fig.gca(projection='3d')
|
||||
ax.voxels(voxels, facecolors=colors, edgecolor='k')
|
||||
plt.show()
|
||||
|
||||
|
||||
put_in(set_origin(form,3),g_cube,(1,2,1),1)
|
||||
put_in(set_origin(form,4),g_cube,(2,2,2),2)
|
||||
put_in(set_origin(form,3),g_cube,(3,2,3),1)
|
||||
put_in(set_origin(form,4),g_cube,(4,2,4),2)
|
||||
draw_field(g_cube)
|
||||
@@ -1,175 +0,0 @@
|
||||
import pprint
|
||||
import operator
|
||||
import numpy as np
|
||||
import math
|
||||
from copy import copy, deepcopy
|
||||
import profile
|
||||
|
||||
piece=[[0,0,0],[0,1,0],[0,2,0],[0,3,0],[1,2,0]]
|
||||
sizeofcube=5
|
||||
|
||||
def init_cube(size=sizeofcube):
|
||||
return [[[0 for x in range(0,size)] for y in range(0,size)] for z in range(0,size)]
|
||||
|
||||
def move_start_position(piece,index):
|
||||
return [np.subtract(x, piece[index]) for x in piece]
|
||||
|
||||
def draw_cube(cube):
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import matplotlib.pyplot as plt
|
||||
fig = plt.figure()
|
||||
ax = fig.gca(projection='3d')
|
||||
ax.set_aspect('equal')
|
||||
ax.set_xlabel('x', fontsize=10)
|
||||
ax.set_ylabel('y', fontsize=10)
|
||||
ax.set_zlabel('z', fontsize=10)
|
||||
|
||||
ma=np.array(cube)
|
||||
ax.voxels(ma, edgecolor="k")
|
||||
plt.show()
|
||||
|
||||
def set_cube_vals(cursors,cube,value):
|
||||
for cursor in cursors:
|
||||
cube[cursor[0]][cursor[1]][cursor[2]]=value
|
||||
|
||||
def is_valid(piece,position):
|
||||
global sizeofcube
|
||||
upper_x=sizeofcube-position[0]
|
||||
upper_y=sizeofcube-position[1]
|
||||
upper_z=sizeofcube-position[2]
|
||||
for (x,y,z) in piece:
|
||||
if x<-position[0] or x>upper_x:
|
||||
return False
|
||||
if y<-position[1] or y>upper_y:
|
||||
return False
|
||||
if z<-position[2] or z>upper_z:
|
||||
return False
|
||||
return True
|
||||
|
||||
def put_piece_in_cube(piece,cube,position,index):
|
||||
if is_valid(piece,position):
|
||||
# cursors = [np.add(position,p) for p in piece]
|
||||
# for cursor in cursors:
|
||||
cursors=[]
|
||||
for (x,y,z) in piece:
|
||||
cursor=[(x+position[0]),(y+position[1]),(z+position[2])]
|
||||
cursors.append(cursor)
|
||||
try:
|
||||
if cube[cursor[0]][cursor[1]][cursor[2]]!=0:
|
||||
return False
|
||||
except:
|
||||
return False
|
||||
set_cube_vals(cursors, cube, index)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def remove_piece_in_cube(piece,cube,position):
|
||||
cursors = [np.add(position,p) for p in piece]
|
||||
set_cube_vals(cursors, cube, 0)
|
||||
|
||||
def rotate_vector(vector,axis,angle):
|
||||
x,y,z=vector
|
||||
angle=math.radians(angle)
|
||||
if axis == "z":
|
||||
return (int(round((x*math.cos(angle)) - (y*math.sin(angle)))),int(round((x*math.sin(angle)) + (y*math.cos(angle)))),z)
|
||||
if axis == "y":
|
||||
return (int(round(x*math.cos(angle) + z*math.sin(angle))),y,int(round(-x*math.sin(angle) + z*math.cos(angle))))
|
||||
if axis == "x":
|
||||
return (x,int(round(y*math.cos(angle) - z*math.sin(angle))),int(round(y*math.sin(angle) + z*math.cos(angle))))
|
||||
|
||||
def rotate_piece(piece,axis,angle):
|
||||
return [rotate_vector(x, axis, angle) for x in piece]
|
||||
|
||||
def shift_piece(piece,anchor_index):
|
||||
anchor=piece[anchor_index]
|
||||
return [np.subtract(p,anchor) for p in piece]
|
||||
|
||||
def generate_rotations(piece):
|
||||
all_rotations=set()
|
||||
for i in range(0,4):
|
||||
for j in range(0,4):
|
||||
for k in range(0,4):
|
||||
for p in range(0,len(piece)):
|
||||
rotated_piece=rotate_piece(rotate_piece(rotate_piece(shift_piece(piece,p),"x",k*90),"y",j*90),"z",i*90)
|
||||
all_rotations.add(tuple(rotated_piece))
|
||||
return frozenset(all_rotations)
|
||||
|
||||
def find_empty_spot(cube):
|
||||
for z in range(0,sizeofcube):
|
||||
for y in range(0,sizeofcube):
|
||||
for x in range(0,sizeofcube):
|
||||
if cube[x][y][z]==0:
|
||||
return (x,y,z)
|
||||
return None
|
||||
|
||||
def printstats():
|
||||
global stat_counter
|
||||
global stats
|
||||
stat_counter=stat_counter+1
|
||||
if stat_counter%10000==0:
|
||||
print(stat_counter)
|
||||
for x in stats:
|
||||
print("{}:{}".format(x,stats[x]))
|
||||
if x>5:
|
||||
break
|
||||
|
||||
def parallel_pool_init():
|
||||
global stats
|
||||
global solutions
|
||||
stats=dict()
|
||||
solutions=list()
|
||||
|
||||
|
||||
def parallel_solve(cube):
|
||||
global all_rotations
|
||||
all_rotations=generate_rotations(piece)
|
||||
pieces=set(all_rotations.copy())
|
||||
first_position=(0,0,0)
|
||||
while len(pieces)>0:
|
||||
piece=pieces.pop()
|
||||
if put_piece_in_cube(piece, cube, first_position, index):
|
||||
solve(cube, 2,):
|
||||
|
||||
|
||||
def solve(cube,index):
|
||||
global stats
|
||||
global solutions
|
||||
global all_rotations
|
||||
pieces=set(all_rotations.copy())
|
||||
|
||||
# print("{}:find empty spot#########################".format(index))
|
||||
empty_pos=find_empty_spot(cube)
|
||||
|
||||
if empty_pos==None:
|
||||
pprint.pprint(cube)
|
||||
draw_cube(cube)
|
||||
solutions.append(cube)
|
||||
return False
|
||||
else:
|
||||
(x,y,z)=empty_pos
|
||||
while len(pieces)>0:
|
||||
#use copy of cube without my parts
|
||||
piece=pieces.pop()
|
||||
if put_piece_in_cube(piece, cube, (x,y,z), index):
|
||||
# print("{}:found fitting piece {} ({} left)".format(index,piece,len(pieces)))
|
||||
stats[index]=len(pieces)
|
||||
if solve(cube, index+1):
|
||||
return True
|
||||
else:
|
||||
remove_piece_in_cube(piece, cube, (x,y,z))
|
||||
#nothing fits return fail
|
||||
return False
|
||||
|
||||
|
||||
# maxindex=0
|
||||
# stat_counter=0
|
||||
# stats=dict()
|
||||
# last_stats=dict()
|
||||
|
||||
def main():
|
||||
parallel_solve(init_cube())
|
||||
|
||||
if __name__ == '__main__':
|
||||
# profile.run('main()')
|
||||
main()
|
||||
@@ -1,177 +0,0 @@
|
||||
import pprint
|
||||
import operator
|
||||
import numpy as np
|
||||
import math
|
||||
from copy import copy, deepcopy
|
||||
import profile
|
||||
|
||||
piece=[[0,0,0],[0,1,0],[0,2,0],[0,3,0],[1,2,0]]
|
||||
sizeofcube=5
|
||||
|
||||
def init_cube(size=sizeofcube):
|
||||
return [[[0 for x in range(0,size)] for y in range(0,size)] for z in range(0,size)]
|
||||
|
||||
def move_start_position(piece,index):
|
||||
return [np.subtract(x, piece[index]) for x in piece]
|
||||
|
||||
def draw_cube(cube):
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import matplotlib.pyplot as plt
|
||||
fig = plt.figure()
|
||||
ax = fig.gca(projection='3d')
|
||||
ax.set_aspect('equal')
|
||||
ax.set_xlabel('x', fontsize=10)
|
||||
ax.set_ylabel('y', fontsize=10)
|
||||
ax.set_zlabel('z', fontsize=10)
|
||||
|
||||
ma=np.array(cube)
|
||||
ax.voxels(ma, edgecolor="k")
|
||||
plt.show()
|
||||
|
||||
def set_cube_vals(cursors,cube,value):
|
||||
for cursor in cursors:
|
||||
cube[cursor[0]][cursor[1]][cursor[2]]=value
|
||||
|
||||
def is_valid(piece,position):
|
||||
global sizeofcube
|
||||
upper_x=sizeofcube-position[0]
|
||||
upper_y=sizeofcube-position[1]
|
||||
upper_z=sizeofcube-position[2]
|
||||
for (x,y,z) in piece:
|
||||
if x<-position[0] or x>upper_x:
|
||||
return False
|
||||
if y<-position[1] or y>upper_y:
|
||||
return False
|
||||
if z<-position[2] or z>upper_z:
|
||||
return False
|
||||
return True
|
||||
|
||||
def put_piece_in_cube(piece,cube,position,index):
|
||||
if is_valid(piece,position):
|
||||
# cursors = [np.add(position,p) for p in piece]
|
||||
# for cursor in cursors:
|
||||
cursors=[]
|
||||
for (x,y,z) in piece:
|
||||
cursor=[(x+position[0]),(y+position[1]),(z+position[2])]
|
||||
cursors.append(cursor)
|
||||
try:
|
||||
if cube[cursor[0]][cursor[1]][cursor[2]]!=0:
|
||||
return False
|
||||
except:
|
||||
return False
|
||||
set_cube_vals(cursors, cube, index)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def remove_piece_in_cube(piece,cube,position):
|
||||
cursors = [np.add(position,p) for p in piece]
|
||||
set_cube_vals(cursors, cube, 0)
|
||||
|
||||
def rotate_vector(vector,axis,angle):
|
||||
x,y,z=vector
|
||||
angle=math.radians(angle)
|
||||
if axis == "z":
|
||||
return (int(round((x*math.cos(angle)) - (y*math.sin(angle)))),int(round((x*math.sin(angle)) + (y*math.cos(angle)))),z)
|
||||
if axis == "y":
|
||||
return (int(round(x*math.cos(angle) + z*math.sin(angle))),y,int(round(-x*math.sin(angle) + z*math.cos(angle))))
|
||||
if axis == "x":
|
||||
return (x,int(round(y*math.cos(angle) - z*math.sin(angle))),int(round(y*math.sin(angle) + z*math.cos(angle))))
|
||||
|
||||
def rotate_piece(piece,axis,angle):
|
||||
return [rotate_vector(x, axis, angle) for x in piece]
|
||||
|
||||
def shift_piece(piece,anchor_index):
|
||||
anchor=piece[anchor_index]
|
||||
return [np.subtract(p,anchor) for p in piece]
|
||||
|
||||
def generate_rotations(piece):
|
||||
all_rotations=set()
|
||||
for i in range(0,4):
|
||||
for j in range(0,4):
|
||||
for k in range(0,4):
|
||||
for p in range(0,len(piece)):
|
||||
rotated_piece=rotate_piece(rotate_piece(rotate_piece(shift_piece(piece,p),"x",k*90),"y",j*90),"z",i*90)
|
||||
all_rotations.add(tuple(rotated_piece))
|
||||
return frozenset(all_rotations)
|
||||
|
||||
def find_empty_spot(cube):
|
||||
for z in range(0,sizeofcube):
|
||||
for y in range(0,sizeofcube):
|
||||
for x in range(0,sizeofcube):
|
||||
if cube[x][y][z]==0:
|
||||
return (x,y,z)
|
||||
return None
|
||||
|
||||
def printstats():
|
||||
global stat_counter
|
||||
global stats
|
||||
stat_counter=stat_counter+1
|
||||
if stat_counter%10000==0:
|
||||
print(stat_counter)
|
||||
for x in stats:
|
||||
print("{}:{}".format(x,stats[x]))
|
||||
if x>5:
|
||||
break
|
||||
|
||||
def parallel_pool_init():
|
||||
global stats
|
||||
global solutions
|
||||
stats=dict()
|
||||
solutions=list()
|
||||
|
||||
|
||||
def parallel_solve(cube):
|
||||
global all_rotations
|
||||
all_rotations=generate_rotations(piece)
|
||||
pieces=set(all_rotations.copy())
|
||||
first_position=(0,0,0)
|
||||
while len(pieces)>0:
|
||||
piece=pieces.pop()
|
||||
if put_piece_in_cube(piece, cube, first_position, index):
|
||||
stats["jobid"]={"0"=>len(pieces)}
|
||||
|
||||
solve(cube, 2,):
|
||||
|
||||
|
||||
def solve(cube,index,jobid):
|
||||
global stats
|
||||
global solutions
|
||||
global all_rotations
|
||||
pieces=set(all_rotations.copy())
|
||||
|
||||
# print("{}:find empty spot#########################".format(index))
|
||||
empty_pos=find_empty_spot(cube)
|
||||
|
||||
if empty_pos==None:
|
||||
pprint.pprint(cube)
|
||||
draw_cube(cube)
|
||||
solutions.append(cube)
|
||||
return False
|
||||
else:
|
||||
(x,y,z)=empty_pos
|
||||
while len(pieces)>0:
|
||||
#use copy of cube without my parts
|
||||
piece=pieces.pop()
|
||||
if put_piece_in_cube(piece, cube, (x,y,z), index):
|
||||
# print("{}:found fitting piece {} ({} left)".format(index,piece,len(pieces)))
|
||||
stats[index]=len(pieces)
|
||||
if solve(cube, index+1):
|
||||
return True
|
||||
else:
|
||||
remove_piece_in_cube(piece, cube, (x,y,z))
|
||||
#nothing fits return fail
|
||||
return False
|
||||
|
||||
|
||||
# maxindex=0
|
||||
# stat_counter=0
|
||||
# stats=dict()
|
||||
# last_stats=dict()
|
||||
|
||||
def main():
|
||||
parallel_solve(init_cube())
|
||||
|
||||
if __name__ == '__main__':
|
||||
# profile.run('main()')
|
||||
main()
|
||||
@@ -1,99 +0,0 @@
|
||||
'''
|
||||
==========================
|
||||
3D voxel / volumetric plot
|
||||
==========================
|
||||
|
||||
Demonstrates plotting 3D volumetric objects with ``ax.voxels``
|
||||
'''
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pprint
|
||||
import random
|
||||
from matplotlib import colors as mcolors
|
||||
|
||||
# This import registers the 3D projection, but is otherwise unused.
|
||||
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 unused import
|
||||
|
||||
g_cube=np.zeros((6,6,6))
|
||||
# prepare some coordinates
|
||||
x, y, z = np.indices((6, 6, 6))
|
||||
|
||||
# farben=["red","blue","green","cyan","magenta","yellow"]
|
||||
farben=[name for name in mcolors.CSS4_COLORS]
|
||||
random.shuffle(farben)
|
||||
g_cube=[[[1, 1, 1, 1, 22],
|
||||
[6, 6, 6, 6, 22],
|
||||
[2, 6, 9, 22, 22],
|
||||
[9, 9, 9, 9, 22],
|
||||
[10, 15, 15, 15, 15]],
|
||||
[[2, 11, 1, 19, 20],
|
||||
[2, 11, 13, 19, 21],
|
||||
[2, 11, 11, 19, 23],
|
||||
[2, 11, 17, 19, 24],
|
||||
[10, 14, 18, 15, 25]],
|
||||
[[3, 3, 3, 3, 20],
|
||||
[4, 13, 13, 19, 21],
|
||||
[8, 8, 8, 8, 23],
|
||||
[10, 14, 17, 17, 24],
|
||||
[10, 14, 18, 18, 25]],
|
||||
[[4, 12, 3, 20, 20],
|
||||
[4, 12, 13, 21, 21],
|
||||
[4, 12, 8, 23, 23],
|
||||
[4, 12, 17, 24, 24],
|
||||
[10, 14, 18, 25, 25]],
|
||||
[[5, 5, 5, 5, 20],
|
||||
[7, 5, 13, 16, 21],
|
||||
[7, 12, 16, 16, 23],
|
||||
[7, 7, 17, 16, 24],
|
||||
[7, 14, 18, 16, 25]]]
|
||||
|
||||
|
||||
list_of_cubes =list()
|
||||
color_counter=0
|
||||
for x_pos in range(0,len(g_cube)):
|
||||
for y_pos in range(0,len(g_cube[x_pos])):
|
||||
for z_pos in range(0,len(g_cube[x_pos][y_pos])):
|
||||
if g_cube[x_pos][y_pos][z_pos]!=0:
|
||||
cur_farbe=g_cube[x_pos][y_pos][z_pos]%len(farben)
|
||||
print("Voxel by in {} for ({}>x>={}//{}>y>={}//{}>z>={}) )".format(farben[cur_farbe],x_pos,x_pos+1,y_pos,y_pos+1,z_pos,z_pos+1))
|
||||
list_of_cubes.append({"cube":(x > x_pos) & (x <= (x_pos+1) ) & (y > y_pos) & (y <= (y_pos+1) ) & (z > z_pos) & (z <= (z_pos+1) ),"farbe":farben[cur_farbe]})
|
||||
color_counter=(color_counter + 1) % len (farben)
|
||||
|
||||
voxels=list_of_cubes[0]["cube"]
|
||||
colors = np.empty(voxels.shape, dtype=object)
|
||||
|
||||
for x in list_of_cubes:
|
||||
voxels=voxels | x["cube"]
|
||||
colors[x["cube"]]=x["farbe"]
|
||||
|
||||
fig = plt.figure()
|
||||
ax = fig.gca(projection='3d')
|
||||
ax.voxels(voxels, facecolors=colors, edgecolor='k')
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
# draw cuboids in the top left and bottom right corners, and a link between them
|
||||
#
|
||||
# cube1 = (x < 3) & (y < 3) & (z < 3)
|
||||
# cube2 = (x >= 5) & (y >= 5) & (z >= 5)
|
||||
# link = abs(x - y) + abs(y - z) + abs(z - x) <= 2
|
||||
#
|
||||
# # combine the objects into a single boolean array
|
||||
# voxels = cube1 | cube2 | link
|
||||
#
|
||||
# # set the colors of each object
|
||||
# colors = np.empty(voxels.shape, dtype=object)
|
||||
# colors[link] = 'red'
|
||||
# colors[cube1] = 'blue'
|
||||
# colors[cube2] = 'green'
|
||||
#
|
||||
# # and plot everything
|
||||
# fig = plt.figure()
|
||||
# ax = fig.gca(projection='3d')
|
||||
# ax.voxels(voxels, facecolors=colors, edgecolor='k')
|
||||
#
|
||||
# plt.show()
|
||||
@@ -1,48 +0,0 @@
|
||||
# Get a list of all installed software from the Windows software library
|
||||
$installedSoftware = Get-Package
|
||||
|
||||
# Get a list of all installed Windows updates
|
||||
$installedUpdates = Get-HotFix
|
||||
|
||||
# Get a list of all Chocolatey packages
|
||||
$chocoPackages = choco list --localonly
|
||||
|
||||
# Create a variable to hold all of the information
|
||||
$sbom = @()
|
||||
|
||||
# Add the installed software to the SBOM
|
||||
$sbom += $installedSoftware
|
||||
|
||||
# Add the formatted updates to the SBOM
|
||||
$sbom += $installedUpdates
|
||||
|
||||
# Add the Chocolatey packages to the SBOM
|
||||
$sbom += $chocoPackages
|
||||
|
||||
# Get the folder path
|
||||
$folderPath = "C:\Forensic Program Files"
|
||||
|
||||
# Get all EXE files in the folder and its subfolders
|
||||
$exeFiles = Get-ChildItem $folderPath -Recurse -Filter "*.exe"
|
||||
|
||||
# Create a variable to hold the EXE file information
|
||||
$exeInfo = @()
|
||||
|
||||
# Loop through each EXE file
|
||||
foreach ($exeFile in $exeFiles) {
|
||||
# Get the file version information
|
||||
$fileVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($exeFile.FullName)
|
||||
|
||||
# Add the EXE file information to the array
|
||||
$exeInfo += New-Object PSObject -Property @{
|
||||
"Path" = $exeFile.FullName
|
||||
"Product Name" = $fileVersion.ProductName
|
||||
"Product Version" = $fileVersion.ProductVersion
|
||||
}
|
||||
}
|
||||
|
||||
# Add the EXE file information to the SBOM
|
||||
$sbom += $exeInfo
|
||||
|
||||
# Export the SBOM to a CSV file
|
||||
$sbom | Export-Csv C:\tmp\sbom.csv -NoTypeInformation
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import requests
|
||||
import sys
|
||||
import hashlib
|
||||
from os.path import expanduser
|
||||
|
||||
|
||||
out_sep=';'
|
||||
|
||||
with open(expanduser('~/.virustotal_api_key')) as api_f:
|
||||
api_key=api_f.readline().strip()
|
||||
|
||||
with open(sys.argv[1],'rb') as f:
|
||||
hash=hashlib.md5(f.read())
|
||||
|
||||
params = {'apikey': api_key, 'resource': hash.hexdigest()}
|
||||
headers = {
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"User-Agent" : "gzip,python_requests,scan_vt.py"
|
||||
}
|
||||
|
||||
response = requests.get('https://www.virustotal.com/vtapi/v2/file/report', params=params, headers=headers)
|
||||
|
||||
try:
|
||||
json_response = response.json()
|
||||
except:
|
||||
print(response)
|
||||
exit(1)
|
||||
|
||||
if json_response["response_code"]:
|
||||
print("{}{}{}{}{}/{}{}{}".format(sys.argv[1],out_sep,hash.hexdigest(),out_sep,json_response["positives"],json_response["total"],out_sep,json_response["permalink"]))
|
||||
else:
|
||||
print("{}{}{}{}{}".format(sys.argv[1],out_sep,hash.hexdigest(),out_sep,out_sep))
|
||||
@@ -1,47 +0,0 @@
|
||||
from scapy.all import srp, Ether, ARP
|
||||
from threading import Thread
|
||||
from ipaddress import IPv4Network
|
||||
from pprint import pprint
|
||||
from time import sleep, time
|
||||
|
||||
threads = []
|
||||
|
||||
clients = list()
|
||||
class Scanner(Thread):
|
||||
def __init__(self, ip):
|
||||
super().__init__()
|
||||
self.ip = ip
|
||||
|
||||
def run(self):
|
||||
# The below code from https://www.thepythoncode.com/article/building-network-scanner-using-scapy
|
||||
packet = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst=self.ip)
|
||||
# this is a tuple, which index 0 is host that answers arp request.
|
||||
# while index 1 is unanswered when no host answers arp request.
|
||||
result = srp(packet, timeout=3, verbose=0)[0]
|
||||
# the result is a tuple with index 0 as sent, and 1 as received.
|
||||
for _, received in result:
|
||||
# psrc is the arp responder's ip address
|
||||
# hwsrc is the arp responder's mac address
|
||||
clients.append(
|
||||
{
|
||||
"ip": received.psrc,
|
||||
"mac": received.hwsrc
|
||||
}
|
||||
)
|
||||
# maintain consistency by forcing this method to sleep for 1 second
|
||||
# before beginning the next host.
|
||||
sleep(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
start = time()
|
||||
for ip in IPv4Network('192.168.178.0/24').hosts():
|
||||
t = Scanner(str(ip))
|
||||
threads.append(t)
|
||||
t.start()
|
||||
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
pprint(clients)
|
||||
print(f"Executed in {time() - start} seconds.")
|
||||
@@ -1,30 +0,0 @@
|
||||
import socket as sk
|
||||
import sys
|
||||
print(sys.argv)
|
||||
print(len(sys.argv))
|
||||
print("Host:" , sys.argv[1])
|
||||
default=(21,22,23,80,110,111,135,139,389,443,515,631,3306,3389)
|
||||
|
||||
def usage():
|
||||
print("Usage:",sys.argv[0],"<ip> ( [<start_port> - <end_port] | [<port>] ) ")
|
||||
|
||||
if (len(sys.argv)==5) and sys.argv[3]=='-':
|
||||
try:
|
||||
ports=range(int(sys.argv[2]),int(sys.argv[4]))
|
||||
except:
|
||||
usage()
|
||||
ports=default
|
||||
elif len(sys.argv)>2:
|
||||
ports=sys.arv[2:]
|
||||
else:
|
||||
ports=default
|
||||
|
||||
print("Ports:", ports)
|
||||
for port in ports:
|
||||
try:
|
||||
s=sk.socket(sk.AF_INET,sk.SOCK_STREAM)
|
||||
s.settimeout(1)
|
||||
s.connect((sys.argv[1],port))
|
||||
print('%d:OPEN' % port)
|
||||
s.close
|
||||
except: continue
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# banner.py
|
||||
|
||||
import sys
|
||||
import socket
|
||||
import argparse
|
||||
|
||||
def grab(ip, port):
|
||||
"""Connects to the specified IP and port, retrieves data and returns the decoded response."""
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP
|
||||
sock.settimeout(5) # Set a timeout of 5 seconds
|
||||
sock.connect((ip, port))
|
||||
ret = sock.recv(1024)
|
||||
return ret.strip().decode()
|
||||
except socket.error as e:
|
||||
return f"Connection error: {e}"
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Retrieve banner information from the specified IP and port.")
|
||||
parser.add_argument("ip", help="The target IP address")
|
||||
parser.add_argument("-p", "--port", type=int, default=25, help="The target port (default: 25)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
ip = args.ip
|
||||
port = args.port
|
||||
|
||||
print(grab(ip, port))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,26 +0,0 @@
|
||||
import speech_recognition as sr
|
||||
|
||||
recognizer = sr.Recognizer()
|
||||
|
||||
''' recording the sound '''
|
||||
|
||||
with sr.Microphone() as source:
|
||||
print("Adjusting noise ")
|
||||
recognizer.adjust_for_ambient_noise(source, duration=1)
|
||||
print("Recording for 4 seconds")
|
||||
recorded_audio = recognizer.listen(source, timeout=4)
|
||||
print("Done recording")
|
||||
|
||||
''' Recorgnizing the Audio '''
|
||||
try:
|
||||
print("Recognizing the text")
|
||||
|
||||
text = recognizer.recognize_sphinx(
|
||||
recorded_audio,
|
||||
language="de-DE"
|
||||
)
|
||||
print("Decoded Text : {}".format(text))
|
||||
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import sys
|
||||
import hashlib
|
||||
import requests
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: python testpw.py <password>")
|
||||
exit(1)
|
||||
|
||||
url="https://api.pwnedpasswords.com/range/"
|
||||
hash_object = hashlib.sha1(sys.argv[1].encode("UTF-8"))
|
||||
pw_hash=hash_object.hexdigest()
|
||||
first_part=pw_hash[:5]
|
||||
second_part=pw_hash[5:]
|
||||
print(pw_hash)
|
||||
furl="{}{}".format(url,first_part)
|
||||
print("Das gehashte Passwort lautet: {}".format(pw_hash))
|
||||
print("Es werden lediglich die ersten 5 Zeichen des Hashes übertragen ({})".format(first_part))
|
||||
print("Dies lässt keinerlei Rückschlusse auf da Passwort zu.")
|
||||
response=requests.get(furl)
|
||||
for line in response.text.splitlines():
|
||||
if second_part.lower() in line.lower():
|
||||
print("Passwort wurde {} mal im Datenbestand gefunden".format(line.split(":")[1]))
|
||||
exit(0)
|
||||
|
||||
print("Passwort wurde nicht im Datenbestand gefunden")
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
|
||||
hashes=set()
|
||||
for line in sys.stdin:
|
||||
h = hash(line)
|
||||
if not h in hashes:
|
||||
hashes.add(h)
|
||||
print(line,end="")
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Decode VBA Macro based on chr() obfuscation
|
||||
# Xavier Mertens <xavier@rootshell.be>
|
||||
#
|
||||
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
def do_chr(m):
|
||||
if m.group(0):
|
||||
return eval(re.sub(r'[cC][hH][rR][wW\$]*\(([\d\+\-\s.]*)\)',r'chr(int(\1))', m.group(0)))
|
||||
return ""
|
||||
|
||||
for line in sys.stdin.readlines():
|
||||
line = re.sub(r'[cC][hH][rR][wW\$]*\(([\d+\+\-\s\.]*)\)', do_chr, line)
|
||||
line = re.sub(" & ", "", line)
|
||||
print line.rstrip()
|
||||
exit
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
def mname(self, arg):
|
||||
do_chr(1);
|
||||
pass
|
||||
@@ -1,84 +0,0 @@
|
||||
import os
|
||||
import argparse
|
||||
from PIL import Image
|
||||
from transformers import CLIPProcessor, CLIPModel
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
def classify_images(model_name, image_paths, class_names):
|
||||
# Load CLIP model and processor
|
||||
model = CLIPModel.from_pretrained(model_name)
|
||||
processor = CLIPProcessor.from_pretrained(model_name)
|
||||
|
||||
classification_results = defaultdict(list)
|
||||
|
||||
# Perform zero-shot classification on each image
|
||||
for image_path in image_paths:
|
||||
try:
|
||||
image = Image.open(image_path)
|
||||
|
||||
# Process the input image and text labels
|
||||
inputs = processor(
|
||||
text=class_names,
|
||||
images=image,
|
||||
return_tensors="pt",
|
||||
padding=True
|
||||
)
|
||||
|
||||
# Run the model and get logits
|
||||
outputs = model(**inputs)
|
||||
logits_per_image = outputs.logits_per_image
|
||||
|
||||
# Calculate probabilities
|
||||
probs = logits_per_image.softmax(dim=1)
|
||||
|
||||
# Get the predicted label
|
||||
pred_label = class_names[probs.argmax(dim=1).item()]
|
||||
|
||||
classification_results[pred_label].append(image_path)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Skipping {image_path} due to error: {e}")
|
||||
|
||||
for label, images in classification_results.items():
|
||||
print(f"{label}:")
|
||||
for image_path in images:
|
||||
print(f" {image_path}")
|
||||
|
||||
|
||||
def main():
|
||||
available_models = [
|
||||
"openai/clip-vit-large-patch14",
|
||||
"openai/clip-vit-base-patch32",
|
||||
"openai/clip-vit-base-patch16"
|
||||
]
|
||||
|
||||
parser = argparse.ArgumentParser(description="CLIP-based Image Classifier")
|
||||
parser.add_argument("--model", type=str, default="openai/clip-vit-base-patch16",
|
||||
help="Model name to use for classification (default: openai/clip-vit-base-patch16)")
|
||||
parser.add_argument("-c", "--category", action="append",default=["image is safe for work", "image is not safe for work"],help="Add a classification category (e.g., 'man', 'woman', 'child', 'animal'). If not specified, the default categories will be 'safe for work' and 'not safe for work'.")
|
||||
parser.add_argument("paths", metavar="path", type=str, nargs="+",
|
||||
help="List of image file paths or directories")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.model.lower() == "list":
|
||||
print("Available models:")
|
||||
for model in available_models:
|
||||
print(f" {model}")
|
||||
return
|
||||
|
||||
image_paths = []
|
||||
for path in args.paths:
|
||||
if os.path.isdir(path):
|
||||
image_paths.extend([os.path.join(path, file) for file in os.listdir(path)])
|
||||
elif os.path.isfile(path):
|
||||
image_paths.append(path)
|
||||
else:
|
||||
print(f"Skipping {path}, not a valid file or directory")
|
||||
|
||||
classify_images(args.model, image_paths, args.category)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import sys
|
||||
import pprint
|
||||
import requests
|
||||
import os.path
|
||||
|
||||
|
||||
# os.path.exists(file_path)
|
||||
|
||||
|
||||
out_sep=';'
|
||||
|
||||
with open(os.path.expanduser('~/.virustotal_api_key')) as api_f:
|
||||
api_key=api_f.readline().strip()
|
||||
|
||||
|
||||
hash=sys.argv[1]
|
||||
url = 'https://www.virustotal.com/vtapi/v2/file/download'
|
||||
params = {'apikey': api_key, 'hash':hash }
|
||||
headers = {
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"User-Agent" : "gzip,python_requests,vt_pdns.py"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(url, params=params, headers=headers)
|
||||
if response.ok:
|
||||
with open(hash, 'wb') as f:
|
||||
f.write(response.content)
|
||||
else:
|
||||
print("NOTFOUND:{}".format(hash))
|
||||
|
||||
|
||||
|
||||
except requests.exceptions.ProxyError as e:
|
||||
print("Proxy Error")
|
||||
print(e)
|
||||
exit(1)
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import sys
|
||||
import pprint
|
||||
import requests
|
||||
import os.path
|
||||
|
||||
|
||||
# os.path.exists(file_path)
|
||||
|
||||
|
||||
out_sep=';'
|
||||
|
||||
with open(os.path.expanduser('~/.virustotal_api_key')) as api_f:
|
||||
api_key=api_f.readline().strip()
|
||||
|
||||
if os.path.exists(os.path.expanduser('~/.ipinfo_api_key')):
|
||||
with open(os.path.expanduser('~/.ipinfo_api_key')) as api_g:
|
||||
ipinfo_api_key=api_g.readline().strip()
|
||||
ipinfo_data=requests.get('http://ipinfo.io/{}'.format(sys.argv[1]), params={'token':ipinfo_api_key})
|
||||
print(ipinfo_data.json())
|
||||
|
||||
ip=sys.argv[1]
|
||||
# url='https://www.virustotal.com/vtapi/v2/ip/report'
|
||||
url = 'https://www.virustotal.com/vtapi/v2/ip-address/report'
|
||||
params = {'apikey': api_key, 'ip':ip }
|
||||
headers = {
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"User-Agent" : "gzip,python_requests,vt_pdns.py"
|
||||
}
|
||||
|
||||
|
||||
|
||||
try:
|
||||
response = requests.get(url, params=params, headers=headers)
|
||||
response_data = response.json()
|
||||
except requests.exceptions.ProxyError as e:
|
||||
print("Proxy Error")
|
||||
print(e)
|
||||
exit(1)
|
||||
|
||||
print("=== Short report for : {} ===".format(ip))
|
||||
print(response_data['verbose_msg'])
|
||||
if 'detected_urls' in response_data :
|
||||
print("{} detected URLs found".format(len(response_data['detected_urls'])))
|
||||
if 'detected_downloaded_samples' in response_data :
|
||||
print("{} detected Downloads found".format(len(response_data['detected_downloaded_samples'])))
|
||||
if 'resolutions' in response_data:
|
||||
print("== Resolutions ==")
|
||||
data=sorted(response_data['resolutions'], key=lambda i:i['last_resolved']) if len(response_data['resolutions'])>1 else response_data['resolutions']
|
||||
for r in data:
|
||||
print(" {} : {}".format(r["last_resolved"],r["hostname"]))
|
||||
|
||||
|
||||
for k in response.json():
|
||||
print("=== {} ===".format(k))
|
||||
print(response_data[k])
|
||||
@@ -1,102 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
import sys
|
||||
import pprint
|
||||
import requests
|
||||
from os.path import expanduser
|
||||
|
||||
|
||||
out_sep=';'
|
||||
|
||||
with open(expanduser('~/.virustotal_api_key')) as api_f:
|
||||
api_key=api_f.readline().strip()
|
||||
|
||||
domain=sys.argv[1]
|
||||
url='https://www.virustotal.com/vtapi/v2/domain/report'
|
||||
params = {'apikey': api_key, 'domain':domain }
|
||||
headers = {
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"User-Agent" : "gzip,python_requests,vt_pdns.py"
|
||||
}
|
||||
|
||||
|
||||
cat_fields=["Alexa category",
|
||||
"categories",
|
||||
"BitDefender category",
|
||||
"TrendMicro category",
|
||||
"Forcepoint ThreatSeeker category"]
|
||||
#
|
||||
# "whois",
|
||||
# "WOT domain info",
|
||||
# "Webutation domain info",
|
||||
# "BitDefender domain info",
|
||||
# "Alexa domain info",
|
||||
# BitDefender category
|
||||
# WOT domain info
|
||||
# Webutation domain info
|
||||
# Alexa category
|
||||
# Opera domain info
|
||||
# TrendMicro category
|
||||
# categories
|
||||
# domain_siblings
|
||||
# BitDefender domain info
|
||||
# whois
|
||||
# Alexa domain info
|
||||
# Forcepoint ThreatSeeker category
|
||||
# Alexa rank
|
||||
#
|
||||
# detected_downloaded_samples
|
||||
# detected_urls
|
||||
#
|
||||
# detected_communicating_samples
|
||||
# detected_referrer_samples
|
||||
# undetected_downloaded_samples
|
||||
# undetected_referrer_samples
|
||||
# undetected_urls
|
||||
# undetected_communicating_samples
|
||||
# resolutions
|
||||
# response_code
|
||||
# verbose_msg
|
||||
# pcaps
|
||||
#
|
||||
try:
|
||||
response = requests.get(url, params=params, headers=headers)
|
||||
response_data = response.json()
|
||||
except requests.exceptions.ProxyError as e:
|
||||
print("Proxy Error")
|
||||
print(e)
|
||||
exit(1)
|
||||
|
||||
# resolutions=[r for r in response.json()['resolutions']]
|
||||
|
||||
|
||||
def get(key,dict):
|
||||
split_key=key.split(sep=" ")
|
||||
if len(split_key)>1:
|
||||
prefix="{}: ".format(split_key[0])
|
||||
else:
|
||||
prefix="VT: "
|
||||
if key in dict:
|
||||
print("{}{}".format(prefix,dict[key]))
|
||||
|
||||
# # detected_downloaded_samples=[d for d in response.json()['detected_downloaded_samples']]
|
||||
# # detected_url=[d for d in response.json()['detected_url']]
|
||||
|
||||
print("=== Short report for : {} ===".format(domain))
|
||||
print(response_data['verbose_msg'])
|
||||
if 'detected_urls' in response_data :
|
||||
print("{} detected URLs found".format(len(response_data['detected_urls'])))
|
||||
if 'detected_downloaded_samples' in response_data :
|
||||
print("{} detected Downloads found".format(len(response_data['detected_downloaded_samples'])))
|
||||
if any([True for x in cat_fields if x in response_data]):
|
||||
print("== Categories ==")
|
||||
for cat in cat_fields:
|
||||
get(cat,response_data)
|
||||
if 'resolutions' in response_data:
|
||||
print("== Resolutions ==")
|
||||
data=sorted(response_data['resolutions'], key=lambda i:i['last_resolved']) if len(response_data['resolutions'])>1 else response_data['resolutions']
|
||||
for r in data:
|
||||
print(" {} : {}".format(r["last_resolved"],r["ip_address"]))
|
||||
|
||||
# print('--------------------------infos')
|
||||
# for k in response.json():
|
||||
# print(k)
|
||||
101
codegrab/wipe.sh
101
codegrab/wipe.sh
@@ -1,101 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#disabling Kernellogging to Console
|
||||
echo '2 4 1 7' > /proc/sys/kernel/printk
|
||||
|
||||
#rechnet die eine centrierierte fensterposition aus anhand von bildschirm- & fenstergröße
|
||||
# 'mitte 50'
|
||||
function mitte(){
|
||||
cols=$(tput cols)
|
||||
mitte=$(echo $(( $cols / 2 - $1 / 2 )) )
|
||||
echo $mitte
|
||||
}
|
||||
|
||||
#zeigt eine infomeldung für x-Sekunden an
|
||||
# 'info text 5'
|
||||
function info(){
|
||||
text=${1}
|
||||
text_len=$(( ${#1} + 4 ))
|
||||
timeout=${2}
|
||||
dialog --backtitle "CERTBw - Zero-Wipe" --infobox "$text" 3 $text_len; sleep $timeout
|
||||
}
|
||||
|
||||
#zeigt überischt von datenträgern an und fragt ab welcher gewipet werden soll
|
||||
function ask_4_device(){
|
||||
[ -e /tmp/devicelist ] || rm /tmp/devicelist
|
||||
lsblk -o NAME,SIZE,TYPE,FSTYPE | tail -n+2 | tr -cd ',.\n [:alnum:]' | awk '{printf "%-5s%6s %s (%s) \n" , $1,$2,$3,$4}' | sed -e "s/()//g" >/tmp/devicelist
|
||||
devlines=$(( $(cat /tmp/devicelist | wc -l) + 2 ))
|
||||
dialog --backtitle "CERTBw - Zero-Wipe" --begin 2 $(mitte 30) --title "Available Devices" --progressbox $devlines 30 --and-widget --stdout --inputbox 'Welche Platte soll gewipet werden?' 7 60 '/dev/sda' < /tmp/devicelist
|
||||
result=${?}
|
||||
return $result
|
||||
}
|
||||
|
||||
#prüft den rückgabewert des vorangegangenen 'dialog' fensters auf abbruch und startet das menu neu
|
||||
function check_result(){
|
||||
result=${?}
|
||||
if ([ $result = 1 ] || [ $result = 255 ]); then
|
||||
info 'CANCELED' 1
|
||||
menu
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
#kopiert Nullen auf das Angegebene Gerät und zeitg den Fortschritt mit 'dialog' an
|
||||
function wipe(){
|
||||
#anlegen von named pipes für den Datenstrom und Statusmeldungen
|
||||
mkfifo data
|
||||
mkfifo status
|
||||
|
||||
size_512=$(blockdev --getsz $1)
|
||||
size=$((512 * ${size_512}))
|
||||
|
||||
echo "wiping Disk $1:"
|
||||
(while read -r line
|
||||
do
|
||||
#Zusammenfassen von Informationen für das Dialogfenster in ein 'dialog' kompatibles Format
|
||||
split=$(echo $line | tr -d "%[]=<>" | xargs)
|
||||
|
||||
space=$(echo "$split" | cut -f1 -d" ")
|
||||
time=$(echo "$split" | cut -f2 -d" ")
|
||||
rate=$(echo "$split" | cut -f3 -d" ")
|
||||
prozent=$(echo "$split" | cut -f4 -d" ")
|
||||
eta=$(echo "$split" | cut -f6 -d" ")
|
||||
echo "XXX"
|
||||
echo $prozent
|
||||
echo "Wiped $space in $time so far. ($rate)"
|
||||
echo "ETA : $eta"
|
||||
echo "XXX"
|
||||
done < <(pv -f -s $size /dev/zero 1>data 2>status | dd bs=1M iflag=fullblock oflag=nocache if=data of=$1 2>/dev/null | stdbuf -oL tr "\r" "\n" <status) ) | dialog --backtitle "CERTBw - Zero-Wipe" --title "Wiping $1" --gauge "Please wait" 7 70 0
|
||||
rm data
|
||||
rm status
|
||||
}
|
||||
|
||||
function menu(){
|
||||
menu=$(dialog --stdout --backtitle "CERTBw - Zero-Wipe" --title "Wiping Complete" --menu "Action:" 0 0 5 1 Reboot 2 Poweroff 3 Verify 4 Re-Wipe 5 Shell)
|
||||
case "$menu" in
|
||||
1) info "REBOOTING" 1; reboot
|
||||
exit 0
|
||||
;;
|
||||
2) info "SHUTTING DOWN" 1; poweroff
|
||||
exit 0
|
||||
;;
|
||||
3) info "Verify - Not yet implemented" 3
|
||||
menu
|
||||
;;
|
||||
4) /etc/wipe.sh
|
||||
exit 0
|
||||
;;
|
||||
5) exit 0
|
||||
;;
|
||||
*) info 'CANCELED' 1
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
##simpler ablauf
|
||||
drive=$(ask_4_device)
|
||||
check_result
|
||||
wipe $drive
|
||||
menu
|
||||
exit 0
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
url=$(echo -ne "${*}" | grep -Pio -m1 'https://www.youtube.com/(watch\?[^&,|]+|embed/[^?/,|]+)')
|
||||
if [[ -n "${url}" ]] ; then
|
||||
title=$(wget -q -O- "${url}" | grep -Po "(?<=title>).*(?=</title)")
|
||||
title_parsed=$(cat <<eof | python3
|
||||
from urllib.parse import unquote
|
||||
from html import unescape
|
||||
url="${title}"
|
||||
print(unescape(unquote(url)))
|
||||
eof
|
||||
)
|
||||
echo "${url};\"${title_parsed}\""
|
||||
|
||||
fi
|
||||
Reference in New Issue
Block a user