About

Hello, I'm pwnwriter, and this is a frontend for my compilation of random notes gathered throughout the year. Here, you'll discover a diverse array of notes spanning topics such as Cybersecurity, shell scripting, rust, and much more, all available under the MIT license. These notes are straightforward, nothing but raw insights into various subjects.

Website : pwnwriter.xyz

Github : @pwnwriter

Twitter : @pwnwriter

Ko-fi : @pwnwriter

cat

Allow rust-analyzer to run on single file for completion

Create a rust-project.json in your directory

{
    "sysroot_src": "path/to/the/library",
    "crates": [
        {
            "root_module": "main.rs",
            "edition": "2021",
            "deps": []
        }
    ]
}

Here, i manually defined rustup home. By default it's ~/.rustup

export RUSTUP_HOME="${XDG_DATA_HOME:-$HOME/.local/share}/rustup"

Define crates deps inside a single file.

//! ```cargo
//! [dependencies]
//! clap = { version = "4.2", features = ["derive"] }
//! ```

extern crate clap;

use clap::Parser;

#[derive(Parser, Debug)]
#[clap(version)]
struct Args {
    #[arg(short, long, default_value = "PwnWriter")]
    pub name: String,
}

fn main() {
    let args = Args::parse();
    println!("{}", args.name);
}

Iterators

extern crate anyhow;

use anyhow::Result;

fn main() -> Result<()> {
    let ports = vec![1, 3, 4];

    let urls = vec![
        "https://github.com",
        "https://metislinux.org",
        "https://kisslinux.org",
    ];

    let urls_with_ports: Vec<String> = urls
        .iter()
        .zip(&ports)
        .map(|(url, &port)| format!("{}:{}", url, port))
        .collect();

    for url in urls_with_ports {
        println!("{}", url);
    }

    Ok(())
}

Standard Input Using Cursor

Sometimes, you may not have access to concatenate a file and pipe it into your code for testing. In such situations, you can utilize the Cursor module.

use std::io::{Cursor, BufRead, BufReader};

fn main() {
    let cursor = Cursor::new("Hey\npwned\n".to_string());
    let buffered_reader = BufReader::new(cursor);
    for line in buffered_reader.lines() {
        println!("{}", line.unwrap());
    }
}

How to Install Nix on any Linux VPS

Nix is a versatile package manager, programming language, and even a complete Linux distribution. It stands out with its focus on reproducibility and declarative configuration.

Download and Run the Installer

We'll be using determinate system's nix installer

curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- --install
Screenshot 2024-06-26 at 12 53 49

You should have nix installed by now.

nix --version

Screenshot 2024-06-26 at 12 57 01

Let's install a pkg tmux

nix profile install nixpkgs#tmux

Screenshot 2024-06-26 at 12 58 46

we can even install package for temp shell

nix-shell -p git

Screenshot 2024-06-26 at 13 08 29 Screenshot 2024-06-26 at 13 08 37

Installing Home Manager

Finally, we'll use Home Manager, a tool designed to manage the user environment (e.g., dotfiles) in a declarative way using Nix. We'll start by adding the minimal configuration needed to get Home Manager up and running.

First, create a dotfiles directory if you don't have one already (the name of the directory does not matter). Use git init (or your favorite GUI) to initialize a Git repository in the folder. Add the following two files:

mkdir dotfiles; cd dotfiles; git init

Screenshot 2024-06-26 at 13 13 40
{
  description = "Your description here";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { nixpkgs, home-manager, ... }: {
    homeConfigurations = {
      <Yourname> = home-manager.lib.homeManagerConfiguration {
        pkgs = nixpkgs.legacyPackages.x86_64-linux;
        modules = [
          ./modules
          {
            home.username = "username";
            home.stateVersion = "23.11";
            home.homeDirectory = "/home/username";
          }
        ];
      };

    };
  };
}

Place the above file as flake.nix.

Now the directory tree should look like this

Screenshot 2024-06-26 at 13 18 31

This flake initiales all the modules from modules directory.

For example to configure git, it goes something like this

{ pkgs, ... }:
let
  name = "username";
  email = "main";
in
{
  programs.git = {
    enable = true;
    userName = name;
    userEmail = email;
  };
}

Now we'll need to source it inside modules,

Like lua's init.lua' we have default.nix in nix.

We'll now import out git.nix using modules/default.nix file and it goes something like this.

{ config, ... }:

let
  modules = [
    ./git.nix
  ];
in
{
  imports = modules;

  xdg.dataHome = "${config.home.homeDirectory}/.local/share";
  programs.home-manager.enable = true;
}

We can now build our config using following.

nix run github:nix-community/home-manager -- switch --flake .#your_name
Screenshot 2024-06-26 at 13 24 51

It should generate your config like below.

Screenshot 2024-06-26 at 13 26 58

Setting Up Google Authentication for SSH on a Linux Server

Step 1: Install Google Authenticator

  1. Update your package list:

    sudo apt update
    
  2. Install the Google Authenticator package:

    sudo apt install libpam-google-authenticator
    

Step 2: Configure Google Authenticator for Your User

  1. Run the Google Authenticator setup:

    google-authenticator
    
  2. Answer the prompts:

    • "Do you want authentication tokens to be time-based (y/n)?": Type y and press Enter.
    • Backup Codes: Write down the emergency scratch codes provided and store them in a safe place.
    • "Do you want me to update your "/home/username/.google_authenticator" file?": Type y and press Enter.
    • "Do you want to disallow multiple uses of the same authentication token? (y/n)": Type y and press Enter.
    • "By default, tokens are good for 30 seconds. Do you want to increase the time skew window to 4 minutes? (y/n)": Type n and press Enter.
    • "Do you want to enable rate-limiting protection? (y/n)": Type y and press Enter.
  3. Scan the QR code: Use the Google Authenticator app on your phone to scan the QR code displayed on your terminal.

Step 3: Configure SSH to Use Google Authenticator

  1. Edit the SSH configuration file:

    sudo vim /etc/pam.d/sshd
    
  2. Add the following line at the end of the file:

    auth required pam_google_authenticator.so nullok
    
  3. Edit the SSH daemon configuration file:

    sudo vim /etc/ssh/sshd_config
    
  4. Find and modify the following lines:

    • Ensure ChallengeResponseAuthentication is set to yes:

      ChallengeResponseAuthentication yes
      
    • Ensure UsePAM is set to yes:

      UsePAM yes
      
    • (Optional) If you want to require both Google Authenticator and your password, add or modify the line:

      AuthenticationMethods publickey,password publickey,keyboard-interactive
      

Step 4: Restart the SSH Service

  1. Restart the SSH service to apply the changes:

    sudo systemctl restart sshd
    

Step 5: Test the Configuration

  1. Open a new SSH session to your server.

  2. Log in with your username and password.

  3. When prompted, enter the verification code from your Google Authenticator app.

Installing an SSL Certificate on a Domain Using Certbot manually

1. Install Certbot

If Certbot is not already installed, you can install it using the following commands:

For Debian/Ubuntu:

sudo apt update
sudo apt install certbot

2. Obtain the SSL Certificate

export DOMAIN=<your domain>

certbot certonly --manual -d *.$DOMAIN -d $DOMAIN --agree-tos --manual-public-ip-logging-ok --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory --register-unsafely-without-email --rsa-key-size 4096

3. Certbot will provide instructions on how to create a DNS TXT record to verify your domain ownership. The output will look something like this:

Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Before continuing, verify the record is deployed.

After creating the DNS TXT record, wait for the changes to propagate. This can take a few minutes. You can verify the DNS record by using a tool like DNSCheckerto ensure it has been properly set.

4. Setup ssl

Your new SSL certificates will be stored in the /etc/letsencrypt/live/$DOMAIN/ directory. You will find the following files:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        root /var/www/html;
        index index.html index.htm;
    }
}

Mount a directory on RAM.

Mount a directory completely on RAM. Everything will be wiped out on reboot.

mount -o size=<x>G -t tmpfs none <dir_name>

Explanation

size=<x>G: Sets the directory size in RAM (replace with GB, e.g., size=4G for a 4GB virtual directory).

-t tmpfs: Specifies tmpfs as the RAM-based filesystem.

none: Represents the virtual directory in RAM, not tied to any physical device.

<dir_name>: Path to the directory where you'll access the RAM directory.

Create SSH Keys

ssh-keygen -t rsa -b 4096 -C "example@example.com"

Generate a new SSH key using RSA encryption with a bit size of 4096 and attach an email address as a label.

Start SSH Agent

eval $(ssh-agent -s)

initialize ssh keys.

Add Generated Key to SSH Agent

ssh-add "~/.ssh/ssh_file_name"

Add newly generated SSH key to the SSH agent.

Some useful commands for enumerating *nix os

CommandsExplanation
uname -aPrint all available system information
uname -rKernel release
uname -nSystem hostname
hostnameAs above
uname -mLinux kernel architecture (32 or 64 bit)
cat /proc/versionKernel information
cat /etc/*-releaseDistribution information
cat /etc/issueAs above
cat /proc/cpuinfoCPU information
df -aFile system information

Users & Groups:

CommandsExplanation
cat /etc/passwdList all users on the system
cat /etc/groupList all groups on the system
cat /etc/shadowShow user hashes – Privileged command
grep -v -E "^#" /etc/passwd | awk -F: '$3 == 0 { print $1}List all super user accounts
fingerUsers currently logged in
pinkyAs above
usersAs above
who -aAs above
wWho is currently logged in and what they’re doing
lastListing of last logged on users
lastlogInformation on when all users last logged in
lastlog –u %username%Information on when the specified user last logged in

User & Privilege Information:

CommandsExplanation
whoamiCurrent username
idCurrent user information
cat /etc/sudoersWho’s allowed to do what as root – Privileged command
sudo -lCan the current user perform anything as root

Environmental Information:

CommandsExplanation
envDisplay environmental variables
setAs above
echo $PATHPath information
historyDisplays command history of current user
pwdPrint working directory, i.e. ‘where am I’
cat /etc/profileDisplay default system variables

Interesting Files:

CommandsExplanation
find / -perm -4000 -type f 2>/dev/nullFind SUID files
find / -uid 0 -perm -4000 -type f 2>/dev/nullFind SUID files owned by root

Common Shell Escape Sequences:

CommandsExplanation
:!bashvi, vim
:set shell=/bin/bash :shellvi, vim
!bashman, more, less
find / -exec /usr/bin/awk 'BEGIN {system("/bin/bash")}' \;find
awk 'BEGIN {system("/bin/bash")}'awk
--interactivenmap
perl -e 'exec "/bin/bash";'Perl

Random scripts

Record with internal sound using wf-recorder

wf-recorder \
-aalsa_input.pci-0000_03_00.6.analog-stereo \
-aalsa_output.pci-0000_03_00.6.analog-stereo.monitor \
-f recording.mkv