Saturday, February 10, 2018

AWS Serverless Example

AWS Lambda and Node.js example

Let's build a page that will calculate the square of the number you provide. This is just a simple static HTML page that will make a POST call to AWS' API Gateway that calls a Lambda function that you have created. Data will be passed using JSON format. 
This example will utilize following AWS Features:
  • Lambda
  • API Gateway
  • S3 Bucket
    • Static Website Configuration
    • Bucket Policy
Other Stateless server example:
References:
  • https://nodejs.org/en/
  • https://aws.amazon.com/lambda/
  • https://aws.amazon.com/api-gateway/
  • https://aws.amazon.com/s3/
  • https://jquery.com/

Here are the steps:

  1. Go to AWS Lambda
  2. Create new function
  3. Create as follows:
  4. You can either create a new Role or use existing, but it should be able to at least write to log
  5.  Runtime and Handler should set properly for you. If you want to know more about handler, press info link
  6. Overwrite the "Hello World" sample with the below code:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    exports.handler = (event, context, callback) => {
        const requestBody = JSON.parse(event.body);
        const argument = requestBody.argument;
        const square = argument * argument;
        const answer = `${argument}^2 = ${square}`;
        console.log(answer);
        callback(null, {
            statusCode:201,
            body: JSON.stringify({
                Response: answer,
            }),
            headers: {
                'Access-Control-Allow-Origin': '*',
            },
        });
    };
    
    • Line 1: This is mandatory, see notes from step 5
    • Line 2: reads the input JSON value from website
    • Line 3: extracts "argument" variable 
    • Line 4 - 5: squares the value received from website
    • Line 6: posts this value to Cloudwatch Log
    • Line 7: callback function has two arguments, the first if this function encounters an error and second if it succeeds. 
    • Line 8 - 15: This is the response that will be sent back to website when it succeeds
    • Line 12: This is mandatory, otherwise you will get "no access-control-allow-origin" error
       
  7. Configure AWS API Gateway: go to API Gateway
  8. Create a new API
  9. Create Resource
  10. Fill the form as follows
  11. Create Method
  12. Select POST (be sure to press the check box)
  13. Fill out the form as follows (substitute for your region of choice)
  14. Enable CORS (Accept all defaults and warnings)
  15. Deploy API
  16. Fill out the form as follows
  17. Make note of the Invoke URL
  18. Create config.js file and populate with the above URL
    1
    2
    3
    4
    5
    window._config = {
        api: {
            invokeUrl: 'https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod'
        }
    };
    
  19. Create mycalc.js and populate as follows
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    (function myScopeWrapper($) {
        $(function onDocReady() {
      alert('Welcome');
      $('#enterBtn').click(handleRequestClick);
    
            if (!_config.api.invokeUrl) {
                $('#noApiMessage').show();
            }
        });
    
     function handleRequestClick(){
      var argument = $('#argument').val();
            calc(argument);
     }
     
     function calc(argument_var){
       $.ajax({
                method: 'POST',
                url: _config.api.invokeUrl + '/mycalc',
                headers: {
                
                },
                data: JSON.stringify({
                    argument: argument_var
                }),
                contentType: 'application/json',
                success: completeRequest,
                error: completeRequest
            });
        }
     
        function completeRequest(result) {
            console.log('Response received from API: ', result);
            displayUpdate(result.Response);
        }
    
        function displayUpdate(text) {
            $('#updates').append($('<li>' + text + '</li>'));
        } 
     
    }(jQuery));
    
    • Line 2: onDocReady is mandatory, the page will load this upon start. It prepares actions.
    • Line 11: This will take the argument variable and call the calc function
    • Line 17 - 29: this is the format you should use to pass HTTP content to the API
    • Line 19: this should point to the API name you defined in AWS API Gateway
    • Line 24: these are your JSON formatted list of variables
    • Line 27: this is the action to take on success
    • Line 28: this is the action to take on failure (I know this is lazy; I'm using the same function as success)
  20. Create myCalc.html
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
        <title>My Calc</title>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="Serverless web application example">
        <meta name="author" content="">
    
    </head>
    
    <body>
        <div class="info panel panel-default">
      <p>Welcome. Enter a number and press enter to get the square value</p>
            <div class="panel-heading">
       <input id="argument"></input>
       <button id="enterBtn" class="btn btn-primary">Enter</button>
       
            </div>
            <div class="panel-body">
                <ul id="updates">
                    <li>2^2 = 4</li>
                </ul>
            </div>
        </div>
        <script src="js/vendor/jquery-3.1.0.js"></script>
        <script src="js/config.js"></script>
        <script src="js/mycalc.js"></script>
    </body>
    
    </html>
    
    • Line 20 of mycalc.html is called by Line 12 of mycalc.js
    • Line 21 of mycalc.html is called by Line 4 of mycalc.js
    • Line 25 of mycalc.html is updated by Line 38 of mycalc.js
    • Line 30 imports jquery library (mandatory), you can either use the file or one of many CDNs available such as https://developers.google.com/speed/libraries/#jquery
    • Line 31 imports the API Gateway location
    • Line 32 imports the JavaScript used in this page
  21. Import three files from above into your S3 bucket, be sure to drop all the JS files into appropriate sub directories
  22. Configure bucket for Static Website
  23. Edit Bucket Policy
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::BUCKET-NAME/*"
            }
        ]
    }
    
  24. Be aware that anyone can use this API call, so if you want to be cautious about it, you can restrict access to just your IP address:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::BUCKET-NAME/*",
                "Condition": {
                    "IpAddress": {
                        "aws:SourceIp": "X.X.X.X/32"
                    }
                }
            }
        ]
    }
    
  25. Go to mycalc.html and open the link, it will look like this:
    https://s3.amazonaws.com/[bucket-name]/mycalc.html
  26. You can also go to the Static URL that was defined from step 22:
    http://[bucket-name].s3-website-us-east-1.amazonaws.com/


Tuesday, February 6, 2018

Powershell Start-Job example

Example Start-Job usage

Example of using Start-Job in your script.

Job file (\\path\job-example2.ps1)

This is the script that will be called multiple times. Wanted to illustrate calling a file with parameters. It's a trival example, but wanted to show different output in the job results.
param(
    $runTask = $false,
    $action
)
if($runTask){
    $message = $action
    switch($action){
        "0"{
            $message = $message + ":zero"
        }
        "1"{
            $message = $message + ":one"
        }
        "2"{
            $message = $message + ":two"
        }
        "3"{
            $message = $message + ":three"
        }
        "4"{
            $message = $message + ":four"
        }
        "5"{
            $message = $message + ":five"
        }
        default{
            $message = $message + ":don't know"
        }
    }
}else{
    write-output "did not run"
}
Write-Output $message

Tasker file (\\path\job-example1.ps1)

This will create multiple jobs. Each job will be assigned a numeric iteration of the loop value as the name. We'll wait for all the jobs to finish and then get the output of each job using the name we assigned.
$scriptfile = $MyInvocation.MyCommand.Path
$scriptPath = split-path -parent $scriptfile

for($i=0;$i -le 5;$i++){
    $arguments = @($true,"$i")
    start-job -filepath "$scriptPath\job-example2.ps1" -ArgumentList $arguments -name $i
    sleep -Seconds 1
}

do{
    $state = get-job | ?{$_.state -eq 'Running'}
    sleep -second 1
}while($state -ne $null)

for($i=0;$i -le 5;$i++){
    receive-job -name $i
}


Expected output:


Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
1      0               BackgroundJob   Running       True            localhost            param(...                
3      1               BackgroundJob   Running       True            localhost            param(...                
5      2               BackgroundJob   Running       True            localhost            param(...                
7      3               BackgroundJob   Running       True            localhost            param(...                
9      4               BackgroundJob   Running       True            localhost            param(...                
11     5               BackgroundJob   Running       True            localhost            param(...                
0:zero
1:one
2:two
3:three
4:four
5:five





Friday, February 2, 2018

ColdFusion and AWS SNS

How to tie ColdFusion 11 server with AWS SNS.
Let's say you have an AWS SNS topic that sends a lot of information. And you're overwhelmed and you want a more streamlined solution such as a dashboard with database backend. And for the sake of this scenario, we'll leave AWS Gateway API and Lambda out of it. Because you already have a ColdFusion just sitting around.

Step 1: Write the CFC files
  1. Go to your website's physical directory and create a new folder called "rest". You don't have to call it that, but I do just for example sake. 
  2. Create two files:
    1. application.cfc
    2. sns.cfc
  3. application.cfc
    component output="false"
    {
         this.name = "my-rest";
         this.applicationTimeout = createTimespan(0,1,0,0);
         this.datasource = "myDB";
    
         this.restSettings.skipCFCWithError = true;
    
         public boolean function onRequestStart()
         {
              request._body = toString(getHttpRequestData().content);
              return true;
         }
    
         public boolean function onRequest()
         {
              return true;
         }
    }
    
    1. It is important that you set "request._body" here. Otherwise, you won't see the content. 
    2. You can put any other functions here to override the one from parent's Application.cfc
  4. sns.cfc
    <cfcomponent rest="true" restpath="sns">
     <cffunction name="postSNSTopic" access="remote" httpMethod="POST" returntype="string" produces="application/json">
      <cfargument name="body" type="string" restArgumentSource="body"/>
      <cfscript>
       response = "y";
    
       messageType = getHttpRequestData().headers["x-amz-sns-message-type"];
       messageID   = getHttpRequestData().headers["x-amz-sns-message-id"];
       topicARN    = getHttpRequestData().headers["x-amz-sns-topic-arn"];
       subject     = "None";
       messageJson = "";
       content     = "";
    
       switch(messageType){
        case "SubscriptionConfirmation":
         //Enter subscription action here
         break;
        case "Notification":
         //Enter notification action here
         break;
        default:
         response = "n";
       }
       
       if(response IS "y"){
        content = getHttpRequestData().content;
        contentLen = len(content);
        if(contentLen GT 0){
         contentStruct = deserializeJson(toString(content));
         subject = contentStruct["Subject"];
         if(len(subject) EQ 0){
          subject = "None";
         }
         messageJson = contentStruct["Message"];
         messageLen  = len(messageJson);
         if(messageLen EQ 0){
          messageJson = "No Content";
         }
        }else{
         content = "No Content";
         //TroubleShooting
         //headers = getHttpRequestData().headers;
         //for(item in headers){
          //content = content & "." & item & ":" & getHttpRequestData().headers[item];
         //}
        }
       }
      </cfscript>
      <cfif response EQ "y">
       <cfquery name = "sns_insert" datasource="mydb">
        insert into sns_listener(messageType, messageID, topicARN, subject, messageJSON, content, timestamp) values (
         <cfqueryParam value=#messageType# cfSqlType="cf_sql_varchar" maxlength="100"/>,
         <cfqueryParam value=#messageID# cfSqlType="cf_sql_varchar" maxlength="100"/>,
         <cfqueryParam value=#topicARN# cfSqlType="cf_sql_varchar" maxlength="100"/>,
         <cfqueryParam value=#subject# cfSqlType="cf_sql_varchar" maxlength="100"/>,
         <cfqueryParam value=#messageJson# cfSqlType="cf_sql_clob" maxlength="100"/>,
         <cfqueryParam value=#content# cfSqlType="cf_sql_clob" maxlength="100"/>,
         sysdate)
       </cfquery>
      <cfelse>
       <cfquery name = "sns_insert" datasource="mydb">
        insert into sns_listener(messageType, timestamp) values ('error',sysdate)
       </cfquery>
      </cfif>
     </cffunction>
    </cfcomponent>
    
  5. Details about HTTP Header and JSON content from SNS message can be found here.
Step 2: Configuring REST Service in ColdFusion 11
  1. Log into ColdFusion Administrator
  2. Under Server Settings, click Mappings
  3. Add Logical Path as "/rest" 
  4. Add Directory Path as the actual path of your files, "E:/website/rest"
  5. Under Data & Services, click REST services
  6. Add the Logical Path you used above, "/rest"
  7. Leave Host as blank
  8. You can leave service mapping blank, it will pick this up from your Application.cfc
  9. Select "Set as default application"
  10. Add service
Step 3: Go to AWS SNS and subscribe your endpoint
  1. Your REST end point will be https://www.mywebsite.com/rest/sns
  2. "rest" says this is a REST call
  3. "sns" is the name of your cfc file that contains the POST function
  4. Once you subscribe, you can manually confirm your subscription by pulling out the subscribeURL in the message or you can write a function in the body of sns.cfc above. 
References: 
GetHttprequest function
cfqueryparam function
HTTPS SNS Issue with CA
SNS JSON format

Wednesday, September 6, 2017

AWS Java SDK Example

AWS Java SDK Example

Connecting to AWS and printing all volumes



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class java-ec2-example{
    public static void main(String[] args){
        String myRegion = "us-east-1";
        String accessKey = "xxxx";
        String secretKey = "xxxx";
        String sessionTk = "xxxx";
        
        //For programmatic access user
        BasicAWSCredentials awsCreds =  new BasicAWSCredentials (accessKey, secretKey);
        
        //For temporary credential
        BasicSessionCredentials sesCreds = new BasicSessionCredentials (accessKey, secretKey, sessionTk);

        //For other credential (e.g. Instance IAM, Environment Variable, etc) leave this as null 
        AWSStaticCredentialsProvider myCredential = null;

        //For this example, we use session credential
        myCredential = new AWSStaticCredentialsProvider(sesCreds);

        AmazonEC2 ec2 = AmazonEC2ClientBuilder.standard()
                     .withCredentials(myCredential)
                     .withRegion(myRegion)
                     .build();

        List<Volume> volumes = ec2.describeVolumes(new DescribeVolumesRequest()).getVolumes();
        for(int i=0;i<volumes.size();i++){
            System.out.println(volumes.get(i));
        }
    }
}

Lines 9-18 are various means to connect to AWS. If you want to rely on the environment variables, you can just comment out line 18 and leave myCredentials as null.

Line 20 is used to build client connector to EC2. Similiar builders are available for all AWS services.

Line 25 returns all the volumes in your account.

Line 26 loops and prints all the volumes.

Wednesday, August 30, 2017

AWS CLI Sample - Find latest snapshot

AWS CLI Sample

Find the most recent snapshots of a volume and update a tag on it



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$volumeid = "vol-0000000000000000000"
$output = aws ec2 describe-snapshots `
   --owner-id 4444444444444 `
   --filters "Name=volume-id,Values='$volumeid'" `
   --query 'Snapshots[].{ID:SnapShotId,StartTime:StartTime}'
$output2 = $output | out-string | convertfrom-json
$highDate = "0"
$highID = "0"
foreach($item in $output2){
   if($item.StartTime -gt $highDate){
      $highDate = $item.StartTime
      $highID = $item.ID
   }
}
write-host $highID
$tag_value = "New Stamp (" + $(get-date).GetDateTimeFormats()[93] + ")"
aws ec2 create-tags --resources $highID --tags "Key='Bookmark',Value='$tag_value'"

Lines 2-5 is your standard describe snapshot command. Be sure to include the account number (owner-id) when we're filtering. The query is to limit the data returned since we don't need to know everything about each snapshots.

Lines 9-14 is looping through all the snapshots returned to get the newest one.

Line 16 is just to put a date stamp. GetDateTimeFormats()[93] returns "yyyy-MM-dd hh:mm:ss" date format.


Sunday, August 27, 2017

AWS CloudFormation Sample


AWS CloudFormation - Using Parameters


 Parameters are input arguments to CloudFormation script. Items like InterfaceID and InstanceProfile are custom parameters where we define the possible values. NameTag is a customer parameter where input values are open-ended with character limit/type limits. The remainder are AWS Supported Parameter Types, more can be found here.

"Parameters":{
        "ImageId":{
            "Description":"Image ID",
            "Type":"String",
            "Default":"ami-284f1a3e",
            "AllowedValues":[
              "ami-284f1a3e",
              "ami-36174e4d"
            ],
            "ConstraintDescription":""

        },
        "InstanceType":{
            "Description":"Instance Type",
            "Type":"String",
            "Default":"t2.small",
            "AllowedValues":[
       "t2.nano",
       "t2.micro",
       "t2.small",
       "t2.medium",
       "t2.large",
       "t2.xlarge",
       "t2.2xlarge"
            ],
            "ConstraintDescription":""
        },
        "KeyName":{
            "Description":"Key Name",
            "Type":"AWS::EC2::KeyPair::KeyName",
            "ConstraintDescription":""
        },
        "InterfaceID":{
            "Description":"Network Interface ID",
            "Type":"String",
            "Default":"eni-db0e3c7a",
            "AllowedValues":[
              "eni-9158e145",
              "eni-db0e3c7a"
            ],
            "ConstraintDescription":""
        },
        "NameTag":{
            "Description":"Name Tag",
            "Type":"String",
            "Default":"NameTag",
            "MinLength":"1",
            "MaxLength":"10",
            "AllowedPattern":"[a-zA-Z][a-zA-Z0-9]*",
            "ConstraintDescription":""
        },
        "InstanceProfile":{
            "Description":"Instance Profile",
            "Type":"String",
            "Default":"read_only_instance",
            "AllowedValues":[
              "read_only_instance",
              "admin_instance"
            ],
            "ConstraintDescription":""
        }
    }

In the Resources, we reference the above parameters using keyword, "Ref"


"Resources": {
        "MyInstance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": {
                    "Ref": "ImageId"
                },
                "InstanceType": {
                    "Ref": "InstanceType"
                },
                "KeyName": {
                    "Ref": "KeyName"
                },
                "NetworkInterfaces": [
                    {
                        "NetworkInterfaceId": 
                            {
                            "Ref": "InterfaceID"
                            },
                        "DeviceIndex":"0"
                    }
                ],
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": {
                            "Ref": "NameTag"
                        }
                    }
                ]
            },
            "Metadata": {
                "AWS::CloudFormation::Designer": {
                    "id": "4b94664e-1e18-400c-9733-ff095ff6e854"
                }
            }
        }
    }


The whole thing looks like this:


{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters":{
        "ImageId":{
            "Description":"Image ID",
            "Type":"String",
            "Default":"ami-284f1a3e",
            "AllowedValues":[
              "ami-284f1a3e",
              "ami-36174e4d"
            ],
            "ConstraintDescription":""

        },
        "InstanceType":{
            "Description":"Instance Type",
            "Type":"String",
            "Default":"t2.small",
            "AllowedValues":[
       "t2.nano",
       "t2.micro",
       "t2.small",
       "t2.medium",
       "t2.large",
       "t2.xlarge",
       "t2.2xlarge"
            ],
            "ConstraintDescription":""
        },
        "KeyName":{
            "Description":"Key Name",
            "Type":"AWS::EC2::KeyPair::KeyName",
            "ConstraintDescription":""
        },
        "InterfaceID":{
            "Description":"Network Interface ID",
            "Type":"String",
            "Default":"eni-db0e3c7a",
            "AllowedValues":[
              "eni-9158e145",
              "eni-db0e3c7a"
            ],
            "ConstraintDescription":""
        },
        "NameTag":{
            "Description":"Name Tag",
            "Type":"String",
            "Default":"NameTag",
            "MinLength":"1",
            "MaxLength":"10",
            "AllowedPattern":"[a-zA-Z][a-zA-Z0-9]*",
            "ConstraintDescription":""
        },
        "InstanceProfile":{
            "Description":"Instance Profile",
            "Type":"String",
            "Default":"read_only_instance",
            "AllowedValues":[
              "read_only_instance",
              "admin_instance"
            ],
            "ConstraintDescription":""
        }
    },
    "Metadata": {
        "AWS::CloudFormation::Designer": {
            "4b94664e-1e18-400c-9733-ff095ff6e854": {
                "size": {
                    "width": 60,
                    "height": 60
                },
                "position": {
                    "x": 304,
                    "y": 225
                },
                "z": 0
            }
        }
    },
    "Resources": {
        "MyInstance": {
            "Type": "AWS::EC2::Instance",
            "Properties": {
                "ImageId": {
                    "Ref": "ImageId"
                },
                "InstanceType": {
                    "Ref": "InstanceType"
                },
                "KeyName": {
                    "Ref": "KeyName"
                },
                "NetworkInterfaces": [
                    {
                        "NetworkInterfaceId": 
                            {
                            "Ref": "InterfaceID"
                            },
                        "DeviceIndex":"0"
                    }
                ],
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": {
                            "Ref": "NameTag"
                        }
                    }
                ]
            },
            "Metadata": {
                "AWS::CloudFormation::Designer": {
                    "id": "4b94664e-1e18-400c-9733-ff095ff6e854"
                }
            }
        }
    }
}

When you create stack from this:


Thursday, August 10, 2017

Powershell Network Tools

Few Powershell Network tools

This is when you are in an environment that won't let you install software. I've collected these from various sources. I use them often enough to keep it handy here.

Check for TCP Listener:

1
2
3
4
$socket = new-object net.sockets.tcpclient
$socket.connect("www.google.com",443)
$socket.connected
$socket = $null

Check for TCP Connections on your machine:

This is more than you really need, but it'll print a table of established connections every 5 seconds. If you just want the raw data and all the available connection state, just run lines 2 and 3.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
do{
 $tcpproperties=[System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
 $connections=$tcpproperties.GetActiveTcpConnections()
 $output=@()
 foreach($conn in $connections){
   if($conn.State -eq 'Established'){
     $outputObj = New-Object -typename PSObject
     $outputObj | Add-Member -MemberType NoteProperty -Name "LocalAddress" -Value $conn.LocalEndPoint.Address 
     $outputObj | Add-Member -MemberType NoteProperty -Name "LocalPort" -Value $conn.LocalEndPoint.Port
     $outputObj | Add-Member -MemberType NoteProperty -Name "RemoteAddress" -Value $conn.RemoteEndPoint.Address
     $outputObj | Add-Member -MemberType NoteProperty -Name "RemotePort" -Value $conn.RemoteEndPoint.Port
     $outputObj | Add-Member -MemberType NoteProperty -Name "State" -Value $conn.State
     $output=$output + $outputObj
   }
 }
 $output | format-table
 sleep 5
}while($true)


Check for UDP Listener

For this one, I'm also illustrating a listener too. Good for troubleshooting firewall.

Receiver

Run this portion on your receive end and wait for traffic.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$udpObject = new-object system.net.sockets.udpclient(1433)
$udpObject.client.ReceiveTimeout = 10000
do{
  $remoteEndPoint = new-object System.Net.IPEndPoint([System.Net.IPAddress]::Any,0)
  $receiveBytes = $udpObject.Receive([ref]$remoteEndPoint)
  $a = New-Object System.Text.AsciiEncoding
  [String]$returnData = $a.GetString($receiveBytes)
  Write-host "Received: $($returnData.ToString())"
  Write-host "Sent from: $($remoteEndPoint.Address.ToString()) on their port: $($remoteEndPoint.port.ToString())"
  $ans = read-host "More (y/n)?"
}while($ans -ne 'n')
$udpObject.close()

Sender

Then run this from your remote machine to see the information show up on the remote end.
1
2
3
4
5
6
$udpObject = new-object system.net.sockets.udpclient(1433)
$udpObject.connect("10.10.10.1",1433)
$a = new-object System.Text.AsciiEncoding
$byte = $a.GetBytes("$(get-date)")
[void]$udpObject.send($byte,$byte.length)
$udpObject.close()


Check for UDP Connection


1
2
$udpProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
$udpProperties.GetActiveUDPListners()


Remote PowerShell Session

Again, more than you need, but incase you don't want to have to type in your password every time. 

1
2
3
4
5
6
$servername = "mydesktop1"
$username = "domain\username"
$password = "password"
$secPassword = convertTo-SecureString $password -AsPlainText -Force
$mycred = New-Object System.Management.Automation.PSCredential($username,$secPassword)
enter-pssession -Credential $mycred -Computername $servername


Send Email

Good way to test your SMTP Server.

1
2
3
4
5
6
$SMTP = "mail.mycompany.net"
$Subject = "Test from $env:Computername"
$toaddress = "myemail@mycompany.net"
$fromaddress = $env:Computername + "@mycompany.net"
$body = "this message was sent via $SMTP at $(get-date)."
send-mailmessage -smtpserver $SMTP -to $toaddress -from $fromaddress -subject $subject -body $body



AWS WAF log4j query

How to query AWS WAF log for log4j attacks 1. Setup your Athena table using this instruction https://docs.aws.amazon.com/athena/latest/ug/wa...