People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!
block.difficulty with block.prevrandao. Although, the opcode is still the same, the values have different meanings now.prevrandao is meant to be a source of randomness on chain that is created using decentralized information. This is generated with the following steps for each validator:
prevrandao from the future. According to the EIP-4399 specification, this should be 4 epochs into the future. The reason for this is that we can limit the influence of an attacker by forcing them to guess earlier on. prevrandao opcode returns a favorable value. To fix this problem, enforce that the transaction happens on a particular block in the future. buy(uint256 _amount) amount variable is for the AMOUNT of NFTs you want to buy. If a user buys 0 NFTs, then the currentId is not set properly. The check from before about the auction being over doesn't work since the currentId is not set from the iteration within a loop. It's obviously lower than the final ID, since it's set to 0.feeReceiver and saleReceiver can be hit over and over again because of the if statement failing.validateWddxFilter() had been added. This did verification on the type attribute of the object to ensure it starts with coldfusion.getClassbySignature() that gets an instance of an arbitrary class. Then, it calls a function that must start with set. Being able to call arbitrary calls with a semi-restricted function is a good primitive to start from! java.util.Date.setDate(). After verifying that this worked in a debugger, they were set to look for more primitives. With the class com.sun.rowset.JdbcRowSetImpl, setDataSourceName() sets a JNDI lookup name. Then, by calling setAutoCommit(), we can create a JNDI injection vulnerability, like with log4shell.commons-beanutils to get code execution. Pretty neat bug and unique primitive.ETH-unshETH pool - over the 3 updates. By sandwiching the update process, the attacker was able to get all of their money back but was still able to manipulate the price.mmap() system call is made, the kernel generates a structure to represent this allocated memory in the Virtual Memory Area (VMA). The structure vm_area_struct contains various items for flags and properties for the memory section.MAP_GROWSDOWN flag, this operation CANNOT be performed atomically. When the gap needs to be removed (aka removal of the node), a new node must be created instead of simply altering the old one. This results in the old node being destroyed in a RCU callback.METHOD_RETURN for a proper call or an ERROR message to the client. Since the D-Bus API is expected to follow the standard for the libraries that utilize it, it is super important that this is correct. This is not a return value though; it appears to be set in some internal structure.user_change_language_authorized_cb, both the error handler and the proper handler were being called. The error handler was called if the $HOME is not mounted and the main path always runs.$HOME check to fail by deleting the home directory and decrementing the reference counter, another call could access this to cause memory corruption shenanigans. dbus-send --system --print-reply \ --dest=org.freedesktop.Accounts \ /org/freedesktop/Accounts/User`id \ -u` org.freedesktop.Accounts.User.SetLanguage string:'**'
.odb output was simply a zip archive with various folders and files. With looking through the files, the author noticed the database/script file with SQL statements inside of it. Arbitrary SQL queries could potential lead to file writes and code execution!SCRIPT statement, which allows us to write to an arbitrary file. However, the file cannot exist already in order to write it. Additionally, the content is somewhat controlled but not fully controlled. ~/.bashrc file when they noticed that both ~/.bash_aliases and ~/.dircolor did not exist. So, these were files that were being executed from the ~/.bashrc and we could write to them!CREATE SEQUENCE "PAYLOAD HERE" would output the content to the file we choose. Then, when a user logs in, it would eventually get executed. SCRIPT command in this context would make sense. Overall, a quick and easy issue!deposit() to add collateral to the protocol so that they can borrow. In return, the contract mints a pro-rata share that is stored in _assetStorage[_asset]. borrow() to temporary gain access to the new asset. On this call, the accrued interest rate is updated and the loan-to-value (LTV) ratio is checked. In loan based protocols, the interest rate is calculated based upon the utilization of the asset. accrueInterest() is called, the utilization rate of the deposit is over 100%, creating an insane interest rate.