6 ms·
Hacking with LaTeX
- ElisaJezz 11y agoQuite helpful article got to know many useful information
- radarsat1 11y ago> That's because Latex is turing complete and that means... The article is of course interesting, but it's really annoying to read claims that Turing completeness has anything to do with security. The danger comes from interaction with the external environment, not whether or not the language is Turing complete. If HTML had a "\write" equivalent, it would be just as dangerous. Conversely, the script, \newwrite\outfile \openout\outfile=cmd.tex \write\outfile{\imm\diate\wwrite\args} \write\outfile{\inp\iput\cmd} \closeout\outfile Doesn't require a loop or anything indicating a Turing complete language. That said the Turing complete aspects of Latex can be very useful, for e.g. using it to calculate results during compilation. But it's the \write etc that make it dangerous, not \loop.
- logicrook 11y agoWell, take things that way: if your language is not Turing-complete, you could lock things down so that no crazy stuff happens, and prove that there is no way to bypass the security --assuming this problem is decidable, which can be the case if the language is not Turin-complete, but is hopeless otherwise. So it's a bit like saying "well, both are dogs so both can bite", when one is well-trained and leashed, and the other is loose and raging.
- radarsat1 11y agoCan you give an example of how the halting problem allows one to make it impossible/difficult to detect malicious code? I sort of get what you are saying, that Turing completeness makes analysis more difficult, but I still don't see what it has to do with security.
- yk 11y agoWell, if you can somehow inject arbitrary code, then you can inject an infinite loop. So a program will only halt on all inputs if you can not inject an infinite loop.
- radarsat1 11y agoSure.. so how is an infinite loop a security vulnerability?
- JadeNB 11y agoIf you are performing data processing on user-supplied inputs (as online compilers do), then an infinite loop can amount to a DoS attack.
- yk 11y agoThe argument is the other way around, if a program halts on all inputs, then there is no possibility to inject arbitrary code. ( There may still be important security vulnerabilities, but there are some limits. Consider a debugger that executes the first 10 000 operations of a program, it would halt, but 10 000 operations is a lot of space to do something malicious.)
- coldtea 11y agoSecurity doesn't end with "privilege escalation". "Killing" (DoS) a system is also an attack.
- yaps8 11y agoThe halting problem makes it impossible to consistently answer the question "Will this instruction be executed ?" This is why you can't know if the code is malicious : you can't (always) infer meaningful properties about the code (Will it write something on the disk ?...).
- JadeNB 11y ago> The halting problem makes it impossible to consistently answer the question "Will this instruction be executed ?" In fact, Rice's theorem says that it's impossible more generally to answer any question about arbitrary code—so no work-arounds like "OK, I can't tell if a particular instruction is executed, but I can just test whether this program is 'safe'" (say, performs no I/O).
- chriswarbo 11y ago> if your language is not Turing-complete, you could lock things down so that no crazy stuff happens, and prove that there is no way to bypass the security --assuming this problem is decidable, which can be the case if the language is not Turin-complete, but is hopeless otherwise. It might be hopeless to try and "lock down" a Turing-complete language, but that's the wrong way to approach the problem. Rather than allowing undesired effects then trying to show they don't happen, simply avoid including them in the first place. For example, consider an implementation of Conway's Game of Life, which takes in a text file describing the initial pattern (program), keeps running it until some stopping criterion is met (say, when the cell at position (0, 0) in the text file first becomes live), and outputs either the final state of the grid, or an error message (parse error, out of memory, etc.). The Game of Life is Turing Complete[1], so it's undecidable in general whether a given text file will eventually produce a given pattern[2], including whether or not it will eventually trigger the stopping criterion. However, it's trivial to prove that our Game of Life implementation is secure against, say, shell execution attacks. How? We just need to prove that there are no patterns which cause shell execution. Since the Game of Life "language" has no concept of shell execution, our implementation doesn't need to expose anything which could allow it; it just needs to get and set booleans in an array, so this should be very straightforward to prove, even in a dangerous language like C. Just by verifying a single, known piece of code (our interpreter) we gain a security proof for all Game of Life programs. Of course the Game of Life is a simplistic example, but this idea has been around for a while in functional programming, where it's common to solve a problem by first embedding a DSL (domain-specific language) inside our main or "host" language, then coding the solution in that DSL. This lets us, for example, write a parser using a DSL specifically tailored for parsing, or describe a diagram in a DSL specially tailored for drawing diagrams, etc. We can prove all sorts of things about these DSLs, even if they're Turing Complete, by simply making them incapable of doing anything we don't want them to do. Since the "host" language (Lisp, Haskell, etc.) can already do potentially-dangerous things like accessing the filesystem, calling out to a shell, etc. there's no need to provide any of those features to the DSLs. For example, if we want to parse the contents of an arbitrary file `F` using an arbitrary parsing program `P`, we can write a small piece of code in the host language for reading the contents of `F` as a string, then passing this string and `P` as arguments to the parsing DSL interpreter. This way, neither the parsing DSL or its interpreter need any access to the filesystem, so it can be straightforward to prove that no filesystem operations (e.g. accessing unauthorised data) can take place, regardless of what `F` and `P` are. Likewise, if we want to render a diagram described by an arbitrary program `D` to an image file `I`, there's no need to provide filesystem access to the diagram DSL. Instead, we pass `D` to the diagram DSL interpreter and have it produce, say, an array of PNG data. The host language can then write this data to `I`, and again we can prove all kinds of properties like not overwriting a user's files, regardless of the program `D`. Another nice benefit of using restricted DSLs like this is the ability to intercept all effects which we do provide to the language. For example, just because we provide `read(path)` and `write(path, string)` primitive to our DSL, doesn't mean that such programs can access the filesystem. We might choose to have an interpreter which implements these by reading and writing files, but we can just as well write an interpreter which loads and stores strings in a hash table. This is useful for testing, debugging, tracing, etc. [1] http://rendell-attic.org/gol/utm/index.htm http://rendell-attic.org/gol/utm/index.htm [2] This only holds "in general"; there are particular patterns which are decidable, known as "Garden of Eden" patterns; these cannot exist after the first time step, so we just need to check whether they appear as-is in the initial program https://en.wikipedia.org/wiki/Garden_of_Eden_(cellular_automaton) https://en.wikipedia.org/wiki/Garden_of_Eden_(cellular_autom...
- JadeNB 11y ago> \newwrite\outfile > \openout\outfile=cmd.tex > \write\outfile{\imm\diate\wwrite\args} > \write\outfile{\inp\iput\cmd} > \closeout\outfile Though a longtime TeXer, I've never used the output facilities very much, so it's probably my fault; but I can't understand what this does (hence what it illustrates), and some things seem like typos. For example, shouldn't `\imm\diate`, `\wwrite`, and `\iput` be `\immediate`, `\write`, and `\input`? (I don't know about `\inp`.) What does this do?
- radarsat1 11y agoIt's from the article.
- JadeNB 11y agoOops! I usually read comments first, to see if the article is worth it. Sorry about that.
- internetwache 11y agoThe abbreviations are defined with the `\def` in the same code snippet. So that aren't typos, but a way to build latex commands like `\immediate` by breaking it up in multiple parts.
- Kristine1975 11y agoYou can also do Lambda Calculus in TeX: http://tug.ctan.org/macros/generic/lambda-lists/lambda-lists.pdf http://tug.ctan.org/macros/generic/lambda-lists/lambda-lists... (source and macros are in the same directory)
- JorgeGT 11y agoIt should be noted that shell escape is disabled by default in standard installations and the -shell-escape flag must be explicitly passed during compilation to enable it. So if someone is knowledgeable enough to add this flag I would assume that they know what they are doing, such as the guys cited in the article who create an isolated Docker container for each compilation cycle [note: very nice use of Docker!].
- zaphar 11y agoWith the caveat, of course, that when it comes to security you can't just say "Docker and done". Docker is one layer of defense but it's not completely vetted and depending on it to fix all your security problems is a terrible practice to get into.
- vanilla 11y agocombining that with a docker container breakout would be interesting https://news.ycombinator.com/item?id=7909622 https://news.ycombinator.com/item?id=7909622 (Docker container breakout?)
- derrzzaa 11y agoI'd hoped this wasn't about the software.
- agumonkey 11y agoICFP 2008 submission http://sdh33b.blogspot.fr/2008/07/icfp-contest-2008.html http://sdh33b.blogspot.fr/2008/07/icfp-contest-2008.html http://pages.physics.cornell.edu/~shicks/icfp08/proof.png http://pages.physics.cornell.edu/~shicks/icfp08/proof.png http://pages.physics.cornell.edu/~shicks/icfp08/proof.pdf http://pages.physics.cornell.edu/~shicks/icfp08/proof.pdf
- Kristine1975 11y agoIt's LaTeX, not Latex. And it's TeX-the-language (as opposed to TeX-the-program) that's Turing-complete; LaTeX is a macro package written in TeX. Also, from 2011: https://cseweb.ucsd.edu/~hovav/dist/tex-login.pdf https://cseweb.ucsd.edu/~hovav/dist/tex-login.pdf TeX files are a common method of collaboration for computer science professionals. It is widely assumed by users that LaTeX files are safe; that is, that no significant harm can come of running LaTeX on an arbitrary computer. Unfortunately, this is not the case: In this article we describe how to exploit LaTeX to build a virus that spreads between documents on the MiKTeX distribution on Windows XP as well as how to use malicious documents to steal data from web-based LaTeX previewer services. Edit: It seems at least TeXlive has configuration options to disallow access to files outside the current directory: http://tex.stackexchange.com/a/116927 http://tex.stackexchange.com/a/116927
- deleted 11y ago[deleted]
- unfamiliar 11y ago>It's LaTeX, not Latex. Who cares, really?
- duncan_bayne 11y agoPeople who cultivate a level of attention to detail that is seen as pedantic by many, but that is utterly essential for creating high quality software.
- deleted 11y ago[deleted]
- catmanjan 11y agoGrammar essential for high quality software? Many would disagree. I'd say its only essential for being no fun at parties.
- gaur 11y agoMaybe we can get some of those people to work on LaTeX. For example, why should the commands for upright Greek letters be different for different fonts? \upalpha for one font, \alphaup for another, and \otheralpha for another -- it's a damn mess. Perhaps someone who's cultivated a level of attention to detail could spend some time fixing this kind of buggy crap, instead of spending time telling people how to properly capitalize LaTeX.
- legulere 11y ago> That's because Latex is turing complete You don't need something to be turing complete to exploit it and something being turing-complete doesn't mean you can exploit it (except DoS, if the process isn't killed automatically after a while).