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!
strncpy and copies the bytes, leading to a buffer overflow on the stack. With 800 bytes at their disposal, they could trivially overwrite EIP on the stack to get code execution. They found several more overflows like this but this was the most juicy.sscanf(). Since this API requires no authentication, we're in business!system and the parameter happened to be controlled by them as well! The binary used many protections, such as RELRO and NX but not stack canaries. Additionally, ASLR/PIE was used on the device but only 8 bits of random for the app code and 12 bits of random for the heap. So, how do we defeat this? Brute force!system appears to be brute forced, since 1/256 is doable on this program. They had some troubles with encoding as well, since everything had to be valid UTF-8 characters and couldn't contain actual nullbytes. But, they worked through this.charset attribute can be set on the Content-Type header, the meta tag within the HTML and finally the byte order mark of U+FeFF. If the browser can't determine the charset from the header, then it does some auto detection on it.0x1b 0x28 0x42 tell the charset to decode the next set of bytes as ASCII instead of the JP charset. What's even better, is that Chrome and Firefox will both autodetect this encoding for us to cause havoc.split() can be used to split a note into different positions. If this is called on a different asset, such as a fungible note, it will treat the second field as the amount even on a non-fungible note type. By using an NFT note for a function meant to be a fungible note, the liquidity from a previous transfer can be split. Now, when the attacker calls uniswapRemoveLiquidity, it will withdraw the funds from the other user. g and ${} then another for g2 and $[]. Double evaluation on templates is a known issue. In particular, if any content from stage 1 with the special tags gets into stage 2, then we have template injection. <g:no_escape> tag. Within one of the default templates, they found that the title of the page was injectable! In particular, they had something similar to register_globals, which meant that it was controllable anywhere, including the login page.style tag was allowed. From the context of the HTML parser, anything within the style is fine! But, this can still be processed in the rendering as XML later, allowing us to smuggle in payloads.j: is bound to Jelly core and g: is bound to ServiceNow custom tags. Then,j2: and g2: are bound to the null namespace, making them passed over.getBufferedReader() can mutate the path in some way?" It turned out that adding a .. into the middle of the path would be REMOVED when a clean up routine is done on the path. As a result, the denylist can be bypassed! Crazy that the normalization which is normally good for security actually caused the issue here.golang.org/x/crypto/ssh for most complicated things. On top of this functionality, Gogs adds authorization checks.env command to get ENV variables. Although, they protect against command injection they do NOT protect against the cousin argument injection. We can control arguments of the env command! --split-string can be used to have a proper command AND get command execution. So, RCE on the server via connecting via SSH has been completed!env binaries matters, as the Alpine Linux version wasn't exploitable, for instance. git diff command. By using the undocumented --output flag, we can open and close an arbitrary file. By forcing this into an error path, the file will be empty. .git/HEAD command is corrupted, then it will function as a bare repo. If the git repo is controlled, then we can add malicious configs (such as git tag. By specifying the --file flag on the command, the file will be used as the tag message. In a future command, just read the tag message for an arbitrary file read. This was not mentioned in the article but was included on their argument injection vectors site. .git/head from a repo, it's treated as a bare directory. For whatever reason, bare repos have special files that do things like execute code. So, using the same primitive as in the second argument injection, code execution is easy.postMessage. From content scripts, there is sendMessage. For background scripts, there is native messaging for communicating with apps running the background with an extension.GetCertLib action, the field PKCS11Lib is directly concatenated with a user controlled field to make a DLL path. By forcing a download in the browser then triggering this flow, it's trivial to get code execution within the context of the native application. Accept() was updating the value. It appears that it was only checking the value. So, the author of the PR had to add code to modify the allowance object to subtract funds from it.