Jump to content
Tuts 4 You

Python Crackme (Custom VM)


Go to solution Solved by Extreme Coders,

Recommended Posts

0verp0wer
Posted

Python Crackme (Custom VM)


Hello, this is a crackme made in python by a friends (wrc3667 on discord)

Difficulty: [95 / 100]

The purpose of this challenge is to find the correct key (note: the key should be in hexadecimal, otherwise the program will istantly close)

Features:

- Constant encryption

- Name encryption

- Opcode shuffling

- Bytecode encryption

- Stack encryption

- Bytecode instruction mangling

- Guillotine Interpreter

- Complete namespace virtualization


 

  • 1 month later...
  • Solution
Extreme Coders
Posted (edited)

Correct key is

Spoiler
db1f8101d77e22d2a549059d6410e812b1f0c508d8463f6323f83e91919bf815da1b95da0eaf3f05561a9dca931242e2f9c5ef92dce8fc767805e892229087f2

The correct key can be obtained at runtime. Not necessary to deal with any of the protection features mentioned.  It can be found by hooking and monitoring the arguments passed/return value of any of the push, pop  functions defined in guillotine.pyd. These values are all PyObject's, hence interacting with the CPython API is necessary to log these to stdout. Essentially tracing the operations of the VM will reveal the key when it compares the user input with the correct key.

Probably will do a mini-write in the future up if I get time.

Edited by Extreme Coders
formatting
  • Like 3
  • Thanks 1
Sean the hard worker
Posted
3 hours ago, Extreme Coders said:

Correct key is

  Reveal hidden contents
db1f8101d77e22d2a549059d6410e812b1f0c508d8463f6323f83e91919bf815da1b95da0eaf3f05561a9dca931242e2f9c5ef92dce8fc767805e892229087f2

The correct key can be obtained at runtime. Not necessary to deal with any of the protection features mentioned.  It can be found by hooking and monitoring the arguments passed/return value of any of the push, pop  functions defined in guillotine.pyd. These values are all PyObject's, hence interacting with the CPython API is necessary to log these to stdout. Essentially tracing the operations of the VM will reveal the key when it compares the user input with the correct key.

Probably will do a mini-write in the future up if I get time.

@Extreme Coders How to execute the guillotine.pyd? 

I did this. this is a python file.

import guillotine

guillotine

The result is below.

Quote

"D:\Downloaded Files\Compressed\password\venv\Scripts\python.exe" "D:\Downloaded Files\Compressed\password\Python3-2.py

Process finished with exit code 0

Many thanks in advance.

Regards.

sean.

  • Like 1
Extreme Coders
Posted

@Sean Park - Lovejoy

guillotine.pyd is a Python extension module built in Cython. An extension module can't be executed directly.

If you decompile password.txt_guillotine.pyc using pycdc,

# Source Generated with Decompyle++
# File: password.txt_guillotine.pyc (Python 3.10)

import sys
sys.dont_write_bytecode = True
from py310_win32t_guillotine import __guillotine_runtime__
__guillotine_runtime__(b'GUILLOTINE\x17\x10\x00\x00\x01<\x01\x00 ...[snip]... \x00\x00', {
    '__annotations__': __annotations__,
    '__builtins__': __builtins__,
    '__doc__': __doc__,
    '__loader__': __loader__,
    '__name__': __name__,
    '__package__': __package__,
    '__spec__': __spec__,
    '__file__': __file__ })

can note that it imports __guillotine_runtime__ function from the pyd and calls it with a large gibberish string passed as an argument. If you are familiar with pyarmor it is quite similar to that.

You can thus run the file password.txt_guillotine.pyc in Python and it would import the pyd.

 

 

  • Thanks 1
Sean the hard worker
Posted
31 minutes ago, Extreme Coders said:

@Sean Park - Lovejoy

guillotine.pyd is a Python extension module built in Cython. An extension module can't be executed directly.

If you decompile password.txt_guillotine.pyc using pycdc,

# Source Generated with Decompyle++
# File: password.txt_guillotine.pyc (Python 3.10)

import sys
sys.dont_write_bytecode = True
from py310_win32t_guillotine import __guillotine_runtime__
__guillotine_runtime__(b'GUILLOTINE\x17\x10\x00\x00\x01<\x01\x00 ...[snip]... \x00\x00', {
    '__annotations__': __annotations__,
    '__builtins__': __builtins__,
    '__doc__': __doc__,
    '__loader__': __loader__,
    '__name__': __name__,
    '__package__': __package__,
    '__spec__': __spec__,
    '__file__': __file__ })

can note that it imports __guillotine_runtime__ function from the pyd and calls it with a large gibberish string passed as an argument. If you are familiar with pyarmor it is quite similar to that.

You can thus run the file password.txt_guillotine.pyc in Python and it would import the pyd.

 

 

@Extreme Coders How can I obtain the password.txt_guillotine.pyc to decompile? I can not find it anywhere.

Many thanks in advance.

Regards.

sean.

  • Like 1
Sean the hard worker
Posted
24 minutes ago, Sean Park - Lovejoy said:

@Extreme Coders How can I obtain the password.txt_guillotine.pyc to decompile? I can not find it anywhere.

Many thanks in advance.

Regards.

sean.

@Extreme Coders Oh, It was your application. called "pyinstxtractor-2024.04".

Okay. I see.

Regards.

sean.

  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...