Open class file in jadx
package p000;
import java.nio.charset.Charset;
import java.util.Scanner;
/* renamed from: FlagChecker */
/* loaded from: FlagChecker.class */
class FlagChecker {
FlagChecker() {
}
public static void main(String[] strArr) {
System.out.print("What's the flag? ");
System.out.flush();
Scanner scanner = new Scanner(System.in);
String nextLine = scanner.nextLine();
scanner.close();
byte[] bytes = nextLine.getBytes(Charset.forName("UTF-8"));
if (bytes.length == 38 && (((bytes[34] ^ (bytes[23] * 7)) ^ ((bytes[36] ^ (-1)) + 13)) & 255) == 182 && (((bytes[37] ^ (bytes[10] * 7)) ^ ((bytes[21] ^ (-1)) + 13)) & 255) == 223 && (((bytes[24] ^ (bytes[23] * 7)) ^ ((bytes[19] ^ (-1)) + 13)) & 255) == 205 && (((bytes[25] ^ (bytes[13] * 7)) ^ ((bytes[23] ^ (-1)) + 13)) & 255) == 144 && (((bytes[6] ^ (bytes[27] * 7)) ^ ((bytes[25] ^ (-1)) + 13)) & 255) == 138 && (((bytes[4] ^ (bytes[32] * 7)) ^ ((bytes[22] ^ (-1)) + 13)) & 255) == 227 && (((bytes[25] ^ (bytes[19] * 7)) ^ ((bytes[1] ^ (-1)) + 13)) & 255) == 107 && (((bytes[22] ^ (bytes[7] * 7)) ^ ((bytes[29] ^ (-1)) + 13)) & 255) == 85 && (((bytes[15] ^ (bytes[10] * 7)) ^ ((bytes[20] ^ (-1)) + 13)) & 255) == 188 && (((bytes[29] ^ (bytes[16] * 7)) ^ ((bytes[12] ^ (-1)) + 13)) & 255) == 88 && (((bytes[35] ^ (bytes[4] * 7)) ^ ((bytes[33] ^ (-1)) + 13)) & 255) == 84 && (((bytes[36] ^ (bytes[2] * 7)) ^ ((bytes[4] ^ (-1)) + 13)) & 255) == 103 && (((bytes[26] ^ (bytes[3] * 7)) ^ ((bytes[1] ^ (-1)) + 13)) & 255) == 216 && (((bytes[12] ^ (bytes[6] * 7)) ^ ((bytes[18] ^ (-1)) + 13)) & 255) == 165 && (((bytes[12] ^ (bytes[28] * 7)) ^ ((bytes[36] ^ (-1)) + 13)) & 255) == 151 && (((bytes[20] ^ (bytes[0] * 7)) ^ ((bytes[21] ^ (-1)) + 13)) & 255) == 101 && (((bytes[27] ^ (bytes[36] * 7)) ^ ((bytes[14] ^ (-1)) + 13)) & 255) == 248 && (((bytes[35] ^ (bytes[2] * 7)) ^ ((bytes[19] ^ (-1)) + 13)) & 255) == 44 && (((bytes[13] ^ (bytes[11] * 7)) ^ ((bytes[33] ^ (-1)) + 13)) & 255) == 242 && (((bytes[33] ^ (bytes[11] * 7)) ^ ((bytes[3] ^ (-1)) + 13)) & 255) == 235 && (((bytes[31] ^ (bytes[37] * 7)) ^ ((bytes[29] ^ (-1)) + 13)) & 255) == 248 && (((bytes[1] ^ (bytes[33] * 7)) ^ ((bytes[31] ^ (-1)) + 13)) & 255) == 33 && (((bytes[34] ^ (bytes[22] * 7)) ^ ((bytes[35] ^ (-1)) + 13)) & 255) == 84 && (((bytes[36] ^ (bytes[16] * 7)) ^ ((bytes[4] ^ (-1)) + 13)) & 255) == 75 && (((bytes[8] ^ (bytes[3] * 7)) ^ ((bytes[10] ^ (-1)) + 13)) & 255) == 214 && (((bytes[20] ^ (bytes[5] * 7)) ^ ((bytes[12] ^ (-1)) + 13)) & 255) == 193 && (((bytes[28] ^ (bytes[34] * 7)) ^ ((bytes[16] ^ (-1)) + 13)) & 255) == 210 && (((bytes[3] ^ (bytes[35] * 7)) ^ ((bytes[9] ^ (-1)) + 13)) & 255) == 205 && (((bytes[27] ^ (bytes[22] * 7)) ^ ((bytes[2] ^ (-1)) + 13)) & 255) == 46 && (((bytes[27] ^ (bytes[18] * 7)) ^ ((bytes[9] ^ (-1)) + 13)) & 255) == 54 && (((bytes[3] ^ (bytes[29] * 7)) ^ ((bytes[22] ^ (-1)) + 13)) & 255) == 32 && (((bytes[24] ^ (bytes[4] * 7)) ^ ((bytes[13] ^ (-1)) + 13)) & 255) == 99 && (((bytes[22] ^ (bytes[16] * 7)) ^ ((bytes[13] ^ (-1)) + 13)) & 255) == 108 && (((bytes[12] ^ (bytes[8] * 7)) ^ ((bytes[30] ^ (-1)) + 13)) & 255) == 117 && (((bytes[25] ^ (bytes[27] * 7)) ^ ((bytes[35] ^ (-1)) + 13)) & 255) == 146 && (((bytes[16] ^ (bytes[10] * 7)) ^ ((bytes[14] ^ (-1)) + 13)) & 255) == 250 && (((bytes[21] ^ (bytes[25] * 7)) ^ ((bytes[12] ^ (-1)) + 13)) & 255) == 195 && (((bytes[26] ^ (bytes[10] * 7)) ^ ((bytes[30] ^ (-1)) + 13)) & 255) == 203 && (((bytes[20] ^ (bytes[2] * 7)) ^ ((bytes[1] ^ (-1)) + 13)) & 255) == 47 && (((bytes[34] ^ (bytes[12] * 7)) ^ ((bytes[27] ^ (-1)) + 13)) & 255) == 121 && (((bytes[19] ^ (bytes[34] * 7)) ^ ((bytes[20] ^ (-1)) + 13)) & 255) == 246 && (((bytes[25] ^ (bytes[22] * 7)) ^ ((bytes[14] ^ (-1)) + 13)) & 255) == 61 && (((bytes[19] ^ (bytes[28] * 7)) ^ ((bytes[37] ^ (-1)) + 13)) & 255) == 189 && (((bytes[24] ^ (bytes[9] * 7)) ^ ((bytes[17] ^ (-1)) + 13)) & 255) == 185) {
System.out.println("Correct!");
} else {
System.out.println("Not quite...");
}
}
}
shove conditions in z3 (find replace ftw):
from z3 import *
flag = []
for x in range(38):
c = BitVec('x%d'%x, 8)
flag.append(c)
s = Solver()
s.add((((flag[34] ^ (flag[23] * 7)) ^ ((flag[36] ^ (-1)) + 13)) & 255) == 182)
s.add((((flag[37] ^ (flag[10] * 7)) ^ ((flag[21] ^ (-1)) + 13)) & 255) == 223)
s.add((((flag[24] ^ (flag[23] * 7)) ^ ((flag[19] ^ (-1)) + 13)) & 255) == 205)
s.add((((flag[25] ^ (flag[13] * 7)) ^ ((flag[23] ^ (-1)) + 13)) & 255) == 144)
s.add((((flag[6] ^ (flag[27] * 7)) ^ ((flag[25] ^ (-1)) + 13)) & 255) == 138)
s.add((((flag[4] ^ (flag[32] * 7)) ^ ((flag[22] ^ (-1)) + 13)) & 255) == 227)
s.add((((flag[25] ^ (flag[19] * 7)) ^ ((flag[1] ^ (-1)) + 13)) & 255) == 107)
s.add((((flag[22] ^ (flag[7] * 7)) ^ ((flag[29] ^ (-1)) + 13)) & 255) == 85)
s.add((((flag[15] ^ (flag[10] * 7)) ^ ((flag[20] ^ (-1)) + 13)) & 255) == 188)
s.add((((flag[29] ^ (flag[16] * 7)) ^ ((flag[12] ^ (-1)) + 13)) & 255) == 88)
s.add((((flag[35] ^ (flag[4] * 7)) ^ ((flag[33] ^ (-1)) + 13)) & 255) == 84)
s.add((((flag[36] ^ (flag[2] * 7)) ^ ((flag[4] ^ (-1)) + 13)) & 255) == 103)
s.add((((flag[26] ^ (flag[3] * 7)) ^ ((flag[1] ^ (-1)) + 13)) & 255) == 216)
s.add((((flag[12] ^ (flag[6] * 7)) ^ ((flag[18] ^ (-1)) + 13)) & 255) == 165)
s.add((((flag[12] ^ (flag[28] * 7)) ^ ((flag[36] ^ (-1)) + 13)) & 255) == 151)
s.add((((flag[20] ^ (flag[0] * 7)) ^ ((flag[21] ^ (-1)) + 13)) & 255) == 101)
s.add((((flag[27] ^ (flag[36] * 7)) ^ ((flag[14] ^ (-1)) + 13)) & 255) == 248)
s.add((((flag[35] ^ (flag[2] * 7)) ^ ((flag[19] ^ (-1)) + 13)) & 255) == 44)
s.add((((flag[13] ^ (flag[11] * 7)) ^ ((flag[33] ^ (-1)) + 13)) & 255) == 242)
s.add((((flag[33] ^ (flag[11] * 7)) ^ ((flag[3] ^ (-1)) + 13)) & 255) == 235)
s.add((((flag[31] ^ (flag[37] * 7)) ^ ((flag[29] ^ (-1)) + 13)) & 255) == 248)
s.add((((flag[1] ^ (flag[33] * 7)) ^ ((flag[31] ^ (-1)) + 13)) & 255) == 33)
s.add((((flag[34] ^ (flag[22] * 7)) ^ ((flag[35] ^ (-1)) + 13)) & 255) == 84)
s.add((((flag[36] ^ (flag[16] * 7)) ^ ((flag[4] ^ (-1)) + 13)) & 255) == 75)
s.add((((flag[8] ^ (flag[3] * 7)) ^ ((flag[10] ^ (-1)) + 13)) & 255) == 214)
s.add((((flag[20] ^ (flag[5] * 7)) ^ ((flag[12] ^ (-1)) + 13)) & 255) == 193)
s.add((((flag[28] ^ (flag[34] * 7)) ^ ((flag[16] ^ (-1)) + 13)) & 255) == 210)
s.add((((flag[3] ^ (flag[35] * 7)) ^ ((flag[9] ^ (-1)) + 13)) & 255) == 205)
s.add((((flag[27] ^ (flag[22] * 7)) ^ ((flag[2] ^ (-1)) + 13)) & 255) == 46)
s.add((((flag[27] ^ (flag[18] * 7)) ^ ((flag[9] ^ (-1)) + 13)) & 255) == 54)
s.add((((flag[3] ^ (flag[29] * 7)) ^ ((flag[22] ^ (-1)) + 13)) & 255) == 32)
s.add((((flag[24] ^ (flag[4] * 7)) ^ ((flag[13] ^ (-1)) + 13)) & 255) == 99)
s.add((((flag[22] ^ (flag[16] * 7)) ^ ((flag[13] ^ (-1)) + 13)) & 255) == 108)
s.add((((flag[12] ^ (flag[8] * 7)) ^ ((flag[30] ^ (-1)) + 13)) & 255) == 117)
s.add((((flag[25] ^ (flag[27] * 7)) ^ ((flag[35] ^ (-1)) + 13)) & 255) == 146)
s.add((((flag[16] ^ (flag[10] * 7)) ^ ((flag[14] ^ (-1)) + 13)) & 255) == 250)
s.add((((flag[21] ^ (flag[25] * 7)) ^ ((flag[12] ^ (-1)) + 13)) & 255) == 195)
s.add((((flag[26] ^ (flag[10] * 7)) ^ ((flag[30] ^ (-1)) + 13)) & 255) == 203)
s.add((((flag[20] ^ (flag[2] * 7)) ^ ((flag[1] ^ (-1)) + 13)) & 255) == 47)
s.add((((flag[34] ^ (flag[12] * 7)) ^ ((flag[27] ^ (-1)) + 13)) & 255) == 121)
s.add((((flag[19] ^ (flag[34] * 7)) ^ ((flag[20] ^ (-1)) + 13)) & 255) == 246)
s.add((((flag[25] ^ (flag[22] * 7)) ^ ((flag[14] ^ (-1)) + 13)) & 255) == 61)
s.add((((flag[19] ^ (flag[28] * 7)) ^ ((flag[37] ^ (-1)) + 13)) & 255) == 189)
s.add((((flag[24] ^ (flag[9] * 7)) ^ ((flag[17] ^ (-1)) + 13)) & 255) == 185)
s.check()
model = s.model()
out = ''
for x in flag:
out += chr(model[x].as_long())
print(out)
profit:
% python dd.py
lactf{1_d0nt_see_3_b1ll10n_s0lv3s_y3t}
entry point looks like:
undefined8 entry(void)
{
char correct_flag_char;
size_t sVar1;
long n;
undefined4 *puVar2;
char input_flag [256];
puts("Welcome to CTFd+!");
puts("So far, we only have one challenge, which is one more than the number of databases we have.\n");
puts("Very Doable Pwn - 500 points, 0 solves");
puts("Can you help me pwn this program?");
puts("#include <stdio.h>\nint main(void) {\n puts(\"Bye!\");\n return 0;\n}\n");
puts("Enter the flag:");
fgets(input_flag,0x100,stdin);
sVar1 = strcspn(input_flag,"\n");
n = 0;
puVar2 = &DAT_00104060;
input_flag[sVar1] = '\0';
do {
correct_flag_char = whatever(puVar2[n]);
if (correct_flag_char != input_flag[n]) {
puts("Incorrect flag.");
return 0;
}
n = n + 1;
} while (n != 0x2f);
puts("You got the flag! Unfortunately we don\'t exactly have a database to store the solve in...");
return 0;
}
we can patch the binary so this is never taken:
if (correct_flag_char != input_flag[n]) {
puts("Incorrect flag.");
return 0;
}
by changing JZ to JMP:
00101106 e8 25 01 00 00 CALL whatever undefined whatever()
0010110b 3a 04 33 CMP correct_flag_char,byte ptr [RBX + n*0x1]=>input_flag
HERE 0010110e 74 e8 JZ LAB_001010f8
00101110 48 8d 3d 11 0f 00 00 LEA RDI,[s_Incorrect_flag._00102028] = "Incorrect flag."
00101117 e8 14 ff ff ff CALL <EXTERNAL>::puts int puts(char * __s)
data = bytearray(open("ctfd_plus", "rb").read())
data[0x110e] = 0xeb # jz -> jmp
open("ctfd_patched", "wb").write(data)
prepare gbd script to dump AL
register after the whatever
function call (AL will contains the correct flag chr):
import gdb
def read_reg(reg):
return gdb.parse_and_eval("${}".format(reg))
def gdb_continue():
gdb.execute('continue')
gdb.execute('break *0x000055555555510b') # fix addr
flag = ''
while 1:
gdb.execute("continue")
bla = int(read_reg('al'))
flag += chr(bla)
print(flag)
then run it on patched binary:
% gdb ./ctfd_patched
pwndbg> starti
pwndbg> source gggdb.py
Breakpoint 1 at 0x55555555510b
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Welcome to CTFd+!
So far, we only have one challenge, which is one more than the number of databases we have.
Very Doable Pwn - 500 points, 0 solves
Can you help me pwn this program?
#include <stdio.h>
int main(void) {
puts("Bye!");
return 0;
}
Enter the flag:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Breakpoint 1, 0x000055555555510b in ?? ()
l
Breakpoint 1, 0x000055555555510b in ?? ()
la
Breakpoint 1, 0x000055555555510b in ?? ()
lac
///
Breakpoint 1, 0x000055555555510b in ?? ()
lactf{m4yb3_th3r3_1s_s0m3_m3r1t_t0_us1ng_4_d
Breakpoint 1, 0x000055555555510b in ?? ()
lactf{m4yb3_th3r3_1s_s0m3_m3r1t_t0_us1ng_4_db
Breakpoint 1, 0x000055555555510b in ?? ()
lactf{m4yb3_th3r3_1s_s0m3_m3r1t_t0_us1ng_4_db}
00401000 int64_t _start() __noreturn
00401017 syscall(sys_write {1}, fd: 1, buf: "Give me the flag: That was not t…", count: 0x12)
00401025 int64_t rax = syscall(sys_read {0}, fd: 0, buf: &__return_addr, count: 0x64)
0040102b if (rax == 0x40)
0040102d int64_t r12_1 = 0
0040103e for (int64_t r10_1 = 0; r10_1 s< rax; r10_1 = r10_1 + 1)
0040104d int64_t r8_2 = rol.q(*((zx.q(*(&__return_addr + r10_1)) << 3) + 0x40203c), 8)
00401051 uint64_t r13_1 = zx.q(r8_2.b)
00401055 int64_t r14_1 = 0
0040105b while (true)
0040105b if (r14_1 s>= r13_1)
0040106b r12_1 = r12_1 + 1
0040106b break
0040105d r8_2 = rol.q(r8_2, 8)
00401064 if (r8_2.b == r10_1.b)
00401064 break
00401066 r14_1 = r14_1 + 1
00401076 if (r12_1 == 0)
00401089 return sub_40109a(0, &data_40202a, 0x12) __tailcall // win
00401098 return sub_40109a(0, "That was not the flag :(That was…", 0x18) __tailcall
input string of len 0x3f (0x40 with \n), then each char is checked i dont care/know how but:
- every incorrect flag char increment r12 register
- at the end, if r12 == 0, it's a win
so we can bruteforce each char using a gdb script:
import gdb
import string
passlen = 0x40
break_addr = 0x00401073
code = ["_"]*passlen
printable = string.printable[:-5]
def gdb_run_with_stdin(pwd):
with open('_cracking', 'w') as f:
f.write(pwd)
gdb.execute('run < _cracking')
def read_reg(reg):
return gdb.parse_and_eval("${}".format(reg))
def gdb_continue():
gdb.execute('continue')
gdb.execute('break *{}'.format(break_addr))
errors = -1
for trial in range(passlen):
for c in range(0x21, 0x7E+1):
code[trial] = chr(c)
print("trying: %s"%''.join(code))
gdb_run_with_stdin(''.join(code))
res = int(read_reg("r12"))
if errors == -1:
errors = res
continue
if res > errors:
errors = res
if res < errors:
print('FOUND: %s'%''.join(code))
errors = res
break
print(''.join(code))
% gdb switcheroo
pwndbg> source lolz.py
//// wait for it
trying: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60az_
Give me the flag:
Breakpoint 1, 0x0000000000401073 in ?? ()
trying: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60a{_
Give me the flag:
Breakpoint 1, 0x0000000000401073 in ?? ()
trying: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60a|_
Give me the flag:
Breakpoint 1, 0x0000000000401073 in ?? ()
trying: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60a}
Give me the flag:
Breakpoint 1, 0x0000000000401073 in ?? ()
FOUND: lactf{4223M8LY_5W17Ch_57473M3n75_4r3_7h3_4850LU73_8357_u+1f60a}_