

Once adjusted, the POC causes the corrupted function pointer to be dereferenced and the function invoked. The POC corrupts an arbitrary function pointer to point to the middle of dosh(), after the sysopt checks but before the call to child(0): intĭosh ( ) # endif NetHack conveniently includes a function dosh() in sys/unixunix.c that launches a shell, although the player command for that function is typically disabled. My POC relies on the 30-bit expansion and would not work as-is in NetHack 3.6.5. A 32-bit build would not have this constraint.ĭespite these constraints, I was able to write a proof-of-concept (POC) exploit that launched a shell in NetHack 3.7. That means the compiler is adding 4 bytes of padding for every cond_hilites, so when maliciously modifying & c ond_hilites, & c ond_hilites, etc., only the first four bytes are modifiable via the vulnerability. On my machine, sizeof(cond_hilites) is 8 even though its type is unsigned long.This is greatly expanded to the low 30 bits in NetHack 3.7 with the addition of new BL_MASK_ constants. The bitmask is limited to the low 13 bits of the word in NetHack 3.6.5.The operation is an OR, meaning bits in the target address can only be turned on.The change to g.cond_hilites in NetHack 3.7 relaxes this. Therefore cond_hilites appears early in the data segment, and few target addresses are available. In NetHack 3.6.5, cond_hilites is linked from botl.o which appears early in the link line.Read-only data and text (code) cannot be modified. The target address must be before cond_hilites / g.cond_hilites (because coloridx is negative).The exploitability of this vulnerability is highly constrained, however: While trivially specifying a negative number will fail the (*str >= '0' & *str <= '9') test, specifying a number greater than 2^31 but less than 2^32 will wrap around to negative and this negative number will not be caught by eitherĪs the return value of match_str2clr is then directly used to index g.cond_hilites, this allows an attacker to OR conditions_bitmask to a location in memory outside the bounds of g.cond_hilites. If (i = SIZE (colornames ) & & ( *str > = '0' & & *str = CLR_MAX, but never check for values less than zero.

match_str2clr normally does a string match to determine the color identified, but curiously will also parse a number if provided:

Prior to this line, coloridx is set to the return value of match_str2clr in options.c.

In this function, the specified color is used as an index into g.cond_hilites (merely cond_hilites prior to NetHack 3.7): This is handled by parse_condition in botl.c. One version of this option allows a user to configure the status highlights for status conditions and afflictions. NetHack 3.6.1 introduced the hilite_status option.
DUNGEON CRAWL STONE SOUP CHEATS HOW TO
Although most of my report was focused on security-and indeed I was able to get full remote code execution (RCE) on pre-release NetHack 3.7 (but not 3.6.5)-I actually thought the more interesting finding was how to exploit the bug as a glitch. The NetHack DevTeam released NetHack 3.6.6 on March 8, 2020, primarily to address CVE-2020-5254, which I reported to them on March 3.
