⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.40
Server IP:
13.127.59.50
Server:
Linux ip-172-31-46-210 5.15.0-1033-aws #37~20.04.1-Ubuntu SMP Fri Mar 17 11:39:30 UTC 2023 x86_64
Server Software:
Apache/2.4.41 (Ubuntu)
PHP Version:
7.4.3-4ubuntu2.29
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
ec2-instance-connect
/
View File Name :
eic_harvest_hostkeys
#!/bin/sh # Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"). You # may not use this file except in compliance with the License. A copy of # the License is located at # # http://aws.amazon.com/apache2.0/ # # or in the "license" file accompanying this file. This file is # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. set -e umask 077 # Fetch the IMDSv2 access token. 5 seconds is overall AKC timeout so we use that. IMDS_TOKEN="$(/usr/bin/curl -s -f -m 1 -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 5")" if [ -z "${IMDS_TOKEN}" ] ; then # Fast fail exit 255 fi # Verify the instance ID itself instance=$(/usr/bin/curl -s -f -m 1 -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/meta-data/instance-id/") if [ -z "${instance}" ] ; then exit 255 fi # Validate the instance ID is i-abcd1234 (8 or 17 char, hex) # We have it buffered to 32 chars to futureproof any further EC2 format changes (given some other EC2 resources are already 32 char) /bin/echo "${instance}" | /usr/bin/head -n 1 | /bin/grep -Eq "^i-[0-9a-f]{8,32}$" || exit 255 # Verify we have an EC2 uuid if [ ! -f /sys/hypervisor/uuid ] ; then # Nitro, switch to DMI check if [ ! -f /sys/devices/virtual/dmi/id/board_asset_tag ] ; then # We're out of options. This is definitely not an instance. exit 255 elif [ "$(/bin/cat /sys/devices/virtual/dmi/id/board_asset_tag)" != "${instance}" ] ; then # The board_asset_tag does not match the instance id. This is not a valid instance. exit 255 fi elif [ "$(/usr/bin/cut -c1-3 < /sys/hypervisor/uuid)" != "ec2" ] ; then # Leading bytes are not "ec2" exit 255 fi # Calculate the SHA256 of a given string # sha256 [string] sha256 () { /bin/echo -n "${1}" | /usr/bin/sha256sum | /bin/sed 's/\s.*$//' } # Sign a message with a given key # sign [key] [msg] sign () { /usr/bin/printf "${2}" | /usr/bin/openssl dgst -binary -hex -sha256 -mac HMAC -macopt hexkey:"${1}" | /bin/sed 's/.* //' } # Derive a sigv4 signing key for the given secret # get_sigv4_key [key] [datestamp] [region name] [service name] getsigv4key () { base="$(/bin/echo -n "AWS4${1}" | /usr/bin/od -A n -t x1 | /bin/sed ':a;N;$!ba;s/[\n ]//g')" kdate="$(sign "${base}" "${2}")" kregion="$(sign "${kdate}" "${3}")" kservice="$(sign "${kregion}" "${4}")" sign "${kservice}" "aws4_request" } # Verify that we have instance identity credentials. Fast-exit if we do not. creds_status="$(/usr/bin/curl -s -f -m 1 -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" -o /dev/null -I -w %{http_code} "http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance/")" if [ "${creds_status}" != "200" ] then # No keys for this user. Nothing to do. exit 0 fi #Iterates overs /etc/ssh to get the host keys for file in /etc/ssh/*.pub; do /usr/bin/test -r "${file}" || continue key=$(/usr/bin/awk '{$1=$1};1' < "${file}") keys="${keys:+${keys},}\"${key}\"" done #Temporary path to store request parameters userpath=$(/bin/mktemp -d /dev/shm/eic-hostkey-XXXXXXXX) trap 'rm -rf "${userpath}"' EXIT #Get zone information zone=$(/usr/bin/curl -s -f -m 1 -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/meta-data/placement/availability-zone/") zone_exit="${?}" if [ "${zone_exit}" -ne 0 ] then exit "${zone_exit}" fi # Validate the zone /bin/echo "${zone}" | /usr/bin/head -n 1 | /bin/grep -Eq "^([a-z]+-){2,3}[0-9][a-z]$" || exit 255 # Get domain for calls domain=$(/usr/bin/curl -s -f -m 1 -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/meta-data/services/domain/") domain_exit="${?}" if [ "${domain_exit}" -ne 0 ] then exit "${domain_exit}" fi #Extract region from zone region=$(/bin/echo "${zone}" | /bin/sed -n 's/\(\([a-z]\+-\)\+[0-9]\+\).*/\1/p') hostkeys=$(/bin/echo "${keys:?}") accountId=$(/usr/bin/curl -s -f -m 1 -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/dynamic/instance-identity/document" | /bin/grep -oP '(?<="accountId" : ")[^"]*(?=")') /bin/echo "${accountId}" | /usr/bin/head -n 1 | /bin/grep -Eq "^[0-9]{12}$" || exit 255 val='{"AccountID":"'${accountId}'","AvailabilityZone":"'${zone}'","HostKeys":['${hostkeys}'],"InstanceId":"'${instance}'"}' # Pull the creds we need for the call creds=$(/usr/bin/curl -s -f -m 1 -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" "http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance/") creds_exit="${?}" if [ "${creds_exit}" -ne 0 ] ; then # We failed to load instance-identity credentials exit "${creds_exit}" fi AWS_ACCESS_KEY_ID=$(/bin/echo "${creds}" | /bin/sed -n 's/.*"AccessKeyId" : "\(.*\)",/\1/p') AWS_SECRET_ACCESS_KEY=$(/bin/echo "${creds}" | /bin/sed -n 's/.*"SecretAccessKey" : "\(.*\)",/\1/p') AWS_SESSION_TOKEN=$(/bin/echo "${creds}" | /bin/sed -n 's/.*"Token" : "\(.*\)",/\1/p') unset creds clearcreds () { unset AWS_SESSION_TOKEN unset AWS_SECRET_ACCESS_KEY unset AWS_ACCESS_KEY_ID } trap clearcreds EXIT # Generate, sign, and send the sigv4 request host="ec2-instance-connect.${region}.${domain}" endpoint="https://${host}" timestamp=$(/bin/date -u "+%Y-%m-%d %H:%M:%S") isoTimestamp=$(/bin/date -ud "${timestamp}" "+%Y%m%dT%H%M%SZ") isoDate=$(/bin/date -ud "${timestamp}" "+%Y%m%d") canonicalQuery="" # We are using POST data, not a querystring canonicalHeaders="host:${host}\nx-amz-date:${isoTimestamp}\nx-amz-security-token:${AWS_SESSION_TOKEN}\n" signedHeaders="host;x-amz-date;x-amz-security-token" payloadHash=$(/bin/echo -n "${val}" | /usr/bin/sha256sum | /bin/sed 's/\s.*$//') canonicalRequest="$(/usr/bin/printf "POST\n/PutEC2HostKeys/\n%s\n${canonicalHeaders}\n${signedHeaders}\n%s" "${canonicalQuery}" "${payloadHash}")" requestHash=$(/bin/echo -n "${canonicalRequest}" | /usr/bin/sha256sum | /bin/sed 's/\s.*$//') # Derive the signature credentialScope="${isoDate}/${region}/ec2-instance-connect/aws4_request" toSign="AWS4-HMAC-SHA256\n${isoTimestamp}\n${credentialScope}\n${requestHash}" signingKey=$(getsigv4key "${AWS_SECRET_ACCESS_KEY}" "${isoDate}" "${region}" "ec2-instance-connect") signature=$(sign "${signingKey}" "${toSign}") authorizationHeader="AWS4-HMAC-SHA256 Credential=${AWS_ACCESS_KEY_ID}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}" # Attempt to publish host keys # 5 second timeout helps avoid choking launches in private subnets (see https://github.com/aws/aws-ec2-instance-connect-config/issues/8) /usr/bin/curl -sS -m 5 -X POST -H "Content-Encoding: amz-1.0" -H "Authorization: ${authorizationHeader}" -H "Content-Type: application/json" -H "x-amz-content-sha256: ${payloadHash}" -H "x-amz-date: ${isoTimestamp}" -H "x-amz-security-token: ${AWS_SESSION_TOKEN}" -H "x-amz-target: com.amazon.aws.sshaccessproxyservice.AWSEC2InstanceConnectService.PutEC2HostKeys" -d "${val}" "${endpoint}/PutEC2HostKeys/" unset AWS_SESSION_TOKEN unset AWS_SECRET_ACCESS_KEY unset AWS_ACCESS_KEY_ID