admin管理员组

文章数量:1581619

这一次ISCC初赛,感觉自己变牛逼了一点,本来想把所有题作完再来整理的,结果内核突然出了好几道超变态的题。顿时没有心思做了。

以前都是分大体写,这次写在一起吧。

//======================================格叽格叽==========================================

入门题

很恶心的选择题,百度 google 各凭本事,总之做了一统,什么都没有记住。

基础题

小豪的健忘症

就是一个hidden标签,没有什么好说的。

大牛们的黑历史

一个莫名其妙的人的照片,拿去google上搜一下,得出名字就好了。

如何得到一个网站的后台地址

这个考察了google hack 使用下面的语句就可以了

inurl:sae.bit   inurl:admin

如何备份数据

考察一个简单的cp语句

cp 源地址/*.data 目的地址

穿越

给出了一个正则表达式,和一个摩尔密码。

这里大括号是重复次数,小括号是分组,这个正则表达的是facebook的网址

w{3}.(?<a>t)w(?<b>i)\k<a>{2}er

这个摩尔密码表达的是一个用户的名字

. . . . /./. . -/. - ./. . -/. . ./.
找到这个用户发的一条状态,是heiligabend1992

H(?<a>e)(?<b>i)l\k<b>gab\k<a>nd[1][9]{2}[2]

是1992年的平安夜


你的鼻子怎么样

这个简单抓一下包,就出来了

隔壁宿舍的无线密码

这题给了握手包,要求破解wifi的密码。

下载一个Elcomsoft Wireless Security Auditor,直接开始跑,如果包的后缀不对可以使用wireshark转一下。

根据提示密码与生日有关,EWSA有一个掩码功能,或者下一个生日字典都可以跑出来。

看看你的基本功

就是一段机器码,随便放到debug里面跑,或者找个工具翻译出来,手动模拟一下都可以得到结果。

C语言进阶

考察一个基本的溢出

name     EBP   EIP
xiaohaoA  AAAA AABB DDDDDDDDDDDDDDDD

简单的破解

很简单,随便逆向一下就可以。

简单的加密算法

一个换位加密密码,百度一下,了解思路就可以手动破解出来。

顺便写了一个加密的代码。

#include <cassert>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <sstream>
#include <vector>
using namespace std;


int main()
{
    string source = "ZHUXINXIANQUANJULEBUWANGLUOANQUANJTNSAIYUANMANCHENGGONG";
    string key = "STUPIDRAGON";
    vector<char> map[37];
    for (int i=0;i<37;i++) map[i].clear();
    for (int i=0;i<source.length();i++){

        map[ key[i%11]-'A' ].push_back(source[i]);
    }
    for (int i=0;i<37;i++)
        for (int j=0;j<map[i].size();j++)
            cout<<map[i][j];
    cout<<endl;


    string a="IBQUGNLAINAUUAOIUOAEQANMGNWANNXJUSHXENYGZUNJAHAGINUNLNC";
    string b="IBQUGNLAINAUUAOIUOAEQANMGNWANNXJUSHXENYGZUNJAHAGTNUNLNC";
    for (int i=0;i<a.length();i++)
        if (a[i]!=b[i]) cout<<i<<endl;

    return 0;
}

脚本题

真的和cookie有关系

题目给了一段Base64代码,解开后是i am the key,看到cookie里面有一个user项,

把它放进去key就出来了。

输不完的验证码

页面会不停的刷新,让你无法输完验证码。刷新的代码分别是一个mate标签和一段js。

一开始想把页面down到本地修改一下提交,不过涉及到跨域post的问题。

最后使用IE浏览器禁止mate标签和js顺利解决

有字典就是感觉不一样

就是跑字典啊,自己实现或者用工具都可以。

给的用户名和密码都是MD5加密的,不用解密直接跑,得到正确的MD5再进行解密。

搞笑图片大收集

一个图片上传漏洞,这种一般随便加点分号空格00什么的就过了。

没什么能阻止我们变身admin

一道cookie注入的题,根据题目提示使用guest guest登陆。

发现cookie中有user password data这几项,其中后两个被base64加密了。

尝试了一下发现,data没有惊醒过滤,但是注入语句要先转成base64

给data赋值单引号报错。

Jw==
把user赋值admin data赋值' or '1'='1,会出现wecome admin

JyBvciAnMScgPSAnMQ==
这时候data里面的数据就会变成admin密码的base64.

破解

简单的看汇编代码

很简单的一道题,随便逆一下就可以看到key。

普通的一道破解题

先使用PEID看了一下,编译器是bloodshed,非常血腥。

先找到了结果返回的字符串,看看是不是直接把key输出,结果这段的意思是“就是这个”

BE CD CA C7 D5 E2 B8 F6 21 7E
看来还是需要找到真正的密码,那ida F5大法还原了一下生成key的函数。

int __cdecl main(int argc, const char **argv, const char *envp)
{
  int v4; // eax@1
  _BYTE *v5; // edx@5
  int v6; // eax@10
  int v7; // eax@11
  signed int v8; // [sp+1Ch] [bp-524Ch]@1
  _BYTE v9[10000]; // [sp+20h] [bp-5248h]@1
  char v10; // [sp+2730h] [bp-2B38h]@1
  char v11; // [sp+4E50h] [bp-418h]@1
  size_t v12; // [sp+5250h] [bp-18h]@1
  int v13; // [sp+5248h] [bp-20h]@1
  signed int v14; // [sp+524Ch] [bp-1Ch]@1
  int v15; // [sp+5254h] [bp-14h]@1
  signed int v16; // [sp+525Ch] [bp-Ch]@1
  int v17; // [sp+5258h] [bp-10h]@3
  _BYTE v18[8]; // [sp+5260h] [bp-8h]@5
  int v19; // [sp+5244h] [bp-24h]@7

  v8 = 16;
  __main();
  memcpy(v9, aK0lzyz9_e0Vwep, 0x2710u);
  memset(&v10, 0, 0x2712u);
  v4 = _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc((int)&dword_4483C0, (int)"请输入密码~");
  unknown_libname_91(v4, _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_);
  _ZStrsIcSt11char_traitsIcEERSt13basic_istreamIT_T0_ES6_PS3_(&dword_448460, &v11);
  v12 = strlen(&v11);
  v13 = 0;
  v14 = 0;
  v15 = 0;
  v16 = 41;
  while ( v16 <= 60 )
  {
    v17 = 1;
    while ( v16 + 5 >= v17 )
    {
      v5 = &v18[v13++ - 1040];
      if ( *v5 != v9[v17 * v16] )
        v14 = 1;
      ++v19;
      ++v17;
    }
    v13 = v13 - v15++ - 1;
    v16 += 6;
  }
  if ( v14 )
  {
    v7 = _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc((int)&dword_4483C0, (int)&unk_444E39);
    unknown_libname_91(v7, _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_);
  }
  else
  {
    v6 = _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc((int)&dword_4483C0, (int)&unk_444E2E);
    unknown_libname_91(v6, _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_);
  }
  system("pause");
  return 0;
}
把乱七八糟的东西删一删找到了主要的函数,运行一下得出key

A{?ZR;J`aEN's3sFn#h>0{jElf0];i'HEil)(qzo0>}&m4QL;s.D!9R`!lOGD05rDi,]b0}K%aeI]LfveL|EE'1SIC:Kql'ZFNy~60Jw)Fy)UEa;Ssy2YS%j2[qqHCq=M0n9iF^9j0wu1ou+}TLbg:o7..<4]To~1p58o1Q,C2^FiUa2RPHkF{8i=Kd7q?X{nf9:mx,gFd]:K{YbUS#r@h
这时却发现这个key不正确,拿od单步一下,发现有一位错了,改正即可。

求帮忙解密课件

这题是一个典型的RSA加密。

同样使用F5大法,这时候发现Hex-Rays1.0对int64兼容的不算特别好,而高版本网上又不提供下载。

Better recognition of 64-bit idioms, example 2

v21 = PageSize * (_DWORD)a6 - a2;
v22 = __MKCADD__(v21, qword_6992C7E0);
*(_DWORD *)&qword_6992C7E0 = v21 + qword_6992C7E0;
*((_DWORD *)&qword_6992C7E0 + 1) += ((unsigned __int64)PageSize * a6 >> 32) - ((unsigned int)(PageSize * (_DWORD)a6 < (_DWORD)a2) + *((_DWORD *)&a2 + 1)) + v22;    

qword_6992C7E0 += PageSize * a6 - a2;
这些宏理应定义在IDA的defs.h中,可是defs.h却很不负责任的这样定义,或许在IDA高版本下有定义。

#define __ROL__(x, y) __rotl__(x, y)       // Rotate left
#define __ROR__(x, y) __rotr__(x, y)       // Rotate right
#define __RCL__(x, y) invalid_operation    // Rotate left thru carry
#define __RCR__(x, y) invalid_operation    // Rotate right thru carry
#define __MKCADD__(x, y) invalid_operation // Generate carry flag for an addition
#define __MKOADD__(x, y) invalid_operation // Generate overflow flag for an addition
#define __MKCSHL__(x, y) invalid_operation // Generate carry flag for a shift left
#define __MKCSHR__(x, y) invalid_operation // Generate carry flag for a shift right
#define __MKCRCL__(x, y) invalid_operation // Generate carry flag for a RCL
#define __MKCRCR__(x, y) invalid_operation // Generate carry flag for a RCR
#define __SETO__(x, y)   invalid_operation // Generate overflow flags for (x-y)
不过这并不重要,把这些乱七八糟的东西删掉,把核心代码还原一下。

int main()
{
    source=1;
    temp=1;
    key=1;
    n =9986801107LL;

    char x;
    cin>>x;
    k = x -1;
    for (int i=1;i<=54517;++i){
        temp = key;
        key = (key + temp*k) % n;
    }
    while (key!=0){
        cout<<key % 10;
        key /= 10;
    }
    cout<<endl;
}

得到算法大概是这样,算法把每两个字符的ascii码进行加密,待加密数字asciiA*1000+asciiB

n    9986801107 = 99877 * 99991
x^d % n  中 d = 54517    (q-1)(p-1) = 9986601240
m * d mod (q-1)(p-1) = 1   得出m=732733

这里计算m的算法

比如rsa算法中 已知 p=101, q=97, e=13, 求d
 N=p*q=101*97=9797
φ(N)=(p-1)(q-1)=9600  欧拉函数
(13,9600)=1
9600=13*738+6    辗转相除法
13=6*2+1
1=13-2*6
 =13-2*(9600-13*738)
 =13*1477-2*9600
e=13,d=1477这里的e,d就是刚说的e1和e2
根据这些很容易的可以写出解密函数,之所以使用java是因为他的大数类或者使用半加法也可以在int64范围内得出正确结果

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.Scanner;


public class main {
    public static BigInteger RSAcode(BigInteger x,BigInteger d,BigInteger n){
        BigInteger ans = new BigInteger("1");
        BigInteger two = new BigInteger("2");
        while (!d.equals(BigInteger.ZERO)){
            if (d.mod(two).equals(BigInteger.ONE)){
                ans = ans.multiply(x).mod(n);
            }
            x = x.multiply(x).mod(n);
            d = d.divide(two);
        }
        return ans;
    }
    public static void main(String args[])
    {
        BigInteger n = new BigInteger("9986801107");
        BigInteger d = new BigInteger("54517");
        BigInteger m = new BigInteger("732733");
        BigInteger x = new BigInteger("49049");    
        
        System.out.println("Secret key:49049 9986801107");
        Scanner in = new Scanner(System.in);
        String code = in.nextLine();
        char[] tcode = new char [10];
        String ttcode = null;
        int icode;
        char ccode;
        for (int i=0;i<code.length();i+=10){
            for (int j=0;j<10;j++){
                tcode[10-j-1]=code.charAt(j+i);
                ttcode = String.valueOf(tcode);
                //System.out.println(ttcode);
            }
            icode = Integer.parseInt(RSAcode(new BigInteger(ttcode),m,n).toString());
            if (1000<icode){
                ccode = (char) (icode / 1000);
                System.out.print(ccode);
                ccode = (char) (icode % 1000);
                System.out.print(ccode);
            }
            else {
                ccode = (char) (icode);
                System.out.print(ccode);
            }
        }
        //System.out.println(RSAcode(x,d,n).toString());
        //System.out.println(RSAcode(RSAcode(x,d,n),m,n).toString());
    }
}

这用了一个壳~好像蛮麻烦的~

这个加了一个壳,首先不想把它脱掉了,太麻烦。这个可很可能有反动态调试的功能,并且修改了资源表。

所以使用IDA静态调试的时候,并无法定位到具体某个函数。使用od动态调试的时候,需要使用hideOD这个插件。

其实因为程序很小,随便单步几下就可以找到关键代码了。其实正确方法是在资源表(.rsc)下内存访问断点,

然后再壳还原资源表的时候,就可以断下了。

找到了关键代码

004010F9  |> /8B0E          /mov     ecx, dword ptr [esi]
004010FB  |. |B8 93244992   |mov     eax, 92492493
00401100  |. |83C1 0A       |add     ecx, 0A
00401103  |. |F7E9          |imul    ecx
00401105  |. |03D1          |add     edx, ecx
00401107  |. |C1FA 02       |sar     edx, 2
0040110A  |. |8BCA          |mov     ecx, edx
0040110C  |. |C1E9 1F       |shr     ecx, 1F
0040110F  |. |03D1          |add     edx, ecx
00401111  |. |8BCA          |mov     ecx, edx
00401113  |. |890E          |mov     dword ptr [esi], ecx
00401115  |. |8B46 04       |mov     eax, dword ptr [esi+4]
00401118  |. |99            |cdq
00401119  |. |F7F9          |idiv    ecx
0040111B  |. |52            |push    edx
0040111C  |. |68 20304000   |push    00403020                        ;  ASCII "%d"
00401121  |. |8916          |mov     dword ptr [esi], edx
00401123  |. |FFD5          |call    ebp
00401125  |. |83C4 08       |add     esp, 8
00401128  |. |83C6 04       |add     esi, 4
0040112B  |. |4F            |dec     edi
0040112C  |.^\75 CB         \jnz     short 004010F9

是一个循环回一个数组进行处理,先看一下这个数组是什么

57 65 64 20                    
4d 61 79 20
31 35 20
31 30 3a 35 37 3a 33 32 20
32 30 31 33
0a

Wed May 15 20:43:32 2013
这样看来,这个加密算法是通过取得一个时间来随机生成key。

再来看程序怎样对这段代码进行变换。


这段很痛疼的代码其实是对整数除法的一个编译器优化,

http://www.pediy/kssd/pediy11/116974.html

004010FB  |. |B8 93244992   |mov     eax, 92492493
00401100  |. |83C1 0A       |add     ecx, 0A
00401103  |. |F7E9          |imul    ecx
00401105  |. |03D1          |add     edx, ecx
00401107  |. |C1FA 02       |sar     edx, 2
0040110A  |. |8BCA          |mov     ecx, edx
其他的都很好懂,使用c++实现一下

#include "stdafx.h"
#include <time.h>
#include <string.h>

int main(int argc, char* argv[])
{
	char source[31];
	unsigned int c,a,d;
	memset(source,0,sizeof(source));
	time_t t = time(0);
	strftime(source,sizeof(source),"%a %b %m %X %Y\n",localtime(&t));
	printf("%s\n",source);
	for (int i=0;i<30;i++){
		c = source[i];
		c = c + 10;
 
		d = c / 7;
		c = d;

		source[i] = c;
		a = source[i+1];

本文标签: 思路