ISCC 2016 逆向部分 writeup

ISCC2016 逆向部分

by GoldsNow

做了这套题目感觉涨了不少的姿势。。渣渣就只能够用渣渣的方法

题目下载

Help me

描述:I’ve got a difficult task and I can’t solve it. I need your help!

思路:爆破

ELF64位的程序,直接在IDA中打开,可以看出来思路应该是比较清晰

先点进去main函数来进行分析。

for ( i = 0; i <= 15; ++i )
{
    if ( !(v11 & 1) )
      ++v5;
    v11 >>= 1;
}

先对这个一段代码进行分析,经过位运算,来判断二进制数字有多少个 0

很明显 这里只需要三个 0

这里的MD5是个比较坑的地方,C语言并没有自带的库, 也不知道它到底进行的是什么。 只知道他是与 unk_6020A0 来比较的 有尝试 对这个地址的数据进行 MD5的解密,可惜最终是失败了的。

换一个思路,我们可以看到这里的 word_602080 经过了异或运算 然后 byte_6020C0 减去 这个的值然后输出最终的flag 所以可以从这个角度来解决题目, 这里面值有 V10也就是输入的那一个数字是不知道的, 可以通过暴力破解来实现。

我在做题目的时候用了C语言来判断, 判断第五个字母是不是‘{’

附上我的c程序可以参考一下。
unsigned char a[]={0x34,0x12,0x78,0x56,0xBC,0x9A,0xFF,0xED,0xEF,0xBE,0x7F,0x22,0xC3,0x90,0x76,0x82,0xAD,0x99,0x2E,0x14,0x7C,0x80};
unsigned char b[]={0x22,0x3F,0xD8,0xEB,0xCC,0xD2,0x42,0x87,0x61,0x75,0x01,0x09,0x27,0xF9,0xDC,0xE8,0x16,0xFC,0x5F,0x89,0xB3,0xFD};
__int16 c[6]={0x3412,0x7856,0xbc9a,0xffed,0xefbe,0x7f22};
__int16 d[6];
__int16 x1=0,x2=0xffff,x=0;
for(int i=0;i<=15;i++)                         // 三重for循环将 v10的可能性都列出来了
    for(int j=i+1;j<=15;j++)
        for(int m=j+1;m<=15;m++)
        {
            x2==0xffff;
            x1=(__int16)(pow(2,i)+pow(2,j)+pow(2,m));
            x=x2-x1;                    //这三行是为了得到V10的可以理解一下   

            for(int n=0;n<=5;n++)
            {
                d[n]=c[n]^x;
                a[2*n]=d[n]>>8;
                a[2*n+1]=( __int8) d[n];
            }
            if(b[4]-a[4]==‘{‘) //如果是‘{‘就输出 可能的flag
            {
                printf("%x ",x);
                for(int i=0;i<22;i++)
                    printf("%c",b[i]-a[i]);
                printf("\n");
            }
        }

破解加密软件

描述:我方截获了敌方的一款加密程序和一段密文,尝试通过对此程序进行分析实现对密文的解密,解密后明文的32位小写MD5值作为flag提交。

思路:扣出程序中所包含的一个加密解密系统,得到密钥 解密

吾爱破解对于这个题目也有比较详细的解题过程 链接

通过OD载入然后搜索里面的字符串可以发现 程序有两个功能,一个就是原题所给的 输入字符串就加密,其实里面还有一个程序就是 通过给与密钥就能够加密与解密

通过修改跳转,或者修改 call 的内容等等其他 方法能够让程序运行到那一段 这样就好办了。但是 还不知道密钥是什么。

想法是密钥肯定会在 初始的加密程序中引用

对程序进行单步跟踪。一步一步运行 到达一定地方的时候堆栈中就出现了如下可惜的八位数字,并且这个不会随着你的输入而改变数字,猜测其为密钥

果然没错 一下子就出来了

这里有一个地方就是 直接用OD跑出来的值会有一个空格多出来也不知道是为什么。

 菜鸟的逆袭

描述:”小明是个游戏新手,一天他闲得无聊去找基友打L4D2,基友嫌他太菜,不愿带他,无奈小明百般纠缠,便给了他一个程序,并且告诉他:“如果你能得到正确答案,我就把我毕生混野绝学传授给你。”聪明的你能帮助小明得到正确的答案吗?

测试环境:干净的WinXP SP3”

找不到动态调试的软件。只能够静态分析,用IDA打开。

可以通过提示 推断出来 这里有两个词,分别是DEAD和BEEF

正好属于A-F 因为是A-F 属于0-F的范围 都符合16进制的值。所以上面的V9就是0xdeadbeef或者说0xDEADBEEF

通过将dword_10F80-dword_10F90与V9异或输出,能够得到 一串看起来很像flag的值但是 要靠程序接下来分析 将字符串进行了转化

orPh0fh!:hlghnoCgalF

这样转化一下就出来了,,是不是很简单,,,但是要去想到却很难。。

矛盾

描述:To be or not to be, that is the question.

思路 去除TLS,暴力

参考资料 http://www.2cto.com/Article/201303/197705.html

IDA载入

找到TLScallback 在010中打开它用00填充此部分 保存文件就能够进入程序的主函数部分了,但是还是不能够得到flag 有点小郁闷

通过查看字符串来寻找有没有弹出窗口,运气不错发现一个弹出窗口。

并且在上面也出现了flag的字样。

函数的上有几个 sub_4385FF 推测他用的就是memset 将目标的地址段 值置零。所以这里就会使最终的flag

最后处理 的是直接打开OD跳转到相关的语段 跑一下就出来了。

 Anti

描述:Every technique has its anti.

这个题目就是 反调试,,绕过dll文件中的对调试器和模拟器的检测。。

操作方法,具体就不介绍了,就是在OD中 一步一步,对于有些 call 直接就nop掉 一些明显要推出的函数就强制跳转或者也nop了

进入主程序之后,难度就会明显下降

很容易就能够找到主要的那个对比的地址, 最后有一段看起来很复杂的加密方法,,,,分析半天没分析出来,后来一看就32位的,,就想到了可能是用了MD5加密方法,,最终在XMD5 一下子就出来flag 了。

GoGoGo

描述:Mission is a go.

这个题目用了GO语言。问了很多人,都说是用动态分析做出来了,但是我最后是通过静态分析,很容易就做出来了。

IDA的分析是非常规的。 只能靠猜

 v38 = "Please input : ";
  v39 = off_4DC4C0[1];
  v40 = 0LL;
  v41 = 0LL;
  if ( &v30 == -88 )
    LODWORD(v40) = 0;
  v42 = &v40;
  v43 = 1;
  v44 = 1;
  v30 = &unk_4A10A0;
  v31 = &v38;
  sub_41FA10(&v42, a2, a3, v3);
  v4 = v42;
  v5 = v42;
  *v42 = v32;
  ++v5;
  *v5 = v33;
  ++v5;
  v30 = v4;
  v31 = v43;
  v32 = v44;
  sub_42C510(v5, &v34, v6, v7, v8, v9);
  sub_400C00(v5, &v34);
  v36 = v30;
  v37 = v31;
  v32 = &unk_4D73F0;
  v33 = *(&off_4D73E0 + 1);
  v10 = &off_4D73E0 + 2;
  sub_446A70(&v34, (&off_4D73E0 + 2), v11, v30, v12, v13);
  v16 = v34;
  v36 = v34;
  v37 = v35;
  if ( v35 != 38 || (v30 = v34, v31 = 38, sub_400CB0(&v34, v10, v14, v34, v15), v32 != 1) )
  {
    v38 = "Wrong!!!";
    v39 = off_4DCCE0[1];
    v40 = 0LL;
    v41 = 0LL;
    if ( &v30 == -88 )
      LODWORD(v40) = 0;
    v42 = &v40;
    v43 = 1;
    v44 = 1;
    v30 = &unk_4A10A0;
    v31 = &v38;
    sub_41FA10(&v42, v10, v14, v16);
    v24 = v42;
    v25 = v42;
    *v42 = v32;
    ++v25;
    *v25 = v33;
    v30 = v24;
    v31 = v43;
    v32 = v44;
    result = sub_42C510((v25 + 1), &v34, v26, v27, v28, v29);
  }
  else
  {
    v38 = "Congratz!!";
    v39 = off_4DB7A0[1];
    v40 = 0LL;
    v41 = 0LL;
    if ( &v30 == -88 )
      LODWORD(v40) = 0;
    v42 = &v40;
    v43 = 1;
    v44 = 1;
    v30 = &unk_4A10A0;
    v31 = &v38;
    sub_41FA10(&v42, v10, v14, v16);
    v17 = v42;
    v18 = v42;
    *v42 = v32;
    ++v18;
    *v18 = v33;
    v30 = v17;
    v31 = v43;
    v32 = v44;
    result = sub_42C510((v18 + 1), &v34, v19, v20, v21, v22);
  }

截图太累 直接把代码复制了,,通过对比 可以看出 这个 ‘sub_42C510’ 才是输出的结束语句

input 那边还需要一个读取字符的语句 就猜测是 ‘sub_446A70’ 这语段是输出语段。

主要起作用的当然是 if语句里的那个 sub_400CB0 了

这里有一个 字符转化和一个内存中的数据很可疑,,刚开始以为是输入的语句经过处理变成这样,但是实际上我错了。是这个内存中的 数据 经过这个处理会出现一段base64加密过的数据。。

附上代码
int b[52]={0xA5,0xD6,0x87,0x86,0xA5,0x33,0x37,0x03,0xE4,0x75,0xE4,0xB6,0x95,0xA7,0xC6,0xD6,0xE4,0x44,0x94,0x53,0xE4,0xA6,0xB6,0x53,0xD4,0x23,0xD4,0x77,0xD4,0xA7,0x46,0xB6,0xA5,0x74,0x55,0x13,0xD4,0xA6,0x36,0x87,0x95,0x75,0x55,0x43,0x95,0xA6,0x15,0x03,0x95,0x33,0x03,0xD3};
for(int j=0;j<52;j++)
{
    printf("%c",(16*b[j]|b[j]>>4));
}

就是这么简单,,然后将这个进过base64解密一下就出来了 我也觉的很意外。

时间: 2024-09-30 10:28:55

ISCC 2016 逆向部分 writeup的相关文章

2016 alictf Timer writeup

Timer-smali逆向 参考文档:http://blog.csdn.net/qq_29343201/article/details/51649962 题目链接: https://pan.baidu.com/s/1jINx7Fo   (在里面找相应的名字就行) 题目描述:每秒触发一次计算,共有200000秒,答案参与计算,不可能等待下去. 使用工具:Android Killer,jadx-gui 解题方法有多种,我参照网上的一种方法.通过对native层,代码的还原,计算出200000秒后的关

【CTF web】ISCC 2016 web 2题记录

偶然看到的比赛,我等渣渣跟风做两题,剩下的题目工作太忙没有时间继续做. 第1题 sql注入: 题目知识 考察sql注入知识,题目地址:http://101.200.145.44/web1//index.php 做题过程 第一步:注入Playload user=flag&pass=' or updatexml(1,concat(0x7e,(select pw from user limit 1,1 )),0)# ' 第二步:注入效果 Masel's secure site 重置数据库 Error:

ctf.360.cn第二届,逆向部分writeup——第四题

题目:见附件 这题开始有些小复杂了. 运行程序,可以看见界面如下 注意看"隐藏信息完毕!"字符串的位置 直接搜索push 40405c,找到代码位置401a48. 网上翻找到代码块的入口地址4017a0.很显然这是一个非常长的函数,使用IDA进行静态分析.   v2 = CreateFileA(*((LPCSTR *)v1 + 24), 0x80000000u, 1u, 0, 3u, 0x80u, 0);   if ( v2 == (HANDLE)-1 )   {     result

ctf.360.cn第二届,逆向部分writeup——第五题

题目:见附件 这是最后一题,难度加倍. 看题目意思,应该是模拟一个下载者,从网上下载一个shellcode然后执行.要求修复这个shellcode然后获得key. OD载入MFC_ASM.exe,F9出现程序界面. 由于平时写C程序访问网络都直接用socket,找了一下竟然没有发现socket调用,看了导入表,发现原来使用wininet.dll提供的http封装. (这里不知道有没有更好的方法能让OD跟踪到button按钮的用户代码调用,还请大牛不吝赐教) 直接按button,出现错误: 此时的

ctf.360.cn第二届,逆向部分writeup——第二题

题目:见附件 这题目被提示的运行两次坑了. OD载入,设置命令行参数pass.db. F8到VirtualAlloc函数,发现size参数为0,导致函数调用失败. 根据pass.db长度,设置size=0x10,F8继续. 发现CreateFileA的FileName参数依然是pass.db,修改成pas1.db. F9正常运行,得到pas1.db文件. 实际上,这里pas1.db的内容已经是答案了,受到提示影响"patch掉bug后运行两次",所以得到pas2.db后,怎么提交都不对

ctf.360.cn第二届,逆向部分writeup——第三题

题目:见附件 这题目是最快搞定的,提示很明确 exe直接运行出错,OD打开后,发现入口点就是一个jmp F8,跟踪到jmp后的地址,发现了程序运行出错的原因. 实际上这个题目就是模拟病毒感染exe,修改文件入口指令,插入恶意代码的行为. 修补实际上就是找到真实的入口函数头的代码,将前面的jmp等指令nop掉.(修改OEP也行)

实验吧逆向catalyst-system Writeup

下载之后查看知道为ELF文件,linux中执行之后发现很慢: 拖入ida中查看发现有循环调用 sleep 函数: 这是已经改过了,edit -> patch program -> change byte 修改一下比较参数可以去除等待时间,总共去除两处: 运行之后发现是输入 username 和 passsword 的方式: 那么问题就在两者上面了. 反编译之后查看源码,v8对应username, v7为password. 点进第一个函数,在 return 中是对用户名的判断,易推断出用户名为

10月月赛

记录下两个逆向的writeup,第二个还是有点费事的. Re elf 题目比较简单,算法也很简单,求用户名为ctfking的注册码. 注册码需要满足条件: 1. 全是数字 2. 长度10的倍数 3. 由serial经过算法生成的serial_gen和由用户名ctfking生成的name_gen相等 如下图: 下面简单分析下算法: Serial_gen 由 输入的serial的每一个字节模上一个从9开始依次递加的值.由于用户名已经固定,即ctfking.所以调试后,可以直接发现name_gen为0

聊一聊前端模板与渲染那些事儿

欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码): https://segmentfault.com/blog/frontenddriver 作为现代应用,ajax的大量使用,使得前端工程师们日常的开发少不了拼装模板,渲染模板.我们今天就来聊聊,拼装与渲染模板的那些事儿. 如果喜欢本文请点击右侧的推荐哦,你的推荐会变为我继续更文的动力 1 页面级的渲染 在刚有web的时候,前端与后端的交互,非常直白,浏览器端发出URL,后端返回一张拼好了的HTML串