Slide 1

Slide 1 text

Writing My First Exploit

Slide 2

Slide 2 text

Exploit? “...is a piece of software, a chunk of data, or a sequence of commands that takes advantage of a bug or vulnerability to cause unintended or unanticipated behavior...” Wikipedia

Slide 3

Slide 3 text

What? Counter-Strike: Global Offensive ● Source code leak from 2013 for reference. ○ github.com/ValveSoftware/source-... ● Lots of existing exploit examples. ○ github.com/search?q=dwLocalPlaye...

Slide 4

Slide 4 text

“Steel-thread” Implementation ● “Out of Box” win32 APIs to exploit the client side process. ○ read/write with kernel32.dll ○ input with with user32.dll ● “Benign” exploit impact. ○ client side jump abuse aka “bunny hop”

Slide 5

Slide 5 text

Video

Slide 6

Slide 6 text

How

Slide 7

Slide 7 text

How?

Slide 8

Slide 8 text

How func RunHop(client *Client) { for { if gomem.IsKeyDown(VK_SPACE) { flags, _ := client.Process.ReadByte(...) if (flags & CSGO_FL_ONGROUND) > 0 { client.Process.WriteByte(...) } } time.Sleep(100 * time.Nanosecond) } }

Slide 9

Slide 9 text

Binary Compatibility Address E.g. 0x59bc2690 Memory E.g. 00001000 ReadByte

Slide 10

Slide 10 text

Binary Compatibility 1.0 1.0 1.1 1.2 1.1 1.2 csgo.exe gohack.exe Broken Broken

Slide 11

Slide 11 text

Binary Compatibility 1.0 1.X w/ auto update 1.1 1.2 csgo.exe gohack.exe

Slide 12

Slide 12 text

How func Instrument() (*gohack.Client, error) { ... offsets, err := gohack.GetOffsets() ... process, err := gomem.GetOpenProcessFromName("csgo.exe") ... client, err := gohack.GetClientFrom(process, offsets) ... return client, err }

Slide 13

Slide 13 text

Testing

Slide 14

Slide 14 text

Testing Value’s CS:GO ● 30GB Package ● Steam DRM + VAC Anti-cheat ● GUI + Internet ● A popular game My CS:GO ● 42KB Binary ● 14 LOC ● Headless + Offline ● Loads a DLL and hangs

Slide 15

Slide 15 text

Testing func TestStubProcess(t *testing.T) { withProcess("test\\dll\\csgo.exe", func() { _, err := Instrument() got := err.Error() want := "Failed to get player offset" if got != want { t.Errorf("%q; want %q", got, want) } }) }

Slide 16

Slide 16 text

Testing

Slide 17

Slide 17 text

github.com/jamesmoriarty/gohack

Slide 18

Slide 18 text

???

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

Testing func TestProcessReadUInt32(t *testing.T) { ... valuePtr := (uintptr)(unsafe.Pointer(&value)) ... process, err := GetOpenProcessFromName(name) ... assertValue, err := process.ReadUInt32(valuePtr) ... }

Slide 21

Slide 21 text

github.com/jamesmoriarty/gomem

Slide 22

Slide 22 text

jamesmoriarty.xyz/software/

Slide 23

Slide 23 text

Video