一篇文章带你读懂 TLS Poison 攻击(二)
2022-11-12 00:0:41 Author: 白帽子(查看原文) 阅读量:14 收藏

STATEMENT

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。

雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

NO.1 前言

本篇文章是《一篇文章带你读懂 XXX 攻击》系列的第二篇文章,主要讲述了 TLS Poison 攻击对应的三种攻击方式、一些可能算是“新”的 DNS Rebinding 技巧以及一些关于 IP 选择探索等内容。

使用《一篇文章带你读懂 XXX 攻击》的标题既是为了督促自己把一个攻击尽可能多的细节尽可能地搞懂,也是为了提升自己的写作能力以及表述水平。本文旨在帮助大家了解学习 TLS Poison 攻击,希望能够通过一篇文章让大家读懂 TLS Poison 攻击。但是,仅仅是网络协议便涉及到很多内容,仅靠本文是不可能完全读懂的,本文的内容也并非完全正确,所以也希望大家抱着怀疑的态度合理对文章提出质疑。

本文主要是对 Black Hat USA 2020 - When TLS Hacks You 议题的整理与复盘,该攻击是一种利用 TLS 协议特性结合客户端实现缺陷达到攻击内网应用的攻击方式,可以达到任意写入 Memcached 等内网服务的攻击效果,进而配合其他漏洞造成 RCE 等危害。

这是去年在 black hat USA 被提出的一项攻击方式,但作者在提出这个攻击方式后,由于种种因素,他放出来的 demo 并不能直接使用,所以我在对该项的研究复现中整理了很多攻击细节,以及一些可以拓展的地方,还有一些关于计算机科学知识的探索。

本文主要分成三部分,第一部分主要简单讲述一些必要的背景知识,第二部分会详细记录三种攻击方式的实现步骤,第三部分会讲述一些关于在复现过程中的一些思考以及相关探索的内容。如果还有后续的进展,我也会同步到自己的个人博客上,欢迎关注,以及前来交流:https://blog.zeddyu.info/

如果对该篇文章有任何疑问或质疑,欢迎来信:

echo emVkZHl1Lmx1QGdtYWlsLmNvbQ==|base64 -d

欢迎对协议安全等内容感兴趣的同学一起交流学习!

PS: 如无特殊说明,整个实验背景均基于 Ubuntu 20.04 LTS ,curl 7.68.0 build with OpenSSL/1.1.1f  ,后文提到的 IPv6 均指的是  IPv4-mapped IPv6 addresses 这类地址

由于内容较多,原文将会被分成四节文章在该平台上进行发布,本篇为该文章的第二节。

点击查看往期文章:
    一篇文章带你读懂 TLS Poison 攻击(一)

NO.2 TLS Poison

在上一篇中,我们终于介绍完背景知识了,现在让我们来看看本次要介绍的 TLS Poison 攻击。

这里一句话帮大家总结概括一下:我们可以利用 TLS Session Resumption 的特性结合 DNS Rebinding 技巧操作一些客户端帮助我们进行 SSRF 攻击。

其实整个攻击就像上述说的一样,非常通俗易懂,无非就是 TLS Session Resumption 、 DNS Rebinding 、一个傻白甜受害者,结合在一起就便有了我们的 TLS Poison 。

- Attack Steps

让我们进一步来看看这个攻击思路:

1、首先我们可以从背景知识当中知道 TLS Session Resumption 特性,无论是 TLS 1.2 或者 1.3 ,它们都会使用了一个凭据一样的东西来表明客户端的身份,就像在 Web 浏览中的 Cookie 一样,这个凭据又是由服务端下发给客户端的,所以如果我们有一个恶意的 Server ,让一个客户端使用 HTTPS 访问我们的服务器时,在 TLS 握手时这个凭据就是我们恶意服务器分配给客户端的,而客户端会把这个凭据按照一定规则存储起来,以便以后需要跟我们恶意服务器恢复上一次会话时使用。所以,从这里我们可以知道,如果可以让客户端以 HTTPS 形式访问任意服务器,在进行 TLS 握手时我们可以让客户端存储我们指定的会话凭据。

2、接着,在进行 HTTPS 请求前,客户端必定需要对我们给的域名进行一次 DNS 查询,而在客户端想要恢复会话的时候,如果客户端的 DNS 缓存过期,则又会进行一次 DNS 查询;如果没有过期,则利用之前的 DNS 查询结果得到的 IP 进行恢复会话。所以当条件满足,也就是正好在客户端想要恢复 TLS 会话,而 DNS 缓存又过期了的时候,就会发起一次 DNS 查询,这里正好就满足了 DNS Rebinding 的条件。

3、这样我们就可以为自己的域名搭建一个 DNS 服务器,在客户端第一次发起 DNS 请求时,我们让 DNS 服务器返回正确的、指向我们恶意服务器的 IP ,让第一次 TLS 握手成功,也让客户端缓存我们制定的会话凭据;在客户端恢复会话时,也就是客户端发起第二次 DNS 请求时,我们让 DNS 服务器返回我们想要攻击的内网地址,例如 127.0.0.1 ,这样在客户端尝试恢复会话的时候,客户端会拿着我们给它的特制票据去与这个地址尝试进行 TLS 握手。

4、这意味着什么呢?特制的票据、指定的内网地址,就构成了一次对内网服务的请求!

但是似乎我们又忽略了什么?如果我想攻击内网的 Memcached ,端口在 11211 不在 443 怎么办?正如我们上面所强调的“客户端会把这个凭据按照一定规则存储起来”,那么这个一定规则又是什么呢?

我们可以随便找个例子来看,比如 curl 7.75.0 ,在 curl 源码的 lib/vtls/vtls.c#408 文件当中,我们可以找到这样的代码:

  for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {    check = &data->state.session[i];    if(!check->sessionid)      /* not session ID means blank entry */      continue;    if(strcasecompare(name, check->name) &&       ((!conn->bits.conn_to_host && !check->conn_to_host) ||        (conn->bits.conn_to_host && check->conn_to_host &&         strcasecompare(conn->conn_to_host.name, check->conn_to_host))) &&       ((!conn->bits.conn_to_port && check->conn_to_port == -1) ||        (conn->bits.conn_to_port && check->conn_to_port != -1 &&         conn->conn_to_port == check->conn_to_port)) &&       (port == check->remote_port) &&       strcasecompare(conn->handler->scheme, check->scheme) &&       Curl_ssl_config_matches(ssl_config, &check->ssl_config)) {      /* yes, we have a session ID! */      (*general_age)++;          /* increase general age */      check->age = *general_age; /* set this as used in this age */      *ssl_sessionid = check->sessionid;      if(idsize)        *idsize = check->idsize;      no_match = FALSE;      break;    }  }

上述代码就是通过对于端口、协议、域名的比较来决定是否使用 sessionid ,而check变量的结构体就是Curl_ssl_session,在 lib/urldata.h#295 当中,我们还可以看到对于Curl_ssl_session结构体的定义

/* information stored about one single SSL session */struct Curl_ssl_session {  char *name;       /* host name for which this ID was used */  char *conn_to_host; /* host name for the connection (may be NULL) */  const char *scheme; /* protocol scheme used */  void *sessionid;  /* as returned from the SSL layer */  size_t idsize;    /* if known, otherwise 0 */  long age;         /* just a number, the higher the more recent */  int remote_port;  /* remote port */  int conn_to_port; /* remote port for the connection (may be -1) */  struct ssl_primary_config ssl_config; /* setup for this session */};

所以对于 curl 7.75.0 来说,这个规则就是端口相同、域名相同、协议相同, curl 就会尝试去使用 sessionid 进行访问。

所以整个攻击思路我们大体上就明白了,让我们再来看看作者当初提出的攻击流程,直观感受一下这个攻击(这里我们用 HTTPS 举例):

1、首先第一步攻击者发送一个 https://jmaddux.com:25 的地址给一个 Client ,Client 会首先进行 DNS 查询询问 jmaddux.com 的 IP 地址,此时攻击者自己控制的 DNS Server 可以自定义响应为一个正常的 IP ,比如 35.x.x.x ,此时我们可以给这个响应记录非常短非常短的 TTL ,以便让 Client 不要缓存我们的 DNS 记录。

2、第二步, Client 会与攻击者指定的 35.x.x.x 这个攻击者的服务器进行 TLS 握手,并获得攻击者服务器返回给 Client 的特制的票据,在图中表示为 Payload ,然后完成 TLS 握手。

3、第三步,当 Client 想与 Server 恢复会话时,需要再次查找 jmaddux.com 的 DNS 记录,由于攻击者之前给的 DNS 记录 TTL 时间非常非常短,让其在此时在自己的缓存中查不到原来的记录,这样会使得 Client 又去询问 jmaddux.com 的 DNS 记录,此时攻击者让其 DNS Server 返回 127.0.0.1 这个地址。

4、最后,如果 Client 不校验本次获得的 ip 是否与上次一致,就会尝试与 127.0.0.1:25 进行 TLS Session Resumption ,也就是说, Client 会拿着攻击者特制的票据访问 127.0.0.1:25 ,尝试与之恢复 TLS 会话,这里就表现为 Client 发送含有 Payload 的 Client Hello 消息到 SMTP 服务器,至此完成一次 SSRF 攻击。

整体的流程图如下:

这里再对图中内容进行一些解释:

1、攻击者通过一些方式让受害者打开一个 HTML 页面,其中内容会向攻击者准备的 TLS Server https://ssltest.jmaddux.com:11211 发起请求;

2、当受害者打开这个页面后,受害者客户端查询 ssltest.jmaddux.com 的 DNS 记录,最终会在攻击者准备的 DNS 服务器查询到攻击者提供的解析记录;

3、此时 DNS 服务器正常返回结果为 TLS Server 地址并且 TTL 为 0 的响应;

4、客户端发送 Client Hello 消息;

5、服务端返回 Server Hello 消息,并在响应包中设置 session_id 为 payload;

6、进行后续的TLS握手;

7、握手完成后进行 http 通信时,攻击者 TLS Server 返回 301 跳转到 https://ssltest.jmaddux.com:11211;

8、受害者客户端重新加载 https://ssltest.jmaddux.com:11211;

9、理论上由于之前 DNS 响应的报文结果中 TTL 为 0 ,受害者客户端会再次向 DNS 服务器询问 ssltest.jmaddux.com 的解析结果;

10、此时攻击者让 DNS 服务器返回解析结果为 127.0.0.1 且 TTL 为 0;

11、接着由于 TLS 会话重用,受害者客户端会使用之前的 session_id 也就是 payload ,带着这个 payload 与 127.0.0.1:11211 进行 TLS 会话重用尝试;

12. payload 被发送至 127.0.0.1:11211 ,达到攻击者目的,但是因为会话重用失败,受害者客户端会得到一个 TLS Error 的错误。至此完成所有攻击步骤。

- Setup

好了,接下来就让我们自己动手试一试吧!由于我是使用的是两个 VPS ,没有像原作者一样使用 docker ,所以使用 docker 的同学还请自行摸索。并且由于国内复杂的网络环境,为了避免不必要的麻烦,我使用的是两台国外的 VPS 作为学习使用。

我准备的是一个域名、两台 VPS ,其中一台 VPS 作为 DNS 服务器,另外一台作为 TLS 服务器,两台 VPS 均是 ubuntu 20.04 LTS 。作者仓库对于各自 VPS 的准备工作已经介绍得比较全面了,详细可以参阅:https://github.com/jmdx/TLS-poison/#instructions ,这里就不再赘述了。

唯一可能需要说一下的就是证书申请,这部分作者没有提到,为了避免一些同学不清楚的,可以参考一下,知道了的同学就可以跳过了。在 TLS 服务器上的证书准备工作:

· 按照 https://certbot.eff.org/instructions 安装对应的 cerbot

· 然后推荐使用 DNS changllenges 的方式弄证书,当然其他方式也可以。certbot --manual --preferred-challenges dns certonly

· 按照自己的信息填好后,会提示需要到你的 DNS 域名管理商处增加一个 TXT 记录,直接添加上去就好了

然后最后我们在域名的 DNS 上配置一下如下的基本设置,这里以域名为 example.com 举例:

然后就先在 DNS VPS 上运行作者的 alternate-dns.py

sudo python3 alternate-dns.py tls.example.com,127.0.0.1 -b 0.0.0.0 -t Your_TLS_IP -d 8.8.8.8

现在就万事俱备啦!

Let's Try!

Original Method

接下来我们在 TLS VPS 进行一下操作,首先由于作者原来是使用的是 docker ,所以有些配置我们需要更改一下:

● 在 client-hello-poisoning/custom-tls/src/main.rs#642 文件中,需要把redis://redis/更改为自己 TLS 服务器上的 redis 地址,比如默认的是 127.0.0.1:6379 ,这里我们就改成redis://127.0.0.1:6379/ 

● 在原作者的方法中, payload 的设置需要在 redis 当中设置,所以我们可以在 redis 设置好 payload ,如:set payload "\r\nset foo 0 0 12\r\ntls session \r\n"

◆ 其中 payload 是 redis 当中的 key ,value 是真正发送给 memcached 的内容
◆ Memcached 需要以 CRLF 作为整个命令的结束,并且可以忽略之前的语句错误,而原作者的文档中给出的 payload 是以 \r 结束,会导致写不进 memcached ,所以我们需要注意一下,我们这里可以使用"\r\nset foo 0 0 13\ni in ur cache\r\n"作为 payload 。
■ 这里如果要修改的话记得改 set 命令的第三个数字参数,该参数为设置数据的长度,否则也会发生错误写不进 memcahed,比如i in ur cache这里是 13 个字节,前面的第三个数字参数就需要为 13 ;前面的命令与数据间的换行我们可以使用 LF 作为换行,可以节省一个字节长度。

■ 这里建议先使用echo -e "\r\nset foo 0 0 13\ni in ur cache\r\n"|nc 127.0.0.1 11211来尝试自己的 pyaload 是否能够写入 memcached ,这样如果后面失败了,对后面的排错很有用!至少能排除一个可能存在的问题!

● 在原作者的方法中,为了让 TLS 进行 Session Resumption ,作者使用了 HTTP 301 跳转的方式让 TLS 进行恢复会话,而跳转的地址则也需要我们通过 redis 来设置,设置的 key 为 redirect ,以 example.com 举例,我们可以这样进行设置:set redirect  "https://tls.example.com:11211/" 。(这里是原作者没有在文档中做出说明的地方,得需要阅读 main.rs 代码才能看出来)

● 还有一点就是作者还提供了一个延迟的选项,以免请求过快(这里有一些其他原因在此处,后续我们会分析到)。我们还是可以通过 redis 来设置 sleep 这个参数,可以达到延迟多少 ms 的效果,如果不设置的话,默认值为 2000 ms ,一般这个数值就可以了。

我们这里以攻击本地的 memcached 为例,在 ubuntu 20.04 LTS 上默认使用apt install memcached安装完成之后,其默认监听在 11211 端口上。之后我们按照作者的说明,在 TLS VPS 上运行 TLSServer :

target/debug/custom-tls -p 11211 --verbose --certs /path/to/fullchain.pem --key /path/to/privkey.pem http

好了,现在才终于是一切准备就绪了,我们就可以直接使用 curl 进行测试了。这里为了直观查看 TLS Session Resumption 的效果,我们可以打开两个 wireshark 来观察,一个 wireshark 监听在你对外通信的网络接口上,一个 wireshark 监听在本地回环接口上。运行一下命令访问你的 TLSServer :

curl https://tls.example.com:11211/ -Lv

PS: 注意这里需要加上-L参数允许 curl 进行重定向。

接着如果第一次 DNS 就把我们的域名解析到 127.0.0.1的话,可以多试几次直到域名解析到你的 TLS VPS IP 上为止,然后等待 1 min 左右,如果网络顺畅,一切顺利的话,在 1min 左右就可以完成本次攻击。攻击效果如下图所示:

其中可能会产生几种结果:

● 第一种最常见的结果就是curl: (47) Maximum (50) redirects followed,表示重定向次数已经超过了 curl 默认的最大深度 50 次,说明 DNS Rebinding 没有将 127.0.0.1 返回到给 Client ,这里因素也比较多,后文会提到,可以说运气比较差,多试几次就行了。

● 第二种结果是curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number,如果上面的信息你还看到了Trying 127.0.0.1,那么恭喜你,很有可能这次就成功了,赶紧去 memcached 看看吧

The Details OF Original Method

在整理这篇文章之前,我也参考了很多文章,虽然这些文章没有明确的说明这个攻击的攻击载体,也就是 Payload 最大长度是 32 字节,但是都给了让我产生了一种先入为主的概念,在我印象当中它就只局限于 32 字节,然后我去详细去看作者公开的 PDF 时,发现作者在演示攻击 SMTP 时有一个图是这样的:

其中我们可以看到这个 payload 已经远远超过了 32 字节,然后我抱着疑惑去反复查看作者公布的演讲录像,其中他有这么说到(但愿我的英语听力以及 Youtube 字幕足够准确):

It might seem too good to be ture but TLS actually provides us exactly that in the form of a session id. Most clients even persist this field for later use. Session ids are limited to 32 bytes as you can see but depending on the implementation you might have session ticket. This one is about 200 bytes but these can be up to around 65 kilobytes. But session ids and session tickets are mechanisms for a TLS client to go. Remember that cryptographic key exchange we did earlier let's just keep using that key in this new connection. TLS 1.3 includes a slightly more complicated but similar mechanism called a pre-shared key identity which pretty much does the smae thing for our purposes. All of these are about optimization since key exchange can be time consuming. But they provide a certain way for a server to tell whatever is connecting to it to persist some data for lighter use, almost like a cookie that lives in plain text. So it's perfect for the surf attack we're trying to do.

也就是说这个攻击本来就可以做到超过 32 字节的做法,也就是我们之前所说的那几种 Session Resumption ,只有 SessionID 局限于 32 字节以下。

并且按照上面我们的实验结果其中我们可以看到,按照原来作者在其仓库 README 描述的方法,我们可以从实践中看出如下几个点:

● 双方默认使用 TLS 1.3 进行握手数据交互,当然这里需要你的 curl 支持 TLS 1.3

● TLS 1.3 使用 PSK 进行 Session Resumption

● PSK 后面还包含了很多个 0x00 ,总长度远远超过了 32 字节

所以作者原仓库实现的是基于 TLS 1.3 的 Session Resumption ,后面我们具体看其实现代码发现也确是如此,作者只实现了基于 PSK 的会话恢复 SSRF ,其他几类都没有实现。

所以,感觉一切都有些明朗了,那我们再来尝试一下超越 32 字节的 payload ,看看到底能不能实现。依旧按照如上的流程做好 setup ,只不过不同的是我们需要在 TLS VPS 的 redis 上修改一下 payload ,这次我们随意修改一下,只要够长就好,这里一定要注意把要发给 memcached 的 payload 当中的set指令的第三个参数修改成其 value 的长度,比如说我们这里修改 payload 为:set payload "\r\nset foo 0 0 79\nThis time I'm really in your cache and I can write what I want into your cache.\r\n"。(当然还是建议在实验之前使用之前的方法测试一下自己的 payload 能否写入到 memcached 当中)

Ok. Here we go.

当当~我们已经可以写入超过 32 字节的数据啦!

The Bad Code IN Original Method

经过上述两个实验,我已经猜到可能大多数同学的实验并不是一次都成功,很多人可能都是得到第一种结果,也就是超过了 curl 最多重定向次数而失败,而导致这个结果的原因一般来说就是 DNS Rebinding 失败,没有在第二次 DNS 查询的时候返回 127.0.0.1 ,这样一直在与 TLSServer 进行通信导致最后重定向次数过多而失败。

让我们简单看看作者的 DNS Rebinding 怎么写的,我们重点关注以下代码:

spoof_count = 0start = time()last_ip = None
def get_spoofed_IP(domain, ip): global spoof_count global start global last_ip start = time() last_ip = ip
for d in HOSTS_LIST: if re.match(d[0], domain.lower()) or True: spoof_count = (spoof_count + 1) % 3 # The below line will result in the answer switching after 30 seconds, # instead of alternating # return d[1] if (time() - start > 30) else args.TARGET return d[1] if spoof_count == 0 else args.TARGET return None

这是作者自己写的代码,这段代码的意思大概就是通过记录 DNS 查询的总次数,如果查询总次数模 3 为 0 的话,也就是 3 的倍数,返回d[1],也就是 127.0.0.1 ,否则就返回我们的 TLS VPS IP 。这种方式我们暂且不谈,先不关注。

我们再来看看其注释的方式,也就是我们可以使用注释当中的方式,DNS Server 启动 30s 之前返回 TLS VPS IP ,只需要在 30s 之后, DNS 就会一直返回我们的目标地址 127.0.0.1 。

我们现在先接受一个结论,就是 curl 对于一个域名有一定的 DNS 缓存时间,那么如果我们想让 curl 第一次 DNS 查询得到 TLS VPS IP ,在缓存时间结束之后查询的结果返回 127.0.0.1 ,那么注释当中的方式是最好不过的了。

好了,接下来就是公开处刑(我也不知道作者是不是粗心大意写出这样的代码):

spoof_count = 0start = time()last_ip = None
def get_spoofed_IP(domain, ip): global spoof_count global start global last_ip start = time() last_ip = ip
for d in HOSTS_LIST: if re.match(d[0], domain.lower()) or True: spoof_count = (spoof_count + 1) % 3 # The below line will result in the answer switching after 30 seconds, # instead of alternating return d[1] if (time() - start > 30) else args.TARGET return None

让我们再来回顾这段代码:嗯,写的非常的棒,用time()计时,超过 30s 就返回目标 IP ,太对了哥。如果还没看出来的同学,我再简化一下:

spoof_count = 0start = time()last_ip = None
def get_spoofed_IP(domain, ip): global spoof_count global start global last_ip start = time() if time() - start > 30: return d[1] else: return args.TARGET

我觉得只要你的机器稍微正常一点,正常执行几行赋值语句的 python 代码的速度应该不会超过 30s 吧?这个在使用time()函数对start变量赋值之后,又使用了time()函数获取时间戳与start变量相减。啊这,反正我的机器是减不出 30s ,这段代码就让我感觉到作者写的非常的离谱...当然这里纯属个人吐槽,这里我们只需要把函数内对于start变量再次赋值的操作删除就行了,这样start得到的时间就是程序启动的时间了。(除非我哪里误解了这段代码)

当然我建议时间间隔在 10s 这样就行,这样就能比较精准的让 curl 在第二次 DNS 查询的时候拿到 127.0.0.1 的响应了。(一只黄色的哆啦A梦:这人也太菜了.jpg

当然,或者你也可以使用总次数的方式,如果总次数超过一次立即返回 127.0.0.1 也是可以的,不过万一被别人查了第一次就尴尬了,但是一般来说不会。

今天的文章主要讲述了 TLS Poison 攻击的准备阶段以及复现流程,不过还没结束,让我们在下一周的文章再继续。

RECRUITMENT

招聘启事

安恒雷神众测SRC运营(实习生)
————————
【职责描述】
1.  负责SRC的微博、微信公众号等线上新媒体的运营工作,保持用户活跃度,提高站点访问量;
2.  负责白帽子提交漏洞的漏洞审核、Rank评级、漏洞修复处理等相关沟通工作,促进审核人员与白帽子之间友好协作沟通;
3.  参与策划、组织和落实针对白帽子的线下活动,如沙龙、发布会、技术交流论坛等;
4.  积极参与雷神众测的品牌推广工作,协助技术人员输出优质的技术文章;
5.  积极参与公司媒体、行业内相关媒体及其他市场资源的工作沟通工作。

【任职要求】 
 1.  责任心强,性格活泼,具备良好的人际交往能力;
 2.  对网络安全感兴趣,对行业有基本了解;
 3.  良好的文案写作能力和活动组织协调能力。

简历投递至 

[email protected]

设计师(实习生)

————————

【职位描述】
负责设计公司日常宣传图片、软文等与设计相关工作,负责产品品牌设计。

【职位要求】
1、从事平面设计相关工作1年以上,熟悉印刷工艺;具有敏锐的观察力及审美能力,及优异的创意设计能力;有 VI 设计、广告设计、画册设计等专长;
2、有良好的美术功底,审美能力和创意,色彩感强;

3、精通photoshop/illustrator/coreldrew/等设计制作软件;
4、有品牌传播、产品设计或新媒体视觉工作经历;

【关于岗位的其他信息】
企业名称:杭州安恒信息技术股份有限公司
办公地点:杭州市滨江区安恒大厦19楼
学历要求:本科及以上
工作年限:1年及以上,条件优秀者可放宽

简历投递至 

[email protected]

安全招聘

————————

公司:安恒信息
岗位:Web安全 安全研究员
部门:战略支援部
薪资:13-30K
工作年限:1年+
工作地点:杭州(总部)、广州、成都、上海、北京

工作环境:一座大厦,健身场所,医师,帅哥,美女,高级食堂…

【岗位职责】
1.定期面向部门、全公司技术分享;
2.前沿攻防技术研究、跟踪国内外安全领域的安全动态、漏洞披露并落地沉淀;
3.负责完成部门渗透测试、红蓝对抗业务;
4.负责自动化平台建设
5.负责针对常见WAF产品规则进行测试并落地bypass方案

【岗位要求】
1.至少1年安全领域工作经验;
2.熟悉HTTP协议相关技术
3.拥有大型产品、CMS、厂商漏洞挖掘案例;
4.熟练掌握php、java、asp.net代码审计基础(一种或多种)
5.精通Web Fuzz模糊测试漏洞挖掘技术
6.精通OWASP TOP 10安全漏洞原理并熟悉漏洞利用方法
7.有过独立分析漏洞的经验,熟悉各种Web调试技巧
8.熟悉常见编程语言中的至少一种(Asp.net、Python、php、java)

【加分项】
1.具备良好的英语文档阅读能力;
2.曾参加过技术沙龙担任嘉宾进行技术分享;
3.具有CISSP、CISA、CSSLP、ISO27001、ITIL、PMP、COBIT、Security+、CISP、OSCP等安全相关资质者;
4.具有大型SRC漏洞提交经验、获得年度表彰、大型CTF夺得名次者;
5.开发过安全相关的开源项目;
6.具备良好的人际沟通、协调能力、分析和解决问题的能力者优先;
7.个人技术博客;
8.在优质社区投稿过文章;

岗位:安全红队武器自动化工程师
薪资:13-30K
工作年限:2年+
工作地点:杭州(总部)

【岗位职责】
1.负责红蓝对抗中的武器化落地与研究;
2.平台化建设;
3.安全研究落地。

【岗位要求】
1.熟练使用Python、java、c/c++等至少一门语言作为主要开发语言;
2.熟练使用Django、flask 等常用web开发框架、以及熟练使用mysql、mongoDB、redis等数据存储方案;
3:熟悉域安全以及内网横向渗透、常见web等漏洞原理;
4.对安全技术有浓厚的兴趣及热情,有主观研究和学习的动力;
5.具备正向价值观、良好的团队协作能力和较强的问题解决能力,善于沟通、乐于分享。

【加分项】
1.有高并发tcp服务、分布式等相关经验者优先;
2.在github上有开源安全产品优先;
3:有过安全开发经验、独自分析过相关开源安全工具、以及参与开发过相关后渗透框架等优先;
4.在freebuf、安全客、先知等安全平台分享过相关技术文章优先;
5.具备良好的英语文档阅读能力。

简历投递至

[email protected]

岗位:红队武器化Golang开发工程师

薪资:13-30K
工作年限:2年+
工作地点:杭州(总部)

【岗位职责】
1.负责红蓝对抗中的武器化落地与研究;
2.平台化建设;
3.安全研究落地。

【岗位要求】
1.掌握C/C++/Java/Go/Python/JavaScript等至少一门语言作为主要开发语言;
2.熟练使用Gin、Beego、Echo等常用web开发框架、熟悉MySQL、Redis、MongoDB等主流数据库结构的设计,有独立部署调优经验;
3.了解docker,能进行简单的项目部署;
3.熟悉常见web漏洞原理,并能写出对应的利用工具;
4.熟悉TCP/IP协议的基本运作原理;
5.对安全技术与开发技术有浓厚的兴趣及热情,有主观研究和学习的动力,具备正向价值观、良好的团队协作能力和较强的问题解决能力,善于沟通、乐于分享。

【加分项】
1.有高并发tcp服务、分布式、消息队列等相关经验者优先;
2.在github上有开源安全产品优先;
3:有过安全开发经验、独自分析过相关开源安全工具、以及参与开发过相关后渗透框架等优先;
4.在freebuf、安全客、先知等安全平台分享过相关技术文章优先;
5.具备良好的英语文档阅读能力。

简历投递至

[email protected]

END

长按识别二维码关注我们


文章来源: http://mp.weixin.qq.com/s?__biz=MzAwMDQwNTE5MA==&mid=2650246415&idx=1&sn=964bd7794cee73c1993adb84c821a58a&chksm=82ea56a6b59ddfb0ae24b72f0d99257fe90d0520a64cf5b8e92b433a4876085e746cb8eed21d#rd
如有侵权请联系:admin#unsafe.sh