Cookies op Tweakers

Tweakers maakt gebruik van cookies, onder andere om de website te analyseren, het gebruiksgemak te vergroten en advertenties te tonen. Door gebruik te maken van deze website, of door op 'Ga verder' te klikken, geef je toestemming voor het gebruik van cookies. Wil je meer informatie over cookies en hoe ze worden gebruikt, bekijk dan ons cookiebeleid.

Meer informatie

Microsoft patchte oud Office-lek zonder code te hercompileren

Een lek in een oude Office-component is volgens onderzoekers van 0patch op een bijzondere manier gepatcht. Het lek is gedicht door niet de broncode, maar de exe aan te passen. Mogelijk is Microsoft de betreffende broncode kwijt, maar er zijn ook andere verklaringen.

0patch meldt dat het normale proces van het uitvoeren van een patch bestaat uit het herschrijven van een deel van de broncode, waarna het betreffende exe-bestand weer opnieuw gecompileerd wordt. Dat gebeurde in dit geval niet, waardoor iemand bij Microsoft de exe heeft aangepast zonder over de broncode te beschikken. De auteurs van de 0patch-blogpost zeggen onder de indruk te zijn van het resultaat en willen graag in contact komen met de verantwoordelijke.

Ze baseren hun conclusie dat de exe handmatig is aangepast op de bevinding dat alle functies na de patch nog op hetzelfde adres te vinden zijn, wat niet zou gebeuren als er eerst een compiler overheen was gegaan. Het bestand in kwestie is eqnedt32.exe, een editor voor wiskundige vergelijkingen in Office-software. De oorspronkelijke exe is volgens 0patch in 2000 gecompileerd, wat het een antiek stukje software maakt.

Vorige week bleek uit onderzoek van beveiligingsbedrijf Embedi dat het mogelijk is een buffer overflow in de software teweeg te brengen, waardoor kwaadwillenden code kunnen uitvoeren op kwetsbare systemen. Reden dus voor Microsoft om een patch uit te voeren. Waarom het bedrijf niet de broncode heeft aangepast om de code vervolgens te hercompileren, is onduidelijk, wellicht speelt er een licentiekwestie of is er een kans dat de code gewoonweg kwijt is, naast veel andere mogelijke verklaringen.

Uit de exe is op te maken dat het auteursrecht toekomt aan het bedrijf Design Science, dat tegenwoordig een vergelijkingseditor met de naam MathType ontwikkelt. Volgens 0patch kan Microsoft de oude editor niet zomaar uit zijn software verwijderen, omdat dit voor compatibiliteitsproblemen zorgt.

Screenshot van de bestandseigenschappen

Door

Nieuwsredacteur

74 Linkedin Google+

Reacties (74)

Wijzig sortering
Ze baseren hun conclusie dat de exe handmatig is aangepast op de bevinding dat alle functies na de patch nog op hetzelfde adres te vinden zijn, wat niet zou gebeuren als er eerst een compiler overheen was gegaan.
Dit is niet in alle gevallen correct. Bij kleine veranderingen is het mogelijk dat de binary grotendeels hetzelfde blijft. Het is ook mogelijk dat er achteraf nog met de binary gespeeld is om het zo min mogelijk te doen verschillen met de vorige build. Waarom zouden ze dat doen? Omdat je dan meer zekerheid hebt dat je programma zich gedraagt zoals de vorige versie en dus eventueel de QA testing relevant blijft voor deze versie.
Als je het originele artikel leest (en begrijpt) dan zie je nog veel duidelijkere tekens. Zo is in de gewijzigde versie een snelle versie van mempcy vervangen door een tragere. De snelle versie kopieert 4 bytes per keer, met aan het einde nog een separate kopie van de laatste 0-3 bytes. De gewijzigde versie kopieert 1 byte per keer, waardoor die tweede kopie overbodig is. Dat levert genoeg ruimte op om er een bounds check in te duwen.

Een andere opvallende wijziging is dat een stack variable naar een register is verplaatst, maar de stack grootte is niet aangepast. Register instructies in x86 zijn korter, dus ook deze truc leverde weer extra bytes op om een check in kwijt te kunnen.
Het is quasi onmogelijk dat men oude source code opnieuw door een recente compiler haalt en byte for byte exact dezelfde output heeft...
Maar je haalt hem ook niet door een nieuwe compiler, als het slechts om een eenvoudige bugfix gaat. De code zal niet zonder meer compileren, en je moet er dus een hoop tijd instoppen, en verder loop je kans allerlei subtiele bugs te gaan triggeren.
Maar je haalt hem ook niet door een nieuwe compiler
Ik denk dat daar het probleem zit. Russinovich (CTO Windows Azure) heeft ooit gezegd:
"If you open source something but it comes with a build system that takes rocket scientists and three months to set up, what's the point?"
Ik denk dat een belangrijk verschil tussen open- en closed source software is: de open source software moet op meerdere plaatsen te compileren zijn. Voor closed source software heb je in prinicpe maar één computer nodig met de juiste hardware, software en instellingen om het pakket uit te kunnen brengen (een build server als er meerdere mensen aan werken). Het is niet ondenkbaar dat de vergelijkingseditor door maar weinig mensen onderhouden werd, en de compilatiemachine jaren geleden afgeschreven is. Nu de juiste omgeving herstellen zou wel eens meer moeite kunnen zijn dan een hexeditor aanslingeren.

edit:
De quote toegevoegd

[Reactie gewijzigd door 84hannes op 20 november 2017 15:03]

Je belicht hier slechts één aspect van open source: de mogelijkheid om zelf te compileren (al dan niet na het doen van aanpassingen). Een ander aspect is de mogelijkheid tot openbare code review, op zoek naar kwetsbaarheden, of bijvoorbeeld de mogelijkheid om van code te leren. Die laatste twee punten waren nog steeds valide geweest als Windows open source was geworden, ook al was het 'niet te compilen'.
Daar heb je gelijk in. Wel blijf ik van mening dat je bij open source code die niet gecompileerd kan worden impliciet om vertrouwen vraagt: vertrouwen dat de binaire code die je krijgt inderdaad gemaakt is met behulp van de geleverde broncode. Een achterdeurtje inbouwen en opnieuw compileren blijft immers mogelijk.
Op dat gebied heeft Microsoft vrij grote stappen gemaakt. Een heleboel van die build problemen zijn opgelost in Windows 8 en 10. Zo had je vroeger een aantal cyclische dependencies. Om A.DLL te bouwen moest je B.DLL al gebouwd hadden, en ook andersom. Dat maakte een clean build onmogelijk. Maar in nieuwe Windows builds zijn A.DLL en B.DLL simpele wrappers voor AA.DLL, AB.DLL en BB.DLL, en die nieuwe DLL's hebben dan geen cyclische depencies meer.
Bedankt voor je toevoeging, ik heb nooit willen beweren dat Microsoft dezelfde puinhoop is/levert als tien jaar geleden.
Dat is minder opzienbarend dan het lijkt. In programmeertalen waarin je de definities van de implementaties kunt scheiden heb je daar geen last van.
Zo simpel ligt het niet, anders had Microsoft het 20 jaar geleden wel gefixt. De problemen waren (als ik het goed begreep) gelegen in COM/IDL. In het bijzonder kun je met COM interface definities uit een binary trekken, en als pseudo-header includen in source code. B.cpp kan dus afhankelijk zijn van A.DLL, en dat is precies de omgekeerde richting (source met dependency op binary). Als A.cpp dan weer afhankelijk is van B.DLL, dan heb je dus die cyclische dependency te pakken.
Al is dat niet altijd per definitie een regel. Solaris was lange tijd closed source, en toen het open source werd bleek de code heel netjes te zijn, blijkbaar.

Overigens denk ik dat Microsoft onderhand wel zijn build farm al een paar keer vervangen heeft; anders zou Windows nog steeds op systemen uit '93 gecompiled worden - en bovendien was de NT-kernel altijd al gebouwd op het ondersteunen van meerdere platformen. Ohja, en anders zou het compilen van nieuwere versies van Windows steeds trager worden.

[Reactie gewijzigd door field33P op 20 november 2017 15:08]

"If you open source something but it comes with a build system that takes rocket scientists and three months to set up, what's the point?"
The point is dat er waarschijnlijk wel ergens in de wereld build system wizards zijn met een hoop tijd over die het er voor over hebben, of die je kan inhuren om dingen voor u te fixen.

Ik heb toevallig enkele jaren ervaring in het laten werken van ingewikkelde build systems die bedoeld zijn voor de gnu toolchain toch te laten compileren met bvb de intel compilers. Ja het vergt soms heel wat uitpluiswerk, maar ik ben nog nooit een project tegengekomen dat niet te fixen valt (ja, soms moet je zelf wat gcc-isms en assembly fixen, maar met de nodige tijd en moeite raak je er vaak toch wel.)

De resultaten van al dit werk (we automatiseren al deze builds in een build framework) (merendeel van collega's en conculega's) is natuurlijk open source en te vinden op https://easybuilders.github.io/easybuild/
Ik vraag me af of dat wel zo is, als de aanpassing op een hele kleine plek zit en de compiler dezelfde weg aflegt dan is het heel goed mogelijk dat de meeste functies gewoon nog steeds op dezelfde plek blijven zitten. Zou eigenlijk ook raar zijn als je zonder aanpassingen telkens een ander resultaat zou krijgen na een compile.
Het deel
recente compiler
is hierin essentieel gezien de bewuste binary in 2000 is geproduceerd. Er is in de tussentijd waarschijnlijk zoveel gewijzigd aan de bewuste compiler dat het aannemelijk is dat je het zeker gezien had als het bestand opnieuw gecompileerd zou zijn.

Als ze zouden compileren met de oude compiler dan zou je waarschijnlijk gelijk hebben.
T punt is eerder dat ze wel vc6 van destijds gebruikt zouden kunnen hebben, maar die kon geen reproduceerbare builds maken. Sowieso kan VC dat niet.
en de oude runtime !

memcpy() is onderdeel van de stdlib en ook een functie waarvoor de compiler typisch zelf geoptimaliseerde runtime implementatie(s) biedt.
Optuigen van de oude build zal niet hebben gebaat in dit geval, dan had de aanroep van memcpy() moeten worden vervangen door die naar een "eigen" functie.
Zou eigenlijk ook raar zijn als je zonder aanpassingen telkens een ander resultaat zou krijgen na een compile.
Dat is juist de regel; twee keer compileren en dan ook twee keer exact hetzelfde resultaat krijgen is de uitzondering. Google maar eens naar "reproducible build".
Is het niet mogelijk om, als de code is geschreven in een .net taal, deze met ildasm (IL Disassembler) terug te compilen naar een bestand in deze taal en deze vervolgens met ilasm weer terug te brengen naar een exe? Of gaat dan het verhaal niet op van de ongewijzigde adressen? Zelf wel eens gespeeld met de ildasm tool, maar nooit gekeken of dan de adressen wijzigen. In feite is ildasm ook een soort compiler, maar zou het op deze manier kunnen zijn gedaan?

Zelf in de Exe de zaken aanpassen is wel een heel ander verhaal inderdaad. Als dit het geval is, dan hebben ze knap werk geleverd.


--edit--
Zoals aangegeven in de reacties hieronder kan dit niet, aangezien .Net later uitkwam dan wanneer dit programma was gecompileerd.

[Reactie gewijzigd door YdieresiS op 20 november 2017 11:59]

Het stuk software komt uit 2000, dat zal wel niet in een .NET taal geschreven zijn. De eerste beta's van .NET 1.0 zijn van eind 2000.
@rhuijben en @Morgan4321
Bedankt voor de verbetering, zo goed was ik niet op de hoogte van de geschiedenis van .NET. Zal het volgende keer nog wat verder onderzoeken voordat ik een reactie plaats.

Mijn bedachte wijziging kan dus niet uitgevoerd zijn. Ben wel erg benieuwd naar hoe Microsoft dit dan precies gedaan is. Hopelijk komt er nog een statement van Microsoft of komen de onderzoekers van 0patch nog met een grondigere verklaring.
Op dezelfde manier als al die game crackers natuurlijk. Desnoods decompileren naar assembler en kijken wat aangepast moet worden.
Ben wel erg benieuwd naar hoe Microsoft dit dan precies gedaan is.
Gewoon door iemand met de hand object code te laten aanpassen. Ja, het is een vervelend rotwerkje en ja, het vereist een nogal specialistische set van skills, maar object code is niet magisch of wat dan ook. :-o Er is geen enkele reden dat een mens dit niet handmatig zou kunnen doen. Er is een gigantische waslijst van redenen waarom een mens het niet zou willen doen, maar in geval van nood is het prima mogelijk.
Het programma was gecompileerd in 2000, zie artikel. .Net 1.0 werd gereleased in 2002.
ik vermoed dat hij het meteen hex editor heeft gedaan.
Het principe is hetzelfde met een 'normale' decompiler, of met een debugger..
Vooropgesteld dat iemand die de exe heeft gehacked op deze manier enorme vaardigheid in coderen heeft en hiermee een behoorlijke hoeveelheid bragging rights verkrijgt, vraag ik me af waarom.
De output van de equation editor is niet extreem complex. Je hebt elementen met een positie en een programma wat dit aanstuurt. Dat zou geen rocketscience moeten zijn.
Was het dan niet eenvoudiger geweest om het programma opnieuw te schrijven, zodat deze het bestaande formaat kan inlezen en weergeven en dat de output naar de huidige standaard is? Technisch gezien ben ik daar vrij zeker van. Dit zou suggereren dat de gestelde hypothese van het ontbreken van een licentie de oorzaak van deze exe aanpassing is.

En dat baart me zorgen. Je hebt nu een congolomeraat als Microsoft wat de skills in huis heeft om dit te doen, maar elke normale partij had de keuze gehad tussen een nieuwe licentie afsluiten, de functionaliteit uitschakelen en de fout laten bestaan.
Een lek wil je zo snel mogelijk dichten en als de exe patchen sneller is dan het programma opnieuw schrijven kies je daarvoor. Maar het is denkbaar dat later een nettere oplossing volgt.
Was het dan niet eenvoudiger geweest om het programma opnieuw te schrijven, zodat deze het bestaande formaat kan inlezen en weergeven en dat de output naar de huidige standaard is?
De volledige equation editor herschrijven kost maanden; als dat zo simpel was, waarom denk je dan dat ze het ding oorspronkelijk bij een externe partij hebben ingekocht...!? Al die maanden blijft het lek bestaan en is vatbaar voor misbruik. Daarnaast is het een gigantische investering, de kosten zullen talloze malen hoger zijn dan de oplossing waar nu voor is gekozen.
een congolomeraat als Microsoft wat de skills in huis heeft om dit te doen
Ehm ja, ik zou toch hopen dat een conglomeraat als Microsoft een paar mensen in dienst heeft die weten wat object code is, hoe je dat leest en hoe je dat aanpast. Zo ongeveer iedereen in het compiler team, om maar wat te noemen. Plus een flink deel van het security team. En een boel random programmeurs die dit uit interesse geleerd hebben of die nog hebben leren programmeren in de tijd dat elke programmeur dat moest kunnen.
elke normale partij had de keuze gehad tussen een nieuwe licentie afsluiten, de functionaliteit uitschakelen en de fout laten bestaan.
Dat ze geen licentie meer hebben is een aanname, geen feit. Zelfs als het zo was, dan nog kost het een boel tijd om over die nieuwe licentie te onderhandelen; op dit niveau is "ehm ja, die ouwe meuk, het zal wel, doe er maar lekker mee wat je wilt" niet iets waar je een handtekening onder gaat zetten.

Functionaliteit uitschakelen is geen realistische optie, dan zouden alle documenten met een equation object erin opeens niet meer te openen zijn. Een van de sterkste kanten van Microsoft is nou juist dat ze zich een slag in de rondte werken om backward compatibiliteit te garanderen, zelfs met spul van tientallen jaren geleden.

De fout laten bestaan is al helemaal geen optie, het ging hier om een beveiligingslek!
dat baart me zorgen
Waarom...!? We weten nu dat er iemand bij MS is die low level code kan schrijven. Ten eerste, dat had ik je vorige week ook kunnen vertellen. Ten tweede, dat is niet evil of zo, dus waar ben je bang voor? En ten derde, zelfs al zou dat zo zijn; ja, ik mag hopen dat er bij MS mensen zijn die precies weten hoe alle evil trucjes werken. Niet om ze toe te passen, maar om zich ertegen te verdedigen. Als jij niet weer hoe je een slot open krijgt met een paperclip, dan ga ik van jou geen sloten kopen. Als je nog nooit van SQL injectie gehoord hebt, dan hoef ik jouw database engine niet op mijn computer te hebben.
Ehm ja, ik zou toch hopen dat een conglomeraat als Microsoft een paar mensen in dienst heeft die weten wat object code is, hoe je dat leest en hoe je dat aanpast. Zo ongeveer iedereen in het compiler team, om maar wat te noemen.
Dat heeft meer te maken met het feit dat het slimme mensen zijn; de bulk van het compiler (tools) team houdt zich daar niet actief mee bezig. Codegen is zelfs daarbinnen nog een specialisme.

(Ik heb jaren geleden nog gesolliciteerd bij dat team :D )
Is inderdaad indrukwekkend. Vooral als je niet precies weet waar je de fout moet zoeken in de EXE en dat dat ook nog goed aan te passen.

Weet nog hoe ik vroeger probeerde de EXE van Mechwarrior 2 aan te passen met een HEX editor om de CD check te omzeilen. Was niet makkelijk, maar uit eindelijk wel gelukt. Veel trial & error.
Input validatie en daarmee specifieke parameters afvangen.
Leuk bedacht, maar betekent extra coding, en dan verplaatsen alle adressen van functies na dit codeadres (tenzij dit toevallig de allerlaatste subroutine was). Je kunt wel jump in te lassen met eventueel een aantal NOP's naar 'oude' einde van de exe te doen en daar de check te doen en terug jumpen.
Of zoals oorspronkelijke artikel aangeeft de coding is efficiënter te maken, en een paar bytes te winnen, en dan ruimte te hebben voor extra checks. Maar moet je ontzettend goed zijn in 386/486 assembly, beter dan de compiler uit die tijd.
Petje af voor die code vogels.
Dat klinkt allemaal vrij complex, maar het is "off-the-shelf" technologie. Sterker nog, Microsoft Detours is een bestaande tool die dat soort dingen dynamisch kan doen. Die zoekt zelf het begin van de oude code, patched daarin een call naar de nieuwe code, en vanuit die nieuwe code kun je ook weer terugspringen naar de originele functie. Ideaal dus voor parameter validatie.
Die zoekt zelf het begin van de oude code, patched daarin een call naar de nieuwe code, en vanuit die nieuwe code kun je ook weer terugspringen naar de originele functie. Ideaal dus voor parameter validatie.

Alleen dat is dus niet wat Microsoft gedaan heeft. Immers de extra beperking die zij hadden was dat ze geen externe call konden doen. De binary mocht niet groter worden namelijk. Dus men heeft echt in-functie de assembly herschreven.
De binary mocht niet groter worden namelijk.
Heb net het oorspronkelijke artikel helemaal gelezen, maar deze claim kan ik daar nergens terugvinden; mag ik vragen waar je dit vandaan haalt?
Trucen genoeg. (Ik loop al lang genoeg mee om al dit soort dingen nog te herinneren). De executable zal tenminste 1 DLL gebruiken. Je kunt in de patch een nieuwe DLL introduceren met alle extra code, plus forwards naar de originele DLL, en dan de bestaande EXE patchen om die nieuwe DLL te gebruiken.

Overigens ontgaat het me waarom de binary niet groter mag worden. Het is een executable; andere processen kunnen geen aannames doen over de grootte of function calls direct naar de executable doen. Sowieso is de executable al eerder gegroeid, toen er een digitale handtekening aan werd toegevoegd.
clue: het betreft aanpassing van een statically linked in de DLL aangeroepen functie, dus niet een entry point van de DDL zelf noch een functie die extern (in een andere DLL) wordt aangeroepen.
Klopt. Maar je mist de subtiliteit van mijn idee. Ik misbruik de DLL alleen maar om extra code in de address space van de bestaande EXE te krijgen. De DLL zelf bevat helemaal geen aanroepbare functies, alleen een extra code segment met een DllMain functie. Die wordt uitgevoerd nog voor de EXE zelf, en kan de EXE dynamisch patchen - inclusief redirects naar extra patches in de DLL zelf.
Jump lijkt niet mogelijk. Die suggestie haal ik uit onderstaande links, loader doet vrij weinig en heeft geen invloed nadat windows oroces heeft overgenomen.

https://msdn.microsoft.com/en-us/magazine/ms809762.aspx

https://msdn.microsoft.com/en-us/magazine/bb985992.aspx
Jaren terug deden we ook zoiets met een online MMO, MuOnline. Het IP adres van de server was ingebakken in de .exe file, dus als je een eigen private server opzette moest je met een HEX editor aan de gang om het IP adres van jou server in je client te zetten. En dan verdraaid goed opletten, want als je bijvoorbeeld een extra karakter toevoegde werkte de hele client niet meer.

Ik vond het al enorm knap dat iemand uitvogelde precies waar in de client dat IP adres zat, en hoe je het kon fixen, laat staan dat iemand zo een buffer overflow fixed in een binary. Petje af voor de MS medewerker die dit gefixed heeft!
Decompiler en/of remotedebugger..
waardoor iemand bij Microsoft de exe heeft aangepast zonder over de broncode te beschikken.
Maar dan zouden andere personen die de exe (code) hebben, het toch ook aan kunnen passen? :? (Sorry als ik iets raars zeg, ik heb er niet zo veel verstand van.)
Tuurlijk! Je kan alle niet-cryptografisch beveiligde software gewoon met de hand aanpassen zodat het iets anders doet. Het is alleen extreem ingewikkeld vergeleken met de broncode aanpassen en opnieuw compileren... Mits je de broncode en de "build environment" nog hebt.
Vooral dat laatste puntje, de "build enviroment" kan nog wel eens grote invloed hebben ja, leuk als je de code hebt, maar als je niet meer de complete "build enviroment" hebt is het nog steeds niet handig.
Nee.

Zoals in het artikel al te zien is staat er een digitale handtekening op alle Windows executables. Alleen Microsoft heeft de private key daarvoor. Het plaatsen van een digitale handtekening is de laatste stap in het proces, omdat je daarmee de integriteit van de voorafgaande stappen garandeert. Je hebt daarvoor dus de source code niet nodig.

De nieuwe executable is dus ook opnieuw gesigned - de aanpassing heeft de oude handtekening ongeldig gemaakt.
Dat kán ook... alleen is het verre van eenvoudig!
tja, wat is verre van eenvoudig.. als je assembly en decompiling gewend bent dan valt het allemaal nog best wel mee, probleem is wel dat er nog maar weinig mensen zijn die dat gewend zijn.
Iets hackers/crackers/security engineers dagelijks doen, waarom zou MS dit niet kunnen dan?
Omdat men de indruk lijkt te hebben dat er bij MS enkel wat codemonkeys werken.
Ik geloof niet dat de insteek van het artikel is dat ze het niet zouden kunnen, maar wel dat het klaarblijkelijk nodig is omdat de broncode en of compiler niet meer beschikbaar zijn. Het is niet de meest voor de hand liggende methode als je normaal toegang tot je eigen bestanden zou hebben.
Zou leuk zijn als Raymond Chen in zijn blog een tipje van de sluier oplicht over het hoe en waarom van deze actie.

https://blogs.msdn.microsoft.com/oldnewthing/
In assembly kun je natuurlijk makkelijk een "goto" instructie maken en daar de goede implementatie maken, iets wat in de coding standard van bijna alle bedrijven die in een een moderne taal programmeren verboden is. Zo omzeil je de originele, brakke, implementatie van de functionaliteit. De originele functies blijven dan idd op dezelfde adressen.
De oorspronkelijke exe is volgens 0patch in 2000 gecompileerd, wat het een antiek stukje software maakt.
Het "wat word ik toch oud" momentje van de dag... :+
Hoezo, heb je geen spiegel dan ?
:+
Het "wat word ik toch oud" momentje van de dag... :+
... is alle reacties lezen van mensen die denken dat je zonder source code en compiler niets kunt aanpassen. :|
Damn, je zou je broncode maar kwijt zijn zeg.
Enorme hulde voor de MS medewerker(s) die hierachter zit(ten), en hoop dat hij/ze op zn minst iets leuks of een dagje vrij ofzo heeft gekregen voor deze truc, dit is nogal wat.

(en ja, oke, een hacker etc kan dit ook, maar die doet dan maar wat/probeert juist fouten te creëren, moet je je voorstellen dat je dit zelf moet doen, wetend hoe een systeem werkt en wat de bugs zijn, maar geen mogelijkheid hebben het goed te patchen, dus ga je maar handmatig de halve exe verbouwen, damn..)
Tsja als je IDA hebt en wat verstand van x86 instructies ;)

Op dit item kan niet meer gereageerd worden.


Apple iPhone X Google Pixel 2 XL LG W7 Samsung Galaxy S9 Google Pixel 2 Far Cry 5 Microsoft Xbox One X Apple iPhone 8

© 1998 - 2017 de Persgroep Online Services B.V. Tweakers vormt samen met o.a. Autotrack en Hardware.Info de Persgroep Online Services B.V. Hosting door True

*