[攻防世界]Hello,CTF 超详细题解(逆向CTF)

深入浅出,知无不答,言无不尽,力求详尽


下载附件, 老样子查壳

无壳放心反编译, IDA!启动!

直接F5, 

main函数都不用跳转直接就是

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int i; // ebx
  char v4; // al
  int result; // eax
  int v6; // [esp+0h] [ebp-70h]
  int v7; // [esp+0h] [ebp-70h]
  char Buffer[2]; // [esp+12h] [ebp-5Eh] BYREF
  char v9[20]; // [esp+14h] [ebp-5Ch] BYREF
  char v10[32]; // [esp+28h] [ebp-48h] BYREF
  __int16 v11; // [esp+48h] [ebp-28h]
  char v12; // [esp+4Ah] [ebp-26h]
  char v13[36]; // [esp+4Ch] [ebp-24h] BYREF

  strcpy(v13, "437261636b4d654a757374466f7246756e");
  while ( 1 )
  {
    memset(v10, 0, sizeof(v10));
    v11 = 0;
    v12 = 0;
    sub_40134B(aPleaseInputYou, v6);
    scanf("%s", v9);
    if ( strlen(v9) > 0x11 )
      break;
    for ( i = 0; i < 17; ++i )
    {
      v4 = v9[i];
      if ( !v4 )
        break;
      sprintf(Buffer, "%x", v4);
      strcat(v10, Buffer);
    }
    if ( !strcmp(v10, v13) )
      sub_40134B(aSuccess, v7);
    else
      sub_40134B(aWrong, v7);
  }
  sub_40134B(aWrong, v7);
  result = --Stream._cnt;
  if ( Stream._cnt < 0 )
    return _filbuf(&Stream);
  ++Stream._ptr;
  return result;
}

虽然简单, 依然的逐行分析。


1、第一行主函数参数, argc和argv不再赘述, 详细看上一篇文章

const char **envp

这句代码的含义不像看起来那样, 不是简单的创建一个常量 字符型 二级指针, envp在main函数里是有特殊含义的, 它一般代表系统中的环境变量, 而且内容非常详细, 有的小伙伴可能会问了, "有多详细?", 这你得去问baidu, 我怎么知道多详细...我的脑袋又不是通电才能工作。

2、3-13行初始化变量数据类型。(c语言基础)

3、strcpy函数接受了一串数据"437261636b4d654a757374466f7246756e"传递给了v13, 等价于

v13 = "437261636b4d654a757374466f7246756e"

4、接着进入循环体。

利用memset函数把v10这个字符型数组数据初始化成0, v11和v12赋值为0。

接下来这个sub_40134B点进去分析一通(叽里咕噜在干啥, 初学者看不懂直接当成内存操作就行了),

对内存进行了很多移位操作, 还有部分代码进行了文件校验, 具体细节还不是我这个小菜鸡需要分析的(毕竟这题难度才4)。

scanf函数接受我们的输入赋值给v9。

如果我们输入的数据超过0x11(十进制17), 直接跳出循环。

        然后进入for循环, 循环17次, 遍历v9赋值给v4, v4如果是0则打断循环, 任何非0的字符和数字都是1(真值), 我们要让下面的语句执行, 输入的值里就不能包含0。

      sprintf(Buffer, "%x", v4);
      strcat(v10, Buffer);

sprintf函数举个例子说明, sprintf(a, b, c), a变量会被以b的格式赋值为c, c会被先以b的方式处理再赋值给a。所以这里的Buffer会等于v4(%x无符号十六进制转换), Buffer在编程里是缓冲的意思, 这是一个缓冲变量, 就是暂存数据的变量。 

strcat函数类似python里的列表append方法, 前一个参数是需要添加元素的数组, 后一个参数是被添加进数组末尾的数据。

    if ( !strcmp(v10, v13) )
      sub_40134B(aSuccess, v7);
    else
      sub_40134B(aWrong, v7);

接下来把v10数组和v13数组比较, 两者相等才能输出aSuccess, 否则就aWrong咯。

sub40134B还是不看。

5、最后一段

  sub_40134B(aWrong, v7);
  result = --Stream._cnt;
  if ( Stream._cnt < 0 )
    return _filbuf(&Stream);
  ++Stream._ptr;
  return result;

这一段其实是对输入流的处理, 需要一部分高级编程知识, stream._cnt访问了 stream这个对象中的_cnt成员, 这个成员一般表示当前缓冲区中剩余可读取的字符数, 后面的判断检测它还有没有数据未读取, _filbuf函数填入新的流数据。

如果还有数据, 这里将stream对象中的)_ptr成员(通常指向当前缓冲区中下一个要读取的字符的位置)加1, 更新缓冲数据的位置, 最后返回流, 确保数据正确的更新。


其实逻辑已经很清晰了, 既然我们输入的数据要等于"437261636b4d654a757374466f7246756e"
那就逆回来我们输入的数据呗, 这里面唯一对我们输入数据进行处理的地方, 就是第30行, sprintf函数把我们输入的数据变成了无符号十六进制, 而且填入了只有两个位的数组, 也就是说要从v13中两个两个取出再转换成ASCII码, 就能得到flag了。

python代码如下:

flag:

CrackMeJustForFun

### Web CTF 初学者 'Hello World' 示例 对于初次接触Web CTF的新手来说,理解基本概念和常见漏洞至关重要。一个典型的‘Hello World’级别挑战通常涉及简单的SQL注入或源码泄露等问题。 #### SQL 注入基础示例[^1] 假设存在如下PHP代码片段用于处理登录请求: ```php <?php $username = $_GET['username']; $password = $_GET['password']; $query = "SELECT * FROM users WHERE username='$username' AND password='$password'"; $result = mysqli_query($connection, $query); if (mysqli_num_rows($result) > 0){ echo "Login successful!"; } else { echo "Invalid credentials"; } ?> ``` 在这个例子中,如果攻击者提交`?username=admin' -- &password=anything`作为参数,则查询语句变为: ```sql SELECT * FROM users WHERE username='admin' -- ' AND password='anything' ``` 由于双连字符(`--`)表示SQL中的注释符,因此后续部分被忽略,最终导致绕过密码验证成功登录管理员账户。 为了防止此类攻击,在构建应用程序时应始终采用预编译语句或其他安全措施来过滤用户输入的数据[^2]。 #### 文件包含漏洞简介[^3] 另一个常见的初学题目可能是本地文件包含(LFI),其中服务器端脚本未正确校验传入路径变量就直接读取并显示指定文件内容。例如下面这段易受攻击的Python Flask应用代码: ```python from flask import Flask, request, send_file app = Flask(__name__) @app.route('/view') def view(): filename = request.args.get('file', '') return send_file(filename) if __name__ == '__main__': app.run(debug=True) ``` 通过精心构造URL参数(如`/view?file=/etc/passwd`),可以迫使程序返回系统敏感配置文件的内容给客户端浏览器查看。 为了避免这种情况发生,开发者应当严格限定允许访问的具体目录范围,并对所有外部可控数据执行严格的白名单验证逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值