2009-09-25

批量检测可用域名

批量检测可用域名

redraiment, 2009-09-25





  在《内网IP自动获取》的评论中,有个网友希望能帮忙写一个批处理来批量检测域名的可用性。但前两天都在赶文档,刚刚接到老师电话说推迟到1008日交,心头大石终于落地^_^。所以就马上开工帮那位朋友实现这个批处理!
  原理很简单,就是找一个域名注册网站(比如我这里找的中国域名为http://www.chinadomain.com.cn/),这类网站一般都提供了域名查询功能,我们只要用 curl 等命令行 Web 客户端来提交表单就能获得域名的信息,然后通过 grep 来提取可用域名。
  :这两个工具在 Linux 系统中是自带的,但 Windows 中没有。我已经将它们和批处理文件一起上传到我的 Google Sites https://sites.google.com/site/redraiment/sunshine/domain)里,方便大家下载。下面是批处理的代码:
:: 查询可用域名
:: 使用方法:domain.bat hostname ...
:: By redraiment
@echo off
:loop
if "%1"=="" goto end
curl "http://www.chinadomain.com.cn/whoischeck.asp?domain_type=en_domain&ifcn=en&name=%1&imageField44.x=0&imageField44.y=0&suffix=.com&suffix=.com.cn&suffix=.cn&suffix=.net&suffix=.net.cn&suffix=.org&suffix=.org.cn&suffix=.biz&suffix=.info&suffix=.mobi&suffix=.tel&suffix=.me&suffix=.cc&suffix=.hk&suffix=.tv&suffix=.asia&suffix=.name&suffix=.gov.cn" 2>nul | grep -Eo "%1(.[a-z]+)+</td><td[^>]*>可以注册" | grep -Eo "^[^<]*"
shift
goto loop
:end

  运行效果如下图所示(查询 CSDN redraiment 的可用域名):
  



2009-09-24

内网IP自动获取V2

内网IP自动获取V2

redraiment, 2009-09-24




  为解决上内网问题,我需要找一个 DHCP 未分配的 IP 地址来使用,在《内网IP自动获取》一文中的批处理能成功实现自动搜索。原理是逐个尝试地址是否可用,测试方法就是将本地地址设置成指定的静态 IP,然后去 ping 网关,直到找到一个成功的地址。但这种方法有些美中不足:
  1. 通过 netsh 设置本地静态 IP 比较耗时间;
  2. 如果 IP 已经被分配就会弹出一个消息框需要手工确认,因此并不算真正的自动化。
  在前一篇评论里也有朋友在问,能 ping 通的主机就是在线主机,这样只要搜索不能 ping 通的 IP 地址即可。其实不然,大部分防火墙默认都开启了防 ping 规则,ping 都会被拦截,因此即使在线也 ping 不通。但转念一想:如果主机在线,它的物理地址机会记录在 ARP 列表里,在 ping 完一个地址后到 ARP 列表中检查是否存在该地址的记录,就可以确定这个地址是否已经被 DHCP 分配出去!用下面的代码去替换《内网IP自动获取》中的 scan 模块:
:scan
arp -d
for /l %%d in (2,1,253) do (
  ping -n 1 %~n1.%%d & arp -a | find " %~n1.%%d "
  if ERRORLEVEL 1 (
    netsh int ip set address "本地连接" static %~n1.%%d 255.255.255.0 %1 1
    ping -w 10 -n 1 %1 | find /I "TTL"
    if NOT ERRORLEVEL 1 (
      netsh int ip set dns "本地连接" static 210.33.88.1 primary
      exit
    )
  )
)
  这段代码只在最终找到可用地址后才设置本地地址,执行效率比上一版本要高,但也有美中不足的地方:首先需是要清空 ARP 列表(arp -d),而清空列表操作需要有管理员权限才能执行。比如在 VISIA 系统中,需要右击批处理文件,选择“以管理员身份运行”。不过介于大部分人都是以 Administrator 的身份登入系统,所以不用太担心。呵呵。

2009-09-23

内网IP自动获取

内网IP自动获取

redraiment, 2009-09-23





  在寝室上内网真的是很闹心呀~稍微迟点开机,IP 地址就被别人抢去了。昨晚九点放学后,一直等到十点半才连上,实在忍无可忍了!
  IP 被抢后解决方法无非就是找一个没被占用的地址,但手工去测试 256 个地址太折磨人了,早些时候我们班的两个同学就分别用 Java C# 来实现过类似的小工具。但解决这样的小问题有点杀鸡用牛刀的感觉,不符合我的性格^_^,我当然还是用批处理来解决。
  批处理中核心的两条语句就是:
设置静态IP地址
netsh int ip set address "本地连接" static IP地址 子网掩码 网关 1
设置域名解析器
netsh int ip set dns "本地连接" static 域名解析器地址 primary

  程序使用时需要提供一个网关地址,为了方便大家使用,在 XP Vista 系统能自动检测网关地址,如果正确的话直接敲一个回车就可以了。下面是批处理的代码,大家只要将下面的代码复制到记事本里,另存为 sip.bat,双击即可运行。
:: 自动查找可用 IP
:: 适用于浙江工商大学
:: by redraiment
@echo off
setlocal enabledelayedexpansion

if NOT "%1"=="" goto scan

:: 检测可识别的系统版本
:: XP
ver | find "[版本 5"
if NOT ERRORLEVEL 1 (
  set SV=XP
  set CG='"ipconfig|find /I "gate""'
  set TS=13
)

:: VISTA
ver | find "[版本 6"
if NOT ERRORLEVEL 1 (
  set SV=VISTA
  set CG='"ipconfig|find /V "::"|find "网关""'
  set TS=15
)

if NOT "%SV%"=="" (for /F "tokens=%TS%" %%i in (%CG%) do set g=%%i)
echo 您的网关可能是:!g!
set /P gateway=如果不正确请重新输入,否则输入回车:
if "!gateway!"=="" set gateway=!g!
echo %0 !gateway!
pause
exit

:scan
for /l %%d in (2,1,253) do (
  echo 正在验证 %~n1.%%d 是否被占用 ...
  ping -w 10 -n 1 %~n1.%%d | find /I "TTL"
  if ERRORLEVEL 1 (
    echo 设置本地IP ...
    netsh int ip set address "本地连接" static %~n1.%%d 255.255.255.0 %1 1

    echo 测试连接网关 ...
    ping -w 10 -n 1 %1 | find /I "TTL"
    if NOT ERRORLEVEL 1 (
      echo 恭喜,%~n1.%%d 可用!
      echo 设置域名解析器 ...
      netsh int ip set dns "本地连接" static 210.33.88.1 primary
      exit
    )
  )
)
  下面是在 XP 环境下运行的效果图,它将本地 IP 设置成 10.230.71.6
  



2009-09-11

解决 Debian 升级后小键盘失效

解决 Debian 升级后小键盘失效

redraiment, 2009-09-11

  经过两个月的假期,寝室里蒙上了厚厚的一层灰。擦桌子、拖地、刷马桶……忙得不亦乐乎!回到实验室,第一件事就是“aptitude update && aptitude upgrade”。
  经过一段不算漫长的等待,Debian 以崭新的面貌展现在我面前。但想输入密码的时候发现小键盘没反应了:按“Num Lock”指示灯还会改变,回车也依然有效,按数字却就“没反应”。再仔细观察一下,发现按“8、2、4、6”时,鼠标指针分别按“上、下、左、右”移动。莫非这就是传说中的“鼠标键”?
  打开“键盘手选项”,切换到“鼠标键”,“允许键盘控制鼠标指针”这个选项果然是选中了,去掉后就恢复正常了。难道升级后覆盖了原来的配置文件,大家有没有遇到过这个问题?

2009-09-05

DuplexPipe二三事(六)——没有第七

DuplexPipe二三事(六)——没有第七

redraiment, 2009-09-04

我的设想





  在着手编写 DuplexPipe 之前,我规划过我的需求:我想要一个最通用的通信工具,换言之就是能让所有具有输入/输出的程序都可以相互通信。DuplexPipe 本身远没达到这个设想,至少还得具备以下几中模式:
-f file       # 通过读写文件获得数据
-s            # 从 stdio 中获得数据
-e exefile    # 从本地程序的输入输出中获得数据
-r url        # 这是一个附加功能。如果你玩过几天木马,你可能也渴望将它变成一个强大的后门!通过这个选项可以从URL中获得IP地址和端口,主动进行连接。

没有第七

  但我会很遗憾的宣布,上述功能不会被加入 DuplexPipe 中。这也意味着介绍 DuplexPipe 到此为止,不会再有《DuplexPipe二三事(七)》,关于 DuplexPipe 维护的动态则会更新在项目主页 http://code.google.com/p/duplexpipe/ 中。
  你可能听说过:“一篇文章的完成不是再也不能往里面加内容,而是再也没法删内容时。”写程序也是如此。我们来看上面提到的四个功能:
-f file       # 这条可以最先被排除,因为主流的系统都支持输入输出重定向('<'、'>'和'>>')。
-s            # -s 和 -e 两种模式 nc 都支持!写程序也很机会重复制造车轮。
-e exefile    # 理由同上
-r url        # 这个功能虽然诱人,但很明显和主要功能无关,没必要保留。
  因此,前三个功能都可以通过和 nc 配合来完成(瑞士军刀 nc 的使用方法请参看《DuplexPipe二三事(二)》)!而且现在 Http Client 遍地开花(例如 wget curl),要完成第四个功能也很简单。比如我用来搞定我们校园内部计算机的 Shell 脚本:
#!/bin/sh

# 外网计算机的IP文件,格式是ip port
IP_FILE='http://www.xxx.com/ip.txt'

while true
do
    wget -O ip.txt $IP_FILE
    read ip port < ip.txt
    java -jar DuplexPipe-0.1_0.jar -v -c $ip $port -c 10.21.*.* 3389
    # 如果失败,每分钟尝试连接一次
    sleep 60
done

曲终

  善用身边的小工具,这是我推崇的“物尽其(奇)用”!也体现了 UNIX 的哲学:只提供机制,不提供策略。通过善用他人的成果,可以降低我们编码的复杂度,节省下更多的时间做更有意义的事情!



DuplexPipe二三事(五)——来自内网的呼唤

DuplexPipe二三事(五)——来自内网的呼唤

redraiment, 2009-09-04

穿越防火墙





  你是否曾经尝试过去连接一台远程计算机,却因为被防火墙拦截或路由器没有转发而造成无法通信?这是主动式连接的一个弊端:它依赖服务器的状态,而对服务器有生杀大权的只有管理员。如果能让服务器主动尝试连接我们的计算机,那就没问题了!因为防火墙、路由等一般不会过滤向外的连接(反弹式木马就是利用这一原理)。
  但以往的服务端程序都是采用监听本地端口的方式(比如 Windows 远程桌面程序监听本地 3389 端口),我们需要将它的连接方式改成主动连接外部网络的方式。我想你也一定要将想到(如果你看过《DuplexPipe二三事(四)》),用 DuplexPipe 来转换它的连接方式!

反弹式远程桌面

  在此以 Windows 远程桌面为例,演示如何用一个正向连接的程序实现反向连接。本次演示的环境:
  1. 主机A(客户端):处于外网,IP 地址为 60.180.*.*。系统环境为 Vista 家庭版,自带远程桌面连接客户端;
  2. 主机B(服务端):处于内网。系统环境为 Win XP SP2,并开启了远程桌面服务
  具体操作步骤如下:
  一、将客户端的“连接式”转换为“监听式”。
打开命令提示符,执行:
java -jar DuplexPipe.jar -l 1234 -l 3389

  
  二、将服务器端“监听式”转换为“连接式”,并连接客户端监听的 1234 端口。
打开命令提示符,执行:
java -jar DuplexPipe.jar -c 60.180.*.* 1234 -c localhost 3389
  
  三、启动客户端上的远程桌面连接程序,连接本地的 3389 (默认)端口,即可连接成功!
  
  连接成功后:
  

总结

  如果你能理解上面的操作,就可以照样画葫芦去连接任何其他程序!我在前面提到过,DuplexPipe 目前还有待完善,那它以后还会添加些什么功能?会不会发展成为一个反弹式木马?请看《DuplexPipe二三事(六)》。

2009-09-04

DuplexPipe二三事(三)——网络中转站:端口映射

DuplexPipe二三事(三)——网络中转站:端口映射

redraiment, 2009-09-03

端口映射





  在《DuplexPipe二三事(二)》中介绍了瑞士军刀 nc 的用法:nc 就像给程序一张飞机票,让原本只能在本地执行的程序也能运行在网络上!但网络和现实交通一样,很多地方需要中转才能到达(比如外网计算机无法直接访问公司内部 Web 服务器)。
  为实现公网对内部网络的访问,需要对数据进行转发(即端口映射)。比如内网“主机A”开启了 Web(port 80)服务,需要在“服务器的网关”上设置:凡来自 Internet 上对 80 端口的请求,全部转发给内部网络中的“主机A”。这里的“服务器网关”可以是路由器、交换机或者一台 PC

工具简介

  FPipe 是一款命令行下的端口映射工具,可以映射 TCP/UDP 协议,支持连接数的最大上限。你可以从它的官网(http://www.foundstone.com)下载到最新版本。下面是它的用法和几个常用的选项:
FPipe [-hvu?] [-lrs <port>] [-i IP] IP
  -l 在本地监听的端口
  -s 从哪个端口发送出重定向的信息
  -r 要定向到IP主机的端口号
  -u UDP 模式
  -v 详细地显示过程
示例:
  FPipe -v -l 80 -s 90 -r 80 192.168.1.100
  作用就是将来自本机80端口的信息,通过90端口,转发到主机192.168.1.100的80端口上去。
  你可以尝试执行:“FPipe -l 80 -s 80 -r 80 203.208.39.160”,然后访问“http://localhost/”就会打开 Google 首页,因为203.208.39.160就是 Google 主机的 IP 地址,^_^。更多的内容请参见程序附带的帮助文档。

总结

  对于在《DuplexPipe二三事(一)》中提出的“进程通信”问题,nc 可以让本地程序通过网络进行通信;本文介绍的 FPipe 就像一座桥梁,让内网和外网的网络程序也能顺利通信。但可惜 FPipe 本身不够灵活,它只有“监听本地端口,连接远程主机”这一种通信模式。用来应付服务端监听、客户端主动连接的 C/S 模式还可以,如果碰到两端都监听或两端都主动连接的网络程序,就无能力为了。为解决这个问题,需要清除我们的主角——“DuplexPipe”,详细内容请看《DuplexPipe二三事(四)》。

DuplexPipe二三事(四)——网络连接方式随心换

DuplexPipe二三事(四)——网络连接方式随心换

redraiment, 2009-09-04

连接方式





  在《DuplexPipe二三事(一)》中提到建立连接有两种方式:监听本地端口,等待其他程序来连接(以下简称“监听方式”);或者主动连接其他程序(以下简称“连接方式”)。排列组合一下,会得到三种结果:监听-连接、监听-监听、连接-连接。其中只有“监听-连接”方式能正确地建立连接,《DuplexPipe二三事(三)》中介绍的 FPipe 只是在其中添加了一节“监听-连接-监听-连接”,其中粗体部分就是 FPipe 的工作。
  那有没有办法让“监听-监听”、“连接-连接”这两种方式也能通信呢?或者说,有没有办法在不修改程序的前提下转换它的连接方式?这就是 DuplexPipe 提供的功能!

DuplexPipe简介

  DuplexPipe FPipe 类似,也是命令行下的转发工具,但它允许你自己选择连接方式,因此比 FPipe 更加灵活!DuplexPipe 目前还只有 Java 实现方式,开放源代码,目前还不支持 UDP 模式。欢迎有兴趣的同学一起参与开发和维护!项目主页:http://code.google.com/p/duplexpipe。下面来介绍一下它的选项和用法:
用法: java -jar DuplexPipe [-vh] model model
选项:
        -v              输出一些提示信息
        -h              显示本帮助文档
模式:
        -l port         监听本地端口
        -c host port    连接远程端口
示例:
        java pipe.DuplexPipe -c 192.168.1.100 3389 -l 1234
        将本地 1234 号端口上的信息转发给 192.168.1.100 的 3389 端口,这样的用法类似 FPipe。
  由上述可知,执行“java -jar DuplexPipe -c host1 port1 -c host2 port2”就能让“监听-监听”方式的两个程序通信;执行“java -jar DuplexPipe -l port1 -l port2”可以让“连接-连接”方式的两个程序交流。

总结

  从功能上来说,DuplexPipe FPipe 有部分重合,不过这并不是 DuplexPipe 的亮点。思索一下你会发现它能做很多事情!你不想知道我是如何用它将“Windows 远程桌面”改造成反弹式连接的吗?你不想看看怎么让这些小工具配合来创造一个后门?请看《DuplexPipe二三事(五)》。

2009-09-03

DuplexPipe二三事(二)——瑞士军刀再显锋芒:让程序相互聊天

DuplexPipe二三事(二)——瑞士军刀再显锋芒:让程序相互聊天

redraiment, 2009-09-02

瑞士军刀NC





  nc(NetCat)是我很喜欢的一个小工具。在我常用的网络小工具中使用频率仅次于 cURL nc 属于传输层的工具(TCP/IP 四层模型请看这里),它能保证准确无误地发送和接收数据,但并不关心数据的具体含义(这些工作交给应用层的软件)。难怪说 nc 是网络的瑞士军刀,因为所有应用层的软件都是通过各自的网络协议来解析来自传输层的数据。所以,只要你了解应用层协议(比如HTTP、POP3等),就可以手工模拟出任何服务端或客户端程序。而且,只要你愿意,以后设计网络程序完全可以只实现一个“解析器”,数据传输的工作则全权交给 nc 了。

常用功能

  网络程序要建立连接有两种方式:主动去连接、监听本地端口等待连接。nc 也提供了这两种方式:
1) nc host port
    主动连接 hostport 端口。
2) nc -l -p port
    监听本地 port 端口,等待其他程序来连接。
示例:
    运行 nc g.cn 80
    这样就连接上“谷歌中国”的服务器,输入“GET / HTTP/1.1<CR><CR>”(不包括引号,其中<CR>是回车,这里需要敲两次回车),服务器就会返回“谷歌”首页的 HTML 源代码。
  上面是一个网络程序最基本的功能,默认下输入输出为 stdin stdout (也就是“键盘”和“屏幕”)。nc 让我最欣赏的就是“-e”选项,通过它能将输入输出重定向到本地可执行程序。例如在 windows 环境下执行:
nc -l -p 1234 -e cmd.exe
  这样,从端口 1234 获得的数据都会转发给 cmd.exe ,而 cmd.exe 的输出也会返回给网络。此时的 nc 就像一件外衣罩在 cmd.exe 上,让原本不具备网络通信功能的 cmd.exe 也成为网络程序。更多关于 nc 的用法可以参见这里

程序自动“聊天”

  如果你能理解上述 nc 的用法,那解决《DuplexPipe二三事(一)》中提到的进程通信问题也就很简单了!打开两个终端分别执行:“nc -l -p 1234 -e 24.sh”和“nc localhost 1234 -e r24.sh”,这样两个 Shell 脚本就通过本地 1234 端口进行通信了!我就是用这种方法让我的 ThinkPad 疯狂了一把~

总结

  作为一个通讯工具,nc 最神奇的地方就是能让本地非网络程序(比如 cmd.exe)实现网络通讯。但如果是两个网络程序,因为某种原因没办法直接建立连接(比如想在外网访问内网服务器),此时 nc 就无能为力了。这时候需要做的就是数据转发(端口映射),《DuplexPipe二三事(三)》中会介绍如何用 FPipe 来实现端口映射。



2009-09-02

DuplexPipe二三事(一)——有趣的起因:算24

DuplexPipe二三事(一)——有趣的起因:算24

redraiment, 2009-09-02





  写 DuplexPipe 是因为“无聊”!真的,那天很无聊,想起小时候用扑克牌和姐姐比赛算24,就随手写了一个 Shell 脚本重温一下:
#!/bin/sh

for ((i=0;i<4;i++))
do
    ((n=$RANDOM%10+1))
    echo -n "$n "
done
echo

i=0
while read exp
do
    ((i++))
    ((value=$exp))
    if [[ $value -ne 24 ]]
    then
        echo -n "Wrong! "
        echo "$exp=$value"
        echo "try again!"
    else
        echo "OK!"
        echo "Total use ${i}s"
        break
    fi
done

  最近好像养成一个习惯:能让计算机自动处理的尽量不制作。才玩了几盘,就开始动歪脑筋要写一个求24的程序来自动计算。方法就是最简单的穷举,下面是一个最初的简陋版本(有兴趣的朋友可以在此再添加五种括号):
#!/bin/sh

s[0]='+'
s[1]='-'
s[2]='*'
s[3]='/'

read a b c d

for ((i=0;i<64;i++))
do
    ((k=i%4))
    x=${s[$k]}
    ((k=i/4%4))
    y=${s[$k]}
    ((k=i/16))
    z=${s[$k]}
    e="$a$x$b$y$c$z$d"
    r=`echo $e | bc -l | sed -e 's/\.0\+$//'`
    if [[ "$r" == "24" ]]
    then
        echo "$e=$r"
    fi
done
  既然能让计算机自动计算结果,那我先运行程序1,显示4个随机数;运行程序2,输入程序1生成的4个数字,获得结果后再反馈给程序1。但转念一想:我这样手工进行输入输出的工作,不是比算24本身更枯燥、单调?而且是重复的劳动!理所当然应该由计算机自动完成。
  为完成这个任务,计算机要做的就是让“程序1”和“程序2”进行聊天:“程序1”的输出作为“程序2”的输入、“程序2”的输出作为“程序1”的输入。这一定义会让人立刻联想到“管道”(exe1 | exe2),但遗憾的是“管道”是单向的——只能满足“程序1”的输出作为“程序2”的输入。
  其实这就是一个“进程通信”(IPC)的问题,如果你熟悉 UNIX 的历史,也会和我一样联想到 Socket 。我随即想起了网络瑞士军刀——nc(netcat),并用它顺利解决了这个问题!我会在《DuplexPipe二三事(二)》中介绍这个方法。