<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://maxodnovolyk.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://maxodnovolyk.com/" rel="alternate" type="text/html" /><updated>2024-08-05T17:48:26+03:00</updated><id>https://maxodnovolyk.com/feed.xml</id><title type="html">Max Odnovolyk</title><subtitle>There is no such thing as a failed experiment..., including this blog.
</subtitle><author><name>Max Odnovolyk</name></author><entry><title type="html">How To Jailbreak iOS 8.2 in 2017</title><link href="https://maxodnovolyk.com/ios8-jailbreak/" rel="alternate" type="text/html" title="How To Jailbreak iOS 8.2 in 2017" /><published>2017-02-15T11:00:00+02:00</published><updated>2017-02-15T11:00:00+02:00</updated><id>https://maxodnovolyk.com/ios8-jailbreak</id><content type="html" xml:base="https://maxodnovolyk.com/ios8-jailbreak/"><![CDATA[<p>Last week I’ve tried to figure out how cheap Chinese AV to Wi-Fi signal converter (903W) works to be able to capture streamed video in my own application. For this purpose I needed access to jailbroken iOS device to run such tools as <code class="language-plaintext highlighter-rouge">cycript</code> and to have ability to dump decrypted iOS application binaries with <code class="language-plaintext highlighter-rouge">dumpdecrypted</code>.
<!-- more --></p>

<p>In most cases jailbreaking modern iOS devices is a trivial process except devices that were updated to the latest iOS version. In my specific case I had my old iPhone 5 with iOS 8.2 available for experiments, but, unfortunately, it wasn’t possible to update this device to anything but iOS 10.2.x. Jailbreak for iOS 10.2.x on iPhone 5 wasn’t available as of January 2017, so I decided to move on with already installed iOS 8.2 and try to jailbreak two-year-old OS with TaiG tool.</p>

<p>First of all, it should be noted that success of whole process depends on right combination of installed iTunes (Apple Mobile Device Support package on Windows) and jailbreak tool version, which, in turn, supports your iOS version. To be honest, I don’t feel myself comfortable running applications created by Chinese hackers on my work machine, that’s why I completed all steps below on my old HP XW6600 with installed Windows 7 on it. I didn’t consider virtual machine usage due to reported issues of TaiG Jailbreak Tool running on VM.</p>

<p>There are two jailbreak options available for iOS 8.x series from TaiG and Pangu, but only TaiG supports iOS 8.2 and available in both Windows and OS X versions. Last version of TaiG Jailbreak Tool for iOS 8.x is v2.4.5, but alas, it doesn’t work with iOS 8.2, installed on my iPhone 5. I’ve tried to run it with different iTunes versions, but had no luck. So I decided to rollback to v2.4.3 in conjunction with iTunes v12.1.2.27. Looking ahead I can say that this combination was successful and I was able to jailbreak my iPhone 5 with it.</p>

<p>TaiG Jailbreak Tool prevents you from running previous versions of application by checking the version of launched application with the last one available on TaiG homepage. This check is obligatory and blocking. Also it won’t allow you to run the tool when TaiG Update Check service is unavailable what happens sometimes.</p>

<p>
  <div class="slideshow">
    <div class="controls">
      <a class="prev fa fa-angle-left" onclick="prevSlide(event);" title="Previous photo"></a>
      <span class="slide-number">1/4</span>
      <a class="next fa fa-angle-right" onclick="nextSlide(event);" title="Next photo"></a>
    </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/ios8-jailbreak/taig-update-required.png" alt="TaiG Jailbreak Tool V2.4.3 requires update" title="Update Required" onclick="nextSlide(event);" />
        
          <div class="caption">TaiG Jailbreak Tool V2.4.3 requires you to install the latest v2.4.5 on launch
</div>
        
      </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/ios8-jailbreak/taig-connection-issue.png" alt="TaiG Jailbreak Tool V2.4.3 doesn't work offline" title="Doesn't Work Offline" onclick="nextSlide(event);" />
        
          <div class="caption">Turning off internet connection does not help to bypass update check
</div>
        
      </div>
    
  </div>
</p>

<p>So what can we undertake here? There are a lot of tools that allow us to view what requests are sent from our computer and what responses it receives. They are called packet sniffers or analyzers. Even the simplest one will cover our needs as we need to determine only URL of the Update Check request.</p>

<p class="center"><img src="/img/ios8-jailbreak/http-network-sniffer.jpg" alt="HTTPNetworkSniffer Screenshot" title="HTTPNetworkSniffer" class="thumbnail" />
<em class="caption">HTTPNetworkSniffer is a simple packet sniffer tool that captures all HTTP requests/responses, and that information is enough for us in this specific case. Alternatively, you can use monstrous Wireshark, that can capture everything, but let’s keep things simple.</em></p>

<p>With help of HTTPNetworkSniffer we can figure out that TaiG Jailbreak Tool sends request to <code class="language-plaintext highlighter-rouge">i_get_taig_pc_config.php</code> with <code class="language-plaintext highlighter-rouge">data</code> GET parameter, probably, the current version signature:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>http://f_bb.taig.com/Interface/i_get_taig_pc_config.php?data=sU40nFL43ykkDN0HS445RDwWUi%43RPgyKpSJ21HdsDDCRyNarODu%2FHGXEE5Wxf%2FJPYlzztfTSYkw940%0D%0AdcsVU20AXAF0WQD92%2Ff9yI324FCMGEvE%3D
</code></pre></div></div>

<p>Now, when we know this detail, we can emulate work of Update Check logic on our local server and point TaiG Jailbreak Tool to it.</p>

<p>But first we need to get successful Update Check request response structure. To get it we can run the latest TaiG Jailbreak Tool v2.4.5 and capture Update Check request URL with HTTPNetworkSniffer. Putting this URL into any browser will reveal JSON response structure that application gets in case of successfully passed check:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[{</span><span class="w">
  </span><span class="nl">"VERSION"</span><span class="p">:</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w">
  </span><span class="nl">"TIME"</span><span class="p">:</span><span class="w"> </span><span class="mi">600</span><span class="p">,</span><span class="w">
  </span><span class="nl">"RESULT"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="w">
</span><span class="p">},</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span><span class="p">}]</span><span class="w">
</span></code></pre></div></div>

<p>That’s all we need to emulate Update Check service. We can skip <code class="language-plaintext highlighter-rouge">data</code> GET parameter analysis as our Update Check service will respond with <code class="language-plaintext highlighter-rouge">success</code> for all application versions.</p>

<p>Let’s use simple web server <a href="https://www.cesanta.com/products/binary">Mongoose</a> to host plain text file as <code class="language-plaintext highlighter-rouge">i_get_taig_pc_config.php</code>. Re-create next folder structure and put successful JSON response, mentioned above, into <code class="language-plaintext highlighter-rouge">i_get_taig_pc_config.php</code>.</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>|_____c:
|  |_____wwww
|  |  |_____Interface
|  |  |  |_____i_get_taig_pc_config.php
</code></pre></div></div>

<p>Run Mongoose with following command-line arguments:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>c:\ &gt; mongoose.exe -document_root C:\www -listening_port 80 -cgi_pattern ""
</code></pre></div></div>

<p>Final step - append Windows <code class="language-plaintext highlighter-rouge">hosts</code> file (<code class="language-plaintext highlighter-rouge">C:\Windows\System32\drivers\etc\hosts</code>) with new line to point TaiG Jailbreak Tool to our masqueraded service instead of genuine one:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>127.0.0.1		f_bb.taig.com
</code></pre></div></div>

<p>Now we are ready to launch any version of TaiG Jailbreak Tool or reload already launched application by pressing Try Again button.</p>

<p>
  <div class="slideshow">
    <div class="controls">
      <a class="prev fa fa-angle-left" onclick="prevSlide(event);" title="Previous photo"></a>
      <span class="slide-number">1/4</span>
      <a class="next fa fa-angle-right" onclick="nextSlide(event);" title="Next photo"></a>
    </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/ios8-jailbreak/taig-ready-to-jailbreak.png" alt="TaiG Jailbreak Tool V2.4.3 update check successfully bypassed" title="Update Check Successfully Bypassed" onclick="nextSlide(event);" />
        
          <div class="caption">You can select preferred options and proceed to jailbreak
</div>
        
      </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/ios8-jailbreak/taig-jailbreaking.png" alt="TaiG Jailbreak Tool V2.4.3 jailbreaking..." title="Jailbreaking..." onclick="nextSlide(event);" />
        
          <div class="caption">This step could take about 15 minutes. If it stucks longer, try to attach your iPhone into another USB port.</div>
        
      </div>
    
  </div>
</p>

<p>After approximately 15 minutes and several iPhone reboots you will get access to unrestricted iOS environment perfect for debugging and reverse engineering.</p>

<p>Similar steps could be used to overcome updates checks in most applications. In fact, described approach could be classified as spoofing attack, which aims to masquerade one person or service (endpoint) as another by falsifying data, thereby gaining an illegitimate advantage (successfully passed update check).</p>

<p>Speaking of APIs for updates check and beyond, use of secure HTTP instead of plain together with SSL pinning can make this type of attack more difficult or indeed impossible.</p>]]></content><author><name>Max Odnovolyk</name></author><summary type="html"><![CDATA[Bypassing TaiG Tool version checking mechanism to jailbreak old iOS 8.2 in order to get access to unrestricted environment for debugging. Similar spoofing approach could be used to overcome update checks in most applications.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://maxodnovolyk.com/%7B%22facebook%22=%3E%22/assets/images/max-odnovolyk-fb-wide.png%22,%20%22twitter%22=%3E%22/assets/images/max-odnovolyk-twitter.png%22%7D" /><media:content medium="image" url="https://maxodnovolyk.com/%7B%22facebook%22=%3E%22/assets/images/max-odnovolyk-fb-wide.png%22,%20%22twitter%22=%3E%22/assets/images/max-odnovolyk-twitter.png%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Jekyll Cheat Sheet</title><link href="https://maxodnovolyk.com/jekyll-cheat-sheet/" rel="alternate" type="text/html" title="Jekyll Cheat Sheet" /><published>2017-01-28T11:00:00+02:00</published><updated>2017-01-28T11:00:00+02:00</updated><id>https://maxodnovolyk.com/jekyll-cheat-sheet</id><content type="html" xml:base="https://maxodnovolyk.com/jekyll-cheat-sheet/"><![CDATA[<p>I’ve discovered Jekyll in fall 2016. It’s a simple static site generator which transforms your plain text and markdown documents into websites and blogs. Comparing to Wordpress (or other dynamic blogging engines), Jekyll doesn’t run any logic on the web server, as a result, you can host it on the simplest HTTP server and don’t worry about any vulnerabilities. All “dirty” job is done on your local work machine or CI server.<!-- more --></p>

<p>Despite such architecture, you still can add dynamic features like comments or search by using third-party services (e.g. Disqus, Google Custom Search). I really like the idea of ramping up functionality on top of a simple but flexible base, instead of cutting off complex universal engines.</p>

<p>Here’s shortened list of commands, settings, plugins, Liquid tags and filters which I frequently use while working with Jekyll.</p>

<h2 id="setting-up-and-running">Setting Up and Running</h2>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Install Jekyll and Bundler through RubyGems</span>
<span class="nv">$ </span>gem <span class="nb">install </span>jekyll bundler

<span class="c"># To be able to run Jelyll without prefixing it with bundle exec ensure that you do not</span>
<span class="c"># have different versions of the same gems installed simultaneously on your machine</span>
<span class="nv">$ </span><span class="nb">sudo </span>gem update
<span class="nv">$ </span><span class="nb">sudo </span>gem cleanup

<span class="c"># Create new Jekyll blog with default theme (minima)</span>
<span class="nv">$ </span>jekyll new blog-directory
	
<span class="c"># After adding new dependencies to Gemfile and _config.yml execute `bundle`</span>
<span class="c"># to download them</span>
<span class="nv">$ </span>bundle
<span class="c"># or check updates availability for dependencies and install them</span>
<span class="nv">$ </span>bundle update

<span class="c"># Run server. All changes will be automatically applied, except changes in _config.yml </span>
<span class="c"># (server restart is required to pick them up).</span>
<span class="nv">$ </span>jekyll s

<span class="c"># Process and render draft posts</span>
<span class="nv">$ </span>jekyll s <span class="nt">-D</span>

<span class="c"># Publish posts or collection documents with a future date</span>
<span class="nv">$ </span>jekyll s <span class="nt">--future</span>

<span class="c"># Run production environment (with Google Analytics and Disqus turned on)</span>
<span class="nv">$ JEKYLL_ENV</span><span class="o">=</span>production jekyll serve
<span class="c"># you can specify server host (to be able to test from other devices in same network) </span>
<span class="nv">$ JEKYLL_ENV</span><span class="o">=</span>production jekyll s <span class="nt">-H</span> 192.168.1.47

<span class="c"># Just build production html to _site directory (output path could be changed with -d argument)</span>
<span class="nv">$ JEKYLL_ENV</span><span class="o">=</span>production jekyll build

<span class="c"># You can use multiple configuration files to override Jekyll options (e.g. use `_dev.yml` to </span>
<span class="c"># disable HTML compression while running development environment)</span>
<span class="nv">$ </span>jekyll s <span class="nt">--config</span> _config.yml,_dev.yml

<span class="c"># And finally, of course, you can print help for Jekyll</span>
<span class="nv">$ </span>jekyll —help
<span class="c"># or review help for specific subcommand</span>
<span class="nv">$ </span>jekyll build —help
</code></pre></div></div>

<h2 id="configuration-settings">Configuration Settings</h2>

<p>Most of the Jekyll command-line arguments can be specified in configuration YAML file. By default Jekyll loads <code class="language-plaintext highlighter-rouge">_config.yml</code>, but you can specify one or more custom configuration files with <code class="language-plaintext highlighter-rouge">--config</code> command-line argument.</p>

<p>You can create two separate configuration files for development and production. For instance, if you use <code class="language-plaintext highlighter-rouge">octopress-minify-html</code> plugin, it’s a good idea to skip HTML compression while building or running server for development purposes. To achieve it you can create separate <code class="language-plaintext highlighter-rouge">_dev.yml</code> file with the following setting:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">env</span><span class="pi">:</span> <span class="s">dev</span>
</code></pre></div></div>
<p>and run your <code class="language-plaintext highlighter-rouge">serve</code> or <code class="language-plaintext highlighter-rouge">build</code> command with <code class="language-plaintext highlighter-rouge">--config</code> argument:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>jekyll s <span class="nt">--config</span> _config.yml,_dev.yml
</code></pre></div></div>
<p>Settings from <code class="language-plaintext highlighter-rouge">_dev.yml</code> will override corresponding values from <code class="language-plaintext highlighter-rouge">_config.yml</code>.</p>

<p>All settings from your configuration are available through your posts and pages via <code class="language-plaintext highlighter-rouge">site</code> object. Also, you can add any custom settings to your configuration file, which will be available through <code class="language-plaintext highlighter-rouge">site</code> object too. Third-party plugins often use this ability to configure itself.</p>

<h2 id="yaml-front-matter">YAML Front Matter</h2>

<p>In the YAML Front Matter section you can set predefined variables or create custom ones for using them in Liquid tags within further down code and also in all included files and layouts that the current page or post depends on.</p>

<p>There are few predefined global variables: <code class="language-plaintext highlighter-rouge">layout</code>, <code class="language-plaintext highlighter-rouge">permalink</code>, <code class="language-plaintext highlighter-rouge">published</code>. Posts predefined variables: <code class="language-plaintext highlighter-rouge">date</code>, <code class="language-plaintext highlighter-rouge">category</code>, <code class="language-plaintext highlighter-rouge">categories</code>, <code class="language-plaintext highlighter-rouge">tags</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
layout: post
title:  "New Testshare Post with Comments"
date:   2017-02-04 11:17:29 +0200
permalink: welcome/
share: false
comments: false
sitemap: true
image:
  facebook: img/facebook.png
  twitter: img/twitter.png
---
</code></pre></div></div>

<p>To use these values in Liquid tags you should refer <code class="language-plaintext highlighter-rouge">page</code> or <code class="language-plaintext highlighter-rouge">post</code> objects:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
<span class="nt">&lt;head&gt;</span>
  <span class="nt">&lt;title&gt;</span>{{ page.title }}<span class="nt">&lt;/title&gt;</span>
<span class="nt">&lt;/head&gt;</span>
...
</code></pre></div></div>

<p>You can set default values for your YAML Front Matter variables in <code class="language-plaintext highlighter-rouge">_config.yml</code> to avoid repeating of the same lines in all post files:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">defaults</span><span class="pi">:</span>
  <span class="pi">-</span> <span class="na">scope</span><span class="pi">:</span>
      <span class="na">path</span><span class="pi">:</span> <span class="s2">"</span><span class="s">"</span> <span class="c1"># all files within the project</span>
    <span class="na">values</span><span class="pi">:</span>
      <span class="na">image</span><span class="pi">:</span> 
        <span class="na">facebook</span><span class="pi">:</span> <span class="s">/assets/images/max-fb.png</span>
        <span class="na">twitter</span><span class="pi">:</span> <span class="s">/assets/images/max-twitter.png</span>
        <span class="na">width</span><span class="pi">:</span> <span class="m">200</span>
        <span class="na">height</span><span class="pi">:</span> <span class="m">200</span>
      <span class="na">share</span><span class="pi">:</span> <span class="no">true</span>
</code></pre></div></div>

<h2 id="liquid-tags-and-filters">Liquid Tags and Filters</h2>

<h4 id="variables">Variables</h4>

<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{%</span><span class="w"> </span><span class="nt">assign</span><span class="w"> </span><span class="nv">integer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">assign</span><span class="w"> </span><span class="nv">condition</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="p">%}</span>
<span class="p">{%</span><span class="w"> </span><span class="nt">assign</span><span class="w"> </span><span class="nv">string</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Hello World!!!"</span><span class="w"> </span><span class="p">%}</span>
</code></pre></div></div>

<h4 id="control-flow">Control Flow</h4>

<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{%</span><span class="w"> </span><span class="kr">if</span><span class="w"> </span><span class="nv">condition</span><span class="w"> </span><span class="p">%}</span>
  ...
<span class="p">{%</span><span class="w"> </span><span class="kr">elsif</span><span class="w"> </span><span class="nv">second_condition</span><span class="w"> </span><span class="p">%}</span>
  ...
<span class="p">{%</span><span class="w"> </span><span class="kr">else</span><span class="w"> </span><span class="p">%}</span>
  ...
<span class="p">{%</span><span class="w"> </span><span class="kr">endif</span><span class="w"> </span><span class="p">%}</span>
</code></pre></div></div>

<h4 id="iterations">Iterations</h4>

<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{%</span><span class="w"> </span><span class="nt">for</span><span class="w"> </span><span class="nv">slide</span><span class="w"> </span><span class="nt">in</span><span class="w"> </span><span class="nv">site.data.about-slides</span><span class="w"> </span><span class="p">%}</span>
  &lt;img src="<span class="p">{{</span><span class="w"> </span><span class="s2">"/img/"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">append</span><span class="p">:</span><span class="w"> </span><span class="nv">slide</span><span class="p">.</span><span class="nv">image</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">relative_url</span><span class="w"> </span><span class="p">}}</span>"&gt;
<span class="p">{%</span><span class="w"> </span><span class="nt">endfor</span><span class="w"> </span><span class="p">%}</span>
</code></pre></div></div>

<h4 id="includes">Includes</h4>

<p>The <code class="language-plaintext highlighter-rouge">include</code> tag allows you to include content from another file stored in the <code class="language-plaintext highlighter-rouge">_includes</code> folder. You can pass parameters to included piece of code from a parent file.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- post.html --&gt;</span>
...
{% include slideshow.html slides=site.data.about-slides max-width=500 %}
...

<span class="c">&lt;!-- slideshow.html --&gt;</span>
...
{% for slide in include.slides %}
  <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"{{ slide.image }}"</span> <span class="na">style=</span><span class="s">"max-width: {{ include.max-width }}px;"</span><span class="nt">&gt;</span>
{% endfor %}
...
</code></pre></div></div>

<h4 id="url-filters">URL Filters</h4>

<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{{</span><span class="w"> </span><span class="s2">"/assets/style.css"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">absolute_url</span><span class="w"> </span><span class="p">}}</span>
Output: http://127.0.0.1:4000/jekyll/assets/style.css

<span class="p">{{</span><span class="w"> </span><span class="s2">"/assets/style.css"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">relative_url</span><span class="w"> </span><span class="p">}}</span>
Output: /jekyll/assets/style.css

<span class="p">{{</span><span class="w"> </span><span class="s2">"Email info@liquid.com"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">cgi_escape</span><span class="w"> </span><span class="p">}}</span>
Output: Email+info%40liquid.com
</code></pre></div></div>

<h2 id="markdown-extra-image-with-caption">Markdown Extra Image with Caption</h2>

<p>By default Jekyll uses <em>kramdown</em> as a Markdown processor, which is enhanced with features that are found in other Markdown implementations like Maruku, PHP Markdown Extra and Pandoc. For instance, it supports attribute list definitions with the help of which you can add attributes to block and span-level elements.</p>

<p>Let’s say you have following styles:</p>

<div class="language-scss highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">.center</span> <span class="p">{</span>
  <span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.thumbnail</span> <span class="p">{</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="nv">$grey-color-light</span><span class="p">;</span>
  <span class="nl">border-radius</span><span class="p">:</span> <span class="m">4px</span><span class="p">;</span>
  <span class="nl">padding</span><span class="p">:</span> <span class="m">4px</span><span class="p">;</span>
  <span class="nl">margin</span><span class="p">:</span> <span class="m">5px</span> <span class="m">0px</span><span class="p">;</span>
<span class="p">}</span>

<span class="nc">.caption</span> <span class="p">{</span>
  <span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span>
  <span class="nl">font-style</span><span class="p">:</span> <span class="nb">normal</span><span class="p">;</span>
  <span class="nl">font-size</span><span class="p">:</span> <span class="nv">$small-font-size</span><span class="p">;</span>
  <span class="nl">color</span><span class="p">:</span> <span class="nv">$grey-color</span><span class="p">;</span>
  <span class="nl">line-height</span><span class="p">:</span> <span class="m">1</span><span class="mi">.4</span><span class="p">;</span>
  <span class="nl">margin</span><span class="p">:</span> <span class="nb">auto</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>You can use them to insert image with caption using next Markdown Extra text:</p>

<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code>![Surprised ALF](<span class="p">{{</span><span class="w"> </span><span class="s2">"/assets/images/surprised-alf.gif"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nf">relative_url</span><span class="w"> </span><span class="p">}}</span> "Oops!"){:.thumbnail}
*I guess we'll have to order in*{:.caption}
{:.center}
</code></pre></div></div>

<p class="center"><img src="/assets/images/surprised-alf.gif" alt="Surprised ALF" title="Oops!" class="thumbnail" />
<em class="caption">I guess we’ll have to order in</em></p>

<p>Note that you mustn’t have an empty line between the image and the caption. Also, attribute lists should immediately follow their blocks or elements.</p>

<h2 id="jekyll-plugins">Jekyll Plugins</h2>

<ul>
  <li><em><a href="https://github.com/jekyll/jekyll-feed">jekyll-feed</a></em> - generates an Atom feed of your posts</li>
  <li><em><a href="https://github.com/jekyll/jekyll-sitemap">jekyll-sitemap</a></em> - generates a sitemaps.org compliant sitemap for your Jekyll site</li>
  <li><em><a href="https://jekyllrb.com/docs/pagination/">jekyll-paginate</a></em> - enables pagination for your blog</li>
  <li><em><a href="https://github.com/jekyll/jekyll-seo-tag">jekyll-seo-tag</a></em> - adds metadata tags for search engines and social networks to better index and display your site’s content</li>
  <li><em><a href="https://github.com/octopress/minify-html">octopress-minify-html</a></em> - minifies Jekyll’s HTML output by removing whitespace junk with <a href="https://github.com/stereobooster/html_press">HtmlPress</a></li>
</ul>

<h2 id="useful-links">Useful Links</h2>

<ul>
  <li><a href="https://jekyllrb.com/docs/structure/">Jekyll Directory Structure</a></li>
  <li><a href="http://shopify.github.io/liquid/basics/introduction/">Liquid Documentation</a></li>
  <li><a href="https://kramdown.gettalong.org/syntax.html">kramdown Syntax</a></li>
  <li><a href="http://jekyll.tips/jekyll-casts/seo-in-jekyll/">SEO in Jekyll</a></li>
  <li><a href="https://www.google.com/webmasters/tools/mobile-friendly/">Mobile-Friendly Test</a></li>
</ul>]]></content><author><name>Max Odnovolyk</name></author><summary type="html"><![CDATA[List of useful and frequently used Jekyll commands, settings, plugins and code snippets to kickstart your blog.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://maxodnovolyk.com/%7B%22facebook%22=%3E%22/assets/images/max-odnovolyk-fb-wide.png%22,%20%22twitter%22=%3E%22/assets/images/max-odnovolyk-twitter.png%22%7D" /><media:content medium="image" url="https://maxodnovolyk.com/%7B%22facebook%22=%3E%22/assets/images/max-odnovolyk-fb-wide.png%22,%20%22twitter%22=%3E%22/assets/images/max-odnovolyk-twitter.png%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">git init</title><link href="https://maxodnovolyk.com/about/" rel="alternate" type="text/html" title="git init" /><published>2017-01-16T11:00:00+02:00</published><updated>2017-01-16T11:00:00+02:00</updated><id>https://maxodnovolyk.com/about</id><content type="html" xml:base="https://maxodnovolyk.com/about/"><![CDATA[<p>Hi there! My name is Max Odnovolyk, and I am a Software Engineer, as you probably already know. At present, I am focused on designing and developing iOS and macOS applications, mainly in Swift. My interests include software architecture, design patterns, best coding practices, IoT, drones, and everything related to aviation. As a traveler and a recreational athlete, I strongly believe in Mobile’s future. That is why I have been in the loop since 2009 and am not going to leave it.
<!-- more --></p>

<p>
  <div class="slideshow">
    <div class="controls">
      <a class="prev fa fa-angle-left" onclick="prevSlide(event);" title="Previous photo"></a>
      <span class="slide-number">1/4</span>
      <a class="next fa fa-angle-right" onclick="nextSlide(event);" title="Next photo"></a>
    </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/about/max-montmartre.jpg" alt="Max - software engineer" title="Max Odnovolyk" onclick="nextSlide(event);" style="max-width: 500px; width: 100%;" />
        
          <div class="caption" style="max-width: 500px;">Everyday Max - software engineer - designs and develops iOS and macOS applications in Swift and Objective-C
</div>
        
      </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/about/max-with-folding-quad.jpg" alt="Flying folding quadcopter" title="Flying Quadcopter" onclick="nextSlide(event);" style="max-width: 500px; width: 100%;" />
        
          <div class="caption" style="max-width: 500px;">On weekends - UAV designer and pilot - draws, builds, tests unmanned aerial vehicles (drones)
</div>
        
      </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/about/max-indian-himalayas.jpg" alt="Riding Indian Himalayas on bike" title="Indian Himalayas" onclick="nextSlide(event);" style="max-width: 500px; width: 100%;" />
        
          <div class="caption" style="max-width: 500px;">During vacation, you can see me riding my bicycle somewhere in distant places like the Indian Himalayas
</div>
        
      </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/about/max-skiing.jpg" alt="Late spring skiing" title="Late Spring Skiing" onclick="nextSlide(event);" style="max-width: 500px; width: 100%;" />
        
          <div class="caption" style="max-width: 500px;">Or closing ski season in May. I prefer backcountry skiing in remote serene sites like Gulmarg with lots of steep and deep.
</div>
        
      </div>
    
      <div class="slide center">
        

        <img class="thumbnail" src="/img/about/max-yak52.jpg" alt="Flying aerobatic Yak-52" title="Flying Yak-52" onclick="nextSlide(event);" style="max-width: 500px; width: 100%;" />
        
          <div class="caption" style="max-width: 500px;">And sometimes, I even train to pilot a real Yak-52. Who didn't dream of being an astronaut or at least an aircraft pilot?</div>
        
      </div>
    
  </div>
</p>

<p>But first things first. My IT journey started in 1999, when I was 10, from an ancient IBM 386 with 2MB of RAM and fake<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> green Turbo button, DOS and QuickBASIC IDE. A few years later, I was lucky enough to get subscribed to Xakep magazine (‘Hacker‘ in russian spelling), which positioned itself as a “computer hooligans journal“. Kris Kaspersky’s articles, together with <code class="language-plaintext highlighter-rouge">wasm.ru</code>, left a lasting impression on me. I still remember the feeling I experienced when my custom-modified Phoenix BIOS started successfully for the first time after two previous motherboards’ incapacitation. Those were really exciting and carefree times, which have defined my future place in IT.</p>

<p>In 2006, I entered the National Bohdan Khmelnytsky University of Cherkasy, Ukraine, at the Faculty of Information Technologies and Biomedical Cybernetics. During my second year of studying, I got my first part-time job as a Flash/AS Developer. Four years later, I received a bachelor’s degree in Computer Software Engineering.</p>

<p>In early 2009, I went through Hackintosh hell on my cheap Intel Celeron without SSE3, which proved my sense of purpose and allowed me to develop and release my first iPhone OS Application in the fall of 2009. Since then, I have completely moved to native iOS development and become inseparable from the Apple ecosystem. It has captivated me with its attention to detail, environment predictability, consistency, and ability to reach millions of App Store users.</p>

<p>Since 2010, I have participated in numerous mobile projects as an iOS engineer, mobile team lead, and architect. My web and networking background allows me to be a key contributor in complex client-server architectures that require offline-first experience, local and remote database synchronization, and variable conflict resolution mechanisms. I led several long-term mobile projects (3+ years) with a significant user base.</p>

<p>I spend my free time doing different sports and learning something new. I like to go backcountry skiing in winter and prefer MTB, trekking, and running during the warm part of the year. In 2016, I ran my first half marathon and plan to do the full distance next year. Over the past ten years, I have visited about 20 countries. Two years ago, I started experimenting with unmanned aerial vehicles (drones).</p>

<p>Why am I telling you all this stuff? I believe that magic happens at the crossroads of disciplines. That is why I am continuously looking for opportunities that will involve not only my professional skills but also some of my personal interests. I am still in search.</p>

<p>So now you have a better picture of me, and if you want to contact me,  email <code class="language-plaintext highlighter-rouge">modnovolyk</code> at Gmail or use the links in the top-right corner of this page.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>In fact, that button did CPU slowdown for software compatibility reasons instead of boosting, as you may guess from its name. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Max Odnovolyk</name></author><summary type="html"><![CDATA[Max Odnovolyk is a Software Engineer mainly focused on Apple iOS and macOS platforms. As an electrical engineering enthusiast interested in UAVs, IoT, and robotics. Traveler, recreational athlete.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://maxodnovolyk.com/%7B%22facebook%22=%3E%22/assets/images/max-odnovolyk-fb-wide.png%22,%20%22twitter%22=%3E%22/assets/images/max-odnovolyk-twitter.png%22%7D" /><media:content medium="image" url="https://maxodnovolyk.com/%7B%22facebook%22=%3E%22/assets/images/max-odnovolyk-fb-wide.png%22,%20%22twitter%22=%3E%22/assets/images/max-odnovolyk-twitter.png%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>