Batch File Hacking
Essay by review • December 17, 2010 • Research Paper • 3,134 Words (13 Pages) • 1,520 Views
Batch files are much more powerful than most may initially believe, with sufficient knowledge one could use them to introduce directly executable code into a system. I will demonstrate how this can be done with a harmless example and explore other ways to perform the same task that may or may not be better in some way.
There are two main ways one could go about doing this, the first being incredibly easier. The first method utilizes echo statements that redirect their output to a file, this file being used much like a script by using its contents for "console input" into a program instead of the default keyboard. The program used is called debug and is on every computer running windows or dos AFAIK unless the user manually deletes it, and can be used to write and execute stuff in memory among other things. The second method is more difficult to prepare, but does not require debug to be present or accessible (many school machines e.g. disallow access to it) to execute the hidden code as if it were a program they downloaded instead of the batch (it actually uses the batch to write out the program to disk). when the programs are executed, it would be a good idea to have them wipe the script and/or program file itself so undeletion attempts won't yield any clues.
The example program will be an implementation of a program that goes full screen and makes your screen flash random colors (though inevitably optimizable). First off it would be wise to be fairly familiar with x86 assembly language and how dos works in order to write your own programs to be run, but I'll try to explain how things work for those who aren't. Yes it is possible to write it in something like C++, but you must be aware that it has to run in dos (though it could use dpmi in windows) and its easiest to do with .com files. Exes have lovely headers that you must meddle with for full compatibility, mmm fun (you can't load a .exe into memory via debug enter statements and expect it to execute properly at all because the way exe headers are interpreted during loading).
The example batch file before we start:
@echo off
echo e100 B8 13 00 CD 10 E4 40 88 C3 E4 40 88 C7 F6 E3 30>z.dbg
echo e110 DF 88 C1 BA C8 03 30 C0 EE BA DA 03 EC A8 08 75>>z.dbg
echo e120 FB EC A8 08 74 FB BA C9 03 88 D8 EE 88 F8 EE 88>>z.dbg
echo e130 C8 EE B4 01 CD 16 74 CD B8 03 00 CD 10 C3>>z.dbg
echo g=100>>z.dbg
echo q>>z.dbg
debug nul
del z.dbg
Basically what this does is make your monitor flash pseudo-random colors for every screen refresh until you hit a key, at which point it exits. There's a lot to be explained, however, to completely understand HOW it works from the ground up, knowing little or nothing of assembly or dos internals. Good thing I won't be explaining everything in excruciating detail.
To keep the batch file's size to a minimum, the program contained must also be as small as possible. Usually this means that you must use as many system calls as possible that are practical to do and tend not to do everything yourself. Granted, there are things you can't call the system to do for you, in which case the code should be further size optimized. In DOS, system calls are usually done by an assembly instruction mnemonic called INT, short for INTerrupt. For now, you can think of them as little black boxes that do what you want with the proper inputs and outputs until you read an assembly tutorial off somewhere where you'll realize there's really much more to it. Anyway, most software interrupts (usually used for system calls) take inputs in registers, which are like a select few speedy memory locations contained in the CPU itself. I guess I'd better explain and list the registers before I go further:
General Purpose (GP) registers:
AX - Accumulator
BX - Base
CX - Counter
DX - Displacement
BP - Base Pointer
SP - Stack Pointer
SI - Source Index
DI - Destination Index
Segment Registers (not explained here because they're not needed to understand the example, go to a tut for info):
CS - Code Segment
DS - Data Segment
ES - Extra Segment
FS - Extra Segment #2 (386+)
GS - Extra Segment #3 (386+)
SS - Stack Segment
Half of the GPregs (general purpose registers as I call them) can be broken up into byte-sized chunks and used as such. These would be the ones ending in X such as AX, its component registers being AH (Accumulator High, high byte of AX) and AL (Accumulator Low, low byte of AX). The remaining half of the group can only be accessed as 16-bit quantities. All GPregs can also be accessed as 32-bit entities, prefixed with E as in EAX for Extended Accumulator, beginning with the 386 (not like anyone cares, most people today haven't even heard of a 386).
I wrote the program above in debug, although you could do it in some symbolic assembler like nasm or fasm. Remember EVERYTHING in debug is either in hex or ascii. Here is a disassembly with corresponding addresses and hex encoded machine code eqivalents preceding each instruction mnemonic:
1370:0100 B81300 MOV AX,0013
1370:0103 CD10 INT 10
1370:0105 E440 IN AL,40
1370:0107 88C3 MOV BL,AL
1370:0109 E440 IN AL,40
1370:010B 88C7 MOV BH,AL
1370:010D F6E3 MUL BL
1370:010F 30DF XOR BH,BL
1370:0111 88C1 MOV CL,AL
1370:0113 BAC803 MOV DX,03C8
1370:0116
...
...