打赏
随笔 - 111,  文章 - 0,  评论 - 36,  阅读 - 29万

起源:

问题源于解析kissanime.io这个网站。
为反扒抑或是防止ddos攻击,此视频页面,初进去会有个5秒延迟并提交一表单验证。而其表单验证,为下面一段html代码:

  <form id="challenge-form" action="/cdn-cgi/l/chk_jschl" method="get">
    <input type="hidden" name="jschl_vc" value="d5f32a77955a830758982219a37f1124"/>
    <input type="hidden" name="pass" value="1500949414.776-fpKIjtEKZR"/>
    <input type="hidden" id="jschl-answer" name="jschl_answer"/>
  </form>

求jschl-answer值 ,用了一段js代码,此段js代码为随机生成,如下:

复制代码
    var s,t,o,p,b,r,e,a,k,i,n,g,f, nyqPwxi={"KxtkYgr":+((!+[]+!![]+!![]+[])+(+!![]))};
    t = document.createElement('div');
    t.innerHTML="<a href='/'>x</a>";
    t = t.firstChild.href;r = t.match(/https?:\/\//)[0];
    t = t.substr(r.length); t = t.substr(0,t.length-1);
    a = document.getElementById('jschl-answer');
    f = document.getElementById('challenge-form');
    ;nyqPwxi.KxtkYgr*=+((!+[]+!![]+[])+(!+[]+!![]+!![]));nyqPwxi.KxtkYgr+=+((!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]));nyqPwxi.KxtkYgr+=+((!+[]+!![]+!![]+[])+(+!![]));nyqPwxi.KxtkYgr*=+((+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]));nyqPwxi.KxtkYgr+=!+[]+!![]+!![];nyqPwxi.KxtkYgr+=+((!+[]+!![]+!![]+[])+(+!![]));a.value = parseInt(nyqPwxi.KxtkYgr, 10) + t.length; '; 121'
    f.submit();
复制代码

没有格式化,比较凌乱。
由其可见,jschl-answer值域,是通过一系列公式运算所得。运行js得到其值,就可以模拟表单提交,通过验证

 

1、获取需要的js代码段

不外乎用到re这个东西。参照一个开源项目,通过以下python代码,实现js代码提取:

复制代码
    try:
        js = re.search(r"setTimeout\(function\(\){\s+(var "
            "s,t,o,p,b,r,e,a,k,i,n,g,f.+?\r?\n[\s\S]+?a\.value =.+?)\r?\n", body).group(1)
    except Exception:
        raise ValueError("Unable to identify Cloudflare IUAM Javascript on website.")

    js = re.sub(r"a\.value = (parseInt\(.+?\)).+", r"\1", js)
    js = re.sub(r"\s{3,}[a-z](?: = |\.).+", "", js)
    js = re.sub(r"[\n\\']", "", js)
    if "parseInt" not in js:
        raise ValueError("Error parsing Cloudflare IUAM Javascript challenge.")

    js = js.replace('parseInt', ';return parseInt')
    js = 'function answer(){%s}' % js
复制代码

中间这一段:

js = re.sub(r"a\.value = (parseInt\(.+?\)).+", r"\1", js)

被蒙到了!对re.sub运用尚未纯熟,此写法,一开始忽住了我,随搜集其做研究学习,倒也有些收获。

 

2、re.sub(pattern, repl, string, count=0, flags=0)

这是它的原型,网上对此式解说文章,多不胜数。对第二个参数,repl,上述用法,述者寥寥
但其功能,是以第一个参数,pattern中第一个组中值,替换pattern所匹配的字串,其格式为\number,编号从1开始第应第1组,以此类推,功能与\g<number>相同,为简洁写法。

比如:

s = '2017-01-22'
s = re.sub('(\d{4})-(\d{2})-(\d{2})', r'\2-\3-\1', s)
print s  # 01-22-2017

r'\g<0>'能匹配pattern所适配的字串,而r'\0'却不能,这是测试中发现其不同处。

若在patter中有\number写法,则是要匹配其中分组,如下写法:

inputStr = "hello crifan, nihao crifan";
replacedStr = re.sub(r"hello (\w+), nihao \1", "crifanli", inputStr);
print "replacedStr=", replacedStr; #crifanli

它匹配了inuptStr整个字串,此字串,被crifanli完整替换之。

 

3、其它写法

repl除了字串外,它还可以是函数,以对匹配到的组,做其它操作。

照搬一个例子:

复制代码
def replace_digit(m):
    ss = u'〇一二三四五六七八九'
    index = int(m.group())
    return ss[index]

s = u'1990年3月27日'
result = re.sub(u'\d', replace_digit, s, count=4)

print result # 一九九〇年3月27日
复制代码

 

参考资料:

http://www.jianshu.com/p/731efbd6029b

https://docs.python.org/2/library/re.html#re.sub

posted on   楚人无衣  阅读(10622)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示