mirror of
https://gitgud.io/yats/cerberus.git
synced 2026-04-30 01:32:05 -04:00
Don't overwrite existing CheckRedirect
This commit is contained in:
@@ -6,7 +6,7 @@ For technical details, you can try asking Josh (not me) or reverse engineer the
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
Donations are always appreciated but never expected nor required:
|
I do this shit for free, sometimes to my own detriment, for no good reason. Consider donating if you appreciate this monumental waste of my time.
|
||||||
|
|
||||||
XMR: `8BjCARiV2uB2gZTbbiMUetfRxcAYZgVM5fXxjEbpmb2nAu8ND1grazZ1EhMGdRqVerAtvEJeiy7SzA3SLXpg2CtRDtCAFfn`
|
XMR: `8BjCARiV2uB2gZTbbiMUetfRxcAYZgVM5fXxjEbpmb2nAu8ND1grazZ1EhMGdRqVerAtvEJeiy7SzA3SLXpg2CtRDtCAFfn`
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ type Solution struct {
|
|||||||
Nonce uint32 // Solution nonce. This is the "answer" to the problem.
|
Nonce uint32 // Solution nonce. This is the "answer" to the problem.
|
||||||
Redirect string // Relative path to redirect to after Solution is accepted.
|
Redirect string // Relative path to redirect to after Solution is accepted.
|
||||||
|
|
||||||
Steps int8 // Steps, as described in Challenge.
|
|
||||||
|
|
||||||
// TODO: Maybe make the redirect shit auto, idk.
|
// TODO: Maybe make the redirect shit auto, idk.
|
||||||
|
|
||||||
host *url.URL
|
host *url.URL
|
||||||
@@ -102,7 +100,6 @@ func genHashes(ctx context.Context, c Challenge) <-chan Solution {
|
|||||||
Salt: c.Salt,
|
Salt: c.Salt,
|
||||||
Nonce: nonce,
|
Nonce: nonce,
|
||||||
Redirect: "/", // Use sensible default for placeholder, for now.
|
Redirect: "/", // Use sensible default for placeholder, for now.
|
||||||
Steps: c.Steps - 1,
|
|
||||||
}
|
}
|
||||||
// Ensure we don't hang if out channel is full on ctx close.
|
// Ensure we don't hang if out channel is full on ctx close.
|
||||||
select {
|
select {
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/cookiejar"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -31,26 +33,33 @@ func solveTest(ctx context.Context, hc http.Client, host string) error {
|
|||||||
connType = "tor"
|
connType = "tor"
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Fetching new %s challenge...", connType)
|
steps := int8(1)
|
||||||
c, err := NewChallenge(ctx, hc, host)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("Challenge: %s, Difficulty: %d, Steps: %d\n", c.Salt, c.Diff, c.Steps)
|
|
||||||
|
|
||||||
s, err := Solve(ctx, c)
|
for steps > 0 {
|
||||||
if err != nil {
|
log.Printf("Fetching new %s challenge...", connType)
|
||||||
return err
|
c, err := NewChallenge(ctx, hc, host)
|
||||||
}
|
if err != nil {
|
||||||
log.Printf("Solution hash: %x, nonce: %d\n", s.Hash, s.Nonce)
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("Challenge: %s, Difficulty: %d, Steps: %d\n", c.Salt, c.Diff, c.Steps)
|
||||||
|
steps = c.Steps
|
||||||
|
|
||||||
resp, err := Submit(ctx, hc, s, "")
|
s, err := Solve(ctx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
log.Printf("Solution hash: %x, nonce: %d\n", s.Hash, s.Nonce)
|
||||||
|
|
||||||
log.Printf("Response: %s\n\n", resp.Header.Get("Set-Cookie"))
|
resp, err := Submit(ctx, hc, s, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := io.ReadAll(resp.Body)
|
||||||
|
log.Printf("Response: %s\n\n", b[:60])
|
||||||
|
|
||||||
|
resp.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -67,9 +76,16 @@ func newProxyTransport() *http.Transport {
|
|||||||
func TestSubmit(t *testing.T) {
|
func TestSubmit(t *testing.T) {
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
|
|
||||||
err := solveTest(ctx, http.Client{}, _TEST_HOST)
|
jar, err := cookiejar.New(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = solveTest(ctx, http.Client{Jar: jar}, _TEST_HOST)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var dnsErr *net.DNSError
|
var dnsErr *net.DNSError
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module github.com/y-a-t-s/cerberus
|
module gitgud.io/yats/cerberus
|
||||||
|
|
||||||
go 1.25.5
|
go 1.25.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/minio/sha256-simd v1.0.1
|
github.com/minio/sha256-simd v1.0.1
|
||||||
|
|||||||
55
http.go
55
http.go
@@ -34,14 +34,16 @@ func NewChallenge(ctx context.Context, hc http.Client, host string) (Challenge,
|
|||||||
return Challenge{}, err
|
return Challenge{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update host url in case we get redirected across domains.
|
if hc.CheckRedirect == nil {
|
||||||
hc.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
// Update host url in case we get redirected across domains.
|
||||||
rh := req.URL.Host
|
hc.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||||
if rh != u.Host && strings.HasPrefix(rh, "kiwifarms") {
|
rh := req.URL.Host
|
||||||
u.Host = rh
|
if rh != u.Host && strings.HasPrefix(rh, "kiwifarms") {
|
||||||
}
|
u.Host = rh
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil)
|
req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil)
|
||||||
@@ -95,31 +97,7 @@ func Submit(ctx context.Context, hc http.Client, s Solution, redirect string) (*
|
|||||||
s.Redirect = redirect
|
s.Redirect = redirect
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := postSolution(ctx, hc, s)
|
return postSolution(ctx, hc, s)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// This feels gross, but it works.
|
|
||||||
for s.Steps > 0 {
|
|
||||||
resp.Body.Close()
|
|
||||||
|
|
||||||
c, err := NewChallenge(ctx, hc, s.host.String())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s, err = Solve(ctx, c)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resp, err = Submit(ctx, hc, s, redirect)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseHost(addr string) (*url.URL, error) {
|
func parseHost(addr string) (*url.URL, error) {
|
||||||
@@ -144,18 +122,7 @@ func postSolution(ctx context.Context, hc http.Client, s Solution) (*http.Respon
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := hc.Do(req)
|
return hc.Do(req)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Additionally verify failure from response JSON. Maybe include resp body in err type.
|
|
||||||
// Rejected solution response: status=400 body={"success":false,"reason":"invalid_solution","action":"retry"}
|
|
||||||
if resp.StatusCode == 400 {
|
|
||||||
return resp, &ErrInvalidSolution{s}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseTags(r io.Reader) (Challenge, error) {
|
func parseTags(r io.Reader) (Challenge, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user