问题

Your task is to decode the following:

%59%69%70%70%65%68%21%20%59%6F%75%72%20%55%52%4C%20%69%73%20%63%68%61%6C%6C%65%6E%67%65%2F%74%72%61%69%6E%69%6E%67%2F%65%6E%63%6F%64%69%6E%67%73%2F%75%72%6C%2F%73%61%77%5F%6C%6F%74%69%6F%6E%2E%70%68%70%3F%70%3D%64%6E%73%65%72%68%63%69%70%72%63%69%26%63%69%64%3D%35%32%23%70%61%73%73%77%6F%72%64%3D%66%69%62%72%65%5F%6F%70%74%69%63%73%20%56%65%72%79%20%77%65%6C%6C%20%64%6F%6E%65%21

解释

猜测上面几行代码是url编码。

任何特殊的字符(就是那些不是简单的七位ASCII,如汉字)将以百分符%用十六进制编码,当然也包括象 =,&;,和 % 这些特殊的字符。其实url编码就是一个字符ascii码的十六进制。不过稍微有些变动,需要在前面加上“%”。比如“”,它的ascii码是92,92的十六进制是5c,所以“”的url编码就是%5c。----------来自百度百科

所以来解码下。

答题

打开UrlEncode编码/UrlDecode解码 - 站长工具

输入上面内容,点击URLDecode解码按钮,显示:

Yippeh! Your URL is challenge/training/encodings/url/saw_lotion.php?p=dnserhciprci&cid=52#password=fibre_optics Very well done!

把上面URL合并到主站点,访问http://www.wechall.net/challenge/training/encodings/url/saw_lotion.php?p=dnserhciprci&cid=52#password=fibre_optics

即可成功。

其他

上面其实就已经结束了。 下面是用多种代码来实现url解码

Python3

方法一

可以用urllib.parse这个方法来解析URL。 查看官方文档

import urllib
import urllib.parse

q = urllib.parse.unquote('%59%69%70%70%65%68%21%20%59%6F%75%72%20%55%52%4C%20%69%73%20%63%68%61%6C%6C%65%6E%67%65%2F%74%72%61%69%6E%69%6E%67%2F%65%6E%63%6F%64%69%6E%67%73%2F%75%72%6C%2F%73%61%77%5F%6C%6F%74%69%6F%6E%2E%70%68%70%3F%70%3D%6F%6C%69%6F%62%66%69%6D%70%6C%6D%67%26%63%69%64%3D%35%32%23%70%61%73%73%77%6F%72%64%3D%66%69%62%72%65%5F%6F%70%74%69%63%73%20%56%65%72%79%20%77%65%6C%6C%20%64%6F%6E%65%21')

print(q)

方法二

除了使用已有的库函数,还可以根据“url编码就是一个字符ascii码的十六进制”来手动解码。但是这种方法不能解析中文,要想对中文解码还是需要用第一个方法。

步骤:首先将所有%符号去掉,接着按16进制格式读取数字,最后把数字转成ASCII字符

url = '%59%69%70%70%65%68%21%20%59%6F%75%72%20%55%52%4C%20%69%73%20%63%68%61%6C%6C%65%6E%67%65%2F%74%72%61%69%6E%69%6E%67%2F%65%6E%63%6F%64%69%6E%67%73%2F%75%72%6C%2F%73%61%77%5F%6C%6F%74%69%6F%6E%2E%70%68%70%3F%70%3D%6F%6C%69%6F%62%66%69%6D%70%6C%6D%67%26%63%69%64%3D%35%32%23%70%61%73%73%77%6F%72%64%3D%66%69%62%72%65%5F%6F%70%74%69%63%73%20%56%65%72%79%20%77%65%6C%6C%20%64%6F%6E%65%21'
print (''.join(map(lambda x:chr(int(x, 16)), url[1:].split('%'))))

JavaScript

使用decodeURIComponent函数

url = decodeURIComponent("%59%69%70%70%65%68%21%20%59%6F%75%72%20%55%52%4C%20%69%73%20%63%68%61%6C%6C%65%6E%67%65%2F%74%72%61%69%6E%69%6E%67%2F%65%6E%63%6F%64%69%6E%67%73%2F%75%72%6C%2F%73%61%77%5F%6C%6F%74%69%6F%6E%2E%70%68%70%3F%70%3D%6F%6C%69%6F%62%66%69%6D%70%6C%6D%67%26%63%69%64%3D%35%32%23%70%61%73%73%77%6F%72%64%3D%66%69%62%72%65%5F%6F%70%74%69%63%73%20%56%65%72%79%20%77%65%6C%6C%20%64%6F%6E%65%21")
console.log(url)

PHP

使用urldecode函数

<?php
echo urldecode("%59%69%70%70%65%68%21%20%59%6F%75%72%20%55%52%4C%20%69%73%20%63%68%61%6C%6C%65%6E%67%65%2F%74%72%61%69%6E%69%6E%67%2F%65%6E%63%6F%64%69%6E%67%73%2F%75%72%6C%2F%73%61%77%5F%6C%6F%74%69%6F%6E%2E%70%68%70%3F%70%3D%6F%6C%69%6F%62%66%69%6D%70%6C%6D%67%26%63%69%64%3D%35%32%23%70%61%73%73%77%6F%72%64%3D%66%69%62%72%65%5F%6F%70%74%69%63%73%20%56%65%72%79%20%77%65%6C%6C%20%64%6F%6E%65%21");
?>

C语言

支持中文,这只是解码的部分,需要需要编码,可以参考C语言实现url的编码和解码

#include <stdio.h>
#include <string.h>

#define BUFSIZE 2048

int hex2dec(char c)
{
    if ('0' <= c && c <= '9')
    {
        return c - '0';
    }
    else if ('a' <= c && c <= 'f')
    {
        return c - 'a' + 10;
    }
    else if ('A' <= c && c <= 'F')
    {
        return c - 'A' + 10;
    }
    else
    {
        return -1;
    }
}

// 解码url
void urldecode(char url[])
{
    int i = 0;
    int len = strlen(url);
    int res_len = 0;
    char res[BURSIZE];
    for (i = 0; i < len; ++i)
    {
        char c = url[i];
        if (c != '%')
        {
            res[res_len++] = c;
        }
        else
        {
            char c1 = url[++i];
            char c0 = url[++i];
            int num = 0;
            num = hex2dec(c1) * 16 + hex2dec(c0);
            res[res_len++] = num;
        }
    }
    res[res_len] = '\0';
    strcpy(url, res);
}

int main(int argc, char *argv[])
{
    char buf[BUFSIZE] = "%59%69%70%70%65%68%21%20%59%6F%75%72%20%55%52%4C%20%69%73%20%63%68%61%6C%6C%65%6E%67%65%2F%74%72%61%69%6E%69%6E%67%2F%65%6E%63%6F%64%69%6E%67%73%2F%75%72%6C%2F%73%61%77%5F%6C%6F%74%69%6F%6E%2E%70%68%70%3F%70%3D%6F%6C%69%6F%62%66%69%6D%70%6C%6D%67%26%63%69%64%3D%35%32%23%70%61%73%73%77%6F%72%64%3D%66%69%62%72%65%5F%6F%70%74%69%63%73%20%56%65%72%79%20%77%65%6C%6C%20%64%6F%6E%65%21";
    urldecode(buf); 
    printf("%s\n", buf);
    return 0;
}

Bash

如果是在linux中,可以直接在终端解码

xxd 命令用于用二进制或十六进制显示文件的内容
-p 以 postscript的连续十六进制转储输出,这也叫做纯十六进制转储。
-r 逆向操作: 把xxd的十六进制输出内容转换回原文件的二进制内容。

echo -n "%59%69%70%70%65%68%21%20%59%6F%75%72%20%55%52%4C%20%69%73%20%63%68%61%6C%6C%65%6E%67%65%2F%74%72%61%69%6E%69%6E%67%2F%65%6E%63%6F%64%69%6E%67%73%2F%75%72%6C%2F%73%61%77%5F%6C%6F%74%69%6F%6E%2E%70%68%70%3F%70%3D%6F%6C%69%6F%62%66%69%6D%70%6C%6D%67%26%63%69%64%3D%35%32%23%70%61%73%73%77%6F%72%64%3D%66%69%62%72%65%5F%6F%70%74%69%63%73%20%56%65%72%79%20%77%65%6C%6C%20%64%6F%6E%65%21" | tr -d % | xxd -r -p; printf "\n"

顺便提下利用xxd进行url编码的方法:

echo -n "兔子昂" | xxd -p | sed 's/\(..\)/%\1/g'