← Ingestions

Ingestion 78c3c03e extracted

Format
transcript
Kind
talk
External ID
How to hijack - David Halasz - wroc_love.rb 2019.txt
Content hash
b24f2f6215fa
Source at
2019-03-22 09:00
Manual extractions are temporarily disabled.

Extractions (1)

Status Model Tokens (in/out) Duration Cost Nodes/edges Read set (nodes/edges) Time
completed claude-opus-4-7
126,516 / 10,030
50,929 cached ยท 7,621 write
141.0s - 29 / 44 77 / 3 2026-04-17 16:18

Content

so hi everyone jesh welcome to my talk


about smuggling hijacking and proxying


in nothing disorder sockets with wreck


and Ruby my name is David


I pronounce my name as Hollis not as


hellish as polish people would think we


had this deal with Hungarians and polish


had this deal with let's confuse the


world how we pronounce the SC you can


find me on twitter under this handle


feel free to tweet about bad stuff so


let's get into this


so I'm from Hungary and speaking part of


Slovakia but I live in the Czech


Republic in a town called Brenau which


is famous for beer not my type motogp if


anyone's watching it and there was a


genetical experiment in Brno a really


famous one but not that one if you heard


about you hungry or Mendel he was


experimenting with beasts and the city I


worked for Red Hat an open-source


company if you would guess and I'm


working on a manager IQ project which is


an open-source hybrid cloud


infrastructure management platform if


you have a cloud or an on-premise


infrastructure we were able to manage it


doesn't matter what kind of providers


you use even multiple at the same time


the important part about this for you at


the conference is that it's written in


Ruby and rails and it has over a million


lines of code so stuff I'm working on


mostly is in browser remote consoles


which are basically remove des


obsessions in a browser surprisingly so


if someone wouldn't know what remote


console is Remote Desktop session is


there is a nice example from Windows


where I don't know the password but you


will get the idea


you see wandering faces so you never


sell this right yeah so the same


in-browser


basically the same stuff in browser here


you can see a flux box Desktop Manager


running in a browser window in manager


queue we have implemented it in a way


that you have a summary screen of a


virtual machine you click on access and


VM console and you have a pop-up window


with the VNC session something like this


the architecture you have your VM and


your browser the VM runs on a hypervisor


which runs VMs and it provides you a VNC


endpoint even if you are running like


VMware or or VirtualBox on your local


workstation you can set this VNC


endpoint up and run a VNC session so you


can try this out unfortunately the


browser doesn't really understand VNC


the closest thing to your streaming is


WebSocket so we need something in the


middle let's call it proxy and if you


look into this proxy a little closer


even closer then we see some scary stuff


from computer science class like threads


and events and a synchronous i/o and


blocking rate and all those things we're


gonna touch all of it


don't worry so if we look into the proxy


inside the proxy we have two endpoints


or more but in a simplified version just


to one for the WebSocket part and one


for the VNC part and you need to


transmit data to one direction and to


the other direction and somehow


translate between the two endpoints I


think it's pretty clear for now but not


Google so what the hell is this what


what is it when I'm talking about


endpoints and if we uncover it


they are basically sockets not this kind


of sockets but


I was speaking and I was Australia they


didn't get this joke so here is an


example of sockets in Ruby you need to


require it if you are not running rails


because in rails it's fortunately there


because you're using webserver sin' you


know so here I'm opening an HTTP


connection on port 80 to the website of


the conference I'm setting some headers


writing them I'm getting back some


headers and I'm getting some payload


that I'm not using HTTPS so well played


organizers yours you have a secure site


if you look at the operations I'm doing


right read close what things from from


the other worlds come into your mind


right so basically they are files but


for networking and if you remember your


old hard rice which were spinning or if


you are younger than they were hard


drives that were spinning they were a


little slower because you needed some


time to to the head to get to the data


if you were reading so they came up with


the idea of buffering in both directions


in both reading and writing so when you


were writing data you actually wrote to


a buffer anyway when you're reading data


you were eating from a buffer which was


like prefetched for you and this thing


is actually really useful still for


sockets so when you use sockets and you


write the sockets you actually write to


your buffer and when the operating


system the scheduler in your network


card sees that there is free time on the


network card it's able to send some data


to the network it starts forming packets


from this data and sends it out you


don't have to care about it problem is


what happens if the buffer is full and


the answer is easy you wait wait until


the buffer gets empty or there is some


space in the buffer this is why it's


called blocking right you block until


you don't have the time to


it and for reading I was lazy to make


slides so use your imagination a naive


implementation of proxy using blocking


read and write would be something like


this you have to endless loops because


you can block here you can block here


and you need some translation in the


middle and to actually be able to run


both of these stuff you need one of them


in at read this implementation is


probably the worst possible never use it


Ruby doesn't really handle well threads


and if you have 50 connections then you


need 100 threads so it doesn't scale


really well so there is a solution for


that called non-blocking i/o you have


the same methods with an unblocked


prefix methods aren't waiting if the


buffer is full or empty when reading it


just drops you an evil block or a again


error or depending on the context and


the testing of readiness is extracted


out to a separate method or system call


basically you can use a single loop to


handle all selects so if you want to


read from multiple sockets you would


want to do something like this you have


a thread the transcend event loop that


iterates through all the sockets with


i/o select which gets you the ready


ready sockets into an array you iterate


through it and read from it and write to


your screen it's really good if you do


it in one direction but when you try to


produce write a proxy for this kind of


things and you don't want to use threads


then you get into problems so this is my


first try of writing a proxy I cannot


really see the screen so you know walk


here I hope I won't get some echo so you


have a pairing of sockets you have two


sockets a and B and you have a method


pair to that to translate both


directions and you do an i/o selecting


an endless loop iterate through all the


old already sockets and if


other part isn't ready you just skip it


skip the iteration and here you do the


same transmission as we did in the


threading example but with non-blocking


i/o problem with this is these two lines


can cause you an endless loop a spin


lock because if only socket a is ready


for reading and so I could be isn't


ready for reading yeah loop feedback


loop so it's it's not ready for writing


then this I of select we return the


reach array will have one element the


rights will be empty and this next gets


figured and we get back here again where


the I also like will again return with


the same data and it will eat up your


CPU on 100% and just waste your


resources that's not really good if you


want to use this in production so I


started looking into alternatives first


was dropping Ruby but we're not going to


talk about it a ruby conference using


threads with blocking i/o is a bad idea


because you need a lot of threads and


that doesn't scale well or you can use


some libraries like even machine or


celluloid which would be cool if we


wouldn't use Postgres in async mode in


our application so they are just failing


crashing there is a cool library async


which is kinda new and it wasn't


available when I started working on this


also if I would do it now I would just


use it but then we will not have this


talk I kind of don't have the font of


the like emoji but it should be like


emoji then we can have all two fibers


which are also cool because fibers were


already explained so I'm not going to do


that they are automatically yielding on


I await normal fibers don't do that


until you yield in your context they


will just run and you need to explicitly


old without the fibers this will happen


automatically if you have a sleep or


weight or i/o select call inside the


fiber it's very similar how crystal


implements concurrency here is an


example a hypothetical example with all


the fibers you basically have a pool of


fibers and you put the two endless loops


into that and call them


it's basically magic that converts your


blocking Gayo into a non-blocking i/o


with same as you would do in go or


crystal unfortunately it's not available


in Ruby until the version three they


promised it into the version three but


we don't have that much time so the idea


I came up with is called bouncing select


the main concept is to make to those


arrays storing storing the sockets


dynamic so here is the code a little on


steroids and I marked all the lines I


added to those dynamic arrays and after


an i/o select basically I'm removing the


ready sockets from the original arrays


and if a transmission happened this is a


little off sorry for that if the


transmission happened we bounced them


back so if socket a is only ready you


get to the eye of select here you get


through it it gets removed from the to


read on the iteration it fails because


suck it B isn't ready for writing but


when we get back to the eye of select


it's no longer there so can we can wait


passively not eating up the CPU


problem solved unfortunately IO select


is an ideal if you have thousands of


sockets because it's a system call to


the kernel and you need to pass all your


sockets into the system call every time


you call it so if you have like 500 you


have to wait until you copy the socket


descriptors into the kernel space before


actually waiting for it so the Linux


kernel developers came up with the idea


of eople where you split up select into


two calls one of them is for registering


the socket and the other one is for


actually doing the wait so this way you


don't have to pass all the time all the


sockets you just register one and two


it's available only on Linux


unfortunately so sorry Mac users but you


can use KQ which is kind of similar or


it's possible to fall back to the eye of


select bouncing in a bouncing version


I've when I was playing with it I found


a really interesting feature in a flag


called a pole one shot which basically


after a socket is ready for reading or


writing it gets removed from the array


automatically so basically doing for us


this operation sorry this operation here


for free unfortunately when I was


looking into the Ruby wrappers around


eople I found like five or six on the


internet none of them were working well


with equal one shot so I had to


implement it on my own in C this is


absurd the code let's say from from my


codebase where I have the register


function with some with a socket and and


all in out and one should flex and this


is the Select call where I enter 8


through this equal weight results and I


remove the Ruby code which actually sets


the readiness of the sockets that can be


consumed in the future this works well


on Linux sorry for the Mac users but


here is a repo if you would like to


contribute and write the actual KQ


implementation I will be really happy to


merge it because we also have some Mac


developers who are still using the old


fallback mechanism this was like the


computer science part of the thing all


the i/o I would like to talk about


WebSockets all the remote consoles we


use are using WebSockets


they are basically HTTP on steroids


upgraded for bi-directional HTTP 1.1 not


HTTP 2 to be precise they are used for


bi-directional transfer after an HTTP


upgrade which I will explain now so when


you have your browser in your web server


your browser sends an HTTP GET request


with the upgrade header which tells the


web server that hey I'm opening an HTTP


connection but I would like to talk in


WebSockets so the web server sent back


an HTTP 101 switching protocols and


after that the protocol changes it


upgrades to WebSocket


as you know all the Rubies servers are


employed servers are implemented in rec


if you look at rec you basically can


have anything as a rec server response


to a call method and return this three


elemental array with the HTTP status the


headers and the body here we can


implement your own server it doesn't


have to be a lambda it can be whatever


you want basically the whole idea is


that you run the server and any incoming


request calls this function or method or


whatever so it's basically a function as


a server


no so rec is really good for request


response model but if you are using


WebSocket you don't really want here to


hang on on an incoming request so it's


not really good for for long-running


requests so the developers of rec


implemented a way to actually get out


from this loop or from this function


call when you have a persistent


connection


it's called socket hijacking yeah


I'm sorry for that gifts it's a video


about guy trying to hijack the core so


when we use this hijacking here in a web


server we are able to get the socket


that's behind the request that's coming


in in the end of hash do some magic


function to get the other endpoint in


our case the VNC server and push it to


the proxy which is outside in a separate


thread and be able to serve the next req


request we need some dumb is here to


make RAC happy so it wouldn't fail that


you you did an invalid request or


something like that but that's a detail


and basically this is how our remote


consoles work here you have the upgrade


and the proxy as you've seen and I would


say thank you but I promised some


smuggling in my talk so when I was


implementing this upgrade and WebSocket


part of the remote consoles I would


start thinking about what if we upgrade


to something else


will it work so when I realize it will I


started to have weird ideas of not


upgrading but downgrading to something


else and my idea was to downgrade to TCP


and then send through data in whatever


format you want and the answer why would


I do something crazy as this is in this


old war when we have your browser


applications and desktop applications


and if you think about it I don't want


to offend anyone desktop application is


still faster and if you think about how


slow can be an html5 canvas and you


would like to do stuff like key mapping


or clipboard it's not really easy to do


or keyboard shortcuts it's not really


easy to do in browser so if you want to


try to do a VNC remote desktop


connection it's much better experience


in desktop so I came up with this


architecture where you have the VM and


the hypervisor that gives you the VNC


endpoint on the other side instead of


the browser you have the VNC client with


the VNC connection it wants to create


you have a server proxy that it's very


similar to the one we I showed in the


previous slides and on the client you


would like to have an also client proxy


so they can figure out the language here


which is basically HTTP but after they


upgrade it became becomes VNC let's call


it / because why not


I have those stickers if someone's


interested it actually stands for


protocol upgrade raw request so it's not


like some something I just made up


yeah it's part of the show that I'm


showing my cat t-shirt but I get tangled


into my sari for that so / is basically


HTTP upgrade plus we and see but you can


send through SSH or any kind of TCP


based protocol so it's basically TCP


smuggled through HTTP you open an HTTP


connection you downgrade to TCP and send


you whatever you want in the case of


manage IQ we are imagining a situation


where you have your manager IQ appliance


with the webserver and our proxy you


have a virtualized environment let's say


overt with a VM you want to access and


you click on a new button called native


console that will send a request to the


web server that we would like to open a


connection that sends back a request


that go to / : / / miq which activates a


browser plugin because you cannot open a


TCP connection from the browser the


browser plug-in opens up says I'm


assigning a local as 1 2 3 4 which opens


page where they ask you to open


localhost 1 2 3 4 you open in your


favorite client localhost 1 2 3 4 which


gets routed to the plug-in plug-in open


sir connection yeah it became sui and


see the plug-in opens the connection to


the web server but because the proxy is


inside a web server it will know that it


should be sent there with the HTTP


upgrade request 2 / HTTP one-on-one


arrives you have your / connection in


the same time the proxy opens the VNC


connection and you have your nice tunnel


between the VM and the VNC client


there is a problem with all of this and


[Music]


not talking about it is complicated the


browser plug-in cannot really open a TCP


connection it's still in the browser


sandbox so I kind of lied you actually


need a browser plug-in and a client app


but the browser plug-in API allows you


to call binaries if you have the right


permissions this can be all go away in a


few years when the they will actually


the world w3c will actually implement


the draft for opening TCP connections


with user permission inside a browser so


I came up with this architecture with


the server I described the browser


plugin and the client which are


communicating with each other and then


missing front-end library because I


don't like writing JavaScript it kind of


works I can show you the server part


it's really similar to rack you just


pass a block where you need to write


your own magic function that gives you a


host and a port and run with Puma


basically this is how you get to the


other endpoint nothing more the


advantage of this are or disadvantages


that it behaves like HTTP so you can do


all the routing all the HTTP headers you


can do use HTTP to secure it you can


have your cookies your favorite rack


middleware so you can use it in rails as


a route no problems the only


disadvantage is that it needs a browser


plug-in and the binary for now in the


future it might change it's not fully


done and really far from production


ready but it works and I can prove it


I'll give you some time


okay so you probably don't believe me so


I will show you talk is cheap right I


don't know how to exit from full screen


and from this thing and it's really hard


to see but yes yes so this is a VNC


session running in a demo remote


container you can see the window and I


will show you how it works so I have an


actual demo where I'm I'm connecting to


this so let's close this window and so I


have a VM define is it visible okay so I


have a VM running in background Vox I'm


installing docker I'm pulling down two


containers one for sent to s1 for an SSH


server this one has a VNC server I'm


setting up on some environment I'm


setting up on Etsy host file and


installing Ruby so I can run perform the


VM and this is the server I'm running


basically a ruby 2.4 run Puma which per


per looks like this so depending on the


endpoint URL connect to the VNC server


on this port or the SSH server in that


port and we have a nice simple website


where we call the plug-in with some


event dispatching because I still like


the front and library so I open the URL


to VNC or SSH when I get the response I


displayed on the web on the page so if I


show you the site here it is and it's


listening on localhost something where


I'm actually connected with the VNC if I


hit the stop button if you close me the


connection


so let's try to reopen it it's really


bad with the screen


so I'm connecting to localhost but it's


actually running in a container and it


failed typo thank you what did I miss


oh yes it's here in the same time we can


open an SSH connection I just need the


port I have prepared the connection


already so here it is we're in and if


you don't believe me it's running in the


container here I have the background box


I'm trying to ping from the inside of


box the containers it works and I'm


trying to copy now the IP or as it zero


- okay so I leave the con the background


box 1702 did I write it correctly okay


so it shouldn't go through because it's


not visible


I'm trying to find my slides sorry for


that yeah that's all thank you and I


believe it was a crazy topic so we have


some questions for sure you can win the


school bag if you ask a question and I


have some stickers of course I have some


stickers those nice animals this is the


manager IQ mascot George and this is the


person yeah thank you it's not a


question but can I ask some stickers


instead of question seriously yeah yes


thank you man any other character


questions considering it's a ruby


conference it will be my last question


before I die but why did you do it in


Ruby I think that there are better texts


for proxy requests and goodbye guys so


we have an environment where we cannot


run anything else than Ruby for now so I


needed a quick solution and this is what


we used for now yes - just make the


client install a binary and do it


without so if you think about like a


role based access control and one-time


passwords and all those things you don't


want your person who's using using your


VM somewhere to use it all the time you


want to set some quotas and you just


want to give to the person just some


temporary access in this sense this one


is better because you have a cloud


management application that implements


you all these access rules and you can


limit the whole VNC session into that


scope


hi thus every Red Hat developer get a


Red Hat yes so when you join the company


you go to a new hire orientation where


you can pick one very cool excuse me we


do I'm not sure about how they get their


hats but I saw on like videoconferencing


in the background of some of my art


colleagues so hat so I'm pretty sure


they do as well my colleague here we


have new hire they have new hire


orientation - can you tell us anything


about the translation between V and C


and the websocket so can you just


practice rusev in C frame so do you have


to do any kind of post-processing and


how efficient is in Ruby it's definitely


not the most efficient in Ruby if you


are trying to ask about it you can do it


with a method call so from the one side


from the TCP side is to from the VNC


side Eustis route TCP and you are


basically pushing roll white translation


about the remote console in the browser


not in the I do I do of course but in


the smuggling you don't have to convert


it just route TCP okay and one


recommendation for the smuggling you can


probably just place the sockets together


it's a kernel and never reach the data


to the user space there are certain kind


of features which allow this and do not


often know the exact cause of core


system codes to splice two sockets


together but it's probably best to


investigate it I ride that one as well


but it was problematic let's say


come get some stickers okay thank you