pwn小姿势二
本帖最后由 T_MAC仔 于 2017-5-12 16:59 编辑http://pwnable.kr-- collision工具:gdb调试中的peda插件下载教程: http://www.genshuixue.com/i-cxy/p/15510697
本文零基础使用peda 当ssh进服务器后,同样的使用ls-l命令查看文件的具体信息即:
http://imglf1.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEwMHFqKzE5SzB3RjJyc3NYNGMzUmV0TDFiMnpGRHN4WC9nPT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
同样的使用cat col.c 查看源文件得源码: #include <stdio.h>#include <string.h>unsigned long hashcode = 0x21DD09EC;unsigned long check_password(const char* p){ int* ip = (int*)p; int i; int res=0; for(i=0; i<5; i++){ res += ip; } return res;}int main(int argc, char* argv[]){ if(argc<2){ printf("usage : %s \n", argv); return 0; } if(strlen(argv) != 20){ printf("passcode length should be 20 bytes\n"); return 0; } if(hashcode == check_password( argv )){ system("/bin/cat flag"); return 0; } else printf("wrong passcode.\n"); return 0;}由col.c可以获取到的知识点:
[*]if(argc<2) 命令行参数至少为两个
[*]if(strlen(argv) != 20) 第二个命令行参数的长度为20字节
[*]if(hashcode == check_password( argv )) ,,check_password( argv )函数的返回值必须==0x21DD09EC
GDB调试获取更多要点:把代码copy下来,gcc下进行编译 gcc -g fun.c -o main gdb main 直接进入调试如图:
http://imglf1.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEwOFljREV3bzRuZDY5YnlPMFArRUxpQzVWbDNsS3lHVy9BPT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
首先输入命令行参数用命令: set args 12345678900987654321 如图所示:
http://imglf.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEwL3lvUzdWTmNpRUhmY3h5SXV1d1hiUE9GWVNXOSt3YnJ3PT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
输入命令start 开始调试:连续使用两个n命令 来到函数 check_password()处,即:
http://imglf0.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEwNVZ4YXRxYTFaOFdsVGFrNzVUYU1jbk4wMit3eTFOM3BRPT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
此时我们可以使用命令’s‘进入此函数。如图所示:
http://imglf1.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEwMFlMQmtYR3pWZ29lWjBLY1V5QWh5V2ExNXF0dEhSYWNRPT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
如上图所示我们可以得到: 1. 指针 p 指向我们输入的命令行字符串 argv【1】。并且 *p= 0x31 即字符串首位字符的十六进制表示值 0x31
2. ip指向p
接下来接着执行 n 命令来到如图所示:
http://imglf2.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEweGFueUorZk8wenVWb0lQNnN5Y1JFcTNxZjF5UW1wdXhBPT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
如上图可得到 变量 i 变量res 的内存地址。放执行完:res+=ip【o】时候可以观测到:
http://imglf0.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEwN1RQS09Db1lBUjcxZUE4cllSNC9KSzIySU9yTDZ5Rk9nPT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
可以发现res== 1234 此时;接下来继续执行命令n 观测res的变化 以及ip【i】的值可以发现原理;原理解析
[*]此题利用函数check_password() 将命令行参数字符串转换为十六进制数据进行相加,并且以最终的res的值是否是0x21dd09ec为准是否读取正确的flag,由于输入的字符的为20字节,函数将其分为五组,一组为四个字节,进行想加。
解体思路可以直接在20字节中的最后四个字节填充值 0x21dd09ec,即:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\x09\xdd\x21
“\x”代表转义符 \xhh 表示两位十六进制数据,但是由于\x09 是HT (horizontal tab)水平制表符,故不可行。所以可将0x21dd09ec中数据进行改变但最终结果总和为此值即可:参考网上各位大佬给出的payload: ./col python -c "print '\x01' * 16 + '\xE8\x05\xD9\x1D'"
利用python 调用cmd 的输出值作为col elf的输入值,亲测可行。、 感谢发布原创作品,吾爱破解论坛因你更精彩! 用心讨论,共获提升 1.http://imglf1.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEwMFlMQmtYR3pWZ29lWjBLY1V5QWh5V2ExNXF0dEhSYWNRPT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
楼主你这张图,还没有执行int* ip = (int*)p;.就查看ip的值,没有意义吧 0.0
2.http://imglf2.nosdn.127.net/img/dnUxZE56SzVQeDdJTEZvcXd5TzEweGFueUorZk8wenVWb0lQNnN5Y1JFcTNxZjF5UW1wdXhBPT0.png?imageView&thumbnail=500x0&quality=96&stripmeta=0&type=jpg
这张图,第一个命令,楼主是想写p /x &(ip,i)吧,因为把res当做数组没什么意义吧
3.最后不仅仅是/x09会被截断,/x00等也是会被截断的.所以要用/x01
最重要的是执行的时候python语句必须要被反引号即``包裹,这样才会把python当做命令执行.所以最后一句话应该是
./col `python -c "print '\x01' * 16 + '\xE8\x05\xD9\x1D'"`
我非常感谢楼主的分享,因为网上关于pwn的资料的确不多,但我仍希望楼主在发表到论坛前,能够稍微再检查一下,避免一些错误,做一些简单的排版,避免让新手感到不知所措.
还是感谢. 谢谢,下载学习
页:
[1]