Keygenme
**  
reverse  
picoctf

Can you get the flag?
The Ghidra code for the binary:


undefined8 FUN_0010148b(void)

{
char cVar1;
long in_FS_OFFSET;
char local_38 [40];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
printf("Enter your license key: ");
fgets(local_38,0x25,stdin);
cVar1 = FUN_00101209(local_38);
if (cVar1 == '\0') {
puts("That key is invalid.");
}
else {
puts("That key is valid.");
}
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}




undefined8 FUN_00101209(char *param_1)

{
size_t sVar1;
undefined8 uVar2;
long in_FS_OFFSET;
int local_d0;
int local_cc;
int local_c8;
int local_c4;
int local_c0;
undefined2 local_ba;
byte local_b8 [16];
byte local_a8 [16];
undefined8 local_98;
undefined8 local_90;
undefined8 local_88;
undefined4 local_80;
char local_78 [13];
undefined local_6b;
undefined local_6a;
undefined local_66;
undefined local_60;
undefined local_5e;
undefined local_5b;
char local_58 [32];
char acStack_38 [40];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
local_98 = 0x7b4654436f636970;
local_90 = 0x30795f676e317262;
local_88 = 0x6b5f6e77305f7275;
local_80 = 0x5f7933;
local_ba = 0x7d;
sVar1 = strlen((char *)&local_98);
MD5((uchar *)&local_98,sVar1,local_b8);
sVar1 = strlen((char *)&local_ba);
MD5((uchar *)&local_ba,sVar1,local_a8);
local_d0 = 0;
for (local_cc = 0; local_cc < 0x10; local_cc = local_cc + 1) {
sprintf(local_78 + local_d0,"%02x",(ulong)local_b8[local_cc]);
local_d0 = local_d0 + 2;
}
local_d0 = 0;
for (local_c8 = 0; local_c8 < 0x10; local_c8 = local_c8 + 1) {
sprintf(local_58 + local_d0,"%02x",(ulong)local_a8[local_c8]);
local_d0 = local_d0 + 2;
}
for (local_c4 = 0; local_c4 < 0x1b; local_c4 = local_c4 + 1) {
acStack_38[local_c4] = *(char *)((long)&local_98 + (long)local_c4);
}
acStack_38[0x1b] = local_6b;
acStack_38[0x1c] = local_66;
acStack_38[0x1d] = local_5b;
acStack_38[0x1e] = local_78[1];
acStack_38[0x1f] = local_6a;
acStack_38[0x20] = local_60;
acStack_38[0x21] = local_5e;
acStack_38[0x22] = local_5b;
acStack_38[0x23] = (undefined)local_ba;
sVar1 = strlen(param_1);
if (sVar1 == 0x24) {
for (local_c0 = 0; local_c0 < 0x24; local_c0 = local_c0 + 1) {
if (param_1[local_c0] != acStack_38[local_c0]) {
uVar2 = 0;
goto LAB_00101475;
}
}
uVar2 = 1;
}
else {
uVar2 = 0;
}
LAB_00101475:
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return uVar2;
}



These variables
local_98 = 0x7b4654436f636970;
local_90 = 0x30795f676e317262;
local_88 = 0x6b5f6e77305f7275;
local_80 = 0x5f7933;
local_ba = 0x7d;
are the begining of the flag "picoCTF{br1ng_y0ur_0wn_k3y_" and the end "}"
The instructions that follow are building the flag from the MD5 of those values.
After running the program with pwndbg I entered inside __libc_start_main
 ► 0x555555555148    call   qword ptr [rip + 0x2e92]      <__libc_start_main>
and checked for any functions.

The one I wanted to jump to was 
0x00005555555550f0  MD5@plt
as right after it the flag is built and saved into memory.

After skipping some of the instructions I finally got to 
sVar1 = strlen(param_1);
then I searched for picoCTF 
pwndbg> search pico
Searching for value: 'pico'
keygenme 0x555555555230 jo 0x55555555529b
[stack] 0x7fffffffdc90 'picoCTF{br1ng_y0ur_0wn_k3y_'
[stack] 0x7fffffffdcf0 0x7b4654436f636970 ('picoCTF{')
[stack] 0x7fffffffe232 'picoctf/keygenm/keygenme'
[stack] 0x7fffffffe487 'picoctf/keygenm'
[stack] 0x7fffffffefdf 'picoctf/keygenm/keygenme'
pwndbg> search k3y
Searching for value: 'k3y'
[stack] 0x7fffffffdca7 0x5555005f79336b /* 'k3y_' */
[stack] 0x7fffffffdd07 0x333839315f79336b ('k3y_1983')
pwndbg> search k3y_1983
Searching for value: 'k3y_1983'
[stack] 0x7fffffffdd07 0x333839315f79336b ('k3y_1983')
pwndbg> search y_1983
Searching for value: 'y_1983'
[stack] 0x7fffffffdd09 0x6336333839315f79 ('y_19836c')
pwndbg> search 1983
Searching for value: '1983'
[stack] 0x7fffffffdd0b 0x3864633633383931 ('19836cd8')
pwndbg>


picoCTF{br1ng_y0ur_0wn_k3y_19836cd8}