4 ms·
One of the Capture the Flag challenges at CCC last year was to figure out a way to leak the contents of a file on a remote compiler server. The server would acc
by rgovostes 7y ago
One of the Capture the Flag challenges at CCC last year was to figure out a way to leak the contents of a file on a remote compiler server. The server would accept some C code and just give you a boolean true/false value whether the code compiled or not---without ever executing it.
Others came up with a solution abusing the C preprocessor by defining macros that would make the known structure of the file valid C and therefore they could just #include it. But my solution works with arbitrary files, without knowing the structure beforehand.
As others have pointed out here, you can use inline assembly and the .incbin directive to include a file. But how could that influence whether the compilation succeeds or fails? I figured out how to guess a byte of the file and create metadata sections only accepted by the linker if the guess was correct.
https://ryan.govost.es/2019/12/18/compilerbot.html https://ryan.govost.es/2019/12/18/compilerbot.html
- saagarjha 7y agoWe didn't actually use .incbin on that challenge, interestingly; however, we did use it (along with some nested static constructor function trickery) for Online Calc from TokyoWesterns CTF. For that we had some straightforward tricks to get around the forbidden characters, then we abused the flag format to get the #include to work. After that we could leak the flag byte-by-byte using Linux's BUILD_BUG_ON_ZERO, which is basically an upgraded static_assert. I think this is the code we ran: """ _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \\"-Wtrigraphs\\"") ??= define STRINGIZE(...) ??=__VA_ARGS__ ??= define EXPAND_AND_STRINGIZE(...) STRINGIZE(__VA_ARGS__) ??= define hxp EXPAND_AND_STRINGIZE( ??= define BUILD_BUG_ON_ZERO(e) (sizeof(struct <% int:-!!(e); %>)) ??= define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition)) const char flag = ??= include "flag" )[{}]; BUILD_BUG_ON(flag == {}); _Pragma("clang diagnostic pop") """ (The {}, of course, being Python format parameters from our script.)