Who broke my crypto

Chapter 0 — The Problem

Chapter 1 — The Puzzle

Chapter 2 — The Chase


  • nc -zv <ec2_instance_ip> 22
  • The -z option is “zero-I/O mode” specifically for scanning.
  • The -v option means “verbose” and actually causes the output to be generated; without this option only the exit status will indicate whether the port is open or not (0 = yes, 1 = no). This makes it easy to use this in scripting.

Nping — Network packet generation tool / ping utility

  • nping -c 5 –tcp-connect -p 22 <ec2_instance_ip>
  • -c, — count <n> : Stop after <n> rounds.
    — tcp-connect : Unprivileged TCP connect probe mode.
    — tcp : TCP probe mode.
    — udp : UDP probe mode.
    — icmp : ICMP probe mode.
    — arp : ARP/RARP probe mode.
    — tr, — traceroute : Traceroute mode (can only be used with TCP/UDP/ICMP modes).

Reference for Nping:

Oh wait, you said SSH. I know how to debug this.

Its simple:

  • Instead of SSH, just add –vvv for further debug.
  • ssh -v will tell you what is happening mostly on your end
  • ssh -vv will tell you low level on both ends
  • ssh -vvv will tell you almost everything from both ends.

Contacted AWS support.

A very patient support rep helped me debug the issue further

Step 0: SSH with “-vvv” flag for verbosity

I did that, didn’t help. Still lost connection.

Step 1: Create packet capture using tcpdump (command-line packet analyzer)

$ sudo -i
# tcpdump -i any -w /tmp/$(hostname)_capturefile.cap -s 256 port 22

# ssh -vvv user@<elastic_ip_ec2_instance>

# killall tcpdump ; pkill tcpdump

# zip -9 /tmp/$(hostname)_capturefile.cap.zip /tmp/$(hostname)_capturefile.cap

  • -i interface — interface=interface
  • -w file
    Write the raw packets to file rather than parsing and printing them out. They can later be printed with the -r option.
  • -s snaplen — snapshot-length=snaplen
    Snarf snaplen bytes of data from each packet rather than the default of 262144 bytes. Packets truncated because of a limited snapshot are indicated in the output

Step 2: Perform TCP traceroute (helps diagnose network issue) over different ports, such as 22 and 443. Also add mtr (my traceroute — combines much of the functionality of ping and traceroute into one interface) to the mix .

$ mtr -c 50 — no-dns — show-ips — report-wide — report — tcp — port 443 <elastic_Ip>

$ mtr -c 50 — no-dns — show-ips — report-wide — report — tcp — port 22 <elastic_Ip>

— no-dns

Use this option to force mtr to display numeric IP numbers and not try to resolve the host names.

— report-wide
This option puts mtr into wide report mode. When in this mode, mtr will not cut hostnames in the report.
— show-ips

Use this option to tell mtr to display both the host names and numeric IP numbers.

— report

This option puts mtr into report mode. When in this mode, mtr will run for the number of cycles specified by the -c option, and then print statistics and exit.

$ tcptraceroute <elastic_Ip> 22

$ traceroute -T -p 22 –n <elastic_Ip>


Use TCP SYN for probes


Do not try to map IP addresses to host names when displaying them.

And that didn’t help either.

Okay, Let’s take a step back and check my email.

“IT has upgraded your VM from RHEL6 to RHEL8 over the weekend. Please open a support case with us in case you are facing issues”.

Check the host machine:

Vm>lsb_release -a

LSB Version: :core-4.1-amd64:core-4.1-noarch

Distributor ID: RedHatEnterprise

Description: Red Hat Enterprise Linux release 8.1 (Ootpa)

Release: 8.1

Codename: Ootpa

Great, something has changed with respect to host machine, but what exactly.

<Few days pass by>

How does SSH work behind the scenes?

<opens textbook>

Information Security: Principles and Practice, Mark Stamp

<Search google for Red Hat documentation>


  • Two versions of SSH currently exist: version 1, and the newer version 2.
  • The OpenSSH suite in Red Hat Enterprise Linux 8 supports only SSH version 2, which has an enhanced key-exchange algorithm not vulnerable to known exploits in version 1.
  • OpenSSH is a program depending on OpenSSL the library, specifically OpenSSH uses the libcrypto part of OpenSSL.

man ssh_config: (on RHEL8)

The supported ciphers are:

<deep google search for redhat issues>

Go back to my host machine and look at logs:

  • debug1: SSH2_MSG_KEXINIT sent
  • debug1: SSH2_MSG_KEXINIT received
  • debug1: kex: algorithm: ecdh-sha2-nistp256
  • debug1: kex: host key algorithm: ecdsa-sha2-nistp256
  • debug1: kex: server->client cipher: aes256-gcm@openssh.com MAC: <implicit> compression: none

debug1: kex: client->server cipher: aes256-gcm@openssh.com MAC: <implicit> compression: none

  • debug1: sending SSH2_MSG_KEX_ECDH_INIT
  • debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
  • Connection closed by <elastic-ip> port 22

Go to my EC2 instance and take a look:

ec2:/etc/ssh# cat ssh_config

# Cipher 3des

# Port 22

# Protocol 2

# Cipher 3des

Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc

Lessons learned:

  1. Issue in EC2 instance code where its defaulting to GCM ciphers.
    Real bug- filed and fixed
  2. Genuine Red Hat bug which accidentally blocks GCM ciphers, which kept me hanging (still not fixed yet)
  3. Simple workaround:
    Look for any common cipher in host and EC2 instance:
    For example: “AES256-CTR” is there in both places
    Use it to SSH to the instance:
    Example usage: ssh — c “AES256-CTR” user@<elastic_ip_ec2_instance>

Happy Ending after all.

Slide deck link:

Presentation YouTube Link:



I read and write about cyber security, software, bug finding, quality assurance, software engineering best practices etc.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Nikhil Prathapani

I read and write about cyber security, software, bug finding, quality assurance, software engineering best practices etc.