Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

京东面试题 #19

Open
mylamour opened this issue Apr 7, 2018 · 8 comments

Comments

@mylamour
Copy link
Owner

commented Apr 7, 2018

4月3号,愚人节后的两天,也恰是清明的前两天。意外收到来自京东的面试,简历是3月28号投的,未曾想到能会通过筛选,面试官聊了一会,不出意外,并没有通过。自省之余,对其中的5道问题并不能很好的回答,因此予以记录


一面

  1. 一般sql注入怎么发现触点的,从源码阐述sqlmap如何测试注入点的.
  2. masscan扫描端口时靠什么检测,为什么这么快? 请详述.
  3. 你写过哪些小工具,你为你使用过的工具做过什么修改.
  4. 如何提高采用python编写的扫描速度,谈谈对GIL锁的了解.
  5. 你觉得你发现的那个漏洞影响比较大.

Other

  • 常见的web漏洞有哪些.
  • 有没有玩过硬件安全,研究程度如何.

Backup
收货很多,面试官脾气很好,虽不曾相识,但十分感谢。保持学习,以免退步。


二面和三面是一天,周四,4月19号。请了一天假,太阳很热。没想到的是夏初的时候,两盆绿植却要凋零了。熬过了秋冬春,却没赶得上盛夏。不过生命的尽头就是死亡,也没什么可悲哀的。早走晚走都是要走的。

二面

  1. 反爬虫,如果是你如何进行反爬虫,如何绕过反爬措施。 使用无头浏览器被检测到了,如何绕过
  2. nmap扫描如何进行扫描。发包与协议,握手和不握手,哪些协议握手,哪些不握手. 如何不直接接触目标服务器探测对方端口是否开放
  3. 有没有自己编写过yara扫描模块,如果要解决扫描{k1:v1, k2:v2, k3:v3} ,保证同时在k1中的v1里出现特定值,k2中出现v2特定值,以及k3,v3。怎么实现
  4. xss什么原理,如何自己实现一个beef类似的xss平台. 既然这样实现,面临的跨域如何解决?

Other
对移动安全有了解吗?你想不想做移动安全

现在大多数APP都是hybird的,所以既有移动安全,也有web安全

Backup
顺着问,都能挖的深,不仅在面试,更像是在讨论。自己觉得自己实力不行,但这并不是放弃。所有的答案都会自己找到,也将会站在终点。或者永远没有终点。

三面

三面问题太多,几乎是10分钟不到的时间内平均每分钟几个问题的速度不停的在问...自我介绍,为什么跳槽,介绍下webshell检测怎么实现,为什么apt检测没做了,没有卖点吗?办公网怎么重组,安全运维这一块讲讲。nmap扫描问题同二面如何不直接接触检测,不会。三面像是在做填空题。

  1. 讲讲web漏洞有哪些?
  2. xss怎么个原理,如何防御,能防御透彻吗?

CSP,不能。(连CSP的常见配置都没有问...)

  1. sql注入怎么测试的,工具呢?

单引号测试,sqlmap

update: 2018.4.21


你有什么想问我的
Q1: masscan是怎么实现扫描的?

Q2.1:你是xxx吗?
Q2.2: 能介绍下这边的移动安全主要在做什么的?
Q2.3: 要涉及到扫描器编写吗?

Q3: 这个问题本来是想问2面的,当时觉得自己1面不太好时,恰好看到这句话,三十而立四十balabala,七十而从心所欲不逾矩。你如何理解
A3.: 我不信这个

Other: 信,不信。无所谓的。但你该问还是要问的。

@mylamour

This comment has been minimized.

Copy link
Owner Author

commented Apr 7, 2018

  1. 一般sql注入怎么发现触点的,从源码阐述sqlmap如何测试注入点的.
    暂时pass,因为还没有读sqlmap的源码
@mylamour

This comment has been minimized.

Copy link
Owner Author

commented Apr 7, 2018

从源码浅谈masscan

为什么这么快,为什么这么快

索引目标,选择协议,建立连接,端口开放则发送报文。解析返回的内容or banner,在其中搜索pattern,判断结果目标端口及类型。主要涉及到有扫描算法,索引算法,搜索算法(优化后的AC自动机算法,详见源码smack1.c)。暂时不涉及pfring。

struct Banner1
{
    struct SMACK *smack;
    struct SMACK *http_fields;
    struct SMACK *html_fields;
    struct SMACK *memcached_responses;
    struct SMACK *memcached_stats;

    unsigned is_capture_html:1;
    unsigned is_capture_cert:1;
    unsigned is_capture_heartbleed:1;
    unsigned is_capture_ticketbleed:1;
    unsigned is_heartbleed:1;
    unsigned is_ticketbleed:1;
    unsigned is_poodle_sslv3:1;

    struct ProtocolParserStream *tcp_payloads[65536];
};

数据包传送的主要函数为以下三个,解析返回时的数据在smack,发送的数据格式有专门的template,在templ-payloads.h

  • rawsock_send_packet
  • rawsock_recv_packet
  • rawsock_send_probe

算法:

以文档中的js为例,这是核心的扫描算法。

  1. Masscan首先存储一系列的ip到一个结构体,port存到另一个结构体中。然后,用一个索引枚举所有的ip:port组合(32位整型:16位整型)。在每一次的枚举前,把该索引置换到另一个随机表示的索引,这样也就是说,根据后面的一个索引可以得到原始的索引
    function Range(begin,end){
    }
    function RangeList(){
        // A list of Range  
    }
    function Targets(){
    }
function TransmitThread(targets, transmit, seed) {
    var range = targets.ips.count() * targets.ports.count();
    var b = Blackrock(range, seed);

    for (var i = 0; i < range; i++) {
        var xXx = b.shuffle(i);

        var ip_index = Math.floor(xXx / targets.ports.count());
        var port_index = Math.floor(xXx % targets.ports.count());

        var ip = targets.ips.pick(ip_index);
        var port = targets.ports.pick(port_index);

        transmit(ip, port);
    }
}

整体并不难理解。然后我们看到了Blackrock这个东西,这个东西是什么?

  1. Blackrock实现了一个基于DES的置换函数

使用真正的DES加密会限制置换后的范围为2-14,作者因此需要做一些操作使得二进制运算符和非二进制运算相等(不懂什么意思),例如XOR。

function Blackrock(range, seed) {
    var split = Math.floor(Math.sqrt(range * 1.0));

    this.rounds = 3;
    this.seed = seed;
    this.range = range;
    this.a = split - 1;
    this.b = split + 1;

    while (this.a * this.b <= range)
        this.b++;

    /** Inner permutation function */
    this.F = function (j, R, seed) {
        var primes = [961752031, 982324657, 15485843, 961752031];
        R = ((R << (R & 0x4)) + R + seed);
        return Math.abs((((primes[j] * R + 25) ^ R) + j));
    }

    /** Outer feistal construction */
    this.fe = function (r, a, b, m, seed) {
        var L, R;
        var j;
        var tmp;

        L = m % a;
        R = Math.floor(m / a);

        for (j = 1; j <= r; j++) {
            if (j & 1) {
                tmp = (L + this.F(j, R, seed)) % a;
            } else {
                tmp = (L + this.F(j, R, seed)) % b;
            }
            L = R;
            R = tmp;
        }
        if (r & 1) {
            return a * L + R;
        } else {
            return a * R + L;
        }
    }

    /** Outer reverse feistal construction */
    this.unfe = function (r, a, b, m, seed) {
        var L, R;
        var j;
        var tmp;

        if (r & 1) {
            R = m % a;
            L = Math.floor(m / a);
        } else {
            L = m % a;
            R = Math.floor(m / a);
        }

        for (j = r; j >= 1; j--) {
            if (j & 1) {
                tmp = this.F(j, L, seed);
                if (tmp > R) {
                    tmp = (tmp - R);
                    tmp = a - (tmp % a);
                    if (tmp == a)
                        tmp = 0;
                } else {
                    tmp = (R - tmp);
                    tmp %= a;
                }
            } else {
                tmp = this.F(j, L, seed);
                if (tmp > R) {
                    tmp = (tmp - R);
                    tmp = b - (tmp % b);
                    if (tmp == b)
                        tmp = 0;
                } else {
                    tmp = (R - tmp);
                    tmp %= b;
                }
            }
            R = L;
            L = tmp;
        }
        return a * R + L;
    }

    this.shuffle = function (m) {
        var c;

        c = this.fe(this.rounds, this.a, this.b, m, this.seed);
        while (c >= this.range)
            c = this.fe(this.rounds, this.a, this.b, c, this.seed);

        return c;
    }

    this.unshuffle = function (m) {
        var c;

        c = unfe(this.rounds, this.a, this.b, m, this.seed);
        while (c >= this.range)
            c = unfe(this.rounds, this.a, this.b, c, this.seed);

        return c;
    }
    return this;
}
function transmit(ip, port) {
    var proto = "tcp";
    if (port > 65536 * 2) {
        proto = "sctp";
        port -= 65536 * 2;
    } else if (port > 65536) {
        proto = "udp";
        port -= 65536;
    }

    var ipstring = ((ip >> 24) & 0xFF)
            + "." + ((ip >> 16) & 0xFF)
            + "." + ((ip >> 8) & 0xFF)
            + "." + ((ip >> 0) & 0xFF)

    console.log("--> " + ipstring + " " + proto + ":" + port);
}

协议

struct Masscan
{
    //...
    struct {
        unsigned tcp:1;
        unsigned udp:1;
        unsigned sctp:1;
        unsigned ping:1;
    } scan_type;
    //...
}

可以看出masscan支持上述四种协议。而从js代码里可以看出来port索引个数少于65536的采用tcp扫描,大于的采用udp扫描,大于两倍及以上的采用sctp扫描。

TCP

  • 连接: syn-syn/ack-ack
  • 关闭: fin-ack-fin-ack

UDP

SCTP

不仅提供了像 TCP 一样可靠、有序地发送数据的功能,而且可以像UDP一样面向消息的方式来进行操作,这可以保护消息边界。高级特性:

  • 多宿主(Multi-homing)
    两台主机之间,可以使用每台主机上的多个接口进行协作
  • 多流(Multi-streaming)
    一个联合中的所有流都是独立的,但均与该联合相关
  • 初始化保护(Initiation protection)
    多了个cookie-ack
  • 消息分帧(Message framing)
    当一端对一个套接字执行写操作时,可确保对等端读出的数据大小与此相同
  • 可配置的无序发送(Configurable unordered delivery)
  • 平滑关闭(Graceful shutdown)

Other

  • masscan当前暂时不支持nmap的的扫描方式以及输出格式。
  • masscan输出模式中可以直接输出为redis模式。

References

@mylamour

This comment has been minimized.

Copy link
Owner Author

commented Apr 7, 2018

  1. 你写过哪些小工具
    Es 9200端口检测,对于其他工具的修改顶多是自己写聚合类脚本使其综合运行。例如domainGather.sh。 当时只想到攻击性工具的编写,其实还可以将自己对yara的修改,pastbinhunter中的loki代码重写。插件式扫描工具的编写。github repo里有。以及一些小的脚本方便临时测试用的。
@mylamour

This comment has been minimized.

Copy link
Owner Author

commented Apr 7, 2018

  1. 如何提高采用python编写的扫描速度,谈谈对GIL的了解.
    这是顺着当时聊到ES检测工具聊下来的,我是采用线程池的方式加快其扫描速度。但是面试官主要是想把我往GIL上引,虽然GIL并不是问题的关键。由于我不是很清楚GIL,所以让我给出方法的过程中只是给出了:
  • shell脚本启动多个python进程
  • 及分布式的方式(启动多台机器)
  • 直接采用gevent的monkey patch(这是协程的方式)

当然除了这些方式,结束之后还突然想到了:

  • ctypes编写c库,由python调用
  • 或者编写rust扩展也行,
  • 换解释器,换成pypy解释器,据说代码运行速度可以快6.3倍

衍生问题是:
a. 对写同一个文件时出现同时写怎么办?

  • 可以数据库队列方式,避免出现锁。
  • 资源请求时加锁。生产者消费者模型

现在才发现,面试官问我出现同时写的情况怎么办,因为并没有出现过。所以一瞬间也没想到。一着急就懵逼了。(资料说multiprocessing 本身避免了GIL的问题)。

b. 进程间数据间如何同步,或者线程间数据如何同步?
具体记不清了,就是问数据如何同步,由于进程是独立的内存,而线程是共享内存。线程间的通信,在python中可以采用queue的方式(我在proxycheck里就是这样实现的,然而没有回答出来,真让人头秃)。

def worker():
    while True:
        item = q.get()
        do_work(item)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
     t = Thread(target=worker)
     t.daemon = True
     t.start()

for item in source():
    q.put(item)

q.join()  

还可以采用Pipe的方式, 如果只是为了分享状态可以采用Array实现。(以上都是基于python的multiprocessing)

上述方式GIL没有关系,和面试官想引导的方向不一样,这一题GG了。

GIL Global Interpreter Lock

GIL不是python特性,是Cpython实现导致的。像Jython,IronPython并不具有这种问题。

Python 3.2开始使用新的GIL。新的GIL实现中用一个固定的超时时间来指示当前的线程放弃全局锁。在当前线程保持这个锁,且其他线程请求这个锁时,当前线程就会在5毫秒后被强制释放该锁。

References

@mylamour

This comment has been minimized.

Copy link
Owner Author

commented Apr 7, 2018

5.你觉得你发现的那个漏洞影响比较大,挖到时的难点在哪里。

经过确认之后,说了不一定是纯技术的。可以从影响上面来说。个人觉得操作系统级别的漏洞,框架级别的RCE,错误配置以及敏感信息泄露危害比较严重。 然而这个是要根据自身来讲,并且范围有点限定在web的感觉。所以就讲了下一个api key分享链接中key泄露事件(应该再讲下oauth授权对redirect_uri无验证)。但从技术上来说,这两个案列其实都不存在技术壁垒。只是认真的测一下就能发现。

关于难点,今天突然想到,可以把微盟的那个案例拿出来说一下,扫描到集群的后台之后,可进行密码爆破,但是密码强度应该比较强。然后github信息泄露收集点进去该员工的repo,发现并无密码,最后查看commit的历史发现之前提交过的密码选项,通过该员工的权限进入之后,后面就是后渗透了。基本可以登录所有平台,以及LDAP服务器,最后等等。而且很幸运的是这个员工已经准备离职交接了,所以并不容易发现我的行踪。最后截图走人。

但自己也没有挖到过0Day,最后就GG了。祈祷以后挖到厉害的0day,像去年的s2-048,即便不知道原理,拿来就用,威力一样大的不行。

@mylamour

This comment has been minimized.

Copy link
Owner Author

commented Apr 21, 2018

2.1. 如果是你如何进行反爬虫,如何绕过反爬措施。使用无头浏览器被检测到了,如何绕过

web端

  • js 埋点
  • css 移位
  • 字符集替换
  • js 加密
  • 验证码
  • UA and Rreferer
  • cookie
  • 异步加载
  • 设备指纹

表示没想起来全,只想起来了几个。

后端

  • ip 频率限制, ip信誉度模型
  • (我的不确定的想法)分析日志得到最近请求url的批量ip,去重。看每个去重后的ip访问请求内容的相似度

越想越觉得这个方式可行啊。实时日志分析,请求内容相似度分析,关联分析???

当时谈到了京东的代码检测里有针对无头浏览器这一块,会检测phantomjs,ghost这一类的关键词。如果是我我是会重新编译一下,改个名字就行了。

@mylamour

This comment has been minimized.

Copy link
Owner Author

commented Apr 21, 2018

2.3. nmap扫描如何进行扫描。发包与协议,握手和不握手,哪些协议握手,哪些不握手,如何不直接接触目标服务器探测对方端口是否开放

暂时pass,这个问题已经第二次出现了,同程也问过。之后学习了再详解

@mylamour

This comment has been minimized.

Copy link
Owner Author

commented Apr 21, 2018

2.6. xss什么原理,如何自己实现一个beef类似的xss平台 ,面临的跨域如何解决?
一切可控输入在响应中有输出。 如何实现,hook.js的页面和不停的轮训服务器。这样就面临着跨域问题。

解决跨域

web端

  • jsonp(json padding)
    js脚本可以加载任何东西,ajxa请求数据,请求之后,由回调函数进行解析.详细参考这篇
<script src="http://xxx.com?callback=ohoh"> </script>

$callback= !empty($_GET['callback']) ? $_GET['callback'] : 'callback';
echo $callback.'(.json.encode($data).)';
  • document.domain
    适用于主域相同的跨域
    http://dev.aha.com/list.html中设置为document.domain="aha.com";就可以访问http://static.aha.com
    下的资源了

  • windows.name -> location.href

  • windows.postMesage

服务器端

  • nginx 反向代理

  • CORS

other

  • websocket
  • location.hash

XSS 防御

CSP

配置
*,slef,unsafe-inline,strict-dynamic

think:

  • 限制js执行
  • 限制对不可信域的请求
  • 跳转本身就是跨域
  • 可信js生成的js一定是可信的吗

动态生成的nonce字符串(nonce-{random-str}),只包含nonce字段并字符串相等的script块可以被执行。这应该是比较好的防御方式,但是也是有问题的。应该黑名单配合CSP。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.