【看雪2017安全開發者峰會演講回顧0x8】那些年,你怎麼寫總會出現的漏洞
看雪編輯按:隨著專案的業務模組越來越多,程式碼越來越零碎,協同開發的重要性不言而喻。越來越多的專案由多個程式設計師或者多個部門的技術人員進行協作開發。但是由於程式設計師的水平及經驗參差不齊,相當大一部分程式設計師在編寫程式碼的時候,沒有對使用者輸入資料的合法性進行判斷,從而使得應用程式存在安全隱患。作為一名合格的開發人員,不僅僅需要完成專案需求的業務功能,更要考慮到安全性。多數情況下,安全人員在對目標網站和系統進行挖掘漏洞的時候,都是黑盒測試,看不到具體的程式碼邏輯。本次議題站在不同水平程式設計師的角度從程式碼層面來分析為什麼寫出的程式碼會有漏洞,以及如何去防禦此類安全問題。
以下內容為鄧永凱演講實錄,由看雪學院(微信公眾號:ikanxue)整理。
鄧永凱
鄧永凱,綠盟科技安全工程師,主要負責綠盟科技的系統和web漏掃開發工作,並擔任攻防產品攻防代表,後加入研究院做web和IoT安全研究的工作,電子雜誌《安全參考》、《書安》創辦人。
鄧永凱:大家下午好。很榮幸跟大家探討關於安全開發的問題。為什麼取這個名字《那些年,你怎麼寫總會出現的漏洞》?今天是安全開發者大會,在座各位基本上都是開發為主的,我們在開發的過程當中不僅僅要把功能完善好,也要注意在開發過程中的安全問題,是不是你就會在你的程式碼裡面埋下一些雷。
今天主要從這三個方面給大家展開來講,利用大量案例講解初級程式設計師、高階程式設計師以及瘋狂程式設計師,他們在開發編碼的過程當中是怎樣把漏洞寫出來的。為什麼我加了防禦、做了過濾、漏洞已經修復還是不斷被黑客攻擊?
1、初級程式設計師的寫法
初級程式設計師開發的時候基本上不會考慮安全問題,因為他只要把任務完成了,功能開發OK了,上線執行OK就可以了,他不會考慮到安全漏洞,或者沒有安全開發的概念。
很簡單,直接獲取引數進到資料庫操作裡面,一個赤裸裸的注入。
$id
= $_POST[ 'id' ]; // Check database 上下文無過濾處理 $query = "SELECT name
FROM users WHERE user_id = 通過GPC獲取引數 '$id';"; $result = mysql_query(
$query ) or die(mysql_error() ); 直接帶入資料庫操作
直接把引數拼接到系統命令裡面,執行命令裡面,很暴力的命令注入。
$target
= $REQUEST[ 'ip' ]; 上下文無過濾處理 $cmd = 'ping -c 4 ' . $target; 通過GPC獲取引數
$result = shellexec($cmd); //直接帶入執行命令 直接拼接系統命令 $html .= "
{$cmd}
"; 最後帶入命令執行函式
另外檔案上傳,直接獲取檔案上傳無任何判斷。
$target_path
= ROOT . "hackable/uploads/"; $target_path .= basename( $_FILES[
'uploaded' ][ 'name' ] ); //上下文無過濾處理,直接上傳任意檔案 //無判斷直接上傳檔案
move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path );
這些簡單例子功能上來看沒有問題,我可以查閱資料,可以執行命令,可以上傳檔案,但是有一個共同的缺陷就是,它獲取資料之後根本沒有考慮到使用者資料是正常資料還是惡意資料,如果傳入惡意資料那麼這些地方就會被黑客利用,那麼你的業務功能也就會存在問題。
初級開發者就會說:“我把東西只要寫完了,功能已經OK,上線正常執行了,你現在跟我說安全開發,什麼是安全編碼?我只是個寫程式碼的啊,你要我怎樣?”。
2、高階程式設計師的寫法
高階程式設計師經驗非常豐富做過很多專案,有很多的經驗。對使用者的資料進行一些處理,或者是加一些過濾,給業務裡面加一些軟WAF等。但是,雖然做了這些安全措施,如果不到位或者是不完整或者是錯誤的方法,錯誤的修復或者是加過濾了,結果是一樣的仍然存在漏洞。
比如獲取引數了,加入資料庫之前進行了處理,這個時候把使用者資料過濾了,但是在資料庫操作時這個ID沒有單雙引號的保護,這個過濾有什麼用?過濾跟沒有過濾不是一個樣子嗎?
無單引號保護:
$id
= $POST[ 'id' ]; //$id = addslashes( $id ); $id =
mysqlrealescapestring( $id ); // Check database $query = "SELECT name
FROM users WHERE userid = $id;"; $result = mysqlquery( $query ) or
die(mysql_error() );
//mysqlrealescape_string過濾 或者addslashes過濾 最後帶入資料庫操作
一些經驗的開發者在程式碼全域入口加上軟WAF服務,通過一些請求包把獲得的引數統一過濾了,都可轉義了,而且變數的資料庫進到資料裡面加上一些引號保護,也就是說想來注入,必須繞過我的單雙引號,這個時候就沒有辦法了,感覺很完美!
非GPC獲取引數:
foreach(array('COOKIE',
'POST', 'GET') as $request) { foreach($$request as $key => $value) {
$key{0} != '' && $$key = addslashes($value); $M['form'][$key] =
addslashes($value); } } //軟WAF: 全域性addslashes過濾GPC,全域性將變數雙引號保護
萬事大吉,完美!!!???
別忘了獲取資料不僅僅通過GET、POST、COOKIE,通過別的方式也可以獲取,比如FILES、SERVER,前面就沒有考慮。
非GPC獲取引數:
$pseudourl=$SERVER[REQUESTURI];
$dirs=explode('/',$pseudourl); $dirdirname=$dirs[count($dirs)-2];
$query="select * from setting where name='$dirdirname'";
$jump=$db->get_one($query);
//$SERVER[] $FILE[],不受全域性軟WAF影響
上傳這個檔案的考慮你的檔案有單雙引號嗎,這樣就不受全域性軟WAF的影響。通過count做一些資訊帶到庫裡面,雖然軟AWF服務,但是這個裡面Select根本不受你的控制。
很多時候程式設計師在寫程式碼的時候會經過各種各樣的處理,在進行核心操作的時候比如說查詢資料庫或者進入資料庫的時候會給你一個反編碼,因為他害怕裡面有一些他不想要的東西,比如說不合法的東西,他先給你反編碼一下,或者說他乾脆給你一個反轉義,比如說反轉義,那麼前面處理轉義已經沒有用了,而且進入資料庫的時候跟他有一個反編碼、反轉義,那提交資料的時候編碼不就行了嗎,多來幾次編碼,編碼之後就沒有惡意資料了,提交資料後你再反轉義反編碼不照樣惡意資料就還原回去了。
編碼等:
$pseudourl=
addslashes ($POST[‘url’]); $dirdirname =urldecode($pseudourl); //
$dirdirname =base64decode($pseudourl); // $dirdirname
=stripslashes($pseudo_url); $query="select * from setting where
name='$dirdirname'"; $jump=$db->getone($query);
//URL編碼繞過 Base64編碼繞過 反轉義繞過 ......
還有其他的案例,它想到了安全問題,你要逃逸單引號,我把你變成兩個單引號,單引號成對出現之後就沒有逃逸功能,就沒有辦法注入了。我輸入單引號你給我編兩個單一號,我輸入一個斜槓單引號,但是斜槓並沒有處理,斜槓是一個轉義的的功能。(如果資料庫用的是postgresql,就沒有辦法繞過了,因為它每個這個反斜線。不同的資料庫也有不同的效果。)
替換:
String
assetIp = Request(‘address'); String conditionSql = "and (e.sip='"
+assetIp.replaceAll("'", "''") +"')"; //String querySql = ......
Conn.Execute(querySql );
//Mysql: \' Bypass //Postgresql: No Bypass
下面這個案例是一個意料之外的問題。這個都進入到那個prepare裡面,把裡面’%s’,”%s”統一替換為’%s’,要注入首先逃逸單引號,但是前面做了處理逃逸單引號是不可能的,所以是沒有問題的。
格式化字串:
$A
= prepare(" AND metavalue = %s", $value1); $B = prepare("SELECT * FROM
table WHERE key = %s $A", $value2); //'%s' 和 "%s"替換為'%s' function
prepare( $query, $args ) { $query = strreplace( "'%s'", '%s', $query );
//Bypass必須逃逸單引號 $query = str_replace( '"%s"', '%s', $query ); $query =
pregreplace( '|(?
'|(?
這樣來看可能是沒有問題,他所有的東西都包括進來了,而且對方想要逃逸單雙引號是不可能,恰恰是格式化的時候就有一個問題,比如說這是一個合法格式化的東西,格式化的內容。
格式化字串:
輸入:
1
%1$%s (here sqli payload) -- , dump AND metavalue = %s AND metavalue =
'1 %1$%s (here sqli payload) --' SELECT * FROM table WHERE key = %s AND
metavalue = '1 %1$'%s' (here sqli payload) --' SELECT * FROM table WHERE
key = 'dump' AND metavalue = '1 _dump' (here sqli payload) --'
/* %1$'%s 1 第一個引數 $型別 ' 附加值padding % padding字元 */
第一次進入prepare函式之後進行一個替換,變成下面的一個,這還是’%s’,再替換一下,有一些資料庫拼接起來,所以這個地方紅色標入的地方都有一個單引號。但是那個單引號最後被吃掉了,為什麼中間單引號不見了,這就是格式化字串的東西。
這個東西1就是代表了格式化第一個型別,後面那個單引號是幹什麼,是格式化時候的一個附加值用來做padding的,比如說單引號後面必須有一個字元,如果這個字元不夠會以單引號後面的另外一個字元附加進去。附加多少也是在後面一個數字,如果你不給數字的話就返回空,比如說這個裡面單引號%S,就是不加任何東西反饋一個空,這個時候恰恰那個裡面一個單引號就被當成Padding功能幹掉了,這個時候就逃逸單引號進行注入了,這是一種繞過方法。
格式化字串:
輸 :空格%s空格, array(_dump, OR 1=1 --)
AND metavalue = %s AND metavalue = ' %s '
SELECT
* FROM table WHERE key = %s AND metavalue = ' %s ' SELECT * FROM table
WHERE key = '%s' AND metavalue = ' '%s' ' SELECT * FROM table WHERE key =
'dump' AND metavalue = ' ' OR 1=1 -- ' '
另外一種繞過方法,可以傳入空格+%s+空格,第一次替換變成這樣,這樣會不會有問題?如果第一個%S被拒了是不是就直接執行了?這個是合法,而且可以成功執行。看起來是非常正常而且考慮很多功能的程式碼,還是會產生很多的問題,也有很多辦法可以繞過。
做專案的時候有這樣一個案例,在前臺找到注入管理的帳號,但是管理員沒有辦法登陸,因為找不到後臺,前臺的功能有限,所以做滲透測試的時候拿不到shell都是耍流氓。你找不到後臺,前臺沒有辦法讓你登陸,你就只能看程式碼。前臺限制登陸的時候,有這樣一個程式碼。如果你登入的使用者名稱是admin就直接退出了,前臺登不了,後臺也登不了,這樣寫大家看看是不是沒有問題,但是這裡存在一個登入繞過。
字符集:
$mysqli->query("set
names utf8"); $username = addslashes($_GET['username']); if ($username
== "admin"){ die("not loing use admin"); } $sql = "SELECT *
FROM users WHERE user='{$username}'";
//無法找到後臺 前臺禁止admin登入 //程式設計師: 我不讓你admin使用者登入,你還能奈我何?
Myspl儲存資料的時候有格式,首先是字符集用什麼語言儲存,哪種比對格式,Ci,大小寫不敏感。那麼ADMIN前面判斷不等admin,但是查詢出來這個結果是一樣的。這樣ADMIN就繞過了。
字符集:
繞過方法一 http://localhost/kanxue.php?username=AdmiN
Mysql儲存字元的格式: 字符集語言比對方式 例如:utf8generalci/cs/bin ci=case insensitive 大小寫不敏感 繞過判斷!
第二種情況,剛剛前面也有一句話程式碼set names utf8,這個功能是什麼,將這個客戶端所有的字符集都變為utf8,服務端模擬為latin1,這字符集有差異,有差異的時候就會進行這個字符集的轉換,轉換的過程中就有這個錯誤的編碼字元。繼續繞過!
字符集:
繞過方法二: http://localhost/kanxue.php?username=admin%D3
set names utf8 客戶端(php mysqli)字符集utf8 服務端(mysql)字符集latin1 字符集轉換導致繞過 繞過判斷!
獲取一個使用者名稱,獲取一個密碼,密碼Md5加密,看你使用者名稱密碼對不對,這是很簡單的幾句話。剛剛開始看的時候我也沒發現有什麼問題,但是你注意到這個MD5有兩個引數,一個是字串,一個輸出格式。第二個引數預設為False。如果為True就是以16位原始二進位制字元返回,如果是False就是32位十六進位制數。如果輸入129等等一大串之後,返回的內容裡面有一個單引號’Or’8其他字元,這個時候相當於一個萬能密碼。
為什麼呢,把後面那個密碼帶到那個密碼之後,’Or’8其他字元就相當於萬能密碼了,而且這個O單引號的後面必須是數字開頭,這個時候查詢出來的資料是OK的,相當於一個萬能密碼繞過。如果’Or’8其他字元後面是字母或者非數字的話就不行了,因為’Or’的字元是數字開頭則永遠返回True,這個時候就繞過了。可以寫一個指令碼爆破一下,只要有一個單引號數字開頭的就可以了,就可以繞過了。
md5:
$username
= mysqlrealescapestring ($POST['username']); $password =
md5($POST['password'], TRUE); $query = "select *
from userswhere username= '$username' and password='$password'"; $result
= $db->getone($query); if ($result == TRUE ){ echo "login success"; }
//登入繞過
前面都是各種資料傳輸過程中出現了缺陷,有一些比較聰明,把資料在傳輸過程中都簽名一下,簽名的過程中肯定有金鑰,金鑰拿不到,你沒有辦法偽造的簽名,你有問題也沒辦法利用。但是簽名並不是萬能的。萬一您的Key被洩露了怎麼辦,或者你的Key直接可以破解。你的Key通過各種各樣的途徑被洩露,或者是被破解。這些例子具體就不講了,因為每一個例子都很多樣式,我們部落格(http://blog.nsfocus.com
)裡面可以把這個東西搜尋出來看一下,只要你的Key洩露之後就繼續偽造資料進行注入,進行漏洞利用。
md5:
string
md5( string $str [, bool $raw_output = false] ) String:必需。規定要計算的字串
Raw:可選。 TRUE - 原始 16 字元 進位制格式 FALSE - 預設。32 字元 六進位制數
字串:129581926211651571912466741651878684928
Md5(‘129581926211651571912466741651878684928’, TRUE) TRUE - 原始 16 字元
進位制格式: ?T0D??o#??'or'8.N=? FALSE - 32 字元
六進位制格式:06da5430449f8f6f23dfc1276f722738
1、通過快取介面獲取包含auth_key的快取資料(PHPCMS)
2、通過未授權訪問配置檔案獲取auth_key(PHPCMS)
3、設計缺陷導致任意檔案下載洩露auth_key(PHPCMS)
4、通過二次注入、接力注入等繞過auth_key驗證(PHPCMS)
5、偽隨機數缺陷導致auth_key被破解(PHPCMS、Discuz!X)
6、Hash長度擴充套件攻擊導致auth_key被破解(PHPWind)
7、忘記使用token驗證接 (WordPress nonce機制)
拿到Auth_key後即可SQL隱碼攻擊、GetShell等 http://blog.nsfocus.net/
二次漏洞利用,大家經常聽到這樣的話“使用者一切輸入都是有害的”,這句話說得還不夠完整,應該是“進入核心操作的一切資料都是有害的”。因為資料在系統裡面核心操作的時候,這些資料不一定是使用者直接傳進來的,也有可能是從其他地方查出來的,比如說另外一個系統,另外一個儲存介質或者另外一個資料庫或者配置檔案裡面取出來的,你取出來之後在某一天某一個時刻,通過另外一個地方又傳進去了,就是來回的處理的過程,這個裡面會引發多次的漏洞利用。
比如說使用者先輸入了一個資料,插入這個資料庫裡面了,或者插入到檔案或者全域性陣列裡面,跟蹤了一大堆但是他沒有利用這個資料,但是存到儲存介質裡面,某一天某一個時刻他從這個儲存介質裡面取出來了,因為你在想你是從資料庫或者儲存介質裡面取出來東西,不是使用者直接傳給你,他就是安全的,你可以直接進行操作了。但是你取出來這個資料,是有隱患的資料,是不可信任的資料。比如說先插入一個使用者名稱,進行操作的時候轉義了。某一天取出來了,取出來了之後他想這是我取的東西,不是使用者輸給我的再進行一次操作,再繼續注入,這是很簡單的一個二次注入。
某知名攝像頭0day:前面有一個設定資料的地方,第一次先設定進去,第二次再取出來,取出來之後沒有進行處理直接命令執行,這樣就可以利用。
二次命令執行:
public
function update() { $this->conf->set($POST["group"],
$_POST["param"], $POST["value"]); } protected function
index(&$vparams) { $vparams["TimeFormat"] =
$this->conf->get("Video", "TimeFormat"); passthru("date +\"" .
$vparams["TimeFormat"] . "\""); }
還有把上面所有東西加起來一起用,有很多的方法來防禦,我也有很多的方法繞過。
在檔案上傳的時候我給你限制各種能執行的字尾,但是有三種方法,第一個給bypass.php加一個X,這個x是%80-%99。
第二個是在windows,小於號代表星號,星號可以代表任何字元,第一次傳一個空檔案,然後在覆蓋之前的檔案。
第三種就是直接::$DASTA,就是這個資料流。
php邂逅windows:
$upfile
= $FILES['file']['name']; $filesuffix = strtolower(substr($upfile,
strrpos($upfile, '.') +1)); $notallowext = array( "php", "phps", "php3",
"exe", "bat" ); if (inarray($filesuffix, $notallowext )){ die( " File
type error.. "); }
/* 1、bypass.phpX 2、bypass.php:jpg bypass.<<< 3、bypass.php::$DATA */
另外一個通用方法就是直接在檔案後面加/.,在開啟這個檔案先判斷這個檔案是不是目錄,如果目錄就報錯,不是目錄就會開啟。怎麼判斷是不是目錄,就要以斜槓,不是斜槓就是開啟。獲取最後開啟檔案長度的時候,把那個斜槓那個點去掉了,經過一切處理,就直接開啟了,就導致任意程式碼寫入了。
通用繞過:
$content
= $POST['content']; $filename = $POST['filename'];
if(preg_match('/.+.ph(p[3457]?|t|tml)$/i', $filename)){ die("Bad file
extension"); }else{ $f = fopen($filename, ‘w’); fwrite($f, $content);}
/* filename=kanxue.php/. filename=kanxue.php/././. filename=kanxue.php/////. */
還有GD庫的處理,雖然我們上傳的圖片被gd庫處理了,但是如果我們上傳一個特意構造好的圖片,那麼處理後,圖片裡面存在php程式碼,這個時候字尾可控那麼就導致程式碼執行。
利用條件競爭,上傳檔案了,處理之後我給你刪了,但是你在刪了之後,再處理的過程中有一個時間差,利用那個時間差可以生成另外一個檔案。上傳了一個檔案,有一堆處理,處理之後刪除,但是再刪除之前有一個時間差,利用這個時間差可以寫多執行緒角本,不停請求再生成另外一個就可以了。
這是一個國外知名廠商的安全裝置的一個0day漏洞。
命令執行時使用easpaceshellarg和easpaceshellcmd,如果這兩個函式沒有用對的話,本來沒有漏洞就造出一個漏洞,就有這樣一個例子。你輸入一個引號他給你轉移,最後處理完了之後單引號不見了。
命令執行函式過濾:
string
escapeshellarg ( string $arg ) escapeshellarg()
將給字串增加一個單引號並且能引用或者轉碼任何已經存在的單引號,這樣以確保能夠直接將一個字串傳入shell
函式,並且還是確保安全的。對於使用者輸入的部分引數就應該使用這個函式。shell 函式包含exec(), system() ,執行運算子。
string
escapeshellcmd ( string $command ) escapeshellcmd() 對字串中可能會欺騙 shell
命令執行任意命令的字元進行轉義。 此函式保證使用者輸 的資料在傳送到 exec() 或 system() 函式,或者執行操作符之前進行轉義。
反斜線()會在以下字元之前插 : &#;`|*?~<>^()[]{}$\, \x0A 和 \xFF。 ' 和 " 僅在不配對兒的時候被轉義。 在 Windows 平臺上,所有這些字元以及 % 和 ! 字元都會被空格代替。
命令執行函式過濾:
$cmd
= 127.0.0.1' -v –d id=1 escapeshellarg() !'127.0.0.1'\' ' -v –d id=1'
escapeshellcmd() !'127.0.0.1'\' ' -v –d id=1\' $cmd = '127.0.0.1'\' ' -v
–d id=1\' $cmd = 127.0.0.1\ -v –d id=1'
命令執行、引數注入案例:
SquirrelMail (CVE-2017-7692) zend-mail (CVE-2016-10034) SwiftMailer
(CVE-2016-10074) PHPMailer (CVE-2016-10045) PHPMailer (CVE-2016-10033)
Nagios Core Curl (CVE-2016-9565)
命令執行的時候會限制你的字元,比如說這裡限制你的輸入內容必須是數字字母,我們可以用這兩個方法繞過。
命令執行限制字串:
function clear($string){ if(!pregmatch("/^\w+$/", $string)){ exit('
error'); } return $string; } $cmd = clear($GET['cmd']); system($cmd);
// Bypass 1: wget + redirect // Bypass 2: wget +tar + php
還有限制你的長度,根據輸出命令只能是七個字元或者五個字元,或者只能是四個字元,這個時候怎麼執行命令,拿不到shell?利用這種方法可以搞定,把你的命令分割了,切割之後建立成一個檔案,再利用各種各樣的構造,然後將命令輸入到一個檔案,構造完了之後再執行那個檔案,那個檔案裡面包含你所需要的命令。
命令執行限制長度一:
// Hitcon ctf 2015 // babyfirst
命令執行限制長度二:
// Hitcon ctf 2017 // Babyfirst revenge
命令執行限制長度三:
// Hitcon ctf 2017 // Babyfirst revenge V2
無法直接執行命令,將執行命令進行分割
將分割後的內容作為檔名建立檔案
使用ls命令將檔案按順序輸出到檔案中
最後執行生成的檔案
說來說去無論就是Bypass,Bypass真的是一門藝術,不同的人,不同的漏洞,不同的場景,具有不同的方法。架構層,資源層,規則層,人的層面都可以Bypass。你的程式碼寫的再好,肯定也有薄弱的地方。只要你有薄弱的地方,我就可以繞過你。
程式設計師們“狠死你們這幫黑客”,我寫了那麼多的東西,做了各種防禦你還各種繞,繞了還給我報到漏洞平臺,我天天加班。
3、瘋狂程式設計師的寫法
瘋狂程式設計師,一個重置密碼的功能就能有十幾種方法繞過,我想不通一個重置密碼功能這麼多人開發出不同的邏輯,這些邏輯裡面都有問題,都可以重置密碼。是不是很瘋狂?
這是某銀行的專案,修改A使用者資訊時,可以新增一個欄位,換成B使用者的手機號碼,正常情況下把A使用者資訊修改了,有漏洞的情況下把B使用者資訊修改了,它這兒不是,修改A使用者的時候A使用者資訊被B使用者資訊覆蓋了,而且把A使用者資訊刪掉了,還進入到了B使用者,如果你把B使用者修成一個老闆或者一個大BOSS,你瞬間進入到他的帳戶裡面去了,你就很有錢了。
場景:修改賬戶A資訊時,新增手機號欄位內容為受害者手機號B 正常情況:只能修改當前登入使用者A的資訊 越權漏洞:可以修改受害者B的使用者資訊 秒變富豪:當前登入使用者A的資訊被受害者B的資訊覆蓋,並且進入受害者使用者B,使用者A也被刪除
還有這樣一個專案只有一個登陸框,登陸不了什麼也幹不了,這是一個硬體裝置。把這個韌體下來,這裡面也有一大堆的引數,也沒有介面,訪問一下這個檔案,構造這個引數它真的可以訪問,而且直接進入到後臺了。想不通它這個是為什麼,估計是傳說中的後門。
還有指哪修哪,永遠修不好,永遠修不完。第四次繞過,第八次繞過,最後程式設計師被開除了。這是真實的案例。當時我們也提了很多的漏洞,他說他們已經把程式設計師開除了。
一切漏洞都來源於有缺陷的程式碼,但是一切程式碼都是可愛的程式設計師寫的,謝謝大家
想要獲取本演講PPT,
點選此處:檢視、下載哦!
相關文章
- 【看雪2017安全開發者峰會演講回顧0x1】如何黑掉無人機2017-11-21無人機
- 【看雪2017安全開發者峰會演講回顧0x5】Flash 之殤:漏洞之王 Flash Player 的末路2017-11-25
- Java JSON 反序列化之殤(看雪2017安全開發者峰會演講回顧11)2017-12-04JavaJSON
- 【看雪2017安全開發者峰會演講回顧0x3】淺析WEB安全程式設計2017-11-23Web程式設計
- 【看雪2017安全開發者峰會演講回顧0x6】智慧化的安全: 裝置&應用&ICS2017-11-27
- 【看雪2017安全開發者峰會演講回顧0x7】開啟IoT裝置的上帝模式2017-11-28模式
- [推薦][看雪2017安全開發者峰會演講回顧11]Java JSON 反序列化之殤2017-12-02JavaJSON
- 【看雪2017安全開發者峰會演講回顧0x9】Windows 10新子系統*新挑戰2017-11-30Windows
- 【看雪2017安全開發者峰會演講回顧0xA】移動APP灰色產業案例分析與防範2017-12-01APP產業
- 【看雪2017安全開發者峰會演講回顧0x4】業務安全發展趨勢及對安全研發的挑戰2017-11-24
- 【看雪2017安全開發者峰會演講回顧 0x2】定製化對抗——遊戲反外掛的安全實踐2017-11-22遊戲
- 看雪論壇版主座談 | 看雪2017安全開發者峰會2017-12-09
- 一石多鳥——擊潰全線移動平臺瀏覽器(看雪2017安全開發者峰會演講回顧12)2017-12-04瀏覽器
- 2017 看雪安全開發者峰會 圓滿結束!2017-11-21
- 回顧 2021 中國 .NET 開發者峰會2022-02-07
- Develop as One | 2021 Google 開發者大會主旨演講精彩回顧2021-11-20devGo
- TrustAsia(亞洲誠信)助力看雪2018安全開發者峰會2018-07-23Rust
- 精彩回顧 | 2021 Android 開發者峰會2021-12-11Android
- 2018 第二屆看雪安全開發者峰會 | 徵集贊助商2018-03-07
- 議題徵集 | 2017 安全開發者峰會2017-06-21
- 武漢科銳,助力2019 第三屆看雪安全開發者峰會,引航創新!2019-05-14
- 【資料合集】2017雲棲大會·北京峰會回顧合集:PDF下載2017-12-27
- 活動預告 | 網易易盾受邀出席7月20日北京舉辦的看雪安全開發者峰會2019-07-12
- OSRC攜手共建2020第四屆看雪安全開發者峰會,築夢未來!2020-10-12
- 【資料合集】2017雲棲大會·蘇州峰會回顧合集:PDF下載2017-12-12
- 百度安全攜手共建2020第四屆看雪安全開發者峰會,築夢未來!2020-09-24
- 2021 .NET 開發者峰會順利在網上落幕,線上直播回看彙總2021-12-19
- 極棒攜手共建2020第四屆看雪安全開發者峰會,築夢未來!2020-09-22
- 深信服攜手共建2020第四屆看雪安全開發者峰會,築夢未來!2020-10-15
- 限時2.5折購票 | 看雪安全開發者峰會將於7月21號火熱來襲!2018-06-21
- ZUK Edge怎麼樣 ZUK Edge釋出會圖文回顧2016-12-21
- 武漢科銳攜手共建2020第四屆看雪安全開發者峰會,築夢未來!2020-09-21
- 豹趣科技攜手共建2020第四屆看雪安全開發者峰會,築夢未來!2020-09-22
- 同盾科技攜手共建2020第四屆看雪安全開發者峰會,築夢未來!2020-10-07
- 2017 安全開發者峰會門票,2.5折限時搶購!2017-09-27
- 李開復就中國移動開發者大會的演講總結2010-10-21移動開發
- 榮耀5A怎麼樣 榮耀5A釋出會全程回顧2016-06-13
- 2010年RSA大會RSA總裁主題演講:雲的安全2019-05-13