monster's Blog

夕阳碧霄亭

HITCTF

monster posted @ 2014年7月07日 15:38 in 心情 , 1930 阅读

入职前一天,增强来找我说是中心里组了只队要参加下HITCTF。正好无聊就跟着大家水了一把。
这里简单说下我做的几道题。

ROT

题目就给了一个 ip 和端口。nc 连上去以后返回一个老 jb 长的字符串(长相略像 base64 编码),最后一行有几个字符,“Answer:”,过了两秒以后连接自动断开了。 又连了几次,发现每次得到的 base64 字串都不一样,而且都是两秒后断开。 对该长字符串 Base64 解码,得到了一个 png 图,如下: 

仔细观察一发。应该只要把相应的部位拼凑在一起就行。。。题目中不是也说rot90。。。

。。。。好了。。开始编码吧。。。。

import Image
import socket
import base64
import pytesser

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('41.231.53.40', 9090))
c = ''
while True:
  t = sock.recv(100)
  c = c + t
  if len(t) < 100:
    break
data = base64.decodestring(c[:-8])
open('t.png','wb').write(data)

img = Image.new('RGB',(160,20))
out = img.load()

pix = Image.open('t.png').load()
for i in xrange(160):
  for j in xrange(20):
    if reduce(lambda x, y : x + y, pix[105 + j, 190 - i] + pix[94 - j, 9 + i]) < 1000:
      out[i, j] = (255, 255, 255)

ans = pytesser.image_to_string(img)  
print ans
sock.send(ans)
print sock.recv(1024)

。。。运行后的结果如下。

pytesser的判断偶尔也会失误。。。提交个三四次。。。成功得到flag

RE10

把题目中给的文件下载下来。。。发现是个ELF文件

。运行了一下。。无限输出“baby crackme”。。。

扔ida里。

Main函数如下

.text:08048454                 public main
.text:08048454 main            proc near               ; DATA XREF: _start+17o
.text:08048454
.text:08048454 arg_0           = dword ptr  8
.text:08048454
.text:08048454                 push    ebp
.text:08048455                 mov     ebp, esp
.text:08048457                 and     esp, 0FFFFFFF0h
.text:0804845A                 sub     esp, 10h
.text:0804845D                 cmp     [ebp+arg_0], 1
.text:08048461                 jg      short loc_8048471
.text:08048463
.text:08048463 loc_8048463:                            ; CODE XREF: main+1Bj
.text:08048463                 mov     dword ptr [esp], offset s ; "Baby Crackme"
.text:0804846A                 call    _puts
.text:0804846F                 jmp     short loc_8048463
.text:08048471 ; ---------------------------------------------------------------------------
.text:08048471
.text:08048471 loc_8048471:                            ; CODE XREF: main+Dj
.text:08048471                 mov     dword ptr [esp], 47h ; c
.text:08048478                 call    _putchar
.text:0804847D                 mov     dword ptr [esp], 30h ; c
.text:08048484                 call    _putchar
.text:08048489                 mov     dword ptr [esp], 30h ; c
.text:08048490                 call    _putchar
.text:08048495                 mov     dword ptr [esp], 64h ; c
.text:0804849C                 call    _putchar
.text:080484A1                 mov     dword ptr [esp], 5Fh ; c
.text:080484A8                 call    _putchar
.text:080484AD                 mov     dword ptr [esp], 42h ; c
.text:080484B4                 call    _putchar
.text:080484B9                 mov     dword ptr [esp], 30h ; c
.text:080484C0                 call    _putchar
.text:080484C5                 mov     eax, offset format ; "%c\n"
.text:080484CA                 mov     dword ptr [esp+4], 79h
.text:080484D2                 mov     [esp], eax      ; format
.text:080484D5                 call    _printf
.text:080484DA                 mov     eax, 0
.text:080484DF                 leave
.text:080484E0                 retn
.text:080484E0 main            endp

逆一下。。。

int __cdecl main(signed int argc)
{
  if ( argc <= 1 )
  {
    while ( 1 )
      puts("Baby Crackme");
  }
  putchar('G');
  putchar('0');
  putchar('0');
  putchar('d');
  putchar('_');
  putchar('B');
  putchar('0');
  printf("%c\n", 'y');
  return 0;
}

。。这里判断命令行参数个数。。。无参数的话就无循环。。随便加个参数就输出  G00d_B0y。。。。这是个啥东西。。莫非是flag?不要吓我。。。这么简单。后来又看了下题目。只有10分,弱弱的一试。还真是flag

Linux Kernel

下载题目中给出的文件。。。先跑下。。。segment fault、。。。ida调试刚连上去就自己断开。咋回事?到最后都没搞明白。。。

直接扔ida里开始逆吧。。。

从启动函数开始看,一路设置GDT,IDT,IRQ。。。然后开个定时器,主线程就结束了。。。。没发现啥和flag有关的。。。。把定时器翻出来看看,代码如下:

.text:00100958                 public timer_tick
.text:00100958 timer_tick      proc near               ; DATA XREF: timer_init+3o
.text:00100958                 sub     esp, 14h
.text:0010095B                 mov     eax, ds:1060C0h
.text:00100960                 lea     edx, [eax+1]
.text:00100963                 mov     ds:1060C0h, edx
.text:00100969                 push    eax
.text:0010096A                 push    offset aDTick__ ; "%d Tick..\n"
.text:0010096F                 call    printf
.text:00100974                 movzx   ecx, byte ptr ds:1060C0h
.text:0010097B                 add     esp, 10h
.text:0010097E                 mov     eax, 0
.text:00100983
.text:00100983 loc_100983:                             ; CODE XREF: timer_tick+42j
.text:00100983                 mov     edx, ecx
.text:00100985                 xor     dl, byte ptr ds:flag[eax]
.text:0010098B                 add     edx, 1
.text:0010098E                 mov     byte ptr ds:flag[eax], dl
.text:00100994                 add     eax, 1
.text:00100997                 cmp     eax, 28h
.text:0010099A                 jnz     short loc_100983
.text:0010099C                 add     esp, 0Ch
.text:0010099F                 retn
.text:0010099F timer_tick      endp

。。。。。。。用IDA来F5一下。。。。               

int __cdecl timer_tick()
{
  char tick; // cl@1
  int i; // eax@1

  ++*(_DWORD *)&idt[128];                       // int x = idt[128] + 1
  printf("%d Tick..\n");
  tick = idt[128];
  i = 0;
  do
  {
    flag[i] = (flag[i] ^ tick) + 1;
    ++i;
  }
  while ( i != 40 );
  return i;
}

出现这样的代码。。。。不知道这里是IDA脑抽了还是我的智商太低理解不了。。ida的地址是106140h居然把1060C0h翻译成了&idt[128]。。不应该是&idt[-128]么。。

害我还跟踪了半天的idt[128]。。。结果一无所获。。。。

。。。郁闷。这个值到底咋计算出来了。。。。把程序看了好几遍依然没看出来。。。

之后灵光一闪。。。发现了一个比较蛋疼的办法。。

这里的flag只和tick进行运算。。。而tick是个char。。。也就是说现在flag可能的取值一共有256种。。。。

那就爆破吧。。。。程序如下

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


int f(char b[])
{
	for (int i = 0;i < strlen(b);i++)
	{
		if ((int)b[i] < 0x10 || (int)b[i] > 0x80)
		{
			return 0;
		}
	}
	return 1;
}

int main(int argc, char* argv[]) 
{
	int i, j;
	char s[] = {
		0x49, 0x74, 0x6F, 0x66, 0x72, 0x6A, 0x78, 0x62, 0x32, 0x60, 
		0x2E, 0x2E, 0x63, 0x2E, 0x32, 0x2E, 0x36, 0x30, 0x33, 0x31, 
		0x5D, 0x67, 0x36, 0x62, 0x31, 0x67, 0x67, 0x30, 0x5E, 0x29, 
		0x62, 0x31, 0x31, 0x63, 0x62, 0x5E, 0x5E, 0x2D, 0x5D, 0x7A, 0x00};
	char d[100];
	for (i = 0;i < 255;i++)
	{
		for (j = 0;j < strlen(s);j++)
		{
			d[j] = ((int)s[j] ^ i) + 1;
		}
		for (j = 0;j < strlen(s);j++)
		{
			d[j] = ((int)d[j] ^ (i + 1)) + 1;
		}
		for (j = 0;j < strlen(s);j++)
		{
			d[j] = ((int)d[j] ^ (i + 2)) + 1;
		}
		d[j] = 0;
		if (f(d))
		{
			printf("%s\n", d);
		}
	}
	return 0;
}

编译。。。运行。。。

结果如下

crackme

。。。题目忘了叫啥了。。。三百分的一个题。。感觉这个题分给高了。200分差不多。。。

题目中给了个地址。http://41.231.53.44:9393/。。。访问下。。下载到一个文件。。。

打开看看。。

文件头是个lpck。。。不知道啥格式。。。不过在之后看到了MZ头。。。把MZ头之前的部分统统删掉。。。成功得到一个exe

。。。。password是啥。。我哪知道。。。直接扔进ida….找到关键部分如下:

.text:00401363                 mov     [esp+5Ch+var_5C], offset aPassword ; "Password :"
.text:0040136A                 call    puts
.text:0040136F                 lea     eax, [esp+5Ch+var_3E]
.text:00401373                 mov     [esp+5Ch+var_58], eax
.text:00401377                 mov     [esp+5Ch+var_5C], offset aS ; "%s"
.text:0040137E                 call    scanf
.text:00401383                 mov     [esp+5Ch+var_14], 0
.text:0040138B                 jmp     short loc_4013B1
.text:0040138D ; ---------------------------------------------------------------------------
.text:0040138D
.text:0040138D loc_40138D:                             ; CODE XREF: main+8Fj
.text:0040138D                 mov     eax, [esp+5Ch+var_14]
.text:00401391                 mov     eax, [esp+eax*4+5Ch+var_34]
.text:00401395                 mov     ecx, eax
.text:00401397                 xor     ecx, 1
.text:0040139A                 lea     edx, [esp+5Ch+var_3E]
.text:0040139E                 mov     eax, [esp+5Ch+var_14]
.text:004013A2                 add     eax, edx
.text:004013A4                 mov     al, [eax]
.text:004013A6                 movsx   eax, al
.text:004013A9                 cmp     ecx, eax
.text:004013AB                 jnz     short loc_4013C7
.text:004013AD                 inc     [esp+5Ch+var_14]
.text:004013B1
.text:004013B1 loc_4013B1:                             ; CODE XREF: main+57j
.text:004013B1                 mov     ebx, [esp+5Ch+var_14]
.text:004013B5                 lea     eax, [esp+5Ch+var_3E]
.text:004013B9                 mov     [esp+5Ch+var_5C], eax
.text:004013BC                 call    strlen
.text:004013C1                 cmp     ebx, eax
.text:004013C3                 jb      short loc_40138D
.text:004013C5                 jmp     short loc_4013C8
.text:004013C7 ; ---------------------------------------------------------------------------
.text:004013C7
.text:004013C7 loc_4013C7:                             ; CODE XREF: main+77j
.text:004013C7                 nop
.text:004013C8
.text:004013C8 loc_4013C8:                             ; CODE XREF: main+91j
.text:004013C8                 lea     eax, [esp+5Ch+var_3E]
.text:004013CC                 mov     [esp+5Ch+var_5C], eax
.text:004013CF                 call    strlen
.text:004013D4                 cmp     eax, 8
.text:004013D7                 jnz     short loc_4013E8
.text:004013D9                 cmp     [esp+5Ch+var_14], 8
.text:004013DE                 jnz     short loc_4013E8
.text:004013E0                 mov     [esp+5Ch+var_10], 1
.text:004013E8
.text:004013E8 loc_4013E8:                             ; CODE XREF: main+A3j
.text:004013E8                                         ; main+AAj
.text:004013E8                 cmp     [esp+5Ch+var_10], 1
.text:004013ED                 jnz     short loc_4013FD
.text:004013EF                 mov     [esp+5Ch+var_5C], offset aGoodBoySendTha ; "Good Boy ! Send That pass to server to "...
.text:004013F6                 call    printf
.text:004013FB                 jmp     short loc_401409
.text:004013FD ; ---------------------------------------------------------------------------
.text:004013FD
.text:004013FD loc_4013FD:                             ; CODE XREF: main+B9j
.text:004013FD                 mov     [esp+5Ch+var_5C], offset aSorryIncorrect ; "Sorry ! Incorrect pass"
.text:00401404                 call    printf

大概理解一下。。这里输入的字符串为8个字符…然后以esp+5Ch+var_34为地址之后的8个DWORD,取低8位字符,然后都xor 1。。。结果与输入的串比较。。相等刚正确。。

来看看esp+5Ch+var_34的数据怎么得到的

.text:00401345                 lea     edx, [esp+5Ch+var_34]
.text:00401349                 mov     ebx, 402000h
.text:0040134E                 mov     eax, 8
.text:00401353                 mov     edi, edx
.text:00401355                 mov     esi, ebx
.text:00401357                 mov     ecx, eax
.text:00401359                 rep movsd

..看样子是从402000h复制过来的啊。。。跟过去看看…

…看样子把这些东西xor 1一下就可以得到password了。。。拿到key以后提交上去。。。结果。。”Too late”…好吧。人家要求两秒种之内。。。

那就把VA转换成文件便宜。。。得到0x1310。。。。写个脚本自动破解吧。。

import requests

cookie = {'symfony':'1gc3ucf1kdqqgjeoektjd04703','PHPSESSID':'hql5vuag24tq3vllehoe9r5kg0'}

r = requests.get('http://41.231.53.44:9393/', cookies=cookie)
print r
s = str(r.content[0x1310:0x1330])
k = ''
for i in range(0x20):
	if i % 4 == 0:
		k = k + chr(ord(s[i]) ^ 1)

print k

r1 = requests.get('http://41.231.53.44:9393/check.php?p=' + k, cookies=cookie)
print r1
print r1.content

 

 

 

 

Avatar_small
del 说:
2014年12月12日 01:16

好厉害,脚本都是python写的么,汇编好牛

Avatar_small
cleaning companies 说:
2019年11月02日 01:01

Your dirty house is actually a sanctuary for an array of uncontrollable terrible bacteria plus viruses. The extra dirt plus dust this passes through the home from the doors and windows, the extra expected you're letting around unwanted germs and terrible bacteria. While an easy surface get rid of might keep several of the lesser bugs away, it is simply through your deep cleaning that you may really get rid of and get rid of the bigger terrible germs this skulk underneath the surface. At SpringCLeaning Expert services Dubai most people aid all of our customers to achieve the core of their total deep cleaning up issues resolved by presenting professional, quality profound cleaning expert services in Dubai as well as surrounding spots.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter