Archive for 安全

这题纯编程题,二分法实现的,没啥意思。一直在调程序,最后发现超时了,还是在pwn服务器上很快跑完了。

Continue

这题没做出来,bash本来就不熟,去查了一些bash的语法,以为可以替换命令名称之类实现。 最终搜了一下答案,利用的bash之前的一个漏洞。这个漏洞之前新闻好像有印象,不太确定是不是同一个。 我看了一下漏洞介绍,使用bash -c执行命令的时候,虽然检查了环境变量传入的是一个函数,然后执行他,但是执行完函数后,并没有停止,会继续执行后面的代码。 这种题做起来有点难,不知道就很难做出来。

Continue

只能说我c写的还是少了,这题排除法做的。 看完代码先想的xor操作能不能推出密码,然后发现不行。然后根据题目提示,也没找到有优先级的问题。然后反着把代码看了一遍,发现有两处if语句优先级问题。 赋值运算算是最低优先级了,打开文件成功后,先进行比较运算为true,fd的值最终为true。导致从标准输入读取密码。 xor 1,前七位为0不变,最后一位取反。相当于找一个最后一位为0的字母,然后再输入下一个字母就可以了。

Continue

这题又出的巧妙啊,本来我想动态调试一下,直接看寄存器值。但是还得准备环境,就放弃了。因为看代码比较简单,查了pc和lr盲猜了一波错了。然后就详细查了一波arm的pc指令。 先说key3的,这个盲猜的对了。lr就是回调返回地址,跟x86的一致。 key1考察pc指令,我查文章发现,arm指令流水线三级,包括取指(fetch)、译码(decode)、执行(execute)三级。 当前正在执行的指令获取pc值,pc其实指向的是fetch那条指令。相当于当前指令下面第二条指令的地址。 我看文章,这里arm还分ARM状态和Thumb状态,两种状态指令长度不一样。看来arm架构虽然指令长度是固定长度的,但是不同情况下不同的固定长度。这里就是key2里的.code16和.code32,指明指令长度。其实反汇编里有指令长度,所以这里也不需要关注,只要关注是往下数第二条指令就可以了。 这里key2一顿花里胡哨,其实还是pc+4的值。 最后求和提交就可以了。 我这里又多想了一点,二字节指令和四字节指令的区分方式问题,因为反汇编直接就显示出指令来了。我想了一下,可能在指令的机器码上还是有区分的。也懒得找资料认证了,arm汇编暂时也不想搞。

Continue

这个题比较简单,主要是讲程序的数据输入方式有哪些。 涉及参数,环境变量,输入输出,文件,网络等方式。

Continue

这个题比较简单,刚开始我想错方向了。 其实考察c的rand函数需要一个seed。其实每次随机数都不变。gdb看一下随机值,然后得到异或值提交就可以了。

Continue

这个题耗费了我基本一天的时间,属于知识盲区题。 ``` int passcode1; scanf("%d", passcode1); ``` 程序在调用scanf函数的时候,传的不是指针是一个int类型。编译会有warning,但是能通过编译。最终代码是以passcode1的值为地址进行数据存储。如果正常执行,因为passcode1的值不确定,所以很容易段异常退出。 在这调用login之前,调用了welcome,进行name[100]的输入。导致栈内存是共用的,所以可以通过设置name的值,来修改passcode1的值。 这里的分析都还好,再往下就不通了。因为共用栈刚好到name结束,而且二进制编译开启了函数调用的栈溢出检查,这就导致passcode2没有办法修改。只能说题出的精巧。 然后我从网上找了一下答案,然后再查了一些资料,基本就捋清楚了。 首先这里二进制未开启随机的内存地址空间的保护,导致每个指令地址固定。第二点,未开启got全保护,所以got可以写,导致可以修改动态库函数的调用地址,从而达到跳转到目的。 所以,继续往下的解题思路就是,在输入name的时候,修改passcode1的值为got函数的地址(通过查看plt段的内容)。这个函数取scanf后的一个函数,这样保证到达不了passcode2的scanf。这一步做完就可以保证,passcode1输入的时候不会段错误。然后在进行passcode1输入的时候,将最后的system调用的地址作为输入数据。因为指令地址固定,所以在这里行得通。

Continue

这个比较简单,upx脱个壳。因为提示过会复制字符串,然后我查看数据段的字符串,第一个看起来就是答案,一提交就对了。 分析代码也不难,其实就是复制了然后就退出了。

Continue

第三题做起来不太难,考察缓冲区溢出,使用radare2反编译了一下,看了一下参数地址和buf地址的距离,直接填充就可以了。 这里用到pwn这个python库,因为这次又涉及到不可见字符,我就网上搜了一下一般用什么工具。发现这个工具是专门用来提交pwn的库。既可以调用本地二进制,也可以远程连接。 最后获得shell之后,cat以下flag就可以了。 程序二进制是开启了缓冲区溢出的编译,我开始写溢出buf的时候,还考虑了这个校验值。但是发现好像不起作用,然后我进行动态调试的时候,radare2还不会交互使用,就切换到gdb。发现确实是走了__stack_chk_fail的逻辑,函数异常退出了。但因为程序提前先返回了shell,所以没影响获取flag。然后再没尝试这个变量值修改的问题。

Continue

这个题比想象中难,形式跟第一题差不多,考察MD5加密的知识。代码比较简单,输入一个20字符的字符串,字符串相当于密码,检查密码通过后,就能获取flag。 这里主要流程是,首先20字符,转成int指针,然后相当于五个int相加,结果为hash后的值。到这里我还以为很简单。 后来发现这个值不能5整除,即使整除也可能是不可见字符。然后发现这个值没办法在可见字符里凑数。我仔细看了一下代码,求和变量是int类型,能溢出。所以就好搞一点。 凑数思路就是,2**32先除4,找个差不多的值,换算成附近的可见字符值。然后再求第五个值变成可见字符的值,进行微调。 不知道还有没有更好一点的解题思路。

Continue