Hack The Box – Postman

Run Nmap

Shows a few ports we can play with including http so lets dirb it.

Dirb the website

Its interesting, the js scripts might have an exec we can use but not sure. Lets run a full nmap to see what info we can get on OS and versions.

Full nmap

The verbose nmap shows some extra info including; OpenSSH, Apache httpd 2.4.29, MiniServ 1.910 (Webmin httpd) and ubuntu.

Lets google these versions for exploits as it might be easier than manipulating the js, if that’s possible.

The google

Interesting we seem to see 2 exploits that might be useful.

For Webmin (CVE-2019-12840) https://www.rapid7.com/db/modules/exploit/linux/http/webmin_packageup_rce

This is interesting and might be useful if we can get the webmin credentials.

For Apache – https://www.rapid7.com/db/vulnerabilities/apache-httpd-cve-2019-0211

Interesting as well, might be how we get root but not the door we are looking for.

Webmin enum

So lets checkout webmin first.

Researching webmin vulnerabilities we see https://www.rapid7.com/db/modules/exploit/linux/http/webmin_backdoor could potentially let us change the password. We know the device is linux so the default username is root. Lets see if we can change the password.

Nope. Researching the Apache version also didn’t do much good. When speaking to a friend I am told I am an idiot and lazy with nmap, and I should redo my nmap and not be stooopid. As such I am now redoing nmap with sadness in my heart.

Sure enough we see port 6379 – Redis Key-Value Store 4.0.9. Abit of research shows Redis to be a mix of nosql and caching software that, as it says, acts as a key value store. Guessing our user credentials are stored in it so after installing redis-cli we can connect to the box;

Using HackTricks site we are able to learn about more about redis and how to enumerate it; https://book.hacktricks.xyz/pentesting/6379-pentesting-redis

Using CONFIG GET * we can see the configuration;> CONFIG GET *
  1) "dbfilename"
  2) "authorized_keys"
  3) "requirepass"
  4) ""
  5) "masterauth"
  6) ""
  7) "cluster-announce-ip"
  8) ""
  9) "unixsocket"
 10) ""
 11) "logfile"
 12) "/var/log/redis/redis-server.log"
 13) "pidfile"
 14) "/var/run/redis/redis-server.pid"
 15) "slave-announce-ip"
 16) ""
 17) "maxmemory"
 18) "0"
 19) "proto-max-bulk-len"
 20) "536870912"
 21) "client-query-buffer-limit"
 22) "1073741824"
 23) "maxmemory-samples"
 24) "5"
 25) "lfu-log-factor"
 26) "10"
 27) "lfu-decay-time"
 28) "1"
 29) "timeout"
 30) "0"
 31) "active-defrag-threshold-lower"
 32) "10"
 33) "active-defrag-threshold-upper"
 34) "100"
 35) "active-defrag-ignore-bytes"
 36) "104857600"
 37) "active-defrag-cycle-min"
 38) "25"
 39) "active-defrag-cycle-max"
 40) "75"
 41) "auto-aof-rewrite-percentage"
 42) "100"
 43) "auto-aof-rewrite-min-size"
 44) "67108864"
 45) "hash-max-ziplist-entries"
 46) "512"
 47) "hash-max-ziplist-value"
 48) "64"
 49) "list-max-ziplist-size"
 50) "-2"
 51) "list-compress-depth"
 52) "0"
 53) "set-max-intset-entries"
 54) "512"
 55) "zset-max-ziplist-entries"
 56) "128"
 57) "zset-max-ziplist-value"
 58) "64"
 59) "hll-sparse-max-bytes"
 60) "3000"
 61) "lua-time-limit"
 62) "5000"
 63) "slowlog-log-slower-than"
 64) "10000"
 65) "latency-monitor-threshold"
 66) "0"
 67) "slowlog-max-len"
 68) "128"
 69) "port"
 70) "6379"
 71) "cluster-announce-port"
 72) "0"
 73) "cluster-announce-bus-port"
 74) "0"
 75) "tcp-backlog"
 76) "511"
 77) "databases"
 78) "16"
 79) "repl-ping-slave-period"
 80) "10"
 81) "repl-timeout"
 82) "60"
 83) "repl-backlog-size"
 84) "1048576"
 85) "repl-backlog-ttl"
 86) "3600"
 87) "maxclients"
 88) "10000"
 89) "watchdog-period"
 90) "0"
 91) "slave-priority"
 92) "100"
 93) "slave-announce-port"
 94) "0"
 95) "min-slaves-to-write"
 96) "0"
 97) "min-slaves-max-lag"
 98) "10"
 99) "hz"
100) "10"
101) "cluster-node-timeout"
102) "15000"
103) "cluster-migration-barrier"
104) "1"
105) "cluster-slave-validity-factor"
106) "10"
107) "repl-diskless-sync-delay"
108) "5"
109) "tcp-keepalive"
110) "300"
111) "cluster-require-full-coverage"
112) "yes"
113) "cluster-slave-no-failover"
114) "no"
115) "no-appendfsync-on-rewrite"
116) "no"
117) "slave-serve-stale-data"
118) "yes"
119) "slave-read-only"
120) "yes"
121) "stop-writes-on-bgsave-error"
122) "yes"
123) "daemonize"
124) "yes"
125) "rdbcompression"
126) "yes"
127) "rdbchecksum"
128) "yes"
129) "activerehashing"
130) "yes"
131) "activedefrag"
132) "no"
133) "protected-mode"
134) "no"
135) "repl-disable-tcp-nodelay"
136) "no"
137) "repl-diskless-sync"
138) "no"
139) "aof-rewrite-incremental-fsync"
140) "yes"
141) "aof-load-truncated"
142) "yes"
143) "aof-use-rdb-preamble"
144) "no"
145) "lazyfree-lazy-eviction"
146) "no"
147) "lazyfree-lazy-expire"
148) "no"
149) "lazyfree-lazy-server-del"
150) "no"
151) "slave-lazy-flush"
152) "no"
153) "maxmemory-policy"
154) "noeviction"
155) "loglevel"
156) "notice"
157) "supervised"
158) "no"
159) "appendfsync"
160) "everysec"
161) "syslog-facility"
162) "local0"
163) "appendonly"
164) "no"
165) "dir"
166) "/var/lib/redis/.ssh"
167) "save"
168) "900 1 300 10 60 10000"
169) "client-output-buffer-limit"
170) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
171) "unixsocketperm"
172) "0"
173) "slaveof"
174) ""
175) "notify-keyspace-events"
176) ""
177) "bind"
178) " ::1"

We learn abit about the config file locations, the DB filename and that protected mode(whatever that is) is not enabled.. not much I can think of using so lets try the next command HackTricks suggests;

Looks like we will be able to get the public ssh_key for the user, red. After some more research we come to this blog; https://medium.com/@Victor.Z.Zhu/redis-unauthorized-access-vulnerability-simulation-victor-zhu-ac7a71b2e419 shows how we can use protected mode being disabled to upload our own trusted public key. As per that blog we create temp.txt and upload it to redis.

We can see our key s-key. Next what we want to do with our uploaded ssh key is to get it into the authorized keys file and save it, this way we should be able to ssh.

We don’t have permission to write the authorized_key to the user, reds .ssh folder so let’s try it in the default /var/lib/redis/.ssh. Now trying to SSH as Root, Red and Redis doesn’t seem to work. Let’s try again incase we did something incorrect, this time I will do it as root, just incase there is some unlikely permission issue. We run a flushall command in redis-cli to clear everything and begin again.
This time it seems to work, guessing I typo’d the DIR, or misspelled the auth_keys 😕 Who doesn’t love life..

So now we are logged into the system as Redis, we can view one other user on the system, /home/Matt and the user key is there but unreadable as Redis. The user Red seems to be a red haring. So now we will go through the system to see what we can see.

Checking through the bash history for redis we can see scan.py and sshd_config and id_rsa.bak. Lets check these out first. Sshd_config didn’t show anything interesting but we were able to find a passphrase protected id_rsa.bak file in /opt;

googling how to enumerate id_rsa files shows us we might be able to get a password from this file; https://bytesoverbombs.io/cracking-everything-with-john-the-ripper-d434f0f6dc1c. We copy/paste the file contents into a file on our kali machine, setup john the ripper and.. ah… let ‘er rip!

Computer2008 seems to be our pass, so lets su into Matt and grab that user key.

Everythings coming up matthouse! So now we have user how will we get root. We know we have webmin and redis on the machine so are there any privilege escalations that will help? Checking running processes we can see webmin is being run as root so that might be a good start for checking;

Cant read most of the webmin files but we can confirm the version and search sploit shows one option for us.

And this is in MSF, we can be lazy. MSF module shows we need the webmin password to exploit. Lets see if Matt/computer2008 lets is log into it.

It does, we are in! 😊

Now we run and… we are in!

Lets see if we can get root flag now.

And we win! 😊

HTB – NetMon

As always first step is to run nmap and see what we find.

kali@kali:~$ sudo nmap -v -A -O
Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-08 07:02 EDT
NSE: Loaded 151 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 07:02
Completed NSE at 07:02, 0.00s elapsed
Initiating NSE at 07:02
Completed NSE at 07:02, 0.00s elapsed
Initiating NSE at 07:02
Completed NSE at 07:02, 0.00s elapsed
Initiating Ping Scan at 07:02
Scanning [4 ports]
Completed Ping Scan at 07:02, 0.08s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 07:02
Completed Parallel DNS resolution of 1 host. at 07:02, 0.01s elapsed
Initiating SYN Stealth Scan at 07:02
Scanning [1000 ports]
Discovered open port 21/tcp on
Discovered open port 445/tcp on
Discovered open port 135/tcp on
Discovered open port 139/tcp on
Increasing send delay for from 0 to 5 due to 113 out of 376 dropped probes since last increase.
Increasing send delay for from 5 to 10 due to max_successful_tryno increase to 4
Completed SYN Stealth Scan at 07:02, 25.20s elapsed (1000 total ports)
Initiating Service scan at 07:02
Scanning 4 services on
Completed Service scan at 07:02, 6.57s elapsed (4 services on 1 host)
Initiating OS detection (try #1) against
Retrying OS detection (try #2) against
Retrying OS detection (try #3) against
Retrying OS detection (try #4) against
Retrying OS detection (try #5) against
Initiating Traceroute at 07:03
Completed Traceroute at 07:03, 0.03s elapsed
Initiating Parallel DNS resolution of 2 hosts. at 07:03
Completed Parallel DNS resolution of 2 hosts. at 07:03, 0.01s elapsed
NSE: Script scanning
Initiating NSE at 07:03
NSE: [ftp-bounce] PORT response: 501 Server cannot accept argument.
Completed NSE at 07:03, 8.26s elapsed
Initiating NSE at 07:03
Completed NSE at 07:03, 0.08s elapsed
Initiating NSE at 07:03
Completed NSE at 07:03, 0.00s elapsed
Nmap scan report for
Host is up (0.13s latency).
Not shown: 996 closed ports
21/tcp  open  ftp          Microsoft ftpd
| ftp-syst: 
|_  SYST: Windows_NT
135/tcp open  msrpc        Microsoft Windows RPC
139/tcp open  netbios-ssn  Microsoft Windows netbios-ssn
445/tcp open  microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:

Uptime guess: 0.001 days (since Sun Mar  8 07:01:37 2020)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=258 (Good luck!)
IP ID Sequence Generation: Incremental
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2m03s, deviation: 0s, median: 2m03s
|_smb-os-discovery: ERROR: Script execution failed (use -d to debug)
| smb-security-mode: 
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2020-03-08T11:05:18
|_  start_date: 2020-03-08T11:03:54

TRACEROUTE (using port 256/tcp)
1   30.47 ms
2   30.59 ms

NSE: Script Post-scanning.
Initiating NSE at 07:03
Completed NSE at 07:03, 0.00s elapsed
Initiating NSE at 07:03
Completed NSE at 07:03, 0.00s elapsed
Initiating NSE at 07:03
Completed NSE at 07:03, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 53.31 seconds
           Raw packets sent: 2006 (91.810KB) | Rcvd: 1265 (54.086KB)

We see FTP, SMB, NetBios and RPC ports open.. lets try enumerating what we can find in FTP first. Lets spin up MSF and search what FTP options we have.

We see alot of ways to play around with FTP, but first we want to check for guest, anonymous and no password logins. First check shows anonymous is allowed, lets see what we can see. As part of researching i found this nice blog; https://shahmeeramir.com/penetration-testing-of-an-ftp-server-19afe538be4b?gi=961d209d3042

Using scanner/ftp/anonymous we cab see that anonymous logins are allowed, so lets log in and see what we can see.

lucky day – looks like the whole C drive is available; everything from program files to users – lets see if we can get both flags.. we can get the user flag easily.

Lets see if we can also get admin. If blue was easy maybe this will be too.

Boo we cant. lets check out the other directories.

Not much interesting to find (dont forget to escape your spaces!) PRTG is the only program – which ties into the netmon name so lets google this. Its an interesting monitoring tool ive used before but not sure how we can use this to get admin; https://blog.paessler.com/monitor-applications-and-services-with-prtg lets check version and see what vulns show. Lets first try playing around with the website.

After about too many tears shed from searching the FTP drive and the website I still cant find anything interesting. Lets try the web app.. DIRB and a manual search dont give anything i can use, common accounts arnt recognised.. back to google. i got this blog https://kb.paessler.com/en/topic/463-how-and-where-does-prtg-store-its-data looks like program data might give us something

ProgramData.. hidden folders shouldent be forgotten about. 🙂 Going through the folder we see a .dat, .old and .old.bak config files. lets pull down the 3 config files and see whats in them

We have the version from .dat file; the config itself is very long with most setting seem unimportant, and searching through “user” doesn’t give any results. Lets see if we can find any vulnerabilities for that version.

Found a few CVE’s, CVE-2018-19203, CVE-2018-19204 and CVE-2018-9276 but nothing that we can use.

Success? After being stumped for awhile i was going through the .bak.old I found something – never forget to search for admin in all files 😮

                  PRTG System Administrator
                  <cell col="0" crypt="PRTG">
                  <cell col="1" crypt="PRTG">
            <!-- User: prtgadmin -->

Lets see if we can log into the website with these credentials…

suspenseful pause and it fails. Checking the other config files for this we find that the DBPassword is now set to encrypt and inherit, nice and secure 😦 .. not in plain text anymore. After playing around i noticed the .dat file has a saved date of 2019, and changing the year in the password to 2019 lets us log in!

Now that we are logged into the app we can use one of the CVE’s we found earlier. Started trying the OS command injection CVE-2018-19204.. but there was no MSF module and I wasnt able to find a working PoC to use it but while searching a few more articles referenced CVE-2018-9276 which might work and has a python script prebuild; https://github.com/wildkindcc/CVE-2018-9276 so lets give this a go.

After some playing around the python script wasnt working so i ended up using exploitdb’s bash script instead; https://www.exploit-db.com/exploits/46527 .

With this we have created an admin user account on the system itself so lets try to login. Reading up on https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-2-psexec-and-services/ we can try using PSexec to get a shell.

And we are in as admin! The flag has been found in the Admins users desktop! 🙂

HTB – Blue

First blog in a long time wanted to do something fast to get back into it – I want to start doing more HTB this year and using a quick and dirty walk-through lets me get two birds with one stone!


  1. Run Nmap scan

We see 445 smb! With a name like blue i wonder what smb vulnerability could be our target.. 🙂

2. MSF
Spin up msf and search for smb to see what options we have.

smb_version looks like a good start.

SMB_Version is a good starting point to see what SMB tells us about the host, we can then cross check that with ExploitDB or something similar to see what vulnerabilities are present

With SMB running on Windows 7 SP1 we should have all we need.


Lets check vulnerabilities for that Windows version – I am specifically looking to see if its vulnerable to eternal blue; https://docs.microsoft.com/en-us/security-updates/securitybulletins/2017/ms17-010

Wonderful! Its vulnerable. lets exploit it. We could use ExploitDB’s script; https://www.exploit-db.com/exploits/42031 but lets be lazy and see what MSF has for us by searching for eternal blue, or for MS17-010.

We can see there are several pre-made payloads for eternal blue and one interesting result, but not for this box, is the doublepulsar RCE payload.. Wannacry leveraged that.. the memories :’) but for now we will use Exploit/windows/smb/ms17_010_eternalblue.

Using this we are able to get a shell and it shows we are running as system! Looks like there will only one stage for finding flags with this box. Checking Users we see haris and Admin, both flags were found in the respective users Desktop.

And with that we have our flags. Easy box but good for beginners!

What is incident response?

not all incidents can be prevented. An incident response capability is therefore necessary for rapidly detecting incidents, minimizing loss and destruction, mitigating the weaknesses that were exploited, and restoring IT services

Incident response(or IR) is the portion of our security where we have to deal with, or respond, to adverse events that threaten security. While Business Continuity Planning can deal with outages caused by natural disasters, mechanical failures or similar events that can impact the business from performing; IR deals with events that impact the security of the organisation. Because performing incident response effectively is a complex undertaking, establishing a successful incident response capability requires substantial planning and resources. One of the best resources we can use are SANS Digital Forensics and Incident Response resources and the NIST 800-61r2 guidelines. The NIST guidelines would have provided the bulk of the research for this post as i went through it, understood it and simplify it here for easy reference. The full guidelines are here.

Before we go into IR lets go back to ITIL and the difference between an event and an incident. An event is any observable occurrence in a system or network. Events include a user connecting to a file share, a server receiving a request for a web page, a user sending email, and a firewall blocking a connection attempt. Adverse events are events with a negative consequence, such as system crashes, packet floods, unauthorised use of system privileges, unauthorised access to sensitive data, and execution of malware that destroys data. This guide addresses only adverse events that are computer security related, not those caused by natural disasters, power failures, etc. A computer security incident is a violation or imminent threat of violation of computer security policies, acceptable use policies, or standard security practices.

Types of incidents

There are several different types of incidents we can look at depending on what their goal is and how they are carried out. These can include;

  • Confidentiality
  • Integrity
  • Availability
  • Reconnaissance
  • Repudiation
  • Harassment
  • Extortion
  • Hoaxes

Why do we need IR?

Having an incident response function becomes ever more vital as our society becomes more connected. With the exponentially growing amount of publicly known security vulnerabilities for all types of technology and the increasingly connected and interconnected organisation’s around the world, criminals have plenty of ways to attack your systems. Added to the amount of information and intellectual property companies store on their systems, the transactions and analytics carried out and the technical links between businesses across the supply chain, there are many ways a criminal or state organisation can benefit from compromising your networks. The regulatory, financial, reputational and productivity impacts could be catastrophic. The benefits of having Incident Response capabilities include;

  • reduce the frequency of incidents by effectively securing networks, systems, and applications.
  • communications often need to occur quickly, organisations should define communication guidelines so that the appropriate information is shared with the appropriate parties.
  • Allowing more prioritised preparations for handling incidents by focusing on being incidents that use common attack vectors.
    • External/Removable Media: An attack executed from removable media (e.g., flash drive, CD) or a peripheral device. Attrition: An attack that employs brute force methods to compromise, degrade, or destroy systems, networks, or services. Web: An attack executed from a website or web-based application. Email: An attack executed via an email message or attachment. Improper Usage: Any incident resulting from violation of an organisation’s acceptable usage policies by an authorised user, excluding the above categories. Loss or Theft of Equipment: The loss or theft of a computing device or media used by the organisation, such as a laptop or smartphone. Other: An attack that does not fit into any of the other categories.
  • By emphasising the importance of incident detection and analysis throughout the organisation we can make sure unusual activities are investigated faster.
  • Written guidelines for prioritising incidents reducing confusion and time lost during an incident while allowing for more effective resource allocation.
  • Using the lessons learned process we gain value from incidents allowing us to iteratively improve our security.

So whats needed for establishing our incident response capability? In general our organisation should take a policy based approach to all aspects of information security to make us a well oiled machine! We can see this approach when we have high level description of the essential elements of information security, an understanding from users and system administrators about what they can and cannot do, and sanctions for infractions. We have this approach as it improves security by having everybody aware of what they must do and how they must do it. Incident response is no different and at a minimum it should include the following actions:

  • Creating an incident response policy and plan
  • Developing procedures for performing incident handling and reporting
  • Setting guidelines for communicating with outside parties regarding incidents
  • Selecting a team structure for an incident.
  • Establishing relationships and lines of communication between the incident response team and other groups, both internal (legal department) and external (law enforcement agencies)
  • Determining what services the incident response team should provide.
  • Staffing and training for the incident response team

Incident Response process

There are 6 steps in the standard SANS Incident Response process.

SANS Incident Response Process

Phase 1: Preparation.

Preparation phase comes before we have identified an attack. It is the stage where we start layering or defences and security controls to reduce the risk of a(successful) attack and where we start getting our policies and procedures created and distributed. Having all our staff trained up in what to do in an incident and ensuring any tools or infrastructure our incident response activity relies on are present and available is essential.

Phase 2: Identification.

At this point we have our Intrusion Detection, SIEM and other detective controls which will identify any attack taking place on your system. Here is where our analysts take in offences/tickets and investigate them to distinguish between false positives and legitimate incidents.

Phase 3: Containment.

If we reach this phase than an active attack is occurring. Before eradicating the attack and beginning our recovery we must stop it from spreading further throughout our estate. There are several strategies we can follow but whichever we apply we must be sure to keep a record of any actions taken. The strategies include;

  • Shutting down a system
  • Disconnect the infected asset from the network
  • Change filtering rules of firewalls
  • Disabling or deleting compromised accounts
  • Increasing monitoring levels
  • Setting traps such as honeypot
  • Striking back at the attacker’s system

Phase 4: Eradication.

At this point the attack is no longer spreading and we have an idea of the cause of the incident. We now proceed to eradicate that cause, for example eliminating the virus or worm. At this stage procedures are very important to ensure the eradication is completed as expected.

Phase 5: Recovery.

At this stage our goal is to return the compromised systems to their normal state. We should have recovery procedures in place tailored to potential incidents but the safest is a full rebuild of systems and restoring data from the last backup. Dont forget to patch impacted machines and again it is important to keep a record of any action taken and to keep users aware of the recovery status. This communication reduces confusion and rumours and allows us to advise them of major developments that may impact them. Adhering to local laws and internal policies in relation to media contact should also be considered with key employees being assigned this responsibility.

Phase 6: Lessons Learned.

The lessons learned phase is usually neglected but a post-mortem can be improvement to help us gain an exact understanding of the incident, its time line and the adequacy of our response. We can see what procedures worked and what did not, what the damage was and what we need to change going forward. This allows us to continually improve what we do and how we do it.


So how do we view our incident response as being successful? Good security should mean no incidents but everybody will suffer a breach at some point. So how do we measure success then? There are a few metrics we can use including;

  • Number of incidents,
  • Estimated financial loss – the more effective we are at incident response the less loss we will incur,
  • After each incident our lessons learned phase should include honest self evaluation,
  • Average time and resource required per incident,
  • Documentation and procedure quality by team.

We will always suffer incidents but by having a solid methodology and procedures to guide us when it happens we can be in a better place to reduce the damage caused to us. It can take time for the teams involved to get comfortable with the process so war gaming and mock events can be vital to improving our efficiency. With this in place from Preparation through to Lessons Learned attackers will have a much harder time breaking through our defences and maintaining persistence.

Malware Analysis Lesson 8; The final boss of the assembly.

Last lesson was pretty heavy, covering even more instruction but also seeing how they come together to create the standard instruction sets that form the structures we expect to see from “regular” programming language like if statements, for and while loops. This time we are going to go into arrays, switch statements, windows API calls and some other bits and pieces as we try to round off these notes.

Switch statements are similar to IF statements only when we assign the variable a value and that value is used to select from a large number of switch options. It sounds abit weird but generally any menu we see where we chose from a selection of options uses switches. There are two common ways to implement switches, “if style” and “jump tables”.

If Style

If style switch statements are the standard one we think about where a variable is received, usually from the user, and the program goes through each switch case until a match is found and the code in that case is executed. If no match is found generally there is a default case that is used.

The above image shows the standard syntax for a high level switch statement. In Assembly this looks like;

Here we can see the variable i which is moved to the register EAX. We then use CMP command to try and find a match. If a match is found we execute the code, if its not we JMP to the next bit of assembly. On a side note this is actually quite a cool moment for me, reading through the assembly for this switch statement is now super easy. After the first 3 RE blog posts I am now able to recognize and understand the assembly commands used and the logic behind the flow of the code. If your getting lost when I mention EAX, JMP and CMP read my previous blog posts as they go through it all in detail. 🙂 Back on track now though. The JE command is new and means jump if equal. There is a good thread on it here. What JE does is it jumps to a given point if the cmp values match/are true. If they are not true than the code moves to the next line, in this case our JMP. At the end of this code block is an unconditional JMP to break out of the switch statement. By using obfuscated variables to match and a large number of switch cases this could be another area to obfuscate malware.

Jump Table

If styles work well with a limited number of options but as the number of cases grow performance can degrade. To prevent this and optimize the code we create jump tables. The jump tables define the offsets to the memory location of each separate case statements, acting as an index table with the switch variable as the search term. This allows for less comparisons needed by the code.

Switch jump table
High level vies of jump tables

In this example we can see a few things happening. Firstly the variable is subtracted by 1. This is because jump table index starts at 0. So in this case we see jump table cases 0-3 and not 1-4. Next we can see the code cmp each case label to see if it is out of range using JA, which is Jump if variable is above/greater than (description of this is here.).


Arrays are made up similarly to code we have seen before. The main thing about arrays are how the values are assigned to the indices. In assembly Arrays are accessed using a base address as a starting point. Since these are both arrays of integers, each element is of size 4 and so each subsequent element can be accessed by a multiple of 4. This is because each entry is 4 bytes in size.

Arrays are simple data structures used to store similar data. In the example above we can see the square brackets used in the assembly to reference an array value. They are important for us to know though as malware is sometimes written to use and array of pointers to strings that contain multiple host names that are used as options for connections.

Calling conventions

Calling conventions are how we call functions. These function calls can appear differently in assembly code and calling conventions govern the way the function call occurs. Conventions include the order parameters are placed on the stacks and in the registers, as well as who is responsible for cleaning up the stack when the function is complete. There are different conventions and the convention used is specific to the compiler. Despite these differences we need to use certain universal conventions when using the Windows API.


CDECL is one of the most common function call conventions and pushes parameters onto the stack from right to left. It is the responsibility of the caller to clean the stack after the function completes and the return value is stored in EAX. This is the convention thats been used in this blog. The way it cleans the stack is by using an ADD instruction to dereference the parameters pushed into stack by adding 8 bytes to the stack pointer.


This convention is similar to CDECL except it requires the callee to clean the stack after the function complete. The way this works is that the ADD instruction is not needed to clean the stack. STDCALL is used for Windows API calls. Any code calling these API functions will not need to clean up the stack after as the DLLs do this instead.


With that last bit done we are mostly finished with Assembly but there are a few tidbits on malware analysis I am going to include here. These bits are important as to understand malware functionality we also need to know the key components of the target OS outside of the assembly code that’s run. Lets focus on Windows APIs, The Registry and Networking API’s. The windows API is a broad set of functionality that governs the way that programs, including malware, can interact with the Microsoft libraries.

Hungarian Notation

Windows uses its own names to represent c value types, and some types like INT, SHORT and LONG are not used at all. We see this best in the windows registry where we have types like DWORD (32bit) and WORD(16bit) unsigned integers. Windows also uses Hungarian notation for API function identifiers. What this means is that a prefex is added to help identify the variable type such as dwSize as a parameter where the dw stands for DWORD.

Filesystem functions

One of the most common IoC’s for malware is when they create or modify files. When we are looking at an infection the file system and changes to the file system should be monitored and reviewed. We can uses some tools like Process Monitor for this. Some of the functions that can be called are;

  • CreateFile – This function is used to open files, pipes, streams and I/O devices as well as to create new files. The parameter dwCreationDisposition controls whether the call creats a new file or opens an existing one. Remember the dw prefix means ins a 32bit unsigned integer.
  • ReadFile and WriteFile – These functions are used for reading from and writing to files and operate on files as a stream. Both functions contain a parameter that signifies the number of bytes to read or write. That parameter controls the size of the data chunk that is read or written.
  • CreateFileMapping and MapViewOfFile – File mapping are commonly used by malware as they allow a file to be loaded into memory and manipulated. Creating a mapping loads a file from disk into memory while viewing a mapping returns a pointer to the base address of the mapping which can be used to access the file in memory. The program calling these function can use the pointer to read and write anywhere in the file.

The registry

The windows registry is used to store OS and program configuration information like settings or options. You are possibly familiar with it if you have used the regedit application. The registry is a hierarchical database of information and most windows configuration information is stored there including networking information, driver configuration, startup settings and useraccounts. The amount stored is quite vast and anyone looking for a career in IT should spend time going through it and learning the different categories. Knowing it is particularly helpful to malware analysts and malware uses the registry to gain persistance or to access or modify configuration data. The malware often adds entries into the registry that will allow it to run automatically when the computer boots.

The hierarchy

  • Root key – the registry has 5 top level sections called root keys or HKEY’s. Each root has a specific purpose or target.
  • Subkey – is a subfolder of the root key.
  • Key – is a folder in the registry that can contain additional folders or values. Root keys and sub keys are both “keys”.
  • Value entry – is an ordered name-value pair.
  • value or data – is the data stored in a registry entry.

Root keys

  • HKEY_LOCAL_MACHINE (HKLM) Stores settings that are global to the local machine.
  • HKEY_CURRENT_USER (HKCU) Stores settings specific to the current user.
  • HKEY_CLASSES_ROOT Stores information defining types.
  • HKEY_CURRENT_CONFIG Stores settings about the current hardware configuration, specifically differences between the current and standard configuration.
  • HKEY_USERS Defines setting s for the default user, new users and current users.

Common registry functions

Malware often uses registry functions that are part of the windows API in order to modify the registry to run automatically when the system boots. The most common registry functions used are;

  • RegOpenKeyEx – Opens a registry for editing and querying. There are functions that allow you to query and edit a registry key without opening it first, but most use RegOpenKeyEx.
  • RegSetValueEx – Adds a new value to the registry and sets it data.
  • RegGetValue – returns the data for a value entry in the registry.

These functions are used by malware and when we see them we should investigate the keys they are trying to access. There are also keys that will allow the malware to run at startup but many more deal with a systems security and settings so persistence may not be the only reason the malware is accessing the registry.

Networking API

Malware can also make use of network functions using API calls. There are many potential functions malware could take advantage of but of these option malware most commonly uses Berkeley Compatible Sockets. This allows malware to work across both windows and unix/linux systems. In windows this functionality is implemented in the Winsock Libraries, primarily in ws2_32.dll. Common functions include;

  • Socket – creates a socket.
  • Bind – Attaches a socket to a particular port, prior to accepting a call.
  • Listen – indicates that a socket will listen for incoming connections.
  • Accept – Opens a connection to a remote socket and accepts a connection
  • Connect – Opens a connection to a remote socket; the remote socket must be waiting for the connection.
  • Recv – Recieves data from the remote socket.
  • Send – Sends data to the remote socket.

The WSAStartup function must be called before any other networking functions in order to allocate resources for the networking libraries. When investigating network activity we need to consider both local and remote sides of the connection. The remote side usually maintains an open socket that is listening for incoming connections while the local side connects to that waiting port. Malware can use either side’s functionality and can act as a client(sending information to a C2) or a server (receiving instructions from a C2).

For a client side/local side application that connects to a remote socket we will see the socket call followed by the connect call, followed by send and recv.

For a server application/remote side that listens for incoming connections we will see a socket call, followed by a bind call, followed by a listen call and finally an accept call in this order. After this accept we will see send and recv calls.

Dynamic Link Libraries (DLL)

DLL’s are windows code libraries used by multiple applications. A DLL is an executable file that does not run alone but exports functions that can be used by other application. Static libraries still exist in windows but DLL’s are more common as they allow for code reuse and sharing. Sharing is possible as the single instance of the DLL loaded in memory can be accessed by multiple processes. #Optimized!

Unfortunatly Malware authors take advantage of DLLs in 3 primary ways;

  1. They use the basic Windows DLLs found on every system to interact with the OS. As malware analysts we can see what DLLs are being used by malware to gain an understanding for what is being achieved. With the static analysis we did previously we could get the functions called using strings.exe.
  2. They store malicious code in the DLL. Similar to how trojans work this can allow the author to attach their malware to multiple processes.
  3. Using third party DLLs the malware can also interact with other programs. We can see this when malware imports functions from a third party DLL and this can help us identify what the malwares goal is.


Malware can also execute code outside of whichever program it is in by creating new processes or modifying existing ones. In the past malware has been a stand alone process but now adays malware tries to avoid detection by running as part of another process, a process we trust. Windows uses processes as containers to manage resources and keep separate programs from interfering with each other. Malware can use CreateProcess to spawn a new process. With CreateProcess malware has a high degree of control over how the new process is created. For example the malware could use this to create a process to execute malicious code, or to create an instance of Internet Explorer(They still exist!) and direct the browser to access malicious sites and content. The most common thing for malware to do with a new process is to create a simple remote shell that the malware author can use to gain access to the machine without any other tools. Scary.

From endgame.com


It has taken us a few months but our series on Malware Analysis has finally come to an end. Its been an incredible journey for me growing from having no knowledge to where i am now. Through these blog posts we should now understand what IoC’s can suggest a malware infection, how to safely carry out static and dynamic analysis(including the tools to use!), how malware can hide from detection(and why signature based antivirus’ are no longer sufficient) and finally we spent a lot of time going through reverse engineering, expanding our under standing of assembly and the most common instructions we will see.

At this point if you have been following the blog you, like me, should now have strong entry level understanding of malware analysis and how malware analysts carry out their day to day jobs. From here the next step is practice. Grab malware samples, put them onto your lab and start analysis them and trying to reverse engineer them to understand what the code is doing. This is the only way to get familiar with the concepts and who knows, you might end up like Marcus Hutchins and stop the spread of the next WannaCry.

Best of luck!

Malware Analysis Lesson 7; More assembly!

Last week we made good headway into assembly. This week I am going to go through variables, a few more assembly operations and finally start looking at code constructs; loops, and branch statements. One of the biggest challenges to reverse engineers is that it can be impossible to step through an executables disassembled files due to the sheer amount of assembly instructions we would need to read through. I used to work with a bank and often spoke with their CTI team. On one occasion they gave me advice on how to handle navigating the amount of assembly instructions is to keep in mind the overall picture, the high level understanding of what the code does by looking at the groups of instructions, rather that panicking and trying to figure out and trace what malicious action “mov eax, ebx” is actually part of unless it is needed.

Most malware is written in C or C++ and we can see the coding constructs like loops, if statements, arrays, goto statements, switch statements and more in the assembly code as well as in the high level code itself. This blog is going to look at some more assembly instructions but also how these standard constructs look in assembly.

We already spoke about some of the registers in a previous blog but we still have some more to review;

  • ECX – Counter for string and loop operations
  • EDX – I/O pointer
  • ESI – Source pointer for stream/string operations
  • EDI – Destination pointer for stream/string operations
  • EAX (AX, AH, AL)
  • EBX (BX, BH, BL)
  • ECX (CX, CH, CL)
  • EDX (DX, DH, DL)

Global vs local variables

Like with high level languages global variables can be accessed by any function in a program while local variables can be accessed only by the function where its defined. While the declaration of each is similar in C, in assembly they look completely different;

Global and local variables – how it looks in C

We can see the main difference is where the line “uint8_t global_1;” is called. But with assembly global variables are referenced by memory addresses while local variables are referenced by stack addresses.

Global and local variables – how it looks in Assembly


Aside from the ADD and SUB operations we looked at the other arithmetic operations are;

  • INC – increment a destination value eg INC EAX
  • DEC – decrement a destination value eg. DEC EAX
  • MUL – multiply EAX register by a value eg. MUL $VALUE. The result is stored as a 64 bit value across EDX and EAX.
  • DIV – Divide 64 bits across EDX and EAX by value. The result is stored in EAX and the remainder is stored in EDX.

Logical operators

Logical operators consist of OR, AND, NOT and XOR can all be used in x86 architecture. These instructions operate similarly to the ADD and SUB instructions with the syntax XOR SRC,DEST with the result stored in the destination. The XOR instruction is frequently encountered in disassembly. For example XOR EAX,EAX is a quick way to set the EAX register to zero. This is done for optimization as the instruction requires less bytes and cpu cycle than MOV.

AND, OR, XOR and NOR logical bitwise operations.
  • AND – Destination operand can be r/m32 or a register. The source operand can be r/m32 or a register too, or even an immediate value(i.e. no source and destination as r/m32’s)
  • OR – Destination operand can be r/m32 or a register. The source operand can be r/m32 or a register too, or even an immediate value(i.e. no source and destination as r/m32’s)
  • XOR – Destination operand can be r/m32 or a register. The source operand can be r/m32 or a register too, or even an immediate value(i.e. no source and destination as r/m32’s)
  • NOT – Ones complement Negation(remember that?). The sing source/destination operand can be r/m32.


In order to shift registers we use the SHR and SHL instructions; “SHR/SHL destination, count”. These instructions shift the bits in the destination to the right or left and the number of shifts is the “count” field. If bits are shifted beyond the destinations boundary they are first shifted in the CF Flag. Zero Bits are filled in during the shift. At the end of the shift instruction the CF flag contains the last bit shifted out of the destination operand. Shifting is often used in place of multiplication as an optimisation. Shifting is simplet and faster than multipication as you dont need to mess around with registers or moving data around. The way we use shifting in place of multiplication is “shl eax, 1” is the same as multiplying EAX by 2. To figure out what you are multiplying by remember CCNA subnetting; https://www.9tut.com/subnetting-tutorial/2


Rotation is similar to shifting only instead of the bits disappearing when they fall off the edge of the destination the bits reappear on the opposite side, like a conveyor belt. ROR allows us to Rotate Right, while ROL allows us to rotate left.

Some of the items we discussed; Shifting, Rotation, and XOR/OR/AND are all encountered by analysts when we encounter encryption or compression. They will often look random and be in repeated a large number of times. Its one of the reasons we try and gain and overview of what the code does rather than investigating individual functions. When we do find and encrypted function we make a note of this and move on.

Branch statements

Branch statement, like if-else, are conditionally executed depending on the flow of the program. The most popular way of seeing this in assembly is through jump or JMP instructions. The format is “jmp location” and causes the next instruction executed to be the one specified by the jump. This is known as unconditional jumping as the execution will always execute such as with procedure calls, GoTo statements, exceptions and interrupts.

An always on jmp doesnt always fulfil our needs however. If-else isnt possible with jmp. We need some way to add conditions and this comes to us through conditional jumps usings flags to decide when to jump. There are more than 30 different jumps that can be used;

Before we can do a conditional jump we need to set the condition flags first. Typically this is done with CMP, TEST or whatever we have the sets flags.


CMP Compares two operands by subtracting the second operand from the first. It differers from the SUB operand in that the result is not stored. CMP computes the result, sets the flag then discards the result. This way it only sets the flag without impacting registers.


Like CMP, TEST sets flags and discards the results. It computes the AND of value 1 and value 2, then sets the SF, ZF and PF flags according to the result.

If statements

If statements alter the programs execution based on a set condition (ie if (1=1)). Most languages have these but we will see how basics and nested if statements look in assembly. It is good to know that all if statements need a conditional jump, but not all conditional jumps are if statements. We can see an example of an if statement here;

The If statement itself is seen in the “Mov[move], Cmp[compare], jne[conditional jump if ZF flag is 0/FALSE] and jmp to L2 to skip the else execution.

For Nested if statements to code is the same as the above only additional if statements have been included within the initial if statements. This should be understandable if you do any coding, if not play with python! 😀 Make a game, its great fun! But in assembly the code looks more complicated and difficult to follow.

We can see there are 3 conditional checks in this “x==y”, “z==0” and “X=!y”. We can see reading through the code it can get complicated fast, and this is before we encountered a malware authors intentional obfuscation, htis is why its important to focus on the overall flow of what the program is doing rather that identifying what is happening at each step.


Loops, like the for loop, are ways of repeating the same piece of code according to some parameters. In assembly this is achieved through the use of conditional jmps such as JGE. Having trouble finding a For loop example online but the basic principle would be similar to;

CLR a // clear register and start at 0
~some action~ // carry out whatever action we want
INC a // increment a
cjne a, b, $jump-address // compares the first two operands and branches to $jumpaddress if their values are not equal, giving us our loop.

Its interesting that in assembly we seem to be looking for an exact match. In the above example if a is > than b.. what would happen? Must remember to test this later. Its probably the case that the next relevent instruction in the code is executed(ie the instruction after the for loop).

While loops are similar but have the condition set at the beginning of the loop and in order to execute the loop this condition must be true. To avoid an infinite loop occuring we must make sure there is some change to the condition(such as an increment of the condition value) within the loop. Malware authors tend to use while loops to monitor for some action before executing malicious code, such as recieving a connection from a C2 server. This allows the malware to continuously listen for this.

We can see in this sample how the jmp at the end keeps bring the code back to the cmp instructions at the start. Once x is greater than or equal to 10 the jge instruction kicks in the let us skip the loop and go to the xor at the end.


I need a break after all this assembly. Theres alot of information and ive found going through the actual code, and code samples to be the best way to figure out what is happening. I think there will be one more lesson in Malware and then we will take a random piece of malware that has not been analysed yet and start putting it all together to come out with an awesome analysis report. 🙂

Malware Analysis Lesson 6; Intel x86 Architecture and Assembly

At this stage in our series we know what malware is, we know how to use Dynamic and Static analysis tools, we know how malware tries to avoid detection and we have edited the obfuscation methods ourselves. The next step in our path to becoming malware analyst’s is to gain an understanding of Reverse Engineering. The first thing we must know for this is the basics of assembly and Intel x86. By reverse engineering malicious code we can delve deeper into the structure and behavior of suspect files and gain a greater understanding into the codes authors.

Generally a computer system can be represented as several layers of abstraction in order to allow cross layer integration. A good example of the reason for this is how Windows or Linux OS can run off many different types of hardware. Similarly malware authors tend to create the program in a high level language like C, C++, C# or Python, which is then compiled into machine code to be executed by the CPU. As analysts we generally dont have access to the source code, though we can certainly try to decompile the application we usually need to rely on our under standing of low level languages like Assembly to figure out how a program operates.

Sounds though right? Fortunately assembly isn’t as bad as you might think. Its estimated that 14 assembly instructions account for 90% of all code. With the top 5 instruction accounting for 64% of the total code. Here we can see that the number of assembly instructions we need to know is very accessible. For the curious, those 5 instructions are; MOV, PUSH, POP, CALL and CMP.

x86 Architecture

Malware is usually stored in binary, when we disassemble malware we take the binary is an input into our disassembled to output the assembly language code that we can review. This can be difficult as Assembly is a category of different languages depending on the processor in use. x86 Architecture and its associated language are the most common and what we will learn about here but others include; x64, SPARC, PowerPC, MIPS and ARM.

Most modern computer architectures including x86 use the Von Neumann architecture which has 3 components – the CPU that executes the code, fast and volatile Main Memory that stores all data and code that has been called and an I/O system that interfaces with hard drives, monitors and peripherals.

  • The Control Unit get instructions from the ram using one of the CPU’s Register’s, which act as an instruction pointer to store the address of the instruction to execute.
  • The registers act as basic data storage units and are very fast compared to RAM. It allows the CPU to fetch and store instructions faster.
  • The Arithmetic Logic Unit executes the instructions and store the results.

Main memory can be divided into 4 main sections; DATA – which holds alues that are put in place when the program is initially loaded such as static values or global variables; CODE – which includes the instructions fetched by the CPU to be executed, this controls what the program does; HEAP which is used for dynamic memory allocation and elimination where the contents change frequently during execution; STACK – which is used for local variables, parameters and is used to control the program flow.


CISC and RISC are two types of processor. Intel uses a software centric ISA called CISC, Complex Instruction Set Computer which has many special purpose instructions and a given compiler we may never use. We just need to know how to use the manual. It has variable length instructions between 1 and 15 bytes long. RISC ISA’s such as ARM on the other hand is Hardware Centric with more registers and fewer, fixed-size instructions.


Endianess comes in two flavours, Little Endian where bytes are stored with the little end first. This can be seen with the byte 0x12345678 which would be stored 0x78563412. Intel uses Little Endian. Big Endian on the other hand would stored 0x12345678 as is. This can be important to be aware of as malware changes from Big to little Endian during its life time as over the network Big Endian tends to be used and on the OS(Intel), little Endian is used.


Registers are small memory storage areas built into processors. They are faster than ram and volatile. We have 8 general purpose registers and an instruction pointer which points at the next instruction to execute. On x86-32, registers are 32 bits long and on x86-64, they are 64 bits long. While the registers are general purpose Intel has a suggested convention to follow for compiler developers and assembly coders. While this convention does not have to be used in general it is followed;

  • EAX – Stores function return values
  • EBX – Base pointer to the data section
  • ECX – Counter for string and loop operations
  • ESP – Stack pointer
  • EBP – Stack frame base pointer
  • EIP – Pointer to next instruction to execute (“instruction pointer”)
  • Caller-save registers – eax, edx, ecx
  • Callee-save registers – ebp, ebx, esi, edi


EFLAGS is a register that holds many single bit flags. There are two we need to be aware of; ZERO FLAG(ZF) – Set if the result of some instruction is zero, and SIGN FLAG (SF) – Set equal to the most significant bit of a result. There is a good rundown on flags here; https://en.wikipedia.org/wiki/FLAGS_register

So what instructions can we use?

First: The Stack

The stack is a conceptual area of main memory which is designated by the OS when a program is started. By general convention different OS start the stack at different addresses. Generally stacks follow a Last-In-First-Out (LIFO/FILO) data structure where data is pushed on to the top of the stack and popped off the top (we will talk more about these operations shortly). The stack is used normally for temporary storage space. By convention the stack grows towards lower memory addresses so that by adding something to the stack the top of the stack is now at a lower memory address. The ESP points to the top of the stack, which is the lowest address in use. Data that exists at addresses beyond the top of the stack are considered as being undefined. The stack keeps track of which functions were called before the current one, holds local variables and is frequently used to pass arguments to the next function to be called. We need to keep in mind what is happening on the stack in order to understand any programs operation.

The stack’s LIFO


NOP, or No Operation, indicates to registers and no values. It existance is to pad/align bytes, delay time or, as we discussed in Lesson 5 obfuscation and to confuse malware detectors. A one-byte NOP instruction is an alias mnemonic for “XCHG EAX, EAX” instruction.


Push is the simplest instruction that lets us add something to the stack. This can be a Word, Double/Dword or QuadWord, but usually a Dword. It can be an immediate value(a numeric constant), hte value in a register or a register segment. The push instruction automatically decrements the stack pointer ESP by 4.


To then remove a value from the stack we must use the POP instruction which takes the DWORD off the stack, puts it in a register and increments the ESP by 4.


The call procedures job is to transfer control to a different function in a way that control can later be resumed where it left off. This allows separate programmers to share code and develop libraries for use by many programs What this means is the value of the instruction pointer is pushed into the stack, which at that time points to the instruction following the CALL instruction. First it pushes the address of the next instruction onto the stack for use by the RET (which is discussed next) for when the procedure is done. Then it changes the EIP to the address in the instruction.


There are two forms of the RET function;
1. It pops the top of the stack into the EIP, which also increments the ESP. In this form it is written as “RET”
2. It pops the top of the stack and EIP and add a constant number of bytes to ESP. In this form it is written as “ret 0x8”, “ret 0x20” and so on.


The move instruction can move a register value to another register, a memory value to a register, a register value to memory, an immediate value to a register and an immediate value to memory. BUT it can never move a memory value to memory.

r/m32 Addressing Forms

Anywhere we see r/m32 it means the code could be taking a value from a register or a memory address. In Intel processors most of the time square brackets [] tell us to treat the value within as a memory address, and fetch the value at the address.

LEA – Load Effectiveness Address

Frequently used with pointer arithmetic, and sometimes for arithmetic in general. It uses the r/m32 form but is more the exception to the rule that the square brackets [] syntax means dereference. For example that in a piece of arithmetic the resulting value stored is the values address, and not the value itself. This can be useful when passing the address of an array element to a subroutine. It may also be a slightly sneaky way of doing more calculations than normal in one instruction This is where its confusing me, we will have to do some examples later to get clarification.


These commands do what you think, they add and subtract values. The destination operand can be r/m32 or a register and the source operand can be r/m32 or a register or an immediate. It evaluates the operation and sets flags as appropriate. Instructions modify OF, SF, ZF, AF, PF and CF flags.


With the basics of assembly and its instructions under our belt the outputs of many tools like IDA pro and Ghidra are more clear and easier to understand but we will need more time, and one more blog post, before we fully digest assembly but already the output of our malware lesson 5 the debugger output is much more clear.

Until next time,