forsooth!

By necessity, by proclivity, and by delight, we all quote.

PoC||GTFO


What’s that?

PoC||GTFO is a samizdat with a focus on Reverse Engineering and hacking. It is wonderfully put together, with pretty TeX work, old school ads, and illustrations.

Due to their strict licensing:

Legal Note: We politely ask that you copy this document far and wide.

I’ll mirror them here. All issues are available below. Many of these PDFs are polyglots, e.g. they also are valid zip files, and sometimes even executables, the PDFs have more details on that.

file sha256sum
pocorgtfo00.pdf c4d1d1091187b98a9bb28452bc6564a1e8c0ce10d20ba2b4a20f8b7798f7ab64
pocorgtfo01.pdf a0f93a265d38257a06fd7fd210f73ea9c55a94ac1305c65c0510ada236c2cc88
pocorgtfo02.pdf f427e8d95c0ac15abe61d96fb75cfb55df1fd5ac9e713cf968f3602267ca155e
pocorgtfo03.pdf 7094f5c6a3936e0d0b8f5e42b4d1940413f568e9a3617be0d7d6dc73cb3420e1
pocorgtfo04.pdf 1d1567b8ac533cd142a8af560266ca60939fed02e3af1f6fd0816b26473afd01
pocorgtfo05.pdf 9623609a9c0ecd95674e6da3de322baa141f5460cbcb93eeaade22eaf2c80640
pocorgtfo06.pdf bf4d8846fbbb1071c7ec033004eda8ea8809676fe388db6faa020d781cb8ac26
pocorgtfo07.pdf 601534f4355c5e0eb292c6dd6edaf5055625d23e0de869f88193606415e6a35f
pocorgtfo08.pdf 7a942c425f471f99d8cba8da117cc4a53cddb3551e4b16c8b9feae31b5654a33
pocorgtfo09.pdf 8ad70d4dd0c0f53e8c479d1d573e5a365ea673acafa9fd61fa5231e18502a6ad
pocorgtfo10.pdf 1e350e30383fd332678654b6067fe4b6ea3d25d7f41a24a4c81fe913b295c9de
pocorgtfo11.pdf 44d56d717c7b3baf7e11aa6624d5a80a90b132a519e61b9682a5f4a635b04c78
pocorgtfo12.pdf 441216e475e69564192f2121daa5dd465835072718366b75b08b9272ff9cf08b
pocorgtfo13.pdf c881c67557af52864654791a2a494f329a2fa397236bf0e961508f0769b0a3f5
pocorgtfo14.pdf b9db617dcc146cc99f4379b3162a35818d884bf4032ab854b6ec00b5ec98138d
pocorgtfo15.pdf c9b3f5026640efae12d75e62868931e2b2b5ad98a9b858408266ac5c35815bf4
pocorgtfo16.pdf 10f0cb977f03824737a413079ded14b237b7ee155a5397e804586ab7151ed0a3
pocorgtfo17.pdf 40b8985521e671b59c305d2f5512f31b95f1e8c59b9c05ad2ca6413a99d59c97
pocorgtfo18.pdf cd1e5a8f9fdda3a950556ad77db706ab8a01c97662e79c46d417e0e7858aa742 or f427637767d7aea764e0f2045ea4de86bbf5410a43535e70285add347047b283
pocorgtfo19.pdf 891b6c4e0cc8f88af2b8c2467c1558b806d2f21be4c7518e7833c27885713464

Python/Ruby Polyglot

It also inspired me to play around with polyglots a bit. Albeit nowhere near as clever as the things I’ve read in the issues already, I wanted to write a script that can be run with Python and Ruby. I wanted the results to differ meaningfully, and try to exploit as many tricks as possible to actually make both interpreters run the same lines of code, rather than doing some eval tricks or whatever.

I came up with this script, which encrypts when run with Python3 and decrypts when run with Ruby2, I explicitly disabled syntax highlighting, so it isn’t so obvious what’s going on:

key = """PoC||GTFO"
def read(*) STDIN.read.chars end
def ord(x) x.ord end
"""
import sys
begin, read, STDOUT, end = \
__name__, sys.stdin.read(), sys.stdout, sys.exit
#"

i = 0
for c in read \
    :begin; \
    v = (i % 2) * 2 - 1 and 1 - 2 * (i % 2); \
    STDOUT.write("%c" % ((256 + ord(c) + v * ord(key[i % 9])) & 0xff)); \
    i += 1; \
end

Running it encrypts stdin to stdout:

% cat > input <<EOF
Olympian bards who sung
Divine ideas below,
Which always find us young
And always keep us so.
EOF

% <input python polyglot | hexdump -C
00000000  c3 bf c3 bd 36 c3 b1 c3  b4 22 0d 28 c3 91 12 c3  |....6....".(....|
00000010  b2 2f c3 a8 c3 b7 c3 99  23 22 20 c3 90 04 32 c3  |./......#" ...2.|
00000020  b2 c3 ab c3 83 c3 b0 23  27 19 c3 bf 22 c2 a4 c3  |.......#'..."...|
00000030  ad 1d 11 1b 24 c3 90 c3  b3 22 c3 b0 c3 b3 30 c3  |....$...."....0.|
00000040  98 c3 84 08 18 c3 ba 20  c3 ac c2 a4 1a 18 31 12  |....... ......1.|
00000050  29 04 c3 9d c3 aa c3 ad  27 10 c3 9a 26 23 c2 b1  |).......'...&#..|
00000060  36 c3 b3 c3 b9 27 13 c3  84 c3 b2 1e c3 b5 c3 9d  |6....'..........|
00000070  c3 a5 c3 b0 30 0d 33 24  c3 90 c3 bc 22 c3 a9 c3  |....0.3$...."...|
00000080  b4 c3 99 21 2d c3 91 23  00 c3 ab c2 8e           |...!-..#.....|
0000008d

Python cannot decrypt it:

% <input python polyglot | python polyglot | hexdump -C
00000000  c2 af c2 8e c3 b3 75 78  c3 9b c2 b9 c3 a2 c2 82  |......ux........|
00000010  c3 82 c2 83 c3 ac 6c 7b  c2 92 c3 8f c3 9c c3 91  |......l{........|
00000020  c2 80 c2 95 c3 af 76 6f  7c c2 9c c3 9d c3 98 c3  |......vo|.......|
00000030  89 c2 90 c3 9f 28 71 c3  96 c2 bd c3 95 c3 95 c2  |.....(q.........|
00000040  80 c2 84 c3 9f 74 77 c3  a9 c2 84 7e c2 b9 c3 88  |.....tw....~....|
00000050  c2 8b c3 9d 70 28 c3 93  c3 84 c3 ab c3 83 c3 99  |....p(..........|
00000060  c2 95 c2 9a 6e 71 c3 a0  c2 bc c2 94 c3 97 c3 93  |....nq..........|
00000070  42 c3 b3 77 7d c3 a0 c2  bf 7e c2 a3 c3 8e c2 86  |B..w}....~......|
00000080  c2 9a 69 74 c3 a9 c2 b9  c3 ad c3 95 c2 80 c2 8d  |..it............|
00000090  c3 9f 6d 78 c2 92 c3 8d  c3 a7 c2 82 c3 93 c2 91  |..mx............|
000000a0  c2 a8 12                                          |...|
000000a3

But Ruby can:

% <input python polyglot | ruby polyglot
Olympian bards who sung
Divine ideas below,
Which always find us young
And always keep us so.

And the other way around:

% <input ruby polyglot | python polyglot
Olympian bards who sung
Divine ideas below,
Which always find us young
And always keep us so.

Current Python/Ruby versions:

% python --version
Python 3.6.3

% ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]

How does it work?

I won’t go into detail too much. It’s not a very complicated script, but the main tricks employed are:

  • Ruby doesn’t have ​"""​ quotes
  • Ruby doesn’t require parentheses for function calls
  • Python has different block syntax
  • Ruby has silly operator precedence

There are three tricks in there that are not immediately obvious, I think, but I won’t spoil any furher.

The main trick with the ​"""​ quotation could be used to write two entirely separate scripts, of course, but that’d be rather boring, so I only used it to get a foot in the door, setting up some symbols I couldn’t easily write around.

#+TITLE: PoC||GTFO
#+DATE: <2017-11-08 Wed>
#+AUTHOR: @or
#+CATEGORY: tech
#+SUMMARY: Reverse engineering samizdat
#+SLUG: pocorgtfo
#+TAGS: hack, reverse-engineering

** What's that?
[[https://www.alchemistowl.org/pocorgtfo/][PoC||GTFO]] is a [[https://en.wikipedia.org/wiki/Samizdat][samizdat]] with a focus on Reverse Engineering and hacking. It is
wonderfully put together, with pretty TeX work, old school ads, and
illustrations.

Due to their strict licensing:
#+begin_quote
*Legal Note*: We politely ask that you copy this document far and wide.
#+end_quote

I'll mirror them here. All issues are available below. Many of these PDFs are
polyglots, e.g. they also are valid zip files, and sometimes even executables,
the PDFs have more details on that.

| file            | sha256sum                                                                                                                                |
| [[file:/pocorgtfo/pocorgtfo00.pdf][pocorgtfo00.pdf]] | =c4d1d1091187b98a9bb28452bc6564a1e8c0ce10d20ba2b4a20f8b7798f7ab64=                                                                       |
| [[file:/pocorgtfo/pocorgtfo01.pdf][pocorgtfo01.pdf]] | =a0f93a265d38257a06fd7fd210f73ea9c55a94ac1305c65c0510ada236c2cc88=                                                                       |
| [[file:/pocorgtfo/pocorgtfo02.pdf][pocorgtfo02.pdf]] | =f427e8d95c0ac15abe61d96fb75cfb55df1fd5ac9e713cf968f3602267ca155e=                                                                       |
| [[file:/pocorgtfo/pocorgtfo03.pdf][pocorgtfo03.pdf]] | =7094f5c6a3936e0d0b8f5e42b4d1940413f568e9a3617be0d7d6dc73cb3420e1=                                                                       |
| [[file:/pocorgtfo/pocorgtfo04.pdf][pocorgtfo04.pdf]] | =1d1567b8ac533cd142a8af560266ca60939fed02e3af1f6fd0816b26473afd01=                                                                       |
| [[file:/pocorgtfo/pocorgtfo05.pdf][pocorgtfo05.pdf]] | =9623609a9c0ecd95674e6da3de322baa141f5460cbcb93eeaade22eaf2c80640=                                                                       |
| [[file:/pocorgtfo/pocorgtfo06.pdf][pocorgtfo06.pdf]] | =bf4d8846fbbb1071c7ec033004eda8ea8809676fe388db6faa020d781cb8ac26=                                                                       |
| [[file:/pocorgtfo/pocorgtfo07.pdf][pocorgtfo07.pdf]] | =601534f4355c5e0eb292c6dd6edaf5055625d23e0de869f88193606415e6a35f=                                                                       |
| [[file:/pocorgtfo/pocorgtfo08.pdf][pocorgtfo08.pdf]] | =7a942c425f471f99d8cba8da117cc4a53cddb3551e4b16c8b9feae31b5654a33=                                                                       |
| [[file:/pocorgtfo/pocorgtfo09.pdf][pocorgtfo09.pdf]] | =8ad70d4dd0c0f53e8c479d1d573e5a365ea673acafa9fd61fa5231e18502a6ad=                                                                       |
| [[file:/pocorgtfo/pocorgtfo10.pdf][pocorgtfo10.pdf]] | =1e350e30383fd332678654b6067fe4b6ea3d25d7f41a24a4c81fe913b295c9de=                                                                       |
| [[file:/pocorgtfo/pocorgtfo11.pdf][pocorgtfo11.pdf]] | =44d56d717c7b3baf7e11aa6624d5a80a90b132a519e61b9682a5f4a635b04c78=                                                                       |
| [[file:/pocorgtfo/pocorgtfo12.pdf][pocorgtfo12.pdf]] | =441216e475e69564192f2121daa5dd465835072718366b75b08b9272ff9cf08b=                                                                       |
| [[file:/pocorgtfo/pocorgtfo13.pdf][pocorgtfo13.pdf]] | =c881c67557af52864654791a2a494f329a2fa397236bf0e961508f0769b0a3f5=                                                                       |
| [[file:/pocorgtfo/pocorgtfo14.pdf][pocorgtfo14.pdf]] | =b9db617dcc146cc99f4379b3162a35818d884bf4032ab854b6ec00b5ec98138d=                                                                       |
| [[file:/pocorgtfo/pocorgtfo15.pdf][pocorgtfo15.pdf]] | =c9b3f5026640efae12d75e62868931e2b2b5ad98a9b858408266ac5c35815bf4=                                                                       |
| [[file:/pocorgtfo/pocorgtfo16.pdf][pocorgtfo16.pdf]] | =10f0cb977f03824737a413079ded14b237b7ee155a5397e804586ab7151ed0a3=                                                                       |
| [[file:/pocorgtfo/pocorgtfo17.pdf][pocorgtfo17.pdf]] | =40b8985521e671b59c305d2f5512f31b95f1e8c59b9c05ad2ca6413a99d59c97=                                                                       |
| [[file:/pocorgtfo/pocorgtfo18.pdf][pocorgtfo18.pdf]] | =cd1e5a8f9fdda3a950556ad77db706ab8a01c97662e79c46d417e0e7858aa742= or =f427637767d7aea764e0f2045ea4de86bbf5410a43535e70285add347047b283= |
| [[file:/pocorgtfo/pocorgtfo19.pdf][pocorgtfo19.pdf]] | =891b6c4e0cc8f88af2b8c2467c1558b806d2f21be4c7518e7833c27885713464=                                                                       |

** Python/Ruby Polyglot
It also inspired me to play around with polyglots a bit. Albeit nowhere near as
clever as the things I've read in the issues already, I wanted to write a script
that can be run with Python and Ruby. I wanted the results to differ
meaningfully, and try to exploit as many tricks as possible to actually make
both interpreters run the same lines of code, rather than doing some eval tricks
or whatever.

I came up with this script, which encrypts when run with Python3 and decrypts
when run with Ruby2, I explicitly disabled syntax highlighting, so it isn't so
obvious what's going on:
#+begin_src text
key = """PoC||GTFO"
def read(*) STDIN.read.chars end
def ord(x) x.ord end
"""
import sys
begin, read, STDOUT, end = \
__name__, sys.stdin.read(), sys.stdout, sys.exit
#"

i = 0
for c in read \
    :begin; \
    v = (i % 2) * 2 - 1 and 1 - 2 * (i % 2); \
    STDOUT.write("%c" % ((256 + ord(c) + v * ord(key[i % 9])) & 0xff)); \
    i += 1; \
end
#+end_src

Running it encrypts =stdin= to =stdout=:
#+begin_src text
% cat > input <<EOF
Olympian bards who sung
Divine ideas below,
Which always find us young
And always keep us so.
EOF

% <input python polyglot | hexdump -C
00000000  c3 bf c3 bd 36 c3 b1 c3  b4 22 0d 28 c3 91 12 c3  |....6....".(....|
00000010  b2 2f c3 a8 c3 b7 c3 99  23 22 20 c3 90 04 32 c3  |./......#" ...2.|
00000020  b2 c3 ab c3 83 c3 b0 23  27 19 c3 bf 22 c2 a4 c3  |.......#'..."...|
00000030  ad 1d 11 1b 24 c3 90 c3  b3 22 c3 b0 c3 b3 30 c3  |....$...."....0.|
00000040  98 c3 84 08 18 c3 ba 20  c3 ac c2 a4 1a 18 31 12  |....... ......1.|
00000050  29 04 c3 9d c3 aa c3 ad  27 10 c3 9a 26 23 c2 b1  |).......'...&#..|
00000060  36 c3 b3 c3 b9 27 13 c3  84 c3 b2 1e c3 b5 c3 9d  |6....'..........|
00000070  c3 a5 c3 b0 30 0d 33 24  c3 90 c3 bc 22 c3 a9 c3  |....0.3$...."...|
00000080  b4 c3 99 21 2d c3 91 23  00 c3 ab c2 8e           |...!-..#.....|
0000008d
#+end_src

Python cannot decrypt it:
#+begin_src text
% <input python polyglot | python polyglot | hexdump -C
00000000  c2 af c2 8e c3 b3 75 78  c3 9b c2 b9 c3 a2 c2 82  |......ux........|
00000010  c3 82 c2 83 c3 ac 6c 7b  c2 92 c3 8f c3 9c c3 91  |......l{........|
00000020  c2 80 c2 95 c3 af 76 6f  7c c2 9c c3 9d c3 98 c3  |......vo|.......|
00000030  89 c2 90 c3 9f 28 71 c3  96 c2 bd c3 95 c3 95 c2  |.....(q.........|
00000040  80 c2 84 c3 9f 74 77 c3  a9 c2 84 7e c2 b9 c3 88  |.....tw....~....|
00000050  c2 8b c3 9d 70 28 c3 93  c3 84 c3 ab c3 83 c3 99  |....p(..........|
00000060  c2 95 c2 9a 6e 71 c3 a0  c2 bc c2 94 c3 97 c3 93  |....nq..........|
00000070  42 c3 b3 77 7d c3 a0 c2  bf 7e c2 a3 c3 8e c2 86  |B..w}....~......|
00000080  c2 9a 69 74 c3 a9 c2 b9  c3 ad c3 95 c2 80 c2 8d  |..it............|
00000090  c3 9f 6d 78 c2 92 c3 8d  c3 a7 c2 82 c3 93 c2 91  |..mx............|
000000a0  c2 a8 12                                          |...|
000000a3
#+end_src

But Ruby can:
#+begin_src sh
% <input python polyglot | ruby polyglot
Olympian bards who sung
Divine ideas below,
Which always find us young
And always keep us so.
#+end_src

And the other way around:
#+begin_src sh
% <input ruby polyglot | python polyglot
Olympian bards who sung
Divine ideas below,
Which always find us young
And always keep us so.
#+end_src

Current Python/Ruby versions:
#+begin_src text
% python --version
Python 3.6.3

% ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
#+end_src

*** How does it work?
I won't go into detail too much. It's not a very complicated script, but the
main tricks employed are:
- Ruby doesn't have =​"""​= quotes
- Ruby doesn't require parentheses for function calls
- Python has different block syntax
- Ruby has silly operator precedence

There are three tricks in there that are not immediately obvious, I think, but I
won't spoil any furher.

The main trick with the =​"""​= quotation could be used to write two entirely
separate scripts, of course, but that'd be rather boring, so I only used it to
get a foot in the door, setting up some symbols I couldn't easily write around.