Normal_gaussian 8 days ago

I guess an interesting attack would be a screen in a public setting that alters the QR code based on information it has about the current user, without appearing to change significantly.

setup:

- make the QR code as a half/half code

- have a system to decide preference of target based on external input (e.g. camera based characteristic evaluation)

- make slight dynamic alterations to the colours of the code to bias the probability of it being picked up as the desired target. Desirable black/white can be made blacker/whiter, less desirable less so.

Where to use it maliciously:

- anywhere where people provide feedback - present alternate feedback forms to different demographics to engender the most positive (or negative) results.

- pretend to offer some form of probabilistic chance to win a prize, but bias winning to some identifiable characteristic. e.g. race, age, "beauty"

- target a specific person - have them join a different WiFi network, alter a payment page, etc.

In a static setting its less effective. I can't immediately think of a static attack that benefits from siphoning some reduced fraction of users.

I'm doubtful most people would notice a QR code dynamically changing, particularly in most public lighting.

  • t_mann 8 days ago

    All of those could be done much more stealthily server-side, though, I don't get what the QR code modification would add here? Also, neither use case makes use of the hack described in the OP. Where I could see an attack based on that hack would be where an attacker plasters their code over a legitimate one. It would be kind of random which code gets read, so they could send some %-age of users to the original destination, hence possibly delaying detection. But it doesn't seem a given that this would compensate for the reduced traffic to their link.

    • post-it 8 days ago

      Some sort of MITM attack by someone who owns the display but not the server, maybe. Like a malicious ad company.

      • t_mann 8 days ago

        Ok, but then I'd still prefer a method that sends users to a unique URL. OP's method may help with obfuscating the changing of the code, but I'm sure there are ways to better achieve that without having to introduce this quasi-randomness. The simplest would probably be to just to regularly hide/show the code (which would happen anyway on a typical digital ad display that cycles through a number of ads).

        • post-it 7 days ago

          But hypothetically, the owner of the ad might pop in and make sure

          1. the ad looks correct, and

          2. the URL is the one they expect

          So there may be a use case for a QR code that looks almost identical but goes somewhere else, allowing them to swap it out while someone is looking at it without them realizing.

          A niche use case, to be sure, but being able to exploit a niche vulnerability is a skill.

      • michaelmior 7 days ago

        But if you own the display, you can send the user to whatever server you want.

    • dspillett 7 days ago

      > All of those could be done much more stealthily server-side, though, I don't get what the QR code modification would add here?

      Even if the adversary controls the server side as well, you need to tell the server the information needed to make a decision If you control everything that is easy enough too, but perhaps you want to keep the decision-making process local – for plausible deniability server-side, just to reduce server & bandwidth load, or because you are sending people to completely different destinations not just altering link parameters.

      Replacing the QR code more statically sends everyone to the new address, not just the target(s), altering the QR code by a bit or two (and the relevant error correction bits too) in response to a pile of information available at the QR reading site (feeds from cameras, and such) would be how the server knows to react differently without having access to that collection of information itself. You might want to use some clever analysis to minimise the visual effect if you are altering the QR code while it is already displayed – the two examples here look very different, but the change could be much more subtle. If sending to very different destinations, so the codes for the URLs will look very different, then adding a link anonymiser between would keep the change minimal.

      > Also, neither use case makes use of the hack described in the OP.

      True.

  • michaelt 7 days ago

    There are actually attacks based on changing public QR codes already!

    They don't need anything as sophisticated as this dual QR code, though - the attackers just go to a car park with a "pay by phone" sign, slap their own QR code over the "scan to pay" code, and wait for the credit card details to start coming in.

    • Terr_ 7 days ago

      Hmmm, there might be some criminal utility in capturing <100% of visitors, so that the true owner doesn't easily realize that activity for that location has ceased. In other words, giving up a certain number of victims in order to keep the attack going for longer.

      That said, it'd probably be easier to implement that in software, where the phishing site redirects a certain portion of visits back to the legitimate one.

      P.S.: There's also the physical stealth aspect, but I think a lenticular design would probably be easier for a human worker to notice, compared to a regular flat sticker which just happens to encode a typo-squatting URL.

      • alphan0n 7 days ago

        I almost got taken in by a fake parking ticket scam, perfect ticket/envelope, the url printed on the ticket led to a 404 on the legitimate city website, the QR code led to a very convincing website/url, especially on mobile.

        The only reason I caught it was that I had gotten a legitimate ticket a month prior for parking too close to the fire hydrant and had marked the curb with chalk at the correct distance. So I tried to dispute the fine and discover that the ticket didn’t actually exist. And the city had no interest in the fake ticket whatsoever. They were just like “yeah, it happens all the time”.

  • nroets 7 days ago

    I guess similarly you can carefully craft a poster with a QR code and put it on a wall in a room with two LED bulbs. The bulbs will have different color temperature and the decoding will be dependent on which bulb is lit.

    Another idea would be a poster that's not quite flat: Each pixel that is different is slightly raised (pyramid shaped) and the sides of the pyramid is colored differently. So the QR code scans differently from different sides.

    One of the dominant banks here in Tbilisi allows sharing of IBAN number as QR codes. In theory, the trick could be used to steal money, but in practice, there are many safeguards such as the banking app displaying the name of the beneficiary before completing the process.

    • chii 7 days ago

      > banking app displaying the name of the beneficiary

      and the scammer make an account with a name that look similar at a glance (e.g., swap the l with a 1, or something of the sort).

      • fxtentacle 7 days ago

        Most likely, they have <1s bank transfers, too, like pretty much all of Asia. That way, if you pay someone with a QR code, they'll immediately get the notification that they received your payment. And if they don't, you immediately know that something went wrong.

        • echoangle 7 days ago

          But then it’s too late, you have to find out before send the money.

          • fxtentacle 7 days ago

            Most scammers will try to avoid situations where you can punch them in the face. => If scams usually get notified before the perpetrator can run away, that will discourage scamming. => In practice, it might be "good enough" if you know immediately after sending money.

    • heeen2 7 days ago

      you could use glossy/matte or metallic finish, then the reflected light could appear brighter than the white parts

  • hnlmorg 7 days ago

    > alters the QR code based on information it has about the current user, without appearing to change significantly.

    I doubt many people would notice if your average QR code was to change significantly. Most machine readable formats are just indistinguishable white noise to most people.

  • eieio 8 days ago

    I appreciate you laying out malicious use-cases instead of just having the setup section; I would have struggled to think of those!

    FWIW the place my brain went was some kind of magic trick, since having control of this could function kind of like a forcing a specific card or something

  • alan 8 days ago

    Static a/b testing?

  • tbrownaw 8 days ago

    > pretend to offer some form of probabilistic chance to win a prize, but bias winning to some identifiable characteristic. e.g. race, age, "beauty"

    Do a facial recognition lookup against the RealID database (I'm sure someone must be selling a leaked or hacked copy by now) and make the prize depend on the first letter of the person's last name.

  • Normal_gaussian 8 days ago

    Identifying this should be relatively easy in the core libraries; finding alternate valid QR codes using "less optimal" grids.

    Of course the API confusion here becomes non-trivial, which hampers securing against it. And with existing libraries being widespread, its going to linger as an attack for a long time.

  • pockmarked19 8 days ago

    You don’t need any of this if you control the app doing the scanning (or the website/app handling the result).

    • Normal_gaussian 8 days ago

      You wouldn't control the app doing the scanning.

      The attack is that a user looking at a QR code cannot determine that they are being served a different code to another person.

      In a public setting a user would have no idea they are even capable of being targetted and treated differently.

      • t_mann 8 days ago

        You don't even need to change the QR code to treat users differently, that's the point. You just send users to some fixed URL, which is by far the most common use for QR codes (hence completely unsuspicious), and you decide who gets served what there, based on whatever data you gathered about them. And the users that would care are already acutely aware that that's how a majority of the web works nowadays, QR codes or not.

        • Normal_gaussian 8 days ago

          The value of an attack vector is not negated by there being other ways to achieve it.

          This particular vector has the strength of being able to manipulate things other than URLs; QR codes support WiFi credentials, contact details, call, text (with content), email (with content), calendar events. Additionally, many app specific URIs never leave the device.

          It has the significant downside of being plainly visible as a possibility to those in the know.

          However, I suspect it may still be desirable to do this on the device rather than the server.

          The other properties it varies are the obvious lack of reliance on a server. The improved "transparency" of showing the target URL for trust. The removal of the need for an internet connection.

          But for an implementer I'd imagine the most beneficial upside is not needing to manage a timing-attack, and gaining additional targetting accuracy in the common case of a picture. There may also be organisational complexity reduction in pushing all the decisioning to the display/camera system.

          Its fun to think about, with the significant weakness in both its visibility and its probabilistic nature I wouldn't expect widespread use.

      • csomar 8 days ago

        Static Qr-Code but serve different content? If you are targeting by the camera, you can try to link the person to the time the QrCode was scanned and have each QrCode print identified.

jdoe1337halo 7 days ago

Hey guys I made a website so yall can try this out yourself! I don't have the exact methodology that Christian uses, so here is how I did it:

The ambiguous QR code in this application works by combining two different QR codes into a single image using a diagonal split pattern. When two QR codes have different patterns at the same position, the cell is split diagonally - one half represents the first QR code and the other half represents the second QR code. When both QR codes have the same pattern at a position (both black or both white), the cell is filled with a solid color. Due to the high error correction capability of QR codes (using error correction level 'H'), QR code scanners can still read either URL depending on the scanning angle, though as noted in the UI, it tends to favor the second URL more frequently.

https://dualqrcode.com/

  • HenryBemis 7 days ago

    It didn't work for me. I generated two links (BBC, CNN) and tried on my Android, with the app "QR & Barcode Scanner" v2.2.47. I also tried with the stock camera of an iPhone 13. In both they couldn't 'read' them.

nixpulvis 8 days ago

The most interesting thing about this to me is that on iOS a long press on the image claimed it's going to github.com, while the preview itself was for mastadon. This indicates that it's parsing the QR code twice and getting different results? I could see this being used to mislead some people, though I'm not sire how many people look at the long press dropdown URL.

  • codetrotter 8 days ago

    Tangential but once in a blue moon I come by some situation where I’m on my phone and I’m looking at something that has a QR code showing on the screen of the phone itself.

    And so I do something silly like airdropping a screenshot of it to my laptop so I can scan it with my phone camera, or I get someone else (friends, family) to use their phone to scan the code from my phone screen with the camera app on their phone.

    And all this time I was annoyed why I couldn’t just get the link directly from the image on my phone without involving another device, and without having to install yet another third-party app.

    And today I learned that all I had to do was long press the QR code in the screenshot in my camera roll and it would actually parse it and make it so I could visit the link!

    I think I must have tried long pressing QR code in an image in the camera roll years ago because it always seemed like something that would make sense to support via long press. Maybe they introduced this feature after I had tried to long press a QR code in an image in the past. Or maybe it was always possible and I didn’t actually ever try to long press it. Or maybe I long pressed the wrong part of the image that first one or two times I ever tried to do it in the past. Either way, very happy to have learned that this is actually possible.

    • kccqzy 8 days ago

      Long pressing still doesn't work for me. Perhaps because I turned off some features related to image intelligence.

      • poglet 8 days ago

        On iOS I believe the option is in Settings > General > Language & Region > Live Text. This was introduced in iOS 15.

    • davchana 8 days ago

      Yes, I usually share it with Google App, and Lens tab.

  • russellbeattie 7 days ago

    I can totally see two parts of the OS both using their own QR parsing code - SmartText using one, and the imaging system another. Apparently each one has their own slightly different error correction implementation.

    I bet it'd be possible to create a standard QR Code with a deliberate error that does the same thing. You'd just have to figure out how they're correcting the error differently.

    Seems like you discovered a bug-bounty bug just waiting for someone to claim.

  • the_arun 8 days ago

    QRCode should also show the target url in text, so the user knows where it is taking - something like explicit consent.

    • efreak 7 days ago

      Google lens and other apps do this.

      I've seen apps that read QR codes that don't, however. Usually they're single-purpose and just don't recognize unexpected data (scan the magic code to get a character in a game, etc) but if the expected data is formatted as a URL, maybe it tries to fetch resources there (character information and image).

      I can also see someone making a browser extension that allows scanning a QR code to immediately open it so you don't have to leave your current app.

    • jimjimwii 7 days ago

      Yep, like how browsers show users urls in their location bars.

  • _august 8 days ago

    When I long-press on iOS, it shows me the mastadon link as the main "Open" link, as well as "Open in Github" (app link) in the context menu.

  • layer8 7 days ago

    This is likely the typical case of related code calling the same function or getter method twice in a context where it is imperative for both calls to return the same result.

    It is reminds me of code like

       if someCondition(getFoo()) 
       then doSomethingWith(getFoo())
    
    or even just

        doSomethingWith(getFoo())
        doAnotherThingWith(getFoo())
    
    which is always a code smell, as opposed to

        foo := getFoo()
        if someCondition(foo) 
        then doSomethingWith(foo)
    
    and

        foo := getFoo()
        doSomethingWith(foo)
        doAnotherThingWith(foo)
  • noitpmeder 8 days ago

    now THIS sounds like an exploit

re 8 days ago

(Scroll up from the starting position to see the lenticular one)

ShakataGaNai 8 days ago

That is gnarly. My iPhone tended to lock into one or the other, rotating the phone seemed to help it go one way or the other. But a couple times it did flash back and forth between the Mastadon and GitHub links.

andrewla 7 days ago

If you want to try it out, here's some quick and dirty code.

Install the qrcode python package and run this code:

    import qrcode

    bar = qrcode.QRCode(border=0)
    bar.add_data('bar')
    bar.make()
    bar_mat = bar.get_matrix()

    foo = qrcode.QRCode(border=0)
    foo.add_data('foo')
    foo.make()
    foo_mat = foo.get_matrix()

    for l, r in zip(foo_mat, bar_mat):
        line = ''
        for lc, rc in zip(l, r):
            line = line + (lc and '\u2588' or ' ')
            line = line + (rc and '\u2588' or ' ')
        print(line)
        print(line)
What you get is indeed a dualing qrcode (which I can't quite paste here because no unicode on HN, and using "8" or "0" isn't enough to get my phone to recognize it).
dwheeler 7 days ago

Shouldn't one of the URLs implement a Rick Roll :-) ?

65 8 days ago

This would be cool to use in a scavenger hunt.

  • TOMDM 8 days ago

    Maybe make it so that you need the results of both (all?) QR codes to get the final code/link/key.

johnea 7 days ago

QR codes, like shortened URLs, are just begging to exploit.

It's an inherently unreadable URL, you really have no idea where you will be sent, or how many times you will be redirected.

I don't use them...

danvoell 7 days ago

This is such a cool concept! If you're focusing on the end goal, another approach could be using a "switch" at the URL destination—something that redirects users to a different page based on a randomizer, user data, or other criteria. For anyone exploring this kind of functionality and interested in testing physical stickers for their projects, I work with a lot of SaaS companies on variable labels and would be happy to share insights, print some samples or collaborate.

mkl 7 days ago

My phone (Samsung Galaxy Note 20) seems to reject almost all of these, and not recognise them as QR codes. I got one to work for one URL by moving way away from the screen.

trebligdivad 7 days ago

Someone needs to define a human-readable attachment to QR that can be checked by the QR reader; e.g. the root of the URL printed above the QR code at a specific position offset or with a specific mark; so then the QR decoder could OCR it and verify it matched the URL encoded. Only the root of the URL would be included so the QR could include a specific to that location complex path. Now, we just need to backronym SPQR to fit...

hammock 8 days ago

Can someone explain how it works?

  • jkingsman 8 days ago

    A QR code is just a series of square pixels, and whether the pixel is black or white contributes to the data. This has two QR codes, essentially overlayed one on the other. Some pixels are half black/half white, so depending on the angle you hold your phone at, the software that decodes QR codes will detect a different color as being centered in the pixel it's examining. So, based on the angle you hold your phone (some people had better success with rotation), you get one QR code or the other.

    • hammock 7 days ago

      What is half black/white though? I don’t see any gray. Only black and white

      Did he subdivide the qr code cell into four sub pixels and make the left two one color and the right two another? That’s what I would have guessed for the “lenticular” effect at different angles. But the subpixels I see are more checkerboard ish

      • layer8 7 days ago

        QR code decoders usually work by sampling the values from a dot grid overlayed on the camera image (or something along those lines). If a QR square isn’t actually uniform, the sampled value for that square will change if you move the camera a bit. When you hold a QR code in front of the camera, the picture is continuously sampled, yielding different bit values all the time because you don’t hold the camera a 100% still (in addition to sensor noise and the like). The QR decoder is however satisfied as soon as the result passes the QR checksum verification.

        The image recognition that outputs the bit pattern of the QR code is inherently heuristic in nature, and only the checksum verification is what decides if the recognition worked successfully. The trick in TFA is to produce an image where two different results of the heuristics can both pass the checksum verification, so which one you get depends on circumstantial factors.

        • hammock 7 days ago

          More non-deterministic than I would have thought. Your explanation makes sense tho thanks

Joker_vD 7 days ago

Wait, don't QR codes have checksums in them? Or do they have some sort of error correction built-in? That's the only way I can imagine it can possibly work with e.g. 85% of one QR-code blended with 15% of another one.

  • blueflow 7 days ago

    Yes, but the checksum is in the same bitstream, so it is swapped together with the data.

soheil 7 days ago

With the same link you can serve different content, QR codes typically resolve to links.

Looking up user IP (and thus country of origin), user agent, etc is enough to determine what content needs to be served.

buildbot 8 days ago

Interestingly, MacOS only sees the mastodon link when right clicking on the QR code.

  • etrautmann 8 days ago

    That makes sense, I would imagine it would require some variability via a camera with different angles/lighting conditions in order to get both links at different times.

  • tzs 8 days ago

    That's also what Mathematica's BarcodeRecognize[] sees.

  • yoz-y 7 days ago

    Funnily though, iOS recognizes the GitHub part when long pressing on it.

  • smashah 8 days ago

    Can MacOS natively scan QR codes?

Gryadn 8 days ago

[flagged]

  • casey2 8 days ago

    Attention sells products, if the next apple visions' 3D is good enough it will create a whole new product line, creating thousands of technical problem solving jobs.

    Pretty impressive for plastic waste.

daft_pink 8 days ago

I don’t really understand the value of this compared to just putting another QR code right over the pre-existing code? Why bother getting a fraction of users, when you can get all of them.

  • notRobot 8 days ago

    The value is that it's cool.