在本文中,我们将考虑来自站点
pwnable.kr的3个任务的解决方案。
组织信息特别是对于那些想要学习新知识并在信息和计算机安全性的任何领域中发展的人们,我将撰写和讨论以下类别:
- PWN;
- 密码学(加密);
- 网络技术(网络);
- 反向(反向工程);
- 隐写术(Stegano);
- 搜索和利用Web漏洞。
除此之外,我将分享我在计算机取证,恶意软件和固件分析,对无线网络和局域网的攻击,进行笔测试和编写漏洞利用程序方面的经验。
为了使您可以查找有关新文章,软件和其他信息的信息,我
在Telegram中创建了一个
频道,并创建了一个
小组来讨论 ICD领域中的
所有问题 。 另外,我会亲自考虑您的个人要求,问题,建议和建议,
并会回答所有人 。
提供所有信息仅出于教育目的。 对于由于使用本文档而获得的知识和方法对某人造成的任何损害,本文档的作者不承担任何责任。
问题解决硬币1
单击带有签名coin1的图标,并提供用于连接的地址和端口。

连接后,我们可以玩游戏并提供游戏规则。 他们还给了我们60秒的完成时间,因此我们必须使一切自动化。

根据游戏规则,我们给了N枚硬币,每枚重10枚硬币,但一个除外-它的权重为9。我们给出了一场游戏的机会(回合)数C。 在每个回合中,我们都会发送硬币指数,并且还会给出总权重。 因此,使用
二进制搜索 ,我们将找到所需的硬币。
让我们写一个代码。 首先,建立与服务器的连接,接受并解析数字N和C。
from pwn import * r = remote('pwnable.kr', 9007) r.recv() s = r.recv() print(s) n = int(s.split(' ')[0][2:]) c = int(s.split('=')[2].split('\n')[0]) print(n, c)

太好了 现在,我们将编写一个通过一个级别的部分。 为此,我们需要一个从1到N + 1的值的数组和一个C步的周期,每次迭代将发送该数组的一半。 如果答案中返回的权重除以10,而没有余数,则我们的硬币位于数组的另一部分。 因此,我们将再次将另一半分开并对其进行相同操作,依此类推。 直到发现硬币为止。
mas = range(1,n+1) for i in range(c): s = "" if len(mas)==1: mas.append(mas[0]) for j in mas[:len(mas)/2]: s += (str(j)+" ") print(s) r.send(s+"\n") nr = r.recv() print(nr) if int(nr) % 10: mas = mas[:len(mas)/2] else: mas = mas[len(mas)/2:] r.send(str(mas[0])+"\n") print(r.recv())

现在,将此解决方案添加到循环中以完成所有级别。
from pwn import * r = remote('pwnable.kr', 9007) r.recv() for level in range(1, 101): s = r.recvline() n = int(s.split(' ')[0][2:]) c = int(s.split('=')[2].split('\n')[0]) mas = range(1,n+1) for i in range(c): s = "" if len(mas)==1: mas.append(mas[0]) for j in mas[:len(mas)/2]: s += (str(j)+" ") r.send(s+"\n") nr = r.recv() if int(nr) % 10: mas = mas[:len(mas)/2] else: mas = mas[len(mas)/2:] r.send(str(mas[0])+"\n") r.recvline() if level%5==0: print("Check "+str(level)+"/100") print(r.recv())

我们交出国旗并获得积分。
二十一点工作解决方案
单击带有签名coin1的第一个图标,然后提供用于连接的地址和端口。 他们还说您需要赢一百万。

连接后,我们可以玩游戏并询问准备情况。

在我们回答之后,转到菜单,开始游戏,找到规则或退出游戏。

开始新游戏。

此类任务通常在CTF中找到,了解它们非常有用。 很可能没有负数处理程序。 因此,如果您输入-999500并输了,则将从我们的银行中减去负数,即添加正数(500-(-500)= 500 + 500 = 1000)。 我们介绍-1000000。


我们交出国旗,再得一分。
解决乐透的追求
我们单击带有乐透签名的第一个图标,然后被告知我们需要通过SSH与密码guest连接。

连接后,我们会看到相应的横幅。

让我们找出服务器上有哪些文件,以及我们拥有的权限。

让我们看看代码的结果。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> unsigned char submit[6]; void play(){ int i; printf("Submit your 6 lotto bytes : "); fflush(stdout); int r; r = read(0, submit, 6); printf("Lotto Start!\n"); //sleep(1); // generate lotto numbers int fd = open("/dev/urandom", O_RDONLY); if(fd==-1){ printf("error. tell admin\n"); exit(-1); } unsigned char lotto[6]; if(read(fd, lotto, 6) != 6){ printf("error2. tell admin\n"); exit(-1); } for(i=0; i<6; i++){ lotto[i] = (lotto[i] % 45) + 1; // 1 ~ 45 } close(fd); // calculate lotto score int match = 0, j = 0; for(i=0; i<6; i++){ for(j=0; j<6; j++){ if(lotto[i] == submit[j]){ match++; } } } // win! if(match == 6){ system("/bin/cat flag"); } else{ printf("bad luck...\n"); } } void help(){ printf("- nLotto Rule -\n"); printf("nlotto is consisted with 6 random natural numbers less than 46\n"); printf("your goal is to match lotto numbers as many as you can\n"); printf("if you win lottery for *1st place*, you will get reward\n"); printf("for more details, follow the link below\n"); printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01\n\n"); printf("mathematical chance to win this game is known to be 1/8145060.\n"); } int main(int argc, char* argv[]){ // menu unsigned int menu; while(1){ printf("- Select Menu -\n"); printf("1. Play Lotto\n"); printf("2. Help\n"); printf("3. Exit\n"); scanf("%d", &menu); switch(menu){ case 1: play(); break; case 2: help(); break; case 3: printf("bye\n"); return 0; default: printf("invalid menu\n"); break; } } return 0; }
main()函数没有什么有趣的。 在分析了play()函数之后,我们将了解程序的逻辑。 首先,我们输入6个值,然后程序伪随机生成范围(1-45)内的另外6个,然后将这两个序列进行比较。 我们得到了一个有6个匹配项的标志。 但是检查不正确。 因此,在一个循环中,将输入序列的每个字符与生成的每个字符进行比较。

因此,我们每次将输入6个相同的字符,直到获得该标志。 我输入!!!!!!,并获得了7次标志。

我们交出国旗并获得两分。 在以下文章中见!
我们在电报频道中:
Telegram中的
频道 。