Já faz um tempo que estou me aprofundando nos conceitos da OWASP, há muito no que aprofundar ainda. Estou desenvolvendo um WAS (Web Application Scanner) open source e apenas “free for fun”, mesmo. 🙂
Esse source code que fiz foi para explorar Http Methods, sendo que pode detectar alguns considerados vulneráveis em um web server.
Referência:
https://www.owasp.org/index.php/Test_HTTP_Methods_(OTG-CONFIG-006)
golang.org
my brain;)
/* Http Methods Tester v0.1
* RFC 2616 http://www.ietf.org/rfc/rfc2616.txt
* Obtem os HTTP Methods de uma web app
* Mauro Risonho de Paula Assumpção aka firebits
* 24.03.2014 23:01:17
* License BSD 3
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of the nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package main
import (
“net”
“os”
“fmt”
“io/ioutil”
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, “Uso: %s host:port “, os.Args[0])
os.Exit(1)
}
service := os.Args[1]
tcpAddr, err := net.ResolveTCPAddr(“tcp4”, service)
//Verificador de Error(err)
//TODO:
// tentar usar while e usar vetor
conn_TRACE, err := net.DialTCP(“tcp”, nil, tcpAddr)
conn_CONNECT, err := net.DialTCP(“tcp”, nil, tcpAddr)
conn_OPTIONS, err := net.DialTCP(“tcp”, nil, tcpAddr)
conn_PUT, err := net.DialTCP(“tcp”, nil, tcpAddr)
conn_POST, err := net.DialTCP(“tcp”, nil, tcpAddr)
conn_GET, err := net.DialTCP(“tcp”, nil, tcpAddr)
conn_HEAD, err := net.DialTCP(“tcp”, nil, tcpAddr)
conn_DELETE, err := net.DialTCP(“tcp”, nil, tcpAddr)
//Verificador de Error(err)
_, err = conn_TRACE.Write([]byte(“TRACE / HTTP/1.0\r\n\r\n”))
_, err = conn_CONNECT.Write([]byte(“CONNECT / HTTP/1.0\r\n\r\n”))
_, err = conn_OPTIONS.Write([]byte(“OPTIONS / HTTP/1.0\r\n\r\n”))
_, err = conn_PUT.Write([]byte(“PUT / HTTP/1.0\r\n\r\n”))
_, err = conn_POST.Write([]byte(“POST / HTTP/1.0\r\n\r\n”))
_, err = conn_GET.Write([]byte(“GET / HTTP/1.0\r\n\r\n”))
_, err = conn_HEAD.Write([]byte(“HEAD / HTTP/1.0\r\n\r\n”))
_, err = conn_DELETE.Write([]byte(“DELETE / HTTP/1.0\r\n\r\n”))
//Verificador de Error(err)
//resultado, err := readFully(conn_Method)
result_TRACE, err := ioutil.ReadAll(conn_TRACE)
result_CONNECT, err := ioutil.ReadAll(conn_CONNECT)
result_OPTIONS, err := ioutil.ReadAll(conn_OPTIONS)
result_PUT, err := ioutil.ReadAll(conn_PUT)
result_POST, err := ioutil.ReadAll(conn_POST)
result_GET, err := ioutil.ReadAll(conn_GET)
result_HEAD, err := ioutil.ReadAll(conn_HEAD)
result_DELETE, err := ioutil.ReadAll(conn_DELETE)
checkError(err)
// exibir os resultados dos HTTP Methods
// TODO fazer algo que detecte se foi renderizado ou não, ou se retorna request 200
// ou 405
fmt.Println(“TRACE”)
fmt.Println(string(result_TRACE))
fmt.Println(“============================================================”)
fmt.Println(“CONNECT”)
fmt.Println(string(result_CONNECT))
fmt.Println(“============================================================”)
fmt.Println(“OPTIONS”)
fmt.Println(string(result_OPTIONS))
fmt.Println(“============================================================”)
fmt.Println(“PUT”)
fmt.Println(string(result_PUT))
fmt.Println(“============================================================”)
fmt.Println(“POST”)
fmt.Println(string(result_POST))
fmt.Println(“============================================================”)
fmt.Println(“GET”)
fmt.Println(string(result_GET))
fmt.Println(“============================================================”)
fmt.Println(“HEAD”)
fmt.Println(string(result_HEAD))
fmt.Println(“============================================================”)
fmt.Println(“DELETE”)
fmt.Println(string(result_DELETE))
fmt.Println(“============================================================”)
os.Exit(0)
}
func checkError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, “Erro Fatal: %s”, err.Error())
os.Exit(1)
}
}
Há muito o que melhorar ainda, como usar vetor e quem sabe um while e ir fazendo trocas de http methods, mas vou revisando e postando aqui no blog.
Depois passo para meu git também.
No próximo post, vou falar sobre http methods com webdav, que é similar na essência, mas tem outra utilidade, um pouco diferenciada.
@firebitsbr