gxkyrftx 发表于 2019-4-8 10:28

CBMCTF2019逆向题目(1&2&3)writeup

本帖最后由 gxkyrftx 于 2019-4-8 16:42 编辑

# 0.前言
毕设做的心烦,于是到(https://ctftime.org/event/783)找了一个简单的比赛玩了一天。做出来三个逆向,随手抓包干掉一个web签到题。现在将wp发出来,主要是逆向,web不太会。

# 1.hashish
## 1.1 静态分析
签到题目,下载之后解压,查看readme.txt,内容如下
~~~ c
Hi
My friend made a hash algo which he thought was irreversible....however he was on Manali Cream.
so he print something he should not print while making hashes.


Below is the output of given binary with flag as input... get the flag.



hash-0 : 138

hash-1 : 512

hash-2 : 1645

hash-3 : 5034

hash-4 : 15218

hash-5 : 45756

hash-6 : 137391

hash-7 : 412292

hash-8 : 1236927

hash-9 : 3710845

hash-10 : 11132642

hash-11 : 33398021

hash-12 : 100194167

hash-13 : 300582553

hash-14 : 901747774

hash-15 : 2705243426

hash-16 : 8115730373

hash-17 : 24347191171

hash-18 : 73041573621

hash-19 : 219124720917

hash-20 : 657374162799

hash-21 : 1972122488522

hash-22 : 5916367465576
~~~
大致意思是,文件实现一个算法,flag的输出应该是下面的这个样子。上IDA,分析
main函数如下
~~~ c
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; //

puts("enter the string");      //输出字符串
fgets(&s, 50, _bss_start);      //获取输入
genhash(&s, 50LL);                //产生hash
return 0;
}
~~~

关注的是产生hash的算法,genhash内容如下:

~~~ c
__int64 __fastcall genhash(char *a1)
{
unsigned int v1; // eax
char *v2; // rax
__int64 result; // rax
char *v4; //
unsigned int v5; //
signed __int64 v6; //

v4 = a1;
v6 = 13LL;                           //常数
v5 = 0;
while ( 1 )
{
    v2 = v4++;
    result = (unsigned int)*v2;
    if ( !(_DWORD)result )
      break;
    v6 = 3 * v6 + (signed int)result;   //主要算法
    v1 = v5++;
    printf("hash-%d : %ld\n", v1, v6);       //输出
}
return result;
}
~~~

函数的流程就是将字符串的每一个字符取出来,然后加上3乘v6,v6初始值是13,每一轮都会更新,然后格式化输出v6.
## 1.2 破解脚本
因为程序流程比较简单,不再演示动态调试了。如果想验证,可以在虚拟机远程调试。直接上脚本
~~~ python
temp=13
a=0
flag=''
sn=[138,512,1645,5034,15218,45756,137391,412292,1236927,3710845,11132642,33398021,100194167,300582553
,901747774,2705243426,8115730373,24347191171,73041573621,219124720917,657374162799,1972122488522,
5916367465576]
for i in range(0,23):
      result=sn-temp*3
      temp=sn
      #print result
      flag=flag+chr(result)

print flag
~~~

# 2.simpleCryptoWare

## 2.1 静态分析

这个题目的readme.txt描述如下
~~~
Hi

My girlfriend is new in hacking world and she is learning writing crypto ransomwares.

After so much hardwork she managed to write one.

She encrypt my seceret info file with her cryware.

However she do not know much about encryption algorithm and used some crackable encryption.

I have the executable binary of her cryware.

Can you reverse it and decrypt the secretInfo file for me as I am too lazy for this stuff.


Thanks in advance ;-)
~~~

大致意思,secretInfo文件被一个软件加密了,尝试恢复明文。上IDA分析。
main函数如下
~~~c++
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rdx
__int64 v6; // rax

if ( argc == 2 )
{
    encrypt((char *)argv);
}
else
{
    v3 = std::operator<<<std::char_traits<char>>(&std::cout, " ", envp);
    v4 = std::operator<<<std::char_traits<char>>(v3, *argv, v3);
    v6 = std::operator<<<std::char_traits<char>>(v4, " <filename>", v5);
    std::ostream::operator<<(v6, &std::endl<char,std::char_traits<char>>);
}
return 0;
}
~~~

encrypt函数如下
~~~c++
__int64 __fastcall encrypt(char *a1)
{
unsigned int v1; // eax
int v2; // eax
__int64 v3; // rdx
_QWORD *v4; // rax
__int64 v5; // rdx
__int64 v6; // rax
char v8; //
char v9; //
__int64 v10; //
char v11; //
char v12; //
char v13; //
int v14; //
int j; //
int i; //

v1 = time(0LL);
srand(v1);
v2 = rand() % 95;       //上面几行,获取随机值,然后模95,所以每次运行程序得到的加密结果是不一样的
v14 = v2 + 32;      
v13 = v2 + 32;      //v13是模95后的随机值加32
std::basic_ifstream<char,std::char_traits<char>>::basic_ifstream(&v9);
std::basic_ifstream<char,std::char_traits<char>>::open(&v9, a1, 8LL);
if ( (unsigned __int8)std::basic_ios<char,std::char_traits<char>>::operator!(&v10) )
{
    std::operator<<<std::char_traits<char>>(&std::cerr, "File not found", v3);
    exit(1);
}
for ( i = 0; ; ++i )
{
    v4 = (_QWORD *)std::operator>><char,std::char_traits<char>>(&v9, &v12);
    if ( !(unsigned __int8)std::basic_ios<char,std::char_traits<char>>::operator bool((char *)v4 + *(_QWORD *)(*v4 - 24LL)) )
      break;
    v11 = v12;
}
std::basic_ifstream<char,std::char_traits<char>>::close(&v9);
v6 = std::operator<<<std::char_traits<char>>(&std::cout, v11, v5);
std::ostream::operator<<(v6, &std::endl<char,std::char_traits<char>>);
std::basic_ofstream<char,std::char_traits<char>>::basic_ofstream(&v8, a1, 16LL);      //上面都是一些读文件,复制的操作,没有加密
for ( j = 0; j < i; ++j )
    std::operator<<<std::char_traits<char>>(&v8, (unsigned int)(char)(v13 ^ v11));      //这里是加密文件操作,将上面的v13随机值,与v11(文件中的字符串)的每一个字符进行异或加密。
std::basic_ofstream<char,std::char_traits<char>>::close(&v8);
std::basic_ofstream<char,std::char_traits<char>>::~basic_ofstream(&v8);
return std::basic_ifstream<char,std::char_traits<char>>::~basic_ifstream(&v9);
}
~~~

总结就是,0-94的随机值与文件进行异或加密,破解思路就是爆破就好,才95种可能,然后人工筛选一下结果。

## 2.2 解密脚本
解密脚本如下
~~~ python
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import binascii

def xor(decrypt_key, data):
    length = len(data)
    m_data = []
    for i in range(length):
      m_index = i % len(decrypt_key)
      m_key = decrypt_key

      m_data +=chr(ord(data)^ ord(m_key))
    data = "".join(m_data)
    return data

if __name__ == '__main__':
    with open("secretInfo", 'rb') as fp:
       a = fp.read()
    a=a.encode('hex')
    m_a = list(binascii.unhexlify(a))
    for i in range(0,95):
      print chr(i)
            m_b = list(binascii.unhexlify(chr(i).encode('hex')) )
            print xor(m_b,m_a)
~~~
解密结果
~~~ c
TheXORoperatorisextremelycommonasacomponentinmorecomplexciphers.Byitself,usingaconstantrepeatingkey,asimpleXORciphercantriviallybebrokenusingfrequencyanalysis.Ifthecontentofanymessagecanbeguessedorotherwiseknownthenthekeycanberevealed.Itsprimarymeritisthatitissimpletoimplement,andthattheXORoperationiscomputationallyinexpensive.AsimplerepeatingXOR(i.e.usingthesamekeyforxoroperationonthewholedata)cipheristhereforesometimesusedforhidinginformationincaseswherenoparticularsecurityisrequired.Bythewayflagiscbmctf{shedonotknowaboutreversing}
~~~
# 3. and70
这是一个安卓逆向,原来没怎么玩过逆向,但是上过安卓开发的课,学过Java,现学现卖吧。

## 3.1 静态分析
安卓静态分析工具我选用了jeb,爱盘里有,用的最新的jeb3.0.然后双击jeb_wincon.bat,打开jeb,将apk拖进去,分析就好。
根据安卓文件的包结构,查看MainActivity

~~~ android
public class MainActivity extends AppCompatActivity {
    Button getFlag;

    public MainActivity() {
      super();
    }

    protected void onCreate(Bundle arg3) {
      super.onCreate(arg3);
      this.setContentView(0x7F09001D);
      this.getFlag = this.findViewById(0x7F070022);
      this.getFlag.setOnClickListener(new View$OnClickListener() {
            public void onClick(View arg4) {
                MainActivity.this.startActivity(new Intent(MainActivity.this, ButtonListner.class));
            }
      });
    }
}
~~~

没啥有用的,看到了按钮监听事件,看看这个ButtonListner
~~~android
public class ButtonListner extends AppCompatActivity {
    String flag;
    TextView showFlag;

    public ButtonListner() {
      super();
      this.flag = "";
    }

    protected void onCreate(Bundle arg2) {
      super.onCreate(arg2);
      this.setContentView(0x7F09001C);
      this.showFlag = this.findViewById(0x7F07003D);
      if(ValidateUser.validate().booleanValue()) {
            this.flag = GenerateFlag.genFlag();
      }
    }
}
~~~

查看genFlag()

~~~android
public class GenerateFlag {
    public GenerateFlag() {
      super();
    }

    public static String genFlag() {
      return "Do you really think it is that simple!!";
    }
}
~~~
然后就卡在这儿了,看了半天也没思路,就去秒了一个web题。回来继续看,继续找了很长时间,在resources文件里,看到了secret字符串,字符串内容如下
~~~ txt
IHN0YXRpYyBwdWJsaWMgU3RyaW5nIGdlbkZsYWcoKXsKICAgICAgICBTdHJpbmcgZmxhZz0iY2JtY3RmeyI7CiAgICAgICAgY2hhciBjPSchJzsKICAgICAgICBmb3IoaW50IGk9MDtpPDE1O2krKyl7CiAgICAgICAgICAgIGZsYWcrPTMzKyhjK2krMTAwKSU4OTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGZsYWcrIn0iOwogICAgfQ==
~~~

妥妥的base64,直接找网站解密,解密内容如下

~~~ java
static public String genFlag(){
      String flag="cbmctf{";
      char c='!';
      for(int i=0;i<15;i++){
            flag+=33+(c+i+100)%89;
      }
      return flag+"}";
    }
~~~

根据这个,就可以写脚本破解了

## 3.2 破解脚本

~~~ java
public class HelloWorld {
    public static void main(String []args) {
       genFlag();
    }
         static public String genFlag(){
      String flag="cbmctf{";
      char c='!';
      for(int i=0;i<15;i++){
            flag+=33+(c+i+100)%89;
                        System.out.println(flag+'}');
      }
      return flag+"}";
    }
}
~~~
# 4.web签到
这个比较水,直接访问网站,抓包,追踪tcp流,cookie就是flag,太水了。。。

# 5.总结
自己瞎玩玩而已,希望各位大佬指点。 [题目在这里](https://github.com/gxkyrftx/CBMCTF)

gxkyrftx 发表于 2019-4-8 10:49

这个排版怎么肥四啊,我怎么弄不好

cn52pojie 发表于 2019-4-8 11:41


感谢分享!

zhaolisheng 发表于 2019-4-8 12:30

谢谢分享,论坛有你更好

weikun444 发表于 2019-4-8 16:51

学习了,楼主辛苦了。谢谢分享!

gxkyrftx 发表于 2019-4-8 17:50

他们的服务器现在还开着,想玩的可以继续玩,这些题目我感觉都不算太难

gxkyrftx 发表于 2019-4-8 17:51

weikun444 发表于 2019-4-8 16:51
学习了,楼主辛苦了。谢谢分享!

一起学习{:1_893:},我其实是个新手,才学了没几天

Misscitel 发表于 2019-4-8 23:02

学习了,楼主辛苦

gxkyrftx 发表于 2019-4-9 08:20

Misscitel 发表于 2019-4-8 23:02
学习了,楼主辛苦

一起学习{:1_893:}{:1_893:}{:1_893:}

Hmily 发表于 2019-4-28 08:35

gxkyrftx 发表于 2019-4-8 10:49
这个排版怎么肥四啊,我怎么弄不好

排版有什么问题?我看用了md代码挺好的?
页: [1]
查看完整版本: CBMCTF2019逆向题目(1&2&3)writeup