Security PWNing 2018: 10 grants from Google

By Gynvael Coldwind | Fri, 15 Jun 2018 00:11:24 +0200 | @domain:

This year Google is offering 10 grants (mainly for students) for visiting Security PWNing 2018 conference in Poland in November. Each grant covers travel, lodging and the conference entry fee itself.

Note: The conference is mostly in Polish, but it will be simultaneously translated to English as well.
Link: formularz zgłoszeniowy do programu grantów
Deadline: end of June

More about the conference:
conference page (in English)

Best of luck!

Slides from my ZIP talk in Ingolstadt

By Gynvael Coldwind | Wed, 18 Apr 2018 00:11:22 +0200 | @domain:
Slides from my lecture today on the ZIP file formats looked at from various sides (though mostly security related):

Download: slides (1.7 MB)
Files: files (46 KB)

EDIT: I've uploaded the weird ZIP files (examples, scripts, exploits, etc) I've used/shown on my presentation.

ZIP file format talk at Technische Hochschule Ingolstadt

By Gynvael Coldwind | Wed, 04 Apr 2018 00:11:21 +0200 | @domain:
On 18th of April I will be presenting on the ZIP file format from a security point of view (which is one of my favorite topics) at the THI in Ingolstadt / Germany. The talk is free to attend, but requires registration as space is limited.

What: "Ten thousand security pitfalls: the ZIP file format"
When: 18 April 2018, 17:00 CEST (i.e. local time)
Where: Technische Hochschule Ingolstadt, Germany
WWW: More information and registration

I would like to thank Kevin and Prof. Dr.-Ing. Hans-Joachim Hof for the invitation.

See you at the THI!

Livestream: 28.03 8PM CEST - Soundcard networking

By Gynvael Coldwind | Mon, 26 Mar 2018 00:11:18 +0200 | @domain:

Connecting two PCs with audio cables is something I wanted to do for a long long time - it's a pretty simple yet interesting project touching a little on the subjects of signal processing and how to actually hook something into the operating system's TCP/IP stack. Don't expect blazing speed and low latency, but it should be fun anyway.

When: Wednesday (28.03 8PM CEST)
What to expect: Very simple signal processing, Python programming, a negligible amount of electronic circuits, IRC over audio cables if everything works out fine.

See you Thursday!

PWNing 2018: Looking for sponsors

By Gynvael Coldwind | Mon, 05 Feb 2018 00:11:14 +0100 | @domain:
I realize that it's quite a long shot posting this request on the English side of my blog, but it may be worth a try, so here it goes :)

Security PWNing is a Polish commercial (i.e. you need to buy a ticket) conference I help co-organize, i.e. I'm responsible for selecting speakers, CFP, etc; most of the conference work itself is done by folks from the Polish Scientific Publishers PWN. There have been two successful editions so far, one in 2016 and one in 2017, and both had over 300 participants attendees. The conference itself is mostly in Polish, with simultaneous translation to English available starting this year (that's why I said it's a "long shot" at the beginning), and it's purely technical with some additional security/privacy popular science talks.

Anyway, we're looking for sponsors (companies, individuals, we're not picky) that would be able to add some funds into the mix that could be used to help cover either the standard conference expenses, or some extras we would like for to happen (e.g. ranked open CTF with cool prizes, or electronic badges).

So if you know someone / could ask someone about it, and they would be interested, please direct them my way ( - thanks :)


GWGC 2017/18: Results

By Gynvael Coldwind | Wed, 31 Jan 2018 00:11:12 +0100 | @domain:

As usual with this sort of competitions it was really hard to select the winner. Every submitted game had a thing or two that caught my eye and made it a worthy submission. Every submitted game had something special about it, be it a fun gameplay, aesthetic graphic design, or an overall polished feel to it. But it the end, there can be only one. Without further ado, the winners, runner-ups and third places of Gynvael's Winter GameDev Challenge:

Best Game Award

1. Dungemoji by Vassildador - award of 150 USD (or equivalent)

2. Against the Endless Enemy by drekmonger - award of 100 USD (or equivalent)

3 (ex aequo). Battle Chess by Mart - award of 50 USD (or equivalent)

3 (ex aequo). Taktyka by Cody Ebberson - award of 50 USD (or equivalent)

Community Choice Award*

1. Battle of the Dawn by Fanna - award of 100 USD (or equivalent)

2. You Shall Not Pass by Marcin Lasota (Codeboy) - award of 50 USD (or equivalent)

2. X-PL: 1830/31 by Arkadiusz Cholewa, Maciej Szymański - award of 50 USD (or equivalent)

3. Dungemoji by Vassildador - award of 25 USD (or equivalent)

* For reasons purely of my fault I didn't collect voting data from the exact deadline. In the end the I decided that the best solution in this case is to do a max(place) from available data, which in this case were YouTube analytics for the deadline (which I think is shifted a few hours due to timezones) and YouTube voting data from after a few hours from the deadline. Apologies for the mixup (though in the end it's probably beneficial for the authors).

Final note

I would like to thank once again all participants for their submissions and congratulate all the winners (I will contact you about rewards shortly).

If you're wondering how I selected the winners in the main category, I looked at the art style (is it well designed? elegant? aesthetic?), gameplay (is it fun? polished? non-trivial? can you win/loose? how closely does it fit a "turn-based tactical game" description?), sound & music (though most games didn't have any) and additional features which made the game interesting, unique or just plain cool.

Overall the level of submitted games was quite amazing and I had a lot of fun testing them. I'm really looking forward to Gynvael's Summer GameDev Challenge 2018 :)

Surprising CTF task solution using php://filter

By Gynvael Coldwind | Sun, 21 Jan 2018 00:11:11 +0100 | @domain:

PHP I/O functions support a handful of weird non-standard protocols and wrappers, with the most fun one probably being php://filter. I can recall at least several occasions where e.g. php://filter/resource=/some/file helped bypass a "remote URL only" restriction or php://filter/convert.base64-encode/resource=/some/file helped exfiltrate a binary file in an text-only or otherwise filtered (think: keyword blacklisting) output.
When playing Insomni'hack teaser 2018 I discovered yet another trick, which surprised me to the extent that I couldn't believe my eyes that it actually worked. But to explain the trick, I'm actually going to have the explain the task.

Cool Storage Service

The task itself had two stages, first of which was an HTML/CSS-injection and exfiltration of an anti-XSRF token on a Content Security Policy protected website. At core this wasn't that different from the 34C3 CTF 2017 urlstorage task (see e.g. this write-up by l4w) - it's a pretty amazing attack, but out of scope for today's post. Sufficient to say that at the end of this stage you have modified admin's e-mail address and reset his password to the one of your liking. Therefore you begin the next stage with an admin account.

While the first stage is a client-side web challenge, the second one moved to server-side. It was known from the task description that the flag is in the /flag file on the file system, but you had to find a way to leak it.

At your disposal were the following features/bugs (starting from the bottom):
  • You could upload an image file (it was verified whether it's an actual image in some way), which would then be stored with a random file name (but same extension) in /uploads/random directory name/file name.ext. PHP-related extensions were blacklisted, and you couldn't access these files via HTTP, but...
  • (Admin-only option) You could provide a URL with the image and it would be downloaded, verified and stored by the service. Both the directory and name were random (as in previous case) and the extension was hardcoded to .png. While some URL schemas were blacklisted, as was as the host, it quickly turned out that the php:// family still works.
So, to get code execution (in order to read the flag file) one just needs to use the first option to somehow inject a file that is both an image and a PHP script (simple - just append the PHP script at the end of a legit image), and has such an extension that the PHP engine would be called to execute it on access. And then just execute it using either or php://filter/resource= Right. Easy.

I failed at the second part. I tried .php, .php{3-7} and .phtml, and nothing. I tried, but only the last extension prevailed. So I started looking for other ideas.
In case you're wondering - yes, I didn't think about testing .pht, even though I'm sure I saw it before. And that was the correct, planned solution.

After reading some PHP source-code around the php://filter functionality, I've stumbled on the iconv conversion filter (under the name of convert.iconv.*), which wasn't really mentioned in the PHP documentation (well, in all fairness, it's mentioned in a heavily downvoted comment in one place, some bugs, and the example output of phpinfo() function in yet another comment). This filter basically allows you to use iconv to convert all processed data from charset A to charset B, where both character sets can be chosen from a surprisingly long list of supported encodings - there are 1173 (sic) entries on that list, some being aliases for other encodings though:

$ iconv -l
The following list contains all the coded character sets known. This does
not necessarily mean that all combinations of these names can be used for
the FROM and TO command line parameters. One coded character set can be
listed with several different names (aliases).
437, 500, 500V1, 850, 851, 852, 855, 856, 857, 860, 861, 862, 863, 864, 865,
866, 866NAV, 869, 874, 904, 1026, 1046, 1047, 8859_1, 8859_2, 8859_3, 8859_4,
8859_5, 8859_6, 8859_7, 8859_8, 8859_9, 10646-1:1993, 10646-1:1993/UCS4,

To give you an example, the following code changes a UTF-8 encoded string into hackers' favorite UTF-7:

$url = "php://filter/convert.iconv.UTF-8%2fUTF-7/resource=data:,some<>text";
echo file_get_contents($url);
// Output:
// some+ADwAPg-text

At that point a seemingly crazy idea popped into my head: perhaps there is such a charset pair, that converting the /flag content between these encodings would actually result in a valid image file?


But the basic PHP's image verification routines are, well, pretty basic (see these three posts: 1, 2, 3). On top of that it was almost 3am, I was almost out of ideas and it would take at most 15 minutes to code it. So whatever, I just went with it.

The script that I've written would select two charsets at random, form a php://filter/convert.iconv.CHARSET1%2fCHARSET2/resource=/flag URL and submit it to the service. If the service would answer with "Not an image", it would start over. And in the unlikely event of the service replying with "View here...", signaling successful processing, it would exit printing out both the URL of the result file and the charset pair.

I've run the script in the background and went to discuss other potential ideas with my teammates. We were thinking if we could use mcrypt/mdecrypt filter (I don't think you can invoke it through this interface though) with a selected IV, which would perhaps allow us to trick the image verification into accepting the flag as an image (in a somewhat similar manner to what I described in this post - look for "Bug 3 (unexploitable)" located at the very end).
To my great surprise, the script exited 5 minutes later outputting the following two words:

IBM1154 UTF-32BE
Wait. What?

I've quickly downloaded the "image" file and wrote a reverse-conversion script:

$d = file_get_contents(
echo $d;

And then executed it, both expecting it to fail for some reason and hoping it wouldn't:

$ php wtf.php

It actually worked! And we even got "first blood" on the task :)

The actual URL to get the flag, in case you're wondering:

I've chatted with clZ (the task author) about this and he was as surprised as I was with the solution - looks like it wasn't the intended one.

And that's it. A funny story of a crazy 3am idea that actually worked, and yet another PHP quirk that might be useful on another CTF some day.

P.S. It seems that IBM1154 is actually "EBCDIC Cyrillic, Multilingual with euro" (charset).

P.S.2. When the "flag-image" is passed to PHP's getimagesize() we get the following output:

array(5) {
string(21) "width="4" height="88""
string(18) "image/vnd.wap.wbmp"

So, image/vnd.wap.wbmp, is it? Well then. Whatever works ;)

P.S.3. Turns out p4 team had an equally crazy solution. They didn't publish a write-up yet, but I'm looking out for it (here). EDIT: You can read their full write-up here or checkout akrasuski1's comment down below for a brief version.

GWGC 2017/18: Vote for Community Choice Award

By Gynvael Coldwind | Wed, 17 Jan 2018 00:11:10 +0100 | @domain:

TL;DR: Please vote for the Community Choice Award in Gynvael's Winter GameDev Challenge 2017/18 (deadline for voting is 23:59 CET on 28 Jan 2018).

Longer version: The goal of my Winter Challenge was for participants to create a tactical turn-based game in JavaScript that would fit within a 20KB limit and have the form of a single HTML file that works well on the most up to date version of Google Chrome on Microsoft Windows 10. I received 14 entries for the competition, two of which unfortunately didn't fully meet the criteria (one of which I still decided to showcase, but it won't be in the final ranking), which leaves 12 games to be considered for both Best Game Award (chosen by me) and Community Choice Award (chosen by you).

Community Choice Award
Starting with the latter - to see and play the games please go to the following website:

You can both read about the games there, as well as see a ~2 minute raw footage of each game and play the game yourself (look for the "Click here to play!" link).

Also, please vote!
• To vote for a given entry please upvote a given video (i.e. click the 'thumbs up' button under the video on YouTube).
• You can vote on all the entries you liked.
• The deadline for voting is 23:59 CET on 28 Jan 2018 - at that time I'll do a snapshot of upvotes for all the videos and map that to 1st-3rd places of this award.

Best Game Award
I'm still to grade the games (and perhaps ask various people for a second opinion - still to be decided) and I expect this to be a hard task as the games are pretty awesome.

I'll announce the winners of both categories near the end the month (i.e. between 29 and 31 of January).

That's about it for now. Please cast your vote(s) for the Community Choice Award - thanks!

Python 3 BrokenPipeError woes (debugging notes)

By Gynvael Coldwind | Thu, 04 Jan 2018 00:11:09 +0100 | @domain:
Yesterday I've spent a fair amount of time trying to do a simple thing: in Python 3 write logs to a FIFO (created with mkfifo(1)) in a somewhat reliable way (i.e. without loosing logs on the writer end when the reader disconnects, nor duplicating them). It turned out to be quite an unforeseen adventure with what seems to be 3 levels of buffering on the way.

The exact scenario:
1. Both reader and writer connect to a FIFO.
2. Reader disconnects for some reason.
3. Writer writes N bytes of data and flushes it (and in the process gets a BrokenPipeError as expected).
4. Reader re-connects.
5. Writer does a flush (or disconnects, which implicitly invokes flush).
6. Reader reads data from the pipe (if any).

The main question here is:
How many bytes (sent in the 3rd step) did the reader receive in the end?
The answer to the question is pretty important as in the end it tells you whether to attempt to re-send the data (note that the reader can re-connect to the same FIFO and the communication can continue) or just re-flush the buffer as the data is already stored somewhere internally. Initially I actually expected there to be a way to check how many bytes are already in the buffer after the write, but that seemed not to be the case (or at least I couldn't find a way to do it without hacking too deep into the objects memory internals).

I've started with an experiment like this:

f = open('/tmp/mypipe', 'w')
input() # Wait for reader to connect and disconnect.
f.write("A"*N) # For various values of N.
input() # Waif for reader to re-connect.
f.close() # Implicit flush.

For N<=4096 reader actually received all the sent data, i.e. the data was successfully saved inside the internal buffer and re-transmitted on the implicit flush when close() was called. When N was larger than 4K, no data was received.

Where does the 4K boundary come from? It's a nice number and all, but instead of relying on the value itself it's always better to know where it is defined.

After digging into Python 3.6 source code and documentation I discovered two clues:

1. In Modules/_io/_iomodule.h (also exported as io.DEFAULT_BUFFER_SIZE):

#define DEFAULT_BUFFER_SIZE (8 * 1024) /* bytes */
Wait, but that's 8K, not 4K...

2. In the documentation for io.DEFAULT_BUFFER_SIZE:

An int containing the default buffer size used by the module’s buffered I/O classes. open() uses the file’s blksize (as obtained by os.stat()) if possible.

Checking os.stat('/tmp/mypipe').st_blksize indeed yields 4K sa the value.

Knowing the above I figured that it surely must mean that if N is lower-than-or-equal-to 4K, then the BrokenPipeError exception is raised on flush(), but if it's larger than 4K then the exception would be raised on write() (as the internal buffer would be omitted and the write would be passed straight into the lower layers of I/O).

Of course, that proved not to be the case.

I've automated the way to test this and got the following results (on Python 3.5 and 3.6):

--- Testing 1 byte(s)
Writer raised BrokenPipeError on flush().
Reader read 1 byte(s).

--- Testing 4096 byte(s)
Writer raised BrokenPipeError on flush().
Reader read 4096 byte(s).

--- Testing 4097 byte(s)
Writer raised BrokenPipeError on flush().
Reader read 0 byte(s).

--- Testing 8192 byte(s)
Writer raised BrokenPipeError on flush().
Reader read 0 byte(s).

--- Testing 8193 byte(s)
Writer raised BrokenPipeError on write().
Reader read 0 byte(s).

There seems to be an area between 4K+1 and 8K bytes where write() is still successful, but the reader doesn't receive any data at all. This points to another layer of buffering (third one if you're counting the kernel one as well), which actually has a buffer of 8K (?io.DEFAULT_BUFFER_SIZE?) and perhaps doesn't necessarily make sure the data actually is written to lower I/O levels before clearing the buffer in error conditions (for example when encountering the BrokenPipeError).

I traced this back to the manner I'm opening the file object - my test cases always opened it in text mode (i.e. "w"), but when I switched it to binary mode (i.e. "wb"), the behavior suddenly changed to this:

--- Testing 1 byte(s)
Writer raised BrokenPipeError on flush().
Reader read 1 byte(s).

--- Testing 4096 byte(s)
Writer raised BrokenPipeError on flush().
Reader read 4096 byte(s).

--- Testing 4097 byte(s)
Writer raised BrokenPipeError on write().
Reader read 0 byte(s).

--- Testing 8192 byte(s)
Writer raised BrokenPipeError on write().
Reader read 0 byte(s).

--- Testing 8193 byte(s)
Writer raised BrokenPipeError on write().
Reader read 0 byte(s).

Now it behaves as expected! So who's the culprit? Let's compare the file object layers for both the "text" and "binary" cases. First, "text" one:

>>> p = open('/tmp/mypipe', 'w')
>>> p
<_io.TextIOWrapper name='/tmp/mypipe' mode='w' encoding='UTF-8'>
>>> p.buffer
<_io.BufferedWriter name='/tmp/mypipe'>
>>> p.buffer.raw
<_io.FileIO name='/tmp/mypipe' mode='wb' closefd=True>
>>> p.close()

And now the "binary" case:

>>> p = open('/tmp/mypipe', 'wb')
>>> p
<_io.BufferedWriter name='/tmp/mypipe'>
>>> p.raw
<_io.FileIO name='/tmp/mypipe' mode='wb' closefd=True>

The only additional layer seems to be TextIOWrapper. After looking into it's code (Modules/_io/textio.c) I found another buffer, 8K in size as expected, and the following flush function:

/* Flush the internal write buffer. This doesn't explicitly flush the
underlying buffered object, though. */
static int
_textiowrapper_writeflush(textio *self)
PyObject *pending, *b, *ret;

if (self->pending_bytes == NULL)
return 0;

pending = self->pending_bytes;
self->pending_bytes_count = 0;

b = _PyBytes_Join(_PyIO_empty_bytes, pending);
if (b == NULL)
return -1;
ret = NULL;
do {
ret = PyObject_CallMethodObjArgs(self->buffer,
_PyIO_str_write, b, NULL);
} while (ret == NULL && _PyIO_trap_eintr());
if (ret == NULL)
return -1;
return 0;

The issue with the above code is that it doesn't make sure the data is successfully written to the underlying layer before removing it from its internal buffer (yellow part) - this behavior differs from that of _io.BufferedWriter+_io.FileIO (which do keep the data in the buffer on similar error conditions) and explains the 4K+1...8K data size weirdness.

Well, knowing the above I could finally write some code which correctly re-tries either write+flush or only flush when hit with the BrokenPipeError exception.

continue # Done.
except BrokenPipeError:

redo_write = (len(final) > self._sink_buffer_size) # 4096

while not self._the_end.is_set():
if redo_write:
break # Done.
except BrokenPipeError:
time.sleep(5) # Wait 5 seconds for a reconnect.

I'm still double checking if this is enough to make sure the writer side doesn't loose/duplicate any data, but it seems as soon as the data reaches kernel internal buffer (which seems to be 72KB or so) the ball is reader's court.

And that's it.

Gynvael's Winter GameDev Challenge 2017

By Gynvael Coldwind | Sun, 10 Dec 2017 00:11:08 +0100 | @domain:

Winter is upon us (well, at least where I live) and that seems to be a clear signal to make another gamedev challenge - a game programming competition where the rules are made up (by me) and the constraints put in place are pretty challenging. And there are rewards too!

Without further ado, welcome to the GWGC2017!
Create a game that meets the following requirements:
• Is a turn-based tactical game (like Jagged Alliance, the tactical part of X-COM, etc - see also this list on Wikipedia and this article for inspiration).
• Is made in client-side web technology that runs by default on the newest stable Chrome on Windows 10 (yes, that means HTML/CSS, JavaScript and/or WebAssembly).
• The whole game fits into one .html file that is at most 20 KB (20480 bytes) (everything, including all art, fonts, etc).
• The text in game, if any, must be in English.
• The game cannot be created using any "game maker" software or use a dedicated game engine (like RPG Maker, Unity, Unreal Engine, etc). Basic libraries like jQuery are fine (if, you can squeeze it inside the 20KB limit that is). If in doubt, ask in the comment section.

Contest related rules:
• Submission deadline is 7th of January 2018 at 11:59pm (23:59) CET (i.e. GMT+1).
• Games must be submitted by sending a link to a downloadable package (hosted e.g. on Google Drive or something similar) to the following e-mail address: (please also add a comment under this post that you sent an e-mail - otherwise I won't know that I didn't get an e-mail and can't debug it).
• Source code and all the scripts used to build the game MUST be included in the submitted package (alongside the ready-to-test .html file). By submitting the game its author(s) agree to the game being re-hosted by me for anyone to download and test once the competition is over. I won't be doing anything weird with the game after the competition, but I want participants to learn from each other after the compo is over.
• If you are using assets/sfx/music/etc created by someone else, please make sure its license allows you to use them for commercial purposes and redistribution. Please note that some licenses require proper attribution - be sure to meet these requirements.
• Games not following the rules/constraints will not be able participate in the competition.
• When in doubt, ask in the comment section below.
• Gynvael's Livestream crew cannot participate in the "Best Game Award" contest (but can submit games to be showcased and chosen for the "Community Choice Award" part).

All prizes will come in a form of a giftcard for either / / .jp or .de, or steam (author's choice).
In some cases I might agree to the winner's request for a giftcard at a different internet store, but this will be considered at a per-case basis.

Best Game Award:
Top 1: 150 USD (or equivalent in different currency)
Top 2: 100 USD (or equivalent...)
Top 3: 50 USD (or equivalent...)

Community Choice Award:
Top 1: 100 USD (or equivalent...)
Top 2: 50 USD (or equivalent...)
Top 3: 25 USD (or equivalent...)

How will the games be judged:
Best Game Award:
• There are no written-in-stone rules about that, but...
• I'll focus on the overall game quality (gameplay, is it fun to play, aesthetics, etc).
• I will totally ignore source code quality - please focus on the gameplay/etc. If the game crashes, but is mostly playable, I'll ignore the crashes too.
• One of my PCs must be able to run the game smoothly (I will test the game on one/both of the following specs: i7 8-core/16-thread 128GB RAM with GTX 980 Ti and/or i7 4-core/8-thread 32GB RAM with GTX 1080 Ti).
• I will generally try my best (including consulting the game author if needed) to make sure that the game is running as intended by the creator, as long as eventual patches / resubmissions are within the deadline mentioned in above sections.
• If I will invite more judges to participate (e.g. if I feel the need for a second opinion) they will follow the same guidelines.

Community Choice Award:
• Details are yet to be decided, but there will be some kind of a poll for the community to vote. Some kind of an account on some kind of a popular service might be required to vote too.

Hints, protips, random thoughts:
• Be sure to remember about the game having some sound effects. Music is a nice-to-have, but I don't mind if it's not there.
• Browse through and similar sites - you can find good quality art there (be sure to double-check the licenses).
• Browse through the FAQ section below - there are some additional hints / explanations there.

Q: JavaScript? In Chrome? Seriously?!
A: Yes. Think of it as a challenge!

Q: But I don't know JS...
A: Isn't this a great opportunity to learn then?

Q: People who know JS have a HUGE!!1 advantage.
A: Please note that I won't be looking at the source code of the game, but at the game itself (the gameplay, the overall feel, the aesthetics). And somewhat (un)surprisingly, you can win a gamedev competition without being an expert in a given programming language.

Q: Can my game download something from the Internet?
A: No. The test machine(s) will not have any network connection.

Q: Can I grab resources which are by default on the disk?
A: This won't work. The game will be hosted on a local HTTP server before testing, and the server will be set in such a way that only one file will be served (the sole game file).

Q: What will be the name of the file?
A: It's going to be index.html and it will be served with the following Content-Type: text/html; charset=utf-8.

Q: What fonts do you have installed on the test machines?
A: Assume the default (i.e. fonts present after the operating system is newly installed). If you need to use any more fonts be sure to embed them in the submission (keep in mind the size limit though).

Q: Can I use any minifier / this custom compression trick I know?
A: Sure. As long as it works on the newest stable Chrome on Windows 10 that's fine with me.

Q: Will this one feature be enabled in the browser during judging?
A: Please ask in the comments - I'll check. A safe rule of thumb is to assume only the features which are enabled by default in the newest Chrome version (at the moment of judging) are actually enabled, and no other features are.

Q: Will WebGL / Webassembly be enabled in the browser during judging?
A: Yes (these are enabled by default).

Q: Will the Same Origin Policy be disabled?
A: No, it will be enabled.

Q: Can my game be a Chrome Extension / Plugin?
A: No. The game must be a standalone .html file which will be loaded via a web server that only serves this one file.

Q: Are Flash / Java Applets enabled?
A: No.

Q: 20 KB? That's not a lot...
A: It's enough :) Size optimization is quite fun and there is a multitude of ways to approach this.

Q: When will the results be announced?
A: Late January. I'll try to be as fast as possible, but it does usually take some time (it also depends on submission count).

Q: I never took part in any gamedev compo like this. Can I still participate?
A: Sure! It's a great learning experience!

Q: Can I blog / tweet / livestream the making of my game?
A: Sure. Keep in mind that you will be revealing your ideas to other participants this way (it's within the rules to do it though).

Q: Can I create a game with my friend(s)/team/etc?
A: Yes!

Q: I would like to become a sponsor to make the awards more awesome!
A: Sure, get in touch :) (you can find my e-mail in the About section)

EDIT: Added 2017-12-11 11:19PM CET
Q: Will your HTTP server send any Content-Encoding headers (gzip/br/deflate/etc)? I.e. can we benefit from HTTP transport encoding (compression) possibilities with regards to the file size limit?
A: The server will not send any Content-Encoding header at all. As far as I have tested newest Chrome DOES NOT attempt any decompression algorithms in such case. So no, this will not work.

Q: What if let's say... I have a trick that actually makes newest Chrome decompress such compressed data stream?
A: If it still works with Content-Type as specified in FAQ, then it should be fine. That said, please contact me first so I can double-check this.

EDIT: Added 2017-12-12 1:35AM CET
Q: Does the game have to explain the basics ingame, or can a simple guide/manual be part of the submission?
A: It doesn't have to be in-game - a readme.txt or a similar guide attached to the submission is fine. This manual won't count towards the limit.

Q: So, can the game load the readme.txt file and use resources/code hidden in it?
A: No, the readme.txt is not part of the submission per se and so the web server will not allow the game to download it. The web server will only ever allow downloading of the index.html file (i.e. the submitted game).
End of edits.

See also the comment section for possibly more questions and answers. Feel free to also ask there if you have any questions.

Final words
Feel free to let your friends know about this competition - the more, the merrier.

Have fun, good luck!

FAQ: How to learn reverse-engineering?

By Gynvael Coldwind | Sun, 24 Sep 2017 00:11:04 +0200 | @domain:
Obligatory FAQ note: Sometimes I get asked questions, e.g. on IRC, via e-mail or during my livestreams. And sometimes I get asked the same question repeatedly. To save myself some time (*cough* and be able to give the same answer instead of conflicting ones *cough*) I decided to write up selected question and answer pairs in separate blog posts. Please remember that these answers are by no means authoritative - they are limited by my experience, my knowledge and my opinions on things. Do look in the comment section as well - a lot of smart people read my blog and might have a different, and likely better, answer to the same question. If you disagree or just have something to add - by all means, please do comment.

Q: How to learn reverse-engineering?
Q: Could you recommend any resources for learning reverse-engineering?
A: For the sake of this blog post I'll assume that the question is about reverse code engineering (RE for short), as I don't know anything about reverse hardware/chip engineering. My answer is also going to be pretty high-level, but I'll assume that the main subject of interest is x86 as that is the architecture one usually starts with. Please also note that this is not a reverse-engineering tutorial - it's a set of tips that are supposed to hint you what to learn first.
I'll start by noting two crucial things:

1. RE is best learnt by practice. One does not learn RE by reading about it or watching tutorials - these are valuable additions and allow you to pick up tricks, tools and the general workflow, but should not be the core of any learning process.

2. RE takes time. A lot of time. Please prepare yourself for reverse-engineering sessions which will takes multiple (or even tens of) hours to finish. This is normal - don't be afraid to dedicate the required time.

While reverse-engineering a given target one usually uses a combination of three means:
Analysis of the dead-listing - i.e. analyzing the result of the disassembly of a binary file, commonly known as static analysis.
Debugging the live target - i.e. using a debugger on a running process, commonly known as dynamic analysis.
Behavioral analysis - i.e. using high-level tools to get selected signals on what the process is doing; examples might be strace or Process Monitor.

Given the above, a high-level advice would be to learn a mix of the means listed above while working through a series of reverse-engineering challenges (e.g. crackmes or CTF RE tasks1).

1 While reversing a crackme/CTF task is slightly different than a normal application, the former will teach you a lot of anti-RE tricks you might find and how to deal with them. Normal applications however are usually larger and it's easier to get lost in the huge code base at the beginning.

Below, in sections detailing the techniques mentioned above, I've listed resources and tools that one might want to get familiar with when just starting. Please note that these are just examples and other (similar) tools might be better suited for a given person - I encourage you to experiment with different programs and see what you like best.

Analysis of the dead-listing
Time to call out the elephant in the room - yes, you will have to learn x86 assembly. There isn't a specific tutorial or course I would recommend (please check out the comment section though), however I would suggest starting with 64-bit or 32-bit x86 assembly. Do not start with 16-bit DOS/real-mode stuff - things are different in 64-/32-bit modes (plus 64-/32-bit modes are easier in user-land2) and 16-bit is not used almost anywhere in modern applications. Of course if you are curious about the old times and care about things like DOS or BIOS, then by all means, learn 16-bit assembly at some point - just not as the first variation.

2 16-bit assembly has a really weird addressing mode which has been replaced in 64-/32-bit mode with a different, more intuitive model; another change is related to increasing the number of possible address encodings in opcodes, which make things easier when writing assembly.

When learning assembly try two things:

See how your C/C++ compiler translates high-level code into assembly. While almost all compilers have an option to generate output in assembly (instead of machine code wrapped in object files), I would like to recommend the Compiler Explorer (aka project for this purpose - it's an easy to use online service that automates this process.

Try writing some assembly code from scratch. It might be a pain to find a tutorial / book for your architecture + operating system + assembler (i.e. assembly compiler) of choice3 and later to actually compile and link the created code, but it's a skill one needs to learn. Once successfully completed the exercise with one set of tools, try the same with a different assembler/linker (assembly dialects vary a little, or a little more if we point at Intel vs AT&T syntax issue - try to get familiar with such small variations to not get surprised by them). I would recommend trying out the following combinations:
• Linux 32-/64-bits and GNU Assembler (Intel, AT&T, or both),
• Windows 32-/64-bits and fasm,
• Linux 32-/64-bits and nasm + GCC.

3 A common mistake is to try to learn assembly from e.g. a 16-bit + DOS + tasm tutorial while using e.g. 32-bit + Linux + nasm - this just won't work. Be sure that you use a tutorial matched to your architecture + operating system + assembler (these three things), otherwise you'll run into unexpected problems.

One thing to remember while learning assembly is that it's a really really simple language on syntax level, but the complexity comes with having to remember various implicit details related to the ABI (Application Binary Interface), the OS and the architecture. Assembly is actually pretty easy once you get the general idea, so don't be scared by it.

A couple of supporting links:
The Complete Pentium Instruction Set Table (32 Bit Addressing Mode Only) by Sang Cho - a cheatsheet of 32-bit x86 instructions and their machine-code encoding; really handy at times.
Intel® 64 and IA-32 Architectures Software Developer Manuals - Volume 2 (detailed description of the instructions) is something you want to keep close and learn how to use it really well. I would recommend going through Volume 1 when learning, and Volume 3 at intermediate/advance level.
AMD's Developer Guides, Manuals & ISA Documents - similar manuals, but from AMD; some people prefere these.
[Please look in the comment section for any additional links recommended by others.]

One way of learning assembly I didn't mention so far, but which is really obvious in the context of this post, is learning by reading it, i.e. by reverse engineering code4.

4 Do remember however that reading the code will not teach you how to write it. These are related but still separate skills. Please also note that in order to be able to modify the behavior of an application you do have to be able to write small assembly snippets (i.e. patches).

To do that one usually needs a disassembler, ideally an interactive one (that allows you to comment, modify the annotations, display the code in graph form, etc):
• Most professionals use IDA Pro, a rather expensive but powerful interactive disassembler, that has a free version (for non-commercial use) that's pretty limited, but works just fine for 64-bit (and some 32-bit) x86 Windows (PE), Linux (ELF) and OSX (Mach-O) targets (technically there seems to be 16-bit x86 support too, but without MZ file support).
• The new player on the market is Binary Ninja, which is much cheaper, but still might be on the expensive side for hobbyists.
• Another one is called Hopper, though it's available only for Linux and macOS.
• There is also an open source solution in the form of radare2 - it's pretty powerful and free, but has the usual UX problems of open-source software (i.e. the learning curve for the tool itself is much steeper).
• If all else fails, one can always default to non-interactive disassembler such as objdump from GNU binutils that supports architectures that even IDA doesn't (note that in such case you can always save the output in a text file and then add comments there - this is also a good fallback when IDA/BN/etc don't support a given architecture of interest).

Having the tool of choice installed and already knowing some assembly it's good to just jump straight into reverse-engineering of small and simple targets.

A good exercise is to write a program in C/C++ and compile it, and then just having the disassembler output trying to reverse it into a high-level representation, and finally into proper C/C++ code (see the illustration below).

Once you get a hang of this process you should also be able to skip it altogether and still be able to understand what a given function does just after analyzing it and putting some comments here and there (keep in mind that this does take some practice).

One important thing I have not yet mentioned is that being able to reverse a given function only gives you a low-level per-function view of the application. Usually to understand an application you need to first find which functions is it worth to analyze at all. For example, you probably don't want to get sidetracked by spending a few hours reversing a set of related functions just to find out they are actually the implementation of malloc or std::cout (well, you'll reverse your share of these anyway while learning, that's just how it is). There are a few tips I can give you here:
• Find the main function and start the analysis from there.
• Look at the strings and imported functions; find where they are used and go up the call-stack from there.
• More advance reversers also like to do trace diffing in case of larger apps, though this FAQ isn't a place to discuss this technique.

Debugging the live target
Needless to say that a debugger is a pretty important tool - it allows you to stop execution of a process at any given point and analyze the memory state, the registers and the general process environment - these elements provide valuable hints towards the understanding the code you're looking at. For example, it's much easier to understand what a function does if you can pause its execution at any given moment and take a look what exactly does the state consist of; sometimes you can just take an educated guess (see also the illustration below).

Of course the assembly language mentioned in the previous section comes into play here as well - one of the main views of a debugger is the instruction list nearby the instruction pointer.

There is a pretty good choice of assembly-level debuggers out there, though most of them are for Windows for some reason5:

x64dbg - an open-source Windows debugger similar in UX to the classic OllyDbg. This would be my recommendation for the first steps in RE; you can find it here.
Microsoft WinDbg - a free and very powerful user-land and kernel-land debugger for Windows made by Microsoft. The learning curve is pretty steep as it's basically a command-line tool with only some features available as separate UI widgets. It's available as part of Windows SDK. On a sidenote, honorary_bot did a series of livestreams about WinDbg - it was in context of kernel debugging, but you still can pick up some basics there (1, 2, 3, 4; at first start with the 2nd part).
GDB - the GNU Debugger is a powerful open-source command-line tool, which does require you to memorize a set of commands in order to be able to use it. That said, there are a couple of scripts that make life easier, e.g. pwndbg. You can find GDB for both Linux and Windows (e.g. as part of MinGW-w64 packet), and other platforms; this includes non-x86 architectures.
• [Some interactive disassemblers also have debugging capabilities.]
• [Do check out the comment section for other recommendations.]

5 The reason is pretty obvious - Windows is the most popular closed-source platform, therefore Windows branch of reverse-engineering is the most developed one.

The basic step after installing a debugger is getting to know it, therefore I would recommend:
• walking through the UI with a tutorial,
• and also seeing how someone familiar with the debugger is using it.
YouTube and similar sites seem to be a good starting point to look for these.

After spending some time getting familiar with the debugger and attempting to solve a couple of crackmes I would recommend learning how a debugger works internally, initially focussing on the different forms of breakpoints and how are they technically implemented (e.g. software breakpoints, hardware breakpoints, memory breakpoints, and so on). This gives you the basis to understand how certain anti-RE tricks work and how to bypass them.

Further learning milestones include getting familiar with various debugger plugins and also learning how to use a scripting language to automate tasks (writing ad-hoc scripts is a useful skill).

Behavioral analysis
The last group of methods is related to monitoring how a given target interacts with the environment - mainly the operating system and various resources like files, sockets, pipes, register and so on. This gives you high-level information on what to expect from the application, and at times also some lower-level hints (e.g. instruction pointer when a given event happened or a call stack).

At start I would recommend taking a look at the following tools:

Process Monitor is a free Windows application that allows you to monitor system-wide (with a convenient filtering options) access to files, register, network, as well as process-related events.
Process Hacker and Process Explorer are two free replacements for Windows' Task Manager - both offer more details information about a running process though.
Wireshark is a cross-platform network sniffer - pretty handy when reversing a network-oriented target. You might also want to check out Message Analyzer for Windows.
strace is a Linux tool for monitoring syscall access of a given process (or tree of processes). It's extremely useful at times.
ltrace is similar to strace, however it monitors dynamic library calls instead of syscalls.
• [On Windows you might also want to search for a "WinAPI monitor", i.e. a similar tool to ltrace (I'm not sure which tool to recommend here though).]
• [Some sandboxing tools for Windows also might give you behavioural logs for an application (but again, I'm not sure which tool to recommend).]
• [Do check out the comment section for other recommendations.]

The list above barely scratches the surface of existing monitoring tools. A good habit to have is to search if a monitoring tool exists for the given resource you want to monitor.

Other useful resources and closing words
As I mentioned at the beginning, this post is only supposed to get you started, therefore everything mentioned above is just the tip of the proverbial iceberg (though now you should at least know where the iceberg is located). Needless to say that there are countless things I have not mentioned here, e.g. the whole executable packing/unpacking problems and other anti-RE & anti-anti-RE struggles, etc. But you'll meet them soon enough.

The rest of this section contains various a list of books, links and other resources that might be helpful (but please please keep in mind that in context of RE the most important thing is almost always actually applying the knowledge and almost never just reading about it).

Let's start with books:
Reverse Engineering for Beginners (2017) by Dennis Yurichev (CC BY-SA 4.0, so yes, it's free and open)
Practical Malware Analysis (2012) by Michael Sikorski and Andrew Honig
Practical Reverse Engineering (2014) by Bruce Dang, Alexandre Gazet, Elias Bachaalany, Sebastien Josse
• [Do check out the comment section for other recommendations.]

There are of course more books on the topic, some of which I learnt from, but time has passed and things have changed, so while the books still contain valuable information some of it might be outdated or targeting deprecated tools and environments/architectures. Nonetheless I'll list a couple here just in case someone interested in historic RE stumbles upon this post:
• Hacker Disassembling Uncovered (2003) by Kris Kaspersky (note: first edition of this book was made available for free by the author, however the links no longer work)
• Reversing: Secrets of Reverse Engineering (2005) by Eldad Eilam
• [Do check out the comment section for other recommendations.]

Some other resources that you might find useful:
Tuts 4 You - a large website dedicated to reverse-engineering. I would especially like to point out the Downloads section which, among other things, contains tutorials, papers and CrackMe challenges (you can find the famous archive there too).
/r/ReverseEngineering - reddit has a well maintained section with news from the RE industry.
Reverse Engineering at StackExchange - in case you want to skim through commonly asked questions or ask your own.
PE Format - Windows executable file format - it's pretty useful to be familiar with it when working on this OS.
Executable and Linkable Format (ELF) - Linux executable file format (see note above).
Ange Albertini's executable format posters (among many other things) - analyzing Ange's PE and ELF posters greatly simplifies the learning process for these formats.
• [Do check out the comment section for other recommendations.]

I'll add a few more links to my creations, in case someone finds it useful:
Practical RE tips (1.5h lecture)
• You might also find some reverse-engineering action as part of my weekly livestreams. An archive can be found on my YouTube channel.

Good luck! And most of all, have fun!

GSGC 2017: Results

By Gynvael Coldwind | Wed, 13 Sep 2017 00:11:03 +0200 | @domain:
The results for Gynvael's Summer GameDev Challenge are in! You can find them below with an additional commentary for each game and category.

TL;DR: The results!
Games From Scratch category
1. Space Logic Adventure (by Luke)
2. Untitled RTS (by mactec)
3. Space (by Seba)
HM. The Fate of IsoGuy (by Piotr Krupa)

Games Created Using a Game Engine category
1. SpaceShooter (by GjM & mioot)

Game sources and binaries: click to download (138 MB)
(you can find videos of all the games in my previous post)
Starting with the Games From Scratch category, allow me to say that the level of submitted* games exceeded my expectations. I had real problems selecting the best one and had to think hard about the criteria I would use - I settled for a mix that included (but wasn't limited to) "what game was fully finished", "what game I would like to play more of" and "what game I had most fun playing". In the end there can be only one winner so a decision had to be made, but believe me when I say that the choice was tough to make.

* There were also some unsubmitted ones btw, e.g. this one.

I'll note at this point that several of submissions had problems with the 2+1 UI color rule (i.e. more colors were used in the UI at times). In a few cases I asked the authors to correct the games, but in the end I decided that I'll just ignore it and look at the UI as if it was limited to the aforementioned 2+1 colors. I was also careful not to give additional figurative points for better looking UI if the points would originate from using more colors than it was allowed. Therefore even if you see more colors in the UI in one of the games - don't worry, I did notice that and it had not influenced the results in any way.

The second thing I would like to note is that, since there was only one submission to the second category, I decided to slightly modify the third place reward (+25 USD, total of 75 USD in form of a giftcard) and add a reward to Honorary Mentions (50 USD gift card).

Alright. Let's go through the games in this category one by one, starting with the winner!

Winner: Space Logic Adventure by Luke

Reward: 150 USD Amazon Giftcard

What I really like about Space Logic Adventure by Luke is that it was basically a complete and almost ready to ship game. Be it fun and challenging gameplay, level system with old-school style codes to jump to a later stage, music and sound effects (these things tend to be missing in compo/hackathon games) or a movie-like scrolling credit scene - it was all there.

What helped me make my decision to award this game the first place was that it was well balanced in terms of gameplay. It was hard enough so that I had to replay almost every level several times, dynamic enough so that retrying didn't take too much time, and simple enough so that you eventually always got through.

The author also put the 2+1 color UI rule to good use with a minimalistic but elegant interface - sometimes less is more.

The only thing missing was more levels.

Runner-up: Untitled RTS by mactec

Reward: 100 USD Amazon Giftcard

The RTS game by mactec was pretty fun and well made. I liked that the UI was a more refined with verbose messaging all around. I enjoyed the little details like tooltips when hovering over random game objects. And I did like the map being pretty spacious. I also appreciated someone trying to actually write an RTS game - there are usually a lot of small edge cases that you have to take care of in order for it to be playable at all and mactec handled this well.

There were basically two reasons why this game is the runner-up and not the winner.

First, the gameplay requires more balancing work. I found it too slow and, depending on a throw of a coin, either too easy (if you don't find aliens in the first few minutes) or too hard (if you find a lot of aliens in the first few minutes and had to micro your astronauts like crazy). The mission could have been expanded to include more intermediary goals too, especially that it was the sole mission in the game.

Secondly - a minor point but still one I have to make - the UI could use a retouch from the aesthetics point of view. Let's just say that dark blue, gray and black wouldn't exactly be my first palette choice, even though they are readable enough. I assure you that I realize that a programmer isn't always a design artist, but then again there are a lot of web services offering free color palette generation, either from scratch or basing on a supplied image (just google for "palette generator").

Given the above the RTS seems to be halfway between a techdemo and a finished hackathon game. Still that's enough for it to end up on the second place!

Third Place: Space by Seba

Reward: 75 USD Amazon Giftcard

Space by Seba is a well made game all around. It has great aesthetics, sound and music fits the game well, and I did enjoy the dynamic gameplay a lot.

The main reason Space is on the third place and not higher is that the gameplay feels it is missing something that would make it more complex and a bit harder / more challenging. An example might be enemy space ships shooting back at you. Or the asteroids being harder to destroy and forming a predefined pattern forcing the player to choose their flight path carefully. Or anything else that would take the game beyond the "shoot the rocks fast" boundary.

All in all I did enjoy Space a lot and I'm happy to present it with the bronze medal.

Honorable Mention: The Fate of IsoGuy by Piotr Krupa

Reward: 50 USD Amazon Giftcard

The Fate of IsoGuy by Piotr Krupa gets an Honorable Mention for its multi-screen diverse explorable map with a fascinating old-school design that basically screams "I am an 8-bit computer game with nicer graphics!".

The reason The Fate of IsoGuy didn't end up on one of the top places is that it's lacking sound effects and music. While this is usually acceptable on 8h-48h competitions, I couldn't overlook it on a month-long gamedev compo.

Remaining games in random order

I'll also include a 1-2 sentence comment for each of the games that did not make it. Please note that the games are in random order.

Wolf and Sheep by dontru is a well made board game adaptation complete with AI and hot-seat multiplayer. It was the first game I've looked at and I immediately thought to myself "woah, the level of the submissions is amazing!". It was missing sound, music, and perhaps movement animation, but also I'm not sure if adding these things would be enough to get it in the top three - a simple board game like Fox and Hounds might just not be enough when compared with dynamic more common computer games (unless you go full Archon).

Space Ride by michael2001 had a great concept (who doesn't love Raptor/Tyrian), but the game required some more love to include e.g. enemies, be more dynamic, and fully finished and tested. With better execution this idea could go really far.

SpaceMiners by emis2000 was the second RTS contender. The idea was pretty fun (flying harvesters - why not!), but the game looked unfinished - it was missing sound effects, music, and the "player versus the timer" concept looked quickly stitched together due to lack of time for finishing a proper RTS mission. Given some more work this could turn up to be a pretty fun game!

Desert Aircraft Shooter by Marcin648 was technically amazing! Great aesthetics, dynamic gameplay, well executed isometric view of the map - a worthy contender for the top places. It was just missing this small "something" to make the gameplay be more enjoyable - e.g. various different weapon types or huge explosions sending out shockwaves throughout the map - something to make you want to play again, and again, and again. A great entry nonetheless!

It's Super Cool by pr0gramista is going to be a fun party game, I'm sure of it! The gameplay is fun, the arena looks incredible, and it has a good balance of toughness. On the other hand making a multiplayer-only game for a competition is always risky, as you sacrifice the single player and have to work really hard to make the server-side stable for multiple testers during the judging phase - and we did run into issues here when testing (worked well for 2 players though). I think that the game would also benefit from making it a little more dynamic (e.g. the player basically throwing themselves at the opponent when trying to tackle them, or moving slightly faster with some inertia), and well also moving the setup UI from the console into the game screen itself. That said, I did enjoy this game a lot and it missed the top places only by a hair!

Moving onto the Games Created Using a Game Engine category ...

Winner: SpaceShooter by GjM & mioot

Reward: 150 USD Amazon Giftcard

SpaceShooter by GjM & mioot was the only entry in this category - it is an isometric shooter made using the Unity engine. There are several levels filled with spikes, shooting enemies and obstacles that try to block you from reaching the portal to the next level - all in all a pretty classic and fun idea.

Now let's get to the elephant out of the room - if there would only be only one common category SpaceShooter would probably not have made it to the top three. Unfortunately the game does have a multitude of problems all around and requires more time and love to make it reach its full potential. But in the end we do have two categories and sometimes just submitting a game is enough to win a competition :)


I think this was the first time I've organized a month-long gamedev compo and I'm very happy with the results and the overall high quality of the games, therefore I would like to thank all participants for taking part and again congratulate the winners.

I'll probably make another longer-term (two weeks? a month?) compo in the winter season (e.g. Gynvael's Winter GameDev Challenge) with a yet again different set of rules.

I'm still thinking what to do with the 'Games Created Using a Game Engine' category given its relatively low popularity in this contest. There are three options I'm considering:

• Keep it as is (well, one competition doesn't make a meaningful statistic). In such case I would also probably add a rule that would allow me to merge the categories in case there is less than N games (e.g. 3) submitted to either.
• Merge the categories, i.e. still allow participants to use game engines, but rate the games together.
• Revert to banning the game engines altogether as I've always done until this point.

I'm also interested in your opinion in this matter - please let me know what you think in the comments down below.

Of course the whole discussion is moot if the rules for the next competition include e.g. "total game size must be below 4 kilobytes", but it's still worth chatting about it for the sake of future challenges.

That's about it! Good Game :)

GSGC 2017: Game Review

By Gynvael Coldwind | Sun, 10 Sep 2017 00:11:02 +0200 | @domain:
While the Gynvael's Summer GameDev Challenge 2017 results are not yet up (I'll announce them probably on Wednesday) I did review all the submitted games and created a 10-minute showcasing video with 1 minute dedicated for each game. You can find the video either on my channel on YouTube or simply down below.

EDIT: And an erratum video with a missing game and a correction about another:

Once I publish the results it will be possible to download both the source code and the binaries for each game.

HackYeah - a huge hackathon in Krakow (27 Oct 2017)

By Gynvael Coldwind | Mon, 21 Aug 2017 00:11:01 +0200 | @domain:
As it's pretty obvious from my blog I really enjoy competitions - both participating and running them. Recently I was approached by the HackYeah team with an invitation to become a community partner (whose role is basically letting the community know that such an event is happening) to which I happily agreed to as it seems to be a pretty interesting and fun... well... competition :).

Competition information:
Event: HackYeah
Format: 48-hour, team (6 person limit), offline, hackathon
Ticket: 61-63 PLN (~18 USD) per person (as a community partner I have some discount code: coldwindyeah; it's ~17.8% off)
Dates: Oct 27, 2017 - Oct 29, 2017 (48h)
Place: Tauron Arena, Kraków, Poland, Europe, Earth (that's the third planet in the Solar system)

So HackYeah is a hackathon happening in October in Krakow, Poland in the Tauron Arena (if you're into CS:GO, that's the same place where the last major took place). The idea is for the event to be HUGE (over 2000 participants) and to even have a go at the Guinness World Records (what's the current one in offline hackathon size? anyone?).
The topic of the hackathon is going to be "EXTREME LIVING" (or "living extreme", something along these lines; check the website for details), i.e. an application / hardware+application (any technology is allowed according to the orgs, this includes, but is not limited to, keywords like VR, AR or IoT) for people doing extreme sports (as a pretty broad definition, that includes things like e.g. hiking, diving, flying, etc), and there will be several categories for prizes (copy-pasting from here):

- Hacking Rock Star - for the best solution
- Extremely The Best - for the best use of the “extreme” theme
- Coder Angelo - for the most creative ones
- It’s funny because it’s real - for the funniest, yet working solution
- The Best Hacking Student - separate category for the ones who do not have too much experience in coding, but they rocked!

Personally I would really recommend participating - as I mentioned several times on my blog / in my videos, I find time-limited competitions with additional constraints to be really motivating, plus they give one a clear time frame when one can just focus on coding / learning and not be preempted by other things. If you don't have a team, don't worry - the organizers will help people create teams during the event (that's pretty standard for compos/hackathons to make ad-hoc teams if one doesn't attend with their one team).

Ah, one more thing: since it seems to be a big event and there will be booths from sponsors, the website suggests that there might be other mini-challenges prepared by the sponsors as well (I don't believe any details are available yet though).

Good luck :)

FAQ: How to find vulnerabilities?

By Gynvael Coldwind | Mon, 14 Aug 2017 00:10:59 +0200 | @domain:
Obligatory FAQ note: Sometimes I get asked questions, e.g. on IRC, via e-mail or during my livestreams. And sometimes I get asked the same question repeatedly. To save myself some time (*cough* and be able to give the same answer instead of conflicting ones *cough*) I decided to write up selected question and answer pairs in separate blog posts. Please remember that these answers are by no means authoritative - they are limited by my experience, my knowledge and my opinions on things. Do look in the comment section as well - a lot of smart people read my blog and might have a different, and likely better, answer to the same question. If you disagree or just have something to add - by all means, please do comment.

Q: How does one find vulnerabilities?
A: I'll start by noting that this question is quite high-level - e.g. it doesn't reveal the technology of interest. More importantly, it's not clear whether we're discussing a system vulnerability (i.e. a configuration weakness or a known-but-unpatched bug in an installed service) that one usually looks for during a regular network-wide pentest, or if it's about discovering a previously unknown vulnerability in a an application, service, driver / kernel module, operating system, firmware, etc. Given that I'm more into vulnerability research than penetration testing I'll assume it's the latter. And also, the answer will be as high-level as the question, but should give one a general idea.

My personal pet theory is that there are three* main groups of methods (I'll go in more details below):
* If I missed anything, please let me know in the comments; as said, it's just a pet theory (or actually a pet hypothesis).

1. Code review (this also includes code that had to be reverse-engineered).
2. Black box (this includes using automated tools like scanners, fuzzers, etc).
3. Documentation research.

All of the above methods have a set of requirements and limitations, and are good at one thing or the other. There is no "best method" that always works - it's more target specific I would say. Usually a combination of the above methods is used during a review of a target anyway.
1. Code review
• Knowledge of vulnerability classes** specific to the given technology, as well as universal bug classes.
• [In case of binary targets] Reverse engineering skills.
• Ability to find quite complicated bugs.
• Takes a lot of time and focus.

** - A vulnerability class is a type of a vulnerability that is usually well known, there are known mitigations and sometimes even known patterns/ways/tools to discover it. An example would be e.g. a stack-based buffer overflow, a reflected XSS or an SQL injection. Sometimes security bugs occur due to a couple of problems mixed together (a common example would be an integer overflow into a buffer overflow). Please note that not all vulnerabilities which are being found have actually been classified (as in "classification", not "kept secret") - you might encounter application-specific or technology-specific bugs which don't fall into any common category. For comprehensive lists of classes please check out these three links: Common Weakness Enumeration (MITRE), Adversarial Tactics, Techniques & Common Knowledge (MITRE) and OWASP Periodic Table of Vulnerabilities (special thanks to these folks on twitter and cody for links).

The general idea is to analyze the code and try to pinpoint both errors in logic and classic vulnerability classes (e.g. XSSes, buffer overflows, wrong ACLs, etc). This method is basically as good as the researcher is - i.e. if one loses focus (and just skims through the code instead of trying to truly understand it) or a given vulnerability class is unknown to them, then a bug will be missed.

This method doesn't really scale - the smaller the project, the easier it is to do a full code review. However the more lines of code, the more it's needed to actually limit the review to only interesting sections of code (usually the ones where we expect the most bugs to be, e.g. protocol / file format parsers, usage of user input, etc).

2. Black box
• Knowledge of vulnerability classes specific to the given technology, as well as universal bug classes.
• [Automated black box] Knowledge of how a given tool works and how to set it up.
• [Automated black box] Scales well.
• [Manual black box] If you trigger a bug, you found a bug. The rate of false-positives will be limited (where e.g. during code review you might think you've found a bug, but later discover that something is checked/sanitized/escaped in a lower/upper layer of the code).
• [Automated black box] Scanners/fuzzers are great tools, but they are pretty much limited to low-hanging fruits. Most complicated bugs won't get discovered by them.
• [Manual black box] Takes less time than a code review, but still doesn't scale as well as e.g. automated black box.
• [Manual black box] Limited by the imagination of the researcher (i.e. a lot of complicated bugs will probably not be discovered this way).

The idea here is to "poke" at the application without looking at the code itself, focusing on the interactive side instead. This method focuses on attacking the application from the surface and observing its responses, instead of going through its internals as is the usual approach during a code review.

Manual black box is usually what I would start with when working with a web application, as it gives one a general overview of the tested target. In case of other technologies setting up the application and poking around (checking ACLs, etc) doesn't hurt either.

Automated black box usually scales very well. From my experience, it's good to set up a fuzzer / scanner and let it run in the background while using another (manual) method at the same time. Also, don't forget to review the findings - depending on the technology and the tool there might be a lot of false positives or duplicates. And remember, that these tools are usually limited to only a subset of classes and won't find anything beyond that.

3. Documentation research
• Experience as a programmer or knowledge how a programmer thinks.
• Knowledge of vulnerability classes specific to the given technology, as well as universal bug classes.
• Possibility of discovering the same vulnerability in a set of similar targets.
• Limited by the imagination of the researcher.
• Focuses on a single protocol / format / part of the system.

The general idea is to go through the documentation / specification / reference manual and pinpoint places where the programmer implementing the target might understand something in an incorrect way. In contrast to both code review and black box review there is no interaction with the tested implementation until later phases. To give you an example, please consider the following:

Specification of a format says:
The output codes are of variable length, starting at <code size>+1 bits per code, up to 12 bits per code.

What some programmers might think (e.g. when having a bad day or due to lack of experience):
No need to check the code's length - it's guaranteed to be 12 bits or less.

The correct interpretation:
Verify that the length is 12 or less, otherwise bad things may happen.

And yes, this is a real example from the GIF specification and vulnerabilities related to this were discovered.

Having found an interesting bit one usually creates a set of inputs that break the rule specified in the documentation and then use them to test a given implementation (and perhaps other implementations as well) to check if any problem is triggered (alternatively one can also do a selective code review to check if the programmer got this right).

In some cases it's possible to automate browsing the documentation as was shown e.g. by Mateusz "j00ru" Jurczyk and (a few years later) by James Forshaw.

Final notes
Please remember that once you think you've discovered a vulnerability the work is not yet done. Usually the following steps need to be taken:

0. [Prerequisite] A potential vulnerability must be discovered.
1. [Usually not needed in black box review] An exploit triggering the vulnerability must be created to make sure the code path to the vulnerability is actually reachable (it happens surprisingly often that at this phase it turns out that the vulnerability is not triggerable due to various reasons).
2. A proof of concept exploit (commonly referred to as PoC) must be created to prove the actual effect of the vulnerability (is it really a code execution? maybe due to some reasons its effects are limited to a denial of service?).
3. [Optional] During penetration testing one usually would also create a fully weaponized exploit (spawning a shell, limiting the damage to the process, etc).

And also, please remember that not every bug is a security bug. The rule of thumb here is the following:
• A security bug (i.e. a vulnerability) breaks a context boundary (e.g. is triggerable from low-privileged context, but affects high-privileged context that normally is inaccessible to the attacker).
• A non-security bug stays within the same context (e.g. it influences only the attackers domain, things that the attacker could do anyway or things that affect only the attacker).

One more note is that even security bugs are not always the end of the world (hint: when reporting a bug, don't try to oversell it) - there are several more things that one needs to take into consideration, like the severity (in the worst case scenario, what can a skilled attacker do with such bug?) and risk of exploitation (i.e. will anyone even care to exploit this in real world? or maybe one has to do a billion attempts before hitting the correct conditions and with each attempt the server reboots?). An example of a high-severity high-risk bug is a stable remote code execution in Apache web server. On the other hand an example of a low-severity low-risk bug is changing the language of the UI in a web framework used by 10 people by exploiting an XSRF that requires guessing a 16-bit number (sure, an attacker could do it, but why bother?). A common mistake done by junior researchers (and this includes me in the past as well) is to try to claim high-severity high-risk for every bug, when that's obviously not the case.

And here you go - a high-level answer to a high-level question

In practice start by learning vulnerability classes specific to the technology you're most interested in (and in time extend this to other technologies and universal vulnerability classes as well of course), and then try all of the above methods or a mix of them. And don't be afraid to dedicate A LOT of time to this - even great researchers might go weeks without finding anything (but one still learns through this process), so don't expect to find a good bug in a few hours.

Windows Kernel Debugging - archived videos

By Gynvael Coldwind | Sat, 12 Aug 2017 00:10:58 +0200 | @domain:
As I mentioned in this post the last four livestreams on my YouTube channel were done by Artem "honorary_bot" Shishkin (github) and were on the quite anticipated and demanding topic of Windows kernel debugging with a healthy dose of both x86 from a system programming perspective, and an unexpected but very welcomed venture into the world of hypervisors. The series came to an end, therefore I would like again to thank Artem for both reaching out to me offering to do the streams and actually doing them in such a spectacular fashion - speaking for myself, I've learnt a lot!

All the videos are already uploaded on YouTube (links below), so in case you've missed them, nothing is lost (well, maybe for the ability to ask question, but I guess one can always reach out to Artem on Twitter). Please note that the links that Artem visited during the livestream are available for your convenience in each of the video descriptions on YouTube (if I missed anything please let me know).

Windows Kernel Debugging - Part I, in which Artem shows how to configure your kernel debugging environment in several different ways, both including a virtual machine (with/without VirutalKD) and a second PC (controlled using Intel AMT and connected using various means, e.g. USB, Firewire or ethernet).

Windows Kernel Debugging - Part II, during which Artem shows how to work with and configure WinDbg.

Windows Kernel Debugging - Part III, in which Artem goes through the meanders of virtual memory and navigating through it using WinDbg. He also goes into the details of what's in a process and kernels virtual memory.

Windows Kernel Debugging - Part IV, in which Artem showcases the physical memory and explains why a physical address is not always equal to RAM address, as well as ventures into the land of ACPI tables (if you're thinking about OSDev, you should check out this part regardless of whether you're interested in Windows kernel debugging or not). Artem also demos a hypervisor-level system debugger of his making.
On a more technical note, this was the first stream I've done with someone in a remote location (both the streams I've done with Carstein and lcamtuf were at my place), so at the initial concept phase it was a technical riddle that needed to be solved. There were two factors that came into play:

• First, I did not want to go the route of catching skype's/hangout's/your-favorite-video-conference-tool's window / sounds and restreaming that. I do believe that it may work rather well, but it seems to have many unnecessary steps in the middle. And the user has usually very little to say about the quality, codecs, etc. Though it must be noted that the capture→transmit→display lag is pretty small as these tend to be real-time communication tools.

• Second, Artem was already used to Open Broadcast Software, so we wanted to take that into account.

In the end what worked (and what surprisingly was also the first idea) was to use an RTMP restreaming server, i.e. Artem would connect to the RTMP restreaming server as the broadcaster and upload his OBS generated livestream there, and my OBS (using the Media source aka VLC plugin) would download it and embed into one of my scenes (so, to answer one of the questions that appeared on chat, no, Artem did not have to stream from my basement). This worked surprisingly well with about 2-5 second lag between Artem's action and me seeing it in OBS (where my OBS+YouTube added another 3-10 seconds before viewers saw the effect of an action).

However, given the total lag mentioned above (going into the 15 second territory in the worst case scenario) we also used a voice chat for synchronizing scene switches, so that Artem would know when his stream is live immediately as I switch the scene (and not after 15 seconds when he sees it on YouTube; it was a little easier for me as I did see the video signal he broadcasted in OBS preview with a much smaller lag).

All in all thanks for these streams, apart from learning quite a lot of cool tricks / details about WinDbg/kernel debugging/x86, I've also learnt a couple of useful tricks when doing live video broadcasting - this should give me more options to do livestreams with guests in the future. And I also can say that 4 displays which I'm currently using were barely enough to see all important windows (video previous, chats, OBS, music, voice+chat with Artem, etc) at the same time - I guess I've learnt first handed why real pro broadcasting crews have more monitors than NASA's space center ;).

So once again: thanks and kudos go to Artem! Having the opportunity I would also like to thank my livestream crew (especially foxtrot_charlie and KrzaQ) for their usual and irreplaceable help.

And that's it.

Gynvael's Summer GameDev Challenge 2017

By Gynvael Coldwind | Fri, 04 Aug 2017 00:10:57 +0200 | @domain:
While gamedev and coding challenges were something I've usually done on the Polish side of the mirror, I finally felt brave enough to try and invite all of my readers/viewers/visitors to participate. So, long story short, I would like to propose a month-long game development challenge - i.e. a kind of an informal (think: compo) competition where the participants (for example: you) try to create a game under a specific set of constraints written below.
EDIT: New category added 2017-08-05:
Since quite a lot of folks are asking about using game engines, game frameworks, high-level libraries for game development and other types of game makers, I have decided to add a second category to the competition: Games Created Using a Game Engine. All rules apart from "Games cannot be created in any "game maker" software or dedicated engines" still apply, and there will be a separate ranking and set of prizes (see Prizes section below) for this category. Have fun!
For the sake of this compo I will refer to the original category (the one disallowing game engines/etc) as Games From Scratch Category.

Game related:
• The game can be of any genre or be a mix of genres.
• The game can only use THIS (click to download) graphical art (created by Kenney; see License.txt file for licensing details, but it's CC0). Yes, this will make all the games look the same - please focus on gameplay.
• Modifying the above assets is not allowed. Exceptions: standard transformations like resizing, rotating, moving around, moving sprites to different files, converting to different file types, color transformations. When in doubt, please ask in the comment section.
• The game can use one additional font, provided that it's a monochrome font (e.g. a single color + transparency/single-background-color bitmap font or a ttf/otf/woff vector font or similar); however only characters present in the IBM 437 code page can be used. "Monochrome" requirement is related to the file - you can color the font in game as you like.
• The text in game, if any, must be in English.
• There are no rules regarding music or sound (but please make sure that you can use a given asset for commercial purposes and distribution).
EDIT: New category added 2017-08-05:
• In the Games From Scratch Category games cannot be created in any "game maker" software or dedicated engines (e.g. RPG Maker, Unity, Unreal Engine, etc). Libraries providing I/O, reading assets, rendering fonts, etc are most welcomed. If in doubt, ask in the comments.
• In the Games Created Using a Game Engine Category the above rule does not apply, i.e. you can use any "game maker", game library or game engine. All other rules apply.
• A given game MUST run on one of the following operating systems: Ubuntu Desktop 17.04, Microsoft Windows 7 or Microsoft Windows 10. One exception is: a game can run in a standard web browser (Chrome, Firefox, Edge or IE) too.
EDIT: Rules added 2017-08-05 (after discussion in the comments):
• You are allowed to use and/or create additional UI assets, however the UI must be three colors at most (one background color and two foreground colors; antialiasing can be turned on and doesn't count into the limit). I.e. please settle for a simple UI. If you are using UI assets created by someone else, please make sure the license allows you to use them for commercial purposes.
• You are allowed to use procedurally generated graphical effects (but please do not use this rule to create additional object/background assets).
Contest related:
• Games must be submitted by sending a link to a downloadable package (hosted e.g. on Google Drive or something similar) to the following e-mail address: (please also add a comment under this post that you sent an e-mail - otherwise I won't know that I didn't get an e-mail and can't debug it).
• Source code MUST be included (all required binaries should be too). By submitting the game you agree to the game being re-hosted by me for anyone to download and test once the competition is over. I won't be doing anything weird with the game after the competition, but I want participants to learn from each other after the compo is over.
• Submission deadline is 3rd of September 11:59pm (23:59) CEST (i.e. GMT+2).
• Games not following above rules will not participate in the competition.
• When in doubt, ask in the comment section below.
• Gynvael's Livestream crew cannot participate in the contest (but can submit games to be showcased).

The prizes are somewhat symbolic, but I wanted to have some anyway:

Games From Scratch Category
Top 1: 150 USD (or equivalent) giftcard in / / .jp or .de (winner's choice).
Top 2: 100 USD (or equivalent) giftcard in / / .jp or .de (runner up's choice).
Top 3: 50 USD (or equivalent) giftcard in / / .jp or .de (third place's choice).

Games Created Using a Game Engine Category
Top 1: 150 USD (or equivalent) giftcard in / / .jp or .de (winner's choice).
Top 2: 100 USD (or equivalent) giftcard in / / .jp or .de (runner up's choice).
Top 3: 50 USD (or equivalent) giftcard in / / .jp or .de (third place's choice).

Unfortunately due to local and international laws participants from countries where this would be disallowed due to embargoes by Switzerland/European Union/Poland are not eligible for prizes (sorry). They can still participate though.

How the games be judged:
• There are no written-in-stone rules about that, but...
• I'll generally focus on the overall game quality (gameplay, creative use of assets, fun to play).
• I will totally ignore source code quality - please focus on the gameplay/etc. If the game crashes, but is mostly playable, I'll ignore the crashes too.
• I will also ignore game size / requirements, but I do expect that one of my PCs will be able to run the game smoothly (I will test the game on one/both of the following specs: i7 8-core/16-thread 128GB RAM with GTX 980 Ti and/or i7 4-core/8-thread 32GB RAM with GTX 1080 Ti).
• I will generally try my best (including consulting with the participant if needed) to make sure that the game is running as intended by the creator, as long as eventual patches / resubmissions are within the deadline mentioned in the Constraints section.
• If I will invite more judges to participate (e.g. if I feel the need for a second opinion) they will follow the same guidelines.

Q: Who made the game art that we'll be using?
A: It was created by Kenney. Be sure to visit his site. If you would like to donate, he has both a donation page and patreon running.

Q: Should I write in a Readme.txt / game credits about Kenney?
A: Formally Kenney doesn't require it, but it's always a nice gesture to give credit where credits are due :)

Q: I found Kenney's assets on OpenGameArt/other site and there were additional assets in the "Space Kit" you posted. Can I use them?
A: No. For the sake of the competition please only use the once linked in the rules above.

Q: Why can't I use other graphical assets? Why must I use only the one you posted (by Kenney)?
A: Think of it as a challenge! Try to be creative, focus on the game play. This one time you don't have to worry about making your game assets look super awesome - everyone will have the same assets.

Q: You said I can use resize on the assets... Can I resize each asset to 1px and then make a new asset out of that?
A: No.

Q: Can I use the assets which are available by default on Windows/Ubuntu?
A: For sound? Yes. For graphical assets? Only fonts (see above font rules though).

Q: So how about I put some new graphical assets in the bitmap font sprite? I can use one, right?
A: You can put the assets there, but you cannot use them (see the IBM 437 rule).

Q: Ah, right. So how about I convert my graphical assets to a sound file and render said sound file as a graphical asset?
A: No.

Q: But...
A: No. Please don't try to bypass the asset rule :) Instead e.g. focus on the gameplay.

Q: I've created my own game engine in the past - can I use it in this competition?
EDIT: Answer changed on 2017-08-05 (after adding the new category):
A: Yes, you can use any game engine in the "Games Created Using a Game Engine Category". In the "Games From Scratch Category" only very simple frameworks are allowed that don't do much more than SDL/SFML/etc.

Q: I'm using this AMD Radeon / Intel specific graphical option, but your specs don't cover it.
A: Yes, in such case I won't be able to run your game. Maybe there is a way for you to work around the issue and get a similar effect using more common features?

Q: Can I write my game in JavaScript for a web browser?
A: Sure :)

Q: Hey, it's me again. About new assets - can I just put some new pixel bitmap data as a byte/float/string/whatever array in the code?
A: No. Please use only the allowed graphical assets. Seriously.

Q: So how about I convert the pixel bitmap data to a series of "PutPixel" calls?
A: No. Please don't try to bypass this rule. Pretty please. With cherry on top ;)

Q: When will the results be announced?
A: Middle/late September, depending on the number of submissions. I will do a blog post announcing the winners at some point.

Q: I never took part in any gamedev compo like this. Can I still participate?
A: Sure! It's a great learning experience!

Q: Can I blog / tweet / livestream the making of my game?
A: Sure. Keep in mind that you will be revealing your ideas to other participants this way (it's within the rules to do it, but not everyone likes doing it).

Q: So what if I create a new sprite by using top-left corner pixels of various sprites shifted by small offsets and then crop it a little?
A: ...

EDIT: Entries added 2017-08-05 (after adding the UI/procedurally generated graphics rule):
Q: Can my UI elements be a part of the game world (i.e. interact with in-game elements, e.g. collide with assets)?
A: No. This would bypass the "no new graphical assets" constraint. The UI should be the UI and not part of the world.

Q: Can my procedurally generated effects interact with the world elements?
A: It depends. E.g. it would be OK for debris falling after an explosion to collide / cause damage to the surroundings. However, please do not use the procedurally generated graphics to bypass the "no new graphical assets" constraint; these should be used for graphical effects only.

See also the comment section for possibly more questions and answers. Feel free to also ask there if you have any questions.

Final words
Feel free to let your friends know about this competition - the more, the merrier.

Have fun, good luck!

Windows Kernel Debugging livestreams

By Gynvael Coldwind | Sun, 30 Jul 2017 00:10:56 +0200 | @domain:
It's a real pleasure for me to announce that the next four livestreams will feature Artem "honorary_bot" Shishkin (github), who will do an introduction into a long awaited topic of Windows Kernel Debugging. Artem, in his own words, is a fan of Windows RE, debugging and low-level stuff. He's been using WinDbg for kernel debugging for several years now for fun, customizing BSODs, building Windows kernel source tree or boot dependencies graph. Sometimes he might also accidentally discover such things as SMEP bypass on Windows 8 or how to disable PatchGuard in runtime. Being a great fan of Intel and specifically VMX technology he maintains his own bicycle debugger based on a bare metal hypervisor.

• 2017-08-02 (Wednesday), 8pm CET
• 2017-08-03 (Thursday), 8pm CET
• 2017-08-09 (Wednesday), 8pm CET
• 2017-08-10 (Thursday), 8pm CET

My YouTube livestreaming channel: (or if you prefer darker theme).

How to not forget:
• Subscribe to the YouTube channel and allow notifications.
• Subscribe to Gynvael Hacking Livestreams calendar (also: ICS, calendar ID:

Since I expect some technical problems (first time we'll be doing livestreaming with a guest in a remote location) I'll skip the usual news/announcements/mission solutions part of the streams to save some time (I'll probably do a dedicated stream for mission solutions later on). However DO expect new missions after each episode :)

See you Wednesday!

The mystery of two file descriptors

By Gynvael Coldwind | Sun, 30 Jul 2017 00:10:55 +0200 | @domain:
At my last livestream, around 1:02:15, I tried to show an old (as in: 2006) GDB detection trick relying on the fact that GDB "leaked" two file descriptors into the child process, i.e. the child process was spawned having 5 descriptors already allocated instead of the default 3 (stdin/stdout/stderr or 0/1/2). So I've created a small program that opened a file (i.e. allocated the next available file descriptor) and printed the descriptor, compiled it and executed (without GDB) assuming that number 3 will be printed. Instead 5 showed up and left me staring in amazement wondering what just happened. Since investigating this wasn't really the topic of my livestream I ended there, but today I found a few minutes to investigate the mysterious file descriptors. As expected, in the end it turned out that it was a mix of my mistake and unexpected behaviours of other programs. Furthermore, the descriptors could be used to escalate privileges under some very specific and weird conditions. To sum up - it turned out to be a fun bug.
My investigation started with trying to determine the nature of the file descriptors - so I started with the standard ls -l /proc/self/fd followed by lsof:

00:27:30 gynvael:haven> ls -l /proc/self/fd
total 0
lrwx------ 1 gynvael gynvael 64 Jul 30 00:27 0 -> /dev/pts/1
lrwx------ 1 gynvael gynvael 64 Jul 30 00:27 1 -> /dev/pts/1
lrwx------ 1 gynvael gynvael 64 Jul 30 00:27 2 -> /dev/pts/1
lrwx------ 1 gynvael gynvael 64 Jul 30 00:27 3 -> socket:[36875]
lrwx------ 1 gynvael gynvael 64 Jul 30 00:27 4 -> socket:[36612]
lr-x------ 1 gynvael gynvael 64 Jul 30 00:27 5 -> /proc/3800/fd

00:28:31 gynvael:haven> cat wth.c
int main(void) {
return 0;

00:28:42 gynvael:haven> gcc wth.c && ./a.out &
[1] 3831

00:29:21 gynvael:haven> lsof | grep `pgrep a.out`
a.out ... 3u IPv4 ... TCP localhost:33321 (LISTEN)
a.out ... 4u IPv4 ... TCP haven5:38666-> (ESTABLISHED)

Sockets listening on port 33321 - this actually rung a bell! These are sockets from my Windows↔Linux RPC interface.

The weird thing is that I could have sworn that I never noticed them before and I'm sure I listed file descriptors more than once during the years I've been using this Windows↔Linux setup. There was however one thing that changed a few months ago though - due to a bug in newer versions of GNOME Terminal on Ubuntu Server (i.e. if you don't have a full graphical environment installed it runs only from root for some reason) I recently switched to xterm. Maybe one terminal emulator made sure children processes get only stdin/stdout/stderr, and the other just passes the environment it inherited?

It turned out that that was (almost) exactly the case. I've done a quick test on three emulators (KDE konsole, xterm and GNOME Terminal) and indeed the first two passed on all inherited handles, while GNOME Terminal didn't exhibit this behaviour. However after further investigation it turned out that the latter is actually a side effect of GNOME Terminal being launched by dbus-daemon after an RPC call via dbus-launch.

Regardless of the above, of course the terminal emulators are not to be blamed for "leaking" handles - my RPC interface is.

The solution for this is rather obvious - just close the handles in the forked process when launching the terminal emulator. Since I'm using Python's (with shell=True) I could achieve this in various different ways:

1. Add closing the sockets (i.e. 3<&- 4<&-) to the issued commands:

command = "(cd '%s'; /usr/local/bin/xterm -fa 'Monospace' -fs 14 -bg 'rgb:00/00/00' -xrm '*metaSendEscape:true' -xrm '*eightBitInput:false' 3<&- 4<&- & )" % cwd

# Spawn.
return, shell=True)

2. Set the FD_CLOEXEC flag on the descriptors in question (e.g. like it's shown here) - this would close them when execve is invoked.

3. When creating the socket use the SOCK_CLOEXEC option.

I initially went for the first approach (enough for testing), but for the sake of the patch pushed to github I wanted a less "hacky" method, so I settled for SOCK_CLOEXEC. Sadly, it turned out that Python doesn't support this option until the Python 3 family, so I had to fall back to FD_CLOEXEC. The fix has been pushed to github.

Since the problem was fixed I started thinking what was the actual severity of this mistake. I came to a conclusion that this might be a funny (almost horizontal) local privilege escalation vulnerability if the sockets would ever be passed to a child process running under a different (less trusted / less privileged user).

The above would be possible due to a somewhat embarrassing bug with the CMD_l_cmd RPC call. By design this call should only allow the terminal to be executed in the specified location, however it seems I've messed up escaping the shell characters:

# Spawn the terminal.
cwd = cwd.replace("'", "\\'")
command = "(cd '%s'; /usr/local/bin/xterm -fa 'Monospace' -fs 14 -bg 'rgb:00/00/00' -xrm '*metaSendEscape:true' -xrm '*eightBitInput:false' 3<&- 4<&- & )" % cwd

That's not good at all - \' doesn't escape ' in Bash - you have to use '"'"' (seriously). In the current form one could just do a standard '; evil code; ' injection and would get the command launched with the privileges of the user running the RPC script.

One thing left to do is actually call the proper CMD_l_cmd implementation, though this isn't really straightforward (or maybe it is?) given that neither of the two sockets is connected to the "Linux VM" endpoint (see drawing above) - to be more specific, only the Linux VM endpoint implements the CMD_l_cmd call in a way that executes command. This would be the place where I would say "so the bug is not exploitable after all", but that turns out not to be the case, for two reasons:

1. While my RPC's description begins with words "Rather bad", it still requires knowing a secret key to be able to call the RPC. However, since the child process inherited the local RPC listening socket (i.e. socket "C" on the drawing above), it can "race" the actual RPC daemon to accept() an incoming local connection (e.g. one that happens if I click on a link in a Linux process and want it loaded in my Windows Chrome browser), and then happily receive the secret key from the connected RPC client (so it seems "Rather bad" holds true after all as this would not happen if there was a proper private/public-crypto mutual authentication scheme in play). The key can be used to then connect to the local RPC interface, authenticate, and issue the CMD_l_cmd call.

2. That said, the above is not even needed, as while the Windows endpoint doesn't actually execute the CMD_l_cmd call, it does by default forward it to the Linux VM. Well then.

Thankfully all above can be fixed by just doing a simple cwd = cwd.replace("'", "'"'"'") escape (unless... someone knows a bypass for this? if so, please let me know in the comments down below).

In the end the mystery of two additional sockets was indeed fun and led to the discovery of another interesting bug. And while severity was there, the risk was minimal (well, at least in my use case) as the exploitation scenario is really unlikely.

Debugging story: a crash while mapping a texture

By Gynvael Coldwind | Sun, 16 Jul 2017 00:10:51 +0200 | @domain:
Recently on my Polish livestreams I've been writing a somewhat simple raytracer (see screenshot on the right; source code; test scene by ufukufuk), with the intention of talking a bit on optimization, multithreading, distributed rendering, etc. As expected, there were a multitude of bugs on the way, some more visual than others. My favorite one so far was a mysterious buffer overflow resulting with a C++ exception being thrown when rendering in 4K UHD (3840x2160) but not in 1080p (1920x1080). While trying to find the root cause I also run into a standard C library bug with the sqrt function (though it turned out not to be related in the end), which made the run even more entertaining.
It all started with a thrown C++ exception:

.............terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 9223372036854775808) >= this->size() (which is 845824)

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Well, I had to agree that 9223372036854775808 is larger-or-equal to 845824. I immediately knew where the exception was thrown, as there was only one place in the whole code base where I used the at() method of a std::vector which could throw this exception*.
* The difference between using some_vector[i] and is that the prior doesn't do any range checking (at least in popular implementations) while the latter does and throws an exception when i points out of bounds.

V3D Texture::GetColorAt(double u, double v, double distance) const {
(void)distance; // TODO(gynvael): Add mipmaps.

u = fmod(u, 1.0);
v = fmod(v, 1.0);
if (u < 0.0) u += 1.0;
if (v < 0.0) v += 1.0;

// Flip the vertical.
v = 1.0 - v;

double x = u * (double)(width - 1);
double y = v * (double)(height - 1);

size_t base_x = (size_t)x;
size_t base_y = (size_t)y;

size_t coords[4][2] = {
{ base_x,
base_y },
{ base_x + 1 == width ? base_x : base_x + 1,
base_y },
{ base_x,
base_y + 1 == height ? base_y : base_y + 1 },
{ base_x + 1 == width ? base_x : base_x + 1,
base_y + 1 == height ? base_y : base_y + 1 }

V3D c[4];
for (int i = 0; i < 4; i++) {
c[i] =[i][0] + coords[i][1] * width);

I started by running the raytracer with a debugger attached and waited for it to trigger again - it took about 20 minutes to reach the state where the bug was triggered (I felt like I was debugging something that's located on Mars). However it seems that GDB doesn't break by default on C++ exceptions (TIL: you have to issue the catch throw command first):

...........terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 9223372036854775808) >= this->size() (which is 845824)

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
[Thread 26080.0x7b58 exited with code 3]
[Thread 26080.0x7024 exited with code 3]
[Thread 26080.0x8648 exited with code 3]
[Thread 26080.0x84fc exited with code 3]
[Thread 26080.0x81e8 exited with code 3]
[Thread 26080.0x525c exited with code 3]
[Thread 26080.0x53a8 exited with code 3]
[Thread 26080.0x87d0 exited with code 3]
[Thread 26080.0x7de0 exited with code 3]
[Thread 26080.0x41b0 exited with code 3]
[Thread 26080.0x63e4 exited with code 3]
[Thread 26080.0x7e10 exited with code 3]
[Thread 26080.0x6c28 exited with code 3]
[Thread 26080.0x84dc exited with code 3]
[Thread 26080.0x7044 exited with code 3]
[Thread 26080.0x816c exited with code 3]
[Inferior 1 (process 26080) exited with code 03]
(gdb) where
No stack.

I decided to change the strategy and replace the at() method with the operator[] so that the C++ exception is not thrown, but instead a Windows exception (ACCESS_VIOLATION) is raised (which are caught by default by the debugger). A quiet voice in my head told me "that won't work if the value multiplied by the size of the element will overflow and fall within the range" - and sure enough, after 40 minutes of rendering I got a 4K image without any crashes. The reason was that the actual index - 9223372036854775808 (0x8000000000000000 hexadecimal) multiplied by the size of the vector element (12 bytes) overflows into the value 0, and index 0 is perfectly valid.

The next strategy change involved actually catching the exception in C++ (as in a try-catch block) and doing lots of debug prints on such an event. This (after another 20 minutes) yielded good results:

.....u v: nan nan
x y: nan nan
base x y: 9223372036854775808 9223372036854775808
0: 9223372036854775808 9223372036854775808
1: 9223372036854775809 9223372036854775808
2: 9223372036854775808 9223372036854775809
3: 9223372036854775809 9223372036854775809
w h: 826 1024

The problem seemed to be that u and v were NaN, which is a special IEEE-754 floating point value that has the habit of being propagated all around once some expression yields it as a result, i.e. any operation on NaN will yield NaN, with a small exception of sign change which produces -NaN.

One more exception is actually casting it to integers. The C++ standard is pretty clear here - it's undefined behavior. However, in low-level land there actually needs to be an effect and usually there is an explanation for that effect. I started looking into it by running a simple snippet like cout << (size_t)NAN which produced the value 0 (and not the expected 0x8000000000000000). After doing some more experiments and reading in Intel Manual (Indefinites and Results of Operations with NaN Operands or a NaN Result for SSE/SSE2/SSE3 Numeric Instructions sections) I figured out that the x86 assembly instructions themselves (both fist/fistp from the FPU group, as well as cvttsd2si/vcvttsd2si from the SSE/AVX group) return 0x8000000000000000 (called the indefinite value) in such case (a more general rule is: all bits apart from the most significant one are cleared); the #IA fault might be thrown as well, but it's almost always masked out. That said, since technically this is an UB, the compiler can do whatever it feels like and e.g. put a 0 as the result of a (size_t)NAN cast during compilation time. To quote our IRC bot (courtesy of KrzaQ):

<@Gynvael> cxx: { double x = NAN; cout << (size_t)x; }
<+cxx> 9223372036854775808
<Gynvael> cxx: { cout << (size_t)NAN; }
<+cxx> 0

Back to the original problem. Looking at the code, u and v actually come from outside of the function and are modified only in the first lines of the function:

V3D Texture::GetColorAt(double u, double v, double distance) const {
u = fmod(u, 1.0);
v = fmod(v, 1.0);
if (u < 0.0) u += 1.0;
if (v < 0.0) v += 1.0;

The fmod function doesn't seem to ever return NaN, so u and v arrived at the function already containing the NaN value. The function itself is called from the main shader and the interesting values are the result of a call to the V3D Triangle::GetUVW(const V3D& point) function. The function itself uses the barycentric interpolation method to calculate the UVW texel coordinates given three points making a triangle, UVW values for each of them and an "intersection" point on the triangle that the interpolated value is calculated for. It looks like this:

V3D Triangle::GetUVW(const V3D& point) const {
V3D::basetype a = vertex[0].Distance(vertex[1]);
V3D::basetype b = vertex[1].Distance(vertex[2]);
V3D::basetype c = vertex[2].Distance(vertex[0]);

V3D::basetype p0 = point.Distance(vertex[0]);
V3D::basetype p1 = point.Distance(vertex[1]);
V3D::basetype p2 = point.Distance(vertex[2]);

V3D::basetype n0 = AreaOfTriangle(b, p2, p1);
V3D::basetype n1 = AreaOfTriangle(c, p0, p2);
V3D::basetype n2 = AreaOfTriangle(a, p1, p0);

V3D::basetype n = n0 + n1 + n2;

return (uvw[0] * n0 + uvw[1] * n1 + uvw[2] * n2) / n;

The barycentric interpolation method itself is actually pretty simple - the final result is the weighted average of the UVWs of all three points making the triangle, where the weight of the value is actually the area of the triangle made by the provided "intersection" point and the two triangle points that are not the point the weight is calculated for (see the slides liked above for a better explaination).

After adding some more debug prints and waiting another 20 minutes it turned out that the AreaOfTriangle returned the NaN value in some cases when the triangle in question was actually a line (i.e. one of the three points that make the triangle was located exactly on the edge between two other points). This led me to the AreaOfTriangle function itself:

static V3D::basetype AreaOfTriangle(
V3D::basetype a, V3D::basetype b, V3D::basetype c) {
V3D::basetype p = (a + b + c) / 2.0;
V3D::basetype area_sqr = p * (p - a) * (p - b) * (p - c);

return sqrt(area_sqr);

The function is rather simple - it uses the Heron's Formula to calculate the area given the length of all three edges of the triangle, by calculating half of the perimeter (variable p in my code), then multiplying with the difference between each length of the edge and p and then calculating the square root out of the result. The last bit is what caught my attention - as far as I knew sqrt() function would actually return NaN if a negative value was fed to it.

I started by verifying both in the documentation and experimentally for the value -1 (no, these are not complex numbers, it's not i). The said "a domain error occurs, an implementation-defined value is returned (NaN where supported)", stopped at "a domain error occurs", MSDN mentioned "returns an indefinite NaN" and man for glibc agreed. The experimental part had actually much weirder results: on Ubuntu sqrt(-1) yielded the value -NaN (well, I guess -NaN is still technically a NaN), but on Windows I've got -1 (wait, what?). I tried on Windows with a couple other values and it turned out that sqrt is just returning the negatives as I pass them. Given that MSDN claimed that a NaN will be returned I launched IDA and found that the mingw-w64 GCC 7.0.1 compiler I'm using actually has it's own implementation of the sqrt function, which happened to suffer from a regression in the recent months. Oh well.

Wait. Why did I actually get NaN in my raytracer if there is such a bug? It turned out that I'm actually using -O3 when compiling my app and using -O3 causes a sqrt to actually work correctly (probably due to some random compiler optimizations) and return NaN (a positive one for a change).

This left the question of "why is the value passed to sqrt negative?". The answer is the one you would expect: floating point inaccuracies. I printed the exact (somewhat - i.e. in decimal form) lengths of the triangle edges that were passed to the function upon crash:


Given that one of the points lies on the edge between the two other, a should be exactly equal to b+c, however that wasn't the case:

a =66.2214810193791976189459091983735561370849609375
b+c =66.2214810193791834080911939963698387145996093750

This also means that one of the brackets in the area_sqr calculation will probably yield a negative value (even though 0 would be the correct result):

p =66.22148101937918340809119399636983871459960937500

After the multiplications and the sqrt call we arrive at the infamous NaN, which solves the whole riddle.

The fix was rather easy - since I know that there is no such thing as "negative area", I can just check if area_sqr is negative and correct it to 0.0 in such a case:

// It seems that due to floating point inaccuracies it's possible to get a
// negative result here when we are dealing with a triangle having all points
// on the same line (i.e. with a zero size area).
if (area_sqr < 0.0) {
return 0.0;

To sum up, the invalid index calculation was caused by float inaccuracies earlier on in the calculations, which caused an area of triangle to be a square root of a negative number. I must admit I really had fun debugging this bug, especially that I encountered both the interesting NaN-to-integer cast scenario, as well as the sqrt mingw-w64 bug on the way.

And that's about it.

Blind ROP livestream followup

By Gynvael Coldwind | Thu, 13 Jul 2017 00:10:50 +0200 | @domain:
Yesterday I've done a livestream during which I tried to learn the Blind Return Oriented Programming technique. Well, that isn't fully accurate - I already read the paper and had one attempt the evening before, so I knew that the ideas I wanted to try live should work. And they did, but only in part - I was able to find a signaling gadget (i.e. a gadget that sent some data to the socket) which could be used later on, as well as a "pop rsi; ret"-equivalent gadget (using a different method than described in the paper - it was partly accidental and heavily challenge specific). But throughout the rest of the livestream I was able to find neither a puts function nor use the gadget I already had to get a "pop rdi; ret"-equivalent gadget. The bug, as expected, was trivial.

Long story short (a more verbose version follows), my mistake was in the following code:

if err == "CRASH" and len(ret) > 0:
return (err, ret)

The correct form is:

if err == "DISCONNECTED" and len(ret) > 0:
return (err, ret)

And that's it. If you were on the YT chat or IRC you probably saw me "facepalming" (is that even a word? it should be) and pointing out the bug even before the stream went offline (i.e. during the mission screen). In the next 5 minutes I had both gadgets I needed, so that was the only bug there. Oh well.

Full version of the story:
I'll start by saying that if you don't know what ROP is (Return Oriented Programming, which is actually an exploitation technique), you might want to start there as BROP (or Blind ROP) is a technique that heavily builds on top of ROP. Here are some random links about ROP:

The Geometry of Innocent Flesh on the Bone: Return-into-libc without Function Calls (on the x86) (Hovav Shacham)
Return-Oriented Programming: Exploits Without Code Injection
Doing ret2libc with a Buffer Overflow because of restricted return pointer - bin 0x0F (LiveOverflow)
ROP with a very small stack - 32C3CTF teufel (pwnable 200) (LiveOverflow)
And also:
Return-oriented exploiting
Hacking Livestream #20: Return-oriented Programming

There were some follow-up papers and techniques , e.g. Return-Oriented Programming without Returns, but the above should be enough to get you started.

One of such follow-ups was the Hacking Blind paper by Andrea Bittau, Adam Belay, Ali Mashtizadeh, David Mazieres and Dan Boneh from Stanford University - a really cool piece of research that showed that you don't really need the binary to find gadgets. I highly recommend reading the paper, but as a summary I'll note that it boils down to first locating the binary in memory (by basically reading the stack using e.g. Ben Hawkes' byte-by-byte brute force technique also described by pi3 in Phrack), then finding a gadget which has an observable effect (e.g. it hangs the connection or sends some additional data through the socket) and finally finding gadgets using pretty clever heuristics that boil down to observing one of three signals (a crash, the normal behavior, or the aforementioned observable effect). So yeah, it's the blind SQLI of ROP ;).

The original paper showcases several optimizations, but I decided to start with the basics (I'm a fan of reinventing the wheel). I prepared a small forking-server binary (an echo server basically) that had PIE and stack cookies disabled (and ASLR was also disabled system-wide), compiled it statically and run on a virtual machine.

Both the binary and the source code created before and after the stream are available on my github (the binary listens on port 1337; please note that when learning blind ROP you should not look at the binary in IDA/etc and pretend you don't have access to it).

The first step was to look for the bug (though that was trivial in this case as there is only one input length+data pair basically) and the size of the overflowed buffer. This was done by using growing data lengths (from 1 byte upwards) and checking whether the "Done!" message was transmitted via the socket (denoted as "OK" in my code) or whether the connection abruptly stopped before that (denoted as "DISCONNECTED" or "ERROR" in my socket code, or just "CRASH" later on - I mixed this up on the stream thus I couldn't get it to work to the full extent in the end). It turned out that the buffer was 40 bytes long.

The next step was to find a signaling gadget. A signaling gadget (similarly to a signaling behavior in Blind SQLI) can either be some data transmitted over the socket or a connection hang (i.e. the server application entering an infinite loop or hanging on some input which can be detected e.g. using the socket timeout mechanism). During the livestream I found a gadget which did both, i.e. it printed a 16-hexdigit number (so it was probably a printf("%.16x", arg2) function call) and then started reading from the socket (which basically stopped the application and caused a socket timeout on my side).

This gadget was actually really useful, since it being (probably) a printf("%.16x", arg2) call meant that jumping just after the instruction that puts the second argument in the RSI register (64-bit Linux calling convention) would output the current value of the RSI register. This also meant that I could easily find a "pop rsi; ret"-equivalent gadget (I keep writing "-equivalent" as found gadgets might be a lot large and have unpredictable side-effects, but in the end they would e.g. also pop a value from the stack and place it in a given register) just by using the following ROP-chain:

[unknown-scanned address]
[address of the printf("%.16x", rsi) gadget]

The unknown-scanned address would be a sequential-or-random address within the assumed range of the executable section of the binary. Since one needs probably quite a lot of attempts to find such gadget (tens of thousands) I decided (as the paper suggested) to use multiple threads/connections to do it (20 threads worked fine in my case). Part of the output log looked like this (this is actually from the pre-stream version):

0x37b4 PRINT
Data size:
0x37ef PRINT
Data size:
Data size:

Due to multithreading this isn't really readable, but one can observe some non-4141414141414141 values (mainly 00000000006ee3c3) and then in the end the magical 4141414141414141 value right next to the "PRINT 0x38e2" information (which means: the gadget is at image_base+0x38e2 address).

The next step was to find the puts function (followed probably by a crash) that could be used to easily find a "pop rdi; ret"-equivalent gadget (the idea was to do puts(image_base+1) which would echo "ELF" when the correct gadget is found), but for some reason it didn't work (yeah, this is the place where the "CRASH"/"DISCONNECTED" mix up started to be a problem). I then tried to use the print-gadget I had already, but actually jumping 7 or 8 bytes after it to skip setting the RDI register (and using that instead of puts, risking an accidental format tag like %s at the beginning of the binary resulting in a false negative). This didn't work either (though probably because I wasn't patient enough with 8 bytes variant - well, a stream is time limited).

After some more minutes of trying I decided to finish the stream at that point (it was already 1.5h long) and promised to do this blogpost about what went wrong. So yeah, I mixed up the name of the signal from my socket-helper implementation (serves me right for using strings instead of any sane type of enums/constants).

When I spotted the problem I was able to both find the puts gadget I wanted and the "pop rdi; ret"-equivalent gadget within the next few minutes. Having these two what was left to do was actually just dumping the binary as a puts(controlled_rdi) allows one to do it by sequentially reading the memory (and assuming that there is a \0 at the end of every piece of data). It must be noted that it took several hours to dump the binary (as it was over 1MB in size).

Having the binary would bring this to a standard ROP exploitation which wouldn't take much more time (especially if the magic gadget would be found in the binary; I guess one can look for this gadget in BROP as well).

So there you have it :). Again I would like to recommend reading the paper, especially the sections about the "BROP-gadget" and PLT/GOT methods - I really liked them.

And that's it.

Announcing Bochspwn Reloaded and my REcon Montreal 2017 slides

By j00ru | Tue, 20 Jun 2017 16:14:58 +0000 | @domain:
A few days ago at the REcon conference in Montreal, I gave a talk titled Bochspwn Reloaded: Detecting Kernel Memory Disclosure with x86 Emulation and Taint Tracking. During the presentation, I introduced and thoroughly explained the core concept, inner workings and results of my latest research project: a custom full-system instrumentation based on the Bochs ... Read more

Google Capture the Flag 2017 Quals start today

By Gynvael Coldwind | Fri, 16 Jun 2017 00:10:49 +0200 | @domain:
Google Capture the Flag 2017 (Quals) start today at 2am CEST tonight! The format will be pretty standard - teams / jeopardy / 48h / dynamic scoring, with one interesting addition - the submitted write-ups might win rewards ($100 - $500) as well - see the rules for details. In any case, I hope it turns out to be a fun and challenging CTF - I personally have every reason to hope the best, as the people behind the scenes are both amazing and experienced. And hey, there is even one task from me :)

I wish you all best of luck!


Windows Kernel Local Denial-of-Service #5: win32k!NtGdiGetDIBitsInternal (Windows 7-10)

By j00ru | Mon, 24 Apr 2017 09:39:26 +0000 | @domain:
Today I’ll discuss yet another way to bring the Windows operating system down from the context of an unprivileged user, in a 5th and final post in the series. It hardly means that this is the last way to crash the kernel or even the last way that I’m aware of, but covering these bugs indefinitely ... Read more

Windows Kernel Local Denial-of-Service #4: nt!NtAccessCheck and family (Windows 8-10)

By j00ru | Mon, 03 Apr 2017 10:59:46 +0000 | @domain:
After a short break, we’re back with another local Windows kernel DoS. As a quick reminder, this is the fourth post in the series, and links to the previous ones can be found below: Windows Kernel Local Denial-of-Service #3: nt!NtDuplicateToken (Windows 7-8) Windows Kernel Local Denial-of-Service #2: win32k!NtDCompositionBeginFrame (Windows 8-10) Windows Kernel Local Denial-of-Service #1: ... Read more