Monday, February 17, 2020

Install StudioTax 2019 on Ubuntu 18.04


Step 1: install Wine

sudo apt install wine-stable

sudo apt install winetricks

sudo apt install winbind


Step 2: install .Net4.5.2 which is required by StudioTax

env WINEPREFIX=$HOME/WineStudioTax wineboot --init

env WINEPREFIX=$HOME/WineStudioTax winetricks dotnet452 corefonts


Step 3: install IE7 (Although it is not in the requirements of StudioTax, if IE is not installed, notes spit out by StudioTax won't show on some popup dialogues.)

env WINEPREFIX=$HOME/WineStudioTax winetricks ie7


Step 4: install StudioTax 2019
-- Download StudioTax2019Install.exe
-- Check its md5sum

env WINEPREFIX=$HOME/WineStudioTax wine StudioTax2019Install.exe /extract

env WINEPREFIX=$HOME/WineStudioTax winetricks settings win7

env WINEPREFIX=$HOME/WineStudioTax wine msiexec /i StudioTax.msi


Step 5: For the autofill feature, we need to install a Windows version Firefox to do the authentication with CRA.

Download Firefox 49.0.2 Win32 version. Then run command:

env WINEPREFIX=$HOME/WineStudioTax wine 'Firefox Setup 49.0.2.exe'

Set up Firefox as default to open URL. Run:
env WINEPREFIX=$HOME/WineStudioTax wine regedit


Change in Regedit:

    HKEY_CLASSES_ROOT -> http -> shell -> open
        Create/Edit command key to:
            "C:\Program Files\Mozilla Firefox\firefox.exe" "%1"

    (Repeat for https:)
    HKEY_CLASSES_ROOT -> https -> shell -> open
        Create/Edit command key to:
            "C:\Program Files\Mozilla Firefox\firefox.exe" "%1"

Save/close regedit



References:
1. Install .NET with Wine: https://appdb.winehq.org/objectManager.php?sClass=version&iId=25478&iTestingId=104233

2. Install StudioTax with Wine: https://appdb.winehq.org/objectManager.php?sClass=version&iId=37634

3.  Installing StudioTax 2017 on Wine: http://pnijjar.freeshell.org/2018/studiotax/

Wednesday, January 29, 2020

Powershell Script: Write to a file


1. Append a string to the end of a file

Add-Content -Path .\theFile -Value "the string to be appended"


2. Append file_a to the end of file_b

Get-Content -Path .\file_a | Add-Content -Path .\file_b


3. Create a new file with a sting as the content

"the string to be put into the file" | Out-File -FilePath .\theFile


Tuesday, January 28, 2020

Powershell Script: Read input with default value


$defaultVal = 'No'

$inputVal = Read-Host -Prompt "Input something? [$defaultVal]"

if ($inputVal -eq '')
{
  $inputVal = $defaultVal
}


Monday, January 27, 2020

Speakout and Android Oreo


When inserting the Speakout SIM into an Android Oreo phone, the APN settings are pushed from the Rogers Network as "ltemobile.apn".

As Speakout does not support LTE, that APN setting does not work. And APN settings are locked for Speakout SIM. The "Add APN" button is not there and the only available APN is grayed out that we cannot change it.

The workaround is to use an unrestricted SIM to generate an APN profile.

Steps:

1. With Speakout SIM in, change the Network Operator to "Speakout 3G" (Settings / Network&Internet / Mobile network / Network operators) (However, I am not sure if this step is necessary. But in my case, it didn't work when on Speakout 4G.)

2. Power off the phone. Remove Speakout SIM.

3. Insert an unlocked/unrestricted SIM, e.g. Roam Mobility. Power on.

4. Go to APN settings (Settings / Network&Internet / Mobile network / Access point names). Now we can add a new APN.

5. Tap the "+" icon on the top right. Add an new profile with this values:
      APN: speakout
      APN: rogers-core-appl1.apn
      APN type: default,supl
      APN Protocol: IPv4/IPv6
      APN Roaming Protocol: IPV4
      MVNO type: None

    Don't touch the MCC and MNC fields which are set as the US codes.

6. Tap the Save button to save it. Check that speakout is generated.

7. Power off the phone. Remove Roam Mobility SIM.

8. Insert Speakout SIM. Power on.

9. Go to APN settings. Tap to select the newly created "speakout" profile. If you look into it, you can find that MCC and MNC are automatically updated to what Speakout uses:
      MCC: 302
      MNC: 720
      MVNO type: GID
      MVNO value: D4

10. Switch back the Network Operator to "Speakout 4G" (refer to step 1).

11. Reboot if necessary.


Tuesday, December 31, 2019

C# programming: Debug and trace


To generate a trace, use

System.Diagnostics.Trace.WriteLine("some trace");

This code works when TRACE is turned on during compiling. Add the compile option in web.config:

<compilation defaultLanguage="c#" debug="true" targetFramework="4.5">
  <compilers>
    <compiler language="c#" ... compilerOptions="/d:DEBUG;TRACE" />
  </compilers>
</compilation>

During the development, the trace can be found in the Visual Studio's console. If the application is deployed, the trace can be seen with the tool Debugview, which can be downloaded from:

https://docs.microsoft.com/en-us/sysinternals/downloads/debugview


Monday, December 30, 2019

OWASP Top Ten 2017 Examples and Fixes | C# Programming


1. Injection

The problem: SQL Injection

string sql = @"SELECT *  FROM Memos WHERE Id = " + idString;
using (OleDbConnection cnn = new OleDbConnection(connectionString))
{
  cnn.Open();
  OleDbCommand cmd = new OleDbCommand(sql, cnn);
  OleDbDataReader reader = cmd.ExecuteReader();

  while (read.Read())
  {
    ...
  }
}

If idString comes from the user input, it can be manipulated to create unexpected SQL commands.

The fix is to use prepared statement:

string sql = @"SELECT *  FROM Memos WHERE Id = ?";
using (OleDbConnection cnn = new OleDbConnection(connectionString))
{
  cnn.Open();
  OleDbCommand cmd = new OleDbCommand(sql, cnn);

  cmd.Parameters.AddWithValue("@Id", idString);
 
  OleDbDataReader reader = cmd.ExecuteReader();

  while (read.Read())
  {
    ...
  }
}



2. Broken Authentication

The problem: Session is kept after logout

public ActionResult LogOut()
{
  return RedirectToAction("LogOn");
}

The fix is to remove the user session from DB and server side:

public ActionResult LogOut()
{
  string userName = Session["UserName"].ToString();
  db.RemoveUserSession(userName);
  Session.Abandon();
  return RedirectToAction("LogOn");
}


3. Sensitive Data Exposure

The problem: Store password in plain text

var user = new User()
{
  Email = email,
  Login = login,
  Password = password,
  Name = name,
  Role = role
};

The fix is to store the hash so that the password won't be stolen from the memory:

var user = new User()
{
  Email = email,
  Login = login,
  Password = Argon2.Hash(password),
  Name = name,
  Role = role
};


4. XML External Entities (XXE)

var resolver = new XmlUrlResolver();

var settings = new XmlReaderSettings
{
  DtdProcessing = DtdProcessing.Parse,
  XmlResolver = resolver
};

XmlReader reader = XmlReader.Create("items.xml", settings);

The fix:

var resolver = new XmlUrlResolver();

var settings = new XmlReaderSettings
{
  DtdProcessing = DtdProcessing.Prohibit,
  XmlResolver = null
};

XmlReader reader = XmlReader.Create("items.xml", settings);


5. Broken Access Control

The problem: Unvalidated Redirects and Forwards

private ActionResult RedirectToLocal(string retureUrl)
{
  if (!string.IsNullOrEmpty(returnUrl))
  {
    return Redirect(returnUrl);
  }
  return RedirectToAction("Index");
}

The fix is to validate the URL first before redirect:

private ActionResult RedirectToLocal(string retureUrl)
{
  if (Url.IsLocalUrl(returnUrl))
  {
    return Redirect(returnUrl);
  }
  return RedirectToAction("Index");
}


6. Security Misconfiguration

The problem: Information Exposure of Error Details

Logger.LogError(ex.Message + ex.StackTrace);

The fix is to avoid logging stack trace unless it is in debugging:

if (Debugger.IsAttached)
  Logger.LogDebug(ex.Message + ex.StackTrace);

Logger.LogError(ex.Message);


7. Cross Site Scripting (XSS)

userModel.Information = reader["Information"].ToString();

The fix:

string information = reader["Information"].ToString();
string encodedInfo = AntiXssEncoder.HtmlEncode(information, false);
userModel.Information = encodedInfo.ToString();


8. Insecure Deserialization

using (var filestream = File.Open(filename, FileMode.Open))
{
  return DeserializeObject<T>(filestream, settings);
}

The fix is to use encryption/decryption during serialization/deserialization:

using (var filestream = File.Open(filename, FileMode.Open))
{
  using (var cs = new CryptoStream(filestream,
                        CreateRijndael(password).CreateDecryptor(),
                        CryptoStreamMode.Read))
  {
    return DeserializeObject<T>(cs, settings);
  }
}

private static Rijndael CreateRijndael(string password)
{
  var rijndael = Rijndael.Create();
  var pdb = new Rfc2898DeriveBytes(password, Pepper, 1000000);
  rijndael.Key = pdb.GetBytes(32);
  rijndael.IV = pdb.GetBytes(16);
  return rijndael;
}


9. Using Components with Known Vulnerabilities

Linking a file from an untrusted website:

<link href="http://a.company.com/some.styles.css" rel="stylesheet" />

The fix:

 <link href="https://a.trustworthy.website.com/some.styles.css"
       rel="stylesheet" 
       integrity="sha256-......." 
       crossorigin="anonymous" />









10. Insufficient Logging and Monitoring

Console.WriteLine(ex.Message);

The fix:

Logger.LogError(ex.Message);



Friday, November 22, 2019

Oracle: create index for column that allows NULL



CREATE INDEX table1_nullable_col1_idx
       ON table1 (nullable_col1, 1);

The ", 1" makes Oracle add into the index the record whose nullable_col1 field has a NULL value.


Thursday, November 21, 2019

Oracle: update one table with joined condition from another table


UPDATE table1 
       SET t1_col1 = 'something'
       WHERE id IN (SELECT t1.id FROM table1 t1, table2 t2
                                 WHERE t1.id = t2.id
                                 AND t2.t2_col1 = 'some condition');

Monday, November 11, 2019

Adding a CA to the trust store for Eclipse


If a Eclipse plugin uses a self-signed updating web site, you may encounter the authentication failure error when updating the plugin.

The solution is to add the CA of the self-signed certificate to the trust store that Eclipse uses.

By default, Eclipse uses the Java trust store at $JAVA_HOME/lib/security/cacerts.

To list the certificates in it, go to $JAVA_HOME/lib/security/ and run command:
$ $JAVA_HOME/bin/keytool -list -keystore ./cacerts

You may not have the permission to add a new certificate into the default trust store. We can make a copy of the default trust store and add the new certificate in the new copy.
$ cd /path/to/my/trust/store/location
$ cp $JAVA_HOME/lib/security/cacerts mytruststore

The password of Java's default cacerts is "changeit". You will need to input it when adding a new certificate into mytruststore.

Run the following command to import the new certificate (e.g. cloudServicesRootCA.cer, this post shows how to download the certificate of a CA) into mytruststore:
$ $JAVA_HOME/bin/keytool -alias cloudServicesRootCA -import -file cloudServicesRootCA.cer -keystore mytruststore

Exit Eclipse if you are running it and let Eclipse know the new trust store by adding it to Eclipse's configuration file eclipse.ini which locates in the root directory of the Eclipse installation. Use an editor to open eclipse.ini and add/modify these two parameters:
-Djavax.net.ssl.trustStore=/path/to/my/trust/store/location/mytruststore
-Djavax.net.ssl.trustStorePassword=changeit

Friday, November 8, 2019

Windows 10: use MMC (Microsoft Management Console) to add a trusted CA


1. Right click on the Windows icon. Select menu Run.

2. Input command: mmc

3. In MMC, click on menu File->Add/Remove Snap-in...

4. Select Certificates in the snap-ins list; Click on the Add button. "Certificates - Current User" will be added in the "Selected snap-ins" list. Click on the OK button.

5. In the left panel, expand "Certificates - Current User"; Right click on "Trusted Root Certification Authorities"; Select "All Tasks->Import...".

6. Use the Import Wizard to browse and select the certificate to import.

Note: Only add the CA if you absolutely trust it.


 
Get This <