Tuesday, June 14, 2016

Set the maximum number of connections on a per user basis

Set the maximum number of connections on a per user basis:





Monday, June 13, 2016

To allow the machines behind NAT accessing the public WAN IP address of the router (port forwarding to a internal web server)

Potential DNS Rebind attack detected, see http://en.wikipedia.org/wiki/DNS_rebinding

Try accessing the router by IP address instead of by hostname.

To allow the machines behind NAT accessing the public WAN IP address of the router (port forwarding to a internal web server)

Method 1 - On pfSense:
System > Advanced > Firewall / NAT:
- NAT Reflection mode for port forwards: Enable (Pure NAT) or try (NAT + Proxy) if it did not work.
- click on "Save" button.

Method 2 - On pfSense:
Firewall > NAT > Port Forward > Edit Rule >:

NAT reflection: Enable (Pure NAT) or try (NAT + Proxy) if it did not work.

Method 3 - On pfSense:
Firewall > NAT > NAT: 1:1

External IP:
Internal IP:

Description: VC to gatekeeper (DMZ)


Method 4 - On pfSense:

Under System->Advanced->Firewall and NAT there is an option "Automatically create outbound NAT rules which assist inbound NAT rules that direct traffic back out to the same subnet it originated from."

Method 5 - On pfSense:

I found it is better to use Services->DNS Resolver->General Settings and check Register DHCP leases in the DNS Resolver and Register DHCP static mappings in the DNS Resolver then add the server to the Host Overrides.






How to check the external IP address on Linux

# curl -s checkip.dyndns.org | sed -e 's/.*Current IP Address: //' -e 's/<.*$//'

or shorter

# wget http://ipinfo.io/ip -qO



Thursday, June 9, 2016

penetration test 滲透測試

penetration test 滲透測試

Wednesday, June 8, 2016

trafshow - network monitoring tool

trafshow - network monitoring tool

Friday, June 3, 2016

Error during SSL Handshake with remote server

Error during SSL Handshake with remote server

The comment by MK pointed me in the right direction.

In the case of Apache 2.4 and up, there are different defaults and a new directive.

I am running Apache 2.4.6, and I had to add the following directives to get it working:

SSLProxyEngine on
SSLProxyVerify none 
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off




Thursday, June 2, 2016

Custom URL protocol - Registering the Application Handling the Custom URI Scheme

Custom URL protocol - Registering the Application Handling the Custom URI Scheme

Here's how it works:

1. User clicks "Print" on the website.

2. Website links user to "CustomURL://Print/{ID}

3. Application is launched by windows via the custom uri scheme.

4. Application communicates with the pre-configured server to confirm the print request and in my case get the actual print command.

5. The application then uses the C# RawPrinterHelper class to send commands directly to the printer.

To handle the alert scheme:

<a href="alert:test1 test2">test</a>


      (Default) = "URL:Alert Protocol"
      URL Protocol = ""
         (Default) = "alert.exe,1"
               (Default) = "C:\Program Files\Alert\alert.exe" "%1"

Alert.reg example:

Windows Registry Editor Version 5.00

"URL Protocol"="\"\""
@="\"URL:Alert Protocol\""




@="\"C:\\Program Files\\Alert\\alert.exe\" \"%1\""


using System;
using System.Collections.Generic;
using System.Text;

namespace Alert
  class Program
    static string ProcessInput(string s)
       // TODO Verify and validate the input 
       // string as appropriate for your application.
       return s;

    static void Main(string[] args)
      Console.WriteLine("Alert.exe invoked with the following parameters.\r\n");
      Console.WriteLine("Raw command-line: \n\t" + Environment.CommandLine);

      foreach (string s in args)
        Console.WriteLine("\t" + ProcessInput(s));
      Console.WriteLine("\nPress any key to continue...");


cmd> "C:\Program Files\Alert\alert.exe" "alert:Hello World"

To reset the external protocol handler setting in Chrome:

Edit "Local State" this file:

C:\Users\Username\AppData\Local\Google\Chrome\User Data\Local State


%USERPROFILE%\AppData\Local\Google\Chrome\User Data\

Search for: protocol_handler

Security Issues

As noted above, the string that is passed to a pluggable protocol handler might be broken across multiple parameters. Malicious parties could use additional quote or backslash characters to pass additional command line parameters. For this reason, pluggable protocol handlers should assume that any parameters on the command line could come from malicious parties, and carefully validate them. Applications that could initiate dangerous actions based on external data must first confirm those actions with the user. In addition, handling applications should be tested with URIs that are overly long or contain unexpected (or undesirable) character sequences.
For more information, please see Writing Secure Code.





To get the default printer in C#

The easiest way I found is to create a new PrinterSettings object. It starts with all default values, so you can check its Name property to get the name of the default printer.

PrinterSettings is in System.Drawing.dll in the namespace System.Drawing.Printing.

PrinterSettings settings = new PrinterSettings();



To reset the external protocol handler setting in Chrome

To reset the external protocol handler setting in Chrome:

Edit "Local State" this file:

C:\Users\Username\AppData\Local\Google\Chrome\User Data\Local State


%USERPROFILE%\AppData\Local\Google\Chrome\User Data\

Search for: protocol_handler



Hide Console Window in C# Console Application

Solution 1:

Change the output type from Console Application to Windows Application. This can be done under Project -> Properties -> Application in Visual Studio

Solution 2:

If you are using the ProcessStartInfo class you can set the window style to hidden:

System.Diagnostics.ProcessStartInfo start =
      new System.Diagnostics.ProcessStartInfo();     
start.FileName = dir + @"\Myprocesstostart.exe";
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

Solution 3:

If you are using Process Class then you can write:

yourprocess.StartInfo.UseShellExecute = false;
yourprocess.StartInfo.CreateNoWindow = true;

before yourprocess.start(); and process will be hidden.



How to create an HTML button that acts like a link?

    // PrintBtn
    $('#PrintBtn').on('click', function(event){

      window.location.href = 'customprotocol:Hello World';

.NET code to send ZPL to Zebra printers

.NET code to send ZPL to Zebra printers

This way you will be able to send ZPL to a printer no matter how it is connected (LPT, USB, Network Share...)

Create the RawPrinterHelper class (from the Microsoft article on How to send raw data to a printer by using Visual C# .NET):

using System;
using System.IO;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public class RawPrinterHelper
    // Structure and API declarions:
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public class DOCINFOA
        [MarshalAs(UnmanagedType.LPStr)] public string pDocName;
        [MarshalAs(UnmanagedType.LPStr)] public string pOutputFile;
        [MarshalAs(UnmanagedType.LPStr)] public string pDataType;
    [DllImport("winspool.Drv", EntryPoint="OpenPrinterA", SetLastError=true, CharSet=CharSet.Ansi, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
    public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

    [DllImport("winspool.Drv", EntryPoint="ClosePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
    public static extern bool ClosePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint="StartDocPrinterA", SetLastError=true, CharSet=CharSet.Ansi, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
    public static extern bool StartDocPrinter( IntPtr hPrinter, Int32 level,  [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);

    [DllImport("winspool.Drv", EntryPoint="EndDocPrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
    public static extern bool EndDocPrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint="StartPagePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
    public static extern bool StartPagePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint="EndPagePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
    public static extern bool EndPagePrinter(IntPtr hPrinter);

    [DllImport("winspool.Drv", EntryPoint="WritePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
    public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten );

    // SendBytesToPrinter()
    // When the function is given a printer name and an unmanaged array
    // of bytes, the function sends those bytes to the print queue.
    // Returns true on success, false on failure.
    public static bool SendBytesToPrinter( string szPrinterName, IntPtr pBytes, Int32 dwCount)
        Int32    dwError = 0, dwWritten = 0;
        IntPtr    hPrinter = new IntPtr(0);
        DOCINFOA    di = new DOCINFOA();
        bool    bSuccess = false; // Assume failure unless you specifically succeed.

        di.pDocName = "My C#.NET RAW Document";
        di.pDataType = "RAW";

        // Open the printer.
        if( OpenPrinter( szPrinterName.Normalize(), out hPrinter, IntPtr.Zero ) )
            // Start a document.
            if( StartDocPrinter(hPrinter, 1, di) )
                // Start a page.
                if( StartPagePrinter(hPrinter) )
                    // Write your bytes.
                    bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
        // If you did not succeed, GetLastError may give more information
        // about why not.
        if( bSuccess == false )
                dwError = Marshal.GetLastWin32Error();
        return bSuccess;

    public static bool SendFileToPrinter( string szPrinterName, string szFileName )
        // Open the file.
        FileStream fs = new FileStream(szFileName, FileMode.Open);
        // Create a BinaryReader on the file.
        BinaryReader br = new BinaryReader(fs);
        // Dim an array of bytes big enough to hold the file's contents.
        Byte []bytes = new Byte[fs.Length];
        bool bSuccess = false;
        // Your unmanaged pointer.
        IntPtr pUnmanagedBytes = new IntPtr(0);
        int nLength;

        nLength = Convert.ToInt32(fs.Length);
        // Read the contents of the file into the array.
        bytes = br.ReadBytes( nLength );
        // Allocate some unmanaged memory for those bytes.
        pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
        // Copy the managed byte array into the unmanaged array.
        Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
        // Send the unmanaged bytes to the printer.
        bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
        // Free the unmanaged memory that you allocated earlier.
        return bSuccess;
    public static bool SendStringToPrinter( string szPrinterName, string szString )
        IntPtr pBytes;
        Int32 dwCount;
        // How many characters are in the string?
        dwCount = szString.Length;
        // Assume that the printer is expecting ANSI text, and then convert
        // the string to ANSI text.
        pBytes = Marshal.StringToCoTaskMemAnsi(szString);
        // Send the converted ANSI string to the printer.
        SendBytesToPrinter(szPrinterName, pBytes, dwCount);
        return true;

Call the print method:

using System.Windows.Forms;
using System.Drawing.Printing;

private void button2_Click(object sender, System.EventArgs e)
    string s = "^XA^LH30,30\n^FO20,10^ADN,90,50^AD^FDHello World^FS\n^XZ";

    // Print directly wiht the default printer.
    PrinterSettings printerSetting = new PrinterSettings();
    RawPrinterHelper.SendStringToPrinter(printerSetting.PrinterName, s);

    // Allow the user to select a printer.
    PrintDialog pd  = new PrintDialog();
    pd.PrinterSettings = new PrinterSettings();

    if( DialogResult.OK == pd.ShowDialog(this) )
        // Send a printer-specific to the printer.
        RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, s);

There are 2 gotchas I've come across that happen when you're sending txt files with ZPL codes to the printer:

1. The file has to end with a new line character.

2. Encoding has to be set to Encoding.Default when reading ANSI txt files with special characters.

public static bool SendTextFileToPrinter(string szFileName, string printerName)
    var sb = new StringBuilder();

    using (var sr = new StreamReader(szFileName, Encoding.Default)) // Set the correct encoding
        while (!sr.EndOfStream)
            sb.AppendLine(sr.ReadLine()); // This will automatically fix the last line

    return RawPrinterHelper.SendStringToPrinter(printerName, sb.ToString());


I've managed a project that does this with sockets for years. Zebra's typically use port 6101. I'll look through the code and post what I can.

public void SendData(string zpl)
    NetworkStream ns = null;
    Socket socket = null;

        if (printerIP == null)
            /* IP is a string property for the printer's IP address. */
            /* 6101 is the common port of all our Zebra printers. */
            printerIP = new IPEndPoint(IPAddress.Parse(IP), 6101);  

        socket = new Socket(AddressFamily.InterNetwork,

        ns = new NetworkStream(socket);

        byte[] toSend = Encoding.ASCII.GetBytes(zpl);
        ns.Write(toSend, 0, toSend.Length);
        if (ns != null)

        if (socket != null && socket.Connected)

Note: Zebra Mobile printers use port 6101 (QL, RW, MZ, etc). Larger printers usually use port 9100.


SharpZebra - A C# library that simplifies printing to Zebra printers in their native EPL2/ZPL languages without needing to know EPL2 or ZPL.


Here is how to do it using TCP IP protocol:

// Printer IP Address and communication port
    string ipAddress = "";
   int port = 9100;

// ZPL Command(s)
   string ZPLString =
    "^XA" +
    "^FO50,50" +
    "^A0N50,50" +
    "^FDHello, World!^FS" +

    // Open connection
    System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
    client.Connect(ipAddress, port);

    // Write ZPL String to connection
    System.IO.StreamWriter writer =
    new System.IO.StreamWriter(client.GetStream());

    // Close Connection
catch (Exception ex)
    // Catch Exception





Write an asynchronous web server in .NET in few lines

Write an asynchronous web server in .NET in few lines

/// <summary>
/// A simple program to show off an OWIN self-hosted web app.
/// </summary>
public class Program
    /// <summary>
    /// The entry point for the console application.
    /// </summary>
    /// <param name="args">The arguments to the execution of the console application. Ignored.</param>
    static void Main(string[] args)
        // Start OWIN host
        using (WebApp.Start<Startup>(url: "http://localhost:8000"))
            // Runs until a key is pressed
    /// <summary>
    /// This code configures the OWIN web app. The Startup class is specified as a type parameter in the WebApp.Start method.
    /// </summary>
    private class Startup
        /// <summary>
        /// Configures the web app.
        /// </summary>
        /// <param name="app">The app builder.</param>
        public void Configuration( IAppBuilder app )
            // We ignore any rules here and just return the same response for any request
            app.Run( context =>
                context.Response.ContentType = "text/plain";
                return context.Response.WriteAsync( "Hello World\n" );
            } );



WebRTC in the real world: STUN, TURN and signaling

WebRTC enables peer to peer communication.


WebRTC still needs servers:

For clients to exchange metadata to coordinate communication: this is called signaling.
To cope with network address translators (NATs) and firewalls.
In this article we show you how to build a signaling service, and how to deal with the quirks of real-world connectivity by using STUN and TURN servers. We also explain how WebRTC apps can handle multi-party calls and interact with services such as VoIP and PSTN (aka telephones).

If you're not familiar with the basics of WebRTC, we strongly recommend you take a look at Getting Started With WebRTC before reading this article.

What is signaling?

Signaling is the process of coordinating communication. In order for a WebRTC application to set up a 'call', its clients need to exchange information:

Session control messages used to open or close communication.
Error messages.
Media metadata such as codecs and codec settings, bandwidth and media types.
Key data, used to establish secure connections.
Network data, such as a host's IP address and port as seen by the outside world.
This signaling process needs a way for clients to pass messages back and forth. That mechanism is not implemented by the WebRTC APIs: you need to build it yourself. We describe below some ways to build a signaling service. First, however, a little context...



Wednesday, June 1, 2016

Setting golang secure WebSocket server behind Apache 2.4

Setting golang secure WebSocket server behind Apache 2.4

Make sure the system has mod_proxy_wstunnel:

# find /usr/lib64/httpd/modules/ | grep ws


Add the following line in 00-proxy.conf:

# vim /etc/httpd/conf.modules.d/00-proxy.conf

LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

Restart Apache:

# systemctl restart httpd

Check the setting:

# httpd -M | grep -iE 'proxy'

 proxy_module (shared)
 proxy_fcgi_module (shared)
 proxy_http_module (shared)
 proxy_wstunnel_module (shared)

Edit httpd-vhosts.conf:

# vim /etc/httpd/conf.d/httpd-vhosts.conf

<VirtualHost *:443>
    ServerName go.mydomain.com:443

    ProxyPreserveHost On
    ProxyRequests off

    SSLProxyEngine On
    SSLCertificateFile "/etc/pki/tls/certs/mydomain.com/mydomain.crt"
    SSLCertificateKeyFile "/etc/pki/tls/certs/mydomain.com/mydomain.key"

    ### The configured ProxyPass and ProxyPassMatch rules are checked
    ### in the order of configuration. The first rule that matches wins.
    ProxyPassMatch ^/(ws(/.*)?)$ wss://$1

    ProxyPass /
    ProxyPassReverse /

    ErrorLog "/var/log/httpd/go.mydomain.com-error_log"
    CustomLog "/var/log/httpd/go.mydomain.com-access_log" common

<VirtualHost *:80>
    ServerName go.mydomain.com:80

    ProxyPreserveHost On
    ProxyRequests off

    ProxyPassMatch ^/(ws(/.*)?)$ ws://$1

    ProxyPass /
    ProxyPassReverse /

    ErrorLog "/var/log/httpd/go.mydomain.com-error_log"
    CustomLog "/var/log/httpd/go.mydomain.com-access_log" common