How to create an extremely comfortable pwn environment (Season 2)
Now the question is, if you temporarily go home without your computer, but still want to control the computer at school, what should you do?
Result Preview:

We assume the reader has completed the configuration from the previous session and ensured they have a public IP.
Method 1 — Using DDNS
Every device has its own unique IP address. Theoretically, if you want to access a device, you only need to visit its IP address.
However, due to the scarcity of IPv4 resources today (world population > 7 billion, while the theoretically available IPv4 addresses are only
How to check if you have a public IP? Enter
ipconfig
in the command line to view your IP, and compare it with the result from a search engine. If they are the same, it's a public IP; otherwise, it's a private IP.
Even if your device is lucky enough to have a public IP, there is still a problem for accessing it—generally, the IP address assigned by the device's ISP is dynamic and changes periodically, ranging from a few hours to half a month. If your connection is disconnected or the device is restarted, the corresponding IP will also change.
DDNS solves the latter problem—it maps the device's changing IP to a fixed domain name. Users only need to access this domain name to connect to the device.
I use Peanut Hull DDNS. After downloading and registering on the official website, the system automatically assigns you a domain name. You can connect to it from other devices using SSH to access this domain.
Issues:
- Another application is added to startup.
- Cannot use a proxy.
- In some cases, using DDNS may cause broadband disconnection and prevent reconnection.
Method 2 — Using an IP Detection Script and Sending It to Email
Another idea is to use a script to query your IP address on an IP lookup website. If the script detects a change in the IP, it sends the new IP address to your email.
This idea seems straightforward, but the actual implementation is not so simple.
First, I copied a Python script that implements the above functionality (it's a bit long):
import json
from urllib.request import urlopen
import os
import time
import smtplib
from email.header import Header
from email.mime.text import MIMEText
# Two websites to get the IP address
ip_url_1 = 'https://api.ipify.org/?format=json'
ip_url_2 = 'http://jsonip.com'
# Configuration file name
config_file_name = '.global_ip.json'
# Third-party SMTP service
mail_host = "smtp.qq.com" # SMTP server
mail_user = "2658799217" # Username
mail_pass = "<thisisasecret>" # Authorization password, not the login password. I believe everyone knows how to get the authorization code—you need to send a text message to Tencent.
sender = '2658799217@qq.com' # Sender's email (preferably written in full, otherwise it may fail)
receivers = ['2658799217@qq.com'] # Recipient email, can be set to your QQ email or other email
title = 'update_addr' # Email subject
content = '' # Email content
# Check configuration file and its permissions
def check_configfile_exist():
file_exist = os.access(config_file_name, os.F_OK)
file_read = os.access(config_file_name, os.R_OK)
file_write = os.access(config_file_name, os.W_OK)
return{'file_exist':file_exist,'file_read':file_read,'file_write':file_write}
def generate_configfile(ip_addr):
config_construct = {
"ip_addr": ip_addr
}
with open(config_file_name, "w", encoding='utf8') as fp:
fp.write(json.dumps(config_construct,indent=4, ensure_ascii=False))
fp.close()
def sendEmail():
message = MIMEText(content, 'plain', 'utf-8') # Content, format, encoding
message['From'] = "{}".format(sender)
message['To'] = ",".join(receivers)
message['Subject'] = title
try:
smtpObj = smtplib.SMTP_SSL(mail_host, 465) # Enable SSL sending, port is usually 465
smtpObj.login(mail_user, mail_pass) # Login verification
smtpObj.sendmail(sender, receivers, message.as_string()) # Send
print("mail has been send successfully.")
except smtplib.SMTPException as e:
print(e)
def send_email2(SMTP_host, from_account, from_passwd, to_account, subject, content):
email_client = smtplib.SMTP(SMTP_host)
email_client.login(from_account, from_passwd)
# create msg
msg = MIMEText(content, 'plain', 'utf-8')
msg['Subject'] = Header(subject, 'utf-8') # subject
msg['From'] = from_account
msg['To'] = to_account
email_client.sendmail(from_account, to_account, msg.as_string())
email_client.quit()
localtime = time.localtime(time.time()) # 打印本地时间
print("\n" + time.asctime(localtime))
# 通过两个网站获取ip地址
my_ip_1 = str(json.load(urlopen(ip_url_1))['ip'])
my_ip_2 = str(json.load(urlopen(ip_url_2))['ip'])
if (my_ip_1 == my_ip_2):
ip_addr = my_ip_1
else:
ip_addr = "ip_1 :" + my_ip_1 + "\n" + "ip_2 :" + my_ip_2
if(check_configfile_exist()['file_exist'] & check_configfile_exist()['file_write']):
config_file = open(config_file_name,'r')
read_context = json.load(config_file)
old_ip = read_context['ip_addr']
config_file.close()
if (old_ip == ip_addr):
print("ip address is up-to-date")
else:
content = "old ip address is : " + old_ip + '\n' + "new ip address is : " + ip_addr
sendEmail()
generate_configfile(ip_addr)
else:
generate_configfile(ip_addr)
content = "new ip address is : " + ip_addr
sendEmail()
Of course, with just this script, it is indeed possible to achieve the above functionality. But what should we do in an unattended situation?
With the meager syntax I learned from writing differential test scripts in high school, I wrote a bat file. It first checks whether the device is connected to the internet. If it is not, it waits 10 seconds and checks again. Otherwise, it calls this script and then pauses for 10 minutes.
@echo off
:start
ping -n 2 114.114.114.114 | find "TTL=" >nul
if errorlevel 1 (
TIMEOUT 10
goto:start
) else (
pythonw D:/tmp1/tmp/test.py ::Here pythonw is used to prevent a popup window, which is very important when playing games.
)
TIMEOUT 600
goto:start
But then another new problem arises—the script itself also pops up a window, right? Isn’t this a bit like recursion?
So, I looked up some information online and found out that vbs scripts do not produce any prompts when running (except when a command fails), which can solve this issue.
I also borrowed some code from the internet that uses a vbs script to run commands and bat files:
CreateObject("WScript.Shell").run"Rasdial 123 <telephone> <passwd>",0
set ws=wscript.createobject("wscript.shell")
ws.run "D:/tmp1/tmp/start.bat /start",0
This vbs script does two things: first, it automatically dials to connect to the internet, and second, it calls the previous bat file.
I disconnected the internet and actually ran it myself. I found that the dial-up was successful, and I also received the long-awaited email about the IP change.
There remains the final question—how to schedule this script to run at specific times?
Sub-method 1 — Write code in a VBS script to make it run at scheduled times
Haven't learned VBS syntax yet (╹◡╹ლ) — temporarily filling the gap.
Sub-method 2 — Using Task Scheduler
I added this VBS script to the Task Scheduler, configured it to run at system startup and user login, and even set it to trigger every ten minutes, as shown in the image below:

However, during system startup, the system does automatically dial, but I do not receive the email about the IP change. Only when I manually run this VBS script does it successfully send the email.
Existing issues:
- At startup, it only dials but does not send an email.
- It cannot use a proxy.
- The operation is somewhat cumbersome.
Windows Default Terminal Settings
The old cmd is very inconvenient to use—it lacks syntax highlighting, and switching to a different drive path requires an extra command. It's too troublesome.
Running the following command in PowerShell allows you to change the device's default terminal to PowerShell:
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
Why don't I use cmder? I tried it, but when SSH calls cmder, it crashes. I'm not exactly sure why.