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!
ClientHello and a ServerHello message. After this, they exchange cipher suites. However, if the client decides to use a cipher suite that the server does not support then the exchange will fail. According to the documentation of nanoSSL, this should result in the termination of the connection.register category. If data can be read back, then it's a valid handler. Neat trick to figure out how things work! Every device that used this interface did it in a completely different way, making the reverse engineering even more fun to deal with. memcpy. Since we control BOTH the size of the overflow and the bytes with no character restrictions, this is a pretty awesome bug to exploit. socket fd. So, they brute forced the socket fd between different runs. system. We still need a place to reference a string and we do not have a stack leak. So, they used a known trick with 32-bit and mmap not being randomized so well. By making a large enough allocation in LibC, it creates an mmap call directly, making it trivial to find our string. "nvram set http_passwd=nccgroup && sleep 4 && utelnetd -d -i br0" to backdoor the device. Now, The password is reset and we can take full control of the router. slaacd is a stateless address auto configuration (SLAAC) daemon. In the IPv6 protocol stack, the Neighbor Discovery (ND) protocol is used for gathering information about network communications, gateways and many other things. One particular type is a Router Advertisement (RA) packet. This particular bug is an OpenBSD. length byte is improperly used as a signed value instead of an unsigned value. By crafting a length that has the most significant bit set to 1, it believes that it is a negative number instead of a large positive number. memcpy. memcpy, the signed integer is transparently turned into an unsigned integer. This leads to a huge write occurring within this memory space, ending up as a heap overflow. Since this is a bad size wildcopy, it is unlikely to be exploitable. entry = &flow->rule->action.entries[ctx->num_actions++];This line caught their eye because it was incrementing
ctx->num_actions and using it as an index without any bounds checks. Secondly, the struct flow->rule->action.entries had seemingly not obvious relationship with ctx->num_actions. Not a bug yet but a code smell that prompted for more review!action.entries array, what are the controls on this function and how are things initialized? All great questions to get to the point of figuring out if this is a bug or not. While diving into this, they found that the path for how things were called. Additionally, they found that the num_actions counter is ONLY incremented when the NFT_OFFLOAD_F_ACTION flag is set on the offload flags. NFT_OFFLOAD_F_ACTION. The problem is that the actions array is allocated based on the number of immediate expressions types and does NOT take into consideration that this index could be incremented. As a result, the MAX index would be different than the original allocation size. nftables. After playing around with the CLI for a while, they noticed it was adding arbitrary restrictions, which screwed up his exploitation attempts. Because of this, they use the GoLang implementation with custom overwrites. After playing with binary settings and tracing code, they were able to trigger the bug with a kernel panic. Exploitation time :) entry struct to play with. In particular, the fields id and dev were being written. To find the offsets of these structs, they used pahole. The id field writes a value of 4 or 5; dev was writing a pointer 24 bytes past the end of the array. msg_msg at offset 40 (which is hittable offset by us) to land an arbitrary kfree. msg_msg as a target, it will eventually be freed. Since the write will have our net_device pointer (dev in the code above), we have manufactured a use after free from this. In order to make this viable, a ton of heap spraying was done to get tihs to line up JUST right for the attack. net_device.netdev_ops function pointer to get code execution in the kernel when this object is overlapped. The exploit chain above has a few nice quirks:
list_head.prev inside of the msg_msg can be FOUND by calling MSG_CPY. This allows us to know which one is corrupted. /code> of a security pointer tells us WHICH one was corrupted with the ID value from above. Boom, code execution! decompressed_size field. When the copy actually happened, this size value is not used though! Instead, the data within the buffer is used instead. This creates a fairly standard buffer overflow. compressed_data field. This is then subtracted from the current pointer location. There is NO validation that the offset is smaller than the real pointer being used. Down the road, a copy is done, leading to an out of bounds read. A similar variant of this bug exists but is going forward on the offset instead of backwards. m_keyBlobBlock. If this variable is harder than 128, then a buffer global memory buffer overflow occurs. %ENV_VAR% can be used to reference environmental variables. Commonly, this is used within CMD as developers.%username%, it would return the value of the environmental variable! It is common for developers to store secret information, such as AWS_SECRET_ACCESS_KEY, Github secrets and many other things. As a result, this attack could be used to steal sensitive information from a device. window.showSaveFilePicker function, a malicious website can specify the suggstedName field for the file.