xctf reverse

oprn-source

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 4) {                      //判断传入给argc是不是4
    	printf("what?\n");                
    	exit(1);
    }

    unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {
    	printf("you are wrong, sorry.\n");  //first = 0xcafe
    	exit(2);
    }

    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {   //second = 25
    	printf("ha, you won't get it!\n");
    	exit(3);
    }

    if (strcmp("h4cky0u", argv[3])) {
    	printf("so close, dude!\n");             //直接把h4cky0u给argv[3]
    	exit(4);
    }

    printf("Brr wrrr grr\n");

    unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

    printf("Get your key: ");
    printf("%x\n", hash);
    return 0;
}

我们粗略看一下源码,是四个if,然后把赋的值给三个变量,最后的flag是hash的值,那我们一段段来分析

(1)

int main(int argc, char *argv[]) {
    if (argc != 4) {                    //判断是不是四个参数,传入到agrc里面
    	printf("what?\n");                
    	exit(1);

这里表示的是传入main函数参数的个数,argc是一个整型变量,也就是有四个参数传入main

(2)

unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {
    	printf("you are wrong, sorry.\n");  //first = 0xcafe
    	exit(2);
    }

先把argv[1]的值传给first。这里,如果first不等于0xcafe,那就退出程序了所以argv【1】=0xcafe

(3)

unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {   //second = 25
    	printf("ha, you won't get it!\n");
    	exit(3);
    }

把argv【2】的值给second变量,如果second模5等于3或者second模17不等于8,只要满足其中一个就会退出进程,那这里我们让second = 25

(4)

if (strcmp("h4cky0u", argv[3])) {
    	printf("so close, dude!\n");
    	exit(4);
    }

下面是 strcmp() 函数的声明。

int strcmp(const char *str1, const char *str2)
该函数返回值如下:
如果返回值小于 0,则表示 str1 小于 str2。
如果返回值大于 0,则表示 str1 大于 str2。
如果返回值等于 0,则表示 str1 等于 str2。

令if条件里的值为0,所以让h4ckyou和argv【3】相等

(5)

根据这一段编写expunsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
exp:

a = int('0xcafe',16)
payload = a * 31337 + (25 % 17)*11 + 7 -1615810207
print(hex(hash))

python trade

打开,是个pyc文件
这里需要进行反编译查看源码,其实平常使用ida也是进行反编译,只不过反编译的C
用在线工具

# uncompyle6 version 3.5.0
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.5 (default, Aug  7 2019, 00:51:29) 
# [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
# Embedded file name: 1.py
# Compiled at: 2017-06-03 10:20:43
import base64

def encode(message):
    s = ''
    for i in message:
        x = ord(i) ^ 32
        x = x + 16
        s += chr(x)

    return base64.b64encode(s)


correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'  #定义了一个字符串
flag = ''   #定义一个空的变量
print 'Input flag:'  # 在交互界面打印:INput flag
flag = raw_input() # 接收字符串 1*
if encode(flag) == correct:  #如果调用encode函数,参数是flag后的返回值等于correct 就对了
    print 'correct'
else:
    print 'wrong'

*1:python raw_input() 用来获取控制台的输入。
raw_input() 将所有输入作为字符串看待,返回字符串类型。
注意:input() 和 raw_input() 这两个函数均能接收 字符串 ,但 raw_input() 直接读取控制台的输入(任何类型的输入它都可以接收)。而对于 input() ,它希望能够读取一个合法的 python 表达式,即你输入字符串的时候必须使用引号将它括起来,否则它会引发一个 SyntaxError 。
除非对 input() 有特别需要,否则一般情况下我们都是推荐使用 raw_input() 来与用户交互。
注意:python3 里 input() 默认接收到的是 str 类型。

看encode函数

def encode(message):        # 参数是message
    s = ''                  #s的局部变量先定义为空
    for i in message:       #参数message里面的每一个字符              
        x = ord(i) ^ 32     #把该字符的ascii码与32异或,值传给局部变量x
        x = x + 16          #x+16
        s += chr(x)         #返回当前整数对应的ascii符号传给s,然后每一个字符拼接

    return base64.b64encode(s) #返回值是s的base64编码

编写exp

mport base64
correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
message=base64.b64decode(correct)
s=' '
for i in message:
    x = (ord(i) -16)^32      #这里是encode函数的逆运算,注意这里异或逆运算还是异或哈
    s += chr(x)
print(s)

得到flag
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值