HTB{qu35t_f0r_th3_f0rb1dd3n_t3mpl4t35!!}

O desafio nos apresenta a uma tela onde existe um campo passível de (CWE-918) Server-Side Request Forgery (SSRF). Entretanto, o foco principal do desafio não é esse.

Ao analisar o código fonte, temos que:

tmpl, err := template.New("page").Parse(tmplFile)
    if err != nil {
        http.Error(w, "Internal Server Error", http.StatusInternalServerError)
        return
    }

Ou seja, a página solicitada é demonstrada na aplicação de forma renderizada (passada pela função Parse). Assim, podemos tentar executar um (CWE-1336) Server-Side Template Injection (SSTI) para conseguirmos acesso a funções privilegiadas.

Em GO, os templates somente aceitam structs. Podemos acessar todas as structs locais utilizando o {{ . }}.

Para fazer isso, iremos utilizar o Pastebin para criar esse payload. Ao enviar o payload em formato raw para a aplicação, recebemos a seguinte resposta:

center

Parece que temos um (CWE-1336) Server-Side Template Injection (SSTI) funcional! Agora, só precisamos explorar o código fonte para tentar encontrar alguma função declarada que possa nos ajudar.

Explorando o código fonte, nos deparamos com uma função bem conveniente. Sendo ela:

func (p RequestData) FetchServerInfo(command string) string {
    out, err := exec.Command("sh", "-c", command).Output()
    if err != nil {
        return ""
    }
    return string(out)
}

Assim, podemos chamar a função FetchServerInfo para conseguirmos um (CWE-94) Improper Control of Generation of Code (‘Code Injection’).

Ao criar o payload {{ .FetchServerInfo "ls -la ../" }} e enviá-lo para a aplicação, podemos obter a seguinte resposta:

center

Pronto! Agora basta pegar a flag com {{ .FetchServerInfo "cat ../flag0afeb09c5f.txt" }}.

center