mirror of
https://github.com/maride/barf.git
synced 2024-12-22 22:47:30 +00:00
Add chunk support
This commit is contained in:
parent
c397b3640e
commit
31ab515a01
3
barf.py
3
barf.py
@ -41,7 +41,7 @@ def main():
|
|||||||
|
|
||||||
# start the bruteforcing madness ;)
|
# start the bruteforcing madness ;)
|
||||||
# DisableLogging()
|
# DisableLogging()
|
||||||
Bruteforce(bm, args["knownPrefix"], args["knownSuffix"])
|
Bruteforce(bm, args["knownPrefix"], args["knownSuffix"], args["chunksize"])
|
||||||
|
|
||||||
# g'night, gdb
|
# g'night, gdb
|
||||||
gdb.execute("quit")
|
gdb.execute("quit")
|
||||||
@ -55,6 +55,7 @@ def getArguments():
|
|||||||
a["winAddr"] = barf_win_addr
|
a["winAddr"] = barf_win_addr
|
||||||
a["knownPrefix"] = barf_known_prefix
|
a["knownPrefix"] = barf_known_prefix
|
||||||
a["knownSuffix"] = barf_known_suffix
|
a["knownSuffix"] = barf_known_suffix
|
||||||
|
a["chunksize"] = barf_chunksize
|
||||||
return a
|
return a
|
||||||
|
|
||||||
|
|
||||||
|
8
barf.sh
8
barf.sh
@ -12,6 +12,7 @@ WINADDR=""
|
|||||||
KNOWNPREFIX=""
|
KNOWNPREFIX=""
|
||||||
KNOWNSUFFIX=""
|
KNOWNSUFFIX=""
|
||||||
BARFPATH="$(dirname $(realpath $0))/src"
|
BARFPATH="$(dirname $(realpath $0))/src"
|
||||||
|
CHUNKSIZE=1
|
||||||
|
|
||||||
# getopt is kind-of unstable across distributions and versions, so we implement it on our own
|
# getopt is kind-of unstable across distributions and versions, so we implement it on our own
|
||||||
# hat-tip to https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash
|
# hat-tip to https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash
|
||||||
@ -43,6 +44,10 @@ while [[ $# -gt 0 ]]; do
|
|||||||
KNOWNSUFFIX="$2"
|
KNOWNSUFFIX="$2"
|
||||||
shift; shift
|
shift; shift
|
||||||
;;
|
;;
|
||||||
|
-c|--chunksize)
|
||||||
|
CHUNKSIZE="$2"
|
||||||
|
shift; shift
|
||||||
|
;;
|
||||||
*) # unknown option - we assume it is the target literal
|
*) # unknown option - we assume it is the target literal
|
||||||
TARGETFILE="$key"
|
TARGETFILE="$key"
|
||||||
shift
|
shift
|
||||||
@ -70,6 +75,7 @@ if [ "$SHOWHELP" == 1 ]; then
|
|||||||
echo " -w | --win-addr 0xDEF042 a location reached if your input is correct"
|
echo " -w | --win-addr 0xDEF042 a location reached if your input is correct"
|
||||||
echo " -< | --prefix CTF{ a known prefix, e.g. the prefix of your flag"
|
echo " -< | --prefix CTF{ a known prefix, e.g. the prefix of your flag"
|
||||||
echo " -> | --suffix } a known suffix, e.g. the suffix of your flag"
|
echo " -> | --suffix } a known suffix, e.g. the suffix of your flag"
|
||||||
|
echo " -c | --chunksize 1 amount of characters to try at once"
|
||||||
echo " -h | --help a great and useful help message, you should try it!"
|
echo " -h | --help a great and useful help message, you should try it!"
|
||||||
echo " ./path/to/your/crackme the path to the target to be fuzzed"
|
echo " ./path/to/your/crackme the path to the target to be fuzzed"
|
||||||
echo "Note that you need to either specify --positive-addr or --negative-addr and your target of course."
|
echo "Note that you need to either specify --positive-addr or --negative-addr and your target of course."
|
||||||
@ -77,5 +83,5 @@ if [ "$SHOWHELP" == 1 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# ready for take-off
|
# ready for take-off
|
||||||
gdb --quiet -nx --eval-command "py barf_positive_addr='$POSITIVEADDR';barf_negative_addr='$NEGATIVEADDR';barf_win_addr='$WINADDR';barf_known_prefix='$KNOWNPREFIX';barf_known_suffix='$KNOWNSUFFIX';barf_path='$BARFPATH'" --command barf.py $TARGETFILE
|
gdb --quiet -nx --eval-command "py barf_positive_addr='$POSITIVEADDR';barf_negative_addr='$NEGATIVEADDR';barf_win_addr='$WINADDR';barf_known_prefix='$KNOWNPREFIX';barf_known_suffix='$KNOWNSUFFIX';barf_path='$BARFPATH';barf_chunksize=$CHUNKSIZE" --command barf.py $TARGETFILE
|
||||||
|
|
||||||
|
BIN
examples/double-trouble
Executable file
BIN
examples/double-trouble
Executable file
Binary file not shown.
53
examples/double-trouble.c
Normal file
53
examples/double-trouble.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// double-trouble.c
|
||||||
|
// ----------------
|
||||||
|
//
|
||||||
|
// The binary reads some chars from stdin and checks it against a hard-coded flag.
|
||||||
|
// It checks two chars at a time, this time with a positive counter :)
|
||||||
|
// If the entered flag is correct, a corresponding message will be printed out.
|
||||||
|
//
|
||||||
|
// Compile with
|
||||||
|
// gcc -o double-trouble double-trouble.c
|
||||||
|
//
|
||||||
|
// Quick binary analysis
|
||||||
|
// - load into gdb
|
||||||
|
// - execute "start", so the binary is mapped to the final position
|
||||||
|
// - execute "disas main"
|
||||||
|
// Look at 0x00005555555551f5 <+160>. It moves 2 to rbp-0x4, that's the correctChars += 2 below.
|
||||||
|
// Right after that, the i value is also increased with 2, so double-check to get the right address ;)
|
||||||
|
// Anyway, that's the right address for --positive-address
|
||||||
|
// Finding the win function is easy as always. We need to search for the point where puts("yay, ...") is called.
|
||||||
|
// And that is at 0x000055555555523d!
|
||||||
|
//
|
||||||
|
// With the addresses identified above, we call barf with:
|
||||||
|
// ./barf.sh --positive-addr 0x5555555551f5 --win-addr 0x55555555523d --chunksize 2 ./double-trouble
|
||||||
|
//
|
||||||
|
// Please note that your addresses will likely differ, e.g. if you edit the source file below.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define BUFSIZE 32
|
||||||
|
|
||||||
|
int main(int argc ,char* argv[]) {
|
||||||
|
char buf[BUFSIZE];
|
||||||
|
char flag[BUFSIZE] = "CTF{w3_h4ck_1n_du4l1ty!}";
|
||||||
|
|
||||||
|
// read flag
|
||||||
|
fgets(buf, BUFSIZE, stdin);
|
||||||
|
|
||||||
|
// walk flag
|
||||||
|
int correctChars = 0;
|
||||||
|
int i = 0;
|
||||||
|
while(buf[i] != '\0' && flag[i] != '\0' && i < BUFSIZE) {
|
||||||
|
if(buf[i] == flag[i] && buf[i+1] == flag[i+1]) {
|
||||||
|
correctChars += 2;
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check flag
|
||||||
|
if(strlen(flag) == correctChars) {
|
||||||
|
puts("yay, that's the flag! :)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}_!?"
|
|||||||
|
|
||||||
# bruteforces a single character, sandwiched between the known parts.
|
# bruteforces a single character, sandwiched between the known parts.
|
||||||
# Returns the most promising string.
|
# Returns the most promising string.
|
||||||
def BruteforceChar(bm, knownPrefix, knownSuffix):
|
def BruteforceChar(bm, knownPrefix, knownSuffix, chunksize):
|
||||||
# keyFragment is the variable were we store our found-to-be-correct chars
|
# keyFragment is the variable were we store our found-to-be-correct chars
|
||||||
keyFragment = ""
|
keyFragment = ""
|
||||||
|
|
||||||
@ -19,11 +19,11 @@ def BruteforceChar(bm, knownPrefix, knownSuffix):
|
|||||||
# the resulting score is the base for the next round of guessing, hopefully with a single solution better than the score of knownPrefix + keyFragment + impossibleChar.
|
# the resulting score is the base for the next round of guessing, hopefully with a single solution better than the score of knownPrefix + keyFragment + impossibleChar.
|
||||||
# please also note that this will massively fail if the "impossible" character is part of the flag, at the very position it was tested on ... have fun detecting that
|
# please also note that this will massively fail if the "impossible" character is part of the flag, at the very position it was tested on ... have fun detecting that
|
||||||
bm.ResetBreakpoints()
|
bm.ResetBreakpoints()
|
||||||
TryInput(knownPrefix + keyFragment + "^" + knownSuffix)
|
TryInput(knownPrefix + keyFragment + "^" * chunksize + knownSuffix)
|
||||||
refScore = bm.PopScore()
|
refScore = bm.PopScore()
|
||||||
|
|
||||||
# iterate over every character in the charset
|
# iterate over every character in the charset
|
||||||
for c in charset:
|
for c in generateCharset(chunksize):
|
||||||
# generate full input string
|
# generate full input string
|
||||||
inp = knownPrefix + keyFragment + c + knownSuffix
|
inp = knownPrefix + keyFragment + c + knownSuffix
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ def BruteforceChar(bm, knownPrefix, knownSuffix):
|
|||||||
score = bm.PopScore()
|
score = bm.PopScore()
|
||||||
|
|
||||||
# yay, that's a hit
|
# yay, that's a hit
|
||||||
if score > refScore:
|
if score > refScore or bm.HitWin():
|
||||||
keyFragment += c
|
keyFragment += c
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
@ -45,9 +45,9 @@ def BruteforceChar(bm, knownPrefix, knownSuffix):
|
|||||||
# Bruteforce calls BruteforceChar until:
|
# Bruteforce calls BruteforceChar until:
|
||||||
# - BruteforceChar was unable to increase the score using any character in the charset, OR
|
# - BruteforceChar was unable to increase the score using any character in the charset, OR
|
||||||
# - the "win" breakpoint is hit :)
|
# - the "win" breakpoint is hit :)
|
||||||
def Bruteforce(bm, knownPrefix, knownSuffix):
|
def Bruteforce(bm, knownPrefix, knownSuffix, chunksize):
|
||||||
while True:
|
while True:
|
||||||
res = BruteforceChar(bm, knownPrefix, knownSuffix)
|
res = BruteforceChar(bm, knownPrefix, knownSuffix, chunksize)
|
||||||
if res is False:
|
if res is False:
|
||||||
# no character from the given charset matched. :(
|
# no character from the given charset matched. :(
|
||||||
EnableLogging()
|
EnableLogging()
|
||||||
@ -78,3 +78,11 @@ def Bruteforce(bm, knownPrefix, knownSuffix):
|
|||||||
return knownPrefix + knownSuffix
|
return knownPrefix + knownSuffix
|
||||||
|
|
||||||
|
|
||||||
|
# generateCharset returns an iteratable object (string or set) to be used by the bruteforce function.
|
||||||
|
# the chunksize is the amount of characters to stuff into an entry
|
||||||
|
def generateCharset(chunksize):
|
||||||
|
c = charset
|
||||||
|
for i in range(chunksize - 1):
|
||||||
|
c = [ a + b for a in c for b in charset ]
|
||||||
|
return c
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user