Tutkija murtautui Bitcoin-haasteen PHP-palvelimelle 19 tunnissa
James Pavurin pystyttämä stealmybitcoin.com-haaste päättyi 25. lokakuuta kello 15.47 UTC, kun KillaBoi-nimellä esiintyvä tutkija sai PHP-palvelimen suorittamaan komennon ja luki palkintopotin avaimen. Ratkaisu osoittaa, että lokakuun PHP2Shell-haavoittuvuudet ovat hyödynnettävissä oikeassa palvelimessa – mutta vain tarkasti räätälöidyssä ympäristössä.

Näin haaste rakennettiin
Haasteen pystytti Hacker News -palvelussa nimimerkillä cloudlandsdev esiintyvä James Pavur. Sivusto avautui 24. lokakuuta illalla, ja sen idea oli yksinkertainen: palvelimella oli Bitcoin-lompakon yksityinen avain, ja PHP:n käyttäjänä toimiva prosessi saattoi lukea sen vain käynnistämällä print-flag-nimisen ohjelman. Se, joka sai ohjelman suoritetuksi, sai pitää rahat. Kaikki liikenne lokitettiin.
Pavur kertoi tehneensä haasteen, koska halusi tietää, osaako kukaan todella hyödyntää sitä PHP:n etäkoodin suorittamisen haavoittuvuutta, josta verkkoyhteisö oli panikoinut edellisinä päivinä. Palvelin oli rakennettu tarkoituksella PHP-versiolle 8.4.26, joka oli julkaistu ennen 21. lokakuuta korjattuja kriittisiä haavoittuvuuksia. Kokoonpano oli nginx-palvelin PHP:n sisäänrakennetun kehityspalvelimen edessä ja neljä työprosessia. Aluksi sivusto tarjoili vain staattista HTML:ää PHP:n kautta, ja noin kello 13 UTC Pavur lisäsi php-version.php-sivun, jolla hän osoitti PHP:n olevan käynnissä.
Palkintopotti alkoi 0,00625104 bitcoinista eli noin 500 dollarista. Muut käyttäjät lisäsivät samaan lompakkoon rahaa, ja ratkaisuhetkellä potti oli 0,02511679 bitcoinia eli 2 021,22 dollaria. Pavur kuvaili ideaa vertaamalla sitä siihen, että jättää 500 dollarin setelin kadunkulmaan kyltin kanssa: ”Ota minut!” ja katsoo, kauanko se kestää.
Ratkaisu kulki muistivuodon kautta
KillaBoi julkaisi ratkaisunsa GitHubissa pian voiton jälkeen. StealMyBitcoin-PoC on yhden tiedoston Python-ohjelma, joka käyttää vain Pythonin standardikirjastoa ja tekee enintään parikymmentä HTTP-pyyntöä ilman silmukoita tai uusintayrityksiä.
Hyökkäysketju etenee neljässä vaiheessa. Ensin ohjelma lähettää multipart-muotoisen tiedostolatauksen, jonka käsittely vie PHP:n muistin rajoille asti. Kun PHP keskeytyy kesken latauksen edistymisen käsittelyn, työprosessiin jää vanhentunutta tilaa. Seuraavat pyynnöt osuvat samaan prosessiin ja saavat PHPSESSID-evästeen, josta vuotaa muistiosoitteita: ensin 256 tavua Zend-muistikasan osoitteen selvittämiseen ja sitten 16 tavua PHP:n koodiosoitteen eli zval_ptr_dtor-funktion löytämiseen.
Kun molemmat osoitteet ovat tiedossa, viimeinen pyyntö kirjoittaa muistiin väärennetyn HashTable-rakenteen, jonka puhdistuspolku tulkitsee zif_system-funktioksi. Se on PHP:n oma käsittelijä system-komennolle, joten järjestelmä suorittaa hyökkääjän komennon ja palauttaa print-flag-ohjelman tulosteen samassa yhteydessä.
Ratkaisu on kuitenkin räätälöity yhteen ympäristöön: muistiosoitteiden etäisyydet on kalibroitu Alpine Linuxille, PHP 8.4.26:lle ja neljälle työprosessille. Debian-pohjainen PHP-FPM-asennus samalla versionumerolla ei läpäise koodiosoitteen tarkistusta. KillaBoi kertoo, että hänen laboratoriossaan ketju onnistui seitsemän kertaa kymmenestä.
Palvelimella oli väärä avain
Voitto ei kuitenkaan mennyt aivan suunnitellusti. KillaBoi sai palvelimelta WIF-muotoisen yksityisavaimen, jonka tarkistussumma oli kunnossa, mutta avain ei johtanut sivustolla näkyvään palkintolompakon osoitteeseen. Pavur kertoi Hacker Newsissä laittaneensa palvelimelle lompakon haarautuman avaimen eikä rahoitetun osoitteen avainta. Hänen mukaansa hyvin muodostetun Bitcoin-avaimen vieminen lompakosta on yllättävän vaikeaa.

Pavur hyväksyi suorituksen voitoksi silti. Palvelimen lokit tukivat sitä, että print-flag oli suoritettu onnistuneesti ensimmäistä kertaa ja että tuloste oli saatu ulos palvelimelta. Lisäksi KillaBoi tunsi palvelimella olleen avaimen tarkan arvon ja oli julkaissut sen kolme viimeistä merkkiä keskusteluketjussa jo ennen voiton vahvistamista. Pavur siirsi palkinnon heti tarkistettuaan todisteet.
Lohkoketju vahvistaa rahojen liikkeen. Palkintolompakko bc1qlnu50y4zm0nwxkckxu09thn5xdcz8aw6t3cxqy vastaanotti seitsemässä siirrossa yhteensä 0,02511679 bitcoinia, ja koko saldo siirrettiin pois kahdessa tapahtumassa 25. lokakuuta illalla. Viimeinen siirto, 0,02509122 bitcoinia, lähti uuteen osoitteeseen kello 23.17 UTC (mempool.space, 26.10.2026). Julkinen kirjanpito ei kerro, kenen hallussa varat nyt ovat.
Taustalla PHP2Shell ja tekoälyn löytämä haavoittuvuus
Haasteen taustalla ovat PHP:n kaksi kriittistä haavoittuvuutta, CVE-2026-109618 ja CVE-2026-109619, jotka tunnetaan yhteisnimellä PHP2Shell. PHP julkaisi korjaukset 21. lokakuuta versioissa 8.5.12, 8.4.27, 8.3.36 ja 8.2.35. Molempien vakavuusluokitus on CVSS 9.2, ja ne mahdollistavat autentikoimattoman koodin suorittamisen palvelimella.
Wiz Research löysi haavoittuvuudet tekoälymallien avulla. Yhtiön mukaan viat ovat olleet PHP:n ytimessä yli vuosikymmenen, ja niiden hyödyntäminen vaati aiemmin poikkeuksellisen monimutkaisen ketjun. Wiz käytti työssään muun muassa Gemini 4 Argon- ja GPT-5.6 Sol -malleja. Haavoittuvuudet koskevat PHP-versioita 5.4 lähtien, ja ne toimivat sovelluksen koodista riippumatta.
PHP:n oma tiedote korostaa, että päivitys on ainoa täydellinen korjaus. Jos päivitys ei ole heti mahdollinen, PHP suosittelee muun muassa muistirajan poistamista käytöstä, post_max_size-asetuksen pienentämistä ja session.upload_progress.enabled=0 -asetusta. Jälkimmäinen sulkee yhden hyökkäysreitin, muttei kaikkia.
Mitä tapaus todistaa ja mitä ei
Osa keskustelijoista huomautti, että ympäristö ei vastannut tavallista tuotantopalvelinta: PHP:n sisäänrakennettu kehityspalvelin on tarkoitettu paikalliseen kehitykseen, ja sen dokumentaatio varoittaa käyttämästä sitä julkisessa verkossa. Pavur vastasi, että tavoitteena oli jäljitellä melko tavallista kokoonpanoa ja että nginx-asetuksilla näyttää voivan lieventää PHP2Shellin vaikutusta.
Ratkaisun todistusarvoa rajaa myös se, että hyökkäys onnistui yhdessä ympäristössä 19 tunnin aikana, kun palvelin oli jatkuvan kuormituksen ja kaatumisten kohteena. KillaBoi korostaa itse, että ohjelma on kalibroitu yhteen ympäristöön eikä toimi sellaisenaan toisessa. Hän ei myöskään mainitse kirjoituksessaan disable_functions-asetusta, eikä julkisesti ole osoitettu, pysäyttäisikö se ketjun. Pavur on luvannut kirjoittaa kokemuksistaan haasteen ylläpitäjänä, ja sivusto vihjaa, että uusia haasteita voi tulla.
Lähteet
- Steal my Bitcoin -sivusto – Challenge won – 25.10.2026 – https://stealmybitcoin.com/
- GitHub – KillaBoi/StealMyBitcoin-PoC – 25.10.2026 – https://github.com/KillaBoi/StealMyBitcoin-PoC
- Hacker News – Show HN: Steal My Bitcoin – 24.10.2026, klo 23.30 (Europe/Helsinki) – https://news.ycombinator.com/item?id=50224916
- X – LiveOverflow – stealmybitcoin was just solved by @killa – 26.10.2026, klo 01.45 (Europe/Helsinki) – https://x.com/LiveOverflow/status/2114488571021398330
- PHP – Security advisory: Critical remote code execution vulnerabilities, update now – 21.10.2026 – https://www.php.net/archive/2026.php#2026-10-21-5
- Wiz Research – PHP2Shell: AI uncovers critical RCE vulnerabilities affecting 70% of the Internet – 21.10.2026 – https://www.wiz.io/blog/php2shell-php-rce
- mempool.space – Palkintolompakko bc1qlnu50y4zm0nwxkckxu09thn5xdcz8aw6t3cxqy – haettu 26.10.2026 – https://mempool.space/address/bc1qlnu50y4zm0nwxkckxu09thn5xdcz8aw6t3cxqy
Vastuuvapauslauseke: Tämä artikkeli on tarkoitettu vain tiedotustarkoituksiin. Sitä ei tarjota tai ole tarkoitettu käytettäväksi oikeudellisena, verotuksellisena, sijoitus-, rahoitus- tai muuna neuvona.
Mainos: jutun lopussa on kumppanimainoksia ja mainoslinkkejä. Kryptouutiset.net voi saada provision, jos rekisteröidyt palveluun kutsukoodin tai linkin kautta. Tämä kaupallinen yhteistyö ei vaikuta uutisten sisältöön tai toimituksellisiin johtopäätöksiin.


