ByteBanditsCTF
Sat, 11 April 2020, 23:30 CST — Sun, 12 April 2020, 23:30 CST
write
Description
You can write, what can you byte.
nc pwn.byteband.it 9000
Attachment
Analysis
1 | int __cdecl __noreturn main(int argc, const char **argv, const char **envp){ |
- address of
libc
andstack
were given - choose
w
to overwrite any memory with any values (unlimited times) - choose
q
to callexit(0)
Solution
calc base address of libc
1 | ru('puts: ') |
overwrite ptr in _dl_fini
there are 2 pointer used in _dl_fini+98
and _dl_fini+105
the program will execute to
_dl_fini
afterexit
called
all of them are in _rtld_golbal
:
1 | ptr = libcbase+0x619f60 #0x239f68 |
overwrite _rtld_golbal+2312
with /bin/sh
and overwrite _rtld_golbal+3834
with address of system
:
1 | sl('w') |
getshell
system("/bin/sh")
will be executed after after call exit
1 | sl('q') |
More
you can download full exp from my github
fmt-me
Description
Format strings are so 2000s.
nc pwn.byteband.it 6969
Attachment
Analysis
In snprintf
, our input string (buf
) will be formated to other_buf
:
1 | int __cdecl main(int argc, const char **argv, const char **envp){ |
string will not print to
stdin
, so we can use%ln
to write memory with any values directly
Solution
infinite loop
First of all, as the binary closes after system
function, an infinite loop
should be created.
We need overwrite GOT of system
with address of main
and it can be easily done by fmtstr_payload
of pwntools
:
1 | # infinite loop |
after that we can repeat calling
snprintf
to do more thing.
overwrite GOT of snprintf
As
snprintf
would not print any char tostdin
, it was hard to leak the base address of libc.But we can use
system
function in binary instead of libc.
Overwrite GOT of snprintf
with the original address in GOT of system
(system@plt+6
)
1 | ► 0x401070 <snprintf@plt> jmp qword ptr [rip + 0x2fc2] <0x401056> |
dl_resolver
will resolve real address of system in libc then call it.
When we construct the second format string, make sure that the beginning of our input string was /bin/sh;
:
1 | fmt2 = '/bin/sh;' |
The string stored in
other_buf
was/bin/sh;......
and will not change whensnprintf
were called at next time
getshell
system('/bin/sh;')
executed after any chars sent:
1 | sla('Choice: ','2') |
More
you can download full exp from my github
look-beyond
Description
Beyond the Aquila Rift, or is it in between?
nc pwn.byteband.it 8000
Update
Remote kernel is
Linux 4.15.0-1057-aws #59-Ubuntu SMP Wed Dec 4 10:02:00 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Attachment
Analysis
Environment
We can got the OS from the dockerfile
:
1 | cat Dockerfile |
so the remote environment is same as our local ubuntu 18.04
main function
1 | __int64 __fastcall main(__int64 a1, char **a2, char **a3){ |
at the beginning of
main
, ifdword_60107C==1
,puts
address would be leakedthat means we should return to
main
againset
chunk[idx]
to1
after any size of chunk allocatedoverwrite anywhere with 8 bytes any values
at the end of
main
, setdword_60107C
to1
Solution
We can hack canary
to solve this challenges.
find stack_guard
stack_guard
was the ptr pointed to canary
in a struct of Thread Local Storage
Thread-local storage (TLS) is a computer programming method that uses static or global memory local to a thread.
1 | typedef struct |
We can find the address of stack_guard
by searching memory in gdb
.
At the beginning of main
, canary
was putted into stack:
1 | 0x4007de mov rax, qword ptr fs:[0x28] |
search it:
1 | pwndbg> search -8 0x9435c714eedda900 |
gdb runnin in Ubuntu 18.04
the address of stack_guard
was between ld-2.27.so
and stack
Modify canary in TLS
the address of a large allocated memory (e.g. 1000000 bytes) was near the address of libc
and ld
1 | search -8 0x9435c714eedda900 |
and the offset between of chunk
and stack_guard
doesn’t change
so we can allocate a 1000000 bytes chuck and modify canary to trigger __stack_chk_fail
:
1 | se('1000000') # size |
back to main
then overwrite GOT of __stack_chk_fail
with address of main
1 | se('1000000') # size |
so that we can back to main
again and the real address of puts
in libc would be leaked:
1 | ru('puts: ') |
one gadget
1 | libcbase = puts-libc.sym['puts'] |
modify canary
again and overwrite GOT of __stack_chk_fail
with the address ofone_gadget
to getsehll.
More
the offset is not same between different OS, so we have to download an ubnutu 18.04 environment
you can download full exp from my github