奇怪的pwn入门(第n+2天)

奇怪的pwn入门(第n+2天)

  • 字符指针

    C语言中编译器会给字符串常量分配地址,如果 "Hello", 存储在内存中的 0x3000 0x3001 0x3002 0x3003 0x3004 0x3005。

    s = "Hello" 真正的意义是 s ="Hello" = 0x3000。Hello 看作是字符串,但是编译器把它看作是地址 0x3000,即字符串常量的本质表现是代表它的第一个字符的地址s = 0x3000

    那么 %s ,它的原理其实也是通过字符串首地址输出字符串,printf("%s ", s); 传给它的其实是s所保存的字符串的地址

  • 转义字符

    \141表示ASCII码为97(八进制61)的字符a

    \x61表示ASCII码为97(十六进制61)的字符a

  • perl -e语句可以直接在命令行后直接执行后面的代码

    本题中可通过./col perl -e 'print "\xe8\x05\xd9\x1d"."\x01"x16' 直接传入字符,其中'.'运算符是将两个字符串连接起来;'x'运算符后面是字符串重复的次数

2.collision

和上一道题差不多,先看一眼C代码:

大概意思是要输入长度为20的数字串,使他经过check_password函数转换后的结果和hashcode一致,模拟数据库中存密码的hash的存储方式。所以我们只要搞懂这个check_password函数是怎么回事就行了。

这里可能说的不太对,回头我再学下《深入理解C指针》。观察函数大致是输入一个字符指针,把它转换成int指针,由于int指针是4字节,字符指针是1字节,所以int指针中每单位会包含4个字符指针的值(胡言乱语中~!@#¥%……&*)。

这里网上有个例子比较好。比如字符串是20个9,就是“99999999999999999999”=[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9] 。事实上它在内存中以ASCII码形式存放(9对应57=0x39),于是内存中的字符串为[0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39,0x39]。这20个字符之后经过int* ip=(int*)p转换后,变为五个int为[0x39393939,0x39393939,0x39393939,0x39393939,0x39393939]。

题目里的意思是要让这五个数加起来结果与hashcode相同,那么我们就得构造这玩意

我们从后往前考虑,使结果为 0x21DD09EC 最简单的方法是 0x21DD09EC +0+0+0+0,但是这里的五个数字串是要由字符转变成的ASCII码,而0号ASCII码对应null,为了方便我们就用1号ASCII码来构造,合并后即为0x01010101,通过计算器可以得出 0x21DD09EC = 0x1DD905E8+0x01010101+0x01010101+0x01010101+0x01010101。根据小端法,我们输入E8 05 D9 1D 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01对应的ASCII码代号即可

这里可以在远程机器中直接输入命令./col perl -e 'print "\xe8\x05\xd9\x1d"."\x01"x16'来传入该值,也可以通过编写如下exp完成

from pwn import *
import os
pwn_ssh=ssh(host='pwnable.kr',user='col',password='guest',port=2222)
print(pwn_ssh.connected())
sh=pwn_ssh.process(argv=['collision','\xe8\x05\xd9\x1d'+'\x01'*16],executable='./col')
print(sh.recvall())

得到结果

posted @ 2020-07-07 17:03  一个李长兴  阅读(209)  评论(0编辑  收藏  举报