# pyny ## Source ``` #coding: punycode def _(): pass ('Correct!' if ('Enter the flag: ') == 'DUCTF{%s}' % _.____ else 'Wrong!')-gdd7dd23l3by980a4baunja1d4ukc3a3e39172b4sagce87ciajq2bi5atq4b9b3a3cy0gqa9019gtar0ck ``` ## Solve You probably want to do some easy stuff, like.. "decoding", and sure you can do that apparently. Well I'm different, and went for the debugger route. Sadly the debugger shipped with Pycharm and VSCode seems to be incapable of running this punycode. So if python is based on C and the python debugger is not an option, what do you do? Correct, you step through the literal python elf with gdb. Set a breakpoint at several Functions that might compare memory and get ready to cramp from the constant Enter Spam in order to continue through that binary. At Some point you will get the flag, but that can be optimised. Luckily some guy called Juan Cespedes, might have had a similar problem and decided to do something: ![](justuseltrace.jpg) And thats what i did (plus some minor modification to shrink the output): ```bash $ echo abc | ltrace python3 pyny.py 2>&1 | grep "DUCTF" -A 10 memcpy(0x7f4171ffbe90, "'DUCTF{%s}'", 11) = 0x7f4171ffbe90 __ctype_b_loc() = 0x7f41724fbfe0 memcpy(0x7f4171fe9e30, "\340\253\377qA\177\0\005\037rA\177\0\0p:\004rA\177\0\0\020\262\245\0\0\0\0\0"..., 192) = 0x7f4171fe9e30 memset(0xdb2210, '\0', 24) = 0xdb2210 strlen("DUCTF{%s}'") = 10 strchr("DUCTF{%s}'", '\\') = nil memcpy(0x7f4172043be0, "DUCTF{%s}", 9) = 0x7f4172043be0 memcpy(0x7f417203f620, "", 0) = 0x7f417203f620 memcpy(0x7f4172008b20, "\001\0\0\0\0\0\0\0\200Y\225\0\0\0\0\0\037\0\0\0\0\0\0\0\377\377\377\377\377\377\377\377"..., 100) = 0x7f4172008b20 memcpy(0x7f41720501d0, "\341\265\226\312\270\341\265\227\312\260\302\272\342\201\277_\312\267\302\252\312\263\341\265\220\341\265\230\341\265\226", 31) = 0x7f41720501d0 strlen("\341\265\226\312\270\341\265\227\312\260\302\272\342\201\277_\312\267\302\252\312\263\341\265\220\341\265\230\341\265\226") = 31 memcpy(0x7f4172008b20, "\001\0\0\0\0\0\0\0\200Y\225\0\0\0\0\0\037\0\0\0\0\0\0\0\377\377\377\377\377\377\377\377"..., 100) = 0x7f4172008b20 strlen("NFKC") = 4 memcpy(0x7f4172050220, "NFKC", 4) = 0x7f4172050220 strlen("NFC") = 3 memcmp(0x7f4172050220, 0x85ba56, 3, 0xa476e0) = 8 strlen("NFKC") = 4 -- memcpy(0x7f4172198560, "DUCTF{", 6) = 0x7f4172198560 memcpy(0x7f4172198566, "python_warmup", 13) = 0x7f4172198566 memcpy(0x7f4172198573, "}", 1) = 0x7f4172198573 memcpy(0x7f417203edd0, "\001\0\0\0\0\0\0\0\200Y\225\0\0\0\0\0m\0\0\0\0\0\0\0\377\377\377\377\377\377\377\377"..., 69) = 0x7f417203edd0 memset(0x7f417203f708, '\0', 32) = 0x7f417203f708 strlen("sep") = 3 memcmp(0x9888f0, 0x7f41720504e0, 3, 0xd47b70) = 0 strlen("end") = 3 memcpy(0x7f41720504e0, "end", 3) = 0x7f41720504e0 memcmp(0x968390, 0x7f41720504e0, 3, 0xd47b70) = 0 ``` And we can literally see python move that flag into memory and grab it for some quick points. ``` DUCTF{python_warmup} ```