-1

I am trying to automate my recon tool using Go. So far I can run two basic tools in kali (Nikto/whois). Now I want them to execute parallelly rather than waiting for one function to finish. After reading a bit, I came to know this can be achieved by using goroutines. But my code doesn't seem to work:

package main

import (
    "log"
    "os/exec"
    "os"
    "fmt"
)

var url string

func nikto(){
    cmd := exec.Command("nikto","-h",url)
    cmd.Stdout = os.Stdout
    err := cmd.Run()
    if err != nil {
        log.Fatal(err)
    }
}

func whois() {
    cmd := exec.Command("whois","google.co")
    cmd.Stdout = os.Stdout
    err := cmd.Run()
    if err !=nil {
        log.Fatal(err)
    }
}

func main(){
    fmt.Printf("Please input URL")
    fmt.Scanln(&url)
    nikto()
    go whois()
}

I do understand that here, go whois() would execute till main() would, but I still can't see them both execute parallel.

Leon
  • 2,926
  • 1
  • 25
  • 34
  • You're running `nikto()` not in a goroutine, so it blocks until it returns. Then you run `go whois()` concurrently, and `main()` immediately returns. When `main` returns, your application exits. – Adrian Sep 21 '18 at 19:44
  • @Adrian What would be the correct way to work this out? When I try to run both as `go routines` the main returns so how can I hold it till both executes and execute them in parallel manner? – Saubhagya Srivastava Sep 21 '18 at 19:50
  • 2
    Take a look at `sync.WaitGroup` or one of the many questions here on StackOverflow on that topic, e.g. https://stackoverflow.com/questions/18207772/how-to-wait-for-all-goroutines-to-finish-without-using-time-sleep/18215175 – Adrian Sep 21 '18 at 20:00

1 Answers1

5

If I understood your question correctly, you want to execute both nikto() and whois() in parallel and wait until both returned. To wait until a set of goroutines has finished, sync.WaitGroup is a good way to archive this. For you, it could look something like this:

func main(){
    fmt.Printf("Please input URL")
    fmt.Scanln(&url)

    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
        defer wg.Done()
        nikto()
    }()
    go func() {
        defer wg.Done()
        whois()
    }()
    wg.Wait()
}

Here wg.Add(2) tells the WaitGroup, that we will wait for 2 goroutines.

Then your two functions are called inside small wrapper functions, which also call wg.Done() once each function is done. This tells the WaitGroup, that the function finished. The defer keyword just tells Go, to execute the function call, once the surrounding function returns. Also notice the go keyword before the two calls to the wrapper functions, which causes the execution to happen in 2 separate goroutines.

Finally, once both goroutines have been started, the call to wg.Wait() inside the main function blocks until wg.Done() was called twice, which will happen once both nikto() and whois() have finished.

Leon
  • 2,926
  • 1
  • 25
  • 34