Step 4
Figure out how to get the flag
Take a look at the smart contract source code
The first step in figuring out how to get the flag is view the source code. The source code was provided was the event and can be viewed here. Navigate to move_lock.move in the source directory to find the module source code.
The flag
Take a moment to look through the module. Try to locate the get_flag() function.
This time the get_flag() function requires a ResourceObject and specifically will only emit the Flag event when the the ResourceObject's q1 attribute is true.
public entry fun get_flag(resource_object: &ResourceObject, ctx: &mut TxContext) {
if (resource_object.q1) {
event::emit(Flag { user: tx_context::sender(ctx), flag: true })
}
}The ResourceObject
The ResourceObject is an struct in the module.
struct ResourceObject has key, store {
id : UID,
balance: u128,
q1: bool
}The ResourceObject struct has an id, balance, and q1. We can see that during module deployment, a ResourceObject is created with balance set to 100 and q1 set to false.
Take a moment to look at the rest of the module and figure out how to get the q1 attribute to true.
The bigger picture
There is a entry function called movectf_unlock(). The function takes in two vector<u64> (u64 arrays) and the ResourceObject. The function creates another array labeled as the encrypted_flag. The two data arrays are passed into the movectf_lock() function and the output is compared with the encrypted_flag. If the output is equal to the encrypted_flag, and if the q1 attribute of the resourceObject is not true, it sets the attribute to true. This is what we want! We just need to find out how to get the output of movectf_lock() to equal the encrypted_flag.
Take a look at the movectf_lock() function to understand what is happening.
It looks like the movectf_lock() function takes the two arrays and performs a few operations on them which result in the output array. We need to reverse engineering the combination algorithm to figure out what data to feed into the function to get the desired output.
Breaking down the algorithm
The first thing that is checked is that the length of data1 is greater than 3. This is checked on line 6 of the above code block with the assert function. The assert() function is a built-in function that will halt the program if the first argument does not evaulate to true. The second argument is the error value that is outputted with the error.
In the next section of code, the if statement on line 8 is checking if the length of data1 is divisible by 3 or not. This section ensures that the array length will be divisible by 3. Make sure to go through the cases to understand how it is done. For reference the vector::push_back() function appends the given element to the end of the given array.
In the next section, starting on line 20, a new array is created and filled with some numbers. That contents of data1 is then added to the end of the new array. This new array is called, complete_plaintext.
In the next section, starting on line 33, the first nine items in data2 are store as separate variables. There is also a check that makes sure that length of data2 is exactly 9.
In the final section, starting on line 47, we are creating a new array based on the provided and generated data. The array is created 3 items at a time, and uses a certain algorithm to determine the values of the new array. Take some time to break down the algorithm that generates the new array.
So we need two pieces of data, the plaintext and the key will are used to get the encrypted_flag.
Creating a script to find the key and plaintext
This program will use the known plaintext and the encrypted_flag to find the key, use the key to generate the full plaintext, and then interact with the module to get the Flag event emitted.
View the transaction on the Sui blockchain explorer
The script will output all of the generate encryption data as well as the transaction data for function calls, including the transaction hash that contains the Flag event emittance.
Submit transaction hash
The transaction hash associated with the transaction where the Flag event was emitted can now be submitted!
Last updated